Convert RSA blinding to new multi-threading API Reviewed-by: Matt Caswell <matt@openssl.org> Reviewed-by: Rich Salz <rsalz@openssl.org>
diff --git a/crypto/bn/bn_blind.c b/crypto/bn/bn_blind.c index a08d821..81b895c 100644 --- a/crypto/bn/bn_blind.c +++ b/crypto/bn/bn_blind.c
@@ -110,6 +110,7 @@ #include <openssl/opensslconf.h> #include "internal/cryptlib.h" +#include "internal/threads.h" #include "bn_lcl.h" #define BN_BLINDING_COUNTER 32 @@ -119,16 +120,13 @@ BIGNUM *Ai; BIGNUM *e; BIGNUM *mod; /* just a reference */ -#if OPENSSL_API_COMPAT < 0x10000000L - unsigned long thread_id; /* added in OpenSSL 0.9.6j and 0.9.7b; used - * only by crypto/rsa/rsa_eay.c, rsa_lib.c */ -#endif - CRYPTO_THREADID tid; + CRYPTO_THREAD_ID tid; int counter; unsigned long flags; BN_MONT_CTX *m_ctx; int (*bn_mod_exp) (BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); + CRYPTO_RWLOCK *lock; }; BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod) @@ -139,12 +137,23 @@ if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) { BNerr(BN_F_BN_BLINDING_NEW, ERR_R_MALLOC_FAILURE); - return (NULL); + return NULL; } + + ret->lock = CRYPTO_THREAD_lock_new(); + if (ret->lock == NULL) { + BNerr(BN_F_BN_BLINDING_NEW, ERR_R_MALLOC_FAILURE); + OPENSSL_free(ret); + return NULL; + } + + BN_BLINDING_set_current_thread(ret); + if (A != NULL) { if ((ret->A = BN_dup(A)) == NULL) goto err; } + if (Ai != NULL) { if ((ret->Ai = BN_dup(Ai)) == NULL) goto err; @@ -153,6 +162,7 @@ /* save a copy of mod in the BN_BLINDING structure */ if ((ret->mod = BN_dup(mod)) == NULL) goto err; + if (BN_get_flags(mod, BN_FLG_CONSTTIME) != 0) BN_set_flags(ret->mod, BN_FLG_CONSTTIME); @@ -162,11 +172,12 @@ * use. */ ret->counter = -1; - CRYPTO_THREADID_current(&ret->tid); - return (ret); + + return ret; + err: BN_BLINDING_free(ret); - return (NULL); + return NULL; } void BN_BLINDING_free(BN_BLINDING *r) @@ -178,6 +189,7 @@ BN_free(r->Ai); BN_free(r->e); BN_free(r->mod); + CRYPTO_THREAD_lock_free(r->lock); OPENSSL_free(r); } @@ -271,21 +283,24 @@ return (ret); } -#if OPENSSL_API_COMPAT < 0x10000000L -unsigned long BN_BLINDING_get_thread_id(const BN_BLINDING *b) +int BN_BLINDING_is_current_thread(BN_BLINDING *b) { - return b->thread_id; + return CRYPTO_THREAD_compare_id(CRYPTO_THREAD_get_current_id(), b->tid); } -void BN_BLINDING_set_thread_id(BN_BLINDING *b, unsigned long n) +void BN_BLINDING_set_current_thread(BN_BLINDING *b) { - b->thread_id = n; + b->tid = CRYPTO_THREAD_get_current_id(); } -#endif -CRYPTO_THREADID *BN_BLINDING_thread_id(BN_BLINDING *b) +int BN_BLINDING_lock(BN_BLINDING *b) { - return &b->tid; + return CRYPTO_THREAD_write_lock(b->lock); +} + +int BN_BLINDING_unlock(BN_BLINDING *b) +{ + return CRYPTO_THREAD_unlock(b->lock); } unsigned long BN_BLINDING_get_flags(const BN_BLINDING *b)
diff --git a/crypto/rsa/rsa_crpt.c b/crypto/rsa/rsa_crpt.c index 466eefc..cec4a7c 100644 --- a/crypto/rsa/rsa_crpt.c +++ b/crypto/rsa/rsa_crpt.c
@@ -217,7 +217,9 @@ RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_BN_LIB); goto err; } - CRYPTO_THREADID_current(BN_BLINDING_thread_id(ret)); + + BN_BLINDING_set_current_thread(ret); + err: BN_CTX_end(ctx); if (ctx != in_ctx)
diff --git a/crypto/rsa/rsa_ossl.c b/crypto/rsa/rsa_ossl.c index 925cf65..8d3383b 100644 --- a/crypto/rsa/rsa_ossl.c +++ b/crypto/rsa/rsa_ossl.c
@@ -248,7 +248,6 @@ static BN_BLINDING *rsa_get_blinding(RSA *rsa, int *local, BN_CTX *ctx) { BN_BLINDING *ret; - CRYPTO_THREADID cur; CRYPTO_THREAD_write_lock(rsa->lock); @@ -260,8 +259,7 @@ if (ret == NULL) goto err; - CRYPTO_THREADID_current(&cur); - if (!CRYPTO_THREADID_cmp(&cur, BN_BLINDING_thread_id(ret))) { + if (BN_BLINDING_is_current_thread(ret)) { /* rsa->blinding is ours! */ *local = 1; @@ -299,9 +297,11 @@ * Shared blinding: store the unblinding factor outside BN_BLINDING. */ int ret; - CRYPTO_w_lock(CRYPTO_LOCK_RSA_BLINDING); + + BN_BLINDING_lock(b); ret = BN_BLINDING_convert_ex(f, unblind, b, ctx); - CRYPTO_w_unlock(CRYPTO_LOCK_RSA_BLINDING); + BN_BLINDING_unlock(b); + return ret; } }