Add DSA keygen to provider
authorShane Lontis <shane.lontis@oracle.com>
Wed, 15 Apr 2020 11:02:52 +0000 (21:02 +1000)
committerShane Lontis <shane.lontis@oracle.com>
Wed, 15 Apr 2020 11:02:52 +0000 (21:02 +1000)
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)

39 files changed:
crypto/dh/dh_ameth.c
crypto/dh/dh_group_params.c
crypto/dh/dh_key.c
crypto/dsa/build.info
crypto/dsa/dsa_ameth.c
crypto/dsa/dsa_backend.c
crypto/dsa/dsa_gen.c
crypto/dsa/dsa_key.c
crypto/dsa/dsa_lib.c
crypto/evp/p_lib.c
crypto/evp/pmeth_lib.c
crypto/ffc/ffc_backend.c
crypto/ffc/ffc_key_generate.c
crypto/ffc/ffc_params.c
crypto/ffc/ffc_params_generate.c
doc/man1/openssl-genpkey.pod.in
doc/man3/EVP_PKEY_CTX_ctrl.pod
doc/man7/provider-keymgmt.pod
include/crypto/dsa.h
include/internal/ffc.h
include/openssl/core_names.h
include/openssl/dsa.h
providers/implementations/keymgmt/dh_kmgmt.c
providers/implementations/keymgmt/dsa_kmgmt.c
providers/implementations/serializers/build.info
providers/implementations/serializers/serializer_common.c
providers/implementations/serializers/serializer_dsa.c
providers/implementations/serializers/serializer_ffc_params.c [new file with mode: 0644]
providers/implementations/serializers/serializer_local.h
test/dsatest.c
test/evp_pkey_provided_test.c
test/recipes/15-test_gendsa.t [new file with mode: 0644]
test/recipes/30-test_evp_pkey_provided/DSA.priv.der [new file with mode: 0644]
test/recipes/30-test_evp_pkey_provided/DSA.priv.pem [new file with mode: 0644]
test/recipes/30-test_evp_pkey_provided/DSA.priv.txt [new file with mode: 0644]
test/recipes/30-test_evp_pkey_provided/DSA.pub.der [new file with mode: 0644]
test/recipes/30-test_evp_pkey_provided/DSA.pub.pem [new file with mode: 0644]
test/recipes/30-test_evp_pkey_provided/DSA.pub.txt [new file with mode: 0644]
util/libcrypto.num

index f5bcee246086b4815a89cf234f28fc6f81604bc0..9c1fa0388d26597a59c1e69e349ec03cc15a0ef0 100644 (file)
@@ -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);
index d672ae303421faf02777e4d03e0b6928f75df83b..cc1c5466553ed981c5f787b9f82521dcfdaf1e57 100644 (file)
 #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);
 
index ab2e25ea87252636e9866300d5588149a11ca66a..e46946153be195eb6fca577cd805db013e413242 100644 (file)
 #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;
             }
index fb5a4fee2a9f0b7f1ed8f6978bcae524e76234ce..7f621cb56be348beda8a229478330e4cd1fd5647 100644 (file)
@@ -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
index d63c142fdd157c3fc3aeb9bb94aa4f281f545dd5..81bb6d88f73770115b07f55d94a332cdcf7f166f 100644 (file)
 #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);
index b927465cfa3a4e69b6b15f6ed91c659ebb65c2d3..461cb187dd5c72004164507a2c73aa363413e19c 100644 (file)
@@ -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)
index 2148a1a487c46fdb0d6e93da586662d5e3f9db4c..7b72867f71979143cd0796f4fb917cf7667e1be8 100644 (file)
 #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
index 2dec35f28f9c0a6bbe7cf9d92eaa5df479513ff8..1d625272e506681fee26b6ef70ebeba17a2a9979 100644 (file)
 #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) {
