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); 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; } 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/pwdbased.c b/wolfcrypt/src/pwdbased.c index 5ca98cb0fb..1aef716bca 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) @@ -183,6 +186,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 +213,24 @@ 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 FIPS_VERSION3_GE(6,0,0) && defined(DEBUG_WOLFSSL) + /* 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 section 5.2"); + } +#endif if (iterations <= 0) iterations = 1; 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/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 18844c2614..e5e47bbcf7 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); @@ -26039,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]; 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)