Add CRYPTO_EX_DATA; remove EC_EXTRA_DATA
[openssl.git] / crypto / ec / ec_mult.c
index 7e29397..8a4e23d 100644 (file)
@@ -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);
 }