summaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorRichard Levitte <levitte@openssl.org>2020-12-01 19:11:59 +0100
committerRichard Levitte <levitte@openssl.org>2020-12-16 11:55:39 +0100
commitc829c23b67308ad8e8ab677c78db1d5151106c3c (patch)
treea1b4b7aeb5cc3093db9df76e06e02ce18f1653ed /crypto
parentd33ab074ef9847b67d96961f85f4ad614395d2c2 (diff)
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)
Diffstat (limited to 'crypto')
-rw-r--r--crypto/dh/build.info2
-rw-r--r--crypto/dh/dh_group_params.c162
-rw-r--r--crypto/evp/build.info4
-rw-r--r--crypto/evp/dh_ctrl.c (renamed from crypto/dh/dh_ctrl.c)46
-rw-r--r--crypto/evp/dh_support.c48
-rw-r--r--crypto/evp/p_lib.c8
-rw-r--r--crypto/evp/pmeth_lib.c33
-rw-r--r--crypto/ffc/build.info5
-rw-r--r--crypto/ffc/ffc_backend.c10
-rw-r--r--crypto/ffc/ffc_dh.c154
-rw-r--r--crypto/ffc/ffc_params.c8
11 files changed, 275 insertions, 205 deletions
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,160 +21,43 @@
#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)
+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++;
}
}
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
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 <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;
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 <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;
+}
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,