From 205403ebb29afce61ce9aa3750be6a636e5874b2 Mon Sep 17 00:00:00 2001 From: David Garske Date: Mon, 18 Dec 2023 17:11:16 -0800 Subject: [PATCH 01/13] Add more information in the `DEBUG_CRYPTOCB`. --- wolfcrypt/src/cryptocb.c | 14 ++++++++------ wolfssl/wolfcrypt/cryptocb.h | 2 ++ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/wolfcrypt/src/cryptocb.c b/wolfcrypt/src/cryptocb.c index cc09ec04f..299118f70 100644 --- a/wolfcrypt/src/cryptocb.c +++ b/wolfcrypt/src/cryptocb.c @@ -186,16 +186,18 @@ WOLFSSL_API void wc_CryptoCb_InfoString(wc_CryptoInfo* info) } } else if (info->algo_type == WC_ALGO_TYPE_CIPHER) { - printf("Crypto CB: %s %s (%d)\n", GetAlgoTypeStr(info->algo_type), - GetCipherTypeStr(info->cipher.type), info->cipher.type); + printf("Crypto CB: %s %s (%d) (%p ctx)\n", GetAlgoTypeStr(info->algo_type), + GetCipherTypeStr(info->cipher.type), info->cipher.type, info->cipher.ctx); } else if (info->algo_type == WC_ALGO_TYPE_HASH) { - printf("Crypto CB: %s %s (%d)\n", GetAlgoTypeStr(info->algo_type), - GetHashTypeStr(info->hash.type), info->hash.type); + printf("Crypto CB: %s %s (%d) (%p ctx) %s\n", GetAlgoTypeStr(info->algo_type), + GetHashTypeStr(info->hash.type), info->hash.type, info->hash.ctx, + (info->hash.in != NULL) ? "Update" : "Final"); } else if (info->algo_type == WC_ALGO_TYPE_HMAC) { - printf("Crypto CB: %s %s (%d)\n", GetAlgoTypeStr(info->algo_type), - GetHashTypeStr(info->hmac.macType), info->hmac.macType); + printf("Crypto CB: %s %s (%d) (%p ctx) %s\n", GetAlgoTypeStr(info->algo_type), + GetHashTypeStr(info->hmac.macType), info->hmac.macType, info->hmac.hmac, + (info->hmac.in != NULL) ? "Update" : "Final"); } #ifdef WOLF_CRYPTO_CB_CMD else if (info->algo_type == WC_ALGO_TYPE_NONE) { diff --git a/wolfssl/wolfcrypt/cryptocb.h b/wolfssl/wolfcrypt/cryptocb.h index cf38444f0..04548e386 100644 --- a/wolfssl/wolfcrypt/cryptocb.h +++ b/wolfssl/wolfcrypt/cryptocb.h @@ -296,6 +296,7 @@ typedef struct wc_CryptoInfo { word32 sz; } des3; #endif + void* ctx; #if HAVE_ANONYMOUS_INLINE_AGGREGATES }; #endif @@ -326,6 +327,7 @@ typedef struct wc_CryptoInfo { #ifdef WOLFSSL_SHA512 wc_Sha512* sha512; #endif + void* ctx; #if HAVE_ANONYMOUS_INLINE_AGGREGATES }; #endif From d5e83310b623f83e6bc35af8d2a4be0aec8e07f3 Mon Sep 17 00:00:00 2001 From: David Garske Date: Mon, 18 Dec 2023 17:11:33 -0800 Subject: [PATCH 02/13] Fix typo with HMAC determination of update/final. --- wolfcrypt/test/test.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 0d1bf239c..fe8e4ec92 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -49461,13 +49461,13 @@ static int myCryptoDevCb(int devIdArg, wc_CryptoInfo* info, void* ctx) /* set devId to invalid, so software is used */ info->hmac.hmac->devId = INVALID_DEVID; - if (info->hash.in != NULL) { + if (info->hmac.in != NULL) { ret = wc_HmacUpdate( info->hmac.hmac, info->hmac.in, info->hmac.inSz); } - else if (info->hash.digest != NULL) { + else if (info->hmac.digest != NULL) { ret = wc_HmacFinal( info->hmac.hmac, info->hmac.digest); From 8b203719d3369809a8b7cc6d836e622640bdab85 Mon Sep 17 00:00:00 2001 From: David Garske Date: Mon, 18 Dec 2023 17:14:43 -0800 Subject: [PATCH 03/13] Add support for using `devId` with one-shot hash functions. --- wolfcrypt/src/hash.c | 184 ++++++++++++++++++++++++++++----------- wolfssl/wolfcrypt/hash.h | 33 +++++++ 2 files changed, 166 insertions(+), 51 deletions(-) diff --git a/wolfcrypt/src/hash.c b/wolfcrypt/src/hash.c index 7f6148033..22931c3bc 100644 --- a/wolfcrypt/src/hash.c +++ b/wolfcrypt/src/hash.c @@ -552,8 +552,8 @@ int wc_HashGetBlockSize(enum wc_HashType hash_type) } /* Generic Hashing Wrapper */ -int wc_Hash(enum wc_HashType hash_type, const byte* data, - word32 data_len, byte* hash, word32 hash_len) +int wc_Hash_ex(enum wc_HashType hash_type, const byte* data, + word32 data_len, byte* hash, word32 hash_len, void* heap, int devId) { int ret = HASH_TYPE_E; /* Default to hash type error */ int dig_size; @@ -578,39 +578,39 @@ int wc_Hash(enum wc_HashType hash_type, const byte* data, { case WC_HASH_TYPE_MD5: #ifndef NO_MD5 - ret = wc_Md5Hash(data, data_len, hash); + ret = wc_Md5Hash_ex(data, data_len, hash, heap, devId); #endif break; case WC_HASH_TYPE_SHA: #ifndef NO_SHA - ret = wc_ShaHash(data, data_len, hash); + ret = wc_ShaHash_ex(data, data_len, hash, heap, devId); #endif break; case WC_HASH_TYPE_SHA224: #ifdef WOLFSSL_SHA224 - ret = wc_Sha224Hash(data, data_len, hash); + ret = wc_Sha224Hash_ex(data, data_len, hash, heap, devId); #endif break; case WC_HASH_TYPE_SHA256: #ifndef NO_SHA256 - ret = wc_Sha256Hash(data, data_len, hash); + ret = wc_Sha256Hash_ex(data, data_len, hash, heap, devId); #endif break; case WC_HASH_TYPE_SHA384: #ifdef WOLFSSL_SHA384 - ret = wc_Sha384Hash(data, data_len, hash); + ret = wc_Sha384Hash_ex(data, data_len, hash, heap, devId); #endif break; case WC_HASH_TYPE_SHA512: #ifdef WOLFSSL_SHA512 - ret = wc_Sha512Hash(data, data_len, hash); + ret = wc_Sha512Hash_ex(data, data_len, hash, heap, devId); #endif break; #ifndef WOLFSSL_NOSHA512_224 case WC_HASH_TYPE_SHA512_224: #if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) #if defined(WOLFSSL_SHA512) && !defined(WOLFSSL_NOSHA512_224) - ret = wc_Sha512_224Hash(data, data_len, hash); + ret = wc_Sha512_224Hash_ex(data, data_len, hash, heap, devId); #endif #endif /* !HAVE_FIPS && !HAVE_SELFTEST */ break; @@ -619,44 +619,45 @@ int wc_Hash(enum wc_HashType hash_type, const byte* data, case WC_HASH_TYPE_SHA512_256: #if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) #if defined(WOLFSSL_SHA512) && !defined(WOLFSSL_NOSHA512_224) - ret = wc_Sha512_256Hash(data, data_len, hash); + ret = wc_Sha512_256Hash_ex(data, data_len, hash, heap, devId); #endif #endif /* !HAVE_FIPS && !HAVE_SELFTEST */ break; #endif case WC_HASH_TYPE_MD5_SHA: #if !defined(NO_MD5) && !defined(NO_SHA) - ret = wc_Md5Hash(data, data_len, hash); + ret = wc_Md5Hash_ex(data, data_len, hash, heap, devId); if (ret == 0) { - ret = wc_ShaHash(data, data_len, &hash[WC_MD5_DIGEST_SIZE]); + ret = wc_ShaHash_ex(data, data_len, &hash[WC_MD5_DIGEST_SIZE], + heap, devId); } #endif break; case WC_HASH_TYPE_SHA3_224: #if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_224) - ret = wc_Sha3_224Hash(data, data_len, hash); + ret = wc_Sha3_224Hash_ex(data, data_len, hash, heap, devId); #endif break; case WC_HASH_TYPE_SHA3_256: #if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_256) - ret = wc_Sha3_256Hash(data, data_len, hash); + ret = wc_Sha3_256Hash_ex(data, data_len, hash, heap, devId); #endif break; case WC_HASH_TYPE_SHA3_384: #if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_384) - ret = wc_Sha3_384Hash(data, data_len, hash); + ret = wc_Sha3_384Hash_ex(data, data_len, hash, heap, devId); #endif break; case WC_HASH_TYPE_SHA3_512: #if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_512) - ret = wc_Sha3_512Hash(data, data_len, hash); + ret = wc_Sha3_512Hash_ex(data, data_len, hash, heap, devId); #endif break; #ifdef WOLFSSL_SM3 case WC_HASH_TYPE_SM3: - ret = wc_Sm3Hash(data, data_len, hash); + ret = wc_Sm3Hash_ex(data, data_len, hash, heap, devId); break; #endif @@ -678,6 +679,12 @@ int wc_Hash(enum wc_HashType hash_type, const byte* data, } return ret; } +int wc_Hash(enum wc_HashType hash_type, const byte* data, + word32 data_len, byte* hash, word32 hash_len) +{ + return wc_Hash_ex(hash_type, data, data_len, hash, hash_len, + NULL, INVALID_DEVID); +} int wc_HashInit_ex(wc_HashAlg* hash, enum wc_HashType type, void* heap, int devId) @@ -1279,7 +1286,8 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags) #if !defined(WOLFSSL_TI_HASH) #if !defined(NO_MD5) - int wc_Md5Hash(const byte* data, word32 len, byte* hash) + int wc_Md5Hash_ex(const byte* data, word32 len, byte* hash, + void* heap, int devId) { int ret; #ifdef WOLFSSL_SMALL_STACK @@ -1294,7 +1302,7 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags) return MEMORY_E; #endif - if ((ret = wc_InitMd5(md5)) != 0) { + if ((ret = wc_InitMd5_ex(md5, heap, devId)) != 0) { WOLFSSL_MSG("InitMd5 failed"); } else { @@ -1313,10 +1321,15 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags) return ret; } + int wc_Md5Hash(const byte* data, word32 len, byte* hash) + { + return wc_Md5Hash_ex(data, len, hash, NULL, INVALID_DEVID); + } #endif /* !NO_MD5 */ #if !defined(NO_SHA) - int wc_ShaHash(const byte* data, word32 len, byte* hash) + int wc_ShaHash_ex(const byte* data, word32 len, byte* hash, + void* heap, int devId) { int ret = 0; #ifdef WOLFSSL_SMALL_STACK @@ -1338,7 +1351,7 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags) devId = wc_CryptoCb_GetDevIdAtIndex(0); #endif - if ((ret = wc_InitSha_ex(sha, NULL, devId)) != 0) { + if ((ret = wc_InitSha_ex(sha, heap, devId)) != 0) { WOLFSSL_MSG("InitSha failed"); } else { @@ -1357,10 +1370,15 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags) return ret; } + int wc_ShaHash(const byte* data, word32 len, byte* hash) + { + return wc_ShaHash_ex(data, len, hash, NULL, INVALID_DEVID); + } #endif /* !NO_SHA */ #if defined(WOLFSSL_SHA224) - int wc_Sha224Hash(const byte* data, word32 len, byte* hash) + int wc_Sha224Hash_ex(const byte* data, word32 len, byte* hash, + void* heap, int devId) { int ret = 0; #ifdef WOLFSSL_SMALL_STACK @@ -1376,7 +1394,7 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags) return MEMORY_E; #endif - if ((ret = wc_InitSha224(sha224)) != 0) { + if ((ret = wc_InitSha224_ex(sha224, heap, devId)) != 0) { WOLFSSL_MSG("InitSha224 failed"); } else { @@ -1393,12 +1411,17 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags) XFREE(sha224, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif - return ret; -} + return ret; + } + int wc_Sha224Hash(const byte* data, word32 len, byte* hash) + { + return wc_Sha224Hash_ex(data, len, hash, NULL, INVALID_DEVID); + } #endif /* WOLFSSL_SHA224 */ #if !defined(NO_SHA256) - int wc_Sha256Hash(const byte* data, word32 len, byte* hash) + int wc_Sha256Hash_ex(const byte* data, word32 len, byte* hash, + void* heap, int devId) { int ret = 0; #ifdef WOLFSSL_SMALL_STACK @@ -1421,7 +1444,7 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags) devId = wc_CryptoCb_GetDevIdAtIndex(0); #endif - if ((ret = wc_InitSha256_ex(sha256, NULL, devId)) != 0) { + if ((ret = wc_InitSha256_ex(sha256, heap, devId)) != 0) { WOLFSSL_MSG("InitSha256 failed"); } else { @@ -1441,13 +1464,18 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags) return ret; } + int wc_Sha256Hash(const byte* data, word32 len, byte* hash) + { + return wc_Sha256Hash_ex(data, len, hash, NULL, INVALID_DEVID); + } #endif /* !NO_SHA256 */ #endif /* !defined(WOLFSSL_TI_HASH) */ #if defined(WOLFSSL_SHA512) - int wc_Sha512Hash(const byte* data, word32 len, byte* hash) + int wc_Sha512Hash_ex(const byte* data, word32 len, byte* hash, + void* heap, int devId) { int ret = 0; #ifdef WOLFSSL_SMALL_STACK @@ -1463,7 +1491,7 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags) return MEMORY_E; #endif - if ((ret = wc_InitSha512(sha512)) != 0) { + if ((ret = wc_InitSha512_ex(sha512, heap, devId)) != 0) { WOLFSSL_MSG("InitSha512 failed"); } else { @@ -1482,9 +1510,14 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags) return ret; } + int wc_Sha512Hash(const byte* data, word32 len, byte* hash) + { + return wc_Sha512Hash_ex(data, len, hash, NULL, INVALID_DEVID); + } #if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) #ifndef WOLFSSL_NOSHA512_224 - int wc_Sha512_224Hash(const byte* data, word32 len, byte* hash) + int wc_Sha512_224Hash_ex(const byte* data, word32 len, byte* hash, + void* heap, int devId) { int ret = 0; #ifdef WOLFSSL_SMALL_STACK @@ -1500,7 +1533,7 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags) return MEMORY_E; #endif - if ((ret = wc_InitSha512_224(sha512)) != 0) { + if ((ret = wc_InitSha512_224_ex(sha512, heap, devId)) != 0) { WOLFSSL_MSG("wc_InitSha512_224 failed"); } else { @@ -1519,12 +1552,17 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags) return ret; } + int wc_Sha512_224Hash(const byte* data, word32 len, byte* hash) + { + return wc_Sha512_224Hash_ex(data, len, hash, NULL, INVALID_DEVID); + } #endif /* !WOLFSSL_NOSHA512_224 */ #endif /* !HAVE_FIPS && !HAVE_SELFTEST */ #if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) #ifndef WOLFSSL_NOSHA512_256 - int wc_Sha512_256Hash(const byte* data, word32 len, byte* hash) + int wc_Sha512_256Hash_ex(const byte* data, word32 len, byte* hash, + void* heap, int devId) { int ret = 0; #ifdef WOLFSSL_SMALL_STACK @@ -1540,7 +1578,7 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags) return MEMORY_E; #endif - if ((ret = wc_InitSha512_256(sha512)) != 0) { + if ((ret = wc_InitSha512_256_ex(sha512, heap, devId)) != 0) { WOLFSSL_MSG("wc_InitSha512_256 failed"); } else { @@ -1559,13 +1597,18 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags) return ret; } + int wc_Sha512_256Hash(const byte* data, word32 len, byte* hash) + { + return wc_Sha512_256Hash_ex(data, len, hash, NULL, INVALID_DEVID); + } #endif /* !WOLFSSL_NOSHA512_256 */ #endif /* !HAVE_FIPS && !HAVE_SELFTEST */ #endif /* WOLFSSL_SHA512 */ #if defined(WOLFSSL_SHA384) - int wc_Sha384Hash(const byte* data, word32 len, byte* hash) + int wc_Sha384Hash_ex(const byte* data, word32 len, byte* hash, + void* heap, int devId) { int ret = 0; #ifdef WOLFSSL_SMALL_STACK @@ -1581,7 +1624,7 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags) return MEMORY_E; #endif - if ((ret = wc_InitSha384(sha384)) != 0) { + if ((ret = wc_InitSha384_ex(sha384, heap, devId)) != 0) { WOLFSSL_MSG("InitSha384 failed"); } else { @@ -1600,11 +1643,16 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags) return ret; } + int wc_Sha384Hash(const byte* data, word32 len, byte* hash) + { + return wc_Sha384Hash_ex(data, len, hash, NULL, INVALID_DEVID); + } #endif /* WOLFSSL_SHA384 */ #if defined(WOLFSSL_SHA3) #if !defined(WOLFSSL_NOSHA3_224) - int wc_Sha3_224Hash(const byte* data, word32 len, byte* hash) + int wc_Sha3_224Hash_ex(const byte* data, word32 len, byte* hash, + void* heap, int devId) { int ret = 0; #ifdef WOLFSSL_SMALL_STACK @@ -1620,7 +1668,7 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags) return MEMORY_E; #endif - if ((ret = wc_InitSha3_224(sha3, NULL, INVALID_DEVID)) != 0) { + if ((ret = wc_InitSha3_224(sha3, heap, devId)) != 0) { WOLFSSL_MSG("InitSha3_224 failed"); } else { @@ -1639,10 +1687,15 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags) return ret; } + int wc_Sha3_224Hash(const byte* data, word32 len, byte* hash) + { + return wc_Sha3_224Hash_ex(data, len, hash, NULL, INVALID_DEVID); + } #endif /* !WOLFSSL_NOSHA3_224 */ #if !defined(WOLFSSL_NOSHA3_256) - int wc_Sha3_256Hash(const byte* data, word32 len, byte* hash) + int wc_Sha3_256Hash_ex(const byte* data, word32 len, byte* hash, + void* heap, int devId) { int ret = 0; #ifdef WOLFSSL_SMALL_STACK @@ -1658,7 +1711,7 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags) return MEMORY_E; #endif - if ((ret = wc_InitSha3_256(sha3, NULL, INVALID_DEVID)) != 0) { + if ((ret = wc_InitSha3_256(sha3, heap, devId)) != 0) { WOLFSSL_MSG("InitSha3_256 failed"); } else { @@ -1677,10 +1730,15 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags) return ret; } + int wc_Sha3_256Hash(const byte* data, word32 len, byte* hash) + { + return wc_Sha3_256Hash_ex(data, len, hash, NULL, INVALID_DEVID); + } #endif /* !WOLFSSL_NOSHA3_256 */ #if !defined(WOLFSSL_NOSHA3_384) - int wc_Sha3_384Hash(const byte* data, word32 len, byte* hash) + int wc_Sha3_384Hash_ex(const byte* data, word32 len, byte* hash, + void* heap, int devId) { int ret = 0; #ifdef WOLFSSL_SMALL_STACK @@ -1696,7 +1754,7 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags) return MEMORY_E; #endif - if ((ret = wc_InitSha3_384(sha3, NULL, INVALID_DEVID)) != 0) { + if ((ret = wc_InitSha3_384(sha3, heap, devId)) != 0) { WOLFSSL_MSG("InitSha3_384 failed"); } else { @@ -1715,10 +1773,15 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags) return ret; } + int wc_Sha3_384Hash(const byte* data, word32 len, byte* hash) + { + return wc_Sha3_384Hash_ex(data, len, hash, NULL, INVALID_DEVID); + } #endif /* !WOLFSSL_NOSHA3_384 */ #if !defined(WOLFSSL_NOSHA3_512) - int wc_Sha3_512Hash(const byte* data, word32 len, byte* hash) + int wc_Sha3_512Hash_ex(const byte* data, word32 len, byte* hash, + void* heap, int devId) { int ret = 0; #ifdef WOLFSSL_SMALL_STACK @@ -1734,7 +1797,7 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags) return MEMORY_E; #endif - if ((ret = wc_InitSha3_512(sha3, NULL, INVALID_DEVID)) != 0) { + if ((ret = wc_InitSha3_512(sha3, heap, devId)) != 0) { WOLFSSL_MSG("InitSha3_512 failed"); } else { @@ -1753,11 +1816,15 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags) return ret; } + int wc_Sha3_512Hash(const byte* data, word32 len, byte* hash) + { + return wc_Sha3_512Hash_ex(data, len, hash, NULL, INVALID_DEVID); + } #endif /* !WOLFSSL_NOSHA3_512 */ #ifdef WOLFSSL_SHAKE128 - int wc_Shake128Hash(const byte* data, word32 len, byte* hash, - word32 hashLen) + int wc_Shake128Hash_ex(const byte* data, word32 len, byte* hash, + word32 hashLen, void* heap, int devId) { int ret = 0; #ifdef WOLFSSL_SMALL_STACK @@ -1773,7 +1840,7 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags) return MEMORY_E; #endif - if ((ret = wc_InitShake128(shake, NULL, INVALID_DEVID)) != 0) { + if ((ret = wc_InitShake128(shake, heap, devId)) != 0) { WOLFSSL_MSG("InitShake128 failed"); } else { @@ -1792,11 +1859,16 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags) return ret; } + int wc_Shake128Hash(const byte* data, word32 len, byte* hash, + word32 hashLen) + { + return wc_Shake128Hash_ex(data, len, hash, hashLen, NULL, INVALID_DEVID); + } #endif /* WOLFSSL_SHAKE_128 */ #ifdef WOLFSSL_SHAKE256 - int wc_Shake256Hash(const byte* data, word32 len, byte* hash, - word32 hashLen) + int wc_Shake256Hash_ex(const byte* data, word32 len, byte* hash, + word32 hashLen, void* heap, int devId) { int ret = 0; #ifdef WOLFSSL_SMALL_STACK @@ -1812,7 +1884,7 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags) return MEMORY_E; #endif - if ((ret = wc_InitShake256(shake, NULL, INVALID_DEVID)) != 0) { + if ((ret = wc_InitShake256(shake, heap, devId)) != 0) { WOLFSSL_MSG("InitShake256 failed"); } else { @@ -1831,11 +1903,17 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags) return ret; } + int wc_Shake256Hash(const byte* data, word32 len, byte* hash, + word32 hashLen) + { + return wc_Shake256Hash_ex(data, len, hash, hashLen, NULL, INVALID_DEVID); + } #endif /* WOLFSSL_SHAKE_256 */ #endif /* WOLFSSL_SHA3 */ #ifdef WOLFSSL_SM3 - int wc_Sm3Hash(const byte* data, word32 len, byte* hash) + int wc_Sm3Hash_ex(const byte* data, word32 len, byte* hash, + void* heap, int devId) { int ret = 0; #ifdef WOLFSSL_SMALL_STACK @@ -1850,7 +1928,7 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags) return MEMORY_E; #endif - if ((ret = wc_InitSm3(sm3, NULL, INVALID_DEVID)) != 0) { + if ((ret = wc_InitSm3(sm3, heap, devId)) != 0) { WOLFSSL_MSG("InitSm3 failed"); } else { @@ -1869,6 +1947,10 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags) return ret; } + int wc_Sm3Hash(const byte* data, word32 len, byte* hash) + { + return wc_Sm3Hash_ex(data, len, hash, NULL, INVALID_DEVID); + } #endif /* !WOLFSSL_NOSHA3_224 */ #endif /* !NO_HASH_WRAPPER */ diff --git a/wolfssl/wolfcrypt/hash.h b/wolfssl/wolfcrypt/hash.h index b8079ba28..27b142378 100644 --- a/wolfssl/wolfcrypt/hash.h +++ b/wolfssl/wolfcrypt/hash.h @@ -170,6 +170,9 @@ WOLFSSL_API int wc_HashGetBlockSize(enum wc_HashType hash_type); WOLFSSL_API int wc_Hash(enum wc_HashType hash_type, const byte* data, word32 data_len, byte* hash, word32 hash_len); +WOLFSSL_API int wc_Hash_ex(enum wc_HashType hash_type, + const byte* data, word32 data_len, + byte* hash, word32 hash_len, void* heap, int devId); /* generic hash operation wrappers */ WOLFSSL_API int wc_HashInit_ex(wc_HashAlg* hash, enum wc_HashType type, @@ -191,26 +194,36 @@ WOLFSSL_API int wc_HashFree(wc_HashAlg* hash, enum wc_HashType type); #ifndef NO_MD5 #include WOLFSSL_API int wc_Md5Hash(const byte* data, word32 len, byte* hash); +WOLFSSL_API int wc_Md5Hash_ex(const byte* data, word32 len, byte* hash, + void* heap, int devId); #endif #ifndef NO_SHA #include WOLFSSL_API int wc_ShaHash(const byte* data, word32 len, byte* hash); +WOLFSSL_API int wc_ShaHash_ex(const byte* data, word32 len, byte* hash, + void* heap, int devId); #endif #ifdef WOLFSSL_SHA224 #include WOLFSSL_API int wc_Sha224Hash(const byte* data, word32 len, byte* hash); +WOLFSSL_API int wc_Sha224Hash_ex(const byte* data, word32 len, byte* hash, + void* heap, int devId); #endif /* defined(WOLFSSL_SHA224) */ #ifndef NO_SHA256 #include WOLFSSL_API int wc_Sha256Hash(const byte* data, word32 len, byte* hash); +WOLFSSL_API int wc_Sha256Hash_ex(const byte* data, word32 len, byte* hash, + void* heap, int devId); #endif #ifdef WOLFSSL_SHA384 #include WOLFSSL_API int wc_Sha384Hash(const byte* data, word32 len, byte* hash); +WOLFSSL_API int wc_Sha384Hash_ex(const byte* data, word32 len, byte* hash, + void* heap, int devId); #endif /* defined(WOLFSSL_SHA384) */ #ifdef WOLFSSL_SHA512 @@ -218,6 +231,12 @@ WOLFSSL_API int wc_Sha384Hash(const byte* data, word32 len, byte* hash); WOLFSSL_API int wc_Sha512Hash(const byte* data, word32 len, byte* hash); WOLFSSL_API int wc_Sha512_224Hash(const byte* data, word32 len, byte* hash); WOLFSSL_API int wc_Sha512_256Hash(const byte* data, word32 len, byte* hash); +WOLFSSL_API int wc_Sha512Hash_ex(const byte* data, word32 len, byte* hash, + void* heap, int devId); +WOLFSSL_API int wc_Sha512_224Hash_ex(const byte* data, word32 len, byte* hash, + void* heap, int devId); +WOLFSSL_API int wc_Sha512_256Hash_ex(const byte* data, word32 len, byte* hash, + void* heap, int devId); #endif /* WOLFSSL_SHA512 */ #ifdef WOLFSSL_SHA3 @@ -226,18 +245,32 @@ WOLFSSL_API int wc_Sha3_224Hash(const byte* data, word32 len, byte* hash); WOLFSSL_API int wc_Sha3_256Hash(const byte* data, word32 len, byte* hash); WOLFSSL_API int wc_Sha3_384Hash(const byte* data, word32 len, byte* hash); WOLFSSL_API int wc_Sha3_512Hash(const byte* data, word32 len, byte* hash); +WOLFSSL_API int wc_Sha3_224Hash_ex(const byte* data, word32 len, byte* hash, + void* heap, int devId); +WOLFSSL_API int wc_Sha3_256Hash_ex(const byte* data, word32 len, byte* hash, + void* heap, int devId); +WOLFSSL_API int wc_Sha3_384Hash_ex(const byte* data, word32 len, byte* hash, + void* heap, int devId); +WOLFSSL_API int wc_Sha3_512Hash_ex(const byte* data, word32 len, byte* hash, + void* heap, int devId); #ifdef WOLFSSL_SHAKE128 WOLFSSL_API int wc_Shake128Hash(const byte* data, word32 len, byte* hash, word32 hashLen); +WOLFSSL_API int wc_Shake128Hash_ex(const byte* data, word32 len, byte* hash, + word32 hashLen, void* heap, int devId); #endif #ifdef WOLFSSL_SHAKE256 WOLFSSL_API int wc_Shake256Hash(const byte* data, word32 len, byte* hash, word32 hashLen); +WOLFSSL_API int wc_Shake256Hash_ex(const byte* data, word32 len, byte* hash, + word32 hashLen, void* heap, int devId); #endif #endif /* WOLFSSL_SHA3 */ #ifdef WOLFSSL_SM3 WOLFSSL_API int wc_Sm3Hash(const byte* data, word32 len, byte* hash); +WOLFSSL_API int wc_Sm3Hash_ex(const byte* data, word32 len, byte* hash, + void* heap, int devId); #endif #endif /* !NO_HASH_WRAPPER */ From 90748b5f6184b9eaa4c9c2ce12dfd447106bef14 Mon Sep 17 00:00:00 2001 From: David Garske Date: Mon, 18 Dec 2023 17:14:58 -0800 Subject: [PATCH 04/13] Remove the SHA1-/SHA2-256 auto devId selection `devId = wc_CryptoCb_GetDevIdAtIndex(0);` --- wolfcrypt/src/hash.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/wolfcrypt/src/hash.c b/wolfcrypt/src/hash.c index 22931c3bc..41ec31cc2 100644 --- a/wolfcrypt/src/hash.c +++ b/wolfcrypt/src/hash.c @@ -1337,7 +1337,6 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags) #else wc_Sha sha[1]; #endif - int devId = INVALID_DEVID; #ifdef WOLFSSL_SMALL_STACK sha = (wc_Sha*)XMALLOC(sizeof(wc_Sha), NULL, DYNAMIC_TYPE_TMP_BUFFER); @@ -1345,12 +1344,6 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags) return MEMORY_E; #endif - #ifdef WOLF_CRYPTO_CB - /* only use devId if its not an empty hash */ - if (data != NULL && len > 0) - devId = wc_CryptoCb_GetDevIdAtIndex(0); - #endif - if ((ret = wc_InitSha_ex(sha, heap, devId)) != 0) { WOLFSSL_MSG("InitSha failed"); } @@ -1429,7 +1422,6 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags) #else wc_Sha256 sha256[1]; #endif - int devId = INVALID_DEVID; #ifdef WOLFSSL_SMALL_STACK sha256 = (wc_Sha256*)XMALLOC(sizeof(wc_Sha256), NULL, @@ -1438,12 +1430,6 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags) return MEMORY_E; #endif - #ifdef WOLF_CRYPTO_CB - /* only use devId if its not an empty hash */ - if (data != NULL && len > 0) - devId = wc_CryptoCb_GetDevIdAtIndex(0); - #endif - if ((ret = wc_InitSha256_ex(sha256, heap, devId)) != 0) { WOLFSSL_MSG("InitSha256 failed"); } From 2001d1c74b7bebd9b9f37bec282b52eb2c11be2b Mon Sep 17 00:00:00 2001 From: David Garske Date: Mon, 18 Dec 2023 17:16:54 -0800 Subject: [PATCH 05/13] Fixes for TLS v1.3 with crypto callbacks not offloading DeriveKeyMsg, KDF HMAC and ECH. --- src/tls13.c | 80 +++++++++++++++++++++++++++++----------- wolfcrypt/src/hmac.c | 27 +++++++++++--- wolfcrypt/src/kdf.c | 43 +++++++++++++++++++-- wolfssl/wolfcrypt/hmac.h | 7 ++++ wolfssl/wolfcrypt/kdf.h | 10 +++++ 5 files changed, 136 insertions(+), 31 deletions(-) diff --git a/src/tls13.c b/src/tls13.c index d16a5761f..455cb10cf 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -225,10 +225,18 @@ static int Tls13HKDFExpandLabel(WOLFSSL* ssl, byte* okm, word32 okmLen, #endif (void)ssl; PRIVATE_KEY_UNLOCK(); +#if !defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)) + ret = wc_Tls13_HKDF_Expand_Label_ex(okm, okmLen, prk, prkLen, + protocol, protocolLen, + label, labelLen, + info, infoLen, digest, + ssl->heap, ssl->devId); +#else ret = wc_Tls13_HKDF_Expand_Label(okm, okmLen, prk, prkLen, protocol, protocolLen, label, labelLen, info, infoLen, digest); +#endif PRIVATE_KEY_LOCK(); return ret; } @@ -266,10 +274,18 @@ PRAGMA_GCC_DIAG_PUSH PRAGMA_GCC("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") (void)ssl; (void)side; +#if !defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)) + return wc_Tls13_HKDF_Expand_Label_ex(okm, okmLen, prk, prkLen, + protocol, protocolLen, + label, labelLen, + info, infoLen, digest, + ssl->heap, ssl->devId); +#else return wc_Tls13_HKDF_Expand_Label(okm, okmLen, prk, prkLen, protocol, protocolLen, label, labelLen, info, infoLen, digest); +#endif PRAGMA_GCC_DIAG_POP } #endif /* !HAVE_FIPS || !wc_Tls13_HKDF_Expand_Label */ @@ -302,7 +318,7 @@ static int DeriveKeyMsg(WOLFSSL* ssl, byte* output, int outputLen, switch (hashAlgo) { #ifndef NO_WOLFSSL_SHA256 case sha256_mac: - ret = wc_InitSha256_ex(&digest.sha256, ssl->heap, INVALID_DEVID); + ret = wc_InitSha256_ex(&digest.sha256, ssl->heap, ssl->devId); if (ret == 0) { ret = wc_Sha256Update(&digest.sha256, msg, msgLen); if (ret == 0) @@ -315,7 +331,7 @@ static int DeriveKeyMsg(WOLFSSL* ssl, byte* output, int outputLen, #endif #ifdef WOLFSSL_SHA384 case sha384_mac: - ret = wc_InitSha384_ex(&digest.sha384, ssl->heap, INVALID_DEVID); + ret = wc_InitSha384_ex(&digest.sha384, ssl->heap, ssl->devId); if (ret == 0) { ret = wc_Sha384Update(&digest.sha384, msg, msgLen); if (ret == 0) @@ -328,7 +344,7 @@ static int DeriveKeyMsg(WOLFSSL* ssl, byte* output, int outputLen, #endif #ifdef WOLFSSL_TLS13_SHA512 case sha512_mac: - ret = wc_InitSha512_ex(&digest.sha512, ssl->heap, INVALID_DEVID); + ret = wc_InitSha512_ex(&digest.sha512, ssl->heap, ssl->devId); if (ret == 0) { ret = wc_Sha512Update(&digest.sha512, msg, msgLen); if (ret == 0) @@ -341,7 +357,7 @@ static int DeriveKeyMsg(WOLFSSL* ssl, byte* output, int outputLen, #endif #ifdef WOLFSSL_SM3 case sm3_mac: - ret = wc_InitSm3(&digest.sm3, ssl->heap, INVALID_DEVID); + ret = wc_InitSm3(&digest.sm3, ssl->heap, ssl->devId); if (ret == 0) { ret = wc_Sm3Update(&digest.sm3, msg, msgLen); if (ret == 0) @@ -1108,8 +1124,8 @@ static int DeriveTrafficSecret(WOLFSSL* ssl, byte* secret, int side) } -static int Tls13_HKDF_Extract(WOLFSSL *ssl, byte* prk, const byte* salt, int saltLen, - byte* ikm, int ikmLen, int digest) +static int Tls13_HKDF_Extract(WOLFSSL *ssl, byte* prk, const byte* salt, + int saltLen, byte* ikm, int ikmLen, int digest) { int ret; #ifdef HAVE_PK_CALLBACKS @@ -1121,8 +1137,12 @@ static int Tls13_HKDF_Extract(WOLFSSL *ssl, byte* prk, const byte* salt, int sal else #endif { - (void)ssl; + #if !defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)) + ret = wc_Tls13_HKDF_Extract_ex(prk, salt, saltLen, ikm, ikmLen, digest, + ssl->heap, ssl->devId); + #else ret = wc_Tls13_HKDF_Extract(prk, salt, saltLen, ikm, ikmLen, digest); + #endif } return ret; } @@ -4786,17 +4806,29 @@ static int EchCheckAcceptance(WOLFSSL* ssl, const byte* input, } } /* extract clientRandomInner with a key of all zeros */ - if (ret == 0) + if (ret == 0) { + PRIVATE_KEY_UNLOCK(); + #if !defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)) + ret = wc_HKDF_Extract_ex(digestType, zeros, digestSize, + ssl->arrays->clientRandomInner, RAN_LEN, expandLabelPrk, + ssl->heap, ssl->devId); + #else ret = wc_HKDF_Extract(digestType, zeros, digestSize, ssl->arrays->clientRandomInner, RAN_LEN, expandLabelPrk); + #endif + PRIVATE_KEY_LOCK(); + } /* tls expand with the confirmation label */ - if (ret == 0) - ret = wc_Tls13_HKDF_Expand_Label(acceptConfirmation, - ECH_ACCEPT_CONFIRMATION_SZ, - expandLabelPrk, digestSize, tls13ProtocolLabel, - TLS13_PROTOCOL_LABEL_SZ, echAcceptConfirmationLabel, - ECH_ACCEPT_CONFIRMATION_LABEL_SZ, transcriptEchConf, digestSize, - digestType); + if (ret == 0) { + PRIVATE_KEY_UNLOCK(); + ret = Tls13HKDFExpandKeyLabel(ssl, + acceptConfirmation, ECH_ACCEPT_CONFIRMATION_SZ, + expandLabelPrk, digestSize, + tls13ProtocolLabel, TLS13_PROTOCOL_LABEL_SZ, + echAcceptConfirmationLabel, ECH_ACCEPT_CONFIRMATION_LABEL_SZ, + transcriptEchConf, digestSize, digestType, WOLFSSL_SERVER_END); + PRIVATE_KEY_LOCK(); + } if (ret == 0) { /* last 8 bytes should match our expand output */ ret = XMEMCMP(acceptConfirmation, @@ -4913,21 +4945,27 @@ static int EchWriteAcceptance(WOLFSSL* ssl, byte* output, /* extract clientRandom with a key of all zeros */ if (ret == 0) { PRIVATE_KEY_UNLOCK(); + #if !defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)) + ret = wc_HKDF_Extract_ex(digestType, zeros, digestSize, + ssl->arrays->clientRandom, RAN_LEN, expandLabelPrk, + ssl->heap, ssl->devId); + #else ret = wc_HKDF_Extract(digestType, zeros, digestSize, ssl->arrays->clientRandom, RAN_LEN, expandLabelPrk); + #endif PRIVATE_KEY_LOCK(); } /* tls expand with the confirmation label */ if (ret == 0) { PRIVATE_KEY_UNLOCK(); - ret = wc_Tls13_HKDF_Expand_Label( + ret = Tls13HKDFExpandKeyLabel(ssl, output + serverRandomOffset + RAN_LEN - ECH_ACCEPT_CONFIRMATION_SZ, - ECH_ACCEPT_CONFIRMATION_SZ, - expandLabelPrk, digestSize, tls13ProtocolLabel, - TLS13_PROTOCOL_LABEL_SZ, echAcceptConfirmationLabel, - ECH_ACCEPT_CONFIRMATION_LABEL_SZ, transcriptEchConf, digestSize, - digestType); + ECH_ACCEPT_CONFIRMATION_SZ, + expandLabelPrk, digestSize, + tls13ProtocolLabel, TLS13_PROTOCOL_LABEL_SZ, + echAcceptConfirmationLabel, ECH_ACCEPT_CONFIRMATION_LABEL_SZ, + transcriptEchConf, digestSize, digestType, WOLFSSL_SERVER_END); PRIVATE_KEY_LOCK(); } diff --git a/wolfcrypt/src/hmac.c b/wolfcrypt/src/hmac.c index 83e693b25..9a80cb1e2 100644 --- a/wolfcrypt/src/hmac.c +++ b/wolfcrypt/src/hmac.c @@ -1195,8 +1195,8 @@ int wolfSSL_GetHmacMaxSize(void) * 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) + int wc_HKDF_Extract_ex(int type, const byte* salt, word32 saltSz, + const byte* inKey, word32 inKeySz, byte* out, void* heap, int devId) { byte tmp[WC_MAX_DIGEST_SIZE]; /* localSalt helper */ #ifdef WOLFSSL_SMALL_STACK @@ -1228,7 +1228,7 @@ int wolfSSL_GetHmacMaxSize(void) saltSz = hashSz; } - ret = wc_HmacInit(myHmac, NULL, INVALID_DEVID); + ret = wc_HmacInit(myHmac, heap, devId); if (ret == 0) { ret = wc_HmacSetKey(myHmac, type, localSalt, saltSz); if (ret == 0) @@ -1244,6 +1244,13 @@ int wolfSSL_GetHmacMaxSize(void) return ret; } + int wc_HKDF_Extract(int type, const byte* salt, word32 saltSz, + const byte* inKey, word32 inKeySz, byte* out) + { + return wc_HKDF_Extract_ex(type, salt, saltSz, inKey, inKeySz, out, NULL, + INVALID_DEVID); + } + /* HMAC-KDF-Expand. * RFC 5869 - HMAC-based Extract-and-Expand Key Derivation Function (HKDF). * @@ -1255,8 +1262,9 @@ int wolfSSL_GetHmacMaxSize(void) * 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) + int wc_HKDF_Expand_ex(int type, const byte* inKey, word32 inKeySz, + const byte* info, word32 infoSz, byte* out, word32 outSz, + void* heap, int devId) { byte tmp[WC_MAX_DIGEST_SIZE]; #ifdef WOLFSSL_SMALL_STACK @@ -1289,7 +1297,7 @@ int wolfSSL_GetHmacMaxSize(void) } #endif - ret = wc_HmacInit(myHmac, NULL, INVALID_DEVID); + ret = wc_HmacInit(myHmac, heap, devId); if (ret != 0) { #ifdef WOLFSSL_SMALL_STACK XFREE(myHmac, NULL, DYNAMIC_TYPE_HMAC); @@ -1334,6 +1342,13 @@ int wolfSSL_GetHmacMaxSize(void) return ret; } + int wc_HKDF_Expand(int type, const byte* inKey, word32 inKeySz, + const byte* info, word32 infoSz, byte* out, word32 outSz) + { + return wc_HKDF_Expand_ex(type, inKey, inKeySz, info, infoSz, out, outSz, + NULL, INVALID_DEVID); + } + /* HMAC-KDF. * RFC 5869 - HMAC-based Extract-and-Expand Key Derivation Function (HKDF). * diff --git a/wolfcrypt/src/kdf.c b/wolfcrypt/src/kdf.c index 4921e5bb0..9b289be45 100644 --- a/wolfcrypt/src/kdf.c +++ b/wolfcrypt/src/kdf.c @@ -362,8 +362,8 @@ int wc_PRF_TLS(byte* digest, word32 digLen, const byte* secret, word32 secLen, * digest The type of digest to use. * returns 0 on success, otherwise failure. */ - int wc_Tls13_HKDF_Extract(byte* prk, const byte* salt, word32 saltLen, - byte* ikm, word32 ikmLen, int digest) + int wc_Tls13_HKDF_Extract_ex(byte* prk, const byte* salt, word32 saltLen, + byte* ikm, word32 ikmLen, int digest, void* heap, int devId) { int ret; word32 len = 0; @@ -410,7 +410,15 @@ int wc_PRF_TLS(byte* digest, word32 digLen, const byte* secret, word32 secLen, WOLFSSL_BUFFER(ikm, ikmLen); #endif +#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \ + (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3))) + ret = wc_HKDF_Extract_ex(digest, salt, saltLen, ikm, ikmLen, prk, heap, + devId); +#else ret = wc_HKDF_Extract(digest, salt, saltLen, ikm, ikmLen, prk); + (void)heap; + (void)devId; +#endif #ifdef WOLFSSL_DEBUG_TLS WOLFSSL_MSG(" PRK"); @@ -420,6 +428,13 @@ int wc_PRF_TLS(byte* digest, word32 digLen, const byte* secret, word32 secLen, return ret; } + int wc_Tls13_HKDF_Extract(byte* prk, const byte* salt, word32 saltLen, + byte* ikm, word32 ikmLen, int digest) + { + return wc_Tls13_HKDF_Extract_ex(prk, salt, saltLen, ikm, ikmLen, digest, + NULL, INVALID_DEVID); + } + /* Expand data using HMAC, salt and label and info. * TLS v1.3 defines this function. * @@ -435,12 +450,12 @@ int wc_PRF_TLS(byte* digest, word32 digLen, const byte* secret, word32 secLen, * digest The type of digest to use. * returns 0 on success, otherwise failure. */ - int wc_Tls13_HKDF_Expand_Label(byte* okm, word32 okmLen, + int wc_Tls13_HKDF_Expand_Label_ex(byte* okm, word32 okmLen, const byte* prk, word32 prkLen, const byte* protocol, word32 protocolLen, const byte* label, word32 labelLen, const byte* info, word32 infoLen, - int digest) + int digest, void* heap, int devId) { int ret = 0; word32 idx = 0; @@ -494,7 +509,15 @@ int wc_PRF_TLS(byte* digest, word32 digLen, const byte* secret, word32 secLen, WOLFSSL_MSG_EX(" Digest %d", digest); #endif +#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \ + (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3))) + ret = wc_HKDF_Expand_ex(digest, prk, prkLen, data, idx, okm, okmLen, + heap, devId); +#else ret = wc_HKDF_Expand(digest, prk, prkLen, data, idx, okm, okmLen); + (void)heap; + (void)devId; +#endif #ifdef WOLFSSL_DEBUG_TLS WOLFSSL_MSG(" OKM"); @@ -512,6 +535,18 @@ int wc_PRF_TLS(byte* digest, word32 digLen, const byte* secret, word32 secLen, return ret; } + int wc_Tls13_HKDF_Expand_Label(byte* okm, word32 okmLen, + const byte* prk, word32 prkLen, + const byte* protocol, word32 protocolLen, + const byte* label, word32 labelLen, + const byte* info, word32 infoLen, + int digest) + { + return wc_Tls13_HKDF_Expand_Label_ex(okm, okmLen, prk, prkLen, protocol, + protocolLen, label, labelLen, info, infoLen, digest, + NULL, INVALID_DEVID); + } + #if defined(WOLFSSL_TICKET_NONCE_MALLOC) && \ (!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3))) /* Expand data using HMAC, salt and label and info. diff --git a/wolfssl/wolfcrypt/hmac.h b/wolfssl/wolfcrypt/hmac.h index f325dd35d..fc6dc2ee3 100644 --- a/wolfssl/wolfcrypt/hmac.h +++ b/wolfssl/wolfcrypt/hmac.h @@ -210,8 +210,15 @@ WOLFSSL_LOCAL int _InitHmac(Hmac* hmac, int type, void* heap); #ifdef HAVE_HKDF +WOLFSSL_LOCAL int wc_HKDF_Extract_ex(int type, const byte* salt, word32 saltSz, + const byte* inKey, word32 inKeySz, byte* out, void* heap, int devId); + WOLFSSL_API int wc_HKDF_Extract(int type, const byte* salt, word32 saltSz, const byte* inKey, word32 inKeySz, byte* out); + +WOLFSSL_LOCAL int wc_HKDF_Expand_ex(int type, const byte* inKey, word32 inKeySz, + const byte* info, word32 infoSz, + byte* out, word32 outSz, void* heap, int devId); WOLFSSL_API int wc_HKDF_Expand(int type, const byte* inKey, word32 inKeySz, const byte* info, word32 infoSz, byte* out, word32 outSz); diff --git a/wolfssl/wolfcrypt/kdf.h b/wolfssl/wolfcrypt/kdf.h index 6a6a85698..ab4df120c 100644 --- a/wolfssl/wolfcrypt/kdf.h +++ b/wolfssl/wolfcrypt/kdf.h @@ -76,9 +76,19 @@ enum { MAX_TLS13_HKDF_LABEL_SZ = 47 + WC_MAX_DIGEST_SIZE }; +WOLFSSL_LOCAL int wc_Tls13_HKDF_Extract_ex(byte* prk, const byte* salt, + word32 saltLen, byte* ikm, word32 ikmLen, int digest, void* heap, int devId); + WOLFSSL_API int wc_Tls13_HKDF_Extract(byte* prk, const byte* salt, word32 saltLen, byte* ikm, word32 ikmLen, int digest); +WOLFSSL_LOCAL int wc_Tls13_HKDF_Expand_Label_ex(byte* okm, word32 okmLen, + const byte* prk, word32 prkLen, + const byte* protocol, word32 protocolLen, + const byte* label, word32 labelLen, + const byte* info, word32 infoLen, + int digest, void* heap, int devId); + WOLFSSL_API int wc_Tls13_HKDF_Expand_Label(byte* okm, word32 okmLen, const byte* prk, word32 prkLen, const byte* protocol, word32 protocolLen, From fb5eab8f79559ed38ae6664ba552dbcc01351445 Mon Sep 17 00:00:00 2001 From: David Garske Date: Tue, 19 Dec 2023 11:20:18 -0800 Subject: [PATCH 06/13] Fix one shot hash routines to attempt offloading to crypto callbacks. Fix random.c health test to use devId. Fix FIPS unused "ssl". --- src/tls13.c | 1 + wolfcrypt/src/cryptocb.c | 3 +- wolfcrypt/src/hash.c | 105 +++++++++++++++++++++++++++++++++++++++ wolfcrypt/src/random.c | 62 +++++++++++++---------- 4 files changed, 143 insertions(+), 28 deletions(-) diff --git a/src/tls13.c b/src/tls13.c index 455cb10cf..af7971aa3 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -1142,6 +1142,7 @@ static int Tls13_HKDF_Extract(WOLFSSL *ssl, byte* prk, const byte* salt, ssl->heap, ssl->devId); #else ret = wc_Tls13_HKDF_Extract(prk, salt, saltLen, ikm, ikmLen, digest); + (void)ssl; #endif } return ret; diff --git a/wolfcrypt/src/cryptocb.c b/wolfcrypt/src/cryptocb.c index 299118f70..e46429d87 100644 --- a/wolfcrypt/src/cryptocb.c +++ b/wolfcrypt/src/cryptocb.c @@ -1446,7 +1446,8 @@ int wc_CryptoCb_DefaultDevID(void) #elif defined(WC_USE_DEVID) ret = WC_USE_DEVID; #else - ret = INVALID_DEVID; + /* try first available */ + ret = wc_CryptoCb_GetDevIdAtIndex(0); #endif return ret; diff --git a/wolfcrypt/src/hash.c b/wolfcrypt/src/hash.c index 41ec31cc2..3f6488660 100644 --- a/wolfcrypt/src/hash.c +++ b/wolfcrypt/src/hash.c @@ -1302,6 +1302,13 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags) return MEMORY_E; #endif + #ifdef WOLF_CRYPTO_CB + /* find devId if its not an empty hash */ + if (devId == INVALID_DEVID && data != NULL && len > 0) { + devId = wc_CryptoCb_DefaultDevID(); + } + #endif + if ((ret = wc_InitMd5_ex(md5, heap, devId)) != 0) { WOLFSSL_MSG("InitMd5 failed"); } @@ -1344,6 +1351,13 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags) return MEMORY_E; #endif + #ifdef WOLF_CRYPTO_CB + /* find devId if its not an empty hash */ + if (devId == INVALID_DEVID && data != NULL && len > 0) { + devId = wc_CryptoCb_DefaultDevID(); + } + #endif + if ((ret = wc_InitSha_ex(sha, heap, devId)) != 0) { WOLFSSL_MSG("InitSha failed"); } @@ -1387,6 +1401,13 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags) return MEMORY_E; #endif + #ifdef WOLF_CRYPTO_CB + /* find devId if its not an empty hash */ + if (devId == INVALID_DEVID && data != NULL && len > 0) { + devId = wc_CryptoCb_DefaultDevID(); + } + #endif + if ((ret = wc_InitSha224_ex(sha224, heap, devId)) != 0) { WOLFSSL_MSG("InitSha224 failed"); } @@ -1430,6 +1451,13 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags) return MEMORY_E; #endif + #ifdef WOLF_CRYPTO_CB + /* find devId if its not an empty hash */ + if (devId == INVALID_DEVID && data != NULL && len > 0) { + devId = wc_CryptoCb_DefaultDevID(); + } + #endif + if ((ret = wc_InitSha256_ex(sha256, heap, devId)) != 0) { WOLFSSL_MSG("InitSha256 failed"); } @@ -1477,6 +1505,13 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags) return MEMORY_E; #endif + #ifdef WOLF_CRYPTO_CB + /* find devId if its not an empty hash */ + if (devId == INVALID_DEVID && data != NULL && len > 0) { + devId = wc_CryptoCb_DefaultDevID(); + } + #endif + if ((ret = wc_InitSha512_ex(sha512, heap, devId)) != 0) { WOLFSSL_MSG("InitSha512 failed"); } @@ -1519,6 +1554,13 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags) return MEMORY_E; #endif + #ifdef WOLF_CRYPTO_CB + /* find devId if its not an empty hash */ + if (devId == INVALID_DEVID && data != NULL && len > 0) { + devId = wc_CryptoCb_DefaultDevID(); + } + #endif + if ((ret = wc_InitSha512_224_ex(sha512, heap, devId)) != 0) { WOLFSSL_MSG("wc_InitSha512_224 failed"); } @@ -1564,6 +1606,13 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags) return MEMORY_E; #endif + #ifdef WOLF_CRYPTO_CB + /* find devId if its not an empty hash */ + if (devId == INVALID_DEVID && data != NULL && len > 0) { + devId = wc_CryptoCb_DefaultDevID(); + } + #endif + if ((ret = wc_InitSha512_256_ex(sha512, heap, devId)) != 0) { WOLFSSL_MSG("wc_InitSha512_256 failed"); } @@ -1610,6 +1659,13 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags) return MEMORY_E; #endif + #ifdef WOLF_CRYPTO_CB + /* find devId if its not an empty hash */ + if (devId == INVALID_DEVID && data != NULL && len > 0) { + devId = wc_CryptoCb_DefaultDevID(); + } + #endif + if ((ret = wc_InitSha384_ex(sha384, heap, devId)) != 0) { WOLFSSL_MSG("InitSha384 failed"); } @@ -1654,6 +1710,13 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags) return MEMORY_E; #endif + #ifdef WOLF_CRYPTO_CB + /* find devId if its not an empty hash */ + if (devId == INVALID_DEVID && data != NULL && len > 0) { + devId = wc_CryptoCb_DefaultDevID(); + } + #endif + if ((ret = wc_InitSha3_224(sha3, heap, devId)) != 0) { WOLFSSL_MSG("InitSha3_224 failed"); } @@ -1697,6 +1760,13 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags) return MEMORY_E; #endif + #ifdef WOLF_CRYPTO_CB + /* find devId if its not an empty hash */ + if (devId == INVALID_DEVID && data != NULL && len > 0) { + devId = wc_CryptoCb_DefaultDevID(); + } + #endif + if ((ret = wc_InitSha3_256(sha3, heap, devId)) != 0) { WOLFSSL_MSG("InitSha3_256 failed"); } @@ -1740,6 +1810,13 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags) return MEMORY_E; #endif + #ifdef WOLF_CRYPTO_CB + /* find devId if its not an empty hash */ + if (devId == INVALID_DEVID && data != NULL && len > 0) { + devId = wc_CryptoCb_DefaultDevID(); + } + #endif + if ((ret = wc_InitSha3_384(sha3, heap, devId)) != 0) { WOLFSSL_MSG("InitSha3_384 failed"); } @@ -1783,6 +1860,13 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags) return MEMORY_E; #endif + #ifdef WOLF_CRYPTO_CB + /* find devId if its not an empty hash */ + if (devId == INVALID_DEVID && data != NULL && len > 0) { + devId = wc_CryptoCb_DefaultDevID(); + } + #endif + if ((ret = wc_InitSha3_512(sha3, heap, devId)) != 0) { WOLFSSL_MSG("InitSha3_512 failed"); } @@ -1826,6 +1910,13 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags) return MEMORY_E; #endif + #ifdef WOLF_CRYPTO_CB + /* find devId if its not an empty hash */ + if (devId == INVALID_DEVID && data != NULL && len > 0) { + devId = wc_CryptoCb_DefaultDevID(); + } + #endif + if ((ret = wc_InitShake128(shake, heap, devId)) != 0) { WOLFSSL_MSG("InitShake128 failed"); } @@ -1870,6 +1961,13 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags) return MEMORY_E; #endif + #ifdef WOLF_CRYPTO_CB + /* find devId if its not an empty hash */ + if (devId == INVALID_DEVID && data != NULL && len > 0) { + devId = wc_CryptoCb_DefaultDevID(); + } + #endif + if ((ret = wc_InitShake256(shake, heap, devId)) != 0) { WOLFSSL_MSG("InitShake256 failed"); } @@ -1914,6 +2012,13 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags) return MEMORY_E; #endif + #ifdef WOLF_CRYPTO_CB + /* find devId if its not an empty hash */ + if (devId == INVALID_DEVID && data != NULL && len > 0) { + devId = wc_CryptoCb_DefaultDevID(); + } + #endif + if ((ret = wc_InitSm3(sm3, heap, devId)) != 0) { WOLFSSL_MSG("InitSm3 failed"); } diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c index cc47fab27..16c0d3309 100644 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -311,7 +311,7 @@ enum { typedef struct DRBG_internal DRBG_internal; -static int wc_RNG_HealthTestLocal(int reseed); +static int wc_RNG_HealthTestLocal(int reseed, void* heap, int devId); /* Hash Derivation Function */ /* Returns: DRBG_SUCCESS or DRBG_FAILURE */ @@ -1619,7 +1619,7 @@ static int _InitRng(WC_RNG* rng, byte* nonce, word32 nonceSz, if (nonceSz == 0) seedSz = MAX_SEED_SZ; - if (wc_RNG_HealthTestLocal(0) == 0) { + if (wc_RNG_HealthTestLocal(0, rng->heap, devId) == 0) { #ifndef WOLFSSL_SMALL_STACK byte seed[MAX_SEED_SZ]; #else @@ -1830,7 +1830,11 @@ int wc_RNG_GenerateBlock(WC_RNG* rng, byte* output, word32 sz) ret = Hash_DRBG_Generate((DRBG_internal *)rng->drbg, output, sz); if (ret == DRBG_NEED_RESEED) { - if (wc_RNG_HealthTestLocal(1) == 0) { + int devId = INVALID_DEVID; + #if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLF_CRYPTO_CB) + devId = rng->devId; + #endif + if (wc_RNG_HealthTestLocal(1, rng->heap, devId) == 0) { #ifndef WOLFSSL_SMALL_STACK byte newSeed[SEED_SZ + SEED_BLOCK_SZ]; ret = DRBG_SUCCESS; @@ -2083,7 +2087,7 @@ const FLASH_QUALIFIER byte outputB_data[] = { }; -static int wc_RNG_HealthTestLocal(int reseed) +static int wc_RNG_HealthTestLocal(int reseed, void* heap, int devId) { int ret = 0; #ifdef WOLFSSL_SMALL_STACK @@ -2102,17 +2106,17 @@ static int wc_RNG_HealthTestLocal(int reseed) if (reseed) { #ifdef WOLFSSL_USE_FLASHMEM - byte* seedA = (byte*)XMALLOC(sizeof(seedA_data), NULL, + byte* seedA = (byte*)XMALLOC(sizeof(seedA_data), heap, DYNAMIC_TYPE_TMP_BUFFER); - byte* reseedSeedA = (byte*)XMALLOC(sizeof(reseedSeedA_data), NULL, + byte* reseedSeedA = (byte*)XMALLOC(sizeof(reseedSeedA_data), heap, DYNAMIC_TYPE_TMP_BUFFER); - byte* outputA = (byte*)XMALLOC(sizeof(outputA_data), NULL, + byte* outputA = (byte*)XMALLOC(sizeof(outputA_data), heap, DYNAMIC_TYPE_TMP_BUFFER); if (!seedA || !reseedSeedA || !outputA) { - XFREE(seedA, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(reseedSeedA, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(outputA, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(seedA, heap, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(reseedSeedA, heap, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(outputA, heap, DYNAMIC_TYPE_TMP_BUFFER); ret = MEMORY_E; } else { @@ -2124,9 +2128,11 @@ static int wc_RNG_HealthTestLocal(int reseed) const byte* reseedSeedA = reseedSeedA_data; const byte* outputA = outputA_data; #endif - ret = wc_RNG_HealthTest(1, seedA, sizeof(seedA_data), - reseedSeedA, sizeof(reseedSeedA_data), - check, RNG_HEALTH_TEST_CHECK_SIZE); + ret = wc_RNG_HealthTest_ex(1, NULL, 0, + seedA, sizeof(seedA_data), + reseedSeedA, sizeof(reseedSeedA_data), + check, RNG_HEALTH_TEST_CHECK_SIZE, + heap, devId); if (ret == 0) { if (ConstantCompare(check, outputA, RNG_HEALTH_TEST_CHECK_SIZE) != 0) @@ -2142,14 +2148,14 @@ static int wc_RNG_HealthTestLocal(int reseed) } else { #ifdef WOLFSSL_USE_FLASHMEM - byte* seedB = (byte*)XMALLOC(sizeof(seedB_data), NULL, + byte* seedB = (byte*)XMALLOC(sizeof(seedB_data), heap, DYNAMIC_TYPE_TMP_BUFFER); - byte* outputB = (byte*)XMALLOC(sizeof(outputB_data), NULL, + byte* outputB = (byte*)XMALLOC(sizeof(outputB_data), heap, DYNAMIC_TYPE_TMP_BUFFER); if (!seedB || !outputB) { - XFREE(seedB, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(outputB, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(seedB, heap, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(outputB, heap, DYNAMIC_TYPE_TMP_BUFFER); ret = MEMORY_E; } else { @@ -2159,9 +2165,11 @@ static int wc_RNG_HealthTestLocal(int reseed) const byte* seedB = seedB_data; const byte* outputB = outputB_data; #endif - ret = wc_RNG_HealthTest(0, seedB, sizeof(seedB_data), - NULL, 0, - check, RNG_HEALTH_TEST_CHECK_SIZE); + ret = wc_RNG_HealthTest_ex(0, NULL, 0, + seedB, sizeof(seedB_data), + NULL, 0, + check, RNG_HEALTH_TEST_CHECK_SIZE, + heap, devId); if (ret == 0) { if (ConstantCompare(check, outputB, RNG_HEALTH_TEST_CHECK_SIZE) != 0) @@ -2174,11 +2182,11 @@ static int wc_RNG_HealthTestLocal(int reseed) * byte 32, feed them into the health test separately. */ if (ret == 0) { ret = wc_RNG_HealthTest_ex(0, - seedB + 32, sizeof(seedB_data) - 32, - seedB, 32, - NULL, 0, - check, RNG_HEALTH_TEST_CHECK_SIZE, - NULL, INVALID_DEVID); + seedB + 32, sizeof(seedB_data) - 32, + seedB, 32, + NULL, 0, + check, RNG_HEALTH_TEST_CHECK_SIZE, + heap, devId); if (ret == 0) { if (ConstantCompare(check, outputB, sizeof(outputB_data)) != 0) ret = -1; @@ -2186,8 +2194,8 @@ static int wc_RNG_HealthTestLocal(int reseed) } #ifdef WOLFSSL_USE_FLASHMEM - XFREE(seedB, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(outputB, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(seedB, heap, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(outputB, heap, DYNAMIC_TYPE_TMP_BUFFER); } #endif } From 41d4f4a972231a9be1423766f178eb7a4f9c6fd7 Mon Sep 17 00:00:00 2001 From: David Garske Date: Tue, 19 Dec 2023 12:30:53 -0800 Subject: [PATCH 07/13] Fix TLS v1.2 case where SHA-1 could be used uninitialized. Exclude the SHA1 struct from HS_Hashes when not needed. Fixes mix-match of the SHA-1 with `NO_OLD_TLS` and `WOLFSSL_ALLOW_TLS_SHA1`. --- src/internal.c | 54 +++++++++++++++++++++++----------------------- wolfssl/internal.h | 3 ++- 2 files changed, 29 insertions(+), 28 deletions(-) diff --git a/src/internal.c b/src/internal.c index beff94a31..df21a6bfb 100644 --- a/src/internal.c +++ b/src/internal.c @@ -6839,8 +6839,7 @@ int InitHandshakeHashes(WOLFSSL* ssl) } XMEMSET(ssl->hsHashes, 0, sizeof(HS_Hashes)); -#ifndef NO_OLD_TLS -#ifndef NO_MD5 +#if !defined(NO_MD5) && !defined(NO_OLD_TLS) ret = wc_InitMd5_ex(&ssl->hsHashes->hashMd5, ssl->heap, ssl->devId); if (ret != 0) return ret; @@ -6848,7 +6847,8 @@ int InitHandshakeHashes(WOLFSSL* ssl) wc_Md5SetFlags(&ssl->hsHashes->hashMd5, WC_HASH_FLAG_WILLCOPY); #endif #endif -#ifndef NO_SHA +#if !defined(NO_SHA) && (!defined(NO_OLD_TLS) || \ + defined(WOLFSSL_ALLOW_TLS_SHA1)) ret = wc_InitSha_ex(&ssl->hsHashes->hashSha, ssl->heap, ssl->devId); if (ret != 0) return ret; @@ -6856,7 +6856,6 @@ int InitHandshakeHashes(WOLFSSL* ssl) wc_ShaSetFlags(&ssl->hsHashes->hashSha, WC_HASH_FLAG_WILLCOPY); #endif #endif -#endif /* !NO_OLD_TLS */ #ifndef NO_SHA256 ret = wc_InitSha256_ex(&ssl->hsHashes->hashSha256, ssl->heap, ssl->devId); if (ret != 0) @@ -6896,14 +6895,13 @@ int InitHandshakeHashes(WOLFSSL* ssl) void FreeHandshakeHashes(WOLFSSL* ssl) { if (ssl->hsHashes) { -#ifndef NO_OLD_TLS - #ifndef NO_MD5 + #if !defined(NO_MD5) && !defined(NO_OLD_TLS) wc_Md5Free(&ssl->hsHashes->hashMd5); #endif - #ifndef NO_SHA + #if !defined(NO_SHA) && (!defined(NO_OLD_TLS) || \ + defined(WOLFSSL_ALLOW_TLS_SHA1)) wc_ShaFree(&ssl->hsHashes->hashSha); #endif -#endif /* !NO_OLD_TLS */ #ifndef NO_SHA256 wc_Sha256Free(&ssl->hsHashes->hashSha256); #endif @@ -9836,14 +9834,13 @@ int HashRaw(WOLFSSL* ssl, const byte* data, int sz) } #endif /* WOLFSSL_RENESAS_TSIP_TLS */ -#ifndef NO_OLD_TLS - #ifndef NO_SHA - wc_ShaUpdate(&ssl->hsHashes->hashSha, data, sz); - #endif - #ifndef NO_MD5 - wc_Md5Update(&ssl->hsHashes->hashMd5, data, sz); - #endif -#endif /* NO_OLD_TLS */ +#if !defined(NO_SHA) && (!defined(NO_OLD_TLS) || \ + defined(WOLFSSL_ALLOW_TLS_SHA1)) + wc_ShaUpdate(&ssl->hsHashes->hashSha, data, sz); +#endif +#if !defined(NO_MD5) && !defined(NO_OLD_TLS) + wc_Md5Update(&ssl->hsHashes->hashMd5, data, sz); +#endif if (IsAtLeastTLSv1_2(ssl)) { #ifndef NO_SHA256 @@ -11454,7 +11451,7 @@ static int BuildMD5(WOLFSSL* ssl, Hashes* hashes, const byte* sender) if (ret == 0) ret = wc_Md5Update(md5, sender, SIZEOF_SENDER); if (ret == 0) - ret = wc_Md5Update(md5, ssl->arrays->masterSecret,SECRET_LEN); + ret = wc_Md5Update(md5, ssl->arrays->masterSecret, SECRET_LEN); if (ret == 0) ret = wc_Md5Update(md5, PAD1, PAD_MD5); if (ret == 0) @@ -11464,7 +11461,7 @@ static int BuildMD5(WOLFSSL* ssl, Hashes* hashes, const byte* sender) if (ret == 0) { ret = wc_InitMd5_ex(md5, ssl->heap, ssl->devId); if (ret == 0) { - ret = wc_Md5Update(md5, ssl->arrays->masterSecret,SECRET_LEN); + ret = wc_Md5Update(md5, ssl->arrays->masterSecret, SECRET_LEN); if (ret == 0) ret = wc_Md5Update(md5, PAD2, PAD_MD5); if (ret == 0) @@ -11500,7 +11497,7 @@ static int BuildSHA(WOLFSSL* ssl, Hashes* hashes, const byte* sender) if (ret == 0) ret = wc_ShaUpdate(sha, sender, SIZEOF_SENDER); if (ret == 0) - ret = wc_ShaUpdate(sha, ssl->arrays->masterSecret,SECRET_LEN); + ret = wc_ShaUpdate(sha, ssl->arrays->masterSecret, SECRET_LEN); if (ret == 0) ret = wc_ShaUpdate(sha, PAD1, PAD_SHA); if (ret == 0) @@ -11510,7 +11507,7 @@ static int BuildSHA(WOLFSSL* ssl, Hashes* hashes, const byte* sender) if (ret == 0) { ret = wc_InitSha_ex(sha, ssl->heap, ssl->devId); if (ret == 0) { - ret = wc_ShaUpdate(sha, ssl->arrays->masterSecret,SECRET_LEN); + ret = wc_ShaUpdate(sha, ssl->arrays->masterSecret, SECRET_LEN); if (ret == 0) ret = wc_ShaUpdate(sha, PAD2, PAD_SHA); if (ret == 0) @@ -21992,7 +21989,8 @@ static int BuildMD5_CertVerify(const WOLFSSL* ssl, byte* digest) int ret; byte md5_result[WC_MD5_DIGEST_SIZE]; #ifdef WOLFSSL_SMALL_STACK - wc_Md5* md5 = (wc_Md5*)XMALLOC(sizeof(wc_Md5), ssl->heap, DYNAMIC_TYPE_HASHCTX); + wc_Md5* md5 = (wc_Md5*)XMALLOC(sizeof(wc_Md5), ssl->heap, + DYNAMIC_TYPE_HASHCTX); #else wc_Md5 md5[1]; #endif @@ -22000,7 +21998,7 @@ static int BuildMD5_CertVerify(const WOLFSSL* ssl, byte* digest) /* make md5 inner */ ret = wc_Md5Copy(&ssl->hsHashes->hashMd5, md5); /* Save current position */ if (ret == 0) - ret = wc_Md5Update(md5, ssl->arrays->masterSecret,SECRET_LEN); + ret = wc_Md5Update(md5, ssl->arrays->masterSecret, SECRET_LEN); if (ret == 0) ret = wc_Md5Update(md5, PAD1, PAD_MD5); if (ret == 0) @@ -22036,7 +22034,8 @@ static int BuildSHA_CertVerify(const WOLFSSL* ssl, byte* digest) int ret; byte sha_result[WC_SHA_DIGEST_SIZE]; #ifdef WOLFSSL_SMALL_STACK - wc_Sha* sha = (wc_Sha*)XMALLOC(sizeof(wc_Sha), ssl->heap, DYNAMIC_TYPE_HASHCTX); + wc_Sha* sha = (wc_Sha*)XMALLOC(sizeof(wc_Sha), ssl->heap, + DYNAMIC_TYPE_HASHCTX); #else wc_Sha sha[1]; #endif @@ -22044,7 +22043,7 @@ static int BuildSHA_CertVerify(const WOLFSSL* ssl, byte* digest) /* make sha inner */ ret = wc_ShaCopy(&ssl->hsHashes->hashSha, sha); /* Save current position */ if (ret == 0) - ret = wc_ShaUpdate(sha, ssl->arrays->masterSecret,SECRET_LEN); + ret = wc_ShaUpdate(sha, ssl->arrays->masterSecret, SECRET_LEN); if (ret == 0) ret = wc_ShaUpdate(sha, PAD1, PAD_SHA); if (ret == 0) @@ -22054,7 +22053,7 @@ static int BuildSHA_CertVerify(const WOLFSSL* ssl, byte* digest) if (ret == 0) { ret = wc_InitSha_ex(sha, ssl->heap, ssl->devId); if (ret == 0) { - ret = wc_ShaUpdate(sha, ssl->arrays->masterSecret,SECRET_LEN); + ret = wc_ShaUpdate(sha, ssl->arrays->masterSecret, SECRET_LEN); if (ret == 0) ret = wc_ShaUpdate(sha, PAD2, PAD_SHA); if (ret == 0) @@ -22085,7 +22084,8 @@ int BuildCertHashes(const WOLFSSL* ssl, Hashes* hashes) if (ret != 0) return ret; #endif - #if !defined(NO_SHA) + #if !defined(NO_SHA) && (!defined(NO_OLD_TLS) || \ + defined(WOLFSSL_ALLOW_TLS_SHA1)) ret = wc_ShaGetHash(&ssl->hsHashes->hashSha, hashes->sha); if (ret != 0) return ret; @@ -34935,7 +34935,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #ifndef NO_SHA wc_ShaUpdate(&ssl->hsHashes->hashSha, input + idx, sz); #endif -#endif +#endif /* !NO_OLD_TLS */ #ifndef NO_SHA256 if (IsAtLeastTLSv1_2(ssl)) { int shaRet = wc_Sha256Update(&ssl->hsHashes->hashSha256, diff --git a/wolfssl/internal.h b/wolfssl/internal.h index f59da64fa..658a90a4d 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -5189,7 +5189,8 @@ typedef struct MsgsReceived { typedef struct HS_Hashes { Hashes verifyHashes; Hashes certHashes; /* for cert verify */ -#ifndef NO_SHA +#if !defined(NO_SHA) && (!defined(NO_OLD_TLS) || \ + defined(WOLFSSL_ALLOW_TLS_SHA1)) wc_Sha hashSha; /* sha hash of handshake msgs */ #endif #if !defined(NO_MD5) && !defined(NO_OLD_TLS) From 0d212d805546d53d77fc4ca78dbd23f7e13934d0 Mon Sep 17 00:00:00 2001 From: David Garske Date: Thu, 21 Dec 2023 09:41:29 -0800 Subject: [PATCH 08/13] Further cleanup for `Hashes.sha` when not required. Gate all TLS SHA-1 on either old TLS or `WOLFSSL_ALLOW_TLS_SHA1`. --- src/internal.c | 5 +++-- wolfssl/internal.h | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/internal.c b/src/internal.c index df21a6bfb..61bffd7bc 100644 --- a/src/internal.c +++ b/src/internal.c @@ -4644,7 +4644,8 @@ static WC_INLINE void EncodeSigAlg(byte hashAlgo, byte hsType, byte* output) static void SetDigest(WOLFSSL* ssl, int hashAlgo) { switch (hashAlgo) { - #ifndef NO_SHA + #if !defined(NO_SHA) && (!defined(NO_OLD_TLS) || \ + defined(WOLFSSL_ALLOW_TLS_SHA1)) case sha_mac: ssl->options.dontFreeDigest = 1; ssl->buffers.digest.buffer = ssl->hsHashes->certHashes.sha; @@ -22028,7 +22029,7 @@ static int BuildMD5_CertVerify(const WOLFSSL* ssl, byte* digest) #endif /* !NO_MD5 && !NO_OLD_TLS */ #if !defined(NO_SHA) && (!defined(NO_OLD_TLS) || \ - defined(WOLFSSL_ALLOW_TLS_SHA1)) + defined(WOLFSSL_ALLOW_TLS_SHA1)) static int BuildSHA_CertVerify(const WOLFSSL* ssl, byte* digest) { int ret; diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 658a90a4d..6da5b895a 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -4176,7 +4176,8 @@ typedef struct Hashes { #if !defined(NO_MD5) && !defined(NO_OLD_TLS) byte md5[WC_MD5_DIGEST_SIZE]; #endif - #if !defined(NO_SHA) + #if !defined(NO_SHA) && (!defined(NO_OLD_TLS) || \ + defined(WOLFSSL_ALLOW_TLS_SHA1)) byte sha[WC_SHA_DIGEST_SIZE]; #endif #ifndef NO_SHA256 From d9ac8b5422ff76f0799f205f99c0116f6ac39058 Mon Sep 17 00:00:00 2001 From: David Garske Date: Fri, 22 Dec 2023 14:16:59 -0800 Subject: [PATCH 09/13] Peer review fixes. Fix issues with `Tls13HKDFExpandKeyLabel`. Fix crypto callback line lengths. --- src/tls13.c | 37 ++++++++++++++++--------------------- wolfcrypt/src/cryptocb.c | 24 ++++++++++++++++-------- 2 files changed, 32 insertions(+), 29 deletions(-) diff --git a/src/tls13.c b/src/tls13.c index af7971aa3..e59942576 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -241,7 +241,6 @@ static int Tls13HKDFExpandLabel(WOLFSSL* ssl, byte* okm, word32 okmLen, return ret; } -#if !defined(HAVE_FIPS) || !defined(wc_Tls13_HKDF_Expand_Label) /* Same as above, but pass in the side we are expanding for. * * side The side (WOLFSSL_CLIENT_END or WOLFSSL_SERVER_END). @@ -253,8 +252,9 @@ static int Tls13HKDFExpandKeyLabel(WOLFSSL* ssl, byte* okm, word32 okmLen, const byte* info, word32 infoLen, int digest, int side) { + int ret; #if defined(HAVE_PK_CALLBACKS) - int ret = NOT_COMPILED_IN; + ret = NOT_COMPILED_IN; if (ssl->ctx && ssl->ctx->HKDFExpandLabelCb) { ret = ssl->ctx->HKDFExpandLabelCb(okm, okmLen, prk, prkLen, protocol, protocolLen, @@ -262,33 +262,38 @@ static int Tls13HKDFExpandKeyLabel(WOLFSSL* ssl, byte* okm, word32 okmLen, info, infoLen, digest, side); } - if (ret != NOT_COMPILED_IN) return ret; #endif -/* hash buffer may not be fully initialized, but the sending length won't - * extend beyond the initialized span. - */ + /* Hash buffer may not be fully initialized, but the sending length won't + * extend beyond the initialized span. */ PRAGMA_GCC_DIAG_PUSH PRAGMA_GCC("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") - (void)ssl; - (void)side; #if !defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)) - return wc_Tls13_HKDF_Expand_Label_ex(okm, okmLen, prk, prkLen, + ret = wc_Tls13_HKDF_Expand_Label_ex(okm, okmLen, prk, prkLen, protocol, protocolLen, label, labelLen, info, infoLen, digest, ssl->heap, ssl->devId); + +#elif defined(HAVE_FIPS) && defined(wc_Tls13_HKDF_Expand_Label) + ret = wc_Tls13_HKDF_Expand_Label_fips(okm, okmLen, prk, prkLen, + protocol, protocolLen, + label, labelLen, + info, infoLen, digest); #else - return wc_Tls13_HKDF_Expand_Label(okm, okmLen, prk, prkLen, + ret = wc_Tls13_HKDF_Expand_Label(okm, okmLen, prk, prkLen, protocol, protocolLen, label, labelLen, info, infoLen, digest); #endif PRAGMA_GCC_DIAG_POP + (void)ssl; + (void)side; + return ret; } -#endif /* !HAVE_FIPS || !wc_Tls13_HKDF_Expand_Label */ + /* Derive a key from a message. * @@ -493,26 +498,16 @@ int Tls13DeriveKey(WOLFSSL* ssl, byte* output, int outputLen, /* hash buffer may not be fully initialized, but the sending length won't * extend beyond the initialized span. */ - PRAGMA_GCC_DIAG_PUSH - PRAGMA_GCC("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") PRIVATE_KEY_UNLOCK(); - #if defined(HAVE_FIPS) && defined(wc_Tls13_HKDF_Expand_Label) - (void)side; - ret = wc_Tls13_HKDF_Expand_Label_fips(output, outputLen, secret, hashSz, - protocol, protocolLen, label, labelLen, - hash, hashOutSz, digestAlg); - #else ret = Tls13HKDFExpandKeyLabel(ssl, output, outputLen, secret, hashSz, protocol, protocolLen, label, labelLen, hash, hashOutSz, digestAlg, side); - #endif PRIVATE_KEY_LOCK(); #ifdef WOLFSSL_CHECK_MEM_ZERO wc_MemZero_Add("TLS 1.3 derived key", output, outputLen); #endif return ret; - PRAGMA_GCC_DIAG_POP } /* Convert TLS mac ID to a hash algorithm ID diff --git a/wolfcrypt/src/cryptocb.c b/wolfcrypt/src/cryptocb.c index e46429d87..ce49e4671 100644 --- a/wolfcrypt/src/cryptocb.c +++ b/wolfcrypt/src/cryptocb.c @@ -181,27 +181,35 @@ WOLFSSL_API void wc_CryptoCb_InfoString(wc_CryptoInfo* info) else #endif { - printf("Crypto CB: %s %s (%d)\n", GetAlgoTypeStr(info->algo_type), + printf("Crypto CB: %s %s (%d)\n", + GetAlgoTypeStr(info->algo_type), GetPkTypeStr(info->pk.type), info->pk.type); } } else if (info->algo_type == WC_ALGO_TYPE_CIPHER) { - printf("Crypto CB: %s %s (%d) (%p ctx)\n", GetAlgoTypeStr(info->algo_type), - GetCipherTypeStr(info->cipher.type), info->cipher.type, info->cipher.ctx); + printf("Crypto CB: %s %s (%d) (%p ctx)\n", + GetAlgoTypeStr(info->algo_type), + GetCipherTypeStr(info->cipher.type), + info->cipher.type, info->cipher.ctx); } else if (info->algo_type == WC_ALGO_TYPE_HASH) { - printf("Crypto CB: %s %s (%d) (%p ctx) %s\n", GetAlgoTypeStr(info->algo_type), - GetHashTypeStr(info->hash.type), info->hash.type, info->hash.ctx, + printf("Crypto CB: %s %s (%d) (%p ctx) %s\n", + GetAlgoTypeStr(info->algo_type), + GetHashTypeStr(info->hash.type), + info->hash.type, info->hash.ctx, (info->hash.in != NULL) ? "Update" : "Final"); } else if (info->algo_type == WC_ALGO_TYPE_HMAC) { - printf("Crypto CB: %s %s (%d) (%p ctx) %s\n", GetAlgoTypeStr(info->algo_type), - GetHashTypeStr(info->hmac.macType), info->hmac.macType, info->hmac.hmac, + printf("Crypto CB: %s %s (%d) (%p ctx) %s\n", + GetAlgoTypeStr(info->algo_type), + GetHashTypeStr(info->hmac.macType), + info->hmac.macType, info->hmac.hmac, (info->hmac.in != NULL) ? "Update" : "Final"); } #ifdef WOLF_CRYPTO_CB_CMD else if (info->algo_type == WC_ALGO_TYPE_NONE) { - printf("Crypto CB: %s %s (%d)\n", GetAlgoTypeStr(info->algo_type), + printf("Crypto CB: %s %s (%d)\n", + GetAlgoTypeStr(info->algo_type), GetCryptoCbCmdTypeStr(info->cmd.type), info->cmd.type); } #endif From b86dfffdbed71c889f6e6f8cea6bcf7404b8fa12 Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 27 Dec 2023 09:52:56 -0800 Subject: [PATCH 10/13] Improve the TLS v1.3 expand key label warning for possible use of uninitialized "hash". --- src/tls13.c | 22 ++++++++++++---------- wolfcrypt/src/kdf.c | 24 +++++++++++++++--------- 2 files changed, 27 insertions(+), 19 deletions(-) diff --git a/src/tls13.c b/src/tls13.c index e59942576..208ce0e13 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -266,10 +266,6 @@ static int Tls13HKDFExpandKeyLabel(WOLFSSL* ssl, byte* okm, word32 okmLen, return ret; #endif - /* Hash buffer may not be fully initialized, but the sending length won't - * extend beyond the initialized span. */ -PRAGMA_GCC_DIAG_PUSH -PRAGMA_GCC("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") #if !defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)) ret = wc_Tls13_HKDF_Expand_Label_ex(okm, okmLen, prk, prkLen, protocol, protocolLen, @@ -288,7 +284,6 @@ PRAGMA_GCC("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") label, labelLen, info, infoLen, digest); #endif -PRAGMA_GCC_DIAG_POP (void)ssl; (void)side; return ret; @@ -490,14 +485,21 @@ int Tls13DeriveKey(WOLFSSL* ssl, byte* output, int outputLen, } #endif /* WOLFSSL_DTLS13 */ - if (outputLen == -1) + if (outputLen == -1) { outputLen = hashSz; - if (includeMsgs) + } + if (includeMsgs) { hashOutSz = hashSz; + } + else { + /* Appease static analyzers by making sure hash is cleared, since it is + * passed into expand key label where older wc_Tls13_HKDF_Expand_Label + * will unconditionally try to call a memcpy on it, however length will + * always be 0. */ + XMEMSET(hash, 0, sizeof(hash)); + hashOutSz = 0; + } - /* hash buffer may not be fully initialized, but the sending length won't - * extend beyond the initialized span. - */ PRIVATE_KEY_UNLOCK(); ret = Tls13HKDFExpandKeyLabel(ssl, output, outputLen, secret, hashSz, protocol, protocolLen, label, labelLen, diff --git a/wolfcrypt/src/kdf.c b/wolfcrypt/src/kdf.c index 9b289be45..9dcb12076 100644 --- a/wolfcrypt/src/kdf.c +++ b/wolfcrypt/src/kdf.c @@ -485,17 +485,23 @@ int wc_PRF_TLS(byte* digest, word32 digLen, const byte* secret, word32 secLen, data[idx++] = (byte)okmLen; /* Length of protocol | label. */ data[idx++] = (byte)(protocolLen + labelLen); - /* Protocol */ - XMEMCPY(&data[idx], protocol, protocolLen); - idx += protocolLen; - /* Label */ - XMEMCPY(&data[idx], label, labelLen); - idx += labelLen; + if (protocolLen > 0) { + /* Protocol */ + XMEMCPY(&data[idx], protocol, protocolLen); + idx += protocolLen; + } + if (labelLen > 0) { + /* Label */ + XMEMCPY(&data[idx], label, labelLen); + idx += labelLen; + } /* Length of hash of messages */ data[idx++] = (byte)infoLen; - /* Hash of messages */ - XMEMCPY(&data[idx], info, infoLen); - idx += infoLen; + if (infoLen > 0) { + /* Hash of messages */ + XMEMCPY(&data[idx], info, infoLen); + idx += infoLen; + } #ifdef WOLFSSL_CHECK_MEM_ZERO wc_MemZero_Add("wc_Tls13_HKDF_Expand_Label data", data, idx); From 0d057099af551dab1e8b6336d35f89b500bb887f Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 27 Dec 2023 10:12:52 -0800 Subject: [PATCH 11/13] Fix line lengths. --- src/tls13.c | 9 ++++++--- wolfcrypt/src/hash.c | 6 ++++-- wolfssl/wolfcrypt/kdf.h | 3 ++- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/tls13.c b/src/tls13.c index 208ce0e13..432eb2a96 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -1134,7 +1134,8 @@ static int Tls13_HKDF_Extract(WOLFSSL *ssl, byte* prk, const byte* salt, else #endif { - #if !defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)) + #if !defined(HAVE_FIPS) || \ + (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)) ret = wc_Tls13_HKDF_Extract_ex(prk, salt, saltLen, ikm, ikmLen, digest, ssl->heap, ssl->devId); #else @@ -4806,7 +4807,8 @@ static int EchCheckAcceptance(WOLFSSL* ssl, const byte* input, /* extract clientRandomInner with a key of all zeros */ if (ret == 0) { PRIVATE_KEY_UNLOCK(); - #if !defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)) + #if !defined(HAVE_FIPS) || \ + (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)) ret = wc_HKDF_Extract_ex(digestType, zeros, digestSize, ssl->arrays->clientRandomInner, RAN_LEN, expandLabelPrk, ssl->heap, ssl->devId); @@ -4943,7 +4945,8 @@ static int EchWriteAcceptance(WOLFSSL* ssl, byte* output, /* extract clientRandom with a key of all zeros */ if (ret == 0) { PRIVATE_KEY_UNLOCK(); - #if !defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)) + #if !defined(HAVE_FIPS) || \ + (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)) ret = wc_HKDF_Extract_ex(digestType, zeros, digestSize, ssl->arrays->clientRandom, RAN_LEN, expandLabelPrk, ssl->heap, ssl->devId); diff --git a/wolfcrypt/src/hash.c b/wolfcrypt/src/hash.c index 3f6488660..62f9980e1 100644 --- a/wolfcrypt/src/hash.c +++ b/wolfcrypt/src/hash.c @@ -1939,7 +1939,8 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags) int wc_Shake128Hash(const byte* data, word32 len, byte* hash, word32 hashLen) { - return wc_Shake128Hash_ex(data, len, hash, hashLen, NULL, INVALID_DEVID); + return wc_Shake128Hash_ex(data, len, hash, hashLen, + NULL, INVALID_DEVID); } #endif /* WOLFSSL_SHAKE_128 */ @@ -1990,7 +1991,8 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags) int wc_Shake256Hash(const byte* data, word32 len, byte* hash, word32 hashLen) { - return wc_Shake256Hash_ex(data, len, hash, hashLen, NULL, INVALID_DEVID); + return wc_Shake256Hash_ex(data, len, hash, hashLen, + NULL, INVALID_DEVID); } #endif /* WOLFSSL_SHAKE_256 */ #endif /* WOLFSSL_SHA3 */ diff --git a/wolfssl/wolfcrypt/kdf.h b/wolfssl/wolfcrypt/kdf.h index ab4df120c..fe551dc3b 100644 --- a/wolfssl/wolfcrypt/kdf.h +++ b/wolfssl/wolfcrypt/kdf.h @@ -77,7 +77,8 @@ enum { }; WOLFSSL_LOCAL int wc_Tls13_HKDF_Extract_ex(byte* prk, const byte* salt, - word32 saltLen, byte* ikm, word32 ikmLen, int digest, void* heap, int devId); + word32 saltLen, byte* ikm, word32 ikmLen, int digest, + void* heap, int devId); WOLFSSL_API int wc_Tls13_HKDF_Extract(byte* prk, const byte* salt, word32 saltLen, byte* ikm, word32 ikmLen, int digest); From cca6cc0495c3577e0ea78447767bae384fd71767 Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 27 Dec 2023 11:40:29 -0800 Subject: [PATCH 12/13] Make new HDFK _ex functions public. --- wolfssl/wolfcrypt/hmac.h | 7 ++++--- wolfssl/wolfcrypt/kdf.h | 8 ++++---- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/wolfssl/wolfcrypt/hmac.h b/wolfssl/wolfcrypt/hmac.h index fc6dc2ee3..929d8b2b0 100644 --- a/wolfssl/wolfcrypt/hmac.h +++ b/wolfssl/wolfcrypt/hmac.h @@ -210,13 +210,14 @@ WOLFSSL_LOCAL int _InitHmac(Hmac* hmac, int type, void* heap); #ifdef HAVE_HKDF -WOLFSSL_LOCAL int wc_HKDF_Extract_ex(int type, const byte* salt, word32 saltSz, - const byte* inKey, word32 inKeySz, byte* out, void* heap, int devId); +WOLFSSL_API int wc_HKDF_Extract_ex(int type, const byte* salt, word32 saltSz, + const byte* inKey, word32 inKeySz, byte* out, + void* heap, int devId); WOLFSSL_API int wc_HKDF_Extract(int type, const byte* salt, word32 saltSz, const byte* inKey, word32 inKeySz, byte* out); -WOLFSSL_LOCAL int wc_HKDF_Expand_ex(int type, const byte* inKey, word32 inKeySz, +WOLFSSL_API int wc_HKDF_Expand_ex(int type, const byte* inKey, word32 inKeySz, const byte* info, word32 infoSz, byte* out, word32 outSz, void* heap, int devId); WOLFSSL_API int wc_HKDF_Expand(int type, const byte* inKey, word32 inKeySz, diff --git a/wolfssl/wolfcrypt/kdf.h b/wolfssl/wolfcrypt/kdf.h index fe551dc3b..7fa3c7e78 100644 --- a/wolfssl/wolfcrypt/kdf.h +++ b/wolfssl/wolfcrypt/kdf.h @@ -76,14 +76,14 @@ enum { MAX_TLS13_HKDF_LABEL_SZ = 47 + WC_MAX_DIGEST_SIZE }; -WOLFSSL_LOCAL int wc_Tls13_HKDF_Extract_ex(byte* prk, const byte* salt, - word32 saltLen, byte* ikm, word32 ikmLen, int digest, - void* heap, int devId); +WOLFSSL_API int wc_Tls13_HKDF_Extract_ex(byte* prk, const byte* salt, + word32 saltLen, byte* ikm, word32 ikmLen, int digest, + void* heap, int devId); WOLFSSL_API int wc_Tls13_HKDF_Extract(byte* prk, const byte* salt, word32 saltLen, byte* ikm, word32 ikmLen, int digest); -WOLFSSL_LOCAL int wc_Tls13_HKDF_Expand_Label_ex(byte* okm, word32 okmLen, +WOLFSSL_API int wc_Tls13_HKDF_Expand_Label_ex(byte* okm, word32 okmLen, const byte* prk, word32 prkLen, const byte* protocol, word32 protocolLen, const byte* label, word32 labelLen, From 1c4d7285d377535990f727fed7fe7f349f9f25dc Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 27 Dec 2023 13:56:40 -0800 Subject: [PATCH 13/13] Add documentation for HKDF functions. Improve param comments for devId. --- doc/dox_comments/header_files/aes.h | 22 +- doc/dox_comments/header_files/cmac.h | 2 +- doc/dox_comments/header_files/ecc.h | 8 +- doc/dox_comments/header_files/hmac.h | 439 +++++++++++++++++++++++++++ doc/dox_comments/header_files/rsa.h | 4 +- doc/dox_comments/header_files/ssl.h | 84 ++--- src/tls13.c | 21 +- wolfcrypt/src/kdf.c | 42 +-- 8 files changed, 504 insertions(+), 118 deletions(-) diff --git a/doc/dox_comments/header_files/aes.h b/doc/dox_comments/header_files/aes.h index 997bc58c0..764c4d5f2 100644 --- a/doc/dox_comments/header_files/aes.h +++ b/doc/dox_comments/header_files/aes.h @@ -668,13 +668,13 @@ int wc_AesCcmDecrypt(Aes* aes, byte* out, \param aes AES keys for encrypt/decrypt process \param heap heap hint to use for memory. Can be NULL - \param devId id to use with async crypto. Can be 0 + \param devId ID to use with crypto callbacks or async hardware. Set to INVALID_DEVID (-2) if not used _Example_ \code XtsAes aes; - if(wc_AesXtsInit(&aes, NULL, 0) != 0) + if(wc_AesXtsInit(&aes, NULL, INVALID_DEVID) != 0) { // Handle error } @@ -749,13 +749,13 @@ int wc_AesXtsSetKeyNoInit(XtsAes* aes, const byte* key, i.e. 32 for a 16 byte key. \param dir direction, either AES_ENCRYPTION or AES_DECRYPTION \param heap heap hint to use for memory. Can be NULL - \param devId id to use with async crypto. Can be 0 + \param devId ID to use with crypto callbacks or async hardware. Set to INVALID_DEVID (-2) if not used _Example_ \code XtsAes aes; - if(wc_AesXtsSetKey(&aes, key, sizeof(key), AES_ENCRYPTION, NULL, 0) != 0) + if(wc_AesXtsSetKey(&aes, key, sizeof(key), AES_ENCRYPTION, NULL, INVALID_DEVID) != 0) { // Handle error } @@ -974,7 +974,7 @@ int wc_AesXtsFree(XtsAes* aes); \param aes aes structure in to initialize \param heap heap hint to use for malloc / free if needed - \param devId ID to use with async hardware + \param devId ID to use with crypto callbacks or async hardware. Set to INVALID_DEVID (-2) if not used _Example_ \code @@ -1455,7 +1455,7 @@ WOLFSSL_API int wc_AesEaxEncryptUpdate(AesEax* eax, byte* out, This argument should be NULL if not used \param authInSz size in bytes of the input authentication data - + _Example_ \code AesEax eax; @@ -1571,8 +1571,8 @@ WOLFSSL_API int wc_AesEaxAuthDataUpdate(AesEax* eax, /*! \ingroup AES - \brief This function finalizes the encrypt AEAD operation, producing an auth - tag over the current authentication stream. \c eax must have been previously + \brief This function finalizes the encrypt AEAD operation, producing an auth + tag over the current authentication stream. \c eax must have been previously initialized with a call to \ref wc_AesEaxInit. When done using the \c AesEax context structure, make sure to free it using \ref wc_AesEaxFree. @@ -1632,10 +1632,10 @@ WOLFSSL_API int wc_AesEaxEncryptFinal(AesEax* eax, /*! \ingroup AES - \brief This function finalizes the decrypt AEAD operation, finalizing the + \brief This function finalizes the decrypt AEAD operation, finalizing the auth tag computation and checking it for validity against the user supplied - tag. \c eax must have been previously initialized with a call to - \ref wc_AesEaxInit. When done using the \c AesEax context structure, make + tag. \c eax must have been previously initialized with a call to + \ref wc_AesEaxInit. When done using the \c AesEax context structure, make sure to free it using \ref wc_AesEaxFree. \return 0 if data is authenticated successfully diff --git a/doc/dox_comments/header_files/cmac.h b/doc/dox_comments/header_files/cmac.h index 96d5bc8cc..58ea35ea4 100644 --- a/doc/dox_comments/header_files/cmac.h +++ b/doc/dox_comments/header_files/cmac.h @@ -40,7 +40,7 @@ int wc_InitCmac(Cmac* cmac, \param type Always WC_CMAC_AES = 1 \param unused not used, exists for potential future use around compatibility \param heap pointer to the heap hint used for dynamic allocation. Typically used with our static memory option. Can be NULL. - \param devId ID to use with async hardware. Set to INVALID_DEVID if not using async hardware. + \param devId ID to use with crypto callbacks or async hardware. Set to INVALID_DEVID (-2) if not used _Example_ \code diff --git a/doc/dox_comments/header_files/ecc.h b/doc/dox_comments/header_files/ecc.h index 24e888efb..49de5aa02 100644 --- a/doc/dox_comments/header_files/ecc.h +++ b/doc/dox_comments/header_files/ecc.h @@ -572,8 +572,8 @@ int wc_ecc_init(ecc_key* key); \return MEMORY_E Returned if there is an error allocating memory \param key pointer to the ecc_key object to initialize - \param devId ID to use with async hardware \param heap pointer to a heap identifier + \param devId ID to use with crypto callbacks or async hardware. Set to INVALID_DEVID (-2) if not used _Example_ \code @@ -1968,7 +1968,7 @@ int wc_ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg, /*! \ingroup ECC - \brief Enable ECC support for non-blocking operations. Supported for + \brief Enable ECC support for non-blocking operations. Supported for Single Precision (SP) math with the following build options: WOLFSSL_SP_NONBLOCK WOLFSSL_SP_SMALL @@ -1978,7 +1978,7 @@ int wc_ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg, \return 0 Returned upon successfully setting the callback context the input message \param key pointer to the ecc_key object - \param ctx pointer to ecc_nb_ctx_t structure with stack data cache for SP + \param ctx pointer to ecc_nb_ctx_t structure with stack data cache for SP _Example_ \code @@ -1998,7 +1998,7 @@ int wc_ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg, &key ); - // TODO: Real-time work can be called here + // TODO: Real-time work can be called here } while (ret == FP_WOULDBLOCK); } wc_ecc_free(&key); diff --git a/doc/dox_comments/header_files/hmac.h b/doc/dox_comments/header_files/hmac.h index ca6dcd325..a7c416828 100644 --- a/doc/dox_comments/header_files/hmac.h +++ b/doc/dox_comments/header_files/hmac.h @@ -129,6 +129,9 @@ int wolfSSL_GetHmacMaxSize(void); optional info into a derived key, which it stores in out. The hash type defaults to MD5 if 0 or NULL is given. + The HMAC configure option is --enable-hmac (on by default) or if building + sources directly HAVE_HKDF + \return 0 Returned upon successfully generating a key with the given inputs \return BAD_FUNC_ARG Returned if an invalid hash type is given (see type param) \return MEMORY_E Returned if there is an error allocating memory @@ -170,3 +173,439 @@ int wc_HKDF(int type, const byte* inKey, word32 inKeySz, const byte* salt, word32 saltSz, const byte* info, word32 infoSz, byte* out, word32 outSz); + + +/*! + \ingroup HMAC + + \brief This function provides access to a HMAC Key Derivation Function + (HKDF). It utilizes HMAC to convert inKey, with an optional salt + into a derived key, which it stores in out. The hash type + defaults to MD5 if 0 or NULL is given. + + The HMAC configure option is --enable-hmac (on by default) or if building + sources directly HAVE_HKDF + + \return 0 Returned upon successfully generating a key with the given inputs + \return BAD_FUNC_ARG Returned if an invalid hash type is given (see type param) + \return MEMORY_E Returned if there is an error allocating memory + \return HMAC_MIN_KEYLEN_E May be returned when using a FIPS implementation + and the key length specified is shorter than the minimum acceptable FIPS + standard + + \param type hash type to use for the HKDF. Valid types are: WC_MD5, WC_SHA, + WC_SHA256, WC_SHA384, WC_SHA512, WC_SHA3_224, WC_SHA3_256, WC_SHA3_384 or + WC_SHA3_512 + \param salt pointer to a buffer containing an optional salt. Use NULL + instead if not using a salt + \param saltSz length of the salt. Use 0 if not using a salt + \param inKey pointer to the buffer containing the key to use for KDF + \param inKeySz length of the input key + \param out pointer to the buffer in which to store the derived key + + _Example_ + \code + byte key[] = { // initialize with key }; + byte salt[] = { // initialize with salt }; + byte derivedKey[MAX_DIGEST_SIZE]; + + int ret = wc_HKDF_Extract(WC_SHA512, salt, sizeof(salt), key, sizeof(key), + derivedKey); + if ( ret != 0 ) { + // error generating derived key + } + \endcode + + \sa wc_HKDF + \sa wc_HKDF_Extract_ex + \sa wc_HKDF_Expand + \sa wc_HKDF_Expand_ex +*/ +int wc_HKDF_Extract( + int type, + const byte* salt, word32 saltSz, + const byte* inKey, word32 inKeySz, + byte* out); + +/*! + \ingroup HMAC + + \brief This function provides access to a HMAC Key Derivation Function + (HKDF). It utilizes HMAC to convert inKey, with an optional salt + into a derived key, which it stores in out. The hash type + defaults to MD5 if 0 or NULL is given. This is the _ex version adding + heap hint and device identifier. + + The HMAC configure option is --enable-hmac (on by default) or if building + sources directly HAVE_HKDF + + \return 0 Returned upon successfully generating a key with the given inputs + \return BAD_FUNC_ARG Returned if an invalid hash type is given (see type param) + \return MEMORY_E Returned if there is an error allocating memory + \return HMAC_MIN_KEYLEN_E May be returned when using a FIPS implementation + and the key length specified is shorter than the minimum acceptable FIPS + standard + + \param type hash type to use for the HKDF. Valid types are: WC_MD5, WC_SHA, + WC_SHA256, WC_SHA384, WC_SHA512, WC_SHA3_224, WC_SHA3_256, WC_SHA3_384 or + WC_SHA3_512 + \param salt pointer to a buffer containing an optional salt. Use NULL + instead if not using a salt + \param saltSz length of the salt. Use 0 if not using a salt + \param inKey pointer to the buffer containing the key to use for KDF + \param inKeySz length of the input key + \param out pointer to the buffer in which to store the derived key + \param heap heap hint to use for memory. Can be NULL + \param devId ID to use with crypto callbacks or async hardware. Set to INVALID_DEVID (-2) if not used + + _Example_ + \code + byte key[] = { // initialize with key }; + byte salt[] = { // initialize with salt }; + byte derivedKey[MAX_DIGEST_SIZE]; + + int ret = wc_HKDF_Extract_ex(WC_SHA512, salt, sizeof(salt), key, sizeof(key), + derivedKey, NULL, INVALID_DEVID); + if ( ret != 0 ) { + // error generating derived key + } + \endcode + + \sa wc_HKDF + \sa wc_HKDF_Extract + \sa wc_HKDF_Expand + \sa wc_HKDF_Expand_ex +*/ +int wc_HKDF_Extract_ex( + int type, + const byte* salt, word32 saltSz, + const byte* inKey, word32 inKeySz, + byte* out, + void* heap, int devId); + +/*! + \ingroup HMAC + + \brief This function provides access to a HMAC Key Derivation Function + (HKDF). It utilizes HMAC to convert inKey, with optional info into a + derived key, which it stores in out. The hash type + defaults to MD5 if 0 or NULL is given. + + The HMAC configure option is --enable-hmac (on by default) or if building + sources directly HAVE_HKDF + + \return 0 Returned upon successfully generating a key with the given inputs + \return BAD_FUNC_ARG Returned if an invalid hash type is given (see type param) + \return MEMORY_E Returned if there is an error allocating memory + \return HMAC_MIN_KEYLEN_E May be returned when using a FIPS implementation + and the key length specified is shorter than the minimum acceptable FIPS + standard + + \param type hash type to use for the HKDF. Valid types are: WC_MD5, WC_SHA, + WC_SHA256, WC_SHA384, WC_SHA512, WC_SHA3_224, WC_SHA3_256, WC_SHA3_384 or + WC_SHA3_512 + \param inKey pointer to the buffer containing the key to use for KDF + \param inKeySz length of the input key + \param info pointer to a buffer containing optional additional info. + Use NULL if not appending extra info + \param infoSz length of additional info. Use 0 if not using additional info + \param out pointer to the buffer in which to store the derived key + \param outSz space available in the output buffer to store the + generated key + + _Example_ + \code + byte key[] = { // initialize with key }; + byte salt[] = { // initialize with salt }; + byte derivedKey[MAX_DIGEST_SIZE]; + + int ret = wc_HKDF_Expand(WC_SHA512, key, sizeof(key), NULL, 0, + derivedKey, sizeof(derivedKey)); + if ( ret != 0 ) { + // error generating derived key + } + \endcode + + \sa wc_HKDF + \sa wc_HKDF_Extract + \sa wc_HKDF_Extract_ex + \sa wc_HKDF_Expand_ex +*/ +int wc_HKDF_Expand( + int type, + const byte* inKey, word32 inKeySz, + const byte* info, word32 infoSz, + byte* out, word32 outSz); + +/*! + \ingroup HMAC + + \brief This function provides access to a HMAC Key Derivation Function + (HKDF). It utilizes HMAC to convert inKey, with optional info into a + derived key, which it stores in out. The hash type + defaults to MD5 if 0 or NULL is given. This is the _ex version adding + heap hint and device identifier. + + The HMAC configure option is --enable-hmac (on by default) or if building + sources directly HAVE_HKDF + + \return 0 Returned upon successfully generating a key with the given inputs + \return BAD_FUNC_ARG Returned if an invalid hash type is given (see type param) + \return MEMORY_E Returned if there is an error allocating memory + \return HMAC_MIN_KEYLEN_E May be returned when using a FIPS implementation + and the key length specified is shorter than the minimum acceptable FIPS + standard + + \param type hash type to use for the HKDF. Valid types are: WC_MD5, WC_SHA, + WC_SHA256, WC_SHA384, WC_SHA512, WC_SHA3_224, WC_SHA3_256, WC_SHA3_384 or + WC_SHA3_512 + \param inKey pointer to the buffer containing the key to use for KDF + \param inKeySz length of the input key + \param info pointer to a buffer containing optional additional info. + Use NULL if not appending extra info + \param infoSz length of additional info. Use 0 if not using additional info + \param out pointer to the buffer in which to store the derived key + \param outSz space available in the output buffer to store the + generated key + \param heap heap hint to use for memory. Can be NULL + \param devId ID to use with crypto callbacks or async hardware. Set to INVALID_DEVID (-2) if not used + + _Example_ + \code + byte key[] = { // initialize with key }; + byte salt[] = { // initialize with salt }; + byte derivedKey[MAX_DIGEST_SIZE]; + + int ret = wc_HKDF_Expand_ex(WC_SHA512, key, sizeof(key), NULL, 0, + derivedKey, sizeof(derivedKey), NULL, INVALID_DEVID); + if ( ret != 0 ) { + // error generating derived key + } + \endcode + + \sa wc_HKDF + \sa wc_HKDF_Extract + \sa wc_HKDF_Extract_ex + \sa wc_HKDF_Expand +*/ +int wc_HKDF_Expand_ex( + int type, + const byte* inKey, word32 inKeySz, + const byte* info, word32 infoSz, + byte* out, word32 outSz, + void* heap, int devId); + +/*! + \ingroup HMAC + + \brief This function provides access to RFC 5869 + HMAC-based Extract-and-Expand Key Derivation Function (HKDF) for TLS v1.3 + key derivation + + \return 0 Returned upon successfully generating a key with the given inputs + \return BAD_FUNC_ARG Returned if an invalid hash type is given (see type param) + \return MEMORY_E Returned if there is an error allocating memory + \return HMAC_MIN_KEYLEN_E May be returned when using a FIPS implementation + and the key length specified is shorter than the minimum acceptable FIPS + standard + + \param prk Generated pseudorandom key + \param salt salt. + \param saltLen length of the salt + \param ikm pointer to putput for keying material + \param ikmLen length of the input keying material buffer + \param digest hash type to use for the HKDF. Valid types are: WC_SHA256, WC_SHA384 or WC_SHA512 + + _Example_ + \code + byte secret[] = { // initialize with random key }; + byte salt[] = { // initialize with optional salt }; + byte masterSecret[MAX_DIGEST_SIZE]; + + int ret = wc_Tls13_HKDF_Extract(secret, salt, sizeof(salt), 0, + masterSecret, sizeof(masterSecret), WC_SHA512); + if ( ret != 0 ) { + // error generating derived key + } + \endcode + + \sa wc_HKDF + \sa wc_HKDF_Extract + \sa wc_HKDF_Extract_ex + \sa wc_HKDF_Expand + \sa wc_Tls13_HKDF_Extract_ex +*/ +int wc_Tls13_HKDF_Extract( + byte* prk, + const byte* salt, word32 saltLen, + byte* ikm, word32 ikmLen, int digest); + +/*! + \ingroup HMAC + + \brief This function provides access to RFC 5869 + HMAC-based Extract-and-Expand Key Derivation Function (HKDF) for TLS v1.3 + key derivation. This is the _ex version adding heap hint and device identifier. + + \return 0 Returned upon successfully generating a key with the given inputs + \return BAD_FUNC_ARG Returned if an invalid hash type is given (see type param) + \return MEMORY_E Returned if there is an error allocating memory + \return HMAC_MIN_KEYLEN_E May be returned when using a FIPS implementation + and the key length specified is shorter than the minimum acceptable FIPS + standard + + \param prk Generated pseudorandom key + \param salt Salt. + \param saltLen Length of the salt + \param ikm Pointer to output for keying material + \param ikmLen Length of the input keying material buffer + \param digest Hash type to use for the HKDF. Valid types are: WC_SHA256, WC_SHA384 or WC_SHA512 + \param heap Heap hint to use for memory. Can be NULL + \param devId ID to use with crypto callbacks or async hardware. Set to INVALID_DEVID (-2) if not used + + _Example_ + \code + byte secret[] = { // initialize with random key }; + byte salt[] = { // initialize with optional salt }; + byte masterSecret[MAX_DIGEST_SIZE]; + + int ret = wc_Tls13_HKDF_Extract_ex(secret, salt, sizeof(salt), 0, + masterSecret, sizeof(masterSecret), WC_SHA512, NULL, INVALID_DEVID); + if ( ret != 0 ) { + // error generating derived key + } + \endcode + + \sa wc_HKDF + \sa wc_HKDF_Extract + \sa wc_HKDF_Extract_ex + \sa wc_HKDF_Expand + \sa wc_Tls13_HKDF_Extract +*/ +int wc_Tls13_HKDF_Extract_ex( + byte* prk, + const byte* salt, word32 saltLen, + byte* ikm, word32 ikmLen, int digest, + void* heap, int devId); + +/*! + \ingroup HMAC + + \brief Expand data using HMAC, salt and label and info. TLS v1.3 defines + this function for key derivation. This is the _ex version adding heap hint + and device identifier. + + \return 0 Returned upon successfully generating a key with the given inputs + \return BAD_FUNC_ARG Returned if an invalid hash type is given (see type param) + \return MEMORY_E Returned if there is an error allocating memory + \return HMAC_MIN_KEYLEN_E May be returned when using a FIPS implementation + and the key length specified is shorter than the minimum acceptable FIPS + standard + + \param okm Generated pseudorandom key - output key material. + \param okmLen Length of generated pseudorandom key - output key material. + \param prk Salt - pseudo-random key. + \param prkLen Length of the salt - pseudo-random key. + \param protocol TLS protocol label. + \param protocolLen Length of the TLS protocol label. + \param info Information to expand. + \param infoLen Length of the information. + \param digest Hash type to use for the HKDF. Valid types are: WC_SHA256, WC_SHA384 or WC_SHA512 + \param heap Heap hint to use for memory. Can be NULL + \param devId ID to use with crypto callbacks or async hardware. Set to INVALID_DEVID (-2) if not used + + \sa wc_HKDF + \sa wc_HKDF_Extract + \sa wc_HKDF_Extract_ex + \sa wc_HKDF_Expand + \sa wc_Tls13_HKDF_Expand_Label + \sa wc_Tls13_HKDF_Expand_Label_Alloc +*/ +int wc_Tls13_HKDF_Expand_Label_ex( + byte* okm, word32 okmLen, + const byte* prk, word32 prkLen, + const byte* protocol, word32 protocolLen, + const byte* label, word32 labelLen, + const byte* info, word32 infoLen, + int digest, + void* heap, int devId); + +/*! + \ingroup HMAC + + \brief Expand data using HMAC, salt and label and info. TLS v1.3 defines + this function for key derivation. This is the _ex version adding heap hint + and device identifier. + + \return 0 Returned upon successfully generating a key with the given inputs + \return BAD_FUNC_ARG Returned if an invalid hash type is given (see type param) + \return MEMORY_E Returned if there is an error allocating memory + \return HMAC_MIN_KEYLEN_E May be returned when using a FIPS implementation + and the key length specified is shorter than the minimum acceptable FIPS + standard + + \param okm Generated pseudorandom key - output key material. + \param okmLen Length of generated pseudorandom key - output key material. + \param prk Salt - pseudo-random key. + \param prkLen Length of the salt - pseudo-random key. + \param protocol TLS protocol label. + \param protocolLen Length of the TLS protocol label. + \param info Information to expand. + \param infoLen Length of the information. + \param digest Hash type to use for the HKDF. Valid types are: WC_SHA256, WC_SHA384 or WC_SHA512 + + \sa wc_HKDF + \sa wc_HKDF_Extract + \sa wc_HKDF_Extract_ex + \sa wc_HKDF_Expand + \sa wc_Tls13_HKDF_Expand_Label_ex + \sa wc_Tls13_HKDF_Expand_Label_Alloc +*/ +int wc_Tls13_HKDF_Expand_Label( + byte* okm, word32 okmLen, + const byte* prk, word32 prkLen, + const byte* protocol, word32 protocolLen, + const byte* label, word32 labelLen, + const byte* info, word32 infoLen, + int digest); + +/*! + \ingroup HMAC + + \brief This functions is very similar to wc_Tls13_HKDF_Expand_Label(), but it + allocates memory if the stack space usually used isn't enough. Expand data + using HMAC, salt and label and info. TLS v1.3 defines this function for + key derivation. This is the _ex version adding heap hint and device identifier. + + \return 0 Returned upon successfully generating a key with the given inputs + \return BAD_FUNC_ARG Returned if an invalid hash type is given (see type param) + \return MEMORY_E Returned if there is an error allocating memory + \return HMAC_MIN_KEYLEN_E May be returned when using a FIPS implementation + and the key length specified is shorter than the minimum acceptable FIPS + standard + + \param okm Generated pseudorandom key - output key material. + \param okmLen Length of generated pseudorandom key - output key material. + \param prk Salt - pseudo-random key. + \param prkLen Length of the salt - pseudo-random key. + \param protocol TLS protocol label. + \param protocolLen Length of the TLS protocol label. + \param info Information to expand. + \param infoLen Length of the information. + \param digest Hash type to use for the HKDF. Valid types are: WC_SHA256, WC_SHA384 or WC_SHA512 + \param heap Heap hint to use for memory. Can be NULL + + \sa wc_HKDF + \sa wc_HKDF_Extract + \sa wc_HKDF_Extract_ex + \sa wc_HKDF_Expand + \sa wc_Tls13_HKDF_Expand_Label + \sa wc_Tls13_HKDF_Expand_Label_ex +*/ +int wc_Tls13_HKDF_Expand_Label_Alloc( + byte* okm, word32 okmLen, + const byte* prk, word32 prkLen, + const byte* protocol, word32 protocolLen, + const byte* label, word32 labelLen, + const byte* info, word32 infoLen, + int digest, void* heap); diff --git a/doc/dox_comments/header_files/rsa.h b/doc/dox_comments/header_files/rsa.h index 6e8c75268..f62e1686c 100644 --- a/doc/dox_comments/header_files/rsa.h +++ b/doc/dox_comments/header_files/rsa.h @@ -56,7 +56,7 @@ int wc_InitRsaKey(RsaKey* key, void* heap); \param heap pointer to a heap identifier, for use with memory overrides, allowing custom handling of memory allocation. This heap will be the default used when allocating memory for use with this RSA object - \param devId ID to use with hardware device + \param devId ID to use with crypto callbacks or async hardware. Set to INVALID_DEVID (-2) if not used _Example_ \code @@ -1377,7 +1377,7 @@ int wc_RsaKeyToPublicDer(RsaKey* key, byte* output, word32 inLen); \ingroup RSA \brief Convert RSA Public key to DER format. Writes to output, and - returns count of bytes written. If with_header is 0 then only the + returns count of bytes written. If with_header is 0 then only the ( seq + n + e) is returned in ASN.1 DER format and will exclude the header. \return >0 Success, number of bytes written. diff --git a/doc/dox_comments/header_files/ssl.h b/doc/dox_comments/header_files/ssl.h index 5965f11d3..a96b3888f 100644 --- a/doc/dox_comments/header_files/ssl.h +++ b/doc/dox_comments/header_files/ssl.h @@ -1063,12 +1063,12 @@ int wolfSSL_CTX_use_certificate_file(WOLFSSL_CTX* ctx, const char* file, argument specifies the format type of the file - SSL_FILETYPE_ASN1or SSL_FILETYPE_PEM. Please see the examples for proper usage. - If using an external key store and do not have the private key you can - instead provide the public key and register the crypro callback to handle - the signing. For this you can build with either build with crypto callbacks + If using an external key store and do not have the private key you can + instead provide the public key and register the crypro callback to handle + the signing. For this you can build with either build with crypto callbacks or PK callbacks. To enable crypto callbacks use --enable-cryptocb - or WOLF_CRYPTO_CB and register a crypto callback using - wc_CryptoCb_RegisterDevice and set the associated devId using + or WOLF_CRYPTO_CB and register a crypto callback using + wc_CryptoCb_RegisterDevice and set the associated devId using wolfSSL_CTX_SetDevId. \return SSL_SUCCESS upon success. @@ -1554,12 +1554,12 @@ int wolfSSL_use_certificate_file(WOLFSSL* ssl, const char* file, int format); The format argument specifies the format type of the file - SSL_FILETYPE_ASN1 or SSL_FILETYPE_PEM. - If using an external key store and do not have the private key you can - instead provide the public key and register the crypro callback to handle - the signing. For this you can build with either build with crypto callbacks + If using an external key store and do not have the private key you can + instead provide the public key and register the crypro callback to handle + the signing. For this you can build with either build with crypto callbacks or PK callbacks. To enable crypto callbacks use --enable-cryptocb or - WOLF_CRYPTO_CB and register a crypto callback using - wc_CryptoCb_RegisterDevice and set the associated devId using + WOLF_CRYPTO_CB and register a crypto callback using + wc_CryptoCb_RegisterDevice and set the associated devId using wolfSSL_SetDevId. \return SSL_SUCCESS upon success. @@ -3041,7 +3041,7 @@ int wolfSSL_library_init(void); \return BAD_FUNC_ARG if ssl is NULL. \param ssl pointer to a SSL object, created with wolfSSL_new(). - \param devId ID to use with async hardware + \param devId ID to use with crypto callbacks or async hardware. Set to INVALID_DEVID (-2) if not used _Example_ \code @@ -3064,7 +3064,7 @@ int wolfSSL_SetDevId(WOLFSSL* ssl, int devId); \return BAD_FUNC_ARG if ssl is NULL. \param ctx pointer to the SSL context, created with wolfSSL_CTX_new(). - \param devId ID to use with async hardware + \param devId ID to use with crypto callbacks or async hardware. Set to INVALID_DEVID (-2) if not used _Example_ \code @@ -6246,7 +6246,7 @@ int wolfSSL_set_timeout(WOLFSSL* ssl, unsigned int to); \brief This function sets the timeout value for SSL sessions, in seconds, for the specified SSL context. - \return the previous timeout value, if WOLFSSL_ERROR_CODE_OPENSSL is + \return the previous timeout value, if WOLFSSL_ERROR_CODE_OPENSSL is \return defined on success. If not defined, SSL_SUCCESS will be returned. \return BAD_FUNC_ARG will be returned when the input context (ctx) is null. @@ -7755,7 +7755,7 @@ int wolfSSL_CTX_load_verify_buffer(WOLFSSL_CTX* ctx, const unsigned char* in, The buffer is provided by the in argument of size sz. format specifies the format type of the buffer; SSL_FILETYPE_ASN1 or SSL_FILETYPE_PEM. More than one CA certificate may be loaded per buffer as long as the - format is in PEM. The _ex version was added in PR 2413 and supports + format is in PEM. The _ex version was added in PR 2413 and supports additional arguments for userChain and flags. \return SSL_SUCCESS upon success @@ -14421,7 +14421,7 @@ int wolfSSL_set_ephemeral_key(WOLFSSL* ssl, int keyAlgo, const char* key, unsign \param keySz key size pointer \sa wolfSSL_CTX_set_ephemeral_key */ -int wolfSSL_CTX_get_ephemeral_key(WOLFSSL_CTX* ctx, int keyAlgo, +int wolfSSL_CTX_get_ephemeral_key(WOLFSSL_CTX* ctx, int keyAlgo, const unsigned char** key, unsigned int* keySz); /*! @@ -14434,7 +14434,7 @@ int wolfSSL_CTX_get_ephemeral_key(WOLFSSL_CTX* ctx, int keyAlgo, \param keySz key size pointer \sa wolfSSL_set_ephemeral_key */ -int wolfSSL_get_ephemeral_key(WOLFSSL* ssl, int keyAlgo, +int wolfSSL_get_ephemeral_key(WOLFSSL* ssl, int keyAlgo, const unsigned char** key, unsigned int* keySz); /*! @@ -14504,18 +14504,18 @@ unsigned int wolfSSL_SESSION_get_max_early_data(const WOLFSSL_SESSION *s); int wolfSSL_CRYPTO_get_ex_new_index(int, void*, void*, void*, void*); /*! - \ingroup Setup - \brief In case this function is called in a client side, set certificate types + \ingroup Setup + \brief In case this function is called in a client side, set certificate types that can be sent to its peer. In case called in a server side, set certificate types that can be acceptable from its peer. Put cert types in the buffer with prioritised order. To reset the settings to default, pass NULL - for the buffer or pass zero for len. By default, certificate type is only X509. + for the buffer or pass zero for len. By default, certificate type is only X509. In case both side intend to send or accept "Raw public key" cert, WOLFSSL_CERT_TYPE_RPK should be included in the buffer to set. \return WOLFSSL_SUCCESS if cert types set successfully \return BAD_FUNC_ARG if NULL was passed for ctx, illegal value was specified as - cert type, buf size exceed MAX_CLIENT_CERT_TYPE_CNT was specified or + cert type, buf size exceed MAX_CLIENT_CERT_TYPE_CNT was specified or a duplicate value is found in buf. \param ctx WOLFSSL_CTX object pointer @@ -14540,18 +14540,18 @@ int wolfSSL_CRYPTO_get_ex_new_index(int, void*, void*, void*, void*); int wolfSSL_CTX_set_client_cert_type(WOLFSSL_CTX* ctx, const char* buf, int len); /*! - \ingroup Setup - \brief In case this function is called in a server side, set certificate types + \ingroup Setup + \brief In case this function is called in a server side, set certificate types that can be sent to its peer. In case called in a client side, set certificate types that can be acceptable from its peer. Put cert types in the buffer with prioritised order. To reset the settings to default, pass NULL - for the buffer or pass zero for len. By default, certificate type is only X509. + for the buffer or pass zero for len. By default, certificate type is only X509. In case both side intend to send or accept "Raw public key" cert, WOLFSSL_CERT_TYPE_RPK should be included in the buffer to set. \return WOLFSSL_SUCCESS if cert types set successfully \return BAD_FUNC_ARG if NULL was passed for ctx, illegal value was specified as - cert type, buf size exceed MAX_SERVER_CERT_TYPE_CNT was specified or + cert type, buf size exceed MAX_SERVER_CERT_TYPE_CNT was specified or a duplicate value is found in buf. \param ctx WOLFSSL_CTX object pointer @@ -14576,18 +14576,18 @@ int wolfSSL_CTX_set_client_cert_type(WOLFSSL_CTX* ctx, const char* buf, int len) int wolfSSL_CTX_set_server_cert_type(WOLFSSL_CTX* ctx, const char* buf, int len); /*! - \ingroup Setup - \brief In case this function is called in a client side, set certificate types + \ingroup Setup + \brief In case this function is called in a client side, set certificate types that can be sent to its peer. In case called in a server side, set certificate types that can be acceptable from its peer. Put cert types in the buffer with prioritised order. To reset the settings to default, pass NULL - for the buffer or pass zero for len. By default, certificate type is only X509. + for the buffer or pass zero for len. By default, certificate type is only X509. In case both side intend to send or accept "Raw public key" cert, WOLFSSL_CERT_TYPE_RPK should be included in the buffer to set. \return WOLFSSL_SUCCESS if cert types set successfully \return BAD_FUNC_ARG if NULL was passed for ctx, illegal value was specified as - cert type, buf size exceed MAX_CLIENT_CERT_TYPE_CNT was specified or + cert type, buf size exceed MAX_CLIENT_CERT_TYPE_CNT was specified or a duplicate value is found in buf. \param ssl WOLFSSL object pointer @@ -14612,18 +14612,18 @@ int wolfSSL_CTX_set_server_cert_type(WOLFSSL_CTX* ctx, const char* buf, int len) int wolfSSL_set_client_cert_type(WOLFSSL* ssl, const char* buf, int len); /*! - \ingroup Setup - \brief In case this function is called in a server side, set certificate types + \ingroup Setup + \brief In case this function is called in a server side, set certificate types that can be sent to its peer. In case called in a client side, set certificate types that can be acceptable from its peer. Put cert types in the buffer with prioritised order. To reset the settings to default, pass NULL - for the buffer or pass zero for len. By default, certificate type is only X509. + for the buffer or pass zero for len. By default, certificate type is only X509. In case both side intend to send or accept "Raw public key" cert, WOLFSSL_CERT_TYPE_RPK should be included in the buffer to set. \return WOLFSSL_SUCCESS if cert types set successfully \return BAD_FUNC_ARG if NULL was passed for ctx, illegal value was specified as - cert type, buf size exceed MAX_SERVER_CERT_TYPE_CNT was specified or + cert type, buf size exceed MAX_SERVER_CERT_TYPE_CNT was specified or a duplicate value is found in buf. \param ctx WOLFSSL_CTX object pointer @@ -14648,17 +14648,17 @@ int wolfSSL_set_client_cert_type(WOLFSSL* ssl, const char* buf, int len); int wolfSSL_set_server_cert_type(WOLFSSL* ssl, const char* buf, int len); /*! - \ingroup SSL - \brief This function returns the result of the client certificate type + \ingroup SSL + \brief This function returns the result of the client certificate type negotiation done in ClientHello and ServerHello. WOLFSSL_SUCCESS is returned as - a return value if no negotiation occurs and WOLFSSL_CERT_TYPE_UNKNOWN is + a return value if no negotiation occurs and WOLFSSL_CERT_TYPE_UNKNOWN is returned as the certificate type. \return WOLFSSL_SUCCESS if a negotiated certificate type could be got \return BAD_FUNC_ARG if NULL was passed for ctx or tp \param ssl WOLFSSL object pointer - \param tp A buffer where a certificate type is to be returned. One of three - certificate types will be returned: WOLFSSL_CERT_TYPE_RPK, + \param tp A buffer where a certificate type is to be returned. One of three + certificate types will be returned: WOLFSSL_CERT_TYPE_RPK, WOLFSSL_CERT_TYPE_X509 or WOLFSSL_CERT_TYPE_UNKNOWN. _Example_ @@ -14679,17 +14679,17 @@ int wolfSSL_set_server_cert_type(WOLFSSL* ssl, const char* buf, int len); int wolfSSL_get_negotiated_client_cert_type(WOLFSSL* ssl, int* tp); /*! - \ingroup SSL - \brief This function returns the result of the server certificate type + \ingroup SSL + \brief This function returns the result of the server certificate type negotiation done in ClientHello and ServerHello. WOLFSSL_SUCCESS is returned as - a return value if no negotiation occurs and WOLFSSL_CERT_TYPE_UNKNOWN is + a return value if no negotiation occurs and WOLFSSL_CERT_TYPE_UNKNOWN is returned as the certificate type. \return WOLFSSL_SUCCESS if a negotiated certificate type could be got \return BAD_FUNC_ARG if NULL was passed for ctx or tp \param ssl WOLFSSL object pointer - \param tp A buffer where a certificate type is to be returned. One of three - certificate types will be returned: WOLFSSL_CERT_TYPE_RPK, + \param tp A buffer where a certificate type is to be returned. One of three + certificate types will be returned: WOLFSSL_CERT_TYPE_RPK, WOLFSSL_CERT_TYPE_X509 or WOLFSSL_CERT_TYPE_UNKNOWN. _Example_ \code diff --git a/src/tls13.c b/src/tls13.c index 432eb2a96..eb4618075 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -187,21 +187,7 @@ static WC_INLINE int GetMsgHash(WOLFSSL* ssl, byte* hash); #endif /* Expand data using HMAC, salt and label and info. - * TLS v1.3 defines this function. Use callback if available. - * - * ssl The SSL/TLS object. - * okm The generated pseudorandom key - output key material. - * okmLen The length of generated pseudorandom key - - * output key material. - * prk The salt - pseudo-random key. - * prkLen The length of the salt - pseudo-random key. - * protocol The TLS protocol label. - * protocolLen The length of the TLS protocol label. - * info The information to expand. - * infoLen The length of the information. - * digest The type of digest to use. - * returns 0 on success, otherwise failure. - */ + * TLS v1.3 defines this function. Use callback if available. */ static int Tls13HKDFExpandLabel(WOLFSSL* ssl, byte* okm, word32 okmLen, const byte* prk, word32 prkLen, const byte* protocol, word32 protocolLen, @@ -241,9 +227,8 @@ static int Tls13HKDFExpandLabel(WOLFSSL* ssl, byte* okm, word32 okmLen, return ret; } -/* Same as above, but pass in the side we are expanding for. - * - * side The side (WOLFSSL_CLIENT_END or WOLFSSL_SERVER_END). +/* Same as above, but pass in the side we are expanding for: + * side: either WOLFSSL_CLIENT_END or WOLFSSL_SERVER_END. */ static int Tls13HKDFExpandKeyLabel(WOLFSSL* ssl, byte* okm, word32 okmLen, const byte* prk, word32 prkLen, diff --git a/wolfcrypt/src/kdf.c b/wolfcrypt/src/kdf.c index 9dcb12076..2bda46ef7 100644 --- a/wolfcrypt/src/kdf.c +++ b/wolfcrypt/src/kdf.c @@ -353,14 +353,6 @@ int wc_PRF_TLS(byte* digest, word32 digLen, const byte* secret, word32 secLen, /* Extract data using HMAC, salt and input. * RFC 5869 - HMAC-based Extract-and-Expand Key Derivation Function (HKDF) - * - * prk The generated pseudorandom key. - * salt The salt. - * saltLen The length of the salt. - * ikm The input keying material. - * ikmLen The length of the input keying material. - * digest The type of digest to use. - * returns 0 on success, otherwise failure. */ int wc_Tls13_HKDF_Extract_ex(byte* prk, const byte* salt, word32 saltLen, byte* ikm, word32 ikmLen, int digest, void* heap, int devId) @@ -436,20 +428,7 @@ int wc_PRF_TLS(byte* digest, word32 digLen, const byte* secret, word32 secLen, } /* Expand data using HMAC, salt and label and info. - * TLS v1.3 defines this function. - * - * okm The generated pseudorandom key - output key material. - * okmLen The length of generated pseudorandom key - - * output key material. - * prk The salt - pseudo-random key. - * prkLen The length of the salt - pseudo-random key. - * protocol The TLS protocol label. - * protocolLen The length of the TLS protocol label. - * info The information to expand. - * infoLen The length of the information. - * digest The type of digest to use. - * returns 0 on success, otherwise failure. - */ + * TLS v1.3 defines this function. */ int wc_Tls13_HKDF_Expand_Label_ex(byte* okm, word32 okmLen, const byte* prk, word32 prkLen, const byte* protocol, word32 protocolLen, @@ -556,24 +535,7 @@ int wc_PRF_TLS(byte* digest, word32 digLen, const byte* secret, word32 secLen, #if defined(WOLFSSL_TICKET_NONCE_MALLOC) && \ (!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3))) /* Expand data using HMAC, salt and label and info. - * TLS v1.3 defines this function. - * - * okm The generated pseudorandom key - output key material. - * okmLen The length of generated pseudorandom key - - * output key material. - * prk The salt - pseudo-random key. - * prkLen The length of the salt - pseudo-random key. - * protocol The TLS protocol label. - * protocolLen The length of the TLS protocol label. - * info The information to expand. - * infoLen The length of the information. - * digest The type of digest to use. - * - * This functions is very similar to wc_Tls13_HKDF_Expand_Label() but it - * allocate memory if the stack space usually used isn't enough. - * - * returns 0 on success, otherwise failure. - */ + * TLS v1.3 defines this function. */ int wc_Tls13_HKDF_Expand_Label_Alloc(byte* okm, word32 okmLen, const byte* prk, word32 prkLen, const byte* protocol, word32 protocolLen, const byte* label, word32 labelLen,