[prev in list] [next in list] [prev in thread] [next in thread] 

List:       openssl-cvs
Subject:    [CVS] OpenSSL: OpenSSL-fips-0_9_8-stable: openssl/ CHANGES openssl/cry...
From:       "Dr. Stephen Henson" <steve () openssl ! org>
Date:       2007-03-28 12:38:56
Message-ID: 20070328123856.F049E1AC606F () master ! openssl ! org
[Download RAW message or body]

  OpenSSL CVS Repository
  http://cvs.openssl.org/
  ____________________________________________________________________________

  Server: cvs.openssl.org                  Name:   Dr. Stephen Henson
  Root:   /v/openssl/cvs                   Email:  steve@openssl.org
  Module: openssl                          Date:   28-Mar-2007 14:38:56
  Branch: OpenSSL-fips-0_9_8-stable        Handle: 2007032813384708

  Modified files:           (Branch: OpenSSL-fips-0_9_8-stable)
    openssl                 CHANGES
    openssl/crypto/bn       bn.h bn_blind.c bn_div.c bn_exp.c bn_gcd.c
                            bn_lib.c
    openssl/crypto/dh       dh_key.c
    openssl/crypto/dsa      dsa_key.c dsa_ossl.c
    openssl/crypto/rsa      rsa.h rsa_eay.c rsa_gen.c rsa_lib.c rsa_test.c
    openssl/fips-1.0/dh     fips_dh_key.c
    openssl/fips-1.0/dsa    fips_dsa_key.c fips_dsa_ossl.c
    openssl/fips-1.0/rsa    fips_rsa_eay.c fips_rsa_gen.c

  Log:
    Update from 0.9.8-stable with patches also applied to equivalent FIPS
    sources.

  Summary:
    Revision    Changes     Path
    1.1238.2.65.2.5+37 -0      openssl/CHANGES
    1.100.2.6.2.2+18 -4      openssl/crypto/bn/bn.h
    1.9.2.1.2.1 +9  -3      openssl/crypto/bn/bn_blind.c
    1.37.2.1.2.1+229 -0     openssl/crypto/bn/bn_div.c
    1.27.4.1    +10 -10     openssl/crypto/bn/bn_exp.c
    1.18.2.1.2.1+159 -0     openssl/crypto/bn/bn_gcd.c
    1.63.2.1.2.2+1  -1      openssl/crypto/bn/bn_lib.c
    1.24.2.5.2.2+2  -2      openssl/crypto/dh/dh_key.c
    1.12.2.1.2.2+1  -1      openssl/crypto/dsa/dsa_key.c
    1.24.2.2.2.2+1  -1      openssl/crypto/dsa/dsa_ossl.c
    1.55.2.7.2.2+15 -1      openssl/crypto/rsa/rsa.h
    1.46.2.7.2.2+72 -15     openssl/crypto/rsa/rsa_eay.c
    1.17.2.1.2.2+29 -4      openssl/crypto/rsa/rsa_gen.c
    1.39.2.3.2.2+12 -2      openssl/crypto/rsa/rsa_lib.c
    1.13.4.1    +1  -1      openssl/crypto/rsa/rsa_test.c
    1.1.4.3     +2  -2      openssl/fips-1.0/dh/fips_dh_key.c
    1.1.2.2     +1  -1      openssl/fips-1.0/dsa/fips_dsa_key.c
    1.1.4.3     +1  -1      openssl/fips-1.0/dsa/fips_dsa_ossl.c
    1.1.4.3     +72 -15     openssl/fips-1.0/rsa/fips_rsa_eay.c
    1.1.4.3     +29 -4      openssl/fips-1.0/rsa/fips_rsa_gen.c
  ____________________________________________________________________________

  patch -p0 <<'@@ .'
  Index: openssl/CHANGES
  ============================================================================
  $ cvs diff -u -r1.1238.2.65.2.4 -r1.1238.2.65.2.5 CHANGES
  --- openssl/CHANGES	27 Mar 2007 00:03:40 -0000	1.1238.2.65.2.4
  +++ openssl/CHANGES	28 Mar 2007 12:38:47 -0000	1.1238.2.65.2.5
  @@ -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,
  @@ .
  patch -p0 <<'@@ .'
  Index: openssl/crypto/bn/bn.h
  ============================================================================
  $ cvs diff -u -r1.100.2.6.2.1 -r1.100.2.6.2.2 bn.h
  --- openssl/crypto/bn/bn.h	22 Mar 2007 00:37:53 -0000	1.100.2.6.2.1
  +++ openssl/crypto/bn/bn.h	28 Mar 2007 12:38:49 -0000	1.100.2.6.2.2
  @@ -245,8 +245,18 @@
   
   #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 @@
   
   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_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 @@
   #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 @@
   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);
  @@ .
  patch -p0 <<'@@ .'
  Index: openssl/crypto/bn/bn_blind.c
  ============================================================================
  $ cvs diff -u -r1.9.2.1 -r1.9.2.1.2.1 bn_blind.c
  --- openssl/crypto/bn/bn_blind.c	26 May 2005 04:30:48 -0000	1.9.2.1
  +++ openssl/crypto/bn/bn_blind.c	28 Mar 2007 12:38:49 -0000	1.9.2.1.2.1
  @@ -131,7 +131,7 @@
   			  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 @@
   		{
   		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 @@
   	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 @@
   	}
   
   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)
  @@ .
  patch -p0 <<'@@ .'
  Index: openssl/crypto/bn/bn_div.c
  ============================================================================
  $ cvs diff -u -r1.37.2.1 -r1.37.2.1.2.1 bn_div.c
  --- openssl/crypto/bn/bn_div.c	28 Aug 2005 23:20:43 -0000	1.37.2.1
  +++ openssl/crypto/bn/bn_div.c	28 Mar 2007 12:38:49 -0000	1.37.2.1.2.1
  @@ -185,6 +185,11 @@
   	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);
  @@ -397,4 +402,228 @@
   	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)
  +			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);
  +	}
  +
   #endif
  @@ .
  patch -p0 <<'@@ .'
  Index: openssl/crypto/bn/bn_exp.c
  ============================================================================
  $ cvs diff -u -r1.27 -r1.27.4.1 bn_exp.c
  --- openssl/crypto/bn/bn_exp.c	16 May 2005 01:43:29 -0000	1.27
  +++ openssl/crypto/bn/bn_exp.c	28 Mar 2007 12:38:50 -0000	1.27.4.1
  @@ -122,9 +122,9 @@
   	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 @@
   	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 @@
   	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 @@
   	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 @@
   #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 @@
   	/* 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;
   		}
  @@ .
  patch -p0 <<'@@ .'
  Index: openssl/crypto/bn/bn_gcd.c
  ============================================================================
  $ cvs diff -u -r1.18.2.1 -r1.18.2.1.2.1 bn_gcd.c
  --- openssl/crypto/bn/bn_gcd.c	28 Aug 2005 23:20:43 -0000	1.18.2.1
  +++ openssl/crypto/bn/bn_gcd.c	28 Mar 2007 12:38:50 -0000	1.18.2.1.2.1
  @@ -210,6 +210,11 @@
   	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 @@
   	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);
  +	}
  @@ .
  patch -p0 <<'@@ .'
  Index: openssl/crypto/bn/bn_lib.c
  ============================================================================
  $ cvs diff -u -r1.63.2.1.2.1 -r1.63.2.1.2.2 bn_lib.c
  --- openssl/crypto/bn/bn_lib.c	22 Mar 2007 00:37:53 -0000	1.63.2.1.2.1
  +++ openssl/crypto/bn/bn_lib.c	28 Mar 2007 12:38:50 -0000	1.63.2.1.2.2
  @@ -744,7 +744,7 @@
   	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)
  @@ .
  patch -p0 <<'@@ .'
  Index: openssl/crypto/dh/dh_key.c
  ============================================================================
  $ cvs diff -u -r1.24.2.5.2.1 -r1.24.2.5.2.2 dh_key.c
  --- openssl/crypto/dh/dh_key.c	22 Mar 2007 00:38:00 -0000	1.24.2.5.2.1
  +++ openssl/crypto/dh/dh_key.c	28 Mar 2007 12:38:51 -0000	1.24.2.5.2.2
  @@ -152,7 +152,7 @@
   			{
   			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 @@
   		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;
  @@ .
  patch -p0 <<'@@ .'
  Index: openssl/crypto/dsa/dsa_key.c
  ============================================================================
  $ cvs diff -u -r1.12.2.1.2.1 -r1.12.2.1.2.2 dsa_key.c
  --- openssl/crypto/dsa/dsa_key.c	22 Mar 2007 00:38:02 -0000	1.12.2.1.2.1
  +++ openssl/crypto/dsa/dsa_key.c	28 Mar 2007 12:38:51 -0000	1.12.2.1.2.2
  @@ -109,7 +109,7 @@
   			{
   			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;
  @@ .
  patch -p0 <<'@@ .'
  Index: openssl/crypto/dsa/dsa_ossl.c
  ============================================================================
  $ cvs diff -u -r1.24.2.2.2.1 -r1.24.2.2.2.2 dsa_ossl.c
  --- openssl/crypto/dsa/dsa_ossl.c	22 Mar 2007 00:38:02 -0000	1.24.2.2.2.1
  +++ openssl/crypto/dsa/dsa_ossl.c	28 Mar 2007 12:38:51 -0000	1.24.2.2.2.2
  @@ -231,7 +231,7 @@
   	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)
  @@ .
  patch -p0 <<'@@ .'
  Index: openssl/crypto/rsa/rsa.h
  ============================================================================
  $ cvs diff -u -r1.55.2.7.2.1 -r1.55.2.7.2.2 rsa.h
  --- openssl/crypto/rsa/rsa.h	22 Mar 2007 00:38:34 -0000	1.55.2.7.2.1
  +++ openssl/crypto/rsa/rsa.h	28 Mar 2007 12:38:52 -0000	1.55.2.7.2.2
  @@ -199,13 +199,27 @@
                                                   * 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
  @@ .
  patch -p0 <<'@@ .'
  Index: openssl/crypto/rsa/rsa_eay.c
  ============================================================================
  $ cvs diff -u -r1.46.2.7.2.1 -r1.46.2.7.2.2 rsa_eay.c
  --- openssl/crypto/rsa/rsa_eay.c	22 Mar 2007 00:38:34 -0000	1.46.2.7.2.1
  +++ openssl/crypto/rsa/rsa_eay.c	28 Mar 2007 12:38:52 -0000	1.46.2.7.2.2
  @@ -429,11 +429,11 @@
   		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 @@
   		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 @@
   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 @@
   	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 @@
   		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 @@
   			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;
  @@ .
  patch -p0 <<'@@ .'
  Index: openssl/crypto/rsa/rsa_gen.c
  ============================================================================
  $ cvs diff -u -r1.17.2.1.2.1 -r1.17.2.1.2.2 rsa_gen.c
  --- openssl/crypto/rsa/rsa_gen.c	22 Mar 2007 00:38:34 -0000	1.17.2.1.2.1
  +++ openssl/crypto/rsa/rsa_gen.c	28 Mar 2007 12:38:53 -0000	1.17.2.1.2.2
  @@ -87,6 +87,8 @@
   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 @@
   	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:
  @@ .
  patch -p0 <<'@@ .'
  Index: openssl/crypto/rsa/rsa_lib.c
  ============================================================================
  $ cvs diff -u -r1.39.2.3.2.1 -r1.39.2.3.2.2 rsa_lib.c
  --- openssl/crypto/rsa/rsa_lib.c	22 Mar 2007 00:38:34 -0000	1.39.2.3.2.1
  +++ openssl/crypto/rsa/rsa_lib.c	28 Mar 2007 12:38:53 -0000	1.39.2.3.2.2
  @@ -152,7 +152,8 @@
   
   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 @@
   		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)
   		{
  @@ .
  patch -p0 <<'@@ .'
  Index: openssl/crypto/rsa/rsa_test.c
  ============================================================================
  $ cvs diff -u -r1.13 -r1.13.4.1 rsa_test.c
  --- openssl/crypto/rsa/rsa_test.c	16 May 2005 01:43:31 -0000	1.13
  +++ openssl/crypto/rsa/rsa_test.c	28 Mar 2007 12:38:53 -0000	1.13.4.1
  @@ -242,7 +242,7 @@
   	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);
  @@ .
  patch -p0 <<'@@ .'
  Index: openssl/fips-1.0/dh/fips_dh_key.c
  ============================================================================
  $ cvs diff -u -r1.1.4.2 -r1.1.4.3 fips_dh_key.c
  --- openssl/fips-1.0/dh/fips_dh_key.c	22 Mar 2007 00:38:56 -0000	1.1.4.2
  +++ openssl/fips-1.0/dh/fips_dh_key.c	28 Mar 2007 12:38:54 -0000	1.1.4.3
  @@ -154,7 +154,7 @@
   			{
   			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 @@
   		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;
  @@ .
  patch -p0 <<'@@ .'
  Index: openssl/fips-1.0/dsa/fips_dsa_key.c
  ============================================================================
  $ cvs diff -u -r1.1.2.1 -r1.1.2.2 fips_dsa_key.c
  --- openssl/fips-1.0/dsa/fips_dsa_key.c	22 Mar 2007 00:38:58 -0000	1.1.2.1
  +++ openssl/fips-1.0/dsa/fips_dsa_key.c	28 Mar 2007 12:38:54 -0000	1.1.2.2
  @@ -132,7 +132,7 @@
   			{
   			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;
  @@ .
  patch -p0 <<'@@ .'
  Index: openssl/fips-1.0/dsa/fips_dsa_ossl.c
  ============================================================================
  $ cvs diff -u -r1.1.4.2 -r1.1.4.3 fips_dsa_ossl.c
  --- openssl/fips-1.0/dsa/fips_dsa_ossl.c	22 Mar 2007 00:38:58 -0000	1.1.4.2
  +++ openssl/fips-1.0/dsa/fips_dsa_ossl.c	28 Mar 2007 12:38:54 -0000	1.1.4.3
  @@ -214,7 +214,7 @@
   	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)
  @@ .
  patch -p0 <<'@@ .'
  Index: openssl/fips-1.0/rsa/fips_rsa_eay.c
  ============================================================================
  $ cvs diff -u -r1.1.4.2 -r1.1.4.3 fips_rsa_eay.c
  --- openssl/fips-1.0/rsa/fips_rsa_eay.c	22 Mar 2007 00:39:04 -0000	1.1.4.2
  +++ openssl/fips-1.0/rsa/fips_rsa_eay.c	28 Mar 2007 12:38:55 -0000	1.1.4.3
  @@ -442,11 +442,11 @@
   		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 @@
   		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 @@
   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 @@
   	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 @@
   		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 @@
   			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;
  @@ .
  patch -p0 <<'@@ .'
  Index: openssl/fips-1.0/rsa/fips_rsa_gen.c
  ============================================================================
  $ cvs diff -u -r1.1.4.2 -r1.1.4.3 fips_rsa_gen.c
  --- openssl/fips-1.0/rsa/fips_rsa_gen.c	22 Mar 2007 00:39:04 -0000	1.1.4.2
  +++ openssl/fips-1.0/rsa/fips_rsa_gen.c	28 Mar 2007 12:38:55 -0000	1.1.4.3
  @@ -152,6 +152,8 @@
   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 @@
   	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;
  @@ .
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
CVS Repository Commit List                     openssl-cvs@openssl.org
Automated List Manager                           majordomo@openssl.org

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic