hmac.c 39 KB

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