1
Description: fix "Lucky Thirteen" timing side-channel TLS attack
2
Origin: backport, https://gitorious.org/gnutls/gnutls/commit/7b65049a81ea02a92fef934318a680afd55e98d2
3
Origin: backport, https://gitorious.org/gnutls/gnutls/commit/458c67cf98740e7b12404f6c30e0d5317d56fd30
4
Origin: backport, https://gitorious.org/gnutls/gnutls/commit/93b7fcfa3297a9123630704668b2946f602b910e
6
Index: gnutls26-2.10.5/lib/gnutls_cipher.c
7
===================================================================
8
--- gnutls26-2.10.5.orig/lib/gnutls_cipher.c 2013-02-25 11:52:27.670965684 -0500
9
+++ gnutls26-2.10.5/lib/gnutls_cipher.c 2013-02-25 12:04:38.642984400 -0500
14
+static void dummy_wait(gnutls_session_t session, gnutls_datum_t* plaintext,
15
+ unsigned pad_failed, unsigned int pad, unsigned total, int ver)
17
+ /* this hack is only needed on CBC ciphers */
18
+ if (_gnutls_cipher_is_block (session->security_parameters.read_bulk_cipher_algorithm) == CIPHER_BLOCK)
20
+ uint8_t MAC[MAX_HASH_SIZE];
25
+ ret = mac_init (&td, session->security_parameters.read_mac_algorithm,
26
+ session->connection_state.read_mac_secret.data,
27
+ session->connection_state.read_mac_secret.size, ver);
32
+ /* force an additional hash compression function evaluation to prevent timing
33
+ * attacks that distinguish between wrong-mac + correct pad, from wrong-mac + incorrect pad.
35
+ if (pad_failed == 0 && pad > 0)
37
+ len = _gnutls_get_hash_block_len(session->security_parameters.read_mac_algorithm);
40
+ /* This is really specific to the current hash functions.
41
+ * It should be removed once a protocol fix is in place.
43
+ if ((pad+total) % len > len-9 && total % len <= len-9)
45
+ if (len < plaintext->size)
46
+ mac_hash (&td, plaintext->data, len, ver);
48
+ mac_hash (&td, plaintext->data, plaintext->size, ver);
53
+ mac_deinit (&td, MAC, ver);
57
/* Deciphers the ciphertext packet, and puts the result to compress_data, of compress_size.
58
* Returns the actual compressed packet size.
62
uint8_t MAC[MAX_HASH_SIZE];
65
+ unsigned int pad = 0;
68
int ret, i, pad_failed = 0;
69
opaque preamble[PREAMBLE_SIZE];
71
+ int preamble_size = 0;
72
int ver = gnutls_protocol_get_version (session);
74
_gnutls_hash_get_algo_len (session->
77
return GNUTLS_E_DECRYPTION_FAILED;
79
- pad = ciphertext.data[ciphertext.size - 1] + 1; /* pad */
80
+ pad = ciphertext.data[ciphertext.size - 1]; /* pad */
82
- if ((int) pad > (int) ciphertext.size - hash_size)
86
- ("REC[%p]: Short record length %d > %d - %d (under attack?)\n",
87
- session, pad, ciphertext.size, hash_size);
88
- /* We do not fail here. We check below for the
89
- * the pad_failed. If zero means success.
91
- pad_failed = GNUTLS_E_DECRYPTION_FAILED;
94
- length = ciphertext.size - hash_size - pad;
96
- /* Check the pading bytes (TLS 1.x)
97
+ /* Check the pading bytes (TLS 1.x).
98
+ * Note that we access all 256 bytes of ciphertext for padding check
99
+ * because there is a timing channel in that memory access (in certain CPUs).
101
if (_gnutls_version_has_variable_padding (ver) && pad_failed == 0)
102
- for (i = 2; i < pad; i++)
103
+ for (i = 2; i <= pad; i++)
105
- if (ciphertext.data[ciphertext.size - i] !=
106
- ciphertext.data[ciphertext.size - 1])
107
+ if (ciphertext.data[ciphertext.size - i] != pad)
108
pad_failed = GNUTLS_E_DECRYPTION_FAILED;
113
+ length = ciphertext.size - hash_size - pad - 1;
118
@@ -585,24 +620,19 @@
119
mac_deinit (&td, MAC, ver);
122
- /* This one was introduced to avoid a timing attack against the TLS
125
- if (pad_failed != 0)
131
/* HMAC was not the same.
133
- if (memcmp (MAC, &ciphertext.data[length], hash_size) != 0)
134
+ if (memcmp (MAC, &ciphertext.data[length], hash_size) != 0 || pad_failed != 0)
136
+ gnutls_datum_t compressed = {compress_data, compress_size};
137
+ /* HMAC was not the same. */
138
+ dummy_wait(session, &compressed, pad_failed, pad, length+preamble_size, ver);
141
return GNUTLS_E_DECRYPTION_FAILED;
144
- /* copy the decrypted stuff to compress_data.
145
+ /* copy the decrypted stuff to compressed_data.
147
if (compress_size < length)
149
Index: gnutls26-2.10.5/lib/gnutls_hash_int.h
150
===================================================================
151
--- gnutls26-2.10.5.orig/lib/gnutls_hash_int.h 2013-02-25 11:52:27.670965684 -0500
152
+++ gnutls26-2.10.5/lib/gnutls_hash_int.h 2013-02-25 11:52:27.666965683 -0500
155
int _gnutls_hash_copy (digest_hd_st * dst_handle, digest_hd_st * src_handle);
157
+/* We shouldn't need to know that, but a work-around in decoding
158
+ * TLS record padding requires that.
160
+inline static size_t
161
+_gnutls_get_hash_block_len (gnutls_digest_algorithm_t algo)
165
+ case GNUTLS_DIG_MD5:
166
+ case GNUTLS_DIG_SHA1:
167
+ case GNUTLS_DIG_RMD160:
168
+ case GNUTLS_DIG_SHA256:
169
+ case GNUTLS_DIG_SHA384:
170
+ case GNUTLS_DIG_SHA512:
171
+ case GNUTLS_DIG_SHA224:
178
#endif /* GNUTLS_HASH_INT_H */