Skip to content

Commit e3f2989

Browse files
committed
FIPS: Default to 2048 bit min DH crypto
1 parent 18c9684 commit e3f2989

5 files changed

Lines changed: 51 additions & 32 deletions

File tree

tests/api.c

Lines changed: 7 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -12610,12 +12610,7 @@ static int test_wolfSSL_tmp_dh(void)
1261012610
#endif
1261112611
static const unsigned char g[] = { 0x02 };
1261212612
int gSz = (int)sizeof(g);
12613-
#if !defined(NO_DSA)
12614-
char file[] = "./certs/dsaparams.pem";
12615-
DSA* dsa = NULL;
12616-
#else
1261712613
char file[] = "./certs/dh2048.pem";
12618-
#endif
1261912614
XFILE f = XBADFILE;
1262012615
int bytes = 0;
1262112616
DH* dh = NULL;
@@ -12657,14 +12652,7 @@ static int test_wolfSSL_tmp_dh(void)
1265712652

1265812653
ExpectNotNull(bio = BIO_new_mem_buf((void*)buff, bytes));
1265912654

12660-
#if !defined(NO_DSA)
12661-
dsa = wolfSSL_PEM_read_bio_DSAparams(bio, NULL, NULL, NULL);
12662-
ExpectNotNull(dsa);
12663-
12664-
dh = wolfSSL_DSA_dup_DH(dsa);
12665-
#else
1266612655
dh = wolfSSL_PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
12667-
#endif
1266812656
ExpectNotNull(dh);
1266912657
#if defined(WOLFSSL_DH_EXTRA) && \
1267012658
(defined(WOLFSSL_QT) || defined(OPENSSL_ALL) || defined(WOLFSSL_OPENSSH))
@@ -12750,9 +12738,6 @@ static int test_wolfSSL_tmp_dh(void)
1275012738
#endif
1275112739

1275212740
BIO_free(bio);
12753-
#if !defined(NO_DSA)
12754-
DSA_free(dsa);
12755-
#endif
1275612741
DH_free(dh);
1275712742
dh = NULL;
1275812743
#ifndef NO_WOLFSSL_CLIENT
@@ -20525,13 +20510,12 @@ static int test_wolfSSL_CTX_ctrl(void)
2052520510
char clientFile[] = "./certs/client-cert.pem";
2052620511
SSL_CTX* ctx = NULL;
2052720512
X509* x509 = NULL;
20528-
#if !defined(NO_DH) && !defined(NO_DSA) && !defined(NO_BIO)
20513+
#if !defined(NO_DH) && !defined(NO_BIO)
2052920514
byte buf[6000];
20530-
char file[] = "./certs/dsaparams.pem";
20515+
char file[] = "./certs/dh2048.pem";
2053120516
XFILE f = XBADFILE;
2053220517
int bytes = 0;
2053320518
BIO* bio = NULL;
20534-
DSA* dsa = NULL;
2053520519
DH* dh = NULL;
2053620520
#endif
2053720521
#ifdef HAVE_ECC
@@ -20550,7 +20534,7 @@ static int test_wolfSSL_CTX_ctrl(void)
2055020534
ExpectNotNull(x509 = wolfSSL_X509_load_certificate_file(clientFile,
2055120535
WOLFSSL_FILETYPE_PEM));
2055220536

20553-
#if !defined(NO_DH) && !defined(NO_DSA) && !defined(NO_BIO)
20537+
#if !defined(NO_DH) && !defined(NO_BIO)
2055420538
/* Initialize DH */
2055520539
ExpectTrue((f = XFOPEN(file, "rb")) != XBADFILE);
2055620540
ExpectIntGT(bytes = (int)XFREAD(buf, 1, sizeof(buf), f), 0);
@@ -20559,9 +20543,7 @@ static int test_wolfSSL_CTX_ctrl(void)
2055920543

2056020544
ExpectNotNull(bio = BIO_new_mem_buf((void*)buf, bytes));
2056120545

