Merge pull request #10820 from lealem47/dh_min_sz

FIPS: Default to 2048 bit min DH crypto
This commit is contained in:
Daniel Pouzzner
2026-07-01 14:40:04 -05:00
committed by GitHub
6 changed files with 55 additions and 56 deletions
+7 -28
View File
@@ -12610,12 +12610,7 @@ static int test_wolfSSL_tmp_dh(void)
#endif
static const unsigned char g[] = { 0x02 };
int gSz = (int)sizeof(g);
#if !defined(NO_DSA)
char file[] = "./certs/dsaparams.pem";
DSA* dsa = NULL;
#else
char file[] = "./certs/dh2048.pem";
#endif
XFILE f = XBADFILE;
int bytes = 0;
DH* dh = NULL;
@@ -12657,14 +12652,7 @@ static int test_wolfSSL_tmp_dh(void)
ExpectNotNull(bio = BIO_new_mem_buf((void*)buff, bytes));
#if !defined(NO_DSA)
dsa = wolfSSL_PEM_read_bio_DSAparams(bio, NULL, NULL, NULL);
ExpectNotNull(dsa);
dh = wolfSSL_DSA_dup_DH(dsa);
#else
dh = wolfSSL_PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
#endif
ExpectNotNull(dh);
#if defined(WOLFSSL_DH_EXTRA) && \
(defined(WOLFSSL_QT) || defined(OPENSSL_ALL) || defined(WOLFSSL_OPENSSH))
@@ -12750,9 +12738,6 @@ static int test_wolfSSL_tmp_dh(void)
#endif
BIO_free(bio);
#if !defined(NO_DSA)
DSA_free(dsa);
#endif
DH_free(dh);
dh = NULL;
#ifndef NO_WOLFSSL_CLIENT
@@ -20525,13 +20510,12 @@ static int test_wolfSSL_CTX_ctrl(void)
char clientFile[] = "./certs/client-cert.pem";
SSL_CTX* ctx = NULL;
X509* x509 = NULL;
#if !defined(NO_DH) && !defined(NO_DSA) && !defined(NO_BIO)
#if !defined(NO_DH) && !defined(NO_BIO)
byte buf[6000];
char file[] = "./certs/dsaparams.pem";
char file[] = "./certs/dh2048.pem";
XFILE f = XBADFILE;
int bytes = 0;
BIO* bio = NULL;
DSA* dsa = NULL;
DH* dh = NULL;
#endif
#ifdef HAVE_ECC
@@ -20550,7 +20534,7 @@ static int test_wolfSSL_CTX_ctrl(void)
ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(clientFile,
WOLFSSL_FILETYPE_PEM));
#if !defined(NO_DH) && !defined(NO_DSA) && !defined(NO_BIO)
#if !defined(NO_DH) && !defined(NO_BIO)
/* Initialize DH */
ExpectTrue((f = XFOPEN(file, "rb")) != XBADFILE);
ExpectIntGT(bytes = (int)XFREAD(buf, 1, sizeof(buf), f), 0);
@@ -20559,9 +20543,7 @@ static int test_wolfSSL_CTX_ctrl(void)
ExpectNotNull(bio = BIO_new_mem_buf((void*)buf, bytes));
ExpectNotNull(dsa = wolfSSL_PEM_read_bio_DSAparams(bio, NULL, NULL, NULL));
ExpectNotNull(dh = wolfSSL_DSA_dup_DH(dsa));
ExpectNotNull(dh = wolfSSL_PEM_read_bio_DHparams(bio, NULL, NULL, NULL));
#endif
#ifdef HAVE_ECC
/* Initialize WOLFSSL_EC_KEY */
@@ -20606,7 +20588,7 @@ static int test_wolfSSL_CTX_ctrl(void)
/* Tests should fail with passed in NULL pointer */
ExpectIntEQ((int)wolfSSL_CTX_ctrl(ctx, SSL_CTRL_EXTRA_CHAIN_CERT, 0, NULL),
WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#if !defined(NO_DH) && !defined(NO_DSA)
#if !defined(NO_DH)
ExpectIntEQ((int)wolfSSL_CTX_ctrl(ctx, SSL_CTRL_SET_TMP_DH, 0, NULL),
WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
#endif
@@ -20634,7 +20616,7 @@ static int test_wolfSSL_CTX_ctrl(void)
/* Test with SSL_CTRL_SET_TMP_DH
* wolfSSL_CTX_ctrl should succesffuly call wolfSSL_SSL_CTX_set_tmp_dh
*/
#if !defined(NO_DH) && !defined(NO_DSA) && !defined(NO_BIO)
#if !defined(NO_DH) && !defined(NO_BIO)
ExpectIntEQ((int)wolfSSL_CTX_ctrl(ctx, SSL_CTRL_SET_TMP_DH, 0, dh),
SSL_SUCCESS);
#endif
@@ -20674,14 +20656,11 @@ static int test_wolfSSL_CTX_ctrl(void)
#endif
#endif
/* Cleanup and Pass */
#if !defined(NO_DH) && !defined(NO_DSA)
#ifndef NO_BIO
#if !defined(NO_DH) && !defined(NO_BIO)
BIO_free(bio);
DSA_free(dsa);
DH_free(dh);
dh = NULL;
#endif
#endif
#ifdef HAVE_ECC
wolfSSL_EC_KEY_free(ecKey);
#endif
+1 -1
View File
@@ -84,7 +84,7 @@ int test_wc_DhAgree_subgroup_check(void)
{
EXPECT_DECLS;
#if !defined(NO_DH) && !defined(WOLFSSL_SP_MATH) && !defined(HAVE_SELFTEST) && \
(!defined(HAVE_FIPS) || FIPS_VERSION3_GT(7,0,0))
(!defined(HAVE_FIPS) || FIPS_VERSION3_GT(7,0,0)) && DH_MIN_SIZE <= 512
DhKey key;
WC_RNG rng;
byte agree[64];
+22
View File
@@ -1261,6 +1261,12 @@ static int GeneratePrivateDh(DhKey* key, WC_RNG* rng, byte* priv,
int ret = 0;
word32 sz = 0;
/* reject primes below the minimum allowed size */
if (mp_count_bits(&key->p) < DH_MIN_SIZE) {
WOLFSSL_MSG("DH prime smaller than DH_MIN_SIZE");
return WC_KEY_SIZE_E;
}
if (mp_iseven(&key->p) == MP_YES) {
ret = MP_VAL;
}
@@ -1346,6 +1352,12 @@ static int GeneratePublicDh(DhKey* key, byte* priv, word32 privSz,
return WC_KEY_SIZE_E;
}
/* reject primes below the minimum allowed size */
if (mp_count_bits(&key->p) < DH_MIN_SIZE) {
WOLFSSL_MSG("DH prime smaller than DH_MIN_SIZE");
return WC_KEY_SIZE_E;
}
#ifdef WOLFSSL_HAVE_SP_DH
#ifndef WOLFSSL_SP_NO_2048
if (mp_count_bits(&key->p) == 2048)
@@ -2033,6 +2045,12 @@ static int wc_DhAgree_Sync(DhKey* key, byte* agree, word32* agreeSz,
#endif
#endif
/* reject primes below the minimum allowed size */
if (mp_count_bits(&key->p) < DH_MIN_SIZE) {
WOLFSSL_MSG("DH prime smaller than DH_MIN_SIZE");
return WC_KEY_SIZE_E;
}
if (mp_iseven(&key->p) == MP_YES) {
return MP_VAL;
}
@@ -2361,6 +2379,10 @@ int wc_DhAgree(DhKey* key, byte* agree, word32* agreeSz, const byte* priv,
#ifdef WOLFSSL_KCAPI_DH
(void)priv;
(void)privSz;
if (mp_count_bits(&key->p) < DH_MIN_SIZE) {
WOLFSSL_MSG("DH prime smaller than DH_MIN_SIZE");
return WC_KEY_SIZE_E;
}
ret = KcapiDh_SharedSecret(key, otherPub, pubSz, agree, agreeSz);
#else
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_DH)
+4 -24
View File
@@ -30003,18 +30003,6 @@ static wc_test_ret_t dh_generate_test(WC_RNG *rng)
#endif
byte p[2] = { 1, 7 }; /* 263 in decimal */
byte g[2] = { 0, 2 };
#if !defined(WOLFSSL_SP_MATH) && !defined(HAVE_FFDHE)
#ifdef WOLFSSL_DH_CONST
/* the table for constant DH lookup will round to the lowest byte size 21 */
byte priv[21];
byte pub[21];
#else
byte priv[2];
byte pub[2];
#endif
word32 privSz = sizeof(priv);
word32 pubSz = sizeof(pub);
#endif
int smallKey_inited = 0;
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
@@ -30057,20 +30045,12 @@ static wc_test_ret_t dh_generate_test(WC_RNG *rng)
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit_gen_test);
#if !defined(WOLFSSL_SP_MATH) && !defined(HAVE_FFDHE)
/* Use API. */
ret = wc_DhGenerateKeyPair(smallKey, rng, priv, &privSz, pub, &pubSz);
#if defined(WOLFSSL_ASYNC_CRYPT)
ret = wc_AsyncWait(ret, &smallKey->asyncDev, WC_ASYNC_FLAG_NONE);
#endif
if (ret != 0) {
ret = WC_TEST_RET_ENC_EC(ret);
}
#else
/* Generation with this sub-DH_MIN_SIZE prime is intentionally not
* exercised here; wc_DhGenerateKeyPair is covered with a valid group in
* dh_fips_generate_test. */
(void)rng;
#if defined(HAVE_FIPS) || !defined(WOLFSSL_NO_DH186)
#if defined(HAVE_FIPS) || !defined(WOLFSSL_NO_DH186)
ret = 0;
#endif
#endif
#if !defined(HAVE_FIPS) && defined(WOLFSSL_NO_DH186)
+7 -3
View File
@@ -1231,10 +1231,8 @@ enum {
#elif WOLFSSL_HARDEN_TLS >= 112
#define WOLFSSL_MIN_DHKEY_BITS 2048
#endif
#elif defined(WOLFSSL_MAX_STRENGTH)
#define WOLFSSL_MIN_DHKEY_BITS 2048
#else
#define WOLFSSL_MIN_DHKEY_BITS 1024
#define WOLFSSL_MIN_DHKEY_BITS DH_MIN_SIZE
#endif
#endif
#if defined(WOLFSSL_HARDEN_TLS) && WOLFSSL_MIN_DHKEY_BITS < 2048 && \
@@ -1252,6 +1250,12 @@ enum {
#if (WOLFSSL_MIN_DHKEY_BITS > 16000)
#error DH minimum bit size must not be greater than 16000
#endif
#if (WOLFSSL_MIN_DHKEY_BITS < DH_MIN_SIZE)
/* The TLS-layer minimum must not be looser than the wolfCrypt DH primitive
* minimum (DH_MIN_SIZE), otherwise a key size accepted during negotiation
* is later rejected by wc_DhAgree with WC_KEY_SIZE_E. */
#error "WOLFSSL_MIN_DHKEY_BITS must be >= DH_MIN_SIZE"
#endif
#define MIN_DHKEY_SZ (WOLFSSL_MIN_DHKEY_BITS / 8)
/* set maximum DH key size allowed */
#ifndef WOLFSSL_MAX_DHKEY_BITS
+14
View File
@@ -4908,6 +4908,20 @@ blinding by defining WC_BLINDING_NO_RNG_ACKNOWLEDGE_WEAKNESS."
#endif
#endif
/* Minimum allowed DH prime size in bits. SP 800-56A Rev3 / SP 800-131A
* disallow FFC below 2048 bits. Override to permit legacy sizes. */
#ifndef DH_MIN_SIZE
#ifdef HAVE_FIPS
#define DH_MIN_SIZE 2048
#elif defined(WOLFSSL_MIN_DHKEY_BITS)
/* For existing build settings that use WOLFSSL_MIN_DHKEY_BITS, map
* DH_MIN_SIZE to the user's desired minimum */
#define DH_MIN_SIZE WOLFSSL_MIN_DHKEY_BITS
#else
#define DH_MIN_SIZE 1024
#endif
#endif
/* wc_Sha512.devId isn't available before FIPS 5.1 */
#if defined(HAVE_FIPS) && FIPS_VERSION_LT(5,1)
#define NO_SHA2_CRYPTO_CB