Port BN_MONT_CTX_set_locked() from stable branch.

The function rsa_eay_mont_helper() has been removed because it is no longer
needed after this change.
This commit is contained in:
Dr. Stephen Henson 2005-04-26 23:58:54 +00:00
parent 465b9f6b26
commit 6ec8e63af6
7 changed files with 53 additions and 76 deletions

View File

@ -794,6 +794,11 @@
Changes between 0.9.7g and 0.9.7h [XX xxx XXXX] 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 *) Include the fixed error library code in the C error file definitions
instead of fixing them up at runtime. This keeps the error code instead of fixing them up at runtime. This keeps the error code
structures constant. structures constant.

View File

@ -837,31 +837,3 @@ be added to the end of this file.
Enable shared link on HP-UX. Enable shared link on HP-UX.
2005-04-22 07:17 steve
Changed:
CHANGES (1.977.2.156), "Exp", lines: +5 -0
crypto/bn/bn.h (1.66.2.4), "Exp", lines: +2 -0
crypto/bn/bn_mont.c (1.30.2.3), "Exp", lines: +20 -0
crypto/dh/dh_key.c (1.16.2.4), "Exp", lines: +14 -10
crypto/dsa/dsa_ossl.c (1.12.2.7), "Exp", lines: +12 -9
crypto/rsa/rsa_eay.c (1.28.2.10), "Exp", lines: +16 -90
fips/fipshashes.c (1.1.2.5), "Exp", lines: +3 -3
fips/dh/fips_dh_key.c (1.1.2.4), "Exp", lines: +13 -10
fips/dsa/fips_dsa_ossl.c (1.1.2.8), "Exp", lines: +12 -9
fips/rsa/fips_rsa_eay.c (1.1.4.5), "Exp", lines: +17 -90
New function BN_MONT_CTX_set_locked, to set montgomery parameters
in a threadsafe manner.
Modify or add calls to use it in rsa, dsa and dh
algorithms.
2005-04-23 06:46 nils
Changed:
crypto/dsa/dsa_ossl.c (1.12.2.8), "Exp", lines: +1 -1
crypto/rsa/rsa_eay.c (1.28.2.11), "Exp", lines: +4 -4
fix typo

View File

@ -510,6 +510,8 @@ int BN_from_montgomery(BIGNUM *r,const BIGNUM *a,
void BN_MONT_CTX_free(BN_MONT_CTX *mont); void BN_MONT_CTX_free(BN_MONT_CTX *mont);
int BN_MONT_CTX_set(BN_MONT_CTX *mont,const BIGNUM *mod,BN_CTX *ctx); 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_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 flags */ /* BN_BLINDING flags */
#define BN_BLINDING_NO_UPDATE 0x00000001 #define BN_BLINDING_NO_UPDATE 0x00000001

View File

@ -350,3 +350,21 @@ BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from)
return(to); 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;
}

View File

