summaryrefslogtreecommitdiffstats
path: root/crypto
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 /crypto
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)
Diffstat (limited to 'crypto')
-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
15 files changed, 388 insertions, 40 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,
+ OSSL_PARAM params[])
+{
+ if (ffc == NULL)
+ return 0;
+
+ if (ffc->p != NULL
+ && !ossl_param_build_set_bn(bld, params, OSSL_PKEY_PARAM_FFC_P, ffc->p))
+ return 0;
+ if (ffc->q != NULL
+ && !ossl_param_build_set_bn(bld, params, OSSL_PKEY_PARAM_FFC_Q, ffc->q))
+ return 0;
+ if (ffc->g != NULL
+ && !ossl_param_build_set_bn(bld, params, OSSL_PKEY_PARAM_FFC_G, ffc->g))
+ return 0;
+ if (ffc->j != NULL
+ && !ossl_param_build_set_bn(bld, params, OSSL_PKEY_PARAM_FFC_COFACTOR,
+ ffc->j))
+ return 0;
+ if (!ossl_param_build_set_int(bld, params, OSSL_PKEY_PARAM_FFC_GINDEX,
+ ffc->gindex))
+ return 0;
+ if (!ossl_param_build_set_int(bld, params, OSSL_PKEY_PARAM_FFC_PCOUNTER,
+ ffc->pcounter))
+ return 0;
+ if (!ossl_param_build_set_int(bld, params, OSSL_PKEY_PARAM_FFC_H, ffc->h))
+ return 0;
+ if (ffc->seed != NULL
+ && !ossl_param_build_set_octet_string(bld, params,
+ OSSL_PKEY_PARAM_FFC_SEED,
+ ffc->seed, ffc->seedlen))
+ return 0;
+ if (ffc->nid != NID_undef) {
+ const char *name = ffc_named_group_from_nid(ffc->nid);
+
+ if (name == NULL
+ || !ossl_param_build_set_utf8_string(bld, params,
+ OSSL_PKEY_PARAM_FFC_GROUP,
+ name))
+ return 0;
+ }
+ return 1;
+}
+
#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/crypto/ffc/ffc_params_generate.c b/crypto/ffc/ffc_params_generate.c
index cb51bf0e76..6d9b924387 100644
--- a/crypto/ffc/ffc_params_generate.c
+++ b/crypto/ffc/ffc_params_generate.c
@@ -487,7 +487,7 @@ int ffc_params_FIPS186_4_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params,
BIGNUM *g = NULL, *q = NULL, *p = NULL;
BN_MONT_CTX *mont = NULL;
int n = 0, m = 0, qsize = N >> 3;
- int canonical_g = 0, hret = -1;
+ int canonical_g = 0, hret = 0;
BN_CTX *ctx = NULL;
EVP_MD_CTX *mctx = NULL;
int generate = (validate_flags == 0);