summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2018-06-22 06:34:17 +0000
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2018-06-22 06:34:17 +0000
commit3b688838f340fce4eedbf181a147a3537b81693b (patch)
treee0007c56ec4afb093f91ade9ce8aa1a6a97cd72f
parentc41cb0664c94d4e00d4d798c8bddc9f385880b0a (diff)
parent29ffa2a1fa4cc396c5d1563a3e5cdca0174de28b (diff)
downloadgnutls-3b688838f340fce4eedbf181a147a3537b81693b.tar.gz
Merge branch 'gnutls_3_3_x' into 'gnutls_3_3_x'
3.3.x: backport fixes in record layer decoding See merge request gnutls/gnutls!676
-rw-r--r--lib/algorithms/mac.c4
-rw-r--r--lib/gnutls_cipher.c67
-rw-r--r--lib/gnutls_priority.c8
-rw-r--r--tests/priorities.c10
4 files changed, 46 insertions, 43 deletions
diff --git a/lib/algorithms/mac.c b/lib/algorithms/mac.c
index 0527ca4f18..a39acd49f7 100644
--- a/lib/algorithms/mac.c
+++ b/lib/algorithms/mac.c
@@ -37,9 +37,9 @@ static const mac_entry_st hash_algorithms[] = {
{"SHA256", HASH_OID_SHA256, MAC_OID_SHA256, GNUTLS_MAC_SHA256, 32, 32, 0, 0, 1,
64},
{"SHA384", HASH_OID_SHA384, MAC_OID_SHA384, GNUTLS_MAC_SHA384, 48, 48, 0, 0, 1,
- 64},
+ 128},
{"SHA512", HASH_OID_SHA512, MAC_OID_SHA512, GNUTLS_MAC_SHA512, 64, 64, 0, 0, 1,
- 64},
+ 128},
{"SHA224", HASH_OID_SHA224, MAC_OID_SHA224, GNUTLS_MAC_SHA224, 28, 28, 0, 0, 1,
64},
{"UMAC-96", NULL, NULL, GNUTLS_MAC_UMAC_96, 12, 16, 8, 0, 1, 0},
diff --git a/lib/gnutls_cipher.c b/lib/gnutls_cipher.c
index 58ce797757..8b34472b73 100644
--- a/lib/gnutls_cipher.c
+++ b/lib/gnutls_cipher.c
@@ -434,37 +434,41 @@ compressed_to_ciphertext(gnutls_session_t session,
return length;
}
-static void dummy_wait(record_parameters_st * params,
- gnutls_datum_t * plaintext, unsigned pad_failed,
- unsigned int pad, unsigned total)
+static void dummy_wait(record_parameters_st *params,
+ gnutls_datum_t *plaintext,
+ unsigned int mac_data, unsigned int max_mac_data)
{
/* this hack is only needed on CBC ciphers */
if (_gnutls_cipher_is_block(params->cipher) == CIPHER_BLOCK) {
- unsigned len;
+ unsigned v;
+ unsigned int tag_size =
+ _gnutls_auth_cipher_tag_len(&params->read.cipher_state);
+ unsigned hash_block = _gnutls_mac_block_size(params->mac);
- /* force an additional hash compression function evaluation to prevent timing
+ /* force additional hash compression function evaluations to prevent timing
* attacks that distinguish between wrong-mac + correct pad, from wrong-mac + incorrect pad.
*/
- if (pad_failed == 0 && pad > 0) {
- len = _gnutls_mac_block_size(params->mac);
- 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)
- _gnutls_auth_cipher_add_auth
- (&params->read.
- cipher_state,
- plaintext->data, len);
- else
- _gnutls_auth_cipher_add_auth
- (&params->read.
- cipher_state,
- plaintext->data,
- plaintext->size);
- }
+ if (params->mac && params->mac->id == GNUTLS_MAC_SHA384)
+ /* v = 1 for the hash function padding + 16 for message length */
+ v = 17;
+ else /* v = 1 for the hash function padding + 8 for message length */
+ v = 9;
+
+ if (hash_block > 0) {
+ int max_blocks = (max_mac_data+v+hash_block-1)/hash_block;
+ int hashed_blocks = (mac_data+v+hash_block-1)/hash_block;
+ unsigned to_hash;
+
+ max_blocks -= hashed_blocks;
+ if (max_blocks < 1)
+ return;
+
+ to_hash = max_blocks * hash_block;
+ if ((unsigned)to_hash+1+tag_size < plaintext->size) {
+ _gnutls_auth_cipher_add_auth
+ (&params->read.cipher_state,
+ plaintext->data+plaintext->size-tag_size-to_hash-1,
+ to_hash);
}
}
}
@@ -655,7 +659,11 @@ ciphertext_to_compressed(gnutls_session_t session,
* 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 (ver->id != GNUTLS_SSL3)
+ if (ver->id == GNUTLS_SSL3) {
+ if (pad >= blocksize)
+ pad_failed = 1;
+ } else
+ {
for (i = 2; i <= MIN(256, ciphertext->size); i++) {
tmp_pad_failed |=
(compressed->
@@ -663,6 +671,7 @@ ciphertext_to_compressed(gnutls_session_t session,
pad_failed |=
((i <= (1 + pad)) & (tmp_pad_failed));
}
+ }
if (unlikely
(pad_failed != 0
@@ -722,8 +731,10 @@ ciphertext_to_compressed(gnutls_session_t session,
if (unlikely
(memcmp(tag, tag_ptr, tag_size) != 0 || pad_failed != 0)) {
/* HMAC was not the same. */
- dummy_wait(params, compressed, pad_failed, pad,
- length + preamble_size);
+ gnutls_datum_t data = {compressed->data, ciphertext->size};
+
+ dummy_wait(params, &data, length + preamble_size,
+ preamble_size + ciphertext->size - tag_size - 1);
return gnutls_assert_val(GNUTLS_E_DECRYPTION_FAILED);
}
diff --git a/lib/gnutls_priority.c b/lib/gnutls_priority.c
index c5998abe67..f3e19105f3 100644
--- a/lib/gnutls_priority.c
+++ b/lib/gnutls_priority.c
@@ -491,8 +491,6 @@ static const int sign_priority_secure192[] = {
static const int mac_priority_normal_default[] = {
GNUTLS_MAC_SHA1,
- GNUTLS_MAC_SHA256,
- GNUTLS_MAC_SHA384,
GNUTLS_MAC_AEAD,
GNUTLS_MAC_MD5,
0
@@ -500,8 +498,6 @@ static const int mac_priority_normal_default[] = {
static const int mac_priority_normal_fips[] = {
GNUTLS_MAC_SHA1,
- GNUTLS_MAC_SHA256,
- GNUTLS_MAC_SHA384,
GNUTLS_MAC_AEAD,
0
};
@@ -530,15 +526,11 @@ static const int mac_priority_suiteb192[] = {
static const int mac_priority_secure128[] = {
GNUTLS_MAC_SHA1,
- GNUTLS_MAC_SHA256,
- GNUTLS_MAC_SHA384,
GNUTLS_MAC_AEAD,
0
};
static const int mac_priority_secure192[] = {
- GNUTLS_MAC_SHA256,
- GNUTLS_MAC_SHA384,
GNUTLS_MAC_AEAD,
0
};
diff --git a/tests/priorities.c b/tests/priorities.c
index f22b08b625..46221fcc02 100644
--- a/tests/priorities.c
+++ b/tests/priorities.c
@@ -100,18 +100,18 @@ try_prio(const char *prio, unsigned expected_cs, unsigned expected_ciphers)
void doit(void)
{
- const int normal = 61;
- const int null = 5;
- const int sec128 = 56;
+ const int normal = 41;
+ const int null = 4;
+ const int sec128 = 36;
try_prio("NORMAL", normal, 9);
try_prio("NORMAL:-MAC-ALL:+MD5:+MAC-ALL", normal, 9);
try_prio("NORMAL:+CIPHER-ALL", normal, 9); /* all (except null) */
try_prio("NORMAL:-CIPHER-ALL:+NULL", null, 1); /* null */
try_prio("NORMAL:-CIPHER-ALL:+NULL:+CIPHER-ALL", normal + null, 10); /* should be null + all */
- try_prio("NORMAL:-CIPHER-ALL:+NULL:+CIPHER-ALL:-CIPHER-ALL:+AES-128-CBC", 10, 1); /* should be null + all */
+ try_prio("NORMAL:-CIPHER-ALL:+NULL:+CIPHER-ALL:-CIPHER-ALL:+AES-128-CBC", 5, 1);
try_prio("PERFORMANCE", normal, 9);
- try_prio("SECURE256", 20, 4);
+ try_prio("SECURE256", 10, 4);
try_prio("SECURE128", sec128, 8);
try_prio("SECURE128:+SECURE256", sec128, 8); /* should be the same as SECURE128 */
try_prio("SECURE128:+SECURE256:+NORMAL", normal, 9); /* should be the same as NORMAL */