Latest update.
This commit is contained in:
@@ -1,5 +1,9 @@
|
||||
LIBS=../../libcrypto
|
||||
SOURCE[../../libcrypto]=\
|
||||
dh_asn1.c dh_gen.c dh_key.c dh_lib.c dh_check.c dh_err.c dh_depr.c \
|
||||
dh_ameth.c dh_pmeth.c dh_prn.c dh_rfc5114.c dh_kdf.c dh_meth.c \
|
||||
dh_rfc7919.c
|
||||
|
||||
$COMMON=dh_lib.c dh_key.c dh_group_params.c
|
||||
|
||||
SOURCE[../../libcrypto]=$COMMON\
|
||||
dh_asn1.c dh_gen.c dh_check.c dh_err.c dh_depr.c \
|
||||
dh_ameth.c dh_pmeth.c dh_prn.c dh_rfc5114.c dh_kdf.c dh_meth.c
|
||||
|
||||
SOURCE[../../providers/libfips.a]=$COMMON
|
||||
+34
-105
@@ -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)
|
||||
@@ -550,51 +482,47 @@ static size_t dh_pkey_dirty_cnt(const EVP_PKEY *pkey)
|
||||
return pkey->pkey.dh->dirty_cnt;
|
||||
}
|
||||
|
||||
static void *dh_pkey_export_to(const EVP_PKEY *pk, EVP_KEYMGMT *keymgmt,
|
||||
int want_domainparams)
|
||||
static int dh_pkey_export_to(const EVP_PKEY *from, void *to_keydata,
|
||||
EVP_KEYMGMT *to_keymgmt)
|
||||
{
|
||||
DH *dh = pk->pkey.dh;
|
||||
DH *dh = from->pkey.dh;
|
||||
OSSL_PARAM_BLD tmpl;
|
||||
const BIGNUM *p = DH_get0_p(dh), *g = DH_get0_g(dh), *q = DH_get0_q(dh);
|
||||
const BIGNUM *pub_key = DH_get0_pub_key(dh);
|
||||
const BIGNUM *priv_key = DH_get0_priv_key(dh);
|
||||
OSSL_PARAM *params;
|
||||
void *provdata = NULL;
|
||||
int rv;
|
||||
|
||||
if (p == 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_G, g))
|
||||
return NULL;
|
||||
return 0;
|
||||
if (q != NULL) {
|
||||
if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_FFC_Q, q))
|
||||
return NULL;
|
||||
return 0;
|
||||
}
|
||||
/* A key must at least have a public part. */
|
||||
if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_DH_PUB_KEY, pub_key))
|
||||
return 0;
|
||||
if (priv_key != NULL) {
|
||||
if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_DH_PRIV_KEY,
|
||||
priv_key))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!want_domainparams) {
|
||||
/* A key must at least have a public part. */
|
||||
if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_DH_PUB_KEY,
|
||||
pub_key))
|
||||
return NULL;
|
||||
|
||||
if (priv_key != NULL) {
|
||||
if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_DH_PRIV_KEY,
|
||||
priv_key))
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
const EVP_PKEY_ASN1_METHOD dh_asn1_meth = {
|
||||
@@ -820,6 +748,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)
|
||||
|
||||
+42
-28
@@ -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,8 +82,10 @@ 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();
|
||||
if (dh == NULL)
|
||||
return NULL;
|
||||
@@ -93,22 +95,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;
|
||||
DH_set0_pqg(dh, 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 +121,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;
|
||||
dhx.vparams = &dhv;
|
||||
} else
|
||||
dhx.vparams = NULL;
|
||||
int_dhvparams dhv = { NULL, NULL };
|
||||
ASN1_BIT_STRING seed;
|
||||
size_t seedlen = 0;
|
||||
const FFC_PARAMS *params = &dh->params;
|
||||
int counter;
|
||||
|
||||
return i2d_int_dhx(&dhx, pp);
|
||||
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 {
|
||||
dhx.vparams = NULL;
|
||||
}
|
||||
ret = i2d_int_dhx(&dhx, pp);
|
||||
err:
|
||||
BN_free(dhv.counter);
|
||||
return ret;
|
||||
}
|
||||
+22
-19
@@ -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;
|
||||
|
||||
+74
-4
@@ -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,
|
||||
@@ -81,9 +150,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 +184,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;
|
||||
@@ -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 */
|
||||
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright 2017-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
|
||||
*/
|
||||
|
||||
/* DH parameters from RFC7919 and RFC3526 */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include "dh_local.h"
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/objects.h>
|
||||
#include "crypto/bn_dh.h"
|
||||
|
||||
static DH *dh_param_init(int nid, const BIGNUM *p, int32_t nbits)
|
||||
{
|
||||
BIGNUM *q = NULL;
|
||||
DH *dh = DH_new();
|
||||
|
||||
if (dh == NULL)
|
||||
return NULL;
|
||||
|
||||
q = BN_dup(p);
|
||||
/* Set q = (p - 1) / 2 (p is known to be odd so just shift right ) */
|
||||
if (q == NULL || !BN_rshift1(q, q)) {
|
||||
BN_free(q);
|
||||
DH_free(dh);
|
||||
return NULL;
|
||||
}
|
||||
dh->params.nid = nid;
|
||||
dh->params.p = (BIGNUM *)p;
|
||||
dh->params.q = (BIGNUM *)q;
|
||||
dh->params.g = (BIGNUM *)&_bignum_const_2;
|
||||
/* Private key length = 2 * max_target_security_strength */
|
||||
dh->length = nbits;
|
||||
dh->dirty_cnt++;
|
||||
return dh;
|
||||
}
|
||||
|
||||
DH *DH_new_by_nid(int nid)
|
||||
{
|
||||
/*
|
||||
* The last parameter specified in these fields is
|
||||
* 2 * max_target_security_strength.
|
||||
* See SP800-56Ar3 Table(s) 25 & 26.
|
||||
*/
|
||||
switch (nid) {
|
||||
case NID_ffdhe2048:
|
||||
return dh_param_init(nid, &_bignum_ffdhe2048_p, 225);
|
||||
case NID_ffdhe3072:
|
||||
return dh_param_init(nid, &_bignum_ffdhe3072_p, 275);
|
||||
case NID_ffdhe4096:
|
||||
return dh_param_init(nid, &_bignum_ffdhe4096_p, 325);
|
||||
case NID_ffdhe6144:
|
||||
return dh_param_init(nid, &_bignum_ffdhe6144_p, 375);
|
||||
case NID_ffdhe8192:
|
||||
return dh_param_init(nid, &_bignum_ffdhe8192_p, 400);
|
||||
#ifndef FIPS_MODE
|
||||
case NID_modp_1536:
|
||||
return dh_param_init(nid, &_bignum_modp_1536_p, 190);
|
||||
#endif
|
||||
case NID_modp_2048:
|
||||
return dh_param_init(nid, &_bignum_modp_2048_p, 225);
|
||||
case NID_modp_3072:
|
||||
return dh_param_init(nid, &_bignum_modp_3072_p, 275);
|
||||
case NID_modp_4096:
|
||||
return dh_param_init(nid, &_bignum_modp_4096_p, 325);
|
||||
case NID_modp_6144:
|
||||
return dh_param_init(nid, &_bignum_modp_6144_p, 375);
|
||||
case NID_modp_8192:
|
||||
return dh_param_init(nid, &_bignum_modp_8192_p, 400);
|
||||
default:
|
||||
DHerr(DH_F_DH_NEW_BY_NID, DH_R_INVALID_PARAMETER_NID);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int DH_get_nid(DH *dh)
|
||||
{
|
||||
int nid = dh->params.nid;
|
||||
|
||||
if (nid != NID_undef)
|
||||
return nid;
|
||||
|
||||
if (BN_get_word(dh->params.g) != 2)
|
||||
return NID_undef;
|
||||
if (!BN_cmp(dh->params.p, &_bignum_ffdhe2048_p))
|
||||
nid = NID_ffdhe2048;
|
||||
else if (!BN_cmp(dh->params.p, &_bignum_ffdhe3072_p))
|
||||
nid = NID_ffdhe3072;
|
||||
else if (!BN_cmp(dh->params.p, &_bignum_ffdhe4096_p))
|
||||
nid = NID_ffdhe4096;
|
||||
else if (!BN_cmp(dh->params.p, &_bignum_ffdhe6144_p))
|
||||
nid = NID_ffdhe6144;
|
||||
else if (!BN_cmp(dh->params.p, &_bignum_ffdhe8192_p))
|
||||
nid = NID_ffdhe8192;
|
||||
#ifndef FIPS_MODE
|
||||
else if (!BN_cmp(dh->params.p, &_bignum_modp_1536_p))
|
||||
nid = NID_modp_1536;
|
||||
#endif
|
||||
else if (!BN_cmp(dh->params.p, &_bignum_modp_2048_p))
|
||||
nid = NID_modp_2048;
|
||||
else if (!BN_cmp(dh->params.p, &_bignum_modp_3072_p))
|
||||
nid = NID_modp_3072;
|
||||
else if (!BN_cmp(dh->params.p, &_bignum_modp_4096_p))
|
||||
nid = NID_modp_4096;
|
||||
else if (!BN_cmp(dh->params.p, &_bignum_modp_6144_p))
|
||||
nid = NID_modp_6144;
|
||||
else if (!BN_cmp(dh->params.p, &_bignum_modp_8192_p))
|
||||
nid = NID_modp_8192;
|
||||
else
|
||||
return NID_undef;
|
||||
|
||||
/* Verify q is correct if it exists - reset the nid if it is not correct */
|
||||
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->params.q, q) != 0))
|
||||
nid = NID_undef;
|
||||
BN_free(q);
|
||||
}
|
||||
dh->params.nid = nid; /* cache the nid */
|
||||
return nid;
|
||||
}
|
||||
+2
-2
@@ -43,14 +43,14 @@ int DH_KDF_X9_42(unsigned char *out, size_t outlen,
|
||||
if ((kctx = EVP_KDF_CTX_new(kdf)) == NULL)
|
||||
goto err;
|
||||
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST,
|
||||
(char *)mdname, strlen(mdname) + 1);
|
||||
(char *)mdname, 0);
|
||||
*p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY,
|
||||
(unsigned char *)Z, Zlen);
|
||||
if (ukm != NULL)
|
||||
*p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_UKM,
|
||||
(unsigned char *)ukm, ukmlen);
|
||||
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_CEK_ALG,
|
||||
(char *)oid_sn, strlen(oid_sn) + 1);
|
||||
(char *)oid_sn, 0);
|
||||
*p = OSSL_PARAM_construct_end();
|
||||
ret = EVP_KDF_CTX_set_params(kctx, params) > 0
|
||||
&& EVP_KDF_derive(kctx, out, outlen) > 0;
|
||||
|
||||
+180
-117
@@ -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
|
||||
@@ -11,20 +11,102 @@
|
||||
#include "internal/cryptlib.h"
|
||||
#include "dh_local.h"
|
||||
#include "crypto/bn.h"
|
||||
#include "crypto/dh.h"
|
||||
|
||||
static int generate_key(DH *dh);
|
||||
static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh);
|
||||
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);
|
||||
static int dh_init(DH *dh);
|
||||
static int dh_finish(DH *dh);
|
||||
|
||||
int DH_generate_key(DH *dh)
|
||||
int dh_compute_key(OPENSSL_CTX *libctx, unsigned char *key,
|
||||
const BIGNUM *pub_key, DH *dh)
|
||||
{
|
||||
return dh->meth->generate_key(dh);
|
||||
BN_CTX *ctx = NULL;
|
||||
BN_MONT_CTX *mont = NULL;
|
||||
BIGNUM *tmp;
|
||||
int ret = -1;
|
||||
#ifndef FIPS_MODE
|
||||
int check_result;
|
||||
#endif
|
||||
|
||||
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->params.p) < DH_MIN_MODULUS_BITS) {
|
||||
DHerr(0, DH_R_MODULUS_TOO_SMALL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ctx = BN_CTX_new_ex(libctx);
|
||||
if (ctx == NULL)
|
||||
goto err;
|
||||
BN_CTX_start(ctx);
|
||||
tmp = BN_CTX_get(ctx);
|
||||
if (tmp == NULL)
|
||||
goto err;
|
||||
|
||||
if (dh->priv_key == NULL) {
|
||||
DHerr(0, DH_R_NO_PRIVATE_VALUE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (dh->flags & DH_FLAG_CACHE_MONT_P) {
|
||||
mont = BN_MONT_CTX_set_locked(&dh->method_mont_p,
|
||||
dh->lock, dh->params.p, ctx);
|
||||
BN_set_flags(dh->priv_key, BN_FLG_CONSTTIME);
|
||||
if (!mont)
|
||||
goto err;
|
||||
}
|
||||
/* TODO(3.0) : Solve in a PR related to Key validation for DH */
|
||||
#ifndef FIPS_MODE
|
||||
if (!DH_check_pub_key(dh, pub_key, &check_result) || check_result) {
|
||||
DHerr(0, DH_R_INVALID_PUBKEY);
|
||||
goto err;
|
||||
}
|
||||
#endif
|
||||
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;
|
||||
}
|
||||
|
||||
ret = BN_bn2bin(tmp, key);
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
|
||||
{
|
||||
return dh_compute_key(NULL, key, pub_key, dh);
|
||||
}
|
||||
|
||||
int dh_compute_key_padded(OPENSSL_CTX *libctx, unsigned char *key,
|
||||
const BIGNUM *pub_key, DH *dh)
|
||||
{
|
||||
int rv, pad;
|
||||
|
||||
#ifdef FIPS_MODE
|
||||
rv = dh_compute_key(libctx, key, pub_key, dh);
|
||||
#else
|
||||
rv = dh->meth->compute_key(key, pub_key, dh);
|
||||
#endif
|
||||
if (rv <= 0)
|
||||
return rv;
|
||||
pad = BN_num_bytes(dh->params.p) - rv;
|
||||
if (pad > 0) {
|
||||
memmove(key + pad, key, rv);
|
||||
memset(key, 0, pad);
|
||||
}
|
||||
return rv + pad;
|
||||
}
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
int DH_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
|
||||
{
|
||||
return dh->meth->compute_key(key, pub_key, dh);
|
||||
@@ -32,17 +114,9 @@ int DH_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
|
||||
|
||||
int DH_compute_key_padded(unsigned char *key, const BIGNUM *pub_key, DH *dh)
|
||||
{
|
||||
int rv, pad;
|
||||
rv = dh->meth->compute_key(key, pub_key, dh);
|
||||
if (rv <= 0)
|
||||
return rv;
|
||||
pad = BN_num_bytes(dh->p) - rv;
|
||||
if (pad > 0) {
|
||||
memmove(key + pad, key, rv);
|
||||
memset(key, 0, pad);
|
||||
}
|
||||
return rv + pad;
|
||||
return dh_compute_key_padded(NULL, key, pub_key, dh);
|
||||
}
|
||||
#endif
|
||||
|
||||
static DH_METHOD dh_ossl = {
|
||||
"OpenSSL DH Method",
|
||||
@@ -63,36 +137,66 @@ const DH_METHOD *DH_OpenSSL(void)
|
||||
return &dh_ossl;
|
||||
}
|
||||
|
||||
void DH_set_default_method(const DH_METHOD *meth)
|
||||
{
|
||||
default_DH_method = meth;
|
||||
}
|
||||
|
||||
const DH_METHOD *DH_get_default_method(void)
|
||||
{
|
||||
return default_DH_method;
|
||||
}
|
||||
|
||||
static int generate_key(DH *dh)
|
||||
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)
|
||||
{
|
||||
return BN_mod_exp_mont(r, a, p, m, ctx, m_ctx);
|
||||
}
|
||||
|
||||
static int dh_init(DH *dh)
|
||||
{
|
||||
dh->flags |= DH_FLAG_CACHE_MONT_P;
|
||||
ffc_params_init(&dh->params);
|
||||
dh->dirty_cnt++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int dh_finish(DH *dh)
|
||||
{
|
||||
BN_MONT_CTX_free(dh->method_mont_p);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
void DH_set_default_method(const DH_METHOD *meth)
|
||||
{
|
||||
default_DH_method = meth;
|
||||
}
|
||||
|
||||
int DH_generate_key(DH *dh)
|
||||
{
|
||||
return dh->meth->generate_key(dh);
|
||||
}
|
||||
#endif /* FIPS_MODE */
|
||||
|
||||
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->p) > OPENSSL_DH_MAX_MODULUS_BITS) {
|
||||
DHerr(DH_F_GENERATE_KEY, DH_R_MODULUS_TOO_LARGE);
|
||||
if (BN_num_bits(dh->params.p) > OPENSSL_DH_MAX_MODULUS_BITS) {
|
||||
DHerr(0, DH_R_MODULUS_TOO_LARGE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (BN_num_bits(dh->p) < DH_MIN_MODULUS_BITS) {
|
||||
DHerr(DH_F_GENERATE_KEY, DH_R_MODULUS_TOO_SMALL);
|
||||
if (BN_num_bits(dh->params.p) < DH_MIN_MODULUS_BITS) {
|
||||
DHerr(0, DH_R_MODULUS_TOO_SMALL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ctx = BN_CTX_new();
|
||||
ctx = BN_CTX_new_ex(libctx);
|
||||
if (ctx == NULL)
|
||||
goto err;
|
||||
|
||||
@@ -113,30 +217,58 @@ 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) {
|
||||
do {
|
||||
if (!BN_priv_rand_range(priv_key, dh->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;
|
||||
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->g, DH_GENERATOR_2) && !BN_is_bit_set(dh->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;
|
||||
}
|
||||
}
|
||||
@@ -149,7 +281,9 @@ 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)) {
|
||||
/* 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);
|
||||
goto err;
|
||||
}
|
||||
@@ -163,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);
|
||||
@@ -173,80 +307,9 @@ static int generate_key(DH *dh)
|
||||
return ok;
|
||||
}
|
||||
|
||||
static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
|
||||
static int generate_key(DH *dh)
|
||||
{
|
||||
BN_CTX *ctx = NULL;
|
||||
BN_MONT_CTX *mont = NULL;
|
||||
BIGNUM *tmp;
|
||||
int ret = -1;
|
||||
int check_result;
|
||||
|
||||
if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS) {
|
||||
DHerr(DH_F_COMPUTE_KEY, DH_R_MODULUS_TOO_LARGE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (BN_num_bits(dh->p) < DH_MIN_MODULUS_BITS) {
|
||||
DHerr(DH_F_COMPUTE_KEY, DH_R_MODULUS_TOO_SMALL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ctx = BN_CTX_new();
|
||||
if (ctx == NULL)
|
||||
goto err;
|
||||
BN_CTX_start(ctx);
|
||||
tmp = BN_CTX_get(ctx);
|
||||
if (tmp == NULL)
|
||||
goto err;
|
||||
|
||||
if (dh->priv_key == NULL) {
|
||||
DHerr(DH_F_COMPUTE_KEY, DH_R_NO_PRIVATE_VALUE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (dh->flags & DH_FLAG_CACHE_MONT_P) {
|
||||
mont = BN_MONT_CTX_set_locked(&dh->method_mont_p,
|
||||
dh->lock, dh->p, ctx);
|
||||
BN_set_flags(dh->priv_key, BN_FLG_CONSTTIME);
|
||||
if (!mont)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!DH_check_pub_key(dh, pub_key, &check_result) || check_result) {
|
||||
DHerr(DH_F_COMPUTE_KEY, DH_R_INVALID_PUBKEY);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!dh->
|
||||
meth->bn_mod_exp(dh, tmp, pub_key, dh->priv_key, dh->p, ctx, mont)) {
|
||||
DHerr(DH_F_COMPUTE_KEY, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = BN_bn2bin(tmp, key);
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return BN_mod_exp_mont(r, a, p, m, ctx, m_ctx);
|
||||
}
|
||||
|
||||
static int dh_init(DH *dh)
|
||||
{
|
||||
dh->flags |= DH_FLAG_CACHE_MONT_P;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int dh_finish(DH *dh)
|
||||
{
|
||||
BN_MONT_CTX_free(dh->method_mont_p);
|
||||
return 1;
|
||||
return dh_generate_key(NULL, dh);
|
||||
}
|
||||
|
||||
int dh_buf2key(DH *dh, const unsigned char *buf, size_t len)
|
||||
|
||||
+38
-45
@@ -8,12 +8,15 @@
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/engine.h>
|
||||
#include <openssl/obj_mac.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include "internal/refcount.h"
|
||||
#include <openssl/bn.h>
|
||||
#include "crypto/dh.h"
|
||||
#include "dh_local.h"
|
||||
#include <openssl/engine.h>
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
int DH_set_method(DH *dh, const DH_METHOD *meth)
|
||||
{
|
||||
/*
|
||||
@@ -33,6 +36,7 @@ int DH_set_method(DH *dh, const DH_METHOD *meth)
|
||||
meth->init(dh);
|
||||
return 1;
|
||||
}
|
||||
#endif /* !FIPS_MODE */
|
||||
|
||||
DH *DH_new(void)
|
||||
{
|
||||
@@ -57,7 +61,7 @@ DH *DH_new_method(ENGINE *engine)
|
||||
}
|
||||
|
||||
ret->meth = DH_get_default_method();
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
#if !defined(FIPS_MODE) && !defined(OPENSSL_NO_ENGINE)
|
||||
ret->flags = ret->meth->flags; /* early default init */
|
||||
if (engine) {
|
||||
if (!ENGINE_init(engine)) {
|
||||
@@ -81,7 +85,7 @@ DH *DH_new_method(ENGINE *engine)
|
||||
#ifndef FIPS_MODE
|
||||
if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_DH, ret, &ret->ex_data))
|
||||
goto err;
|
||||
#endif
|
||||
#endif /* FIPS_MODE */
|
||||
|
||||
if ((ret->meth->init != NULL) && !ret->meth->init(ret)) {
|
||||
DHerr(DH_F_DH_NEW_METHOD, ERR_R_INIT_FAIL);
|
||||
@@ -110,22 +114,16 @@ void DH_free(DH *r)
|
||||
|
||||
if (r->meth != NULL && r->meth->finish != NULL)
|
||||
r->meth->finish(r);
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
#if !defined(FIPS_MODE)
|
||||
# if !defined(OPENSSL_NO_ENGINE)
|
||||
ENGINE_finish(r->engine);
|
||||
#endif
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
# endif
|
||||
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DH, r, &r->ex_data);
|
||||
#endif
|
||||
|
||||
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);
|
||||
@@ -157,36 +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)
|
||||
@@ -194,26 +186,16 @@ 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);
|
||||
dh->params.nid = NID_undef;
|
||||
DH_get_nid(dh); /* Check if this is a named group and cache it */
|
||||
|
||||
if (q != NULL) {
|
||||
if (q != NULL)
|
||||
dh->length = BN_num_bits(q);
|
||||
}
|
||||
|
||||
dh->dirty_cnt++;
|
||||
return 1;
|
||||
@@ -255,17 +237,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)
|
||||
@@ -293,7 +275,18 @@ void DH_set_flags(DH *dh, int flags)
|
||||
dh->flags |= flags;
|
||||
}
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
ENGINE *DH_get0_engine(DH *dh)
|
||||
{
|
||||
return dh->engine;
|
||||
}
|
||||
#endif /*FIPS_MODE */
|
||||
|
||||
FFC_PARAMS *dh_get0_params(DH *dh)
|
||||
{
|
||||
return &dh->params;
|
||||
}
|
||||
int dh_get0_nid(const DH *dh)
|
||||
{
|
||||
return dh->params.nid;
|
||||
}
|
||||
+5
-11
@@ -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,25 +20,18 @@ 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;
|
||||
ENGINE *engine;
|
||||
#endif
|
||||
const DH_METHOD *meth;
|
||||
ENGINE *engine;
|
||||
CRYPTO_RWLOCK *lock;
|
||||
|
||||
/* Provider data */
|
||||
|
||||
+57
-58
@@ -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,27 +300,47 @@ 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;
|
||||
BN_GENCB *pcb;
|
||||
BN_GENCB *pcb = NULL;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Look for a safe prime group for key establishment. Which uses
|
||||
* either RFC_3526 (modp_XXXX) or RFC_7919 (ffdheXXXX).
|
||||
*/
|
||||
if (dctx->param_nid != NID_undef) {
|
||||
if ((dh = DH_new_by_nid(dctx->param_nid)) == NULL)
|
||||
return 0;
|
||||
EVP_PKEY_assign(pkey, EVP_PKEY_DH, dh);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
if (dctx->rfc5114_param) {
|
||||
switch (dctx->rfc5114_param) {
|
||||
case 1:
|
||||
@@ -351,36 +361,25 @@ static int pkey_dh_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
|
||||
EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
|
||||
return 1;
|
||||
}
|
||||
#endif /* FIPS_MODE */
|
||||
|
||||
if (dctx->param_nid != 0) {
|
||||
if ((dh = DH_new_by_nid(dctx->param_nid)) == NULL)
|
||||
return 0;
|
||||
EVP_PKEY_assign(pkey, EVP_PKEY_DH, dh);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (ctx->pkey_gencb) {
|
||||
if (ctx->pkey_gencb != NULL) {
|
||||
pcb = BN_GENCB_new();
|
||||
if (pcb == NULL)
|
||||
return 0;
|
||||
evp_pkey_set_cb_translate(pcb, ctx);
|
||||
} else
|
||||
pcb = NULL;
|
||||
#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);
|
||||
@@ -401,11 +400,11 @@ static int pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
|
||||
DH_PKEY_CTX *dctx = ctx->data;
|
||||
DH *dh = NULL;
|
||||
|
||||
if (ctx->pkey == NULL && dctx->param_nid == 0) {
|
||||
if (ctx->pkey == NULL && dctx->param_nid == NID_undef) {
|
||||
DHerr(DH_F_PKEY_DH_KEYGEN, DH_R_NO_PARAMETERS_SET);
|
||||
return 0;
|
||||
}
|
||||
if (dctx->param_nid != 0)
|
||||
if (dctx->param_nid != NID_undef)
|
||||
dh = DH_new_by_nid(dctx->param_nid);
|
||||
else
|
||||
dh = DH_new();
|
||||
|
||||
@@ -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; \
|
||||
} \
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
/*
|
||||
* Copyright 2017 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 <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include "dh_local.h"
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/objects.h>
|
||||
#include "crypto/bn_dh.h"
|
||||
|
||||
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->length = nbits;
|
||||
dh->dirty_cnt++;
|
||||
return dh;
|
||||
}
|
||||
|
||||
DH *DH_new_by_nid(int nid)
|
||||
{
|
||||
switch (nid) {
|
||||
case NID_ffdhe2048:
|
||||
return dh_param_init(&_bignum_ffdhe2048_p, 225);
|
||||
case NID_ffdhe3072:
|
||||
return dh_param_init(&_bignum_ffdhe3072_p, 275);
|
||||
case NID_ffdhe4096:
|
||||
return dh_param_init(&_bignum_ffdhe4096_p, 325);
|
||||
case NID_ffdhe6144:
|
||||
return dh_param_init(&_bignum_ffdhe6144_p, 375);
|
||||
case NID_ffdhe8192:
|
||||
return dh_param_init(&_bignum_ffdhe8192_p, 400);
|
||||
default:
|
||||
DHerr(DH_F_DH_NEW_BY_NID, DH_R_INVALID_PARAMETER_NID);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int DH_get_nid(const DH *dh)
|
||||
{
|
||||
int nid;
|
||||
|
||||
if (BN_get_word(dh->g) != 2)
|
||||
return NID_undef;
|
||||
if (!BN_cmp(dh->p, &_bignum_ffdhe2048_p))
|
||||
nid = NID_ffdhe2048;
|
||||
else if (!BN_cmp(dh->p, &_bignum_ffdhe3072_p))
|
||||
nid = NID_ffdhe3072;
|
||||
else if (!BN_cmp(dh->p, &_bignum_ffdhe4096_p))
|
||||
nid = NID_ffdhe4096;
|
||||
else if (!BN_cmp(dh->p, &_bignum_ffdhe6144_p))
|
||||
nid = NID_ffdhe6144;
|
||||
else if (!BN_cmp(dh->p, &_bignum_ffdhe8192_p))
|
||||
nid = NID_ffdhe8192;
|
||||
else
|
||||
return NID_undef;
|
||||
if (dh->q != NULL) {
|
||||
BIGNUM *q = BN_dup(dh->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))
|
||||
nid = NID_undef;
|
||||
BN_free(q);
|
||||
}
|
||||
return nid;
|
||||
}
|
||||
Reference in New Issue
Block a user