Permalink
Browse files

Update OpenSSL package for Ubuntu 13.04

Includes patches pulled from Ubuntu's saucy update with fixes for CVE-2014-0076
and CVE-2014-0160 (heartbleed).
  • Loading branch information...
1 parent ad77608 commit 72cf5750a4c522486fcbbc08cf7fc5dd20bf1bd3 @krobertson committed Apr 10, 2014
Showing with 275 additions and 2 deletions.
  1. +167 −0 packages/openssl/CVE-2014-0076.patch
  2. +94 −0 packages/openssl/CVE-2014-0160.patch
  3. +14 −2 packages/openssl/formula.rb
@@ -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
@@ -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.1e/ssl/d1_both.c
+===================================================================
+--- openssl-1.0.1e.orig/ssl/d1_both.c 2014-04-07 15:43:34.152341111 -0400
++++ openssl-1.0.1e/ssl/d1_both.c 2014-04-07 15:43:34.148341111 -0400
+@@ -1458,26 +1458,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 */
+@@ -1488,11 +1498,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.1e/ssl/t1_lib.c
+===================================================================
+--- openssl-1.0.1e.orig/ssl/t1_lib.c 2014-04-07 15:43:34.152341111 -0400
++++ openssl-1.0.1e/ssl/t1_lib.c 2014-04-07 15:43:34.148341111 -0400
+@@ -2486,16 +2486,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;
@@ -1,4 +1,16 @@
class OpenSSL < DebianSourceFormula
- url 'http://www.jp.backports.org/pool/main/o/openssl/openssl_0.9.8o-4~bpo50+1.dsc'
- md5 '0ce765777672340889a9cad03ee50fe6'
+ url 'http://archive.ubuntu.com/ubuntu/pool/main/o/openssl/openssl_1.0.1c-4ubuntu8.2.dsc'
+ md5 '4ef383f9233622981412a9c4c8818ae5'
+ version '1.0.1c-4ubuntu8.2apcera1'
+
+ def build
+ ENV['EDITOR'] = '/bin/true'
+ safe_system 'dpkg-source', '--commit', '.', 'brew2deb'
+ super
+ end
+
+ def patches
+ # packages retrieved from Ubuntu's openssl build for saucy on 2014-04-09
+ [ 'CVE-2014-0076.patch', 'CVE-2014-0160.patch' ]
+ end
end

0 comments on commit 72cf575

Please sign in to comment.