test/mesh: net_mic len depends on CTL, add network_encrypt

This commit is contained in:
Matthias Ringwald 2019-10-18 22:28:32 +02:00
parent bbaf89325d
commit 6d64841b77
2 changed files with 40 additions and 7 deletions

View File

@ -76,15 +76,36 @@ 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]
def network_pecb(privacy_random, iv_index, privacy_key):
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)
privacy_random = network_pdu[7:14]
pecb = network_pecb(privacy_random, iv_index, privacy_key)
deobfuscated = bytes([(a ^ b) for (a,b) in zip(pecb, network_pdu[1:7])])
if deobfuscated[0] & 0x80:
net_mic_len = 8
else:
net_mic_len = 4
nonce = bytes(1) + deobfuscated + bytes(2) + iv_index
decrypted = aes_ccm_decrypt(encryption_key, nonce, network_pdu[7:-8], b'', 8, network_pdu[-8:])
ciphertext = network_pdu[7:-net_mic_len]
net_mic = network_pdu[-net_mic_len:]
decrypted = aes_ccm_decrypt(encryption_key, nonce, ciphertext, b'', net_mic_len, net_mic)
if decrypted == None:
return None
return network_pdu[0:1] + deobfuscated + decrypted
def network_encrypt(network_pdu, iv_index, encryption_key, privacy_key):
nonce = bytes(1) + network_pdu[1:7] + bytes(2) + iv_index
if network_pdu[1] & 0x80:
net_mic_len = 8
else:
net_mic_len = 4
plaintext = network_pdu[7:]
(ciphertext, net_mic) = aes_ccm_encrypt(encryption_key, nonce, plaintext, b'', net_mic_len)
ciphertext_and_mic = ciphertext + net_mic
privacy_random = ciphertext_and_mic[0:7]
pecb = network_pecb(privacy_random, iv_index, privacy_key)
obfuscated = bytes([(a ^ b) for (a,b) in zip(pecb, network_pdu[1:7])])
return network_pdu[0:1] + obfuscated + ciphertext_and_mic

View File

@ -92,7 +92,8 @@ if aes_expected != aes_actual:
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)
privacy_random = message_1_network_pdu[7:14]
message_1_pecb = network_pecb(privacy_random, iv_index, privacy_key)
message_1_pecb_expected = bytes.fromhex('6ca487507564')
if message_1_pecb_expected != message_1_pecb:
@ -103,8 +104,19 @@ 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 = 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())
print("network_pdu: encrypt expected " + message_1_decrypted_expected.hex() + ", but got " + message_1_decrypted.hex())
# message x decrypt
iv_index = bytes.fromhex('00000001')
privacy_key = bytes.fromhex('035efaafbbd84f898b95190cc3cac36b')
encryption_key = bytes.fromhex('9ba46b86afbe8b7f0b63db597372babe')
message_1_network_pdu = bytes.fromhex('B10000520D001C000155555555555555555555555555555555')
message_1_encrypted = network_encrypt(message_1_network_pdu, iv_index, encryption_key, privacy_key)
message_1_expected = bytes.fromhex('b12a7492504b03fa604d6d2f298ad31233fe1d568175b2f1104e23380b')
if message_1_expected != message_1_encrypted:
print("network_pdu: decrypt expected " + message_1_expected.hex() + ", but got " + message_1_encrypted.hex())