aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNatanael Copa <ncopa@alpinelinux.org>2013-04-11 13:10:14 +0000
committerNatanael Copa <ncopa@alpinelinux.org>2013-04-11 13:28:14 +0000
commit47656f3ce258fd3968b8f4dc2c27c2fa4e71a70d (patch)
tree1a7e73b6231545f5a2d492ec887cb4ac3dbab03d
parentce3adccd9865fd634d89940731b9c81c178a9b4c (diff)
downloadaports-47656f3ce258fd3968b8f4dc2c27c2fa4e71a70d.tar.bz2
aports-47656f3ce258fd3968b8f4dc2c27c2fa4e71a70d.tar.xz
main/gnutls: security fix (CVE-2013-1619)
Patch from ubuntu: https://launchpadlibrarian.net/132499561/gnutls26_2.10.5-1ubuntu3.2_2.10.5-1ubuntu3.3.diff.gz fixes #1657
-rw-r--r--main/gnutls/APKBUILD10
-rw-r--r--main/gnutls/CVE-2011-4128.patch24
-rw-r--r--main/gnutls/CVE-2012-1573.patch27
-rw-r--r--main/gnutls/CVE-2013-1619.patch178
-rw-r--r--main/gnutls/cve-2012-1573.patch22
5 files changed, 236 insertions, 25 deletions
diff --git a/main/gnutls/APKBUILD b/main/gnutls/APKBUILD
index 4eb2c53630..31999f7f6a 100644
--- a/main/gnutls/APKBUILD
+++ b/main/gnutls/APKBUILD
@@ -2,7 +2,7 @@
# Maintainer: Natanael Copa <ncopa@alpinelinux.org>
pkgname=gnutls
pkgver=2.10.5
-pkgrel=3
+pkgrel=4
pkgdesc="A library which provides a secure connection"
url="http://www.gnu.org/software/gnutls/"
arch="all"
@@ -13,7 +13,9 @@ makedepends="$depends_dev perl"
install=
subpackages="$pkgname-doc $pkgname-dev"
source="http://ftp.gnu.org/pub/gnu/gnutls/$pkgname-$pkgver.tar.bz2
- cve-2012-1573.patch
+ CVE-2011-4128.patch
+ CVE-2012-1573.patch
+ CVE-2013-1619.patch
"
prepare() {
@@ -42,4 +44,6 @@ package() {
}
md5sums="1b032e07ccd22f71a5df78aa73bd91f2 gnutls-2.10.5.tar.bz2
-b37bbb419598cf04d3cc9b9d9d5dd79e cve-2012-1573.patch"
+fce93a1175f9af9bc8db02e4fe2eeabf CVE-2011-4128.patch
+6c3fbdd0fe2cb7519284350363edc432 CVE-2012-1573.patch
+846e66213a5b854053151f1ef8e6f097 CVE-2013-1619.patch"
diff --git a/main/gnutls/CVE-2011-4128.patch b/main/gnutls/CVE-2011-4128.patch
new file mode 100644
index 0000000000..2e9c5f88a9
--- /dev/null
+++ b/main/gnutls/CVE-2011-4128.patch
@@ -0,0 +1,24 @@
+Description: Check buffer size passed in from caller prior to overwriting it
+Origin: upstream, http://git.savannah.gnu.org/gitweb/?p=gnutls.git;a=commitdiff;h=190cef6eed37d0e73a73c1e205eb31d45ab60a3c
+Origin: upstream, http://git.savannah.gnu.org/gitweb/?p=gnutls.git;a=commitdiff;h=e82ef4545e9e98cbcb032f55d7c750b81e3a0450
+
+Index: gnutls26-2.10.5/lib/gnutls_session.c
+===================================================================
+--- gnutls26-2.10.5.orig/lib/gnutls_session.c 2010-08-01 15:37:30.000000000 -0500
++++ gnutls26-2.10.5/lib/gnutls_session.c 2012-04-04 03:25:20.382796666 -0500
+@@ -65,13 +65,14 @@
+ gnutls_assert ();
+ return ret;
+ }
+- *session_data_size = psession.size;
+
+ if (psession.size > *session_data_size)
+ {
++ *session_data_size = psession.size;
+ ret = GNUTLS_E_SHORT_MEMORY_BUFFER;
+ goto error;
+ }
++ *session_data_size = psession.size;
+
+ if (session_data != NULL)
+ memcpy (session_data, psession.data, psession.size);
diff --git a/main/gnutls/CVE-2012-1573.patch b/main/gnutls/CVE-2012-1573.patch
new file mode 100644
index 0000000000..4cd5fe9ff8
--- /dev/null
+++ b/main/gnutls/CVE-2012-1573.patch
@@ -0,0 +1,27 @@
+Description: Validate record size when parsing GenericBlockCipher structure
+Origin: backport, http://git.savannah.gnu.org/gitweb/?p=gnutls.git;a=commit;h=422214868061370aeeb0ac9cd0f021a5c350a57d
+
+Index: gnutls26-2.10.5/lib/gnutls_cipher.c
+===================================================================
+--- gnutls26-2.10.5.orig/lib/gnutls_cipher.c 2012-04-04 04:17:33.902871139 -0500
++++ gnutls26-2.10.5/lib/gnutls_cipher.c 2012-04-04 04:17:56.666871679 -0500
+@@ -515,14 +515,13 @@
+ {
+ ciphertext.size -= blocksize;
+ ciphertext.data += blocksize;
+-
+- if (ciphertext.size == 0)
+- {
+- gnutls_assert ();
+- return GNUTLS_E_DECRYPTION_FAILED;
+- }
+ }
+
++ if (ciphertext.size < hash_size)
++ {
++ gnutls_assert ();
++ return GNUTLS_E_DECRYPTION_FAILED;
++ }
+ pad = ciphertext.data[ciphertext.size - 1] + 1; /* pad */
+
+ if ((int) pad > (int) ciphertext.size - hash_size)
diff --git a/main/gnutls/CVE-2013-1619.patch b/main/gnutls/CVE-2013-1619.patch
new file mode 100644
index 0000000000..7b9938c600
--- /dev/null
+++ b/main/gnutls/CVE-2013-1619.patch
@@ -0,0 +1,178 @@
+Description: fix "Lucky Thirteen" timing side-channel TLS attack
+Origin: backport, https://gitorious.org/gnutls/gnutls/commit/7b65049a81ea02a92fef934318a680afd55e98d2
+Origin: backport, https://gitorious.org/gnutls/gnutls/commit/458c67cf98740e7b12404f6c30e0d5317d56fd30
+Origin: backport, https://gitorious.org/gnutls/gnutls/commit/93b7fcfa3297a9123630704668b2946f602b910e
+
+Index: gnutls26-2.10.5/lib/gnutls_cipher.c
+===================================================================
+--- gnutls26-2.10.5.orig/lib/gnutls_cipher.c 2013-02-25 11:52:27.670965684 -0500
++++ gnutls26-2.10.5/lib/gnutls_cipher.c 2013-02-25 12:04:38.642984400 -0500
+@@ -447,6 +447,49 @@
+ return length;
+ }
+
++static void dummy_wait(gnutls_session_t session, gnutls_datum_t* plaintext,
++ unsigned pad_failed, unsigned int pad, unsigned total, int ver)
++{
++ /* this hack is only needed on CBC ciphers */
++ if (_gnutls_cipher_is_block (session->security_parameters.read_bulk_cipher_algorithm) == CIPHER_BLOCK)
++ {
++ uint8_t MAC[MAX_HASH_SIZE];
++ unsigned len;
++ digest_hd_st td;
++ int ret;
++
++ ret = mac_init (&td, session->security_parameters.read_mac_algorithm,
++ session->connection_state.read_mac_secret.data,
++ session->connection_state.read_mac_secret.size, ver);
++
++ if (ret < 0)
++ return;
++
++ /* force an additional hash compression function evaluation to prevent timing
++ * attacks that distinguish between wrong-mac + correct pad, from wrong-mac + incorrect pad.
++ */
++ if (pad_failed == 0 && pad > 0)
++ {
++ len = _gnutls_get_hash_block_len(session->security_parameters.read_mac_algorithm);
++ if (len > 0)
++ {
++ /* This is really specific to the current hash functions.
++ * It should be removed once a protocol fix is in place.
++ */
++ if ((pad+total) % len > len-9 && total % len <= len-9)
++ {
++ if (len < plaintext->size)
++ mac_hash (&td, plaintext->data, len, ver);
++ else
++ mac_hash (&td, plaintext->data, plaintext->size, ver);
++ }
++ }
++ }
++
++ mac_deinit (&td, MAC, ver);
++ }
++}
++
+ /* Deciphers the ciphertext packet, and puts the result to compress_data, of compress_size.
+ * Returns the actual compressed packet size.
+ */
+@@ -458,12 +501,12 @@
+ {
+ uint8_t MAC[MAX_HASH_SIZE];
+ uint16_t c_length;
+- uint8_t pad;
++ unsigned int pad = 0;
+ int length;
+ uint16_t blocksize;
+ int ret, i, pad_failed = 0;
+ opaque preamble[PREAMBLE_SIZE];
+- int preamble_size;
++ int preamble_size = 0;
+ int ver = gnutls_protocol_get_version (session);
+ int hash_size =
+ _gnutls_hash_get_algo_len (session->
+@@ -522,31 +565,23 @@
+ gnutls_assert ();
+ return GNUTLS_E_DECRYPTION_FAILED;
+ }
+- pad = ciphertext.data[ciphertext.size - 1] + 1; /* pad */
++ pad = ciphertext.data[ciphertext.size - 1]; /* pad */
+
+- if ((int) pad > (int) ciphertext.size - hash_size)
+- {
+- gnutls_assert ();
+- _gnutls_record_log
+- ("REC[%p]: Short record length %d > %d - %d (under attack?)\n",
+- session, pad, ciphertext.size, hash_size);
+- /* We do not fail here. We check below for the
+- * the pad_failed. If zero means success.
+- */
+- pad_failed = GNUTLS_E_DECRYPTION_FAILED;
+- }
+-
+- length = ciphertext.size - hash_size - pad;
+-
+- /* Check the pading bytes (TLS 1.x)
++ /* Check the pading bytes (TLS 1.x).
++ * Note that we access all 256 bytes of ciphertext for padding check
++ * because there is a timing channel in that memory access (in certain CPUs).
+ */
+ if (_gnutls_version_has_variable_padding (ver) && pad_failed == 0)
+- for (i = 2; i < pad; i++)
++ for (i = 2; i <= pad; i++)
+ {
+- if (ciphertext.data[ciphertext.size - i] !=
+- ciphertext.data[ciphertext.size - 1])
++ if (ciphertext.data[ciphertext.size - i] != pad)
+ pad_failed = GNUTLS_E_DECRYPTION_FAILED;
+ }
++
++ if (pad_failed)
++ pad = 0;
++ length = ciphertext.size - hash_size - pad - 1;
++
+ break;
+ default:
+ gnutls_assert ();
+@@ -585,24 +620,19 @@
+ mac_deinit (&td, MAC, ver);
+ }
+
+- /* This one was introduced to avoid a timing attack against the TLS
+- * 1.0 protocol.
+- */
+- if (pad_failed != 0)
+- {
+- gnutls_assert ();
+- return pad_failed;
+- }
+-
+ /* HMAC was not the same.
+ */
+- if (memcmp (MAC, &ciphertext.data[length], hash_size) != 0)
++ if (memcmp (MAC, &ciphertext.data[length], hash_size) != 0 || pad_failed != 0)
+ {
++ gnutls_datum_t compressed = {compress_data, compress_size};
++ /* HMAC was not the same. */
++ dummy_wait(session, &compressed, pad_failed, pad, length+preamble_size, ver);
++
+ gnutls_assert ();
+ return GNUTLS_E_DECRYPTION_FAILED;
+ }
+
+- /* copy the decrypted stuff to compress_data.
++ /* copy the decrypted stuff to compressed_data.
+ */
+ if (compress_size < length)
+ {
+Index: gnutls26-2.10.5/lib/gnutls_hash_int.h
+===================================================================
+--- gnutls26-2.10.5.orig/lib/gnutls_hash_int.h 2013-02-25 11:52:27.670965684 -0500
++++ gnutls26-2.10.5/lib/gnutls_hash_int.h 2013-02-25 11:52:27.666965683 -0500
+@@ -98,4 +98,25 @@
+
+ int _gnutls_hash_copy (digest_hd_st * dst_handle, digest_hd_st * src_handle);
+
++/* We shouldn't need to know that, but a work-around in decoding
++ * TLS record padding requires that.
++ */
++inline static size_t
++_gnutls_get_hash_block_len (gnutls_digest_algorithm_t algo)
++{
++ switch (algo)
++ {
++ case GNUTLS_DIG_MD5:
++ case GNUTLS_DIG_SHA1:
++ case GNUTLS_DIG_RMD160:
++ case GNUTLS_DIG_SHA256:
++ case GNUTLS_DIG_SHA384:
++ case GNUTLS_DIG_SHA512:
++ case GNUTLS_DIG_SHA224:
++ return 64;
++ default:
++ return 0;
++ }
++}
++
+ #endif /* GNUTLS_HASH_INT_H */
diff --git a/main/gnutls/cve-2012-1573.patch b/main/gnutls/cve-2012-1573.patch
deleted file mode 100644
index b377c391c2..0000000000
--- a/main/gnutls/cve-2012-1573.patch
+++ /dev/null
@@ -1,22 +0,0 @@
---- ./lib/gnutls_cipher.c.orig
-+++ ./lib/gnutls_cipher.c
-@@ -515,14 +515,13 @@
- {
- ciphertext.size -= blocksize;
- ciphertext.data += blocksize;
--
-- if (ciphertext.size == 0)
-- {
-- gnutls_assert ();
-- return GNUTLS_E_DECRYPTION_FAILED;
-- }
- }
-
-+ if (ciphertext.size < hash_size)
-+ {
-+ gnutls_assert ();
-+ return GNUTLS_E_DECRYPTION_FAILED;
-+ }
- pad = ciphertext.data[ciphertext.size - 1] + 1; /* pad */
-
- if ((int) pad > (int) ciphertext.size - hash_size)