sync
This commit is contained in:
parent
82bafdd0b3
commit
ae25582c29
37 changed files with 421 additions and 1406 deletions
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: ec_key.c,v 1.32 2023/03/27 10:25:02 tb Exp $ */
|
||||
/* $OpenBSD: ec_key.c,v 1.33 2023/06/25 18:52:27 tb Exp $ */
|
||||
/*
|
||||
* Written by Nils Larsch for the OpenSSL project.
|
||||
*/
|
||||
|
@ -122,16 +122,12 @@ EC_KEY_free(EC_KEY *r)
|
|||
EC_POINT_free(r->pub_key);
|
||||
BN_free(r->priv_key);
|
||||
|
||||
EC_EX_DATA_free_all_data(&r->method_data);
|
||||
|
||||
freezero(r, sizeof(EC_KEY));
|
||||
}
|
||||
|
||||
EC_KEY *
|
||||
EC_KEY_copy(EC_KEY *dest, const EC_KEY *src)
|
||||
{
|
||||
EC_EXTRA_DATA *d;
|
||||
|
||||
if (dest == NULL || src == NULL) {
|
||||
ECerror(ERR_R_PASSED_NULL_PARAMETER);
|
||||
return NULL;
|
||||
|
@ -175,18 +171,6 @@ EC_KEY_copy(EC_KEY *dest, const EC_KEY *src)
|
|||
if (!bn_copy(dest->priv_key, src->priv_key))
|
||||
return NULL;
|
||||
}
|
||||
/* copy method/extra data */
|
||||
EC_EX_DATA_free_all_data(&dest->method_data);
|
||||
|
||||
for (d = src->method_data; d != NULL; d = d->next) {
|
||||
void *t = d->dup_func(d->data);
|
||||
|
||||
if (t == NULL)
|
||||
return 0;
|
||||
if (!EC_EX_DATA_set_data(&dest->method_data, t, d->dup_func,
|
||||
d->free_func, d->clear_free_func))
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* copy the rest */
|
||||
dest->enc_flag = src->enc_flag;
|
||||
|
@ -526,38 +510,6 @@ EC_KEY_set_conv_form(EC_KEY *key, point_conversion_form_t cform)
|
|||
EC_GROUP_set_point_conversion_form(key->group, cform);
|
||||
}
|
||||
|
||||
void *
|
||||
EC_KEY_get_key_method_data(EC_KEY *key,
|
||||
void *(*dup_func) (void *),
|
||||
void (*free_func) (void *),
|
||||
void (*clear_free_func) (void *))
|
||||
{
|
||||
void *ret;
|
||||
|
||||
CRYPTO_r_lock(CRYPTO_LOCK_EC);
|
||||
ret = EC_EX_DATA_get_data(key->method_data, dup_func, free_func, clear_free_func);
|
||||
CRYPTO_r_unlock(CRYPTO_LOCK_EC);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *
|
||||
EC_KEY_insert_key_method_data(EC_KEY *key, void *data,
|
||||
void *(*dup_func) (void *),
|
||||
void (*free_func) (void *),
|
||||
void (*clear_free_func) (void *))
|
||||
{
|
||||
EC_EXTRA_DATA *ex_data;
|
||||
|
||||
CRYPTO_w_lock(CRYPTO_LOCK_EC);
|
||||
ex_data = EC_EX_DATA_get_data(key->method_data, dup_func, free_func, clear_free_func);
|
||||
if (ex_data == NULL)
|
||||
EC_EX_DATA_set_data(&key->method_data, data, dup_func, free_func, clear_free_func);
|
||||
CRYPTO_w_unlock(CRYPTO_LOCK_EC);
|
||||
|
||||
return ex_data;
|
||||
}
|
||||
|
||||
void
|
||||
EC_KEY_set_asn1_flag(EC_KEY *key, int flag)
|
||||
{
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: ec_kmeth.c,v 1.7 2022/11/26 16:08:52 tb Exp $ */
|
||||
/* $OpenBSD: ec_kmeth.c,v 1.8 2023/06/25 18:52:27 tb Exp $ */
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project.
|
||||
|
@ -168,7 +168,6 @@ EC_KEY_new_method(ENGINE *engine)
|
|||
ret->enc_flag = 0;
|
||||
ret->conv_form = POINT_CONVERSION_UNCOMPRESSED;
|
||||
ret->references = 1;
|
||||
ret->method_data = NULL;
|
||||
|
||||
if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data))
|
||||
goto err;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: ec_lib.c,v 1.58 2023/06/20 14:37:15 tb Exp $ */
|
||||
/* $OpenBSD: ec_lib.c,v 1.61 2023/06/25 18:52:27 tb Exp $ */
|
||||
/*
|
||||
* Originally written by Bodo Moeller for the OpenSSL project.
|
||||
*/
|
||||
|
@ -93,8 +93,6 @@ EC_GROUP_new(const EC_METHOD *meth)
|
|||
}
|
||||
ret->meth = meth;
|
||||
|
||||
ret->extra_data = NULL;
|
||||
|
||||
ret->generator = NULL;
|
||||
BN_init(&ret->order);
|
||||
BN_init(&ret->cofactor);
|
||||
|
@ -123,8 +121,6 @@ EC_GROUP_free(EC_GROUP *group)
|
|||
if (group->meth->group_finish != NULL)
|
||||
group->meth->group_finish(group);
|
||||
|
||||
EC_EX_DATA_clear_free_all_data(&group->extra_data);
|
||||
|
||||
EC_POINT_free(group->generator);
|
||||
BN_free(&group->order);
|
||||
BN_free(&group->cofactor);
|
||||
|
@ -142,8 +138,6 @@ EC_GROUP_clear_free(EC_GROUP *group)
|
|||
int
|
||||
EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src)
|
||||
{
|
||||
EC_EXTRA_DATA *d;
|
||||
|
||||
if (dest->meth->group_copy == NULL) {
|
||||
ECerror(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
|
||||
return 0;
|
||||
|
@ -155,18 +149,6 @@ EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src)
|
|||
if (dest == src)
|
||||
return 1;
|
||||
|
||||
EC_EX_DATA_free_all_data(&dest->extra_data);
|
||||
|
||||
for (d = src->extra_data; d != NULL; d = d->next) {
|
||||
void *t = d->dup_func(d->data);
|
||||
|
||||
if (t == NULL)
|
||||
return 0;
|
||||
if (!EC_EX_DATA_set_data(&dest->extra_data, t, d->dup_func,
|
||||
d->free_func, d->clear_free_func))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (src->generator != NULL) {
|
||||
if (dest->generator == NULL) {
|
||||
dest->generator = EC_POINT_new(dest);
|
||||
|
@ -669,158 +651,6 @@ ec_point_blind_coordinates(const EC_GROUP *group, EC_POINT *p, BN_CTX *ctx)
|
|||
return group->meth->blind_coordinates(group, p, ctx);
|
||||
}
|
||||
|
||||
/* this has 'package' visibility */
|
||||
int
|
||||
EC_EX_DATA_set_data(EC_EXTRA_DATA ** ex_data, void *data,
|
||||
void *(*dup_func) (void *),
|
||||
void (*free_func) (void *),
|
||||
void (*clear_free_func) (void *))
|
||||
{
|
||||
EC_EXTRA_DATA *d;
|
||||
|
||||
if (ex_data == NULL)
|
||||
return 0;
|
||||
|
||||
for (d = *ex_data; d != NULL; d = d->next) {
|
||||
if (d->dup_func == dup_func && d->free_func == free_func &&
|
||||
d->clear_free_func == clear_free_func) {
|
||||
ECerror(EC_R_SLOT_FULL);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (data == NULL)
|
||||
/* no explicit entry needed */
|
||||
return 1;
|
||||
|
||||
d = malloc(sizeof *d);
|
||||
if (d == NULL)
|
||||
return 0;
|
||||
|
||||
d->data = data;
|
||||
d->dup_func = dup_func;
|
||||
d->free_func = free_func;
|
||||
d->clear_free_func = clear_free_func;
|
||||
|
||||
d->next = *ex_data;
|
||||
*ex_data = d;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* this has 'package' visibility */
|
||||
void *
|
||||
EC_EX_DATA_get_data(const EC_EXTRA_DATA *ex_data,
|
||||
void *(*dup_func) (void *),
|
||||
void (*free_func) (void *),
|
||||
void (*clear_free_func) (void *))
|
||||
{
|
||||
const EC_EXTRA_DATA *d;
|
||||
|
||||
for (d = ex_data; d != NULL; d = d->next) {
|
||||
if (d->dup_func == dup_func && d->free_func == free_func && d->clear_free_func == clear_free_func)
|
||||
return d->data;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* this has 'package' visibility */
|
||||
void
|
||||
EC_EX_DATA_free_data(EC_EXTRA_DATA ** ex_data,
|
||||
void *(*dup_func) (void *),
|
||||
void (*free_func) (void *),
|
||||
void (*clear_free_func) (void *))
|
||||
{
|
||||
EC_EXTRA_DATA **p;
|
||||
|
||||
if (ex_data == NULL)
|
||||
return;
|
||||
|
||||
for (p = ex_data; *p != NULL; p = &((*p)->next)) {
|
||||
if ((*p)->dup_func == dup_func &&
|
||||
(*p)->free_func == free_func &&
|
||||
(*p)->clear_free_func == clear_free_func) {
|
||||
EC_EXTRA_DATA *next = (*p)->next;
|
||||
|
||||
(*p)->free_func((*p)->data);
|
||||
free(*p);
|
||||
|
||||
*p = next;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* this has 'package' visibility */
|
||||
void
|
||||
EC_EX_DATA_clear_free_data(EC_EXTRA_DATA ** ex_data,
|
||||
void *(*dup_func) (void *),
|
||||
void (*free_func) (void *),
|
||||
void (*clear_free_func) (void *))
|
||||
{
|
||||
EC_EXTRA_DATA **p;
|
||||
|
||||
if (ex_data == NULL)
|
||||
return;
|
||||
|
||||
for (p = ex_data; *p != NULL; p = &((*p)->next)) {
|
||||
if ((*p)->dup_func == dup_func &&
|
||||
(*p)->free_func == free_func &&
|
||||
(*p)->clear_free_func == clear_free_func) {
|
||||
EC_EXTRA_DATA *next = (*p)->next;
|
||||
|
||||
(*p)->clear_free_func((*p)->data);
|
||||
free(*p);
|
||||
|
||||
*p = next;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* this has 'package' visibility */
|
||||
void
|
||||
EC_EX_DATA_free_all_data(EC_EXTRA_DATA ** ex_data)
|
||||
{
|
||||
EC_EXTRA_DATA *d;
|
||||
|
||||
if (ex_data == NULL)
|
||||
return;
|
||||
|
||||
d = *ex_data;
|
||||
while (d) {
|
||||
EC_EXTRA_DATA *next = d->next;
|
||||
|
||||
d->free_func(d->data);
|
||||
free(d);
|
||||
|
||||
d = next;
|
||||
}
|
||||
*ex_data = NULL;
|
||||
}
|
||||
|
||||
/* this has 'package' visibility */
|
||||
void
|
||||
EC_EX_DATA_clear_free_all_data(EC_EXTRA_DATA ** ex_data)
|
||||
{
|
||||
EC_EXTRA_DATA *d;
|
||||
|
||||
if (ex_data == NULL)
|
||||
return;
|
||||
|
||||
d = *ex_data;
|
||||
while (d) {
|
||||
EC_EXTRA_DATA *next = d->next;
|
||||
|
||||
d->clear_free_func(d->data);
|
||||
free(d);
|
||||
|
||||
d = next;
|
||||
}
|
||||
*ex_data = NULL;
|
||||
}
|
||||
|
||||
EC_POINT *
|
||||
EC_POINT_new(const EC_GROUP *group)
|
||||
{
|
||||
|
@ -1408,33 +1238,13 @@ EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
|
|||
int
|
||||
EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx_in)
|
||||
{
|
||||
BN_CTX *ctx;
|
||||
int ret = 0;
|
||||
|
||||
if (group->meth->precompute_mult == NULL)
|
||||
return 1;
|
||||
|
||||
if ((ctx = ctx_in) == NULL)
|
||||
ctx = BN_CTX_new();
|
||||
if (ctx == NULL)
|
||||
goto err;
|
||||
|
||||
ret = group->meth->precompute_mult(group, ctx);
|
||||
|
||||
err:
|
||||
if (ctx != ctx_in)
|
||||
BN_CTX_free(ctx);
|
||||
|
||||
return ret;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
EC_GROUP_have_precompute_mult(const EC_GROUP *group)
|
||||
{
|
||||
if (group->meth->have_precompute_mult == NULL)
|
||||
return 0;
|
||||
|
||||
return group->meth->have_precompute_mult(group);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: ec_local.h,v 1.14 2023/06/12 18:17:18 jsing Exp $ */
|
||||
/* $OpenBSD: ec_local.h,v 1.21 2023/06/25 19:22:21 tb Exp $ */
|
||||
/*
|
||||
* Originally written by Bodo Moeller for the OpenSSL project.
|
||||
*/
|
||||
|
@ -145,8 +145,6 @@ struct ec_method_st {
|
|||
int (*mul_double_nonct)(const EC_GROUP *group, EC_POINT *r,
|
||||
const BIGNUM *g_scalar, const BIGNUM *p_scalar,
|
||||
const EC_POINT *point, BN_CTX *);
|
||||
int (*precompute_mult)(EC_GROUP *group, BN_CTX *);
|
||||
int (*have_precompute_mult)(const EC_GROUP *group);
|
||||
|
||||
/*
|
||||
* Internal methods.
|
||||
|
@ -175,14 +173,6 @@ struct ec_method_st {
|
|||
BN_CTX *ctx);
|
||||
} /* EC_METHOD */;
|
||||
|
||||
typedef struct ec_extra_data_st {
|
||||
struct ec_extra_data_st *next;
|
||||
void *data;
|
||||
void *(*dup_func)(void *);
|
||||
void (*free_func)(void *);
|
||||
void (*clear_free_func)(void *);
|
||||
} EC_EXTRA_DATA; /* used in EC_GROUP */
|
||||
|
||||
struct ec_group_st {
|
||||
/*
|
||||
* Methods and members exposed via the public API.
|
||||
|
@ -209,8 +199,6 @@ struct ec_group_st {
|
|||
* if they appear to be generic.
|
||||
*/
|
||||
|
||||
EC_EXTRA_DATA *extra_data;
|
||||
|
||||
/*
|
||||
* Field specification. For GF(p) this is the modulus; for GF(2^m),
|
||||
* this is the irreducible polynomial defining the field.
|
||||
|
@ -264,28 +252,9 @@ struct ec_key_st {
|
|||
int references;
|
||||
int flags;
|
||||
|
||||
EC_EXTRA_DATA *method_data;
|
||||
CRYPTO_EX_DATA ex_data;
|
||||
} /* EC_KEY */;
|
||||
|
||||
/* Basically a 'mixin' for extra data, but available for EC_GROUPs/EC_KEYs only
|
||||
* (with visibility limited to 'package' level for now).
|
||||
* We use the function pointers as index for retrieval; this obviates
|
||||
* global ex_data-style index tables.
|
||||
*/
|
||||
int EC_EX_DATA_set_data(EC_EXTRA_DATA **, void *data,
|
||||
void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
|
||||
void *EC_EX_DATA_get_data(const EC_EXTRA_DATA *,
|
||||
void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
|
||||
void EC_EX_DATA_free_data(EC_EXTRA_DATA **,
|
||||
void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
|
||||
void EC_EX_DATA_clear_free_data(EC_EXTRA_DATA **,
|
||||
void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
|
||||
void EC_EX_DATA_free_all_data(EC_EXTRA_DATA **);
|
||||
void EC_EX_DATA_clear_free_all_data(EC_EXTRA_DATA **);
|
||||
|
||||
int ec_group_simple_order_bits(const EC_GROUP *group);
|
||||
|
||||
struct ec_point_st {
|
||||
const EC_METHOD *meth;
|
||||
|
||||
|
@ -308,9 +277,6 @@ struct ec_point_st {
|
|||
* (ec_lib.c uses these as defaults if group->method->mul is 0) */
|
||||
int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
|
||||
size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *);
|
||||
int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *);
|
||||
int ec_wNAF_have_precompute_mult(const EC_GROUP *group);
|
||||
|
||||
|
||||
/* method functions in ecp_smpl.c */
|
||||
int ec_GFp_simple_group_init(EC_GROUP *);
|
||||
|
@ -355,6 +321,7 @@ int ec_GFp_simple_mul_single_ct(const EC_GROUP *, EC_POINT *r, const BIGNUM *sca
|
|||
int ec_GFp_simple_mul_double_nonct(const EC_GROUP *, EC_POINT *r, const BIGNUM *g_scalar,
|
||||
const BIGNUM *p_scalar, const EC_POINT *point, BN_CTX *);
|
||||
|
||||
int ec_group_simple_order_bits(const EC_GROUP *group);
|
||||
int ec_point_blind_coordinates(const EC_GROUP *group, EC_POINT *p, BN_CTX *ctx);
|
||||
|
||||
/* EC_METHOD definitions */
|
||||
|
@ -395,12 +362,11 @@ int ossl_ecdsa_verify(int type, const unsigned char *dgst, int dgst_len,
|
|||
int ossl_ecdsa_verify_sig(const unsigned char *dgst, int dgst_len,
|
||||
const ECDSA_SIG *sig, EC_KEY *eckey);
|
||||
|
||||
void *EC_KEY_get_key_method_data(EC_KEY *key,
|
||||
void *(*dup_func)(void *), void (*free_func)(void *),
|
||||
void (*clear_free_func)(void *));
|
||||
void *EC_KEY_insert_key_method_data(EC_KEY *key, void *data,
|
||||
void *(*dup_func)(void *), void (*free_func)(void *),
|
||||
void (*clear_free_func)(void *));
|
||||
/*
|
||||
* ECDH Key Derivation Function as defined in ANSI X9.63.
|
||||
*/
|
||||
int ecdh_KDF_X9_63(unsigned char *out, size_t outlen, const unsigned char *Z,
|
||||
size_t Zlen, const unsigned char *sinfo, size_t sinfolen, const EVP_MD *md);
|
||||
|
||||
int EC_POINT_set_Jprojective_coordinates(const EC_GROUP *group, EC_POINT *p,
|
||||
const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *ctx);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: ec_mult.c,v 1.29 2023/04/11 18:58:20 jsing Exp $ */
|
||||
/* $OpenBSD: ec_mult.c,v 1.31 2023/06/24 17:49:44 jsing Exp $ */
|
||||
/*
|
||||
* Originally written by Bodo Moeller and Nils Larsch for the OpenSSL project.
|
||||
*/
|
||||
|
@ -67,7 +67,6 @@
|
|||
|
||||
#include "ec_local.h"
|
||||
|
||||
|
||||
/*
|
||||
* This file implements the wNAF-based interleaving multi-exponentation method
|
||||
* (<URL:http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/moeller.html#multiexp>);
|
||||
|
@ -75,114 +74,6 @@
|
|||
* (<URL:http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/moeller.html#fastexp>).
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
/* structure for precomputed multiples of the generator */
|
||||
typedef struct ec_pre_comp_st {
|
||||
const EC_GROUP *group; /* parent EC_GROUP object */
|
||||
size_t blocksize; /* block size for wNAF splitting */
|
||||
size_t numblocks; /* max. number of blocks for which we have
|
||||
* precomputation */
|
||||
size_t w; /* window size */
|
||||
EC_POINT **points; /* array with pre-calculated multiples of
|
||||
* generator: 'num' pointers to EC_POINT
|
||||
* objects followed by a NULL */
|
||||
size_t num; /* numblocks * 2^(w-1) */
|
||||
int references;
|
||||
} EC_PRE_COMP;
|
||||
|
||||
/* functions to manage EC_PRE_COMP within the EC_GROUP extra_data framework */
|
||||
static void *ec_pre_comp_dup(void *);
|
||||
static void ec_pre_comp_free(void *);
|
||||
static void ec_pre_comp_clear_free(void *);
|
||||
|
||||
static EC_PRE_COMP *
|
||||
ec_pre_comp_new(const EC_GROUP *group)
|
||||
{
|
||||
EC_PRE_COMP *ret = NULL;
|
||||
|
||||
if (!group)
|
||||
return NULL;
|
||||
|
||||
ret = malloc(sizeof(EC_PRE_COMP));
|
||||
if (!ret) {
|
||||
ECerror(ERR_R_MALLOC_FAILURE);
|
||||
return ret;
|
||||
}
|
||||
ret->group = group;
|
||||
ret->blocksize = 8; /* default */
|
||||
ret->numblocks = 0;
|
||||
ret->w = 4; /* default */
|
||||
ret->points = NULL;
|
||||
ret->num = 0;
|
||||
ret->references = 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void *
|
||||
ec_pre_comp_dup(void *src_)
|
||||
{
|
||||
EC_PRE_COMP *src = src_;
|
||||
|
||||
/* no need to actually copy, these objects never change! */
|
||||
|
||||
CRYPTO_add(&src->references, 1, CRYPTO_LOCK_EC_PRE_COMP);
|
||||
|
||||
return src_;
|
||||
}
|
||||
|
||||
static void
|
||||
ec_pre_comp_free(void *pre_)
|
||||
{
|
||||
int i;
|
||||
EC_PRE_COMP *pre = pre_;
|
||||
|
||||
if (!pre)
|
||||
return;
|
||||
|
||||
i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP);
|
||||
if (i > 0)
|
||||
return;
|
||||
|
||||
if (pre->points) {
|
||||
EC_POINT **p;
|
||||
|
||||
for (p = pre->points; *p != NULL; p++)
|
||||
EC_POINT_free(*p);
|
||||
free(pre->points);
|
||||
}
|
||||
free(pre);
|
||||
}
|
||||
|
||||
static void
|
||||
ec_pre_comp_clear_free(void *pre_)
|
||||
{
|
||||
int i;
|
||||
EC_PRE_COMP *pre = pre_;
|
||||
|
||||
if (!pre)
|
||||
return;
|
||||
|
||||
i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP);
|
||||
if (i > 0)
|
||||
return;
|
||||
|
||||
if (pre->points) {
|
||||
EC_POINT **p;
|
||||
|
||||
for (p = pre->points; *p != NULL; p++) {
|
||||
EC_POINT_free(*p);
|
||||
explicit_bzero(p, sizeof *p);
|
||||
}
|
||||
free(pre->points);
|
||||
}
|
||||
freezero(pre, sizeof *pre);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Determine the modified width-(w+1) Non-Adjacent Form (wNAF) of 'scalar'.
|
||||
* This is an array r[] of values that are either zero or odd with an
|
||||
* absolute value less than 2^w satisfying
|
||||
|
@ -338,8 +229,7 @@ ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
|
|||
const EC_POINT *generator = NULL;
|
||||
EC_POINT *tmp = NULL;
|
||||
size_t totalnum;
|
||||
size_t blocksize = 0, numblocks = 0; /* for wNAF splitting */
|
||||
size_t pre_points_per_block = 0;
|
||||
size_t numblocks = 0; /* for wNAF splitting */
|
||||
size_t i, j;
|
||||
int k;
|
||||
int r_is_inverted = 0;
|
||||
|
@ -354,7 +244,6 @@ ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
|
|||
EC_POINT **v;
|
||||
EC_POINT ***val_sub = NULL; /* pointers to sub-arrays of 'val' or
|
||||
* 'pre_comp->points' */
|
||||
const EC_PRE_COMP *pre_comp = NULL;
|
||||
int num_scalar = 0; /* flag: will be set to 1 if 'scalar' must be
|
||||
* treated like other scalars, i.e.
|
||||
* precomputation is not available */
|
||||
|
@ -380,42 +269,10 @@ ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
|
|||
ECerror(EC_R_UNDEFINED_GENERATOR);
|
||||
goto err;
|
||||
}
|
||||
/* look if we can use precomputed multiples of generator */
|
||||
|
||||
pre_comp = EC_EX_DATA_get_data(group->extra_data, ec_pre_comp_dup, ec_pre_comp_free, ec_pre_comp_clear_free);
|
||||
|
||||
if (pre_comp && pre_comp->numblocks &&
|
||||
(EC_POINT_cmp(group, generator, pre_comp->points[0], ctx) == 0)) {
|
||||
blocksize = pre_comp->blocksize;
|
||||
|
||||
/*
|
||||
* determine maximum number of blocks that wNAF
|
||||
* splitting may yield (NB: maximum wNAF length is
|
||||
* bit length plus one)
|
||||
*/
|
||||
numblocks = (BN_num_bits(scalar) / blocksize) + 1;
|
||||
|
||||
/*
|
||||
* we cannot use more blocks than we have
|
||||
* precomputation for
|
||||
*/
|
||||
if (numblocks > pre_comp->numblocks)
|
||||
numblocks = pre_comp->numblocks;
|
||||
|
||||
pre_points_per_block = (size_t) 1 << (pre_comp->w - 1);
|
||||
|
||||
/* check that pre_comp looks sane */
|
||||
if (pre_comp->num != (pre_comp->numblocks * pre_points_per_block)) {
|
||||
ECerror(ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
} else {
|
||||
/* can't use precomputation */
|
||||
pre_comp = NULL;
|
||||
numblocks = 1;
|
||||
num_scalar = 1; /* treat 'scalar' like 'num'-th
|
||||
* element of 'scalars' */
|
||||
}
|
||||
numblocks = 1;
|
||||
num_scalar = 1; /* treat 'scalar' like 'num'-th
|
||||
* element of 'scalars' */
|
||||
}
|
||||
totalnum = num + numblocks;
|
||||
|
||||
|
@ -457,111 +314,9 @@ ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
|
|||
if (numblocks) {
|
||||
/* we go here iff scalar != NULL */
|
||||
|
||||
if (pre_comp == NULL) {
|
||||
if (num_scalar != 1) {
|
||||
ECerror(ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
/* we have already generated a wNAF for 'scalar' */
|
||||
} else {
|
||||
size_t tmp_len = 0;
|
||||
|
||||
if (num_scalar != 0) {
|
||||
ECerror(ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
/*
|
||||
* use the window size for which we have
|
||||
* precomputation
|
||||
*/
|
||||
wsize[num] = pre_comp->w;
|
||||
tmp_wNAF = compute_wNAF(scalar, wsize[num], &tmp_len);
|
||||
if (tmp_wNAF == NULL)
|
||||
goto err;
|
||||
|
||||
if (tmp_len <= max_len) {
|
||||
/*
|
||||
* One of the other wNAFs is at least as long
|
||||
* as the wNAF belonging to the generator, so
|
||||
* wNAF splitting will not buy us anything.
|
||||
*/
|
||||
|
||||
numblocks = 1;
|
||||
totalnum = num + 1; /* don't use wNAF
|
||||
* splitting */
|
||||
wNAF[num] = tmp_wNAF;
|
||||
tmp_wNAF = NULL;
|
||||
wNAF[num + 1] = NULL;
|
||||
wNAF_len[num] = tmp_len;
|
||||
if (tmp_len > max_len)
|
||||
max_len = tmp_len;
|
||||
/*
|
||||
* pre_comp->points starts with the points
|
||||
* that we need here:
|
||||
*/
|
||||
val_sub[num] = pre_comp->points;
|
||||
} else {
|
||||
/*
|
||||
* don't include tmp_wNAF directly into wNAF
|
||||
* array - use wNAF splitting and include the
|
||||
* blocks
|
||||
*/
|
||||
|
||||
signed char *pp;
|
||||
EC_POINT **tmp_points;
|
||||
|
||||
if (tmp_len < numblocks * blocksize) {
|
||||
/*
|
||||
* possibly we can do with fewer
|
||||
* blocks than estimated
|
||||
*/
|
||||
numblocks = (tmp_len + blocksize - 1) / blocksize;
|
||||
if (numblocks > pre_comp->numblocks) {
|
||||
ECerror(ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
totalnum = num + numblocks;
|
||||
}
|
||||
/* split wNAF in 'numblocks' parts */
|
||||
pp = tmp_wNAF;
|
||||
tmp_points = pre_comp->points;
|
||||
|
||||
for (i = num; i < totalnum; i++) {
|
||||
if (i < totalnum - 1) {
|
||||
wNAF_len[i] = blocksize;
|
||||
if (tmp_len < blocksize) {
|
||||
ECerror(ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
tmp_len -= blocksize;
|
||||
} else
|
||||
/*
|
||||
* last block gets whatever
|
||||
* is left (this could be
|
||||
* more or less than
|
||||
* 'blocksize'!)
|
||||
*/
|
||||
wNAF_len[i] = tmp_len;
|
||||
|
||||
wNAF[i + 1] = NULL;
|
||||
wNAF[i] = malloc(wNAF_len[i]);
|
||||
if (wNAF[i] == NULL) {
|
||||
ECerror(ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
memcpy(wNAF[i], pp, wNAF_len[i]);
|
||||
if (wNAF_len[i] > max_len)
|
||||
max_len = wNAF_len[i];
|
||||
|
||||
if (*tmp_points == NULL) {
|
||||
ECerror(ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
val_sub[i] = tmp_points;
|
||||
tmp_points += pre_points_per_block;
|
||||
pp += blocksize;
|
||||
}
|
||||
}
|
||||
if (num_scalar != 1) {
|
||||
ECerror(ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
/*
|
||||
|
@ -693,181 +448,3 @@ ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
|
|||
free(val_sub);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* ec_wNAF_precompute_mult()
|
||||
* creates an EC_PRE_COMP object with preprecomputed multiples of the generator
|
||||
* for use with wNAF splitting as implemented in ec_wNAF_mul().
|
||||
*
|
||||
* 'pre_comp->points' is an array of multiples of the generator
|
||||
* of the following form:
|
||||
* points[0] = generator;
|
||||
* points[1] = 3 * generator;
|
||||
* ...
|
||||
* points[2^(w-1)-1] = (2^(w-1)-1) * generator;
|
||||
* points[2^(w-1)] = 2^blocksize * generator;
|
||||
* points[2^(w-1)+1] = 3 * 2^blocksize * generator;
|
||||
* ...
|
||||
* points[2^(w-1)*(numblocks-1)-1] = (2^(w-1)) * 2^(blocksize*(numblocks-2)) * generator
|
||||
* points[2^(w-1)*(numblocks-1)] = 2^(blocksize*(numblocks-1)) * generator
|
||||
* ...
|
||||
* points[2^(w-1)*numblocks-1] = (2^(w-1)) * 2^(blocksize*(numblocks-1)) * generator
|
||||
* points[2^(w-1)*numblocks] = NULL
|
||||
*/
|
||||
int
|
||||
ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
|
||||
{
|
||||
const EC_POINT *generator;
|
||||
EC_POINT *tmp_point = NULL, *base = NULL, **var;
|
||||
BIGNUM *order;
|
||||
size_t i, bits, w, pre_points_per_block, blocksize, numblocks,
|
||||
num;
|
||||
EC_POINT **points = NULL;
|
||||
EC_PRE_COMP *pre_comp;
|
||||
int ret = 0;
|
||||
|
||||
/* if there is an old EC_PRE_COMP object, throw it away */
|
||||
EC_EX_DATA_free_data(&group->extra_data, ec_pre_comp_dup, ec_pre_comp_free, ec_pre_comp_clear_free);
|
||||
|
||||
if ((pre_comp = ec_pre_comp_new(group)) == NULL)
|
||||
return 0;
|
||||
|
||||
generator = EC_GROUP_get0_generator(group);
|
||||
if (generator == NULL) {
|
||||
ECerror(EC_R_UNDEFINED_GENERATOR);
|
||||
goto err;
|
||||
}
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
|
||||
if ((order = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
|
||||
if (!EC_GROUP_get_order(group, order, ctx))
|
||||
goto err;
|
||||
if (BN_is_zero(order)) {
|
||||
ECerror(EC_R_UNKNOWN_ORDER);
|
||||
goto err;
|
||||
}
|
||||
bits = BN_num_bits(order);
|
||||
/*
|
||||
* The following parameters mean we precompute (approximately) one
|
||||
* point per bit.
|
||||
*
|
||||
* TBD: The combination 8, 4 is perfect for 160 bits; for other bit
|
||||
* lengths, other parameter combinations might provide better
|
||||
* efficiency.
|
||||
*/
|
||||
blocksize = 8;
|
||||
w = 4;
|
||||
if (EC_window_bits_for_scalar_size(bits) > w) {
|
||||
/* let's not make the window too small ... */
|
||||
w = EC_window_bits_for_scalar_size(bits);
|
||||
}
|
||||
numblocks = (bits + blocksize - 1) / blocksize; /* max. number of blocks
|
||||
* to use for wNAF
|
||||
* splitting */
|
||||
|
||||
pre_points_per_block = (size_t) 1 << (w - 1);
|
||||
num = pre_points_per_block * numblocks; /* number of points to
|
||||
* compute and store */
|
||||
|
||||
points = reallocarray(NULL, (num + 1), sizeof(EC_POINT *));
|
||||
if (!points) {
|
||||
ECerror(ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
var = points;
|
||||
var[num] = NULL; /* pivot */
|
||||
for (i = 0; i < num; i++) {
|
||||
if ((var[i] = EC_POINT_new(group)) == NULL) {
|
||||
ECerror(ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(tmp_point = EC_POINT_new(group)) || !(base = EC_POINT_new(group))) {
|
||||
ECerror(ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
if (!EC_POINT_copy(base, generator))
|
||||
goto err;
|
||||
|
||||
/* do the precomputation */
|
||||
for (i = 0; i < numblocks; i++) {
|
||||
size_t j;
|
||||
|
||||
if (!EC_POINT_dbl(group, tmp_point, base, ctx))
|
||||
goto err;
|
||||
|
||||
if (!EC_POINT_copy(*var++, base))
|
||||
goto err;
|
||||
|
||||
for (j = 1; j < pre_points_per_block; j++, var++) {
|
||||
/* calculate odd multiples of the current base point */
|
||||
if (!EC_POINT_add(group, *var, tmp_point, *(var - 1), ctx))
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (i < numblocks - 1) {
|
||||
/*
|
||||
* get the next base (multiply current one by
|
||||
* 2^blocksize)
|
||||
*/
|
||||
size_t k;
|
||||
|
||||
if (blocksize <= 2) {
|
||||
ECerror(ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
if (!EC_POINT_dbl(group, base, tmp_point, ctx))
|
||||
goto err;
|
||||
for (k = 2; k < blocksize; k++) {
|
||||
if (!EC_POINT_dbl(group, base, base, ctx))
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!EC_POINTs_make_affine(group, num, points, ctx))
|
||||
goto err;
|
||||
|
||||
pre_comp->group = group;
|
||||
pre_comp->blocksize = blocksize;
|
||||
pre_comp->numblocks = numblocks;
|
||||
pre_comp->w = w;
|
||||
pre_comp->points = points;
|
||||
points = NULL;
|
||||
pre_comp->num = num;
|
||||
|
||||
if (!EC_EX_DATA_set_data(&group->extra_data, pre_comp,
|
||||
ec_pre_comp_dup, ec_pre_comp_free, ec_pre_comp_clear_free))
|
||||
goto err;
|
||||
pre_comp = NULL;
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
ec_pre_comp_free(pre_comp);
|
||||
if (points) {
|
||||
EC_POINT **p;
|
||||
|
||||
for (p = points; *p != NULL; p++)
|
||||
EC_POINT_free(*p);
|
||||
free(points);
|
||||
}
|
||||
EC_POINT_free(tmp_point);
|
||||
EC_POINT_free(base);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ec_wNAF_have_precompute_mult(const EC_GROUP *group)
|
||||
{
|
||||
if (EC_EX_DATA_get_data(group->extra_data, ec_pre_comp_dup, ec_pre_comp_free, ec_pre_comp_clear_free) != NULL)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: ec_pmeth.c,v 1.17 2023/04/25 15:48:48 tb Exp $ */
|
||||
/* $OpenBSD: ec_pmeth.c,v 1.18 2023/06/25 19:26:04 tb Exp $ */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 2006.
|
||||
*/
|
||||
|
@ -68,7 +68,6 @@
|
|||
|
||||
#include "bn_local.h"
|
||||
#include "ec_local.h"
|
||||
#include "ech_local.h"
|
||||
#include "evp_local.h"
|
||||
|
||||
/* EC pkey context structure */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue