test/mesh: add mesh network pdu deobfuscation and decryption

This commit is contained in:
Matthias Ringwald 2019-10-18 19:25:27 +02:00
parent 1d0ba3a509
commit bbaf89325d
2 changed files with 49 additions and 2 deletions

View File

@ -8,8 +8,13 @@
from Cryptodome.Cipher import AES
from Cryptodome.Hash import CMAC
def aes_cmac(k, n):
cobj = CMAC.new(k, ciphermod=AES)
def aes128(key, n):
cipher = AES.new(key, AES.MODE_ECB)
ciphertext = cipher.encrypt(n)
return ciphertext
def aes_cmac(key, n):
cobj = CMAC.new(key, ciphermod=AES)
cobj.update(n)
return cobj.digest()
@ -71,3 +76,15 @@ def k4(n):
t = aes_cmac(salt, n)
return aes_cmac(t, b'id6' + b'\x01')[15] & 0x3f
def network_pecb(network_pdu, iv_index, privacy_key):
privacy_random = network_pdu[7:14]
privacy_plaintext = bytes(5) + iv_index + privacy_random
return aes128(privacy_key, privacy_plaintext)[0:6]
def network_decrypt(network_pdu, iv_index, encryption_key, privacy_key):
pecb = network_pecb(network_pdu, iv_index, privacy_key)
deobfuscated = bytes([(a ^ b) for (a,b) in zip(pecb, network_pdu[1:7])])
nonce = bytes(1) + deobfuscated + bytes(2) + iv_index
decrypted = aes_ccm_decrypt(encryption_key, nonce, network_pdu[7:-8], b'', 8, network_pdu[-8:])
return network_pdu[0:1] + deobfuscated + decrypted

View File

@ -78,3 +78,33 @@ if message_1_plaintext_decrypted == None:
print("aes_ccm_decrypt: digest validation failed")
elif message_1_network_plaintext != message_1_plaintext_decrypted:
print("aes_ccm: plaintext expected " + hex(message_1_network_plaintext) + ", but got " + hex(message_1_plaintext_decrypted))
# aes128 encrypt
aes_key = bytes(16)
aes_n = bytes(16)
aes_actual = aes128(aes_key, aes_n)
aes_expected = bytes.fromhex('66E94BD4EF8A2C3B884CFA59CA342B2E')
if aes_expected != aes_actual:
print("aes128: expected " + aes_expected.hex() + ", but got " + aes_actual.hex())
# network PECB
iv_index = bytes.fromhex('12345678')
privacy_key = bytes.fromhex('8b84eedec100067d670971dd2aa700cf')
message_1_network_pdu = bytes.fromhex('68eca487516765b5e5bfdacbaf6cb7fb6bff871f035444ce83a670df')
message_1_pecb = network_pecb(message_1_network_pdu, iv_index, privacy_key)
message_1_pecb_expected = bytes.fromhex('6ca487507564')
if message_1_pecb_expected != message_1_pecb:
print("network_pecb: expected " + message_1_pecb_expected.hex() + ", but got " + message_1_pecb.hex())
# message 1
iv_index = bytes.fromhex('12345678')
privacy_key = bytes.fromhex('8b84eedec100067d670971dd2aa700cf')
message_1_network_pdu = bytes.fromhex('68eca487516765b5e5bfdacbaf6cb7fb6bff871f035444ce83a670df')
message_1_encryption_key = bytes.fromhex('0953fa93e7caac9638f58820220a398e')
message_1_decrypted = network_decrypt(message_1_network_pdu, iv_index, message_1_encryption_key, privacy_key)
message_1_decrypted_expected = bytes.fromhex('68800000011201fffd034b50057e400000010000')
if message_1_decrypted_expected != message_1_decrypted:
print("network_pdu: expected " + message_1_decrypted_expected.hex() + ", but got " + message_1_decrypted.hex())