summaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorShane Lontis <shane.lontis@oracle.com>2020-01-24 14:09:33 +1000
committerShane Lontis <shane.lontis@oracle.com>2020-01-24 14:09:33 +1000
commitdc8de3e6f1eed18617dc42d41dec6c6566c2ac0c (patch)
tree5cf78a6ef780836f16831f2776c0dc155047d742 /crypto
parent21d08b9ee9c0f7fabcad27b5d0b0c8c16f7dd1e9 (diff)
Modify DSA and DH keys to use a shared FFC_PARAMS struct
This is required in order to share code for FIPS related parameter generation and validation routinues. Note the 'counter' field is now stored as a integer (as that is the form required for generation/validation functions). Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/10860)
Diffstat (limited to 'crypto')
-rw-r--r--crypto/build.info3
-rw-r--r--crypto/dh/dh_ameth.c93
-rw-r--r--crypto/dh/dh_asn1.c67
-rw-r--r--crypto/dh/dh_check.c41
-rw-r--r--crypto/dh/dh_gen.c8
-rw-r--r--crypto/dh/dh_key.c30
-rw-r--r--crypto/dh/dh_lib.c56
-rw-r--r--crypto/dh/dh_local.h14
-rw-r--r--crypto/dh/dh_rfc5114.c8
-rw-r--r--crypto/dh/dh_rfc7919.c22
-rw-r--r--crypto/dsa/dsa_ameth.c62
-rw-r--r--crypto/dsa/dsa_asn1.c18
-rw-r--r--crypto/dsa/dsa_gen.c44
-rw-r--r--crypto/dsa/dsa_key.c4
-rw-r--r--crypto/dsa/dsa_lib.c79
-rw-r--r--crypto/dsa/dsa_local.h5
-rw-r--r--crypto/dsa/dsa_ossl.c86
-rw-r--r--crypto/dsa/dsa_sign.c2
-rw-r--r--crypto/ffc/build.info6
-rw-r--r--crypto/ffc/ffc_params.c191
20 files changed, 464 insertions, 375 deletions
diff --git a/crypto/build.info b/crypto/build.info
index daa26b8ed4..6906c54db2 100644
--- a/crypto/build.info
+++ b/crypto/build.info
@@ -5,7 +5,8 @@ SUBDIRS=objects buffer bio stack lhash rand evp asn1 pem x509 conf \
md2 md4 md5 sha mdc2 hmac ripemd whrlpool poly1305 \
siphash sm3 des aes rc2 rc4 rc5 idea aria bf cast camellia \
seed sm4 chacha modes bn ec rsa dsa dh sm2 dso engine \
- err comp ocsp cms ts srp cmac ct async ess crmf cmp serializer
+ err comp ocsp cms ts srp cmac ct async ess crmf cmp serializer \
+ ffc
LIBS=../libcrypto
diff --git a/crypto/dh/dh_ameth.c b/crypto/dh/dh_ameth.c
index 174bd04cef..fd241831dc 100644
--- a/crypto/dh/dh_ameth.c
+++ b/crypto/dh/dh_ameth.c
@@ -282,7 +282,7 @@ static int do_dh_print(BIO *bp, const DH *x, int indent, int ptype)
else
pub_key = NULL;
- if (x->p == NULL || (ptype == 2 && priv_key == NULL)
+ if (x->params.p == NULL || (ptype == 2 && priv_key == NULL)
|| (ptype > 0 && pub_key == NULL)) {
reason = ERR_R_PASSED_NULL_PARAMETER;
goto err;
@@ -296,7 +296,7 @@ static int do_dh_print(BIO *bp, const DH *x, int indent, int ptype)
ktype = "DH Parameters";
if (!BIO_indent(bp, indent, 128)
- || BIO_printf(bp, "%s: (%d bit)\n", ktype, BN_num_bits(x->p)) <= 0)
+ || BIO_printf(bp, "%s: (%d bit)\n", ktype, DH_bits(x)) <= 0)
goto err;
indent += 4;
@@ -305,35 +305,9 @@ static int do_dh_print(BIO *bp, const DH *x, int indent, int ptype)
if (!ASN1_bn_print(bp, "public-key:", pub_key, NULL, indent))
goto err;
- if (!ASN1_bn_print(bp, "prime:", x->p, NULL, indent))
+ if (!ffc_params_print(bp, &x->params, indent))
goto err;
- if (!ASN1_bn_print(bp, "generator:", x->g, NULL, indent))
- goto err;
- if (x->q && !ASN1_bn_print(bp, "subgroup order:", x->q, NULL, indent))
- goto err;
- if (x->j && !ASN1_bn_print(bp, "subgroup factor:", x->j, NULL, indent))
- goto err;
- if (x->seed) {
- int i;
- if (!BIO_indent(bp, indent, 128)
- || BIO_puts(bp, "seed:") <= 0)
- goto err;
- for (i = 0; i < x->seedlen; i++) {
- if ((i % 15) == 0) {
- if (BIO_puts(bp, "\n") <= 0
- || !BIO_indent(bp, indent + 4, 128))
- goto err;
- }
- if (BIO_printf(bp, "%02x%s", x->seed[i],
- ((i + 1) == x->seedlen) ? "" : ":") <= 0)
- goto err;
- }
- if (BIO_write(bp, "\n", 1) <= 0)
- return 0;
- }
- if (x->counter && !ASN1_bn_print(bp, "counter:", x->counter, NULL, indent))
- goto err;
if (x->length != 0) {
if (!BIO_indent(bp, indent, 128)
|| BIO_printf(bp, "recommended-private-length: %d bits\n",
@@ -355,7 +329,7 @@ static int int_dh_size(const EVP_PKEY *pkey)
static int dh_bits(const EVP_PKEY *pkey)
{
- return BN_num_bits(pkey->pkey.dh->p);
+ return DH_bits(pkey->pkey.dh);
}
static int dh_security_bits(const EVP_PKEY *pkey)
@@ -365,59 +339,17 @@ static int dh_security_bits(const EVP_PKEY *pkey)
static int dh_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
{
- if (BN_cmp(a->pkey.dh->p, b->pkey.dh->p) ||
- BN_cmp(a->pkey.dh->g, b->pkey.dh->g))
- return 0;
- else if (a->ameth == &dhx_asn1_meth) {
- if (BN_cmp(a->pkey.dh->q, b->pkey.dh->q))
- return 0;
- }
- return 1;
-}
-
-static int int_dh_bn_cpy(BIGNUM **dst, const BIGNUM *src)
-{
- BIGNUM *a;
-
- /*
- * If source is read only just copy the pointer, so
- * we don't have to reallocate it.
- */
- if (src == NULL)
- a = NULL;
- else if (BN_get_flags(src, BN_FLG_STATIC_DATA)
- && !BN_get_flags(src, BN_FLG_MALLOCED))
- a = (BIGNUM *)src;
- else if ((a = BN_dup(src)) == NULL)
- return 0;
- BN_clear_free(*dst);
- *dst = a;
- return 1;
+ return ffc_params_cmp(&a->pkey.dh->params, &a->pkey.dh->params,
+ a->ameth != &dhx_asn1_meth);
}
static int int_dh_param_copy(DH *to, const DH *from, int is_x942)
{
if (is_x942 == -1)
- is_x942 = ! !from->q;
- if (!int_dh_bn_cpy(&to->p, from->p))
+ is_x942 = (from->params.q != NULL);
+ if (!ffc_params_copy(&to->params, &from->params))
return 0;
- if (!int_dh_bn_cpy(&to->g, from->g))
- return 0;
- if (is_x942) {
- if (!int_dh_bn_cpy(&to->q, from->q))
- return 0;
- if (!int_dh_bn_cpy(&to->j, from->j))
- return 0;
- OPENSSL_free(to->seed);
- to->seed = NULL;
- to->seedlen = 0;
- if (from->seed) {
- to->seed = OPENSSL_memdup(from->seed, from->seedlen);
- if (!to->seed)
- return 0;
- to->seedlen = from->seedlen;
- }
- } else
+ if (!is_x942)
to->length = from->length;
to->dirty_cnt++;
return 1;
@@ -449,9 +381,9 @@ static int dh_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
static int dh_missing_parameters(const EVP_PKEY *a)
{
- if (a->pkey.dh == NULL || a->pkey.dh->p == NULL || a->pkey.dh->g == NULL)
- return 1;
- return 0;
+ return a->pkey.dh == NULL
+ || a->pkey.dh->params.p == NULL
+ || a->pkey.dh->params.g == NULL;
}
static int dh_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
@@ -820,6 +752,7 @@ static int dh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri)
static int dh_cms_decrypt(CMS_RecipientInfo *ri)
{
EVP_PKEY_CTX *pctx;
+
pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
if (pctx == NULL)
diff --git a/crypto/dh/dh_asn1.c b/crypto/dh/dh_asn1.c
index 2708a81cd0..75f2dd5bde 100644
--- a/crypto/dh/dh_asn1.c
+++ b/crypto/dh/dh_asn1.c
@@ -34,8 +34,8 @@ static int dh_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
}
ASN1_SEQUENCE_cb(DHparams, dh_cb) = {
- ASN1_SIMPLE(DH, p, BIGNUM),
- ASN1_SIMPLE(DH, g, BIGNUM),
+ ASN1_SIMPLE(DH, params.p, BIGNUM),
+ ASN1_SIMPLE(DH, params.g, BIGNUM),
ASN1_OPT_EMBED(DH, length, ZINT32),
} ASN1_SEQUENCE_END_cb(DH, DHparams)
@@ -82,6 +82,7 @@ IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(int_dhx942_dh, DHxparams, int_dhx)
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();
@@ -93,22 +94,22 @@ DH *d2i_DHxparams(DH **a, const unsigned char **pp, long length)
return NULL;
}
- if (a) {
+ if (a != NULL) {
DH_free(*a);
*a = dh;
}
- dh->p = dhx->p;
- dh->q = dhx->q;
- dh->g = dhx->g;
- dh->j = dhx->j;
+ params = &dh->params;
+ ffc_params_set0_pqg(params, dhx->p, dhx->q, dhx->g);
+ ffc_params_set0_j(params, dhx->j);
- if (dhx->vparams) {
- dh->seed = dhx->vparams->seed->data;
- dh->seedlen = dhx->vparams->seed->length;
- dh->counter = dhx->vparams->counter;
- dhx->vparams->seed->data = NULL;
+ if (dhx->vparams != NULL) {
+ /* The counter has a maximum value of 4 * numbits(p) - 1 */
+ size_t counter = (size_t)BN_get_word(dhx->vparams->counter);
+ ffc_params_set_validate_params(params, dhx->vparams->seed->data,
+ dhx->vparams->seed->length, counter);
ASN1_BIT_STRING_free(dhx->vparams->seed);
+ BN_free(dhx->vparams->counter);
OPENSSL_free(dhx->vparams);
dhx->vparams = NULL;
}
@@ -119,22 +120,34 @@ DH *d2i_DHxparams(DH **a, const unsigned char **pp, long length)
int i2d_DHxparams(const DH *dh, unsigned char **pp)
{
+ int ret = 0;
int_dhx942_dh dhx;
- int_dhvparams dhv;
- ASN1_BIT_STRING bs;
- dhx.p = dh->p;
- dhx.g = dh->g;
- dhx.q = dh->q;
- dhx.j = dh->j;
- if (dh->counter && dh->seed && dh->seedlen > 0) {
- bs.flags = ASN1_STRING_FLAG_BITS_LEFT;
- bs.data = dh->seed;
- bs.length = dh->seedlen;
- dhv.seed = &bs;
- dhv.counter = dh->counter;
+ int_dhvparams dhv = { NULL, NULL };
+ ASN1_BIT_STRING seed;
+ size_t seedlen = 0;
+ const FFC_PARAMS *params = &dh->params;
+ int counter;
+
+ ffc_params_get0_pqg(params, (const BIGNUM **)&dhx.p,
+ (const BIGNUM **)&dhx.q, (const BIGNUM **)&dhx.g);
+ dhx.j = params->j;
+ ffc_params_get_validate_params(params, &seed.data, &seedlen, &counter);
+ seed.length = (int)seedlen;
+
+ if (counter != -1 && seed.data != NULL && seed.length > 0) {
+ seed.flags = ASN1_STRING_FLAG_BITS_LEFT;
+ dhv.seed = &seed;
+ dhv.counter = BN_new();
+ if (dhv.counter == NULL)
+ return 0;
+ if (!BN_set_word(dhv.counter, (BN_ULONG)counter))
+ goto err;
dhx.vparams = &dhv;
- } else
+ } else {
dhx.vparams = NULL;
-
- return i2d_int_dhx(&dhx, pp);
+ }
+ ret = i2d_int_dhx(&dhx, pp);
+err:
+ BN_free(dhv.counter);
+ return ret;
}
diff --git a/crypto/dh/dh_check.c b/crypto/dh/dh_check.c
index 70f083603f..8bb245207b 100644
--- a/crypto/dh/dh_check.c
+++ b/crypto/dh/dh_check.c
@@ -52,17 +52,19 @@ int DH_check_params(const DH *dh, int *ret)
if (tmp == NULL)
goto err;
- if (!BN_is_odd(dh->p))
+ if (!BN_is_odd(dh->params.p))
*ret |= DH_CHECK_P_NOT_PRIME;
- if (BN_is_negative(dh->g) || BN_is_zero(dh->g) || BN_is_one(dh->g))
+ if (BN_is_negative(dh->params.g)
+ || BN_is_zero(dh->params.g)
+ || BN_is_one(dh->params.g))
*ret |= DH_NOT_SUITABLE_GENERATOR;
- if (BN_copy(tmp, dh->p) == NULL || !BN_sub_word(tmp, 1))
+ if (BN_copy(tmp, dh->params.p) == NULL || !BN_sub_word(tmp, 1))
goto err;
- if (BN_cmp(dh->g, tmp) >= 0)
+ if (BN_cmp(dh->params.g, tmp) >= 0)
*ret |= DH_NOT_SUITABLE_GENERATOR;
- if (BN_num_bits(dh->p) < DH_MIN_MODULUS_BITS)
+ if (BN_num_bits(dh->params.p) < DH_MIN_MODULUS_BITS)
*ret |= DH_MODULUS_TOO_SMALL;
- if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS)
+ if (BN_num_bits(dh->params.p) > OPENSSL_DH_MAX_MODULUS_BITS)
*ret |= DH_MODULUS_TOO_LARGE;
ok = 1;
@@ -123,39 +125,40 @@ int DH_check(const DH *dh, int *ret)
if (t2 == NULL)
goto err;
- if (dh->q) {
- if (BN_cmp(dh->g, BN_value_one()) <= 0)
+ if (dh->params.q != NULL) {
+ if (BN_cmp(dh->params.g, BN_value_one()) <= 0)
*ret |= DH_NOT_SUITABLE_GENERATOR;
- else if (BN_cmp(dh->g, dh->p) >= 0)
+ else if (BN_cmp(dh->params.g, dh->params.p) >= 0)
*ret |= DH_NOT_SUITABLE_GENERATOR;
else {
/* Check g^q == 1 mod p */
- if (!BN_mod_exp(t1, dh->g, dh->q, dh->p, ctx))
+ if (!BN_mod_exp(t1, dh->params.g, dh->params.q, dh->params.p, ctx))
goto err;
if (!BN_is_one(t1))
*ret |= DH_NOT_SUITABLE_GENERATOR;
}
- r = BN_check_prime(dh->q, ctx, NULL);
+ r = BN_check_prime(dh->params.q, ctx, NULL);
if (r < 0)
goto err;
if (!r)
*ret |= DH_CHECK_Q_NOT_PRIME;
/* Check p == 1 mod q i.e. q divides p - 1 */
- if (!BN_div(t1, t2, dh->p, dh->q, ctx))
+ if (!BN_div(t1, t2, dh->params.p, dh->params.q, ctx))
goto err;
if (!BN_is_one(t2))
*ret |= DH_CHECK_INVALID_Q_VALUE;
- if (dh->j && BN_cmp(dh->j, t1))
+ if (dh->params.j != NULL
+ && BN_cmp(dh->params.j, t1))
*ret |= DH_CHECK_INVALID_J_VALUE;
}
- r = BN_check_prime(dh->p, ctx, NULL);
+ r = BN_check_prime(dh->params.p, ctx, NULL);
if (r < 0)
goto err;
if (!r)
*ret |= DH_CHECK_P_NOT_PRIME;
- else if (!dh->q) {
- if (!BN_rshift1(t1, dh->p))
+ else if (dh->params.q == NULL) {
+ if (!BN_rshift1(t1, dh->params.p))
goto err;
r = BN_check_prime(t1, ctx, NULL);
if (r < 0)
@@ -203,14 +206,14 @@ int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *ret)
goto err;
if (BN_cmp(pub_key, tmp) <= 0)
*ret |= DH_CHECK_PUBKEY_TOO_SMALL;
- if (BN_copy(tmp, dh->p) == NULL || !BN_sub_word(tmp, 1))
+ if (BN_copy(tmp, dh->params.p) == NULL || !BN_sub_word(tmp, 1))
goto err;
if (BN_cmp(pub_key, tmp) >= 0)
*ret |= DH_CHECK_PUBKEY_TOO_LARGE;
- if (dh->q != NULL) {
+ if (dh->params.q != NULL) {
/* Check pub_key^q == 1 mod p */
- if (!BN_mod_exp(tmp, pub_key, dh->q, dh->p, ctx))
+ if (!BN_mod_exp(tmp, pub_key, dh->params.q, dh->params.p, ctx))
goto err;
if (!BN_is_one(tmp))
*ret |= DH_CHECK_PUBKEY_INVALID;
diff --git a/crypto/dh/dh_gen.c b/crypto/dh/dh_gen.c
index 0506bbe2e5..75548592b8 100644
--- a/crypto/dh/dh_gen.c
+++ b/crypto/dh/dh_gen.c
@@ -81,9 +81,9 @@ static int dh_builtin_genparams(DH *ret, int prime_len, int generator,
goto err;
/* Make sure 'ret' has the necessary elements */
- if (!ret->p && ((ret->p = BN_new()) == NULL))
+ if (ret->params.p == NULL && ((ret->params.p = BN_new()) == NULL))
goto err;
- if (!ret->g && ((ret->g = BN_new()) == NULL))
+ if (ret->params.g == NULL && ((ret->params.g = BN_new()) == NULL))
goto err;
if (generator <= 1) {
@@ -115,11 +115,11 @@ static int dh_builtin_genparams(DH *ret, int prime_len, int generator,
g = generator;
}
- if (!BN_generate_prime_ex(ret->p, prime_len, 1, t1, t2, cb))
+ if (!BN_generate_prime_ex(ret->params.p, prime_len, 1, t1, t2, cb))
goto err;
if (!BN_GENCB_call(cb, 3, 0))
goto err;
- if (!BN_set_word(ret->g, g))
+ if (!BN_set_word(ret->params.g, g))
goto err;
ret->dirty_cnt++;
ok = 1;
diff --git a/crypto/dh/dh_key.c b/crypto/dh/dh_key.c
index bd9b5c824b..4c5d78a19f 100644
--- a/crypto/dh/dh_key.c
+++ b/crypto/dh/dh_key.c
@@ -34,12 +34,12 @@ int dh_compute_key(OPENSSL_CTX *libctx, unsigned char *key,
int check_result;
#endif
- if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS) {
+ if (BN_num_bits(dh->params.p) > OPENSSL_DH_MAX_MODULUS_BITS) {
DHerr(0, DH_R_MODULUS_TOO_LARGE);
goto err;
}
- if (BN_num_bits(dh->p) < DH_MIN_MODULUS_BITS) {
+ if (BN_num_bits(dh->params.p) < DH_MIN_MODULUS_BITS) {
DHerr(0, DH_R_MODULUS_TOO_SMALL);
return 0;
}
@@ -59,7 +59,7 @@ int dh_compute_key(OPENSSL_CTX *libctx, unsigned char *key,
if (dh->flags & DH_FLAG_CACHE_MONT_P) {
mont = BN_MONT_CTX_set_locked(&dh->method_mont_p,
- dh->lock, dh->p, ctx);
+ dh->lock, dh->params.p, ctx);
BN_set_flags(dh->priv_key, BN_FLG_CONSTTIME);
if (!mont)
goto err;
@@ -71,7 +71,7 @@ int dh_compute_key(OPENSSL_CTX *libctx, unsigned char *key,
goto err;
}
#endif
- if (!dh->meth->bn_mod_exp(dh, tmp, pub_key, dh->priv_key, dh->p, ctx,
+ if (!dh->meth->bn_mod_exp(dh, tmp, pub_key, dh->priv_key, dh->params.p, ctx,
mont)) {
DHerr(0, ERR_R_BN_LIB);
goto err;
@@ -101,7 +101,7 @@ int dh_compute_key_padded(OPENSSL_CTX *libctx, unsigned char *key,
#endif
if (rv <= 0)
return rv;
- pad = BN_num_bytes(dh->p) - rv;
+ pad = BN_num_bytes(dh->params.p) - rv;
if (pad > 0) {
memmove(key + pad, key, rv);
memset(key, 0, pad);
@@ -159,6 +159,7 @@ static int dh_bn_mod_exp(const DH *dh, BIGNUM *r,
static int dh_init(DH *dh)
{
dh->flags |= DH_FLAG_CACHE_MONT_P;
+ ffc_params_init(&dh->params);
return 1;
}
@@ -189,12 +190,12 @@ static int generate_key(DH *dh)
BN_MONT_CTX *mont = NULL;
BIGNUM *pub_key = NULL, *priv_key = NULL;
- if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS) {
+ if (BN_num_bits(dh->params.p) > OPENSSL_DH_MAX_MODULUS_BITS) {
DHerr(DH_F_GENERATE_KEY, DH_R_MODULUS_TOO_LARGE);
return 0;
}
- if (BN_num_bits(dh->p) < DH_MIN_MODULUS_BITS) {
+ if (BN_num_bits(dh->params.p) < DH_MIN_MODULUS_BITS) {
DHerr(DH_F_GENERATE_KEY, DH_R_MODULUS_TOO_SMALL);
return 0;
}
@@ -220,28 +221,29 @@ static int generate_key(DH *dh)
if (dh->flags & DH_FLAG_CACHE_MONT_P) {
mont = BN_MONT_CTX_set_locked(&dh->method_mont_p,
- dh->lock, dh->p, ctx);
+ dh->lock, dh->params.p, ctx);
if (!mont)
goto err;
}
if (generate_new_key) {
- if (dh->q) {
+ if (dh->params.q != NULL) {
do {
- if (!BN_priv_rand_range(priv_key, dh->q))
+ 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->p) - 1;
+ 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;
/*
* We handle just one known case where g is a quadratic non-residue:
* for g = 2: p % 8 == 3
*/
- if (BN_is_word(dh->g, DH_GENERATOR_2) && !BN_is_bit_set(dh->p, 2)) {
+ 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;
@@ -256,7 +258,8 @@ static int generate_key(DH *dh)
goto err;
BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME);
- if (!dh->meth->bn_mod_exp(dh, pub_key, dh->g, prk, dh->p, ctx, mont)) {
+ if (!dh->meth->bn_mod_exp(dh, pub_key, dh->params.g, prk, dh->params.p,
+ ctx, mont)) {
BN_clear_free(prk);
goto err;
}
@@ -280,6 +283,7 @@ static int generate_key(DH *dh)
return ok;
}
+
int dh_buf2key(DH *dh, const unsigned char *buf, size_t len)
{
int err_reason = DH_R_BN_ERROR;
diff --git a/crypto/dh/dh_lib.c b/crypto/dh/dh_lib.c
index c9679d7e52..2f5aa10401 100644
--- a/crypto/dh/dh_lib.c
+++ b/crypto/dh/dh_lib.c
@@ -14,6 +14,7 @@
#include "dh_local.h"
#include "crypto/dh.h"
#include <openssl/engine.h>
+#include "crypto/dh.h"
#ifndef FIPS_MODE
int DH_set_method(DH *dh, const DH_METHOD *meth)
@@ -122,12 +123,7 @@ void DH_free(DH *r)
CRYPTO_THREAD_lock_free(r->lock);
- BN_clear_free(r->p);
- BN_clear_free(r->g);
- BN_clear_free(r->q);
- BN_clear_free(r->j);
- OPENSSL_free(r->seed);
- BN_clear_free(r->counter);
+ ffc_params_cleanup(&r->params);
BN_clear_free(r->pub_key);
BN_clear_free(r->priv_key);
OPENSSL_free(r);
@@ -159,35 +155,30 @@ void *DH_get_ex_data(DH *d, int idx)
int DH_bits(const DH *dh)
{
- return BN_num_bits(dh->p);
+ return BN_num_bits(dh->params.p);
}
int DH_size(const DH *dh)
{
- return BN_num_bytes(dh->p);
+ return BN_num_bytes(dh->params.p);
}
int DH_security_bits(const DH *dh)
{
int N;
- if (dh->q)
- N = BN_num_bits(dh->q);
+ if (dh->params.q != NULL)
+ N = BN_num_bits(dh->params.q);
else if (dh->length)
N = dh->length;
else
N = -1;
- return BN_security_bits(BN_num_bits(dh->p), N);
+ return BN_security_bits(BN_num_bits(dh->params.p), N);
}
void DH_get0_pqg(const DH *dh,
const BIGNUM **p, const BIGNUM **q, const BIGNUM **g)
{
- if (p != NULL)
- *p = dh->p;
- if (q != NULL)
- *q = dh->q;
- if (g != NULL)
- *g = dh->g;
+ ffc_params_get0_pqg(&dh->params, p, q, g);
}
int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g)
@@ -195,26 +186,14 @@ int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g)
/* If the fields p and g in d are NULL, the corresponding input
* parameters MUST be non-NULL. q may remain NULL.
*/
- if ((dh->p == NULL && p == NULL)
- || (dh->g == NULL && g == NULL))
+ if ((dh->params.p == NULL && p == NULL)
+ || (dh->params.g == NULL && g == NULL))
return 0;
- if (p != NULL) {
- BN_free(dh->p);
- dh->p = p;
- }
- if (q != NULL) {
- BN_free(dh->q);
- dh->q = q;
- }
- if (g != NULL) {
- BN_free(dh->g);
- dh->g = g;
- }
+ ffc_params_set0_pqg(&dh->params, p, q, g);
- if (q != NULL) {
+ if (q != NULL)
dh->length = BN_num_bits(q);
- }
dh->dirty_cnt++;
return 1;
@@ -256,17 +235,17 @@ int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key)
const BIGNUM *DH_get0_p(const DH *dh)
{
- return dh->p;
+ return dh->params.p;
}
const BIGNUM *DH_get0_q(const DH *dh)
{
- return dh->q;
+ return dh->params.q;
}
const BIGNUM *DH_get0_g(const DH *dh)
{
- return dh->g;
+ return dh->params.g;
}
const BIGNUM *DH_get0_priv_key(const DH *dh)
@@ -300,3 +279,8 @@ ENGINE *DH_get0_engine(DH *dh)
return dh->engine;
}
#endif /*FIPS_MODE */
+
+FFC_PARAMS *dh_get0_params(DH *dh)
+{
+ return &dh->params;
+}
diff --git a/crypto/dh/dh_local.h b/crypto/dh/dh_local.h
index 2a200c748e..57d9d3489f 100644
--- a/crypto/dh/dh_local.h
+++ b/crypto/dh/dh_local.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2016-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
@@ -9,6 +9,7 @@
#include <openssl/dh.h>
#include "internal/refcount.h"
+#include "internal/ffc.h"
#define DH_MIN_MODULUS_BITS 512
@@ -19,19 +20,12 @@ struct dh_st {
*/
int pad;
int version;
- BIGNUM *p;
- BIGNUM *g;
- int32_t length; /* optional */
+ FFC_PARAMS params;
+ int32_t length; /* optional value of N (if there is no q) */
BIGNUM *pub_key; /* g^x % p */
BIGNUM *priv_key; /* x */
int flags;
BN_MONT_CTX *method_mont_p;
- /* Place holders if we want to do X9.42 DH */
- BIGNUM *q;
- BIGNUM *j;
- unsigned char *seed;
- int seedlen;
- BIGNUM *counter;
CRYPTO_REF_COUNT references;
#ifndef FIPS_MODE
CRYPTO_EX_DATA ex_data;
diff --git a/crypto/dh/dh_rfc5114.c b/crypto/dh/dh_rfc5114.c
index 823f6d92e3..3bbfea12d3 100644
--- a/crypto/dh/dh_rfc5114.c
+++ b/crypto/dh/dh_rfc5114.c
@@ -26,10 +26,10 @@ DH *DH_get_##x(void) \
\
if (dh == NULL) \
return NULL; \
- dh->p = BN_dup(&_bignum_dh##x##_p); \
- dh->g = BN_dup(&_bignum_dh##x##_g); \
- dh->q = BN_dup(&_bignum_dh##x##_q); \
- if (dh->p == NULL || dh->q == NULL || dh->g == NULL) {\
+ dh->params.p = BN_dup(&_bignum_dh##x##_p); \
+ dh->params.g = BN_dup(&_bignum_dh##x##_g); \
+ dh->params.q = BN_dup(&_bignum_dh##x##_q); \
+ if (dh->params.p == NULL || dh->params.q == NULL || dh->params.g == NULL) {\
DH_free(dh); \
return NULL; \
} \
diff --git a/crypto/dh/dh_rfc7919.c b/crypto/dh/dh_rfc7919.c
index e36712facf..92e5000e28 100644
--- a/crypto/dh/dh_rfc7919.c
+++ b/crypto/dh/dh_rfc7919.c
@@ -19,8 +19,8 @@ static DH *dh_param_init(const BIGNUM *p, int32_t nbits)
DH *dh = DH_new();
if (dh == NULL)
return NULL;
- dh->p = (BIGNUM *)p;
- dh->g = (BIGNUM *)&_bignum_const_2;
+ dh->params.p = (BIGNUM *)p;
+ dh->params.g = (BIGNUM *)&_bignum_const_2;
dh->length = nbits;
dh->dirty_cnt++;
return dh;
@@ -49,25 +49,25 @@ int DH_get_nid(const DH *dh)
{
int nid;
- if (BN_get_word(dh->g) != 2)
+ if (BN_get_word(dh->params.g) != 2)
return NID_undef;
- if (!BN_cmp(dh->p, &_bignum_ffdhe2048_p))
+ if (!BN_cmp(dh->params.p, &_bignum_ffdhe2048_p))
nid = NID_ffdhe2048;
- else if (!BN_cmp(dh->p, &_bignum_ffdhe3072_p))
+ else if (!BN_cmp(dh->params.p, &_bignum_ffdhe3072_p))
nid = NID_ffdhe3072;
- else if (!BN_cmp(dh->p, &_bignum_ffdhe4096_p))
+ else if (!BN_cmp(dh->params.p, &_bignum_ffdhe4096_p))
nid = NID_ffdhe4096;
- else if (!BN_cmp(dh->p, &_bignum_ffdhe6144_p))
+ else if (!BN_cmp(dh->params.p, &_bignum_ffdhe6144_p))
nid = NID_ffdhe6144;
- else if (!BN_cmp(dh->p, &_bignum_ffdhe8192_p))
+ else if (!BN_cmp(dh->params.p, &_bignum_ffdhe8192_p))
nid = NID_ffdhe8192;
else
return NID_undef;
- if (dh->q != NULL) {
- BIGNUM *q = BN_dup(dh->p);
+ if (dh->params.q != NULL) {
+ BIGNUM *q = BN_dup(dh->params.p);
/* Check q = p * 2 + 1 we already know q is odd, so just shift right */
- if (q == NULL || !BN_rshift1(q, q) || !BN_cmp(dh->q, q))
+ if (q == NULL || !BN_rshift1(q, q) || !BN_cmp(dh->params.q, q))
nid = NID_undef;
BN_free(q);
}
diff --git a/crypto/dsa/dsa_ameth.c b/crypto/dsa/dsa_ameth.c
index ddd262bdde..510b204b2d 100644
--- a/crypto/dsa/dsa_ameth.c
+++ b/crypto/dsa/dsa_ameth.c
@@ -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;