summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRich Salz <rsalz@akamai.com>2016-01-05 13:06:03 -0500
committerRich Salz <rsalz@openssl.org>2016-01-13 14:32:59 -0500
commit3aef36ffef89849348049296892327e6fdf9d705 (patch)
treea8a89aedef46029fcd855e4d9ad1d19c279b8483
parent8ffcca65861520fb95e4603b2cb80b3028e56baa (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.c61
-rw-r--r--crypto/ec/ec_kmeth.c34
-rw-r--r--crypto/ec/ec_lcl.h70
-rw-r--r--crypto/ec/ec_lib.c223
-rw-r--r--crypto/ec/ec_mult.c91
-rw-r--r--crypto/ec/ecp_nistp224.c71
-rw-r--r--crypto/ec/ecp_nistp256.c70
-rw-r--r--crypto/ec/ecp_nistp521.c69
-rw-r--r--crypto/ec/ecp_nistz256.c89
-rw-r--r--doc/crypto/CRYPTO_get_ex_new_index.pod3
-rw-r--r--doc/crypto/EC_KEY_new.pod57
-rw-r--r--doc/crypto/ec.pod7
-rw-r--r--include/openssl/crypto.h17
-rw-r--r--include/openssl/ec.h29
-rwxr-xr-xutil/libeay.num14
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