static BN_BLINDING *rsa_get_blinding(RSA *rsa, int *local, BN_CTX *ctx) { BN_BLINDING *ret; int got_write_lock = 0; CRYPTO_r_lock(CRYPTO_LOCK_RSA); if (rsa->blinding == NULL) { CRYPTO_r_unlock(CRYPTO_LOCK_RSA); CRYPTO_w_lock(CRYPTO_LOCK_RSA); got_write_lock = 1; if (rsa->blinding == NULL) rsa->blinding = RSA_setup_blinding(rsa, ctx); } ret = rsa->blinding; if (ret == NULL) goto err; if (BN_BLINDING_get_thread_id(ret) == CRYPTO_thread_id()) { /* rsa->blinding is ours! */ *local = 1; } else { /* resort to rsa->mt_blinding instead */ *local = 0; /* instructs rsa_blinding_convert(), rsa_blinding_invert() * that the BN_BLINDING is shared, meaning that accesses * require locks, and that the blinding factor must be * stored outside the BN_BLINDING */ if (rsa->mt_blinding == NULL) { if (!got_write_lock) { CRYPTO_r_unlock(CRYPTO_LOCK_RSA); CRYPTO_w_lock(CRYPTO_LOCK_RSA); got_write_lock = 1; } if (rsa->mt_blinding == NULL) rsa->mt_blinding = RSA_setup_blinding(rsa, ctx); } ret = rsa->mt_blinding; } err: if (got_write_lock) CRYPTO_w_unlock(CRYPTO_LOCK_RSA); else CRYPTO_r_unlock(CRYPTO_LOCK_RSA); return ret; }
static BN_BLINDING *rsa_get_blinding(RSA *rsa, BIGNUM **r, int *local, BN_CTX *ctx) { BN_BLINDING *ret; if (rsa->blinding == NULL) { if (rsa->blinding == NULL) { CRYPTO_w_lock(CRYPTO_LOCK_RSA); if (rsa->blinding == NULL) rsa->blinding = RSA_setup_blinding(rsa, ctx); CRYPTO_w_unlock(CRYPTO_LOCK_RSA); } } ret = rsa->blinding; if (ret == NULL) return NULL; if (BN_BLINDING_get_thread_id(ret) != CRYPTO_thread_id()) { *local = 0; if (rsa->mt_blinding == NULL) { CRYPTO_w_lock(CRYPTO_LOCK_RSA); if (rsa->mt_blinding == NULL) rsa->mt_blinding = RSA_setup_blinding(rsa, ctx); CRYPTO_w_unlock(CRYPTO_LOCK_RSA); } ret = rsa->mt_blinding; } else *local = 1; return ret; }