From 246b05d1f3d4b4b5d131bf2fc345d1e894fc3f32 Mon Sep 17 00:00:00 2001 From: lanming1120 Date: Tue, 5 Dec 2023 19:53:02 +0800 Subject: [PATCH] Make DH_check_pub_key() and DH_generate_key() safer yet --- Cryptlib/Include/openssl/dh.h | 7 +++++-- Cryptlib/OpenSSL/crypto/dh/dh_check.c | 13 +++++++++++++ Cryptlib/OpenSSL/crypto/dh/dh_err.c | 2 ++ Cryptlib/OpenSSL/crypto/dh/dh_key.c | 12 ++++++++++++ 4 files changed, 32 insertions(+), 2 deletions(-) diff --git a/Cryptlib/Include/openssl/dh.h b/Cryptlib/Include/openssl/dh.h index 6488879..890f007 100644 --- a/Cryptlib/Include/openssl/dh.h +++ b/Cryptlib/Include/openssl/dh.h @@ -162,14 +162,15 @@ struct dh_st { /* #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 # define DH_NOT_SUITABLE_GENERATOR 0x08 # define DH_CHECK_Q_NOT_PRIME 0x10 -# define DH_CHECK_INVALID_Q_VALUE 0x20 +# define DH_CHECK_INVALID_Q_VALUE 0x20 /* +DH_check_pub_key */ # define DH_CHECK_INVALID_J_VALUE 0x40 +# define DH_MODULUS_TOO_LARGE 0x100 /* DH_check_pub_key error codes */ # define DH_CHECK_PUBKEY_TOO_SMALL 0x01 @@ -389,7 +390,9 @@ void ERR_load_DH_strings(void); # define DH_R_NO_PRIVATE_VALUE 100 # define DH_R_PARAMETER_ENCODING_ERROR 105 # define DH_R_PEER_KEY_ERROR 113 +# define DH_R_Q_TOO_LARGE 130 # define DH_R_SHARED_INFO_ERROR 114 +# define DH_F_DH_CHECK_PUB_KEY 128 #ifdef __cplusplus } diff --git a/Cryptlib/OpenSSL/crypto/dh/dh_check.c b/Cryptlib/OpenSSL/crypto/dh/dh_check.c index 9f3b174..30b2d6c 100644 --- a/Cryptlib/OpenSSL/crypto/dh/dh_check.c +++ b/Cryptlib/OpenSSL/crypto/dh/dh_check.c @@ -162,6 +162,19 @@ int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *ret) 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_PUB_KEY, 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 --git a/Cryptlib/OpenSSL/crypto/dh/dh_err.c b/Cryptlib/OpenSSL/crypto/dh/dh_err.c index b890cca..7615558 100644 --- a/Cryptlib/OpenSSL/crypto/dh/dh_err.c +++ b/Cryptlib/OpenSSL/crypto/dh/dh_err.c @@ -73,6 +73,7 @@ static ERR_STRING_DATA DH_str_functs[] = { {ERR_FUNC(DH_F_COMPUTE_KEY), "COMPUTE_KEY"}, {ERR_FUNC(DH_F_DHPARAMS_PRINT_FP), "DHparams_print_fp"}, {ERR_FUNC(DH_F_DH_BUILTIN_GENPARAMS), "DH_BUILTIN_GENPARAMS"}, + {ERR_FUNC(DH_F_DH_CHECK_PUB_KEY), "DH_check_pub_key"}, {ERR_FUNC(DH_F_DH_CMS_DECRYPT), "DH_CMS_DECRYPT"}, {ERR_FUNC(DH_F_DH_CMS_SET_PEERKEY), "DH_CMS_SET_PEERKEY"}, {ERR_FUNC(DH_F_DH_CMS_SET_SHARED_INFO), "DH_CMS_SET_SHARED_INFO"}, @@ -108,6 +109,7 @@ static ERR_STRING_DATA DH_str_reasons[] = { {ERR_REASON(DH_R_NO_PRIVATE_VALUE), "no private value"}, {ERR_REASON(DH_R_PARAMETER_ENCODING_ERROR), "parameter encoding error"}, {ERR_REASON(DH_R_PEER_KEY_ERROR), "peer key error"}, + {ERR_REASON(DH_R_Q_TOO_LARGE), "q too large"}, {ERR_REASON(DH_R_SHARED_INFO_ERROR), "shared info error"}, {0, NULL} }; diff --git a/Cryptlib/OpenSSL/crypto/dh/dh_key.c b/Cryptlib/OpenSSL/crypto/dh/dh_key.c index f235e0d..d66de13 100644 --- a/Cryptlib/OpenSSL/crypto/dh/dh_key.c +++ b/Cryptlib/OpenSSL/crypto/dh/dh_key.c @@ -134,6 +134,12 @@ static int generate_key(DH *dh) 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; @@ -218,6 +224,12 @@ static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) 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; -- 2.27.0