kdf.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873
  1. /* kdf.c
  2. *
  3. * Copyright (C) 2006-2023 wolfSSL Inc.
  4. *
  5. * This file is part of wolfSSL.
  6. *
  7. * wolfSSL is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * wolfSSL is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
  20. */
  21. #ifdef HAVE_CONFIG_H
  22. #include <config.h>
  23. #endif
  24. #include <wolfssl/wolfcrypt/wc_port.h>
  25. #include <wolfssl/wolfcrypt/error-crypt.h>
  26. #include <wolfssl/wolfcrypt/logging.h>
  27. #ifndef NO_KDF
  28. #if defined(HAVE_FIPS) && \
  29. defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 5)
  30. /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
  31. #define FIPS_NO_WRAPPERS
  32. #ifdef USE_WINDOWS_API
  33. #pragma code_seg(".fipsA$m")
  34. #pragma const_seg(".fipsB$m")
  35. #endif
  36. #endif
  37. #ifdef NO_INLINE
  38. #include <wolfssl/wolfcrypt/misc.h>
  39. #else
  40. #define WOLFSSL_MISC_INCLUDED
  41. #include <wolfcrypt/src/misc.c>
  42. #endif
  43. #include <wolfssl/wolfcrypt/hmac.h>
  44. #include <wolfssl/wolfcrypt/kdf.h>
  45. #if defined(WOLFSSL_HAVE_PRF) && !defined(NO_HMAC)
  46. #ifdef WOLFSSL_SHA512
  47. #define P_HASH_MAX_SIZE WC_SHA512_DIGEST_SIZE
  48. #elif defined(WOLFSSL_SHA384)
  49. #define P_HASH_MAX_SIZE WC_SHA384_DIGEST_SIZE
  50. #else
  51. #define P_HASH_MAX_SIZE WC_SHA256_DIGEST_SIZE
  52. #endif
  53. /* Pseudo Random Function for MD5, SHA-1, SHA-256, SHA-384, or SHA-512 */
  54. int wc_PRF(byte* result, word32 resLen, const byte* secret,
  55. word32 secLen, const byte* seed, word32 seedLen, int hash,
  56. void* heap, int devId)
  57. {
  58. word32 len = P_HASH_MAX_SIZE;
  59. word32 times;
  60. word32 lastLen;
  61. word32 lastTime;
  62. int ret = 0;
  63. #ifdef WOLFSSL_SMALL_STACK
  64. byte* previous;
  65. byte* current;
  66. Hmac* hmac;
  67. #else
  68. byte previous[P_HASH_MAX_SIZE]; /* max size */
  69. byte current[P_HASH_MAX_SIZE]; /* max size */
  70. Hmac hmac[1];
  71. #endif
  72. switch (hash) {
  73. #ifndef NO_MD5
  74. case md5_mac:
  75. hash = WC_MD5;
  76. len = WC_MD5_DIGEST_SIZE;
  77. break;
  78. #endif
  79. #ifndef NO_SHA256
  80. case sha256_mac:
  81. hash = WC_SHA256;
  82. len = WC_SHA256_DIGEST_SIZE;
  83. break;
  84. #endif
  85. #ifdef WOLFSSL_SHA384
  86. case sha384_mac:
  87. hash = WC_SHA384;
  88. len = WC_SHA384_DIGEST_SIZE;
  89. break;
  90. #endif
  91. #ifdef WOLFSSL_SHA512
  92. case sha512_mac:
  93. hash = WC_SHA512;
  94. len = WC_SHA512_DIGEST_SIZE;
  95. break;
  96. #endif
  97. #ifdef WOLFSSL_SM3
  98. case sm3_mac:
  99. hash = WC_SM3;
  100. len = WC_SM3_DIGEST_SIZE;
  101. break;
  102. #endif
  103. #ifndef NO_SHA
  104. case sha_mac:
  105. hash = WC_SHA;
  106. len = WC_SHA_DIGEST_SIZE;
  107. break;
  108. #endif
  109. default:
  110. return HASH_TYPE_E;
  111. }
  112. times = resLen / len;
  113. lastLen = resLen % len;
  114. if (lastLen)
  115. times += 1;
  116. /* times == 0 if resLen == 0, but times == 0 abides clang static analyzer
  117. while resLen == 0 doesn't */
  118. if (times == 0)
  119. return BAD_FUNC_ARG;
  120. lastTime = times - 1;
  121. #ifdef WOLFSSL_SMALL_STACK
  122. previous = (byte*)XMALLOC(P_HASH_MAX_SIZE, heap, DYNAMIC_TYPE_DIGEST);
  123. current = (byte*)XMALLOC(P_HASH_MAX_SIZE, heap, DYNAMIC_TYPE_DIGEST);
  124. hmac = (Hmac*)XMALLOC(sizeof(Hmac), heap, DYNAMIC_TYPE_HMAC);
  125. if (previous == NULL || current == NULL || hmac == NULL) {
  126. if (previous) XFREE(previous, heap, DYNAMIC_TYPE_DIGEST);
  127. if (current) XFREE(current, heap, DYNAMIC_TYPE_DIGEST);
  128. if (hmac) XFREE(hmac, heap, DYNAMIC_TYPE_HMAC);
  129. return MEMORY_E;
  130. }
  131. #endif
  132. #ifdef WOLFSSL_CHECK_MEM_ZERO
  133. XMEMSET(previous, 0xff, P_HASH_MAX_SIZE);
  134. wc_MemZero_Add("wc_PRF previous", previous, P_HASH_MAX_SIZE);
  135. wc_MemZero_Add("wc_PRF current", current, P_HASH_MAX_SIZE);
  136. wc_MemZero_Add("wc_PRF hmac", hmac, sizeof(Hmac));
  137. #endif
  138. ret = wc_HmacInit(hmac, heap, devId);
  139. if (ret == 0) {
  140. ret = wc_HmacSetKey(hmac, hash, secret, secLen);
  141. if (ret == 0)
  142. ret = wc_HmacUpdate(hmac, seed, seedLen); /* A0 = seed */
  143. if (ret == 0)
  144. ret = wc_HmacFinal(hmac, previous); /* A1 */
  145. if (ret == 0) {
  146. word32 i;
  147. word32 idx = 0;
  148. for (i = 0; i < times; i++) {
  149. ret = wc_HmacUpdate(hmac, previous, len);
  150. if (ret != 0)
  151. break;
  152. ret = wc_HmacUpdate(hmac, seed, seedLen);
  153. if (ret != 0)
  154. break;
  155. ret = wc_HmacFinal(hmac, current);
  156. if (ret != 0)
  157. break;
  158. if ((i == lastTime) && lastLen)
  159. XMEMCPY(&result[idx], current,
  160. min(lastLen, P_HASH_MAX_SIZE));
  161. else {
  162. XMEMCPY(&result[idx], current, len);
  163. idx += len;
  164. ret = wc_HmacUpdate(hmac, previous, len);
  165. if (ret != 0)
  166. break;
  167. ret = wc_HmacFinal(hmac, previous);
  168. if (ret != 0)
  169. break;
  170. }
  171. }
  172. }
  173. wc_HmacFree(hmac);
  174. }
  175. ForceZero(previous, P_HASH_MAX_SIZE);
  176. ForceZero(current, P_HASH_MAX_SIZE);
  177. ForceZero(hmac, sizeof(Hmac));
  178. #if defined(WOLFSSL_CHECK_MEM_ZERO)
  179. wc_MemZero_Check(previous, P_HASH_MAX_SIZE);
  180. wc_MemZero_Check(current, P_HASH_MAX_SIZE);
  181. wc_MemZero_Check(hmac, sizeof(Hmac));
  182. #endif
  183. #ifdef WOLFSSL_SMALL_STACK
  184. XFREE(previous, heap, DYNAMIC_TYPE_DIGEST);
  185. XFREE(current, heap, DYNAMIC_TYPE_DIGEST);
  186. XFREE(hmac, heap, DYNAMIC_TYPE_HMAC);
  187. #endif
  188. return ret;
  189. }
  190. #undef P_HASH_MAX_SIZE
  191. /* compute PRF (pseudo random function) using SHA1 and MD5 for TLSv1 */
  192. int wc_PRF_TLSv1(byte* digest, word32 digLen, const byte* secret,
  193. word32 secLen, const byte* label, word32 labLen,
  194. const byte* seed, word32 seedLen, void* heap, int devId)
  195. {
  196. int ret = 0;
  197. word32 half = (secLen + 1) / 2;
  198. const byte* md5_half;
  199. const byte* sha_half;
  200. byte* md5_result;
  201. #ifdef WOLFSSL_SMALL_STACK
  202. byte* sha_result;
  203. byte* labelSeed;
  204. #else
  205. byte sha_result[MAX_PRF_DIG]; /* digLen is real size */
  206. byte labelSeed[MAX_PRF_LABSEED];
  207. #endif
  208. if (half > MAX_PRF_HALF ||
  209. labLen + seedLen > MAX_PRF_LABSEED ||
  210. digLen > MAX_PRF_DIG)
  211. {
  212. return BUFFER_E;
  213. }
  214. #ifdef WOLFSSL_SMALL_STACK
  215. sha_result = (byte*)XMALLOC(MAX_PRF_DIG, heap, DYNAMIC_TYPE_DIGEST);
  216. labelSeed = (byte*)XMALLOC(MAX_PRF_LABSEED, heap, DYNAMIC_TYPE_DIGEST);
  217. if (sha_result == NULL || labelSeed == NULL) {
  218. XFREE(sha_result, heap, DYNAMIC_TYPE_DIGEST);
  219. XFREE(labelSeed, heap, DYNAMIC_TYPE_DIGEST);
  220. return MEMORY_E;
  221. }
  222. #endif
  223. md5_half = secret;
  224. sha_half = secret + half - secLen % 2;
  225. md5_result = digest;
  226. XMEMCPY(labelSeed, label, labLen);
  227. XMEMCPY(labelSeed + labLen, seed, seedLen);
  228. if ((ret = wc_PRF(md5_result, digLen, md5_half, half, labelSeed,
  229. labLen + seedLen, md5_mac, heap, devId)) == 0) {
  230. if ((ret = wc_PRF(sha_result, digLen, sha_half, half, labelSeed,
  231. labLen + seedLen, sha_mac, heap, devId)) == 0) {
  232. #ifdef WOLFSSL_CHECK_MEM_ZERO
  233. wc_MemZero_Add("wc_PRF_TLSv1 sha_result", sha_result, digLen);
  234. #endif
  235. /* calculate XOR for TLSv1 PRF */
  236. /* md5 result is placed directly in digest */
  237. xorbuf(digest, sha_result, digLen);
  238. ForceZero(sha_result, digLen);
  239. }
  240. }
  241. #if defined(WOLFSSL_CHECK_MEM_ZERO)
  242. wc_MemZero_Check(sha_result, MAX_PRF_DIG);
  243. #endif
  244. #ifdef WOLFSSL_SMALL_STACK
  245. XFREE(sha_result, heap, DYNAMIC_TYPE_DIGEST);
  246. XFREE(labelSeed, heap, DYNAMIC_TYPE_DIGEST);
  247. #endif
  248. return ret;
  249. }
  250. /* Wrapper for TLS 1.2 and TLSv1 cases to calculate PRF */
  251. /* In TLS 1.2 case call straight thru to wc_PRF */
  252. int wc_PRF_TLS(byte* digest, word32 digLen, const byte* secret, word32 secLen,
  253. const byte* label, word32 labLen, const byte* seed, word32 seedLen,
  254. int useAtLeastSha256, int hash_type, void* heap, int devId)
  255. {
  256. int ret = 0;
  257. if (useAtLeastSha256) {
  258. #ifdef WOLFSSL_SMALL_STACK
  259. byte* labelSeed;
  260. #else
  261. byte labelSeed[MAX_PRF_LABSEED];
  262. #endif
  263. if (labLen + seedLen > MAX_PRF_LABSEED) {
  264. return BUFFER_E;
  265. }
  266. #ifdef WOLFSSL_SMALL_STACK
  267. labelSeed = (byte*)XMALLOC(MAX_PRF_LABSEED, heap, DYNAMIC_TYPE_DIGEST);
  268. if (labelSeed == NULL) {
  269. return MEMORY_E;
  270. }
  271. #endif
  272. XMEMCPY(labelSeed, label, labLen);
  273. XMEMCPY(labelSeed + labLen, seed, seedLen);
  274. /* If a cipher suite wants an algorithm better than sha256, it
  275. * should use better. */
  276. if (hash_type < sha256_mac || hash_type == blake2b_mac) {
  277. hash_type = sha256_mac;
  278. }
  279. /* compute PRF for MD5, SHA-1, SHA-256, or SHA-384 for TLSv1.2 PRF */
  280. ret = wc_PRF(digest, digLen, secret, secLen, labelSeed,
  281. labLen + seedLen, hash_type, heap, devId);
  282. #ifdef WOLFSSL_SMALL_STACK
  283. XFREE(labelSeed, heap, DYNAMIC_TYPE_DIGEST);
  284. #endif
  285. }
  286. else {
  287. #ifndef NO_OLD_TLS
  288. /* compute TLSv1 PRF (pseudo random function using HMAC) */
  289. ret = wc_PRF_TLSv1(digest, digLen, secret, secLen, label, labLen, seed,
  290. seedLen, heap, devId);
  291. #else
  292. ret = BAD_FUNC_ARG;
  293. #endif
  294. }
  295. return ret;
  296. }
  297. #endif /* WOLFSSL_HAVE_PRF && !NO_HMAC */
  298. #if defined(HAVE_HKDF) && !defined(NO_HMAC)
  299. /* Extract data using HMAC, salt and input.
  300. * RFC 5869 - HMAC-based Extract-and-Expand Key Derivation Function (HKDF)
  301. *
  302. * prk The generated pseudorandom key.
  303. * salt The salt.
  304. * saltLen The length of the salt.
  305. * ikm The input keying material.
  306. * ikmLen The length of the input keying material.
  307. * digest The type of digest to use.
  308. * returns 0 on success, otherwise failure.
  309. */
  310. int wc_Tls13_HKDF_Extract(byte* prk, const byte* salt, word32 saltLen,
  311. byte* ikm, word32 ikmLen, int digest)
  312. {
  313. int ret;
  314. word32 len = 0;
  315. switch (digest) {
  316. #ifndef NO_SHA256
  317. case WC_SHA256:
  318. len = WC_SHA256_DIGEST_SIZE;
  319. break;
  320. #endif
  321. #ifdef WOLFSSL_SHA384
  322. case WC_SHA384:
  323. len = WC_SHA384_DIGEST_SIZE;
  324. break;
  325. #endif
  326. #ifdef WOLFSSL_TLS13_SHA512
  327. case WC_SHA512:
  328. len = WC_SHA512_DIGEST_SIZE;
  329. break;
  330. #endif
  331. #ifdef WOLFSSL_SM3
  332. case WC_SM3:
  333. len = WC_SM3_DIGEST_SIZE;
  334. break;
  335. #endif
  336. default:
  337. return BAD_FUNC_ARG;
  338. }
  339. /* When length is 0 then use zeroed data of digest length. */
  340. if (ikmLen == 0) {
  341. ikmLen = len;
  342. XMEMSET(ikm, 0, len);
  343. }
  344. #ifdef WOLFSSL_DEBUG_TLS
  345. WOLFSSL_MSG(" Salt");
  346. WOLFSSL_BUFFER(salt, saltLen);
  347. WOLFSSL_MSG(" IKM");
  348. WOLFSSL_BUFFER(ikm, ikmLen);
  349. #endif
  350. ret = wc_HKDF_Extract(digest, salt, saltLen, ikm, ikmLen, prk);
  351. #ifdef WOLFSSL_DEBUG_TLS
  352. WOLFSSL_MSG(" PRK");
  353. WOLFSSL_BUFFER(prk, len);
  354. #endif
  355. return ret;
  356. }
  357. /* Expand data using HMAC, salt and label and info.
  358. * TLS v1.3 defines this function.
  359. *
  360. * okm The generated pseudorandom key - output key material.
  361. * okmLen The length of generated pseudorandom key -
  362. * output key material.
  363. * prk The salt - pseudo-random key.
  364. * prkLen The length of the salt - pseudo-random key.
  365. * protocol The TLS protocol label.
  366. * protocolLen The length of the TLS protocol label.
  367. * info The information to expand.
  368. * infoLen The length of the information.
  369. * digest The type of digest to use.
  370. * returns 0 on success, otherwise failure.
  371. */
  372. int wc_Tls13_HKDF_Expand_Label(byte* okm, word32 okmLen,
  373. const byte* prk, word32 prkLen,
  374. const byte* protocol, word32 protocolLen,
  375. const byte* label, word32 labelLen,
  376. const byte* info, word32 infoLen,
  377. int digest)
  378. {
  379. int ret = 0;
  380. word32 idx = 0;
  381. #ifdef WOLFSSL_SMALL_STACK
  382. byte* data;
  383. #else
  384. byte data[MAX_TLS13_HKDF_LABEL_SZ];
  385. #endif
  386. /* okmLen (2) + protocol|label len (1) + info len(1) + protocollen +
  387. * labellen + infolen */
  388. idx = 4 + protocolLen + labelLen + infoLen;
  389. if (idx > MAX_TLS13_HKDF_LABEL_SZ) {
  390. return BUFFER_E;
  391. }
  392. #ifdef WOLFSSL_SMALL_STACK
  393. data = (byte*)XMALLOC(idx, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  394. if (data == NULL) {
  395. return MEMORY_E;
  396. }
  397. #endif
  398. idx = 0;
  399. /* Output length. */
  400. data[idx++] = (byte)(okmLen >> 8);
  401. data[idx++] = (byte)okmLen;
  402. /* Length of protocol | label. */
  403. data[idx++] = (byte)(protocolLen + labelLen);
  404. /* Protocol */
  405. XMEMCPY(&data[idx], protocol, protocolLen);
  406. idx += protocolLen;
  407. /* Label */
  408. XMEMCPY(&data[idx], label, labelLen);
  409. idx += labelLen;
  410. /* Length of hash of messages */
  411. data[idx++] = (byte)infoLen;
  412. /* Hash of messages */
  413. XMEMCPY(&data[idx], info, infoLen);
  414. idx += infoLen;
  415. #ifdef WOLFSSL_CHECK_MEM_ZERO
  416. wc_MemZero_Add("wc_Tls13_HKDF_Expand_Label data", data, idx);
  417. #endif
  418. #ifdef WOLFSSL_DEBUG_TLS
  419. WOLFSSL_MSG(" PRK");
  420. WOLFSSL_BUFFER(prk, prkLen);
  421. WOLFSSL_MSG(" Info");
  422. WOLFSSL_BUFFER(data, idx);
  423. WOLFSSL_MSG_EX(" Digest %d", digest);
  424. #endif
  425. ret = wc_HKDF_Expand(digest, prk, prkLen, data, idx, okm, okmLen);
  426. #ifdef WOLFSSL_DEBUG_TLS
  427. WOLFSSL_MSG(" OKM");
  428. WOLFSSL_BUFFER(okm, okmLen);
  429. #endif
  430. ForceZero(data, idx);
  431. #ifdef WOLFSSL_CHECK_MEM_ZERO
  432. wc_MemZero_Check(data, idx);
  433. #endif
  434. #ifdef WOLFSSL_SMALL_STACK
  435. XFREE(data, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  436. #endif
  437. return ret;
  438. }
  439. #if defined(WOLFSSL_TICKET_NONCE_MALLOC) && \
  440. (!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
  441. /* Expand data using HMAC, salt and label and info.
  442. * TLS v1.3 defines this function.
  443. *
  444. * okm The generated pseudorandom key - output key material.
  445. * okmLen The length of generated pseudorandom key -
  446. * output key material.
  447. * prk The salt - pseudo-random key.
  448. * prkLen The length of the salt - pseudo-random key.
  449. * protocol The TLS protocol label.
  450. * protocolLen The length of the TLS protocol label.
  451. * info The information to expand.
  452. * infoLen The length of the information.
  453. * digest The type of digest to use.
  454. *
  455. * This functions is very similar to wc_Tls13_HKDF_Expand_Label() but it
  456. * allocate memory if the stack space usually used isn't enough.
  457. *
  458. * returns 0 on success, otherwise failure.
  459. */
  460. int wc_Tls13_HKDF_Expand_Label_Alloc(byte* okm, word32 okmLen,
  461. const byte* prk, word32 prkLen, const byte* protocol,
  462. word32 protocolLen, const byte* label, word32 labelLen,
  463. const byte* info, word32 infoLen, int digest, void* heap)
  464. {
  465. int ret = 0;
  466. int idx = 0;
  467. int len;
  468. byte *data;
  469. (void)heap;
  470. /* okmLen (2) + protocol|label len (1) + info len(1) + protocollen +
  471. * labellen + infolen */
  472. len = 4 + protocolLen + labelLen + infoLen;
  473. data = (byte*)XMALLOC(len, heap, DYNAMIC_TYPE_TMP_BUFFER);
  474. if (data == NULL)
  475. return BUFFER_E;
  476. /* Output length. */
  477. data[idx++] = (byte)(okmLen >> 8);
  478. data[idx++] = (byte)okmLen;
  479. /* Length of protocol | label. */
  480. data[idx++] = (byte)(protocolLen + labelLen);
  481. /* Protocol */
  482. XMEMCPY(&data[idx], protocol, protocolLen);
  483. idx += protocolLen;
  484. /* Label */
  485. XMEMCPY(&data[idx], label, labelLen);
  486. idx += labelLen;
  487. /* Length of hash of messages */
  488. data[idx++] = (byte)infoLen;
  489. /* Hash of messages */
  490. XMEMCPY(&data[idx], info, infoLen);
  491. idx += infoLen;
  492. #ifdef WOLFSSL_CHECK_MEM_ZERO
  493. wc_MemZero_Add("wc_Tls13_HKDF_Expand_Label data", data, idx);
  494. #endif
  495. #ifdef WOLFSSL_DEBUG_TLS
  496. WOLFSSL_MSG(" PRK");
  497. WOLFSSL_BUFFER(prk, prkLen);
  498. WOLFSSL_MSG(" Info");
  499. WOLFSSL_BUFFER(data, idx);
  500. WOLFSSL_MSG_EX(" Digest %d", digest);
  501. #endif
  502. ret = wc_HKDF_Expand(digest, prk, prkLen, data, idx, okm, okmLen);
  503. #ifdef WOLFSSL_DEBUG_TLS
  504. WOLFSSL_MSG(" OKM");
  505. WOLFSSL_BUFFER(okm, okmLen);
  506. #endif
  507. ForceZero(data, idx);
  508. #ifdef WOLFSSL_CHECK_MEM_ZERO
  509. wc_MemZero_Check(data, len);
  510. #endif
  511. XFREE(data, heap, DYNAMIC_TYPE_TMP_BUFFER);
  512. return ret;
  513. }
  514. #endif
  515. /* defined(WOLFSSL_TICKET_NONCE_MALLOC) && (!defined(HAVE_FIPS) ||
  516. * FIPS_VERSION_GE(5,3)) */
  517. #endif /* HAVE_HKDF && !NO_HMAC */
  518. #ifdef WOLFSSL_WOLFSSH
  519. /* hash union */
  520. typedef union {
  521. #ifndef NO_MD5
  522. wc_Md5 md5;
  523. #endif
  524. #ifndef NO_SHA
  525. wc_Sha sha;
  526. #endif
  527. #ifdef WOLFSSL_SHA224
  528. wc_Sha224 sha224;
  529. #endif
  530. #ifndef NO_SHA256
  531. wc_Sha256 sha256;
  532. #endif
  533. #ifdef WOLFSSL_SHA384
  534. wc_Sha384 sha384;
  535. #endif
  536. #ifdef WOLFSSL_SHA512
  537. wc_Sha512 sha512;
  538. #endif
  539. #ifdef WOLFSSL_SHA3
  540. wc_Sha3 sha3;
  541. #endif
  542. } _hash;
  543. static
  544. int _HashInit(byte hashId, _hash* hash)
  545. {
  546. int ret = BAD_FUNC_ARG;
  547. switch (hashId) {
  548. #ifndef NO_SHA
  549. case WC_SHA:
  550. ret = wc_InitSha(&hash->sha);
  551. break;
  552. #endif /* !NO_SHA */
  553. #ifndef NO_SHA256
  554. case WC_SHA256:
  555. ret = wc_InitSha256(&hash->sha256);
  556. break;
  557. #endif /* !NO_SHA256 */
  558. #ifdef WOLFSSL_SHA384
  559. case WC_SHA384:
  560. ret = wc_InitSha384(&hash->sha384);
  561. break;
  562. #endif /* WOLFSSL_SHA384 */
  563. #ifdef WOLFSSL_SHA512
  564. case WC_SHA512:
  565. ret = wc_InitSha512(&hash->sha512);
  566. break;
  567. #endif /* WOLFSSL_SHA512 */
  568. }
  569. return ret;
  570. }
  571. static
  572. int _HashUpdate(byte hashId, _hash* hash,
  573. const byte* data, word32 dataSz)
  574. {
  575. int ret = BAD_FUNC_ARG;
  576. switch (hashId) {
  577. #ifndef NO_SHA
  578. case WC_SHA:
  579. ret = wc_ShaUpdate(&hash->sha, data, dataSz);
  580. break;
  581. #endif /* !NO_SHA */
  582. #ifndef NO_SHA256
  583. case WC_SHA256:
  584. ret = wc_Sha256Update(&hash->sha256, data, dataSz);
  585. break;
  586. #endif /* !NO_SHA256 */
  587. #ifdef WOLFSSL_SHA384
  588. case WC_SHA384:
  589. ret = wc_Sha384Update(&hash->sha384, data, dataSz);
  590. break;
  591. #endif /* WOLFSSL_SHA384 */
  592. #ifdef WOLFSSL_SHA512
  593. case WC_SHA512:
  594. ret = wc_Sha512Update(&hash->sha512, data, dataSz);
  595. break;
  596. #endif /* WOLFSSL_SHA512 */
  597. }
  598. return ret;
  599. }
  600. static
  601. int _HashFinal(byte hashId, _hash* hash, byte* digest)
  602. {
  603. int ret = BAD_FUNC_ARG;
  604. switch (hashId) {
  605. #ifndef NO_SHA
  606. case WC_SHA:
  607. ret = wc_ShaFinal(&hash->sha, digest);
  608. break;
  609. #endif /* !NO_SHA */
  610. #ifndef NO_SHA256
  611. case WC_SHA256:
  612. ret = wc_Sha256Final(&hash->sha256, digest);
  613. break;
  614. #endif /* !NO_SHA256 */
  615. #ifdef WOLFSSL_SHA384
  616. case WC_SHA384:
  617. ret = wc_Sha384Final(&hash->sha384, digest);
  618. break;
  619. #endif /* WOLFSSL_SHA384 */
  620. #ifdef WOLFSSL_SHA512
  621. case WC_SHA512:
  622. ret = wc_Sha512Final(&hash->sha512, digest);
  623. break;
  624. #endif /* WOLFSSL_SHA512 */
  625. }
  626. return ret;
  627. }
  628. static
  629. void _HashFree(byte hashId, _hash* hash)
  630. {
  631. switch (hashId) {
  632. #ifndef NO_SHA
  633. case WC_SHA:
  634. wc_ShaFree(&hash->sha);
  635. break;
  636. #endif /* !NO_SHA */
  637. #ifndef NO_SHA256
  638. case WC_SHA256:
  639. wc_Sha256Free(&hash->sha256);
  640. break;
  641. #endif /* !NO_SHA256 */
  642. #ifdef WOLFSSL_SHA384
  643. case WC_SHA384:
  644. wc_Sha384Free(&hash->sha384);
  645. break;
  646. #endif /* WOLFSSL_SHA384 */
  647. #ifdef WOLFSSL_SHA512
  648. case WC_SHA512:
  649. wc_Sha512Free(&hash->sha512);
  650. break;
  651. #endif /* WOLFSSL_SHA512 */
  652. }
  653. }
  654. #define LENGTH_SZ 4
  655. int wc_SSH_KDF(byte hashId, byte keyId, byte* key, word32 keySz,
  656. const byte* k, word32 kSz, const byte* h, word32 hSz,
  657. const byte* sessionId, word32 sessionIdSz)
  658. {
  659. word32 blocks, remainder;
  660. _hash hash;
  661. enum wc_HashType enmhashId = (enum wc_HashType)hashId;
  662. byte kPad = 0;
  663. byte pad = 0;
  664. byte kSzFlat[LENGTH_SZ];
  665. word32 digestSz;
  666. int ret;
  667. if (key == NULL || keySz == 0 ||
  668. k == NULL || kSz == 0 ||
  669. h == NULL || hSz == 0 ||
  670. sessionId == NULL || sessionIdSz == 0) {
  671. return BAD_FUNC_ARG;
  672. }
  673. ret = wc_HmacSizeByType(enmhashId);
  674. if (ret <= 0) {
  675. return BAD_FUNC_ARG;
  676. }
  677. digestSz = (word32)ret;
  678. if (k[0] & 0x80) kPad = 1;
  679. c32toa(kSz + kPad, kSzFlat);
  680. blocks = keySz / digestSz;
  681. remainder = keySz % digestSz;
  682. ret = _HashInit(enmhashId, &hash);
  683. if (ret == 0)
  684. ret = _HashUpdate(enmhashId, &hash, kSzFlat, LENGTH_SZ);
  685. if (ret == 0 && kPad)
  686. ret = _HashUpdate(enmhashId, &hash, &pad, 1);
  687. if (ret == 0)
  688. ret = _HashUpdate(enmhashId, &hash, k, kSz);
  689. if (ret == 0)
  690. ret = _HashUpdate(enmhashId, &hash, h, hSz);
  691. if (ret == 0)
  692. ret = _HashUpdate(enmhashId, &hash, &keyId, sizeof(keyId));
  693. if (ret == 0)
  694. ret = _HashUpdate(enmhashId, &hash, sessionId, sessionIdSz);
  695. if (ret == 0) {
  696. if (blocks == 0) {
  697. if (remainder > 0) {
  698. byte lastBlock[WC_MAX_DIGEST_SIZE];
  699. ret = _HashFinal(enmhashId, &hash, lastBlock);
  700. if (ret == 0)
  701. XMEMCPY(key, lastBlock, remainder);
  702. }
  703. }
  704. else {
  705. word32 runningKeySz, curBlock;
  706. runningKeySz = digestSz;
  707. ret = _HashFinal(enmhashId, &hash, key);
  708. for (curBlock = 1; curBlock < blocks; curBlock++) {
  709. ret = _HashInit(enmhashId, &hash);
  710. if (ret != 0) break;
  711. ret = _HashUpdate(enmhashId, &hash, kSzFlat, LENGTH_SZ);
  712. if (ret != 0) break;
  713. if (kPad)
  714. ret = _HashUpdate(enmhashId, &hash, &pad, 1);
  715. if (ret != 0) break;
  716. ret = _HashUpdate(enmhashId, &hash, k, kSz);
  717. if (ret != 0) break;
  718. ret = _HashUpdate(enmhashId, &hash, h, hSz);
  719. if (ret != 0) break;
  720. ret = _HashUpdate(enmhashId, &hash, key, runningKeySz);
  721. if (ret != 0) break;
  722. ret = _HashFinal(enmhashId, &hash, key + runningKeySz);
  723. if (ret != 0) break;
  724. runningKeySz += digestSz;
  725. }
  726. if (remainder > 0) {
  727. byte lastBlock[WC_MAX_DIGEST_SIZE];
  728. if (ret == 0)
  729. ret = _HashInit(enmhashId, &hash);
  730. if (ret == 0)
  731. ret = _HashUpdate(enmhashId, &hash, kSzFlat, LENGTH_SZ);
  732. if (ret == 0 && kPad)
  733. ret = _HashUpdate(enmhashId, &hash, &pad, 1);
  734. if (ret == 0)
  735. ret = _HashUpdate(enmhashId, &hash, k, kSz);
  736. if (ret == 0)
  737. ret = _HashUpdate(enmhashId, &hash, h, hSz);
  738. if (ret == 0)
  739. ret = _HashUpdate(enmhashId, &hash, key, runningKeySz);
  740. if (ret == 0)
  741. ret = _HashFinal(enmhashId, &hash, lastBlock);
  742. if (ret == 0)
  743. XMEMCPY(key + runningKeySz, lastBlock, remainder);
  744. }
  745. }
  746. }
  747. _HashFree(enmhashId, &hash);
  748. return ret;
  749. }
  750. #endif /* WOLFSSL_WOLFSSH */
  751. #endif /* NO_KDF */