Xuyi Wang / wolfcrypt

Dependents:   OS

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers hmac.c Source File

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