Update from 0.9.8-stable with patches also applied to equivalent FIPS
sources.
This commit is contained in:
parent
dc83f2e312
commit
8c3b5d5f27
20 changed files with 701 additions and 68 deletions
37
CHANGES
37
CHANGES
|
@ -61,6 +61,43 @@
|
|||
|
||||
Changes between 0.9.8e and 0.9.8f [23 Feb 2007]
|
||||
|
||||
*) Mitigate branch prediction attacks, which can be practical if a
|
||||
single processor is shared, allowing a spy process to extract
|
||||
information. For detailed background information, see
|
||||
http://eprint.iacr.org/2007/039 (O. Aciicmez, S. Gueron,
|
||||
J.-P. Seifert, "New Branch Prediction Vulnerabilities in OpenSSL
|
||||
and Necessary Software Countermeasures"). The core of the change
|
||||
are new versions BN_div_no_branch() and
|
||||
BN_mod_inverse_no_branch() of BN_div() and BN_mod_inverse(),
|
||||
respectively, which are slower, but avoid the security-relevant
|
||||
conditional branches. These are automatically called by BN_div()
|
||||
and BN_mod_inverse() if the flag BN_FLG_CONSTTIME is set for the
|
||||
modulus. Also, BN_is_bit_set() has been changed to remove a
|
||||
conditional branch.
|
||||
|
||||
BN_FLG_CONSTTIME is the new name for the previous
|
||||
BN_FLG_EXP_CONSTTIME flag, since it now affects more than just
|
||||
modular exponentiation. (Since OpenSSL 0.9.7h, setting this flag
|
||||
in the exponent causes BN_mod_exp_mont() to use the alternative
|
||||
implementation in BN_mod_exp_mont_consttime().) The old name
|
||||
remains as a deprecated alias.
|
||||
|
||||
Similary, RSA_FLAG_NO_EXP_CONSTTIME is replaced by a more general
|
||||
RSA_FLAG_NO_CONSTTIME flag since the RSA implementation now uses
|
||||
constant-time implementations for more than just exponentiation.
|
||||
Here too the old name is kept as a deprecated alias.
|
||||
|
||||
BN_BLINDING_new() will now use BN_dup() for the modulus so that
|
||||
the BN_BLINDING structure gets an independent copy of the
|
||||
modulus. This means that the previous "BIGNUM *m" argument to
|
||||
BN_BLINDING_new() and to BN_BLINDING_create_param() now
|
||||
essentially becomes "const BIGNUM *m", although we can't actually
|
||||
change this in the header file before 0.9.9. It allows
|
||||
RSA_setup_blinding() to use BN_with_flags() on the modulus to
|
||||
enable BN_FLG_CONSTTIME.
|
||||
|
||||
[Matthew D Wood (Intel Corp)]
|
||||
|
||||
*) In the SSL/TLS server implementation, be strict about session ID
|
||||
context matching (which matters if an application uses a single
|
||||
external cache for different purposes). Previously,
|
||||
|
|
|
@ -245,8 +245,18 @@ extern "C" {
|
|||
|
||||
#define BN_FLG_MALLOCED 0x01
|
||||
#define BN_FLG_STATIC_DATA 0x02
|
||||
#define BN_FLG_EXP_CONSTTIME 0x04 /* avoid leaking exponent information through timings
|
||||
* (BN_mod_exp_mont() will call BN_mod_exp_mont_consttime) */
|
||||
#define BN_FLG_CONSTTIME 0x04 /* avoid leaking exponent information through timing,
|
||||
* BN_mod_exp_mont() will call BN_mod_exp_mont_consttime,
|
||||
* BN_div() will call BN_div_no_branch,
|
||||
* BN_mod_inverse() will call BN_mod_inverse_no_branch.
|
||||
*/
|
||||
|
||||
#ifndef OPENSSL_NO_DEPRECATED
|
||||
#define BN_FLG_EXP_CONSTTIME BN_FLG_CONSTTIME /* deprecated name for the flag */
|
||||
/* avoid leaking exponent information through timings
|
||||
* (BN_mod_exp_mont() will call BN_mod_exp_mont_consttime) */
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_NO_DEPRECATED
|
||||
#define BN_FLG_FREE 0x8000 /* used for debuging */
|
||||
#endif
|
||||
|
@ -425,6 +435,8 @@ void BN_set_negative(BIGNUM *b, int n);
|
|||
|
||||
int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
|
||||
BN_CTX *ctx);
|
||||
int BN_div_no_branch(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m,
|
||||
const BIGNUM *d, BN_CTX *ctx);
|
||||
#define BN_mod(rem,m,d,ctx) BN_div(NULL,(rem),(m),(d),(ctx))
|
||||
int BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx);
|
||||
int BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_CTX *ctx);
|
||||
|
@ -493,6 +505,8 @@ int BN_gcd(BIGNUM *r,const BIGNUM *a,const BIGNUM *b,BN_CTX *ctx);
|
|||
int BN_kronecker(const BIGNUM *a,const BIGNUM *b,BN_CTX *ctx); /* returns -2 for error */
|
||||
BIGNUM *BN_mod_inverse(BIGNUM *ret,
|
||||
const BIGNUM *a, const BIGNUM *n,BN_CTX *ctx);
|
||||
BIGNUM *BN_mod_inverse_no_branch(BIGNUM *ret,
|
||||
const BIGNUM *A, const BIGNUM *n,BN_CTX *ctx);
|
||||
BIGNUM *BN_mod_sqrt(BIGNUM *ret,
|
||||
const BIGNUM *a, const BIGNUM *n,BN_CTX *ctx);
|
||||
|
||||
|
@ -554,7 +568,7 @@ BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, int lock,
|
|||
#define BN_BLINDING_NO_UPDATE 0x00000001
|
||||
#define BN_BLINDING_NO_RECREATE 0x00000002
|
||||
|
||||
BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod);
|
||||
BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, /* const */ BIGNUM *mod);
|
||||
void BN_BLINDING_free(BN_BLINDING *b);
|
||||
int BN_BLINDING_update(BN_BLINDING *b,BN_CTX *ctx);
|
||||
int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx);
|
||||
|
@ -566,7 +580,7 @@ void BN_BLINDING_set_thread_id(BN_BLINDING *, unsigned long);
|
|||
unsigned long BN_BLINDING_get_flags(const BN_BLINDING *);
|
||||
void BN_BLINDING_set_flags(BN_BLINDING *, unsigned long);
|
||||
BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b,
|
||||
const BIGNUM *e, BIGNUM *m, BN_CTX *ctx,
|
||||
const BIGNUM *e, /* const */ BIGNUM *m, BN_CTX *ctx,
|
||||
int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
|
||||
const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx),
|
||||
BN_MONT_CTX *m_ctx);
|
||||
|
|
|
@ -131,7 +131,7 @@ struct bn_blinding_st
|
|||
BN_MONT_CTX *m_ctx);
|
||||
};
|
||||
|
||||
BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod)
|
||||
BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, /* const */ BIGNUM *mod)
|
||||
{
|
||||
BN_BLINDING *ret=NULL;
|
||||
|
||||
|
@ -151,7 +151,12 @@ BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod)
|
|||
{
|
||||
if ((ret->Ai = BN_dup(Ai)) == NULL) goto err;
|
||||
}
|
||||
ret->mod = mod;
|
||||
|
||||
/* save a copy of mod in the BN_BLINDING structure */
|
||||
if ((ret->mod = BN_dup(mod)) == NULL) goto err;
|
||||
if (BN_get_flags(mod, BN_FLG_CONSTTIME) != 0)
|
||||
BN_set_flags(ret->mod, BN_FLG_CONSTTIME);
|
||||
|
||||
ret->counter = BN_BLINDING_COUNTER;
|
||||
return(ret);
|
||||
err:
|
||||
|
@ -167,6 +172,7 @@ void BN_BLINDING_free(BN_BLINDING *r)
|
|||
if (r->A != NULL) BN_free(r->A );
|
||||
if (r->Ai != NULL) BN_free(r->Ai);
|
||||
if (r->e != NULL) BN_free(r->e );
|
||||
if (r->mod != NULL) BN_free(r->mod);
|
||||
OPENSSL_free(r);
|
||||
}
|
||||
|
||||
|
@ -278,7 +284,7 @@ void BN_BLINDING_set_flags(BN_BLINDING *b, unsigned long flags)
|
|||
}
|
||||
|
||||
BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b,
|
||||
const BIGNUM *e, BIGNUM *m, BN_CTX *ctx,
|
||||
const BIGNUM *e, /* const */ BIGNUM *m, BN_CTX *ctx,
|
||||
int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
|
||||
const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx),
|
||||
BN_MONT_CTX *m_ctx)
|
||||
|
|
|
@ -185,6 +185,11 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
|
|||
BN_ULONG d0,d1;
|
||||
int num_n,div_n;
|
||||
|
||||
if (BN_get_flags(num, BN_FLG_CONSTTIME) != 0)
|
||||
{
|
||||
return BN_div_no_branch(dv, rm, num, divisor, ctx);
|
||||
}
|
||||
|
||||
bn_check_top(dv);
|
||||
bn_check_top(rm);
|
||||
bn_check_top(num);
|
||||
|
@ -330,6 +335,230 @@ X) -> 0x%08X\n",
|
|||
rem=(n1-q*d0)&BN_MASK2;
|
||||
#endif
|
||||
|
||||
#if defined(BN_UMULT_LOHI)
|
||||
BN_UMULT_LOHI(t2l,t2h,d1,q);
|
||||
#elif defined(BN_UMULT_HIGH)
|
||||
t2l = d1 * q;
|
||||
t2h = BN_UMULT_HIGH(d1,q);
|
||||
#else
|
||||
t2l=LBITS(d1); t2h=HBITS(d1);
|
||||
ql =LBITS(q); qh =HBITS(q);
|
||||
mul64(t2l,t2h,ql,qh); /* t2=(BN_ULLONG)d1*q; */
|
||||
#endif
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if ((t2h < rem) ||
|
||||
((t2h == rem) && (t2l <= wnump[-2])))
|
||||
break;
|
||||
q--;
|
||||
rem += d0;
|
||||
if (rem < d0) break; /* don't let rem overflow */
|
||||
if (t2l < d1) t2h--; t2l -= d1;
|
||||
}
|
||||
#endif /* !BN_LLONG */
|
||||
}
|
||||
#endif /* !BN_DIV3W */
|
||||
|
||||
l0=bn_mul_words(tmp->d,sdiv->d,div_n,q);
|
||||
tmp->d[div_n]=l0;
|
||||
wnum.d--;
|
||||
/* ingore top values of the bignums just sub the two
|
||||
* BN_ULONG arrays with bn_sub_words */
|
||||
if (bn_sub_words(wnum.d, wnum.d, tmp->d, div_n+1))
|
||||
{
|
||||
/* Note: As we have considered only the leading
|
||||
* two BN_ULONGs in the calculation of q, sdiv * q
|
||||
* might be greater than wnum (but then (q-1) * sdiv
|
||||
* is less or equal than wnum)
|
||||
*/
|
||||
q--;
|
||||
if (bn_add_words(wnum.d, wnum.d, sdiv->d, div_n))
|
||||
/* we can't have an overflow here (assuming
|
||||
* that q != 0, but if q == 0 then tmp is
|
||||
* zero anyway) */
|
||||
(*wnump)++;
|
||||
}
|
||||
/* store part of the result */
|
||||
*resp = q;
|
||||
}
|
||||
bn_correct_top(snum);
|
||||
if (rm != NULL)
|
||||
{
|
||||
/* Keep a copy of the neg flag in num because if rm==num
|
||||
* BN_rshift() will overwrite it.
|
||||
*/
|
||||
int neg = num->neg;
|
||||
BN_rshift(rm,snum,norm_shift);
|
||||
if (!BN_is_zero(rm))
|
||||
rm->neg = neg;
|
||||
bn_check_top(rm);
|
||||
}
|
||||
BN_CTX_end(ctx);
|
||||
return(1);
|
||||
err:
|
||||
bn_check_top(rm);
|
||||
BN_CTX_end(ctx);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/* BN_div_no_branch is a special version of BN_div. It does not contain
|
||||
* branches that may leak sensitive information.
|
||||
*/
|
||||
int BN_div_no_branch(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num,
|
||||
const BIGNUM *divisor, BN_CTX *ctx)
|
||||
{
|
||||
int norm_shift,i,loop;
|
||||
BIGNUM *tmp,wnum,*snum,*sdiv,*res;
|
||||
BN_ULONG *resp,*wnump;
|
||||
BN_ULONG d0,d1;
|
||||
int num_n,div_n;
|
||||
|
||||
bn_check_top(dv);
|
||||
bn_check_top(rm);
|
||||
bn_check_top(num);
|
||||
bn_check_top(divisor);
|
||||
|
||||
if (BN_is_zero(divisor))
|
||||
{
|
||||
BNerr(BN_F_BN_DIV,BN_R_DIV_BY_ZERO);
|
||||
return(0);
|
||||
}
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
tmp=BN_CTX_get(ctx);
|
||||
snum=BN_CTX_get(ctx);
|
||||
sdiv=BN_CTX_get(ctx);
|
||||
if (dv == NULL)
|
||||
res=BN_CTX_get(ctx);
|
||||
else res=dv;
|
||||
if (sdiv == NULL || res == NULL) goto err;
|
||||
|
||||
/* First we normalise the numbers */
|
||||
norm_shift=BN_BITS2-((BN_num_bits(divisor))%BN_BITS2);
|
||||
if (!(BN_lshift(sdiv,divisor,norm_shift))) goto err;
|
||||
sdiv->neg=0;
|
||||
norm_shift+=BN_BITS2;
|
||||
if (!(BN_lshift(snum,num,norm_shift))) goto err;
|
||||
snum->neg=0;
|
||||
|
||||
/* Since we don't know whether snum is larger than sdiv,
|
||||
* we pad snum with enough zeroes without changing its
|
||||
* value.
|
||||
*/
|
||||
if (snum->top <= sdiv->top+1)
|
||||
{
|
||||
if (bn_wexpand(snum, sdiv->top + 2) == NULL) goto err;
|
||||
for (i = snum->top; i < sdiv->top + 2; i++) snum->d[i] = 0;
|
||||
snum->top = sdiv->top + 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bn_wexpand(snum, snum->top + 1) == NULL) goto err;
|
||||
snum->d[snum->top] = 0;
|
||||
snum->top ++;
|
||||
}
|
||||
|
||||
div_n=sdiv->top;
|
||||
num_n=snum->top;
|
||||
loop=num_n-div_n;
|
||||
/* Lets setup a 'window' into snum
|
||||
* This is the part that corresponds to the current
|
||||
* 'area' being divided */
|
||||
wnum.neg = 0;
|
||||
wnum.d = &(snum->d[loop]);
|
||||
wnum.top = div_n;
|
||||
/* only needed when BN_ucmp messes up the values between top and max */
|
||||
wnum.dmax = snum->dmax - loop; /* so we don't step out of bounds */
|
||||
|
||||
/* Get the top 2 words of sdiv */
|
||||
/* div_n=sdiv->top; */
|
||||
d0=sdiv->d[div_n-1];
|
||||
d1=(div_n == 1)?0:sdiv->d[div_n-2];
|
||||
|
||||
/* pointer to the 'top' of snum */
|
||||
wnump= &(snum->d[num_n-1]);
|
||||
|
||||
/* Setup to 'res' */
|
||||
res->neg= (num->neg^divisor->neg);
|
||||
if (!bn_wexpand(res,(loop+1))) goto err;
|
||||
res->top=loop-1;
|
||||
resp= &(res->d[loop-1]);
|
||||
|
||||
/* space for temp */
|
||||
if (!bn_wexpand(tmp,(div_n+1))) goto err;
|
||||
|
||||
/* if res->top == 0 then clear the neg value otherwise decrease
|
||||
* the resp pointer */
|
||||
if (res->top == 0)
|
||||
res->neg = 0;
|
||||
else
|
||||
resp--;
|
||||
|
||||
for (i=0; i<loop-1; i++, wnump--, resp--)
|
||||
{
|
||||
BN_ULONG q,l0;
|
||||
/* the first part of the loop uses the top two words of
|
||||
* snum and sdiv to calculate a BN_ULONG q such that
|
||||
* | wnum - sdiv * q | < sdiv */
|
||||
#if defined(BN_DIV3W) && !defined(OPENSSL_NO_ASM)
|
||||
BN_ULONG bn_div_3_words(BN_ULONG*,BN_ULONG,BN_ULONG);
|
||||
q=bn_div_3_words(wnump,d1,d0);
|
||||
#else
|
||||
BN_ULONG n0,n1,rem=0;
|
||||
|
||||
n0=wnump[0];
|
||||
n1=wnump[-1];
|
||||
if (n0 == d0)
|
||||
q=BN_MASK2;
|
||||
else /* n0 < d0 */
|
||||
{
|
||||
#ifdef BN_LLONG
|
||||
BN_ULLONG t2;
|
||||
|
||||
#if defined(BN_LLONG) && defined(BN_DIV2W) && !defined(bn_div_words)
|
||||
q=(BN_ULONG)(((((BN_ULLONG)n0)<<BN_BITS2)|n1)/d0);
|
||||
#else
|
||||
q=bn_div_words(n0,n1,d0);
|
||||
#ifdef BN_DEBUG_LEVITTE
|
||||
fprintf(stderr,"DEBUG: bn_div_words(0x%08X,0x%08X,0x%08\
|
||||
X) -> 0x%08X\n",
|
||||
n0, n1, d0, q);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef REMAINDER_IS_ALREADY_CALCULATED
|
||||
/*
|
||||
* rem doesn't have to be BN_ULLONG. The least we
|
||||
* know it's less that d0, isn't it?
|
||||
*/
|
||||
rem=(n1-q*d0)&BN_MASK2;
|
||||
#endif
|
||||
t2=(BN_ULLONG)d1*q;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (t2 <= ((((BN_ULLONG)rem)<<BN_BITS2)|wnump[-2]))
|
||||
break;
|
||||
q--;
|
||||
rem += d0;
|
||||
if (rem < d0) break; /* don't let rem overflow */
|
||||
t2 -= d1;
|
||||
}
|
||||
#else /* !BN_LLONG */
|
||||
BN_ULONG t2l,t2h,ql,qh;
|
||||
|
||||
q=bn_div_words(n0,n1,d0);
|
||||
#ifdef BN_DEBUG_LEVITTE
|
||||
fprintf(stderr,"DEBUG: bn_div_words(0x%08X,0x%08X,0x%08\
|
||||
X) -> 0x%08X\n",
|
||||
n0, n1, d0, q);
|
||||
#endif
|
||||
#ifndef REMAINDER_IS_ALREADY_CALCULATED
|
||||
rem=(n1-q*d0)&BN_MASK2;
|
||||
#endif
|
||||
|
||||
#if defined(BN_UMULT_LOHI)
|
||||
BN_UMULT_LOHI(t2l,t2h,d1,q);
|
||||
#elif defined(BN_UMULT_HIGH)
|
||||
|
|
|
@ -122,9 +122,9 @@ int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
|
|||
int i,bits,ret=0;
|
||||
BIGNUM *v,*rr;
|
||||
|
||||
if (BN_get_flags(p, BN_FLG_EXP_CONSTTIME) != 0)
|
||||
if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0)
|
||||
{
|
||||
/* BN_FLG_EXP_CONSTTIME only supported by BN_mod_exp_mont() */
|
||||
/* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
|
||||
BNerr(BN_F_BN_EXP,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
|
||||
return -1;
|
||||
}
|
||||
|
@ -213,7 +213,7 @@ int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
|
|||
if (BN_is_odd(m))
|
||||
{
|
||||
# ifdef MONT_EXP_WORD
|
||||
if (a->top == 1 && !a->neg && (BN_get_flags(p, BN_FLG_EXP_CONSTTIME) == 0))
|
||||
if (a->top == 1 && !a->neg && (BN_get_flags(p, BN_FLG_CONSTTIME) == 0))
|
||||
{
|
||||
BN_ULONG A = a->d[0];
|
||||
ret=BN_mod_exp_mont_word(r,A,p,m,ctx,NULL);
|
||||
|
@ -245,9 +245,9 @@ int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
|
|||
BIGNUM *val[TABLE_SIZE];
|
||||
BN_RECP_CTX recp;
|
||||
|
||||
if (BN_get_flags(p, BN_FLG_EXP_CONSTTIME) != 0)
|
||||
if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0)
|
||||
{
|
||||
/* BN_FLG_EXP_CONSTTIME only supported by BN_mod_exp_mont() */
|
||||
/* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
|
||||
BNerr(BN_F_BN_MOD_EXP_RECP,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
|
||||
return -1;
|
||||
}
|
||||
|
@ -379,7 +379,7 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
|
|||
BIGNUM *val[TABLE_SIZE];
|
||||
BN_MONT_CTX *mont=NULL;
|
||||
|
||||
if (BN_get_flags(p, BN_FLG_EXP_CONSTTIME) != 0)
|
||||
if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0)
|
||||
{
|
||||
return BN_mod_exp_mont_consttime(rr, a, p, m, ctx, in_mont);
|
||||
}
|
||||
|
@ -745,9 +745,9 @@ int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p,
|
|||
#define BN_TO_MONTGOMERY_WORD(r, w, mont) \
|
||||
(BN_set_word(r, (w)) && BN_to_montgomery(r, r, (mont), ctx))
|
||||
|
||||
if (BN_get_flags(p, BN_FLG_EXP_CONSTTIME) != 0)
|
||||
if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0)
|
||||
{
|
||||
/* BN_FLG_EXP_CONSTTIME only supported by BN_mod_exp_mont() */
|
||||
/* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
|
||||
BNerr(BN_F_BN_MOD_EXP_MONT_WORD,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
|
||||
return -1;
|
||||
}
|
||||
|
@ -881,9 +881,9 @@ int BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
|
|||
/* Table of variables obtained from 'ctx' */
|
||||
BIGNUM *val[TABLE_SIZE];
|
||||
|
||||
if (BN_get_flags(p, BN_FLG_EXP_CONSTTIME) != 0)
|
||||
if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0)
|
||||
{
|
||||
/* BN_FLG_EXP_CONSTTIME only supported by BN_mod_exp_mont() */
|
||||
/* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
|
||||
BNerr(BN_F_BN_MOD_EXP_SIMPLE,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -210,6 +210,11 @@ BIGNUM *BN_mod_inverse(BIGNUM *in,
|
|||
BIGNUM *ret=NULL;
|
||||
int sign;
|
||||
|
||||
if (BN_get_flags(n, BN_FLG_CONSTTIME) != 0)
|
||||
{
|
||||
return BN_mod_inverse_no_branch(in, a, n, ctx);
|
||||
}
|
||||
|
||||
bn_check_top(a);
|
||||
bn_check_top(n);
|
||||
|
||||
|
@ -491,3 +496,157 @@ err:
|
|||
bn_check_top(ret);
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
/* BN_mod_inverse_no_branch is a special version of BN_mod_inverse.
|
||||
* It does not contain branches that may leak sensitive information.
|
||||
*/
|
||||
BIGNUM *BN_mod_inverse_no_branch(BIGNUM *in,
|
||||
const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx)
|
||||
{
|
||||
BIGNUM *A,*B,*X,*Y,*M,*D,*T,*R=NULL;
|
||||
BIGNUM local_A, local_B;
|
||||
BIGNUM *pA, *pB;
|
||||
BIGNUM *ret=NULL;
|
||||
int sign;
|
||||
|
||||
bn_check_top(a);
|
||||
bn_check_top(n);
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
A = BN_CTX_get(ctx);
|
||||
B = BN_CTX_get(ctx);
|
||||
X = BN_CTX_get(ctx);
|
||||
D = BN_CTX_get(ctx);
|
||||
M = BN_CTX_get(ctx);
|
||||
Y = BN_CTX_get(ctx);
|
||||
T = BN_CTX_get(ctx);
|
||||
if (T == NULL) goto err;
|
||||
|
||||
if (in == NULL)
|
||||
R=BN_new();
|
||||
else
|
||||
R=in;
|
||||
if (R == NULL) goto err;
|
||||
|
||||
BN_one(X);
|
||||
BN_zero(Y);
|
||||
if (BN_copy(B,a) == NULL) goto err;
|
||||
if (BN_copy(A,n) == NULL) goto err;
|
||||
A->neg = 0;
|
||||
|
||||
if (B->neg || (BN_ucmp(B, A) >= 0))
|
||||
{
|
||||
/* Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked,
|
||||
* BN_div_no_branch will be called eventually.
|
||||
*/
|
||||
pB = &local_B;
|
||||
BN_with_flags(pB, B, BN_FLG_CONSTTIME);
|
||||
if (!BN_nnmod(B, pB, A, ctx)) goto err;
|
||||
}
|
||||
sign = -1;
|
||||
/* From B = a mod |n|, A = |n| it follows that
|
||||
*
|
||||
* 0 <= B < A,
|
||||
* -sign*X*a == B (mod |n|),
|
||||
* sign*Y*a == A (mod |n|).
|
||||
*/
|
||||
|
||||
while (!BN_is_zero(B))
|
||||
{
|
||||
BIGNUM *tmp;
|
||||
|
||||
/*
|
||||
* 0 < B < A,
|
||||
* (*) -sign*X*a == B (mod |n|),
|
||||
* sign*Y*a == A (mod |n|)
|
||||
*/
|
||||
|
||||
/* Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked,
|
||||
* BN_div_no_branch will be called eventually.
|
||||
*/
|
||||
pA = &local_A;
|
||||
BN_with_flags(pA, A, BN_FLG_CONSTTIME);
|
||||
|
||||
/* (D, M) := (A/B, A%B) ... */
|
||||
if (!BN_div(D,M,pA,B,ctx)) goto err;
|
||||
|
||||
/* Now
|
||||
* A = D*B + M;
|
||||
* thus we have
|
||||
* (**) sign*Y*a == D*B + M (mod |n|).
|
||||
*/
|
||||
|
||||
tmp=A; /* keep the BIGNUM object, the value does not matter */
|
||||
|
||||
/* (A, B) := (B, A mod B) ... */
|
||||
A=B;
|
||||
B=M;
|
||||
/* ... so we have 0 <= B < A again */
|
||||
|
||||
/* Since the former M is now B and the former B is now A,
|
||||
* (**) translates into
|
||||
* sign*Y*a == D*A + B (mod |n|),
|
||||
* i.e.
|
||||
* sign*Y*a - D*A == B (mod |n|).
|
||||
* Similarly, (*) translates into
|
||||
* -sign*X*a == A (mod |n|).
|
||||
*
|
||||
* Thus,
|
||||
* sign*Y*a + D*sign*X*a == B (mod |n|),
|
||||
* i.e.
|
||||
* sign*(Y + D*X)*a == B (mod |n|).
|
||||
*
|
||||
* So if we set (X, Y, sign) := (Y + D*X, X, -sign), we arrive back at
|
||||
* -sign*X*a == B (mod |n|),
|
||||
* sign*Y*a == A (mod |n|).
|
||||
* Note that X and Y stay non-negative all the time.
|
||||
*/
|
||||
|
||||
if (!BN_mul(tmp,D,X,ctx)) goto err;
|
||||
if (!BN_add(tmp,tmp,Y)) goto err;
|
||||
|
||||
M=Y; /* keep the BIGNUM object, the value does not matter */
|
||||
Y=X;
|
||||
X=tmp;
|
||||
sign = -sign;
|
||||
}
|
||||
|
||||
/*
|
||||
* The while loop (Euclid's algorithm) ends when
|
||||
* A == gcd(a,n);
|
||||
* we have
|
||||
* sign*Y*a == A (mod |n|),
|
||||
* where Y is non-negative.
|
||||
*/
|
||||
|
||||
if (sign < 0)
|
||||
{
|
||||
if (!BN_sub(Y,n,Y)) goto err;
|
||||
}
|
||||
/* Now Y*a == A (mod |n|). */
|
||||
|
||||
if (BN_is_one(A))
|
||||
{
|
||||
/* Y*a == 1 (mod |n|) */
|
||||
if (!Y->neg && BN_ucmp(Y,n) < 0)
|
||||
{
|
||||
if (!BN_copy(R,Y)) goto err;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!BN_nnmod(R,Y,n,ctx)) goto err;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
BNerr(BN_F_BN_MOD_INVERSE,BN_R_NO_INVERSE);
|
||||
goto err;
|
||||
}
|
||||
ret=R;
|
||||
err:
|
||||
if ((ret == NULL) && (in == NULL)) BN_free(R);
|
||||
BN_CTX_end(ctx);
|
||||
bn_check_top(ret);
|
||||
return(ret);
|
||||
}
|
||||
|
|
|
@ -744,7 +744,7 @@ int BN_is_bit_set(const BIGNUM *a, int n)
|
|||
i=n/BN_BITS2;
|
||||
j=n%BN_BITS2;
|
||||
if (a->top <= i) return 0;
|
||||
return((a->d[i]&(((BN_ULONG)1)<<j))?1:0);
|
||||
return(((a->d[i])>>j)&((BN_ULONG)1));
|
||||
}
|
||||
|
||||
int BN_mask_bits(BIGNUM *a, int n)
|
||||
|
|
|
@ -152,7 +152,7 @@ static int generate_key(DH *dh)
|
|||
{
|
||||
BN_init(&local_prk);
|
||||
prk = &local_prk;
|
||||
BN_with_flags(prk, priv_key, BN_FLG_EXP_CONSTTIME);
|
||||
BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME);
|
||||
}
|
||||
else
|
||||
prk = priv_key;
|
||||
|
@ -205,7 +205,7 @@ static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
|
|||
if ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) == 0)
|
||||
{
|
||||
/* XXX */
|
||||
BN_set_flags(dh->priv_key, BN_FLG_EXP_CONSTTIME);
|
||||
BN_set_flags(dh->priv_key, BN_FLG_CONSTTIME);
|
||||
}
|
||||
if (!mont)
|
||||
goto err;
|
||||
|
|
|
@ -109,7 +109,7 @@ static int dsa_builtin_keygen(DSA *dsa)
|
|||
{
|
||||
BN_init(&local_prk);
|
||||
prk = &local_prk;
|
||||
BN_with_flags(prk, priv_key, BN_FLG_EXP_CONSTTIME);
|
||||
BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME);
|
||||
}
|
||||
else
|
||||
prk = priv_key;
|
||||
|
|
|
@ -231,7 +231,7 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
|
|||
while (BN_is_zero(&k));
|
||||
if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0)
|
||||
{
|
||||
BN_set_flags(&k, BN_FLG_EXP_CONSTTIME);
|
||||
BN_set_flags(&k, BN_FLG_CONSTTIME);
|
||||
}
|
||||
|
||||
if (dsa->flags & DSA_FLAG_CACHE_MONT_P)
|
||||
|
|
|
@ -199,13 +199,27 @@ struct rsa_st
|
|||
* default (ignoring RSA_FLAG_BLINDING),
|
||||
* but other engines might not need it
|
||||
*/
|
||||
#define RSA_FLAG_NO_EXP_CONSTTIME 0x0100 /* new with 0.9.7h; the built-in RSA
|
||||
#define RSA_FLAG_NO_CONSTTIME 0x0100 /* new with 0.9.8f; the built-in RSA
|
||||
* implementation now uses constant time
|
||||
* operations by default in private key operations,
|
||||
* e.g., constant time modular exponentiation,
|
||||
* modular inverse without leaking branches,
|
||||
* division without leaking branches. This
|
||||
* flag disables these constant time
|
||||
* operations and results in faster RSA
|
||||
* private key operations.
|
||||
*/
|
||||
#ifndef OPENSSL_NO_DEPRECATED
|
||||
#define RSA_FLAG_NO_EXP_CONSTTIME RSA_FLAG_NO_CONSTTIME /* deprecated name for the flag*/
|
||||
/* new with 0.9.7h; the built-in RSA
|
||||
* implementation now uses constant time
|
||||
* modular exponentiation for secret exponents
|
||||
* by default. This flag causes the
|
||||
* faster variable sliding window method to
|
||||
* be used for all exponents.
|
||||
*/
|
||||
#endif
|
||||
|
||||
|
||||
#define RSA_PKCS1_PADDING 1
|
||||
#define RSA_SSLV23_PADDING 2
|
||||
|
|
|
@ -429,11 +429,11 @@ static int RSA_eay_private_encrypt(int flen, const unsigned char *from,
|
|||
BIGNUM local_d;
|
||||
BIGNUM *d = NULL;
|
||||
|
||||
if (!(rsa->flags & RSA_FLAG_NO_EXP_CONSTTIME))
|
||||
if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
|
||||
{
|
||||
BN_init(&local_d);
|
||||
d = &local_d;
|
||||
BN_with_flags(d, rsa->d, BN_FLG_EXP_CONSTTIME);
|
||||
BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
|
||||
}
|
||||
else
|
||||
d = rsa->d;
|
||||
|
@ -551,10 +551,10 @@ static int RSA_eay_private_decrypt(int flen, const unsigned char *from,
|
|||
BIGNUM local_d;
|
||||
BIGNUM *d = NULL;
|
||||
|
||||
if (!(rsa->flags & RSA_FLAG_NO_EXP_CONSTTIME))
|
||||
if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
|
||||
{
|
||||
d = &local_d;
|
||||
BN_with_flags(d, rsa->d, BN_FLG_EXP_CONSTTIME);
|
||||
BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
|
||||
}
|
||||
else
|
||||
d = rsa->d;
|
||||
|
@ -715,8 +715,9 @@ err:
|
|||
static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
|
||||
{
|
||||
BIGNUM *r1,*m1,*vrfy;
|
||||
BIGNUM local_dmp1, local_dmq1;
|
||||
BIGNUM *dmp1, *dmq1;
|
||||
BIGNUM local_dmp1,local_dmq1,local_c,local_r1;
|
||||
BIGNUM *dmp1,*dmq1,*c,*pr1;
|
||||
int bn_flags;
|
||||
int ret=0;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
|
@ -724,26 +725,72 @@ static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
|
|||
m1 = BN_CTX_get(ctx);
|
||||
vrfy = BN_CTX_get(ctx);
|
||||
|
||||
/* Make sure mod_inverse in montgomerey intialization use correct
|
||||
* BN_FLG_CONSTTIME flag.
|
||||
*/
|
||||
bn_flags = rsa->p->flags;
|
||||
if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
|
||||
{
|
||||
rsa->p->flags |= BN_FLG_CONSTTIME;
|
||||
}
|
||||
MONT_HELPER(rsa, ctx, p, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err);
|
||||
/* We restore bn_flags back */
|
||||
rsa->p->flags = bn_flags;
|
||||
|
||||
/* Make sure mod_inverse in montgomerey intialization use correct
|
||||
* BN_FLG_CONSTTIME flag.
|
||||
*/
|
||||
bn_flags = rsa->q->flags;
|
||||
if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
|
||||
{
|
||||
rsa->q->flags |= BN_FLG_CONSTTIME;
|
||||
}
|
||||
MONT_HELPER(rsa, ctx, q, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err);
|
||||
/* We restore bn_flags back */
|
||||
rsa->q->flags = bn_flags;
|
||||
|
||||
MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err);
|
||||
|
||||
if (!BN_mod(r1,I,rsa->q,ctx)) goto err;
|
||||
if (!(rsa->flags & RSA_FLAG_NO_EXP_CONSTTIME))
|
||||
/* compute I mod q */
|
||||
if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
|
||||
{
|
||||
c = &local_c;
|
||||
BN_with_flags(c, I, BN_FLG_CONSTTIME);
|
||||
if (!BN_mod(r1,c,rsa->q,ctx)) goto err;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!BN_mod(r1,I,rsa->q,ctx)) goto err;
|
||||
}
|
||||
|
||||
/* compute r1^dmq1 mod q */
|
||||
if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
|
||||
{
|
||||
dmq1 = &local_dmq1;
|
||||
BN_with_flags(dmq1, rsa->dmq1, BN_FLG_EXP_CONSTTIME);
|
||||
BN_with_flags(dmq1, rsa->dmq1, BN_FLG_CONSTTIME);
|
||||
}
|
||||
else
|
||||
dmq1 = rsa->dmq1;
|
||||
if (!rsa->meth->bn_mod_exp(m1,r1,dmq1,rsa->q,ctx,
|
||||
rsa->_method_mod_q)) goto err;
|
||||
|
||||
if (!BN_mod(r1,I,rsa->p,ctx)) goto err;
|
||||
if (!(rsa->flags & RSA_FLAG_NO_EXP_CONSTTIME))
|
||||
/* compute I mod p */
|
||||
if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
|
||||
{
|
||||
c = &local_c;
|
||||
BN_with_flags(c, I, BN_FLG_CONSTTIME);
|
||||
if (!BN_mod(r1,c,rsa->p,ctx)) goto err;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!BN_mod(r1,I,rsa->p,ctx)) goto err;
|
||||
}
|
||||
|
||||
/* compute r1^dmp1 mod p */
|
||||
if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
|
||||
{
|
||||
dmp1 = &local_dmp1;
|
||||
BN_with_flags(dmp1, rsa->dmp1, BN_FLG_EXP_CONSTTIME);
|
||||
BN_with_flags(dmp1, rsa->dmp1, BN_FLG_CONSTTIME);
|
||||
}
|
||||
else
|
||||
dmp1 = rsa->dmp1;
|
||||
|
@ -757,7 +804,17 @@ static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
|
|||
if (!BN_add(r0,r0,rsa->p)) goto err;
|
||||
|
||||
if (!BN_mul(r1,r0,rsa->iqmp,ctx)) goto err;
|
||||
if (!BN_mod(r0,r1,rsa->p,ctx)) goto err;
|
||||
|
||||
/* Turn BN_FLG_CONSTTIME flag on before division operation */
|
||||
if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
|
||||
{
|
||||
pr1 = &local_r1;
|
||||
BN_with_flags(pr1, r1, BN_FLG_CONSTTIME);
|
||||
}
|
||||
else
|
||||
pr1 = r1;
|
||||
if (!BN_mod(r0,pr1,rsa->p,ctx)) goto err;
|
||||
|
||||
/* If p < q it is occasionally possible for the correction of
|
||||
* adding 'p' if r0 is negative above to leave the result still
|
||||
* negative. This can break the private key operations: the following
|
||||
|
@ -790,10 +847,10 @@ static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
|
|||
BIGNUM local_d;
|
||||
BIGNUM *d = NULL;
|
||||
|
||||
if (!(rsa->flags & RSA_FLAG_NO_EXP_CONSTTIME))
|
||||
if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
|
||||
{
|
||||
d = &local_d;
|
||||
BN_with_flags(d, rsa->d, BN_FLG_EXP_CONSTTIME);
|
||||
BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
|
||||
}
|
||||
else
|
||||
d = rsa->d;
|
||||
|
|
|
@ -87,6 +87,8 @@ int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb)
|
|||
static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb)
|
||||
{
|
||||
BIGNUM *r0=NULL,*r1=NULL,*r2=NULL,*r3=NULL,*tmp;
|
||||
BIGNUM local_r0,local_d,local_p;
|
||||
BIGNUM *pr0,*d,*p;
|
||||
int bitsp,bitsq,ok= -1,n=0;
|
||||
BN_CTX *ctx=NULL;
|
||||
|
||||
|
@ -167,16 +169,39 @@ static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb)
|
|||
if (!BN_sub(r1,rsa->p,BN_value_one())) goto err; /* p-1 */
|
||||
if (!BN_sub(r2,rsa->q,BN_value_one())) goto err; /* q-1 */
|
||||
if (!BN_mul(r0,r1,r2,ctx)) goto err; /* (p-1)(q-1) */
|
||||
if (!BN_mod_inverse(rsa->d,rsa->e,r0,ctx)) goto err; /* d */
|
||||
if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
|
||||
{
|
||||
pr0 = &local_r0;
|
||||
BN_with_flags(pr0, r0, BN_FLG_CONSTTIME);
|
||||
}
|
||||
else
|
||||
pr0 = r0;
|
||||
if (!BN_mod_inverse(rsa->d,rsa->e,pr0,ctx)) goto err; /* d */
|
||||
|
||||
/* set up d for correct BN_FLG_CONSTTIME flag */
|
||||
if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
|
||||
{
|
||||
d = &local_d;
|
||||
BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
|
||||
}
|
||||
else
|
||||
d = rsa->d;
|
||||
|
||||
/* calculate d mod (p-1) */
|
||||
if (!BN_mod(rsa->dmp1,rsa->d,r1,ctx)) goto err;
|
||||
if (!BN_mod(rsa->dmp1,d,r1,ctx)) goto err;
|
||||
|
||||
/* calculate d mod (q-1) */
|
||||
if (!BN_mod(rsa->dmq1,rsa->d,r2,ctx)) goto err;
|
||||
if (!BN_mod(rsa->dmq1,d,r2,ctx)) goto err;
|
||||
|
||||
/* calculate inverse of q mod p */
|
||||
if (!BN_mod_inverse(rsa->iqmp,rsa->q,rsa->p,ctx)) goto err;
|
||||
if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
|
||||
{
|
||||
p = &local_p;
|
||||
BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME);
|
||||
}
|
||||
else
|
||||
p = rsa->p;
|
||||
if (!BN_mod_inverse(rsa->iqmp,rsa->q,p,ctx)) goto err;
|
||||
|
||||
ok=1;
|
||||
err:
|
||||
|
|
|
@ -152,7 +152,8 @@ err:
|
|||
|
||||
BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *in_ctx)
|
||||
{
|
||||
BIGNUM *e;
|
||||
BIGNUM local_n;
|
||||
BIGNUM *e,*n;
|
||||
BN_CTX *ctx;
|
||||
BN_BLINDING *ret = NULL;
|
||||
|
||||
|
@ -191,7 +192,16 @@ BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *in_ctx)
|
|||
RAND_add(rsa->d->d, rsa->d->dmax * sizeof rsa->d->d[0], 0.0);
|
||||
}
|
||||
|
||||
ret = BN_BLINDING_create_param(NULL, e, rsa->n, ctx,
|
||||
if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
|
||||
{
|
||||
/* Set BN_FLG_CONSTTIME flag */
|
||||
n = &local_n;
|
||||
BN_with_flags(n, rsa->n, BN_FLG_CONSTTIME);
|
||||
}
|
||||
else
|
||||
n = rsa->n;
|
||||
|
||||
ret = BN_BLINDING_create_param(NULL, e, n, ctx,
|
||||
rsa->meth->bn_mod_exp, rsa->_method_mod_n);
|
||||
if (ret == NULL)
|
||||
{
|
||||
|
|
|
@ -242,7 +242,7 @@ int main(int argc, char *argv[])
|
|||
clen = key3(key, ctext_ex);
|
||||
break;
|
||||
}
|
||||
if (v/3 > 1) key->flags |= RSA_FLAG_NO_EXP_CONSTTIME;
|
||||
if (v/3 >= 1) key->flags |= RSA_FLAG_NO_CONSTTIME;
|
||||
|
||||
num = RSA_public_encrypt(plen, ptext_ex, ctext, key,
|
||||
RSA_PKCS1_PADDING);
|
||||
|
|
|
@ -154,7 +154,7 @@ static int generate_key(DH *dh)
|
|||
{
|
||||
BN_init(&local_prk);
|
||||
prk = &local_prk;
|
||||
BN_with_flags(prk, priv_key, BN_FLG_EXP_CONSTTIME);
|
||||
BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME);
|
||||
}
|
||||
else
|
||||
prk = priv_key;
|
||||
|
@ -202,7 +202,7 @@ static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
|
|||
if ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) == 0)
|
||||
{
|
||||
/* XXX */
|
||||
BN_set_flags(dh->priv_key, BN_FLG_EXP_CONSTTIME);
|
||||
BN_set_flags(dh->priv_key, BN_FLG_CONSTTIME);
|
||||
}
|
||||
if (!mont)
|
||||
goto err;
|
||||
|
|
|
@ -132,7 +132,7 @@ static int dsa_builtin_keygen(DSA *dsa)
|
|||
{
|
||||
BN_init(&local_prk);
|
||||
prk = &local_prk;
|
||||
BN_with_flags(prk, priv_key, BN_FLG_EXP_CONSTTIME);
|
||||
BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME);
|
||||
}
|
||||
else
|
||||
prk = priv_key;
|
||||
|
|
|
@ -214,7 +214,7 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
|
|||
while (BN_is_zero(&k));
|
||||
if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0)
|
||||
{
|
||||
BN_set_flags(&k, BN_FLG_EXP_CONSTTIME);
|
||||
BN_set_flags(&k, BN_FLG_CONSTTIME);
|
||||
}
|
||||
|
||||
if (dsa->flags & DSA_FLAG_CACHE_MONT_P)
|
||||
|
|
|
@ -442,11 +442,11 @@ static int RSA_eay_private_encrypt(int flen, const unsigned char *from,
|
|||
BIGNUM local_d;
|
||||
BIGNUM *d = NULL;
|
||||
|
||||
if (!(rsa->flags & RSA_FLAG_NO_EXP_CONSTTIME))
|
||||
if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
|
||||
{
|
||||
BN_init(&local_d);
|
||||
d = &local_d;
|
||||
BN_with_flags(d, rsa->d, BN_FLG_EXP_CONSTTIME);
|
||||
BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
|
||||
}
|
||||
else
|
||||
d = rsa->d;
|
||||
|
@ -570,10 +570,10 @@ static int RSA_eay_private_decrypt(int flen, const unsigned char *from,
|
|||
BIGNUM local_d;
|
||||
BIGNUM *d = NULL;
|
||||
|
||||
if (!(rsa->flags & RSA_FLAG_NO_EXP_CONSTTIME))
|
||||
if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
|
||||
{
|
||||
d = &local_d;
|
||||
BN_with_flags(d, rsa->d, BN_FLG_EXP_CONSTTIME);
|
||||
BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
|
||||
}
|
||||
else
|
||||
d = rsa->d;
|
||||
|
@ -740,8 +740,9 @@ err:
|
|||
static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
|
||||
{
|
||||
BIGNUM *r1,*m1,*vrfy;
|
||||
BIGNUM local_dmp1, local_dmq1;
|
||||
BIGNUM *dmp1, *dmq1;
|
||||
BIGNUM local_dmp1,local_dmq1,local_c,local_r1;
|
||||
BIGNUM *dmp1,*dmq1,*c,*pr1;
|
||||
int bn_flags;
|
||||
int ret=0;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
|
@ -749,26 +750,72 @@ static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
|
|||
m1 = BN_CTX_get(ctx);
|
||||
vrfy = BN_CTX_get(ctx);
|
||||
|
||||
/* Make sure mod_inverse in montgomerey intialization use correct
|
||||
* BN_FLG_CONSTTIME flag.
|
||||
*/
|
||||
bn_flags = rsa->p->flags;
|
||||
if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
|
||||
{
|
||||
rsa->p->flags |= BN_FLG_CONSTTIME;
|
||||
}
|
||||
MONT_HELPER(rsa, ctx, p, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err);
|
||||
/* We restore bn_flags back */
|
||||
rsa->p->flags = bn_flags;
|
||||
|
||||
/* Make sure mod_inverse in montgomerey intialization use correct
|
||||
* BN_FLG_CONSTTIME flag.
|
||||
*/
|
||||
bn_flags = rsa->q->flags;
|
||||
if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
|
||||
{
|
||||
rsa->q->flags |= BN_FLG_CONSTTIME;
|
||||
}
|
||||
MONT_HELPER(rsa, ctx, q, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err);
|
||||
/* We restore bn_flags back */
|
||||
rsa->q->flags = bn_flags;
|
||||
|
||||
MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err);
|
||||
|
||||
if (!BN_mod(r1,I,rsa->q,ctx)) goto err;
|
||||
if (!(rsa->flags & RSA_FLAG_NO_EXP_CONSTTIME))
|
||||
/* compute I mod q */
|
||||
if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
|
||||
{
|
||||
c = &local_c;
|
||||
BN_with_flags(c, I, BN_FLG_CONSTTIME);
|
||||
if (!BN_mod(r1,c,rsa->q,ctx)) goto err;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!BN_mod(r1,I,rsa->q,ctx)) goto err;
|
||||
}
|
||||
|
||||
/* compute r1^dmq1 mod q */
|
||||
if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
|
||||
{
|
||||
dmq1 = &local_dmq1;
|
||||
BN_with_flags(dmq1, rsa->dmq1, BN_FLG_EXP_CONSTTIME);
|
||||
BN_with_flags(dmq1, rsa->dmq1, BN_FLG_CONSTTIME);
|
||||
}
|
||||
else
|
||||
dmq1 = rsa->dmq1;
|
||||
if (!rsa->meth->bn_mod_exp(m1,r1,dmq1,rsa->q,ctx,
|
||||
rsa->_method_mod_q)) goto err;
|
||||
|
||||
if (!BN_mod(r1,I,rsa->p,ctx)) goto err;
|
||||
if (!(rsa->flags & RSA_FLAG_NO_EXP_CONSTTIME))
|
||||
/* compute I mod p */
|
||||
if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
|
||||
{
|
||||
c = &local_c;
|
||||
BN_with_flags(c, I, BN_FLG_CONSTTIME);
|
||||
if (!BN_mod(r1,c,rsa->p,ctx)) goto err;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!BN_mod(r1,I,rsa->p,ctx)) goto err;
|
||||
}
|
||||
|
||||
/* compute r1^dmp1 mod p */
|
||||
if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
|
||||
{
|
||||
dmp1 = &local_dmp1;
|
||||
BN_with_flags(dmp1, rsa->dmp1, BN_FLG_EXP_CONSTTIME);
|
||||
BN_with_flags(dmp1, rsa->dmp1, BN_FLG_CONSTTIME);
|
||||
}
|
||||
else
|
||||
dmp1 = rsa->dmp1;
|
||||
|
@ -782,7 +829,17 @@ static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
|
|||
if (!BN_add(r0,r0,rsa->p)) goto err;
|
||||
|
||||
if (!BN_mul(r1,r0,rsa->iqmp,ctx)) goto err;
|
||||
if (!BN_mod(r0,r1,rsa->p,ctx)) goto err;
|
||||
|
||||
/* Turn BN_FLG_CONSTTIME flag on before division operation */
|
||||
if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
|
||||
{
|
||||
pr1 = &local_r1;
|
||||
BN_with_flags(pr1, r1, BN_FLG_CONSTTIME);
|
||||
}
|
||||
else
|
||||
pr1 = r1;
|
||||
if (!BN_mod(r0,pr1,rsa->p,ctx)) goto err;
|
||||
|
||||
/* If p < q it is occasionally possible for the correction of
|
||||
* adding 'p' if r0 is negative above to leave the result still
|
||||
* negative. This can break the private key operations: the following
|
||||
|
@ -815,10 +872,10 @@ static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
|
|||
BIGNUM local_d;
|
||||
BIGNUM *d = NULL;
|
||||
|
||||
if (!(rsa->flags & RSA_FLAG_NO_EXP_CONSTTIME))
|
||||
if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
|
||||
{
|
||||
d = &local_d;
|
||||
BN_with_flags(d, rsa->d, BN_FLG_EXP_CONSTTIME);
|
||||
BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
|
||||
}
|
||||
else
|
||||
d = rsa->d;
|
||||
|
|
|
@ -152,6 +152,8 @@ int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb)
|
|||
static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb)
|
||||
{
|
||||
BIGNUM *r0=NULL,*r1=NULL,*r2=NULL,*r3=NULL,*tmp;
|
||||
BIGNUM local_r0,local_d,local_p;
|
||||
BIGNUM *pr0,*d,*p;
|
||||
int bitsp,bitsq,ok= -1,n=0;
|
||||
BN_CTX *ctx=NULL;
|
||||
|
||||
|
@ -244,16 +246,39 @@ static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb)
|
|||
if (!BN_sub(r1,rsa->p,BN_value_one())) goto err; /* p-1 */
|
||||
if (!BN_sub(r2,rsa->q,BN_value_one())) goto err; /* q-1 */
|
||||
if (!BN_mul(r0,r1,r2,ctx)) goto err; /* (p-1)(q-1) */
|
||||
if (!BN_mod_inverse(rsa->d,rsa->e,r0,ctx)) goto err; /* d */
|
||||
if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
|
||||
{
|
||||
pr0 = &local_r0;
|
||||
BN_with_flags(pr0, r0, BN_FLG_CONSTTIME);
|
||||
}
|
||||
else
|
||||
pr0 = r0;
|
||||
if (!BN_mod_inverse(rsa->d,rsa->e,pr0,ctx)) goto err; /* d */
|
||||
|
||||
/* set up d for correct BN_FLG_CONSTTIME flag */
|
||||
if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
|
||||
{
|
||||
d = &local_d;
|
||||
BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
|
||||
}
|
||||
else
|
||||
d = rsa->d;
|
||||
|
||||
/* calculate d mod (p-1) */
|
||||
if (!BN_mod(rsa->dmp1,rsa->d,r1,ctx)) goto err;
|
||||
if (!BN_mod(rsa->dmp1,d,r1,ctx)) goto err;
|
||||
|
||||
/* calculate d mod (q-1) */
|
||||
if (!BN_mod(rsa->dmq1,rsa->d,r2,ctx)) goto err;
|
||||
if (!BN_mod(rsa->dmq1,d,r2,ctx)) goto err;
|
||||
|
||||
/* calculate inverse of q mod p */
|
||||
if (!BN_mod_inverse(rsa->iqmp,rsa->q,rsa->p,ctx)) goto err;
|
||||
if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
|
||||
{
|
||||
p = &local_p;
|
||||
BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME);
|
||||
}
|
||||
else
|
||||
p = rsa->p;
|
||||
if (!BN_mod_inverse(rsa->iqmp,rsa->q,p,ctx)) goto err;
|
||||
|
||||
if(!fips_check_rsa(rsa))
|
||||
goto err;
|
||||
|
|
Loading…
Reference in a new issue