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)
#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"
/*
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);
#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;
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);
#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,
* 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;
}
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
#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"
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);
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)
#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,
/* 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;
}
*h_ret = dsa->params.h;
return 1;
}
+#endif
#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);
}
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) {
#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() */
{
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
# 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)) {
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);
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);
*/
/*
- * 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"
}
}
# 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) {
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;
#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
* 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);
#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)].
*
*/
#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
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);
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;
}
} else {
dst->seed = NULL;
}
+ dst->nid = src->nid;
dst->pcounter = src->pcounter;
+ dst->h = src->h;
+ dst->gindex = src->gindex;
return 1;
}
&& (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))
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);
=item B<dsa_paramgen_q_bits>:I<numbits>
+=item B<qbits>:I<numbits>
+
The number of bits in the q parameter. Must be one of 160, 224 or 256. If not
specified 224 is used.
=item B<dsa_paramgen_md>:I<digest>
+=item B<digest>:I<digest>
+
The digest to use during parameter generation. Must be one of B<sha1>, B<sha224>
or B<sha256>. If set, then the number of bits in B<q> will match the output size
of the specified digest and the B<dsa_paramgen_q_bits> parameter will be
the number of bits in B<q>, i.e. B<sha1> if q length is 160, B<sha224> if it 224
or B<sha256> if it is 256.
+
+=item B<properties>:I<query>
+
+The I<digest> property I<query> string to use when fetching a digest from a provider.
+
+=item B<type>:I<type>
+
+The type of generation to use. Set this to 1 to use legacy FIPS186-2 parameter
+generation. The default of 0 uses FIPS186-4 parameter generation.
+
+=item B<gindex>:I<index>
+
+The index to use for canonical generation and verification of the generator g.
+Set this to a positive value ranging from 0..255 to use this mode. Larger values
+will only use the bottom byte.
+This I<index> must then be reused during key validation to verify the value of g.
+If this value is not set then g is not verifiable. The default value is -1.
+
+=item B<hexseed>:I<seed>
+
+The seed I<seed> data to use instead of generating a random seed internally.
+This should be used for testing purposes only. This will either produced fixed
+values for the generated parameters OR it will fail if the seed did not
+generate valid primes.
+
=back
=head2 DH Parameter Generation Options
openssl genpkey -algorithm RSA -out key.pem \
-pkeyopt rsa_keygen_bits:2048 -pkeyopt rsa_keygen_pubexp:3
-Generate 2048 bit DSA parameters:
+Generate 2048 bit DSA parameters that can be validated: The output values for
+gindex and seed are required for key validation purposes and are not saved to
+the output pem file).
- openssl genpkey -genparam -algorithm DSA -out dsap.pem \
- -pkeyopt dsa_paramgen_bits:2048
+ openssl genpkey -genparam -algorithm DSA -out dsap.pem -pkeyopt pbits:2048 \
+ -pkeyopt qbits:224 -pkeyopt digest:SHA256 -pkeyopt gindex:1 -text
Generate DSA key from parameters:
EVP_PKEY_CTX_set_dsa_paramgen_bits,
EVP_PKEY_CTX_set_dsa_paramgen_q_bits,
EVP_PKEY_CTX_set_dsa_paramgen_md,
+EVP_PKEY_CTX_set_dsa_paramgen_md_props,
+EVP_PKEY_CTX_set_dsa_paramgen_gindex,
+EVP_PKEY_CTX_set_dsa_paramgen_type,
+EVP_PKEY_CTX_set_dsa_paramgen_seed,
EVP_PKEY_CTX_set_dh_paramgen_prime_len,
EVP_PKEY_CTX_set_dh_paramgen_subprime_len,
EVP_PKEY_CTX_set_dh_paramgen_generator,
int EVP_PKEY_CTX_set_dsa_paramgen_bits(EVP_PKEY_CTX *ctx, int nbits);
int EVP_PKEY_CTX_set_dsa_paramgen_q_bits(EVP_PKEY_CTX *ctx, int qbits);
int EVP_PKEY_CTX_set_dsa_paramgen_md(EVP_PKEY_CTX *ctx, const EVP_MD *md);
+ int EVP_PKEY_CTX_set_dsa_paramgen_md_props(EVP_PKEY_CTX *ctx,
+ const char *md_name,
+ const char *md_properties);
+ int EVP_PKEY_CTX_set_dsa_paramgen_type(EVP_PKEY_CTX *ctx, const char *name);
+ int EVP_PKEY_CTX_set_dsa_paramgen_gindex(EVP_PKEY_CTX *ctx, int gindex);
+ int EVP_PKEY_CTX_set_dsa_paramgen_seed(EVP_PKEY_CTX *ctx,
+ const unsigned char *seed,
+ size_t seedlen);
#include <openssl/dh.h>
=head2 DSA parameters
-The EVP_PKEY_CTX_set_dsa_paramgen_bits() macro sets the number of bits used
+The EVP_PKEY_CTX_set_dsa_paramgen_bits() method sets the number of bits used
for DSA parameter generation to I<nbits>. If not specified, 2048 is used.
-The EVP_PKEY_CTX_set_dsa_paramgen_q_bits() macro sets the number of bits in the
+The EVP_PKEY_CTX_set_dsa_paramgen_q_bits() method sets the number of bits in the
subprime parameter I<q> for DSA parameter generation to I<qbits>. If not
specified, 224 is used. If a digest function is specified below, this parameter
is ignored and instead, the number of bits in I<q> matches the size of the
digest.
-The EVP_PKEY_CTX_set_dsa_paramgen_md() macro sets the digest function used for
+The EVP_PKEY_CTX_set_dsa_paramgen_md() method sets the digest function used for
DSA parameter generation to I<md>. If not specified, one of SHA-1, SHA-224, or
SHA-256 is selected to match the bit length of I<q> above.
+The EVP_PKEY_CTX_set_dsa_paramgen_md_props() method sets the digest function
+used for DSA parameter generation using I<md_name> and I<md_properties> to
+retrieve the digest from a provider.
+If not specified, I<md_name> will be set to one of SHA-1, SHA-224, or
+SHA-256 depending on the bit length of I<q> above. I<md_properties> is a
+property query string that has a default value of '' if not specified.
+
+The EVP_PKEY_CTX_set_dsa_paramgen_gindex() method sets the I<gindex> used by
+the generator G. The default value is -1 which uses unverifiable g, otherwise
+a positive value uses verifiable g. This value must be saved if key validation
+of g is required, since it is not part of a persisted key.
+
+The EVP_PKEY_CTX_set_dsa_paramgen_seed() method sets the I<seed> to use for
+generation rather than using a randomly generated value for the seed. This is
+useful for testing purposes only and can fail if the seed does not produce
+primes for both p & q on its first iteration. This value must be saved if
+key validation of p, q, and verifiable g are required, since it is not part of
+a persisted key.
+
+The EVP_PKEY_CTX_set_dsa_paramgen_type() method sets the generation type to
+use FIPS186-4 generation if I<name> is "fips186_4", or FIPS186-2 generation if
+I<name> is "fips186_2". The default value is "fips186_4".
+
=head2 DH parameters
The EVP_PKEY_CTX_set_dh_paramgen_prime_len() macro sets the length of the DH
The EVP_PKEY_CTX_set_dh_paramgen_subprime_len() macro sets the length of the DH
optional subprime parameter I<q> for DH parameter generation. The default is
256 if the prime is at least 2048 bits long or 160 otherwise. The DH
-paramgen type must have been set to B<DH_PARAMGEN_TYPE_FIPS_186_2> or
-B<DH_PARAMGEN_TYPE_FIPS_186_4>.
+paramgen type must have been set to "fips186_4".
The EVP_PKEY_CTX_set_dh_paramgen_generator() macro sets DH generator to I<gen>
for DH parameter generation. If not specified 2 is used.
EVP_PKEY_CTX_set_rsa_mgf1_md(), EVP_PKEY_CTX_set_rsa_oaep_md(),
EVP_PKEY_CTX_get_rsa_oaep_md(), EVP_PKEY_CTX_set0_rsa_oaep_label(),
EVP_PKEY_CTX_get0_rsa_oaep_label(), EVP_PKEY_CTX_set_rsa_pss_saltlen(),
-EVP_PKEY_CTX_get_rsa_pss_saltlen(), were macros in OpenSSL 1.1.1 and below.
+EVP_PKEY_CTX_get_rsa_pss_saltlen(), EVP_PKEY_CTX_set_dsa_paramgen_bits(),
+EVP_PKEY_CTX_set_dsa_paramgen_q_bits() and EVP_PKEY_CTX_set_dsa_paramgen_md()
+were macros in OpenSSL 1.1.1 and below.
From OpenSSL 3.0 they are functions.
EVP_PKEY_CTX_get_rsa_oaep_md_name(), EVP_PKEY_CTX_get_rsa_mgf1_md_name(),
-EVP_PKEY_CTX_set_rsa_mgf1_md_name() and EVP_PKEY_CTX_set_rsa_oaep_md_name() were
-added in OpenSSL 3.0.
+EVP_PKEY_CTX_set_rsa_mgf1_md_name(), EVP_PKEY_CTX_set_rsa_oaep_md_name(),
+EVP_PKEY_CTX_set_dsa_paramgen_md_props(), EVP_PKEY_CTX_set_dsa_paramgen_gindex(),
+EVP_PKEY_CTX_set_dsa_paramgen_type() and EVP_PKEY_CTX_set_dsa_paramgen_seed()
+were added in OpenSSL 3.0.
The EVP_PKEY_CTX_set1_id(), EVP_PKEY_CTX_get1_id() and
EVP_PKEY_CTX_get1_id_len() macros were added in 1.1.1, other functions were
=head1 COPYRIGHT
-Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2006-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
has ensured that I<keydata_to> and I<keydata_from> are both owned by
the implementation of this function.
+=head2 Built-in DSA Key Generation Types
+
+The following Key Generation types are available for the built-in DSA algorithm:
+
+=over 4
+
+=item "pbits" (B<OSSL_PKEY_PARAM_FFC_PBITS>) <unsigned integer>
+
+Sets the DSA size (in bits) of the prime 'p'.
+The value should be 2048 or 3072.
+
+=item "qbits" (B<OSSL_PKEY_PARAM_FFC_QBITS>) <unsigned integer>
+
+Sets the DSA size (in bits) of the prime 'q'.
+The value should be 224 or 256.
+
+=item "type" (B<OSSL_PKEY_PARAM_FFC_TYPE>) <integer>
+
+Sets the type of parameter generation.
+Use 0 for FIPS186-4, or 1 for legacy FIPS186-2.
+The default is 0.
+
+=item "digest" (B<OSSL_PKEY_PARAM_FFC_DIGEST>) <utf8_string>
+
+Sets the Digest algorithm to be used as part of the Key Generation Function
+associated with the given Key Generation I<ctx>.
+
+=item "properties" (B<OSSL_PKEY_PARAM_FFC_DIGEST_PROPS>) <utf8_string>
+
+Sets properties to be used upon look up of the implementation for the selected
+Digest algorithm for the Key Generation Function associated with the given key
+Generation I<ctx>.
+
+=item "gindex" (B<OSSL_PKEY_PARAM_FFC_GINDEX>) <integer>
+
+Sets the index to use for canonical generation and verification of the generator g.
+Set this to a positive value to use this mode. This I<index> can then be reused
+during key validation to verify the value of g. If this value is not set then
+g is not verifiable. The default value is -1.
+
+=item "seed" (B<OSSL_PKEY_PARAM_FFC_SEED>) <octet_string>
+
+Sets the I<seed> data to use instead of generating a random seed internally.
+This should be used for testing purposes only. This will either produced fixed
+values for the generated parameters OR it will fail if the seed did not
+generate valid primes.
+
+=back
+
+
=head2 Built-in RSA Import/Export Types
The following Import/Export types are available for the built-in RSA algorithm:
#include <openssl/dsa.h>
#include "internal/ffc.h"
+#define DSA_PARAMGEN_TYPE_FIPS_186_4 0 /* Use FIPS186-4 standard */
#define DSA_PARAMGEN_TYPE_FIPS_186_2 1 /* Use legacy FIPS186-2 standard */
-#define DSA_PARAMGEN_TYPE_FIPS_186_4 2 /* Use FIPS186-4 standard */
DSA *dsa_new_with_ctx(OPENSSL_CTX *libctx);
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 dsa_sign_int(int type, const unsigned char *dgst,
int dlen, unsigned char *sig, unsigned int *siglen, DSA *dsa);
const unsigned char *dsa_algorithmidentifier_encoding(int md_nid, size_t *len);
FFC_PARAMS *dsa_get0_params(DSA *dsa);
+int dsa_ffc_params_fromdata(DSA *dsa, const OSSL_PARAM params[]);
int dsa_key_fromdata(DSA *dsa, const OSSL_PARAM params[]);
int dsa_generate_public_key(BN_CTX *ctx, const DSA *dsa, const BIGNUM *priv_key,
# include <openssl/bn.h>
# include <openssl/evp.h>
# include <openssl/dh.h> /* Uses Error codes from DH */
+# include <openssl/params.h>
+# include <openssl/param_build.h>
/* Default value for gindex when canonical generation of g is not used */
# define FFC_UNVERIFIABLE_GINDEX -1
void ffc_params_get0_pqg(const FFC_PARAMS *params, const BIGNUM **p,
const BIGNUM **q, const BIGNUM **g);
void ffc_params_set0_j(FFC_PARAMS *d, BIGNUM *j);
+int ffc_params_set_seed(FFC_PARAMS *params,
+ const unsigned char *seed, size_t seedlen);
+void ffc_params_set_gindex(FFC_PARAMS *params, int index);
+void ffc_params_set_pcounter(FFC_PARAMS *params, int index);
+void ffc_params_set_h(FFC_PARAMS *params, int index);
+
int ffc_params_set_validate_params(FFC_PARAMS *params,
const unsigned char *seed, size_t seedlen,
int counter);
int ffc_validate_private_key(const BIGNUM *upper, const BIGNUM *priv_key,
int *ret);
-int ffc_fromdata(FFC_PARAMS *ffc, const OSSL_PARAM params[]);
+int ffc_params_todata(const FFC_PARAMS *ffc, OSSL_PARAM_BLD *tmpl,
+ OSSL_PARAM params[]);
+int ffc_params_fromdata(FFC_PARAMS *ffc, const OSSL_PARAM params[]);
+int ffc_named_group_to_nid(const char *name);
+const char *ffc_named_group_from_nid(int nid);
+int ffc_set_group_pqg(FFC_PARAMS *ffc, const char *group_name);
#endif /* OSSL_INTERNAL_FFC_H */
#define OSSL_PKEY_PARAM_FFC_P "p"
#define OSSL_PKEY_PARAM_FFC_G "g"
#define OSSL_PKEY_PARAM_FFC_Q "q"
+#define OSSL_PKEY_PARAM_FFC_GINDEX "gindex"
+#define OSSL_PKEY_PARAM_FFC_PCOUNTER "pcounter"
+#define OSSL_PKEY_PARAM_FFC_SEED "seed"
+#define OSSL_PKEY_PARAM_FFC_COFACTOR "j"
+#define OSSL_PKEY_PARAM_FFC_H "hindex"
+#define OSSL_PKEY_PARAM_FFC_GROUP "group"
/* Elliptic Curve Domain Parameters */
#define OSSL_PKEY_PARAM_EC_NAME "curve-name"
#define OSSL_PKEY_PARAM_RSA_BITS OSSL_PKEY_PARAM_BITS
#define OSSL_PKEY_PARAM_RSA_PRIMES "primes"
+/* Key generation parameters */
+#define OSSL_PKEY_PARAM_FFC_TYPE "type"
+#define OSSL_PKEY_PARAM_FFC_PBITS "pbits"
+#define OSSL_PKEY_PARAM_FFC_QBITS "qbits"
+#define OSSL_PKEY_PARAM_FFC_DIGEST OSSL_PKEY_PARAM_DIGEST
+#define OSSL_PKEY_PARAM_FFC_DIGEST_PROPS OSSL_PKEY_PARAM_PROPERTIES
+
/* Key Exchange parameters */
#define OSSL_EXCHANGE_PARAM_PAD "pad" /* uint */
DEPRECATEDIN_3_0(DH *DSA_dup_DH(const DSA *r))
# endif
-# define EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, nbits) \
- EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN, \
- EVP_PKEY_CTRL_DSA_PARAMGEN_BITS, nbits, NULL)
-# define EVP_PKEY_CTX_set_dsa_paramgen_q_bits(ctx, qbits) \
- EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN, \
- EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS, qbits, NULL)
-# define EVP_PKEY_CTX_set_dsa_paramgen_md(ctx, md) \
- EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN, \
- EVP_PKEY_CTRL_DSA_PARAMGEN_MD, 0, (void *)(md))
+int EVP_PKEY_CTX_set_dsa_paramgen_bits(EVP_PKEY_CTX *ctx, int nbits);
+int EVP_PKEY_CTX_set_dsa_paramgen_q_bits(EVP_PKEY_CTX *ctx, int qbits);
+int EVP_PKEY_CTX_set_dsa_paramgen_md_props(EVP_PKEY_CTX *ctx,
+ const char *md_name,
+ const char *md_properties);
+int EVP_PKEY_CTX_set_dsa_paramgen_gindex(EVP_PKEY_CTX *ctx, int gindex);
+int EVP_PKEY_CTX_set_dsa_paramgen_type(EVP_PKEY_CTX *ctx, const char *name);
+int EVP_PKEY_CTX_set_dsa_paramgen_seed(EVP_PKEY_CTX *ctx,
+ const unsigned char *seed,
+ size_t seedlen);
+int EVP_PKEY_CTX_set_dsa_paramgen_md(EVP_PKEY_CTX *ctx, const EVP_MD *md);
# define EVP_PKEY_CTRL_DSA_PARAMGEN_BITS (EVP_PKEY_ALG_CTRL + 1)
# define EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS (EVP_PKEY_ALG_CTRL + 2)
#include <openssl/bn.h>
#include <openssl/dh.h>
#include <openssl/params.h>
+#include <openssl/param_build.h>
#include "prov/implementations.h"
#include "prov/providercommon.h"
#include "prov/provider_ctx.h"
#include "crypto/dh.h"
-#include "openssl/param_build.h"
static OSSL_OP_keymgmt_new_fn dh_newdata;
static OSSL_OP_keymgmt_free_fn dh_freedata;
ok = 1;
if ((selection & OSSL_KEYMGMT_SELECT_ALL_PARAMETERS) != 0)
- ok = ok && ffc_fromdata(dh_get0_params(dh), params);
+ ok = ok && ffc_params_fromdata(dh_get0_params(dh), params);
if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0)
ok = ok && dh_key_fromdata(dh, params);
void *cbarg)
{
DH *dh = keydata;
- OSSL_PARAM_BLD *tmpl;
+ OSSL_PARAM_BLD *tmpl = NULL;
OSSL_PARAM *params = NULL;
int ok = 1;
if (!ok
|| (params = OSSL_PARAM_BLD_to_param(tmpl)) == NULL) {
- OSSL_PARAM_BLD_free(tmpl);
- return 0;
+ ok = 0;
+ goto err;
}
- OSSL_PARAM_BLD_free(tmpl);
-
ok = param_cb(params, cbarg);
OSSL_PARAM_BLD_free_params(params);
+err:
+ OSSL_PARAM_BLD_free(tmpl);
return ok;
}
*/
#include "internal/deprecated.h"
+#include "e_os.h" /* strcasecmp */
#include <openssl/core_numbers.h>
#include <openssl/core_names.h>
#include <openssl/bn.h>
-#include <openssl/params.h>
-#include "prov/implementations.h"
+#include <openssl/err.h>
#include "prov/providercommon.h"
+#include "prov/implementations.h"
#include "prov/provider_ctx.h"
#include "crypto/dsa.h"
-#include "openssl/param_build.h"
+#include "internal/sizes.h"
+#include "internal/nelem.h"
+#include "internal/param_build_set.h"
static OSSL_OP_keymgmt_new_fn dsa_newdata;
static OSSL_OP_keymgmt_free_fn dsa_freedata;
+static OSSL_OP_keymgmt_gen_init_fn dsa_gen_init;
+static OSSL_OP_keymgmt_gen_set_template_fn dsa_gen_set_template;
+static OSSL_OP_keymgmt_gen_set_params_fn dsa_gen_set_params;
+static OSSL_OP_keymgmt_gen_settable_params_fn dsa_gen_settable_params;
+static OSSL_OP_keymgmt_gen_fn dsa_gen;
+static OSSL_OP_keymgmt_gen_cleanup_fn dsa_gen_cleanup;
static OSSL_OP_keymgmt_get_params_fn dsa_get_params;
static OSSL_OP_keymgmt_gettable_params_fn dsa_gettable_params;
static OSSL_OP_keymgmt_has_fn dsa_has;
static OSSL_OP_keymgmt_export_types_fn dsa_export_types;
#define DSA_DEFAULT_MD "SHA256"
-#define DSA_POSSIBLE_SELECTIONS \
+#define DSA_POSSIBLE_SELECTIONS \
(OSSL_KEYMGMT_SELECT_KEYPAIR | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS)
-static int domparams_to_params(DSA *dsa, OSSL_PARAM_BLD *tmpl)
-{
- const BIGNUM *dsa_p = NULL, *dsa_q = NULL, *dsa_g = NULL;
+struct dsa_gen_ctx {
+ OPENSSL_CTX *libctx;
+
+ FFC_PARAMS *ffc_params;
+ int selection;
+ /* All these parameters are used for parameter generation only */
+ size_t pbits;
+ size_t qbits;
+ EVP_MD *md;
+ unsigned char *seed; /* optional FIPS186-4 param for testing */
+ size_t seedlen;
+ int gindex; /* optional FIPS186-4 generator index (ignored if -1) */
+ int gen_type; /* DSA_PARAMGEN_TYPE_FIPS_186_2 or DSA_PARAMGEN_TYPE_FIPS_186_4 */
+ int pcounter;
+ int hindex;
+ OSSL_CALLBACK *cb;
+ void *cbarg;
+};
+typedef struct dh_name2id_st{
+ const char *name;
+ int id;
+} DSA_GENTYPE_NAME2ID;
- if (dsa == NULL)
- return 0;
+static const DSA_GENTYPE_NAME2ID dsatype2id[]=
+{
+ { "default", DSA_PARAMGEN_TYPE_FIPS_186_4 },
+ { "fips186_4", DSA_PARAMGEN_TYPE_FIPS_186_4 },
+ { "fips186_2", DSA_PARAMGEN_TYPE_FIPS_186_2 },
+};
- DSA_get0_pqg(dsa, &dsa_p, &dsa_q, &dsa_g);
- if (dsa_p != NULL
- && !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_P, dsa_p))
- return 0;
- if (dsa_q != NULL
- && !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_Q, dsa_q))
- return 0;
- if (dsa_g != NULL
- && !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_G, dsa_g))
- return 0;
+static int dsa_gen_type_name2id(const char *name)
+{
+ size_t i;
- return 1;
+ for (i = 0; i < OSSL_NELEM(dsatype2id); ++i) {
+ if (strcasecmp(dsatype2id[i].name, name) == 0)
+ return dsatype2id[i].id;
+ }
+ return -1;
}
-static int key_to_params(DSA *dsa, OSSL_PARAM_BLD *tmpl)
+static int dsa_key_todata(DSA *dsa, OSSL_PARAM_BLD *bld, OSSL_PARAM params[])
{
- const BIGNUM *priv_key = NULL, *pub_key = NULL;
+ const BIGNUM *priv = NULL, *pub = NULL;
if (dsa == NULL)
return 0;
- if (!domparams_to_params(dsa, tmpl))
- return 0;
- DSA_get0_key(dsa, &pub_key, &priv_key);
- if (priv_key != NULL
- && !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_PRIV_KEY, priv_key))
+ DSA_get0_key(dsa, &pub, &priv);
+ if (priv != NULL
+ && !ossl_param_build_set_bn(bld, params, OSSL_PKEY_PARAM_PRIV_KEY, priv))
return 0;
- if (pub_key != NULL
- && !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_PUB_KEY, pub_key))
+ if (pub != NULL
+ && !ossl_param_build_set_bn(bld, params, OSSL_PKEY_PARAM_PUB_KEY, pub))
return 0;
return 1;
static int dsa_import(void *keydata, int selection, const OSSL_PARAM params[])
{
DSA *dsa = keydata;
- int ok = 0;
+ int ok = 1;
if (dsa == NULL)
return 0;
- if ((selection & DSA_POSSIBLE_SELECTIONS) != 0)
- ok = 1;
+ if ((selection & DSA_POSSIBLE_SELECTIONS) == 0)
+ return 0;
if ((selection & OSSL_KEYMGMT_SELECT_ALL_PARAMETERS) != 0)
- ok = ok && ffc_fromdata(dsa_get0_params(dsa), params);
+ ok = ok && dsa_ffc_params_fromdata(dsa, params);
if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0)
ok = ok && dsa_key_fromdata(dsa, params);
int ok = 1;
if (dsa == NULL)
- goto err;;
+ goto err;
if ((selection & OSSL_KEYMGMT_SELECT_ALL_PARAMETERS) != 0)
- ok = ok && domparams_to_params(dsa, tmpl);
+ ok = ok && ffc_params_todata(dsa_get0_params(dsa), tmpl, NULL);
if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0)
- ok = ok && key_to_params(dsa, tmpl);
+ ok = ok && dsa_key_todata(dsa, tmpl, NULL);
if (!ok
|| (params = OSSL_PARAM_BLD_to_param(tmpl)) == NULL)
/* IMEXPORT = IMPORT + EXPORT */
-# define DSA_IMEXPORTABLE_PARAMETERS \
- OSSL_PARAM_BN(OSSL_PKEY_PARAM_FFC_P, NULL, 0), \
- OSSL_PARAM_BN(OSSL_PKEY_PARAM_FFC_Q, NULL, 0), \
- OSSL_PARAM_BN(OSSL_PKEY_PARAM_FFC_G, NULL, 0)
+# define DSA_IMEXPORTABLE_PARAMETERS \
+ OSSL_PARAM_BN(OSSL_PKEY_PARAM_FFC_P, NULL, 0), \
+ OSSL_PARAM_BN(OSSL_PKEY_PARAM_FFC_Q, NULL, 0), \
+ OSSL_PARAM_BN(OSSL_PKEY_PARAM_FFC_G, NULL, 0), \
+ OSSL_PARAM_BN(OSSL_PKEY_PARAM_FFC_COFACTOR, NULL, 0), \
+ OSSL_PARAM_int(OSSL_PKEY_PARAM_FFC_GINDEX, NULL), \
+ OSSL_PARAM_int(OSSL_PKEY_PARAM_FFC_PCOUNTER, NULL), \
+ OSSL_PARAM_int(OSSL_PKEY_PARAM_FFC_H, NULL), \
+ OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_FFC_GROUP, NULL, 0), \
+ OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_FFC_SEED, NULL, 0)
# define DSA_IMEXPORTABLE_PUBLIC_KEY \
OSSL_PARAM_BN(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0)
# define DSA_IMEXPORTABLE_PRIVATE_KEY \
if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_DEFAULT_DIGEST)) != NULL
&& !OSSL_PARAM_set_utf8_string(p, DSA_DEFAULT_MD))
return 0;
- return 1;
+ return ffc_params_todata(dsa_get0_params(dsa), NULL, params)
+ && dsa_key_todata(dsa, NULL, params);
}
static const OSSL_PARAM dsa_params[] = {
OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL),
OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL),
OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_DEFAULT_DIGEST, NULL, 0),
+ DSA_IMEXPORTABLE_PARAMETERS,
+ DSA_IMEXPORTABLE_PUBLIC_KEY,
+ DSA_IMEXPORTABLE_PRIVATE_KEY,
OSSL_PARAM_END
};
return ok;
}
+static void *dsa_gen_init(void *provctx, int selection)
+{
+ OPENSSL_CTX *libctx = PROV_LIBRARY_CONTEXT_OF(provctx);
+ struct dsa_gen_ctx *gctx = NULL;
+
+ if ((selection & DSA_POSSIBLE_SELECTIONS) == 0)
+ return NULL;
+
+ if ((gctx = OPENSSL_zalloc(sizeof(*gctx))) != NULL) {
+ gctx->selection = selection;
+ gctx->libctx = libctx;
+ gctx->pbits = 2048;
+ gctx->qbits = 224;
+ gctx->md = NULL;
+ gctx->gen_type = DSA_PARAMGEN_TYPE_FIPS_186_4;
+ gctx->gindex = -1;
+ gctx->pcounter = -1;
+ gctx->hindex = 0;
+ }
+ return gctx;
+}
+
+static int dsa_gen_set_template(void *genctx, void *templ)
+{
+ struct dsa_gen_ctx *gctx = genctx;
+ DSA *dsa = templ;
+
+ if (gctx == NULL || dsa == NULL)
+ return 0;
+ gctx->ffc_params = dsa_get0_params(dsa);
+ return 1;
+}
+
+static int dsa_set_gen_seed(struct dsa_gen_ctx *gctx, unsigned char *seed,
+ size_t seedlen)
+{
+ OPENSSL_clear_free(gctx->seed, gctx->seedlen);
+ gctx->seed = NULL;
+ gctx->seedlen = 0;
+ if (seed != NULL && seedlen > 0) {
+ gctx->seed = OPENSSL_memdup(seed, seedlen);
+ if (gctx->seed == NULL)
+ return 0;
+ gctx->seedlen = seedlen;
+ }
+ return 1;
+}
+
+static int dsa_gen_set_params(void *genctx, const OSSL_PARAM params[])
+{
+ struct dsa_gen_ctx *gctx = genctx;
+ const OSSL_PARAM *p;
+
+ if (gctx == NULL)
+ return 0;
+
+ 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 = dsa_gen_type_name2id(p->data)) == -1)) {
+ ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_INVALID_ARGUMENT);
+ return 0;
+ }
+ }
+ p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_GINDEX);
+ if (p != NULL
+ && !OSSL_PARAM_get_int(p, &gctx->gindex))
+ return 0;
+ p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_PCOUNTER);
+ if (p != NULL
+ && !OSSL_PARAM_get_int(p, &gctx->pcounter))
+ return 0;
+ p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_H);
+ if (p != NULL
+ && !OSSL_PARAM_get_int(p, &gctx->hindex))
+ return 0;
+ p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_SEED);
+ if (p != NULL
+ && (p->data_type != OSSL_PARAM_OCTET_STRING
+ || !dsa_set_gen_seed(gctx, p->data, p->data_size)))
+ return 0;
+ if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_PBITS)) != NULL
+ && !OSSL_PARAM_get_size_t(p, &gctx->pbits))
+ return 0;
+ if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_QBITS)) != NULL
+ && !OSSL_PARAM_get_size_t(p, &gctx->qbits))
+ return 0;
+ p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_DIGEST);
+ if (p != NULL) {
+ const OSSL_PARAM *p1;
+ char mdprops[OSSL_MAX_PROPQUERY_SIZE] = { '\0' };
+ char *str = mdprops;
+
+ if (p->data_type != OSSL_PARAM_UTF8_STRING)
+ return 0;
+ p1 = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_DIGEST_PROPS);
+ if (p1 != NULL) {
+ if (!OSSL_PARAM_get_utf8_string(p1, &str, sizeof(mdprops)))
+ return 0;
+ }
+ EVP_MD_free(gctx->md);
+ gctx->md = EVP_MD_fetch(gctx->libctx, p->data, mdprops);
+ if (gctx->md == NULL)
+ return 0;
+ }
+ return 1;
+}
+
+static const OSSL_PARAM *dsa_gen_settable_params(void *provctx)
+{
+ static OSSL_PARAM settable[] = {
+ OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_FFC_TYPE, NULL, 0),
+ OSSL_PARAM_size_t(OSSL_PKEY_PARAM_FFC_PBITS, NULL),
+ OSSL_PARAM_size_t(OSSL_PKEY_PARAM_FFC_QBITS, NULL),
+ OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_FFC_DIGEST, NULL, 0),
+ OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_FFC_DIGEST_PROPS, NULL, 0),
+ OSSL_PARAM_int(OSSL_PKEY_PARAM_FFC_GINDEX, NULL),
+ OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_FFC_SEED, NULL, 0),
+ OSSL_PARAM_int(OSSL_PKEY_PARAM_FFC_PCOUNTER, NULL),
+ OSSL_PARAM_int(OSSL_PKEY_PARAM_FFC_H, NULL),
+ OSSL_PARAM_END
+ };
+ return settable;
+}
+
+static int dsa_gencb(int p, int n, BN_GENCB *cb)
+{
+ struct dsa_gen_ctx *gctx = BN_GENCB_get_arg(cb);
+ OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END };
+
+ params[0] = OSSL_PARAM_construct_int(OSSL_GEN_PARAM_POTENTIAL, &p);
+ params[1] = OSSL_PARAM_construct_int(OSSL_GEN_PARAM_ITERATION, &n);
+
+ return gctx->cb(params, gctx->cbarg);
+}
+
+static void *dsa_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
+{
+ struct dsa_gen_ctx *gctx = genctx;
+ DSA *dsa = NULL;
+ BN_GENCB *gencb = NULL;
+ int ret = 0;
+ FFC_PARAMS *ffc;
+
+ if (gctx == NULL)
+ return NULL;
+ dsa = dsa_new_with_ctx(gctx->libctx);
+ if (dsa == NULL)
+ return NULL;
+
+ gctx->cb = osslcb;
+ gctx->cbarg = cbarg;
+ gencb = BN_GENCB_new();
+ if (gencb != NULL)
+ BN_GENCB_set(gencb, dsa_gencb, genctx);
+
+ ffc = dsa_get0_params(dsa);
+ /* Copy the template value if one was passed */
+ if (gctx->ffc_params != NULL
+ && !ffc_params_copy(ffc, gctx->ffc_params))
+ goto end;
+
+ if (gctx->seed != NULL
+ && !ffc_params_set_seed(ffc, gctx->seed, gctx->seedlen))
+ goto end;
+ if (gctx->gindex != -1) {
+ ffc_params_set_gindex(ffc, gctx->gindex);
+ if (gctx->pcounter != -1)
+ ffc_params_set_pcounter(ffc, gctx->pcounter);
+ } else if (gctx->hindex != 0) {
+ ffc_params_set_h(ffc, gctx->hindex);
+ }
+ if ((gctx->selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) {
+
+ if (dsa_generate_ffc_parameters(dsa, gctx->gen_type,
+ gctx->pbits, gctx->qbits, gctx->md,
+ gencb) <= 0)
+ goto end;
+ }
+ if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
+ if (ffc->p == NULL
+ || ffc->q == NULL
+ || ffc->g == NULL)
+ goto end;
+ if (DSA_generate_key(dsa) <= 0)
+ goto end;
+ }
+ ret = 1;
+end:
+ if (ret <= 0) {
+ DSA_free(dsa);
+ dsa = NULL;
+ }
+ BN_GENCB_free(gencb);
+ return dsa;
+}
+
+static void dsa_gen_cleanup(void *genctx)
+{
+ struct dsa_gen_ctx *gctx = genctx;
+
+ if (gctx == NULL)
+ return;
+
+ OPENSSL_clear_free(gctx->seed, gctx->seedlen);
+ EVP_MD_free(gctx->md);
+ OPENSSL_free(gctx);
+}
+
const OSSL_DISPATCH dsa_keymgmt_functions[] = {
{ OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))dsa_newdata },
+ { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))dsa_gen_init },
+ { OSSL_FUNC_KEYMGMT_GEN_SET_TEMPLATE, (void (*)(void))dsa_gen_set_template },
+ { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))dsa_gen_set_params },
+ { OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS,
+ (void (*)(void))dsa_gen_settable_params },
+ { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))dsa_gen },
+ { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))dsa_gen_cleanup },
{ OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))dsa_freedata },
{ OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))dsa_get_params },
{ OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))dsa_gettable_params },
$SERIALIZER_GOAL=../../libimplementations.a
$RSA_GOAL=../../libimplementations.a
+$FFC_GOAL=../../libimplementations.a
$DH_GOAL=../../libimplementations.a
$DSA_GOAL=../../libimplementations.a
$ECX_GOAL=../../libimplementations.a
SOURCE[$SERIALIZER_GOAL]=serializer_common.c
SOURCE[$RSA_GOAL]=serializer_rsa.c serializer_rsa_priv.c serializer_rsa_pub.c
+IF[{- !$disabled{"dh"} || !$disabled{"dsa"} -}]
+ SOURCE[$FFC_GOAL]=serializer_ffc_params.c
+ENDIF
IF[{- !$disabled{dh} -}]
SOURCE[$DH_GOAL]=serializer_dh.c serializer_dh_priv.c serializer_dh_pub.c serializer_dh_param.c
ENDIF
#include <openssl/types.h>
#include <openssl/x509.h> /* i2d_X509_PUBKEY_bio() */
#include "crypto/bn.h" /* bn_get_words() */
+#include "crypto/ctype.h"
#include "crypto/ecx.h"
#include "prov/bio.h" /* ossl_prov_bio_printf() */
#include "prov/implementations.h"
int ossl_prov_print_labeled_bignum(BIO *out, const char *label,
const BIGNUM *bn)
{
- const char *neg;
+ int ret = 0, use_sep = 0;
+ char *hex_str = NULL, *p;
+ const char spaces[] = " ";
const char *post_label_spc = " ";
+
+ const char *neg = "";
int bytes;
- BN_ULONG *words;
- int n, i;
if (bn == NULL)
return 0;
post_label_spc = "";
}
- bytes = BN_num_bytes(bn);
- words = bn_get_words(bn);
- neg = BN_is_negative(bn) ? "-" : "";
-
if (BN_is_zero(bn))
return ossl_prov_bio_printf(out, "%s%s0\n", label, post_label_spc);
- if (BN_num_bytes(bn) <= BN_BYTES)
+ if (BN_num_bytes(bn) <= BN_BYTES) {
+ BN_ULONG *words = bn_get_words(bn);
+
+ if (BN_is_negative(bn))
+ neg = "-";
+
return ossl_prov_bio_printf(out,
"%s%s%s" BN_FMTu " (%s0x" BN_FMTx ")\n",
label, post_label_spc, neg, words[0],
neg, words[0]);
+ }
- if (neg[0] == '-')
+ hex_str = BN_bn2hex(bn);
+ p = hex_str;
+ if (*p == '-') {
+ ++p;
neg = " (Negative)";
-
+ }
if (ossl_prov_bio_printf(out, "%s%s\n", label, neg) <= 0)
- return 0;
+ goto err;
/* Keep track of how many bytes we have printed out so far */
- n = 0;
-
- /*
- * OpenSSL BIGNUMs are little endian limbs, so we print them last to
- * first limb.
- * i is used as limb index, j is used as the "byte index" in the limb
- */
- for (i = bytes / BN_BYTES - 1; i >= 0; i--) {
- BN_ULONG l = words[i];
- int j;
-
- for (j = BN_BYTES - 1; j >= 0; j--) {
- int o = 8 * j;
- int b = ((l & (0xffLU << o)) >> o) & 0xff;
-
- /* Indent every new line with 4 spaces */
- if ((n % 15) == 0) {
- if (n > 0)
- if (ossl_prov_bio_printf(out, "\n") <= 0)
- return 0;
- if (ossl_prov_bio_printf(out, " ") <= 0)
- return 0;
- }
-
- /*
- * Upper bit set, then we print an extra zero and pretend the
- * BIGNUM was one byte longer
- */
- if (n == 0 && b > 127) {
- if (ossl_prov_bio_printf(out, "%02x:", 0) <= 0)
- return 0;
- n++;
- bytes++;
- }
-
- if (++n < bytes) {
- if (ossl_prov_bio_printf(out, "%02x:", b) <= 0)
- return 0;
- } else {
- if (ossl_prov_bio_printf(out, "%02x", b) <= 0)
- return 0;
- }
+ bytes = 0;
+
+ if (ossl_prov_bio_printf(out, "%s", spaces) <= 0)
+ goto err;
+
+ /* Add a leading 00 if the top bit is set */
+ if (*p >= '8') {
+ if (ossl_prov_bio_printf(out, "%02x", 0) <= 0)
+ goto err;
+ ++bytes;
+ use_sep = 1;
+ }
+ while (*p != '\0') {
+ /* Do a newline after every 15 hex bytes + add the space indent */
+ if ((bytes % 15) == 0 && bytes > 0) {
+ if (ossl_prov_bio_printf(out, ":\n%s", spaces) <= 0)
+ goto err;
+ use_sep = 0; /* The first byte on the next line doesnt have a : */
}
+ if (ossl_prov_bio_printf(out, "%s%c%c", use_sep ? ":" : "",
+ ossl_tolower(p[0]), ossl_tolower(p[1])) <= 0)
+ goto err;
+ ++bytes;
+ p += 2;
+ use_sep = 1;
}
if (ossl_prov_bio_printf(out, "\n") <= 0)
- return 0;
-
- return 1;
+ goto err;
+ ret = 1;
+err:
+ OPENSSL_free(hex_str);
+ return ret;
}
/* Number of octets per line */
#include "prov/implementations.h" /* rsa_keymgmt_functions */
#include "prov/providercommonerr.h" /* PROV_R_BN_ERROR */
#include "serializer_local.h"
+#include "internal/ffc.h"
+#include "crypto/dsa.h"
OSSL_OP_keymgmt_new_fn *ossl_prov_get_keymgmt_dsa_new(void)
{
{
const char *type_label = NULL;
const BIGNUM *priv_key = NULL, *pub_key = NULL;
- const BIGNUM *p = NULL, *q = NULL, *g = NULL;
+ const BIGNUM *p = NULL;
switch (type) {
goto null_err;
}
- p = DSA_get0_p(dsa);
- q = DSA_get0_q(dsa);
- g = DSA_get0_p(dsa);
- if (p == NULL || q == NULL || g == NULL)
+ p = DSA_get0_p(dsa);
+ if (p == NULL)
goto null_err;
- if (ossl_prov_bio_printf(out, "%s: (%d bit)\n", type_label, BN_num_bits(p))
- <= 0)
+ if (ossl_prov_bio_printf(out, "%s: (%d bit)\n", type_label,
+ BN_num_bits(p)) <= 0)
goto err;
if (priv_key != NULL
&& !ossl_prov_print_labeled_bignum(out, "priv:", priv_key))
if (pub_key != NULL
&& !ossl_prov_print_labeled_bignum(out, "pub: ", pub_key))
goto err;
- if (!ossl_prov_print_labeled_bignum(out, "P: ", p))
- goto err;
- if (!ossl_prov_print_labeled_bignum(out, "Q: ", q))
- goto err;
- if (!ossl_prov_print_labeled_bignum(out, "G: ", g))
+ if (!ffc_params_prov_print(out, dsa_get0_params(dsa)))
goto err;
return 1;
--- /dev/null
+/*
+ * 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
+ */
+
+/* Utility function for printing DSA/DH params. */
+
+#include "prov/bio.h"
+#include "serializer_local.h"
+
+int ffc_params_prov_print(BIO *out, const FFC_PARAMS *ffc)
+{
+ if (ffc->nid != NID_undef) {
+ const char *name = ffc_named_group_from_nid(ffc->nid);
+
+ if (name == NULL)
+ goto err;
+ if (ossl_prov_bio_printf(out, "GROUP: %s\n", name) <= 0)
+ goto err;
+ return 1;
+ }
+
+ if (!ossl_prov_print_labeled_bignum(out, "P: ", ffc->p))
+ goto err;
+ if (ffc->q != NULL) {
+ if (!ossl_prov_print_labeled_bignum(out, "Q: ", ffc->q))
+ goto err;
+ }
+ if (!ossl_prov_print_labeled_bignum(out, "G: ", ffc->g))
+ goto err;
+ if (ffc->j != NULL) {
+ if (!ossl_prov_print_labeled_bignum(out, "J: ", ffc->j))
+ goto err;
+ }
+ if (ffc->seed != NULL) {
+ if (!ossl_prov_print_labeled_buf(out, "SEED:", ffc->seed, ffc->seedlen))
+ goto err;
+ }
+ if (ffc->gindex != -1) {
+ if (ossl_prov_bio_printf(out, "gindex: %d\n", ffc->gindex) <= 0)
+ goto err;
+ }
+ if (ffc->pcounter != -1) {
+ if (ossl_prov_bio_printf(out, "pcounter: %d\n", ffc->pcounter) <= 0)
+ goto err;
+ }
+ if (ffc->h != 0) {
+ if (ossl_prov_bio_printf(out, "h: %d\n", ffc->h) <= 0)
+ goto err;
+ }
+ return 1;
+err:
+ return 0;
+}
#include <openssl/x509.h> /* X509_SIG */
#include <openssl/types.h>
#include <crypto/ecx.h>
+#include "internal/ffc.h"
struct pkcs8_encrypt_ctx_st {
/* Set to 1 if intending to encrypt/decrypt, otherwise 0 */
int ossl_prov_ec_pub_to_der(const void *eckey, unsigned char **pder);
int ossl_prov_ec_priv_to_der(const void *eckey, unsigned char **pder);
+int ffc_params_prov_print(BIO *out, const FFC_PARAMS *ffc);
int ossl_prov_prepare_dh_params(const void *dh, int nid,
void **pstr, int *pstrtype);
int ossl_prov_dh_pub_to_der(const void *dh, unsigned char **pder);
#include <openssl/rand.h>
#include <openssl/bn.h>
#include <openssl/dsa.h>
+#include <openssl/evp.h>
+#include <openssl/core_names.h>
#include "testutil.h"
#include "internal/nelem.h"
#ifndef OPENSSL_NO_DSA
static int dsa_cb(int p, int n, BN_GENCB *arg);
-/*
- * seed, out_p, out_q, out_g are taken from the updated Appendix 5 to FIPS
- * PUB 186 and also appear in Appendix 5 to FIPS PIB 186-1
- */
-static unsigned char seed[20] = {
- 0xd5, 0x01, 0x4e, 0x4b, 0x60, 0xef, 0x2b, 0xa8, 0xb6, 0x21, 0x1b, 0x40,
- 0x62, 0xba, 0x32, 0x24, 0xe0, 0x42, 0x7d, 0xd3,
-};
-
-static unsigned char out_p[] = {
- 0x8d, 0xf2, 0xa4, 0x94, 0x49, 0x22, 0x76, 0xaa,
- 0x3d, 0x25, 0x75, 0x9b, 0xb0, 0x68, 0x69, 0xcb,
- 0xea, 0xc0, 0xd8, 0x3a, 0xfb, 0x8d, 0x0c, 0xf7,
- 0xcb, 0xb8, 0x32, 0x4f, 0x0d, 0x78, 0x82, 0xe5,
- 0xd0, 0x76, 0x2f, 0xc5, 0xb7, 0x21, 0x0e, 0xaf,
- 0xc2, 0xe9, 0xad, 0xac, 0x32, 0xab, 0x7a, 0xac,
- 0x49, 0x69, 0x3d, 0xfb, 0xf8, 0x37, 0x24, 0xc2,
- 0xec, 0x07, 0x36, 0xee, 0x31, 0xc8, 0x02, 0x91,
-};
-
-static unsigned char out_q[] = {
- 0xc7, 0x73, 0x21, 0x8c, 0x73, 0x7e, 0xc8, 0xee,
- 0x99, 0x3b, 0x4f, 0x2d, 0xed, 0x30, 0xf4, 0x8e,
- 0xda, 0xce, 0x91, 0x5f,
-};
-
-static unsigned char out_g[] = {
- 0x62, 0x6d, 0x02, 0x78, 0x39, 0xea, 0x0a, 0x13,
- 0x41, 0x31, 0x63, 0xa5, 0x5b, 0x4c, 0xb5, 0x00,
- 0x29, 0x9d, 0x55, 0x22, 0x95, 0x6c, 0xef, 0xcb,
- 0x3b, 0xff, 0x10, 0xf3, 0x99, 0xce, 0x2c, 0x2e,
- 0x71, 0xcb, 0x9d, 0xe5, 0xfa, 0x24, 0xba, 0xbf,
- 0x58, 0xe5, 0xb7, 0x95, 0x21, 0x92, 0x5c, 0x9c,
- 0xc4, 0x2e, 0x9f, 0x6f, 0x46, 0x4b, 0x08, 0x8c,
- 0xc5, 0x72, 0xaf, 0x53, 0xe6, 0xd7, 0x88, 0x02,
-};
-
-static const unsigned char str1[] = "12345678901234567890";
-
static int dsa_test(void)
{
BN_GENCB *cb;
unsigned char sig[256];
unsigned int siglen;
const BIGNUM *p = NULL, *q = NULL, *g = NULL;
+ /*
+ * seed, out_p, out_q, out_g are taken from the updated Appendix 5 to FIPS
+ * PUB 186 and also appear in Appendix 5 to FIPS PIB 186-1
+ */
+ static unsigned char seed[20] = {
+ 0xd5, 0x01, 0x4e, 0x4b, 0x60, 0xef, 0x2b, 0xa8,
+ 0xb6, 0x21, 0x1b, 0x40, 0x62, 0xba, 0x32, 0x24,
+ 0xe0, 0x42, 0x7d, 0xd3,
+ };
+ static unsigned char out_p[] = {
+ 0x8d, 0xf2, 0xa4, 0x94, 0x49, 0x22, 0x76, 0xaa,
+ 0x3d, 0x25, 0x75, 0x9b, 0xb0, 0x68, 0x69, 0xcb,
+ 0xea, 0xc0, 0xd8, 0x3a, 0xfb, 0x8d, 0x0c, 0xf7,
+ 0xcb, 0xb8, 0x32, 0x4f, 0x0d, 0x78, 0x82, 0xe5,
+ 0xd0, 0x76, 0x2f, 0xc5, 0xb7, 0x21, 0x0e, 0xaf,
+ 0xc2, 0xe9, 0xad, 0xac, 0x32, 0xab, 0x7a, 0xac,
+ 0x49, 0x69, 0x3d, 0xfb, 0xf8, 0x37, 0x24, 0xc2,
+ 0xec, 0x07, 0x36, 0xee, 0x31, 0xc8, 0x02, 0x91,
+ };
+ static unsigned char out_q[] = {
+ 0xc7, 0x73, 0x21, 0x8c, 0x73, 0x7e, 0xc8, 0xee,
+ 0x99, 0x3b, 0x4f, 0x2d, 0xed, 0x30, 0xf4, 0x8e,
+ 0xda, 0xce, 0x91, 0x5f,
+ };
+ static unsigned char out_g[] = {
+ 0x62, 0x6d, 0x02, 0x78, 0x39, 0xea, 0x0a, 0x13,
+ 0x41, 0x31, 0x63, 0xa5, 0x5b, 0x4c, 0xb5, 0x00,
+ 0x29, 0x9d, 0x55, 0x22, 0x95, 0x6c, 0xef, 0xcb,
+ 0x3b, 0xff, 0x10, 0xf3, 0x99, 0xce, 0x2c, 0x2e,
+ 0x71, 0xcb, 0x9d, 0xe5, 0xfa, 0x24, 0xba, 0xbf,
+ 0x58, 0xe5, 0xb7, 0x95, 0x21, 0x92, 0x5c, 0x9c,
+ 0xc4, 0x2e, 0x9f, 0x6f, 0x46, 0x4b, 0x08, 0x8c,
+ 0xc5, 0x72, 0xaf, 0x53, 0xe6, 0xd7, 0x88, 0x02,
+ };
+ static const unsigned char str1[] = "12345678901234567890";
if (!TEST_ptr(cb = BN_GENCB_new()))
goto end;
}
return 1;
}
+
+# define P 0
+# define Q 1
+# define G 2
+# define SEED 3
+# define PCOUNT 4
+# define GINDEX 5
+# define HCOUNT 6
+# define GROUP 7
+
+static int dsa_keygen_test(void)
+{
+ int ret = 0;
+ EVP_PKEY *param_key = NULL, *key = NULL;
+ EVP_PKEY_CTX *pg_ctx = NULL, *kg_ctx = NULL;
+ BIGNUM *p_in = NULL, *q_in = NULL, *g_in = NULL;
+ BIGNUM *p_out = NULL, *q_out = NULL, *g_out = NULL;
+ int gindex_out = 0, pcount_out = 0, hcount_out = 0;
+ unsigned char seed_out[32];
+ char group_out[32];
+ size_t len = 0;
+ static const unsigned char seed_data[] = {
+ 0xa6, 0xf5, 0x28, 0x8c, 0x50, 0x77, 0xa5, 0x68,
+ 0x6d, 0x3a, 0xf5, 0xf1, 0xc6, 0x4c, 0xdc, 0x35,
+ 0x95, 0x26, 0x3f, 0x03, 0xdc, 0x00, 0x3f, 0x44,
+ 0x7b, 0x2a, 0xc7, 0x29
+ };
+ static const unsigned char expected_p[]= {
+ 0xdb, 0x47, 0x07, 0xaf, 0xf0, 0x06, 0x49, 0x55,
+ 0xc9, 0xbb, 0x09, 0x41, 0xb8, 0xdb, 0x1f, 0xbc,
+ 0xa8, 0xed, 0x12, 0x06, 0x7f, 0x88, 0x49, 0xb8,
+ 0xc9, 0x12, 0x87, 0x21, 0xbb, 0x08, 0x6c, 0xbd,
+ 0xf1, 0x89, 0xef, 0x84, 0xd9, 0x7a, 0x93, 0xe8,
+ 0x45, 0x40, 0x81, 0xec, 0x37, 0x27, 0x1a, 0xa4,
+ 0x22, 0x51, 0x99, 0xf0, 0xde, 0x04, 0xdb, 0xea,
+ 0xa1, 0xf9, 0x37, 0x83, 0x80, 0x96, 0x36, 0x53,
+ 0xf6, 0xae, 0x14, 0x73, 0x33, 0x0f, 0xdf, 0x0b,
+ 0xf9, 0x2f, 0x08, 0x46, 0x31, 0xf9, 0x66, 0xcd,
+ 0x5a, 0xeb, 0x6c, 0xf3, 0xbb, 0x74, 0xf3, 0x88,
+ 0xf0, 0x31, 0x5c, 0xa4, 0xc8, 0x0f, 0x86, 0xf3,
+ 0x0f, 0x9f, 0xc0, 0x8c, 0x57, 0xe4, 0x7f, 0x95,
+ 0xb3, 0x62, 0xc8, 0x4e, 0xae, 0xf3, 0xd8, 0x14,
+ 0xcc, 0x47, 0xc2, 0x4b, 0x4f, 0xef, 0xaf, 0xcd,
+ 0xcf, 0xb2, 0xbb, 0xe8, 0xbe, 0x08, 0xca, 0x15,
+ 0x90, 0x59, 0x35, 0xef, 0x35, 0x1c, 0xfe, 0xeb,
+ 0x33, 0x2e, 0x25, 0x22, 0x57, 0x9c, 0x55, 0x23,
+ 0x0c, 0x6f, 0xed, 0x7c, 0xb6, 0xc7, 0x36, 0x0b,
+ 0xcb, 0x2b, 0x6a, 0x21, 0xa1, 0x1d, 0x55, 0x77,
+ 0xd9, 0x91, 0xcd, 0xc1, 0xcd, 0x3d, 0x82, 0x16,
+ 0x9c, 0xa0, 0x13, 0xa5, 0x83, 0x55, 0x3a, 0x73,
+ 0x7e, 0x2c, 0x44, 0x3e, 0x70, 0x2e, 0x50, 0x91,
+ 0x6e, 0xca, 0x3b, 0xef, 0xff, 0x85, 0x35, 0x70,
+ 0xff, 0x61, 0x0c, 0xb1, 0xb2, 0xb7, 0x94, 0x6f,
+ 0x65, 0xa4, 0x57, 0x62, 0xef, 0x21, 0x83, 0x0f,
+ 0x3e, 0x71, 0xae, 0x7d, 0xe4, 0xad, 0xfb, 0xe3,
+ 0xdd, 0xd6, 0x03, 0xda, 0x9a, 0xd8, 0x8f, 0x2d,
+ 0xbb, 0x90, 0x87, 0xf8, 0xdb, 0xdc, 0xec, 0x71,
+ 0xf2, 0xdb, 0x0b, 0x8e, 0xfc, 0x1a, 0x7e, 0x79,
+ 0xb1, 0x1b, 0x0d, 0xfc, 0x70, 0xec, 0x85, 0xc2,
+ 0xc5, 0xba, 0xb9, 0x69, 0x3f, 0x88, 0xbc, 0xcb
+ };
+ static const unsigned char expected_q[]= {
+ 0x99, 0xb6, 0xa0, 0xee, 0xb3, 0xa6, 0x99, 0x1a,
+ 0xb6, 0x67, 0x8d, 0xc1, 0x2b, 0x9b, 0xce, 0x2b,
+ 0x01, 0x72, 0x5a, 0x65, 0x76, 0x3d, 0x93, 0x69,
+ 0xe2, 0x56, 0xae, 0xd7
+ };
+ static const unsigned char expected_g[]= {
+ 0x63, 0xf8, 0xb6, 0xee, 0x2a, 0x27, 0xaf, 0x4f,
+ 0x4c, 0xf6, 0x08, 0x28, 0x87, 0x4a, 0xe7, 0x1f,
+ 0x45, 0x46, 0x27, 0x52, 0x3b, 0x7f, 0x6f, 0xd2,
+ 0x29, 0xcb, 0xe8, 0x11, 0x19, 0x25, 0x35, 0x76,
+ 0x99, 0xcb, 0x4f, 0x1b, 0xe0, 0xed, 0x32, 0x9e,
+ 0x05, 0xb5, 0xbe, 0xd7, 0xf6, 0x5a, 0xb2, 0xf6,
+ 0x0e, 0x0c, 0x7e, 0xf5, 0xe1, 0x05, 0xfe, 0xda,
+ 0xaf, 0x0f, 0x27, 0x1e, 0x40, 0x2a, 0xf7, 0xa7,
+ 0x23, 0x49, 0x2c, 0xd9, 0x1b, 0x0a, 0xbe, 0xff,
+ 0xc7, 0x7c, 0x7d, 0x60, 0xca, 0xa3, 0x19, 0xc3,
+ 0xb7, 0xe4, 0x43, 0xb0, 0xf5, 0x75, 0x44, 0x90,
+ 0x46, 0x47, 0xb1, 0xa6, 0x48, 0x0b, 0x21, 0x8e,
+ 0xee, 0x75, 0xe6, 0x3d, 0xa7, 0xd3, 0x7b, 0x31,
+ 0xd1, 0xd2, 0x9d, 0xe2, 0x8a, 0xfc, 0x57, 0xfd,
+ 0x8a, 0x10, 0x31, 0xeb, 0x87, 0x36, 0x3f, 0x65,
+ 0x72, 0x23, 0x2c, 0xd3, 0xd6, 0x17, 0xa5, 0x62,
+ 0x58, 0x65, 0x57, 0x6a, 0xd4, 0xa8, 0xfe, 0xec,
+ 0x57, 0x76, 0x0c, 0xb1, 0x4c, 0x93, 0xed, 0xb0,
+ 0xb4, 0xf9, 0x45, 0xb3, 0x3e, 0xdd, 0x47, 0xf1,
+ 0xfb, 0x7d, 0x25, 0x79, 0x3d, 0xfc, 0xa7, 0x39,
+ 0x90, 0x68, 0x6a, 0x6b, 0xae, 0xf2, 0x6e, 0x64,
+ 0x8c, 0xfb, 0xb8, 0xdd, 0x76, 0x4e, 0x4a, 0x69,
+ 0x8c, 0x97, 0x15, 0x77, 0xb2, 0x67, 0xdc, 0xeb,
+ 0x4a, 0x40, 0x6b, 0xb9, 0x47, 0x8f, 0xa6, 0xab,
+ 0x6e, 0x98, 0xc0, 0x97, 0x9a, 0x0c, 0xea, 0x00,
+ 0xfd, 0x56, 0x1a, 0x74, 0x9a, 0x32, 0x6b, 0xfe,
+ 0xbd, 0xdf, 0x6c, 0x82, 0x54, 0x53, 0x4d, 0x70,
+ 0x65, 0xe3, 0x8b, 0x37, 0xb8, 0xe4, 0x70, 0x08,
+ 0xb7, 0x3b, 0x30, 0x27, 0xaf, 0x1c, 0x77, 0xf3,
+ 0x62, 0xd4, 0x9a, 0x59, 0xba, 0xd1, 0x6e, 0x89,
+ 0x5c, 0x34, 0x9a, 0xa1, 0xb7, 0x4f, 0x7d, 0x8c,
+ 0xdc, 0xbc, 0x74, 0x25, 0x5e, 0xbf, 0x77, 0x46
+ };
+ int expected_c = 1316;
+ int expected_h = 2;
+
+ if (!TEST_ptr(p_in = BN_bin2bn(expected_p, sizeof(expected_p), NULL))
+ || !TEST_ptr(q_in = BN_bin2bn(expected_q, sizeof(expected_q), NULL))
+ || !TEST_ptr(g_in = BN_bin2bn(expected_g, sizeof(expected_g), NULL)))
+ goto end;
+ if (!TEST_ptr(pg_ctx = EVP_PKEY_CTX_new_from_name(NULL, "DSA", NULL))
+ || !TEST_int_gt(EVP_PKEY_paramgen_init(pg_ctx), 0)
+ || !TEST_true(EVP_PKEY_CTX_set_dsa_paramgen_bits(pg_ctx, 2048))
+ || !TEST_true(EVP_PKEY_CTX_set_dsa_paramgen_q_bits(pg_ctx, 224))
+ || !TEST_true(EVP_PKEY_CTX_set_dsa_paramgen_seed(pg_ctx, seed_data,
+ sizeof(seed_data)))
+ || !TEST_true(EVP_PKEY_CTX_set_dsa_paramgen_md_props(pg_ctx, "SHA256",
+ ""))
+ || !TEST_int_gt(EVP_PKEY_gen(pg_ctx, ¶m_key), 0)
+ || !TEST_ptr(kg_ctx = EVP_PKEY_CTX_new_from_pkey(NULL, param_key, NULL))
+ || !TEST_int_gt(EVP_PKEY_keygen_init(kg_ctx), 0)
+ || !TEST_int_gt(EVP_PKEY_gen(kg_ctx, &key), 0))
+ goto end;
+
+ if (!TEST_true(EVP_PKEY_get_bn_param(key, OSSL_PKEY_PARAM_FFC_P, &p_out))
+ || !TEST_BN_eq(p_in, p_out)
+ || !TEST_true(EVP_PKEY_get_bn_param(key, OSSL_PKEY_PARAM_FFC_Q, &q_out))
+ || !TEST_BN_eq(q_in, q_out)
+ || !TEST_true(EVP_PKEY_get_bn_param(key, OSSL_PKEY_PARAM_FFC_G, &g_out))
+ || !TEST_BN_eq(g_in, g_out)
+ || !TEST_true(EVP_PKEY_get_octet_string_param(
+ key, OSSL_PKEY_PARAM_FFC_SEED, seed_out,
+ sizeof(seed_out), &len))
+ || !TEST_mem_eq(seed_out, len, seed_data, sizeof(seed_data))
+ || !TEST_true(EVP_PKEY_get_int_param(key, OSSL_PKEY_PARAM_FFC_GINDEX,
+ &gindex_out))
+ || !TEST_int_eq(gindex_out, -1)
+ || !TEST_true(EVP_PKEY_get_int_param(key, OSSL_PKEY_PARAM_FFC_H,
+ &hcount_out))
+ || !TEST_int_eq(hcount_out, expected_h)
+ || !TEST_true(EVP_PKEY_get_int_param(key,
+ OSSL_PKEY_PARAM_FFC_PCOUNTER,
+ &pcount_out))
+ || !TEST_int_eq(pcount_out, expected_c)
+ || !TEST_false(EVP_PKEY_get_utf8_string_param(key,
+ OSSL_PKEY_PARAM_FFC_GROUP,
+ group_out,
+ sizeof(group_out), &len)))
+ goto end;
+ ret = 1;
+end:
+ BN_free(p_in);
+ BN_free(q_in);
+ BN_free(g_in);
+ BN_free(p_out);
+ BN_free(q_out);
+ BN_free(g_out);
+ EVP_PKEY_free(param_key);
+ EVP_PKEY_free(key);
+ EVP_PKEY_CTX_free(kg_ctx);
+ EVP_PKEY_CTX_free(pg_ctx);
+ return ret;
+}
+
#endif /* OPENSSL_NO_DSA */
int setup_tests(void)
{
#ifndef OPENSSL_NO_DSA
ADD_TEST(dsa_test);
+ ADD_TEST(dsa_keygen_test);
#endif
return 1;
}
{
char filename[80];
BIO *file = NULL;
- char buf[1024];
+ char buf[4096];
char *memdata, *fullfile = NULL;
const char *suffix;
size_t readbytes;
|| !TEST_true(EVP_PKEY_copy_parameters(copy_pk, pk)))
goto err;
- ret = test_print_key_using_pem("DH", pk)
- && test_print_key_using_serializer("DH", pk);
-
if (!TEST_ptr(key_ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pk, "")))
goto err;
if (!TEST_false(EVP_PKEY_check(key_ctx))
|| !TEST_true(EVP_PKEY_public_check(key_ctx))
|| !TEST_false(EVP_PKEY_private_check(key_ctx)) /* Need a q */
- || !TEST_true(EVP_PKEY_pairwise_check(key_ctx)))
+ || !TEST_false(EVP_PKEY_pairwise_check(key_ctx)))
goto err;
+ ret = test_print_key_using_pem("DH", pk)
+ && test_print_key_using_serializer("DH", pk);
err:
EVP_PKEY_free(pk);
EVP_PKEY_free(copy_pk);
#endif /* OPENSSL_NO_EC */
+#ifndef OPENSSL_NO_DSA
+static int test_fromdata_dsa_fips186_4(void)
+{
+ int ret = 0;
+ EVP_PKEY_CTX *ctx = NULL, *key_ctx = NULL;
+ EVP_PKEY *pk = NULL, *copy_pk = NULL;
+ BIGNUM *pub = NULL, *priv = NULL;
+ BIGNUM *p = NULL, *q = NULL, *g = NULL;
+ BIGNUM *pub_out = NULL, *priv_out = NULL;
+ BIGNUM *p_out = NULL, *q_out = NULL, *g_out = NULL, *j_out = NULL;
+ int gindex_out = 0, pcounter_out = 0, hindex_out = 0;
+ char name_out[80];
+ unsigned char seed_out[32];
+ size_t len;
+ OSSL_PARAM_BLD *bld = NULL;
+ OSSL_PARAM *fromdata_params = NULL;
+
+ /*
+ * DSA parameter data was generated using the following:
+ * openssl genpkey -genparam -algorithm DSA -pkeyopt pbits:2048 \
+ * -pkeyopt qbits:256 -pkeyopt type:0 \
+ * -pkeyopt gindex:1 -out dsa_params.pem -text
+ */
+ static const unsigned char p_data[] = {
+ 0x00, 0xa0, 0xb7, 0x02, 0xc4, 0xac, 0xa6, 0x42, 0xab, 0xf2, 0x34, 0x0b,
+ 0x22, 0x47, 0x1f, 0x33, 0xcf, 0xd5, 0x04, 0xe4, 0x3e, 0xec, 0xa1, 0x21,
+ 0xc8, 0x41, 0x2b, 0xef, 0xb8, 0x1f, 0x0b, 0x5b, 0x88, 0x8b, 0x67, 0xf8,
+ 0x68, 0x6d, 0x7c, 0x4d, 0x96, 0x5f, 0x3c, 0x66, 0xef, 0x58, 0x34, 0xd7,
+ 0xf6, 0xa2, 0x1b, 0xad, 0xc8, 0x12, 0x52, 0xb8, 0xe8, 0x2a, 0x63, 0xcc,
+ 0xea, 0xe7, 0x4e, 0xc8, 0x34, 0x4c, 0x58, 0x59, 0x0a, 0xc2, 0x4a, 0xe4,
+ 0xb4, 0x64, 0x20, 0xf4, 0xf6, 0x0a, 0xcf, 0x86, 0x01, 0x6c, 0x7f, 0x23,
+ 0x4a, 0x51, 0x07, 0x99, 0x42, 0x28, 0x7a, 0xff, 0x18, 0x67, 0x52, 0x64,
+ 0xf2, 0x9a, 0x62, 0x30, 0xc3, 0x00, 0xde, 0x23, 0xe9, 0x11, 0x95, 0x7e,
+ 0xd1, 0x3d, 0x8d, 0xb4, 0x0e, 0x9f, 0x9e, 0xb1, 0x30, 0x03, 0xf0, 0x73,
+ 0xa8, 0x40, 0x48, 0x42, 0x7b, 0x60, 0xa0, 0xc4, 0xf2, 0x3b, 0x2d, 0x0a,
+ 0x0c, 0xb8, 0x19, 0xfb, 0xb4, 0xf8, 0xe0, 0x2a, 0xc7, 0xf1, 0xc0, 0xc6,
+ 0x86, 0x14, 0x60, 0x12, 0x0f, 0xc0, 0xde, 0x4a, 0x67, 0xec, 0xc7, 0xde,
+ 0x76, 0x21, 0x1a, 0x55, 0x7f, 0x86, 0xc3, 0x97, 0x98, 0xce, 0xf5, 0xcd,
+ 0xf0, 0xe7, 0x12, 0xd6, 0x93, 0xee, 0x1b, 0x9b, 0x61, 0xef, 0x05, 0x8c,
+ 0x45, 0x46, 0xd9, 0x64, 0x6f, 0xbe, 0x27, 0xaa, 0x67, 0x01, 0xcc, 0x71,
+ 0xb1, 0x60, 0xce, 0x21, 0xd8, 0x51, 0x17, 0x27, 0x0d, 0x90, 0x3d, 0x18,
+ 0x7c, 0x87, 0x15, 0x8e, 0x48, 0x4c, 0x6c, 0xc5, 0x72, 0xeb, 0xb7, 0x56,
+ 0xf5, 0x6b, 0x60, 0x8f, 0xc2, 0xfd, 0x3f, 0x46, 0x5c, 0x00, 0x91, 0x85,
+ 0x79, 0x45, 0x5b, 0x1c, 0x82, 0xc4, 0x87, 0x50, 0x79, 0xba, 0xcc, 0x1c,
+ 0x32, 0x7e, 0x2e, 0xb8, 0x2e, 0xc5, 0x4e, 0xd1, 0x9b, 0xdb, 0x66, 0x79,
+ 0x7c, 0xfe, 0xaf, 0x6a, 0x05
+ };
+ static const unsigned char q_data[] = {
+ 0xa8, 0xcd, 0xf4, 0x33, 0x7b, 0x13, 0x0a, 0x24, 0xc1, 0xde, 0x4a, 0x04,
+ 0x7b, 0x4b, 0x71, 0x51, 0x32, 0xe9, 0x47, 0x74, 0xbd, 0x0c, 0x21, 0x40,
+ 0x84, 0x12, 0x0a, 0x17, 0x73, 0xdb, 0x29, 0xc7
+ };
+ static const unsigned char g_data[] = {
+ 0x6c, 0xc6, 0xa4, 0x3e, 0x61, 0x84, 0xc1, 0xff, 0x6f, 0x4a, 0x1a, 0x6b,
+ 0xb0, 0x24, 0x4b, 0xd2, 0x92, 0x5b, 0x29, 0x5c, 0x61, 0xb8, 0xc9, 0x2b,
+ 0xd6, 0xf7, 0x59, 0xfd, 0xd8, 0x70, 0x66, 0x77, 0xfc, 0xc1, 0xa4, 0xd4,
+ 0xb0, 0x1e, 0xd5, 0xbf, 0x59, 0x98, 0xb3, 0x66, 0x8b, 0xf4, 0x2e, 0xe6,
+ 0x12, 0x3e, 0xcc, 0xf8, 0x02, 0xb8, 0xc6, 0xc3, 0x47, 0xd2, 0xf5, 0xaa,
+ 0x0c, 0x5f, 0x51, 0xf5, 0xd0, 0x4c, 0x55, 0x3d, 0x07, 0x73, 0xa6, 0x57,
+ 0xce, 0x5a, 0xad, 0x42, 0x0c, 0x13, 0x0f, 0xe2, 0x31, 0x25, 0x8e, 0x72,
+ 0x12, 0x73, 0x10, 0xdb, 0x7f, 0x79, 0xeb, 0x59, 0xfc, 0xfe, 0xf7, 0x0c,
+ 0x1a, 0x81, 0x53, 0x96, 0x22, 0xb8, 0xe7, 0x58, 0xd8, 0x67, 0x80, 0x60,
+ 0xad, 0x8b, 0x55, 0x1c, 0x91, 0xf0, 0x72, 0x9a, 0x7e, 0xad, 0x37, 0xf1,
+ 0x77, 0x18, 0x96, 0x8a, 0x68, 0x70, 0xfc, 0x71, 0xa9, 0xa2, 0xe8, 0x35,
+ 0x27, 0x78, 0xf2, 0xef, 0x59, 0x36, 0x6d, 0x7c, 0xb6, 0x98, 0xd8, 0x1e,
+ 0xfa, 0x25, 0x73, 0x97, 0x45, 0x58, 0xe3, 0xae, 0xbd, 0x52, 0x54, 0x05,
+ 0xd8, 0x26, 0x26, 0xba, 0xba, 0x05, 0xb5, 0xe9, 0xe5, 0x76, 0xae, 0x25,
+ 0xdd, 0xfc, 0x10, 0x89, 0x5a, 0xa9, 0xee, 0x59, 0xc5, 0x79, 0x8b, 0xeb,
+ 0x1e, 0x2c, 0x61, 0xab, 0x0d, 0xd1, 0x10, 0x04, 0x91, 0x32, 0x77, 0x4a,
+ 0xa6, 0x64, 0x53, 0xda, 0x4c, 0xd7, 0x3a, 0x29, 0xd4, 0xf3, 0x82, 0x25,
+ 0x1d, 0x6f, 0x4a, 0x7f, 0xd3, 0x08, 0x3b, 0x42, 0x30, 0x10, 0xd8, 0xd0,
+ 0x97, 0x3a, 0xeb, 0x92, 0x63, 0xec, 0x93, 0x2b, 0x6f, 0x32, 0xd8, 0xcd,
+ 0x80, 0xd3, 0xc0, 0x4c, 0x03, 0xd5, 0xca, 0xbc, 0x8f, 0xc7, 0x43, 0x53,
+ 0x64, 0x66, 0x1c, 0x82, 0x2d, 0xfb, 0xff, 0x39, 0xba, 0xd6, 0x42, 0x62,
+ 0x02, 0x6f, 0x96, 0x36
+ };
+ static const unsigned char seed_data[] = {
+ 0x64, 0x46, 0x07, 0x32, 0x8d, 0x70, 0x9c, 0xb3, 0x8a, 0x35, 0xde, 0x62,
+ 0x00, 0xf2, 0x6d, 0x52, 0x37, 0x4d, 0xb3, 0x84, 0xe1, 0x9d, 0x41, 0x04,
+ 0xda, 0x7b, 0xdc, 0x0d, 0x8b, 0x5e, 0xe0, 0x84
+ };
+ const int gindex = 1;
+ const int pcounter = 53;
+ /*
+ * The keypair was generated using
+ * openssl genpkey -paramfile dsa_params.pem --pkeyopt pcounter:53 \
+ * -pkeyopt gindex:1 \
+ * -pkeyopt hexseed:644607328d709cb38a35de6200f26d -text
+ */
+ static const unsigned char priv_data[] = {
+ 0x00, 0x8f, 0xc5, 0x9e, 0xd0, 0xf7, 0x2a, 0x0b, 0x66, 0xf1, 0x32, 0x73,
+ 0xae, 0xf6, 0xd9, 0xd4, 0xdb, 0x2d, 0x96, 0x55, 0x89, 0xff, 0xef, 0xa8,
+ 0x5f, 0x47, 0x8f, 0xca, 0x02, 0x8a, 0xe1, 0x35, 0x90
+ };
+ static const unsigned char pub_data[] = {
+ 0x44, 0x19, 0xc9, 0x46, 0x45, 0x57, 0xc1, 0xa9, 0xd8, 0x30, 0x99, 0x29,
+ 0x6a, 0x4b, 0x63, 0x71, 0x69, 0x96, 0x35, 0x17, 0xb2, 0x62, 0x9b, 0x80,
+ 0x0a, 0x95, 0x9d, 0x6a, 0xc0, 0x32, 0x0d, 0x07, 0x5f, 0x19, 0x44, 0x02,
+ 0xf1, 0xbd, 0xce, 0xdf, 0x10, 0xf8, 0x02, 0x5d, 0x7d, 0x98, 0x8a, 0x73,
+ 0x89, 0x00, 0xb6, 0x24, 0xd6, 0x33, 0xe7, 0xcf, 0x8b, 0x49, 0x2a, 0xaf,
+ 0x13, 0x1c, 0xb2, 0x52, 0x15, 0xfd, 0x9b, 0xd5, 0x40, 0x4a, 0x1a, 0xda,
+ 0x29, 0x4c, 0x92, 0x7e, 0x66, 0x06, 0xdb, 0x61, 0x86, 0xac, 0xb5, 0xda,
+ 0x3c, 0x7d, 0x73, 0x7e, 0x54, 0x32, 0x68, 0xa5, 0x02, 0xbc, 0x59, 0x47,
+ 0x84, 0xd3, 0x87, 0x71, 0x5f, 0xeb, 0x43, 0x45, 0x24, 0xd3, 0xec, 0x08,
+ 0x52, 0xc2, 0x89, 0x2d, 0x9c, 0x1a, 0xcc, 0x91, 0x65, 0x5d, 0xa3, 0xa1,
+ 0x35, 0x31, 0x10, 0x1c, 0x3a, 0xa8, 0x4d, 0x18, 0xd5, 0x06, 0xaf, 0xb2,
+ 0xec, 0x5c, 0x89, 0x9e, 0x90, 0x86, 0x10, 0x01, 0xeb, 0x51, 0xd5, 0x1b,
+ 0x9c, 0xcb, 0x66, 0x07, 0x3f, 0xc4, 0x6e, 0x0a, 0x1b, 0x73, 0xa0, 0x4b,
+ 0x5f, 0x4d, 0xab, 0x35, 0x28, 0xfa, 0xda, 0x3a, 0x0c, 0x08, 0xe8, 0xf3,
+ 0xef, 0x42, 0x67, 0xbc, 0x21, 0xf2, 0xc2, 0xb8, 0xff, 0x1a, 0x81, 0x05,
+ 0x68, 0x73, 0x62, 0xdf, 0xd7, 0xab, 0x0f, 0x22, 0x89, 0x57, 0x96, 0xd4,
+ 0x93, 0xaf, 0xa1, 0x21, 0xa3, 0x48, 0xe9, 0xf0, 0x97, 0x47, 0xa0, 0x27,
+ 0xba, 0x87, 0xb8, 0x15, 0x5f, 0xff, 0x2c, 0x50, 0x41, 0xf1, 0x7e, 0xc6,
+ 0x81, 0xc4, 0x51, 0xf1, 0xfd, 0xd6, 0x86, 0xf7, 0x69, 0x97, 0xf1, 0x49,
+ 0xc9, 0xf9, 0xf4, 0x9b, 0xf4, 0xe8, 0x85, 0xa7, 0xbd, 0x36, 0x55, 0x4a,
+ 0x3d, 0xe8, 0x65, 0x09, 0x7b, 0xb7, 0x12, 0x64, 0xd2, 0x0a, 0x53, 0x60,
+ 0x48, 0xd1, 0x8a, 0xbd
+ };
+
+ if (!TEST_ptr(bld = OSSL_PARAM_BLD_new())
+ || !TEST_ptr(pub = BN_bin2bn(pub_data, sizeof(pub_data), NULL))
+ || !TEST_ptr(priv = BN_bin2bn(priv_data, sizeof(priv_data), NULL))
+ || !TEST_ptr(p = BN_bin2bn(p_data, sizeof(p_data), NULL))
+ || !TEST_ptr(q = BN_bin2bn(q_data, sizeof(q_data), NULL))
+ || !TEST_ptr(g = BN_bin2bn(g_data, sizeof(g_data), NULL))
+
+ || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_FFC_P, p))
+ || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_FFC_Q, q))
+ || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_FFC_G, g))
+ || !TEST_true(OSSL_PARAM_BLD_push_octet_string(bld,
+ OSSL_PKEY_PARAM_FFC_SEED,
+ seed_data,
+ sizeof(seed_data)))
+ || !TEST_true(OSSL_PARAM_BLD_push_int(bld, OSSL_PKEY_PARAM_FFC_GINDEX,
+ gindex))
+ || !TEST_true(OSSL_PARAM_BLD_push_int(bld,
+ OSSL_PKEY_PARAM_FFC_PCOUNTER,
+ pcounter))
+ || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PUB_KEY,
+ pub))
+ || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PRIV_KEY,
+ priv))
+ || !TEST_ptr(fromdata_params = OSSL_PARAM_BLD_to_param(bld)))
+ goto err;
+
+ if (!TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(NULL, "DSA", NULL)))
+ goto err;
+
+ if (!TEST_true(EVP_PKEY_key_fromdata_init(ctx))
+ || !TEST_true(EVP_PKEY_fromdata(ctx, &pk, fromdata_params))
+ || !TEST_int_eq(EVP_PKEY_bits(pk), 2048)
+ || !TEST_int_eq(EVP_PKEY_security_bits(pk), 112)
+ || !TEST_int_eq(EVP_PKEY_size(pk), 2 + 2 * (3 + sizeof(q_data))))
+ goto err;
+
+ if (!TEST_false(EVP_PKEY_get_utf8_string_param(pk, OSSL_PKEY_PARAM_FFC_GROUP,
+ name_out, sizeof(name_out),
+ &len))
+ || !TEST_true(EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_PUB_KEY,
+ &pub_out))
+ || !TEST_BN_eq(pub, pub_out)
+ || !TEST_true(EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_PRIV_KEY,
+ &priv_out))
+ || !TEST_BN_eq(priv, priv_out)
+ || !TEST_true(EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_FFC_P, &p_out))
+ || !TEST_BN_eq(p, p_out)
+ || !TEST_true(EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_FFC_Q, &q_out))
+ || !TEST_BN_eq(q, q_out)
+ || !TEST_true(EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_FFC_G, &g_out))
+ || !TEST_BN_eq(g, g_out)
+ || !TEST_false(EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_FFC_COFACTOR,
+ &j_out))
+ || !TEST_ptr_null(j_out)
+ || !TEST_true(EVP_PKEY_get_octet_string_param(pk,
+ OSSL_PKEY_PARAM_FFC_SEED,
+ seed_out, sizeof(seed_out),
+ &len))
+ || !TEST_true(EVP_PKEY_get_int_param(pk, OSSL_PKEY_PARAM_FFC_GINDEX,
+ &gindex_out))
+ || !TEST_int_eq(gindex, gindex_out)
+ || !TEST_true(EVP_PKEY_get_int_param(pk, OSSL_PKEY_PARAM_FFC_H,
+ &hindex_out))
+ || !TEST_int_eq(hindex_out, 0)
+ || !TEST_true(EVP_PKEY_get_int_param(pk, OSSL_PKEY_PARAM_FFC_PCOUNTER,
+ &pcounter_out))
+ || !TEST_int_eq(pcounter, pcounter_out))
+ goto err;
+
+ if (!TEST_ptr(key_ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pk, "")))
+ goto err;
+
+ if (!TEST_true(EVP_PKEY_check(key_ctx))
+ || !TEST_true(EVP_PKEY_public_check(key_ctx))
+ || !TEST_true(EVP_PKEY_private_check(key_ctx))
+ || !TEST_true(EVP_PKEY_pairwise_check(key_ctx)))
+ goto err;
+
+ if (!TEST_ptr(copy_pk = EVP_PKEY_new())
+ || !TEST_true(EVP_PKEY_copy_parameters(copy_pk, pk)))
+ goto err;
+
+ ret = test_print_key_using_pem("DSA", pk)
+ && test_print_key_using_serializer("DSA", pk);
+ err:
+ OSSL_PARAM_BLD_free_params(fromdata_params);
+ OSSL_PARAM_BLD_free(bld);
+ BN_free(p);
+ BN_free(q);
+ BN_free(g);
+ BN_free(pub);
+ BN_free(priv);
+ BN_free(p_out);
+ BN_free(q_out);
+ BN_free(g_out);
+ BN_free(pub_out);
+ BN_free(priv_out);
+ BN_free(j_out);
+ EVP_PKEY_free(pk);
+ EVP_PKEY_free(copy_pk);
+ EVP_PKEY_CTX_free(ctx);
+ EVP_PKEY_CTX_free(key_ctx);
+
+ return ret;
+}
+#endif /* OPENSSL_NO_DSA */
+
+
int setup_tests(void)
{
if (!test_skip_common_options()) {
#ifndef OPENSSL_NO_DH
ADD_TEST(test_fromdata_dh);
#endif
+#ifndef OPENSSL_NO_DSA
+ ADD_TEST(test_fromdata_dsa_fips186_4);
+#endif
#ifndef OPENSSL_NO_EC
ADD_ALL_TESTS(test_fromdata_ecx, 4);
ADD_TEST(test_fromdata_ec);
--- /dev/null
+#! /usr/bin/env perl
+# Copyright 2017-2018 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
+
+
+use strict;
+use warnings;
+
+use File::Spec;
+use OpenSSL::Test qw/:DEFAULT srctop_file/;
+use OpenSSL::Test::Utils;
+
+setup("test_gendsa");
+
+plan skip_all => "This test is unsupported in a no-dsa build"
+ if disabled("dsa");
+
+plan tests => 8;
+
+ok(run(app([ 'openssl', 'genpkey', '-genparam',
+ '-algorithm', 'DSA',
+ '-pkeyopt', 'gindex:1',
+ '-pkeyopt', 'type:fips186_4',
+ '-text'])),
+ "genpkey DSA params fips186_4 with verifiable g");
+
+ok(run(app([ 'openssl', 'genpkey', '-genparam',
+ '-algorithm', 'DSA',
+ '-pkeyopt', 'type:fips186_4',
+ '-text'])),
+ "genpkey DSA params fips186_4 with unverifiable g");
+
+ok(run(app([ 'openssl', 'genpkey', '-genparam',
+ '-algorithm', 'DSA',
+ '-pkeyopt', 'type:fips186_2',
+ '-text'])),
+ "genpkey DSA params fips186_2");
+
+ok(!run(app([ 'openssl', 'genpkey', '-algorithm', 'DSA',
+ '-pkeyopt', 'type:group',
+ '-text'])),
+ "genpkey DSA does not support groups");
+
+ok(run(app([ 'openssl', 'genpkey', '-genparam',
+ '-algorithm', 'DSA',
+ '-pkeyopt', 'gindex:1',
+ '-pkeyopt', 'type:fips186_4',
+ '-out', 'dsagen.pem'])),
+ "genpkey DSA params fips186_4 PEM");
+
+ok(run(app([ 'openssl', 'genpkey', '-genparam',
+ '-algorithm', 'DSA',
+ '-pkeyopt', 'gindex:1',
+ '-pkeyopt', 'pbits:2048',
+ '-pkeyopt', 'qbits:256',
+ '-pkeyopt', 'type:fips186_4',
+ '-outform', 'DER',
+ '-out', 'dsagen.der'])),
+ "genpkey DSA params fips186_4 DER");
+
+# The seed and counter should be the ones generated from the param generation
+# Just put some dummy ones in to show it works.
+ok(run(app([ 'openssl', 'genpkey',
+ '-paramfile', 'dsagen.der',
+ '-pkeyopt', 'gindex:1',
+ '-pkeyopt', 'hexseed:0102030405060708090A0B0C0D0E0F1011121314',
+ '-pkeyopt', 'pcounter:25',
+ '-text'])),
+ "genpkey DSA fips186_4 with DER params");
+
+ok(!run(app([ 'openssl', 'genpkey',
+ '-algorithm', 'DSA'])),
+ "genpkey DSA with no params should fail");
--- /dev/null
+-----BEGIN PRIVATE KEY-----
+MIICZQIBADCCAjkGByqGSM44BAEwggIsAoIBAQCgtwLErKZCq/I0CyJHHzPP1QTk
+PuyhIchBK++4HwtbiItn+GhtfE2WXzxm71g01/aiG63IElK46CpjzOrnTsg0TFhZ
+CsJK5LRkIPT2Cs+GAWx/I0pRB5lCKHr/GGdSZPKaYjDDAN4j6RGVftE9jbQOn56x
+MAPwc6hASEJ7YKDE8jstCgy4Gfu0+OAqx/HAxoYUYBIPwN5KZ+zH3nYhGlV/hsOX
+mM71zfDnEtaT7hubYe8FjEVG2WRvvieqZwHMcbFgziHYURcnDZA9GHyHFY5ITGzF
+cuu3VvVrYI/C/T9GXACRhXlFWxyCxIdQebrMHDJ+LrguxU7Rm9tmeXz+r2oFAiEA
+qM30M3sTCiTB3koEe0txUTLpR3S9DCFAhBIKF3PbKccCggEAbMakPmGEwf9vShpr
+sCRL0pJbKVxhuMkr1vdZ/dhwZnf8waTUsB7Vv1mYs2aL9C7mEj7M+AK4xsNH0vWq
+DF9R9dBMVT0Hc6ZXzlqtQgwTD+IxJY5yEnMQ239561n8/vcMGoFTliK451jYZ4Bg
+rYtVHJHwcpp+rTfxdxiWimhw/HGpoug1J3jy71k2bXy2mNge+iVzl0VY4669UlQF
+2CYmuroFtenldq4l3fwQiVqp7lnFeYvrHixhqw3REASRMndKpmRT2kzXOinU84Il
+HW9Kf9MIO0IwENjQlzrrkmPskytvMtjNgNPATAPVyryPx0NTZGYcgi37/zm61kJi
+Am+WNgQjAiEAj8We0PcqC2bxMnOu9tnU2y2WVYn/76hfR4/KAorhNZA=
+-----END PRIVATE KEY-----
--- /dev/null
+Private-Key: (2048 bit)
+priv:
+ 00:8f:c5:9e:d0:f7:2a:0b:66:f1:32:73:ae:f6:d9:
+ d4:db:2d:96:55:89:ff:ef:a8:5f:47:8f:ca:02:8a:
+ e1:35:90
+pub:
+ 44:19:c9:46:45:57:c1:a9:d8:30:99:29:6a:4b:63:
+ 71:69:96:35:17:b2:62:9b:80:0a:95:9d:6a:c0:32:
+ 0d:07:5f:19:44:02:f1:bd:ce:df:10:f8:02:5d:7d:
+ 98:8a:73:89:00:b6:24:d6:33:e7:cf:8b:49:2a:af:
+ 13:1c:b2:52:15:fd:9b:d5:40:4a:1a:da:29:4c:92:
+ 7e:66:06:db:61:86:ac:b5:da:3c:7d:73:7e:54:32:
+ 68:a5:02:bc:59:47:84:d3:87:71:5f:eb:43:45:24:
+ d3:ec:08:52:c2:89:2d:9c:1a:cc:91:65:5d:a3:a1:
+ 35:31:10:1c:3a:a8:4d:18:d5:06:af:b2:ec:5c:89:
+ 9e:90:86:10:01:eb:51:d5:1b:9c:cb:66:07:3f:c4:
+ 6e:0a:1b:73:a0:4b:5f:4d:ab:35:28:fa:da:3a:0c:
+ 08:e8:f3:ef:42:67:bc:21:f2:c2:b8:ff:1a:81:05:
+ 68:73:62:df:d7:ab:0f:22:89:57:96:d4:93:af:a1:
+ 21:a3:48:e9:f0:97:47:a0:27:ba:87:b8:15:5f:ff:
+ 2c:50:41:f1:7e:c6:81:c4:51:f1:fd:d6:86:f7:69:
+ 97:f1:49:c9:f9:f4:9b:f4:e8:85:a7:bd:36:55:4a:
+ 3d:e8:65:09:7b:b7:12:64:d2:0a:53:60:48:d1:8a:
+ bd
+P:
+ 00:a0:b7:02:c4:ac:a6:42:ab:f2:34:0b:22:47:1f:
+ 33:cf:d5:04:e4:3e:ec:a1:21:c8:41:2b:ef:b8:1f:
+ 0b:5b:88:8b:67:f8:68:6d:7c:4d:96:5f:3c:66:ef:
+ 58:34:d7:f6:a2:1b:ad:c8:12:52:b8:e8:2a:63:cc:
+ ea:e7:4e:c8:34:4c:58:59:0a:c2:4a:e4:b4:64:20:
+ f4:f6:0a:cf:86:01:6c:7f:23:4a:51:07:99:42:28:
+ 7a:ff:18:67:52:64:f2:9a:62:30:c3:00:de:23:e9:
+ 11:95:7e:d1:3d:8d:b4:0e:9f:9e:b1:30:03:f0:73:
+ a8:40:48:42:7b:60:a0:c4:f2:3b:2d:0a:0c:b8:19:
+ fb:b4:f8:e0:2a:c7:f1:c0:c6:86:14:60:12:0f:c0:
+ de:4a:67:ec:c7:de:76:21:1a:55:7f:86:c3:97:98:
+ ce:f5:cd:f0:e7:12:d6:93:ee:1b:9b:61:ef:05:8c:
+ 45:46:d9:64:6f:be:27:aa:67:01:cc:71:b1:60:ce:
+ 21:d8:51:17:27:0d:90:3d:18:7c:87:15:8e:48:4c:
+ 6c:c5:72:eb:b7:56:f5:6b:60:8f:c2:fd:3f:46:5c:
+ 00:91:85:79:45:5b:1c:82:c4:87:50:79:ba:cc:1c:
+ 32:7e:2e:b8:2e:c5:4e:d1:9b:db:66:79:7c:fe:af:
+ 6a:05
+Q:
+ 00:a8:cd:f4:33:7b:13:0a:24:c1:de:4a:04:7b:4b:
+ 71:51:32:e9:47:74:bd:0c:21:40:84:12:0a:17:73:
+ db:29:c7
+G:
+ 6c:c6:a4:3e:61:84:c1:ff:6f:4a:1a:6b:b0:24:4b:
+ d2:92:5b:29:5c:61:b8:c9:2b:d6:f7:59:fd:d8:70:
+ 66:77:fc:c1:a4:d4:b0:1e:d5:bf:59:98:b3:66:8b:
+ f4:2e:e6:12:3e:cc:f8:02:b8:c6:c3:47:d2:f5:aa:
+ 0c:5f:51:f5:d0:4c:55:3d:07:73:a6:57:ce:5a:ad:
+ 42:0c:13:0f:e2:31:25:8e:72:12:73:10:db:7f:79:
+ eb:59:fc:fe:f7:0c:1a:81:53:96:22:b8:e7:58:d8:
+ 67:80:60:ad:8b:55:1c:91:f0:72:9a:7e:ad:37:f1:
+ 77:18:96:8a:68:70:fc:71:a9:a2:e8:35:27:78:f2:
+ ef:59:36:6d:7c:b6:98:d8:1e:fa:25:73:97:45:58:
+ e3:ae:bd:52:54:05:d8:26:26:ba:ba:05:b5:e9:e5:
+ 76:ae:25:dd:fc:10:89:5a:a9:ee:59:c5:79:8b:eb:
+ 1e:2c:61:ab:0d:d1:10:04:91:32:77:4a:a6:64:53:
+ da:4c:d7:3a:29:d4:f3:82:25:1d:6f:4a:7f:d3:08:
+ 3b:42:30:10:d8:d0:97:3a:eb:92:63:ec:93:2b:6f:
+ 32:d8:cd:80:d3:c0:4c:03:d5:ca:bc:8f:c7:43:53:
+ 64:66:1c:82:2d:fb:ff:39:ba:d6:42:62:02:6f:96:
+ 36
+SEED:
+ 64:46:07:32:8d:70:9c:b3:8a:35:de:62:00:f2:6d:
+ 52:37:4d:b3:84:e1:9d:41:04:da:7b:dc:0d:8b:5e:
+ e0:84
+gindex: 1
+pcounter: 53
--- /dev/null
+-----BEGIN PUBLIC KEY-----
+MIIDRjCCAjkGByqGSM44BAEwggIsAoIBAQCgtwLErKZCq/I0CyJHHzPP1QTkPuyh
+IchBK++4HwtbiItn+GhtfE2WXzxm71g01/aiG63IElK46CpjzOrnTsg0TFhZCsJK
+5LRkIPT2Cs+GAWx/I0pRB5lCKHr/GGdSZPKaYjDDAN4j6RGVftE9jbQOn56xMAPw
+c6hASEJ7YKDE8jstCgy4Gfu0+OAqx/HAxoYUYBIPwN5KZ+zH3nYhGlV/hsOXmM71
+zfDnEtaT7hubYe8FjEVG2WRvvieqZwHMcbFgziHYURcnDZA9GHyHFY5ITGzFcuu3
+VvVrYI/C/T9GXACRhXlFWxyCxIdQebrMHDJ+LrguxU7Rm9tmeXz+r2oFAiEAqM30
+M3sTCiTB3koEe0txUTLpR3S9DCFAhBIKF3PbKccCggEAbMakPmGEwf9vShprsCRL
+0pJbKVxhuMkr1vdZ/dhwZnf8waTUsB7Vv1mYs2aL9C7mEj7M+AK4xsNH0vWqDF9R
+9dBMVT0Hc6ZXzlqtQgwTD+IxJY5yEnMQ239561n8/vcMGoFTliK451jYZ4BgrYtV
+HJHwcpp+rTfxdxiWimhw/HGpoug1J3jy71k2bXy2mNge+iVzl0VY4669UlQF2CYm
+uroFtenldq4l3fwQiVqp7lnFeYvrHixhqw3REASRMndKpmRT2kzXOinU84IlHW9K
+f9MIO0IwENjQlzrrkmPskytvMtjNgNPATAPVyryPx0NTZGYcgi37/zm61kJiAm+W
+NgOCAQUAAoIBAEQZyUZFV8Gp2DCZKWpLY3FpljUXsmKbgAqVnWrAMg0HXxlEAvG9
+zt8Q+AJdfZiKc4kAtiTWM+fPi0kqrxMcslIV/ZvVQEoa2ilMkn5mBtthhqy12jx9
+c35UMmilArxZR4TTh3Ff60NFJNPsCFLCiS2cGsyRZV2joTUxEBw6qE0Y1Qavsuxc
+iZ6QhhAB61HVG5zLZgc/xG4KG3OgS19NqzUo+to6DAjo8+9CZ7wh8sK4/xqBBWhz
+Yt/Xqw8iiVeW1JOvoSGjSOnwl0egJ7qHuBVf/yxQQfF+xoHEUfH91ob3aZfxScn5
+9Jv06IWnvTZVSj3oZQl7txJk0gpTYEjRir0=
+-----END PUBLIC KEY-----
--- /dev/null
+Private-Key: (2048 bit)
+priv:
+ 00:8f:c5:9e:d0:f7:2a:0b:66:f1:32:73:ae:f6:d9:
+ d4:db:2d:96:55:89:ff:ef:a8:5f:47:8f:ca:02:8a:
+ e1:35:90
+pub:
+ 44:19:c9:46:45:57:c1:a9:d8:30:99:29:6a:4b:63:
+ 71:69:96:35:17:b2:62:9b:80:0a:95:9d:6a:c0:32:
+ 0d:07:5f:19:44:02:f1:bd:ce:df:10:f8:02:5d:7d:
+ 98:8a:73:89:00:b6:24:d6:33:e7:cf:8b:49:2a:af:
+ 13:1c:b2:52:15:fd:9b:d5:40:4a:1a:da:29:4c:92:
+ 7e:66:06:db:61:86:ac:b5:da:3c:7d:73:7e:54:32:
+ 68:a5:02:bc:59:47:84:d3:87:71:5f:eb:43:45:24:
+ d3:ec:08:52:c2:89:2d:9c:1a:cc:91:65:5d:a3:a1:
+ 35:31:10:1c:3a:a8:4d:18:d5:06:af:b2:ec:5c:89:
+ 9e:90:86:10:01:eb:51:d5:1b:9c:cb:66:07:3f:c4:
+ 6e:0a:1b:73:a0:4b:5f:4d:ab:35:28:fa:da:3a:0c:
+ 08:e8:f3:ef:42:67:bc:21:f2:c2:b8:ff:1a:81:05:
+ 68:73:62:df:d7:ab:0f:22:89:57:96:d4:93:af:a1:
+ 21:a3:48:e9:f0:97:47:a0:27:ba:87:b8:15:5f:ff:
+ 2c:50:41:f1:7e:c6:81:c4:51:f1:fd:d6:86:f7:69:
+ 97:f1:49:c9:f9:f4:9b:f4:e8:85:a7:bd:36:55:4a:
+ 3d:e8:65:09:7b:b7:12:64:d2:0a:53:60:48:d1:8a:
+ bd
+P:
+ 00:a0:b7:02:c4:ac:a6:42:ab:f2:34:0b:22:47:1f:
+ 33:cf:d5:04:e4:3e:ec:a1:21:c8:41:2b:ef:b8:1f:
+ 0b:5b:88:8b:67:f8:68:6d:7c:4d:96:5f:3c:66:ef:
+ 58:34:d7:f6:a2:1b:ad:c8:12:52:b8:e8:2a:63:cc:
+ ea:e7:4e:c8:34:4c:58:59:0a:c2:4a:e4:b4:64:20:
+ f4:f6:0a:cf:86:01:6c:7f:23:4a:51:07:99:42:28:
+ 7a:ff:18:67:52:64:f2:9a:62:30:c3:00:de:23:e9:
+ 11:95:7e:d1:3d:8d:b4:0e:9f:9e:b1:30:03:f0:73:
+ a8:40:48:42:7b:60:a0:c4:f2:3b:2d:0a:0c:b8:19:
+ fb:b4:f8:e0:2a:c7:f1:c0:c6:86:14:60:12:0f:c0:
+ de:4a:67:ec:c7:de:76:21:1a:55:7f:86:c3:97:98:
+ ce:f5:cd:f0:e7:12:d6:93:ee:1b:9b:61:ef:05:8c:
+ 45:46:d9:64:6f:be:27:aa:67:01:cc:71:b1:60:ce:
+ 21:d8:51:17:27:0d:90:3d:18:7c:87:15:8e:48:4c:
+ 6c:c5:72:eb:b7:56:f5:6b:60:8f:c2:fd:3f:46:5c:
+ 00:91:85:79:45:5b:1c:82:c4:87:50:79:ba:cc:1c:
+ 32:7e:2e:b8:2e:c5:4e:d1:9b:db:66:79:7c:fe:af:
+ 6a:05
+Q:
+ 00:a8:cd:f4:33:7b:13:0a:24:c1:de:4a:04:7b:4b:
+ 71:51:32:e9:47:74:bd:0c:21:40:84:12:0a:17:73:
+ db:29:c7
+G:
+ 6c:c6:a4:3e:61:84:c1:ff:6f:4a:1a:6b:b0:24:4b:
+ d2:92:5b:29:5c:61:b8:c9:2b:d6:f7:59:fd:d8:70:
+ 66:77:fc:c1:a4:d4:b0:1e:d5:bf:59:98:b3:66:8b:
+ f4:2e:e6:12:3e:cc:f8:02:b8:c6:c3:47:d2:f5:aa:
+ 0c:5f:51:f5:d0:4c:55:3d:07:73:a6:57:ce:5a:ad:
+ 42:0c:13:0f:e2:31:25:8e:72:12:73:10:db:7f:79:
+ eb:59:fc:fe:f7:0c:1a:81:53:96:22:b8:e7:58:d8:
+ 67:80:60:ad:8b:55:1c:91:f0:72:9a:7e:ad:37:f1:
+ 77:18:96:8a:68:70:fc:71:a9:a2:e8:35:27:78:f2:
+ ef:59:36:6d:7c:b6:98:d8:1e:fa:25:73:97:45:58:
+ e3:ae:bd:52:54:05:d8:26:26:ba:ba:05:b5:e9:e5:
+ 76:ae:25:dd:fc:10:89:5a:a9:ee:59:c5:79:8b:eb:
+ 1e:2c:61:ab:0d:d1:10:04:91:32:77:4a:a6:64:53:
+ da:4c:d7:3a:29:d4:f3:82:25:1d:6f:4a:7f:d3:08:
+ 3b:42:30:10:d8:d0:97:3a:eb:92:63:ec:93:2b:6f:
+ 32:d8:cd:80:d3:c0:4c:03:d5:ca:bc:8f:c7:43:53:
+ 64:66:1c:82:2d:fb:ff:39:ba:d6:42:62:02:6f:96:
+ 36
+SEED:
+ 64:46:07:32:8d:70:9c:b3:8a:35:de:62:00:f2:6d:
+ 52:37:4d:b3:84:e1:9d:41:04:da:7b:dc:0d:8b:5e:
+ e0:84
+gindex: 1
+pcounter: 53
d2i_PrivateKey_ex_bio ? 3_0_0 EXIST::FUNCTION:
PEM_read_bio_PrivateKey_ex ? 3_0_0 EXIST::FUNCTION:
PEM_read_PrivateKey_ex ? 3_0_0 EXIST::FUNCTION:STDIO
+EVP_PKEY_CTX_set_dsa_paramgen_bits ? 3_0_0 EXIST::FUNCTION:DSA
+EVP_PKEY_CTX_set_dsa_paramgen_q_bits ? 3_0_0 EXIST::FUNCTION:DSA
+EVP_PKEY_CTX_set_dsa_paramgen_md_props ? 3_0_0 EXIST::FUNCTION:DSA
+EVP_PKEY_CTX_set_dsa_paramgen_gindex ? 3_0_0 EXIST::FUNCTION:DSA
+EVP_PKEY_CTX_set_dsa_paramgen_type ? 3_0_0 EXIST::FUNCTION:DSA
+EVP_PKEY_CTX_set_dsa_paramgen_seed ? 3_0_0 EXIST::FUNCTION:DSA
+EVP_PKEY_CTX_set_dsa_paramgen_md ? 3_0_0 EXIST::FUNCTION:DSA