From 49e9c066796a44ea951a35f441661132e96abb04 Mon Sep 17 00:00:00 2001 From: kaleb-himes Date: Thu, 25 Apr 2024 11:56:00 -0400 Subject: [PATCH 01/10] (Has dependency PR) API Service update HmacSizeByType --- wolfcrypt/test/test.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 18844c2614..b5296ead55 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -5888,7 +5888,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hmac_md5_test(void) wc_HmacFree(&hmac); } -#ifndef HAVE_FIPS +#if !defined(HAVE_FIPS) || FIPS_VERSION3_GE(6,0,0) if ((ret = wc_HmacSizeByType(WC_MD5)) != WC_MD5_DIGEST_SIZE) return WC_TEST_RET_ENC_EC(ret); #endif @@ -5996,7 +5996,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hmac_sha_test(void) wc_HmacFree(&hmac); } -#ifndef HAVE_FIPS +#if !defined(HAVE_FIPS) || FIPS_VERSION3_GE(6,0,0) if ((ret = wc_HmacSizeByType(WC_SHA)) != WC_SHA_DIGEST_SIZE) return WC_TEST_RET_ENC_EC(ret); #endif @@ -6096,7 +6096,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hmac_sha224_test(void) wc_HmacFree(&hmac); } -#ifndef HAVE_FIPS +#if !defined(HAVE_FIPS) || FIPS_VERSION3_GE(6,0,0) if ((ret = wc_HmacSizeByType(WC_SHA224)) != WC_SHA224_DIGEST_SIZE) return WC_TEST_RET_ENC_EC(ret); #endif @@ -6217,11 +6217,17 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hmac_sha256_test(void) wc_HmacFree(&hmac); } -#ifndef HAVE_FIPS +#if !defined(HAVE_FIPS) || FIPS_VERSION3_GE(6,0,0) if ((ret = wc_HmacSizeByType(WC_SHA256)) != WC_SHA256_DIGEST_SIZE) return WC_TEST_RET_ENC_EC(ret); +#if FIPS_VERSION3_GE(6,0,0) + if ((ret = wc_HmacSizeByType(21)) != HMAC_KAT_FIPS_E) +#else if ((ret = wc_HmacSizeByType(21)) != BAD_FUNC_ARG) +#endif + { return WC_TEST_RET_ENC_EC(ret); + } #endif if ((ret = wolfSSL_GetHmacMaxSize()) != WC_MAX_DIGEST_SIZE) return WC_TEST_RET_ENC_EC(ret); @@ -6330,7 +6336,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hmac_sha384_test(void) wc_HmacFree(&hmac); } -#ifndef HAVE_FIPS +#if !defined(HAVE_FIPS) || FIPS_VERSION3_GE(6,0,0) if ((ret = wc_HmacSizeByType(WC_SHA384)) != WC_SHA384_DIGEST_SIZE) return WC_TEST_RET_ENC_EC(ret); #endif @@ -6443,7 +6449,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hmac_sha512_test(void) wc_HmacFree(&hmac); } -#ifndef HAVE_FIPS +#if !defined(HAVE_FIPS) || FIPS_VERSION3_GE(6,0,0) if ((ret = wc_HmacSizeByType(WC_SHA512)) != WC_SHA512_DIGEST_SIZE) return WC_TEST_RET_ENC_EC(ret); #endif @@ -6615,7 +6621,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hmac_sha3_test(void) if (i > 0) continue; - #ifndef HAVE_FIPS + #if !defined(HAVE_FIPS) || FIPS_VERSION3_GE(6,0,0) ret = wc_HmacSizeByType(hashType[j]); if (ret != hashSz[j]) return WC_TEST_RET_ENC_EC(ret); From 766c3b5ad8c0dc869df98a8ceef07be2cd387cae Mon Sep 17 00:00:00 2001 From: kaleb-himes Date: Thu, 25 Apr 2024 18:26:43 -0400 Subject: [PATCH 02/10] Comments and further relaxing of some other hmac restrictions --- wolfcrypt/src/hmac.c | 10 ++++++++++ wolfcrypt/src/rsa.c | 8 +++++--- wolfssl/wolfcrypt/hmac.h | 4 ++++ 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/wolfcrypt/src/hmac.c b/wolfcrypt/src/hmac.c index 0608973552..de6f05ce1c 100644 --- a/wolfcrypt/src/hmac.c +++ b/wolfcrypt/src/hmac.c @@ -1275,7 +1275,12 @@ int wolfSSL_GetHmacMaxSize(void) ret = wc_HmacInit(myHmac, heap, devId); if (ret == 0) { + #if FIPS_VERSION3_GE(6,0,0) + ret = wc_HmacSetKey_ex(myHmac, type, localSalt, saltSz, + FIPS_ALLOW_SHORT); + #else ret = wc_HmacSetKey(myHmac, type, localSalt, saltSz); + #endif if (ret == 0) ret = wc_HmacUpdate(myHmac, inKey, inKeySz); if (ret == 0) @@ -1356,7 +1361,12 @@ int wolfSSL_GetHmacMaxSize(void) word32 tmpSz = (n == 1) ? 0 : hashSz; word32 left = outSz - outIdx; + #if FIPS_VERSION3_GE(6,0,0) + ret = wc_HmacSetKey_ex(myHmac, type, inKey, inKeySz, + FIPS_ALLOW_SHORT); + #else ret = wc_HmacSetKey(myHmac, type, inKey, inKeySz); + #endif if (ret != 0) break; ret = wc_HmacUpdate(myHmac, tmp, tmpSz); diff --git a/wolfcrypt/src/rsa.c b/wolfcrypt/src/rsa.c index 717d4cca06..337d652b35 100644 --- a/wolfcrypt/src/rsa.c +++ b/wolfcrypt/src/rsa.c @@ -4510,7 +4510,8 @@ static int _CheckProbablePrime(mp_int* p, mp_int* q, mp_int* e, int nlen, if (q != NULL) { int valid = 0; - /* 5.4 - check that |p-q| <= (2^(1/2))(2^((nlen/2)-1)) */ + /* 5.4 (186-4) 5.5 (186-5) - + * check that |p-q| <= (2^(1/2))(2^((nlen/2)-1)) */ ret = wc_CompareDiffPQ(p, q, nlen, &valid); if ((ret != MP_OKAY) || (!valid)) goto notOkay; prime = q; @@ -4518,14 +4519,15 @@ static int _CheckProbablePrime(mp_int* p, mp_int* q, mp_int* e, int nlen, else prime = p; - /* 4.4,5.5 - Check that prime >= (2^(1/2))(2^((nlen/2)-1)) + /* 4.4,5.5 (186-4) 4.4,5.4 (186-5) - + * Check that prime >= (2^(1/2))(2^((nlen/2)-1)) * This is a comparison against lowerBound */ ret = mp_read_unsigned_bin(tmp1, lower_bound, (word32)nlen/16); if (ret != MP_OKAY) goto notOkay; ret = mp_cmp(prime, tmp1); if (ret == MP_LT) goto exit; - /* 4.5,5.6 - Check that GCD(p-1, e) == 1 */ + /* 4.5,5.6 (186-4 & 186-5) - Check that GCD(p-1, e) == 1 */ ret = mp_sub_d(prime, 1, tmp1); /* tmp1 = prime-1 */ if (ret != MP_OKAY) goto notOkay; #ifdef WOLFSSL_CHECK_MEM_ZERO diff --git a/wolfssl/wolfcrypt/hmac.h b/wolfssl/wolfcrypt/hmac.h index 7a5c457246..0d0844e1fc 100644 --- a/wolfssl/wolfcrypt/hmac.h +++ b/wolfssl/wolfcrypt/hmac.h @@ -43,6 +43,10 @@ WOLFSSL_LOCAL int wolfCrypt_FIPS_HMAC_sanity(void); #endif +#if FIPS_VERSION3_GE(6,0,0) + #define FIPS_ALLOW_SHORT 1 +#endif + /* avoid redefinition of structs */ #if !defined(HAVE_FIPS) || FIPS_VERSION3_GE(2,0,0) From 673c5993a784f643722ce06a4be4866532bffbc1 Mon Sep 17 00:00:00 2001 From: kaleb-himes Date: Thu, 2 May 2024 12:28:22 -0400 Subject: [PATCH 03/10] Make the memzero check default with FIPS, fix benchmark app --- configure.ac | 1 + wolfcrypt/benchmark/benchmark.c | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/configure.ac b/configure.ac index 09bfa9094a..32e241edb3 100644 --- a/configure.ac +++ b/configure.ac @@ -4969,6 +4969,7 @@ AS_CASE([$FIPS_VERSION], -DHAVE_FFDHE_3072 \ -DHAVE_FFDHE_4096 \ -DHAVE_FFDHE_6144 \ + -DWOLFSSL_CHECK_MEM_ZERO \ -DHAVE_FFDHE_8192" # KCAPI API does not support custom k for sign, don't force enable ECC key sizes and do not use seed callback diff --git a/wolfcrypt/benchmark/benchmark.c b/wolfcrypt/benchmark/benchmark.c index b77c5e27db..f413c28664 100644 --- a/wolfcrypt/benchmark/benchmark.c +++ b/wolfcrypt/benchmark/benchmark.c @@ -8158,6 +8158,7 @@ void bench_pbkdf2(void) DECLARE_MULTI_VALUE_STATS_VARS() bench_stats_start(&count, &start); + PRIVATE_KEY_UNLOCK(); do { ret = wc_PBKDF2(derived, (const byte*)passwd32, (int)XSTRLEN(passwd32), salt32, (int)sizeof(salt32), 1000, 32, WC_SHA256); @@ -8168,6 +8169,7 @@ void bench_pbkdf2(void) || runs < minimum_runs #endif ); + PRIVATE_KEY_LOCK(); bench_stats_sym_finish("PBKDF2", 32, count, 32, start, ret); #ifdef MULTI_VALUE_STATISTICS @@ -8248,6 +8250,7 @@ void bench_srtpkdf(void) DECLARE_MULTI_VALUE_STATS_VARS() bench_stats_start(&count, &start); + PRIVATE_KEY_UNLOCK(); do { for (i = 0; i < numBlocks; i++) { ret = wc_SRTP_KDF(key, AES_128_KEY_SIZE, salt, sizeof(salt), @@ -8261,6 +8264,7 @@ void bench_srtpkdf(void) || runs < minimum_runs #endif ); + PRIVATE_KEY_LOCK(); bench_stats_asym_finish("KDF", 128, "SRTP", 0, count, start, ret); #ifdef MULTI_VALUE_STATISTICS bench_multi_value_stats(max, min, sum, squareSum, runs); @@ -8269,6 +8273,7 @@ void bench_srtpkdf(void) RESET_MULTI_VALUE_STATS_VARS(); bench_stats_start(&count, &start); + PRIVATE_KEY_UNLOCK(); do { for (i = 0; i < numBlocks; i++) { ret = wc_SRTP_KDF(key, AES_256_KEY_SIZE, salt, sizeof(salt), @@ -8282,6 +8287,7 @@ void bench_srtpkdf(void) || runs < minimum_runs #endif ); + PRIVATE_KEY_LOCK(); bench_stats_asym_finish("KDF", 256, "SRTP", 0, count, start, ret); #ifdef MULTI_VALUE_STATISTICS bench_multi_value_stats(max, min, sum, squareSum, runs); @@ -8290,6 +8296,7 @@ void bench_srtpkdf(void) RESET_MULTI_VALUE_STATS_VARS(); bench_stats_start(&count, &start); + PRIVATE_KEY_UNLOCK(); do { for (i = 0; i < numBlocks; i++) { ret = wc_SRTCP_KDF(key, AES_128_KEY_SIZE, salt, sizeof(salt), @@ -8303,6 +8310,7 @@ void bench_srtpkdf(void) || runs < minimum_runs #endif ); + PRIVATE_KEY_LOCK(); bench_stats_asym_finish("KDF", 128, "SRTCP", 0, count, start, ret); #ifdef MULTI_VALUE_STATISTICS bench_multi_value_stats(max, min, sum, squareSum, runs); @@ -8311,6 +8319,7 @@ void bench_srtpkdf(void) RESET_MULTI_VALUE_STATS_VARS(); bench_stats_start(&count, &start); + PRIVATE_KEY_UNLOCK(); do { for (i = 0; i < numBlocks; i++) { ret = wc_SRTCP_KDF(key, AES_256_KEY_SIZE, salt, sizeof(salt), @@ -8324,6 +8333,7 @@ void bench_srtpkdf(void) || runs < minimum_runs #endif ); + PRIVATE_KEY_LOCK(); bench_stats_asym_finish("KDF", 256, "SRTCP", 0, count, start, ret); #ifdef MULTI_VALUE_STATISTICS bench_multi_value_stats(max, min, sum, squareSum, runs); From 82d9a7bbae561083bea6a5555956fd87ca91265e Mon Sep 17 00:00:00 2001 From: kaleb-himes Date: Thu, 2 May 2024 15:10:34 -0400 Subject: [PATCH 04/10] Initialize scratch buffer --- wolfcrypt/src/aes.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index e19ec0eedb..6aafcc2d43 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -6056,6 +6056,8 @@ int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) int ret = 0; word32 processed; + XMEMSET(scratch, 0, sizeof(scratch)); + if (aes == NULL || out == NULL || in == NULL) { return BAD_FUNC_ARG; } From a365d387622e3ef5c148f4ec37c40e3530e70430 Mon Sep 17 00:00:00 2001 From: kaleb-himes Date: Thu, 2 May 2024 17:06:00 -0400 Subject: [PATCH 05/10] After careful evaluation deciding not to include mem-zero check (for now) --- configure.ac | 1 - 1 file changed, 1 deletion(-) diff --git a/configure.ac b/configure.ac index 32e241edb3..09bfa9094a 100644 --- a/configure.ac +++ b/configure.ac @@ -4969,7 +4969,6 @@ AS_CASE([$FIPS_VERSION], -DHAVE_FFDHE_3072 \ -DHAVE_FFDHE_4096 \ -DHAVE_FFDHE_6144 \ - -DWOLFSSL_CHECK_MEM_ZERO \ -DHAVE_FFDHE_8192" # KCAPI API does not support custom k for sign, don't force enable ECC key sizes and do not use seed callback From a9511e118a649100a4add0ca1637504a4f3339fb Mon Sep 17 00:00:00 2001 From: kaleb-himes Date: Wed, 8 May 2024 17:14:40 -0400 Subject: [PATCH 06/10] Add SP800-132 112 bit minimum applicable after stretch/strengthen --- wolfcrypt/src/pwdbased.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/wolfcrypt/src/pwdbased.c b/wolfcrypt/src/pwdbased.c index 5ca98cb0fb..6859391288 100644 --- a/wolfcrypt/src/pwdbased.c +++ b/wolfcrypt/src/pwdbased.c @@ -183,6 +183,7 @@ int wc_PBKDF1_ex(byte* key, int keyLen, byte* iv, int ivLen, int wc_PBKDF1(byte* output, const byte* passwd, int pLen, const byte* salt, int sLen, int iterations, int kLen, int hashType) { + return wc_PBKDF1_ex(output, kLen, NULL, 0, passwd, pLen, salt, sLen, iterations, hashType, NULL); } @@ -209,6 +210,15 @@ int wc_PBKDF2_ex(byte* output, const byte* passwd, int pLen, const byte* salt, return BAD_FUNC_ARG; } +#if FIPS_VERSION3_GE(6,0,0) + /* Per SP800-132 section 5 "The kLen value shall be at least 112 bits in + * length", ensure the returned bits for the derived master key are at a + * minimum 14-bytes or 112-bits after stretching and strengthening + * (iterations) */ + if (kLen < HMAC_FIPS_MIN_KEY/8) + return BAD_LENGTH_E; +#endif + if (iterations <= 0) iterations = 1; From 7047991cda8ff202703491143e771cefe9fdcd86 Mon Sep 17 00:00:00 2001 From: kaleb-himes Date: Wed, 8 May 2024 17:43:08 -0400 Subject: [PATCH 07/10] Log when iterations LT 1000 but take no action --- wolfcrypt/src/pwdbased.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/wolfcrypt/src/pwdbased.c b/wolfcrypt/src/pwdbased.c index 6859391288..471b1b0a8c 100644 --- a/wolfcrypt/src/pwdbased.c +++ b/wolfcrypt/src/pwdbased.c @@ -219,6 +219,15 @@ int wc_PBKDF2_ex(byte* output, const byte* passwd, int pLen, const byte* salt, return BAD_LENGTH_E; #endif +#if FIPS_VERSION3_GE(6,0,0) && defined(DEBUG_WOLFSSL) + /* SP800-132 §5.2 recommends an iteration count of 1000 but this is not + * strictly enforceable and is listed in Appendix B Table 1 as a + * non-testable requirement. wolfCrypt will log it when appropriate but + * take no action */ + if (iterations < 1000) { + WOLFSSL_MSG("WARNING: Iteration < 1,000, see SP800-132 §5.2"); + } +#endif if (iterations <= 0) iterations = 1; From 6719909f4e56cb381a1a8b623fd07c581adce5ac Mon Sep 17 00:00:00 2001 From: kaleb-himes Date: Wed, 8 May 2024 18:01:09 -0400 Subject: [PATCH 08/10] Add logging.h header in pwdbased.c when DEBUG_WOLFSSL --- wolfcrypt/src/pwdbased.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/wolfcrypt/src/pwdbased.c b/wolfcrypt/src/pwdbased.c index 471b1b0a8c..eba26f0340 100644 --- a/wolfcrypt/src/pwdbased.c +++ b/wolfcrypt/src/pwdbased.c @@ -52,6 +52,9 @@ #endif #if FIPS_VERSION3_GE(6,0,0) + #ifdef DEBUG_WOLFSSL + #include + #endif const unsigned int wolfCrypt_FIPS_pbkdf_ro_sanity[2] = { 0x1a2b3c4d, 0x00000010 }; int wolfCrypt_FIPS_PBKDF_sanity(void) From fa08e2cb623e27ceab6d7244582aae602c84d609 Mon Sep 17 00:00:00 2001 From: kaleb-himes Date: Wed, 8 May 2024 18:10:03 -0400 Subject: [PATCH 09/10] Fix a long line in pbkdf2 test --- wolfcrypt/test/test.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index b5296ead55..e5e47bbcf7 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -26045,7 +26045,8 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t pkcs12_pbkdf_test(void) WOLFSSL_TEST_SUBROUTINE wc_test_ret_t pbkdf2_test(void) { char passwd[] = "passwordpassword"; - WOLFSSL_SMALL_STACK_STATIC const byte salt[] = { 0x78, 0x57, 0x8E, 0x5a, 0x5d, 0x63, 0xcb, 0x06 }; + WOLFSSL_SMALL_STACK_STATIC const byte salt[] = { 0x78, 0x57, 0x8E, 0x5a, + 0x5d, 0x63, 0xcb, 0x06 }; int iterations = 2048; int kLen = 24; byte derived[64]; From 76527c3eaad430ca890f0ee0ca79efe9bf8b3949 Mon Sep 17 00:00:00 2001 From: kaleb-himes Date: Wed, 15 May 2024 15:21:41 -0400 Subject: [PATCH 10/10] Address a report from multi-test about 8-bit chars --- wolfcrypt/src/pwdbased.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wolfcrypt/src/pwdbased.c b/wolfcrypt/src/pwdbased.c index eba26f0340..1aef716bca 100644 --- a/wolfcrypt/src/pwdbased.c +++ b/wolfcrypt/src/pwdbased.c @@ -223,12 +223,12 @@ int wc_PBKDF2_ex(byte* output, const byte* passwd, int pLen, const byte* salt, #endif #if FIPS_VERSION3_GE(6,0,0) && defined(DEBUG_WOLFSSL) - /* SP800-132 §5.2 recommends an iteration count of 1000 but this is not - * strictly enforceable and is listed in Appendix B Table 1 as a + /* SP800-132 section 5.2 recommends an iteration count of 1000 but this is + * not strictly enforceable and is listed in Appendix B Table 1 as a * non-testable requirement. wolfCrypt will log it when appropriate but * take no action */ if (iterations < 1000) { - WOLFSSL_MSG("WARNING: Iteration < 1,000, see SP800-132 §5.2"); + WOLFSSL_MSG("WARNING: Iteration < 1,000, see SP800-132 section 5.2"); } #endif if (iterations <= 0)