make sure RSA blinding works when the PRNG is not properly seeded;

enable it automatically only for the built-in engine
This commit is contained in:
Bodo Möller 2003-03-19 18:58:55 +00:00
parent 5250725ba5
commit 84b1e84af1
4 changed files with 39 additions and 19 deletions

14
CHANGES
View file

@ -4,12 +4,18 @@
Changes between 0.9.7a and 0.9.7b [xx XXX 2003] Changes between 0.9.7a and 0.9.7b [xx XXX 2003]
*) Turn on RSA blinding by default, to avoid a timing attack. Applications *) Turn on RSA blinding by default in the default implementation
that don't want it can call RSA_blinding_off(). They would be ill-advised to avoid a timing attack. Applications that don't want it can call
to do so in most cases. The automatic enabling can also be turned off RSA_blinding_off() or use the new flag RSA_FLAG_NO_BLINDING.
by defining OPENSSL_FORCE_NO_RSA_BLINDING at compile-time. They would be ill-advised to do so in most cases.
[Ben Laurie, Steve Henson, Geoff Thorpe] [Ben Laurie, Steve Henson, Geoff Thorpe]
*) Change RSA blinding code so that it works when the PRNG is not
seeded (in this case, the secret RSA exponent is abused as
an unpredictable seed -- if it is not unpredictable, there
is no point in blinding anyway).
[Bodo Moeller]
*) Fixed a typo bug that would cause ENGINE_set_default() to set an *) Fixed a typo bug that would cause ENGINE_set_default() to set an
ENGINE as defaults for all supported algorithms irrespective of ENGINE as defaults for all supported algorithms irrespective of
the 'flags' parameter. 'flags' is now honoured, so applications the 'flags' parameter. 'flags' is now honoured, so applications

View file

@ -158,6 +158,11 @@ struct rsa_st
#define RSA_FLAG_CACHE_PUBLIC 0x02 #define RSA_FLAG_CACHE_PUBLIC 0x02
#define RSA_FLAG_CACHE_PRIVATE 0x04 #define RSA_FLAG_CACHE_PRIVATE 0x04
#define RSA_FLAG_BLINDING 0x08 #define RSA_FLAG_BLINDING 0x08
#define RSA_FLAG_NO_BLINDING 0x80 /* new with 0.9.7b; the built-in RSA
* implementation now uses blinding by
* default (ignoring RSA_FLAG_BLINDING),
* but other engines might not need it
*/
#define RSA_FLAG_THREAD_SAFE 0x10 #define RSA_FLAG_THREAD_SAFE 0x10
/* This flag means the private key operations will be handled by rsa_mod_exp /* This flag means the private key operations will be handled by rsa_mod_exp
* and that they do not depend on the private key components being present: * and that they do not depend on the private key components being present:
@ -170,6 +175,8 @@ struct rsa_st
*/ */
#define RSA_FLAG_SIGN_VER 0x40 #define RSA_FLAG_SIGN_VER 0x40
#define RSA_FLAG_NO_BLINDING 0x80
#define RSA_PKCS1_PADDING 1 #define RSA_PKCS1_PADDING 1
#define RSA_SSLV23_PADDING 2 #define RSA_SSLV23_PADDING 2
#define RSA_NO_PADDING 3 #define RSA_NO_PADDING 3

View file

