diff options
author | Rich Salz <rsalz@akamai.com> | 2016-01-05 13:06:03 -0500 |
---|---|---|
committer | Rich Salz <rsalz@openssl.org> | 2016-01-13 14:32:59 -0500 |
commit | 3aef36ffef89849348049296892327e6fdf9d705 (patch) | |
tree | a8a89aedef46029fcd855e4d9ad1d19c279b8483 | |
parent | 8ffcca65861520fb95e4603b2cb80b3028e56baa (diff) |
Add CRYPTO_EX_DATA; remove EC_EXTRA_DATA
Add CRYPTO_EX_DATA add EndC_KEY_[gs]et_method, From Roumen Petrov.
Had to add various exdata calls to init/copy/free the exdata.
Had to remove const from some EC functions because exdata isn't
const-correct. :(
Also remove EC_EXTRA_DATA and use a union to hold the possible
pre-computed values and an enum to tell which value is in the
union. (Rich Salz)
Reviewed-by: Dr. Stephen Henson <steve@openssl.org>
-rw-r--r-- | crypto/ec/ec_key.c | 61 | ||||
-rw-r--r-- | crypto/ec/ec_kmeth.c | 34 | ||||
-rw-r--r-- | crypto/ec/ec_lcl.h | 70 | ||||
-rw-r--r-- | crypto/ec/ec_lib.c | 223 | ||||
-rw-r--r-- | crypto/ec/ec_mult.c | 91 | ||||
-rw-r--r-- | crypto/ec/ecp_nistp224.c | 71 | ||||
-rw-r--r-- | crypto/ec/ecp_nistp256.c | 70 | ||||
-rw-r--r-- | crypto/ec/ecp_nistp521.c | 69 | ||||
-rw-r--r-- | crypto/ec/ecp_nistz256.c | 89 | ||||
-rw-r--r-- | doc/crypto/CRYPTO_get_ex_new_index.pod | 3 | ||||
-rw-r--r-- | doc/crypto/EC_KEY_new.pod | 57 | ||||
-rw-r--r-- | doc/crypto/ec.pod | 7 | ||||
-rw-r--r-- | include/openssl/crypto.h | 17 | ||||
-rw-r--r-- | include/openssl/ec.h | 29 | ||||
-rwxr-xr-x | util/libeay.num | 14 |
15 files changed, 283 insertions, 622 deletions
diff --git a/crypto/ec/ec_key.c b/crypto/ec/ec_key.c index 82d13eb951..f236e3c0da 100644 --- a/crypto/ec/ec_key.c +++ b/crypto/ec/ec_key.c @@ -120,19 +120,16 @@ void EC_KEY_free(EC_KEY *r) ENGINE_finish(r->engine); #endif + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_EC_KEY, r, &r->ex_data); EC_GROUP_free(r->group); EC_POINT_free(r->pub_key); BN_clear_free(r->priv_key); - EC_EX_DATA_free_all_data(&r->method_data); - OPENSSL_clear_free((void *)r, sizeof(EC_KEY)); } -EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src) +EC_KEY *EC_KEY_copy(EC_KEY *dest, EC_KEY *src) { - EC_EXTRA_DATA *d; - if (dest == NULL || src == NULL) { ECerr(EC_F_EC_KEY_COPY, ERR_R_PASSED_NULL_PARAMETER); return NULL; @@ -176,25 +173,15 @@ EC_KEY *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 NULL; - } /* copy the rest */ dest->enc_flag = src->enc_flag; dest->conv_form = src->conv_form; dest->version = src->version; dest->flags = src->flags; + if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_EC_KEY, + &dest->ex_data, &src->ex_data)) + return NULL; if (src->meth != dest->meth) { #ifndef OPENSSL_NO_ENGINE @@ -211,9 +198,10 @@ EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src) return dest; } -EC_KEY *EC_KEY_dup(const EC_KEY *ec_key) +EC_KEY *EC_KEY_dup(EC_KEY *ec_key) { EC_KEY *ret = EC_KEY_new_method(ec_key->engine); + if (ret == NULL) return NULL; if (EC_KEY_copy(ret, ec_key) == NULL) { @@ -513,41 +501,6 @@ void 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) { if (key->group != NULL) diff --git a/crypto/ec/ec_kmeth.c b/crypto/ec/ec_kmeth.c index d6c2811fc8..5d77cbea36 100644 --- a/crypto/ec/ec_kmeth.c +++ b/crypto/ec/ec_kmeth.c @@ -93,6 +93,31 @@ void EC_KEY_set_default_method(const EC_KEY_METHOD *meth) default_ec_key_meth = meth; } +const EC_KEY_METHOD *EC_KEY_get_method(const EC_KEY *key) +{ + return key->meth; +} + +int EC_KEY_set_method(EC_KEY *key, const EC_KEY_METHOD *meth) +{ + void (*finish)(EC_KEY *key) = key->meth->finish; + + if (finish != NULL) + finish(key); + +#ifndef OPENSSL_NO_ENGINE + if (key->engine != NULL) { + ENGINE_finish(key->engine); + key->engine = NULL; + } +#endif + + key->meth = meth; + if (meth->init != NULL) + return meth->init(key); + return 1; +} + EC_KEY *EC_KEY_new_method(ENGINE *engine) { EC_KEY *ret = OPENSSL_zalloc(sizeof(*ret)); @@ -101,6 +126,11 @@ EC_KEY *EC_KEY_new_method(ENGINE *engine) ECerr(EC_F_EC_KEY_NEW_METHOD, ERR_R_MALLOC_FAILURE); return (NULL); } + if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_EC_KEY, ret, &ret->ex_data)) { + OPENSSL_free(ret); + return NULL; + } + ret->meth = EC_KEY_get_default_method(); #ifndef OPENSSL_NO_ENGINE if (engine != NULL) { @@ -146,8 +176,8 @@ int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key, EC_KEY_METHOD *EC_KEY_METHOD_new(const EC_KEY_METHOD *meth) { - EC_KEY_METHOD *ret; - ret = OPENSSL_zalloc(sizeof(*meth)); + EC_KEY_METHOD *ret = OPENSSL_zalloc(sizeof(*meth)); + if (ret == NULL) return NULL; if (meth != NULL) diff --git a/crypto/ec/ec_lcl.h b/crypto/ec/ec_lcl.h index ebfaae3a15..036f9eed20 100644 --- a/crypto/ec/ec_lcl.h +++ b/crypto/ec/ec_lcl.h @@ -198,13 +198,14 @@ struct ec_method_st { int (*field_set_to_one) (const EC_GROUP *, BIGNUM *r, BN_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 */ +/* + * Types and functions to manipulate pre-computed values. + */ +typedef struct nistp224_pre_comp_st NISTP224_PRE_COMP; +typedef struct nistp256_pre_comp_st NISTP256_PRE_COMP; +typedef struct nistp512_pre_comp_st NISTP521_PRE_COMP; +typedef struct nistz256_pre_comp_st NISTZ256_PRE_COMP; +typedef struct ec_pre_comp_st EC_PRE_COMP; struct ec_group_st { const EC_METHOD *meth; @@ -216,7 +217,6 @@ struct ec_group_st { unsigned char *seed; /* optional seed for parameters (appears in * ASN1) */ size_t seed_len; - EC_EXTRA_DATA *extra_data; /* linked list */ /* * The following members are handled by the method functions, even if * they appear generic @@ -254,8 +254,26 @@ struct ec_group_st { BN_CTX *); /* data for ECDSA inverse */ BN_MONT_CTX *mont_data; + + /* precomputed values for speed. */ + enum { + pct_none, + pct_nistp224, pct_nistp256, pct_nistp521, pct_nistz256, + pct_ec } pre_comp_type; + union { + NISTP224_PRE_COMP *nistp224; + NISTP256_PRE_COMP *nistp256; + NISTP521_PRE_COMP *nistp521; + NISTZ256_PRE_COMP *nistz256; + EC_PRE_COMP *ec; + } pre_comp; } /* EC_GROUP */ ; +#define SETPRECOMP(g, type, pre) \ + g->pre_comp_type = pct_##type, g->pre_comp.type = pre +#define HAVEPRECOMP(g, type) \ + g->pre_comp_type == pct_##type && g->pre_comp.type != NULL + struct ec_key_st { const EC_KEY_METHOD *meth; ENGINE *engine; @@ -267,31 +285,9 @@ struct ec_key_st { point_conversion_form_t conv_form; 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 **); - struct ec_point_st { const EC_METHOD *meth; /* @@ -306,6 +302,18 @@ struct ec_point_st { * special case */ } /* EC_POINT */ ; +NISTP224_PRE_COMP *EC_nistp224_pre_comp_dup(NISTP224_PRE_COMP *); +NISTP256_PRE_COMP *EC_nistp256_pre_comp_dup(NISTP256_PRE_COMP *); +NISTP521_PRE_COMP *EC_nistp521_pre_comp_dup(NISTP521_PRE_COMP *); +NISTZ256_PRE_COMP *EC_nistz256_pre_comp_dup(NISTZ256_PRE_COMP *); +NISTP256_PRE_COMP *EC_nistp256_pre_comp_dup(NISTP256_PRE_COMP *); +EC_PRE_COMP *EC_ec_pre_comp_dup(EC_PRE_COMP *); +void EC_nistp224_pre_comp_free(NISTP224_PRE_COMP *); +void EC_nistp256_pre_comp_free(NISTP256_PRE_COMP *); +void EC_nistp521_pre_comp_free(NISTP521_PRE_COMP *); +void EC_nistz256_pre_comp_free(NISTZ256_PRE_COMP *); +void EC_ec_pre_comp_free(EC_PRE_COMP *); + /* * method functions in ec_mult.c (ec_lib.c uses these as defaults if * group->method->mul is 0) diff --git a/crypto/ec/ec_lib.c b/crypto/ec/ec_lib.c index 7cb4759f65..d850b54ef4 100644 --- a/crypto/ec/ec_lib.c +++ b/crypto/ec/ec_lib.c @@ -109,6 +109,32 @@ EC_GROUP *EC_GROUP_new(const EC_METHOD *meth) return NULL; } +static void ec_group_free_precomp(EC_GROUP *group) +{ + switch (group->pre_comp_type) { + default: + break; + case pct_nistz256: + EC_nistz256_pre_comp_free(group->pre_comp.nistz256); + break; +#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 + case pct_nistp224: + EC_nistp224_pre_comp_free(group->pre_comp.nistp224); + break; + case pct_nistp256: + EC_nistp256_pre_comp_free(group->pre_comp.nistp256); + break; + case pct_nistp521: + EC_nistp521_pre_comp_free(group->pre_comp.nistp521); + break; +#endif + case pct_ec: + EC_ec_pre_comp_free(group->pre_comp.ec); + break; + } + group->pre_comp.ec = NULL; +} + void EC_GROUP_free(EC_GROUP *group) { if (!group) @@ -117,7 +143,7 @@ void EC_GROUP_free(EC_GROUP *group) if (group->meth->group_finish != 0) group->meth->group_finish(group); - EC_EX_DATA_free_all_data(&group->extra_data); + ec_group_free_precomp(group); BN_MONT_CTX_free(group->mont_data); EC_POINT_free(group->generator); BN_free(group->order); @@ -136,10 +162,8 @@ void EC_GROUP_clear_free(EC_GROUP *group) else if (group->meth->group_finish != 0) group->meth->group_finish(group); - EC_EX_DATA_clear_free_all_data(&group->extra_data); - + ec_group_free_precomp(group); BN_MONT_CTX_free(group->mont_data); - EC_POINT_clear_free(group->generator); BN_clear_free(group->order); BN_clear_free(group->cofactor); @@ -149,8 +173,6 @@ void 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 == 0) { ECerr(EC_F_EC_GROUP_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; @@ -162,17 +184,29 @@ int 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; + /* Copy precomputed */ + dest->pre_comp_type = src->pre_comp_type; + switch (src->pre_comp_type) { + default: + dest->pre_comp.ec = NULL; + break; + case pct_nistz256: + dest->pre_comp.nistz256 = EC_nistz256_pre_comp_dup(src->pre_comp.nistz256); + break; +#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 + case pct_nistp224: + dest->pre_comp.nistp224 = EC_nistp224_pre_comp_dup(src->pre_comp.nistp224); + break; + case pct_nistp256: + dest->pre_comp.nistp256 = EC_nistp256_pre_comp_dup(src->pre_comp.nistp256); + break; + case pct_nistp521: + dest->pre_comp.nistp521 = EC_nistp521_pre_comp_dup(src->pre_comp.nistp521); + break; +#endif + case pct_ec: + dest->pre_comp.ec = EC_ec_pre_comp_dup(src->pre_comp.ec); + break; } if (src->mont_data != NULL) { @@ -518,151 +552,6 @@ int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx) return r; } -/* 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) { - ECerr(EC_F_EC_EX_DATA_SET_DATA, EC_R_SLOT_FULL); - return 0; - } - } - - if (data == NULL) - /* no explicit entry needed */ - return 1; - - d = OPENSSL_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); - OPENSSL_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); - OPENSSL_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); - OPENSSL_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); - OPENSSL_free(d); - - d = next; - } - *ex_data = NULL; -} - /* functions for EC_POINT objects */ EC_POINT *EC_POINT_new(const EC_GROUP *group) @@ -1091,3 +980,13 @@ int ec_precompute_mont_data(EC_GROUP *group) BN_CTX_free(ctx); return ret; } + +int EC_KEY_set_ex_data(EC_KEY *key, int idx, void *arg) +{ + return CRYPTO_set_ex_data(&key->ex_data, idx, arg); +} + +void *EC_KEY_get_ex_data(const EC_KEY *key, int idx) +{ + return CRYPTO_get_ex_data(&key->ex_data, idx); +} diff --git a/crypto/ec/ec_mult.c b/crypto/ec/ec_mult.c index 7e29397cba..8a4e23d649 100644 --- a/crypto/ec/ec_mult.c +++ b/crypto/ec/ec_mult.c @@ -75,7 +75,7 @@ */ /* structure for precomputed multiples of the generator */ -typedef struct ec_pre_comp_st { +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 @@ -86,12 +86,7 @@ typedef struct ec_pre_comp_st { * 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) { @@ -112,63 +107,29 @@ static EC_PRE_COMP *ec_pre_comp_new(const EC_GROUP *group) return ret; } -static void *ec_pre_comp_dup(void *src_) +EC_PRE_COMP *EC_ec_pre_comp_dup(EC_PRE_COMP *pre) { - 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_; + if (pre != NULL) + CRYPTO_add(&pre->references, 1, CRYPTO_LOCK_EC_PRE_COMP); + return pre; } -static void ec_pre_comp_free(void *pre_) +void EC_ec_pre_comp_free(EC_PRE_COMP *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) + if (pre == NULL + || CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP) > 0) return; - if (pre->points) { - EC_POINT **p; + if (pre->points != NULL) { + EC_POINT **pts; - for (p = pre->points; *p != NULL; p++) - EC_POINT_free(*p); + for (pts = pre->points; *pts != NULL; pts++) + EC_POINT_free(*pts); OPENSSL_free(pre->points); } OPENSSL_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_clear_free(*p); - OPENSSL_cleanse(p, sizeof(*p)); - } - OPENSSL_free(pre->points); - } - OPENSSL_clear_free(pre, sizeof(*pre)); -} - /* * TODO: table should be optimised for the wNAF-based implementation, * sometimes smaller windows will give better performance (thus the @@ -250,10 +211,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, /* 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); - + pre_comp = group->pre_comp.ec; if (pre_comp && pre_comp->numblocks && (EC_POINT_cmp(group, generator, pre_comp->points[0], ctx) == 0)) { @@ -604,9 +562,7 @@ int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx) 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); - + EC_ec_pre_comp_free(group->pre_comp.ec); if ((pre_comp = ec_pre_comp_new(group)) == NULL) return 0; @@ -728,19 +684,15 @@ int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx) 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; + SETPRECOMP(group, ec, pre_comp); pre_comp = NULL; - ret = 1; + err: if (ctx != NULL) BN_CTX_end(ctx); BN_CTX_free(new_ctx); - ec_pre_comp_free(pre_comp); + EC_ec_pre_comp_free(pre_comp); if (points) { EC_POINT **p; @@ -755,10 +707,5 @@ int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx) 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; + return HAVEPRECOMP(group, ec); } diff --git a/crypto/ec/ecp_nistp224.c b/crypto/ec/ecp_nistp224.c index 8b1deaae7b..c2677a85d5 100644 --- a/crypto/ec/ecp_nistp224.c +++ b/crypto/ec/ecp_nistp224.c @@ -227,10 +227,10 @@ static const felem gmul[2][16][3] = { }; /* Precomputation for the group generator. */ -typedef struct { +struct nistp224_pre_comp_st { felem g_pre_comp[2][16][3]; int references; -} NISTP224_PRE_COMP; +}; const EC_METHOD *EC_GFp_nistp224_method(void) { @@ -1209,44 +1209,19 @@ static NISTP224_PRE_COMP *nistp224_pre_comp_new() return ret; } -static void *nistp224_pre_comp_dup(void *src_) +NISTP224_PRE_COMP *EC_nistp224_pre_comp_dup(NISTP224_PRE_COMP *p) { - NISTP224_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_; + if (p != NULL) + CRYPTO_add(&p->references, 1, CRYPTO_LOCK_EC_PRE_COMP); + return p; } -static void nistp224_pre_comp_free(void *pre_) +void EC_nistp224_pre_comp_free(NISTP224_PRE_COMP *p) { - int i; - NISTP224_PRE_COMP *pre = pre_; - - if (!pre) - return; - - i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP); - if (i > 0) + if (p == NULL + || CRYPTO_add(&p->references, -1, CRYPTO_LOCK_EC_PRE_COMP) > 0) return; - - OPENSSL_free(pre); -} - -static void nistp224_pre_comp_clear_free(void *pre_) -{ - int i; - NISTP224_PRE_COMP *pre = pre_; - - if (!pre) - return; - - i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP); - if (i > 0) - return; - - OPENSSL_clear_free(pre, sizeof(*pre)); + OPENSSL_free(p); } /******************************************************************************/ @@ -1413,10 +1388,7 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r, goto err; if (scalar != NULL) { - pre = EC_EX_DATA_get_data(group->extra_data, - nistp224_pre_comp_dup, - nistp224_pre_comp_free, - nistp224_pre_comp_clear_free); + pre = group->pre_comp.nistp224; if (pre) /* we have precomputation, try to use it */ g_pre_comp = (const felem(*)[16][3])pre->g_pre_comp; @@ -1587,9 +1559,7 @@ int ec_GFp_nistp224_precompute_mult(EC_GROUP *group, BN_CTX *ctx) felem tmp_felems[32]; /* throw away old precomputation */ - EC_EX_DATA_free_data(&group->extra_data, nistp224_pre_comp_dup, - nistp224_pre_comp_free, - nistp224_pre_comp_clear_free); + EC_nistp224_pre_comp_free(group->pre_comp.nistp224); if (ctx == NULL) if ((ctx = new_ctx = BN_CTX_new()) == NULL) return 0; @@ -1692,29 +1662,20 @@ int ec_GFp_nistp224_precompute_mult(EC_GROUP *group, BN_CTX *ctx) } make_points_affine(31, &(pre->g_pre_comp[0][1]), tmp_felems); - if (!EC_EX_DATA_set_data(&group->extra_data, pre, nistp224_pre_comp_dup, - nistp224_pre_comp_free, - nistp224_pre_comp_clear_free)) - goto err; - ret = 1; + SETPRECOMP(group, nistp224, pre); pre = NULL; + ret = 1; err: BN_CTX_end(ctx); EC_POINT_free(generator); BN_CTX_free(new_ctx); - nistp224_pre_comp_free(pre); + EC_nistp224_pre_comp_free(pre); return ret; } int ec_GFp_nistp224_have_precompute_mult(const EC_GROUP *group) { - if (EC_EX_DATA_get_data(group->extra_data, nistp224_pre_comp_dup, - nistp224_pre_comp_free, - nistp224_pre_comp_clear_free) - != NULL) - return 1; - else - return 0; + return HAVEPRECOMP(group, nistp224); } #else diff --git a/crypto/ec/ecp_nistp256.c b/crypto/ec/ecp_nistp256.c index 48ed2c452e..26c1693778 100644 --- a/crypto/ec/ecp_nistp256.c +++ b/crypto/ec/ecp_nistp256.c @@ -1756,10 +1756,10 @@ static void batch_mul(felem x_out, felem y_out, felem z_out, } /* Precomputation for the group generator. */ -typedef struct { +struct nistp256_pre_comp_st { smallfelem g_pre_comp[2][16][3]; int references; -} NISTP256_PRE_COMP; +}; const EC_METHOD *EC_GFp_nistp256_method(void) { @@ -1826,46 +1826,21 @@ static NISTP256_PRE_COMP *nistp256_pre_comp_new() return ret; } -static void *nistp256_pre_comp_dup(void *src_) +NISTP256_PRE_COMP *EC_nistp256_pre_comp_dup(NISTP256_PRE_COMP *p) { - NISTP256_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_; + if (p != NULL) + CRYPTO_add(&p->references, 1, CRYPTO_LOCK_EC_PRE_COMP); + return p; } -static void nistp256_pre_comp_free(void *pre_) +void EC_nistp256_pre_comp_free(NISTP256_PRE_COMP *pre) { - int i; - NISTP256_PRE_COMP *pre = pre_; - - if (!pre) - return; - - i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP); - if (i > 0) + if (pre == NULL + || CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP) > 0) return; - OPENSSL_free(pre); } -static void nistp256_pre_comp_clear_free(void *pre_) -{ - int i; - NISTP256_PRE_COMP *pre = pre_; - - if (!pre) - return; - - i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP); - if (i > 0) - return; - - OPENSSL_clear_free(pre, sizeof(*pre)); -} - /******************************************************************************/ /* * OPENSSL EC_METHOD FUNCTIONS @@ -2031,10 +2006,7 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r, goto err; if (scalar != NULL) { - pre = EC_EX_DATA_get_data(group->extra_data, - nistp256_pre_comp_dup, - nistp256_pre_comp_free, - nistp256_pre_comp_clear_free); + pre = group->pre_comp.nistp256; if (pre) /* we have precomputation, try to use it */ g_pre_comp = (const smallfelem(*)[16][3])pre->g_pre_comp; @@ -2212,9 +2184,7 @@ int ec_GFp_nistp256_precompute_mult(EC_GROUP *group, BN_CTX *ctx) felem x_tmp, y_tmp, z_tmp; /* throw away old precomputation */ - EC_EX_DATA_free_data(&group->extra_data, nistp256_pre_comp_dup, - nistp256_pre_comp_free, - nistp256_pre_comp_clear_free); + EC_nistp256_pre_comp_free(group->pre_comp.nistp256); if (ctx == NULL) if ((ctx = new_ctx = BN_CTX_new()) == NULL) return 0; @@ -2326,29 +2296,21 @@ int ec_GFp_nistp256_precompute_mult(EC_GROUP *group, BN_CTX *ctx) } make_points_affine(31, &(pre->g_pre_comp[0][1]), tmp_smallfelems); - if (!EC_EX_DATA_set_data(&group->extra_data, pre, nistp256_pre_comp_dup, - nistp256_pre_comp_free, - nistp256_pre_comp_clear_free)) - goto err; - ret = 1; + SETPRECOMP(group, nistp256, pre); pre = NULL; + ret = 1; + err: BN_CTX_end(ctx); EC_POINT_free(generator); BN_CTX_free(new_ctx); - nistp256_pre_comp_free(pre); + EC_nistp256_pre_comp_free(pre); return ret; } int ec_GFp |