kdf.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755
  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. #ifdef WOLFSSL_SMALL_STACK
  75. previous = (byte*)XMALLOC(P_HASH_MAX_SIZE, heap, DYNAMIC_TYPE_DIGEST);
  76. current = (byte*)XMALLOC(P_HASH_MAX_SIZE, heap, DYNAMIC_TYPE_DIGEST);
  77. hmac = (Hmac*)XMALLOC(sizeof(Hmac), heap, DYNAMIC_TYPE_HMAC);
  78. if (previous == NULL || current == NULL || hmac == NULL) {
  79. if (previous) XFREE(previous, heap, DYNAMIC_TYPE_DIGEST);
  80. if (current) XFREE(current, heap, DYNAMIC_TYPE_DIGEST);
  81. if (hmac) XFREE(hmac, heap, DYNAMIC_TYPE_HMAC);
  82. return MEMORY_E;
  83. }
  84. #endif
  85. #ifdef WOLFSSL_CHECK_MEM_ZERO
  86. wc_MemZero_Add("wc_PRF previous", previous, P_HASH_MAX_SIZE);
  87. wc_MemZero_Add("wc_PRF current", current, P_HASH_MAX_SIZE);
  88. wc_MemZero_Add("wc_PRF hmac", hmac, sizeof(Hmac));
  89. #endif
  90. switch (hash) {
  91. #ifndef NO_MD5
  92. case md5_mac:
  93. hash = WC_MD5;
  94. len = WC_MD5_DIGEST_SIZE;
  95. break;
  96. #endif
  97. #ifndef NO_SHA256
  98. case sha256_mac:
  99. hash = WC_SHA256;
  100. len = WC_SHA256_DIGEST_SIZE;
  101. break;
  102. #endif
  103. #ifdef WOLFSSL_SHA384
  104. case sha384_mac:
  105. hash = WC_SHA384;
  106. len = WC_SHA384_DIGEST_SIZE;
  107. break;
  108. #endif
  109. #ifdef WOLFSSL_SHA512
  110. case sha512_mac:
  111. hash = WC_SHA512;
  112. len = WC_SHA512_DIGEST_SIZE;
  113. break;
  114. #endif
  115. #ifndef NO_SHA
  116. case sha_mac:
  117. hash = WC_SHA;
  118. len = WC_SHA_DIGEST_SIZE;
  119. break;
  120. #endif
  121. default:
  122. #ifdef WOLFSSL_SMALL_STACK
  123. if (previous) XFREE(previous, heap, DYNAMIC_TYPE_DIGEST);
  124. if (current) XFREE(current, heap, DYNAMIC_TYPE_DIGEST);
  125. if (hmac) XFREE(hmac, heap, DYNAMIC_TYPE_HMAC);
  126. #endif
  127. return HASH_TYPE_E;
  128. }
  129. times = resLen / len;
  130. lastLen = resLen % len;
  131. if (lastLen)
  132. times += 1;
  133. /* times == 0 iif resLen == 0, but times == 0 abides clang static analyzer
  134. while resLen == 0 doesn't */
  135. if (times == 0)
  136. return BAD_FUNC_ARG;
  137. lastTime = times - 1;
  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. for (i = 0; i < times; i++) {
  147. ret = wc_HmacUpdate(hmac, previous, len);
  148. if (ret != 0)
  149. break;
  150. ret = wc_HmacUpdate(hmac, seed, seedLen);
  151. if (ret != 0)
  152. break;
  153. ret = wc_HmacFinal(hmac, current);
  154. if (ret != 0)
  155. break;
  156. if ((i == lastTime) && lastLen)
  157. XMEMCPY(&result[idx], current,
  158. min(lastLen, P_HASH_MAX_SIZE));
  159. else {
  160. XMEMCPY(&result[idx], current, len);
  161. idx += len;
  162. ret = wc_HmacUpdate(hmac, previous, len);
  163. if (ret != 0)
  164. break;
  165. ret = wc_HmacFinal(hmac, previous);
  166. if (ret != 0)
  167. break;
  168. }
  169. }
  170. }
  171. wc_HmacFree(hmac);
  172. }
  173. ForceZero(previous, P_HASH_MAX_SIZE);
  174. ForceZero(current, P_HASH_MAX_SIZE);
  175. ForceZero(hmac, sizeof(Hmac));
  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. #elif defined(WOLFSSL_CHECK_MEM_ZERO)
  181. wc_MemZero_Check(previous, P_HASH_MAX_SIZE);
  182. wc_MemZero_Check(current, P_HASH_MAX_SIZE);
  183. wc_MemZero_Check(hmac, sizeof(Hmac));
  184. #endif
  185. return ret;
  186. }
  187. #undef P_HASH_MAX_SIZE
  188. /* compute PRF (pseudo random function) using SHA1 and MD5 for TLSv1 */
  189. int wc_PRF_TLSv1(byte* digest, word32 digLen, const byte* secret,
  190. word32 secLen, const byte* label, word32 labLen,
  191. const byte* seed, word32 seedLen, void* heap, int devId)
  192. {
  193. int ret = 0;
  194. word32 half = (secLen + 1) / 2;
  195. const byte* md5_half;
  196. const byte* sha_half;
  197. byte* md5_result;
  198. #ifdef WOLFSSL_SMALL_STACK
  199. byte* sha_result;
  200. #else
  201. byte sha_result[MAX_PRF_DIG]; /* digLen is real size */
  202. #endif
  203. #if !defined(WOLFSSL_ASYNC_CRYPT) || defined(WC_ASYNC_NO_HASH)
  204. byte labelSeed[MAX_PRF_LABSEED];
  205. #else
  206. WC_DECLARE_VAR(labelSeed, byte, MAX_PRF_LABSEED, heap);
  207. if (labelSeed == NULL)
  208. return MEMORY_E;
  209. #endif
  210. if (half > MAX_PRF_HALF ||
  211. labLen + seedLen > MAX_PRF_LABSEED ||
  212. digLen > MAX_PRF_DIG)
  213. {
  214. #if defined(WOLFSSL_ASYNC_CRYPT) && !defined(WC_ASYNC_NO_HASH)
  215. WC_FREE_VAR(labelSeed, heap);
  216. #endif
  217. return BUFFER_E;
  218. }
  219. #ifdef WOLFSSL_SMALL_STACK
  220. sha_result = (byte*)XMALLOC(MAX_PRF_DIG, heap, DYNAMIC_TYPE_DIGEST);
  221. if (sha_result == NULL) {
  222. #if defined(WOLFSSL_ASYNC_CRYPT) && !defined(WC_ASYNC_NO_HASH)
  223. WC_FREE_VAR(labelSeed, heap);
  224. #endif
  225. return MEMORY_E;
  226. }
  227. #endif
  228. md5_half = secret;
  229. sha_half = secret + half - secLen % 2;
  230. md5_result = digest;
  231. XMEMCPY(labelSeed, label, labLen);
  232. XMEMCPY(labelSeed + labLen, seed, seedLen);
  233. if ((ret = wc_PRF(md5_result, digLen, md5_half, half, labelSeed,
  234. labLen + seedLen, md5_mac, heap, devId)) == 0) {
  235. if ((ret = wc_PRF(sha_result, digLen, sha_half, half, labelSeed,
  236. labLen + seedLen, sha_mac, heap, devId)) == 0) {
  237. #ifdef WOLFSSL_CHECK_MEM_ZERO
  238. wc_MemZero_Add("wc_PRF_TLSv1 sha_result", sha_result, digLen);
  239. #endif
  240. /* calculate XOR for TLSv1 PRF */
  241. /* md5 result is placed directly in digest */
  242. xorbuf(digest, sha_result, digLen);
  243. ForceZero(sha_result, digLen);
  244. }
  245. }
  246. #ifdef WOLFSSL_SMALL_STACK
  247. XFREE(sha_result, heap, DYNAMIC_TYPE_DIGEST);
  248. #elif defined(WOLFSSL_CHECK_MEM_ZERO)
  249. wc_MemZero_Check(sha_result, MAX_PRF_DIG);
  250. #endif
  251. #if defined(WOLFSSL_ASYNC_CRYPT) && !defined(WC_ASYNC_NO_HASH)
  252. WC_FREE_VAR(labelSeed, heap);
  253. #endif
  254. return ret;
  255. }
  256. /* Wrapper for TLS 1.2 and TLSv1 cases to calculate PRF */
  257. /* In TLS 1.2 case call straight thru to wc_PRF */
  258. int wc_PRF_TLS(byte* digest, word32 digLen, const byte* secret, word32 secLen,
  259. const byte* label, word32 labLen, const byte* seed, word32 seedLen,
  260. int useAtLeastSha256, int hash_type, void* heap, int devId)
  261. {
  262. int ret = 0;
  263. if (useAtLeastSha256) {
  264. #if defined(WOLFSSL_ASYNC_CRYPT) && !defined(WC_ASYNC_NO_HASH)
  265. WC_DECLARE_VAR(labelSeed, byte, MAX_PRF_LABSEED, heap);
  266. if (labelSeed == NULL)
  267. return MEMORY_E;
  268. #else
  269. byte labelSeed[MAX_PRF_LABSEED];
  270. #endif
  271. if (labLen + seedLen > MAX_PRF_LABSEED)
  272. return BUFFER_E;
  273. XMEMCPY(labelSeed, label, labLen);
  274. XMEMCPY(labelSeed + labLen, seed, seedLen);
  275. /* If a cipher suite wants an algorithm better than sha256, it
  276. * should use better. */
  277. if (hash_type < sha256_mac || hash_type == blake2b_mac)
  278. hash_type = sha256_mac;
  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. #if defined(WOLFSSL_ASYNC_CRYPT) && !defined(WC_ASYNC_NO_HASH)
  283. WC_FREE_VAR(labelSeed, heap);
  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 */
  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, int saltLen,
  311. byte* ikm, int ikmLen, int digest)
  312. {
  313. int ret;
  314. int 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. default:
  332. return BAD_FUNC_ARG;
  333. }
  334. /* When length is 0 then use zeroed data of digest length. */
  335. if (ikmLen == 0) {
  336. ikmLen = len;
  337. XMEMSET(ikm, 0, len);
  338. }
  339. #ifdef WOLFSSL_DEBUG_TLS
  340. WOLFSSL_MSG(" Salt");
  341. WOLFSSL_BUFFER(salt, saltLen);
  342. WOLFSSL_MSG(" IKM");
  343. WOLFSSL_BUFFER(ikm, ikmLen);
  344. #endif
  345. ret = wc_HKDF_Extract(digest, salt, saltLen, ikm, ikmLen, prk);
  346. #ifdef WOLFSSL_DEBUG_TLS
  347. WOLFSSL_MSG(" PRK");
  348. WOLFSSL_BUFFER(prk, len);
  349. #endif
  350. return ret;
  351. }
  352. /* Expand data using HMAC, salt and label and info.
  353. * TLS v1.3 defines this function.
  354. *
  355. * okm The generated pseudorandom key - output key material.
  356. * okmLen The length of generated pseudorandom key -
  357. * output key material.
  358. * prk The salt - pseudo-random key.
  359. * prkLen The length of the salt - pseudo-random key.
  360. * protocol The TLS protocol label.
  361. * protocolLen The length of the TLS protocol label.
  362. * info The information to expand.
  363. * infoLen The length of the information.
  364. * digest The type of digest to use.
  365. * returns 0 on success, otherwise failure.
  366. */
  367. int wc_Tls13_HKDF_Expand_Label(byte* okm, word32 okmLen,
  368. const byte* prk, word32 prkLen,
  369. const byte* protocol, word32 protocolLen,
  370. const byte* label, word32 labelLen,
  371. const byte* info, word32 infoLen,
  372. int digest)
  373. {
  374. int ret = 0;
  375. int idx = 0;
  376. byte data[MAX_TLS13_HKDF_LABEL_SZ];
  377. /* Output length. */
  378. data[idx++] = (byte)(okmLen >> 8);
  379. data[idx++] = (byte)okmLen;
  380. /* Length of protocol | label. */
  381. data[idx++] = (byte)(protocolLen + labelLen);
  382. /* Protocol */
  383. XMEMCPY(&data[idx], protocol, protocolLen);
  384. idx += protocolLen;
  385. /* Label */
  386. XMEMCPY(&data[idx], label, labelLen);
  387. idx += labelLen;
  388. /* Length of hash of messages */
  389. data[idx++] = (byte)infoLen;
  390. /* Hash of messages */
  391. XMEMCPY(&data[idx], info, infoLen);
  392. idx += infoLen;
  393. #ifdef WOLFSSL_CHECK_MEM_ZERO
  394. wc_MemZero_Add("wc_Tls13_HKDF_Expand_Label data", data, idx);
  395. #endif
  396. #ifdef WOLFSSL_DEBUG_TLS
  397. WOLFSSL_MSG(" PRK");
  398. WOLFSSL_BUFFER(prk, prkLen);
  399. WOLFSSL_MSG(" Info");
  400. WOLFSSL_BUFFER(data, idx);
  401. WOLFSSL_MSG_EX(" Digest %d", digest);
  402. #endif
  403. ret = wc_HKDF_Expand(digest, prk, prkLen, data, idx, okm, okmLen);
  404. #ifdef WOLFSSL_DEBUG_TLS
  405. WOLFSSL_MSG(" OKM");
  406. WOLFSSL_BUFFER(okm, okmLen);
  407. #endif
  408. ForceZero(data, idx);
  409. #ifdef WOLFSSL_CHECK_MEM_ZERO
  410. wc_MemZero_Check(data, MAX_TLS13_HKDF_LABEL_SZ);
  411. #endif
  412. return ret;
  413. }
  414. #endif /* HAVE_HKDF && !NO_HMAC */
  415. #ifdef WOLFSSL_WOLFSSH
  416. /* hash union */
  417. typedef union {
  418. #ifndef NO_MD5
  419. wc_Md5 md5;
  420. #endif
  421. #ifndef NO_SHA
  422. wc_Sha sha;
  423. #endif
  424. #ifdef WOLFSSL_SHA224
  425. wc_Sha224 sha224;
  426. #endif
  427. #ifndef NO_SHA256
  428. wc_Sha256 sha256;
  429. #endif
  430. #ifdef WOLFSSL_SHA384
  431. wc_Sha384 sha384;
  432. #endif
  433. #ifdef WOLFSSL_SHA512
  434. wc_Sha512 sha512;
  435. #endif
  436. #ifdef WOLFSSL_SHA3
  437. wc_Sha3 sha3;
  438. #endif
  439. } _hash;
  440. static
  441. int _HashInit(byte hashId, _hash* hash)
  442. {
  443. int ret = BAD_FUNC_ARG;
  444. switch (hashId) {
  445. #ifndef NO_SHA
  446. case WC_SHA:
  447. ret = wc_InitSha(&hash->sha);
  448. break;
  449. #endif /* !NO_SHA */
  450. #ifndef NO_SHA256
  451. case WC_SHA256:
  452. ret = wc_InitSha256(&hash->sha256);
  453. break;
  454. #endif /* !NO_SHA256 */
  455. #ifdef WOLFSSL_SHA384
  456. case WC_SHA384:
  457. ret = wc_InitSha384(&hash->sha384);
  458. break;
  459. #endif /* WOLFSSL_SHA384 */
  460. #ifdef WOLFSSL_SHA512
  461. case WC_SHA512:
  462. ret = wc_InitSha512(&hash->sha512);
  463. break;
  464. #endif /* WOLFSSL_SHA512 */
  465. }
  466. return ret;
  467. }
  468. static
  469. int _HashUpdate(byte hashId, _hash* hash,
  470. const byte* data, word32 dataSz)
  471. {
  472. int ret = BAD_FUNC_ARG;
  473. switch (hashId) {
  474. #ifndef NO_SHA
  475. case WC_SHA:
  476. ret = wc_ShaUpdate(&hash->sha, data, dataSz);
  477. break;
  478. #endif /* !NO_SHA */
  479. #ifndef NO_SHA256
  480. case WC_SHA256:
  481. ret = wc_Sha256Update(&hash->sha256, data, dataSz);
  482. break;
  483. #endif /* !NO_SHA256 */
  484. #ifdef WOLFSSL_SHA384
  485. case WC_SHA384:
  486. ret = wc_Sha384Update(&hash->sha384, data, dataSz);
  487. break;
  488. #endif /* WOLFSSL_SHA384 */
  489. #ifdef WOLFSSL_SHA512
  490. case WC_SHA512:
  491. ret = wc_Sha512Update(&hash->sha512, data, dataSz);
  492. break;
  493. #endif /* WOLFSSL_SHA512 */
  494. }
  495. return ret;
  496. }
  497. static
  498. int _HashFinal(byte hashId, _hash* hash, byte* digest)
  499. {
  500. int ret = BAD_FUNC_ARG;
  501. switch (hashId) {
  502. #ifndef NO_SHA
  503. case WC_SHA:
  504. ret = wc_ShaFinal(&hash->sha, digest);
  505. break;
  506. #endif /* !NO_SHA */
  507. #ifndef NO_SHA256
  508. case WC_SHA256:
  509. ret = wc_Sha256Final(&hash->sha256, digest);
  510. break;
  511. #endif /* !NO_SHA256 */
  512. #ifdef WOLFSSL_SHA384
  513. case WC_SHA384:
  514. ret = wc_Sha384Final(&hash->sha384, digest);
  515. break;
  516. #endif /* WOLFSSL_SHA384 */
  517. #ifdef WOLFSSL_SHA512
  518. case WC_SHA512:
  519. ret = wc_Sha512Final(&hash->sha512, digest);
  520. break;
  521. #endif /* WOLFSSL_SHA512 */
  522. }
  523. return ret;
  524. }
  525. static
  526. void _HashFree(byte hashId, _hash* hash)
  527. {
  528. switch (hashId) {
  529. #ifndef NO_SHA
  530. case WC_SHA:
  531. wc_ShaFree(&hash->sha);
  532. break;
  533. #endif /* !NO_SHA */
  534. #ifndef NO_SHA256
  535. case WC_SHA256:
  536. wc_Sha256Free(&hash->sha256);
  537. break;
  538. #endif /* !NO_SHA256 */
  539. #ifdef WOLFSSL_SHA384
  540. case WC_SHA384:
  541. wc_Sha384Free(&hash->sha384);
  542. break;
  543. #endif /* WOLFSSL_SHA384 */
  544. #ifdef WOLFSSL_SHA512
  545. case WC_SHA512:
  546. wc_Sha512Free(&hash->sha512);
  547. break;
  548. #endif /* WOLFSSL_SHA512 */
  549. }
  550. }
  551. #define LENGTH_SZ 4
  552. int wc_SSH_KDF(byte hashId, byte keyId, byte* key, word32 keySz,
  553. const byte* k, word32 kSz, const byte* h, word32 hSz,
  554. const byte* sessionId, word32 sessionIdSz)
  555. {
  556. word32 blocks, remainder;
  557. _hash hash;
  558. enum wc_HashType enmhashId = (enum wc_HashType)hashId;
  559. byte kPad = 0;
  560. byte pad = 0;
  561. byte kSzFlat[LENGTH_SZ];
  562. int digestSz;
  563. int ret;
  564. if (key == NULL || keySz == 0 ||
  565. k == NULL || kSz == 0 ||
  566. h == NULL || hSz == 0 ||
  567. sessionId == NULL || sessionIdSz == 0) {
  568. return BAD_FUNC_ARG;
  569. }
  570. digestSz = wc_HmacSizeByType(enmhashId);
  571. if (digestSz < 0) {
  572. return BAD_FUNC_ARG;
  573. }
  574. if (k[0] & 0x80) kPad = 1;
  575. c32toa(kSz + kPad, kSzFlat);
  576. blocks = keySz / digestSz;
  577. remainder = keySz % digestSz;
  578. ret = _HashInit(enmhashId, &hash);
  579. if (ret == 0)
  580. ret = _HashUpdate(enmhashId, &hash, kSzFlat, LENGTH_SZ);
  581. if (ret == 0 && kPad)
  582. ret = _HashUpdate(enmhashId, &hash, &pad, 1);
  583. if (ret == 0)
  584. ret = _HashUpdate(enmhashId, &hash, k, kSz);
  585. if (ret == 0)
  586. ret = _HashUpdate(enmhashId, &hash, h, hSz);
  587. if (ret == 0)
  588. ret = _HashUpdate(enmhashId, &hash, &keyId, sizeof(keyId));
  589. if (ret == 0)
  590. ret = _HashUpdate(enmhashId, &hash, sessionId, sessionIdSz);
  591. if (ret == 0) {
  592. if (blocks == 0) {
  593. if (remainder > 0) {
  594. byte lastBlock[WC_MAX_DIGEST_SIZE];
  595. ret = _HashFinal(enmhashId, &hash, lastBlock);
  596. if (ret == 0)
  597. XMEMCPY(key, lastBlock, remainder);
  598. }
  599. }
  600. else {
  601. word32 runningKeySz, curBlock;
  602. runningKeySz = digestSz;
  603. ret = _HashFinal(enmhashId, &hash, key);
  604. for (curBlock = 1; curBlock < blocks; curBlock++) {
  605. ret = _HashInit(enmhashId, &hash);
  606. if (ret != 0) break;
  607. ret = _HashUpdate(enmhashId, &hash, kSzFlat, LENGTH_SZ);
  608. if (ret != 0) break;
  609. if (kPad)
  610. ret = _HashUpdate(enmhashId, &hash, &pad, 1);
  611. if (ret != 0) break;
  612. ret = _HashUpdate(enmhashId, &hash, k, kSz);
  613. if (ret != 0) break;
  614. ret = _HashUpdate(enmhashId, &hash, h, hSz);
  615. if (ret != 0) break;
  616. ret = _HashUpdate(enmhashId, &hash, key, runningKeySz);
  617. if (ret != 0) break;
  618. ret = _HashFinal(enmhashId, &hash, key + runningKeySz);
  619. if (ret != 0) break;
  620. runningKeySz += digestSz;
  621. }
  622. if (remainder > 0) {
  623. byte lastBlock[WC_MAX_DIGEST_SIZE];
  624. if (ret == 0)
  625. ret = _HashInit(enmhashId, &hash);
  626. if (ret == 0)
  627. ret = _HashUpdate(enmhashId, &hash, kSzFlat, LENGTH_SZ);
  628. if (ret == 0 && kPad)
  629. ret = _HashUpdate(enmhashId, &hash, &pad, 1);
  630. if (ret == 0)
  631. ret = _HashUpdate(enmhashId, &hash, k, kSz);
  632. if (ret == 0)
  633. ret = _HashUpdate(enmhashId, &hash, h, hSz);
  634. if (ret == 0)
  635. ret = _HashUpdate(enmhashId, &hash, key, runningKeySz);
  636. if (ret == 0)
  637. ret = _HashFinal(enmhashId, &hash, lastBlock);
  638. if (ret == 0)
  639. XMEMCPY(key + runningKeySz, lastBlock, remainder);
  640. }
  641. }
  642. }
  643. _HashFree(enmhashId, &hash);
  644. return ret;
  645. }
  646. #endif /* WOLFSSL_WOLFSSH */
  647. #endif /* NO_KDF */