@ -127,13 +127,15 @@ static int generate_key(DH *dh)
else else
pub_key=dh->pub_key; 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) mont = BN_MONT_CTX_set_locked(
if (!BN_MONT_CTX_set((BN_MONT_CTX *)dh->method_mont_p, (BN_MONT_CTX **)&dh->method_mont_p,
dh->p,ctx)) goto err; CRYPTO_LOCK_DH, dh->p, ctx);
if (!mont)
goto err;
} }
mont=(BN_MONT_CTX *)dh->method_mont_p;
if (generate_new_key) if (generate_new_key)
{ {
@ -173,14 +175,16 @@ static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
DHerr(DH_F_COMPUTE_KEY,DH_R_NO_PRIVATE_VALUE); DHerr(DH_F_COMPUTE_KEY,DH_R_NO_PRIVATE_VALUE);
goto err; 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) mont = BN_MONT_CTX_set_locked(
if (!BN_MONT_CTX_set((BN_MONT_CTX *)dh->method_mont_p, (BN_MONT_CTX **)&dh->method_mont_p,
dh->p,ctx)) goto err; 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)) if (!dh->meth->bn_mod_exp(dh, tmp, pub_key, dh->priv_key,dh->p,ctx,mont))
{ {
DHerr(DH_F_COMPUTE_KEY,ERR_R_BN_LIB); DHerr(DH_F_COMPUTE_KEY,ERR_R_BN_LIB);

View File

@ -228,11 +228,12 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
if (!BN_rand_range(&k, dsa->q)) goto err; if (!BN_rand_range(&k, dsa->q)) goto err;
while (BN_is_zero(&k)); 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_locked((BN_MONT_CTX **)&dsa->method_mont_p,
if (!BN_MONT_CTX_set((BN_MONT_CTX *)dsa->method_mont_p, CRYPTO_LOCK_DSA,
dsa->p,ctx)) goto err; dsa->p, ctx))
goto err;
} }
/* Compute r = (g^k mod p) mod q */ /* Compute r = (g^k mod p) mod q */
@ -307,13 +308,15 @@ static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig,
/* u2 = r * w mod q */ /* u2 = r * w mod q */
if (!BN_mod_mul(&u2,sig->r,&u2,dsa->q,ctx)) goto err; 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) mont = BN_MONT_CTX_set_locked(
if (!BN_MONT_CTX_set((BN_MONT_CTX *)dsa->method_mont_p, (BN_MONT_CTX **)&dsa->method_mont_p,
dsa->p,ctx)) goto err; CRYPTO_LOCK_DSA, dsa->p, ctx);
if (!mont)
goto err;
} }
mont=(BN_MONT_CTX *)dsa->method_mont_p;
DSA_MOD_EXP(goto err, dsa, &t1, dsa->g, &u1, dsa->pub_key, &u2, dsa->p, ctx, mont); DSA_MOD_EXP(goto err, dsa, &t1, dsa->g, &u1, dsa->pub_key, &u2, dsa->p, ctx, mont);

View File

@ -97,40 +97,13 @@ const RSA_METHOD *RSA_PKCS1_SSLeay(void)
return(&rsa_pkcs1_eay_meth); return(&rsa_pkcs1_eay_meth);
} }
/* Static helper to reduce oodles of code duplication. As a slight
* optimisation, the "MONT_HELPER() macro must be used as front-end to this
* function, to prevent unnecessary function calls - there is an initial test
* that is performed by the macro-generated code. */
static int rsa_eay_mont_helper(BN_MONT_CTX **ptr, const BIGNUM *modulus, BN_CTX *ctx)
{
BN_MONT_CTX *bn_mont_ctx;
if((bn_mont_ctx = BN_MONT_CTX_new()) == NULL)
return 0;
if(!BN_MONT_CTX_set(bn_mont_ctx, modulus, ctx))
{
BN_MONT_CTX_free(bn_mont_ctx);
return 0;
}
if (*ptr == NULL) /* other thread may have finished first */
{
CRYPTO_w_lock(CRYPTO_LOCK_RSA);
if (*ptr == NULL) /* check again in the lock to stop races */
{
*ptr = bn_mont_ctx;
bn_mont_ctx = NULL;
}
CRYPTO_w_unlock(CRYPTO_LOCK_RSA);
}
if (bn_mont_ctx)
BN_MONT_CTX_free(bn_mont_ctx);
return 1;
}
/* Usage example; /* Usage example;
* MONT_HELPER(rsa, bn_ctx, p, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err); * MONT_HELPER(rsa, bn_ctx, p, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err);
*/ */
#define MONT_HELPER(rsa, ctx, m, pre_cond, err_instr) \ #define MONT_HELPER(rsa, ctx, m, pre_cond, err_instr) \
if((pre_cond) && ((rsa)->_method_mod_##m == NULL) && \ if((pre_cond) && ((rsa)->_method_mod_##m == NULL) && \
!rsa_eay_mont_helper(&((rsa)->_method_mod_##m), \ !BN_MONT_CTX_set_locked(&((rsa)->_method_mod_##m), \
CRYPTO_LOCK_RSA, \
(rsa)->m, (ctx))) \ (rsa)->m, (ctx))) \
err_instr err_instr