From c829c23b67308ad8e8ab677c78db1d5151106c3c Mon Sep 17 00:00:00 2001 From: Richard Levitte Date: Tue, 1 Dec 2020 19:11:59 +0100 Subject: EVP_PKEY & DH: Make DH EVP_PKEY_CTX parameter ctrls / setters more available EVP_PKEY_CTX_set_dh_ functions were only available when DH was enabled ('no-dsa' not configured). However, that makes it impossible to use these functions with an engine or a provider that happens to implement DH. This change solves that problem by shuffling these functions to more appropriate places. By consequence, there are a number of places where we can remove the check of OPENSSL_NO_DH. This requires some re-arrangements of internal tables to translate between numeric identities and names. Partially fixes #13550 Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/13589) --- crypto/dh/dh_group_params.c | 162 ++++++-------------------------------------- 1 file changed, 19 insertions(+), 143 deletions(-) (limited to 'crypto/dh/dh_group_params.c') diff --git a/crypto/dh/dh_group_params.c b/crypto/dh/dh_group_params.c index e03693f687..a752cf9a98 100644 --- a/crypto/dh/dh_group_params.c +++ b/crypto/dh/dh_group_params.c @@ -21,160 +21,43 @@ #include "dh_local.h" #include #include -#include "crypto/bn_dh.h" +#include "internal/nelem.h" #include "crypto/dh.h" #include "e_os.h" /* strcasecmp */ -#define FFDHE(sz) { \ - SN_ffdhe##sz, NID_ffdhe##sz, \ - sz, \ - &_bignum_ffdhe##sz##_p, &_bignum_ffdhe##sz##_q, &_bignum_const_2 \ -} - -#define MODP(sz) { \ - SN_modp_##sz, NID_modp_##sz, \ - sz, \ - &_bignum_modp_##sz##_p, &_bignum_modp_##sz##_q, &_bignum_const_2 \ -} - -#define RFC5114(name, uid, sz, tag) { \ - name, uid, \ - sz, \ - &_bignum_dh##tag##_p, &_bignum_dh##tag##_q, &_bignum_dh##tag##_g \ -} - -typedef struct dh_named_group_st { - const char *name; - int uid; - int32_t nbits; - const BIGNUM *p; - const BIGNUM *q; - const BIGNUM *g; -} DH_NAMED_GROUP; - - -static const DH_NAMED_GROUP dh_named_groups[] = { - FFDHE(2048), - FFDHE(3072), - FFDHE(4096), - FFDHE(6144), - FFDHE(8192), -#ifndef FIPS_MODULE - MODP(1536), -#endif - MODP(2048), - MODP(3072), - MODP(4096), - MODP(6144), - MODP(8192), - /* - * Additional dh named groups from RFC 5114 that have a different g. - * The uid can be any unique identifier. - */ -#ifndef FIPS_MODULE - RFC5114("dh_1024_160", 1, 1024, 1024_160), - RFC5114("dh_2048_224", 2, 2048, 2048_224), - RFC5114("dh_2048_256", 3, 2048, 2048_256), -#endif -}; - -int ossl_ffc_named_group_to_uid(const char *name) -{ - size_t i; - - for (i = 0; i < OSSL_NELEM(dh_named_groups); ++i) { - if (strcasecmp(dh_named_groups[i].name, name) == 0) - return dh_named_groups[i].uid; - } - return NID_undef; -} - -const char *ossl_ffc_named_group_from_uid(int uid) -{ - size_t i; - - for (i = 0; i < OSSL_NELEM(dh_named_groups); ++i) { - if (dh_named_groups[i].uid == uid) - return dh_named_groups[i].name; - } - return NULL; -} - -static DH *dh_param_init(OSSL_LIB_CTX *libctx, int uid, const BIGNUM *p, - const BIGNUM *q, const BIGNUM *g) +static DH *dh_param_init(OSSL_LIB_CTX *libctx, const DH_NAMED_GROUP *group) { DH *dh = dh_new_ex(libctx); if (dh == NULL) return NULL; - dh->params.nid = uid; - dh->params.p = (BIGNUM *)p; - dh->params.q = (BIGNUM *)q; - dh->params.g = (BIGNUM *)g; - dh->length = BN_num_bits(q); + ossl_ffc_named_group_set_pqg(&dh->params, group); + dh->params.nid = ossl_ffc_named_group_get_uid(group); + dh->length = BN_num_bits(dh->params.q); dh->dirty_cnt++; return dh; } -static DH *dh_new_by_group_name(OSSL_LIB_CTX *libctx, const char *name) +DH *dh_new_by_nid_ex(OSSL_LIB_CTX *libctx, int nid) { - int i; + const DH_NAMED_GROUP *group; - if (name == NULL) - return NULL; + if ((group = ossl_ffc_uid_to_dh_named_group(nid)) != NULL) + return dh_param_init(libctx, group); - for (i = 0; i < (int)OSSL_NELEM(dh_named_groups); ++i) { - if (strcasecmp(dh_named_groups[i].name, name) == 0) { - return dh_param_init(libctx, dh_named_groups[i].uid, - dh_named_groups[i].p, - dh_named_groups[i].q, - dh_named_groups[i].g); - } - } ERR_raise(ERR_LIB_DH, DH_R_INVALID_PARAMETER_NID); return NULL; } -DH *dh_new_by_nid_ex(OSSL_LIB_CTX *libctx, int nid) -{ - const char *name = ossl_ffc_named_group_from_uid(nid); - - return dh_new_by_group_name(libctx, name); -} - DH *DH_new_by_nid(int nid) { return dh_new_by_nid_ex(NULL, nid); } -int ossl_ffc_set_group_pqg(FFC_PARAMS *ffc, const char *group_name) -{ - int i; - BIGNUM *q = NULL; - - if (ffc == NULL) - return 0; - - for (i = 0; i < (int)OSSL_NELEM(dh_named_groups); ++i) { - if (strcasecmp(dh_named_groups[i].name, group_name) == 0) { - ossl_ffc_params_set0_pqg(ffc, - (BIGNUM *)dh_named_groups[i].p, - (BIGNUM *)dh_named_groups[i].q, - (BIGNUM *)dh_named_groups[i].g); - /* flush the cached nid, The DH layer is responsible for caching */ - ffc->nid = NID_undef; - return 1; - } - } - /* gets here on error or if the name was not found */ - BN_free(q); - return 0; -} - void dh_cache_named_group(DH *dh) { - int i; + const DH_NAMED_GROUP *group; if (dh == NULL) return; @@ -186,22 +69,15 @@ void dh_cache_named_group(DH *dh) || dh->params.g == NULL) return; - for (i = 0; i < (int)OSSL_NELEM(dh_named_groups); ++i) { - /* Keep searching until a matching p and g is found */ - if (BN_cmp(dh->params.p, dh_named_groups[i].p) == 0 - && BN_cmp(dh->params.g, dh_named_groups[i].g) == 0) { - /* Verify q is correct if it exists */ - if (dh->params.q != NULL) { - if (BN_cmp(dh->params.q, dh_named_groups[i].q) != 0) - continue; /* ignore if q does not match */ - } else { - dh->params.q = (BIGNUM *)dh_named_groups[i].q; - } - dh->params.nid = dh_named_groups[i].uid; /* cache the nid */ - dh->length = BN_num_bits(dh->params.q); - dh->dirty_cnt++; - break; - } + if ((group = ossl_ffc_numbers_to_dh_named_group(dh->params.p, + dh->params.q, + dh->params.g)) != NULL) { + if (dh->params.q == NULL) + dh->params.q = (BIGNUM *)ossl_ffc_named_group_get_q(group); + /* cache the nid */ + dh->params.nid = ossl_ffc_named_group_get_uid(group); + dh->length = BN_num_bits(dh->params.q); + dh->dirty_cnt++; } } -- cgit v1.2.3