index e3205223e96fa7e88069bc4637f4df26b1f1d816..b773f2c52631939b3b7015f33951baaa1421b7b8 100644 (file)
@@ -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
index 9f04c72330414340be419a7ab24bc50019207d20..b0163f579216883e7d043f74518ea564e99dca28 100644 (file)
@@ -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);
index 6a86b26ded844ff48e226c61d146408c94d5db3b..6d34accc3cde7783df80408e5f8f9d67e8bebc93 100644 (file)
@@ -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;
index cde9e43da345a3eab5784427fa4189ff5ecde751..1d076184bc49ee5b7b43d84bedfc7beae92043c9 100644 (file)
@@ -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
  * 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);
index 078e8d39a105854452074af64f241aa84ed8f186..4e2f231d839ca672804c02a33d95ffb4eddd42af 100644 (file)
@@ -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)].
  *
index cb8987b64d2fb77f1859df52b11e9a72ebe4dcb5..59508477031fb6dc1b852157ec18460bab7e0aa6 100644 (file)
@@ -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))
index cb51bf0e76e9e1e3ec6ff3fe953f422403c68d1c..6d9b9243872b30120a022763300b04c408cc3447 100644 (file)
@@ -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);
index 4f1128a04915ac8590e74b1f47ff1dafa2dbfd5d..8d7da6d7c725458d1736ebc7c45163136b3c42f9 100644 (file)
@@ -194,11 +194,15 @@ The number of bits in the generated prime. If not specified 2048 is used.
 
 =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
@@ -206,6 +210,31 @@ ignored. If not set, then a digest will be used that gives an output matching
 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
@@ -269,10 +298,12 @@ Generate a 2048 bit RSA key using 3 as the public exponent:
  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:
 
index 829bdb9e3d1eb0e316c2e720b2526c8283754250..ded779feb09c3b045d0f662c9f856be6febfdab3 100644 (file)
@@ -33,6 +33,10 @@ EVP_PKEY_CTX_get0_rsa_oaep_label,
 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,
@@ -121,6 +125,14 @@ EVP_PKEY_CTX_set1_id, EVP_PKEY_CTX_get1_id, EVP_PKEY_CTX_get1_id_len
  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>
 
@@ -395,19 +407,42 @@ negotiated protocol version. Otherwise it should be left unset.
 
 =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
@@ -417,8 +452,7 @@ then 2048 is used. Only accepts lengths greater than or equal to 256.
 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.
@@ -633,12 +667,16 @@ EVP_PKEY_CTX_get_rsa_padding(), EVP_PKEY_CTX_get_rsa_mgf1_md(),
 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
@@ -646,7 +684,7 @@ added in OpenSSL 1.0.0.
 
 =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
index 52cb977cb469b21e64a2fae5e7cae6520c76772e..c93abba8eb9959c859fac54f9c35f0950ad74163 100644 (file)
@@ -328,6 +328,56 @@ from I<keydata_from> to I<keydata_to>.  It is assumed that the caller
 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:
index 0afec99ae66d1d005e5a59df95e610cfc1dcdd07..1a278fecf2125b4d61e0ab49a4c92cd7fc0984b7 100644 (file)
 #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,
index fd1007631eddb17574f021cf37af0c8b05ae72bf..c8b2cb8c3c4c8fa0cd7f90fcd1e2893524660c5a 100644 (file)
@@ -14,6 +14,8 @@
 # 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
@@ -100,6 +102,12 @@ void ffc_params_set0_pqg(FFC_PARAMS *params, BIGNUM *p, BIGNUM *q, BIGNUM *g);
 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);