@ -208,10 +208,10 @@ static int rsa_eay_blinding(RSA *rsa, BN_CTX *ctx)
#define BLINDING_HELPER(rsa, ctx, err_instr) \ #define BLINDING_HELPER(rsa, ctx, err_instr) \
do { \ do { \
if(((rsa)->flags & RSA_FLAG_BLINDING) && \ if((!((rsa)->flags & RSA_FLAG_NO_BLINDING)) && \
((rsa)->blinding == NULL) && \ ((rsa)->blinding == NULL) && \
!rsa_eay_blinding(rsa, ctx)) \ !rsa_eay_blinding(rsa, ctx)) \
err_instr \ err_instr \
} while(0) } while(0)
/* signing */ /* signing */
@ -260,7 +260,7 @@ static int RSA_eay_private_encrypt(int flen, const unsigned char *from,
BLINDING_HELPER(rsa, ctx, goto err;); BLINDING_HELPER(rsa, ctx, goto err;);
if (rsa->flags & RSA_FLAG_BLINDING) if (!(rsa->flags & RSA_FLAG_NO_BLINDING))
if (!BN_BLINDING_convert(&f,rsa->blinding,ctx)) goto err; if (!BN_BLINDING_convert(&f,rsa->blinding,ctx)) goto err;
if ( (rsa->flags & RSA_FLAG_EXT_PKEY) || if ( (rsa->flags & RSA_FLAG_EXT_PKEY) ||
@ -275,7 +275,7 @@ static int RSA_eay_private_encrypt(int flen, const unsigned char *from,
if (!rsa->meth->bn_mod_exp(&ret,&f,rsa->d,rsa->n,ctx,NULL)) goto err; if (!rsa->meth->bn_mod_exp(&ret,&f,rsa->d,rsa->n,ctx,NULL)) goto err;
} }
if (rsa->flags & RSA_FLAG_BLINDING) if (!(rsa->flags & RSA_FLAG_NO_BLINDING))
if (!BN_BLINDING_invert(&ret,rsa->blinding,ctx)) goto err; if (!BN_BLINDING_invert(&ret,rsa->blinding,ctx)) goto err;
/* put in leading 0 bytes if the number is less than the /* put in leading 0 bytes if the number is less than the
@ -339,7 +339,7 @@ static int RSA_eay_private_decrypt(int flen, const unsigned char *from,
BLINDING_HELPER(rsa, ctx, goto err;); BLINDING_HELPER(rsa, ctx, goto err;);
if (rsa->flags & RSA_FLAG_BLINDING) if (!(rsa->flags & RSA_FLAG_NO_BLINDING))
if (!BN_BLINDING_convert(&f,rsa->blinding,ctx)) goto err; if (!BN_BLINDING_convert(&f,rsa->blinding,ctx)) goto err;
/* do the decrypt */ /* do the decrypt */
@ -356,7 +356,7 @@ static int RSA_eay_private_decrypt(int flen, const unsigned char *from,
goto err; goto err;
} }
if (rsa->flags & RSA_FLAG_BLINDING) if (!(rsa->flags & RSA_FLAG_NO_BLINDING))
if (!BN_BLINDING_invert(&ret,rsa->blinding,ctx)) goto err; if (!BN_BLINDING_invert(&ret,rsa->blinding,ctx)) goto err;
p=buf; p=buf;

View file

@ -74,10 +74,6 @@ RSA *RSA_new(void)
{ {
RSA *r=RSA_new_method(NULL); RSA *r=RSA_new_method(NULL);
#ifndef OPENSSL_NO_FORCE_RSA_BLINDING
r->flags|=RSA_FLAG_BLINDING;
#endif
return r; return r;
} }
@ -313,7 +309,8 @@ void RSA_blinding_off(RSA *rsa)
BN_BLINDING_free(rsa->blinding); BN_BLINDING_free(rsa->blinding);
rsa->blinding=NULL; rsa->blinding=NULL;
} }
rsa->flags&= ~RSA_FLAG_BLINDING; rsa->flags &= ~RSA_FLAG_BLINDING;
rsa->flags |= RSA_FLAG_NO_BLINDING;
} }
int RSA_blinding_on(RSA *rsa, BN_CTX *p_ctx) int RSA_blinding_on(RSA *rsa, BN_CTX *p_ctx)
@ -334,13 +331,23 @@ int RSA_blinding_on(RSA *rsa, BN_CTX *p_ctx)
BN_CTX_start(ctx); BN_CTX_start(ctx);
A = BN_CTX_get(ctx); A = BN_CTX_get(ctx);
if (!BN_rand_range(A,rsa->n)) goto err; if ((RAND_status() == 0) && rsa->d != NULL && rsa->d->d != NULL)
{
/* 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);
if (!BN_pseudo_rand_range(A,rsa->n)) goto err;
}
else
{
if (!BN_rand_range(A,rsa->n)) goto err;
}
if ((Ai=BN_mod_inverse(NULL,A,rsa->n,ctx)) == NULL) goto err; 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)) if (!rsa->meth->bn_mod_exp(A,A,rsa->e,rsa->n,ctx,rsa->_method_mod_n))
goto err; goto err;
rsa->blinding=BN_BLINDING_new(A,Ai,rsa->n); rsa->blinding=BN_BLINDING_new(A,Ai,rsa->n);
rsa->flags|=RSA_FLAG_BLINDING; rsa->flags |= RSA_FLAG_BLINDING;
rsa->flags &= ~RSA_FLAG_NO_BLINDING;
BN_free(Ai); BN_free(Ai);
ret=1; ret=1;
err: err: