def runTest(self): key = b"0" * 16 data = b"\x00\x01\x02" def get_mv_ro(data): return memoryview(data) def get_mv_rw(data): return memoryview(bytearray(data)) for get_mv in (get_mv_ro, get_mv_rw): # Data and key can be a memoryview (during initialization) key_mv = get_mv(key) data_mv = get_mv(data) h1 = CMAC.new(key, data, ciphermod=AES) h2 = CMAC.new(key_mv, data_mv, ciphermod=AES) if not data_mv.readonly: key_mv[:1] = b'\xFF' data_mv[:1] = b'\xFF' self.assertEqual(h1.digest(), h2.digest()) # Data can be a memoryview (during operation) data_mv = get_mv(data) h1 = CMAC.new(key, ciphermod=AES) h2 = CMAC.new(key, ciphermod=AES) h1.update(data) h2.update(data_mv) if not data_mv.readonly: data_mv[:1] = b'\xFF' self.assertEqual(h1.digest(), h2.digest())
def runTest(self): key = b"0" * 16 data = b"\x00\x01\x02" # Data and key can be a bytearray (during initialization) key_ba = bytearray(key) data_ba = bytearray(data) h1 = CMAC.new(key, data, ciphermod=AES) h2 = CMAC.new(key_ba, data_ba, ciphermod=AES) key_ba[:1] = b'\xFF' data_ba[:1] = b'\xFF' self.assertEqual(h1.digest(), h2.digest()) # Data can be a bytearray (during operation) key_ba = bytearray(key) data_ba = bytearray(data) h1 = CMAC.new(key, ciphermod=AES) h2 = CMAC.new(key, ciphermod=AES) h1.update(data) h2.update(data_ba) data_ba[:1] = b'\xFF' self.assertEqual(h1.digest(), h2.digest())
def runTest(self): data_to_mac = get_tag_random("data_to_mac", 128) key = get_tag_random("key", 16) ref_mac = CMAC.new(key, msg=data_to_mac, ciphermod=AES).digest() # Break up in chunks of different length # The result must always be the same for chunk_length in 1, 2, 3, 7, 10, 13, 16, 40, 80, 128: chunks = [ data_to_mac[i:i + chunk_length] for i in range(0, len(data_to_mac), chunk_length) ] mac = CMAC.new(key, ciphermod=AES) for chunk in chunks: mac.update(chunk) self.assertEqual(ref_mac, mac.digest())
def test_create_mac(self, tv): self._id = "Wycheproof MAC creation Test #" + str(tv.id) try: tag = CMAC.new(tv.key, tv.msg, ciphermod=AES, mac_len=tv.tag_size).digest() except ValueError as e: if len(tv.key) not in (16, 24, 32) and "key length" in str(e): return raise e if tv.valid: self.assertEqual(tag, tv.tag) self.warn(tv)
def test_verify_mac(self, tv): self._id = "Wycheproof MAC verification Test #" + str(tv.id) try: mac = CMAC.new(tv.key, tv.msg, ciphermod=AES, mac_len=tv.tag_size) except ValueError as e: if len(tv.key) not in (16, 24, 32) and "key length" in str(e): return raise e try: mac.verify(tv.tag) except ValueError: assert not tv.valid else: assert tv.valid self.warn(tv)
def __init__(self, factory, key, nonce, mac_len, cipher_params): """EAX cipher mode""" self.block_size = factory.block_size """The block size of the underlying cipher, in bytes.""" self.nonce = _copy_bytes(None, None, nonce) """The nonce originally used to create the object.""" self._mac_len = mac_len self._mac_tag = None # Cache for MAC tag # Allowed transitions after initialization self._next = [ self.update, self.encrypt, self.decrypt, self.digest, self.verify ] # MAC tag length if not (4 <= self._mac_len <= self.block_size): raise ValueError("Parameter 'mac_len' must not be larger than %d" % self.block_size) # Nonce cannot be empty and must be a byte string if len(self.nonce) == 0: raise ValueError("Nonce cannot be empty in EAX mode") if not is_buffer(nonce): raise TypeError("nonce must be bytes, bytearray or memoryview") self._omac = [ CMAC.new(key, b'\x00' * (self.block_size - 1) + struct.pack('B', i), ciphermod=factory, cipher_params=cipher_params) for i in range(0, 3) ] # Compute MAC of nonce self._omac[0].update(self.nonce) self._signer = self._omac[1] # MAC of the nonce is also the initial counter for CTR encryption counter_int = bytes_to_long(self._omac[0].digest()) self._cipher = factory.new(key, factory.MODE_CTR, initial_value=counter_int, nonce=b"", **cipher_params)
def derive(self): """"Derive a secret from the vector of components. :Return: a byte string, as long as the block length of the cipher. """ if len(self._last_string) >= 16: # xorend final = self._last_string[:-16] + strxor(self._last_string[-16:], self._cache) else: # zero-pad & xor padded = (self._last_string + b'\x80' + b'\x00' * 15)[:16] final = strxor(padded, self._double(self._cache)) mac = CMAC.new(self._key, msg=final, ciphermod=self._ciphermod, cipher_params=self._cipher_params) return mac.digest()
def update(self, item): """Pass the next component of the vector. The maximum number of components you can pass is equal to the block length of the cipher (in bits) minus 1. :Parameters: item : byte string The next component of the vector. :Raise TypeError: when the limit on the number of components has been reached. """ if self._n_updates == 0: raise TypeError("Too many components passed to S2V") self._n_updates -= 1 mac = CMAC.new(self._key, msg=self._last_string, ciphermod=self._ciphermod, cipher_params=self._cipher_params) self._cache = strxor(self._double(self._cache), mac.digest()) self._last_string = _copy_bytes(None, None, item)