Convert CRYPTO_LOCK_EC_* to new multi-threading API
authorAlessandro Ghedini <alessandro@ghedini.me>
Mon, 29 Feb 2016 16:57:11 +0000 (16:57 +0000)
committerRich Salz <rsalz@openssl.org>
Tue, 8 Mar 2016 16:10:34 +0000 (11:10 -0500)
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Rich Salz <rsalz@openssl.org>
crypto/ec/ec_key.c
crypto/ec/ec_kmeth.c
crypto/ec/ec_lcl.h
crypto/ec/ec_mult.c
crypto/ec/ecp_nistp224.c
crypto/ec/ecp_nistp256.c
crypto/ec/ecp_nistp521.c
crypto/ec/ecp_nistz256.c
include/openssl/crypto.h

index 3b02eca5b5401ac4a59a125c3f893e3f969ac8ae..0d7370eef9a3faa7400bcca5292bcdb6e4181166 100644 (file)
@@ -98,7 +98,7 @@ void EC_KEY_free(EC_KEY *r)
     if (r == NULL)
         return;
 
-    i = CRYPTO_add(&r->references, -1, CRYPTO_LOCK_EC);
+    CRYPTO_atomic_add(&r->references, -1, &i, r->lock);
     REF_PRINT_COUNT("EC_KEY", r);
     if (i > 0)
         return;
@@ -115,6 +115,7 @@ void EC_KEY_free(EC_KEY *r)
         r->group->meth->keyfinish(r);
 
     CRYPTO_free_ex_data(CRYPTO_EX_INDEX_EC_KEY, r, &r->ex_data);
+    CRYPTO_THREAD_lock_free(r->lock);
     EC_GROUP_free(r->group);
     EC_POINT_free(r->pub_key);
     BN_clear_free(r->priv_key);
@@ -204,6 +205,7 @@ EC_KEY *EC_KEY_dup(EC_KEY *ec_key)
 
     if (ret == NULL)
         return NULL;
+
     if (EC_KEY_copy(ret, ec_key) == NULL) {
         EC_KEY_free(ret);
         return NULL;
@@ -213,7 +215,10 @@ EC_KEY *EC_KEY_dup(EC_KEY *ec_key)
 
 int EC_KEY_up_ref(EC_KEY *r)
 {
-    int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_EC);
+    int i;
+
+    if (CRYPTO_atomic_add(&r->references, 1, &i, r->lock) <= 0)
+        return 0;
 
     REF_PRINT_COUNT("EC_KEY", r);
     REF_ASSERT_ISNT(i < 2);
index fad74bf435b701271812e017989f3c9c367b1ae4..c656cc96deca044eaad524be6cb2f026cd5ec51e 100644 (file)
@@ -122,18 +122,27 @@ EC_KEY *EC_KEY_new_method(ENGINE *engine)
 
     if (ret == NULL) {
         ECerr(EC_F_EC_KEY_NEW_METHOD, ERR_R_MALLOC_FAILURE);
-        return (NULL);
+        return NULL;
     }
     if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_EC_KEY, ret, &ret->ex_data)) {
         OPENSSL_free(ret);
         return NULL;
     }
 
