Dependents: HTTPClient-SSL HTTPClient-SSL HTTPClient-SSL HTTPClient-SSL
hmac.c
00001 /* hmac.c 00002 * 00003 * Copyright (C) 2006-2014 wolfSSL Inc. 00004 * 00005 * This file is part of CyaSSL. 00006 * 00007 * CyaSSL 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 * CyaSSL 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-1301, USA 00020 */ 00021 00022 #ifdef HAVE_CONFIG_H 00023 #include <config.h> 00024 #endif 00025 00026 #include <cyassl/ctaocrypt/settings.h> 00027 00028 #ifndef NO_HMAC 00029 00030 #ifdef CYASSL_PIC32MZ_HASH 00031 00032 #define InitMd5 InitMd5_sw 00033 #define Md5Update Md5Update_sw 00034 #define Md5Final Md5Final_sw 00035 00036 #define InitSha InitSha_sw 00037 #define ShaUpdate ShaUpdate_sw 00038 #define ShaFinal ShaFinal_sw 00039 00040 #define InitSha256 InitSha256_sw 00041 #define Sha256Update Sha256Update_sw 00042 #define Sha256Final Sha256Final_sw 00043 00044 #endif 00045 00046 #ifdef HAVE_FIPS 00047 /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */ 00048 #define FIPS_NO_WRAPPERS 00049 #endif 00050 00051 #include <cyassl/ctaocrypt/hmac.h> 00052 #include <cyassl/ctaocrypt/error-crypt.h> 00053 00054 00055 #ifdef HAVE_CAVIUM 00056 static void HmacCaviumFinal(Hmac* hmac, byte* hash); 00057 static void HmacCaviumUpdate(Hmac* hmac, const byte* msg, word32 length); 00058 static void HmacCaviumSetKey(Hmac* hmac, int type, const byte* key, 00059 word32 length); 00060 #endif 00061 00062 static int InitHmac(Hmac* hmac, int type) 00063 { 00064 int ret = 0; 00065 00066 hmac->innerHashKeyed = 0; 00067 hmac->macType = (byte)type; 00068 00069 if (!(type == MD5 || type == SHA || type == SHA256 || type == SHA384 00070 || type == SHA512 || type == BLAKE2B_ID)) 00071 return BAD_FUNC_ARG; 00072 00073 switch (type) { 00074 #ifndef NO_MD5 00075 case MD5: 00076 InitMd5(&hmac->hash.md5); 00077 break; 00078 #endif 00079 00080 #ifndef NO_SHA 00081 case SHA: 00082 ret = InitSha(&hmac->hash.sha); 00083 break; 00084 #endif 00085 00086 #ifndef NO_SHA256 00087 case SHA256: 00088 ret = InitSha256(&hmac->hash.sha256); 00089 break; 00090 #endif 00091 00092 #ifdef CYASSL_SHA384 00093 case SHA384: 00094 ret = InitSha384(&hmac->hash.sha384); 00095 break; 00096 #endif 00097 00098 #ifdef CYASSL_SHA512 00099 case SHA512: 00100 ret = InitSha512(&hmac->hash.sha512); 00101 break; 00102 #endif 00103 00104 #ifdef HAVE_BLAKE2 00105 case BLAKE2B_ID: 00106 ret = InitBlake2b(&hmac->hash.blake2b, BLAKE2B_256); 00107 break; 00108 #endif 00109 00110 default: 00111 return BAD_FUNC_ARG; 00112 } 00113 00114 return ret; 00115 } 00116 00117 00118 int HmacSetKey(Hmac* hmac, int type, const byte* key, word32 length) 00119 { 00120 byte* ip = (byte*) hmac->ipad; 00121 byte* op = (byte*) hmac->opad; 00122 word32 i, hmac_block_size = 0; 00123 int ret; 00124 00125 #ifdef HAVE_CAVIUM 00126 if (hmac->magic == CYASSL_HMAC_CAVIUM_MAGIC) 00127 return HmacCaviumSetKey(hmac, type, key, length); 00128 #endif 00129 00130 ret = InitHmac(hmac, type); 00131 if (ret != 0) 00132 return ret; 00133 00134 #ifdef HAVE_FIPS 00135 if (length < HMAC_FIPS_MIN_KEY) 00136 return HMAC_MIN_KEYLEN_E; 00137 #endif 00138 00139 switch (hmac->macType) { 00140 #ifndef NO_MD5 00141 case MD5: 00142 { 00143 hmac_block_size = MD5_BLOCK_SIZE; 00144 if (length <= MD5_BLOCK_SIZE) { 00145 XMEMCPY(ip, key, length); 00146 } 00147 else { 00148 Md5Update(&hmac->hash.md5, key, length); 00149 Md5Final(&hmac->hash.md5, ip); 00150 length = MD5_DIGEST_SIZE; 00151 } 00152 } 00153 break; 00154 #endif 00155 00156 #ifndef NO_SHA 00157 case SHA: 00158 { 00159 hmac_block_size = SHA_BLOCK_SIZE; 00160 if (length <= SHA_BLOCK_SIZE) { 00161 XMEMCPY(ip, key, length); 00162 } 00163 else { 00164 ShaUpdate(&hmac->hash.sha, key, length); 00165 ShaFinal(&hmac->hash.sha, ip); 00166 length = SHA_DIGEST_SIZE; 00167 } 00168 } 00169 break; 00170 #endif 00171 00172 #ifndef NO_SHA256 00173 case SHA256: 00174 { 00175 hmac_block_size = SHA256_BLOCK_SIZE; 00176 if (length <= SHA256_BLOCK_SIZE) { 00177 XMEMCPY(ip, key, length); 00178 } 00179 else { 00180 ret = Sha256Update(&hmac->hash.sha256, key, length); 00181 if (ret != 0) 00182 return ret; 00183 00184 ret = Sha256Final(&hmac->hash.sha256, ip); 00185 if (ret != 0) 00186 return ret; 00187 00188 length = SHA256_DIGEST_SIZE; 00189 } 00190 } 00191 break; 00192 #endif 00193 00194 #ifdef CYASSL_SHA384 00195 case SHA384: 00196 { 00197 hmac_block_size = SHA384_BLOCK_SIZE; 00198 if (length <= SHA384_BLOCK_SIZE) { 00199 XMEMCPY(ip, key, length); 00200 } 00201 else { 00202 ret = Sha384Update(&hmac->hash.sha384, key, length); 00203 if (ret != 0) 00204 return ret; 00205 00206 ret = Sha384Final(&hmac->hash.sha384, ip); 00207 if (ret != 0) 00208 return ret; 00209 00210 length = SHA384_DIGEST_SIZE; 00211 } 00212 } 00213 break; 00214 #endif 00215 00216 #ifdef CYASSL_SHA512 00217 case SHA512: 00218 { 00219 hmac_block_size = SHA512_BLOCK_SIZE; 00220 if (length <= SHA512_BLOCK_SIZE) { 00221 XMEMCPY(ip, key, length); 00222 } 00223 else { 00224 ret = Sha512Update(&hmac->hash.sha512, key, length); 00225 if (ret != 0) 00226 return ret; 00227 00228 ret = Sha512Final(&hmac->hash.sha512, ip); 00229 if (ret != 0) 00230 return ret; 00231 00232 length = SHA512_DIGEST_SIZE; 00233 } 00234 } 00235 break; 00236 #endif 00237 00238 #ifdef HAVE_BLAKE2 00239 case BLAKE2B_ID: 00240 { 00241 hmac_block_size = BLAKE2B_BLOCKBYTES; 00242 if (length <= BLAKE2B_BLOCKBYTES) { 00243 XMEMCPY(ip, key, length); 00244 } 00245 else { 00246 ret = Blake2bUpdate(&hmac->hash.blake2b, key, length); 00247 if (ret != 0) 00248 return ret; 00249 00250 ret = Blake2bFinal(&hmac->hash.blake2b, ip, BLAKE2B_256); 00251 if (ret != 0) 00252 return ret; 00253 00254 length = BLAKE2B_256; 00255 } 00256 } 00257 break; 00258 #endif 00259 00260 default: 00261 return BAD_FUNC_ARG; 00262 } 00263 if (length < hmac_block_size) 00264 XMEMSET(ip + length, 0, hmac_block_size - length); 00265 00266 for(i = 0; i < hmac_block_size; i++) { 00267 op[i] = ip[i] ^ OPAD; 00268 ip[i] ^= IPAD; 00269 } 00270 return 0; 00271 } 00272 00273 00274 static int HmacKeyInnerHash(Hmac* hmac) 00275 { 00276 int ret = 0; 00277 00278 switch (hmac->macType) { 00279 #ifndef NO_MD5 00280 case MD5: 00281 Md5Update(&hmac->hash.md5, (byte*) hmac->ipad, MD5_BLOCK_SIZE); 00282 break; 00283 #endif 00284 00285 #ifndef NO_SHA 00286 case SHA: 00287 ShaUpdate(&hmac->hash.sha, (byte*) hmac->ipad, SHA_BLOCK_SIZE); 00288 break; 00289 #endif 00290 00291 #ifndef NO_SHA256 00292 case SHA256: 00293 ret = Sha256Update(&hmac->hash.sha256, 00294 (byte*) hmac->ipad, SHA256_BLOCK_SIZE); 00295 if (ret != 0) 00296 return ret; 00297 break; 00298 #endif 00299 00300 #ifdef CYASSL_SHA384 00301 case SHA384: 00302 ret = Sha384Update(&hmac->hash.sha384, 00303 (byte*) hmac->ipad, SHA384_BLOCK_SIZE); 00304 if (ret != 0) 00305 return ret; 00306 break; 00307 #endif 00308 00309 #ifdef CYASSL_SHA512 00310 case SHA512: 00311 ret = Sha512Update(&hmac->hash.sha512, 00312 (byte*) hmac->ipad, SHA512_BLOCK_SIZE); 00313 if (ret != 0) 00314 return ret; 00315 break; 00316 #endif 00317 00318 #ifdef HAVE_BLAKE2 00319 case BLAKE2B_ID: 00320 ret = Blake2bUpdate(&hmac->hash.blake2b, 00321 (byte*) hmac->ipad,BLAKE2B_BLOCKBYTES); 00322 if (ret != 0) 00323 return ret; 00324 break; 00325 #endif 00326 00327 default: 00328 break; 00329 } 00330 00331 hmac->innerHashKeyed = 1; 00332 00333 return ret; 00334 } 00335 00336 00337 int HmacUpdate(Hmac* hmac, const byte* msg, word32 length) 00338 { 00339 int ret; 00340 00341 #ifdef HAVE_CAVIUM 00342 if (hmac->magic == CYASSL_HMAC_CAVIUM_MAGIC) 00343 return HmacCaviumUpdate(hmac, msg, length); 00344 #endif 00345 00346 if (!hmac->innerHashKeyed) { 00347 ret = HmacKeyInnerHash(hmac); 00348 if (ret != 0) 00349 return ret; 00350 } 00351 00352 switch (hmac->macType) { 00353 #ifndef NO_MD5 00354 case MD5: 00355 Md5Update(&hmac->hash.md5, msg, length); 00356 break; 00357 #endif 00358 00359 #ifndef NO_SHA 00360 case SHA: 00361 ShaUpdate(&hmac->hash.sha, msg, length); 00362 break; 00363 #endif 00364 00365 #ifndef NO_SHA256 00366 case SHA256: 00367 ret = Sha256Update(&hmac->hash.sha256, msg, length); 00368 if (ret != 0) 00369 return ret; 00370 break; 00371 #endif 00372 00373 #ifdef CYASSL_SHA384 00374 case SHA384: 00375 ret = Sha384Update(&hmac->hash.sha384, msg, length); 00376 if (ret != 0) 00377 return ret; 00378 break; 00379 #endif 00380 00381 #ifdef CYASSL_SHA512 00382 case SHA512: 00383 ret = Sha512Update(&hmac->hash.sha512, msg, length); 00384 if (ret != 0) 00385 return ret; 00386 break; 00387 #endif 00388 00389 #ifdef HAVE_BLAKE2 00390 case BLAKE2B_ID: 00391 ret = Blake2bUpdate(&hmac->hash.blake2b, msg, length); 00392 if (ret != 0) 00393 return ret; 00394 break; 00395 #endif 00396 00397 default: 00398 break; 00399 } 00400 00401 return 0; 00402 } 00403 00404 00405 int HmacFinal(Hmac* hmac, byte* hash) 00406 { 00407 int ret; 00408 00409 #ifdef HAVE_CAVIUM 00410 if (hmac->magic == CYASSL_HMAC_CAVIUM_MAGIC) 00411 return HmacCaviumFinal(hmac, hash); 00412 #endif 00413 00414 if (!hmac->innerHashKeyed) { 00415 ret = HmacKeyInnerHash(hmac); 00416 if (ret != 0) 00417 return ret; 00418 } 00419 00420 switch (hmac->macType) { 00421 #ifndef NO_MD5 00422 case MD5: 00423 { 00424 Md5Final(&hmac->hash.md5, (byte*) hmac->innerHash); 00425 00426 Md5Update(&hmac->hash.md5, (byte*) hmac->opad, MD5_BLOCK_SIZE); 00427 Md5Update(&hmac->hash.md5, 00428 (byte*) hmac->innerHash, MD5_DIGEST_SIZE); 00429 00430 Md5Final(&hmac->hash.md5, hash); 00431 } 00432 break; 00433 #endif 00434 00435 #ifndef NO_SHA 00436 case SHA: 00437 { 00438 ShaFinal(&hmac->hash.sha, (byte*) hmac->innerHash); 00439 00440 ShaUpdate(&hmac->hash.sha, (byte*) hmac->opad, SHA_BLOCK_SIZE); 00441 ShaUpdate(&hmac->hash.sha, 00442 (byte*) hmac->innerHash, SHA_DIGEST_SIZE); 00443 00444 ShaFinal(&hmac->hash.sha, hash); 00445 } 00446 break; 00447 #endif 00448 00449 #ifndef NO_SHA256 00450 case SHA256: 00451 { 00452 ret = Sha256Final(&hmac->hash.sha256, (byte*) hmac->innerHash); 00453 if (ret != 0) 00454 return ret; 00455 00456 ret = Sha256Update(&hmac->hash.sha256, 00457 (byte*) hmac->opad, SHA256_BLOCK_SIZE); 00458 if (ret != 0) 00459 return ret; 00460 00461 ret = Sha256Update(&hmac->hash.sha256, 00462 (byte*) hmac->innerHash, SHA256_DIGEST_SIZE); 00463 if (ret != 0) 00464 return ret; 00465 00466 ret = Sha256Final(&hmac->hash.sha256, hash); 00467 if (ret != 0) 00468 return ret; 00469 } 00470 break; 00471 #endif 00472 00473 #ifdef CYASSL_SHA384 00474 case SHA384: 00475 { 00476 ret = Sha384Final(&hmac->hash.sha384, (byte*) hmac->innerHash); 00477 if (ret != 0) 00478 return ret; 00479 00480 ret = Sha384Update(&hmac->hash.sha384, 00481 (byte*) hmac->opad, SHA384_BLOCK_SIZE); 00482 if (ret != 0) 00483 return ret; 00484 00485 ret = Sha384Update(&hmac->hash.sha384, 00486 (byte*) hmac->innerHash, SHA384_DIGEST_SIZE); 00487 if (ret != 0) 00488 return ret; 00489 00490 ret = Sha384Final(&hmac->hash.sha384, hash); 00491 if (ret != 0) 00492 return ret; 00493 } 00494 break; 00495 #endif 00496 00497 #ifdef CYASSL_SHA512 00498 case SHA512: 00499 { 00500 ret = Sha512Final(&hmac->hash.sha512, (byte*) hmac->innerHash); 00501 if (ret != 0) 00502 return ret; 00503 00504 ret = Sha512Update(&hmac->hash.sha512, 00505 (byte*) hmac->opad, SHA512_BLOCK_SIZE); 00506 if (ret != 0) 00507 return ret; 00508 00509 ret = Sha512Update(&hmac->hash.sha512, 00510 (byte*) hmac->innerHash, SHA512_DIGEST_SIZE); 00511 if (ret != 0) 00512 return ret; 00513 00514 ret = Sha512Final(&hmac->hash.sha512, hash); 00515 if (ret != 0) 00516 return ret; 00517 } 00518 break; 00519 #endif 00520 00521 #ifdef HAVE_BLAKE2 00522 case BLAKE2B_ID: 00523 { 00524 ret = Blake2bFinal(&hmac->hash.blake2b, (byte*) hmac->innerHash, 00525 BLAKE2B_256); 00526 if (ret != 0) 00527 return ret; 00528 00529 ret = Blake2bUpdate(&hmac->hash.blake2b, 00530 (byte*) hmac->opad, BLAKE2B_BLOCKBYTES); 00531 if (ret != 0) 00532 return ret; 00533 00534 ret = Blake2bUpdate(&hmac->hash.blake2b, 00535 (byte*) hmac->innerHash, BLAKE2B_256); 00536 if (ret != 0) 00537 return ret; 00538 00539 ret = Blake2bFinal(&hmac->hash.blake2b, hash, BLAKE2B_256); 00540 if (ret != 0) 00541 return ret; 00542 } 00543 break; 00544 #endif 00545 00546 default: 00547 break; 00548 } 00549 00550 hmac->innerHashKeyed = 0; 00551 00552 return 0; 00553 } 00554 00555 00556 #ifdef HAVE_CAVIUM 00557 00558 /* Initiliaze Hmac for use with Nitrox device */ 00559 int HmacInitCavium(Hmac* hmac, int devId) 00560 { 00561 if (hmac == NULL) 00562 return -1; 00563 00564 if (CspAllocContext(CONTEXT_SSL, &hmac->contextHandle, devId) != 0) 00565 return -1; 00566 00567 hmac->keyLen = 0; 00568 hmac->dataLen = 0; 00569 hmac->type = 0; 00570 hmac->devId = devId; 00571 hmac->magic = CYASSL_HMAC_CAVIUM_MAGIC; 00572 hmac->data = NULL; /* buffered input data */ 00573 00574 hmac->innerHashKeyed = 0; 00575 00576 return 0; 00577 } 00578 00579 00580 /* Free Hmac from use with Nitrox device */ 00581 void HmacFreeCavium(Hmac* hmac) 00582 { 00583 if (hmac == NULL) 00584 return; 00585 00586 CspFreeContext(CONTEXT_SSL, hmac->contextHandle, hmac->devId); 00587 hmac->magic = 0; 00588 XFREE(hmac->data, NULL, DYNAMIC_TYPE_CAVIUM_TMP); 00589 hmac->data = NULL; 00590 } 00591 00592 00593 static void HmacCaviumFinal(Hmac* hmac, byte* hash) 00594 { 00595 word32 requestId; 00596 00597 if (CspHmac(CAVIUM_BLOCKING, hmac->type, NULL, hmac->keyLen, 00598 (byte*)hmac->ipad, hmac->dataLen, hmac->data, hash, &requestId, 00599 hmac->devId) != 0) { 00600 CYASSL_MSG("Cavium Hmac failed"); 00601 } 00602 hmac->innerHashKeyed = 0; /* tell update to start over if used again */ 00603 } 00604 00605 00606 static void HmacCaviumUpdate(Hmac* hmac, const byte* msg, word32 length) 00607 { 00608 word16 add = (word16)length; 00609 word32 total; 00610 byte* tmp; 00611 00612 if (length > CYASSL_MAX_16BIT) { 00613 CYASSL_MSG("Too big msg for cavium hmac"); 00614 return; 00615 } 00616 00617 if (hmac->innerHashKeyed == 0) { /* starting new */ 00618 hmac->dataLen = 0; 00619 hmac->innerHashKeyed = 1; 00620 } 00621 00622 total = add + hmac->dataLen; 00623 if (total > CYASSL_MAX_16BIT) { 00624 CYASSL_MSG("Too big msg for cavium hmac"); 00625 return; 00626 } 00627 00628 tmp = XMALLOC(hmac->dataLen + add, NULL,DYNAMIC_TYPE_CAVIUM_TMP); 00629 if (tmp == NULL) { 00630 CYASSL_MSG("Out of memory for cavium update"); 00631 return; 00632 } 00633 if (hmac->dataLen) 00634 XMEMCPY(tmp, hmac->data, hmac->dataLen); 00635 XMEMCPY(tmp + hmac->dataLen, msg, add); 00636 00637 hmac->dataLen += add; 00638 XFREE(hmac->data, NULL, DYNAMIC_TYPE_CAVIUM_TMP); 00639 hmac->data = tmp; 00640 } 00641 00642 00643 static void HmacCaviumSetKey(Hmac* hmac, int type, const byte* key, 00644 word32 length) 00645 { 00646 hmac->macType = (byte)type; 00647 if (type == MD5) 00648 hmac->type = MD5_TYPE; 00649 else if (type == SHA) 00650 hmac->type = SHA1_TYPE; 00651 else if (type == SHA256) 00652 hmac->type = SHA256_TYPE; 00653 else { 00654 CYASSL_MSG("unsupported cavium hmac type"); 00655 } 00656 00657 hmac->innerHashKeyed = 0; /* should we key Startup flag */ 00658 00659 hmac->keyLen = (word16)length; 00660 /* store key in ipad */ 00661 XMEMCPY(hmac->ipad, key, length); 00662 } 00663 00664 #endif /* HAVE_CAVIUM */ 00665 00666 int CyaSSL_GetHmacMaxSize(void) 00667 { 00668 return MAX_DIGEST_SIZE; 00669 } 00670 00671 #ifdef HAVE_HKDF 00672 00673 #ifndef min 00674 00675 static INLINE word32 min(word32 a, word32 b) 00676 { 00677 return a > b ? b : a; 00678 } 00679 00680 #endif /* min */ 00681 00682 00683 static INLINE int GetHashSizeByType(int type) 00684 { 00685 if (!(type == MD5 || type == SHA || type == SHA256 || type == SHA384 00686 || type == SHA512 || type == BLAKE2B_ID)) 00687 return BAD_FUNC_ARG; 00688 00689 switch (type) { 00690 #ifndef NO_MD5 00691 case MD5: 00692 return MD5_DIGEST_SIZE; 00693 break; 00694 #endif 00695 00696 #ifndef NO_SHA 00697 case SHA: 00698 return SHA_DIGEST_SIZE; 00699 break; 00700 #endif 00701 00702 #ifndef NO_SHA256 00703 case SHA256: 00704 return SHA256_DIGEST_SIZE; 00705 break; 00706 #endif 00707 00708 #ifdef CYASSL_SHA384 00709 case SHA384: 00710 return SHA384_DIGEST_SIZE; 00711 break; 00712 #endif 00713 00714 #ifdef CYASSL_SHA512 00715 case SHA512: 00716 return SHA512_DIGEST_SIZE; 00717 break; 00718 #endif 00719 00720 #ifdef HAVE_BLAKE2 00721 case BLAKE2B_ID: 00722 return BLAKE2B_OUTBYTES; 00723 break; 00724 #endif 00725 00726 default: 00727 return BAD_FUNC_ARG; 00728 break; 00729 } 00730 } 00731 00732 00733 /* HMAC-KDF with hash type, optional salt and info, return 0 on success */ 00734 int HKDF(int type, const byte* inKey, word32 inKeySz, 00735 const byte* salt, word32 saltSz, 00736 const byte* info, word32 infoSz, 00737 byte* out, word32 outSz) 00738 { 00739 Hmac myHmac; 00740 #ifdef CYASSL_SMALL_STACK 00741 byte* tmp; 00742 byte* prk; 00743 #else 00744 byte tmp[MAX_DIGEST_SIZE]; /* localSalt helper and T */ 00745 byte prk[MAX_DIGEST_SIZE]; 00746 #endif 00747 const byte* localSalt; /* either points to user input or tmp */ 00748 int hashSz = GetHashSizeByType(type); 00749 word32 outIdx = 0; 00750 byte n = 0x1; 00751 int ret; 00752 00753 if (hashSz < 0) 00754 return BAD_FUNC_ARG; 00755 00756 #ifdef CYASSL_SMALL_STACK 00757 tmp = (byte*)XMALLOC(MAX_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00758 if (tmp == NULL) 00759 return MEMORY_E; 00760 00761 prk = (byte*)XMALLOC(MAX_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00762 if (prk == NULL) { 00763 XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00764 return MEMORY_E; 00765 } 00766 #endif 00767 00768 localSalt = salt; 00769 if (localSalt == NULL) { 00770 XMEMSET(tmp, 0, hashSz); 00771 localSalt = tmp; 00772 saltSz = hashSz; 00773 } 00774 00775 do { 00776 ret = HmacSetKey(&myHmac, type, localSalt, saltSz); 00777 if (ret != 0) 00778 break; 00779 ret = HmacUpdate(&myHmac, inKey, inKeySz); 00780 if (ret != 0) 00781 break; 00782 ret = HmacFinal(&myHmac, prk); 00783 } while (0); 00784 00785 if (ret == 0) { 00786 while (outIdx < outSz) { 00787 int tmpSz = (n == 1) ? 0 : hashSz; 00788 word32 left = outSz - outIdx; 00789 00790 ret = HmacSetKey(&myHmac, type, prk, hashSz); 00791 if (ret != 0) 00792 break; 00793 ret = HmacUpdate(&myHmac, tmp, tmpSz); 00794 if (ret != 0) 00795 break; 00796 ret = HmacUpdate(&myHmac, info, infoSz); 00797 if (ret != 0) 00798 break; 00799 ret = HmacUpdate(&myHmac, &n, 1); 00800 if (ret != 0) 00801 break; 00802 ret = HmacFinal(&myHmac, tmp); 00803 if (ret != 0) 00804 break; 00805 00806 left = min(left, (word32)hashSz); 00807 XMEMCPY(out+outIdx, tmp, left); 00808 00809 outIdx += hashSz; 00810 n++; 00811 } 00812 } 00813 00814 #ifdef CYASSL_SMALL_STACK 00815 XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00816 XFREE(prk, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00817 #endif 00818 00819 return ret; 00820 } 00821 00822 #endif /* HAVE_HKDF */ 00823 00824 #endif /* NO_HMAC */ 00825
Generated on Wed Jul 13 2022 02:33:56 by
