Skip to content

Commit 9470ee1

Browse files
committed
Default to 2048 bit DH crypto with DH_MIN_SZ macro
1 parent 18c9684 commit 9470ee1

5 files changed

Lines changed: 59 additions & 4 deletions

File tree

tests/api.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12740,6 +12740,17 @@ static int test_wolfSSL_tmp_dh(void)
1274012740
DH_free(dh2);
1274112741
dh2 = NULL;
1274212742

12743+
DH_free(dh);
12744+
dh = NULL;
12745+
BIO_free(bio);
12746+
bio = NULL;
12747+
ExpectTrue((f = XFOPEN("./certs/dh2048.pem", "rb")) != XBADFILE);
12748+
ExpectIntGT(bytes = (int)XFREAD(buff, 1, sizeof(buff), f), 0);
12749+
if (f != XBADFILE)
12750+
XFCLOSE(f);
12751+
ExpectNotNull(bio = BIO_new_mem_buf((void*)buff, bytes));
12752+
ExpectNotNull(dh = wolfSSL_PEM_read_bio_DHparams(bio, NULL, NULL, NULL));
12753+
1274312754
ExpectIntEQ((int)wolfSSL_CTX_SetTmpDH(ctx, p, pSz, g, gSz),
1274412755
WOLFSSL_SUCCESS);
1274512756
ExpectIntEQ((int)SSL_CTX_set_tmp_dh(ctx, dh), WOLFSSL_SUCCESS);
@@ -20635,6 +20646,16 @@ static int test_wolfSSL_CTX_ctrl(void)
2063520646
* wolfSSL_CTX_ctrl should succesffuly call wolfSSL_SSL_CTX_set_tmp_dh
2063620647
*/
2063720648
#if !defined(NO_DH) && !defined(NO_DSA) && !defined(NO_BIO)
20649+
DH_free(dh);
20650+
dh = NULL;
20651+
BIO_free(bio);
20652+
bio = NULL;
20653+
ExpectTrue((f = XFOPEN("./certs/dh2048.pem", "rb")) != XBADFILE);
20654+
ExpectIntGT(bytes = (int)XFREAD(buf, 1, sizeof(buf), f), 0);
20655+
if (f != XBADFILE)
20656+
XFCLOSE(f);
20657+
ExpectNotNull(bio = BIO_new_mem_buf((void*)buf, bytes));
20658+
ExpectNotNull(dh = wolfSSL_PEM_read_bio_DHparams(bio, NULL, NULL, NULL));
2063820659
ExpectIntEQ((int)wolfSSL_CTX_ctrl(ctx, SSL_CTRL_SET_TMP_DH, 0, dh),
2063920660
SSL_SUCCESS);
2064020661
#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: 18 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)
@@ -2364,6 +2376,12 @@ int wc_DhAgree(DhKey* key, byte* agree, word32* agreeSz, const byte* priv,
23642376
(void)privSz;
23652377
ret = KcapiDh_SharedSecret(key, otherPub, pubSz, agree, agreeSz);
23662378
#else
2379+
/* reject primes below the minimum allowed size */
2380+
if (mp_count_bits(&key->p) < DH_MIN_SIZE) {
2381+
WOLFSSL_MSG("DH prime smaller than DH_MIN_SIZE");
2382+
return WC_KEY_SIZE_E;
2383+
}
2384+
23672385
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_DH)
23682386
/* Async marker takes precedence: when wolfAsync_DoSw (wolfcrypt/src/
23692387
* async.c) re-enters the compute path, wc_DhAgree_Async dispatches

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: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4626,6 +4626,18 @@ 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 WOLFSSL_MIN_DHKEY_BITS
4633+
/* For existing build settings that use WOLFSSL_MIN_DHKEY_BITS, map
4634+
* DH_MIN_SIZE to the user's desired minimum */
4635+
#define DH_MIN_SIZE WOLFSSL_MIN_DHKEY_BITS
4636+
#else
4637+
#define DH_MIN_SIZE 2048
4638+
#endif
4639+
#endif
4640+
46294641
/* wc_Sha512.devId isn't available before FIPS 5.1 */
46304642
#if defined(HAVE_FIPS) && FIPS_VERSION_LT(5,1)
46314643
#define NO_SHA2_CRYPTO_CB

0 commit comments

Comments
 (0)