BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, int lock,
const BIGNUM *mod, BN_CTX *ctx)
{
- if (*pmont)
- return *pmont;
- CRYPTO_w_lock(lock);
+ int got_write_lock = 0;
+ BN_MONT_CTX *ret;
+
+ CRYPTO_r_lock(lock);
if (!*pmont)
{
- BN_MONT_CTX *mtmp;
- mtmp = BN_MONT_CTX_new();
- if (mtmp && !BN_MONT_CTX_set(mtmp, mod, ctx))
- BN_MONT_CTX_free(mtmp);
- else
- *pmont = mtmp;
+ CRYPTO_r_unlock(lock);
+ CRYPTO_w_lock(lock);
+ got_write_lock = 1;
+
+ if (!*pmont)
+ {
+ ret = BN_MONT_CTX_new();
+ if (ret && !BN_MONT_CTX_set(ret, mod, ctx))
+ BN_MONT_CTX_free(ret);
+ else
+ *pmont = ret;
+ }
}
- CRYPTO_w_unlock(lock);
- return *pmont;
+
+ ret = *pmont;
+
+ if (got_write_lock)
+ CRYPTO_w_unlock(lock);
+ else
+ CRYPTO_r_unlock(lock);
+
+ return ret;
}
}
if ((Ai=BN_mod_inverse(NULL,A,rsa->n,ctx)) == NULL) goto err;
+ if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
+ {
+ if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n,
+ CRYPTO_LOCK_RSA, rsa->n, ctx))
+ goto err;
+ }
+
if (!rsa->meth->bn_mod_exp(A,A,rsa->e,rsa->n,ctx,rsa->_method_mod_n))
goto err;
ret = BN_BLINDING_new(A,Ai,rsa->n);