diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2018-06-22 06:34:17 +0000 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2018-06-22 06:34:17 +0000 |
commit | 3b688838f340fce4eedbf181a147a3537b81693b (patch) | |
tree | e0007c56ec4afb093f91ade9ce8aa1a6a97cd72f | |
parent | c41cb0664c94d4e00d4d798c8bddc9f385880b0a (diff) | |
parent | 29ffa2a1fa4cc396c5d1563a3e5cdca0174de28b (diff) | |
download | gnutls-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.c | 4 | ||||
-rw-r--r-- | lib/gnutls_cipher.c | 67 | ||||
-rw-r--r-- | lib/gnutls_priority.c | 8 | ||||
-rw-r--r-- | tests/priorities.c | 10 |
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(¶ms->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 - (¶ms->read. - cipher_state, - plaintext->data, len); - else - _gnutls_auth_cipher_add_auth - (¶ms->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 + (¶ms->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 */ |