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