@@ -155,6 +163,11 @@ int ffc_validate_public_key_partial(const FFC_PARAMS *params,
 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 */
index c8a88285d8bce28aa6c970d4b1473fa49298de55..18f835231c856208b8771f6adef57de84b1bd342 100644 (file)
@@ -191,6 +191,12 @@ extern "C" {
 #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"
@@ -255,6 +261,13 @@ extern "C" {
 #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 */
index c704d5d5c9df85bc08e76b48dd7a66884a7aed43..fce6e94d66953eb7f8fa0d480c451e3b15a055b0 100644 (file)
@@ -182,15 +182,17 @@ DEPRECATEDIN_3_0(int DSA_print_fp(FILE *bp, const DSA *x, int off))
 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)
index 6514d8f06654a658478e0e139dba3641f548752a..250e7aac955d09b32a28071dba5fd3faa8e83f7c 100644 (file)
 #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;
@@ -137,7 +137,7 @@ static int dh_import(void *keydata, int selection, const OSSL_PARAM params[])
         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);
 
@@ -148,7 +148,7 @@ static int dh_export(void *keydata, int selection, OSSL_CALLBACK *param_cb,
                      void *cbarg)
 {
     DH *dh = keydata;
-    OSSL_PARAM_BLD *tmpl;
+    OSSL_PARAM_BLD *tmpl = NULL;
     OSSL_PARAM *params = NULL;
     int ok = 1;
 
@@ -166,13 +166,13 @@ static int dh_export(void *keydata, int selection, OSSL_CALLBACK *param_cb,
 
     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;
 }
 
index 78edcaa9d4417a2b3190447c7ae8e3431aa1a469..1261035296a293be446216995bd8cee20bca000e 100644 (file)
  */
 #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;
@@ -36,45 +45,63 @@ static OSSL_OP_keymgmt_export_fn dsa_export;
 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;
@@ -133,16 +160,16 @@ static int dsa_match(const void *keydata1, const void *keydata2, int selection)
 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);
 
@@ -158,12 +185,12 @@ static int dsa_export(void *keydata, int selection, OSSL_CALLBACK *param_cb,
     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)
@@ -178,10 +205,16 @@ err:
 
 /* 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                   \
@@ -246,7 +279,8 @@ static ossl_inline int dsa_get_params(void *key, OSSL_PARAM params[])
     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[] = {
@@ -254,6 +288,9 @@ 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
 };
 
@@ -311,8 +348,224 @@ static int dsa_validate(void *keydata, int selection)
     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 },
index 66502c76aa573353d5d04b18555a2d2862d4dbd6..097bdcac1cb9910dd9f2ee8b8b436f3c83e2b449 100644 (file)
@@ -3,6 +3,7 @@
 
 $SERIALIZER_GOAL=../../libimplementations.a
 $RSA_GOAL=../../libimplementations.a
+$FFC_GOAL=../../libimplementations.a
 $DH_GOAL=../../libimplementations.a
 $DSA_GOAL=../../libimplementations.a
 $ECX_GOAL=../../libimplementations.a
@@ -10,6 +11,9 @@ $EC_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
index 7c6b5afe18a2657b92399a8b8503007476befb2f..2dbbe6b37c17022a7a9ea3e4920d41c04361aa09 100644 (file)
@@ -14,6 +14,7 @@
 #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"
@@ -161,11 +162,13 @@ OSSL_OP_keymgmt_import_fn *ossl_prov_get_keymgmt_import(const OSSL_DISPATCH *fns
 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;
@@ -174,74 +177,63 @@ int ossl_prov_print_labeled_bignum(BIO *out, const char *label,
         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 */
index c26be47e661e65e249cccfbbdb0eb2ad62c44061..f5189d05fb758bbce35cbb60976f6c011da5675d 100644 (file)
@@ -19,6 +19,8 @@
 #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)
 {
@@ -39,7 +41,7 @@ int ossl_prov_print_dsa(BIO *out, DSA *dsa, enum dsa_print_type type)
 {
     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) {
@@ -66,15 +68,13 @@ int ossl_prov_print_dsa(BIO *out, DSA *dsa, enum dsa_print_type 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))
@@ -82,11 +82,7 @@ int ossl_prov_print_dsa(BIO *out, DSA *dsa, enum dsa_print_type type)
     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;
diff --git a/providers/implementations/serializers/serializer_ffc_params.c b/providers/implementations/serializers/serializer_ffc_params.c
new file mode 100644 (file)
index 0000000..da38763
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * 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;
+}
index b1c36a22212db60734efb1e5a254c81589f41ac6..2ee610565ee5bb957e80b8fdbb351e07042e9870 100644 (file)
@@ -14,6 +14,7 @@
 #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 */
@@ -54,6 +55,7 @@ int ossl_prov_prepare_ec_params(const void *eckey, int nid,
 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);
index 288efb71d062d41ce86c86a18312150c9d6d2686..39a271307b11072130c11ff3de3900e492f01880 100644 (file)
@@ -23,6 +23,8 @@
 #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;
@@ -79,6 +42,41 @@ static int dsa_test(void)
     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;
@@ -136,12 +134,175 @@ static int dsa_cb(int p, int n, BN_GENCB *arg)
     }
     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, &param_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;
 }
