components/openssl/openssl-1.0.0/patches/37-cve-2014-0076.patch
branchs11u1sru20-backport
changeset 3173 c059623861df
parent 3148 bb9303d6e615
child 3174 3b5835d4aaf3
equal deleted inserted replaced
3148:bb9303d6e615 3173:c059623861df
     1 Patch comes from upstream:
       
     2   http://git.openssl.org/gitweb/?p=openssl.git;a=commit;h=2198be3483259de374f91e57d247d0fc667aef29
       
     3 It will be obsoleted when openssl-1.0.0m is available.
       
     4 
       
     5 --- openssl-1.0.0l/crypto/bn/bn.h.orig	Mon Jan  6 07:00:59 2014
       
     6 +++ openssl-1.0.0l/crypto/bn/bn.h		Fri Apr 18 13:03:57 2014
       
     7 @@ -538,6 +538,8 @@
       
     8  BIGNUM *BN_mod_sqrt(BIGNUM *ret,
       
     9  	const BIGNUM *a, const BIGNUM *n,BN_CTX *ctx);
       
    10  
       
    11 +void	BN_consttime_swap(BN_ULONG swap, BIGNUM *a, BIGNUM *b, int nwords);
       
    12 +
       
    13  /* Deprecated versions */
       
    14  #ifndef OPENSSL_NO_DEPRECATED
       
    15  BIGNUM *BN_generate_prime(BIGNUM *ret,int bits,int safe,
       
    16 @@ -759,11 +761,20 @@
       
    17  
       
    18  #define bn_fix_top(a)		bn_check_top(a)
       
    19  
       
    20 +#define bn_check_size(bn, bits) bn_wcheck_size(bn, ((bits+BN_BITS2-1))/BN_BITS2)
       
    21 +#define bn_wcheck_size(bn, words) \
       
    22 +	do { \
       
    23 +		const BIGNUM *_bnum2 = (bn); \
       
    24 +		assert(words <= (_bnum2)->dmax && words >= (_bnum2)->top); \
       
    25 +	} while(0)
       
    26 +
       
    27  #else /* !BN_DEBUG */
       
    28  
       
    29  #define bn_pollute(a)
       
    30  #define bn_check_top(a)
       
    31  #define bn_fix_top(a)		bn_correct_top(a)
       
    32 +#define bn_check_size(bn, bits)
       
    33 +#define bn_wcheck_size(bn, words)
       
    34  
       
    35  #endif
       
    36  
       
    37 --- openssl-1.0.0l/crypto/bn/bn_lib.c.orig	Mon Jan  6 07:00:59 2014
       
    38 +++ openssl-1.0.0l/crypto/bn/bn_lib.c		Fri Apr 18 13:03:08 2014
       
    39 @@ -843,3 +843,55 @@
       
    40  		}
       
    41  	return bn_cmp_words(a,b,cl);
       
    42  	}
       
    43 +
       
    44 +/* 
       
    45 + * Constant-time conditional swap of a and b.  
       
    46 + * a and b are swapped if condition is not 0.  The code assumes that at most one bit of condition is set.
       
    47 + * nwords is the number of words to swap.  The code assumes that at least nwords are allocated in both a and b,
       
    48 + * and that no more than nwords are used by either a or b.
       
    49 + * a and b cannot be the same number
       
    50 + */
       
    51 +void BN_consttime_swap(BN_ULONG condition, BIGNUM *a, BIGNUM *b, int nwords)
       
    52 +	{
       
    53 +	BN_ULONG t;
       
    54 +	int i;
       
    55 +
       
    56 +	bn_wcheck_size(a, nwords);
       
    57 +	bn_wcheck_size(b, nwords);
       
    58 +
       
    59 +	assert(a != b);
       
    60 +	assert((condition & (condition - 1)) == 0);
       
    61 +	assert(sizeof(BN_ULONG) >= sizeof(int));
       
    62 +
       
    63 +	condition = ((condition - 1) >> (BN_BITS2 - 1)) - 1;
       
    64 +
       
    65 +	t = (a->top^b->top) & condition;
       
    66 +	a->top ^= t;
       
    67 +	b->top ^= t;
       
    68 +
       
    69 +#define BN_CONSTTIME_SWAP(ind) \
       
    70 +	do { \
       
    71 +		t = (a->d[ind] ^ b->d[ind]) & condition; \
       
    72 +		a->d[ind] ^= t; \
       
    73 +		b->d[ind] ^= t; \
       
    74 +	} while (0)
       
    75 +
       
    76 +
       
    77 +	switch (nwords) {
       
    78 +	default:
       
    79 +		for (i = 10; i < nwords; i++) 
       
    80 +			BN_CONSTTIME_SWAP(i);
       
    81 +		/* Fallthrough */
       
    82 +	case 10: BN_CONSTTIME_SWAP(9); /* Fallthrough */
       
    83 +	case 9: BN_CONSTTIME_SWAP(8); /* Fallthrough */
       
    84 +	case 8: BN_CONSTTIME_SWAP(7); /* Fallthrough */
       
    85 +	case 7: BN_CONSTTIME_SWAP(6); /* Fallthrough */
       
    86 +	case 6: BN_CONSTTIME_SWAP(5); /* Fallthrough */
       
    87 +	case 5: BN_CONSTTIME_SWAP(4); /* Fallthrough */
       
    88 +	case 4: BN_CONSTTIME_SWAP(3); /* Fallthrough */
       
    89 +	case 3: BN_CONSTTIME_SWAP(2); /* Fallthrough */
       
    90 +	case 2: BN_CONSTTIME_SWAP(1); /* Fallthrough */
       
    91 +	case 1: BN_CONSTTIME_SWAP(0);
       
    92 +	}
       
    93 +#undef BN_CONSTTIME_SWAP
       
    94 +}
       
    95 --- openssl-1.0.0l/crypto/ec/ec2_mult.c.orig	Mon Jan  6 07:00:59 2014
       
    96 +++ openssl-1.0.0l/crypto/ec/ec2_mult.c	Fri Apr 18 13:00:28 2014
       
    97 @@ -206,11 +206,15 @@
       
    98  	return ret;
       
    99  	}
       
   100  
       
   101 +
       
   102  /* Computes scalar*point and stores the result in r.
       
   103   * point can not equal r.
       
   104 - * Uses algorithm 2P of
       
   105 + * Uses a modified algorithm 2P of
       
   106   *     Lopez, J. and Dahab, R.  "Fast multiplication on elliptic curves over 
       
   107   *     GF(2^m) without precomputation" (CHES '99, LNCS 1717).
       
   108 + *
       
   109 + * To protect against side-channel attack the function uses constant time swap,
       
   110 + * avoiding conditional branches.
       
   111   */
       
   112  static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
       
   113  	const EC_POINT *point, BN_CTX *ctx)
       
   114 @@ -244,6 +248,11 @@
       
   115  	x2 = &r->X;
       
   116  	z2 = &r->Y;
       
   117  
       
   118 +	bn_wexpand(x1, group->field.top);
       
   119 +	bn_wexpand(z1, group->field.top);
       
   120 +	bn_wexpand(x2, group->field.top);
       
   121 +	bn_wexpand(z2, group->field.top);
       
   122 +
       
   123  	if (!BN_GF2m_mod_arr(x1, &point->X, group->poly)) goto err; /* x1 = x */
       
   124  	if (!BN_one(z1)) goto err; /* z1 = 1 */
       
   125  	if (!group->meth->field_sqr(group, z2, x1, ctx)) goto err; /* z2 = x1^2 = x^2 */
       
   126 @@ -268,16 +277,12 @@
       
   127  		word = scalar->d[i];
       
   128  		while (mask)
       
   129  			{
       
   130 -			if (word & mask)
       
   131 -				{
       
   132 -				if (!gf2m_Madd(group, &point->X, x1, z1, x2, z2, ctx)) goto err;
       
   133 -				if (!gf2m_Mdouble(group, x2, z2, ctx)) goto err;
       
   134 -				}
       
   135 -			else
       
   136 -				{
       
   137 -				if (!gf2m_Madd(group, &point->X, x2, z2, x1, z1, ctx)) goto err;
       
   138 -				if (!gf2m_Mdouble(group, x1, z1, ctx)) goto err;
       
   139 -				}
       
   140 +			BN_consttime_swap(word & mask, x1, x2, group->field.top);
       
   141 +			BN_consttime_swap(word & mask, z1, z2, group->field.top);
       
   142 +			if (!gf2m_Madd(group, &point->X, x2, z2, x1, z1, ctx)) goto err;
       
   143 +			if (!gf2m_Mdouble(group, x1, z1, ctx)) goto err;
       
   144 +			BN_consttime_swap(word & mask, x1, x2, group->field.top);
       
   145 +			BN_consttime_swap(word & mask, z1, z2, group->field.top);
       
   146  			mask >>= 1;
       
   147  			}
       
   148  		mask = BN_TBIT;