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 <tmraz@fedoraproject.org>
(Merged from https://github.com/openssl/openssl/pull/13589)
This commit is contained in:
Richard Levitte 2020-12-01 19:11:59 +01:00
parent d33ab074ef
commit c829c23b67
16 changed files with 366 additions and 306 deletions

View File

@ -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

View File

@ -21,126 +21,33 @@
#include "dh_local.h"
#include <openssl/bn.h>
#include <openssl/objects.h>
#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++;
}
}

View File

@ -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

View File

@ -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 <stdio.h>
#include "crypto/evp.h"
#include <openssl/bn.h>
#include <openssl/engine.h>
#include <openssl/obj_mac.h>
#include <string.h>
#include <openssl/core_names.h>
#include "internal/cryptlib.h"
#include "internal/refcount.h"
#include <openssl/params.h>
#include <openssl/err.h>
#include <openssl/dh.h>
#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;

48
crypto/evp/dh_support.c Normal file
View File

@ -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 <string.h> /* strcmp */
#include <openssl/dh.h>
#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;
}

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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;
}

154
crypto/ffc/ffc_dh.c Normal file
View File

@ -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

View File

@ -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,

View File

@ -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);

View File

@ -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);

View File

@ -17,21 +17,74 @@
# endif
# include <openssl/opensslconf.h>
# include <openssl/types.h>
# ifdef __cplusplus
extern "C" {
# endif
#include <stdlib.h>
/* 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 <openssl/e_os2.h>
# include <openssl/bio.h>
# include <openssl/asn1.h>
# include <openssl/types.h>
# ifndef OPENSSL_NO_DEPRECATED_1_1_0
# include <openssl/bn.h>
# endif
# include <openssl/dherr.h>
# 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

View File

@ -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;

View File

@ -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;
}