You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
90 lines
3.0 KiB
90 lines
3.0 KiB
diff --git a/lib/gnutls_cipher.c b/lib/gnutls_cipher.c |
|
index 37478a4c3..65dde6899 100644 |
|
--- a/lib/gnutls_cipher.c |
|
+++ b/lib/gnutls_cipher.c |
|
@@ -434,40 +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, v; |
|
+ 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) { |
|
- 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 ((pad + total) % len > len - v |
|
- && total % len <= len - v) { |
|
- 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); |
|
} |
|
} |
|
} |
|
@@ -725,8 +726,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); |
|
} |
|
-- |
|
2.14.3 |
|
|
|
|