update() of CMAC was not throwing an exception after digest was computed

This commit is contained in:
Helder Eijs 2018-11-19 13:58:27 +01:00
parent 4b138584f9
commit 072b54a9be
3 changed files with 28 additions and 4 deletions

View file

@ -14,6 +14,8 @@ Resolved issues
* GH#238: Incorrect digest value produced by CMAC after cloning the object.
* Method ``update()`` of an EAX cipher object was returning the underlying CMAC object,
instead of the EAX object itself.
* Method ``update()`` of a CMAC object was not throwing an exception after the digest
was computed (with ``digest()`` or ``verify()``).
3.7.0 (27 October 2018)
+++++++++++++++++++++++

View file

@ -116,6 +116,9 @@ class CMAC(object):
data (byte string/byte array/memoryview): The next chunk of data
"""
if self._mac_tag is not None:
raise TypeError("update() cannot be called after digest() or verify()")
self._data_size += len(msg)
bs = self._block_size

View file

@ -46,6 +46,7 @@ from Crypto.Hash import SHAKE128
from Crypto.Util._file_system import pycryptodome_filename
from Crypto.Util.strxor import strxor
from Crypto.SelfTest.st_common import list_test_cases
# This is a list of (key, data, result, description, module) tuples.
test_data = [
@ -250,10 +251,10 @@ def get_tag_random(tag, length):
return SHAKE128.new(data=tobytes(tag)).read(length)
class MultipleUpdates(unittest.TestCase):
"""Verify that internal caching is implemented correctly"""
class TestCMAC(unittest.TestCase):
def runTest(self):
def test_internal_caching(self):
"""Verify that internal caching is implemented correctly"""
data_to_mac = get_tag_random("data_to_mac", 128)
key = get_tag_random("key", 16)
@ -271,6 +272,24 @@ class MultipleUpdates(unittest.TestCase):
mac.update(chunk)
self.assertEqual(ref_mac, mac.digest())
def test_update_after_digest(self):
msg = b"rrrrttt"
key = b"4" * 16
# Normally, update() cannot be done after digest()
h = CMAC.new(key, msg[:4], ciphermod=AES)
dig1 = h.digest()
self.assertRaises(TypeError, h.update, msg[4:])
dig2 = CMAC.new(key, msg, ciphermod=AES).digest()
# With the proper flag, it is allowed
#h2 = CMAC.new(key, msg[:4], update_after_digest=True)
#self.assertEquals(h2.digest(), dig1)
# ... and the subsequent digest applies to the entire message
# up to that point
#h2.update(msg[4:])
#self.assertEquals(h2.digest(), dig2)
class ByteArrayTests(unittest.TestCase):
@ -429,8 +448,8 @@ def get_tests(config={}):
params_test_data.append(t)
tests = make_mac_tests(CMAC, "CMAC", params_test_data)
tests.append(MultipleUpdates())
tests.append(ByteArrayTests())
tests.append(list_test_cases(TestCMAC))
import sys
if sys.version[:3] != "2.6":