aboutsummaryrefslogtreecommitdiffstats
path: root/crypto/rsa/rsa_eay.c
diff options
context:
space:
mode:
authorNils Larsch <nils@openssl.org>2005-04-26 22:31:48 +0000
committerNils Larsch <nils@openssl.org>2005-04-26 22:31:48 +0000
commit800e400de5ca30491577301ded618445b48c7911 (patch)
treea6dde859f6c9a77a295aa073d5b37ae422180739 /crypto/rsa/rsa_eay.c
parent05886a6f77e7843c854ed6d0752b6673db45db3c (diff)
downloadopenssl-800e400de5ca30491577301ded618445b48c7911.tar.gz
some updates for the blinding code; summary:
- possibility of re-creation of the blinding parameters after a fixed number of uses (suggested by Bodo) - calculatition of the rsa::e in case it's absent and p and q are present (see bug report #785) - improve the performance when if one rsa structure is shared by more than a thread (see bug report #555) - fix the problem described in bug report #827 - hide the definition ot the BN_BLINDING structure in bn_blind.c
Diffstat (limited to 'crypto/rsa/rsa_eay.c')
-rw-r--r--crypto/rsa/rsa_eay.c178
1 files changed, 76 insertions, 102 deletions
diff --git a/crypto/rsa/rsa_eay.c b/crypto/rsa/rsa_eay.c
index 3ee753ec86..6bf681f1f9 100644
--- a/crypto/rsa/rsa_eay.c
+++ b/crypto/rsa/rsa_eay.c
@@ -212,64 +212,78 @@ err:
return(r);
}
-static int rsa_eay_blinding(RSA *rsa, BN_CTX *ctx)
- {
- int ret = 1;
- CRYPTO_w_lock(CRYPTO_LOCK_RSA);
- /* Check again inside the lock - the macro's check is racey */
- if(rsa->blinding == NULL)
- ret = RSA_blinding_on(rsa, ctx);
- CRYPTO_w_unlock(CRYPTO_LOCK_RSA);
- return ret;
- }
+static BN_BLINDING *rsa_get_blinding(RSA *rsa, BIGNUM **r, int *local, BN_CTX *ctx)
+{
+ BN_BLINDING *ret;
-#define BLINDING_HELPER(rsa, ctx, err_instr) \
- do { \
- if((!((rsa)->flags & RSA_FLAG_NO_BLINDING)) && \
- ((rsa)->blinding == NULL) && \
- !rsa_eay_blinding(rsa, ctx)) \
- err_instr \
- } while(0)
+ 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);
+ }
+ }
-static BN_BLINDING *setup_blinding(RSA *rsa, BN_CTX *ctx)
- {
- BIGNUM *A, *Ai;
- BN_BLINDING *ret = NULL;
+ ret = rsa->blinding;
+ if (ret == NULL)
+ return NULL;
- /* added in OpenSSL 0.9.6j and 0.9.7b */
+ 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;
- /* NB: similar code appears in RSA_blinding_on (rsa_lib.c);
- * this should be placed in a new function of its own, but for reasons
- * of binary compatibility can't */
+ return ret;
+}
- BN_CTX_start(ctx);
- A = BN_CTX_get(ctx);
- if ((RAND_status() == 0) && rsa->d != NULL && rsa->d->d != NULL)
+static int rsa_blinding_convert(BN_BLINDING *b, int local, BIGNUM *f,
+ BIGNUM *r, BN_CTX *ctx)
+{
+ if (local)
+ return BN_BLINDING_convert_ex(f, NULL, b, ctx);
+ else
{
- /* if PRNG is not properly seeded, resort to secret exponent as unpredictable seed */
- RAND_add(rsa->d->d, rsa->d->dmax * sizeof rsa->d->d[0], 0.0);
- if (!BN_pseudo_rand_range(A,rsa->n)) goto err;
- }
+ int ret;
+ CRYPTO_w_lock(CRYPTO_LOCK_RSA_BLINDING);
+ ret = BN_BLINDING_convert_ex(f, r, b, ctx);
+ CRYPTO_w_unlock(CRYPTO_LOCK_RSA_BLINDING);
+ return ret;
+ }
+}
+
+static int rsa_blinding_invert(BN_BLINDING *b, int local, BIGNUM *f,
+ BIGNUM *r, BN_CTX *ctx)
+{
+ if (local)
+ return BN_BLINDING_invert_ex(f, NULL, b, ctx);
else
{
- if (!BN_rand_range(A,rsa->n)) goto err;
+ int ret;
+ CRYPTO_r_lock(CRYPTO_LOCK_RSA_BLINDING);
+ ret = BN_BLINDING_invert_ex(f, r, b, ctx);
+ CRYPTO_r_unlock(CRYPTO_LOCK_RSA_BLINDING);
+ return ret;
}
- if ((Ai=BN_mod_inverse(NULL,A,rsa->n,ctx)) == NULL) 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);
- BN_free(Ai);
-err:
- BN_CTX_end(ctx);
- return ret;
- }
+}
/* signing */
static int RSA_eay_private_encrypt(int flen, const unsigned char *from,
unsigned char *to, RSA *rsa, int padding)
{
- BIGNUM *f,*ret;
+ BIGNUM *f, *ret, *br;
int i,j,k,num=0,r= -1;
unsigned char *buf=NULL;
BN_CTX *ctx=NULL;
@@ -278,9 +292,10 @@ static int RSA_eay_private_encrypt(int flen, const unsigned char *from,
if ((ctx=BN_CTX_new()) == NULL) goto err;
BN_CTX_start(ctx);
- f = BN_CTX_get(ctx);
+ f = BN_CTX_get(ctx);
+ br = BN_CTX_get(ctx);
ret = BN_CTX_get(ctx);
- num=BN_num_bytes(rsa->n);
+ num = BN_num_bytes(rsa->n);
buf = OPENSSL_malloc(num);
if(!f || !ret || !buf)
{
@@ -312,17 +327,9 @@ static int RSA_eay_private_encrypt(int flen, const unsigned char *from,
goto err;
}
- BLINDING_HELPER(rsa, ctx, goto err;);
- blinding = rsa->blinding;
-
- /* Now unless blinding is disabled, 'blinding' is non-NULL.
- * But the BN_BLINDING object may be owned by some other thread
- * (we don't want to keep it constant and we don't want to use
- * lots of locking to avoid race conditions, so only a single
- * thread can use it; other threads have to use local blinding
- * factors) */
if (!(rsa->flags & RSA_FLAG_NO_BLINDING))
{
+ blinding = rsa_get_blinding(rsa, &br, &local_blinding, ctx);
if (blinding == NULL)
{
RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_INTERNAL_ERROR);
@@ -331,20 +338,8 @@ static int RSA_eay_private_encrypt(int flen, const unsigned char *from,
}
if (blinding != NULL)
- {
- if (blinding->thread_id != CRYPTO_thread_id())
- {
- /* we need a local one-time blinding factor */
-
- blinding = setup_blinding(rsa, ctx);
- if (blinding == NULL)
- goto err;
- local_blinding = 1;
- }
- }
-
- if (blinding)
- if (!BN_BLINDING_convert(f, blinding, ctx)) goto err;
+ if (!rsa_blinding_convert(blinding, local_blinding, f, br, ctx))
+ goto err;
if ( (rsa->flags & RSA_FLAG_EXT_PKEY) ||
((rsa->p != NULL) &&
@@ -361,7 +356,8 @@ static int RSA_eay_private_encrypt(int flen, const unsigned char *from,
}
if (blinding)
- if (!BN_BLINDING_invert(ret, blinding, ctx)) goto err;
+ if (!rsa_blinding_invert(blinding, local_blinding, ret, br, ctx))
+ goto err;
/* put in leading 0 bytes if the number is less than the
* length of the modulus */
@@ -377,8 +373,6 @@ err:
BN_CTX_end(ctx);
BN_CTX_free(ctx);
}
- if (local_blinding)
- BN_BLINDING_free(blinding);
if (buf != NULL)
{
OPENSSL_cleanse(buf,num);
@@ -390,7 +384,7 @@ err:
static int RSA_eay_private_decrypt(int flen, const unsigned char *from,
unsigned char *to, RSA *rsa, int padding)
{
- BIGNUM *f,*ret;
+ BIGNUM *f, *ret, *br;
int j,num=0,r= -1;
unsigned char *p;
unsigned char *buf=NULL;
@@ -400,9 +394,10 @@ static int RSA_eay_private_decrypt(int flen, const unsigned char *from,
if((ctx = BN_CTX_new()) == NULL) goto err;
BN_CTX_start(ctx);
- f = BN_CTX_get(ctx);
+ f = BN_CTX_get(ctx);
+ br = BN_CTX_get(ctx);
ret = BN_CTX_get(ctx);
- num=BN_num_bytes(rsa->n);
+ num = BN_num_bytes(rsa->n);
buf = OPENSSL_malloc(num);
if(!f || !ret || !buf)
{
@@ -427,39 +422,19 @@ static int RSA_eay_private_decrypt(int flen, const unsigned char *from,
goto err;
}
- BLINDING_HELPER(rsa, ctx, goto err;);
- blinding = rsa->blinding;
-
- /* Now unless blinding is disabled, 'blinding' is non-NULL.
- * But the BN_BLINDING object may be owned by some other thread
- * (we don't want to keep it constant and we don't want to use
- * lots of locking to avoid race conditions, so only a single
- * thread can use it; other threads have to use local blinding
- * factors) */
if (!(rsa->flags & RSA_FLAG_NO_BLINDING))
{
+ blinding = rsa_get_blinding(rsa, &br, &local_blinding, ctx);
if (blinding == NULL)
{
- RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, ERR_R_INTERNAL_ERROR);
+ RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_INTERNAL_ERROR);
goto err;
}
}
if (blinding != NULL)
- {
- if (blinding->thread_id != CRYPTO_thread_id())
- {
- /* we need a local one-time blinding factor */
-
- blinding = setup_blinding(rsa, ctx);
- if (blinding == NULL)
- goto err;
- local_blinding = 1;
- }
- }
-
- if (blinding)
- if (!BN_BLINDING_convert(f, blinding, ctx)) goto err;
+ if (!rsa_blinding_convert(blinding, local_blinding, f, br, ctx))
+ goto err;
/* do the decrypt */
if ( (rsa->flags & RSA_FLAG_EXT_PKEY) ||
@@ -478,7 +453,8 @@ static int RSA_eay_private_decrypt(int flen, const unsigned char *from,
}
if (blinding)
- if (!BN_BLINDING_invert(ret, blinding, ctx)) goto err;
+ if (!rsa_blinding_invert(blinding, local_blinding, ret, br, ctx))
+ goto err;
p=buf;
j=BN_bn2bin(ret,p); /* j is only used with no-padding mode */
@@ -512,8 +488,6 @@ err:
BN_CTX_end(ctx);
BN_CTX_free(ctx);
}
- if (local_blinding)
- BN_BLINDING_free(blinding);
if (buf != NULL)
{
OPENSSL_cleanse(buf,num);