kdf.c 24 KB

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