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.
hmac.c
00001 /* hmac.c 00002 * 00003 * Copyright (C) 2006-2017 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 <wolfcrypt/settings.h> 00028 #include <wolfcrypt/error-crypt.h> 00029 00030 #ifndef NO_HMAC 00031 00032 #if defined(HAVE_FIPS) && \ 00033 defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2) 00034 00035 /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */ 00036 #define FIPS_NO_WRAPPERS 00037 00038 #ifdef USE_WINDOWS_API 00039 #pragma code_seg(".fipsA$b") 00040 #pragma const_seg(".fipsB$b") 00041 #endif 00042 #endif 00043 00044 #include <wolfcrypt/hmac.h> 00045 00046 #ifdef NO_INLINE 00047 #include <wolfcrypt/misc.h> 00048 #else 00049 #define WOLFSSL_MISC_INCLUDED 00050 #include <wolfcrypt/src/misc.c> 00051 #endif 00052 00053 00054 /* fips wrapper calls, user can call direct */ 00055 /* If building for old FIPS. */ 00056 #if defined(HAVE_FIPS) && \ 00057 (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2)) 00058 00059 /* does init */ 00060 int wc_HmacSetKey(Hmac* hmac, int type, const byte* key, word32 keySz) 00061 { 00062 if (hmac == NULL || (key == NULL && keySz != 0) || 00063 !(type == WC_MD5 || type == WC_SHA || type == WC_SHA256 || 00064 type == WC_SHA384 || type == WC_SHA512 || 00065 type == BLAKE2B_ID)) { 00066 return BAD_FUNC_ARG; 00067 } 00068 00069 return HmacSetKey_fips(hmac, type, key, keySz); 00070 } 00071 int wc_HmacUpdate(Hmac* hmac, const byte* in, word32 sz) 00072 { 00073 if (hmac == NULL || (in == NULL && sz > 0)) { 00074 return BAD_FUNC_ARG; 00075 } 00076 00077 return HmacUpdate_fips(hmac, in, sz); 00078 } 00079 int wc_HmacFinal(Hmac* hmac, byte* out) 00080 { 00081 if (hmac == NULL) { 00082 return BAD_FUNC_ARG; 00083 } 00084 00085 return HmacFinal_fips(hmac, out); 00086 } 00087 int wolfSSL_GetHmacMaxSize(void) 00088 { 00089 return CyaSSL_GetHmacMaxSize(); 00090 } 00091 00092 int wc_HmacInit(Hmac* hmac, void* heap, int devId) 00093 { 00094 (void)hmac; 00095 (void)heap; 00096 (void)devId; 00097 /* FIPS doesn't support: 00098 return HmacInit(hmac, heap, devId); */ 00099 return 0; 00100 } 00101 void wc_HmacFree(Hmac* hmac) 00102 { 00103 (void)hmac; 00104 /* FIPS doesn't support: 00105 HmacFree(hmac); */ 00106 } 00107 00108 #ifdef HAVE_HKDF 00109 int wc_HKDF(int type, const byte* inKey, word32 inKeySz, 00110 const byte* salt, word32 saltSz, 00111 const byte* info, word32 infoSz, 00112 byte* out, word32 outSz) 00113 { 00114 return HKDF(type, inKey, inKeySz, salt, saltSz, 00115 info, infoSz, out, outSz); 00116 } 00117 #endif /* HAVE_HKDF */ 00118 00119 #else /* else build without fips, or for new fips */ 00120 00121 00122 int wc_HmacSizeByType(int type) 00123 { 00124 int ret; 00125 00126 if (!(type == WC_MD5 || type == WC_SHA || 00127 type == WC_SHA224 || type == WC_SHA256 || 00128 type == WC_SHA384 || type == WC_SHA512 || 00129 type == WC_SHA3_224 || type == WC_SHA3_256 || 00130 type == WC_SHA3_384 || type == WC_SHA3_512 || 00131 type == BLAKE2B_ID)) { 00132 return BAD_FUNC_ARG; 00133 } 00134 00135 switch (type) { 00136 #ifndef NO_MD5 00137 case WC_MD5: 00138 ret = WC_MD5_DIGEST_SIZE; 00139 break; 00140 #endif /* !NO_MD5 */ 00141 00142 #ifndef NO_SHA 00143 case WC_SHA: 00144 ret = WC_SHA_DIGEST_SIZE; 00145 break; 00146 #endif /* !NO_SHA */ 00147 00148 #ifdef WOLFSSL_SHA224 00149 case WC_SHA224: 00150 ret = WC_SHA224_DIGEST_SIZE; 00151 break; 00152 #endif /* WOLFSSL_SHA224 */ 00153 00154 #ifndef NO_SHA256 00155 case WC_SHA256: 00156 ret = WC_SHA256_DIGEST_SIZE; 00157 break; 00158 #endif /* !NO_SHA256 */ 00159 00160 #ifdef WOLFSSL_SHA384 00161 case WC_SHA384: 00162 ret = WC_SHA384_DIGEST_SIZE; 00163 break; 00164 #endif /* WOLFSSL_SHA384 */ 00165 #ifdef WOLFSSL_SHA512 00166 case WC_SHA512: 00167 ret = WC_SHA512_DIGEST_SIZE; 00168 break; 00169 #endif /* WOLFSSL_SHA512 */ 00170 00171 #ifdef HAVE_BLAKE2 00172 case BLAKE2B_ID: 00173 ret = BLAKE2B_OUTBYTES; 00174 break; 00175 #endif /* HAVE_BLAKE2 */ 00176 00177 #ifdef WOLFSSL_SHA3 00178 case WC_SHA3_224: 00179 ret = WC_SHA3_224_DIGEST_SIZE; 00180 break; 00181 00182 case WC_SHA3_256: 00183 ret = WC_SHA3_256_DIGEST_SIZE; 00184 break; 00185 00186 case WC_SHA3_384: 00187 ret = WC_SHA3_384_DIGEST_SIZE; 00188 break; 00189 00190 case WC_SHA3_512: 00191 ret = WC_SHA3_512_DIGEST_SIZE; 00192 break; 00193 00194 #endif 00195 00196 default: 00197 ret = BAD_FUNC_ARG; 00198 break; 00199 } 00200 00201 return ret; 00202 } 00203 00204 int _InitHmac(Hmac* hmac, int type, void* heap) 00205 { 00206 int ret = 0; 00207 00208 switch (type) { 00209 #ifndef NO_MD5 00210 case WC_MD5: 00211 ret = wc_InitMd5(&hmac->hash.md5); 00212 break; 00213 #endif /* !NO_MD5 */ 00214 00215 #ifndef NO_SHA 00216 case WC_SHA: 00217 ret = wc_InitSha(&hmac->hash.sha); 00218 break; 00219 #endif /* !NO_SHA */ 00220 00221 #ifdef WOLFSSL_SHA224 00222 case WC_SHA224: 00223 ret = wc_InitSha224(&hmac->hash.sha224); 00224 break; 00225 #endif /* WOLFSSL_SHA224 */ 00226 00227 #ifndef NO_SHA256 00228 case WC_SHA256: 00229 ret = wc_InitSha256(&hmac->hash.sha256); 00230 break; 00231 #endif /* !NO_SHA256 */ 00232 00233 #ifdef WOLFSSL_SHA384 00234 case WC_SHA384: 00235 ret = wc_InitSha384(&hmac->hash.sha384); 00236 break; 00237 #endif /* WOLFSSL_SHA384 */ 00238 #ifdef WOLFSSL_SHA512 00239 case WC_SHA512: 00240 ret = wc_InitSha512(&hmac->hash.sha512); 00241 break; 00242 #endif /* WOLFSSL_SHA512 */ 00243 00244 #ifdef HAVE_BLAKE2 00245 case BLAKE2B_ID: 00246 ret = wc_InitBlake2b(&hmac->hash.blake2b, BLAKE2B_256); 00247 break; 00248 #endif /* HAVE_BLAKE2 */ 00249 00250 #ifdef WOLFSSL_SHA3 00251 case WC_SHA3_224: 00252 ret = wc_InitSha3_224(&hmac->hash.sha3, heap, INVALID_DEVID); 00253 break; 00254 case WC_SHA3_256: 00255 ret = wc_InitSha3_256(&hmac->hash.sha3, heap, INVALID_DEVID); 00256 break; 00257 case WC_SHA3_384: 00258 ret = wc_InitSha3_384(&hmac->hash.sha3, heap, INVALID_DEVID); 00259 break; 00260 case WC_SHA3_512: 00261 ret = wc_InitSha3_512(&hmac->hash.sha3, heap, INVALID_DEVID); 00262 break; 00263 #endif 00264 00265 default: 00266 ret = BAD_FUNC_ARG; 00267 break; 00268 } 00269 00270 /* default to NULL heap hint or test value */ 00271 #ifdef WOLFSSL_HEAP_TEST 00272 hmac->heap = (void)WOLFSSL_HEAP_TEST; 00273 #else 00274 hmac->heap = heap; 00275 #endif /* WOLFSSL_HEAP_TEST */ 00276 00277 return ret; 00278 } 00279 00280 00281 int wc_HmacSetKey(Hmac* hmac, int type, const byte* key, word32 length) 00282 { 00283 byte* ip; 00284 byte* op; 00285 word32 i, hmac_block_size = 0; 00286 int ret = 0; 00287 void* heap = NULL; 00288 00289 if (hmac == NULL || (key == NULL && length != 0) || 00290 !(type == WC_MD5 || type == WC_SHA || 00291 type == WC_SHA224 || type == WC_SHA256 || 00292 type == WC_SHA384 || type == WC_SHA512 || 00293 type == WC_SHA3_224 || type == WC_SHA3_256 || 00294 type == WC_SHA3_384 || type == WC_SHA3_512 || 00295 type == BLAKE2B_ID)) { 00296 return BAD_FUNC_ARG; 00297 } 00298 00299 hmac->innerHashKeyed = 0; 00300 hmac->macType = (byte)type; 00301 00302 ret = _InitHmac(hmac, type, heap); 00303 if (ret != 0) 00304 return ret; 00305 00306 #ifdef HAVE_FIPS 00307 if (length < HMAC_FIPS_MIN_KEY) 00308 return HMAC_MIN_KEYLEN_E; 00309 #endif 00310 00311 ip = (byte*)hmac->ipad; 00312 op = (byte*)hmac->opad; 00313 00314 switch (hmac->macType) { 00315 #ifndef NO_MD5 00316 case WC_MD5: 00317 hmac_block_size = WC_MD5_BLOCK_SIZE; 00318 if (length <= WC_MD5_BLOCK_SIZE) { 00319 if (key != NULL) { 00320 XMEMCPY(ip, key, length); 00321 } 00322 } 00323 else { 00324 ret = wc_Md5Update(&hmac->hash.md5, key, length); 00325 if (ret != 0) 00326 break; 00327 ret = wc_Md5Final(&hmac->hash.md5, ip); 00328 if (ret != 0) 00329 break; 00330 length = WC_MD5_DIGEST_SIZE; 00331 } 00332 break; 00333 #endif /* !NO_MD5 */ 00334 00335 #ifndef NO_SHA 00336 case WC_SHA: 00337 hmac_block_size = WC_SHA_BLOCK_SIZE; 00338 if (length <= WC_SHA_BLOCK_SIZE) { 00339 if (key != NULL) { 00340 XMEMCPY(ip, key, length); 00341 } 00342 } 00343 else { 00344 ret = wc_ShaUpdate(&hmac->hash.sha, key, length); 00345 if (ret != 0) 00346 break; 00347 ret = wc_ShaFinal(&hmac->hash.sha, ip); 00348 if (ret != 0) 00349 break; 00350 00351 length = WC_SHA_DIGEST_SIZE; 00352 } 00353 break; 00354 #endif /* !NO_SHA */ 00355 00356 #ifdef WOLFSSL_SHA224 00357 case WC_SHA224: 00358 { 00359 hmac_block_size = WC_SHA224_BLOCK_SIZE; 00360 if (length <= WC_SHA224_BLOCK_SIZE) { 00361 if (key != NULL) { 00362 XMEMCPY(ip, key, length); 00363 } 00364 } 00365 else { 00366 ret = wc_Sha224Update(&hmac->hash.sha224, key, length); 00367 if (ret != 0) 00368 break; 00369 ret = wc_Sha224Final(&hmac->hash.sha224, ip); 00370 if (ret != 0) 00371 break; 00372 00373 length = WC_SHA224_DIGEST_SIZE; 00374 } 00375 } 00376 break; 00377 #endif /* WOLFSSL_SHA224 */ 00378 00379 #ifndef NO_SHA256 00380 case WC_SHA256: 00381 hmac_block_size = WC_SHA256_BLOCK_SIZE; 00382 if (length <= WC_SHA256_BLOCK_SIZE) { 00383 if (key != NULL) { 00384 XMEMCPY(ip, key, length); 00385 } 00386 } 00387 else { 00388 ret = wc_Sha256Update(&hmac->hash.sha256, key, length); 00389 if (ret != 0) 00390 break; 00391 ret = wc_Sha256Final(&hmac->hash.sha256, ip); 00392 if (ret != 0) 00393 break; 00394 00395 length = WC_SHA256_DIGEST_SIZE; 00396 } 00397 break; 00398 #endif /* !NO_SHA256 */ 00399 00400 #ifdef WOLFSSL_SHA384 00401 case WC_SHA384: 00402 hmac_block_size = WC_SHA384_BLOCK_SIZE; 00403 if (length <= WC_SHA384_BLOCK_SIZE) { 00404 if (key != NULL) { 00405 XMEMCPY(ip, key, length); 00406 } 00407 } 00408 else { 00409 ret = wc_Sha384Update(&hmac->hash.sha384, key, length); 00410 if (ret != 0) 00411 break; 00412 ret = wc_Sha384Final(&hmac->hash.sha384, ip); 00413 if (ret != 0) 00414 break; 00415 00416 length = WC_SHA384_DIGEST_SIZE; 00417 } 00418 break; 00419 #endif /* WOLFSSL_SHA384 */ 00420 #ifdef WOLFSSL_SHA512 00421 case WC_SHA512: 00422 hmac_block_size = WC_SHA512_BLOCK_SIZE; 00423 if (length <= WC_SHA512_BLOCK_SIZE) { 00424 if (key != NULL) { 00425 XMEMCPY(ip, key, length); 00426 } 00427 } 00428 else { 00429 ret = wc_Sha512Update(&hmac->hash.sha512, key, length); 00430 if (ret != 0) 00431 break; 00432 ret = wc_Sha512Final(&hmac->hash.sha512, ip); 00433 if (ret != 0) 00434 break; 00435 00436 length = WC_SHA512_DIGEST_SIZE; 00437 } 00438 break; 00439 #endif /* WOLFSSL_SHA512 */ 00440 00441 #ifdef HAVE_BLAKE2 00442 case BLAKE2B_ID: 00443 hmac_block_size = BLAKE2B_BLOCKBYTES; 00444 if (length <= BLAKE2B_BLOCKBYTES) { 00445 if (key != NULL) { 00446 XMEMCPY(ip, key, length); 00447 } 00448 } 00449 else { 00450 ret = wc_Blake2bUpdate(&hmac->hash.blake2b, key, length); 00451 if (ret != 0) 00452 break; 00453 ret = wc_Blake2bFinal(&hmac->hash.blake2b, ip, BLAKE2B_256); 00454 if (ret != 0) 00455 break; 00456 00457 length = BLAKE2B_256; 00458 } 00459 break; 00460 #endif /* HAVE_BLAKE2 */ 00461 00462 #ifdef WOLFSSL_SHA3 00463 case WC_SHA3_224: 00464 hmac_block_size = WC_SHA3_224_BLOCK_SIZE; 00465 if (length <= WC_SHA3_224_BLOCK_SIZE) { 00466 if (key != NULL) { 00467 XMEMCPY(ip, key, length); 00468 } 00469 } 00470 else { 00471 ret = wc_Sha3_224_Update(&hmac->hash.sha3, key, length); 00472 if (ret != 0) 00473 break; 00474 ret = wc_Sha3_224_Final(&hmac->hash.sha3, ip); 00475 if (ret != 0) 00476 break; 00477 00478 length = WC_SHA3_224_DIGEST_SIZE; 00479 } 00480 break; 00481 case WC_SHA3_256: 00482 hmac_block_size = WC_SHA3_256_BLOCK_SIZE; 00483 if (length <= WC_SHA3_256_BLOCK_SIZE) { 00484 if (key != NULL) { 00485 XMEMCPY(ip, key, length); 00486 } 00487 } 00488 else { 00489 ret = wc_Sha3_256_Update(&hmac->hash.sha3, key, length); 00490 if (ret != 0) 00491 break; 00492 ret = wc_Sha3_256_Final(&hmac->hash.sha3, ip); 00493 if (ret != 0) 00494 break; 00495 00496 length = WC_SHA3_256_DIGEST_SIZE; 00497 } 00498 break; 00499 case WC_SHA3_384: 00500 hmac_block_size = WC_SHA3_384_BLOCK_SIZE; 00501 if (length <= WC_SHA3_384_BLOCK_SIZE) { 00502 if (key != NULL) { 00503 XMEMCPY(ip, key, length); 00504 } 00505 } 00506 else { 00507 ret = wc_Sha3_384_Update(&hmac->hash.sha3, key, length); 00508 if (ret != 0) 00509 break; 00510 ret = wc_Sha3_384_Final(&hmac->hash.sha3, ip); 00511 if (ret != 0) 00512 break; 00513 00514 length = WC_SHA3_384_DIGEST_SIZE; 00515 } 00516 break; 00517 case WC_SHA3_512: 00518 hmac_block_size = WC_SHA3_512_BLOCK_SIZE; 00519 if (length <= WC_SHA3_512_BLOCK_SIZE) { 00520 if (key != NULL) { 00521 XMEMCPY(ip, key, length); 00522 } 00523 } 00524 else { 00525 ret = wc_Sha3_512_Update(&hmac->hash.sha3, key, length); 00526 if (ret != 0) 00527 break; 00528 ret = wc_Sha3_512_Final(&hmac->hash.sha3, ip); 00529 if (ret != 0) 00530 break; 00531 00532 length = WC_SHA3_512_DIGEST_SIZE; 00533 } 00534 break; 00535 #endif /* WOLFSSL_SHA3 */ 00536 00537 default: 00538 return BAD_FUNC_ARG; 00539 } 00540 00541 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC) 00542 if (hmac->asyncDev.marker == WOLFSSL_ASYNC_MARKER_HMAC) { 00543 #if defined(HAVE_INTEL_QA) || defined(HAVE_CAVIUM) 00544 #ifdef HAVE_INTEL_QA 00545 if (IntelQaHmacGetType(hmac->macType, NULL) == 0) 00546 #endif 00547 { 00548 if (length > hmac_block_size) 00549 length = hmac_block_size; 00550 /* update key length */ 00551 hmac->keyLen = (word16)length; 00552 00553 return ret; 00554 } 00555 /* no need to pad below */ 00556 #endif 00557 } 00558 #endif 00559 00560 if (ret == 0) { 00561 if (length < hmac_block_size) 00562 XMEMSET(ip + length, 0, hmac_block_size - length); 00563 00564 for(i = 0; i < hmac_block_size; i++) { 00565 op[i] = ip[i] ^ OPAD; 00566 ip[i] ^= IPAD; 00567 } 00568 } 00569 00570 return ret; 00571 } 00572 00573 00574 static int HmacKeyInnerHash(Hmac* hmac) 00575 { 00576 int ret = 0; 00577 00578 switch (hmac->macType) { 00579 #ifndef NO_MD5 00580 case WC_MD5: 00581 ret = wc_Md5Update(&hmac->hash.md5, (byte*)hmac->ipad, 00582 WC_MD5_BLOCK_SIZE); 00583 break; 00584 #endif /* !NO_MD5 */ 00585 00586 #ifndef NO_SHA 00587 case WC_SHA: 00588 ret = wc_ShaUpdate(&hmac->hash.sha, (byte*)hmac->ipad, 00589 WC_SHA_BLOCK_SIZE); 00590 break; 00591 #endif /* !NO_SHA */ 00592 00593 #ifdef WOLFSSL_SHA224 00594 case WC_SHA224: 00595 ret = wc_Sha224Update(&hmac->hash.sha224, (byte*)hmac->ipad, 00596 WC_SHA224_BLOCK_SIZE); 00597 break; 00598 #endif /* WOLFSSL_SHA224 */ 00599 00600 #ifndef NO_SHA256 00601 case WC_SHA256: 00602 ret = wc_Sha256Update(&hmac->hash.sha256, (byte*)hmac->ipad, 00603 WC_SHA256_BLOCK_SIZE); 00604 break; 00605 #endif /* !NO_SHA256 */ 00606 00607 #ifdef WOLFSSL_SHA384 00608 case WC_SHA384: 00609 ret = wc_Sha384Update(&hmac->hash.sha384, (byte*)hmac->ipad, 00610 WC_SHA384_BLOCK_SIZE); 00611 break; 00612 #endif /* WOLFSSL_SHA384 */ 00613 #ifdef WOLFSSL_SHA512 00614 case WC_SHA512: 00615 ret = wc_Sha512Update(&hmac->hash.sha512, (byte*)hmac->ipad, 00616 WC_SHA512_BLOCK_SIZE); 00617 break; 00618 #endif /* WOLFSSL_SHA512 */ 00619 00620 #ifdef HAVE_BLAKE2 00621 case BLAKE2B_ID: 00622 ret = wc_Blake2bUpdate(&hmac->hash.blake2b, (byte*)hmac->ipad, 00623 BLAKE2B_BLOCKBYTES); 00624 break; 00625 #endif /* HAVE_BLAKE2 */ 00626 00627 #ifdef WOLFSSL_SHA3 00628 case WC_SHA3_224: 00629 ret = wc_Sha3_224_Update(&hmac->hash.sha3, (byte*)hmac->ipad, 00630 WC_SHA3_224_BLOCK_SIZE); 00631 break; 00632 case WC_SHA3_256: 00633 ret = wc_Sha3_256_Update(&hmac->hash.sha3, (byte*)hmac->ipad, 00634 WC_SHA3_256_BLOCK_SIZE); 00635 break; 00636 case WC_SHA3_384: 00637 ret = wc_Sha3_384_Update(&hmac->hash.sha3, (byte*)hmac->ipad, 00638 WC_SHA3_384_BLOCK_SIZE); 00639 break; 00640 case WC_SHA3_512: 00641 ret = wc_Sha3_512_Update(&hmac->hash.sha3, (byte*)hmac->ipad, 00642 WC_SHA3_512_BLOCK_SIZE); 00643 break; 00644 #endif /* WOLFSSL_SHA3 */ 00645 00646 default: 00647 break; 00648 } 00649 00650 if (ret == 0) 00651 hmac->innerHashKeyed = 1; 00652 00653 return ret; 00654 } 00655 00656 00657 int wc_HmacUpdate(Hmac* hmac, const byte* msg, word32 length) 00658 { 00659 int ret = 0; 00660 00661 if (hmac == NULL || (msg == NULL && length > 0)) { 00662 return BAD_FUNC_ARG; 00663 } 00664 00665 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC) 00666 if (hmac->asyncDev.marker == WOLFSSL_ASYNC_MARKER_HMAC) { 00667 #if defined(HAVE_CAVIUM) 00668 return NitroxHmacUpdate(hmac, msg, length); 00669 #elif defined(HAVE_INTEL_QA) 00670 if (IntelQaHmacGetType(hmac->macType, NULL) == 0) { 00671 return IntelQaHmac(&hmac->asyncDev, hmac->macType, 00672 (byte*)hmac->ipad, hmac->keyLen, NULL, msg, length); 00673 } 00674 #endif 00675 } 00676 #endif /* WOLFSSL_ASYNC_CRYPT */ 00677 00678 if (!hmac->innerHashKeyed) { 00679 ret = HmacKeyInnerHash(hmac); 00680 if (ret != 0) 00681 return ret; 00682 } 00683 00684 switch (hmac->macType) { 00685 #ifndef NO_MD5 00686 case WC_MD5: 00687 ret = wc_Md5Update(&hmac->hash.md5, msg, length); 00688 break; 00689 #endif /* !NO_MD5 */ 00690 00691 #ifndef NO_SHA 00692 case WC_SHA: 00693 ret = wc_ShaUpdate(&hmac->hash.sha, msg, length); 00694 break; 00695 #endif /* !NO_SHA */ 00696 00697 #ifdef WOLFSSL_SHA224 00698 case WC_SHA224: 00699 ret = wc_Sha224Update(&hmac->hash.sha224, msg, length); 00700 break; 00701 #endif /* WOLFSSL_SHA224 */ 00702 00703 #ifndef NO_SHA256 00704 case WC_SHA256: 00705 ret = wc_Sha256Update(&hmac->hash.sha256, msg, length); 00706 break; 00707 #endif /* !NO_SHA256 */ 00708 00709 #ifdef WOLFSSL_SHA384 00710 case WC_SHA384: 00711 ret = wc_Sha384Update(&hmac->hash.sha384, msg, length); 00712 break; 00713 #endif /* WOLFSSL_SHA384 */ 00714 #ifdef WOLFSSL_SHA512 00715 case WC_SHA512: 00716 ret = wc_Sha512Update(&hmac->hash.sha512, msg, length); 00717 break; 00718 #endif /* WOLFSSL_SHA512 */ 00719 00720 #ifdef HAVE_BLAKE2 00721 case BLAKE2B_ID: 00722 ret = wc_Blake2bUpdate(&hmac->hash.blake2b, msg, length); 00723 break; 00724 #endif /* HAVE_BLAKE2 */ 00725 00726 #ifdef WOLFSSL_SHA3 00727 case WC_SHA3_224: 00728 ret = wc_Sha3_224_Update(&hmac->hash.sha3, msg, length); 00729 break; 00730 case WC_SHA3_256: 00731 ret = wc_Sha3_256_Update(&hmac->hash.sha3, msg, length); 00732 break; 00733 case WC_SHA3_384: 00734 ret = wc_Sha3_384_Update(&hmac->hash.sha3, msg, length); 00735 break; 00736 case WC_SHA3_512: 00737 ret = wc_Sha3_512_Update(&hmac->hash.sha3, msg, length); 00738 break; 00739 #endif /* WOLFSSL_SHA3 */ 00740 00741 default: 00742 break; 00743 } 00744 00745 return ret; 00746 } 00747 00748 00749 int wc_HmacFinal(Hmac* hmac, byte* hash) 00750 { 00751 int ret; 00752 00753 if (hmac == NULL || hash == NULL) { 00754 return BAD_FUNC_ARG; 00755 } 00756 00757 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC) 00758 if (hmac->asyncDev.marker == WOLFSSL_ASYNC_MARKER_HMAC) { 00759 int hashLen = wc_HmacSizeByType(hmac->macType); 00760 if (hashLen <= 0) 00761 return hashLen; 00762 00763 #if defined(HAVE_CAVIUM) 00764 return NitroxHmacFinal(hmac, hash, hashLen); 00765 #elif defined(HAVE_INTEL_QA) 00766 if (IntelQaHmacGetType(hmac->macType, NULL) == 0) { 00767 return IntelQaHmac(&hmac->asyncDev, hmac->macType, 00768 (byte*)hmac->ipad, hmac->keyLen, hash, NULL, hashLen); 00769 } 00770 #endif 00771 } 00772 #endif /* WOLFSSL_ASYNC_CRYPT */ 00773 00774 if (!hmac->innerHashKeyed) { 00775 ret = HmacKeyInnerHash(hmac); 00776 if (ret != 0) 00777 return ret; 00778 } 00779 00780 switch (hmac->macType) { 00781 #ifndef NO_MD5 00782 case WC_MD5: 00783 ret = wc_Md5Final(&hmac->hash.md5, (byte*)hmac->innerHash); 00784 if (ret != 0) 00785 break; 00786 ret = wc_Md5Update(&hmac->hash.md5, (byte*)hmac->opad, 00787 WC_MD5_BLOCK_SIZE); 00788 if (ret != 0) 00789 break; 00790 ret = wc_Md5Update(&hmac->hash.md5, (byte*)hmac->innerHash, 00791 WC_MD5_DIGEST_SIZE); 00792 if (ret != 0) 00793 break; 00794 ret = wc_Md5Final(&hmac->hash.md5, hash); 00795 break; 00796 #endif /* !NO_MD5 */ 00797 00798 #ifndef NO_SHA 00799 case WC_SHA: 00800 ret = wc_ShaFinal(&hmac->hash.sha, (byte*)hmac->innerHash); 00801 if (ret != 0) 00802 break; 00803 ret = wc_ShaUpdate(&hmac->hash.sha, (byte*)hmac->opad, 00804 WC_SHA_BLOCK_SIZE); 00805 if (ret != 0) 00806 break; 00807 ret = wc_ShaUpdate(&hmac->hash.sha, (byte*)hmac->innerHash, 00808 WC_SHA_DIGEST_SIZE); 00809 if (ret != 0) 00810 break; 00811 ret = wc_ShaFinal(&hmac->hash.sha, hash); 00812 break; 00813 #endif /* !NO_SHA */ 00814 00815 #ifdef WOLFSSL_SHA224 00816 case WC_SHA224: 00817 { 00818 ret = wc_Sha224Final(&hmac->hash.sha224, (byte*)hmac->innerHash); 00819 if (ret != 0) 00820 break; 00821 ret = wc_Sha224Update(&hmac->hash.sha224, (byte*)hmac->opad, 00822 WC_SHA224_BLOCK_SIZE); 00823 if (ret != 0) 00824 break; 00825 ret = wc_Sha224Update(&hmac->hash.sha224, (byte*)hmac->innerHash, 00826 WC_SHA224_DIGEST_SIZE); 00827 if (ret != 0) 00828 break; 00829 ret = wc_Sha224Final(&hmac->hash.sha224, hash); 00830 if (ret != 0) 00831 break; 00832 } 00833 break; 00834 #endif /* WOLFSSL_SHA224 */ 00835 00836 #ifndef NO_SHA256 00837 case WC_SHA256: 00838 ret = wc_Sha256Final(&hmac->hash.sha256, (byte*)hmac->innerHash); 00839 if (ret != 0) 00840 break; 00841 ret = wc_Sha256Update(&hmac->hash.sha256, (byte*)hmac->opad, 00842 WC_SHA256_BLOCK_SIZE); 00843 if (ret != 0) 00844 break; 00845 ret = wc_Sha256Update(&hmac->hash.sha256, (byte*)hmac->innerHash, 00846 WC_SHA256_DIGEST_SIZE); 00847 if (ret != 0) 00848 break; 00849 ret = wc_Sha256Final(&hmac->hash.sha256, hash); 00850 break; 00851 #endif /* !NO_SHA256 */ 00852 00853 #ifdef WOLFSSL_SHA384 00854 case WC_SHA384: 00855 ret = wc_Sha384Final(&hmac->hash.sha384, (byte*)hmac->innerHash); 00856 if (ret != 0) 00857 break; 00858 ret = wc_Sha384Update(&hmac->hash.sha384, (byte*)hmac->opad, 00859 WC_SHA384_BLOCK_SIZE); 00860 if (ret != 0) 00861 break; 00862 ret = wc_Sha384Update(&hmac->hash.sha384, (byte*)hmac->innerHash, 00863 WC_SHA384_DIGEST_SIZE); 00864 if (ret != 0) 00865 break; 00866 ret = wc_Sha384Final(&hmac->hash.sha384, hash); 00867 break; 00868 #endif /* WOLFSSL_SHA384 */ 00869 #ifdef WOLFSSL_SHA512 00870 case WC_SHA512: 00871 ret = wc_Sha512Final(&hmac->hash.sha512, (byte*)hmac->innerHash); 00872 if (ret != 0) 00873 break; 00874 ret = wc_Sha512Update(&hmac->hash.sha512, (byte*)hmac->opad, 00875 WC_SHA512_BLOCK_SIZE); 00876 if (ret != 0) 00877 break; 00878 ret = wc_Sha512Update(&hmac->hash.sha512, (byte*)hmac->innerHash, 00879 WC_SHA512_DIGEST_SIZE); 00880 if (ret != 0) 00881 break; 00882 ret = wc_Sha512Final(&hmac->hash.sha512, hash); 00883 break; 00884 #endif /* WOLFSSL_SHA512 */ 00885 00886 #ifdef HAVE_BLAKE2 00887 case BLAKE2B_ID: 00888 ret = wc_Blake2bFinal(&hmac->hash.blake2b, (byte*)hmac->innerHash, 00889 BLAKE2B_256); 00890 if (ret != 0) 00891 break; 00892 ret = wc_Blake2bUpdate(&hmac->hash.blake2b, (byte*)hmac->opad, 00893 BLAKE2B_BLOCKBYTES); 00894 if (ret != 0) 00895 break; 00896 ret = wc_Blake2bUpdate(&hmac->hash.blake2b, (byte*)hmac->innerHash, 00897 BLAKE2B_256); 00898 if (ret != 0) 00899 break; 00900 ret = wc_Blake2bFinal(&hmac->hash.blake2b, hash, BLAKE2B_256); 00901 break; 00902 #endif /* HAVE_BLAKE2 */ 00903 00904 #ifdef WOLFSSL_SHA3 00905 case WC_SHA3_224: 00906 ret = wc_Sha3_224_Final(&hmac->hash.sha3, (byte*)hmac->innerHash); 00907 if (ret != 0) 00908 break; 00909 ret = wc_Sha3_224_Update(&hmac->hash.sha3, (byte*)hmac->opad, 00910 WC_SHA3_224_BLOCK_SIZE); 00911 if (ret != 0) 00912 break; 00913 ret = wc_Sha3_224_Update(&hmac->hash.sha3, (byte*)hmac->innerHash, 00914 WC_SHA3_224_DIGEST_SIZE); 00915 if (ret != 0) 00916 break; 00917 ret = wc_Sha3_224_Final(&hmac->hash.sha3, hash); 00918 break; 00919 case WC_SHA3_256: 00920 ret = wc_Sha3_256_Final(&hmac->hash.sha3, (byte*)hmac->innerHash); 00921 if (ret != 0) 00922 break; 00923 ret = wc_Sha3_256_Update(&hmac->hash.sha3, (byte*)hmac->opad, 00924 WC_SHA3_256_BLOCK_SIZE); 00925 if (ret != 0) 00926 break; 00927 ret = wc_Sha3_256_Update(&hmac->hash.sha3, (byte*)hmac->innerHash, 00928 WC_SHA3_256_DIGEST_SIZE); 00929 if (ret != 0) 00930 break; 00931 ret = wc_Sha3_256_Final(&hmac->hash.sha3, hash); 00932 break; 00933 case WC_SHA3_384: 00934 ret = wc_Sha3_384_Final(&hmac->hash.sha3, (byte*)hmac->innerHash); 00935 if (ret != 0) 00936 break; 00937 ret = wc_Sha3_384_Update(&hmac->hash.sha3, (byte*)hmac->opad, 00938 WC_SHA3_384_BLOCK_SIZE); 00939 if (ret != 0) 00940 break; 00941 ret = wc_Sha3_384_Update(&hmac->hash.sha3, (byte*)hmac->innerHash, 00942 WC_SHA3_384_DIGEST_SIZE); 00943 if (ret != 0) 00944 break; 00945 ret = wc_Sha3_384_Final(&hmac->hash.sha3, hash); 00946 break; 00947 case WC_SHA3_512: 00948 ret = wc_Sha3_512_Final(&hmac->hash.sha3, (byte*)hmac->innerHash); 00949 if (ret != 0) 00950 break; 00951 ret = wc_Sha3_512_Update(&hmac->hash.sha3, (byte*)hmac->opad, 00952 WC_SHA3_512_BLOCK_SIZE); 00953 if (ret != 0) 00954 break; 00955 ret = wc_Sha3_512_Update(&hmac->hash.sha3, (byte*)hmac->innerHash, 00956 WC_SHA3_512_DIGEST_SIZE); 00957 if (ret != 0) 00958 break; 00959 ret = wc_Sha3_512_Final(&hmac->hash.sha3, hash); 00960 break; 00961 #endif /* WOLFSSL_SHA3 */ 00962 00963 default: 00964 ret = BAD_FUNC_ARG; 00965 break; 00966 } 00967 00968 if (ret == 0) { 00969 hmac->innerHashKeyed = 0; 00970 } 00971 00972 return ret; 00973 } 00974 00975 00976 /* Initialize Hmac for use with async device */ 00977 int wc_HmacInit(Hmac* hmac, void* heap, int devId) 00978 { 00979 int ret = 0; 00980 00981 if (hmac == NULL) 00982 return BAD_FUNC_ARG; 00983 00984 XMEMSET(hmac, 0, sizeof(Hmac)); 00985 hmac->heap = heap; 00986 00987 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC) 00988 hmac->keyLen = 0; 00989 00990 ret = wolfAsync_DevCtxInit(&hmac->asyncDev, WOLFSSL_ASYNC_MARKER_HMAC, 00991 hmac->heap, devId); 00992 #else 00993 (void)devId; 00994 #endif /* WOLFSSL_ASYNC_CRYPT */ 00995 00996 return ret; 00997 } 00998 00999 /* Free Hmac from use with async device */ 01000 void wc_HmacFree(Hmac* hmac) 01001 { 01002 if (hmac == NULL) 01003 return; 01004 01005 switch (hmac->macType) { 01006 #ifndef NO_MD5 01007 case WC_MD5: 01008 wc_Md5Free(&hmac->hash.md5); 01009 break; 01010 #endif /* !NO_MD5 */ 01011 01012 #ifndef NO_SHA 01013 case WC_SHA: 01014 wc_ShaFree(&hmac->hash.sha); 01015 break; 01016 #endif /* !NO_SHA */ 01017 01018 #ifdef WOLFSSL_SHA224 01019 case WC_SHA224: 01020 wc_Sha224Free(&hmac->hash.sha224); 01021 break; 01022 #endif /* WOLFSSL_SHA224 */ 01023 01024 #ifndef NO_SHA256 01025 case WC_SHA256: 01026 wc_Sha256Free(&hmac->hash.sha256); 01027 break; 01028 #endif /* !NO_SHA256 */ 01029 01030 #ifdef WOLFSSL_SHA384 01031 case WC_SHA384: 01032 wc_Sha384Free(&hmac->hash.sha384); 01033 break; 01034 #endif /* WOLFSSL_SHA384 */ 01035 #ifdef WOLFSSL_SHA512 01036 case WC_SHA512: 01037 wc_Sha512Free(&hmac->hash.sha512); 01038 break; 01039 #endif /* WOLFSSL_SHA512 */ 01040 01041 #ifdef HAVE_BLAKE2 01042 case BLAKE2B_ID: 01043 break; 01044 #endif /* HAVE_BLAKE2 */ 01045 01046 #ifdef WOLFSSL_SHA3 01047 case WC_SHA3_224: 01048 wc_Sha3_224_Free(&hmac->hash.sha3); 01049 break; 01050 case WC_SHA3_256: 01051 wc_Sha3_256_Free(&hmac->hash.sha3); 01052 break; 01053 case WC_SHA3_384: 01054 wc_Sha3_384_Free(&hmac->hash.sha3); 01055 break; 01056 case WC_SHA3_512: 01057 wc_Sha3_512_Free(&hmac->hash.sha3); 01058 break; 01059 #endif /* WOLFSSL_SHA3 */ 01060 01061 default: 01062 break; 01063 } 01064 01065 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC) 01066 wolfAsync_DevCtxFree(&hmac->asyncDev, WOLFSSL_ASYNC_MARKER_HMAC); 01067 #endif /* WOLFSSL_ASYNC_CRYPT */ 01068 } 01069 01070 int wolfSSL_GetHmacMaxSize(void) 01071 { 01072 return WC_MAX_DIGEST_SIZE; 01073 } 01074 01075 #ifdef HAVE_HKDF 01076 /* HMAC-KDF-Extract. 01077 * RFC 5869 - HMAC-based Extract-and-Expand Key Derivation Function (HKDF). 01078 * 01079 * type The hash algorithm type. 01080 * salt The optional salt value. 01081 * saltSz The size of the salt. 01082 * inKey The input keying material. 01083 * inKeySz The size of the input keying material. 01084 * out The pseudorandom key with the length that of the hash. 01085 * returns 0 on success, otherwise failure. 01086 */ 01087 int wc_HKDF_Extract(int type, const byte* salt, word32 saltSz, 01088 const byte* inKey, word32 inKeySz, byte* out) 01089 { 01090 byte tmp[WC_MAX_DIGEST_SIZE]; /* localSalt helper */ 01091 Hmac myHmac; 01092 int ret; 01093 const byte* localSalt; /* either points to user input or tmp */ 01094 int hashSz; 01095 01096 ret = wc_HmacSizeByType(type); 01097 if (ret < 0) 01098 return ret; 01099 01100 hashSz = ret; 01101 localSalt = salt; 01102 if (localSalt == NULL) { 01103 XMEMSET(tmp, 0, hashSz); 01104 localSalt = tmp; 01105 saltSz = hashSz; 01106 } 01107 01108 ret = wc_HmacInit(&myHmac, NULL, INVALID_DEVID); 01109 if (ret == 0) { 01110 ret = wc_HmacSetKey(&myHmac, type, localSalt, saltSz); 01111 if (ret == 0) 01112 ret = wc_HmacUpdate(&myHmac, inKey, inKeySz); 01113 if (ret == 0) 01114 ret = wc_HmacFinal(&myHmac, out); 01115 wc_HmacFree(&myHmac); 01116 } 01117 01118 return ret; 01119 } 01120 01121 /* HMAC-KDF-Expand. 01122 * RFC 5869 - HMAC-based Extract-and-Expand Key Derivation Function (HKDF). 01123 * 01124 * type The hash algorithm type. 01125 * inKey The input key. 01126 * inKeySz The size of the input key. 01127 * info The application specific information. 01128 * infoSz The size of the application specific information. 01129 * out The output keying material. 01130 * returns 0 on success, otherwise failure. 01131 */ 01132 int wc_HKDF_Expand(int type, const byte* inKey, word32 inKeySz, 01133 const byte* info, word32 infoSz, byte* out, word32 outSz) 01134 { 01135 byte tmp[WC_MAX_DIGEST_SIZE]; 01136 Hmac myHmac; 01137 int ret = 0; 01138 word32 outIdx = 0; 01139 word32 hashSz = wc_HmacSizeByType(type); 01140 byte n = 0x1; 01141 01142 ret = wc_HmacInit(&myHmac, NULL, INVALID_DEVID); 01143 if (ret != 0) 01144 return ret; 01145 01146 while (outIdx < outSz) { 01147 int tmpSz = (n == 1) ? 0 : hashSz; 01148 word32 left = outSz - outIdx; 01149 01150 ret = wc_HmacSetKey(&myHmac, type, inKey, inKeySz); 01151 if (ret != 0) 01152 break; 01153 ret = wc_HmacUpdate(&myHmac, tmp, tmpSz); 01154 if (ret != 0) 01155 break; 01156 ret = wc_HmacUpdate(&myHmac, info, infoSz); 01157 if (ret != 0) 01158 break; 01159 ret = wc_HmacUpdate(&myHmac, &n, 1); 01160 if (ret != 0) 01161 break; 01162 ret = wc_HmacFinal(&myHmac, tmp); 01163 if (ret != 0) 01164 break; 01165 01166 left = min(left, hashSz); 01167 XMEMCPY(out+outIdx, tmp, left); 01168 01169 outIdx += hashSz; 01170 n++; 01171 } 01172 01173 wc_HmacFree(&myHmac); 01174 01175 return ret; 01176 } 01177 01178 /* HMAC-KDF. 01179 * RFC 5869 - HMAC-based Extract-and-Expand Key Derivation Function (HKDF). 01180 * 01181 * type The hash algorithm type. 01182 * inKey The input keying material. 01183 * inKeySz The size of the input keying material. 01184 * salt The optional salt value. 01185 * saltSz The size of the salt. 01186 * info The application specific information. 01187 * infoSz The size of the application specific information. 01188 * out The output keying material. 01189 * returns 0 on success, otherwise failure. 01190 */ 01191 int wc_HKDF(int type, const byte* inKey, word32 inKeySz, 01192 const byte* salt, word32 saltSz, 01193 const byte* info, word32 infoSz, 01194 byte* out, word32 outSz) 01195 { 01196 byte prk[WC_MAX_DIGEST_SIZE]; 01197 int hashSz = wc_HmacSizeByType(type); 01198 int ret; 01199 01200 if (hashSz < 0) 01201 return BAD_FUNC_ARG; 01202 01203 ret = wc_HKDF_Extract(type, salt, saltSz, inKey, inKeySz, prk); 01204 if (ret != 0) 01205 return ret; 01206 01207 return wc_HKDF_Expand(type, prk, hashSz, info, infoSz, out, outSz); 01208 } 01209 01210 #endif /* HAVE_HKDF */ 01211 01212 #endif /* HAVE_FIPS */ 01213 #endif /* NO_HMAC */ 01214
Generated on Tue Jul 12 2022 16:58:06 by
1.7.2