hmac.c 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306
  1. /* hmac.c
  2. *
  3. * Copyright (C) 2006-2021 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. #ifndef NO_HMAC
  27. #if defined(HAVE_FIPS) && \
  28. defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
  29. /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
  30. #define FIPS_NO_WRAPPERS
  31. #ifdef USE_WINDOWS_API
  32. #pragma code_seg(".fipsA$b")
  33. #pragma const_seg(".fipsB$b")
  34. #endif
  35. #endif
  36. #include <wolfssl/wolfcrypt/hmac.h>
  37. #ifdef WOLF_CRYPTO_CB
  38. #include <wolfssl/wolfcrypt/cryptocb.h>
  39. #endif
  40. #ifdef NO_INLINE
  41. #include <wolfssl/wolfcrypt/misc.h>
  42. #else
  43. #define WOLFSSL_MISC_INCLUDED
  44. #include <wolfcrypt/src/misc.c>
  45. #endif
  46. #ifdef WOLFSSL_KCAPI_HMAC
  47. #include <wolfssl/wolfcrypt/port/kcapi/kcapi_hmac.h>
  48. #define wc_HmacSetKey wc_HmacSetKey_Software
  49. #define wc_HmacUpdate wc_HmacUpdate_Software
  50. #define wc_HmacFinal wc_HmacFinal_Software
  51. #endif
  52. /* fips wrapper calls, user can call direct */
  53. /* If building for old FIPS. */
  54. #if defined(HAVE_FIPS) && \
  55. (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2))
  56. /* does init */
  57. int wc_HmacSetKey(Hmac* hmac, int type, const byte* key, word32 keySz)
  58. {
  59. if (hmac == NULL || (key == NULL && keySz != 0) ||
  60. !(type == WC_MD5 || type == WC_SHA || type == WC_SHA256 ||
  61. type == WC_SHA384 || type == WC_SHA512)) {
  62. return BAD_FUNC_ARG;
  63. }
  64. return HmacSetKey_fips(hmac, type, key, keySz);
  65. }
  66. int wc_HmacUpdate(Hmac* hmac, const byte* in, word32 sz)
  67. {
  68. if (hmac == NULL || (in == NULL && sz > 0)) {
  69. return BAD_FUNC_ARG;
  70. }
  71. return HmacUpdate_fips(hmac, in, sz);
  72. }
  73. int wc_HmacFinal(Hmac* hmac, byte* out)
  74. {
  75. if (hmac == NULL) {
  76. return BAD_FUNC_ARG;
  77. }
  78. return HmacFinal_fips(hmac, out);
  79. }
  80. int wolfSSL_GetHmacMaxSize(void)
  81. {
  82. return CyaSSL_GetHmacMaxSize();
  83. }
  84. int wc_HmacInit(Hmac* hmac, void* heap, int devId)
  85. {
  86. #ifndef WOLFSSL_KCAPI_HMAC
  87. (void)hmac;
  88. (void)heap;
  89. (void)devId;
  90. return 0;
  91. #else
  92. return HmacInit(hmac, heap, devId);
  93. #endif
  94. }
  95. void wc_HmacFree(Hmac* hmac)
  96. {
  97. #ifndef WOLFSSL_KCAPI_HMAC
  98. (void)hmac;
  99. #else
  100. HmacFree(hmac);
  101. #endif
  102. }
  103. #ifdef HAVE_HKDF
  104. int wc_HKDF(int type, const byte* inKey, word32 inKeySz,
  105. const byte* salt, word32 saltSz,
  106. const byte* info, word32 infoSz,
  107. byte* out, word32 outSz)
  108. {
  109. return HKDF(type, inKey, inKeySz, salt, saltSz,
  110. info, infoSz, out, outSz);
  111. }
  112. #endif /* HAVE_HKDF */
  113. #else /* else build without fips, or for new fips */
  114. int wc_HmacSizeByType(int type)
  115. {
  116. int ret;
  117. if (!(type == WC_MD5 || type == WC_SHA ||
  118. type == WC_SHA224 || type == WC_SHA256 ||
  119. type == WC_SHA384 || type == WC_SHA512 ||
  120. type == WC_SHA3_224 || type == WC_SHA3_256 ||
  121. type == WC_SHA3_384 || type == WC_SHA3_512)) {
  122. return BAD_FUNC_ARG;
  123. }
  124. switch (type) {
  125. #ifndef NO_MD5
  126. case WC_MD5:
  127. ret = WC_MD5_DIGEST_SIZE;
  128. break;
  129. #endif /* !NO_MD5 */
  130. #ifndef NO_SHA
  131. case WC_SHA:
  132. ret = WC_SHA_DIGEST_SIZE;
  133. break;
  134. #endif /* !NO_SHA */
  135. #ifdef WOLFSSL_SHA224
  136. case WC_SHA224:
  137. ret = WC_SHA224_DIGEST_SIZE;
  138. break;
  139. #endif /* WOLFSSL_SHA224 */
  140. #ifndef NO_SHA256
  141. case WC_SHA256:
  142. ret = WC_SHA256_DIGEST_SIZE;
  143. break;
  144. #endif /* !NO_SHA256 */
  145. #ifdef WOLFSSL_SHA384
  146. case WC_SHA384:
  147. ret = WC_SHA384_DIGEST_SIZE;
  148. break;
  149. #endif /* WOLFSSL_SHA384 */
  150. #ifdef WOLFSSL_SHA512
  151. case WC_SHA512:
  152. ret = WC_SHA512_DIGEST_SIZE;
  153. break;
  154. #endif /* WOLFSSL_SHA512 */
  155. #ifdef WOLFSSL_SHA3
  156. case WC_SHA3_224:
  157. ret = WC_SHA3_224_DIGEST_SIZE;
  158. break;
  159. case WC_SHA3_256:
  160. ret = WC_SHA3_256_DIGEST_SIZE;
  161. break;
  162. case WC_SHA3_384:
  163. ret = WC_SHA3_384_DIGEST_SIZE;
  164. break;
  165. case WC_SHA3_512:
  166. ret = WC_SHA3_512_DIGEST_SIZE;
  167. break;
  168. #endif
  169. default:
  170. ret = BAD_FUNC_ARG;
  171. break;
  172. }
  173. return ret;
  174. }
  175. int _InitHmac(Hmac* hmac, int type, void* heap)
  176. {
  177. int ret = 0;
  178. #ifdef WOLF_CRYPTO_CB
  179. int devId = hmac->devId;
  180. #else
  181. int devId = INVALID_DEVID;
  182. #endif
  183. switch (type) {
  184. #ifndef NO_MD5
  185. case WC_MD5:
  186. ret = wc_InitMd5_ex(&hmac->hash.md5, heap, devId);
  187. break;
  188. #endif /* !NO_MD5 */
  189. #ifndef NO_SHA
  190. case WC_SHA:
  191. ret = wc_InitSha_ex(&hmac->hash.sha, heap, devId);
  192. break;
  193. #endif /* !NO_SHA */
  194. #ifdef WOLFSSL_SHA224
  195. case WC_SHA224:
  196. ret = wc_InitSha224_ex(&hmac->hash.sha224, heap, devId);
  197. break;
  198. #endif /* WOLFSSL_SHA224 */
  199. #ifndef NO_SHA256
  200. case WC_SHA256:
  201. ret = wc_InitSha256_ex(&hmac->hash.sha256, heap, devId);
  202. break;
  203. #endif /* !NO_SHA256 */
  204. #ifdef WOLFSSL_SHA384
  205. case WC_SHA384:
  206. ret = wc_InitSha384_ex(&hmac->hash.sha384, heap, devId);
  207. break;
  208. #endif /* WOLFSSL_SHA384 */
  209. #ifdef WOLFSSL_SHA512
  210. case WC_SHA512:
  211. ret = wc_InitSha512_ex(&hmac->hash.sha512, heap, devId);
  212. break;
  213. #endif /* WOLFSSL_SHA512 */
  214. #ifdef WOLFSSL_SHA3
  215. #ifndef WOLFSSL_NOSHA3_224
  216. case WC_SHA3_224:
  217. ret = wc_InitSha3_224(&hmac->hash.sha3, heap, devId);
  218. break;
  219. #endif
  220. #ifndef WOLFSSL_NOSHA3_256
  221. case WC_SHA3_256:
  222. ret = wc_InitSha3_256(&hmac->hash.sha3, heap, devId);
  223. break;
  224. #endif
  225. #ifndef WOLFSSL_NOSHA3_384
  226. case WC_SHA3_384:
  227. ret = wc_InitSha3_384(&hmac->hash.sha3, heap, devId);
  228. break;
  229. #endif
  230. #ifndef WOLFSSL_NOSHA3_512
  231. case WC_SHA3_512:
  232. ret = wc_InitSha3_512(&hmac->hash.sha3, heap, devId);
  233. break;
  234. #endif
  235. #endif
  236. default:
  237. ret = BAD_FUNC_ARG;
  238. break;
  239. }
  240. /* default to NULL heap hint or test value */
  241. #ifdef WOLFSSL_HEAP_TEST
  242. hmac->heap = (void*)WOLFSSL_HEAP_TEST;
  243. #else
  244. hmac->heap = heap;
  245. #endif /* WOLFSSL_HEAP_TEST */
  246. return ret;
  247. }
  248. int wc_HmacSetKey(Hmac* hmac, int type, const byte* key, word32 length)
  249. {
  250. byte* ip;
  251. byte* op;
  252. word32 i, hmac_block_size = 0;
  253. int ret = 0;
  254. void* heap = NULL;
  255. if (hmac == NULL || (key == NULL && length != 0) ||
  256. !(type == WC_MD5 || type == WC_SHA ||
  257. type == WC_SHA224 || type == WC_SHA256 ||
  258. type == WC_SHA384 || type == WC_SHA512 ||
  259. type == WC_SHA3_224 || type == WC_SHA3_256 ||
  260. type == WC_SHA3_384 || type == WC_SHA3_512)) {
  261. return BAD_FUNC_ARG;
  262. }
  263. #ifndef HAVE_FIPS
  264. /* if set key has already been run then make sure and free existing */
  265. /* This is for async and PIC32MZ situations, and just normally OK,
  266. provided the user calls wc_HmacInit() first. That function is not
  267. available in FIPS builds. In current FIPS builds, the hashes are
  268. not allocating resources. */
  269. if (hmac->macType != WC_HASH_TYPE_NONE) {
  270. wc_HmacFree(hmac);
  271. }
  272. #endif
  273. hmac->innerHashKeyed = 0;
  274. hmac->macType = (byte)type;
  275. ret = _InitHmac(hmac, type, heap);
  276. if (ret != 0)
  277. return ret;
  278. #ifdef HAVE_FIPS
  279. if (length < HMAC_FIPS_MIN_KEY)
  280. return HMAC_MIN_KEYLEN_E;
  281. #endif
  282. #ifdef WOLF_CRYPTO_CB
  283. hmac->keyRaw = key; /* use buffer directly */
  284. hmac->keyLen = length;
  285. #endif
  286. ip = (byte*)hmac->ipad;
  287. op = (byte*)hmac->opad;
  288. switch (hmac->macType) {
  289. #ifndef NO_MD5
  290. case WC_MD5:
  291. hmac_block_size = WC_MD5_BLOCK_SIZE;
  292. if (length <= WC_MD5_BLOCK_SIZE) {
  293. if (key != NULL) {
  294. XMEMCPY(ip, key, length);
  295. }
  296. }
  297. else {
  298. ret = wc_Md5Update(&hmac->hash.md5, key, length);
  299. if (ret != 0)
  300. break;
  301. ret = wc_Md5Final(&hmac->hash.md5, ip);
  302. if (ret != 0)
  303. break;
  304. length = WC_MD5_DIGEST_SIZE;
  305. }
  306. break;
  307. #endif /* !NO_MD5 */
  308. #ifndef NO_SHA
  309. case WC_SHA:
  310. hmac_block_size = WC_SHA_BLOCK_SIZE;
  311. if (length <= WC_SHA_BLOCK_SIZE) {
  312. if (key != NULL) {
  313. XMEMCPY(ip, key, length);
  314. }
  315. }
  316. else {
  317. ret = wc_ShaUpdate(&hmac->hash.sha, key, length);
  318. if (ret != 0)
  319. break;
  320. ret = wc_ShaFinal(&hmac->hash.sha, ip);
  321. if (ret != 0)
  322. break;
  323. length = WC_SHA_DIGEST_SIZE;
  324. }
  325. break;
  326. #endif /* !NO_SHA */
  327. #ifdef WOLFSSL_SHA224
  328. case WC_SHA224:
  329. hmac_block_size = WC_SHA224_BLOCK_SIZE;
  330. if (length <= WC_SHA224_BLOCK_SIZE) {
  331. if (key != NULL) {
  332. XMEMCPY(ip, key, length);
  333. }
  334. }
  335. else {
  336. ret = wc_Sha224Update(&hmac->hash.sha224, key, length);
  337. if (ret != 0)
  338. break;
  339. ret = wc_Sha224Final(&hmac->hash.sha224, ip);
  340. if (ret != 0)
  341. break;
  342. length = WC_SHA224_DIGEST_SIZE;
  343. }
  344. break;
  345. #endif /* WOLFSSL_SHA224 */
  346. #ifndef NO_SHA256
  347. case WC_SHA256:
  348. hmac_block_size = WC_SHA256_BLOCK_SIZE;
  349. if (length <= WC_SHA256_BLOCK_SIZE) {
  350. if (key != NULL) {
  351. XMEMCPY(ip, key, length);
  352. }
  353. }
  354. else {
  355. ret = wc_Sha256Update(&hmac->hash.sha256, key, length);
  356. if (ret != 0)
  357. break;
  358. ret = wc_Sha256Final(&hmac->hash.sha256, ip);
  359. if (ret != 0)
  360. break;
  361. length = WC_SHA256_DIGEST_SIZE;
  362. }
  363. break;
  364. #endif /* !NO_SHA256 */
  365. #ifdef WOLFSSL_SHA384
  366. case WC_SHA384:
  367. hmac_block_size = WC_SHA384_BLOCK_SIZE;
  368. if (length <= WC_SHA384_BLOCK_SIZE) {
  369. if (key != NULL) {
  370. XMEMCPY(ip, key, length);
  371. }
  372. }
  373. else {
  374. ret = wc_Sha384Update(&hmac->hash.sha384, key, length);
  375. if (ret != 0)
  376. break;
  377. ret = wc_Sha384Final(&hmac->hash.sha384, ip);
  378. if (ret != 0)
  379. break;
  380. length = WC_SHA384_DIGEST_SIZE;
  381. }
  382. break;
  383. #endif /* WOLFSSL_SHA384 */
  384. #ifdef WOLFSSL_SHA512
  385. case WC_SHA512:
  386. hmac_block_size = WC_SHA512_BLOCK_SIZE;
  387. if (length <= WC_SHA512_BLOCK_SIZE) {
  388. if (key != NULL) {
  389. XMEMCPY(ip, key, length);
  390. }
  391. }
  392. else {
  393. ret = wc_Sha512Update(&hmac->hash.sha512, key, length);
  394. if (ret != 0)
  395. break;
  396. ret = wc_Sha512Final(&hmac->hash.sha512, ip);
  397. if (ret != 0)
  398. break;
  399. length = WC_SHA512_DIGEST_SIZE;
  400. }
  401. break;
  402. #endif /* WOLFSSL_SHA512 */
  403. #ifdef WOLFSSL_SHA3
  404. #ifndef WOLFSSL_NOSHA3_224
  405. case WC_SHA3_224:
  406. hmac_block_size = WC_SHA3_224_BLOCK_SIZE;
  407. if (length <= WC_SHA3_224_BLOCK_SIZE) {
  408. if (key != NULL) {
  409. XMEMCPY(ip, key, length);
  410. }
  411. }
  412. else {
  413. ret = wc_Sha3_224_Update(&hmac->hash.sha3, key, length);
  414. if (ret != 0)
  415. break;
  416. ret = wc_Sha3_224_Final(&hmac->hash.sha3, ip);
  417. if (ret != 0)
  418. break;
  419. length = WC_SHA3_224_DIGEST_SIZE;
  420. }
  421. break;
  422. #endif
  423. #ifndef WOLFSSL_NOSHA3_256
  424. case WC_SHA3_256:
  425. hmac_block_size = WC_SHA3_256_BLOCK_SIZE;
  426. if (length <= WC_SHA3_256_BLOCK_SIZE) {
  427. if (key != NULL) {
  428. XMEMCPY(ip, key, length);
  429. }
  430. }
  431. else {
  432. ret = wc_Sha3_256_Update(&hmac->hash.sha3, key, length);
  433. if (ret != 0)
  434. break;
  435. ret = wc_Sha3_256_Final(&hmac->hash.sha3, ip);
  436. if (ret != 0)
  437. break;
  438. length = WC_SHA3_256_DIGEST_SIZE;
  439. }
  440. break;
  441. #endif
  442. #ifndef WOLFSSL_NOSHA3_384
  443. case WC_SHA3_384:
  444. hmac_block_size = WC_SHA3_384_BLOCK_SIZE;
  445. if (length <= WC_SHA3_384_BLOCK_SIZE) {
  446. if (key != NULL) {
  447. XMEMCPY(ip, key, length);
  448. }
  449. }
  450. else {
  451. ret = wc_Sha3_384_Update(&hmac->hash.sha3, key, length);
  452. if (ret != 0)
  453. break;
  454. ret = wc_Sha3_384_Final(&hmac->hash.sha3, ip);
  455. if (ret != 0)
  456. break;
  457. length = WC_SHA3_384_DIGEST_SIZE;
  458. }
  459. break;
  460. #endif
  461. #ifndef WOLFSSL_NOSHA3_512
  462. case WC_SHA3_512:
  463. hmac_block_size = WC_SHA3_512_BLOCK_SIZE;
  464. if (length <= WC_SHA3_512_BLOCK_SIZE) {
  465. if (key != NULL) {
  466. XMEMCPY(ip, key, length);
  467. }
  468. }
  469. else {
  470. ret = wc_Sha3_512_Update(&hmac->hash.sha3, key, length);
  471. if (ret != 0)
  472. break;
  473. ret = wc_Sha3_512_Final(&hmac->hash.sha3, ip);
  474. if (ret != 0)
  475. break;
  476. length = WC_SHA3_512_DIGEST_SIZE;
  477. }
  478. break;
  479. #endif
  480. #endif /* WOLFSSL_SHA3 */
  481. default:
  482. return BAD_FUNC_ARG;
  483. }
  484. #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC)
  485. if (hmac->asyncDev.marker == WOLFSSL_ASYNC_MARKER_HMAC) {
  486. #if defined(HAVE_INTEL_QA) || defined(HAVE_CAVIUM)
  487. #ifdef HAVE_INTEL_QA
  488. if (IntelQaHmacGetType(hmac->macType, NULL) == 0)
  489. #endif
  490. {
  491. if (length > hmac_block_size)
  492. length = hmac_block_size;
  493. /* update key length */
  494. hmac->keyLen = (word16)length;
  495. return ret;
  496. }
  497. /* no need to pad below */
  498. #endif
  499. }
  500. #endif
  501. if (ret == 0) {
  502. if (length < hmac_block_size)
  503. XMEMSET(ip + length, 0, hmac_block_size - length);
  504. for(i = 0; i < hmac_block_size; i++) {
  505. op[i] = ip[i] ^ OPAD;
  506. ip[i] ^= IPAD;
  507. }
  508. }
  509. return ret;
  510. }
  511. static int HmacKeyInnerHash(Hmac* hmac)
  512. {
  513. int ret = 0;
  514. switch (hmac->macType) {
  515. #ifndef NO_MD5
  516. case WC_MD5:
  517. ret = wc_Md5Update(&hmac->hash.md5, (byte*)hmac->ipad,
  518. WC_MD5_BLOCK_SIZE);
  519. break;
  520. #endif /* !NO_MD5 */
  521. #ifndef NO_SHA
  522. case WC_SHA:
  523. ret = wc_ShaUpdate(&hmac->hash.sha, (byte*)hmac->ipad,
  524. WC_SHA_BLOCK_SIZE);
  525. break;
  526. #endif /* !NO_SHA */
  527. #ifdef WOLFSSL_SHA224
  528. case WC_SHA224:
  529. ret = wc_Sha224Update(&hmac->hash.sha224, (byte*)hmac->ipad,
  530. WC_SHA224_BLOCK_SIZE);
  531. break;
  532. #endif /* WOLFSSL_SHA224 */
  533. #ifndef NO_SHA256
  534. case WC_SHA256:
  535. ret = wc_Sha256Update(&hmac->hash.sha256, (byte*)hmac->ipad,
  536. WC_SHA256_BLOCK_SIZE);
  537. break;
  538. #endif /* !NO_SHA256 */
  539. #ifdef WOLFSSL_SHA384
  540. case WC_SHA384:
  541. ret = wc_Sha384Update(&hmac->hash.sha384, (byte*)hmac->ipad,
  542. WC_SHA384_BLOCK_SIZE);
  543. break;
  544. #endif /* WOLFSSL_SHA384 */
  545. #ifdef WOLFSSL_SHA512
  546. case WC_SHA512:
  547. ret = wc_Sha512Update(&hmac->hash.sha512, (byte*)hmac->ipad,
  548. WC_SHA512_BLOCK_SIZE);
  549. break;
  550. #endif /* WOLFSSL_SHA512 */
  551. #ifdef WOLFSSL_SHA3
  552. #ifndef WOLFSSL_NOSHA3_224
  553. case WC_SHA3_224:
  554. ret = wc_Sha3_224_Update(&hmac->hash.sha3, (byte*)hmac->ipad,
  555. WC_SHA3_224_BLOCK_SIZE);
  556. break;
  557. #endif
  558. #ifndef WOLFSSL_NOSHA3_256
  559. case WC_SHA3_256:
  560. ret = wc_Sha3_256_Update(&hmac->hash.sha3, (byte*)hmac->ipad,
  561. WC_SHA3_256_BLOCK_SIZE);
  562. break;
  563. #endif
  564. #ifndef WOLFSSL_NOSHA3_384
  565. case WC_SHA3_384:
  566. ret = wc_Sha3_384_Update(&hmac->hash.sha3, (byte*)hmac->ipad,
  567. WC_SHA3_384_BLOCK_SIZE);
  568. break;
  569. #endif
  570. #ifndef WOLFSSL_NOSHA3_512
  571. case WC_SHA3_512:
  572. ret = wc_Sha3_512_Update(&hmac->hash.sha3, (byte*)hmac->ipad,
  573. WC_SHA3_512_BLOCK_SIZE);
  574. break;
  575. #endif
  576. #endif /* WOLFSSL_SHA3 */
  577. default:
  578. break;
  579. }
  580. if (ret == 0)
  581. hmac->innerHashKeyed = WC_HMAC_INNER_HASH_KEYED_SW;
  582. return ret;
  583. }
  584. int wc_HmacUpdate(Hmac* hmac, const byte* msg, word32 length)
  585. {
  586. int ret = 0;
  587. if (hmac == NULL || (msg == NULL && length > 0)) {
  588. return BAD_FUNC_ARG;
  589. }
  590. #ifdef WOLF_CRYPTO_CB
  591. if (hmac->devId != INVALID_DEVID) {
  592. ret = wc_CryptoCb_Hmac(hmac, hmac->macType, msg, length, NULL);
  593. if (ret != CRYPTOCB_UNAVAILABLE)
  594. return ret;
  595. /* fall-through when unavailable */
  596. ret = 0; /* reset error code */
  597. }
  598. #endif
  599. #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC)
  600. if (hmac->asyncDev.marker == WOLFSSL_ASYNC_MARKER_HMAC) {
  601. #if defined(HAVE_CAVIUM)
  602. return NitroxHmacUpdate(hmac, msg, length);
  603. #elif defined(HAVE_INTEL_QA)
  604. if (IntelQaHmacGetType(hmac->macType, NULL) == 0) {
  605. return IntelQaHmac(&hmac->asyncDev, hmac->macType,
  606. (byte*)hmac->ipad, hmac->keyLen, NULL, msg, length);
  607. }
  608. #endif
  609. }
  610. #endif /* WOLFSSL_ASYNC_CRYPT */
  611. if (!hmac->innerHashKeyed) {
  612. ret = HmacKeyInnerHash(hmac);
  613. if (ret != 0)
  614. return ret;
  615. }
  616. switch (hmac->macType) {
  617. #ifndef NO_MD5
  618. case WC_MD5:
  619. ret = wc_Md5Update(&hmac->hash.md5, msg, length);
  620. break;
  621. #endif /* !NO_MD5 */
  622. #ifndef NO_SHA
  623. case WC_SHA:
  624. ret = wc_ShaUpdate(&hmac->hash.sha, msg, length);
  625. break;
  626. #endif /* !NO_SHA */
  627. #ifdef WOLFSSL_SHA224
  628. case WC_SHA224:
  629. ret = wc_Sha224Update(&hmac->hash.sha224, msg, length);
  630. break;
  631. #endif /* WOLFSSL_SHA224 */
  632. #ifndef NO_SHA256
  633. case WC_SHA256:
  634. ret = wc_Sha256Update(&hmac->hash.sha256, msg, length);
  635. break;
  636. #endif /* !NO_SHA256 */
  637. #ifdef WOLFSSL_SHA384
  638. case WC_SHA384:
  639. ret = wc_Sha384Update(&hmac->hash.sha384, msg, length);
  640. break;
  641. #endif /* WOLFSSL_SHA384 */
  642. #ifdef WOLFSSL_SHA512
  643. case WC_SHA512:
  644. ret = wc_Sha512Update(&hmac->hash.sha512, msg, length);
  645. break;
  646. #endif /* WOLFSSL_SHA512 */
  647. #ifdef WOLFSSL_SHA3
  648. #ifndef WOLFSSL_NOSHA3_224
  649. case WC_SHA3_224:
  650. ret = wc_Sha3_224_Update(&hmac->hash.sha3, msg, length);
  651. break;
  652. #endif
  653. #ifndef WOLFSSL_NOSHA3_256
  654. case WC_SHA3_256:
  655. ret = wc_Sha3_256_Update(&hmac->hash.sha3, msg, length);
  656. break;
  657. #endif
  658. #ifndef WOLFSSL_NOSHA3_384
  659. case WC_SHA3_384:
  660. ret = wc_Sha3_384_Update(&hmac->hash.sha3, msg, length);
  661. break;
  662. #endif
  663. #ifndef WOLFSSL_NOSHA3_512
  664. case WC_SHA3_512:
  665. ret = wc_Sha3_512_Update(&hmac->hash.sha3, msg, length);
  666. break;
  667. #endif
  668. #endif /* WOLFSSL_SHA3 */
  669. default:
  670. break;
  671. }
  672. return ret;
  673. }
  674. int wc_HmacFinal(Hmac* hmac, byte* hash)
  675. {
  676. int ret;
  677. if (hmac == NULL || hash == NULL) {
  678. return BAD_FUNC_ARG;
  679. }
  680. #ifdef WOLF_CRYPTO_CB
  681. if (hmac->devId != INVALID_DEVID) {
  682. ret = wc_CryptoCb_Hmac(hmac, hmac->macType, NULL, 0, hash);
  683. if (ret != CRYPTOCB_UNAVAILABLE)
  684. return ret;
  685. /* fall-through when unavailable */
  686. }
  687. #endif
  688. #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC)
  689. if (hmac->asyncDev.marker == WOLFSSL_ASYNC_MARKER_HMAC) {
  690. int hashLen = wc_HmacSizeByType(hmac->macType);
  691. if (hashLen <= 0)
  692. return hashLen;
  693. #if defined(HAVE_CAVIUM)
  694. return NitroxHmacFinal(hmac, hash, hashLen);
  695. #elif defined(HAVE_INTEL_QA)
  696. if (IntelQaHmacGetType(hmac->macType, NULL) == 0) {
  697. return IntelQaHmac(&hmac->asyncDev, hmac->macType,
  698. (byte*)hmac->ipad, hmac->keyLen, hash, NULL, hashLen);
  699. }
  700. #endif
  701. }
  702. #endif /* WOLFSSL_ASYNC_CRYPT */
  703. if (!hmac->innerHashKeyed) {
  704. ret = HmacKeyInnerHash(hmac);
  705. if (ret != 0)
  706. return ret;
  707. }
  708. switch (hmac->macType) {
  709. #ifndef NO_MD5
  710. case WC_MD5:
  711. ret = wc_Md5Final(&hmac->hash.md5, (byte*)hmac->innerHash);
  712. if (ret != 0)
  713. break;
  714. ret = wc_Md5Update(&hmac->hash.md5, (byte*)hmac->opad,
  715. WC_MD5_BLOCK_SIZE);
  716. if (ret != 0)
  717. break;
  718. ret = wc_Md5Update(&hmac->hash.md5, (byte*)hmac->innerHash,
  719. WC_MD5_DIGEST_SIZE);
  720. if (ret != 0)
  721. break;
  722. ret = wc_Md5Final(&hmac->hash.md5, hash);
  723. break;
  724. #endif /* !NO_MD5 */
  725. #ifndef NO_SHA
  726. case WC_SHA:
  727. ret = wc_ShaFinal(&hmac->hash.sha, (byte*)hmac->innerHash);
  728. if (ret != 0)
  729. break;
  730. ret = wc_ShaUpdate(&hmac->hash.sha, (byte*)hmac->opad,
  731. WC_SHA_BLOCK_SIZE);
  732. if (ret != 0)
  733. break;
  734. ret = wc_ShaUpdate(&hmac->hash.sha, (byte*)hmac->innerHash,
  735. WC_SHA_DIGEST_SIZE);
  736. if (ret != 0)
  737. break;
  738. ret = wc_ShaFinal(&hmac->hash.sha, hash);
  739. break;
  740. #endif /* !NO_SHA */
  741. #ifdef WOLFSSL_SHA224
  742. case WC_SHA224:
  743. ret = wc_Sha224Final(&hmac->hash.sha224, (byte*)hmac->innerHash);
  744. if (ret != 0)
  745. break;
  746. ret = wc_Sha224Update(&hmac->hash.sha224, (byte*)hmac->opad,
  747. WC_SHA224_BLOCK_SIZE);
  748. if (ret != 0)
  749. break;
  750. ret = wc_Sha224Update(&hmac->hash.sha224, (byte*)hmac->innerHash,
  751. WC_SHA224_DIGEST_SIZE);
  752. if (ret != 0)
  753. break;
  754. ret = wc_Sha224Final(&hmac->hash.sha224, hash);
  755. if (ret != 0)
  756. break;
  757. break;
  758. #endif /* WOLFSSL_SHA224 */
  759. #ifndef NO_SHA256
  760. case WC_SHA256:
  761. ret = wc_Sha256Final(&hmac->hash.sha256, (byte*)hmac->innerHash);
  762. if (ret != 0)
  763. break;
  764. ret = wc_Sha256Update(&hmac->hash.sha256, (byte*)hmac->opad,
  765. WC_SHA256_BLOCK_SIZE);
  766. if (ret != 0)
  767. break;
  768. ret = wc_Sha256Update(&hmac->hash.sha256, (byte*)hmac->innerHash,
  769. WC_SHA256_DIGEST_SIZE);
  770. if (ret != 0)
  771. break;
  772. ret = wc_Sha256Final(&hmac->hash.sha256, hash);
  773. break;
  774. #endif /* !NO_SHA256 */
  775. #ifdef WOLFSSL_SHA384
  776. case WC_SHA384:
  777. ret = wc_Sha384Final(&hmac->hash.sha384, (byte*)hmac->innerHash);
  778. if (ret != 0)
  779. break;
  780. ret = wc_Sha384Update(&hmac->hash.sha384, (byte*)hmac->opad,
  781. WC_SHA384_BLOCK_SIZE);
  782. if (ret != 0)
  783. break;
  784. ret = wc_Sha384Update(&hmac->hash.sha384, (byte*)hmac->innerHash,
  785. WC_SHA384_DIGEST_SIZE);
  786. if (ret != 0)
  787. break;
  788. ret = wc_Sha384Final(&hmac->hash.sha384, hash);
  789. break;
  790. #endif /* WOLFSSL_SHA384 */
  791. #ifdef WOLFSSL_SHA512
  792. case WC_SHA512:
  793. ret = wc_Sha512Final(&hmac->hash.sha512, (byte*)hmac->innerHash);
  794. if (ret != 0)
  795. break;
  796. ret = wc_Sha512Update(&hmac->hash.sha512, (byte*)hmac->opad,
  797. WC_SHA512_BLOCK_SIZE);
  798. if (ret != 0)
  799. break;
  800. ret = wc_Sha512Update(&hmac->hash.sha512, (byte*)hmac->innerHash,
  801. WC_SHA512_DIGEST_SIZE);
  802. if (ret != 0)
  803. break;
  804. ret = wc_Sha512Final(&hmac->hash.sha512, hash);
  805. break;
  806. #endif /* WOLFSSL_SHA512 */
  807. #ifdef WOLFSSL_SHA3
  808. #ifndef WOLFSSL_NOSHA3_224
  809. case WC_SHA3_224:
  810. ret = wc_Sha3_224_Final(&hmac->hash.sha3, (byte*)hmac->innerHash);
  811. if (ret != 0)
  812. break;
  813. ret = wc_Sha3_224_Update(&hmac->hash.sha3, (byte*)hmac->opad,
  814. WC_SHA3_224_BLOCK_SIZE);
  815. if (ret != 0)
  816. break;
  817. ret = wc_Sha3_224_Update(&hmac->hash.sha3, (byte*)hmac->innerHash,
  818. WC_SHA3_224_DIGEST_SIZE);
  819. if (ret != 0)
  820. break;
  821. ret = wc_Sha3_224_Final(&hmac->hash.sha3, hash);
  822. break;
  823. #endif
  824. #ifndef WOLFSSL_NOSHA3_256
  825. case WC_SHA3_256:
  826. ret = wc_Sha3_256_Final(&hmac->hash.sha3, (byte*)hmac->innerHash);
  827. if (ret != 0)
  828. break;
  829. ret = wc_Sha3_256_Update(&hmac->hash.sha3, (byte*)hmac->opad,
  830. WC_SHA3_256_BLOCK_SIZE);
  831. if (ret != 0)
  832. break;
  833. ret = wc_Sha3_256_Update(&hmac->hash.sha3, (byte*)hmac->innerHash,
  834. WC_SHA3_256_DIGEST_SIZE);
  835. if (ret != 0)
  836. break;
  837. ret = wc_Sha3_256_Final(&hmac->hash.sha3, hash);
  838. break;
  839. #endif
  840. #ifndef WOLFSSL_NOSHA3_384
  841. case WC_SHA3_384:
  842. ret = wc_Sha3_384_Final(&hmac->hash.sha3, (byte*)hmac->innerHash);
  843. if (ret != 0)
  844. break;
  845. ret = wc_Sha3_384_Update(&hmac->hash.sha3, (byte*)hmac->opad,
  846. WC_SHA3_384_BLOCK_SIZE);
  847. if (ret != 0)
  848. break;
  849. ret = wc_Sha3_384_Update(&hmac->hash.sha3, (byte*)hmac->innerHash,
  850. WC_SHA3_384_DIGEST_SIZE);
  851. if (ret != 0)
  852. break;
  853. ret = wc_Sha3_384_Final(&hmac->hash.sha3, hash);
  854. break;
  855. #endif
  856. #ifndef WOLFSSL_NOSHA3_512
  857. case WC_SHA3_512:
  858. ret = wc_Sha3_512_Final(&hmac->hash.sha3, (byte*)hmac->innerHash);
  859. if (ret != 0)
  860. break;
  861. ret = wc_Sha3_512_Update(&hmac->hash.sha3, (byte*)hmac->opad,
  862. WC_SHA3_512_BLOCK_SIZE);
  863. if (ret != 0)
  864. break;
  865. ret = wc_Sha3_512_Update(&hmac->hash.sha3, (byte*)hmac->innerHash,
  866. WC_SHA3_512_DIGEST_SIZE);
  867. if (ret != 0)
  868. break;
  869. ret = wc_Sha3_512_Final(&hmac->hash.sha3, hash);
  870. break;
  871. #endif
  872. #endif /* WOLFSSL_SHA3 */
  873. default:
  874. ret = BAD_FUNC_ARG;
  875. break;
  876. }
  877. if (ret == 0) {
  878. hmac->innerHashKeyed = 0;
  879. }
  880. return ret;
  881. }
  882. #ifdef WOLFSSL_KCAPI_HMAC
  883. /* implemented in wolfcrypt/src/port/kcapi/kcapi_hmac.c */
  884. #else
  885. /* Initialize Hmac for use with async device */
  886. int wc_HmacInit(Hmac* hmac, void* heap, int devId)
  887. {
  888. int ret = 0;
  889. if (hmac == NULL)
  890. return BAD_FUNC_ARG;
  891. XMEMSET(hmac, 0, sizeof(Hmac));
  892. hmac->macType = WC_HASH_TYPE_NONE;
  893. hmac->heap = heap;
  894. #ifdef WOLF_CRYPTO_CB
  895. hmac->devId = devId;
  896. hmac->devCtx = NULL;
  897. #endif
  898. #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC)
  899. ret = wolfAsync_DevCtxInit(&hmac->asyncDev, WOLFSSL_ASYNC_MARKER_HMAC,
  900. hmac->heap, devId);
  901. #else
  902. (void)devId;
  903. #endif /* WOLFSSL_ASYNC_CRYPT */
  904. return ret;
  905. }
  906. #ifdef HAVE_PKCS11
  907. int wc_HmacInit_Id(Hmac* hmac, unsigned char* id, int len, void* heap,
  908. int devId)
  909. {
  910. int ret = 0;
  911. if (hmac == NULL)
  912. ret = BAD_FUNC_ARG;
  913. if (ret == 0 && (len < 0 || len > HMAC_MAX_ID_LEN))
  914. ret = BUFFER_E;
  915. if (ret == 0)
  916. ret = wc_HmacInit(hmac, heap, devId);
  917. if (ret == 0) {
  918. XMEMCPY(hmac->id, id, len);
  919. hmac->idLen = len;
  920. }
  921. return ret;
  922. }
  923. int wc_HmacInit_Label(Hmac* hmac, const char* label, void* heap, int devId)
  924. {
  925. int ret = 0;
  926. int labelLen = 0;
  927. if (hmac == NULL || label == NULL)
  928. ret = BAD_FUNC_ARG;
  929. if (ret == 0) {
  930. labelLen = (int)XSTRLEN(label);
  931. if (labelLen == 0 || labelLen > HMAC_MAX_LABEL_LEN)
  932. ret = BUFFER_E;
  933. }
  934. if (ret == 0)
  935. ret = wc_HmacInit(hmac, heap, devId);
  936. if (ret == 0) {
  937. XMEMCPY(hmac->label, label, labelLen);
  938. hmac->labelLen = labelLen;
  939. }
  940. return ret;
  941. }
  942. #endif
  943. /* Free Hmac from use with async device */
  944. void wc_HmacFree(Hmac* hmac)
  945. {
  946. if (hmac == NULL)
  947. return;
  948. #ifdef WOLF_CRYPTO_CB
  949. /* handle cleanup case where final is not called */
  950. if (hmac->devId != INVALID_DEVID && hmac->devCtx != NULL) {
  951. int ret;
  952. byte finalHash[WC_HMAC_BLOCK_SIZE];
  953. ret = wc_CryptoCb_Hmac(hmac, hmac->macType, NULL, 0, finalHash);
  954. (void)ret; /* must ignore return code here */
  955. (void)finalHash;
  956. }
  957. #endif
  958. #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC)
  959. wolfAsync_DevCtxFree(&hmac->asyncDev, WOLFSSL_ASYNC_MARKER_HMAC);
  960. #endif /* WOLFSSL_ASYNC_CRYPT */
  961. switch (hmac->macType) {
  962. #ifndef NO_MD5
  963. case WC_MD5:
  964. wc_Md5Free(&hmac->hash.md5);
  965. break;
  966. #endif /* !NO_MD5 */
  967. #ifndef NO_SHA
  968. case WC_SHA:
  969. wc_ShaFree(&hmac->hash.sha);
  970. break;
  971. #endif /* !NO_SHA */
  972. #ifdef WOLFSSL_SHA224
  973. case WC_SHA224:
  974. wc_Sha224Free(&hmac->hash.sha224);
  975. break;
  976. #endif /* WOLFSSL_SHA224 */
  977. #ifndef NO_SHA256
  978. case WC_SHA256:
  979. wc_Sha256Free(&hmac->hash.sha256);
  980. break;
  981. #endif /* !NO_SHA256 */
  982. #ifdef WOLFSSL_SHA384
  983. case WC_SHA384:
  984. wc_Sha384Free(&hmac->hash.sha384);
  985. break;
  986. #endif /* WOLFSSL_SHA384 */
  987. #ifdef WOLFSSL_SHA512
  988. case WC_SHA512:
  989. wc_Sha512Free(&hmac->hash.sha512);
  990. break;
  991. #endif /* WOLFSSL_SHA512 */
  992. #ifdef WOLFSSL_SHA3
  993. #ifndef WOLFSSL_NOSHA3_224
  994. case WC_SHA3_224:
  995. wc_Sha3_224_Free(&hmac->hash.sha3);
  996. break;
  997. #endif
  998. #ifndef WOLFSSL_NOSHA3_256
  999. case WC_SHA3_256:
  1000. wc_Sha3_256_Free(&hmac->hash.sha3);
  1001. break;
  1002. #endif
  1003. #ifndef WOLFSSL_NOSHA3_384
  1004. case WC_SHA3_384:
  1005. wc_Sha3_384_Free(&hmac->hash.sha3);
  1006. break;
  1007. #endif
  1008. #ifndef WOLFSSL_NOSHA3_512
  1009. case WC_SHA3_512:
  1010. wc_Sha3_512_Free(&hmac->hash.sha3);
  1011. break;
  1012. #endif
  1013. #endif /* WOLFSSL_SHA3 */
  1014. default:
  1015. break;
  1016. }
  1017. }
  1018. #endif /* WOLFSSL_KCAPI_HMAC */
  1019. int wolfSSL_GetHmacMaxSize(void)
  1020. {
  1021. return WC_MAX_DIGEST_SIZE;
  1022. }
  1023. #ifdef HAVE_HKDF
  1024. /* HMAC-KDF-Extract.
  1025. * RFC 5869 - HMAC-based Extract-and-Expand Key Derivation Function (HKDF).
  1026. *
  1027. * type The hash algorithm type.
  1028. * salt The optional salt value.
  1029. * saltSz The size of the salt.
  1030. * inKey The input keying material.
  1031. * inKeySz The size of the input keying material.
  1032. * out The pseudorandom key with the length that of the hash.
  1033. * returns 0 on success, otherwise failure.
  1034. */
  1035. int wc_HKDF_Extract(int type, const byte* salt, word32 saltSz,
  1036. const byte* inKey, word32 inKeySz, byte* out)
  1037. {
  1038. byte tmp[WC_MAX_DIGEST_SIZE]; /* localSalt helper */
  1039. Hmac myHmac;
  1040. int ret;
  1041. const byte* localSalt; /* either points to user input or tmp */
  1042. int hashSz;
  1043. ret = wc_HmacSizeByType(type);
  1044. if (ret < 0)
  1045. return ret;
  1046. hashSz = ret;
  1047. localSalt = salt;
  1048. if (localSalt == NULL) {
  1049. XMEMSET(tmp, 0, hashSz);
  1050. localSalt = tmp;
  1051. saltSz = hashSz;
  1052. }
  1053. ret = wc_HmacInit(&myHmac, NULL, INVALID_DEVID);
  1054. if (ret == 0) {
  1055. ret = wc_HmacSetKey(&myHmac, type, localSalt, saltSz);
  1056. if (ret == 0)
  1057. ret = wc_HmacUpdate(&myHmac, inKey, inKeySz);
  1058. if (ret == 0)
  1059. ret = wc_HmacFinal(&myHmac, out);
  1060. ForceZero(&myHmac, sizeof(myHmac));
  1061. wc_HmacFree(&myHmac);
  1062. }
  1063. return ret;
  1064. }
  1065. /* HMAC-KDF-Expand.
  1066. * RFC 5869 - HMAC-based Extract-and-Expand Key Derivation Function (HKDF).
  1067. *
  1068. * type The hash algorithm type.
  1069. * inKey The input key.
  1070. * inKeySz The size of the input key.
  1071. * info The application specific information.
  1072. * infoSz The size of the application specific information.
  1073. * out The output keying material.
  1074. * returns 0 on success, otherwise failure.
  1075. */
  1076. int wc_HKDF_Expand(int type, const byte* inKey, word32 inKeySz,
  1077. const byte* info, word32 infoSz, byte* out, word32 outSz)
  1078. {
  1079. byte tmp[WC_MAX_DIGEST_SIZE];
  1080. Hmac myHmac;
  1081. int ret = 0;
  1082. word32 outIdx = 0;
  1083. word32 hashSz = wc_HmacSizeByType(type);
  1084. byte n = 0x1;
  1085. /* RFC 5869 states that the length of output keying material in
  1086. octets must be L <= 255*HashLen or N = ceil(L/HashLen) */
  1087. if (out == NULL || ((outSz/hashSz) + ((outSz % hashSz) != 0)) > 255)
  1088. return BAD_FUNC_ARG;
  1089. ret = wc_HmacInit(&myHmac, NULL, INVALID_DEVID);
  1090. if (ret != 0)
  1091. return ret;
  1092. while (outIdx < outSz) {
  1093. int tmpSz = (n == 1) ? 0 : hashSz;
  1094. word32 left = outSz - outIdx;
  1095. ret = wc_HmacSetKey(&myHmac, type, inKey, inKeySz);
  1096. if (ret != 0)
  1097. break;
  1098. ret = wc_HmacUpdate(&myHmac, tmp, tmpSz);
  1099. if (ret != 0)
  1100. break;
  1101. ret = wc_HmacUpdate(&myHmac, info, infoSz);
  1102. if (ret != 0)
  1103. break;
  1104. ret = wc_HmacUpdate(&myHmac, &n, 1);
  1105. if (ret != 0)
  1106. break;
  1107. ret = wc_HmacFinal(&myHmac, tmp);
  1108. if (ret != 0)
  1109. break;
  1110. left = min(left, hashSz);
  1111. XMEMCPY(out+outIdx, tmp, left);
  1112. outIdx += hashSz;
  1113. n++;
  1114. }
  1115. ForceZero(&myHmac, sizeof(myHmac));
  1116. wc_HmacFree(&myHmac);
  1117. return ret;
  1118. }
  1119. /* HMAC-KDF.
  1120. * RFC 5869 - HMAC-based Extract-and-Expand Key Derivation Function (HKDF).
  1121. *
  1122. * type The hash algorithm type.
  1123. * inKey The input keying material.
  1124. * inKeySz The size of the input keying material.
  1125. * salt The optional salt value.
  1126. * saltSz The size of the salt.
  1127. * info The application specific information.
  1128. * infoSz The size of the application specific information.
  1129. * out The output keying material.
  1130. * returns 0 on success, otherwise failure.
  1131. */
  1132. int wc_HKDF(int type, const byte* inKey, word32 inKeySz,
  1133. const byte* salt, word32 saltSz,
  1134. const byte* info, word32 infoSz,
  1135. byte* out, word32 outSz)
  1136. {
  1137. byte prk[WC_MAX_DIGEST_SIZE];
  1138. int hashSz = wc_HmacSizeByType(type);
  1139. int ret;
  1140. if (hashSz < 0)
  1141. return BAD_FUNC_ARG;
  1142. ret = wc_HKDF_Extract(type, salt, saltSz, inKey, inKeySz, prk);
  1143. if (ret != 0)
  1144. return ret;
  1145. return wc_HKDF_Expand(type, prk, hashSz, info, infoSz, out, outSz);
  1146. }
  1147. #endif /* HAVE_HKDF */
  1148. #endif /* HAVE_FIPS */
  1149. #endif /* NO_HMAC */