From 0b1a07c8a70486534526d8967f03e32806da5661 Mon Sep 17 00:00:00 2001 From: Alessandro Ghedini Date: Tue, 8 Mar 2016 22:37:01 +0000 Subject: [PATCH] Convert RSA blinding to new multi-threading API Reviewed-by: Matt Caswell Reviewed-by: Rich Salz --- crypto/bn/bn_blind.c | 49 ++++++++++++++++++++++------------ crypto/rsa/rsa_crpt.c | 4 ++- crypto/rsa/rsa_ossl.c | 10 +++---- doc/crypto/BN_BLINDING_new.pod | 42 ++++++++++++++++------------- include/openssl/bn.h | 11 ++++---- include/openssl/crypto.h | 1 - util/libcrypto.num | 10 ++++--- 7 files changed, 77 insertions(+), 50 deletions(-) diff --git a/crypto/bn/bn_blind.c b/crypto/bn/bn_blind.c index a08d821ac3..81b895ce37 100644 --- a/crypto/bn/bn_blind.c +++ b/crypto/bn/bn_blind.c @@ -110,6 +110,7 @@ #include #include "internal/cryptlib.h" +#include "internal/threads.h" #include "bn_lcl.h" #define BN_BLINDING_COUNTER 32 @@ -119,16 +120,13 @@ struct bn_blinding_st { 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 @@ BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod) 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 @@ BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod) /* 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 @@ BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod) * 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 @@ void BN_BLINDING_free(BN_BLINDING *r) 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 @@ int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b, 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 CRYPTO_THREAD_compare_id(CRYPTO_THREAD_get_current_id(), b->tid); +} + +void BN_BLINDING_set_current_thread(BN_BLINDING *b) { - return b->thread_id; + b->tid = CRYPTO_THREAD_get_current_id(); } -void BN_BLINDING_set_thread_id(BN_BLINDING *b, unsigned long n) +int BN_BLINDING_lock(BN_BLINDING *b) { - b->thread_id = n; + return CRYPTO_THREAD_write_lock(b->lock); } -#endif -CRYPTO_THREADID *BN_BLINDING_thread_id(BN_BLINDING *b) +int BN_BLINDING_unlock(BN_BLINDING *b) { - return &b->tid; + 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 466eefc658..cec4a7c2bd 100644 --- a/crypto/rsa/rsa_crpt.c +++ b/crypto/rsa/rsa_crpt.c @@ -217,7 +217,9 @@ BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *in_ctx) 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 925cf65333..8d3383bfb0 100644 --- a/crypto/rsa/rsa_ossl.c +++ b/crypto/rsa/rsa_ossl.c @@ -248,7 +248,6 @@ static int rsa_ossl_public_encrypt(int flen, const unsigned char *from, 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 @@ static BN_BLINDING *rsa_get_blinding(RSA *rsa, int *local, BN_CTX *ctx) 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 @@ static int rsa_blinding_convert(BN_BLINDING *b, BIGNUM *f, BIGNUM *unblind, * 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; } } diff --git a/doc/crypto/BN_BLINDING_new.pod b/doc/crypto/BN_BLINDING_new.pod index 8688e48722..acc122085c 100644 --- a/doc/crypto/BN_BLINDING_new.pod +++ b/doc/crypto/BN_BLINDING_new.pod @@ -4,9 +4,9 @@ BN_BLINDING_new, BN_BLINDING_free, BN_BLINDING_update, BN_BLINDING_convert, BN_BLINDING_invert, BN_BLINDING_convert_ex, BN_BLINDING_invert_ex, -BN_BLINDING_get_thread_id, BN_BLINDING_set_thread_id, BN_BLINDING_thread_id, BN_BLINDING_get_flags, -BN_BLINDING_set_flags, BN_BLINDING_create_param - blinding related BIGNUM -functions. +BN_BLINDING_is_current_thread, BN_BLINDING_set_current_thread, +BN_BLINDING_lock, BN_BLINDING_unlock, BN_BLINDING_get_flags, +BN_BLINDING_set_flags, BN_BLINDING_create_param - blinding related BIGNUM functions. =head1 SYNOPSIS @@ -22,7 +22,10 @@ functions. BN_CTX *ctx); int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b, BN_CTX *ctx); - CRYPTO_THREADID *BN_BLINDING_thread_id(BN_BLINDING *); + int BN_BLINDING_is_current_thread(BN_BLINDING *b); + void BN_BLINDING_set_current_thread(BN_BLINDING *b); + int BN_BLINDING_lock(BN_BLINDING *b); + int BN_BLINDING_unlock(BN_BLINDING *b); unsigned long BN_BLINDING_get_flags(const BN_BLINDING *); void BN_BLINDING_set_flags(BN_BLINDING *, unsigned long); BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b, @@ -31,13 +34,6 @@ functions. const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx), BN_MONT_CTX *m_ctx); -Deprecated: - - #if OPENSSL_API_COMPAT < 0x10000000L - unsigned long BN_BLINDING_get_thread_id(const BN_BLINDING *); - void BN_BLINDING_set_thread_id(BN_BLINDING *, unsigned long); - #endif - =head1 DESCRIPTION BN_BLINDING_new() allocates a new B structure and copies @@ -61,11 +57,16 @@ BN_BLINDING_convert() and BN_BLINDING_invert() are wrapper functions for BN_BLINDING_convert_ex() and BN_BLINDING_invert_ex() with B set to NULL. -BN_BLINDING_thread_id() provides access to the B -object within the B structure. This is to help users -provide proper locking if needed for multi-threaded use. The "thread -id" object of a newly allocated B structure is -initialised to the thread id in which BN_BLINDING_new() was called. +BN_BLINDING_is_current_thread() returns whether the B +structure is owned by the current thread. This is to help users +provide proper locking if needed for multi-threaded use. + +BN_BLINDING_set_current_thread() sets the current thread as the +owner of the B structure. + +BN_BLINDING_lock() locks the B structure. + +BN_BLINDING_unlock() unlocks the B structure. BN_BLINDING_get_flags() returns the BN_BLINDING flags. Currently there are two supported flags: B and @@ -90,8 +91,13 @@ BN_BLINDING_update(), BN_BLINDING_convert(), BN_BLINDING_invert(), BN_BLINDING_convert_ex() and BN_BLINDING_invert_ex() return 1 on success and 0 if an error occurred. -BN_BLINDING_thread_id() returns a pointer to the thread id object -within a B object. +BN_BLINDING_is_current_thread() returns 1 if the current thread owns +the B object, 0 otherwise. + +BN_BLINDING_set_current_thread() doesn't return anything. + +BN_BLINDING_lock(), BN_BLINDING_unlock() return 1 if the operation +succeded or 0 on error. BN_BLINDING_get_flags() returns the currently set B flags (a B value). diff --git a/include/openssl/bn.h b/include/openssl/bn.h index db01b7e3b4..8d2d5a8be0 100644 --- a/include/openssl/bn.h +++ b/include/openssl/bn.h @@ -431,11 +431,12 @@ int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx); int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *); int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b, BN_CTX *); -DEPRECATEDIN_1_0_0(unsigned long - BN_BLINDING_get_thread_id(const BN_BLINDING *)) -DEPRECATEDIN_1_0_0(void - BN_BLINDING_set_thread_id(BN_BLINDING *, unsigned long)) -CRYPTO_THREADID *BN_BLINDING_thread_id(BN_BLINDING *); + +int BN_BLINDING_is_current_thread(BN_BLINDING *b); +void BN_BLINDING_set_current_thread(BN_BLINDING *b); +int BN_BLINDING_lock(BN_BLINDING *b); +int BN_BLINDING_unlock(BN_BLINDING *b); + unsigned long BN_BLINDING_get_flags(const BN_BLINDING *); void BN_BLINDING_set_flags(BN_BLINDING *, unsigned long); BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b, diff --git a/include/openssl/crypto.h b/include/openssl/crypto.h index 3f9ce2b442..d010bfae11 100644 --- a/include/openssl/crypto.h +++ b/include/openssl/crypto.h @@ -168,7 +168,6 @@ extern "C" { # define CRYPTO_LOCK_X509_STORE 11 # define CRYPTO_LOCK_RAND 18 # define CRYPTO_LOCK_RAND2 19 -# define CRYPTO_LOCK_RSA_BLINDING 25 # define CRYPTO_LOCK_DYNLOCK 29 # define CRYPTO_LOCK_ENGINE 30 # define CRYPTO_LOCK_ECDSA 32 diff --git a/util/libcrypto.num b/util/libcrypto.num index 3afb06f7ab..ba3060f102 100644 --- a/util/libcrypto.num +++ b/util/libcrypto.num @@ -1657,7 +1657,7 @@ TS_ext_print_bio 1607 1_1_0 EXIST::FUNCTION: SCT_set1_log_id 1608 1_1_0 EXIST::FUNCTION: X509_get0_pubkey_bitstr 1609 1_1_0 EXIST::FUNCTION: ENGINE_register_all_RAND 1610 1_1_0 EXIST::FUNCTION:ENGINE -BN_BLINDING_thread_id 1611 1_1_0 EXIST::FUNCTION: +BN_BLINDING_thread_id 1611 1_1_0 NOEXIST::FUNCTION: EVP_MD_meth_get_result_size 1612 1_1_0 EXIST::FUNCTION: BIO_ADDRINFO_address 1613 1_1_0 EXIST::FUNCTION: ASN1_STRING_print_ex 1614 1_1_0 EXIST::FUNCTION: @@ -1963,7 +1963,7 @@ UI_UTIL_read_pw_string 1900 1_1_0 EXIST::FUNCTION: NOTICEREF_free 1901 1_1_0 EXIST::FUNCTION: AES_cfb1_encrypt 1902 1_1_0 EXIST::FUNCTION:AES X509v3_get_ext 1903 1_1_0 EXIST::FUNCTION: -BN_BLINDING_set_thread_id 1904 1_1_0 EXIST::FUNCTION:DEPRECATEDIN_1_0_0 +BN_BLINDING_set_thread_id 1904 1_1_0 NOEXIST::FUNCTION: CRYPTO_gcm128_encrypt_ctr32 1905 1_1_0 EXIST::FUNCTION: SCT_set1_signature 1906 1_1_0 EXIST::FUNCTION: CONF_imodule_get_module 1907 1_1_0 EXIST::FUNCTION: @@ -2732,7 +2732,7 @@ d2i_PBKDF2PARAM 2640 1_1_0 EXIST::FUNCTION: ERR_load_COMP_strings 2641 1_1_0 EXIST::FUNCTION: EVP_PKEY_meth_add0 2642 1_1_0 EXIST::FUNCTION: EVP_rc4_40 2643 1_1_0 EXIST::FUNCTION:RC4 -BN_BLINDING_get_thread_id 2644 1_1_0 EXIST::FUNCTION:DEPRECATEDIN_1_0_0 +BN_BLINDING_get_thread_id 2644 1_1_0 NOEXIST::FUNCTION: RSA_bits 2645 1_1_0 EXIST::FUNCTION:RSA ASN1_item_dup 2646 1_1_0 EXIST::FUNCTION: GENERAL_NAMES_it 2647 1_1_0 EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE: @@ -4046,3 +4046,7 @@ EVP_CIPHER_CTX_get_cipher_data 3911 1_1_0 EXIST::FUNCTION: BIO_up_ref 3912 1_1_0 EXIST::FUNCTION: X509_STORE_up_ref 3913 1_1_0 EXIST::FUNCTION: DSA_SIG_get0 3914 1_1_0 EXIST::FUNCTION:DSA +BN_BLINDING_is_current_thread 3915 1_1_0 EXIST::FUNCTION: +BN_BLINDING_set_current_thread 3916 1_1_0 EXIST::FUNCTION: +BN_BLINDING_lock 3917 1_1_0 EXIST::FUNCTION: +BN_BLINDING_unlock 3918 1_1_0 EXIST::FUNCTION: -- 2.34.1