Julien
Julien

Reputation: 11

Decrypt macsec frame python (AES-GCM)

I'm french student and for an exercise, my professor asked me to decrypt a macsec frame with python. I have the key but there is a problem: ValueError: Mac check failed.

Here the frame :

00 0c 29 45 13 e1 00 0c 29 b0 53 b2 88 e5 2c 00 00 00 00 16 00 0c 29 b0 53 b2 00 01 64 ad 0a 24 7f 79 b4 68 2a 4b 37 6e 20 72 c5 e7 af ee 90 7f b6 8c de e7 5e 84 d1 01 9e f2 b6 a4 91 8f f3 bd 62 69 9a 44 86 ad 5a 29 08 a0 98 64 98 74 52 a1 e0 ae 89 10 55 90 a4 5e 99 99 72 d5 91 ac dc c0 c5 c2 c8 93 8f 3f 25 59 d0 9c b6 89 15 86 ae ec 93 0f ce 3b ae f5 91 94 3e 22 67 4d 73 75 39 8b 67 de

Here the algorithm :

key = binascii.unhexlify('fe0969aac4e169dfc89011326418aeae')
data = binascii.unhexlify('000c29b053b2000100000016000c294513e1000c29b053b28888e52C0000000016000c29b053b2000164ad0a247f79b4682a4b376e2072c5e7afee907fb68cdee75e84d1019ef2b6a4918ff3bd62699a4486ad5a2908a09864987452a1e0ae89105590a45e999972d591acdcc0c5c2c8938f3f2559d09cb6891586aeec930fce3baef591943e22674d7375398b67de')

iv, tag = data[:24], data[-32:]
cipher = AES.new(key, AES.MODE_GCM, iv)
cipher.decrypt_and_verify(data[24:-32], tag)

Could you help me please ? :(

Upvotes: 1

Views: 1340

Answers (1)

Topaco
Topaco

Reputation: 49460

The task is essentially to identify from the frame the components necessary for AES-GCM, namely nonce, AAD and tag.

The frame starts with the MAC DA (Destination Address) and the MAC SA (Source Address), each of them 6 bytes long. Then follows the 16 bytes long SecTAG (Security TAG), which is composed of the 2 bytes long MACsec Ether Type (0x88e5), the 1 byte long TCI/AN (TAG Control Information / Association Number), the 1 byte long SL (Short Length of the encrypted data), the 4 bytes long PN (Packet Number) and the 8 bytes long SCI (Secure Channel Identifier). Then comes the encrypted data and finally the 16 bytes long ICV (Integrity Check Value):

MAC DA:             0x000c294513e1
MAC SA:             0x000c29b053b2
MACsec Ether Type:  0x88e5
TCI/AN:             0x2c
SL:                 0x00
PN:                 0x00000016
SCI:                0x000c29b053b20001

enc. user data:     0x64ad0a247f79b4682a4b376e2072c5e7afee907fb68cdee75e84d1019ef2b6a4918ff3bd62699a4486ad5a2908a09864987452a1e0ae89105590a45e999972d591acdcc0c5c2c8938f3f2559d09cb6891586aeec930f

ICV:                0xce3baef591943e22674d7375398b67de

These portions map to the GCM components as follows: The 12 bytes GCM nonce corresponds to the SCI and PN concatenated in this order. The GCM AAD are the concatenated data of MAC DA, MAC SA and SecTAG (Ether Type, TCI/AN, SL, PN, SCI) in this order. The GCM tag corresponds to the ICV:

GCM nonce:          0x000c29b053b2000100000016
GCM AAD:            0x000c294513e1000c29b053b288e52c0000000016000c29b053b20001
GCM tag:            0xce3baef591943e22674d7375398b67de

Thus the encrypted data can be decrypted with PyCryptodome as follows:

from Crypto.Cipher import AES
import binascii

key = binascii.unhexlify('fe0969aac4e169dfc89011326418aeae')
nonce = binascii.unhexlify('000c29b053b2000100000016')
aad = binascii.unhexlify('000c294513e1000c29b053b288e52c0000000016000c29b053b20001')
tag = binascii.unhexlify('ce3baef591943e22674d7375398b67de')
data = binascii.unhexlify('64ad0a247f79b4682a4b376e2072c5e7afee907fb68cdee75e84d1019ef2b6a4918ff3bd62699a4486ad5a2908a09864987452a1e0ae89105590a45e999972d591acdcc0c5c2c8938f3f2559d09cb6891586aeec930f')

cipher = AES.new(key, AES.MODE_GCM, nonce)
cipher.update(aad)
decrypted = cipher.decrypt_and_verify(data, tag)

print(decrypted.hex())

with the output:

080045000054607040004001c6160a01000b0a0100160800b716022b0007a6c0c25e0000000012c5040000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637

More details can be found here (test vectors, identification of the GCM components) and here (structure of the SecTAG).

Upvotes: 2

Related Questions