diff options
author | Shane Lontis <shane.lontis@oracle.com> | 2020-04-16 01:14:00 +1000 |
---|---|---|
committer | Shane Lontis <shane.lontis@oracle.com> | 2020-04-16 01:14:00 +1000 |
commit | 7165593ce5a07a6860d4d408ad640ee707172936 (patch) | |
tree | 3c892cf83045856b44bfaaeea2b67a9f0527e853 | |
parent | b03ec3b5d62ee26bf8437556b9040d4141d5bdd8 (diff) |
Add DH keygen to providers
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/11332)
26 files changed, 1268 insertions, 247 deletions
diff --git a/crypto/dh/build.info b/crypto/dh/build.info index ce0918e7d3..f4498f4d2b 100644 --- a/crypto/dh/build.info +++ b/crypto/dh/build.info @@ -1,9 +1,9 @@ LIBS=../../libcrypto -$COMMON=dh_lib.c dh_key.c dh_group_params.c dh_check.c dh_backend.c +$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_gen.c dh_err.c dh_depr.c \ + dh_asn1.c dh_err.c dh_depr.c \ dh_ameth.c dh_pmeth.c dh_prn.c dh_rfc5114.c dh_kdf.c dh_meth.c SOURCE[../../providers/libfips.a]=$COMMON diff --git a/crypto/dh/dh_backend.c b/crypto/dh/dh_backend.c index bbeb096d55..704f6efac1 100644 --- a/crypto/dh/dh_backend.c +++ b/crypto/dh/dh_backend.c @@ -24,10 +24,8 @@ int dh_key_fromdata(DH *dh, const OSSL_PARAM params[]) if (dh == NULL) return 0; - param_priv_key = - OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PRIV_KEY); - param_pub_key = - OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PUB_KEY); + param_priv_key = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PRIV_KEY); + param_pub_key = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PUB_KEY); /* * DH documentation says that a public key must be present if a diff --git a/crypto/dh/dh_gen.c b/crypto/dh/dh_gen.c index f8cda1b7e9..39bb365216 100644 --- a/crypto/dh/dh_gen.c +++ b/crypto/dh/dh_gen.c @@ -26,6 +26,7 @@ #include <stdio.h> #include "internal/cryptlib.h" #include <openssl/bn.h> +#include <openssl/sha.h> #include "crypto/dh.h" #include "dh_local.h" @@ -34,47 +35,45 @@ static int dh_builtin_genparams(DH *ret, int prime_len, int generator, BN_GENCB *cb); #endif /* FIPS_MODE */ -/* - * TODO(3.0): keygen should be able to use this method to do a FIPS186-4 style - * paramgen. - */ -int dh_generate_ffc_parameters(DH *dh, int bits, - int qbits, int gindex, BN_GENCB *cb) +int dh_generate_ffc_parameters(DH *dh, int type, int pbits, + int qbits, EVP_MD *md, BN_GENCB *cb) { int ret, res; if (qbits <= 0) { - const EVP_MD *evpmd = bits >= 2048 ? EVP_sha256() : EVP_sha1(); - - qbits = EVP_MD_size(evpmd) * 8; + if (md != NULL) + qbits = EVP_MD_size(md) * 8; + else + qbits = (pbits >= 2048 ? SHA256_DIGEST_LENGTH : + SHA_DIGEST_LENGTH) * 8; } - dh->params.gindex = gindex; - ret = ffc_params_FIPS186_4_generate(dh->libctx, &dh->params, - FFC_PARAM_TYPE_DH, - bits, qbits, NULL, &res, cb); +#ifndef FIPS_MODE + if (type == DH_PARAMGEN_TYPE_FIPS_186_2) + ret = ffc_params_FIPS186_2_generate(dh->libctx, &dh->params, + FFC_PARAM_TYPE_DH, + pbits, qbits, md, &res, cb); + else +#endif + ret = ffc_params_FIPS186_4_generate(dh->libctx, &dh->params, + FFC_PARAM_TYPE_DH, + pbits, qbits, md, &res, cb); if (ret > 0) dh->dirty_cnt++; return ret; } -int DH_generate_parameters_ex(DH *ret, int prime_len, int generator, - BN_GENCB *cb) +int dh_get_named_group_uid_from_size(int pbits) { -#ifdef FIPS_MODE /* * Just choose an approved safe prime group. * The alternative to this is to generate FIPS186-4 domain parameters i.e. - * return dh_generate_ffc_parameters(ret, prime_len, -1, -1, cb); + * return dh_generate_ffc_parameters(ret, prime_len, 0, NULL, cb); * As the FIPS186-4 generated params are for backwards compatability, * the safe prime group should be used as the default. */ - DH *dh = NULL; - int ok = 0, nid; + int nid; - if (generator != 2) - return 0; - - switch (prime_len) { + switch (pbits) { case 2048: nid = NID_ffdhe2048; break; @@ -92,15 +91,40 @@ int DH_generate_parameters_ex(DH *ret, int prime_len, int generator, break; /* unsupported prime_len */ default: - return 0; + return NID_undef; } - dh = DH_new_by_nid(nid); - if (dh != NULL && ffc_params_copy(&ret->params, &dh->params)) { + return nid; +} + +#ifdef FIPS_MODE + +static int dh_gen_named_group(OPENSSL_CTX *libctx, DH *ret, int prime_len) +{ + DH *dh; + int ok = 0; + int nid = dh_get_named_group_uid_from_size(prime_len); + + if (nid == NID_undef) + return 0; + + dh = dh_new_by_nid_with_libctx(libctx, nid); + if (dh != NULL + && ffc_params_copy(&ret->params, &dh->params)) { ok = 1; ret->dirty_cnt++; } DH_free(dh); return ok; +} +#endif /* FIPS_MODE */ + +int DH_generate_parameters_ex(DH *ret, int prime_len, int generator, + BN_GENCB *cb) +{ +#ifdef FIPS_MODE + if (generator != 2) + return 0; + return dh_gen_named_group(ret->libctx, ret, prime_len); #else if (ret->meth->generate_params) return ret->meth->generate_params(ret, prime_len, generator, cb); diff --git a/crypto/dh/dh_group_params.c b/crypto/dh/dh_group_params.c index cc1c546655..1f5a58ed87 100644 --- a/crypto/dh/dh_group_params.c +++ b/crypto/dh/dh_group_params.c @@ -17,6 +17,7 @@ #include <stdio.h> #include "internal/cryptlib.h" +#include "internal/ffc.h" #include "dh_local.h" #include <openssl/bn.h> #include <openssl/objects.h> @@ -25,18 +26,35 @@ #include "crypto/security_bits.h" #include "e_os.h" /* strcasecmp */ +#define FFDHE(sz) { \ + SN_ffdhe##sz, NID_ffdhe##sz, \ + sz, \ + &_bignum_ffdhe##sz##_p, NULL, &_bignum_const_2 \ +} + +#define MODP(sz) { \ + SN_modp_##sz, NID_modp_##sz, \ + sz, \ + &_bignum_modp_##sz##_p, NULL, &_bignum_const_2 \ +} -#define FFDHE(sz) { SN_ffdhe##sz, NID_ffdhe##sz, sz, &_bignum_ffdhe##sz##_p } -#define MODP(sz) { SN_modp_##sz, NID_modp_##sz, sz, &_bignum_modp_##sz##_p } +#define RFC5114(name, uid, sz, tag) { \ + name, uid, \ + sz, \ + &_bignum_dh##tag##_p, &_bignum_dh##tag##_q, &_bignum_dh##tag##_g \ +} -typedef struct safe_prime_group_st { +typedef struct dh_named_group_st { const char *name; - int nid; + int uid; int32_t nbits; const BIGNUM *p; -} SP_GROUP; + const BIGNUM *q; + const BIGNUM *g; +} DH_NAMED_GROUP; + -static const SP_GROUP sp_groups[] = { +static const DH_NAMED_GROUP dh_named_groups[] = { FFDHE(2048), FFDHE(3072), FFDHE(4096), @@ -50,74 +68,89 @@ static const SP_GROUP sp_groups[] = { 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_MODE + 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 ffc_named_group_to_nid(const char *name) +int ffc_named_group_to_uid(const char *name) { size_t i; - for (i = 0; i < OSSL_NELEM(sp_groups); ++i) { - if (strcasecmp(sp_groups[i].name, name) == 0) - return sp_groups[i].nid; + 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 *ffc_named_group_from_nid(int nid) +const char *ffc_named_group_from_uid(int uid) { size_t i; - for (i = 0; i < OSSL_NELEM(sp_groups); ++i) { - if (sp_groups[i].nid == nid) - return sp_groups[i].name; + 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; } -#ifndef FIPS_MODE -static DH *dh_new_by_nid_with_ctx(OPENSSL_CTX *libctx, int nid); - -static DH *dh_param_init(OPENSSL_CTX *libctx, int nid, const BIGNUM *p, +static DH *dh_param_init(OPENSSL_CTX *libctx, int uid, const BIGNUM *p, + const BIGNUM *q, const BIGNUM *g, int32_t nbits) { - BIGNUM *q = NULL; - DH *dh = dh_new_with_ctx(libctx); + BIGNUM *qtmp = NULL; + DH *dh = dh_new_with_libctx(libctx); if (dh == NULL) return NULL; - q = BN_dup(p); - /* Set q = (p - 1) / 2 (p is known to be odd so just shift right ) */ - if (q == NULL || !BN_rshift1(q, q)) { - BN_free(q); - DH_free(dh); - return NULL; + if (q == NULL) { + qtmp = BN_dup(p); + /* Set q = (p - 1) / 2 (p is known to be odd so just shift right ) */ + if (qtmp == NULL || !BN_rshift1(qtmp, qtmp)) { + BN_free(qtmp); + DH_free(dh); + return NULL; + } } - dh->params.nid = nid; + dh->params.nid = uid; dh->params.p = (BIGNUM *)p; - dh->params.q = (BIGNUM *)q; - dh->params.g = (BIGNUM *)&_bignum_const_2; + dh->params.q = (q != NULL ? (BIGNUM *)q : qtmp); + dh->params.g = (BIGNUM *)g; /* Private key length = 2 * max_target_security_strength */ dh->length = nbits; dh->dirty_cnt++; return dh; } -static DH *dh_new_by_nid_with_ctx(OPENSSL_CTX *libctx, int nid) +static DH *dh_new_by_group_name(OPENSSL_CTX *libctx, const char *name) { int i; - for (i = 0; i < (int)OSSL_NELEM(sp_groups); ++i) { - if (sp_groups[i].nid == nid) { + 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) { int max_target_security_strength = - ifc_ffc_compute_security_bits(sp_groups[i].nbits); + ifc_ffc_compute_security_bits(dh_named_groups[i].nbits); /* * The last parameter specified here is * 2 * max_target_security_strength. * See SP800-56Ar3 Table(s) 25 & 26. */ - return dh_param_init(libctx, nid, sp_groups[i].p, + 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, 2 * max_target_security_strength); } } @@ -125,11 +158,54 @@ static DH *dh_new_by_nid_with_ctx(OPENSSL_CTX *libctx, int nid) return NULL; } +DH *dh_new_by_nid_with_libctx(OPENSSL_CTX *libctx, int nid) +{ + const char *name = 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_with_ctx(NULL, nid); + return dh_new_by_nid_with_libctx(NULL, nid); +} + +int 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) { + if (dh_named_groups[i].q != NULL) { + /* For groups with a q */ + ffc_params_set0_pqg(ffc, + (BIGNUM *)dh_named_groups[i].p, + (BIGNUM *)dh_named_groups[i].q, + (BIGNUM *)dh_named_groups[i].g); + } else { + /* For SAFE PRIME GROUPS */ + /* Set q = (p - 1) / 2 (p is known to be odd so just shift right) */ + q = BN_dup(dh_named_groups[i].p); + if (q == NULL || !BN_rshift1(q, q)) + break; /* exit with failure */ + + ffc_params_set0_pqg(ffc, + (BIGNUM *)dh_named_groups[i].p, 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; } -#endif int DH_get_nid(DH *dh) { @@ -144,13 +220,28 @@ int DH_get_nid(DH *dh) if (nid != NID_undef) return nid; - if (BN_get_word(dh->params.g) != 2) - return NID_undef; + for (i = 0; i < (int)OSSL_NELEM(dh_named_groups); ++i) { + /* Keep searching until a matching p is found */ + if (BN_cmp(dh->params.p, dh_named_groups[i].p) != 0) + continue; + + /* Return an error if g is not matching */ + if (BN_cmp(dh->params.g, dh_named_groups[i].g) != 0) + break; + if (dh_named_groups[i].q != NULL) { + /* RFC5114 NAMED GROUPS have q defined */ + + /* Verify q is correct if it exists */ + if (dh->params.q != NULL) { + if (BN_cmp(dh->params.q, dh_named_groups[i].q) != 0) + break; /* returns nid = NID_undef if q does not match */ + } else { + dh->params.q = (BIGNUM *)dh_named_groups[i].q; + } + } else { + /* For SAFE PRIME GROUPS */ - for (i = 0; i < (int)OSSL_NELEM(sp_groups); ++i) { - /* If a matching p is found then we will break out of the loop */ - if (!BN_cmp(dh->params.p, sp_groups[i].p)) { - /* Set q = (p - 1) / 2 (p is known to be odd so just shift right ) */ + /* Set q = (p - 1) / 2 (p is known to be odd so just shift right) */ q = BN_dup(dh->params.p); if (q == NULL || !BN_rshift1(q, q)) @@ -165,11 +256,13 @@ int DH_get_nid(DH *dh) dh->params.q = q; q = NULL; /* set to NULL so it is not freed */ } - dh->params.nid = sp_groups[i].nid; /* cache the nid */ - dh->length = 2 * ifc_ffc_compute_security_bits(sp_groups[i].nbits); - dh->dirty_cnt++; - break; } + nid = dh->params.nid = dh_named_groups[i].uid; /* cache the nid */ + dh->length = + 2 * ifc_ffc_compute_security_bits(dh_named_groups[i].nbits); + dh->dirty_cnt++; + /* A matching p was found so break out of the loop */ + break; } BN_free(q); return nid; diff --git a/crypto/dh/dh_lib.c b/crypto/dh/dh_lib.c index 093695c637..3643cb1471 100644 --- a/crypto/dh/dh_lib.c +++ b/crypto/dh/dh_lib.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-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 @@ -17,8 +17,10 @@ #include <openssl/bn.h> #include <openssl/engine.h> #include <openssl/obj_mac.h> +#include <openssl/core_names.h> #include "internal/cryptlib.h" #include "internal/refcount.h" +#include "crypto/evp.h" #include "crypto/dh.h" #include "dh_local.h" @@ -61,7 +63,7 @@ DH *DH_new_method(ENGINE *engine) } #endif /* !FIPS_MODE */ -DH *dh_new_with_ctx(OPENSSL_CTX *libctx) +DH *dh_new_with_libctx(OPENSSL_CTX *libctx) { return dh_new_intern(NULL, libctx); } @@ -319,3 +321,214 @@ int dh_get0_nid(const DH *dh) { return dh->params.nid; } + +int dh_ffc_params_fromdata(DH *dh, const OSSL_PARAM params[]) +{ + int ret; + FFC_PARAMS *ffc; + + if (dh == NULL) + return 0; + ffc = dh_get0_params(dh); + if (ffc == NULL) + return 0; + + ret = ffc_params_fromdata(ffc, params); + if (ret) { + DH_get_nid(dh); + dh->dirty_cnt++; + } + return ret; +} + +static int dh_paramgen_check(EVP_PKEY_CTX *ctx) +{ + if (ctx == NULL || !EVP_PKEY_CTX_IS_GEN_OP(ctx)) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + /* Uses the same return values as EVP_PKEY_CTX_ctrl */ + return -2; + } + /* If key type not DH return error */ + if (ctx->pmeth != NULL + && ctx->pmeth->pkey_id != EVP_PKEY_DH + && ctx->pmeth->pkey_id != EVP_PKEY_DHX) + return -1; + return 1; +} + +int EVP_PKEY_CTX_set_dh_paramgen_gindex(EVP_PKEY_CTX *ctx, int gindex) +{ + int ret; + OSSL_PARAM params[2], *p = params; + + if ((ret = dh_paramgen_check(ctx)) <= 0) + return ret; + + *p++ = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_FFC_GINDEX, &gindex); + *p++ = OSSL_PARAM_construct_end(); + + return EVP_PKEY_CTX_set_params(ctx, params); +} + +int EVP_PKEY_CTX_set_dh_paramgen_seed(EVP_PKEY_CTX *ctx, + const unsigned char *seed, + size_t seedlen) +{ + int ret; + OSSL_PARAM params[2], *p = params; + + if ((ret = dh_paramgen_check(ctx)) <= 0) + return ret; + + *p++ = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_FFC_SEED, + (void *)seed, seedlen); + *p++ = OSSL_PARAM_construct_end(); + + return EVP_PKEY_CTX_set_params(ctx, params); +} + +int EVP_PKEY_CTX_set_dh_paramgen_type(EVP_PKEY_CTX *ctx, int typ) +{ + int ret; + OSSL_PARAM params[2], *p = params; + const char *name; + + if ((ret = dh_paramgen_check(ctx)) <= 0) + return ret; + +#if !defined(FIPS_MODE) + /* TODO(3.0): Remove this eventually when no more legacy */ + if (ctx->op.keymgmt.genctx == NULL) + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, + EVP_PKEY_CTRL_DH_PARAMGEN_TYPE, typ, NULL); +#endif + + name = dh_gen_type_id2name(typ); + if (name == NULL) + return 0; + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_FFC_TYPE, + (char *) name, 0); + *p++ = OSSL_PARAM_construct_end(); + + return EVP_PKEY_CTX_set_params(ctx, params); +} + +int EVP_PKEY_CTX_set_dh_paramgen_prime_len(EVP_PKEY_CTX *ctx, int pbits) +{ + int ret; + OSSL_PARAM params[2], *p = params; + size_t bits = pbits; + + if ((ret = dh_paramgen_check(ctx)) <= 0) + return ret; + +#if !defined(FIPS_MODE) + /* TODO(3.0): Remove this eventually when no more legacy */ + if (ctx->op.keymgmt.genctx == NULL) + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, + EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN, pbits, + NULL); +#endif + *p++ = OSSL_PARAM_construct_size_t(OSSL_PKEY_PARAM_FFC_PBITS, &bits); + *p++ = OSSL_PARAM_construct_end(); + return EVP_PKEY_CTX_set_params(ctx, params); +} + +int EVP_PKEY_CTX_set_dh_paramgen_subprime_len(EVP_PKEY_CTX *ctx, int qbits) +{ + int ret; + OSSL_PARAM params[2], *p = params; + size_t bits2 = qbits; + + if ((ret = dh_paramgen_check(ctx)) <= 0) + return ret; + +#if !defined(FIPS_MODE) + /* TODO(3.0): Remove this eventually when no more legacy */ + if (ctx->op.keymgmt.genctx == NULL) + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, + EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN, qbits, + NULL); +#endif + *p++ = OSSL_PARAM_construct_size_t(OSSL_PKEY_PARAM_FFC_QBITS, &bits2); + *p++ = OSSL_PARAM_construct_end(); + + return EVP_PKEY_CTX_set_params(ctx, params); +} + +int EVP_PKEY_CTX_set_dh_paramgen_generator(EVP_PKEY_CTX *ctx, int gen) +{ + int ret; + OSSL_PARAM params[2], *p = params; + + if ((ret = dh_paramgen_check(ctx)) <= 0) + return ret; + +#if !defined(FIPS_MODE) + /* TODO(3.0): Remove this eventually when no more legacy */ + if (ctx->op.keymgmt.genctx == NULL) + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, + EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR, gen, NULL); +#endif + + *p++ = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_FFC_GENERATOR, &gen); + *p++ = OSSL_PARAM_construct_end(); + + return EVP_PKEY_CTX_set_params(ctx, params); +} + +int EVP_PKEY_CTX_set_dh_rfc5114(EVP_PKEY_CTX *ctx, int gen) +{ + int ret; + OSSL_PARAM params[2], *p = params; + const char *name; + + if ((ret = dh_paramgen_check(ctx)) <= 0) + return ret; + +#if !defined(FIPS_MODE) + /* TODO(3.0): Remove this eventually when no more legacy */ + 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); +#endif + name = ffc_named_group_from_uid(gen); + if (name == NULL) + return 0; + + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_FFC_GROUP, + (void *)name, 0); + *p++ = OSSL_PARAM_construct_end(); + return EVP_PKEY_CTX_set_params(ctx, params); +} + +int EVP_PKEY_CTX_set_dhx_rfc5114(EVP_PKEY_CTX *ctx, int gen) +{ + return EVP_PKEY_CTX_set_dh_rfc5114(ctx, gen); +} + +int EVP_PKEY_CTX_set_dh_nid(EVP_PKEY_CTX *ctx, int nid) +{ + int ret; + OSSL_PARAM params[2], *p = params; + const char *name; + + if ((ret = dh_paramgen_check(ctx)) <= 0) + return ret; + +#if !defined(FIPS_MODE) + /* TODO(3.0): Remove this eventually when no more legacy */ + if (ctx->op.keymgmt.genctx == NULL) + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, + EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN, + EVP_PKEY_CTRL_DH_NID, nid, NULL); +#endif + name = ffc_named_group_from_uid(nid); + if (name == NULL) + return 0; + + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_FFC_GROUP, + (void *)name, 0); + *p++ = OSSL_PARAM_construct_end(); + return EVP_PKEY_CTX_set_params(ctx, params); +} diff --git a/crypto/evp/pmeth_lib.c b/crypto/evp/pmeth_lib.c index 6d34accc3c..b6617492da 100644 --- a/crypto/evp/pmeth_lib.c +++ b/crypto/evp/pmeth_lib.c @@ -24,6 +24,8 @@ #include "internal/cryptlib.h" #include "crypto/asn1.h" #include "crypto/evp.h" +#include "crypto/dh.h" +#include "internal/ffc.h" #include "internal/numbers.h" #include "internal/provider.h" #include "evp_local.h" @@ -808,11 +810,22 @@ static int legacy_ctrl_to_param(EVP_PKEY_CTX *ctx, int keytype, int optype, */ if (cmd == EVP_PKEY_CTRL_CIPHER) return -2; + # ifndef OPENSSL_NO_DH if (keytype == EVP_PKEY_DH) { switch (cmd) { case EVP_PKEY_CTRL_DH_PAD: return EVP_PKEY_CTX_set_dh_pad(ctx, p1); + case EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN: + return EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, p1); + case EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN: + return EVP_PKEY_CTX_set_dh_paramgen_subprime_len(ctx, p1); + case EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR: + return EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, p1); + case EVP_PKEY_CTRL_DH_PARAMGEN_TYPE: + return EVP_PKEY_CTX_set_dh_paramgen_type(ctx, p1); + case EVP_PKEY_CTRL_DH_RFC5114: + return EVP_PKEY_CTX_set_dh_rfc5114(ctx, p1); } } # endif @@ -1021,7 +1034,21 @@ static int legacy_ctrl_str_to_param(EVP_PKEY_CTX *ctx, const char *name, name = OSSL_PKEY_PARAM_FFC_DIGEST; # endif # ifndef OPENSSL_NO_DH - else if (strcmp(name, "dh_pad") == 0) + else if (strcmp(name, "dh_paramgen_generator") == 0) + name = OSSL_PKEY_PARAM_FFC_GENERATOR; + else if (strcmp(name, "dh_paramgen_prime_len") == 0) + name = OSSL_PKEY_PARAM_FFC_PBITS; + else if (strcmp(name, "dh_paramgen_subprime_len") == 0) + name = OSSL_PKEY_PARAM_FFC_QBITS; + else if (strcmp(name, "dh_paramgen_type") == 0) { + name = OSSL_PKEY_PARAM_FFC_TYPE; + value = dh_gen_type_id2name(atoi(value)); + } else if (strcmp(name, "dh_param") == 0) + name = OSSL_PKEY_PARAM_FFC_GROUP; + else if (strcmp(name, "dh_rfc5114") == 0) { + name = OSSL_PKEY_PARAM_FFC_GROUP; + value = ffc_named_group_from_uid(atoi(value)); + } else if (strcmp(name, "dh_pad") == 0) name = OSSL_EXCHANGE_PARAM_PAD; # endif # ifndef OPENSSL_NO_EC diff --git a/crypto/ffc/ffc_backend.c b/crypto/ffc/ffc_backend.c index 1d076184bc..d3661b1706 100644 --- a/crypto/ffc/ffc_backend.c +++ b/crypto/ffc/ffc_backend.c @@ -22,25 +22,19 @@ int ffc_params_fromdata(FFC_PARAMS *ffc, const OSSL_PARAM params[]) const OSSL_PARAM *prm; const OSSL_PARAM *param_p, *param_q, *param_g; BIGNUM *p = NULL, *q = NULL, *g = NULL, *j = NULL; -#if 0 - char group_name[OSSL_MAX_NAME_SIZE]; - char *str = group_name; -#endif int i; if (ffc == NULL) return 0; -/* TODO(3.0) Add for DH PR */ -#if 0 prm = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_GROUP); if (prm != NULL) { - if (!OSSL_PARAM_get_utf8_string(prm, &str, sizeof(group_name))) + if (prm->data_type != OSSL_PARAM_UTF8_STRING) goto err; - if (!ffc_set_group_pqg(ffc, group_name)) + if (!ffc_set_group_pqg(ffc, prm->data)) goto err; } -#endif + param_p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_P); param_g = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_G); param_q = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_Q); @@ -66,6 +60,7 @@ int ffc_params_fromdata(FFC_PARAMS *ffc, const OSSL_PARAM params[]) if (prm != NULL) { if (!OSSL_PARAM_get_BN(prm, &j)) goto err; + j = NULL; } prm = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_H); if (prm != NULL) { diff --git a/crypto/ffc/ffc_params.c b/crypto/ffc/ffc_params.c index 5950847703..89550bedec 100644 --- a/crypto/ffc/ffc_params.c +++ b/crypto/ffc/ffc_params.c @@ -215,7 +215,7 @@ int ffc_params_todata(const FFC_PARAMS *ffc, OSSL_PARAM_BLD *bld, ffc->seed, ffc->seedlen)) return 0; if (ffc->nid != NID_undef) { - const char *name = ffc_named_group_from_nid(ffc->nid); + const char *name = ffc_named_group_from_uid(ffc->nid); if (name == NULL || !ossl_param_build_set_utf8_string(bld, params, @@ -227,7 +227,6 @@ int ffc_params_todata(const FFC_PARAMS *ffc, OSSL_PARAM_BLD *bld, } #ifndef FIPS_MODE - int ffc_params_print(BIO *bp, const FFC_PARAMS *ffc, int indent) { if (!ASN1_bn_print(bp, "prime P:", ffc->p, NULL, indent)) diff --git a/doc/man3/EVP_PKEY_CTX_ctrl.pod b/doc/man3/EVP_PKEY_CTX_ctrl.pod index ded779feb0..039073cacf 100644 --- a/doc/man3/EVP_PKEY_CTX_ctrl.pod +++ b/doc/man3/EVP_PKEY_CTX_ctrl.pod @@ -41,6 +41,8 @@ EVP_PKEY_CTX_set_dh_paramgen_prime_len, EVP_PKEY_CTX_set_dh_paramgen_subprime_len, EVP_PKEY_CTX_set_dh_paramgen_generator, EVP_PKEY_CTX_set_dh_paramgen_type, +EVP_PKEY_CTX_set_dh_paramgen_gindex, +EVP_PKEY_CTX_set_dh_paramgen_seed, EVP_PKEY_CTX_set_dh_rfc5114, EVP_PKEY_CTX_set_dhx_rfc5114, EVP_PKEY_CTX_set_dh_pa |