kdf.c 24 KB

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