summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShane Lontis <shane.lontis@oracle.com>2020-04-15 21:02:52 +1000
committerShane Lontis <shane.lontis@oracle.com>2020-04-15 21:02:52 +1000
commitb03ec3b5d62ee26bf8437556b9040d4141d5bdd8 (patch)
tree1f27a892757c24efab70d2fb8f93110f71c0fbb3
parent09b3654096ed344edd78cf156cb3ddcdbced6f9a (diff)
Add DSA keygen to provider
Moved some shared FFC code into the FFC files. Added extra paramgen parameters for seed, gindex. Fixed bug in ossl_prov util to print bignums. Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/11303)
-rw-r--r--crypto/dh/dh_ameth.c4
-rw-r--r--crypto/dh/dh_group_params.c28
-rw-r--r--crypto/dh/dh_key.c9
-rw-r--r--crypto/dsa/build.info4
-rw-r--r--crypto/dsa/dsa_ameth.c4
-rw-r--r--crypto/dsa/dsa_backend.c2
-rw-r--r--crypto/dsa/dsa_gen.c23
-rw-r--r--crypto/dsa/dsa_key.c8
-rw-r--r--crypto/dsa/dsa_lib.c161
-rw-r--r--crypto/evp/p_lib.c20
-rw-r--r--crypto/evp/pmeth_lib.c22
-rw-r--r--crypto/ffc/ffc_backend.c55
-rw-r--r--crypto/ffc/ffc_key_generate.c1
-rw-r--r--crypto/ffc/ffc_params.c85
-rw-r--r--crypto/ffc/ffc_params_generate.c2
-rw-r--r--doc/man1/openssl-genpkey.pod.in37
-rw-r--r--doc/man3/EVP_PKEY_CTX_ctrl.pod56
-rw-r--r--doc/man7/provider-keymgmt.pod50
-rw-r--r--include/crypto/dsa.h6
-rw-r--r--include/internal/ffc.h15
-rw-r--r--include/openssl/core_names.h13
-rw-r--r--include/openssl/dsa.h20
-rw-r--r--providers/implementations/keymgmt/dh_kmgmt.c14
-rw-r--r--providers/implementations/keymgmt/dsa_kmgmt.c335
-rw-r--r--providers/implementations/serializers/build.info4
-rw-r--r--providers/implementations/serializers/serializer_common.c104
-rw-r--r--providers/implementations/serializers/serializer_dsa.c20
-rw-r--r--providers/implementations/serializers/serializer_ffc_params.c58
-rw-r--r--providers/implementations/serializers/serializer_local.h2
-rw-r--r--test/dsatest.c239
-rw-r--r--test/evp_pkey_provided_test.c239
-rw-r--r--test/recipes/15-test_gendsa.t77
-rw-r--r--test/recipes/30-test_evp_pkey_provided/DSA.priv.derbin0 -> 617 bytes
-rw-r--r--test/recipes/30-test_evp_pkey_provided/DSA.priv.pem15
-rw-r--r--test/recipes/30-test_evp_pkey_provided/DSA.priv.txt72
-rw-r--r--test/recipes/30-test_evp_pkey_provided/DSA.pub.derbin0 -> 842 bytes
-rw-r--r--test/recipes/30-test_evp_pkey_provided/DSA.pub.pem20
-rw-r--r--test/recipes/30-test_evp_pkey_provided/DSA.pub.txt72
-rw-r--r--util/libcrypto.num7
39 files changed, 1678 insertions, 225 deletions
diff --git a/crypto/dh/dh_ameth.c b/crypto/dh/dh_ameth.c
index f5bcee2460..9c1fa0388d 100644
--- a/crypto/dh/dh_ameth.c
+++ b/crypto/dh/dh_ameth.c
@@ -24,7 +24,7 @@
#include "crypto/evp.h"
#include <openssl/cms.h>
#include <openssl/core_names.h>
-#include "openssl/param_build.h"
+#include <openssl/param_build.h>
#include "internal/ffc.h"
/*
@@ -558,7 +558,7 @@ static int dh_pkey_import_from(const OSSL_PARAM params[], void *key)
return 0;
}
- if (!ffc_fromdata(dh_get0_params(dh), params)
+ if (!ffc_params_fromdata(dh_get0_params(dh), params)
|| !dh_key_fromdata(dh, params)
|| !EVP_PKEY_assign_DH(pkey, dh)) {
DH_free(dh);
diff --git a/crypto/dh/dh_group_params.c b/crypto/dh/dh_group_params.c
index d672ae3034..cc1c546655 100644
--- a/crypto/dh/dh_group_params.c
+++ b/crypto/dh/dh_group_params.c
@@ -23,12 +23,14 @@
#include "crypto/bn_dh.h"
#include "crypto/dh.h"
#include "crypto/security_bits.h"
+#include "e_os.h" /* strcasecmp */
-#define FFDHE(sz) { NID_ffdhe##sz, sz, &_bignum_ffdhe##sz##_p }
-#define MODP(sz) { NID_modp_##sz, sz, &_bignum_modp_##sz##_p }
+#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 }
typedef struct safe_prime_group_st {
+ const char *name;
int nid;
int32_t nbits;
const BIGNUM *p;
@@ -50,6 +52,28 @@ static const SP_GROUP sp_groups[] = {
MODP(8192),
};
+int ffc_named_group_to_nid(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;
+ }
+ return NID_undef;
+}
+
+const char *ffc_named_group_from_nid(int nid)
+{
+ size_t i;
+
+ for (i = 0; i < OSSL_NELEM(sp_groups); ++i) {
+ if (sp_groups[i].nid == nid)
+ return sp_groups[i].name;
+ }
+ return NULL;
+}
+
#ifndef FIPS_MODE
static DH *dh_new_by_nid_with_ctx(OPENSSL_CTX *libctx, int nid);
diff --git a/crypto/dh/dh_key.c b/crypto/dh/dh_key.c
index ab2e25ea87..e46946153b 100644
--- a/crypto/dh/dh_key.c
+++ b/crypto/dh/dh_key.c
@@ -19,6 +19,12 @@
#include "crypto/bn.h"
#include "crypto/dh.h"
+#ifdef FIPS_MODE
+# define MIN_STRENGTH 112
+#else
+# define MIN_STRENGTH 80
+#endif
+
static int generate_key(DH *dh);
static int dh_bn_mod_exp(const DH *dh, BIGNUM *r,
const BIGNUM *a, const BIGNUM *p,
@@ -287,7 +293,8 @@ static int generate_key(DH *dh)
* Max Private key size N = len(q)
*/
if (!ffc_generate_private_key(ctx, &dh->params,
- BN_num_bits(dh->params.q), 112,
+ BN_num_bits(dh->params.q),
+ MIN_STRENGTH,
priv_key))
goto err;
}
diff --git a/crypto/dsa/build.info b/crypto/dsa/build.info
index fb5a4fee2a..7f621cb56b 100644
--- a/crypto/dsa/build.info
+++ b/crypto/dsa/build.info
@@ -1,10 +1,10 @@
LIBS=../../libcrypto
$COMMON=dsa_sign.c dsa_vrf.c dsa_lib.c dsa_ossl.c dsa_check.c \
- dsa_key.c dsa_backend.c
+ dsa_key.c dsa_backend.c dsa_gen.c
SOURCE[../../libcrypto]=$COMMON\
- dsa_gen.c dsa_asn1.c \
+ dsa_asn1.c \
dsa_err.c dsa_depr.c dsa_ameth.c dsa_pmeth.c dsa_prn.c \
dsa_meth.c
SOURCE[../../providers/libfips.a]=$COMMON
diff --git a/crypto/dsa/dsa_ameth.c b/crypto/dsa/dsa_ameth.c
index d63c142fdd..81bb6d88f7 100644
--- a/crypto/dsa/dsa_ameth.c
+++ b/crypto/dsa/dsa_ameth.c
@@ -19,11 +19,11 @@
#include <openssl/bn.h>
#include <openssl/cms.h>
#include <openssl/core_names.h>
+#include <openssl/param_build.h>
#include "internal/cryptlib.h"
#include "crypto/asn1.h"
#include "crypto/dsa.h"
#include "crypto/evp.h"
-#include "openssl/param_build.h"
#include "internal/ffc.h"
#include "dsa_local.h"
@@ -586,7 +586,7 @@ static int dsa_pkey_import_from(const OSSL_PARAM params[], void *key)
return 0;
}
- if (!ffc_fromdata(dsa_get0_params(dsa), params)
+ if (!dsa_ffc_params_fromdata(dsa, params)
|| !dsa_key_fromdata(dsa, params)
|| !EVP_PKEY_assign_DSA(pkey, dsa)) {
DSA_free(dsa);
diff --git a/crypto/dsa/dsa_backend.c b/crypto/dsa/dsa_backend.c
index b927465cfa..461cb187dd 100644
--- a/crypto/dsa/dsa_backend.c
+++ b/crypto/dsa/dsa_backend.c
@@ -34,7 +34,7 @@ int dsa_key_fromdata(DSA *dsa, const OSSL_PARAM params[])
return 1;
/*
- * DH documentation says that a public key must be present if a
+ * DSA documentation says that a public key must be present if a
* private key is present.
*/
if (param_priv_key != NULL && param_pub_key == NULL)
diff --git a/crypto/dsa/dsa_gen.c b/crypto/dsa/dsa_gen.c
index 2148a1a487..7b72867f71 100644
--- a/crypto/dsa/dsa_gen.c
+++ b/crypto/dsa/dsa_gen.c
@@ -24,32 +24,34 @@
#include "dsa_local.h"
int dsa_generate_ffc_parameters(DSA *dsa, int type,
- int pbits, int qbits, int gindex,
- BN_GENCB *cb)
+ int pbits, int qbits,
+ EVP_MD *md, BN_GENCB *cb)
{
int ret = 0, res;
if (qbits <= 0) {
- const EVP_MD *evpmd = pbits >= 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;
}
- dsa->params.gindex = gindex;
#ifndef FIPS_MODE
if (type == DSA_PARAMGEN_TYPE_FIPS_186_2)
ret = ffc_params_FIPS186_2_generate(dsa->libctx, &dsa->params,
FFC_PARAM_TYPE_DSA,
- pbits, qbits, NULL, &res, cb);
+ pbits, qbits, md, &res, cb);
else
#endif
ret = ffc_params_FIPS186_4_generate(dsa->libctx, &dsa->params,
FFC_PARAM_TYPE_DSA,
- pbits, qbits, NULL, &res, cb);
+ pbits, qbits, md, &res, cb);
if (ret > 0)
dsa->dirty_cnt++;
return ret;
}
+#ifndef FIPS_MODE
int DSA_generate_parameters_ex(DSA *dsa, int bits,
const unsigned char *seed_in, int seed_len,
int *counter_ret, unsigned long *h_ret,
@@ -68,13 +70,13 @@ int DSA_generate_parameters_ex(DSA *dsa, int bits,
/* The old code used FIPS 186-2 DSA Parameter generation */
if (bits <= 1024 && seed_len == 20) {
if (!dsa_generate_ffc_parameters(dsa, DSA_PARAMGEN_TYPE_FIPS_186_2,
- bits, 160, -1, cb))
+ bits, 160, NULL, cb))
return 0;
} else
#endif
{
if (!dsa_generate_ffc_parameters(dsa, DSA_PARAMGEN_TYPE_FIPS_186_4,
- bits, -1, -1, cb))
+ bits, -1, NULL, cb))
return 0;
}
@@ -84,3 +86,4 @@ int DSA_generate_parameters_ex(DSA *dsa, int bits,
*h_ret = dsa->params.h;
return 1;
}
+#endif
diff --git a/crypto/dsa/dsa_key.c b/crypto/dsa/dsa_key.c
index 2dec35f28f..1d625272e5 100644
--- a/crypto/dsa/dsa_key.c
+++ b/crypto/dsa/dsa_key.c
@@ -21,6 +21,12 @@
#include "crypto/dsa.h"
#include "dsa_local.h"
+#ifdef FIPS_MODE
+# define MIN_STRENGTH 112
+#else
+# define MIN_STRENGTH 80
+#endif
+
static int dsa_keygen(DSA *dsa, int pairwise_test);
static int dsa_keygen_pairwise_test(DSA *dsa, OSSL_CALLBACK *cb, void *cbarg);
@@ -69,7 +75,7 @@ static int dsa_keygen(DSA *dsa, int pairwise_test)
}
if (!ffc_generate_private_key(ctx, &dsa->params, BN_num_bits(dsa->params.q),
- 112, priv_key))
+ MIN_STRENGTH, priv_key))
goto err;
if (dsa->pub_key == NULL) {
diff --git a/crypto/dsa/dsa_lib.c b/crypto/dsa/dsa_lib.c
index e3205223e9..b773f2c526 100644
--- a/crypto/dsa/dsa_lib.c
+++ b/crypto/dsa/dsa_lib.c
@@ -19,7 +19,9 @@
#include <openssl/bn.h>
#include <openssl/asn1.h>
#include <openssl/engine.h>
+#include <openssl/core_names.h>
#include "dsa_local.h"
+#include "crypto/evp.h"
#include "crypto/dsa.h"
#include "crypto/dh.h" /* required by DSA_dup_DH() */
@@ -342,3 +344,162 @@ FFC_PARAMS *dsa_get0_params(DSA *dsa)
{
return &dsa->params;
}
+
+int dsa_ffc_params_fromdata(DSA *dsa, const OSSL_PARAM params[])
+{
+ int ret;
+ FFC_PARAMS *ffc;
+
+ if (dsa == NULL)
+ return 0;
+ ffc = dsa_get0_params(dsa);
+ if (ffc == NULL)
+ return 0;
+
+ ret = ffc_params_fromdata(ffc, params);
+ if (ret)
+ dsa->dirty_cnt++;
+ return ret;
+}
+
+static int dsa_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 DSA return error */
+ if (ctx->pmeth != NULL && ctx->pmeth->pkey_id != EVP_PKEY_DSA)
+ return -1;
+ return 1;
+}
+
+int EVP_PKEY_CTX_set_dsa_paramgen_type(EVP_PKEY_CTX *ctx, const char *name)
+{
+ int ret;
+ OSSL_PARAM params[2], *p = params;
+
+ if ((ret = dsa_paramgen_check(ctx)) <= 0)
+ return ret;
+
+ *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_dsa_paramgen_gindex(EVP_PKEY_CTX *ctx, int gindex)
+{
+ int ret;
+ OSSL_PARAM params[2], *p = params;
+
+ if ((ret = dsa_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_dsa_paramgen_seed(EVP_PKEY_CTX *ctx,
+ const unsigned char *seed,
+ size_t seedlen)
+{
+ int ret;
+ OSSL_PARAM params[2], *p = params;
+
+ if ((ret = dsa_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_dsa_paramgen_bits(EVP_PKEY_CTX *ctx, int nbits)
+{
+ int ret;
+ OSSL_PARAM params[2], *p = params;
+ size_t bits = nbits;
+
+ if ((ret = dsa_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_DSA, EVP_PKEY_OP_PARAMGEN,
+ EVP_PKEY_CTRL_DSA_PARAMGEN_BITS, nbits, 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_dsa_paramgen_q_bits(EVP_PKEY_CTX *ctx, int qbits)
+{
+ int ret;
+ OSSL_PARAM params[2], *p = params;
+ size_t bits2 = qbits;
+
+ if ((ret = dsa_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_DSA, EVP_PKEY_OP_PARAMGEN,
+ EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS, 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_dsa_paramgen_md_props(EVP_PKEY_CTX *ctx,
+ const char *md_name,
+ const char *md_properties)
+{
+ int ret;
+ OSSL_PARAM params[3], *p = params;
+
+ if ((ret = dsa_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) {
+ const EVP_MD *md = EVP_get_digestbyname(md_name);
+
+ EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN,
+ EVP_PKEY_CTRL_DSA_PARAMGEN_MD, 0, (void *)(md));
+ }
+#endif
+
+ *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_FFC_DIGEST,
+ (char *)md_name, 0);
+ if (md_properties != NULL)
+ *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_FFC_DIGEST_PROPS,
+ (char *)md_properties, 0);
+ *p++ = OSSL_PARAM_construct_end();
+
+ return EVP_PKEY_CTX_set_params(ctx, params);
+}
+
+#if !defined(FIPS_MODE)
+int EVP_PKEY_CTX_set_dsa_paramgen_md(EVP_PKEY_CTX *ctx, const EVP_MD *md)
+{
+ const char *md_name = (md == NULL) ? "" : EVP_MD_name(md);
+
+ return EVP_PKEY_CTX_set_dsa_paramgen_md_props(ctx, md_name, NULL);
+}
+#endif
diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c
index 9f04c72330..b0163f5792 100644
--- a/crypto/evp/p_lib.c
+++ b/crypto/evp/p_lib.c
@@ -627,14 +627,6 @@ RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey)
# endif
# ifndef OPENSSL_NO_DSA
-int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key)
-{
- int ret = EVP_PKEY_assign_DSA(pkey, key);
- if (ret)
- DSA_up_ref(key);
- return ret;
-}
-
DSA *EVP_PKEY_get0_DSA(const EVP_PKEY *pkey)
{
if (!evp_pkey_downgrade((EVP_PKEY *)pkey)) {
@@ -648,6 +640,13 @@ DSA *EVP_PKEY_get0_DSA(const EVP_PKEY *pkey)
return pkey->pkey.dsa;
}
+int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key)
+{
+ int ret = EVP_PKEY_assign_DSA(pkey, key);
+ if (ret)
+ DSA_up_ref(key);
+ return ret;
+}
DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey)
{
DSA *ret = EVP_PKEY_get0_DSA(pkey);
@@ -655,10 +654,11 @@ DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey)
DSA_up_ref(ret);
return ret;
}
-# endif
+# endif /* OPENSSL_NO_DSA */
+#endif /* FIPS_MODE */
+#ifndef FIPS_MODE
# ifndef OPENSSL_NO_EC
-
int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key)
{
int ret = EVP_PKEY_assign_EC_KEY(pkey, key);
diff --git a/crypto/evp/pmeth_lib.c b/crypto/evp/pmeth_lib.c
index 6a86b26ded..6d34accc3c 100644
--- a/crypto/evp/pmeth_lib.c
+++ b/crypto/evp/pmeth_lib.c
@@ -8,7 +8,7 @@
*/
/*
- * DH low level APIs are deprecated for public use, but still ok for
+ * Low level key APIs (DH etc) are deprecated for public use, but still ok for
* internal use.
*/
#include "internal/deprecated.h"
@@ -816,6 +816,18 @@ static int legacy_ctrl_to_param(EVP_PKEY_CTX *ctx, int keytype, int optype,
}
}
# endif
+# ifndef OPENSSL_NO_DSA
+ if (keytype == EVP_PKEY_DSA) {
+ switch (cmd) {
+ case EVP_PKEY_CTRL_DSA_PARAMGEN_BITS:
+ return EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, p1);
+ case EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS:
+ return EVP_PKEY_CTX_set_dsa_paramgen_q_bits(ctx, p1);
+ case EVP_PKEY_CTRL_DSA_PARAMGEN_MD:
+ return EVP_PKEY_CTX_set_dsa_paramgen_md(ctx, p2);
+ }
+ }
+# endif
# ifndef OPENSSL_NO_EC
if (keytype == EVP_PKEY_EC) {
switch (cmd) {
@@ -1000,6 +1012,14 @@ static int legacy_ctrl_str_to_param(EVP_PKEY_CTX *ctx, const char *name,
name = OSSL_PKEY_PARAM_RSA_E;
else if (strcmp(name, "rsa_keygen_primes") == 0)
name = OSSL_PKEY_PARAM_RSA_PRIMES;
+# ifndef OPENSSL_NO_DSA
+ else if (strcmp(name, "dsa_paramgen_bits") == 0)
+ name = OSSL_PKEY_PARAM_FFC_PBITS;
+ else if (strcmp(name, "dsa_paramgen_q_bits") == 0)
+ name = OSSL_PKEY_PARAM_FFC_QBITS;
+ else if (strcmp(name, "dsa_paramgen_md") == 0)
+ name = OSSL_PKEY_PARAM_FFC_DIGEST;
+# endif
# ifndef OPENSSL_NO_DH
else if (strcmp(name, "dh_pad") == 0)
name = OSSL_EXCHANGE_PARAM_PAD;
diff --git a/crypto/ffc/ffc_backend.c b/crypto/ffc/ffc_backend.c
index cde9e43da3..1d076184bc 100644
--- a/crypto/ffc/ffc_backend.c
+++ b/crypto/ffc/ffc_backend.c
@@ -9,6 +9,7 @@
#include <openssl/core_names.h>
#include "internal/ffc.h"
+#include "internal/sizes.h"
/*
* The intention with the "backend" source file is to offer backend support
@@ -16,27 +17,75 @@
* implementations alike.
*/
-int ffc_fromdata(FFC_PARAMS *ffc, const OSSL_PARAM params[])
+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;
+ 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)))
+ goto err;
+ if (!ffc_set_group_pqg(ffc, group_name))
+ goto err;
+ }
+#endif
param_p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_P);
- param_q = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_Q);
param_g = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_G);
+ param_q = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_Q);
if ((param_p != NULL && !OSSL_PARAM_get_BN(param_p, &p))
|| (param_q != NULL && !OSSL_PARAM_get_BN(param_q, &q))
|| (param_g != NULL && !OSSL_PARAM_get_BN(param_g, &g)))
goto err;
+ prm = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_GINDEX);
+ if (prm != NULL) {
+ if (!OSSL_PARAM_get_int(prm, &i))
+ goto err;
+ ffc->gindex = i;
+ }
+ prm = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_PCOUNTER);
+ if (prm != NULL) {
+ if (!OSSL_PARAM_get_int(prm, &i))
+ goto err;
+ ffc->pcounter = i;
+ }
+ prm = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_COFACTOR);
+ if (prm != NULL) {
+ if (!OSSL_PARAM_get_BN(prm, &j))
+ goto err;
+ }
+ prm = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_H);
+ if (prm != NULL) {
+ if (!OSSL_PARAM_get_int(prm, &i))
+ goto err;
+ ffc->h = i;
+ }
+ prm = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_SEED);
+ if (prm != NULL) {
+ if (prm->data_type != OSSL_PARAM_OCTET_STRING)
+ goto err;
+ if (!ffc_params_set_seed(ffc, prm->data, prm->data_size))
+ goto err;
+ }
ffc_params_set0_pqg(ffc, p, q, g);
+ ffc_params_set0_j(ffc, j);
return 1;
err:
+ BN_free(j);
BN_free(p);
BN_free(q);
BN_free(g);
diff --git a/crypto/ffc/ffc_key_generate.c b/crypto/ffc/ffc_key_generate.c
index 078e8d39a1..4e2f231d83 100644
--- a/crypto/ffc/ffc_key_generate.c
+++ b/crypto/ffc/ffc_key_generate.c
@@ -10,6 +10,7 @@
#include "internal/ffc.h"
/*
+ * For Fips mode:
* SP800-56Ar3 5.6.1.1.4 Key pair generation by testing candidates.
* Generates a private key in the interval [1, min(2 ^ N - 1, q - 1)].
*
diff --git a/crypto/ffc/ffc_params.c b/crypto/ffc/ffc_params.c
index cb8987b64d..5950847703 100644
--- a/crypto/ffc/ffc_params.c
+++ b/crypto/ffc/ffc_params.c
@@ -8,7 +8,10 @@
*/
#include <string.h> /* memset */
+#include <openssl/core_names.h>
#include "internal/ffc.h"
+#include "internal/param_build_set.h"
+
#ifndef FIPS_MODE
# include <openssl/asn1.h> /* ffc_params_print */
#endif
@@ -67,15 +70,17 @@ void ffc_params_set0_j(FFC_PARAMS *d, BIGNUM *j)
d->j = j;
}
-int ffc_params_set_validate_params(FFC_PARAMS *params,
- const unsigned char *seed, size_t seedlen,
- int counter)
+int ffc_params_set_seed(FFC_PARAMS *params,
+ const unsigned char *seed, size_t seedlen)
{
if (params == NULL)
return 0;
- if (params->seed != NULL)
+ if (params->seed != NULL) {
+ if (params->seed == seed)
+ return 1;
OPENSSL_free(params->seed);
+ }
if (seed != NULL && seedlen > 0) {
params->seed = OPENSSL_memdup(seed, seedlen);
@@ -86,6 +91,30 @@ int ffc_params_set_validate_params(FFC_PARAMS *params,
params->seed = NULL;
params->seedlen = 0;
}
+ return 1;
+}
+
+void ffc_params_set_gindex(FFC_PARAMS *params, int index)
+{
+ params->gindex = index;
+}
+
+void ffc_params_set_pcounter(FFC_PARAMS *params, int index)
+{
+ params->pcounter = index;
+}
+
+void ffc_params_set_h(FFC_PARAMS *params, int index)
+{
+ params->h = index;
+}
+
+int ffc_params_set_validate_params(FFC_PARAMS *params,
+ const unsigned char *seed, size_t seedlen,
+ int counter)
+{
+ if (!ffc_params_set_seed(params, seed, seedlen))
+ return 0;
params->pcounter = counter;
return 1;
}
@@ -139,7 +168,10 @@ int ffc_params_copy(FFC_PARAMS *dst, const FFC_PARAMS *src)
} else {
dst->seed = NULL;
}
+ dst->nid = src->nid;
dst->pcounter = src->pcounter;
+ dst->h = src->h;
+ dst->gindex = src->gindex;
return 1;
}
@@ -150,7 +182,52 @@ int ffc_params_cmp(const FFC_PARAMS *a, const FFC_PARAMS *b, int ignore_q)
&& (ignore_q || BN_cmp(a->q, b->q) == 0); /* Note: q may be NULL */
}
+int ffc_params_todata(const FFC_PARAMS *ffc, OSSL_PARAM_BLD *bld,