Latest update.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
LIBS=../../libcrypto
|
||||
|
||||
$COMMON=dsa_sign.c dsa_vrf.c dsa_lib.c dsa_ossl.c
|
||||
$COMMON=dsa_sign.c dsa_vrf.c dsa_lib.c dsa_ossl.c dsa_aid.c
|
||||
|
||||
SOURCE[../../libcrypto]=$COMMON\
|
||||
dsa_gen.c dsa_key.c dsa_asn1.c \
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <openssl/objects.h>
|
||||
#include "crypto/dsa.h"
|
||||
|
||||
#define ASN1_SEQUENCE 0x30
|
||||
#define ASN1_OID 0x06
|
||||
|
||||
/* dsaWithSHA OIDs are of the form: (1 3 14 3 2 |n|) */
|
||||
#define ENCODE_ALGORITHMIDENTIFIER_SHA(name, n) \
|
||||
static const unsigned char algorithmidentifier_##name##_der[] = { \
|
||||
ASN1_SEQUENCE, 0x07, \
|
||||
ASN1_OID, 0x05, 1 * 40 + 3, 14, 3, 2, n \
|
||||
}
|
||||
|
||||
ENCODE_ALGORITHMIDENTIFIER_SHA(sha, 13);
|
||||
ENCODE_ALGORITHMIDENTIFIER_SHA(sha1, 27);
|
||||
|
||||
/* dsaWithSHA OIDs are of the form: (2 16 840 1 101 3 4 3 |n|) */
|
||||
#define ENCODE_ALGORITHMIDENTIFIER_SHAx(name, n) \
|
||||
static const unsigned char algorithmidentifier_##name##_der[] = { \
|
||||
ASN1_SEQUENCE, 0x0b, \
|
||||
ASN1_OID, 0x09, 2 * 40 + 16, 0x86, 0x48, 1, 101, 3, 4, 3, n \
|
||||
}
|
||||
|
||||
ENCODE_ALGORITHMIDENTIFIER_SHAx(sha224, 1);
|
||||
ENCODE_ALGORITHMIDENTIFIER_SHAx(sha256, 2);
|
||||
ENCODE_ALGORITHMIDENTIFIER_SHAx(sha384, 3);
|
||||
ENCODE_ALGORITHMIDENTIFIER_SHAx(sha512, 4);
|
||||
ENCODE_ALGORITHMIDENTIFIER_SHAx(sha3_224, 5);
|
||||
ENCODE_ALGORITHMIDENTIFIER_SHAx(sha3_256, 6);
|
||||
ENCODE_ALGORITHMIDENTIFIER_SHAx(sha3_384, 7);
|
||||
ENCODE_ALGORITHMIDENTIFIER_SHAx(sha3_512, 8);
|
||||
|
||||
#define MD_CASE(name) \
|
||||
case NID_##name: \
|
||||
*len = sizeof(algorithmidentifier_##name##_der); \
|
||||
return algorithmidentifier_##name##_der
|
||||
|
||||
const unsigned char *dsa_algorithmidentifier_encoding(int md_nid, size_t *len)
|
||||
{
|
||||
switch (md_nid) {
|
||||
MD_CASE(sha);
|
||||
MD_CASE(sha1);
|
||||
MD_CASE(sha224);
|
||||
MD_CASE(sha256);
|
||||
MD_CASE(sha384);
|
||||
MD_CASE(sha512);
|
||||
MD_CASE(sha3_224);
|
||||
MD_CASE(sha3_256);
|
||||
MD_CASE(sha3_384);
|
||||
MD_CASE(sha3_512);
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
+39
-65
@@ -88,7 +88,10 @@ static int dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
|
||||
ASN1_OBJECT *aobj;
|
||||
|
||||
dsa = pkey->pkey.dsa;
|
||||
if (pkey->save_parameters && dsa->p && dsa->q && dsa->g) {
|
||||
if (pkey->save_parameters
|
||||
&& dsa->params.p != NULL
|
||||
&& dsa->params.q != NULL
|
||||
&& dsa->params.g != NULL) {
|
||||
str = ASN1_STRING_new();
|
||||
if (str == NULL) {
|
||||
DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
|
||||
@@ -183,7 +186,8 @@ static int dsa_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8)
|
||||
}
|
||||
|
||||
BN_set_flags(dsa->priv_key, BN_FLG_CONSTTIME);
|
||||
if (!BN_mod_exp(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx)) {
|
||||
if (!BN_mod_exp(dsa->pub_key, dsa->params.g, dsa->priv_key, dsa->params.p,
|
||||
ctx)) {
|
||||
DSAerr(DSA_F_DSA_PRIV_DECODE, DSA_R_BN_ERROR);
|
||||
goto dsaerr;
|
||||
}
|
||||
@@ -275,55 +279,34 @@ static int dsa_missing_parameters(const EVP_PKEY *pkey)
|
||||
{
|
||||
DSA *dsa;
|
||||
dsa = pkey->pkey.dsa;
|
||||
if (dsa == NULL || dsa->p == NULL || dsa->q == NULL || dsa->g == NULL)
|
||||
return 1;
|
||||
return 0;
|
||||
return dsa == NULL
|
||||
|| dsa->params.p == NULL
|
||||
|| dsa->params.q == NULL
|
||||
|| dsa->params.g == NULL;
|
||||
}
|
||||
|
||||
static int dsa_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
|
||||
{
|
||||
BIGNUM *a;
|
||||
|
||||
if (to->pkey.dsa == NULL) {
|
||||
to->pkey.dsa = DSA_new();
|
||||
if (to->pkey.dsa == NULL)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((a = BN_dup(from->pkey.dsa->p)) == NULL)
|
||||
if (!ffc_params_copy(&to->pkey.dsa->params, &from->pkey.dsa->params))
|
||||
return 0;
|
||||
BN_free(to->pkey.dsa->p);
|
||||
to->pkey.dsa->p = a;
|
||||
|
||||
if ((a = BN_dup(from->pkey.dsa->q)) == NULL)
|
||||
return 0;
|
||||
BN_free(to->pkey.dsa->q);
|
||||
to->pkey.dsa->q = a;
|
||||
|
||||
if ((a = BN_dup(from->pkey.dsa->g)) == NULL)
|
||||
return 0;
|
||||
BN_free(to->pkey.dsa->g);
|
||||
to->pkey.dsa->g = a;
|
||||
to->pkey.dsa->dirty_cnt++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int dsa_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
|
||||
{
|
||||
if (BN_cmp(a->pkey.dsa->p, b->pkey.dsa->p) ||
|
||||
BN_cmp(a->pkey.dsa->q, b->pkey.dsa->q) ||
|
||||
BN_cmp(a->pkey.dsa->g, b->pkey.dsa->g))
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
return ffc_params_cmp(&a->pkey.dsa->params, &b->pkey.dsa->params, 1);
|
||||
}
|
||||
|
||||
static int dsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
|
||||
{
|
||||
if (BN_cmp(b->pkey.dsa->pub_key, a->pkey.dsa->pub_key) != 0)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
return BN_cmp(b->pkey.dsa->pub_key, a->pkey.dsa->pub_key) == 0;
|
||||
}
|
||||
|
||||
static void int_dsa_free(EVP_PKEY *pkey)
|
||||
@@ -338,8 +321,8 @@ static int do_dsa_print(BIO *bp, const DSA *x, int off, int ptype)
|
||||
const BIGNUM *priv_key, *pub_key;
|
||||
int mod_len = 0;
|
||||
|
||||
if (x->p != NULL)
|
||||
mod_len = BN_num_bits(x->p);
|
||||
if (x->params.p != NULL)
|
||||
mod_len = DSA_bits(x);
|
||||
|
||||
if (ptype == 2)
|
||||
priv_key = x->priv_key;
|
||||
@@ -358,11 +341,10 @@ static int do_dsa_print(BIO *bp, const DSA *x, int off, int ptype)
|
||||
else
|
||||
ktype = "DSA-Parameters";
|
||||
|
||||
if (priv_key) {
|
||||
if (priv_key != NULL) {
|
||||
if (!BIO_indent(bp, off, 128))
|
||||
goto err;
|
||||
if (BIO_printf(bp, "%s: (%d bit)\n", ktype, BN_num_bits(x->p))
|
||||
<= 0)
|
||||
if (BIO_printf(bp, "%s: (%d bit)\n", ktype, mod_len) <= 0)
|
||||
goto err;
|
||||
} else {
|
||||
if (BIO_printf(bp, "Public-Key: (%d bit)\n", mod_len) <= 0)
|
||||
@@ -373,11 +355,7 @@ static int do_dsa_print(BIO *bp, const DSA *x, int off, int ptype)
|
||||
goto err;
|
||||
if (!ASN1_bn_print(bp, "pub: ", pub_key, NULL, off))
|
||||
goto err;
|
||||
if (!ASN1_bn_print(bp, "P: ", x->p, NULL, off))
|
||||
goto err;
|
||||
if (!ASN1_bn_print(bp, "Q: ", x->q, NULL, off))
|
||||
goto err;
|
||||
if (!ASN1_bn_print(bp, "G: ", x->g, NULL, off))
|
||||
if (!ffc_params_print(bp, &x->params, off))
|
||||
goto err;
|
||||
ret = 1;
|
||||
err:
|
||||
@@ -446,7 +424,7 @@ static int dsa_sig_print(BIO *bp, const X509_ALGOR *sigalg,
|
||||
DSA_SIG *dsa_sig;
|
||||
const unsigned char *p;
|
||||
|
||||
if (!sig) {
|
||||
if (sig == NULL) {
|
||||
if (BIO_puts(bp, "\n") <= 0)
|
||||
return 0;
|
||||
else
|
||||
@@ -454,7 +432,7 @@ static int dsa_sig_print(BIO *bp, const X509_ALGOR *sigalg,
|
||||
}
|
||||
p = sig->data;
|
||||
dsa_sig = d2i_DSA_SIG(NULL, &p, sig->length);
|
||||
if (dsa_sig) {
|
||||
if (dsa_sig != NULL) {
|
||||
int rv = 0;
|
||||
const BIGNUM *r, *s;
|
||||
|
||||
@@ -533,48 +511,44 @@ static size_t dsa_pkey_dirty_cnt(const EVP_PKEY *pkey)
|
||||
return pkey->pkey.dsa->dirty_cnt;
|
||||
}
|
||||
|
||||
static void *dsa_pkey_export_to(const EVP_PKEY *pk, EVP_KEYMGMT *keymgmt,
|
||||
int want_domainparams)
|
||||
static int dsa_pkey_export_to(const EVP_PKEY *from, void *to_keydata,
|
||||
EVP_KEYMGMT *to_keymgmt)
|
||||
{
|
||||
DSA *dsa = pk->pkey.dsa;
|
||||
DSA *dsa = from->pkey.dsa;
|
||||
OSSL_PARAM_BLD tmpl;
|
||||
const BIGNUM *p = DSA_get0_p(dsa), *g = DSA_get0_g(dsa);
|
||||
const BIGNUM *q = DSA_get0_q(dsa), *pub_key = DSA_get0_pub_key(dsa);
|
||||
const BIGNUM *priv_key = DSA_get0_priv_key(dsa);
|
||||
OSSL_PARAM *params;
|
||||
void *provdata = NULL;
|
||||
int rv;
|
||||
|
||||
if (p == NULL || q == NULL || g == NULL)
|
||||
return NULL;
|
||||
return 0;
|
||||
|
||||
ossl_param_bld_init(&tmpl);
|
||||
if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_FFC_P, p)
|
||||
|| !ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_FFC_Q, q)
|
||||
|| !ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_FFC_G, g))
|
||||
return NULL;
|
||||
|
||||
if (!want_domainparams) {
|
||||
/* A key must at least have a public part. */
|
||||
if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_DSA_PUB_KEY,
|
||||
pub_key))
|
||||
return NULL;
|
||||
|
||||
if (priv_key != NULL) {
|
||||
if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_DSA_PRIV_KEY,
|
||||
priv_key))
|
||||
return NULL;
|
||||
}
|
||||
return 0;
|
||||
if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_DSA_PUB_KEY,
|
||||
pub_key))
|
||||
return 0;
|
||||
if (priv_key != NULL) {
|
||||
if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_DSA_PRIV_KEY,
|
||||
priv_key))
|
||||
return 0;
|
||||
}
|
||||
|
||||
params = ossl_param_bld_to_param(&tmpl);
|
||||
if ((params = ossl_param_bld_to_param(&tmpl)) == NULL)
|
||||
return 0;
|
||||
|
||||
/* We export, the provider imports */
|
||||
provdata = want_domainparams
|
||||
? evp_keymgmt_importdomparams(keymgmt, params)
|
||||
: evp_keymgmt_importkey(keymgmt, params);
|
||||
rv = evp_keymgmt_import(to_keymgmt, to_keydata, OSSL_KEYMGMT_SELECT_ALL,
|
||||
params);
|
||||
|
||||
ossl_param_bld_free(params);
|
||||
return provdata;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* NB these are sorted in pkey_id order, lowest first */
|
||||
|
||||
@@ -34,9 +34,9 @@ static int dsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
|
||||
|
||||
ASN1_SEQUENCE_cb(DSAPrivateKey, dsa_cb) = {
|
||||
ASN1_EMBED(DSA, version, INT32),
|
||||
ASN1_SIMPLE(DSA, p, BIGNUM),
|
||||
ASN1_SIMPLE(DSA, q, BIGNUM),
|
||||
ASN1_SIMPLE(DSA, g, BIGNUM),
|
||||
ASN1_SIMPLE(DSA, params.p, BIGNUM),
|
||||
ASN1_SIMPLE(DSA, params.q, BIGNUM),
|
||||
ASN1_SIMPLE(DSA, params.g, BIGNUM),
|
||||
ASN1_SIMPLE(DSA, pub_key, BIGNUM),
|
||||
ASN1_SIMPLE(DSA, priv_key, CBIGNUM)
|
||||
} static_ASN1_SEQUENCE_END_cb(DSA, DSAPrivateKey)
|
||||
@@ -44,18 +44,18 @@ ASN1_SEQUENCE_cb(DSAPrivateKey, dsa_cb) = {
|
||||
IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(DSA, DSAPrivateKey, DSAPrivateKey)
|
||||
|
||||
ASN1_SEQUENCE_cb(DSAparams, dsa_cb) = {
|
||||
ASN1_SIMPLE(DSA, p, BIGNUM),
|
||||
ASN1_SIMPLE(DSA, q, BIGNUM),
|
||||
ASN1_SIMPLE(DSA, g, BIGNUM),
|
||||
ASN1_SIMPLE(DSA, params.p, BIGNUM),
|
||||
ASN1_SIMPLE(DSA, params.q, BIGNUM),
|
||||
ASN1_SIMPLE(DSA, params.g, BIGNUM),
|
||||
} static_ASN1_SEQUENCE_END_cb(DSA, DSAparams)
|
||||
|
||||
IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(DSA, DSAparams, DSAparams)
|
||||
|
||||
ASN1_SEQUENCE_cb(DSAPublicKey, dsa_cb) = {
|
||||
ASN1_SIMPLE(DSA, pub_key, BIGNUM),
|
||||
ASN1_SIMPLE(DSA, p, BIGNUM),
|
||||
ASN1_SIMPLE(DSA, q, BIGNUM),
|
||||
ASN1_SIMPLE(DSA, g, BIGNUM)
|
||||
ASN1_SIMPLE(DSA, params.p, BIGNUM),
|
||||
ASN1_SIMPLE(DSA, params.q, BIGNUM),
|
||||
ASN1_SIMPLE(DSA, params.g, BIGNUM)
|
||||
} static_ASN1_SEQUENCE_END_cb(DSA, DSAPublicKey)
|
||||
|
||||
IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(DSA, DSAPublicKey, DSAPublicKey)
|
||||
|
||||
+69
-591
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-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
|
||||
@@ -7,13 +7,6 @@
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
/*
|
||||
* Parameter generation follows the updated Appendix 2.2 for FIPS PUB 186,
|
||||
* also Appendix 2.2 of FIPS PUB 186-1 (i.e. use SHA as defined in FIPS PUB
|
||||
* 180-1)
|
||||
*/
|
||||
#define xxxHASH EVP_sha1()
|
||||
|
||||
#include <openssl/opensslconf.h>
|
||||
#include <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
@@ -21,594 +14,79 @@
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/sha.h>
|
||||
#include "crypto/dsa.h"
|
||||
#include "dsa_local.h"
|
||||
|
||||
int DSA_generate_parameters_ex(DSA *ret, int bits,
|
||||
int dsa_generate_ffc_parameters(OPENSSL_CTX *libctx, DSA *dsa, int type,
|
||||
int pbits, int qbits, int gindex,
|
||||
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;
|
||||
}
|
||||
dsa->params.gindex = gindex;
|
||||
#ifndef FIPS_MODE
|
||||
if (type == DSA_PARAMGEN_TYPE_FIPS_186_2)
|
||||
ret = ffc_params_FIPS186_2_generate(libctx, &dsa->params,
|
||||
FFC_PARAM_TYPE_DSA,
|
||||
pbits, qbits, NULL, &res, cb);
|
||||
else
|
||||
#endif
|
||||
ret = ffc_params_FIPS186_4_generate(libctx, &dsa->params,
|
||||
FFC_PARAM_TYPE_DSA,
|
||||
pbits, qbits, NULL, &res, cb);
|
||||
if (ret > 0)
|
||||
dsa->dirty_cnt++;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int dsa_generate_parameters_ctx(OPENSSL_CTX *libctx, DSA *dsa, int bits,
|
||||
const unsigned char *seed_in, int seed_len,
|
||||
int *counter_ret, unsigned long *h_ret,
|
||||
BN_GENCB *cb)
|
||||
{
|
||||
#ifndef FIPS_MODE
|
||||
if (dsa->meth->dsa_paramgen)
|
||||
return dsa->meth->dsa_paramgen(dsa, bits, seed_in, seed_len,
|
||||
counter_ret, h_ret, cb);
|
||||
#endif
|
||||
if (seed_in != NULL
|
||||
&& !ffc_params_set_validate_params(&dsa->params, seed_in, seed_len, -1))
|
||||
return 0;
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
/* The old code used FIPS 186-2 DSA Parameter generation */
|
||||
if (bits <= 1024 && seed_len == 20) {
|
||||
if (!dsa_generate_ffc_parameters(libctx, dsa,
|
||||
DSA_PARAMGEN_TYPE_FIPS_186_2,
|
||||
bits, 160, -1, cb))
|
||||
return 0;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
if (!dsa_generate_ffc_parameters(libctx, dsa,
|
||||
DSA_PARAMGEN_TYPE_FIPS_186_4,
|
||||
bits, -1, -1, cb))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (counter_ret != NULL)
|
||||
*counter_ret = dsa->params.pcounter;
|
||||
if (h_ret != NULL)
|
||||
*h_ret = dsa->params.h;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int DSA_generate_parameters_ex(DSA *dsa, int bits,
|
||||
const unsigned char *seed_in, int seed_len,
|
||||
int *counter_ret, unsigned long *h_ret,
|
||||
BN_GENCB *cb)
|
||||
{
|
||||
if (ret->meth->dsa_paramgen)
|
||||
return ret->meth->dsa_paramgen(ret, bits, seed_in, seed_len,
|
||||
return dsa_generate_parameters_ctx(NULL, dsa, bits,
|
||||
seed_in, seed_len,
|
||||
counter_ret, h_ret, cb);
|
||||
else {
|
||||
const EVP_MD *evpmd = bits >= 2048 ? EVP_sha256() : EVP_sha1();
|
||||
size_t qbits = EVP_MD_size(evpmd) * 8;
|
||||
|
||||
return dsa_builtin_paramgen(ret, bits, qbits, evpmd,
|
||||
seed_in, seed_len, NULL, counter_ret,
|
||||
h_ret, cb);
|
||||
}
|
||||
}
|
||||
|
||||
int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
|
||||
const EVP_MD *evpmd, const unsigned char *seed_in,
|
||||
size_t seed_len, unsigned char *seed_out,
|
||||
int *counter_ret, unsigned long *h_ret, BN_GENCB *cb)
|
||||
{
|
||||
int ok = 0;
|
||||
unsigned char seed[SHA256_DIGEST_LENGTH];
|
||||
unsigned char md[SHA256_DIGEST_LENGTH];
|
||||
unsigned char buf[SHA256_DIGEST_LENGTH], buf2[SHA256_DIGEST_LENGTH];
|
||||
BIGNUM *r0, *W, *X, *c, *test;
|
||||
BIGNUM *g = NULL, *q = NULL, *p = NULL;
|
||||
BN_MONT_CTX *mont = NULL;
|
||||
int i, k, n = 0, m = 0, qsize = qbits >> 3;
|
||||
int counter = 0;
|
||||
int r = 0;
|
||||
BN_CTX *ctx = NULL;
|
||||
unsigned int h = 2;
|
||||
|
||||
if (qsize != SHA_DIGEST_LENGTH && qsize != SHA224_DIGEST_LENGTH &&
|
||||
qsize != SHA256_DIGEST_LENGTH)
|
||||
/* invalid q size */
|
||||
return 0;
|
||||
|
||||
if (evpmd == NULL) {
|
||||
if (qsize == SHA_DIGEST_LENGTH)
|
||||
evpmd = EVP_sha1();
|
||||
else if (qsize == SHA224_DIGEST_LENGTH)
|
||||
evpmd = EVP_sha224();
|
||||
else
|
||||
evpmd = EVP_sha256();
|
||||
} else {
|
||||
qsize = EVP_MD_size(evpmd);
|
||||
}
|
||||
|
||||
if (bits < 512)
|
||||
bits = 512;
|
||||
|
||||
bits = (bits + 63) / 64 * 64;
|
||||
|
||||
if (seed_in != NULL) {
|
||||
if (seed_len < (size_t)qsize) {
|
||||
DSAerr(DSA_F_DSA_BUILTIN_PARAMGEN, DSA_R_SEED_LEN_SMALL);
|
||||
return 0;
|
||||
}
|
||||
if (seed_len > (size_t)qsize) {
|
||||
/* Only consume as much seed as is expected. */
|
||||
seed_len = qsize;
|
||||
}
|
||||
memcpy(seed, seed_in, seed_len);
|
||||
}
|
||||
|
||||
if ((mont = BN_MONT_CTX_new()) == NULL)
|
||||
goto err;
|
||||
|
||||
if ((ctx = BN_CTX_new()) == NULL)
|
||||
goto err;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
|
||||
r0 = BN_CTX_get(ctx);
|
||||
g = BN_CTX_get(ctx);
|
||||
W = BN_CTX_get(ctx);
|
||||
q = BN_CTX_get(ctx);
|
||||
X = BN_CTX_get(ctx);
|
||||
c = BN_CTX_get(ctx);
|
||||
p = BN_CTX_get(ctx);
|
||||
test = BN_CTX_get(ctx);
|
||||
|
||||
if (test == NULL)
|
||||
goto err;
|
||||
|
||||
if (!BN_lshift(test, BN_value_one(), bits - 1))
|
||||
goto err;
|
||||
|
||||
for (;;) {
|
||||
for (;;) { /* find q */
|
||||
int use_random_seed = (seed_in == NULL);
|
||||
|
||||
/* step 1 */
|
||||
if (!BN_GENCB_call(cb, 0, m++))
|
||||
goto err;
|
||||
|
||||
if (use_random_seed) {
|
||||
if (RAND_bytes(seed, qsize) <= 0)
|
||||
goto err;
|
||||
} else {
|
||||
/* If we come back through, use random seed next time. */
|
||||
seed_in = NULL;
|
||||
}
|
||||
memcpy(buf, seed, qsize);
|
||||
memcpy(buf2, seed, qsize);
|
||||
/* precompute "SEED + 1" for step 7: */
|
||||
for (i = qsize - 1; i >= 0; i--) {
|
||||
buf[i]++;
|
||||
if (buf[i] != 0)
|
||||
break;
|
||||
}
|
||||
|
||||
/* step 2 */
|
||||
if (!EVP_Digest(seed, qsize, md, NULL, evpmd, NULL))
|
||||
goto err;
|
||||
if (!EVP_Digest(buf, qsize, buf2, NULL, evpmd, NULL))
|
||||
goto err;
|
||||
for (i = 0; i < qsize; i++)
|
||||
md[i] ^= buf2[i];
|
||||
|
||||
/* step 3 */
|
||||
md[0] |= 0x80;
|
||||
md[qsize - 1] |= 0x01;
|
||||
if (!BN_bin2bn(md, qsize, q))
|
||||
goto err;
|
||||
|
||||
/* step 4 */
|
||||
r = BN_check_prime(q, ctx, cb);
|
||||
if (r > 0)
|
||||
break;
|
||||
if (r != 0)
|
||||
goto err;
|
||||
|
||||
/* do a callback call */
|
||||
/* step 5 */
|
||||
}
|
||||
|
||||
if (!BN_GENCB_call(cb, 2, 0))
|
||||
goto err;
|
||||
if (!BN_GENCB_call(cb, 3, 0))
|
||||
goto err;
|
||||
|
||||
/* step 6 */
|
||||
counter = 0;
|
||||
/* "offset = 2" */
|
||||
|
||||
n = (bits - 1) / 160;
|
||||
|
||||
for (;;) {
|
||||
if ((counter != 0) && !BN_GENCB_call(cb, 0, counter))
|
||||
goto err;
|
||||
|
||||
/* step 7 */
|
||||
BN_zero(W);
|
||||
/* now 'buf' contains "SEED + offset - 1" */
|
||||
for (k = 0; k <= n; k++) {
|
||||
/*
|
||||
* obtain "SEED + offset + k" by incrementing:
|
||||
*/
|
||||
for (i = qsize - 1; i >= 0; i--) {
|
||||
buf[i]++;
|
||||
if (buf[i] != 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!EVP_Digest(buf, qsize, md, NULL, evpmd, NULL))
|
||||
goto err;
|
||||
|
||||
/* step 8 */
|
||||
if (!BN_bin2bn(md, qsize, r0))
|
||||
goto err;
|
||||
if (!BN_lshift(r0, r0, (qsize << 3) * k))
|
||||
goto err;
|
||||
if (!BN_add(W, W, r0))
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* more of step 8 */
|
||||
if (!BN_mask_bits(W, bits - 1))
|
||||
goto err;
|
||||
if (!BN_copy(X, W))
|
||||
goto err;
|
||||
if (!BN_add(X, X, test))
|
||||
goto err;
|
||||
|
||||
/* step 9 */
|
||||
if (!BN_lshift1(r0, q))
|
||||
goto err;
|
||||
if (!BN_mod(c, X, r0, ctx))
|
||||
goto err;
|
||||
if (!BN_sub(r0, c, BN_value_one()))
|
||||
goto err;
|
||||
if (!BN_sub(p, X, r0))
|
||||
goto err;
|
||||
|
||||
/* step 10 */
|
||||
if (BN_cmp(p, test) >= 0) {
|
||||
/* step 11 */
|
||||
r = BN_check_prime(p, ctx, cb);
|
||||
if (r > 0)
|
||||
goto end; /* found it */
|
||||
if (r != 0)
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* step 13 */
|
||||
counter++;
|
||||
/* "offset = offset + n + 1" */
|
||||
|
||||
/* step 14 */
|
||||
if (counter >= 4096)
|
||||
break;
|
||||
}
|
||||
}
|
||||
end:
|
||||
if (!BN_GENCB_call(cb, 2, 1))
|
||||
goto err;
|
||||
|
||||
/* We now need to generate g */
|
||||
/* Set r0=(p-1)/q */
|
||||
if (!BN_sub(test, p, BN_value_one()))
|
||||
goto err;
|
||||
if (!BN_div(r0, NULL, test, q, ctx))
|
||||
goto err;
|
||||
|
||||
if (!BN_set_word(test, h))
|
||||
goto err;
|
||||
if (!BN_MONT_CTX_set(mont, p, ctx))
|
||||
goto err;
|
||||
|
||||
for (;;) {
|
||||
/* g=test^r0%p */
|
||||
if (!BN_mod_exp_mont(g, test, r0, p, ctx, mont))
|
||||
goto err;
|
||||
if (!BN_is_one(g))
|
||||
break;
|
||||
if (!BN_add(test, test, BN_value_one()))
|
||||
goto err;
|
||||
h++;
|
||||
}
|
||||
|
||||
if (!BN_GENCB_call(cb, 3, 1))
|
||||
goto err;
|
||||
|
||||
ok = 1;
|
||||
err:
|
||||
if (ok) {
|
||||
BN_free(ret->p);
|
||||
BN_free(ret->q);
|
||||
BN_free(ret->g);
|
||||
ret->p = BN_dup(p);
|
||||
ret->q = BN_dup(q);
|
||||
ret->g = BN_dup(g);
|
||||
ret->dirty_cnt++;
|
||||
if (ret->p == NULL || ret->q == NULL || ret->g == NULL) {
|
||||
ok = 0;
|
||||
goto err;
|
||||
}
|
||||
if (counter_ret != NULL)
|
||||
*counter_ret = counter;
|
||||
if (h_ret != NULL)
|
||||
*h_ret = h;
|
||||
if (seed_out)
|
||||
memcpy(seed_out, seed, qsize);
|
||||
}
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(ctx);
|
||||
BN_MONT_CTX_free(mont);
|
||||
return ok;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is a parameter generation algorithm for the DSA2 algorithm as
|
||||
* described in FIPS 186-3.
|
||||
*/
|
||||
|
||||
int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
|
||||
const EVP_MD *evpmd, const unsigned char *seed_in,
|
||||
size_t seed_len, int idx, unsigned char *seed_out,
|
||||
int *counter_ret, unsigned long *h_ret,
|
||||
BN_GENCB *cb)
|
||||
{
|
||||
int ok = -1;
|
||||
unsigned char *seed = NULL, *seed_tmp = NULL;
|
||||
unsigned char md[EVP_MAX_MD_SIZE];
|
||||
int mdsize;
|
||||
BIGNUM *r0, *W, *X, *c, *test;
|
||||
BIGNUM *g = NULL, *q = NULL, *p = NULL;
|
||||
BN_MONT_CTX *mont = NULL;
|
||||
int i, k, n = 0, m = 0, qsize = N >> 3;
|
||||
int counter = 0;
|
||||
int r = 0;
|
||||
BN_CTX *ctx = NULL;
|
||||
EVP_MD_CTX *mctx = EVP_MD_CTX_new();
|
||||
unsigned int h = 2;
|
||||
|
||||
if (mctx == NULL)
|
||||
goto err;
|
||||
|
||||
/* make sure L > N, otherwise we'll get trapped in an infinite loop */
|
||||
if (L <= N) {
|
||||
DSAerr(DSA_F_DSA_BUILTIN_PARAMGEN2, DSA_R_INVALID_PARAMETERS);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (evpmd == NULL) {
|
||||
if (N == 160)
|
||||
evpmd = EVP_sha1();
|
||||
else if (N == 224)
|
||||
evpmd = EVP_sha224();
|
||||
else
|
||||
evpmd = EVP_sha256();
|
||||
}
|
||||
|
||||
mdsize = EVP_MD_size(evpmd);
|
||||
/* If unverifiable g generation only don't need seed */
|
||||
if (!ret->p || !ret->q || idx >= 0) {
|
||||
if (seed_len == 0)
|
||||
seed_len = mdsize;
|
||||
|
||||
seed = OPENSSL_malloc(seed_len);
|
||||
|
||||
if (seed_out)
|
||||
seed_tmp = seed_out;
|
||||
else
|
||||
seed_tmp = OPENSSL_malloc(seed_len);
|
||||
|
||||
if (seed == NULL || seed_tmp == NULL)
|
||||
goto err;
|
||||
|
||||
if (seed_in)
|
||||
memcpy(seed, seed_in, seed_len);
|
||||
|
||||
}
|
||||
|
||||
if ((ctx = BN_CTX_new()) == NULL)
|
||||
goto err;
|
||||
|
||||
if ((mont = BN_MONT_CTX_new()) == NULL)
|
||||
goto err;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
r0 = BN_CTX_get(ctx);
|
||||
g = BN_CTX_get(ctx);
|
||||
W = BN_CTX_get(ctx);
|
||||
X = BN_CTX_get(ctx);
|
||||
c = BN_CTX_get(ctx);
|
||||
test = BN_CTX_get(ctx);
|
||||
if (test == NULL)
|
||||
goto err;
|
||||
|
||||
/* if p, q already supplied generate g only */
|
||||
if (ret->p && ret->q) {
|
||||
p = ret->p;
|
||||
q = ret->q;
|
||||
if (idx >= 0)
|
||||
memcpy(seed_tmp, seed, seed_len);
|
||||
goto g_only;
|
||||
} else {
|
||||
p = BN_CTX_get(ctx);
|
||||
q = BN_CTX_get(ctx);
|
||||
if (q == NULL)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!BN_lshift(test, BN_value_one(), L - 1))
|
||||
goto err;
|
||||
for (;;) {
|
||||
for (;;) { /* find q */
|
||||
unsigned char *pmd;
|
||||
/* step 1 */
|
||||
if (!BN_GENCB_call(cb, 0, m++))
|
||||
goto err;
|
||||
|
||||
if (!seed_in) {
|
||||
if (RAND_bytes(seed, seed_len) <= 0)
|
||||
goto err;
|
||||
}
|
||||
/* step 2 */
|
||||
if (!EVP_Digest(seed, seed_len, md, NULL, evpmd, NULL))
|
||||
goto err;
|
||||
/* Take least significant bits of md */
|
||||
if (mdsize > qsize)
|
||||
pmd = md + mdsize - qsize;
|
||||
else
|
||||
pmd = md;
|
||||
|
||||
if (mdsize < qsize)
|
||||
memset(md + mdsize, 0, qsize - mdsize);
|
||||
|
||||
/* step 3 */
|
||||
pmd[0] |= 0x80;
|
||||
pmd[qsize - 1] |= 0x01;
|
||||
if (!BN_bin2bn(pmd, qsize, q))
|
||||
goto err;
|
||||
|
||||
/* step 4 */
|
||||
r = BN_check_prime(q, ctx, cb);
|
||||
if (r > 0)
|
||||
break;
|
||||
if (r != 0)
|
||||
goto err;
|
||||
/* Provided seed didn't produce a prime: error */
|
||||
if (seed_in) {
|
||||
ok = 0;
|
||||
DSAerr(DSA_F_DSA_BUILTIN_PARAMGEN2, DSA_R_Q_NOT_PRIME);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* do a callback call */
|
||||
/* step 5 */
|
||||
}
|
||||
/* Copy seed to seed_out before we mess with it */
|
||||
if (seed_out)
|
||||
memcpy(seed_out, seed, seed_len);
|
||||
|
||||
if (!BN_GENCB_call(cb, 2, 0))
|
||||
goto err;
|
||||
if (!BN_GENCB_call(cb, 3, 0))
|
||||
goto err;
|
||||
|
||||
/* step 6 */
|
||||
counter = 0;
|
||||
/* "offset = 1" */
|
||||
|
||||
n = (L - 1) / (mdsize << 3);
|
||||
|
||||
for (;;) {
|
||||
if ((counter != 0) && !BN_GENCB_call(cb, 0, counter))
|
||||
goto err;
|
||||
|
||||
/* step 7 */
|
||||
BN_zero(W);
|
||||
/* now 'buf' contains "SEED + offset - 1" */
|
||||
for (k = 0; k <= n; k++) {
|
||||
/*
|
||||
* obtain "SEED + offset + k" by incrementing:
|
||||
*/
|
||||
for (i = seed_len - 1; i >= 0; i--) {
|
||||
seed[i]++;
|
||||
if (seed[i] != 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!EVP_Digest(seed, seed_len, md, NULL, evpmd, NULL))
|
||||
goto err;
|
||||
|
||||
/* step 8 */
|
||||
if (!BN_bin2bn(md, mdsize, r0))
|
||||
goto err;
|
||||
if (!BN_lshift(r0, r0, (mdsize << 3) * k))
|
||||
goto err;
|
||||
if (!BN_add(W, W, r0))
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* more of step 8 */
|
||||
if (!BN_mask_bits(W, L - 1))
|
||||
goto err;
|
||||
if (!BN_copy(X, W))
|
||||
goto err;
|
||||
if (!BN_add(X, X, test))
|
||||
goto err;
|
||||
|
||||
/* step 9 */
|
||||
if (!BN_lshift1(r0, q))
|
||||
goto err;
|
||||
if (!BN_mod(c, X, r0, ctx))
|
||||
goto err;
|
||||
if (!BN_sub(r0, c, BN_value_one()))
|
||||
goto err;
|
||||
if (!BN_sub(p, X, r0))
|
||||
goto err;
|
||||
|
||||
/* step 10 */
|
||||
if (BN_cmp(p, test) >= 0) {
|
||||
/* step 11 */
|
||||
r = BN_check_prime(p, ctx, cb);
|
||||
if (r > 0)
|
||||
goto end; /* found it */
|
||||
if (r != 0)
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* step 13 */
|
||||
counter++;
|
||||
/* "offset = offset + n + 1" */
|
||||
|
||||
/* step 14 */
|
||||
if (counter >= (int)(4 * L))
|
||||
break;
|
||||
}
|
||||
if (seed_in) {
|
||||
ok = 0;
|
||||
DSAerr(DSA_F_DSA_BUILTIN_PARAMGEN2, DSA_R_INVALID_PARAMETERS);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
end:
|
||||
if (!BN_GENCB_call(cb, 2, 1))
|
||||
goto err;
|
||||
|
||||
g_only:
|
||||
|
||||
/* We now need to generate g */
|
||||
/* Set r0=(p-1)/q */
|
||||
if (!BN_sub(test, p, BN_value_one()))
|
||||
goto err;
|
||||
if (!BN_div(r0, NULL, test, q, ctx))
|
||||
goto err;
|
||||
|
||||
if (idx < 0) {
|
||||
if (!BN_set_word(test, h))
|
||||
goto err;
|
||||
} else
|
||||
h = 1;
|
||||
if (!BN_MONT_CTX_set(mont, p, ctx))
|
||||
goto err;
|
||||
|
||||
for (;;) {
|
||||
static const unsigned char ggen[4] = { 0x67, 0x67, 0x65, 0x6e };
|
||||
if (idx >= 0) {
|
||||
md[0] = idx & 0xff;
|
||||
md[1] = (h >> 8) & 0xff;
|
||||
md[2] = h & 0xff;
|
||||
if (!EVP_DigestInit_ex(mctx, evpmd, NULL))
|
||||
goto err;
|
||||
if (!EVP_DigestUpdate(mctx, seed_tmp, seed_len))
|
||||
goto err;
|
||||
if (!EVP_DigestUpdate(mctx, ggen, sizeof(ggen)))
|
||||
goto err;
|
||||
if (!EVP_DigestUpdate(mctx, md, 3))
|
||||
goto err;
|
||||
if (!EVP_DigestFinal_ex(mctx, md, NULL))
|
||||
goto err;
|
||||
if (!BN_bin2bn(md, mdsize, test))
|
||||
goto err;
|
||||
}
|
||||
/* g=test^r0%p */
|
||||
if (!BN_mod_exp_mont(g, test, r0, p, ctx, mont))
|
||||
goto err;
|
||||
if (!BN_is_one(g))
|
||||
break;
|
||||
if (idx < 0 && !BN_add(test, test, BN_value_one()))
|
||||
goto err;
|
||||
h++;
|
||||
if (idx >= 0 && h > 0xffff)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!BN_GENCB_call(cb, 3, 1))
|
||||
goto err;
|
||||
|
||||
ok = 1;
|
||||
err:
|
||||
if (ok == 1) {
|
||||
if (p != ret->p) {
|
||||
BN_free(ret->p);
|
||||
ret->p = BN_dup(p);
|
||||
}
|
||||
if (q != ret->q) {
|
||||
BN_free(ret->q);
|
||||
ret->q = BN_dup(q);
|
||||
}
|
||||
BN_free(ret->g);
|
||||
ret->g = BN_dup(g);
|
||||
if (ret->p == NULL || ret->q == NULL || ret->g == NULL) {
|
||||
ok = -1;
|
||||
goto err;
|
||||
}
|
||||
ret->dirty_cnt++;
|
||||
if (counter_ret != NULL)
|
||||
*counter_ret = counter;
|
||||
if (h_ret != NULL)
|
||||
*h_ret = h;
|
||||
}
|
||||
OPENSSL_free(seed);
|
||||
if (seed_out != seed_tmp)
|
||||
OPENSSL_free(seed_tmp);
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(ctx);
|
||||
BN_MONT_CTX_free(mont);
|
||||
EVP_MD_CTX_free(mctx);
|
||||
return ok;
|
||||
}
|
||||
+24
-12
@@ -11,42 +11,53 @@
|
||||
#include <time.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/bn.h>
|
||||
#include "crypto/dsa.h"
|
||||
#include "dsa_local.h"
|
||||
|
||||
static int dsa_builtin_keygen(DSA *dsa);
|
||||
static int dsa_builtin_keygen(OPENSSL_CTX *libctx, DSA *dsa);
|
||||
|
||||
int DSA_generate_key(DSA *dsa)
|
||||
{
|
||||
if (dsa->meth->dsa_keygen)
|
||||
if (dsa->meth->dsa_keygen != NULL)
|
||||
return dsa->meth->dsa_keygen(dsa);
|
||||
return dsa_builtin_keygen(dsa);
|
||||
return dsa_builtin_keygen(NULL, dsa);
|
||||
}
|
||||
|
||||
static int dsa_builtin_keygen(DSA *dsa)
|
||||
int dsa_generate_key_ctx(OPENSSL_CTX *libctx, DSA *dsa)
|
||||
{
|
||||
#ifndef FIPS_MODE
|
||||
if (dsa->meth->dsa_keygen != NULL)
|
||||
return dsa->meth->dsa_keygen(dsa);
|
||||
#endif
|
||||
return dsa_builtin_keygen(libctx, dsa);
|
||||
}
|
||||
|
||||
static int dsa_builtin_keygen(OPENSSL_CTX *libctx, DSA *dsa)
|
||||
{
|
||||
int ok = 0;
|
||||
BN_CTX *ctx = NULL;
|
||||
BIGNUM *pub_key = NULL, *priv_key = NULL;
|
||||
|
||||
if ((ctx = BN_CTX_new()) == NULL)
|
||||
if ((ctx = BN_CTX_new_ex(libctx)) == NULL)
|
||||
goto err;
|
||||
|
||||
if (dsa->priv_key == NULL) {
|
||||
if ((priv_key = BN_secure_new()) == NULL)
|
||||
goto err;
|
||||
} else
|
||||
} else {
|
||||
priv_key = dsa->priv_key;
|
||||
}
|
||||
|
||||
do
|
||||
if (!BN_priv_rand_range(priv_key, dsa->q))
|
||||
goto err;
|
||||
while (BN_is_zero(priv_key)) ;
|
||||
if (!ffc_generate_private_key(ctx, &dsa->params, BN_num_bits(dsa->params.q),
|
||||
112, priv_key))
|
||||
goto err;
|
||||
|
||||
if (dsa->pub_key == NULL) {
|
||||
if ((pub_key = BN_new()) == NULL)
|
||||
goto err;
|
||||
} else
|
||||
} else {
|
||||
pub_key = dsa->pub_key;
|
||||
}
|
||||
|
||||
{
|
||||
BIGNUM *prk = BN_new();
|
||||
@@ -55,7 +66,8 @@ static int dsa_builtin_keygen(DSA *dsa)
|
||||
goto err;
|
||||
BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME);
|
||||
|
||||
if (!BN_mod_exp(pub_key, dsa->g, prk, dsa->p, ctx)) {
|
||||
/* pub_key = g ^ priv_key mod p */
|
||||
if (!BN_mod_exp(pub_key, dsa->params.g, prk, dsa->params.p, ctx)) {
|
||||
BN_free(prk);
|
||||
goto err;
|
||||
}
|
||||
|
||||
+47
-76
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-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
|
||||
@@ -11,11 +11,11 @@
|
||||
#include "internal/cryptlib.h"
|
||||
#include "internal/refcount.h"
|
||||
#include <openssl/bn.h>
|
||||
#include "dsa_local.h"
|
||||
#include <openssl/asn1.h>
|
||||
#include <openssl/engine.h>
|
||||
#include <openssl/dh.h>
|
||||
#include "dsa_local.h"
|
||||
#include "crypto/dsa.h"
|
||||
#include "crypto/dh.h" /* required by DSA_dup_DH() */
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
|
||||
@@ -29,34 +29,25 @@ void *DSA_get_ex_data(DSA *d, int idx)
|
||||
return CRYPTO_get_ex_data(&d->ex_data, idx);
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_DH
|
||||
# ifndef OPENSSL_NO_DH
|
||||
DH *DSA_dup_DH(const DSA *r)
|
||||
{
|
||||
/*
|
||||
* DSA has p, q, g, optional pub_key, optional priv_key. DH has p,
|
||||
* optional length, g, optional pub_key, optional priv_key, optional q.
|
||||
* DSA has p, q, g, optional pub_key, optional priv_key.
|
||||
* DH has p, optional length, g, optional pub_key,
|
||||
* optional priv_key, optional q.
|
||||
*/
|
||||
|
||||
DH *ret = NULL;
|
||||
BIGNUM *p = NULL, *q = NULL, *g = NULL, *pub_key = NULL, *priv_key = NULL;
|
||||
BIGNUM *pub_key = NULL, *priv_key = NULL;
|
||||
|
||||
if (r == NULL)
|
||||
goto err;
|
||||
ret = DH_new();
|
||||
if (ret == NULL)
|
||||
goto err;
|
||||
if (r->p != NULL || r->g != NULL || r->q != NULL) {
|
||||
if (r->p == NULL || r->g == NULL || r->q == NULL) {
|
||||
/* Shouldn't happen */
|
||||
goto err;
|
||||
}
|
||||
p = BN_dup(r->p);
|
||||
g = BN_dup(r->g);
|
||||
q = BN_dup(r->q);
|
||||
if (p == NULL || g == NULL || q == NULL || !DH_set0_pqg(ret, p, q, g))
|
||||
goto err;
|
||||
p = g = q = NULL;
|
||||
}
|
||||
|
||||
if (!ffc_params_copy(dh_get0_params(ret), &r->params))
|
||||
goto err;
|
||||
|
||||
if (r->pub_key != NULL) {
|
||||
pub_key = BN_dup(r->pub_key);
|
||||
@@ -77,40 +68,12 @@ DH *DSA_dup_DH(const DSA *r)
|
||||
return ret;
|
||||
|
||||
err:
|
||||
BN_free(p);
|
||||
BN_free(g);
|
||||
BN_free(q);
|
||||
BN_free(pub_key);
|
||||
BN_free(priv_key);
|
||||
DH_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
const BIGNUM *DSA_get0_p(const DSA *d)
|
||||
{
|
||||
return d->p;
|
||||
}
|
||||
|
||||
const BIGNUM *DSA_get0_q(const DSA *d)
|
||||
{
|
||||
return d->q;
|
||||
}
|
||||
|
||||
const BIGNUM *DSA_get0_g(const DSA *d)
|
||||
{
|
||||
return d->g;
|
||||
}
|
||||
|
||||
const BIGNUM *DSA_get0_pub_key(const DSA *d)
|
||||
{
|
||||
return d->pub_key;
|
||||
}
|
||||
|
||||
const BIGNUM *DSA_get0_priv_key(const DSA *d)
|
||||
{
|
||||
return d->priv_key;
|
||||
}
|
||||
# endif /* OPENSSL_NO_DH */
|
||||
|
||||
void DSA_clear_flags(DSA *d, int flags)
|
||||
{
|
||||
@@ -250,9 +213,7 @@ void DSA_free(DSA *r)
|
||||
|
||||
CRYPTO_THREAD_lock_free(r->lock);
|
||||
|
||||
BN_clear_free(r->p);
|
||||
BN_clear_free(r->q);
|
||||
BN_clear_free(r->g);
|
||||
ffc_params_cleanup(&r->params);
|
||||
BN_clear_free(r->pub_key);
|
||||
BN_clear_free(r->priv_key);
|
||||
OPENSSL_free(r);
|
||||
@@ -273,12 +234,7 @@ int DSA_up_ref(DSA *r)
|
||||
void DSA_get0_pqg(const DSA *d,
|
||||
const BIGNUM **p, const BIGNUM **q, const BIGNUM **g)
|
||||
{
|
||||
if (p != NULL)
|
||||
*p = d->p;
|
||||
if (q != NULL)
|
||||
*q = d->q;
|
||||
if (g != NULL)
|
||||
*g = d->g;
|
||||
ffc_params_get0_pqg(&d->params, p, q, g);
|
||||
}
|
||||
|
||||
int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g)
|
||||
@@ -286,28 +242,42 @@ int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g)
|
||||
/* If the fields p, q and g in d are NULL, the corresponding input
|
||||
* parameters MUST be non-NULL.
|
||||
*/
|
||||
if ((d->p == NULL && p == NULL)
|
||||
|| (d->q == NULL && q == NULL)
|
||||
|| (d->g == NULL && g == NULL))
|
||||
if ((d->params.p == NULL && p == NULL)
|
||||
|| (d->params.q == NULL && q == NULL)
|
||||
|| (d->params.g == NULL && g == NULL))
|
||||
return 0;
|
||||
|
||||
if (p != NULL) {
|
||||
BN_free(d->p);
|
||||
d->p = p;
|
||||
}
|
||||
if (q != NULL) {
|
||||
BN_free(d->q);
|
||||
d->q = q;
|
||||
}
|
||||
if (g != NULL) {
|
||||
BN_free(d->g);
|
||||
d->g = g;
|
||||
}
|
||||
ffc_params_set0_pqg(&d->params, p, q, g);
|
||||
d->dirty_cnt++;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
const BIGNUM *DSA_get0_p(const DSA *d)
|
||||
{
|
||||
return d->params.p;
|
||||
}
|
||||
|
||||
const BIGNUM *DSA_get0_q(const DSA *d)
|
||||
{
|
||||
return d->params.q;
|
||||
}
|
||||
|
||||
const BIGNUM *DSA_get0_g(const DSA *d)
|
||||
{
|
||||
return d->params.g;
|
||||
}
|
||||
|
||||
const BIGNUM *DSA_get0_pub_key(const DSA *d)
|
||||
{
|
||||
return d->pub_key;
|
||||
}
|
||||
|
||||
const BIGNUM *DSA_get0_priv_key(const DSA *d)
|
||||
{
|
||||
return d->priv_key;
|
||||
}
|
||||
|
||||
void DSA_get0_key(const DSA *d,
|
||||
const BIGNUM **pub_key, const BIGNUM **priv_key)
|
||||
{
|
||||
@@ -341,12 +311,13 @@ int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key)
|
||||
|
||||
int DSA_security_bits(const DSA *d)
|
||||
{
|
||||
if (d->p && d->q)
|
||||
return BN_security_bits(BN_num_bits(d->p), BN_num_bits(d->q));
|
||||
if (d->params.p != NULL && d->params.q != NULL)
|
||||
return BN_security_bits(BN_num_bits(d->params.p),
|
||||
BN_num_bits(d->params.q));
|
||||
return -1;
|
||||
}
|
||||
|
||||
int DSA_bits(const DSA *dsa)
|
||||
{
|
||||
return BN_num_bits(dsa->p);
|
||||
return BN_num_bits(dsa->params.p);
|
||||
}
|
||||
+2
-15
@@ -9,6 +9,7 @@
|
||||
|
||||
#include <openssl/dsa.h>
|
||||
#include "internal/refcount.h"
|
||||
#include "internal/ffc.h"
|
||||
|
||||
struct dsa_st {
|
||||
/*
|
||||
@@ -17,9 +18,7 @@ struct dsa_st {
|
||||
*/
|
||||
int pad;
|
||||
int32_t version;
|
||||
BIGNUM *p;
|
||||
BIGNUM *q; /* == 20 */
|
||||
BIGNUM *g;
|
||||
FFC_PARAMS params;
|
||||
BIGNUM *pub_key; /* y public key */
|
||||
BIGNUM *priv_key; /* x private key */
|
||||
int flags;
|
||||
@@ -69,17 +68,5 @@ struct dsa_method {
|
||||
int (*dsa_keygen) (DSA *dsa);
|
||||
};
|
||||
|
||||
int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
|
||||
const EVP_MD *evpmd, const unsigned char *seed_in,
|
||||
size_t seed_len, unsigned char *seed_out,
|
||||
int *counter_ret, unsigned long *h_ret,
|
||||
BN_GENCB *cb);
|
||||
|
||||
int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
|
||||
const EVP_MD *evpmd, const unsigned char *seed_in,
|
||||
size_t seed_len, int idx, unsigned char *seed_out,
|
||||
int *counter_ret, unsigned long *h_ret,
|
||||
BN_GENCB *cb);
|
||||
|
||||
DSA_SIG *dsa_do_sign_int(OPENSSL_CTX *libctx, const unsigned char *dgst,
|
||||
int dlen, DSA *dsa);
|
||||
+49
-39
@@ -71,7 +71,9 @@ DSA_SIG *dsa_do_sign_int(OPENSSL_CTX *libctx, const unsigned char *dgst,
|
||||
DSA_SIG *ret = NULL;
|
||||
int rv = 0;
|
||||
|
||||
if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL) {
|
||||
if (dsa->params.p == NULL
|
||||
|| dsa->params.q == NULL
|
||||
|| dsa->params.g == NULL) {
|
||||
reason = DSA_R_MISSING_PARAMETERS;
|
||||
goto err;
|
||||
}
|
||||
@@ -102,13 +104,13 @@ DSA_SIG *dsa_do_sign_int(OPENSSL_CTX *libctx, const unsigned char *dgst,
|
||||
if (!dsa_sign_setup(dsa, ctx, &kinv, &ret->r, dgst, dlen))
|
||||
goto err;
|
||||
|
||||
if (dlen > BN_num_bytes(dsa->q))
|
||||
if (dlen > BN_num_bytes(dsa->params.q))
|
||||
/*
|
||||
* if the digest length is greater than the size of q use the
|
||||
* BN_num_bits(dsa->q) leftmost bits of the digest, see fips 186-3,
|
||||
* 4.2
|
||||
*/
|
||||
dlen = BN_num_bytes(dsa->q);
|
||||
dlen = BN_num_bytes(dsa->params.q);
|
||||
if (BN_bin2bn(dgst, dlen, m) == NULL)
|
||||
goto err;
|
||||
|
||||
@@ -124,7 +126,7 @@ DSA_SIG *dsa_do_sign_int(OPENSSL_CTX *libctx, const unsigned char *dgst,
|
||||
|
||||
/* Generate a blinding value */
|
||||
do {
|
||||
if (!BN_priv_rand_ex(blind, BN_num_bits(dsa->q) - 1,
|
||||
if (!BN_priv_rand_ex(blind, BN_num_bits(dsa->params.q) - 1,
|
||||
BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY, ctx))
|
||||
goto err;
|
||||
} while (BN_is_zero(blind));
|
||||
@@ -133,27 +135,27 @@ DSA_SIG *dsa_do_sign_int(OPENSSL_CTX *libctx, const unsigned char *dgst,
|
||||
BN_set_flags(tmp, BN_FLG_CONSTTIME);
|
||||
|
||||
/* tmp := blind * priv_key * r mod q */
|
||||
if (!BN_mod_mul(tmp, blind, dsa->priv_key, dsa->q, ctx))
|
||||
if (!BN_mod_mul(tmp, blind, dsa->priv_key, dsa->params.q, ctx))
|
||||
goto err;
|
||||
if (!BN_mod_mul(tmp, tmp, ret->r, dsa->q, ctx))
|
||||
if (!BN_mod_mul(tmp, tmp, ret->r, dsa->params.q, ctx))
|
||||
goto err;
|
||||
|
||||
/* blindm := blind * m mod q */
|
||||
if (!BN_mod_mul(blindm, blind, m, dsa->q, ctx))
|
||||
if (!BN_mod_mul(blindm, blind, m, dsa->params.q, ctx))
|
||||
goto err;
|
||||
|
||||
/* s : = (blind * priv_key * r) + (blind * m) mod q */
|
||||
if (!BN_mod_add_quick(ret->s, tmp, blindm, dsa->q))
|
||||
if (!BN_mod_add_quick(ret->s, tmp, blindm, dsa->params.q))
|
||||
goto err;
|
||||
|
||||
/* s := s * k^-1 mod q */
|
||||
if (!BN_mod_mul(ret->s, ret->s, kinv, dsa->q, ctx))
|
||||
if (!BN_mod_mul(ret->s, ret->s, kinv, dsa->params.q, ctx))
|
||||
goto err;
|
||||
|
||||
/* s:= s * blind^-1 mod q */
|
||||
if (BN_mod_inverse(blind, blind, dsa->q, ctx) == NULL)
|
||||
if (BN_mod_inverse(blind, blind, dsa->params.q, ctx) == NULL)
|
||||
goto err;
|
||||
if (!BN_mod_mul(ret->s, ret->s, blind, dsa->q, ctx))
|
||||
if (!BN_mod_mul(ret->s, ret->s, blind, dsa->params.q, ctx))
|
||||
goto err;
|
||||
|
||||
/*
|
||||
@@ -197,13 +199,15 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in,
|
||||
int ret = 0;
|
||||
int q_bits, q_words;
|
||||
|
||||
if (!dsa->p || !dsa->q || !dsa->g) {
|
||||
if (!dsa->params.p || !dsa->params.q || !dsa->params.g) {
|
||||
DSAerr(DSA_F_DSA_SIGN_SETUP, DSA_R_MISSING_PARAMETERS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Reject obviously invalid parameters */
|
||||
if (BN_is_zero(dsa->p) || BN_is_zero(dsa->q) || BN_is_zero(dsa->g)) {
|
||||
if (BN_is_zero(dsa->params.p)
|
||||
|| BN_is_zero(dsa->params.q)
|
||||
|| BN_is_zero(dsa->params.g)) {
|
||||
DSAerr(DSA_F_DSA_SIGN_SETUP, DSA_R_INVALID_PARAMETERS);
|
||||
return 0;
|
||||
}
|
||||
@@ -225,8 +229,8 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in,
|
||||
ctx = ctx_in;
|
||||
|
||||
/* Preallocate space */
|
||||
q_bits = BN_num_bits(dsa->q);
|
||||
q_words = bn_get_top(dsa->q);
|
||||
q_bits = BN_num_bits(dsa->params.q);
|
||||
q_words = bn_get_top(dsa->params.q);
|
||||
if (!bn_wexpand(k, q_words + 2)
|
||||
|| !bn_wexpand(l, q_words + 2))
|
||||
goto err;
|
||||
@@ -238,10 +242,10 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in,
|
||||
* We calculate k from SHA512(private_key + H(message) + random).
|
||||
* This protects the private key from a weak PRNG.
|
||||
*/
|
||||
if (!BN_generate_dsa_nonce(k, dsa->q, dsa->priv_key, dgst,
|
||||
if (!BN_generate_dsa_nonce(k, dsa->params.q, dsa->priv_key, dgst,
|
||||
dlen, ctx))
|
||||
goto err;
|
||||
} else if (!BN_priv_rand_range_ex(k, dsa->q, ctx))
|
||||
} else if (!BN_priv_rand_range_ex(k, dsa->params.q, ctx))
|
||||
goto err;
|
||||
} while (BN_is_zero(k));
|
||||
|
||||
@@ -250,7 +254,7 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in,
|
||||
|
||||
if (dsa->flags & DSA_FLAG_CACHE_MONT_P) {
|
||||
if (!BN_MONT_CTX_set_locked(&dsa->method_mont_p,
|
||||
dsa->lock, dsa->p, ctx))
|
||||
dsa->lock, dsa->params.p, ctx))
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -269,26 +273,27 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in,
|
||||
* https://github.com/openssl/openssl/pull/7486#discussion_r228323705
|
||||
* The fix is to rework BN so these gymnastics aren't required.
|
||||
*/
|
||||
if (!BN_add(l, k, dsa->q)
|
||||
|| !BN_add(k, l, dsa->q))
|
||||
if (!BN_add(l, k, dsa->params.q)
|
||||
|| !BN_add(k, l, dsa->params.q))
|
||||
goto err;
|
||||
|
||||
BN_consttime_swap(BN_is_bit_set(l, q_bits), k, l, q_words + 2);
|
||||
|
||||
if ((dsa)->meth->bn_mod_exp != NULL) {
|
||||
if (!dsa->meth->bn_mod_exp(dsa, r, dsa->g, k, dsa->p, ctx,
|
||||
dsa->method_mont_p))
|
||||
if (!dsa->meth->bn_mod_exp(dsa, r, dsa->params.g, k, dsa->params.p,
|
||||
ctx, dsa->method_mont_p))
|
||||
goto err;
|
||||
} else {
|
||||
if (!BN_mod_exp_mont(r, dsa->g, k, dsa->p, ctx, dsa->method_mont_p))
|
||||
if (!BN_mod_exp_mont(r, dsa->params.g, k, dsa->params.p, ctx,
|
||||
dsa->method_mont_p))
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!BN_mod(r, r, dsa->q, ctx))
|
||||
if (!BN_mod(r, r, dsa->params.q, ctx))
|
||||
goto err;
|
||||
|
||||
/* Compute part of 's = inv(k) (m + xr) mod q' */
|
||||
if ((kinv = dsa_mod_inverse_fermat(k, dsa->q, ctx)) == NULL)
|
||||
if ((kinv = dsa_mod_inverse_fermat(k, dsa->params.q, ctx)) == NULL)
|
||||
goto err;
|
||||
|
||||
BN_clear_free(*kinvp);
|
||||
@@ -313,19 +318,22 @@ static int dsa_do_verify(const unsigned char *dgst, int dgst_len,
|
||||
BN_MONT_CTX *mont = NULL;
|
||||
const BIGNUM *r, *s;
|
||||
int ret = -1, i;
|
||||
if (!dsa->p || !dsa->q || !dsa->g) {
|
||||
|
||||
if (dsa->params.p == NULL
|
||||
|| dsa->params.q == NULL
|
||||
|| dsa->params.g == NULL) {
|
||||
DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_MISSING_PARAMETERS);
|
||||
return -1;
|
||||
}
|
||||
|
||||
i = BN_num_bits(dsa->q);
|
||||
i = BN_num_bits(dsa->params.q);
|
||||
/* fips 186-3 allows only different sizes for q */
|
||||
if (i != 160 && i != 224 && i != 256) {
|
||||
DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_BAD_Q_VALUE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (BN_num_bits(dsa->p) > OPENSSL_DSA_MAX_MODULUS_BITS) {
|
||||
if (BN_num_bits(dsa->params.p) > OPENSSL_DSA_MAX_MODULUS_BITS) {
|
||||
DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_MODULUS_TOO_LARGE);
|
||||
return -1;
|
||||
}
|
||||
@@ -339,12 +347,12 @@ static int dsa_do_verify(const unsigned char *dgst, int dgst_len,
|
||||
DSA_SIG_get0(sig, &r, &s);
|
||||
|
||||
if (BN_is_zero(r) || BN_is_negative(r) ||
|
||||
BN_ucmp(r, dsa->q) >= 0) {
|
||||
BN_ucmp(r, dsa->params.q) >= 0) {
|
||||
ret = 0;
|
||||
goto err;
|
||||
}
|
||||
if (BN_is_zero(s) || BN_is_negative(s) ||
|
||||
BN_ucmp(s, dsa->q) >= 0) {
|
||||
BN_ucmp(s, dsa->params.q) >= 0) {
|
||||
ret = 0;
|
||||
goto err;
|
||||
}
|
||||
@@ -352,7 +360,7 @@ static int dsa_do_verify(const unsigned char *dgst, int dgst_len,
|
||||
/*
|
||||
* Calculate W = inv(S) mod Q save W in u2
|
||||
*/
|
||||
if ((BN_mod_inverse(u2, s, dsa->q, ctx)) == NULL)
|
||||
if ((BN_mod_inverse(u2, s, dsa->params.q, ctx)) == NULL)
|
||||
goto err;
|
||||
|
||||
/* save M in u1 */
|
||||
@@ -367,32 +375,32 @@ static int dsa_do_verify(const unsigned char *dgst, int dgst_len,
|
||||
goto err;
|
||||
|
||||
/* u1 = M * w mod q */
|
||||
if (!BN_mod_mul(u1, u1, u2, dsa->q, ctx))
|
||||
if (!BN_mod_mul(u1, u1, u2, dsa->params.q, ctx))
|
||||
goto err;
|
||||
|
||||
/* u2 = r * w mod q */
|
||||
if (!BN_mod_mul(u2, r, u2, dsa->q, ctx))
|
||||
if (!BN_mod_mul(u2, r, u2, dsa->params.q, ctx))
|
||||
goto err;
|
||||
|
||||
if (dsa->flags & DSA_FLAG_CACHE_MONT_P) {
|
||||
mont = BN_MONT_CTX_set_locked(&dsa->method_mont_p,
|
||||
dsa->lock, dsa->p, ctx);
|
||||
dsa->lock, dsa->params.p, ctx);
|
||||
if (!mont)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (dsa->meth->dsa_mod_exp != NULL) {
|
||||
if (!dsa->meth->dsa_mod_exp(dsa, t1, dsa->g, u1, dsa->pub_key, u2,
|
||||
dsa->p, ctx, mont))
|
||||
if (!dsa->meth->dsa_mod_exp(dsa, t1, dsa->params.g, u1, dsa->pub_key, u2,
|
||||
dsa->params.p, ctx, mont))
|
||||
goto err;
|
||||
} else {
|
||||
if (!BN_mod_exp2_mont(t1, dsa->g, u1, dsa->pub_key, u2, dsa->p, ctx,
|
||||
mont))
|
||||
if (!BN_mod_exp2_mont(t1, dsa->params.g, u1, dsa->pub_key, u2,
|
||||
dsa->params.p, ctx, mont))
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* let u1 = u1 mod q */
|
||||
if (!BN_mod(u1, t1, dsa->q, ctx))
|
||||
if (!BN_mod(u1, t1, dsa->params.q, ctx))
|
||||
goto err;
|
||||
|
||||
/*
|
||||
@@ -413,6 +421,8 @@ static int dsa_do_verify(const unsigned char *dgst, int dgst_len,
|
||||
static int dsa_init(DSA *dsa)
|
||||
{
|
||||
dsa->flags |= DSA_FLAG_CACHE_MONT_P;
|
||||
ffc_params_init(&dsa->params);
|
||||
dsa->dirty_cnt++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -197,7 +197,7 @@ static int pkey_dsa_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
|
||||
DSA *dsa = NULL;
|
||||
DSA_PKEY_CTX *dctx = ctx->data;
|
||||
BN_GENCB *pcb;
|
||||
int ret;
|
||||
int ret, res;
|
||||
|
||||
if (ctx->pkey_gencb) {
|
||||
pcb = BN_GENCB_new();
|
||||
@@ -211,8 +211,9 @@ static int pkey_dsa_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
|
||||
BN_GENCB_free(pcb);
|
||||
return 0;
|
||||
}
|
||||
ret = dsa_builtin_paramgen(dsa, dctx->nbits, dctx->qbits, dctx->pmd,
|
||||
NULL, 0, NULL, NULL, NULL, pcb);
|
||||
ret = ffc_params_FIPS186_4_generate(NULL, &dsa->params, FFC_PARAM_TYPE_DSA,
|
||||
dctx->nbits, dctx->qbits, dctx->pmd,
|
||||
&res, pcb);
|
||||
BN_GENCB_free(pcb);
|
||||
if (ret)
|
||||
EVP_PKEY_assign_DSA(pkey, dsa);
|
||||
|
||||
@@ -115,7 +115,7 @@ int DSA_size(const DSA *dsa)
|
||||
int ret;
|
||||
DSA_SIG sig;
|
||||
|
||||
sig.r = sig.s = dsa->q;
|
||||
sig.r = sig.s = dsa->params.q;
|
||||
ret = i2d_DSA_SIG(&sig, NULL);
|
||||
|
||||
if (ret < 0)
|
||||
|
||||
Reference in New Issue
Block a user