diff options
author | Shane Lontis <shane.lontis@oracle.com> | 2020-04-15 21:02:52 +1000 |
---|---|---|
committer | Shane Lontis <shane.lontis@oracle.com> | 2020-04-15 21:02:52 +1000 |
commit | b03ec3b5d62ee26bf8437556b9040d4141d5bdd8 (patch) | |
tree | 1f27a892757c24efab70d2fb8f93110f71c0fbb3 /crypto | |
parent | 09b3654096ed344edd78cf156cb3ddcdbced6f9a (diff) | |
download | openssl-new-b03ec3b5d62ee26bf8437556b9040d4141d5bdd8.tar.gz |
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.c | 4 | ||||
-rw-r--r-- | crypto/dh/dh_group_params.c | 28 | ||||
-rw-r--r-- | crypto/dh/dh_key.c | 9 | ||||
-rw-r--r-- | crypto/dsa/build.info | 4 | ||||
-rw-r--r-- | crypto/dsa/dsa_ameth.c | 4 | ||||
-rw-r--r-- | crypto/dsa/dsa_backend.c | 2 | ||||
-rw-r--r-- | crypto/dsa/dsa_gen.c | 23 | ||||
-rw-r--r-- | crypto/dsa/dsa_key.c | 8 | ||||
-rw-r--r-- | crypto/dsa/dsa_lib.c | 161 | ||||
-rw-r--r-- | crypto/evp/p_lib.c | 20 | ||||
-rw-r--r-- | crypto/evp/pmeth_lib.c | 22 | ||||
-rw-r--r-- | crypto/ffc/ffc_backend.c | 55 | ||||
-rw-r--r-- | crypto/ffc/ffc_key_generate.c | 1 | ||||
-rw-r--r-- | crypto/ffc/ffc_params.c | 85 | ||||
-rw-r--r-- | crypto/ffc/ffc_params_generate.c | 2 |
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); |