diff options
Diffstat (limited to 'FreeRTOS-Plus/Source/WolfSSL/wolfcrypt/src/hmac.c')
-rw-r--r-- | FreeRTOS-Plus/Source/WolfSSL/wolfcrypt/src/hmac.c | 1619 |
1 files changed, 1015 insertions, 604 deletions
diff --git a/FreeRTOS-Plus/Source/WolfSSL/wolfcrypt/src/hmac.c b/FreeRTOS-Plus/Source/WolfSSL/wolfcrypt/src/hmac.c index 242adfa55..bcebc1ce2 100644 --- a/FreeRTOS-Plus/Source/WolfSSL/wolfcrypt/src/hmac.c +++ b/FreeRTOS-Plus/Source/WolfSSL/wolfcrypt/src/hmac.c @@ -1,8 +1,8 @@ -/* hmac.h +/* hmac.c * - * Copyright (C) 2006-2015 wolfSSL Inc. + * Copyright (C) 2006-2020 wolfSSL Inc. * - * This file is part of wolfSSL. (formerly known as CyaSSL) + * This file is part of wolfSSL. * * wolfSSL is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,170 +16,298 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ + #ifdef HAVE_CONFIG_H #include <config.h> #endif #include <wolfssl/wolfcrypt/settings.h> +#include <wolfssl/wolfcrypt/error-crypt.h> #ifndef NO_HMAC -#include <wolfssl/wolfcrypt/hmac.h> +#if defined(HAVE_FIPS) && \ + defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2) -#ifdef HAVE_FIPS -/* does init */ -int wc_HmacSetKey(Hmac* hmac, int type, const byte* key, word32 keySz) -{ - return HmacSetKey_fips(hmac, type, key, keySz); -} + /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */ + #define FIPS_NO_WRAPPERS + #ifdef USE_WINDOWS_API + #pragma code_seg(".fipsA$b") + #pragma const_seg(".fipsB$b") + #endif +#endif -int wc_HmacUpdate(Hmac* hmac, const byte* in, word32 sz) -{ - return HmacUpdate_fips(hmac, in, sz); -} +#include <wolfssl/wolfcrypt/hmac.h> +#ifdef WOLF_CRYPTO_CB + #include <wolfssl/wolfcrypt/cryptocb.h> +#endif + +#ifdef NO_INLINE + #include <wolfssl/wolfcrypt/misc.h> +#else + #define WOLFSSL_MISC_INCLUDED + #include <wolfcrypt/src/misc.c> +#endif -int wc_HmacFinal(Hmac* hmac, byte* out) -{ - return HmacFinal_fips(hmac, out); -} +/* fips wrapper calls, user can call direct */ +/* If building for old FIPS. */ +#if defined(HAVE_FIPS) && \ + (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2)) -#ifdef HAVE_CAVIUM - int wc_HmacInitCavium(Hmac* hmac, int i) + /* does init */ + int wc_HmacSetKey(Hmac* hmac, int type, const byte* key, word32 keySz) { - return HmacInitCavium(hmac, i); + if (hmac == NULL || (key == NULL && keySz != 0) || + !(type == WC_MD5 || type == WC_SHA || type == WC_SHA256 || + type == WC_SHA384 || type == WC_SHA512)) { + return BAD_FUNC_ARG; + } + + return HmacSetKey_fips(hmac, type, key, keySz); } + int wc_HmacUpdate(Hmac* hmac, const byte* in, word32 sz) + { + if (hmac == NULL || (in == NULL && sz > 0)) { + return BAD_FUNC_ARG; + } + return HmacUpdate_fips(hmac, in, sz); + } + int wc_HmacFinal(Hmac* hmac, byte* out) + { + if (hmac == NULL) { + return BAD_FUNC_ARG; + } - void wc_HmacFreeCavium(Hmac* hmac) + return HmacFinal_fips(hmac, out); + } + int wolfSSL_GetHmacMaxSize(void) { - HmacFreeCavium(hmac); + return CyaSSL_GetHmacMaxSize(); } -#endif -int wolfSSL_GetHmacMaxSize(void) -{ - return CyaSSL_GetHmacMaxSize(); -} - -#ifdef HAVE_HKDF + int wc_HmacInit(Hmac* hmac, void* heap, int devId) + { + (void)hmac; + (void)heap; + (void)devId; + /* FIPS doesn't support: + return HmacInit(hmac, heap, devId); */ + return 0; + } + void wc_HmacFree(Hmac* hmac) + { + (void)hmac; + /* FIPS doesn't support: + HmacFree(hmac); */ + } -int wc_HKDF(int type, const byte* inKey, word32 inKeySz, + #ifdef HAVE_HKDF + int wc_HKDF(int type, const byte* inKey, word32 inKeySz, const byte* salt, word32 saltSz, const byte* info, word32 infoSz, byte* out, word32 outSz) -{ - return HKDF(type, inKey, inKeySz, salt, saltSz, info, infoSz, out, outSz); -} - - -#endif /* HAVE_HKDF */ -#else /* else build without fips */ -#ifdef WOLFSSL_PIC32MZ_HASH - -#define wc_InitMd5 wc_InitMd5_sw -#define wc_Md5Update wc_Md5Update_sw -#define wc_Md5Final wc_Md5Final_sw + { + return HKDF(type, inKey, inKeySz, salt, saltSz, + info, infoSz, out, outSz); + } + #endif /* HAVE_HKDF */ -#define wc_InitSha wc_InitSha_sw -#define wc_ShaUpdate wc_ShaUpdate_sw -#define wc_ShaFinal wc_ShaFinal_sw +#else /* else build without fips, or for new fips */ -#define wc_InitSha256 wc_InitSha256_sw -#define wc_Sha256Update wc_Sha256Update_sw -#define wc_Sha256Final wc_Sha256Final_sw -#endif +int wc_HmacSizeByType(int type) +{ + int ret; -#ifdef HAVE_FIPS - /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */ - #define FIPS_NO_WRAPPERS -#endif + if (!(type == WC_MD5 || type == WC_SHA || + type == WC_SHA224 || type == WC_SHA256 || + type == WC_SHA384 || type == WC_SHA512 || + type == WC_SHA3_224 || type == WC_SHA3_256 || + type == WC_SHA3_384 || type == WC_SHA3_512)) { + return BAD_FUNC_ARG; + } -#include <wolfssl/wolfcrypt/error-crypt.h> + switch (type) { + #ifndef NO_MD5 + case WC_MD5: + ret = WC_MD5_DIGEST_SIZE; + break; + #endif /* !NO_MD5 */ + + #ifndef NO_SHA + case WC_SHA: + ret = WC_SHA_DIGEST_SIZE; + break; + #endif /* !NO_SHA */ + + #ifdef WOLFSSL_SHA224 + case WC_SHA224: + ret = WC_SHA224_DIGEST_SIZE; + break; + #endif /* WOLFSSL_SHA224 */ + + #ifndef NO_SHA256 + case WC_SHA256: + ret = WC_SHA256_DIGEST_SIZE; + break; + #endif /* !NO_SHA256 */ + + #ifdef WOLFSSL_SHA384 + case WC_SHA384: + ret = WC_SHA384_DIGEST_SIZE; + break; + #endif /* WOLFSSL_SHA384 */ + #ifdef WOLFSSL_SHA512 + case WC_SHA512: + ret = WC_SHA512_DIGEST_SIZE; + break; + #endif /* WOLFSSL_SHA512 */ + + #ifdef WOLFSSL_SHA3 + case WC_SHA3_224: + ret = WC_SHA3_224_DIGEST_SIZE; + break; + + case WC_SHA3_256: + ret = WC_SHA3_256_DIGEST_SIZE; + break; + + case WC_SHA3_384: + ret = WC_SHA3_384_DIGEST_SIZE; + break; + + case WC_SHA3_512: + ret = WC_SHA3_512_DIGEST_SIZE; + break; + + #endif + default: + ret = BAD_FUNC_ARG; + break; + } -#ifdef HAVE_CAVIUM - static void HmacCaviumFinal(Hmac* hmac, byte* hash); - static void HmacCaviumUpdate(Hmac* hmac, const byte* msg, word32 length); - static void HmacCaviumSetKey(Hmac* hmac, int type, const byte* key, - word32 length); -#endif + return ret; +} -static int InitHmac(Hmac* hmac, int type) +int _InitHmac(Hmac* hmac, int type, void* heap) { int ret = 0; - hmac->innerHashKeyed = 0; - hmac->macType = (byte)type; - - if (!(type == MD5 || type == SHA || type == SHA256 || type == SHA384 - || type == SHA512 || type == BLAKE2B_ID)) - return BAD_FUNC_ARG; - switch (type) { - #ifndef NO_MD5 - case MD5: - wc_InitMd5(&hmac->hash.md5); - break; - #endif - - #ifndef NO_SHA - case SHA: + #ifndef NO_MD5 + case WC_MD5: + ret = wc_InitMd5(&hmac->hash.md5); + break; + #endif /* !NO_MD5 */ + + #ifndef NO_SHA + case WC_SHA: ret = wc_InitSha(&hmac->hash.sha); - break; - #endif - - #ifndef NO_SHA256 - case SHA256: + break; + #endif /* !NO_SHA */ + + #ifdef WOLFSSL_SHA224 + case WC_SHA224: + ret = wc_InitSha224(&hmac->hash.sha224); + break; + #endif /* WOLFSSL_SHA224 */ + + #ifndef NO_SHA256 + case WC_SHA256: ret = wc_InitSha256(&hmac->hash.sha256); - break; - #endif - - #ifdef WOLFSSL_SHA384 - case SHA384: + break; + #endif /* !NO_SHA256 */ + + #ifdef WOLFSSL_SHA384 + case WC_SHA384: ret = wc_InitSha384(&hmac->hash.sha384); - break; - #endif - - #ifdef WOLFSSL_SHA512 - case SHA512: + break; + #endif /* WOLFSSL_SHA384 */ + #ifdef WOLFSSL_SHA512 + case WC_SHA512: ret = wc_InitSha512(&hmac->hash.sha512); - break; - #endif - - #ifdef HAVE_BLAKE2 - case BLAKE2B_ID: - ret = wc_InitBlake2b(&hmac->hash.blake2b, BLAKE2B_256); - break; - #endif - + break; + #endif /* WOLFSSL_SHA512 */ + + #ifdef WOLFSSL_SHA3 + #ifndef WOLFSSL_NOSHA3_224 + case WC_SHA3_224: + ret = wc_InitSha3_224(&hmac->hash.sha3, heap, INVALID_DEVID); + break; + #endif + #ifndef WOLFSSL_NOSHA3_256 + case WC_SHA3_256: + ret = wc_InitSha3_256(&hmac->hash.sha3, heap, INVALID_DEVID); + break; + #endif + #ifndef WOLFSSL_NOSHA3_384 + case WC_SHA3_384: + ret = wc_InitSha3_384(&hmac->hash.sha3, heap, INVALID_DEVID); + break; + #endif + #ifndef WOLFSSL_NOSHA3_512 + case WC_SHA3_512: + ret = wc_InitSha3_512(&hmac->hash.sha3, heap, INVALID_DEVID); + break; + #endif + #endif + default: - return BAD_FUNC_ARG; + ret = BAD_FUNC_ARG; + break; } + /* default to NULL heap hint or test value */ +#ifdef WOLFSSL_HEAP_TEST + hmac->heap = (void)WOLFSSL_HEAP_TEST; +#else + hmac->heap = heap; +#endif /* WOLFSSL_HEAP_TEST */ + return ret; } int wc_HmacSetKey(Hmac* hmac, int type, const byte* key, word32 length) { - byte* ip = (byte*) hmac->ipad; - byte* op = (byte*) hmac->opad; + byte* ip; + byte* op; word32 i, hmac_block_size = 0; - int ret; + int ret = 0; + void* heap = NULL; + + if (hmac == NULL || (key == NULL && length != 0) || + !(type == WC_MD5 || type == WC_SHA || + type == WC_SHA224 || type == WC_SHA256 || + type == WC_SHA384 || type == WC_SHA512 || + type == WC_SHA3_224 || type == WC_SHA3_256 || + type == WC_SHA3_384 || type == WC_SHA3_512)) { + return BAD_FUNC_ARG; + } -#ifdef HAVE_CAVIUM - if (hmac->magic == WOLFSSL_HMAC_CAVIUM_MAGIC) - return HmacCaviumSetKey(hmac, type, key, length); +#ifndef HAVE_FIPS + /* if set key has already been run then make sure and free existing */ + /* This is for async and PIC32MZ situations, and just normally OK, + provided the user calls wc_HmacInit() first. That function is not + available in FIPS builds. In current FIPS builds, the hashes are + not allocating resources. */ + if (hmac->macType != WC_HASH_TYPE_NONE) { + wc_HmacFree(hmac); + } #endif - ret = InitHmac(hmac, type); + hmac->innerHashKeyed = 0; + hmac->macType = (byte)type; + + ret = _InitHmac(hmac, type, heap); if (ret != 0) return ret; @@ -188,138 +316,255 @@ int wc_HmacSetKey(Hmac* hmac, int type, const byte* key, word32 length) return HMAC_MIN_KEYLEN_E; #endif +#ifdef WOLF_CRYPTO_CB + hmac->keyRaw = key; /* use buffer directly */ + hmac->keyLen = length; +#endif + + ip = (byte*)hmac->ipad; + op = (byte*)hmac->opad; + switch (hmac->macType) { - #ifndef NO_MD5 - case MD5: - { - hmac_block_size = MD5_BLOCK_SIZE; - if (length <= MD5_BLOCK_SIZE) { - XMEMCPY(ip, key, length); + #ifndef NO_MD5 + case WC_MD5: + hmac_block_size = WC_MD5_BLOCK_SIZE; + if (length <= WC_MD5_BLOCK_SIZE) { + if (key != NULL) { + XMEMCPY(ip, key, length); + } } else { - wc_Md5Update(&hmac->hash.md5, key, length); - wc_Md5Final(&hmac->hash.md5, ip); - length = MD5_DIGEST_SIZE; + ret = wc_Md5Update(&hmac->hash.md5, key, length); + if (ret != 0) + break; + ret = wc_Md5Final(&hmac->hash.md5, ip); + if (ret != 0) + break; + length = WC_MD5_DIGEST_SIZE; } - } - break; - #endif - - #ifndef NO_SHA - case SHA: - { - hmac_block_size = SHA_BLOCK_SIZE; - if (length <= SHA_BLOCK_SIZE) { - XMEMCPY(ip, key, length); + break; + #endif /* !NO_MD5 */ + + #ifndef NO_SHA + case WC_SHA: + hmac_block_size = WC_SHA_BLOCK_SIZE; + if (length <= WC_SHA_BLOCK_SIZE) { + if (key != NULL) { + XMEMCPY(ip, key, length); + } } else { - wc_ShaUpdate(&hmac->hash.sha, key, length); - wc_ShaFinal(&hmac->hash.sha, ip); - length = SHA_DIGEST_SIZE; + ret = wc_ShaUpdate(&hmac->hash.sha, key, length); + if (ret != 0) + break; + ret = wc_ShaFinal(&hmac->hash.sha, ip); + if (ret != 0) + break; + + length = WC_SHA_DIGEST_SIZE; } - } - break; - #endif + break; + #endif /* !NO_SHA */ + + #ifdef WOLFSSL_SHA224 + case WC_SHA224: + hmac_block_size = WC_SHA224_BLOCK_SIZE; + if (length <= WC_SHA224_BLOCK_SIZE) { + if (key != NULL) { + XMEMCPY(ip, key, length); + } + } + else { + ret = wc_Sha224Update(&hmac->hash.sha224, key, length); + if (ret != 0) + break; + ret = wc_Sha224Final(&hmac->hash.sha224, ip); + if (ret != 0) + break; - #ifndef NO_SHA256 - case SHA256: - { - hmac_block_size = SHA256_BLOCK_SIZE; - if (length <= SHA256_BLOCK_SIZE) { - XMEMCPY(ip, key, length); + length = WC_SHA224_DIGEST_SIZE; + } + break; + #endif /* WOLFSSL_SHA224 */ + #ifndef NO_SHA256 + case WC_SHA256: + hmac_block_size = WC_SHA256_BLOCK_SIZE; + if (length <= WC_SHA256_BLOCK_SIZE) { + if (key != NULL) { + XMEMCPY(ip, key, length); + } } else { ret = wc_Sha256Update(&hmac->hash.sha256, key, length); if (ret != 0) - return ret; - + break; ret = wc_Sha256Final(&hmac->hash.sha256, ip); if (ret != 0) - return ret; + break; - length = SHA256_DIGEST_SIZE; + length = WC_SHA256_DIGEST_SIZE; } - } - break; - #endif - - #ifdef WOLFSSL_SHA384 - case SHA384: - { - hmac_block_size = SHA384_BLOCK_SIZE; - if (length <= SHA384_BLOCK_SIZE) { - XMEMCPY(ip, key, length); + break; + #endif /* !NO_SHA256 */ + + #ifdef WOLFSSL_SHA384 + case WC_SHA384: + hmac_block_size = WC_SHA384_BLOCK_SIZE; + if (length <= WC_SHA384_BLOCK_SIZE) { + if (key != NULL) { + XMEMCPY(ip, key, length); + } } else { ret = wc_Sha384Update(&hmac->hash.sha384, key, length); if (ret != 0) - return ret; - + break; ret = wc_Sha384Final(&hmac->hash.sha384, ip); if (ret != 0) - return ret; + break; - length = SHA384_DIGEST_SIZE; + length = WC_SHA384_DIGEST_SIZE; } - } - break; - #endif - - #ifdef WOLFSSL_SHA512 - case SHA512: - { - hmac_block_size = SHA512_BLOCK_SIZE; - if (length <= SHA512_BLOCK_SIZE) { - XMEMCPY(ip, key, length); + break; + #endif /* WOLFSSL_SHA384 */ + #ifdef WOLFSSL_SHA512 + case WC_SHA512: + hmac_block_size = WC_SHA512_BLOCK_SIZE; + if (length <= WC_SHA512_BLOCK_SIZE) { + if (key != NULL) { + XMEMCPY(ip, key, length); + } } else { ret = wc_Sha512Update(&hmac->hash.sha512, key, length); if (ret != 0) - return ret; - + break; ret = wc_Sha512Final(&hmac->hash.sha512, ip); if (ret != 0) - return ret; + break; - length = SHA512_DIGEST_SIZE; + length = WC_SHA512_DIGEST_SIZE; } - } - break; - #endif + break; + #endif /* WOLFSSL_SHA512 */ + + #ifdef WOLFSSL_SHA3 + #ifndef WOLFSSL_NOSHA3_224 + case WC_SHA3_224: + hmac_block_size = WC_SHA3_224_BLOCK_SIZE; + if (length <= WC_SHA3_224_BLOCK_SIZE) { + if (key != NULL) { + XMEMCPY(ip, key, length); + } + } + else { + ret = wc_Sha3_224_Update(&hmac->hash.sha3, key, length); + if (ret != 0) + break; + ret = wc_Sha3_224_Final(&hmac->hash.sha3, ip); + if (ret != 0) + break; - #ifdef HAVE_BLAKE2 - case BLAKE2B_ID: - { - hmac_block_size = BLAKE2B_BLOCKBYTES; - if (length <= BLAKE2B_BLOCKBYTES) { - XMEMCPY(ip, key, length); + length = WC_SHA3_224_DIGEST_SIZE; + } + break; + #endif + #ifndef WOLFSSL_NOSHA3_256 + case WC_SHA3_256: + hmac_block_size = WC_SHA3_256_BLOCK_SIZE; + if (length <= WC_SHA3_256_BLOCK_SIZE) { + if (key != NULL) { + XMEMCPY(ip, key, length); + } + } + else { + ret = wc_Sha3_256_Update(&hmac->hash.sha3, key, length); + if (ret != 0) + break; + ret = wc_Sha3_256_Final(&hmac->hash.sha3, ip); + if (ret != 0) + break; + + length = WC_SHA3_256_DIGEST_SIZE; + } + break; + #endif + #ifndef WOLFSSL_NOSHA3_384 + case WC_SHA3_384: + hmac_block_size = WC_SHA3_384_BLOCK_SIZE; + if (length <= WC_SHA3_384_BLOCK_SIZE) { + if (key != NULL) { + XMEMCPY(ip, key, length); + } } else { - ret = wc_Blake2bUpdate(&hmac->hash.blake2b, key, length); + ret = wc_Sha3_384_Update(&hmac->hash.sha3, key, length); if (ret != 0) - return ret; + break; + ret = wc_Sha3_384_Final(&hmac->hash.sha3, ip); + if (ret != 0) + break; - ret = wc_Blake2bFinal(&hmac->hash.blake2b, ip, BLAKE2B_256); + length = WC_SHA3_384_DIGEST_SIZE; + } + break; + #endif + #ifndef WOLFSSL_NOSHA3_512 + case WC_SHA3_512: + hmac_block_size = WC_SHA3_512_BLOCK_SIZE; + if (length <= WC_SHA3_512_BLOCK_SIZE) { + if (key != NULL) { + XMEMCPY(ip, key, length); + } + } + else { + ret = wc_Sha3_512_Update(&hmac->hash.sha3, key, length); + if (ret != 0) + break; + ret = wc_Sha3_512_Final(&hmac->hash.sha3, ip); if (ret != 0) - return ret; + break; - length = BLAKE2B_256; + length = WC_SHA3_512_DIGEST_SIZE; } - } - break; - #endif + break; + #endif + #endif /* WOLFSSL_SHA3 */ default: return BAD_FUNC_ARG; } - if (length < hmac_block_size) - XMEMSET(ip + length, 0, hmac_block_size - length); - for(i = 0; i < hmac_block_size; i++) { - op[i] = ip[i] ^ OPAD; - ip[i] ^= IPAD; +#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC) + if (hmac->asyncDev.marker == WOLFSSL_ASYNC_MARKER_HMAC) { + #if defined(HAVE_INTEL_QA) || defined(HAVE_CAVIUM) + #ifdef HAVE_INTEL_QA + if (IntelQaHmacGetType(hmac->macType, NULL) == 0) + #endif + { + if (length > hmac_block_size) + length = hmac_block_size; + /* update key length */ + hmac->keyLen = (word16)length; + + return ret; + } + /* no need to pad below */ + #endif + } +#endif + + if (ret == 0) { + if (length < hmac_block_size) + XMEMSET(ip + length, 0, hmac_block_size - length); + + for(i = 0; i < hmac_block_size; i++) { + op[i] = ip[i] ^ OPAD; + ip[i] ^= IPAD; + } } - return 0; + + return ret; } @@ -328,59 +573,79 @@ static int HmacKeyInnerHash(Hmac* hmac) int ret = 0; switch (hmac->macType) { - #ifndef NO_MD5 - case MD5: - wc_Md5Update(&hmac->hash.md5, (byte*) hmac->ipad, MD5_BLOCK_SIZE); - break; - #endif - - #ifndef NO_SHA - case SHA: - wc_ShaUpdate(&hmac->hash.sha, (byte*) hmac->ipad, SHA_BLOCK_SIZE); - break; - #endif - - #ifndef NO_SHA256 - case SHA256: - ret = wc_Sha256Update(&hmac->hash.sha256, - (byte*) hmac->ipad, SHA256_BLOCK_SIZE); - if (ret != 0) - return ret; - break; - #endif - - #ifdef WOLFSSL_SHA384 - case SHA384: - ret = wc_Sha384Update(&hmac->hash.sha384, - (byte*) hmac->ipad, SHA384_BLOCK_SIZE); - if (ret != 0) - return ret; - break; - #endif - - #ifdef WOLFSSL_SHA512 - case SHA512: - ret = wc_Sha512Update(&hmac->hash.sha512, - (byte*) hmac->ipad, SHA512_BLOCK_SIZE); - if (ret != 0) - return ret; - break; - #endif - - #ifdef HAVE_BLAKE2 - case BLAKE2B_ID: - ret = wc_Blake2bUpdate(&hmac->hash.blake2b, - (byte*) hmac->ipad,BLAKE2B_BLOCKBYTES); - if (ret != 0) - return ret; - break; - #endif + #ifndef NO_MD5 + case WC_MD5: + ret = wc_Md5Update(&hmac->hash.md5, (byte*)hmac->ipad, + WC_MD5_BLOCK_SIZE); + break; + #endif /* !NO_MD5 */ + + #ifndef NO_SHA + case WC_SHA: + ret = wc_ShaUpdate(&hmac->hash.sha, (byte*)hmac->ipad, + WC_SHA_BLOCK_SIZE); + break; + #endif /* !NO_SHA */ + + #ifdef WOLFSSL_SHA224 + case WC_SHA224: + ret = wc_Sha224Update(&hmac->hash.sha224, (byte*)hmac->ipad, + WC_SHA224_BLOCK_SIZE); + break; + #endif /* WOLFSSL_SHA224 */ + #ifndef NO_SHA256 + case WC_SHA256: + ret = wc_Sha256Update(&hmac->hash.sha256, (byte*)hmac->ipad, + WC_SHA256_BLOCK_SIZE); + break; + #endif /* !NO_SHA256 */ + + #ifdef WOLFSSL_SHA384 + case WC_SHA384: + ret = wc_Sha384Update(&hmac->hash.sha384, (byte*)hmac->ipad, + WC_SHA384_BLOCK_SIZE); + break; + #endif /* WOLFSSL_SHA384 */ + #ifdef WOLFSSL_SHA512 + case WC_SHA512: + ret = wc_Sha512Update(&hmac->hash.sha512, (byte*)hmac->ipad, + WC_SHA512_BLOCK_SIZE); + break; + #endif /* WOLFSSL_SHA512 */ + + #ifdef WOLFSSL_SHA3 + #ifndef WOLFSSL_NOSHA3_224 + case WC_SHA3_224: + ret = wc_Sha3_224_Update(&hmac->hash.sha3, (byte*)hmac->ipad, + WC_SHA3_224_BLOCK_SIZE); + break; + #endif + #ifndef WOLFSSL_NOSHA3_256 + case WC_SHA3_256: + ret = wc_Sha3_256_Update(&hmac->hash.sha3, (byte*)hmac->ipad, + WC_SHA3_256_BLOCK_SIZE); + break; + #endif + #ifndef WOLFSSL_NOSHA3_384 + case WC_SHA3_384: + ret = wc_Sha3_384_Update(&hmac->hash.sha3, (byte*)hmac->ipad, + WC_SHA3_384_BLOCK_SIZE); + break; + #endif + #ifndef WOLFSSL_NOSHA3_512 + case WC_SHA3_512: + ret = wc_Sha3_512_Update(&hmac->hash.sha3, (byte*)hmac->ipad, + WC_SHA3_512_BLOCK_SIZE); + break; + #endif + #endif /* WOLFSSL_SHA3 */ default: - break; + break; } - hmac->innerHashKeyed = 1; + if (ret == 0) + hmac->innerHashKeyed = WC_HMAC_INNER_HASH_KEYED_SW; return ret; } @@ -388,12 +653,33 @@ static int HmacKeyInnerHash(Hmac* hmac) int wc_HmacUpdate(Hmac* hmac, const byte* msg, word32 length) { - int ret; + int ret = 0; + + if (hmac == NULL || (msg == NULL && length > 0)) { + return BAD_FUNC_ARG; + } -#ifdef HAVE_CAVIUM - if (hmac->magic == WOLFSSL_HMAC_CAVIUM_MAGIC) - return HmacCaviumUpdate(hmac, msg, length); +#ifdef WOLF_CRYPTO_CB + if (hmac->devId != INVALID_DEVID) { + ret = wc_CryptoCb_Hmac(hmac, hmac->macType, msg, length, NULL); + if (ret != CRYPTOCB_UNAVAILABLE) + return ret; + /* fall-through when unavailable */ + ret = 0; /* reset error code */ + } #endif +#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC) + if (hmac->asyncDev.marker == WOLFSSL_ASYNC_MARKER_HMAC) { + #if defined(HAVE_CAVIUM) + return NitroxHmacUpdate(hmac, msg, length); + #elif defined(HAVE_INTEL_QA) + if (IntelQaHmacGetType(hmac->macType, NULL) == 0) { + return IntelQaHmac(&hmac->asyncDev, hmac->macType, + (byte*)hmac->ipad, hmac->keyLen, NULL, msg, length); + } + #endif + } +#endif /* WOLFSSL_ASYNC_CRYPT */ if (!hmac->innerHashKeyed) { ret = HmacKeyInnerHash(hmac); @@ -402,55 +688,69 @@ int wc_HmacUpdate(Hmac* hmac, const byte* msg, word32 length) } switch (hmac->macType) { - #ifndef NO_MD5 - case MD5: - wc_Md5Update(&hmac->hash.md5, msg, length); - break; - #endif - - #ifndef NO_SHA - case SHA: - wc_ShaUpdate(&hmac->hash.sha, msg, length); - break; - #endif - - #ifndef NO_SHA256 - case SHA256: + #ifndef NO_MD5 + case WC_MD5: + ret = wc_Md5Update(&hmac->hash.md5, msg, length); + break; + #endif /* !NO_MD5 */ + + #ifndef NO_SHA + case WC_SHA: + ret = wc_ShaUpdate(&hmac->hash.sha, msg, length); + break; + #endif /* !NO_SHA */ + + #ifdef WOLFSSL_SHA224 + case WC_SHA224: + ret = wc_Sha224Update(&hmac->hash.sha224, msg, length); + break; + #endif /* WOLFSSL_SHA224 */ + + #ifndef NO_SHA256 + case WC_SHA256: ret = wc_Sha256Update(&hmac->hash.sha256, msg, length); - if (ret != 0) - return ret; - break; - #endif + break; + #endif /* !NO_SHA256 */ - #ifdef WOLFSSL_SHA384 - case SHA384: + #ifdef WOLFSSL_SHA384 + case WC_SHA384: ret = wc_Sha384Update(&hmac->hash.sha384, msg, length); - if (ret != 0) - return ret; - break; - #endif - - #ifdef WOLFSSL_SHA512 - case SHA512: + break; + #endif /* WOLFSSL_SHA384 */ + #ifdef WOLFSSL_SHA512 + case WC_SHA512: ret = wc_Sha512Update(&hmac->hash.sha512, msg, length); - if (ret != 0) - return ret; - break; - #endif - - #ifdef HAVE_BLAKE2 - case BLAKE2B_ID: - ret = wc_Blake2bUpdate(&hmac->hash.blake2b, msg, length); - if (ret != 0) - return ret; - break; - #endif + break; + #endif /* WOLFSSL_SHA512 */ + + #ifdef WOLFSSL_SHA3 + #ifndef WOLFSSL_NOSHA3_224 + case WC_SHA3_224: + ret = wc_Sha3_224_Update(&hmac->hash.sha3, msg, length); + break; + #endif + #ifndef WOLFSSL_NOSHA3_256 + case WC_SHA3_256: + ret = wc_Sha3_256_Update(&hmac->hash.sha3, msg, length); + break; + #endif + #ifndef WOLFSSL_NOSHA3_384 + case WC_SHA3_384: + ret = wc_Sha3_384_Update(&hmac->hash.sha3, msg, length); + break; + #endif + #ifndef WOLFSSL_NOSHA3_512 + case WC_SHA3_512: + ret = wc_Sha3_512_Update(&hmac->hash.sha3, msg, length); + break; + #endif + #endif /* WOLFSSL_SHA3 */ default: - break; + break; } - return 0; + return ret; } @@ -458,10 +758,34 @@ int wc_HmacFinal(Hmac* hmac, byte* hash) { int ret; -#ifdef HAVE_CAVIUM - if (hmac->magic == WOLFSSL_HMAC_CAVIUM_MAGIC) - return HmacCaviumFinal(hmac, hash); + if (hmac == NULL || hash == NULL) { + return BAD_FUNC_ARG; + } + +#ifdef WOLF_CRYPTO_CB + if (hmac->devId != INVALID_DEVID) { + ret = wc_CryptoCb_Hmac(hmac, hmac->macType, NULL, 0, hash); + if (ret != CRYPTOCB_UNAVAILABLE) + return ret; + /* fall-through when unavailable */ + } #endif +#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC) + if (hmac->asyncDev.marker == WOLFSSL_ASYNC_MARKER_HMAC) { + int hashLen = wc_HmacSizeByType(hmac->macType); + if (hashLen <= 0) + return hashLen; + + #if defined(HAVE_CAVIUM) + return NitroxHmacFinal(hmac, hash, hashLen); + #elif defined(HAVE_INTEL_QA) + if (IntelQaHmacGetType(hmac->macType, NULL) == 0) { + return IntelQaHmac(&hmac->asyncDev, hmac->macType, + (byte*)hmac->ipad, hmac->keyLen, hash, NULL, hashLen); + } + #endif + } +#endif /* WOLFSSL_ASYNC_CRYPT */ if (!hmac->innerHashKeyed) { ret = HmacKeyInnerHash(hmac); @@ -470,377 +794,437 @@ int wc_HmacFinal(Hmac* hmac, byte* hash) } switch (hmac->macType) { - #ifndef NO_MD5 - case MD5: - { - wc_Md5Final(&hmac->hash.md5, (byte*) hmac->innerHash); - - wc_Md5Update(&hmac->hash.md5, (byte*) hmac->opad, MD5_BLOCK_SIZE); - wc_Md5Update(&hmac->hash.md5, - (byte*) hmac->innerHash, MD5_DIGEST_SIZE); - - wc_Md5Final(&hmac->hash.md5, hash); - } - break; - #endif - - #ifndef NO_SHA - case SHA: - { - wc_ShaFinal(&hmac->hash.sha, (byte*) hmac->innerHash); - - wc_ShaUpdate(&hmac->hash.sha, (byte*) hmac->opad, SHA_BLOCK_SIZE); - wc_ShaUpdate(&hmac->hash.sha, - (byte*) hmac->innerHash, SHA_DIGEST_SIZE); - - wc_ShaFinal(&hmac->hash.sha, hash); - } - break; - #endif - - #ifndef NO_SHA256 - case SHA256: - { - ret = wc_Sha256Final(&hmac->hash.sha256, (byte*) hmac->innerHash); + #ifndef NO_MD5 + case WC_MD5: + ret = wc_Md5Final(&hmac->hash.md5, (byte*)hmac->innerHash); if (ret != 0) - return ret; - - ret = wc_Sha256Update(&hmac->hash.sha256, - (byte*) hmac->opad, SHA256_BLOCK_SIZE); + break; + ret = wc_Md5Update(&hmac->hash.md5, (byte*)hmac->opad, + WC_MD5_BLOCK_SIZE); if (ret != 0) - return ret; - - ret = wc_Sha256Update(&hmac->hash.sha256, - (byte*) hmac->innerHash, SHA256_DIGEST_SIZE); + break; + ret = wc_Md5Update(&hmac->hash.md5, (byte*)hmac->innerHash, + WC_MD5_DIGEST_SIZE); if (ret != 0) - return ret; + break; + ret = wc_Md5Final(&hmac->hash.md5, hash); + break; + #endif /* !NO_MD5 */ - ret = wc_Sha256Final(&hmac->hash.sha256, hash); + #ifndef NO_SHA + case WC_SHA: + ret = wc_ShaFinal(&hmac->hash.sha, (byte*)hmac->innerHash); if (ret != 0) - return ret; - } - break; - #endif - - #ifdef WOLFSSL_SHA384 - case SHA384: - { - ret = wc_Sha384Final(&hmac->hash.sha384, (byte*) hmac->innerHash); + break; + ret = wc_ShaUpdate(&hmac->hash.sha, (byte*)hmac->opad, + WC_SHA_BLOCK_SIZE); if (ret != 0) - return ret; - - ret = wc_Sha384Update(&hmac->hash.sha384, - (byte*) hmac->opad, SHA384_BLOCK_SIZE); + break; + ret = wc_ShaUpdate(&hmac->hash.sha, (byte*)hmac->innerHash, + WC_SHA_DIGEST_SIZE); if (ret != 0) - return ret; + break; + ret = wc_ShaFinal(&hmac->hash.sha, hash); + break; + #endif /* !NO_SHA */ - ret = wc_Sha384Update(&hmac->hash.sha384, - (byte*) hmac->innerHash, SHA384_DIGEST_SIZE); + #ifdef WOLFSSL_SHA224 + case WC_SHA224: + ret = wc_Sha224Final(&hmac->hash.sha224, (byte*)hmac->innerHash); + if (ret != 0) + break; + ret = wc_Sha224Update(&hmac->hash.sha224, (byte*)hmac->opad, + WC_SHA224_BLOCK_SIZE); + if (ret != 0) + break; + ret = wc_Sha224Update(&hmac->hash.sha224, (byte*)hmac->innerHash, + WC_SHA224_DIGEST_SIZE); + if (ret != 0) + break; + ret = wc_Sha224Final(&hmac->hash.sha224, hash); + if (ret != 0) + break; + break; + #endif /* WOLFSSL_SHA224 */ + #ifndef NO_SHA256 + case WC_SHA256: + ret = wc_Sha256Final(&hmac->hash.sha256, (byte*)hmac->innerHash); if (ret != 0) - return ret; + break; + ret = wc_Sha256Update(&hmac->hash.sha256, (byte*)hmac->opad, + WC_SHA256_BLOCK_SIZE); + if (ret != 0) + break; + ret = wc_Sha256Update(&hmac->hash.sha256, (byte*)hmac->innerHash, + WC_SHA256_DIGEST_SIZE); + if (ret != 0) + break; + ret = wc_Sha256Final(&hmac->hash.sha256, hash); + break; + #endif /* !NO_SHA256 */ + #ifdef WOLFSSL_SHA384 + case WC_SHA384: + ret = wc_Sha384Final(&hmac->hash.sha384, (byte*)hmac->innerHash); + if (ret != 0) + break; + ret = wc_Sha384Update(&hmac->hash.sha384, (byte*)hmac->opad, + WC_SHA384_BLOCK_SIZE); + if (ret != 0) + break; + ret = wc_Sha384Update(&hmac->hash.sha384, (byte*)hmac->innerHash, + WC_SHA384_DIGEST_SIZE); + if (ret != 0) + break; ret = wc_Sha384Final(&hmac->hash.sha384, hash); + break; + #endif /* WOLFSSL_SHA384 */ + #ifdef WOLFSSL_SHA512 + case WC_SHA512: + ret = wc_Sha512Final(&hmac->hash.sha512, (byte*)hmac->innerHash); if (ret != 0) - return ret; - } - break; - #endif - - #ifdef WOLFSSL_SHA512 - case SHA512: - { - ret = wc_Sha512Final(&hmac->hash.sha512, (byte*) hmac->innerHash); + break; + ret = wc_Sha512Update(&hmac->hash.sha512, (byte*)hmac->opad, + WC_SHA512_BLOCK_SIZE); if (ret != 0) - return ret; - - ret = wc_Sha512Update(&hmac->hash.sha512, - (byte*) hmac->opad, SHA512_BLOCK_SIZE); + break; + ret = wc_Sha512Update(&hmac->hash.sha512, (byte*)hmac->innerHash, + WC_SHA512_DIGEST_SIZE); if (ret != 0) - return ret; + break; + ret = wc_Sha512Final(&hmac->hash.sha512, hash); + break; + #endif /* WOLFSSL_SHA512 */ - ret = wc_Sha512Update(&hmac->hash.sha512, - (byte*) hmac->innerHash, SHA512_DIGEST_SIZE); + #ifdef WOLFSSL_SHA3 + #ifndef WOLFSSL_NOSHA3_224 + case WC_SHA3_224: + ret = wc_Sha3_224_Final(&hmac->hash.sha3, (byte*)hmac->innerHash); if (ret != 0) - return ret; - - ret = wc_Sha512Final(&hmac->hash.sha512, hash); + break; + ret = wc_Sha3_224_Update(&hmac->hash.sha3, (byte*)hmac->opad, + WC_SHA3_224_BLOCK_SIZE); if (ret != 0) - return ret; - } - break; - #endif - - #ifdef HAVE_BLAKE2 - case BLAKE2B_ID: - { - ret = wc_Blake2bFinal(&hmac->hash.blake2b, (byte*) hmac->innerHash, - BLAKE2B_256); + break; + ret = wc_Sha3_224_Update(&hmac->hash.sha3, (byte*)hmac->innerHash, + WC_SHA3_224_DIGEST_SIZE); if (ret != 0) - return ret; - - ret = wc_Blake2bUpdate(&hmac->hash.blake2b, - (byte*) hmac->opad, BLAKE2B_BLOCKBYTES); + break; + ret = wc_Sha3_224_Final(&hmac->hash.sha3, hash); + break; + #endif + #ifndef WOLFSSL_NOSHA3_256 + case WC_SHA3_256: + ret = wc_Sha3_256_Final(&hmac->hash.sha3, (byte*)hmac->innerHash); if (ret != 0) - return ret; - - ret = wc_Blake2bUpdate(&hmac->hash.blake2b, - (byte*) hmac->innerHash, BLAKE2B_256); + break; + ret = wc_Sha3_256_Update(&hmac->hash.sha3, (byte*)hmac->opad, + WC_SHA3_256_BLOCK_SIZE); if (ret != 0) - return ret; - - ret = wc_Blake2bFinal(&hmac->hash.blake2b, hash, BLAKE2B_256); + break; + ret = wc_Sha3_256_Update(&hmac->hash.sha3, (byte*)hmac->innerHash, + WC_SHA3_256_DIGEST_SIZE); if (ret != 0) - return ret; - } - break; - #endif + break; + ret = wc_Sha3_256_Final(&hmac->hash.sha3, hash); + break; + #endif + #ifndef WOLFSSL_NOSHA3_384 + case WC_SHA3_384: + ret = wc_Sha3_384_Final(&hmac->hash.sha3, (byte*)hmac->innerHash); + if (ret != 0) + break; + ret = wc_Sha3_384_Update(&hmac->hash.sha3, (byte*)hmac->opad, + WC_SHA3_384_BLOCK_SIZE); + if (ret != 0) + break; + ret = wc_Sha3_384_Update(&hmac->hash.sha3, (byte*)hmac->innerHash, + WC_SHA3_384_DIGEST_SIZE); + if (ret != 0) + break; + ret = wc_Sha3_384_Final(&hmac->hash.sha3, hash); + break; + #endif + #ifndef WOLFSSL_NOSHA3_512 + case WC_SHA3_512: + ret = wc_Sha3_512_Final(&hmac->hash.sha3, (byte*)hmac->innerHash); + if (ret != 0) + break; + ret = wc_Sha3_512_Update(&hmac->hash.sha3, (byte*)hmac->opad, + WC_SHA3_512_BLOCK_SIZE); + if (ret != 0) + break; + ret = wc_Sha3_512_Update(&hmac->hash.sha3, (byte*)hmac->innerHash, + WC_SHA3_512_DIGEST_SIZE); + if (ret != 0) + break; + ret = wc_Sha3_512_Final(&hmac->hash.sha3, hash); + break; + #endif + #endif /* WOLFSSL_SHA3 */ default: - break; + ret = BAD_FUNC_ARG; + break; } - hmac->innerHashKeyed = 0; + if (ret == 0) { + hmac->innerHashKeyed = 0; + } - return 0; + return ret; } -#ifdef HAVE_CAVIUM - -/* Initiliaze Hmac for use with Nitrox device */ -int wc_HmacInitCavium(Hmac* hmac, int devId) +/* Initialize Hmac for use with async device */ +int wc_HmacInit(Hmac* hmac, void* heap, int devId) { - if (hmac == NULL) - return -1; - - if (CspAllocContext(CONTEXT_SSL, &hmac->contextHandle, devId) != 0) - return -1; - - hmac->keyLen = 0; - hmac->dataLen = 0; - hmac->type = 0; - hmac->devId = devId; - hmac->magic = WOLFSSL_HMAC_CAVIUM_MAGIC; - hmac->data = NULL; /* buffered input data */ - - hmac->innerHashKeyed = 0; - - return 0; -} - + int ret = 0; -/* Free Hmac from use with Nitrox device */ -void wc_HmacFreeCavium(Hmac* hmac) -{ if (hmac == NULL) - return; + return BAD_FUNC_ARG; - CspFreeContext(CONTEXT_SSL, hmac->contextHandle, hmac->devId); - hmac->magic = 0; - XFREE(hmac->data, NULL, DYNAMIC_TYPE_CAVIUM_TMP); - hmac->data = NULL; -} + XMEMSET(hmac, 0, sizeof(Hmac)); + hmac->macType = WC_HASH_TYPE_NONE; + hmac->heap = heap; +#ifdef WOLF_CRYPTO_CB + hmac->devId = devId; + hmac->devCtx = NULL; +#endif +#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC) + ret = wolfAsync_DevCtxInit(&hmac->asyncDev, WOLFSSL_ASYNC_MARKER_HMAC, + hmac->heap, devId); +#else + (void)devId; +#endif /* WOLFSSL_ASYNC_CRYPT */ -static void HmacCaviumFinal(Hmac* hmac, byte* hash) -{ - word32 requestId; - - if (CspHmac(CAVIUM_BLOCKING, hmac->type, NULL, hmac->keyLen, - (byte*)hmac->ipad, hmac->dataLen, hmac->data, hash, &requestId, - hmac->devId) != 0) { - WOLFSSL_MSG("Cavium Hmac failed"); - } - hmac->innerHashKeyed = 0; /* tell update to start over if used again */ + return ret; } - -static void HmacCaviumUpdate(Hmac* hmac, const byte* msg, word32 length) +#ifdef HAVE_PKCS11 +int wc_HmacInit_Id(Hmac* hmac, unsigned char* id, int len, void* heap, + int devId) { - word16 add = (word16)length; - word32 total; - byte* tmp; + int ret = 0; - if (length > WOLFSSL_MAX_16BIT) { - WOLFSSL_MSG("Too big msg for cavium hmac"); - return; - } + if (hmac == NULL) + ret = BAD_FUNC_ARG; + if (ret == 0 && (len < 0 || len > HMAC_MAX_ID_LEN)) + ret = BUFFER_E; - if (hmac->innerHashKeyed == 0) { /* starting new */ - hmac->dataLen = 0; - hmac->innerHashKeyed = 1; + if (ret == 0) + ret = wc_HmacInit(hmac, heap, devId); + if (ret == 0) { + XMEMCPY(hmac->id, id, len); + hmac->idLen = len; } - total = add + hmac->dataLen; - if (total > WOLFSSL_MAX_16BIT) { - WOLFSSL_MSG("Too big msg for cavium hmac"); - return; - } + return ret; +} +#endif - tmp = XMALLOC(hmac->dataLen + add, NULL,DYNAMIC_TYPE_CAVIUM_TMP); - if (tmp == NULL) { - WOLFSSL_MSG("Out of memory for cavium update"); +/* Free Hmac from use with async device */ +void wc_HmacFree(Hmac* hmac) +{ + if (hmac == NULL) return; + +#ifdef WOLF_CRYPTO_CB + /* handle cleanup case where final is not called */ + if (hmac->devId != INVALID_DEVID && hmac->devCtx != NULL) { + int ret; + byte finalHash[WC_HMAC_BLOCK_SIZE]; + ret = wc_CryptoCb_Hmac(hmac, hmac->macType, NULL, 0, finalHash); + (void)ret; /* must ignore return code here */ + (void)finalHash; } - if (hmac->dataLen) - XMEMCPY(tmp, hmac->data, hmac->dataLen); - XMEMCPY(tmp + hmac->dataLen, msg, add); - - hmac->dataLen += add; - XFREE(hmac->data, NULL, DYNAMIC_TYPE_CAVIUM_TMP); - hmac->data = tmp; -} +#endif + switch (hmac->macType) { + #ifndef NO_MD5 + case WC_MD5: + wc_Md5Free(&hmac->hash.md5); + break; + #endif /* !NO_MD5 */ + + #ifndef NO_SHA + case WC_SHA: + wc_ShaFree(&hmac->hash.sha); + break; + #endif /* !NO_SHA */ + + #ifdef WOLFSSL_SHA224 + case WC_SHA224: + wc_Sha224Free(&hmac->hash.sha224); + break; + #endif /* WOLFSSL_SHA224 */ + #ifndef NO_SHA256 + case WC_SHA256: + wc_Sha256Free(&hmac->hash.sha256); + break; + #endif /* !NO_SHA256 */ + + #ifdef WOLFSSL_SHA384 + case WC_SHA384: + wc_Sha384Free(&hmac->hash.sha384); + break; + #endif /* WOLFSSL_SHA384 */ + #ifdef WOLFSSL_SHA512 + case WC_SHA512: + wc_Sha512Free(&hmac->hash.sha512); + break; + #endif /* WOLFSSL_SHA512 */ + + #ifdef WOLFSSL_SHA3 + #ifndef WOLFSSL_NOSHA3_224 + case WC_SHA3_224: + wc_Sha3_224_Free(&hmac->hash.sha3); + break; + #endif + #ifndef WOLFSSL_NOSHA3_256 + case WC_SHA3_256: + wc_Sha3_256_Free(&hmac->hash.sha3); + break; + #endif + #ifndef WOLFSSL_NOSHA3_384 + case WC_SHA3_384: + wc_Sha3_384_Free(&hmac->hash.sha3); + break; + #endif + #ifndef WOLFSSL_NOSHA3_512 + case WC_SHA3_512: + wc_Sha3_512_Free(&hmac->hash.sha3); + break; + #endif + #endif /* WOLFSSL_SHA3 */ -static void HmacCaviumSetKey(Hmac* hmac, int type, const byte* key, - word32 length) -{ - hmac->macType = (byte)type; - if (type == MD5) - hmac->type = MD5_TYPE; - else if (type == SHA) - hmac->type = SHA1_TYPE; - else if (type == SHA256) - hmac->type = SHA256_TYPE; - else { - WOLFSSL_MSG("unsupported cavium hmac type"); + default: + break; } - hmac->innerHashKeyed = 0; /* should we key Startup flag */ +#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC) + wolfAsync_DevCtxFree(&hmac->asyncDev, WOLFSSL_ASYNC_MARKER_HMAC); +#endif /* WOLFSSL_ASYNC_CRYPT */ - hmac->keyLen = (word16)length; - /* store key in ipad */ - XMEMCPY(hmac->ipad, key, length); + switch (hmac->macType) { + #ifndef NO_MD5 + case WC_MD5: + wc_Md5Free(&hmac->hash.md5); + break; + #endif /* !NO_MD5 */ + + #ifndef NO_SHA + case WC_SHA: + wc_ShaFree(&hmac->hash.sha); + break; + #endif /* !NO_SHA */ + + #ifdef WOLFSSL_SHA224 + case WC_SHA224: + wc_Sha224Free(&hmac->hash.sha224); + break; + #endif /* WOLFSSL_SHA224 */ + #ifndef NO_SHA256 + case WC_SHA256: + wc_Sha256Free(&hmac->hash.sha256); + break; + #endif /* !NO_SHA256 */ + + #ifdef WOLFSSL_SHA512 + #ifdef WOLFSSL_SHA384 + case WC_SHA384: + wc_Sha384Free(&hmac->hash.sha384); + break; + #endif /* WOLFSSL_SHA384 */ + case WC_SHA512: + wc_Sha512Free(&hmac->hash.sha512); + break; + #endif /* WOLFSSL_SHA512 */ + } } -#endif /* HAVE_CAVIUM */ - int wolfSSL_GetHmacMaxSize(void) { - return MAX_DIGEST_SIZE; + return WC_MAX_DIGEST_SIZE; } #ifdef HAVE_HKDF - -#ifndef WOLFSSL_HAVE_MIN -#define WOLFSSL_HAVE_MIN - - static INLINE word32 min(word32 a, word32 b) + /* HMAC-KDF-Extract. + * RFC 5869 - HMAC-based Extract-and-Expand Key Derivation Function (HKDF). + * + * type The hash algorithm type. + * salt The optional salt value. + * saltSz The size of the salt. + * inKey The input keying material. + * inKeySz The size of the input keying material. + * out The pseudorandom key with the length that of the hash. + * returns 0 on success, otherwise failure. + */ + int wc_HKDF_Extract(int type, const byte* salt, word32 saltSz, + const byte* inKey, word32 inKeySz, byte* out) { - return a > b ? b : a; - } - -#endif /* WOLFSSL_HAVE_MIN */ - - -static INLINE int GetHashSizeByType(int type) -{ - if (!(type == MD5 || type == SHA || type == SHA256 || type == SHA384 - || type == SHA512 || type == BLAKE2B_ID)) - return BAD_FUNC_ARG; - - switch (type) { - #ifndef NO_MD5 - case MD5: - return MD5_DIGEST_SIZE; - break; - #endif - - #ifndef NO_SHA - case SHA: - return SHA_DIGEST_SIZE; - break; - #endif - - #ifndef NO_SHA256 - case SHA256: - return SHA256_DIGEST_SIZE; - break; - #endif - - #ifdef WOLFSSL_SHA384 - case SHA384: - return SHA384_DIGEST_SIZE; - break; - #endif - - #ifdef WOLFSSL_SHA512 - case SHA512: - return SHA512_DIGEST_SIZE; - break; - #endif - - #ifdef HAVE_BLAKE2 - case BLAKE2B_ID: - return BLAKE2B_OUTBYTES; - break; - #endif - - default: - return BAD_FUNC_ARG; - break; - } -} - - -/* HMAC-KDF with hash type, optional salt and info, return 0 on success */ -int wc_HKDF(int type, const byte* inKey, word32 inKeySz, - const byte* salt, word32 saltSz, - const byte* info, word32 infoSz, - byte* out, word32 outSz) -{ - Hmac myHmac; -#ifdef WOLFSSL_SMALL_STACK - byte* tmp; - byte* prk; -#else - byte tmp[MAX_DIGEST_SIZE]; /* localSalt helper and T */ - byte prk[MAX_DIGEST_SIZE]; -#endif - const byte* localSalt; /* either points to user input or tmp */ - int hashSz = GetHashSizeByType(type); - word32 outIdx = 0; - byte n = 0x1; - int ret; + byte tmp[WC_MAX_DIGEST_SIZE]; /* localSalt helper */ + Hmac myHmac; + int ret; + const byte* localSalt; /* either points to user input or tmp */ + int hashSz; + + ret = wc_HmacSizeByType(type); + if (ret < 0) + return ret; - if (hashSz < 0) - return BAD_FUNC_ARG; + hashSz = ret; + localSalt = salt; + if (localSalt == NULL) { + XMEMSET(tmp, 0, hashSz); + localSalt = tmp; + saltSz = hashSz; + } -#ifdef WOLFSSL_SMALL_STACK - tmp = (byte*)XMALLOC(MAX_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (tmp == NULL) - return MEMORY_E; + ret = wc_HmacInit(&myHmac, NULL, INVALID_DEVID); + if (ret == 0) { + ret = wc_HmacSetKey(&myHmac, type, localSalt, saltSz); + if (ret == 0) + ret = wc_HmacUpdate(&myHmac, inKey, inKeySz); + if (ret == 0) + ret = wc_HmacFinal(&myHmac, out); + wc_HmacFree(&myHmac); + } - prk = (byte*)XMALLOC(MAX_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (prk == NULL) { - XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); - return MEMORY_E; + return ret; } -#endif - localSalt = salt; - if (localSalt == NULL) { - XMEMSET(tmp, 0, hashSz); - localSalt = tmp; - saltSz = hashSz; - } - - do { - ret = wc_HmacSetKey(&myHmac, type, localSalt, saltSz); - if (ret != 0) - break; - ret = wc_HmacUpdate(&myHmac, inKey, inKeySz); - if (ret != 0) - break; - ret = wc_HmacFinal(&myHmac, prk); - } while (0); + /* HMAC-KDF-Expand. + * RFC 5869 - HMAC-based Extract-and-Expand Key Derivation Function (HKDF). + * + * type The hash algorithm type. + * inKey The input key. + * inKeySz The size of the input key. + * info The application specific information. + * infoSz The size of the application specific information. + * out The output keying material. + * returns 0 on success, otherwise failure. + */ + int wc_HKDF_Expand(int type, const byte* inKey, word32 inKeySz, + const byte* info, word32 infoSz, byte* out, word32 outSz) + { + byte tmp[WC_MAX_DIGEST_SIZE]; + Hmac myHmac; + int ret = 0; + word32 outIdx = 0; + word32 hashSz = wc_HmacSizeByType(type); + byte n = 0x1; + + ret = wc_HmacInit(&myHmac, NULL, INVALID_DEVID); + if (ret != 0) + return ret; - if (ret == 0) { while (outIdx < outSz) { int tmpSz = (n == 1) ? 0 : hashSz; word32 left = outSz - outIdx; - ret = wc_HmacSetKey(&myHmac, type, prk, hashSz); + ret = wc_HmacSetKey(&myHmac, type, inKey, inKeySz); if (ret != 0) break; ret = wc_HmacUpdate(&myHmac, tmp, tmpSz); @@ -856,24 +1240,51 @@ int wc_HKDF(int type, const byte* inKey, word32 inKeySz, if (ret != 0) break; - left = min(left, (word32)hashSz); + left = min(left, hashSz); XMEMCPY(out+outIdx, tmp, left); outIdx += hashSz; n++; } + + wc_HmacFree(&myHmac); + + return ret; } -#ifdef WOLFSSL_SMALL_STACK - XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(prk, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif + /* HMAC-KDF. + * RFC 5869 - HMAC-based Extract-and-Expand Key Derivation Function (HKDF). + * + * type The hash algorithm type. + * inKey The input keying material. + * inKeySz The size of the input keying material. + * salt The optional salt value. + * saltSz The size of the salt. + * info The application specific information. + * infoSz The size of the application specific information. + * out The output keying material. + * returns 0 on success, otherwise failure. + */ + int wc_HKDF(int type, const byte* inKey, word32 inKeySz, + const byte* salt, word32 saltSz, + const byte* info, word32 infoSz, + byte* out, word32 outSz) + { + byte prk[WC_MAX_DIGEST_SIZE]; + int hashSz = wc_HmacSizeByType(type); + int ret; - return ret; -} + if (hashSz < 0) + return BAD_FUNC_ARG; + + ret = wc_HKDF_Extract(type, salt, saltSz, inKey, inKeySz, prk); + if (ret != 0) + return ret; + + return wc_HKDF_Expand(type, prk, hashSz, info, infoSz, out, outSz); + } #endif /* HAVE_HKDF */ #endif /* HAVE_FIPS */ #endif /* NO_HMAC */ - |