diff --git a/crypto/dh/dh_check.c b/crypto/dh/dh_check.c index 0b391910d6..84a926998e 100644 --- a/crypto/dh/dh_check.c +++ b/crypto/dh/dh_check.c @@ -152,6 +152,12 @@ int DH_check(const DH *dh, int *ret) if (nid != NID_undef) return 1; + /* Don't do any checks at all with an excessively large modulus */ + if (BN_num_bits(dh->params.p) > OPENSSL_DH_CHECK_MAX_MODULUS_BITS) { + ERR_raise(ERR_LIB_DH, DH_R_MODULUS_TOO_LARGE); + return 0; + } + if (!DH_check_params(dh, ret)) return 0; diff --git a/include/openssl/dh.h b/include/openssl/dh.h index b97871eca7..36420f51d8 100644 --- a/include/openssl/dh.h +++ b/include/openssl/dh.h @@ -89,7 +89,11 @@ int EVP_PKEY_CTX_get0_dh_kdf_ukm(EVP_PKEY_CTX *ctx, unsigned char **ukm); # include # ifndef OPENSSL_DH_MAX_MODULUS_BITS -# define OPENSSL_DH_MAX_MODULUS_BITS 10000 +# define OPENSSL_DH_MAX_MODULUS_BITS 10000 +# endif + +# ifndef OPENSSL_DH_CHECK_MAX_MODULUS_BITS +# define OPENSSL_DH_CHECK_MAX_MODULUS_BITS 32768 # endif # define OPENSSL_DH_FIPS_MIN_MODULUS_BITS 1024 diff --git a/test/dhtest.c b/test/dhtest.c index 7b587f3cfa..f8dd8f3aa7 100644 --- a/test/dhtest.c +++ b/test/dhtest.c @@ -73,7 +73,7 @@ static int dh_test(void) goto err1; /* check fails, because p is way too small */ - if (!DH_check(dh, &i)) + if (!TEST_true(DH_check(dh, &i))) goto err2; i ^= DH_MODULUS_TOO_SMALL; if (!TEST_false(i & DH_CHECK_P_NOT_PRIME) @@ -124,6 +124,17 @@ static int dh_test(void) /* We'll have a stale error on the queue from the above test so clear it */ ERR_clear_error(); + /* Modulus of size: dh check max modulus bits + 1 */ + if (!TEST_true(BN_set_word(p, 1)) + || !TEST_true(BN_lshift(p, p, OPENSSL_DH_CHECK_MAX_MODULUS_BITS))) + goto err3; + + /* + * We expect no checks at all for an excessively large modulus + */ + if (!TEST_false(DH_check(dh, &i))) + goto err3; + /* * II) key generation */ @@ -138,7 +149,7 @@ static int dh_test(void) goto err3; /* ... and check whether it is valid */ - if (!DH_check(a, &i)) + if (!TEST_true(DH_check(a, &i))) goto err3; if (!TEST_false(i & DH_CHECK_P_NOT_PRIME) || !TEST_false(i & DH_CHECK_P_NOT_SAFE_PRIME)