+    ret->lock = CRYPTO_THREAD_lock_new();
+    if (ret->lock == NULL) {
+        ECerr(EC_F_EC_KEY_NEW_METHOD, ERR_R_MALLOC_FAILURE);
+        CRYPTO_free_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) {
         if (!ENGINE_init(engine)) {
             ECerr(EC_F_EC_KEY_NEW_METHOD, ERR_R_ENGINE_LIB);
+            CRYPTO_free_ex_data(CRYPTO_EX_INDEX_EC_KEY, ret, &ret->ex_data);
             OPENSSL_free(ret);
             return NULL;
         }
@@ -145,6 +154,7 @@ EC_KEY *EC_KEY_new_method(ENGINE *engine)
         if (ret->meth == NULL) {
             ECerr(EC_F_EC_KEY_NEW_METHOD, ERR_R_ENGINE_LIB);
             ENGINE_finish(ret->engine);
+            CRYPTO_free_ex_data(CRYPTO_EX_INDEX_EC_KEY, ret, &ret->ex_data);
             OPENSSL_free(ret);
             return NULL;
         }
@@ -154,6 +164,7 @@ EC_KEY *EC_KEY_new_method(ENGINE *engine)
     ret->version = 1;
     ret->conv_form = POINT_CONVERSION_UNCOMPRESSED;
     ret->references = 1;
+
     if (ret->meth->init != NULL && ret->meth->init(ret) == 0) {
         EC_KEY_free(ret);
         return NULL;
index e085f76c2032e2621c342166f32e3dfc8a523f00..e6a491451fc232a8cf46737cc6cdb838b984f583 100644 (file)
@@ -310,6 +310,7 @@ struct ec_key_st {
     int references;
     int flags;
     CRYPTO_EX_DATA ex_data;
+    CRYPTO_RWLOCK *lock;
 } /* EC_KEY */ ;
 
 struct ec_point_st {
index 70c9791f8bc35121f3ac569698309fa9f3bfab05..3c283e5ed6b5be4534a7ecac6ecaa0bf91e49740 100644 (file)
@@ -63,6 +63,7 @@
 #include <string.h>
 #include <openssl/err.h>
 
+#include "internal/cryptlib.h"
 #include "internal/bn_int.h"
 #include "ec_lcl.h"
 
@@ -85,6 +86,7 @@ struct ec_pre_comp_st {
                                  * objects followed by a NULL */
     size_t num;                 /* numblocks * 2^(w-1) */
     int references;
+    CRYPTO_RWLOCK *lock;
 };
 
 static EC_PRE_COMP *ec_pre_comp_new(const EC_GROUP *group)
@@ -99,25 +101,41 @@ static EC_PRE_COMP *ec_pre_comp_new(const EC_GROUP *group)
         ECerr(EC_F_EC_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
         return ret;
     }
+
     ret->group = group;
     ret->blocksize = 8;         /* default */
     ret->w = 4;                 /* default */
     ret->references = 1;
+
+    ret->lock = CRYPTO_THREAD_lock_new();
+    if (ret->lock == NULL) {
+        ECerr(EC_F_EC_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
+        OPENSSL_free(ret);
+        return NULL;
+    }
     return ret;
 }
 
 EC_PRE_COMP *EC_ec_pre_comp_dup(EC_PRE_COMP *pre)
 {
+    int i;
     if (pre != NULL)
-        CRYPTO_add(&pre->references, 1, CRYPTO_LOCK_EC_PRE_COMP);
+        CRYPTO_atomic_add(&pre->references, 1, &i, pre->lock);
     return pre;
 }
 
 void EC_ec_pre_comp_free(EC_PRE_COMP *pre)
 {
-    if (pre == NULL
-        || CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP) > 0)
+    int i;
+
+    if (pre == NULL)
+        return;
+
+    CRYPTO_atomic_add(&pre->references, -1, &i, pre->lock);
+    REF_PRINT_COUNT("EC_ec", pre);
+    if (i > 0)
         return;
+    REF_ASSERT_ISNT(i < 0);
 
     if (pre->points != NULL) {
         EC_POINT **pts;
@@ -126,6 +144,7 @@ void EC_ec_pre_comp_free(EC_PRE_COMP *pre)
             EC_POINT_free(*pts);
         OPENSSL_free(pre->points);
     }
+    CRYPTO_THREAD_lock_free(pre->lock);
     OPENSSL_free(pre);
 }
 
index 0eea2e005d0996a0420b33c9834028b3545fd826..78bdc355bd0f392fa4c87570555bae3a6fe5f841 100644 (file)
@@ -231,6 +231,7 @@ static const felem gmul[2][16][3] = {
 struct nistp224_pre_comp_st {
     felem g_pre_comp[2][16][3];
     int references;
+    CRYPTO_RWLOCK *lock;
 };
 
 const EC_METHOD *EC_GFp_nistp224_method(void)
@@ -1216,22 +1217,40 @@ static NISTP224_PRE_COMP *nistp224_pre_comp_new()
         ECerr(EC_F_NISTP224_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
         return ret;
     }
+
     ret->references = 1;
+
+    ret->lock = CRYPTO_THREAD_lock_new();
+    if (ret->lock == NULL) {
+        ECerr(EC_F_NISTP224_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
+        OPENSSL_free(ret);
+        return NULL;
+    }
     return ret;
 }
 
 NISTP224_PRE_COMP *EC_nistp224_pre_comp_dup(NISTP224_PRE_COMP *p)
 {
+    int i;
     if (p != NULL)
-        CRYPTO_add(&p->references, 1, CRYPTO_LOCK_EC_PRE_COMP);
+        CRYPTO_atomic_add(&p->references, 1, &i, p->lock);
     return p;
 }
 
 void EC_nistp224_pre_comp_free(NISTP224_PRE_COMP *p)
 {
-    if (p == NULL
-        || CRYPTO_add(&p->references, -1, CRYPTO_LOCK_EC_PRE_COMP) > 0)
+    int i;
+
+    if (p == NULL)
+        return;
+
+    CRYPTO_atomic_add(&p->references, -1, &i, p->lock);
+    REF_PRINT_COUNT("EC_nistp224", x);
+    if (i > 0)
         return;
+    REF_ASSERT_ISNT(i < 0);
+
+    CRYPTO_THREAD_lock_free(p->lock);
     OPENSSL_free(p);
 }
 
index 1549b9c6892d0a3a9afe5fb35760d5054ab0cd0f..2da266cb6ead964bc96ed9c61a9956a94749abd6 100644 (file)
@@ -1760,6 +1760,7 @@ static void batch_mul(felem x_out, felem y_out, felem z_out,
 struct nistp256_pre_comp_st {
     smallfelem g_pre_comp[2][16][3];
     int references;
+    CRYPTO_RWLOCK *lock;
 };
 
 const EC_METHOD *EC_GFp_nistp256_method(void)
@@ -1834,21 +1835,38 @@ static NISTP256_PRE_COMP *nistp256_pre_comp_new()
     }
 
     ret->references = 1;
+
+    ret->lock = CRYPTO_THREAD_lock_new();
+    if (ret->lock == NULL) {
+        ECerr(EC_F_NISTP256_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
+        OPENSSL_free(ret);
+        return NULL;
+    }
     return ret;
 }
 
 NISTP256_PRE_COMP *EC_nistp256_pre_comp_dup(NISTP256_PRE_COMP *p)
 {
+    int i;
     if (p != NULL)
-        CRYPTO_add(&p->references, 1, CRYPTO_LOCK_EC_PRE_COMP);
+        CRYPTO_atomic_add(&p->references, 1, &i, p->lock);
     return p;
 }
 
 void EC_nistp256_pre_comp_free(NISTP256_PRE_COMP *pre)
 {
-    if (pre == NULL
-            || CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP) > 0)
+    int i;
+
+    if (pre == NULL)
         return;
+
+    CRYPTO_atomic_add(&pre->references, -1, &i, pre->lock);
+    REF_PRINT_COUNT("EC_nistp256", x);
+    if (i > 0)
+        return;
+    REF_ASSERT_ISNT(i < 0);
+
+    CRYPTO_THREAD_lock_free(pre->lock);
     OPENSSL_free(pre);
 }
 
index 629bf5d7de6e8f28ac4ca147fab826ff6252aa75..a9b4295e3061b5daea47daeb82451cc56dd2cc16 100644 (file)
@@ -1589,6 +1589,7 @@ static void batch_mul(felem x_out, felem y_out, felem z_out,
 struct nistp521_pre_comp_st {
     felem g_pre_comp[16][3];
     int references;
+    CRYPTO_RWLOCK *lock;
 };
 
 const EC_METHOD *EC_GFp_nistp521_method(void)
@@ -1661,22 +1662,40 @@ static NISTP521_PRE_COMP *nistp521_pre_comp_new()
         ECerr(EC_F_NISTP521_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
         return ret;
     }
+
     ret->references = 1;
+
+    ret->lock = CRYPTO_THREAD_lock_new();
+    if (ret->lock == NULL) {
+        ECerr(EC_F_NISTP521_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
+        OPENSSL_free(ret);
+        return NULL;
+    }
     return ret;
 }
 
 NISTP521_PRE_COMP *EC_nistp521_pre_comp_dup(NISTP521_PRE_COMP *p)
 {
+    int i;
     if (p != NULL)
-        CRYPTO_add(&p->references, 1, CRYPTO_LOCK_EC_PRE_COMP);
+        CRYPTO_atomic_add(&p->references, 1, &i, p->lock);
     return p;
 }
 
 void EC_nistp521_pre_comp_free(NISTP521_PRE_COMP *p)
 {
-    if (p == NULL
-            || CRYPTO_add(&p->references, -1, CRYPTO_LOCK_EC_PRE_COMP) > 0)
+    int i;
+
+    if (p == NULL)
+        return;
+
+    CRYPTO_atomic_add(&p->references, -1, &i, p->lock);
+    REF_PRINT_COUNT("EC_nistp521", x);
+    if (i > 0)
         return;
+    REF_ASSERT_ISNT(i < 0);
+
+    CRYPTO_THREAD_lock_free(p->lock);
     OPENSSL_free(p);
 }
 
index 0f8bd85af6252d16df876129e63190c74ea9d780..f2ef9be7f8c013d8d3941de54ed71e50298371ae 100644 (file)
@@ -76,6 +76,7 @@ struct nistz256_pre_comp_st {
     PRECOMP256_ROW *precomp;
     void *precomp_storage;
     int references;
+    CRYPTO_RWLOCK *lock;
 };
 
 /* Functions implemented in assembly */
@@ -1396,22 +1397,39 @@ static NISTZ256_PRE_COMP *ecp_nistz256_pre_comp_new(const EC_GROUP *group)
     ret->group = group;
     ret->w = 6;                 /* default */
     ret->references = 1;
+
+    ret->lock = CRYPTO_THREAD_lock_new();
+    if (ret->lock == NULL) {
+        ECerr(EC_F_ECP_NISTZ256_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
+        OPENSSL_free(ret);
+        return NULL;
+    }
     return ret;
 }
 
 NISTZ256_PRE_COMP *EC_nistz256_pre_comp_dup(NISTZ256_PRE_COMP *p)
 {
+    int i;
     if (p != NULL)
-        CRYPTO_add(&p->references, 1, CRYPTO_LOCK_EC_PRE_COMP);
+        CRYPTO_atomic_add(&p->references, 1, &i, p->lock);
     return p;
 }
 
 void EC_nistz256_pre_comp_free(NISTZ256_PRE_COMP *pre)
 {
-    if (pre == NULL
-            || CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP) > 0)
+    int i;
+
+    if (pre == NULL)
         return;
+
+    CRYPTO_atomic_add(&pre->references, -1, &i, pre->lock);
+    REF_PRINT_COUNT("EC_nistz256", x);
+    if (i > 0)
+        return;
+    REF_ASSERT_ISNT(i < 0);
+
     OPENSSL_free(pre->precomp_storage);
+    CRYPTO_THREAD_lock_free(pre->lock);
     OPENSSL_free(pre);
 }
 
index 4af6f72b0c139665d45dd50758921d736860ed32..5ec134dacdaf72a20b5cf65a8a61daed04259a6c 100644 (file)
@@ -187,10 +187,8 @@ extern "C" {
 # define CRYPTO_LOCK_ENGINE              30
 # define CRYPTO_LOCK_UI                  31
 # define CRYPTO_LOCK_ECDSA               32
-# define CRYPTO_LOCK_EC                  33
 # define CRYPTO_LOCK_ECDH                34
 # define CRYPTO_LOCK_BN                  35
-# define CRYPTO_LOCK_EC_PRE_COMP         36
 # define CRYPTO_LOCK_STORE               37
 # define CRYPTO_LOCK_COMP                38
 # define CRYPTO_LOCK_FIPS                39