diff --git a/crypto/dh/build.info b/crypto/dh/build.info index 887ef78b0b..b413567271 100644 --- a/crypto/dh/build.info +++ b/crypto/dh/build.info @@ -5,7 +5,7 @@ $COMMON=dh_lib.c dh_key.c dh_group_params.c dh_check.c dh_backend.c dh_gen.c \ SOURCE[../../libcrypto]=$COMMON\ dh_asn1.c dh_err.c \ - dh_ameth.c dh_pmeth.c dh_prn.c dh_rfc5114.c dh_meth.c dh_ctrl.c + dh_ameth.c dh_pmeth.c dh_prn.c dh_rfc5114.c dh_meth.c IF[{- !$disabled{'deprecated-0.9.8'} -}] SOURCE[../../libcrypto]=dh_depr.c ENDIF 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,126 +21,33 @@ #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) -{ - int i; - - if (name == NULL) - return NULL; - - 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); + const DH_NAMED_GROUP *group; - return dh_new_by_group_name(libctx, name); + if ((group = ossl_ffc_uid_to_dh_named_group(nid)) != NULL) + return dh_param_init(libctx, group); + + ERR_raise(ERR_LIB_DH, DH_R_INVALID_PARAMETER_NID); + return NULL; } DH *DH_new_by_nid(int nid) @@ -148,33 +55,9 @@ 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++; } } diff --git a/crypto/evp/build.info b/crypto/evp/build.info index 652c3ee74a..8ee6e70c06 100644 --- a/crypto/evp/build.info +++ b/crypto/evp/build.info @@ -2,7 +2,7 @@ LIBS=../../libcrypto $COMMON=digest.c evp_enc.c evp_lib.c evp_fetch.c cmeth_lib.c evp_utils.c \ mac_lib.c mac_meth.c keymgmt_meth.c keymgmt_lib.c kdf_lib.c kdf_meth.c \ m_sigver.c pmeth_lib.c signature.c p_lib.c pmeth_gn.c exchange.c \ - pmeth_check.c evp_rand.c asymcipher.c kem.c + pmeth_check.c evp_rand.c asymcipher.c kem.c dh_support.c SOURCE[../../libcrypto]=$COMMON\ encode.c evp_key.c evp_cnf.c \ @@ -19,7 +19,7 @@ SOURCE[../../libcrypto]=$COMMON\ # Diverse type specific ctrl functions. They are kinda sorta legacy, kinda # sorta not. -SOURCE[../../libcrypto]=dsa_ctrl.c +SOURCE[../../libcrypto]=dh_ctrl.c dsa_ctrl.c IF[{- !$disabled{'deprecated-3.0'} -}] SOURCE[../../libcrypto]=p_enc.c p_dec.c diff --git a/crypto/dh/dh_ctrl.c b/crypto/evp/dh_ctrl.c similarity index 94% rename from crypto/dh/dh_ctrl.c rename to crypto/evp/dh_ctrl.c index 291b0ad419..64492389b7 100644 --- a/crypto/dh/dh_ctrl.c +++ b/crypto/evp/dh_ctrl.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020 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 @@ -7,22 +7,14 @@ * https://www.openssl.org/source/license.html */ -/* - * DH low level APIs are deprecated for public use, but still ok for - * internal use. - */ -#include "internal/deprecated.h" - #include -#include "crypto/evp.h" -#include -#include -#include +#include #include -#include "internal/cryptlib.h" -#include "internal/refcount.h" +#include +#include +#include #include "crypto/dh.h" -#include "dh_local.h" +#include "crypto/evp.h" static int dh_paramgen_check(EVP_PKEY_CTX *ctx) { @@ -179,7 +171,7 @@ int EVP_PKEY_CTX_set_dh_rfc5114(EVP_PKEY_CTX *ctx, int gen) if (ctx->op.keymgmt.genctx == NULL) return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_PARAMGEN, EVP_PKEY_CTRL_DH_RFC5114, gen, NULL); - name = ossl_ffc_named_group_from_uid(gen); + name = ossl_ffc_named_group_get_name(ossl_ffc_uid_to_dh_named_group(gen)); if (name == NULL) return 0; @@ -208,7 +200,7 @@ int EVP_PKEY_CTX_set_dh_nid(EVP_PKEY_CTX *ctx, int nid) return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN, EVP_PKEY_CTRL_DH_NID, nid, NULL); - name = ossl_ffc_named_group_from_uid(nid); + name = ossl_ffc_named_group_get_name(ossl_ffc_uid_to_dh_named_group(nid)); if (name == NULL) return 0; @@ -218,6 +210,28 @@ int EVP_PKEY_CTX_set_dh_nid(EVP_PKEY_CTX *ctx, int nid) return EVP_PKEY_CTX_set_params(ctx, params); } +int EVP_PKEY_CTX_set_dh_pad(EVP_PKEY_CTX *ctx, int pad) +{ + OSSL_PARAM dh_pad_params[2]; + unsigned int upad = pad; + + /* We use EVP_PKEY_CTX_ctrl return values */ + if (ctx == NULL || !EVP_PKEY_CTX_IS_DERIVE_OP(ctx)) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + return -2; + } + + /* TODO(3.0): Remove this eventually when no more legacy */ + if (ctx->op.kex.exchprovctx == NULL) + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_DH_PAD, pad, NULL); + + dh_pad_params[0] = OSSL_PARAM_construct_uint(OSSL_EXCHANGE_PARAM_PAD, &upad); + dh_pad_params[1] = OSSL_PARAM_construct_end(); + + return EVP_PKEY_CTX_set_params(ctx, dh_pad_params); +} + int EVP_PKEY_CTX_set_dh_kdf_type(EVP_PKEY_CTX *ctx, int kdf) { int ret; diff --git a/crypto/evp/dh_support.c b/crypto/evp/dh_support.c new file mode 100644 index 0000000000..212cf908eb --- /dev/null +++ b/crypto/evp/dh_support.c @@ -0,0 +1,48 @@ +/* + * Copyright 2020 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 + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include /* strcmp */ +#include +#include "internal/nelem.h" +#include "crypto/dh.h" + +typedef struct dh_name2id_st{ + const char *name; + int id; +} DH_GENTYPE_NAME2ID; + +static const DH_GENTYPE_NAME2ID dhtype2id[]= +{ + { "fips186_4", DH_PARAMGEN_TYPE_FIPS_186_4 }, + { "fips186_2", DH_PARAMGEN_TYPE_FIPS_186_2 }, + { "group", DH_PARAMGEN_TYPE_GROUP }, + { "generator", DH_PARAMGEN_TYPE_GENERATOR } +}; + +const char *dh_gen_type_id2name(int id) +{ + size_t i; + + for (i = 0; i < OSSL_NELEM(dhtype2id); ++i) { + if (dhtype2id[i].id == id) + return dhtype2id[i].name; + } + return NULL; +} + +int dh_gen_type_name2id(const char *name) +{ + size_t i; + + for (i = 0; i < OSSL_NELEM(dhtype2id); ++i) { + if (strcmp(dhtype2id[i].name, name) == 0) + return dhtype2id[i].id; + } + return -1; +} diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c index 6211019b62..434bd0b61b 100644 --- a/crypto/evp/p_lib.c +++ b/crypto/evp/p_lib.c @@ -1241,8 +1241,12 @@ int EVP_PKEY_get_group_name(const EVP_PKEY *pkey, char *gname, size_t gname_sz, DH *dh = EVP_PKEY_get0_DH(pkey); int uid = DH_get_nid(dh); - if (uid != NID_undef) - name = ossl_ffc_named_group_from_uid(uid); + if (uid != NID_undef) { + const DH_NAMED_GROUP *dh_group = + ossl_ffc_uid_to_dh_named_group(uid); + + name = ossl_ffc_named_group_get_name(dh_group); + } } break; #endif diff --git a/crypto/evp/pmeth_lib.c b/crypto/evp/pmeth_lib.c index 7364a148a6..58ca1d1d93 100644 --- a/crypto/evp/pmeth_lib.c +++ b/crypto/evp/pmeth_lib.c @@ -834,30 +834,6 @@ int evp_pkey_ctx_get_params_strict(EVP_PKEY_CTX *ctx, OSSL_PARAM *params) return EVP_PKEY_CTX_get_params(ctx, params); } -# ifndef OPENSSL_NO_DH -int EVP_PKEY_CTX_set_dh_pad(EVP_PKEY_CTX *ctx, int pad) -{ - OSSL_PARAM dh_pad_params[2]; - unsigned int upad = pad; - - /* We use EVP_PKEY_CTX_ctrl return values */ - if (ctx == NULL || !EVP_PKEY_CTX_IS_DERIVE_OP(ctx)) { - ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); - return -2; - } - - /* TODO(3.0): Remove this eventually when no more legacy */ - if (ctx->op.kex.exchprovctx == NULL) - return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_DERIVE, - EVP_PKEY_CTRL_DH_PAD, pad, NULL); - - dh_pad_params[0] = OSSL_PARAM_construct_uint(OSSL_EXCHANGE_PARAM_PAD, &upad); - dh_pad_params[1] = OSSL_PARAM_construct_end(); - - return EVP_PKEY_CTX_set_params(ctx, dh_pad_params); -} -# endif - int EVP_PKEY_CTX_get_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD **md) { OSSL_PARAM sig_md_params[2], *p = sig_md_params; @@ -1252,7 +1228,6 @@ static int legacy_ctrl_to_param(EVP_PKEY_CTX *ctx, int keytype, int optype, return evp_pkey_ctx_get1_id_len_prov(ctx, p2); } -# ifndef OPENSSL_NO_DH if (keytype == EVP_PKEY_DHX) { switch (cmd) { case EVP_PKEY_CTRL_DH_KDF_TYPE: @@ -1291,7 +1266,6 @@ static int legacy_ctrl_to_param(EVP_PKEY_CTX *ctx, int keytype, int optype, return EVP_PKEY_CTX_set_dh_rfc5114(ctx, p1); } } -# endif # ifndef OPENSSL_NO_DSA if (keytype == EVP_PKEY_DSA) { switch (cmd) { @@ -1579,7 +1553,6 @@ static int legacy_ctrl_str_to_param(EVP_PKEY_CTX *ctx, const char *name, else if (strcmp(name, "dsa_paramgen_md") == 0) name = OSSL_PKEY_PARAM_FFC_DIGEST; # endif -# ifndef OPENSSL_NO_DH else if (strcmp(name, "dh_paramgen_generator") == 0) name = OSSL_PKEY_PARAM_DH_GENERATOR; else if (strcmp(name, "dh_paramgen_prime_len") == 0) @@ -1592,11 +1565,13 @@ static int legacy_ctrl_str_to_param(EVP_PKEY_CTX *ctx, const char *name, } else if (strcmp(name, "dh_param") == 0) name = OSSL_PKEY_PARAM_GROUP_NAME; else if (strcmp(name, "dh_rfc5114") == 0) { + int num = atoi(value); + name = OSSL_PKEY_PARAM_GROUP_NAME; - value = ossl_ffc_named_group_from_uid(atoi(value)); + value = + ossl_ffc_named_group_get_name(ossl_ffc_uid_to_dh_named_group(num)); } else if (strcmp(name, "dh_pad") == 0) name = OSSL_EXCHANGE_PARAM_PAD; -# endif # ifndef OPENSSL_NO_EC else if (strcmp(name, "ec_paramgen_curve") == 0) name = OSSL_PKEY_PARAM_GROUP_NAME; diff --git a/crypto/ffc/build.info b/crypto/ffc/build.info index a04430d1d1..61cca17c5f 100644 --- a/crypto/ffc/build.info +++ b/crypto/ffc/build.info @@ -1,7 +1,8 @@ LIBS=../../libcrypto -$COMMON=ffc_params.c ffc_params_generate.c ffc_key_generate.c\ - ffc_params_validate.c ffc_key_validate.c ffc_backend.c +$COMMON=ffc_params.c ffc_params_generate.c ffc_key_generate.c \ + ffc_params_validate.c ffc_key_validate.c ffc_backend.c \ + ffc_dh.c SOURCE[../../libcrypto]=$COMMON SOURCE[../../providers/libfips.a]=$COMMON diff --git a/crypto/ffc/ffc_backend.c b/crypto/ffc/ffc_backend.c index fddd41557e..43825d9216 100644 --- a/crypto/ffc/ffc_backend.c +++ b/crypto/ffc/ffc_backend.c @@ -29,14 +29,16 @@ int ossl_ffc_params_fromdata(FFC_PARAMS *ffc, const OSSL_PARAM params[]) prm = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_GROUP_NAME); if (prm != NULL) { - if (prm->data_type != OSSL_PARAM_UTF8_STRING) - goto err; -#ifndef OPENSSL_NO_DH /* * In a no-dh build we just go straight to err because we have no * support for this. */ - if (!ossl_ffc_set_group_pqg(ffc, prm->data)) +#ifndef OPENSSL_NO_DH + const DH_NAMED_GROUP *group = NULL; + + if (prm->data_type != OSSL_PARAM_UTF8_STRING + || (group = ossl_ffc_name_to_dh_named_group(prm->data)) == NULL + || !ossl_ffc_named_group_set_pqg(ffc, group)) #endif goto err; } diff --git a/crypto/ffc/ffc_dh.c b/crypto/ffc/ffc_dh.c new file mode 100644 index 0000000000..313466b0ea --- /dev/null +++ b/crypto/ffc/ffc_dh.c @@ -0,0 +1,154 @@ +/* + * Copyright 2020 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 + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "internal/ffc.h" +#include "internal/nelem.h" +#include "crypto/bn_dh.h" +#include "e_os.h" /* strcasecmp */ + +#ifndef OPENSSL_NO_DH + +# 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 \ + } + +#else + +# define FFDHE(sz) { SN_ffdhe##sz, NID_ffdhe##sz } +# define MODP(sz) { SN_modp_##sz, NID_modp_##sz } +# define RFC5114(name, uid, sz, tag) { name, uid } + +#endif + +struct dh_named_group_st { + const char *name; + int uid; +#ifndef OPENSSL_NO_DH + int32_t nbits; + const BIGNUM *p; + const BIGNUM *q; + const BIGNUM *g; +#endif +}; + +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 +}; + +const DH_NAMED_GROUP *ossl_ffc_name_to_dh_named_group(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]; + } + return NULL; +} + +const DH_NAMED_GROUP *ossl_ffc_uid_to_dh_named_group(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]; + } + return NULL; +} + +#ifndef OPENSSL_NO_DH +const DH_NAMED_GROUP *ossl_ffc_numbers_to_dh_named_group(const BIGNUM *p, + const BIGNUM *q, + const BIGNUM *g) +{ + size_t i; + + for (i = 0; i < OSSL_NELEM(dh_named_groups); ++i) { + /* Keep searching until a matching p and g is found */ + if (BN_cmp(p, dh_named_groups[i].p) == 0 + && BN_cmp(g, dh_named_groups[i].g) == 0 + /* Verify q is correct if it exists */ + && (q == NULL || BN_cmp(q, dh_named_groups[i].q) == 0)) + return &dh_named_groups[i]; + } + return NULL; +} +#endif + +int ossl_ffc_named_group_get_uid(const DH_NAMED_GROUP *group) +{ + if (group == NULL) + return NID_undef; + return group->uid; +} + +const char *ossl_ffc_named_group_get_name(const DH_NAMED_GROUP *group) +{ + if (group == NULL) + return NULL; + return group->name; +} + +#ifndef OPENSSL_NO_DH +const BIGNUM *ossl_ffc_named_group_get_q(const DH_NAMED_GROUP *group) +{ + if (group == NULL) + return NULL; + return group->q; +} + +int ossl_ffc_named_group_set_pqg(FFC_PARAMS *ffc, const DH_NAMED_GROUP *group) +{ + if (ffc == NULL || group == NULL) + return 0; + + ossl_ffc_params_set0_pqg(ffc, (BIGNUM *)group->p, (BIGNUM *)group->q, + (BIGNUM *)group->g); + + /* flush the cached nid, The DH layer is responsible for caching */ + ffc->nid = NID_undef; + return 1; +} +#endif diff --git a/crypto/ffc/ffc_params.c b/crypto/ffc/ffc_params.c index edcb44b152..43064c0222 100644 --- a/crypto/ffc/ffc_params.c +++ b/crypto/ffc/ffc_params.c @@ -269,18 +269,14 @@ int ossl_ffc_params_todata(const FFC_PARAMS *ffc, OSSL_PARAM_BLD *bld, ffc->seed, ffc->seedlen)) return 0; if (ffc->nid != NID_undef) { -#ifndef OPENSSL_NO_DH - const char *name = ossl_ffc_named_group_from_uid(ffc->nid); + const DH_NAMED_GROUP *group = ossl_ffc_uid_to_dh_named_group(ffc->nid); + const char *name = ossl_ffc_named_group_get_name(group); if (name == NULL || !ossl_param_build_set_utf8_string(bld, params, OSSL_PKEY_PARAM_GROUP_NAME, name)) return 0; -#else - /* How could this be? We should not have a nid in a no-dh build. */ - return 0; -#endif } if (!ossl_param_build_set_utf8_string(bld, params, OSSL_PKEY_PARAM_FFC_VALIDATE_TYPE, diff --git a/include/crypto/dh.h b/include/crypto/dh.h index 0bd6516e3f..3afe16935f 100644 --- a/include/crypto/dh.h +++ b/include/crypto/dh.h @@ -21,6 +21,7 @@ int dh_generate_public_key(BN_CTX *ctx, const DH *dh, const BIGNUM *priv_key, BIGNUM *pub_key); int dh_get_named_group_uid_from_size(int pbits); const char *dh_gen_type_id2name(int id); +int dh_gen_type_name2id(const char *name); void dh_cache_named_group(DH *dh); FFC_PARAMS *dh_get0_params(DH *dh); diff --git a/include/internal/ffc.h b/include/internal/ffc.h index 3e5d98f8e1..191f9369f1 100644 --- a/include/internal/ffc.h +++ b/include/internal/ffc.h @@ -188,10 +188,22 @@ int ossl_ffc_validate_private_key(const BIGNUM *upper, const BIGNUM *priv_key, int ossl_ffc_params_todata(const FFC_PARAMS *ffc, OSSL_PARAM_BLD *tmpl, OSSL_PARAM params[]); int ossl_ffc_params_fromdata(FFC_PARAMS *ffc, const OSSL_PARAM params[]); -int ossl_ffc_set_group_pqg(FFC_PARAMS *ffc, const char *group_name); -int ossl_ffc_named_group_to_uid(const char *name); -const char *ossl_ffc_named_group_from_uid(int nid); -int ossl_ffc_set_group_pqg(FFC_PARAMS *ffc, const char *group_name); + +typedef struct dh_named_group_st DH_NAMED_GROUP; +const DH_NAMED_GROUP *ossl_ffc_name_to_dh_named_group(const char *name); +const DH_NAMED_GROUP *ossl_ffc_uid_to_dh_named_group(int uid); +#ifndef OPENSSL_NO_DH +const DH_NAMED_GROUP *ossl_ffc_numbers_to_dh_named_group(const BIGNUM *p, + const BIGNUM *q, + const BIGNUM *g); +#endif +int ossl_ffc_named_group_get_uid(const DH_NAMED_GROUP *group); +const char *ossl_ffc_named_group_get_name(const DH_NAMED_GROUP *); +#ifndef OPENSSL_NO_DH +const BIGNUM *ossl_ffc_named_group_get_q(const DH_NAMED_GROUP *group); +int ossl_ffc_named_group_set_pqg(FFC_PARAMS *ffc, const DH_NAMED_GROUP *group); +#endif + const char *ossl_ffc_params_flags_to_name(int flags); int ossl_ffc_params_flags_from_name(const char *name); diff --git a/include/openssl/dh.h b/include/openssl/dh.h index d06fea6a23..67ba0aa687 100644 --- a/include/openssl/dh.h +++ b/include/openssl/dh.h @@ -17,21 +17,74 @@ # endif # include +# include + +# ifdef __cplusplus +extern "C" { +# endif + +#include + +/* DH parameter generation types used by EVP_PKEY_CTX_set_dh_paramgen_type() */ +# define DH_PARAMGEN_TYPE_GENERATOR 0 /* Use a safe prime generator */ +# define DH_PARAMGEN_TYPE_FIPS_186_2 1 /* Use FIPS186-2 standard */ +# define DH_PARAMGEN_TYPE_FIPS_186_4 2 /* Use FIPS186-4 standard */ +# define DH_PARAMGEN_TYPE_GROUP 3 /* Use a named safe prime group */ + +int EVP_PKEY_CTX_set_dh_paramgen_type(EVP_PKEY_CTX *ctx, int typ); +int EVP_PKEY_CTX_set_dh_paramgen_gindex(EVP_PKEY_CTX *ctx, int gindex); +int EVP_PKEY_CTX_set_dh_paramgen_seed(EVP_PKEY_CTX *ctx, + const unsigned char *seed, + size_t seedlen); +int EVP_PKEY_CTX_set_dh_paramgen_prime_len(EVP_PKEY_CTX *ctx, int pbits); +int EVP_PKEY_CTX_set_dh_paramgen_subprime_len(EVP_PKEY_CTX *ctx, int qlen); +int EVP_PKEY_CTX_set_dh_paramgen_generator(EVP_PKEY_CTX *ctx, int gen); +int EVP_PKEY_CTX_set_dh_nid(EVP_PKEY_CTX *ctx, int nid); +int EVP_PKEY_CTX_set_dh_rfc5114(EVP_PKEY_CTX *ctx, int gen); +int EVP_PKEY_CTX_set_dhx_rfc5114(EVP_PKEY_CTX *ctx, int gen); +int EVP_PKEY_CTX_set_dh_pad(EVP_PKEY_CTX *ctx, int pad); + +int EVP_PKEY_CTX_set_dh_kdf_type(EVP_PKEY_CTX *ctx, int kdf); +int EVP_PKEY_CTX_get_dh_kdf_type(EVP_PKEY_CTX *ctx); +int EVP_PKEY_CTX_set0_dh_kdf_oid(EVP_PKEY_CTX *ctx, ASN1_OBJECT *oid); +int EVP_PKEY_CTX_get0_dh_kdf_oid(EVP_PKEY_CTX *ctx, ASN1_OBJECT **oid); +int EVP_PKEY_CTX_set_dh_kdf_md(EVP_PKEY_CTX *ctx, const EVP_MD *md); +int EVP_PKEY_CTX_get_dh_kdf_md(EVP_PKEY_CTX *ctx, const EVP_MD **md); +int EVP_PKEY_CTX_set_dh_kdf_outlen(EVP_PKEY_CTX *ctx, int len); +int EVP_PKEY_CTX_get_dh_kdf_outlen(EVP_PKEY_CTX *ctx, int *len); +int EVP_PKEY_CTX_set0_dh_kdf_ukm(EVP_PKEY_CTX *ctx, unsigned char *ukm, int len); +int EVP_PKEY_CTX_get0_dh_kdf_ukm(EVP_PKEY_CTX *ctx, unsigned char **ukm); + +# define EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN (EVP_PKEY_ALG_CTRL + 1) +# define EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR (EVP_PKEY_ALG_CTRL + 2) +# define EVP_PKEY_CTRL_DH_RFC5114 (EVP_PKEY_ALG_CTRL + 3) +# define EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN (EVP_PKEY_ALG_CTRL + 4) +# define EVP_PKEY_CTRL_DH_PARAMGEN_TYPE (EVP_PKEY_ALG_CTRL + 5) +# define EVP_PKEY_CTRL_DH_KDF_TYPE (EVP_PKEY_ALG_CTRL + 6) +# define EVP_PKEY_CTRL_DH_KDF_MD (EVP_PKEY_ALG_CTRL + 7) +# define EVP_PKEY_CTRL_GET_DH_KDF_MD (EVP_PKEY_ALG_CTRL + 8) +# define EVP_PKEY_CTRL_DH_KDF_OUTLEN (EVP_PKEY_ALG_CTRL + 9) +# define EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN (EVP_PKEY_ALG_CTRL + 10) +# define EVP_PKEY_CTRL_DH_KDF_UKM (EVP_PKEY_ALG_CTRL + 11) +# define EVP_PKEY_CTRL_GET_DH_KDF_UKM (EVP_PKEY_ALG_CTRL + 12) +# define EVP_PKEY_CTRL_DH_KDF_OID (EVP_PKEY_ALG_CTRL + 13) +# define EVP_PKEY_CTRL_GET_DH_KDF_OID (EVP_PKEY_ALG_CTRL + 14) +# define EVP_PKEY_CTRL_DH_NID (EVP_PKEY_ALG_CTRL + 15) +# define EVP_PKEY_CTRL_DH_PAD (EVP_PKEY_ALG_CTRL + 16) + +/* KDF types */ +# define EVP_PKEY_DH_KDF_NONE 1 +# define EVP_PKEY_DH_KDF_X9_42 2 # ifndef OPENSSL_NO_DH # include # include # include -# include # ifndef OPENSSL_NO_DEPRECATED_1_1_0 # include # endif # include -# ifdef __cplusplus -extern "C" { -# endif - # ifndef OPENSSL_DH_MAX_MODULUS_BITS # define OPENSSL_DH_MAX_MODULUS_BITS 10000 # endif @@ -107,12 +160,6 @@ DECLARE_ASN1_ITEM(DHparams) */ # define DH_CHECK_P_NOT_STRONG_PRIME DH_CHECK_P_NOT_SAFE_PRIME -/* DH parameter generation types used by EVP_PKEY_CTX_set_dh_paramgen_type() */ -# define DH_PARAMGEN_TYPE_GENERATOR 0 /* Use a safe prime generator */ -# define DH_PARAMGEN_TYPE_FIPS_186_2 1 /* Use FIPS186-2 standard */ -# define DH_PARAMGEN_TYPE_FIPS_186_4 2 /* Use FIPS186-4 standard */ -# define DH_PARAMGEN_TYPE_GROUP 3 /* Use a named safe prime group */ - # define d2i_DHparams_fp(fp, x) \ (DH *)ASN1_d2i_fp((char *(*)())DH_new, \ (char *(*)())d2i_DHparams, \ @@ -271,53 +318,8 @@ OSSL_DEPRECATEDIN_0_9_8 DH *DH_generate_parameters(int prime_len, int generator, void *cb_arg); # endif -int EVP_PKEY_CTX_set_dh_paramgen_type(EVP_PKEY_CTX *ctx, int typ); -int EVP_PKEY_CTX_set_dh_paramgen_gindex(EVP_PKEY_CTX *ctx, int gindex); -int EVP_PKEY_CTX_set_dh_paramgen_seed(EVP_PKEY_CTX *ctx, - const unsigned char *seed, - size_t seedlen); -int EVP_PKEY_CTX_set_dh_paramgen_prime_len(EVP_PKEY_CTX *ctx, int pbits); -int EVP_PKEY_CTX_set_dh_paramgen_subprime_len(EVP_PKEY_CTX *ctx, int qlen); -int EVP_PKEY_CTX_set_dh_paramgen_generator(EVP_PKEY_CTX *ctx, int gen); -int EVP_PKEY_CTX_set_dh_nid(EVP_PKEY_CTX *ctx, int nid); -int EVP_PKEY_CTX_set_dh_rfc5114(EVP_PKEY_CTX *ctx, int gen); -int EVP_PKEY_CTX_set_dhx_rfc5114(EVP_PKEY_CTX *ctx, int gen); -int EVP_PKEY_CTX_set_dh_pad(EVP_PKEY_CTX *ctx, int pad); - -int EVP_PKEY_CTX_set_dh_kdf_type(EVP_PKEY_CTX *ctx, int kdf); -int EVP_PKEY_CTX_get_dh_kdf_type(EVP_PKEY_CTX *ctx); -int EVP_PKEY_CTX_set0_dh_kdf_oid(EVP_PKEY_CTX *ctx, ASN1_OBJECT *oid); -int EVP_PKEY_CTX_get0_dh_kdf_oid(EVP_PKEY_CTX *ctx, ASN1_OBJECT **oid); -int EVP_PKEY_CTX_set_dh_kdf_md(EVP_PKEY_CTX *ctx, const EVP_MD *md); -int EVP_PKEY_CTX_get_dh_kdf_md(EVP_PKEY_CTX *ctx, const EVP_MD **md); -int EVP_PKEY_CTX_set_dh_kdf_outlen(EVP_PKEY_CTX *ctx, int len); -int EVP_PKEY_CTX_get_dh_kdf_outlen(EVP_PKEY_CTX *ctx, int *len); -int EVP_PKEY_CTX_set0_dh_kdf_ukm(EVP_PKEY_CTX *ctx, unsigned char *ukm, int len); -int EVP_PKEY_CTX_get0_dh_kdf_ukm(EVP_PKEY_CTX *ctx, unsigned char **ukm); - -# define EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN (EVP_PKEY_ALG_CTRL + 1) -# define EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR (EVP_PKEY_ALG_CTRL + 2) -# define EVP_PKEY_CTRL_DH_RFC5114 (EVP_PKEY_ALG_CTRL + 3) -# define EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN (EVP_PKEY_ALG_CTRL + 4) -# define EVP_PKEY_CTRL_DH_PARAMGEN_TYPE (EVP_PKEY_ALG_CTRL + 5) -# define EVP_PKEY_CTRL_DH_KDF_TYPE (EVP_PKEY_ALG_CTRL + 6) -# define EVP_PKEY_CTRL_DH_KDF_MD (EVP_PKEY_ALG_CTRL + 7) -# define EVP_PKEY_CTRL_GET_DH_KDF_MD (EVP_PKEY_ALG_CTRL + 8) -# define EVP_PKEY_CTRL_DH_KDF_OUTLEN (EVP_PKEY_ALG_CTRL + 9) -# define EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN (EVP_PKEY_ALG_CTRL + 10) -# define EVP_PKEY_CTRL_DH_KDF_UKM (EVP_PKEY_ALG_CTRL + 11) -# define EVP_PKEY_CTRL_GET_DH_KDF_UKM (EVP_PKEY_ALG_CTRL + 12) -# define EVP_PKEY_CTRL_DH_KDF_OID (EVP_PKEY_ALG_CTRL + 13) -# define EVP_PKEY_CTRL_GET_DH_KDF_OID (EVP_PKEY_ALG_CTRL + 14) -# define EVP_PKEY_CTRL_DH_NID (EVP_PKEY_ALG_CTRL + 15) -# define EVP_PKEY_CTRL_DH_PAD (EVP_PKEY_ALG_CTRL + 16) - -/* KDF types */ -# define EVP_PKEY_DH_KDF_NONE 1 -# define EVP_PKEY_DH_KDF_X9_42 2 - -# ifdef __cplusplus +# endif +# ifdef __cplusplus } -# endif # endif #endif diff --git a/providers/implementations/encode_decode/encode_key2text.c b/providers/implementations/encode_decode/encode_key2text.c index 2ac5046bf3..49bbf8c2af 100644 --- a/providers/implementations/encode_decode/encode_key2text.c +++ b/providers/implementations/encode_decode/encode_key2text.c @@ -159,7 +159,8 @@ static int ffc_params_to_text(BIO *out, const FFC_PARAMS *ffc) { if (ffc->nid != NID_undef) { #ifndef OPENSSL_NO_DH - const char *name = ossl_ffc_named_group_from_uid(ffc->nid); + const DH_NAMED_GROUP *group = ossl_ffc_uid_to_dh_named_group(ffc->nid); + const char *name = ossl_ffc_named_group_get_name(group); if (name == NULL) goto err; diff --git a/providers/implementations/keymgmt/dh_kmgmt.c b/providers/implementations/keymgmt/dh_kmgmt.c index dc0f3b2acd..1d674a14bf 100644 --- a/providers/implementations/keymgmt/dh_kmgmt.c +++ b/providers/implementations/keymgmt/dh_kmgmt.c @@ -23,7 +23,6 @@ #include "prov/provider_ctx.h" #include "crypto/dh.h" #include "internal/sizes.h" -#include "internal/nelem.h" static OSSL_FUNC_keymgmt_new_fn dh_newdata; static OSSL_FUNC_keymgmt_free_fn dh_freedata; @@ -76,34 +75,8 @@ struct dh_gen_ctx { int dh_type; }; -typedef struct dh_name2id_st{ - const char *name; - int id; -} DH_GENTYPE_NAME2ID; - -static const DH_GENTYPE_NAME2ID dhtype2id[]= +static int dh_gen_type_name2id_w_default(const char *name, int type) { - { "fips186_4", DH_PARAMGEN_TYPE_FIPS_186_4 }, - { "fips186_2", DH_PARAMGEN_TYPE_FIPS_186_2 }, - { "group", DH_PARAMGEN_TYPE_GROUP }, - { "generator", DH_PARAMGEN_TYPE_GENERATOR } -}; - -const char *dh_gen_type_id2name(int id) -{ - size_t i; - - for (i = 0; i < OSSL_NELEM(dhtype2id); ++i) { - if (dhtype2id[i].id == id) - return dhtype2id[i].name; - } - return NULL; -} - -static int dh_gen_type_name2id(const char *name, int type) -{ - size_t i; - if (strcmp(name, "default") == 0) { #ifdef FIPS_MODULE if (type == DH_FLAG_TYPE_DHX) @@ -118,11 +91,7 @@ static int dh_gen_type_name2id(const char *name, int type) #endif } - for (i = 0; i < OSSL_NELEM(dhtype2id); ++i) { - if (strcmp(dhtype2id[i].name, name) == 0) - return dhtype2id[i].id; - } - return -1; + return dh_gen_type_name2id(name); } static void *dh_newdata(void *provctx) @@ -506,16 +475,21 @@ static int dh_gen_set_params(void *genctx, const OSSL_PARAM params[]) p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_TYPE); if (p != NULL) { if (p->data_type != OSSL_PARAM_UTF8_STRING - || ((gctx->gen_type = dh_gen_type_name2id(p->data, - gctx->dh_type)) == -1)) { + || ((gctx->gen_type = + dh_gen_type_name2id_w_default(p->data, + gctx->dh_type)) == -1)) { ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_INVALID_ARGUMENT); return 0; } } p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_GROUP_NAME); if (p != NULL) { + const DH_NAMED_GROUP *group = NULL; + if (p->data_type != OSSL_PARAM_UTF8_STRING - || ((gctx->group_nid = ossl_ffc_named_group_to_uid(p->data)) == NID_undef)) { + || (group = ossl_ffc_name_to_dh_named_group(p->data)) == NULL + || ((gctx->group_nid = + ossl_ffc_named_group_get_uid(group)) == NID_undef)) { ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_INVALID_ARGUMENT); return 0; }