20562-
ExpectNotNull(dsa = wolfSSL_PEM_read_bio_DSAparams(bio, NULL, NULL, NULL));
20563-
20564-
ExpectNotNull(dh = wolfSSL_DSA_dup_DH(dsa));
20546+
ExpectNotNull(dh = wolfSSL_PEM_read_bio_DHparams(bio, NULL, NULL, NULL));
2056520547
#endif
2056620548
#ifdef HAVE_ECC
2056720549
/* Initialize WOLFSSL_EC_KEY */
@@ -20606,7 +20588,7 @@ static int test_wolfSSL_CTX_ctrl(void)
2060620588
/* Tests should fail with passed in NULL pointer */
2060720589
ExpectIntEQ((int)wolfSSL_CTX_ctrl(ctx, SSL_CTRL_EXTRA_CHAIN_CERT, 0, NULL),
2060820590
WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
20609-
#if !defined(NO_DH) && !defined(NO_DSA)
20591+
#if !defined(NO_DH)
2061020592
ExpectIntEQ((int)wolfSSL_CTX_ctrl(ctx, SSL_CTRL_SET_TMP_DH, 0, NULL),
2061120593
WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
2061220594
#endif
@@ -20634,7 +20616,7 @@ static int test_wolfSSL_CTX_ctrl(void)
2063420616
/* Test with SSL_CTRL_SET_TMP_DH
2063520617
* wolfSSL_CTX_ctrl should succesffuly call wolfSSL_SSL_CTX_set_tmp_dh
2063620618
*/
20637-
#if !defined(NO_DH) && !defined(NO_DSA) && !defined(NO_BIO)
20619+
#if !defined(NO_DH) && !defined(NO_BIO)
2063820620
ExpectIntEQ((int)wolfSSL_CTX_ctrl(ctx, SSL_CTRL_SET_TMP_DH, 0, dh),
2063920621
SSL_SUCCESS);
2064020622
#endif
@@ -20674,14 +20656,11 @@ static int test_wolfSSL_CTX_ctrl(void)
2067420656
#endif
2067520657
#endif
2067620658
/* Cleanup and Pass */
20677-
#if !defined(NO_DH) && !defined(NO_DSA)
20678-
#ifndef NO_BIO
20659+
#if !defined(NO_DH) && !defined(NO_BIO)
2067920660
BIO_free(bio);
20680-
DSA_free(dsa);
2068120661
DH_free(dh);
2068220662
dh = NULL;
2068320663
#endif
20684-
#endif
2068520664
#ifdef HAVE_ECC
2068620665
wolfSSL_EC_KEY_free(ecKey);
2068720666
#endif

tests/api/test_dh.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ int test_wc_DhAgree_subgroup_check(void)
8484
{
8585
EXPECT_DECLS;
8686
#if !defined(NO_DH) && !defined(WOLFSSL_SP_MATH) && !defined(HAVE_SELFTEST) && \
87-
(!defined(HAVE_FIPS) || FIPS_VERSION3_GT(7,0,0))
87+
(!defined(HAVE_FIPS) || FIPS_VERSION3_GT(7,0,0)) && DH_MIN_SIZE <= 512
8888
DhKey key;
8989
WC_RNG rng;
9090
byte agree[64];

wolfcrypt/src/dh.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1259,6 +1259,12 @@ static int GeneratePrivateDh(DhKey* key, WC_RNG* rng, byte* priv,
12591259
int ret = 0;
12601260
word32 sz = 0;
12611261

1262+
/* reject primes below the minimum allowed size */
1263+
if (mp_count_bits(&key->p) < DH_MIN_SIZE) {
1264+
WOLFSSL_MSG("DH prime smaller than DH_MIN_SIZE");
1265+
return WC_KEY_SIZE_E;
1266+
}
1267+
12621268
if (mp_iseven(&key->p) == MP_YES) {
12631269
ret = MP_VAL;
12641270
}
@@ -1344,6 +1350,12 @@ static int GeneratePublicDh(DhKey* key, byte* priv, word32 privSz,
13441350
return WC_KEY_SIZE_E;
13451351
}
13461352

1353+
/* reject primes below the minimum allowed size */
1354+
if (mp_count_bits(&key->p) < DH_MIN_SIZE) {
1355+
WOLFSSL_MSG("DH prime smaller than DH_MIN_SIZE");
1356+
return WC_KEY_SIZE_E;
1357+
}
1358+
13471359
#ifdef WOLFSSL_HAVE_SP_DH
13481360
#ifndef WOLFSSL_SP_NO_2048
13491361
if (mp_count_bits(&key->p) == 2048)
@@ -2034,6 +2046,12 @@ static int wc_DhAgree_Sync(DhKey* key, byte* agree, word32* agreeSz,
20342046
#endif
20352047
#endif
20362048

2049+
/* reject primes below the minimum allowed size */
2050+
if (mp_count_bits(&key->p) < DH_MIN_SIZE) {
2051+
WOLFSSL_MSG("DH prime smaller than DH_MIN_SIZE");
2052+
return WC_KEY_SIZE_E;
2053+
}
2054+
20372055
if (mp_iseven(&key->p) == MP_YES) {
20382056
return MP_VAL;
20392057
}
@@ -2362,6 +2380,10 @@ int wc_DhAgree(DhKey* key, byte* agree, word32* agreeSz, const byte* priv,
23622380
#ifdef WOLFSSL_KCAPI_DH
23632381
(void)priv;
23642382
(void)privSz;
2383+
if (mp_count_bits(&key->p) < DH_MIN_SIZE) {
2384+
WOLFSSL_MSG("DH prime smaller than DH_MIN_SIZE");
2385+
return WC_KEY_SIZE_E;
2386+
}
23652387
ret = KcapiDh_SharedSecret(key, otherPub, pubSz, agree, agreeSz);
23662388
#else
23672389
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_DH)

wolfssl/internal.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1231,10 +1231,8 @@ enum {
12311231
#elif WOLFSSL_HARDEN_TLS >= 112
12321232
#define WOLFSSL_MIN_DHKEY_BITS 2048
12331233
#endif
1234-
#elif defined(WOLFSSL_MAX_STRENGTH)
1235-
#define WOLFSSL_MIN_DHKEY_BITS 2048
12361234
#else
1237-
#define WOLFSSL_MIN_DHKEY_BITS 1024
1235+
#define WOLFSSL_MIN_DHKEY_BITS DH_MIN_SIZE
12381236
#endif
12391237
#endif
12401238
#if defined(WOLFSSL_HARDEN_TLS) && WOLFSSL_MIN_DHKEY_BITS < 2048 && \
@@ -1252,6 +1250,12 @@ enum {
12521250
#if (WOLFSSL_MIN_DHKEY_BITS > 16000)
12531251
#error DH minimum bit size must not be greater than 16000
12541252
#endif
1253+
#if (WOLFSSL_MIN_DHKEY_BITS < DH_MIN_SIZE)
1254+
/* The TLS-layer minimum must not be looser than the wolfCrypt DH primitive
1255+
* minimum (DH_MIN_SIZE), otherwise a key size accepted during negotiation
1256+
* is later rejected by wc_DhAgree with WC_KEY_SIZE_E. */
1257+
#error "WOLFSSL_MIN_DHKEY_BITS must be >= DH_MIN_SIZE"
1258+
#endif
12551259
#define MIN_DHKEY_SZ (WOLFSSL_MIN_DHKEY_BITS / 8)
12561260
/* set maximum DH key size allowed */
12571261
#ifndef WOLFSSL_MAX_DHKEY_BITS

wolfssl/wolfcrypt/settings.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4626,6 +4626,20 @@ blinding by defining WC_BLINDING_NO_RNG_ACKNOWLEDGE_WEAKNESS."
46264626
#endif
46274627
#endif
46284628

4629+
/* Minimum allowed DH prime size in bits. SP 800-56A Rev3 / SP 800-131A
4630+
* disallow FFC below 2048 bits. Override to permit legacy sizes. */
4631+
#ifndef DH_MIN_SIZE
4632+
#ifdef HAVE_FIPS
4633+
#define DH_MIN_SIZE 2048
4634+
#elif WOLFSSL_MIN_DHKEY_BITS
4635+
/* For existing build settings that use WOLFSSL_MIN_DHKEY_BITS, map
4636+
* DH_MIN_SIZE to the user's desired minimum */
4637+
#define DH_MIN_SIZE WOLFSSL_MIN_DHKEY_BITS
4638+
#else
4639+
#define DH_MIN_SIZE 1024
4640+
#endif
4641+
#endif
4642+
46294643
/* wc_Sha512.devId isn't available before FIPS 5.1 */
46304644
#if defined(HAVE_FIPS) && FIPS_VERSION_LT(5,1)
46314645
#define NO_SHA2_CRYPTO_CB

0 commit comments

Comments
 (0)