diff --git a/tlslite/utils/constanttime.py b/tlslite/utils/constanttime.py index 60322c14..d4f5b1ce 100644 --- a/tlslite/utils/constanttime.py +++ b/tlslite/utils/constanttime.py @@ -170,7 +170,7 @@ def ct_check_cbc_mac_and_pad(data, mac, seqnumBytes, contentType, version): data_mac.update(compatHMAC(data[:start_pos])) # don't check past the array end (already checked to be >= zero) - end_pos = data_len - 1 - mac.digest_size + end_pos = data_len - mac.digest_size # calculate all possible for i in range(start_pos, end_pos): # constant for given overall length diff --git a/unit_tests/test_tlslite_utils_constanttime.py b/unit_tests/test_tlslite_utils_constanttime.py index 0edaf3f4..0a6446d0 100644 --- a/unit_tests/test_tlslite_utils_constanttime.py +++ b/unit_tests/test_tlslite_utils_constanttime.py @@ -16,6 +16,7 @@ from hypothesis import given, example import hypothesis.strategies as st from tlslite.utils.compat import compatHMAC +from tlslite.utils.cryptomath import getRandomBytes from tlslite.recordlayer import RecordLayer import tlslite.utils.tlshashlib as hashlib import hmac @@ -266,6 +267,26 @@ def test_with_invalid_hash(self): self.assertFalse(ct_check_cbc_mac_and_pad(data, h, seqnum_bytes, content_type, version)) + @given(i=st.integers(1, 20)) + def test_with_invalid_random_hash(self, i): + key = compatHMAC(getRandomBytes(20)) + seqnum_bytes = bytearray(16) + content_type = 0x15 + version = (3, 3) + application_data = getRandomBytes(63) + mac = hashlib.sha1 + + data = self.data_prepare(application_data, seqnum_bytes, content_type, + version, mac, key) + data[-i] ^= 0xff + padding = bytearray(b'\x00') + data += padding + + h = hmac.new(key, digestmod=mac) + h.block_size = mac().block_size + self.assertFalse(ct_check_cbc_mac_and_pad(data, h, seqnum_bytes, + content_type, version)) + def test_with_invalid_pad(self): key = compatHMAC(bytearray(20)) seqnum_bytes = bytearray(16)