threadsafe manner.
Modify or add calls to use it in rsa, dsa and dh algorithms.
Changes between 0.9.7g and 0.9.7h [XX xxx XXXX]
+ *) New function BN_MONT_CTX_set_locked() to set montgomery parameters in
+ a threadsafe manner. Modify rsa code to use new function and add calls
+ to dsa and dh code (which had race conditions before).
+ [Steve Henson]
+
*) Include the fixed error library code in the C error file definitions
instead of fixing them up at runtime. This keeps the error code
structures constant.
void BN_MONT_CTX_free(BN_MONT_CTX *mont);
int BN_MONT_CTX_set(BN_MONT_CTX *mont,const BIGNUM *mod,BN_CTX *ctx);
BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to,BN_MONT_CTX *from);
+BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, int lock,
+ const BIGNUM *mod, BN_CTX *ctx);
BN_BLINDING *BN_BLINDING_new(BIGNUM *A,BIGNUM *Ai,BIGNUM *mod);
void BN_BLINDING_free(BN_BLINDING *b);
return(to);
}
+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);
+ if (!*pmont)
+ {
+ *pmont = BN_MONT_CTX_new();
+ if (*pmont && !BN_MONT_CTX_set(*pmont, mod, ctx))
+ {
+ BN_MONT_CTX_free(*pmont);
+ *pmont = NULL;
+ }
+ }
+ CRYPTO_w_unlock(lock);
+ return *pmont;
+ }
+
+
else
pub_key=dh->pub_key;
- if ((dh->method_mont_p == NULL) && (dh->flags & DH_FLAG_CACHE_MONT_P))
+
+ if (dh->flags & DH_FLAG_CACHE_MONT_P)
{
- if ((dh->method_mont_p=(char *)BN_MONT_CTX_new()) != NULL)
- if (!BN_MONT_CTX_set((BN_MONT_CTX *)dh->method_mont_p,
- dh->p,ctx)) goto err;
+ mont = BN_MONT_CTX_set_locked(
+ (BN_MONT_CTX **)&dh->method_mont_p,
+ CRYPTO_LOCK_DH, dh->p, ctx);
+ if (!mont)
+ goto err;
}
- mont=(BN_MONT_CTX *)dh->method_mont_p;
if (generate_new_key)
{
DHerr(DH_F_DH_COMPUTE_KEY,DH_R_NO_PRIVATE_VALUE);
goto err;
}
- if ((dh->method_mont_p == NULL) && (dh->flags & DH_FLAG_CACHE_MONT_P))
+
+ if (dh->flags & DH_FLAG_CACHE_MONT_P)
{
- if ((dh->method_mont_p=(char *)BN_MONT_CTX_new()) != NULL)
- if (!BN_MONT_CTX_set((BN_MONT_CTX *)dh->method_mont_p,
- dh->p,ctx)) goto err;
+ mont = BN_MONT_CTX_set_locked(
+ (BN_MONT_CTX **)&dh->method_mont_p,
+ CRYPTO_LOCK_DH, dh->p, ctx);
+ if (!mont)
+ goto err;
}
- mont=(BN_MONT_CTX *)dh->method_mont_p;
if (!dh->meth->bn_mod_exp(dh, tmp, pub_key, dh->priv_key,dh->p,ctx,mont))
{
DHerr(DH_F_DH_COMPUTE_KEY,ERR_R_BN_LIB);
if (!BN_rand_range(&k, dsa->q)) goto err;
while (BN_is_zero(&k));
- if ((dsa->method_mont_p == NULL) && (dsa->flags & DSA_FLAG_CACHE_MONT_P))
+ if (dsa->flags & DSA_FLAG_CACHE_MONT_P)
{
- if ((dsa->method_mont_p=(char *)BN_MONT_CTX_new()) != NULL)
- if (!BN_MONT_CTX_set((BN_MONT_CTX *)dsa->method_mont_p,
- dsa->p,ctx)) goto err;
+ if (!BN_MONT_CTX_set_locked((BN_MONT_CTX **)&dsa->method_mont_p,
+ CRYPTO_LOCK_DSA,
+ dsa->p, ctx))
+ goto err;
}
/* Compute r = (g^k mod p) mod q */
/* u2 = r * w mod q */
if (!BN_mod_mul(&u2,sig->r,&u2,dsa->q,ctx)) goto err;
- if ((dsa->method_mont_p == NULL) && (dsa->flags & DSA_FLAG_CACHE_MONT_P))
+
+ if (dsa->flags & DSA_FLAG_CACHE_MONT_P)
{
- if ((dsa->method_mont_p=(char *)BN_MONT_CTX_new()) != NULL)
- if (!BN_MONT_CTX_set((BN_MONT_CTX *)dsa->method_mont_p,
- dsa->p,ctx)) goto err;
+ mont = BN_MONT_CTX_set_locked(
+ (BN_MONT_CTX **)&dsa->method_mont_p,
+ CRYPTO_LOCK_DSA, dsa->p, ctx));
+ if (!mont)
+ goto err;
}
- mont=(BN_MONT_CTX *)dsa->method_mont_p;
#if 0
{
goto err;
}
- if ((rsa->_method_mod_n == NULL) && (rsa->flags & RSA_FLAG_CACHE_PUBLIC))
+ if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
{
- BN_MONT_CTX* bn_mont_ctx;
- if ((bn_mont_ctx=BN_MONT_CTX_new()) == NULL)
+ if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n,
+ CRYPTO_LOCK_RSA, rsa->n, ctx)
goto err;
- if (!BN_MONT_CTX_set(bn_mont_ctx,rsa->n,ctx))
- {
- BN_MONT_CTX_free(bn_mont_ctx);
- goto err;
- }
- 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;
}
/* do the decrypt */
- if ((rsa->_method_mod_n == NULL) && (rsa->flags & RSA_FLAG_CACHE_PUBLIC))
+
+ if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
{
- BN_MONT_CTX* bn_mont_ctx;
- if ((bn_mont_ctx=BN_MONT_CTX_new()) == NULL)
+ if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n,
+ CRYPTO_LOCK_RSA, rsa->n, ctx)
goto err;
- if (!BN_MONT_CTX_set(bn_mont_ctx,rsa->n,ctx))
- {
- BN_MONT_CTX_free(bn_mont_ctx);
- goto err;
- }
- 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;
if (rsa->flags & RSA_FLAG_CACHE_PRIVATE)
{
- 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_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)
- {
- 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_free(bn_mont_ctx);
- goto err;
- }
- 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_MONT_CTX_set_locked(&rsa->_method_mod_p,
+ CRYPTO_LOCK_RSA, rsa->p, ctx)
+ goto err;
+ if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_q,
+ CRYPTO_LOCK_RSA, rsa->q, ctx)
+ goto err;
}
-
+
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;
else
pub_key=dh->pub_key;
- if ((dh->method_mont_p == NULL) && (dh->flags & DH_FLAG_CACHE_MONT_P))
+ if (dh->flags & DH_FLAG_CACHE_MONT_P)
{
- if ((dh->method_mont_p=(char *)BN_MONT_CTX_new()) != NULL)
- if (!BN_MONT_CTX_set((BN_MONT_CTX *)dh->method_mont_p,
- dh->p,ctx)) goto err;
+ mont = BN_MONT_CTX_set_locked(
+ (BN_MONT_CTX **)&dh->method_mont_p,
+ CRYPTO_LOCK_DH, dh->p, ctx);
+ if (!mont)
+ goto err;
}
- mont=(BN_MONT_CTX *)dh->method_mont_p;
if (generate_new_key)
{
DHerr(DH_F_DH_COMPUTE_KEY,DH_R_NO_PRIVATE_VALUE);
goto err;
}
- if ((dh->method_mont_p == NULL) && (dh->flags & DH_FLAG_CACHE_MONT_P))
+
+ if (dh->flags & DH_FLAG_CACHE_MONT_P)
{
- if ((dh->method_mont_p=(char *)BN_MONT_CTX_new()) != NULL)
- if (!BN_MONT_CTX_set((BN_MONT_CTX *)dh->method_mont_p,
- dh->p,ctx)) goto err;
+ mont = BN_MONT_CTX_set_locked(
+ (BN_MONT_CTX **)&dh->method_mont_p,
+ CRYPTO_LOCK_DH, dh->p, ctx);
+ if (!mont)
+ goto err;
}
- mont=(BN_MONT_CTX *)dh->method_mont_p;
if (!dh->meth->bn_mod_exp(dh, tmp, pub_key, dh->priv_key,dh->p,ctx,mont))
{
DHerr(DH_F_DH_COMPUTE_KEY,ERR_R_BN_LIB);
if (!BN_rand_range(&k, dsa->q)) goto err;
while (BN_is_zero(&k));
- if ((dsa->method_mont_p == NULL) && (dsa->flags & DSA_FLAG_CACHE_MONT_P))
+ if (dsa->flags & DSA_FLAG_CACHE_MONT_P)
{
- if ((dsa->method_mont_p=(char *)BN_MONT_CTX_new()) != NULL)
- if (!BN_MONT_CTX_set((BN_MONT_CTX *)dsa->method_mont_p,
- dsa->p,ctx)) goto err;
+ if (!BN_MONT_CTX_set_locked((BN_MONT_CTX **)&dsa->method_mont_p,
+ CRYPTO_LOCK_DSA,
+ dsa->p, ctx))
+ goto err;
}
/* Compute r = (g^k mod p) mod q */
/* u2 = r * w mod q */
if (!BN_mod_mul(&u2,sig->r,&u2,dsa->q,ctx)) goto err;
- if ((dsa->method_mont_p == NULL) && (dsa->flags & DSA_FLAG_CACHE_MONT_P))
+
+ if (dsa->flags & DSA_FLAG_CACHE_MONT_P)
{
- if ((dsa->method_mont_p=(char *)BN_MONT_CTX_new()) != NULL)
- if (!BN_MONT_CTX_set((BN_MONT_CTX *)dsa->method_mont_p,
- dsa->p,ctx)) goto err;
+ mont = BN_MONT_CTX_set_locked(
+ (BN_MONT_CTX **)&dsa->method_mont_p,
+ CRYPTO_LOCK_DSA, dsa->p, ctx);
+ if (!mont)
+ goto err;
}
- mont=(BN_MONT_CTX *)dsa->method_mont_p;
#if 0
{
"HMAC-SHA1(des/fips_des_locl.h)= e008da40dc6913e374edd66a20d44e1752f00583",
"HMAC-SHA1(dh/fips_dh_check.c)= 63347e2007e224381d4a7b6d871633889de72cf3",
"HMAC-SHA1(dh/fips_dh_gen.c)= 93fe69b758ca9d70d70cda1c57fff4eb5c668e85",
-"HMAC-SHA1(dh/fips_dh_key.c)= a84970913f0eaa098fc4e48d4487b45ebe27bcc3",
-"HMAC-SHA1(dsa/fips_dsa_ossl.c)= e02fac446e5f89d22ffa0468fbc97d8dab7a5da8",
+"HMAC-SHA1(dh/fips_dh_key.c)= 90bdc0c2c55aea2feecd16bf9b4bc3717d4c32f4",
+"HMAC-SHA1(dsa/fips_dsa_ossl.c)= 0ff7c3aa1cb111f14ff253870fc2eddfd2224d06",
"HMAC-SHA1(dsa/fips_dsa_gen.c)= c252db14699f3ff641db052311da7d7521569c53",
"HMAC-SHA1(dsa/fips_dsa_selftest.c)= 7c2ba8d82feda2aadc8b769a3b6c4c25a6356e01",
"HMAC-SHA1(rand/fips_rand.c)= 29139e29f56f3ecd99f527af8742d5afb12f409a",
"HMAC-SHA1(rand/fips_rand.h)= bf009ea8963e79b1e414442ede9ae7010a03160b",
-"HMAC-SHA1(rsa/fips_rsa_eay.c)= dc0c262df0a218b290192edb21639ced4532e857",
+"HMAC-SHA1(rsa/fips_rsa_eay.c)= 2596773a7af8f037427217b79f56858296961d66",
"HMAC-SHA1(rsa/fips_rsa_gen.c)= 713d2e0d7a1a682b1794f1224b7afe01272ba755",
"HMAC-SHA1(rsa/fips_rsa_selftest.c)= 8c915b5a4e354dcede93ba08c42858d4dd884e67",
"HMAC-SHA1(sha1/fips_sha1dgst.c)= 867e990149be16fe9e758b916b5ffc9d9fa61afb",
goto err;
}
- if ((rsa->_method_mod_n == NULL) && (rsa->flags & RSA_FLAG_CACHE_PUBLIC))
+ if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
{
- BN_MONT_CTX* bn_mont_ctx;
- if ((bn_mont_ctx=BN_MONT_CTX_new()) == NULL)
+ if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n,
+ CRYPTO_LOCK_RSA, rsa->n, ctx))
goto err;
- if (!BN_MONT_CTX_set(bn_mont_ctx,rsa->n,ctx))
- {
- BN_MONT_CTX_free(bn_mont_ctx);
- goto err;
- }
- 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;
}
/* do the decrypt */
- if ((rsa->_method_mod_n == NULL) && (rsa->flags & RSA_FLAG_CACHE_PUBLIC))
+
+ if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
{
- BN_MONT_CTX* bn_mont_ctx;
- if ((bn_mont_ctx=BN_MONT_CTX_new()) == NULL)
+ if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n,
+ CRYPTO_LOCK_RSA, rsa->n, ctx))
goto err;
- if (!BN_MONT_CTX_set(bn_mont_ctx,rsa->n,ctx))
- {
- BN_MONT_CTX_free(bn_mont_ctx);
- goto err;
- }
- 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;
BN_init(&vrfy);
if ((ctx=BN_CTX_new()) == NULL) goto err;
+
if (rsa->flags & RSA_FLAG_CACHE_PRIVATE)
{
- 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_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)
- {
- 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_free(bn_mont_ctx);
- goto err;
- }
- 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_MONT_CTX_set_locked(&rsa->_method_mod_p,
+ CRYPTO_LOCK_RSA, rsa->p, ctx))
+ goto err;
+ if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_q,
+ CRYPTO_LOCK_RSA, rsa->q, ctx))
+ goto err;
}
-
+
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;