aboutsummaryrefslogtreecommitdiff
path: root/crypto/dsa
diff options
context:
space:
mode:
authorShane Lontis <shane.lontis@oracle.com>2020-04-15 21:02:52 +1000
committerShane Lontis <shane.lontis@oracle.com>2020-04-15 21:02:52 +1000
commitb03ec3b5d62ee26bf8437556b9040d4141d5bdd8 (patch)
tree1f27a892757c24efab70d2fb8f93110f71c0fbb3 /crypto/dsa
parent09b3654096ed344edd78cf156cb3ddcdbced6f9a (diff)
downloadopenssl-b03ec3b5d62ee26bf8437556b9040d4141d5bdd8.zip
openssl-b03ec3b5d62ee26bf8437556b9040d4141d5bdd8.tar.gz
openssl-b03ec3b5d62ee26bf8437556b9040d4141d5bdd8.tar.bz2
Add DSA keygen to provider
Moved some shared FFC code into the FFC files. Added extra paramgen parameters for seed, gindex. Fixed bug in ossl_prov util to print bignums. Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/11303)
Diffstat (limited to 'crypto/dsa')
-rw-r--r--crypto/dsa/build.info4
-rw-r--r--crypto/dsa/dsa_ameth.c4
-rw-r--r--crypto/dsa/dsa_backend.c2
-rw-r--r--crypto/dsa/dsa_gen.c23
-rw-r--r--crypto/dsa/dsa_key.c8
-rw-r--r--crypto/dsa/dsa_lib.c161
6 files changed, 186 insertions, 16 deletions
diff --git a/crypto/dsa/build.info b/crypto/dsa/build.info
index fb5a4fe..7f621cb 100644
--- a/crypto/dsa/build.info
+++ b/crypto/dsa/build.info
@@ -1,10 +1,10 @@
LIBS=../../libcrypto
$COMMON=dsa_sign.c dsa_vrf.c dsa_lib.c dsa_ossl.c dsa_check.c \
- dsa_key.c dsa_backend.c
+ dsa_key.c dsa_backend.c dsa_gen.c
SOURCE[../../libcrypto]=$COMMON\
- dsa_gen.c dsa_asn1.c \
+ dsa_asn1.c \
dsa_err.c dsa_depr.c dsa_ameth.c dsa_pmeth.c dsa_prn.c \
dsa_meth.c
SOURCE[../../providers/libfips.a]=$COMMON
diff --git a/crypto/dsa/dsa_ameth.c b/crypto/dsa/dsa_ameth.c
index d63c142..81bb6d8 100644
--- a/crypto/dsa/dsa_ameth.c
+++ b/crypto/dsa/dsa_ameth.c
@@ -19,11 +19,11 @@
#include <openssl/bn.h>
#include <openssl/cms.h>
#include <openssl/core_names.h>
+#include <openssl/param_build.h>
#include "internal/cryptlib.h"
#include "crypto/asn1.h"
#include "crypto/dsa.h"
#include "crypto/evp.h"
-#include "openssl/param_build.h"
#include "internal/ffc.h"
#include "dsa_local.h"
@@ -586,7 +586,7 @@ static int dsa_pkey_import_from(const OSSL_PARAM params[], void *key)
return 0;
}
- if (!ffc_fromdata(dsa_get0_params(dsa), params)
+ if (!dsa_ffc_params_fromdata(dsa, params)
|| !dsa_key_fromdata(dsa, params)
|| !EVP_PKEY_assign_DSA(pkey, dsa)) {
DSA_free(dsa);
diff --git a/crypto/dsa/dsa_backend.c b/crypto/dsa/dsa_backend.c
index b927465..461cb18 100644
--- a/crypto/dsa/dsa_backend.c
+++ b/crypto/dsa/dsa_backend.c
@@ -34,7 +34,7 @@ int dsa_key_fromdata(DSA *dsa, const OSSL_PARAM params[])
return 1;
/*
- * DH documentation says that a public key must be present if a
+ * DSA documentation says that a public key must be present if a
* private key is present.
*/
if (param_priv_key != NULL && param_pub_key == NULL)
diff --git a/crypto/dsa/dsa_gen.c b/crypto/dsa/dsa_gen.c
index 2148a1a..7b72867 100644
--- a/crypto/dsa/dsa_gen.c
+++ b/crypto/dsa/dsa_gen.c
@@ -24,32 +24,34 @@
#include "dsa_local.h"
int dsa_generate_ffc_parameters(DSA *dsa, int type,
- int pbits, int qbits, int gindex,
- BN_GENCB *cb)
+ int pbits, int qbits,
+ EVP_MD *md, BN_GENCB *cb)
{
int ret = 0, res;
if (qbits <= 0) {
- const EVP_MD *evpmd = pbits >= 2048 ? EVP_sha256() : EVP_sha1();
-
- qbits = EVP_MD_size(evpmd) * 8;
+ if (md != NULL)
+ qbits = EVP_MD_size(md) * 8;
+ else
+ qbits = (pbits >= 2048 ? SHA256_DIGEST_LENGTH :
+ SHA_DIGEST_LENGTH) * 8;
}
- dsa->params.gindex = gindex;
#ifndef FIPS_MODE
if (type == DSA_PARAMGEN_TYPE_FIPS_186_2)
ret = ffc_params_FIPS186_2_generate(dsa->libctx, &dsa->params,
FFC_PARAM_TYPE_DSA,
- pbits, qbits, NULL, &res, cb);
+ pbits, qbits, md, &res, cb);
else
#endif
ret = ffc_params_FIPS186_4_generate(dsa->libctx, &dsa->params,
FFC_PARAM_TYPE_DSA,
- pbits, qbits, NULL, &res, cb);
+ pbits, qbits, md, &res, cb);
if (ret > 0)
dsa->dirty_cnt++;
return ret;
}
+#ifndef FIPS_MODE
int DSA_generate_parameters_ex(DSA *dsa, int bits,
const unsigned char *seed_in, int seed_len,
int *counter_ret, unsigned long *h_ret,
@@ -68,13 +70,13 @@ int DSA_generate_parameters_ex(DSA *dsa, int bits,
/* The old code used FIPS 186-2 DSA Parameter generation */
if (bits <= 1024 && seed_len == 20) {
if (!dsa_generate_ffc_parameters(dsa, DSA_PARAMGEN_TYPE_FIPS_186_2,
- bits, 160, -1, cb))
+ bits, 160, NULL, cb))
return 0;
} else
#endif
{
if (!dsa_generate_ffc_parameters(dsa, DSA_PARAMGEN_TYPE_FIPS_186_4,
- bits, -1, -1, cb))
+ bits, -1, NULL, cb))
return 0;
}
@@ -84,3 +86,4 @@ int DSA_generate_parameters_ex(DSA *dsa, int bits,
*h_ret = dsa->params.h;
return 1;
}
+#endif
diff --git a/crypto/dsa/dsa_key.c b/crypto/dsa/dsa_key.c
index 2dec35f..1d62527 100644
--- a/crypto/dsa/dsa_key.c
+++ b/crypto/dsa/dsa_key.c
@@ -21,6 +21,12 @@
#include "crypto/dsa.h"
#include "dsa_local.h"
+#ifdef FIPS_MODE
+# define MIN_STRENGTH 112
+#else
+# define MIN_STRENGTH 80
+#endif
+
static int dsa_keygen(DSA *dsa, int pairwise_test);
static int dsa_keygen_pairwise_test(DSA *dsa, OSSL_CALLBACK *cb, void *cbarg);
@@ -69,7 +75,7 @@ static int dsa_keygen(DSA *dsa, int pairwise_test)
}
if (!ffc_generate_private_key(ctx, &dsa->params, BN_num_bits(dsa->params.q),
- 112, priv_key))
+ MIN_STRENGTH, priv_key))
goto err;
if (dsa->pub_key == NULL) {
diff --git a/crypto/dsa/dsa_lib.c b/crypto/dsa/dsa_lib.c
index e320522..b773f2c 100644
--- a/crypto/dsa/dsa_lib.c
+++ b/crypto/dsa/dsa_lib.c
@@ -19,7 +19,9 @@
#include <openssl/bn.h>
#include <openssl/asn1.h>
#include <openssl/engine.h>
+#include <openssl/core_names.h>
#include "dsa_local.h"
+#include "crypto/evp.h"
#include "crypto/dsa.h"
#include "crypto/dh.h" /* required by DSA_dup_DH() */
@@ -342,3 +344,162 @@ FFC_PARAMS *dsa_get0_params(DSA *dsa)
{
return &dsa->params;
}
+
+int dsa_ffc_params_fromdata(DSA *dsa, const OSSL_PARAM params[])
+{
+ int ret;
+ FFC_PARAMS *ffc;
+
+ if (dsa == NULL)
+ return 0;
+ ffc = dsa_get0_params(dsa);
+ if (ffc == NULL)
+ return 0;
+
+ ret = ffc_params_fromdata(ffc, params);
+ if (ret)
+ dsa->dirty_cnt++;
+ return ret;
+}
+
+static int dsa_paramgen_check(EVP_PKEY_CTX *ctx)
+{
+ if (ctx == NULL || !EVP_PKEY_CTX_IS_GEN_OP(ctx)) {
+ ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
+ /* Uses the same return values as EVP_PKEY_CTX_ctrl */
+ return -2;
+ }
+ /* If key type not DSA return error */
+ if (ctx->pmeth != NULL && ctx->pmeth->pkey_id != EVP_PKEY_DSA)
+ return -1;
+ return 1;
+}
+
+int EVP_PKEY_CTX_set_dsa_paramgen_type(EVP_PKEY_CTX *ctx, const char *name)
+{
+ int ret;
+ OSSL_PARAM params[2], *p = params;
+
+ if ((ret = dsa_paramgen_check(ctx)) <= 0)
+ return ret;
+
+ *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_FFC_TYPE,
+ (char *)name, 0);
+ *p++ = OSSL_PARAM_construct_end();
+
+ return EVP_PKEY_CTX_set_params(ctx, params);
+}
+
+int EVP_PKEY_CTX_set_dsa_paramgen_gindex(EVP_PKEY_CTX *ctx, int gindex)
+{
+ int ret;
+ OSSL_PARAM params[2], *p = params;
+
+ if ((ret = dsa_paramgen_check(ctx)) <= 0)
+ return ret;
+
+ *p++ = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_FFC_GINDEX, &gindex);
+ *p++ = OSSL_PARAM_construct_end();
+
+ return EVP_PKEY_CTX_set_params(ctx, params);
+}
+
+int EVP_PKEY_CTX_set_dsa_paramgen_seed(EVP_PKEY_CTX *ctx,
+ const unsigned char *seed,
+ size_t seedlen)
+{
+ int ret;
+ OSSL_PARAM params[2], *p = params;
+
+ if ((ret = dsa_paramgen_check(ctx)) <= 0)
+ return ret;
+
+ *p++ = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_FFC_SEED,
+ (void *)seed, seedlen);
+ *p++ = OSSL_PARAM_construct_end();
+
+ return EVP_PKEY_CTX_set_params(ctx, params);
+}
+
+int EVP_PKEY_CTX_set_dsa_paramgen_bits(EVP_PKEY_CTX *ctx, int nbits)
+{
+ int ret;
+ OSSL_PARAM params[2], *p = params;
+ size_t bits = nbits;
+
+ if ((ret = dsa_paramgen_check(ctx)) <= 0)
+ return ret;
+
+#if !defined(FIPS_MODE)
+ /* TODO(3.0): Remove this eventually when no more legacy */
+ if (ctx->op.keymgmt.genctx == NULL)
+ return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN,
+ EVP_PKEY_CTRL_DSA_PARAMGEN_BITS, nbits, NULL);
+#endif
+
+ *p++ = OSSL_PARAM_construct_size_t(OSSL_PKEY_PARAM_FFC_PBITS, &bits);
+ *p++ = OSSL_PARAM_construct_end();
+
+ return EVP_PKEY_CTX_set_params(ctx, params);
+}
+
+int EVP_PKEY_CTX_set_dsa_paramgen_q_bits(EVP_PKEY_CTX *ctx, int qbits)
+{
+ int ret;
+ OSSL_PARAM params[2], *p = params;
+ size_t bits2 = qbits;
+
+ if ((ret = dsa_paramgen_check(ctx)) <= 0)
+ return ret;
+
+#if !defined(FIPS_MODE)
+ /* TODO(3.0): Remove this eventually when no more legacy */
+ if (ctx->op.keymgmt.genctx == NULL)
+ return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN,
+ EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS, qbits, NULL);
+#endif
+
+ *p++ = OSSL_PARAM_construct_size_t(OSSL_PKEY_PARAM_FFC_QBITS, &bits2);
+ *p++ = OSSL_PARAM_construct_end();
+
+ return EVP_PKEY_CTX_set_params(ctx, params);
+}
+
+int EVP_PKEY_CTX_set_dsa_paramgen_md_props(EVP_PKEY_CTX *ctx,
+ const char *md_name,
+ const char *md_properties)
+{
+ int ret;
+ OSSL_PARAM params[3], *p = params;
+
+ if ((ret = dsa_paramgen_check(ctx)) <= 0)
+ return ret;
+
+#if !defined(FIPS_MODE)
+ /* TODO(3.0): Remove this eventually when no more legacy */
+ if (ctx->op.keymgmt.genctx == NULL) {
+ const EVP_MD *md = EVP_get_digestbyname(md_name);
+
+ EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN,
+ EVP_PKEY_CTRL_DSA_PARAMGEN_MD, 0, (void *)(md));
+ }
+#endif
+
+ *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_FFC_DIGEST,
+ (char *)md_name, 0);
+ if (md_properties != NULL)
+ *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_FFC_DIGEST_PROPS,
+ (char *)md_properties, 0);
+ *p++ = OSSL_PARAM_construct_end();
+
+ return EVP_PKEY_CTX_set_params(ctx, params);
+}
+
+#if !defined(FIPS_MODE)
+int EVP_PKEY_CTX_set_dsa_paramgen_md(EVP_PKEY_CTX *ctx, const EVP_MD *md)
+{
+ const char *md_name = (md == NULL) ? "" : EVP_MD_name(md);
+
+ return EVP_PKEY_CTX_set_dsa_paramgen_md_props(ctx, md_name, NULL);
+}
+#endif