Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of wolfSSL by
hmac.c
00001 /* hmac.h 00002 * 00003 * Copyright (C) 2006-2016 wolfSSL Inc. 00004 * 00005 * This file is part of wolfSSL. 00006 * 00007 * wolfSSL is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation; either version 2 of the License, or 00010 * (at your option) any later version. 00011 * 00012 * wolfSSL is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with this program; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA 00020 */ 00021 00022 00023 #ifdef HAVE_CONFIG_H 00024 #include <config.h> 00025 #endif 00026 00027 #include <wolfssl/wolfcrypt/settings.h> 00028 00029 #ifndef NO_HMAC 00030 00031 #include <wolfssl/wolfcrypt/hmac.h> 00032 00033 #ifdef NO_INLINE 00034 #include <wolfssl/wolfcrypt/misc.h> 00035 #else 00036 #define WOLFSSL_MISC_INCLUDED 00037 #include <wolfcrypt/src/misc.c> 00038 #endif 00039 00040 00041 /* fips wrapper calls, user can call direct */ 00042 #ifdef HAVE_FIPS 00043 /* does init */ 00044 int wc_HmacSetKey(Hmac* hmac, int type, const byte* key, word32 keySz) 00045 { 00046 return HmacSetKey_fips(hmac, type, key, keySz); 00047 } 00048 int wc_HmacUpdate(Hmac* hmac, const byte* in, word32 sz) 00049 { 00050 return HmacUpdate_fips(hmac, in, sz); 00051 } 00052 int wc_HmacFinal(Hmac* hmac, byte* out) 00053 { 00054 return HmacFinal_fips(hmac, out); 00055 } 00056 int wolfSSL_GetHmacMaxSize(void) 00057 { 00058 return CyaSSL_GetHmacMaxSize(); 00059 } 00060 00061 int wc_HmacInit(Hmac* hmac, void* heap, int devId) 00062 { 00063 (void)hmac; 00064 (void)heap; 00065 (void)devId; 00066 /* FIPS doesn't support: 00067 return HmacInit(hmac, heap, devId); */ 00068 return 0; 00069 } 00070 void wc_HmacFree(Hmac* hmac) 00071 { 00072 (void)hmac; 00073 /* FIPS doesn't support: 00074 HmacFree(hmac); */ 00075 } 00076 00077 #ifdef HAVE_HKDF 00078 int wc_HKDF(int type, const byte* inKey, word32 inKeySz, 00079 const byte* salt, word32 saltSz, 00080 const byte* info, word32 infoSz, 00081 byte* out, word32 outSz) 00082 { 00083 return HKDF(type, inKey, inKeySz, salt, saltSz, 00084 info, infoSz, out, outSz); 00085 } 00086 #endif /* HAVE_HKDF */ 00087 00088 #else /* else build without fips */ 00089 00090 00091 #include <wolfssl/wolfcrypt/error-crypt.h> 00092 00093 00094 #ifdef WOLFSSL_PIC32MZ_HASH 00095 #define wc_InitMd5 wc_InitMd5_sw 00096 #define wc_Md5Update wc_Md5Update_sw 00097 #define wc_Md5Final wc_Md5Final_sw 00098 00099 #define wc_InitSha wc_InitSha_sw 00100 #define wc_ShaUpdate wc_ShaUpdate_sw 00101 #define wc_ShaFinal wc_ShaFinal_sw 00102 00103 #define wc_InitSha256 wc_InitSha256_sw 00104 #define wc_Sha256Update wc_Sha256Update_sw 00105 #define wc_Sha256Final wc_Sha256Final_sw 00106 #endif /* WOLFSSL_PIC32MZ_HASH */ 00107 00108 00109 00110 int wc_HmacSizeByType(int type) 00111 { 00112 int ret; 00113 00114 if (!(type == MD5 || type == SHA || type == SHA256 || type == SHA384 00115 || type == SHA512 || type == BLAKE2B_ID 00116 || type == SHA224)) { 00117 return BAD_FUNC_ARG; 00118 } 00119 00120 switch (type) { 00121 #ifndef NO_MD5 00122 case MD5: 00123 ret = MD5_DIGEST_SIZE; 00124 break; 00125 #endif /* !NO_MD5 */ 00126 00127 #ifndef NO_SHA 00128 case SHA: 00129 ret = SHA_DIGEST_SIZE; 00130 break; 00131 #endif /* !NO_SHA */ 00132 00133 #ifdef WOLFSSL_SHA224 00134 case SHA224: 00135 ret = SHA224_DIGEST_SIZE; 00136 break; 00137 #endif /* WOLFSSL_SHA224 */ 00138 00139 #ifndef NO_SHA256 00140 case SHA256: 00141 ret = SHA256_DIGEST_SIZE; 00142 break; 00143 #endif /* !NO_SHA256 */ 00144 00145 #ifdef WOLFSSL_SHA512 00146 #ifdef WOLFSSL_SHA384 00147 case SHA384: 00148 ret = SHA384_DIGEST_SIZE; 00149 break; 00150 #endif /* WOLFSSL_SHA384 */ 00151 case SHA512: 00152 ret = SHA512_DIGEST_SIZE; 00153 break; 00154 #endif /* WOLFSSL_SHA512 */ 00155 00156 #ifdef HAVE_BLAKE2 00157 case BLAKE2B_ID: 00158 ret = BLAKE2B_OUTBYTES; 00159 break; 00160 #endif /* HAVE_BLAKE2 */ 00161 00162 default: 00163 ret = BAD_FUNC_ARG; 00164 break; 00165 } 00166 00167 return ret; 00168 } 00169 00170 static int _InitHmac(Hmac* hmac, int type, void* heap) 00171 { 00172 int ret = 0; 00173 00174 switch (type) { 00175 #ifndef NO_MD5 00176 case MD5: 00177 ret = wc_InitMd5(&hmac->hash.md5); 00178 break; 00179 #endif /* !NO_MD5 */ 00180 00181 #ifndef NO_SHA 00182 case SHA: 00183 ret = wc_InitSha(&hmac->hash.sha); 00184 break; 00185 #endif /* !NO_SHA */ 00186 00187 #ifdef WOLFSSL_SHA224 00188 case SHA224: 00189 ret = wc_InitSha224(&hmac->hash.sha224); 00190 break; 00191 #endif /* WOLFSSL_SHA224 */ 00192 00193 #ifndef NO_SHA256 00194 case SHA256: 00195 ret = wc_InitSha256(&hmac->hash.sha256); 00196 break; 00197 #endif /* !NO_SHA256 */ 00198 00199 #ifdef WOLFSSL_SHA512 00200 #ifdef WOLFSSL_SHA384 00201 case SHA384: 00202 ret = wc_InitSha384(&hmac->hash.sha384); 00203 break; 00204 #endif /* WOLFSSL_SHA384 */ 00205 case SHA512: 00206 ret = wc_InitSha512(&hmac->hash.sha512); 00207 break; 00208 #endif /* WOLFSSL_SHA512 */ 00209 00210 #ifdef HAVE_BLAKE2 00211 case BLAKE2B_ID: 00212 ret = wc_InitBlake2b(&hmac->hash.blake2b, BLAKE2B_256); 00213 break; 00214 #endif /* HAVE_BLAKE2 */ 00215 00216 default: 00217 ret = BAD_FUNC_ARG; 00218 break; 00219 } 00220 00221 /* default to NULL heap hint or test value */ 00222 #ifdef WOLFSSL_HEAP_TEST 00223 hmac->heap = (void)WOLFSSL_HEAP_TEST; 00224 #else 00225 hmac->heap = heap; 00226 #endif /* WOLFSSL_HEAP_TEST */ 00227 00228 return ret; 00229 } 00230 00231 00232 int wc_HmacSetKey(Hmac* hmac, int type, const byte* key, word32 length) 00233 { 00234 byte* ip; 00235 byte* op; 00236 word32 i, hmac_block_size = 0; 00237 int ret = 0; 00238 void* heap = NULL; 00239 00240 if (hmac == NULL || (key == NULL && length != 0) || 00241 !(type == MD5 || type == SHA || type == SHA256 || type == SHA384 00242 || type == SHA512 || type == BLAKE2B_ID 00243 || type == SHA224)) { 00244 return BAD_FUNC_ARG; 00245 } 00246 00247 hmac->innerHashKeyed = 0; 00248 hmac->macType = (byte)type; 00249 00250 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC) 00251 if (hmac->asyncDev.marker == WOLFSSL_ASYNC_MARKER_HMAC) { 00252 #if defined(HAVE_CAVIUM) || defined(HAVE_INTEL_QA) 00253 if (length > HMAC_BLOCK_SIZE) { 00254 return WC_KEY_SIZE_E; 00255 } 00256 00257 if (key != NULL) { 00258 XMEMCPY(hmac->keyRaw, key, length); 00259 } 00260 hmac->keyLen = (word16)length; 00261 00262 return 0; /* nothing to do here */ 00263 #endif /* HAVE_CAVIUM || HAVE_INTEL_QA */ 00264 } 00265 #endif /* WOLFSSL_ASYNC_CRYPT */ 00266 00267 ret = _InitHmac(hmac, type, heap); 00268 if (ret != 0) 00269 return ret; 00270 00271 #ifdef HAVE_FIPS 00272 if (length < HMAC_FIPS_MIN_KEY) 00273 return HMAC_MIN_KEYLEN_E; 00274 #endif 00275 00276 ip = (byte*)hmac->ipad; 00277 op = (byte*)hmac->opad; 00278 00279 switch (hmac->macType) { 00280 #ifndef NO_MD5 00281 case MD5: 00282 hmac_block_size = MD5_BLOCK_SIZE; 00283 if (length <= MD5_BLOCK_SIZE) { 00284 if (key != NULL) { 00285 XMEMCPY(ip, key, length); 00286 } 00287 } 00288 else { 00289 ret = wc_Md5Update(&hmac->hash.md5, key, length); 00290 if (ret != 0) 00291 break; 00292 ret = wc_Md5Final(&hmac->hash.md5, ip); 00293 if (ret != 0) 00294 break; 00295 length = MD5_DIGEST_SIZE; 00296 } 00297 break; 00298 #endif /* !NO_MD5 */ 00299 00300 #ifndef NO_SHA 00301 case SHA: 00302 hmac_block_size = SHA_BLOCK_SIZE; 00303 if (length <= SHA_BLOCK_SIZE) { 00304 if (key != NULL) { 00305 XMEMCPY(ip, key, length); 00306 } 00307 } 00308 else { 00309 ret = wc_ShaUpdate(&hmac->hash.sha, key, length); 00310 if (ret != 0) 00311 break; 00312 ret = wc_ShaFinal(&hmac->hash.sha, ip); 00313 if (ret != 0) 00314 break; 00315 00316 length = SHA_DIGEST_SIZE; 00317 } 00318 break; 00319 #endif /* !NO_SHA */ 00320 00321 #ifdef WOLFSSL_SHA224 00322 case SHA224: 00323 { 00324 hmac_block_size = SHA224_BLOCK_SIZE; 00325 if (length <= SHA224_BLOCK_SIZE) { 00326 if (key != NULL) { 00327 XMEMCPY(ip, key, length); 00328 } 00329 } 00330 else { 00331 ret = wc_Sha224Update(&hmac->hash.sha224, key, length); 00332 if (ret != 0) 00333 break; 00334 ret = wc_Sha224Final(&hmac->hash.sha224, ip); 00335 if (ret != 0) 00336 break; 00337 00338 length = SHA224_DIGEST_SIZE; 00339 } 00340 } 00341 break; 00342 #endif /* WOLFSSL_SHA224 */ 00343 00344 #ifndef NO_SHA256 00345 case SHA256: 00346 hmac_block_size = SHA256_BLOCK_SIZE; 00347 if (length <= SHA256_BLOCK_SIZE) { 00348 if (key != NULL) { 00349 XMEMCPY(ip, key, length); 00350 } 00351 } 00352 else { 00353 ret = wc_Sha256Update(&hmac->hash.sha256, key, length); 00354 if (ret != 0) 00355 break; 00356 ret = wc_Sha256Final(&hmac->hash.sha256, ip); 00357 if (ret != 0) 00358 break; 00359 00360 length = SHA256_DIGEST_SIZE; 00361 } 00362 break; 00363 #endif /* !NO_SHA256 */ 00364 00365 #ifdef WOLFSSL_SHA512 00366 #ifdef WOLFSSL_SHA384 00367 case SHA384: 00368 hmac_block_size = SHA384_BLOCK_SIZE; 00369 if (length <= SHA384_BLOCK_SIZE) { 00370 if (key != NULL) { 00371 XMEMCPY(ip, key, length); 00372 } 00373 } 00374 else { 00375 ret = wc_Sha384Update(&hmac->hash.sha384, key, length); 00376 if (ret != 0) 00377 break; 00378 ret = wc_Sha384Final(&hmac->hash.sha384, ip); 00379 if (ret != 0) 00380 break; 00381 00382 length = SHA384_DIGEST_SIZE; 00383 } 00384 break; 00385 #endif /* WOLFSSL_SHA384 */ 00386 case SHA512: 00387 hmac_block_size = SHA512_BLOCK_SIZE; 00388 if (length <= SHA512_BLOCK_SIZE) { 00389 if (key != NULL) { 00390 XMEMCPY(ip, key, length); 00391 } 00392 } 00393 else { 00394 ret = wc_Sha512Update(&hmac->hash.sha512, key, length); 00395 if (ret != 0) 00396 break; 00397 ret = wc_Sha512Final(&hmac->hash.sha512, ip); 00398 if (ret != 0) 00399 break; 00400 00401 length = SHA512_DIGEST_SIZE; 00402 } 00403 break; 00404 #endif /* WOLFSSL_SHA512 */ 00405 00406 #ifdef HAVE_BLAKE2 00407 case BLAKE2B_ID: 00408 hmac_block_size = BLAKE2B_BLOCKBYTES; 00409 if (length <= BLAKE2B_BLOCKBYTES) { 00410 if (key != NULL) { 00411 XMEMCPY(ip, key, length); 00412 } 00413 } 00414 else { 00415 ret = wc_Blake2bUpdate(&hmac->hash.blake2b, key, length); 00416 if (ret != 0) 00417 break; 00418 ret = wc_Blake2bFinal(&hmac->hash.blake2b, ip, BLAKE2B_256); 00419 if (ret != 0) 00420 break; 00421 00422 length = BLAKE2B_256; 00423 } 00424 break; 00425 #endif /* HAVE_BLAKE2 */ 00426 00427 default: 00428 return BAD_FUNC_ARG; 00429 } 00430 00431 if (ret == 0) { 00432 if (length < hmac_block_size) 00433 XMEMSET(ip + length, 0, hmac_block_size - length); 00434 00435 for(i = 0; i < hmac_block_size; i++) { 00436 op[i] = ip[i] ^ OPAD; 00437 ip[i] ^= IPAD; 00438 } 00439 } 00440 00441 return ret; 00442 } 00443 00444 00445 static int HmacKeyInnerHash(Hmac* hmac) 00446 { 00447 int ret = 0; 00448 00449 switch (hmac->macType) { 00450 #ifndef NO_MD5 00451 case MD5: 00452 ret = wc_Md5Update(&hmac->hash.md5, (byte*)hmac->ipad, 00453 MD5_BLOCK_SIZE); 00454 break; 00455 #endif /* !NO_MD5 */ 00456 00457 #ifndef NO_SHA 00458 case SHA: 00459 ret = wc_ShaUpdate(&hmac->hash.sha, (byte*)hmac->ipad, 00460 SHA_BLOCK_SIZE); 00461 break; 00462 #endif /* !NO_SHA */ 00463 00464 #ifdef WOLFSSL_SHA224 00465 case SHA224: 00466 ret = wc_Sha224Update(&hmac->hash.sha224, (byte*)hmac->ipad, 00467 SHA224_BLOCK_SIZE); 00468 break; 00469 #endif /* WOLFSSL_SHA224 */ 00470 00471 #ifndef NO_SHA256 00472 case SHA256: 00473 ret = wc_Sha256Update(&hmac->hash.sha256, (byte*)hmac->ipad, 00474 SHA256_BLOCK_SIZE); 00475 break; 00476 #endif /* !NO_SHA256 */ 00477 00478 #ifdef WOLFSSL_SHA512 00479 #ifdef WOLFSSL_SHA384 00480 case SHA384: 00481 ret = wc_Sha384Update(&hmac->hash.sha384, (byte*)hmac->ipad, 00482 SHA384_BLOCK_SIZE); 00483 break; 00484 #endif /* WOLFSSL_SHA384 */ 00485 case SHA512: 00486 ret = wc_Sha512Update(&hmac->hash.sha512, (byte*)hmac->ipad, 00487 SHA512_BLOCK_SIZE); 00488 break; 00489 #endif /* WOLFSSL_SHA512 */ 00490 00491 #ifdef HAVE_BLAKE2 00492 case BLAKE2B_ID: 00493 ret = wc_Blake2bUpdate(&hmac->hash.blake2b, (byte*)hmac->ipad, 00494 BLAKE2B_BLOCKBYTES); 00495 break; 00496 #endif /* HAVE_BLAKE2 */ 00497 00498 default: 00499 break; 00500 } 00501 00502 if (ret == 0) 00503 hmac->innerHashKeyed = 1; 00504 00505 return ret; 00506 } 00507 00508 00509 int wc_HmacUpdate(Hmac* hmac, const byte* msg, word32 length) 00510 { 00511 int ret = 0; 00512 00513 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC) 00514 if (hmac->asyncDev.marker == WOLFSSL_ASYNC_MARKER_HMAC) { 00515 #if defined(HAVE_CAVIUM) 00516 return NitroxHmacUpdate(hmac, msg, length); 00517 #elif defined(HAVE_INTEL_QA) 00518 return IntelQaHmac(&hmac->asyncDev, hmac->macType, 00519 hmac->keyRaw, hmac->keyLen, NULL, msg, length); 00520 #endif 00521 } 00522 #endif /* WOLFSSL_ASYNC_CRYPT */ 00523 00524 if (!hmac->innerHashKeyed) { 00525 ret = HmacKeyInnerHash(hmac); 00526 if (ret != 0) 00527 return ret; 00528 } 00529 00530 switch (hmac->macType) { 00531 #ifndef NO_MD5 00532 case MD5: 00533 ret = wc_Md5Update(&hmac->hash.md5, msg, length); 00534 break; 00535 #endif /* !NO_MD5 */ 00536 00537 #ifndef NO_SHA 00538 case SHA: 00539 ret = wc_ShaUpdate(&hmac->hash.sha, msg, length); 00540 break; 00541 #endif /* !NO_SHA */ 00542 00543 #ifdef WOLFSSL_SHA224 00544 case SHA224: 00545 ret = wc_Sha224Update(&hmac->hash.sha224, msg, length); 00546 break; 00547 #endif /* WOLFSSL_SHA224 */ 00548 00549 #ifndef NO_SHA256 00550 case SHA256: 00551 ret = wc_Sha256Update(&hmac->hash.sha256, msg, length); 00552 break; 00553 #endif /* !NO_SHA256 */ 00554 00555 #ifdef WOLFSSL_SHA512 00556 #ifdef WOLFSSL_SHA384 00557 case SHA384: 00558 ret = wc_Sha384Update(&hmac->hash.sha384, msg, length); 00559 break; 00560 #endif /* WOLFSSL_SHA384 */ 00561 case SHA512: 00562 ret = wc_Sha512Update(&hmac->hash.sha512, msg, length); 00563 break; 00564 #endif /* WOLFSSL_SHA512 */ 00565 00566 #ifdef HAVE_BLAKE2 00567 case BLAKE2B_ID: 00568 ret = wc_Blake2bUpdate(&hmac->hash.blake2b, msg, length); 00569 break; 00570 #endif /* HAVE_BLAKE2 */ 00571 00572 default: 00573 break; 00574 } 00575 00576 return ret; 00577 } 00578 00579 00580 int wc_HmacFinal(Hmac* hmac, byte* hash) 00581 { 00582 int ret; 00583 00584 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC) 00585 if (hmac->asyncDev.marker == WOLFSSL_ASYNC_MARKER_HMAC) { 00586 int hashLen = wc_HmacSizeByType(hmac->macType); 00587 if (hashLen <= 0) 00588 return hashLen; 00589 00590 #if defined(HAVE_CAVIUM) 00591 return NitroxHmacFinal(hmac, hmac->macType, hash, hashLen); 00592 #elif defined(HAVE_INTEL_QA) 00593 return IntelQaHmac(&hmac->asyncDev, hmac->macType, 00594 hmac->keyRaw, hmac->keyLen, hash, NULL, hashLen); 00595 #endif 00596 } 00597 #endif /* WOLFSSL_ASYNC_CRYPT */ 00598 00599 if (!hmac->innerHashKeyed) { 00600 ret = HmacKeyInnerHash(hmac); 00601 if (ret != 0) 00602 return ret; 00603 } 00604 00605 switch (hmac->macType) { 00606 #ifndef NO_MD5 00607 case MD5: 00608 ret = wc_Md5Final(&hmac->hash.md5, (byte*)hmac->innerHash); 00609 if (ret != 0) 00610 break; 00611 ret = wc_Md5Update(&hmac->hash.md5, (byte*)hmac->opad, 00612 MD5_BLOCK_SIZE); 00613 if (ret != 0) 00614 break; 00615 ret = wc_Md5Update(&hmac->hash.md5, (byte*)hmac->innerHash, 00616 MD5_DIGEST_SIZE); 00617 if (ret != 0) 00618 break; 00619 ret = wc_Md5Final(&hmac->hash.md5, hash); 00620 break; 00621 #endif /* !NO_MD5 */ 00622 00623 #ifndef NO_SHA 00624 case SHA: 00625 ret = wc_ShaFinal(&hmac->hash.sha, (byte*)hmac->innerHash); 00626 if (ret != 0) 00627 break; 00628 ret = wc_ShaUpdate(&hmac->hash.sha, (byte*)hmac->opad, 00629 SHA_BLOCK_SIZE); 00630 if (ret != 0) 00631 break; 00632 ret = wc_ShaUpdate(&hmac->hash.sha, (byte*)hmac->innerHash, 00633 SHA_DIGEST_SIZE); 00634 if (ret != 0) 00635 break; 00636 ret = wc_ShaFinal(&hmac->hash.sha, hash); 00637 break; 00638 #endif /* !NO_SHA */ 00639 00640 #ifdef WOLFSSL_SHA224 00641 case SHA224: 00642 { 00643 ret = wc_Sha224Final(&hmac->hash.sha224, (byte*)hmac->innerHash); 00644 if (ret != 0) 00645 break; 00646 ret = wc_Sha224Update(&hmac->hash.sha224, (byte*)hmac->opad, 00647 SHA224_BLOCK_SIZE); 00648 if (ret != 0) 00649 break; 00650 ret = wc_Sha224Update(&hmac->hash.sha224, (byte*)hmac->innerHash, 00651 SHA224_DIGEST_SIZE); 00652 if (ret != 0) 00653 break; 00654 ret = wc_Sha224Final(&hmac->hash.sha224, hash); 00655 if (ret != 0) 00656 break; 00657 } 00658 break; 00659 #endif /* WOLFSSL_SHA224 */ 00660 00661 #ifndef NO_SHA256 00662 case SHA256: 00663 ret = wc_Sha256Final(&hmac->hash.sha256, (byte*)hmac->innerHash); 00664 if (ret != 0) 00665 break; 00666 ret = wc_Sha256Update(&hmac->hash.sha256, (byte*)hmac->opad, 00667 SHA256_BLOCK_SIZE); 00668 if (ret != 0) 00669 break; 00670 ret = wc_Sha256Update(&hmac->hash.sha256, (byte*)hmac->innerHash, 00671 SHA256_DIGEST_SIZE); 00672 if (ret != 0) 00673 break; 00674 ret = wc_Sha256Final(&hmac->hash.sha256, hash); 00675 break; 00676 #endif /* !NO_SHA256 */ 00677 00678 #ifdef WOLFSSL_SHA512 00679 #ifdef WOLFSSL_SHA384 00680 case SHA384: 00681 ret = wc_Sha384Final(&hmac->hash.sha384, (byte*)hmac->innerHash); 00682 if (ret != 0) 00683 break; 00684 ret = wc_Sha384Update(&hmac->hash.sha384, (byte*)hmac->opad, 00685 SHA384_BLOCK_SIZE); 00686 if (ret != 0) 00687 break; 00688 ret = wc_Sha384Update(&hmac->hash.sha384, (byte*)hmac->innerHash, 00689 SHA384_DIGEST_SIZE); 00690 if (ret != 0) 00691 break; 00692 ret = wc_Sha384Final(&hmac->hash.sha384, hash); 00693 break; 00694 #endif /* WOLFSSL_SHA384 */ 00695 case SHA512: 00696 ret = wc_Sha512Final(&hmac->hash.sha512, (byte*)hmac->innerHash); 00697 if (ret != 0) 00698 break; 00699 ret = wc_Sha512Update(&hmac->hash.sha512, (byte*)hmac->opad, 00700 SHA512_BLOCK_SIZE); 00701 if (ret != 0) 00702 break; 00703 ret = wc_Sha512Update(&hmac->hash.sha512, (byte*)hmac->innerHash, 00704 SHA512_DIGEST_SIZE); 00705 if (ret != 0) 00706 break; 00707 ret = wc_Sha512Final(&hmac->hash.sha512, hash); 00708 break; 00709 #endif /* WOLFSSL_SHA512 */ 00710 00711 #ifdef HAVE_BLAKE2 00712 case BLAKE2B_ID: 00713 ret = wc_Blake2bFinal(&hmac->hash.blake2b, (byte*)hmac->innerHash, 00714 BLAKE2B_256); 00715 if (ret != 0) 00716 break; 00717 ret = wc_Blake2bUpdate(&hmac->hash.blake2b, (byte*)hmac->opad, 00718 BLAKE2B_BLOCKBYTES); 00719 if (ret != 0) 00720 break; 00721 ret = wc_Blake2bUpdate(&hmac->hash.blake2b, (byte*)hmac->innerHash, 00722 BLAKE2B_256); 00723 if (ret != 0) 00724 break; 00725 ret = wc_Blake2bFinal(&hmac->hash.blake2b, hash, BLAKE2B_256); 00726 break; 00727 #endif /* HAVE_BLAKE2 */ 00728 00729 default: 00730 ret = BAD_FUNC_ARG; 00731 break; 00732 } 00733 00734 if (ret == 0) { 00735 hmac->innerHashKeyed = 0; 00736 } 00737 00738 return ret; 00739 } 00740 00741 00742 /* Initialize Hmac for use with async device */ 00743 int wc_HmacInit(Hmac* hmac, void* heap, int devId) 00744 { 00745 int ret = 0; 00746 00747 if (hmac == NULL) 00748 return BAD_FUNC_ARG; 00749 00750 XMEMSET(hmac, 0, sizeof(Hmac)); 00751 hmac->heap = heap; 00752 00753 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC) 00754 hmac->keyLen = 0; 00755 #ifdef HAVE_CAVIUM 00756 hmac->dataLen = 0; 00757 hmac->data = NULL; /* buffered input data */ 00758 #endif /* HAVE_CAVIUM */ 00759 00760 ret = wolfAsync_DevCtxInit(&hmac->asyncDev, WOLFSSL_ASYNC_MARKER_HMAC, 00761 hmac->heap, devId); 00762 #else 00763 (void)devId; 00764 #endif /* WOLFSSL_ASYNC_CRYPT */ 00765 00766 return ret; 00767 } 00768 00769 /* Free Hmac from use with async device */ 00770 void wc_HmacFree(Hmac* hmac) 00771 { 00772 if (hmac == NULL) 00773 return; 00774 00775 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC) 00776 wolfAsync_DevCtxFree(&hmac->asyncDev, WOLFSSL_ASYNC_MARKER_HMAC); 00777 00778 #ifdef HAVE_CAVIUM 00779 XFREE(hmac->data, hmac->heap, DYNAMIC_TYPE_HMAC); 00780 hmac->data = NULL; 00781 #endif /* HAVE_CAVIUM */ 00782 #endif /* WOLFSSL_ASYNC_CRYPT */ 00783 } 00784 00785 int wolfSSL_GetHmacMaxSize(void) 00786 { 00787 return MAX_DIGEST_SIZE; 00788 } 00789 00790 #ifdef HAVE_HKDF 00791 /* HMAC-KDF-Extract. 00792 * RFC 5869 - HMAC-based Extract-and-Expand Key Derivation Function (HKDF). 00793 * 00794 * type The hash algorithm type. 00795 * salt The optional salt value. 00796 * saltSz The size of the salt. 00797 * inKey The input keying material. 00798 * inKeySz The size of the input keying material. 00799 * out The pseudorandom key with the length that of the hash. 00800 * returns 0 on success, otherwise failure. 00801 */ 00802 int wc_HKDF_Extract(int type, const byte* salt, word32 saltSz, 00803 const byte* inKey, word32 inKeySz, byte* out) 00804 { 00805 byte tmp[MAX_DIGEST_SIZE]; /* localSalt helper */ 00806 Hmac myHmac; 00807 int ret; 00808 const byte* localSalt; /* either points to user input or tmp */ 00809 int hashSz = wc_HmacSizeByType(type); 00810 00811 localSalt = salt; 00812 if (localSalt == NULL) { 00813 XMEMSET(tmp, 0, hashSz); 00814 localSalt = tmp; 00815 saltSz = hashSz; 00816 } 00817 00818 ret = wc_HmacSetKey(&myHmac, type, localSalt, saltSz); 00819 if (ret == 0) 00820 ret = wc_HmacUpdate(&myHmac, inKey, inKeySz); 00821 if (ret == 0) 00822 ret = wc_HmacFinal(&myHmac, out); 00823 00824 return ret; 00825 } 00826 00827 /* HMAC-KDF-Expand. 00828 * RFC 5869 - HMAC-based Extract-and-Expand Key Derivation Function (HKDF). 00829 * 00830 * type The hash algorithm type. 00831 * inKey The input key. 00832 * inKeySz The size of the input key. 00833 * info The application specific information. 00834 * infoSz The size of the application specific information. 00835 * out The output keying material. 00836 * returns 0 on success, otherwise failure. 00837 */ 00838 int wc_HKDF_Expand(int type, const byte* inKey, word32 inKeySz, 00839 const byte* info, word32 infoSz, byte* out, word32 outSz) 00840 { 00841 byte tmp[MAX_DIGEST_SIZE]; 00842 Hmac myHmac; 00843 int ret = 0; 00844 word32 outIdx = 0; 00845 word32 hashSz = wc_HmacSizeByType(type); 00846 byte n = 0x1; 00847 00848 while (outIdx < outSz) { 00849 int tmpSz = (n == 1) ? 0 : hashSz; 00850 word32 left = outSz - outIdx; 00851 00852 ret = wc_HmacSetKey(&myHmac, type, inKey, inKeySz); 00853 if (ret != 0) 00854 break; 00855 ret = wc_HmacUpdate(&myHmac, tmp, tmpSz); 00856 if (ret != 0) 00857 break; 00858 ret = wc_HmacUpdate(&myHmac, info, infoSz); 00859 if (ret != 0) 00860 break; 00861 ret = wc_HmacUpdate(&myHmac, &n, 1); 00862 if (ret != 0) 00863 break; 00864 ret = wc_HmacFinal(&myHmac, tmp); 00865 if (ret != 0) 00866 break; 00867 00868 left = min(left, hashSz); 00869 XMEMCPY(out+outIdx, tmp, left); 00870 00871 outIdx += hashSz; 00872 n++; 00873 } 00874 00875 return ret; 00876 } 00877 00878 /* HMAC-KDF. 00879 * RFC 5869 - HMAC-based Extract-and-Expand Key Derivation Function (HKDF). 00880 * 00881 * type The hash algorithm type. 00882 * inKey The input keying material. 00883 * inKeySz The size of the input keying material. 00884 * salt The optional salt value. 00885 * saltSz The size of the salt. 00886 * info The application specific information. 00887 * infoSz The size of the application specific information. 00888 * out The output keying material. 00889 * returns 0 on success, otherwise failure. 00890 */ 00891 int wc_HKDF(int type, const byte* inKey, word32 inKeySz, 00892 const byte* salt, word32 saltSz, 00893 const byte* info, word32 infoSz, 00894 byte* out, word32 outSz) 00895 { 00896 byte prk[MAX_DIGEST_SIZE]; 00897 int hashSz = wc_HmacSizeByType(type); 00898 int ret; 00899 00900 if (hashSz < 0) 00901 return BAD_FUNC_ARG; 00902 00903 ret = wc_HKDF_Extract(type, salt, saltSz, inKey, inKeySz, prk); 00904 if (ret != 0) 00905 return ret; 00906 00907 return wc_HKDF_Expand(type, prk, hashSz, info, infoSz, out, outSz); 00908 } 00909 00910 #endif /* HAVE_HKDF */ 00911 00912 #endif /* HAVE_FIPS */ 00913 #endif /* NO_HMAC */ 00914
Generated on Tue Jul 12 2022 23:30:55 by
1.7.2