index 9f8d0086f7b587644fa927895a3b85b974de1e2f..5a66162caee64f1f812f918e27434cdb75312ade 100644 (file)
@@ -49,7 +49,7 @@ static int compare_with_file(const char *alg, int type, BIO *membio)
 {
     char filename[80];
     BIO *file = NULL;
-    char buf[1024];
+    char buf[4096];
     char *memdata, *fullfile = NULL;
     const char *suffix;
     size_t readbytes;
@@ -437,18 +437,17 @@ static int test_fromdata_dh(void)
         || !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);
@@ -776,6 +775,233 @@ err:
 
 #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()) {
@@ -791,6 +1017,9 @@ int setup_tests(void)
 #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);
diff --git a/test/recipes/15-test_gendsa.t b/test/recipes/15-test_gendsa.t
new file mode 100644 (file)
index 0000000..71d4725
--- /dev/null
@@ -0,0 +1,77 @@
+#! /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");
diff --git a/test/recipes/30-test_evp_pkey_provided/DSA.priv.der b/test/recipes/30-test_evp_pkey_provided/DSA.priv.der
new file mode 100644 (file)
index 0000000..d10a69d
Binary files /dev/null and b/test/recipes/30-test_evp_pkey_provided/DSA.priv.der differ
diff --git a/test/recipes/30-test_evp_pkey_provided/DSA.priv.pem b/test/recipes/30-test_evp_pkey_provided/DSA.priv.pem
new file mode 100644 (file)
index 0000000..8836ac1
--- /dev/null
@@ -0,0 +1,15 @@
+-----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-----
diff --git a/test/recipes/30-test_evp_pkey_provided/DSA.priv.txt b/test/recipes/30-test_evp_pkey_provided/DSA.priv.txt
new file mode 100644 (file)
index 0000000..1b1b758
--- /dev/null
@@ -0,0 +1,72 @@
+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
diff --git a/test/recipes/30-test_evp_pkey_provided/DSA.pub.der b/test/recipes/30-test_evp_pkey_provided/DSA.pub.der
new file mode 100644 (file)
index 0000000..7432479
Binary files /dev/null and b/test/recipes/30-test_evp_pkey_provided/DSA.pub.der differ
diff --git a/test/recipes/30-test_evp_pkey_provided/DSA.pub.pem b/test/recipes/30-test_evp_pkey_provided/DSA.pub.pem
new file mode 100644 (file)
index 0000000..98242b4
--- /dev/null
@@ -0,0 +1,20 @@
+-----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-----
diff --git a/test/recipes/30-test_evp_pkey_provided/DSA.pub.txt b/test/recipes/30-test_evp_pkey_provided/DSA.pub.txt
new file mode 100644 (file)
index 0000000..1b1b758
--- /dev/null
@@ -0,0 +1,72 @@
+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
index dd3ddef8336f1eea2a772989f2938ff291ed7857..032548097e1eaf4ae9aafd8246e2f163cdff23b0 100644 (file)
@@ -5056,3 +5056,10 @@ d2i_PrivateKey_ex_fp                    ?        3_0_0   EXIST::FUNCTION:STDIO
 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