diff --git a/CVE-2014-0076.patch b/CVE-2014-0076.patch new file mode 100644 index 0000000..e784626 --- /dev/null +++ b/CVE-2014-0076.patch @@ -0,0 +1,150 @@ +Index: openssl-1.0.1f/crypto/bn/bn.h +=================================================================== +--- openssl-1.0.1f.orig/crypto/bn/bn.h ++++ openssl-1.0.1f/crypto/bn/bn.h +@@ -538,6 +538,8 @@ BIGNUM *BN_mod_inverse(BIGNUM *ret, + BIGNUM *BN_mod_sqrt(BIGNUM *ret, + const BIGNUM *a, const BIGNUM *n,BN_CTX *ctx); + ++void BN_consttime_swap(BN_ULONG swap, BIGNUM *a, BIGNUM *b, int nwords); ++ + /* Deprecated versions */ + #ifndef OPENSSL_NO_DEPRECATED + BIGNUM *BN_generate_prime(BIGNUM *ret,int bits,int safe, +@@ -774,12 +776,22 @@ int RAND_pseudo_bytes(unsigned char *buf + + #define bn_fix_top(a) bn_check_top(a) + ++#define bn_check_size(bn, bits) bn_wcheck_size(bn, ((bits+BN_BITS2-1))/BN_BITS2) ++#define bn_wcheck_size(bn, words) \ ++ do { \ ++ const BIGNUM *_bnum2 = (bn); \ ++ assert(words <= (_bnum2)->dmax && words >= (_bnum2)->top); \ ++ } while(0) ++ + #else /* !BN_DEBUG */ + + #define bn_pollute(a) + #define bn_check_top(a) + #define bn_fix_top(a) bn_correct_top(a) + ++#define bn_check_size(bn, bits) ++#define bn_wcheck_size(bn, words) ++ + #endif + + #define bn_correct_top(a) \ +Index: openssl-1.0.1f/crypto/bn/bn_lib.c +=================================================================== +--- openssl-1.0.1f.orig/crypto/bn/bn_lib.c ++++ openssl-1.0.1f/crypto/bn/bn_lib.c +@@ -824,3 +824,56 @@ int bn_cmp_part_words(const BN_ULONG *a, + } + return bn_cmp_words(a,b,cl); + } ++ ++/* ++ * Constant-time conditional swap of a and b. ++ * a and b are swapped if condition is not 0. The code assumes that at most one bit of condition is set. ++ * nwords is the number of words to swap. The code assumes that at least nwords are allocated in both a and b, ++ * and that no more than nwords are used by either a or b. ++ * a and b cannot be the same number ++ */ ++void BN_consttime_swap(BN_ULONG condition, BIGNUM *a, BIGNUM *b, int nwords) ++ { ++ BN_ULONG t; ++ int i; ++ ++ bn_wcheck_size(a, nwords); ++ bn_wcheck_size(b, nwords); ++ ++ assert(a != b); ++ assert((condition & (condition - 1)) == 0); ++ assert(sizeof(BN_ULONG) >= sizeof(int)); ++ ++ condition = ((condition - 1) >> (BN_BITS2 - 1)) - 1; ++ ++ t = (a->top^b->top) & condition; ++ a->top ^= t; ++ b->top ^= t; ++ ++#define BN_CONSTTIME_SWAP(ind) \ ++ do { \ ++ t = (a->d[ind] ^ b->d[ind]) & condition; \ ++ a->d[ind] ^= t; \ ++ b->d[ind] ^= t; \ ++ } while (0) ++ ++ ++ switch (nwords) { ++ default: ++ for (i = 10; i < nwords; i++) ++ BN_CONSTTIME_SWAP(i); ++ /* Fallthrough */ ++ case 10: BN_CONSTTIME_SWAP(9); /* Fallthrough */ ++ case 9: BN_CONSTTIME_SWAP(8); /* Fallthrough */ ++ case 8: BN_CONSTTIME_SWAP(7); /* Fallthrough */ ++ case 7: BN_CONSTTIME_SWAP(6); /* Fallthrough */ ++ case 6: BN_CONSTTIME_SWAP(5); /* Fallthrough */ ++ case 5: BN_CONSTTIME_SWAP(4); /* Fallthrough */ ++ case 4: BN_CONSTTIME_SWAP(3); /* Fallthrough */ ++ case 3: BN_CONSTTIME_SWAP(2); /* Fallthrough */ ++ case 2: BN_CONSTTIME_SWAP(1); /* Fallthrough */ ++ case 1: BN_CONSTTIME_SWAP(0); ++ } ++#undef BN_CONSTTIME_SWAP ++} ++ +Index: openssl-1.0.1f/crypto/ec/ec2_mult.c +=================================================================== +--- openssl-1.0.1f.orig/crypto/ec/ec2_mult.c ++++ openssl-1.0.1f/crypto/ec/ec2_mult.c +@@ -210,9 +210,12 @@ static int gf2m_Mxy(const EC_GROUP *grou + + /* Computes scalar*point and stores the result in r. + * point can not equal r. +- * Uses algorithm 2P of ++ * Uses a modified algorithm 2P of + * Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over + * GF(2^m) without precomputation" (CHES '99, LNCS 1717). ++ * ++ * To protect against side-channel attack the function uses constant time swap, ++ * avoiding conditional branches. + */ + static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, + const EC_POINT *point, BN_CTX *ctx) +@@ -246,6 +249,11 @@ static int ec_GF2m_montgomery_point_mult + x2 = &r->X; + z2 = &r->Y; + ++ bn_wexpand(x1, group->field.top); ++ bn_wexpand(z1, group->field.top); ++ bn_wexpand(x2, group->field.top); ++ bn_wexpand(z2, group->field.top); ++ + if (!BN_GF2m_mod_arr(x1, &point->X, group->poly)) goto err; /* x1 = x */ + if (!BN_one(z1)) goto err; /* z1 = 1 */ + if (!group->meth->field_sqr(group, z2, x1, ctx)) goto err; /* z2 = x1^2 = x^2 */ +@@ -270,16 +278,12 @@ static int ec_GF2m_montgomery_point_mult + word = scalar->d[i]; + while (mask) + { +- if (word & mask) +- { +- if (!gf2m_Madd(group, &point->X, x1, z1, x2, z2, ctx)) goto err; +- if (!gf2m_Mdouble(group, x2, z2, ctx)) goto err; +- } +- else +- { +- if (!gf2m_Madd(group, &point->X, x2, z2, x1, z1, ctx)) goto err; +- if (!gf2m_Mdouble(group, x1, z1, ctx)) goto err; +- } ++ BN_consttime_swap(word & mask, x1, x2, group->field.top); ++ BN_consttime_swap(word & mask, z1, z2, group->field.top); ++ if (!gf2m_Madd(group, &point->X, x2, z2, x1, z1, ctx)) goto err; ++ if (!gf2m_Mdouble(group, x1, z1, ctx)) goto err; ++ BN_consttime_swap(word & mask, x1, x2, group->field.top); ++ BN_consttime_swap(word & mask, z1, z2, group->field.top); + mask >>= 1; + } + mask = BN_TBIT; diff --git a/openssl.changes b/openssl.changes index dd31ec4..b081e45 100644 --- a/openssl.changes +++ b/openssl.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Tue Mar 25 08:11:11 UTC 2014 - shchang@suse.com + +- Fix bug[ bnc#869945] CVE-2014-0076: openssl: Recovering OpenSSL ECDSA Nonces Using the FLUSH+RELOAD Cache Side-channel Attack + Add file: CVE-2014-0076.patch + ------------------------------------------------------------------- Mon Mar 3 06:44:52 UTC 2014 - shchang@suse.com diff --git a/openssl.spec b/openssl.spec index 4081e1e..57f9061 100644 --- a/openssl.spec +++ b/openssl.spec @@ -64,6 +64,7 @@ Patch15: openssl-1.0.1e-fips.patch Patch16: openssl-1.0.1e-fips-ec.patch Patch17: openssl-1.0.1e-fips-ctor.patch Patch18: openssl-1.0.1e-new-fips-reqs.patch +Patch19: CVE-2014-0076.patch BuildRoot: %{_tmppath}/%{name}-%{version}-build %description @@ -169,6 +170,7 @@ this package's base documentation. %patch16 -p1 %patch17 -p1 %patch18 -p1 +%patch19 -p1 cp -p %{S:10} . cp -p %{S:11} .