Don't hold CRYPTO_LOCK_RSA during time-consuming operations.
This commit is contained in:
		@@ -138,26 +138,28 @@ static int RSA_eay_public_encrypt(int flen, unsigned char *from,
 | 
			
		||||
	
 | 
			
		||||
	if ((rsa->_method_mod_n == NULL) && (rsa->flags & RSA_FLAG_CACHE_PUBLIC))
 | 
			
		||||
		{
 | 
			
		||||
		CRYPTO_w_lock(CRYPTO_LOCK_RSA);
 | 
			
		||||
		if (rsa->_method_mod_n == NULL)
 | 
			
		||||
		BN_MONT_CTX* bn_mont_ctx;
 | 
			
		||||
		if ((bn_mont_ctx=BN_MONT_CTX_new()) == NULL)
 | 
			
		||||
			goto err;
 | 
			
		||||
		if (!BN_MONT_CTX_set(bn_mont_ctx,rsa->n,ctx))
 | 
			
		||||
			{
 | 
			
		||||
			BN_MONT_CTX* bn_mont_ctx;
 | 
			
		||||
			if ((bn_mont_ctx=BN_MONT_CTX_new()) == NULL)
 | 
			
		||||
				{
 | 
			
		||||
				CRYPTO_w_unlock(CRYPTO_LOCK_RSA);
 | 
			
		||||
				goto err;
 | 
			
		||||
				}
 | 
			
		||||
			if (!BN_MONT_CTX_set(bn_mont_ctx,rsa->n,ctx))
 | 
			
		||||
				{
 | 
			
		||||
				BN_MONT_CTX_free(bn_mont_ctx);
 | 
			
		||||
				CRYPTO_w_unlock(CRYPTO_LOCK_RSA);
 | 
			
		||||
				goto err;
 | 
			
		||||
				}
 | 
			
		||||
			rsa->_method_mod_n = bn_mont_ctx;
 | 
			
		||||
			BN_MONT_CTX_free(bn_mont_ctx);
 | 
			
		||||
			goto err;
 | 
			
		||||
			}
 | 
			
		||||
		CRYPTO_w_unlock(CRYPTO_LOCK_RSA);
 | 
			
		||||
		if (rsa->_method_mod_n == NULL) /* other thread may have finished first */
 | 
			
		||||
			{
 | 
			
		||||
			CRYPTO_w_lock(CRYPTO_LOCK_RSA);
 | 
			
		||||
			if (rsa->_method_mod_n == NULL)
 | 
			
		||||
				{
 | 
			
		||||
				rsa->_method_mod_n = bn_mont_ctx;
 | 
			
		||||
				bn_mont_ctx = NULL;
 | 
			
		||||
				}
 | 
			
		||||
			CRYPTO_w_unlock(CRYPTO_LOCK_RSA);
 | 
			
		||||
			}
 | 
			
		||||
		if (bn_mont_ctx)
 | 
			
		||||
			BN_MONT_CTX_free(bn_mont_ctx);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		
 | 
			
		||||
	if (!rsa->meth->bn_mod_exp(&ret,&f,rsa->e,rsa->n,ctx,
 | 
			
		||||
		rsa->_method_mod_n)) goto err;
 | 
			
		||||
 | 
			
		||||
@@ -384,26 +386,28 @@ static int RSA_eay_public_decrypt(int flen, unsigned char *from,
 | 
			
		||||
	/* do the decrypt */
 | 
			
		||||
	if ((rsa->_method_mod_n == NULL) && (rsa->flags & RSA_FLAG_CACHE_PUBLIC))
 | 
			
		||||
		{
 | 
			
		||||
		CRYPTO_w_lock(CRYPTO_LOCK_RSA);
 | 
			
		||||
		if (rsa->_method_mod_n == NULL)
 | 
			
		||||
		BN_MONT_CTX* bn_mont_ctx;
 | 
			
		||||
		if ((bn_mont_ctx=BN_MONT_CTX_new()) == NULL)
 | 
			
		||||
			goto err;
 | 
			
		||||
		if (!BN_MONT_CTX_set(bn_mont_ctx,rsa->n,ctx))
 | 
			
		||||
			{
 | 
			
		||||
			BN_MONT_CTX* bn_mont_ctx;
 | 
			
		||||
			if ((bn_mont_ctx=BN_MONT_CTX_new()) == NULL)
 | 
			
		||||
				{
 | 
			
		||||
				CRYPTO_w_unlock(CRYPTO_LOCK_RSA);
 | 
			
		||||
				goto err;
 | 
			
		||||
				}
 | 
			
		||||
			if (!BN_MONT_CTX_set(bn_mont_ctx,rsa->n,ctx))
 | 
			
		||||
				{
 | 
			
		||||
				BN_MONT_CTX_free(bn_mont_ctx);
 | 
			
		||||
				CRYPTO_w_unlock(CRYPTO_LOCK_RSA);
 | 
			
		||||
				goto err;
 | 
			
		||||
				}
 | 
			
		||||
			rsa->_method_mod_n = bn_mont_ctx;
 | 
			
		||||
			BN_MONT_CTX_free(bn_mont_ctx);
 | 
			
		||||
			goto err;
 | 
			
		||||
			}
 | 
			
		||||
		CRYPTO_w_unlock(CRYPTO_LOCK_RSA);
 | 
			
		||||
		if (rsa->_method_mod_n == NULL) /* other thread may have finished first */
 | 
			
		||||
			{
 | 
			
		||||
			CRYPTO_w_lock(CRYPTO_LOCK_RSA);
 | 
			
		||||
			if (rsa->_method_mod_n == NULL)
 | 
			
		||||
				{
 | 
			
		||||
				rsa->_method_mod_n = bn_mont_ctx;
 | 
			
		||||
				bn_mont_ctx = NULL;
 | 
			
		||||
				}
 | 
			
		||||
			CRYPTO_w_unlock(CRYPTO_LOCK_RSA);
 | 
			
		||||
			}
 | 
			
		||||
		if (bn_mont_ctx)
 | 
			
		||||
			BN_MONT_CTX_free(bn_mont_ctx);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		
 | 
			
		||||
	if (!rsa->meth->bn_mod_exp(&ret,&f,rsa->e,rsa->n,ctx,
 | 
			
		||||
		rsa->_method_mod_n)) goto err;
 | 
			
		||||
 | 
			
		||||
@@ -451,48 +455,53 @@ static int RSA_eay_mod_exp(BIGNUM *r0, BIGNUM *I, RSA *rsa)
 | 
			
		||||
		{
 | 
			
		||||
		if (rsa->_method_mod_p == NULL)
 | 
			
		||||
			{
 | 
			
		||||
			CRYPTO_w_lock(CRYPTO_LOCK_RSA);
 | 
			
		||||
			if (rsa->_method_mod_p == NULL)
 | 
			
		||||
			BN_MONT_CTX* bn_mont_ctx;
 | 
			
		||||
			if ((bn_mont_ctx=BN_MONT_CTX_new()) == NULL)
 | 
			
		||||
				goto err;
 | 
			
		||||
			if (!BN_MONT_CTX_set(bn_mont_ctx,rsa->p,ctx))
 | 
			
		||||
				{
 | 
			
		||||
				BN_MONT_CTX* bn_mont_ctx;
 | 
			
		||||
				if ((bn_mont_ctx=BN_MONT_CTX_new()) == NULL)
 | 
			
		||||
					{
 | 
			
		||||
					CRYPTO_w_unlock(CRYPTO_LOCK_RSA);
 | 
			
		||||
					goto err;
 | 
			
		||||
					}
 | 
			
		||||
				if (!BN_MONT_CTX_set(bn_mont_ctx,rsa->p,ctx))
 | 
			
		||||
					{
 | 
			
		||||
					BN_MONT_CTX_free(bn_mont_ctx);
 | 
			
		||||
					CRYPTO_w_unlock(CRYPTO_LOCK_RSA);
 | 
			
		||||
					goto err;
 | 
			
		||||
					}
 | 
			
		||||
				rsa->_method_mod_p = bn_mont_ctx;
 | 
			
		||||
				BN_MONT_CTX_free(bn_mont_ctx);
 | 
			
		||||
				goto err;
 | 
			
		||||
				}
 | 
			
		||||
			if (rsa->_method_mod_p == NULL) /* other thread may have finished first */
 | 
			
		||||
				{
 | 
			
		||||
				CRYPTO_w_lock(CRYPTO_LOCK_RSA);
 | 
			
		||||
				if (rsa->_method_mod_p == NULL)
 | 
			
		||||
					{
 | 
			
		||||
					rsa->_method_mod_p = bn_mont_ctx;
 | 
			
		||||
					bn_mont_ctx = NULL;
 | 
			
		||||
					}
 | 
			
		||||
				CRYPTO_w_unlock(CRYPTO_LOCK_RSA);
 | 
			
		||||
				}
 | 
			
		||||
			if (bn_mont_ctx)
 | 
			
		||||
				BN_MONT_CTX_free(bn_mont_ctx);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		if (rsa->_method_mod_q == NULL)
 | 
			
		||||
			{
 | 
			
		||||
			CRYPTO_w_lock(CRYPTO_LOCK_RSA);
 | 
			
		||||
			if (rsa->_method_mod_q == NULL)
 | 
			
		||||
			BN_MONT_CTX* bn_mont_ctx;
 | 
			
		||||
			if ((bn_mont_ctx=BN_MONT_CTX_new()) == NULL)
 | 
			
		||||
				goto err;
 | 
			
		||||
			if (!BN_MONT_CTX_set(bn_mont_ctx,rsa->q,ctx))
 | 
			
		||||
				{
 | 
			
		||||
				BN_MONT_CTX* bn_mont_ctx;
 | 
			
		||||
				if ((bn_mont_ctx=BN_MONT_CTX_new()) == NULL)
 | 
			
		||||
					{
 | 
			
		||||
					CRYPTO_w_unlock(CRYPTO_LOCK_RSA);
 | 
			
		||||
				BN_MONT_CTX_free(bn_mont_ctx);
 | 
			
		||||
					goto err;
 | 
			
		||||
					}
 | 
			
		||||
				if (!BN_MONT_CTX_set(bn_mont_ctx,rsa->q,ctx))
 | 
			
		||||
					{
 | 
			
		||||
					BN_MONT_CTX_free(bn_mont_ctx);
 | 
			
		||||
					CRYPTO_w_unlock(CRYPTO_LOCK_RSA);
 | 
			
		||||
					goto err;
 | 
			
		||||
					}
 | 
			
		||||
				rsa->_method_mod_q = bn_mont_ctx;
 | 
			
		||||
				}
 | 
			
		||||
			CRYPTO_w_unlock(CRYPTO_LOCK_RSA);
 | 
			
		||||
			if (rsa->_method_mod_q == NULL) /* other thread may have finished first */
 | 
			
		||||
				{
 | 
			
		||||
				CRYPTO_w_lock(CRYPTO_LOCK_RSA);
 | 
			
		||||
				if (rsa->_method_mod_q == NULL)
 | 
			
		||||
					{
 | 
			
		||||
					rsa->_method_mod_q = bn_mont_ctx;
 | 
			
		||||
					bn_mont_ctx = NULL;
 | 
			
		||||
					}
 | 
			
		||||
				CRYPTO_w_unlock(CRYPTO_LOCK_RSA);
 | 
			
		||||
				}
 | 
			
		||||
			if (bn_mont_ctx)
 | 
			
		||||
				BN_MONT_CTX_free(bn_mont_ctx);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		
 | 
			
		||||
	if (!BN_mod(&r1,I,rsa->q,ctx)) goto err;
 | 
			
		||||
	if (!rsa->meth->bn_mod_exp(&m1,&r1,rsa->dmq1,rsa->q,ctx,
 | 
			
		||||
		rsa->_method_mod_q)) goto err;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user