diff -Naur a/crypto/dh/dh_check.c b/crypto/dh/dh_check.c --- a/crypto/dh/dh_check.c 2023-11-17 12:04:29.472015740 +0800 +++ b/crypto/dh/dh_check.c 2023-11-17 12:01:49.390161384 +0800 @@ -184,6 +184,19 @@ BN_CTX *ctx = NULL; *ret = 0; + + /* Don't do any checks at all with an excessively large modulus */ + if (BN_num_bits(dh->p) > OPENSSL_DH_CHECK_MAX_MODULUS_BITS) { + DHerr(DH_F_DH_CHECK_EX, DH_R_MODULUS_TOO_LARGE); + *ret = DH_MODULUS_TOO_LARGE | DH_CHECK_PUBKEY_INVALID; + return 0; + } + + if (dh->q != NULL && BN_ucmp(dh->p, dh->q) < 0) { + *ret |= DH_CHECK_INVALID_Q_VALUE | DH_CHECK_PUBKEY_INVALID; + return 1; + } + ctx = BN_CTX_new(); if (ctx == NULL) goto err; diff -Naur a/crypto/dh/dh_err.c b/crypto/dh/dh_err.c --- a/crypto/dh/dh_err.c 2023-11-17 12:04:29.472015740 +0800 +++ b/crypto/dh/dh_err.c 2023-11-17 12:01:49.390161384 +0800 @@ -81,6 +81,7 @@ {ERR_PACK(ERR_LIB_DH, 0, DH_R_PARAMETER_ENCODING_ERROR), "parameter encoding error"}, {ERR_PACK(ERR_LIB_DH, 0, DH_R_PEER_KEY_ERROR), "peer key error"}, + {ERR_PACK(ERR_LIB_DH, 0, DH_R_Q_TOO_LARGE), "q too large"}, {ERR_PACK(ERR_LIB_DH, 0, DH_R_SHARED_INFO_ERROR), "shared info error"}, {ERR_PACK(ERR_LIB_DH, 0, DH_R_UNABLE_TO_CHECK_GENERATOR), "unable to check generator"}, diff -Naur a/crypto/dh/dh_key.c b/crypto/dh/dh_key.c --- a/crypto/dh/dh_key.c 2023-11-17 12:04:29.472015740 +0800 +++ b/crypto/dh/dh_key.c 2023-11-17 12:01:49.390161384 +0800 @@ -109,6 +109,12 @@ BN_MONT_CTX *mont = NULL; BIGNUM *pub_key = NULL, *priv_key = NULL; + if (dh->q != NULL + && BN_num_bits(dh->q) > OPENSSL_DH_MAX_MODULUS_BITS) { + DHerr(DH_F_GENERATE_KEY, DH_R_Q_TOO_LARGE); + return 0; + } + if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS) { DHerr(DH_F_GENERATE_KEY, DH_R_MODULUS_TOO_LARGE); return 0; @@ -202,6 +208,12 @@ int ret = -1; int check_result; + if (dh->q != NULL + && BN_num_bits(dh->q) > OPENSSL_DH_MAX_MODULUS_BITS) { + DHerr(DH_F_COMPUTE_KEY, DH_R_Q_TOO_LARGE); + goto err; + } + if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS) { DHerr(DH_F_COMPUTE_KEY, DH_R_MODULUS_TOO_LARGE); goto err; diff -Naur a/crypto/err/openssl.txt b/crypto/err/openssl.txt --- a/crypto/err/openssl.txt 2023-11-17 12:04:29.480015831 +0800 +++ b/crypto/err/openssl.txt 2023-11-17 12:01:49.394161431 +0800 @@ -2103,6 +2103,7 @@ DH_R_NO_PRIVATE_VALUE:100:no private value DH_R_PARAMETER_ENCODING_ERROR:105:parameter encoding error DH_R_PEER_KEY_ERROR:111:peer key error +DH_R_Q_TOO_LARGE:130:q too large DH_R_SHARED_INFO_ERROR:113:shared info error DH_R_UNABLE_TO_CHECK_GENERATOR:121:unable to check generator DSA_R_BAD_Q_VALUE:102:bad q value diff -Naur a/include/openssl/dherr.h b/include/openssl/dherr.h --- a/include/openssl/dherr.h 2023-11-17 12:04:29.532016422 +0800 +++ b/include/openssl/dherr.h 2023-11-17 12:01:49.430161851 +0800 @@ -81,6 +81,7 @@ # define DH_R_NO_PRIVATE_VALUE 100 # define DH_R_PARAMETER_ENCODING_ERROR 105 # define DH_R_PEER_KEY_ERROR 111 +# define DH_R_Q_TOO_LARGE 130 # define DH_R_SHARED_INFO_ERROR 113 # define DH_R_UNABLE_TO_CHECK_GENERATOR 121 diff -Naur a/include/openssl/dh.h b/include/openssl/dh.h --- a/include/openssl/dh.h 2023-11-17 12:04:29.532016422 +0800 +++ b/include/openssl/dh.h 2023-11-17 12:01:49.430161851 +0800 @@ -68,7 +68,7 @@ /* #define DH_GENERATOR_3 3 */ # define DH_GENERATOR_5 5 -/* DH_check error codes */ +/* DH_check error codes, some of them shared with DH_check_pub_key */ # define DH_CHECK_P_NOT_PRIME 0x01 # define DH_CHECK_P_NOT_SAFE_PRIME 0x02 # define DH_UNABLE_TO_CHECK_GENERATOR 0x04 @@ -80,7 +80,9 @@ /* DH_check_pub_key error codes */ # define DH_CHECK_PUBKEY_TOO_SMALL 0x01 # define DH_CHECK_PUBKEY_TOO_LARGE 0x02 +# define DH_CHECK_INVALID_Q_VALUE 0x20 /* +DH_check_pub_key */ # define DH_CHECK_PUBKEY_INVALID 0x04 +# define DH_MODULUS_TOO_LARGE 0x100 /* +DH_check_pub_key */ /* * primes p where (p-1)/2 is prime too are called "safe"; we define this for