X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fdh%2Fdh_check.c;h=61be68bf64a2ad41c76b7650444317005abfd260;hp=6e1ea5349aaa967b95ec2ea04e3a1cb3644e9266;hb=HEAD;hpb=81d10e61a4b7d5394d08a718bf7d6bae20e818fc diff --git a/crypto/dh/dh_check.c b/crypto/dh/dh_check.c index 6e1ea5349a..ae23f61839 100644 --- a/crypto/dh/dh_check.c +++ b/crypto/dh/dh_check.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -143,7 +143,7 @@ int DH_check(const DH *dh, int *ret) #ifdef FIPS_MODULE return DH_check_params(dh, ret); #else - int ok = 0, r; + int ok = 0, r, q_good = 0; BN_CTX *ctx = NULL; BIGNUM *t1 = NULL, *t2 = NULL; int nid = DH_get_nid((DH *)dh); @@ -172,6 +172,13 @@ int DH_check(const DH *dh, int *ret) goto err; if (dh->params.q != NULL) { + if (BN_ucmp(dh->params.p, dh->params.q) > 0) + q_good = 1; + else + *ret |= DH_CHECK_INVALID_Q_VALUE; + } + + if (q_good) { if (BN_cmp(dh->params.g, BN_value_one()) <= 0) *ret |= DH_NOT_SUITABLE_GENERATOR; else if (BN_cmp(dh->params.g, dh->params.p) >= 0) @@ -242,6 +249,18 @@ int DH_check_pub_key_ex(const DH *dh, const BIGNUM *pub_key) */ int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *ret) { + /* 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); + *ret = DH_MODULUS_TOO_LARGE | DH_CHECK_PUBKEY_INVALID; + return 0; + } + + if (dh->params.q != NULL && BN_ucmp(dh->params.p, dh->params.q) < 0) { + *ret |= DH_CHECK_INVALID_Q_VALUE | DH_CHECK_PUBKEY_INVALID; + return 1; + } + return ossl_ffc_validate_public_key(&dh->params, pub_key, ret); } @@ -252,7 +271,8 @@ int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *ret) */ int ossl_dh_check_pub_key_partial(const DH *dh, const BIGNUM *pub_key, int *ret) { - return ossl_ffc_validate_public_key_partial(&dh->params, pub_key, ret); + return ossl_ffc_validate_public_key_partial(&dh->params, pub_key, ret) + && *ret == 0; } int ossl_dh_check_priv_key(const DH *dh, const BIGNUM *priv_key, int *ret) @@ -331,7 +351,7 @@ int ossl_dh_check_pairwise(const DH *dh) /* recalculate the public key = (g ^ priv) mod p */ if (!ossl_dh_generate_public_key(ctx, dh, dh->priv_key, pub_key)) goto err; - /* check it matches the existing pubic_key */ + /* check it matches the existing public_key */ ret = BN_cmp(pub_key, dh->pub_key) == 0; err: BN_free(pub_key);