From c98ce0d18c460c6fed004d61c96c6fde91ee033b Mon Sep 17 00:00:00 2001 From: kaleb-himes Date: Thu, 24 Aug 2023 14:29:32 -0700 Subject: [PATCH 1/5] FIPS 140-3 Pilot Program Check-in --- wolfcrypt/src/aes.c | 13 +++++++++++++ wolfcrypt/src/dh.c | 2 +- wolfcrypt/src/hmac.c | 2 ++ wolfcrypt/src/kdf.c | 1 + wolfssl/wolfcrypt/aes.h | 3 +++ 5 files changed, 20 insertions(+), 1 deletion(-) diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index bc161630cf..10c6ed6468 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -4385,6 +4385,19 @@ int wc_AesSetIV(Aes* aes, const byte* iv) return 0; } + int wc_AesCtrSetKey(Aes* aes, const byte* key, word32 len, + const byte* iv, int dir) + { + if (aes == NULL) { + return BAD_FUNC_ARG; + } + if (len > sizeof(aes->key)) { + return BAD_FUNC_ARG; + } + + return wc_AesSetKeyLocal(aes, key, len, iv, dir, 0); + } + #endif /* NEED_AES_CTR_SOFT */ #endif /* WOLFSSL_AES_COUNTER */ diff --git a/wolfcrypt/src/dh.c b/wolfcrypt/src/dh.c index 38425aaa82..c1860e24c0 100644 --- a/wolfcrypt/src/dh.c +++ b/wolfcrypt/src/dh.c @@ -1336,7 +1336,7 @@ static int GeneratePublicDh(DhKey* key, byte* priv, word32 privSz, *pubSz = binSz; mp_clear(y); - mp_clear(x); + mp_forcezero(x); #ifdef WOLFSSL_SMALL_STACK XFREE(y, key->heap, DYNAMIC_TYPE_DH); XFREE(x, key->heap, DYNAMIC_TYPE_DH); diff --git a/wolfcrypt/src/hmac.c b/wolfcrypt/src/hmac.c index 47ed04285c..edaa178c03 100644 --- a/wolfcrypt/src/hmac.c +++ b/wolfcrypt/src/hmac.c @@ -1196,6 +1196,7 @@ int wolfSSL_GetHmacMaxSize(void) ret = wc_HmacUpdate(&myHmac, inKey, inKeySz); if (ret == 0) ret = wc_HmacFinal(&myHmac, out); + ForceZero(&myHmac, sizeof(myHmac)); wc_HmacFree(&myHmac); } @@ -1261,6 +1262,7 @@ int wolfSSL_GetHmacMaxSize(void) n++; } + ForceZero(&myHmac, sizeof(myHmac)); wc_HmacFree(&myHmac); return ret; diff --git a/wolfcrypt/src/kdf.c b/wolfcrypt/src/kdf.c index 6556bfdf90..cece182395 100644 --- a/wolfcrypt/src/kdf.c +++ b/wolfcrypt/src/kdf.c @@ -734,6 +734,7 @@ int wc_SSH_KDF(byte hashId, byte keyId, byte* key, word32 keySz, } } + ForceZero(&hash, sizeof(hash)); _HashFree(enmhashId, &hash); return ret; diff --git a/wolfssl/wolfcrypt/aes.h b/wolfssl/wolfcrypt/aes.h index 3ba981062c..9207cc5959 100644 --- a/wolfssl/wolfcrypt/aes.h +++ b/wolfssl/wolfcrypt/aes.h @@ -367,6 +367,9 @@ WOLFSSL_API int wc_AesEcbDecrypt(Aes* aes, byte* out, #ifdef WOLFSSL_AES_COUNTER WOLFSSL_API int wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz); + WOLFSSL_API int wc_AesCtrSetKey(Aes* aes, const byte* key, word32 len, + const byte* iv, int dir); + #endif /* AES-DIRECT */ #if defined(WOLFSSL_AES_DIRECT) From 3a5e1716363be89f4f4abc59fe366ff62cfb0505 Mon Sep 17 00:00:00 2001 From: kaleb-himes Date: Mon, 28 Aug 2023 14:22:37 -0700 Subject: [PATCH 2/5] Check-in fips_test.h changes to master as well --- wolfssl/wolfcrypt/fips_test.h | 42 ++++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/wolfssl/wolfcrypt/fips_test.h b/wolfssl/wolfcrypt/fips_test.h index d2e9867140..d3309361c9 100644 --- a/wolfssl/wolfcrypt/fips_test.h +++ b/wolfssl/wolfcrypt/fips_test.h @@ -31,6 +31,25 @@ extern "C" { #endif +/* Added for FIPS v5.3 or later */ +#if defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3) + /* Determine FIPS in core hash type and size */ + #ifndef NO_SHA256 + #define FIPS_IN_CORE_DIGEST_SIZE 32 + #define FIPS_IN_CORE_HASH_TYPE WC_SHA256 + #define FIPS_IN_CORE_KEY_SZ 32 + #define FIPS_IN_CORE_VERIFY_SZ FIPS_IN_CORE_KEY_SZ + #elif defined(WOLFSSL_SHA384) + #define FIPS_IN_CORE_DIGEST_SIZE 48 + #define FIPS_IN_CORE_HASH_TYPE WC_SHA384 + #define FIPS_IN_CORE_KEY_SZ 48 + #define FIPS_IN_CORE_VERIFY_SZ FIPS_IN_CORE_KEY_SZ + #else + #error No FIPS hash (SHA2-256 or SHA2-384) + #endif +#endif /* FIPS v5.3 or later */ + + enum FipsCastId { FIPS_CAST_AES_CBC, FIPS_CAST_AES_GCM, @@ -58,10 +77,10 @@ enum FipsCastStateId { }; enum FipsModeId { - FIPS_MODE_INIT, - FIPS_MODE_NORMAL, - FIPS_MODE_DEGRADED, - FIPS_MODE_FAILED + FIPS_MODE_INIT = 0, + FIPS_MODE_NORMAL = 1, + FIPS_MODE_DEGRADED = 2, + FIPS_MODE_FAILED = 3 }; @@ -73,20 +92,21 @@ WOLFSSL_API int wolfCrypt_SetCb_fips(wolfCrypt_fips_cb cbf); /* Public get status functions */ WOLFSSL_API int wolfCrypt_GetStatus_fips(void); +WOLFSSL_API int wolfCrypt_GetMode_fips(void); WOLFSSL_API const char* wolfCrypt_GetCoreHash_fips(void); #ifdef HAVE_FORCE_FIPS_FAILURE /* Public function to force failure mode for operational testing */ - WOLFSSL_API int wolfCrypt_SetStatus_fips(int); + WOLFSSL_API int wolfCrypt_SetStatus_fips(int status); #endif -WOLFSSL_LOCAL int DoIntegrityTest(char*, int); -WOLFSSL_LOCAL int DoPOST(char*, int); -WOLFSSL_LOCAL int DoCAST(int); -WOLFSSL_LOCAL int DoKnownAnswerTests(char*, int); /* FIPSv1 and FIPSv2 */ +WOLFSSL_LOCAL int DoPOST(char* base16_hash, int base16_hashSz); +WOLFSSL_LOCAL int DoCAST(int type); +WOLFSSL_LOCAL int DoKnownAnswerTests(char* base16_hash, int base16_hashSz); /* FIPSv1 and FIPSv2 */ -WOLFSSL_API int wc_RunCast_fips(int); -WOLFSSL_API int wc_GetCastStatus_fips(int); +WOLFSSL_API int wc_RunCast_fips(int type); +WOLFSSL_API int wc_GetCastStatus_fips(int type); +WOLFSSL_API int wc_RunAllCast_fips(void); #ifdef __cplusplus } /* extern "C" */ From fb91f1c1fd5f2b26e1249a978aec7731bc666d18 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Tue, 5 Sep 2023 17:07:08 -0700 Subject: [PATCH 3/5] Update the ARM asm files with a missing initialization for SHA2-256 and the AesCtrSetKey function for AES-CTR. --- wolfcrypt/src/port/arm/armv8-aes.c | 6 ++++++ wolfcrypt/src/port/arm/armv8-sha256.c | 7 +++++++ 2 files changed, 13 insertions(+) diff --git a/wolfcrypt/src/port/arm/armv8-aes.c b/wolfcrypt/src/port/arm/armv8-aes.c index fa07d43725..fe6ebff9a0 100644 --- a/wolfcrypt/src/port/arm/armv8-aes.c +++ b/wolfcrypt/src/port/arm/armv8-aes.c @@ -5719,6 +5719,12 @@ int wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) } return 0; } + +int wc_AesCtrSetKey(Aes* aes, const byte* key, word32 len, + const byte* iv, int dir) +{ + return wc_AesSetKey(aes, key, len, iv, AES_ENCRYPTION); +} #endif /* WOLFSSL_AES_COUNTER */ #ifdef HAVE_AESCCM diff --git a/wolfcrypt/src/port/arm/armv8-sha256.c b/wolfcrypt/src/port/arm/armv8-sha256.c index 12a5132fcf..28102930bc 100644 --- a/wolfcrypt/src/port/arm/armv8-sha256.c +++ b/wolfcrypt/src/port/arm/armv8-sha256.c @@ -85,6 +85,10 @@ static int InitSha256(wc_Sha256* sha256) sha256->loLen = 0; sha256->hiLen = 0; +#ifdef WOLFSSL_HASH_FLAGS + sha256->flags = 0; +#endif + return ret; } @@ -1575,6 +1579,9 @@ int wc_Sha256Transform(wc_Sha256* sha256, const unsigned char* data) sha224->loLen = 0; sha224->hiLen = 0; + #ifdef WOLFSSL_HASH_FLAGS + sha224->flags = 0; + #endif return ret; } From 554044931578f405dcfebda02ea44a85ce9cbead Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Tue, 5 Sep 2023 23:37:09 -0500 Subject: [PATCH 4/5] wolfcrypt/src/port/arm/armv8-aes.c: add missing implementations of wc_AesCtrSetKey(), and add (void)dir in implementation to silence -Wunused. --- wolfcrypt/src/port/arm/armv8-aes.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/wolfcrypt/src/port/arm/armv8-aes.c b/wolfcrypt/src/port/arm/armv8-aes.c index fe6ebff9a0..544b3a6190 100644 --- a/wolfcrypt/src/port/arm/armv8-aes.c +++ b/wolfcrypt/src/port/arm/armv8-aes.c @@ -1452,6 +1452,13 @@ int wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) return 0; } +int wc_AesCtrSetKey(Aes* aes, const byte* key, word32 len, + const byte* iv, int dir) +{ + (void)dir; + return wc_AesSetKey(aes, key, len, iv, AES_ENCRYPTION); +} + #endif /* WOLFSSL_AES_COUNTER */ #ifdef HAVE_AESGCM @@ -4212,6 +4219,13 @@ int wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) return 0; } +int wc_AesCtrSetKey(Aes* aes, const byte* key, word32 len, + const byte* iv, int dir) +{ + (void)dir; + return wc_AesSetKey(aes, key, len, iv, AES_ENCRYPTION); +} + #endif /* WOLFSSL_AES_COUNTER */ #ifdef HAVE_AESGCM @@ -5723,6 +5737,7 @@ int wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) int wc_AesCtrSetKey(Aes* aes, const byte* key, word32 len, const byte* iv, int dir) { + (void)dir; return wc_AesSetKey(aes, key, len, iv, AES_ENCRYPTION); } #endif /* WOLFSSL_AES_COUNTER */ From 344e1661e18234c9a3c56d7108aad06987b82b5a Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Wed, 6 Sep 2023 14:53:19 -0500 Subject: [PATCH 5/5] wolfcrypt/src/{hmac.c,sha256.c,sha512.c,kdf.c}: ForceZero() smallstack buffers before freeing them, and ForceZero() the Hmac, wc_Sha512, wc_Sha384, wc_Sha256, and wc_Sha224 structures at the end of their respective freeing routines. also, remove superseded ForceZero() calls in wc_HKDF_Expand(), wc_SSH_KDF(), and wc_HKDF_Extract(). --- wolfcrypt/src/hmac.c | 4 ++-- wolfcrypt/src/kdf.c | 1 - wolfcrypt/src/sha256.c | 23 +++++++++++++++-------- wolfcrypt/src/sha512.c | 9 +++++++++ 4 files changed, 26 insertions(+), 11 deletions(-) diff --git a/wolfcrypt/src/hmac.c b/wolfcrypt/src/hmac.c index 4f1b68c7d7..83e693b257 100644 --- a/wolfcrypt/src/hmac.c +++ b/wolfcrypt/src/hmac.c @@ -1173,6 +1173,8 @@ void wc_HmacFree(Hmac* hmac) default: break; } + + ForceZero(hmac, sizeof(*hmac)); } #endif /* WOLFSSL_KCAPI_HMAC */ @@ -1233,7 +1235,6 @@ int wolfSSL_GetHmacMaxSize(void) ret = wc_HmacUpdate(myHmac, inKey, inKeySz); if (ret == 0) ret = wc_HmacFinal(myHmac, out); - ForceZero(myHmac, sizeof(Hmac)); wc_HmacFree(myHmac); } #ifdef WOLFSSL_SMALL_STACK @@ -1325,7 +1326,6 @@ int wolfSSL_GetHmacMaxSize(void) n++; } - ForceZero(myHmac, sizeof(Hmac)); wc_HmacFree(myHmac); #ifdef WOLFSSL_SMALL_STACK XFREE(myHmac, NULL, DYNAMIC_TYPE_HMAC); diff --git a/wolfcrypt/src/kdf.c b/wolfcrypt/src/kdf.c index 0223817b2c..2568c444c9 100644 --- a/wolfcrypt/src/kdf.c +++ b/wolfcrypt/src/kdf.c @@ -863,7 +863,6 @@ int wc_SSH_KDF(byte hashId, byte keyId, byte* key, word32 keySz, } } - ForceZero(&hash, sizeof(hash)); _HashFree(enmhashId, &hash); return ret; diff --git a/wolfcrypt/src/sha256.c b/wolfcrypt/src/sha256.c index e17ba65ac4..747d3dd46f 100644 --- a/wolfcrypt/src/sha256.c +++ b/wolfcrypt/src/sha256.c @@ -931,6 +931,7 @@ static int InitSha256(wc_Sha256* sha256) } #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SMALL_STACK_CACHE) + ForceZero(W, sizeof(word32) * WC_SHA256_BLOCK_SIZE); XFREE(W, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif return 0; @@ -1690,10 +1691,11 @@ static int InitSha256(wc_Sha256* sha256) return; #ifdef WOLFSSL_SMALL_STACK_CACHE - if (sha224->W != NULL) { - XFREE(sha224->W, NULL, DYNAMIC_TYPE_DIGEST); - sha224->W = NULL; - } + if (sha224->W != NULL) { + ForceZero(sha224->W, sizeof(word32) * WC_SHA224_BLOCK_SIZE); + XFREE(sha224->W, NULL, DYNAMIC_TYPE_DIGEST); + sha224->W = NULL; + } #endif #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA224) @@ -1707,11 +1709,13 @@ static int InitSha256(wc_Sha256* sha256) KcapiHashFree(&sha224->kcapi); #endif #if defined(WOLFSSL_RENESAS_RX64_HASH) - if (sha224->msg != NULL) { - XFREE(sha224->msg, sha224->heap, DYNAMIC_TYPE_TMP_BUFFER); - sha224->msg = NULL; - } + if (sha224->msg != NULL) { + ForceZero(sha224->msg, sha224->len); + XFREE(sha224->msg, sha224->heap, DYNAMIC_TYPE_TMP_BUFFER); + sha224->msg = NULL; + } #endif + ForceZero(sha224, sizeof(*sha224)); } #endif /* WOLFSSL_SHA224 */ #endif /* !defined(WOLFSSL_HAVE_PSA) || defined(WOLFSSL_PSA_NO_HASH) */ @@ -1737,6 +1741,7 @@ void wc_Sha256Free(wc_Sha256* sha256) #ifdef WOLFSSL_SMALL_STACK_CACHE if (sha256->W != NULL) { + ForceZero(sha256->W, sizeof(word32) * WC_SHA256_BLOCK_SIZE); XFREE(sha256->W, NULL, DYNAMIC_TYPE_DIGEST); sha256->W = NULL; } @@ -1772,6 +1777,7 @@ void wc_Sha256Free(wc_Sha256* sha256) defined(WOLFSSL_HASH_KEEP) if (sha256->msg != NULL) { + ForceZero(sha256->msg, sha256->len); XFREE(sha256->msg, sha256->heap, DYNAMIC_TYPE_TMP_BUFFER); sha256->msg = NULL; } @@ -1813,6 +1819,7 @@ void wc_Sha256Free(wc_Sha256* sha256) ESP_LOGV(TAG, "Hardware unlock not needed in wc_Sha256Free."); } #endif + ForceZero(sha256, sizeof(*sha256)); } #endif /* !defined(WOLFSSL_HAVE_PSA) || defined(WOLFSSL_PSA_NO_HASH) */ diff --git a/wolfcrypt/src/sha512.c b/wolfcrypt/src/sha512.c index 0c2750a902..83af39c4b0 100644 --- a/wolfcrypt/src/sha512.c +++ b/wolfcrypt/src/sha512.c @@ -1126,6 +1126,7 @@ void wc_Sha512Free(wc_Sha512* sha512) #ifdef WOLFSSL_SMALL_STACK_CACHE if (sha512->W != NULL) { + ForceZero(sha512->W, sizeof(word64) * 16); XFREE(sha512->W, sha512->heap, DYNAMIC_TYPE_TMP_BUFFER); sha512->W = NULL; } @@ -1137,6 +1138,7 @@ void wc_Sha512Free(wc_Sha512* sha512) #if defined(WOLFSSL_HASH_KEEP) if (sha512->msg != NULL) { + ForceZero(sha512->msg, sha512->len); XFREE(sha512->msg, sha512->heap, DYNAMIC_TYPE_TMP_BUFFER); sha512->msg = NULL; } @@ -1145,6 +1147,8 @@ void wc_Sha512Free(wc_Sha512* sha512) #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA512) wolfAsync_DevCtxFree(&sha512->asyncDev, WOLFSSL_ASYNC_MARKER_SHA512); #endif /* WOLFSSL_ASYNC_CRYPT */ + + ForceZero(sha512, sizeof(*sha512)); } #if (defined(OPENSSL_EXTRA) || defined(HAVE_CURL)) \ && !defined(WOLFSSL_KCAPI_HASH) @@ -1197,6 +1201,7 @@ int wc_Sha512Transform(wc_Sha512* sha, const unsigned char* data) XMEMCPY(sha->buffer, buffer, WC_SHA512_BLOCK_SIZE); #ifdef WOLFSSL_SMALL_STACK + ForceZero(buffer, WC_SHA512_BLOCK_SIZE); XFREE(buffer, sha->heap, DYNAMIC_TYPE_TMP_BUFFER); #endif return ret; @@ -1446,6 +1451,7 @@ void wc_Sha384Free(wc_Sha384* sha384) #ifdef WOLFSSL_SMALL_STACK_CACHE if (sha384->W != NULL) { + ForceZero(sha384->W, sizeof(word64) * 16); XFREE(sha384->W, sha384->heap, DYNAMIC_TYPE_TMP_BUFFER); sha384->W = NULL; } @@ -1457,6 +1463,7 @@ void wc_Sha384Free(wc_Sha384* sha384) #if defined(WOLFSSL_HASH_KEEP) if (sha384->msg != NULL) { + ForceZero(sha384->msg, sha384->len); XFREE(sha384->msg, sha384->heap, DYNAMIC_TYPE_TMP_BUFFER); sha384->msg = NULL; } @@ -1476,6 +1483,8 @@ void wc_Sha384Free(wc_Sha384* sha384) sha384->hSession = NULL; } #endif + + ForceZero(sha384, sizeof(*sha384)); } #endif /* WOLFSSL_SHA384 */