Search code examples
pythonpycryptopycryptodomecmac

Wrong CMAC generation from Pycryptodome


As per the Example given in the documentation of PyCryptodome

>>> from Crypto.Hash import CMAC
>>> from Crypto.Cipher import AES
>>> secret = b'Sixteen byte key'
>>> cobj = CMAC.new(secret, ciphermod=AES)
>>> cobj.update(b'Hello')
>>> print cobj.hexdigest()

it generates the AES CMAC but when I try the test vector from RFC4493, I get the wrong CMAC. for example, the test vectors from RFC4493 are:

K              2b7e1516 28aed2a6 abf71588 09cf4f3c
M              6bc1bee2 2e409f96 e93d7e11 7393172a
AES-CMAC       070a16b4 6b4d4144 f79bdd9d d04a287c

But when I tried the same key and message

>>> from Crypto.Hash import CMAC
>>> from Crypto.Cipher import AES
>>> secret = b'2b7e151628aed2a6abf7158809cf4f3c'
>>> cobj = CMAC.new(secret, ciphermod=AES)
>>> cobj.update(b'6bc1bee2 2e409f96 e93d7e11 7393172a')
>>> print cobj.hexdigest()

I got the following output

a3f10a99bd83f4dee4392d65ed9f76c1

Solution

  • The problem in your code is that your are not treating the message or key 2b7e1516 28aed2a6 abf71588 09cf4f3c as a hex number which it is in this case but you are treating it as bytes where each character is stored in it's ASCII representation rather than being stored as the actual value of hex character so f is stored as binary 0100 0110 rather than as binary 1111. While the RFC deal with input as the numbers encoded as HEX characters, so use this code:

    from Crypto.Hash import CMAC
    from Crypto.Cipher import AES
    secret = "2b7e151628aed2a6abf7158809cf4f3c"
    msg = "6bc1bee22e409f96e93d7e117393172a"
    cobj = CMAC.new(bytes.fromhex(secret), ciphermod=AES)
    cobj.update(bytes.fromhex(msg))
    res = cobj.hexdigest()
    print(res)
    

    which will print correct result of

    070a16b46b4d4144f79bdd9dd04a287c
    

    Hope this solve your problem.