diff options
-rw-r--r-- | crypto/dh/dh_asn1.c | 1 | ||||
-rw-r--r-- | crypto/dh/dh_gen.c | 70 | ||||
-rw-r--r-- | crypto/dh/dh_key.c | 91 | ||||
-rw-r--r-- | crypto/dh/dh_pmeth.c | 84 | ||||
-rw-r--r-- | crypto/dsa/dsa_gen.c | 646 | ||||
-rw-r--r-- | crypto/dsa/dsa_key.c | 34 | ||||
-rw-r--r-- | crypto/dsa/dsa_local.h | 12 | ||||
-rw-r--r-- | crypto/dsa/dsa_ossl.c | 2 | ||||
-rw-r--r-- | crypto/dsa/dsa_pmeth.c | 7 | ||||
-rw-r--r-- | crypto/ffc/build.info | 2 | ||||
-rw-r--r-- | crypto/ffc/ffc_key_generate.c | 61 | ||||
-rw-r--r-- | crypto/ffc/ffc_params.c | 1 | ||||
-rw-r--r-- | crypto/ffc/ffc_params_generate.c | 1001 | ||||
-rw-r--r-- | doc/man3/EVP_PKEY_CTX_ctrl.pod | 26 | ||||
-rw-r--r-- | include/crypto/dh.h | 3 | ||||
-rw-r--r-- | include/crypto/dsa.h | 14 | ||||
-rw-r--r-- | include/internal/ffc.h | 69 | ||||
-rw-r--r-- | include/openssl/dh.h | 5 |
18 files changed, 1433 insertions, 696 deletions
diff --git a/crypto/dh/dh_asn1.c b/crypto/dh/dh_asn1.c index ec589757d0..829cc87464 100644 --- a/crypto/dh/dh_asn1.c +++ b/crypto/dh/dh_asn1.c @@ -85,6 +85,7 @@ DH *d2i_DHxparams(DH **a, const unsigned char **pp, long length) FFC_PARAMS *params; int_dhx942_dh *dhx = NULL; DH *dh = NULL; + dh = DH_new(); if (dh == NULL) return NULL; diff --git a/crypto/dh/dh_gen.c b/crypto/dh/dh_gen.c index 75548592b8..3d3bcb22b2 100644 --- a/crypto/dh/dh_gen.c +++ b/crypto/dh/dh_gen.c @@ -15,19 +15,88 @@ #include <stdio.h> #include "internal/cryptlib.h" #include <openssl/bn.h> +#include "crypto/dh.h" #include "dh_local.h" +#ifndef FIPS_MODE static int dh_builtin_genparams(DH *ret, int prime_len, int generator, BN_GENCB *cb); +#endif /* FIPS_MODE */ + +/* + * TODO(3.0): keygen should be able to use this method to do a FIPS186-4 style + * paramgen. + */ +int dh_generate_ffc_parameters(OPENSSL_CTX *libctx, DH *dh, int bits, + int qbits, int gindex, BN_GENCB *cb) +{ + int ret, res; + + if (qbits <= 0) { + const EVP_MD *evpmd = bits >= 2048 ? EVP_sha256() : EVP_sha1(); + + qbits = EVP_MD_size(evpmd) * 8; + } + dh->params.gindex = gindex; + ret = ffc_params_FIPS186_4_generate(libctx, &dh->params, FFC_PARAM_TYPE_DH, + bits, qbits, NULL, &res, cb); + if (ret > 0) + dh->dirty_cnt++; + return ret; +} int DH_generate_parameters_ex(DH *ret, int prime_len, int generator, BN_GENCB *cb) { +#ifdef FIPS_MODE + /* + * Just choose an approved safe prime group. + * The alternative to this is to generate FIPS186-4 domain parameters i.e. + * return dh_generate_ffc_parameters(ret, prime_len, -1, -1, cb); + * As the FIPS186-4 generated params are for backwards compatability, + * the safe prime group should be used as the default. + */ + DH *dh = NULL; + int ok = 0, nid; + + if (generator != 2) + return 0; + + switch (prime_len) { + case 2048: + nid = NID_ffdhe2048; + break; + case 3072: + nid = NID_ffdhe3072; + break; + case 4096: + nid = NID_ffdhe4096; + break; + case 6144: + nid = NID_ffdhe6144; + break; + case 8192: + nid = NID_ffdhe8192; + break; + /* unsupported prime_len */ + default: + return 0; + } + dh = DH_new_by_nid(nid); + if (dh != NULL && ffc_params_copy(&ret->params, &dh->params)) { + ok = 1; + ret->dirty_cnt++; + } + DH_free(dh); + return ok; +#else if (ret->meth->generate_params) return ret->meth->generate_params(ret, prime_len, generator, cb); return dh_builtin_genparams(ret, prime_len, generator, cb); +#endif /* FIPS_MODE */ } +#ifndef FIPS_MODE /*- * We generate DH parameters as follows * find a prime p which is prime_len bits long, @@ -133,3 +202,4 @@ static int dh_builtin_genparams(DH *ret, int prime_len, int generator, BN_CTX_free(ctx); return ok; } +#endif /* FIPS_MODE */ diff --git a/crypto/dh/dh_key.c b/crypto/dh/dh_key.c index 4c5d78a19f..0bee75c058 100644 --- a/crypto/dh/dh_key.c +++ b/crypto/dh/dh_key.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2019 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 @@ -13,10 +13,7 @@ #include "crypto/bn.h" #include "crypto/dh.h" -#ifndef FIPS_MODE static int generate_key(DH *dh); -#endif /* FIPS_MODE */ - static int dh_bn_mod_exp(const DH *dh, BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); @@ -123,11 +120,7 @@ int DH_compute_key_padded(unsigned char *key, const BIGNUM *pub_key, DH *dh) static DH_METHOD dh_ossl = { "OpenSSL DH Method", -#ifndef FIPS_MODE generate_key, -#else - NULL, /* TODO(3.0) : solve this in a keygen related PR */ -#endif compute_key, dh_bn_mod_exp, dh_init, @@ -160,6 +153,7 @@ static int dh_init(DH *dh) { dh->flags |= DH_FLAG_CACHE_MONT_P; ffc_params_init(&dh->params); + dh->dirty_cnt++; return 1; } @@ -170,7 +164,6 @@ static int dh_finish(DH *dh) } #ifndef FIPS_MODE - void DH_set_default_method(const DH_METHOD *meth) { default_DH_method = meth; @@ -180,27 +173,30 @@ int DH_generate_key(DH *dh) { return dh->meth->generate_key(dh); } +#endif /* FIPS_MODE */ -static int generate_key(DH *dh) +static int dh_generate_key(OPENSSL_CTX *libctx, DH *dh) { int ok = 0; int generate_new_key = 0; +#ifndef FIPS_MODE unsigned l; +#endif BN_CTX *ctx = NULL; BN_MONT_CTX *mont = NULL; BIGNUM *pub_key = NULL, *priv_key = NULL; if (BN_num_bits(dh->params.p) > OPENSSL_DH_MAX_MODULUS_BITS) { - DHerr(DH_F_GENERATE_KEY, DH_R_MODULUS_TOO_LARGE); + DHerr(0, DH_R_MODULUS_TOO_LARGE); return 0; } if (BN_num_bits(dh->params.p) < DH_MIN_MODULUS_BITS) { - DHerr(DH_F_GENERATE_KEY, DH_R_MODULUS_TOO_SMALL); + DHerr(0, DH_R_MODULUS_TOO_SMALL); return 0; } - ctx = BN_CTX_new(); + ctx = BN_CTX_new_ex(libctx); if (ctx == NULL) goto err; @@ -227,25 +223,52 @@ static int generate_key(DH *dh) } if (generate_new_key) { - if (dh->params.q != NULL) { - do { - if (!BN_priv_rand_range(priv_key, dh->params.q)) - goto err; - } - while (BN_is_zero(priv_key) || BN_is_one(priv_key)); - } else { - /* secret exponent length */ - l = dh->length ? dh->length : BN_num_bits(dh->params.p) - 1; - if (!BN_priv_rand(priv_key, l, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY)) - goto err; + /* Is it an approved safe prime ?*/ + if (DH_get_nid(dh) != NID_undef) { /* - * We handle just one known case where g is a quadratic non-residue: - * for g = 2: p % 8 == 3 + * The safe prime group code sets N = 2*s + * (where s = max security strength supported). + * N = dh->length (N = maximum bit length of private key) */ - if (BN_is_word(dh->params.g, DH_GENERATOR_2) - && !BN_is_bit_set(dh->params.p, 2)) { - /* clear bit 0, since it won't be a secret anyway */ - if (!BN_clear_bit(priv_key, 0)) + if (dh->length == 0 + || dh->params.q == NULL + || dh->length > BN_num_bits(dh->params.q)) + goto err; + if (!ffc_generate_private_key(ctx, &dh->params, dh->length, + dh->length / 2, priv_key)) + goto err; + } else { +#ifdef FIPS_MODE + if (dh->params.q == NULL) + goto err; +#else + if (dh->params.q == NULL) { + /* secret exponent length */ + l = dh->length ? dh->length : BN_num_bits(dh->params.p) - 1; + if (!BN_priv_rand_ex(priv_key, l, BN_RAND_TOP_ONE, + BN_RAND_BOTTOM_ANY, ctx)) + goto err; + /* + * We handle just one known case where g is a quadratic non-residue: + * for g = 2: p % 8 == 3 + */ + if (BN_is_word(dh->params.g, DH_GENERATOR_2) + && !BN_is_bit_set(dh->params.p, 2)) { + /* clear bit 0, since it won't be a secret anyway */ + if (!BN_clear_bit(priv_key, 0)) + goto err; + } + } else +#endif + { + /* + * For FFC FIPS 186-4 keygen + * security strength s = 112, + * Max Private key size N = len(q) + */ + if (!ffc_generate_private_key(ctx, &dh->params, + BN_num_bits(dh->params.q), 112, + priv_key)) goto err; } } @@ -258,6 +281,7 @@ static int generate_key(DH *dh) goto err; BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME); + /* pub_key = g^priv_key mod p */ if (!dh->meth->bn_mod_exp(dh, pub_key, dh->params.g, prk, dh->params.p, ctx, mont)) { BN_clear_free(prk); @@ -273,7 +297,7 @@ static int generate_key(DH *dh) ok = 1; err: if (ok != 1) - DHerr(DH_F_GENERATE_KEY, ERR_R_BN_LIB); + DHerr(0, ERR_R_BN_LIB); if (pub_key != dh->pub_key) BN_free(pub_key); @@ -283,6 +307,10 @@ static int generate_key(DH *dh) return ok; } +static int generate_key(DH *dh) +{ + return dh_generate_key(NULL, dh); +} int dh_buf2key(DH *dh, const unsigned char *buf, size_t len) { @@ -346,4 +374,3 @@ size_t dh_key2buf(const DH *dh, unsigned char **pbuf_out) *pbuf_out = pbuf; return p_size; } -#endif /* FIPS_MODE */ diff --git a/crypto/dh/dh_pmeth.c b/crypto/dh/dh_pmeth.c index 4afedb95f6..38935fd9e2 100644 --- a/crypto/dh/dh_pmeth.c +++ b/crypto/dh/dh_pmeth.c @@ -24,7 +24,7 @@ typedef struct { /* Parameter gen parameters */ int prime_len; int generator; - int use_dsa; + int paramgen_type; int subprime_len; int pad; /* message digest used for parameter generation */ @@ -69,6 +69,7 @@ static int pkey_dh_init(EVP_PKEY_CTX *ctx) static void pkey_dh_cleanup(EVP_PKEY_CTX *ctx) { DH_PKEY_CTX *dctx = ctx->data; + if (dctx != NULL) { OPENSSL_free(dctx->kdf_ukm); ASN1_OBJECT_free(dctx->kdf_oid); @@ -88,7 +89,7 @@ static int pkey_dh_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src) dctx->prime_len = sctx->prime_len; dctx->subprime_len = sctx->subprime_len; dctx->generator = sctx->generator; - dctx->use_dsa = sctx->use_dsa; + dctx->paramgen_type = sctx->paramgen_type; dctx->pad = sctx->pad; dctx->md = sctx->md; dctx->rfc5114_param = sctx->rfc5114_param; @@ -120,7 +121,7 @@ static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) return 1; case EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN: - if (dctx->use_dsa == 0) + if (dctx->paramgen_type == DH_PARAMGEN_TYPE_GENERATOR) return -2; dctx->subprime_len = p1; return 1; @@ -130,20 +131,20 @@ static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) return 1; case EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR: - if (dctx->use_dsa) + if (dctx->paramgen_type != DH_PARAMGEN_TYPE_GENERATOR) return -2; dctx->generator = p1; return 1; case EVP_PKEY_CTRL_DH_PARAMGEN_TYPE: #ifdef OPENSSL_NO_DSA - if (p1 != 0) + if (p1 != DH_PARAMGEN_TYPE_GENERATOR) return -2; #else if (p1 < 0 || p1 > 2) return -2; #endif - dctx->use_dsa = p1; + dctx->paramgen_type = p1; return 1; case EVP_PKEY_CTRL_DH_RFC5114: @@ -271,33 +272,22 @@ static int pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx, return -2; } -#ifndef OPENSSL_NO_DSA - -extern 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); - -extern 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); - -static DSA *dsa_dh_generate(DH_PKEY_CTX *dctx, BN_GENCB *pcb) +static DH *ffc_params_generate(OPENSSL_CTX *libctx, DH_PKEY_CTX *dctx, + BN_GENCB *pcb) { - DSA *ret; + DH *ret; int rv = 0; + int res; int prime_len = dctx->prime_len; int subprime_len = dctx->subprime_len; const EVP_MD *md = dctx->md; - if (dctx->use_dsa > 2) + + if (dctx->paramgen_type > DH_PARAMGEN_TYPE_FIPS_186_4) return NULL; - ret = DSA_new(); + ret = DH_new(); if (ret == NULL) return NULL; + if (subprime_len == -1) { if (prime_len >= 2048) subprime_len = 256; @@ -310,22 +300,29 @@ static DSA *dsa_dh_generate(DH_PKEY_CTX *dctx, BN_GENCB *pcb) else md = EVP_sha1(); } - if (dctx->use_dsa == 1) - rv = dsa_builtin_paramgen(ret, prime_len, subprime_len, md, - NULL, 0, NULL, NULL, NULL, pcb); - else if (dctx->use_dsa == 2) - rv = dsa_builtin_paramgen2(ret, prime_len, subprime_len, md, - NULL, 0, -1, NULL, NULL, NULL, pcb); +# ifndef FIPS_MODE + if (dctx->paramgen_type == DH_PARAMGEN_TYPE_FIPS_186_2) + rv = ffc_params_FIPS186_2_generate(libctx, &ret->params, + FFC_PARAM_TYPE_DH, + prime_len, subprime_len, md, &res, + pcb); + else +# endif + /* For FIPS we always use the DH_PARAMGEN_TYPE_FIPS_186_4 generator */ + if (dctx->paramgen_type >= DH_PARAMGEN_TYPE_FIPS_186_2) + rv = ffc_params_FIPS186_4_generate(libctx, &ret->params, + FFC_PARAM_TYPE_DH, + prime_len, subprime_len, md, &res, + pcb); if (rv <= 0) { - DSA_free(ret); + DH_free(ret); return NULL; } return ret; } -#endif - -static int pkey_dh_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) +static int pkey_dh_paramgen(EVP_PKEY_CTX *ctx, + EVP_PKEY *pkey) { DH *dh = NULL; DH_PKEY_CTX *dctx = ctx->data; @@ -372,22 +369,17 @@ static int pkey_dh_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) return 0; evp_pkey_set_cb_translate(pcb, ctx); } -#ifndef OPENSSL_NO_DSA - if (dctx->use_dsa) { - DSA *dsa_dh; - - dsa_dh = dsa_dh_generate(dctx, pcb); +# ifdef FIPS_MODE + dctx->paramgen_type = DH_PARAMGEN_TYPE_FIPS_186_4; +# endif /* FIPS_MODE */ + if (dctx->paramgen_type >= DH_PARAMGEN_TYPE_FIPS_186_2) { + dh = ffc_params_generate(NULL, dctx, pcb); BN_GENCB_free(pcb); - if (dsa_dh == NULL) - return 0; - dh = DSA_dup_DH(dsa_dh); - DSA_free(dsa_dh); - if (!dh) + if (dh == NULL) return 0; EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh); return 1; } -#endif dh = DH_new(); if (dh == NULL) { BN_GENCB_free(pcb); diff --git a/crypto/dsa/dsa_gen.c b/crypto/dsa/dsa_gen.c index 02c2bd8083..aa6b84c091 100644 --- a/crypto/dsa/dsa_gen.c +++ b/crypto/dsa/dsa_gen.c @@ -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,598 +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, - const unsigned char *seed_in, int seed_len, - int *counter_ret, unsigned long *h_ret, - BN_GENCB *cb) +int dsa_generate_ffc_parameters(OPENSSL_CTX *libctx, DSA *dsa, int type, + int pbits, int qbits, int gindex, + BN_GENCB *cb) { - if (ret->meth->dsa_paramgen) - return ret->meth->dsa_paramgen(ret, 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; + int ret = 0, res; - return dsa_builtin_paramgen(ret, bits, qbits, evpmd, - seed_in, seed_len, NULL, counter_ret, - h_ret, cb); + 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_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_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) { - 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 */ +#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; - 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); +#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 (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->params.p); - BN_free(ret->params.q); - BN_free(ret->params.g); - ret->params.p = BN_dup(p); - ret->params.q = BN_dup(q); - ret->params.g = BN_dup(g); - ret->dirty_cnt++; - if (ret->params.p == NULL - || ret->params.q == NULL - || ret->params.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; + if (counter_ret != NULL) + *counter_ret = dsa->params.pcounter; + if (h_ret != NULL) + *h_ret = dsa->params.h; + return 1; } -/* - * 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 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) { - 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->params.p || !ret->params.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->params.p && ret->params.q) { - p = ret->params.p; - q = ret->params.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; |