diff -Nru openssl-1.0.1f/debian/changelog openssl-1.0.1f/debian/changelog --- openssl-1.0.1f/debian/changelog 2014-01-08 21:29:36.000000000 +0000 +++ openssl-1.0.1f/debian/changelog 2014-04-07 19:40:59.000000000 +0000 @@ -1,3 +1,17 @@ +openssl (1.0.1f-1ubuntu2) trusty; urgency=medium + + * SECURITY UPDATE: side-channel attack on Montgomery ladder implementation + - debian/patches/CVE-2014-0076.patch: add and use constant time swap in + crypto/bn/bn.h, crypto/bn/bn_lib.c, crypto/ec/ec2_mult.c, + util/libeay.num. + - CVE-2014-0076 + * SECURITY UPDATE: memory disclosure in TLS heartbeat extension + - debian/patches/CVE-2014-0160.patch: use correct lengths in + ssl/d1_both.c, ssl/t1_lib.c. + - CVE-2014-0160 + + -- Marc Deslauriers Mon, 07 Apr 2014 15:37:53 -0400 + openssl (1.0.1f-1ubuntu1) trusty; urgency=low * Merge with Debian, remaining changes. diff -Nru openssl-1.0.1f/debian/patches/CVE-2014-0076.patch openssl-1.0.1f/debian/patches/CVE-2014-0076.patch --- openssl-1.0.1f/debian/patches/CVE-2014-0076.patch 1970-01-01 00:00:00.000000000 +0000 +++ openssl-1.0.1f/debian/patches/CVE-2014-0076.patch 2014-04-07 19:41:56.000000000 +0000 @@ -0,0 +1,167 @@ +Description: fix side-channel attack on Montgomery ladder implementation +Origin: upstream, http://git.openssl.org/gitweb/?p=openssl.git;a=commit;h=4b7a4ba29cafa432fc4266fe6e59e60bc1c96332 +Origin: upstream, http://git.openssl.org/gitweb/?p=openssl.git;a=commit;h=40acdb192e035f463d3c39c23fd8a68cf54df378 +Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=742923 + +Index: openssl-1.0.1f/crypto/bn/bn.h +=================================================================== +--- openssl-1.0.1f.orig/crypto/bn/bn.h 2014-01-06 08:47:42.000000000 -0500 ++++ openssl-1.0.1f/crypto/bn/bn.h 2014-04-07 15:37:00.924343048 -0400 +@@ -538,6 +538,8 @@ + 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,11 +776,20 @@ + + #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 + +Index: openssl-1.0.1f/crypto/bn/bn_lib.c +=================================================================== +--- openssl-1.0.1f.orig/crypto/bn/bn_lib.c 2014-01-06 08:47:42.000000000 -0500 ++++ openssl-1.0.1f/crypto/bn/bn_lib.c 2014-04-07 15:37:00.924343048 -0400 +@@ -824,3 +824,55 @@ + } + 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 2014-01-06 08:47:42.000000000 -0500 ++++ openssl-1.0.1f/crypto/ec/ec2_mult.c 2014-04-07 15:37:00.924343048 -0400 +@@ -208,11 +208,15 @@ + return ret; + } + ++ + /* 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 +250,11 @@ + 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 +279,12 @@ + 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; +Index: openssl-1.0.1f/util/libeay.num +=================================================================== +--- openssl-1.0.1f.orig/util/libeay.num 2014-01-06 09:35:55.000000000 -0500 ++++ openssl-1.0.1f/util/libeay.num 2014-04-07 15:37:03.976343033 -0400 +@@ -3511,6 +3511,7 @@ + d2i_ASIdOrRange 3904 EXIST::FUNCTION:RFC3779 + i2d_ASIdentifiers 3905 EXIST::FUNCTION:RFC3779 + CRYPTO_memcmp 3906 EXIST::FUNCTION: ++BN_consttime_swap 3907 EXIST::FUNCTION: + SEED_decrypt 3908 EXIST::FUNCTION:SEED + SEED_encrypt 3909 EXIST::FUNCTION:SEED + SEED_cbc_encrypt 3910 EXIST::FUNCTION:SEED diff -Nru openssl-1.0.1f/debian/patches/CVE-2014-0160.patch openssl-1.0.1f/debian/patches/CVE-2014-0160.patch --- openssl-1.0.1f/debian/patches/CVE-2014-0160.patch 1970-01-01 00:00:00.000000000 +0000 +++ openssl-1.0.1f/debian/patches/CVE-2014-0160.patch 2014-04-07 19:42:20.000000000 +0000 @@ -0,0 +1,94 @@ +Description: fix memory disclosure in TLS heartbeat extension +Origin: upstream, http://git.openssl.org/gitweb/?p=openssl.git;a=commit;h=96db9023b881d7cd9f379b0c154650d6c108e9a3 + +Index: openssl-1.0.1f/ssl/d1_both.c +=================================================================== +--- openssl-1.0.1f.orig/ssl/d1_both.c 2014-01-06 08:47:42.000000000 -0500 ++++ openssl-1.0.1f/ssl/d1_both.c 2014-04-07 15:37:38.548342862 -0400 +@@ -1459,26 +1459,36 @@ + unsigned int payload; + unsigned int padding = 16; /* Use minimum padding */ + +- /* Read type and payload length first */ +- hbtype = *p++; +- n2s(p, payload); +- pl = p; +- + if (s->msg_callback) + s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT, + &s->s3->rrec.data[0], s->s3->rrec.length, + s, s->msg_callback_arg); + ++ /* Read type and payload length first */ ++ if (1 + 2 + 16 > s->s3->rrec.length) ++ return 0; /* silently discard */ ++ hbtype = *p++; ++ n2s(p, payload); ++ if (1 + 2 + payload + 16 > s->s3->rrec.length) ++ return 0; /* silently discard per RFC 6520 sec. 4 */ ++ pl = p; ++ + if (hbtype == TLS1_HB_REQUEST) + { + unsigned char *buffer, *bp; ++ unsigned int write_length = 1 /* heartbeat type */ + ++ 2 /* heartbeat length */ + ++ payload + padding; + int r; + ++ if (write_length > SSL3_RT_MAX_PLAIN_LENGTH) ++ return 0; ++ + /* Allocate memory for the response, size is 1 byte + * message type, plus 2 bytes payload length, plus + * payload, plus padding + */ +- buffer = OPENSSL_malloc(1 + 2 + payload + padding); ++ buffer = OPENSSL_malloc(write_length); + bp = buffer; + + /* Enter response type, length and copy payload */ +@@ -1489,11 +1499,11 @@ + /* Random padding */ + RAND_pseudo_bytes(bp, padding); + +- r = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, 3 + payload + padding); ++ r = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, write_length); + + if (r >= 0 && s->msg_callback) + s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT, +- buffer, 3 + payload + padding, ++ buffer, write_length, + s, s->msg_callback_arg); + + OPENSSL_free(buffer); +Index: openssl-1.0.1f/ssl/t1_lib.c +=================================================================== +--- openssl-1.0.1f.orig/ssl/t1_lib.c 2014-01-06 08:47:42.000000000 -0500 ++++ openssl-1.0.1f/ssl/t1_lib.c 2014-04-07 15:37:38.548342862 -0400 +@@ -2558,16 +2558,20 @@ + unsigned int payload; + unsigned int padding = 16; /* Use minimum padding */ + +- /* Read type and payload length first */ +- hbtype = *p++; +- n2s(p, payload); +- pl = p; +- + if (s->msg_callback) + s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT, + &s->s3->rrec.data[0], s->s3->rrec.length, + s, s->msg_callback_arg); + ++ /* Read type and payload length first */ ++ if (1 + 2 + 16 > s->s3->rrec.length) ++ return 0; /* silently discard */ ++ hbtype = *p++; ++ n2s(p, payload); ++ if (1 + 2 + payload + 16 > s->s3->rrec.length) ++ return 0; /* silently discard per RFC 6520 sec. 4 */ ++ pl = p; ++ + if (hbtype == TLS1_HB_REQUEST) + { + unsigned char *buffer, *bp; diff -Nru openssl-1.0.1f/debian/patches/series openssl-1.0.1f/debian/patches/series --- openssl-1.0.1f/debian/patches/series 2014-01-08 20:57:20.000000000 +0000 +++ openssl-1.0.1f/debian/patches/series 2014-04-07 19:37:33.000000000 +0000 @@ -34,3 +34,5 @@ req_bits.patch perlpath-quilt.patch ppc64-support +CVE-2014-0076.patch +CVE-2014-0160.patch