1#!/usr/bin/env python3 2# BlueKitchen GmbH (c) 2019 3 4# pip3 install pycryptodomex 5 6from mesh_crypto import * 7 8try: 9 from Cryptodome.Cipher import AES 10 from Cryptodome.Hash import CMAC 11except ImportError: 12 # fallback: try to import PyCryptodome as (an almost drop-in) replacement for the PyCrypto library 13 try: 14 from Crypto.Cipher import AES 15 from Crypto.Hash import CMAC 16 except ImportError: 17 print("\n[!] PyCryptodome required but not installed (using random value instead)") 18 print("[!] Please install PyCryptodome, e.g. 'pip3 install pycryptodomex' or 'pip3 install pycryptodome'\n") 19 20# S1('test') = b73cefbd641ef2ea598c2b6efb62f79c 21s1_input = b'test' 22s1_actual = s1(s1_input) 23 24s1_expected = bytes.fromhex('b73cefbd641ef2ea598c2b6efb62f79c') 25if s1_actual != s1_expected: 26 print("s1: expected " + s1_expected.hex + ", but got " + s1_actual.hex()) 27 28# K1(3216d1509884b533248541792b877f98, 2ba14ffa0df84a2831938d57d276cab4, 5a09d60797eeb4478aada59db3352a0d) = f6ed15a8934afbe7d83e8dcb57fcf5d7 29k1_n = bytes.fromhex("3216d1509884b533248541792b877f98") 30k1_salt = bytes.fromhex("2ba14ffa0df84a2831938d57d276cab4") 31k1_p = bytes.fromhex("5a09d60797eeb4478aada59db3352a0d") 32k1_actual = k1(k1_n, k1_salt, k1_p) 33 34k1_expected = bytes.fromhex("f6ed15a8934afbe7d83e8dcb57fcf5d7") 35if k1_actual != k1_expected: 36 print("k1: expected " + k1_expected.hex() + ", but got " + k1_actual.hex()) 37 38# k2 test 39k2_n = bytes.fromhex('7dd7364cd842ad18c17c2b820c84c3d6') 40k2_p = bytes.fromhex('00') 41(k2_nid, k2_encryption_key, k2_privacy_key) = k2(k2_n, k2_p) 42 43k2_nid_expected = 0x68 44k2_encryption_key_expected = bytes.fromhex('0953fa93e7caac9638f58820220a398e') 45k2_privacy_key_expected = bytes.fromhex('8b84eedec100067d670971dd2aa700cf') 46if k2_nid_expected != k2_nid: 47 print("k2: nid expected " + hex(k2_nid_expected) + ", but got " + hex(k2_nid)) 48if k2_encryption_key_expected != k2_encryption_key: 49 print("k2: encryption key expected " + k2_encryption_key_expected.hex() + ", but got " + k2_encryption_key.hex()) 50if k2_privacy_key_expected != k2_privacy_key: 51 print("k2: privacy key expected " + k2_privacy_key_expected.hex() + ", but got " + k2_privacy_key.hex()) 52 53# k3 test 54k3_n = bytes.fromhex('f7a2a44f8e8a8029064f173ddc1e2b00') 55k3_actual = k3(k3_n) 56 57k3_expected = bytes.fromhex('ff046958233db014') 58if k3_actual != k3_expected: 59 print("k3: expected " + k3_expected.hex() + ", but got " + k3_actual.hex()) 60 61# k4 test 62k4_n = bytes.fromhex('3216d1509884b533248541792b877f98') 63k4_actual = k4(k4_n) 64 65k4_expected = 0x38 66if k4_actual != k4_expected: 67 print("k4: expected " + hex(k4_expected) + ", but got " + hex(k4_actual)) 68 69# aes-ccm-encrypt test 70message_1_network_nonce = bytes.fromhex('00800000011201000012345678') 71message_1_network_plaintext = bytes.fromhex('fffd' + '034b50057e400000010000') 72message_1_encryption_key = bytes.fromhex('0953fa93e7caac9638f58820220a398e') 73(message_1_ciphertext, message_1_mic) = aes_ccm_encrypt(message_1_encryption_key, message_1_network_nonce, message_1_network_plaintext, b'', 8) 74 75message_1_ciphertext_expected = bytes.fromhex('b5e5bfdacbaf6cb7fb6bff871f') 76message_1_mic_expected = bytes.fromhex('035444ce83a670df') 77if message_1_ciphertext_expected != message_1_ciphertext: 78 print("aes_ccm_encrypt: ciphertext expected " + hex(message_1_ciphertext_expected) + ", but got " + hex(message_1_ciphertext)) 79if message_1_mic_expected != message_1_mic: 80 print("aes_ccm_encrypt: encryption key expected " + message_1_mic_expected.hex() + ", but got " + message_1_mic.hex()) 81 82# aes-ccm-decrypt test 83message_1_network_nonce = bytes.fromhex('00800000011201000012345678') 84message_1_ciphertext_expected = bytes.fromhex('b5e5bfdacbaf6cb7fb6bff871f') 85message_1_mic_expected = bytes.fromhex('035444ce83a670df') 86message_1_plaintext_decrypted = aes_ccm_decrypt(message_1_encryption_key, message_1_network_nonce, message_1_ciphertext_expected, b'', 8, message_1_mic_expected) 87 88message_1_network_plaintext = bytes.fromhex('fffd' + '034b50057e400000010000') 89if message_1_plaintext_decrypted == None: 90 print("aes_ccm_decrypt: digest validation failed") 91elif message_1_network_plaintext != message_1_plaintext_decrypted: 92 print("aes_ccm: plaintext expected " + hex(message_1_network_plaintext) + ", but got " + hex(message_1_plaintext_decrypted)) 93 94# aes128 encrypt 95aes_key = bytes(16) 96aes_n = bytes(16) 97aes_actual = aes128(aes_key, aes_n) 98 99aes_expected = bytes.fromhex('66E94BD4EF8A2C3B884CFA59CA342B2E') 100if aes_expected != aes_actual: 101 print("aes128: expected " + aes_expected.hex() + ", but got " + aes_actual.hex()) 102 103# network PECB 104iv_index = bytes.fromhex('12345678') 105privacy_key = bytes.fromhex('8b84eedec100067d670971dd2aa700cf') 106message_1_network_pdu = bytes.fromhex('68eca487516765b5e5bfdacbaf6cb7fb6bff871f035444ce83a670df') 107privacy_random = message_1_network_pdu[7:14] 108message_1_pecb = network_pecb(privacy_random, iv_index, privacy_key) 109 110message_1_pecb_expected = bytes.fromhex('6ca487507564') 111if message_1_pecb_expected != message_1_pecb: 112 print("network_pecb: expected " + message_1_pecb_expected.hex() + ", but got " + message_1_pecb.hex()) 113 114# message 1 115iv_index = bytes.fromhex('12345678') 116privacy_key = bytes.fromhex('8b84eedec100067d670971dd2aa700cf') 117message_1_network_pdu = bytes.fromhex('68eca487516765b5e5bfdacbaf6cb7fb6bff871f035444ce83a670df') 118message_1_encryption_key = bytes.fromhex('0953fa93e7caac9638f58820220a398e') 119message_1_decrypted = network_decrypt(message_1_network_pdu, iv_index, message_1_encryption_key, privacy_key) 120 121message_1_decrypted_expected = bytes.fromhex('68800000011201fffd034b50057e400000010000') 122if message_1_decrypted_expected != message_1_decrypted: 123 print("network_pdu: encrypt expected " + message_1_decrypted_expected.hex() + ", but got " + message_1_decrypted.hex()) 124 125# message x decrypt 126iv_index = bytes.fromhex('00000001') 127privacy_key = bytes.fromhex('035efaafbbd84f898b95190cc3cac36b') 128encryption_key = bytes.fromhex('9ba46b86afbe8b7f0b63db597372babe') 129message_1_network_pdu = bytes.fromhex('B10000520D001C000155555555555555555555555555555555') 130message_1_encrypted = network_encrypt(message_1_network_pdu, iv_index, encryption_key, privacy_key) 131 132message_1_expected = bytes.fromhex('b12a7492504b03fa604d6d2f298ad31233fe1d568175b2f1104e23380b') 133if message_1_expected != message_1_encrypted: 134 print("network_pdu: decrypt expected " + message_1_expected.hex() + ", but got " + message_1_encrypted.hex()) 135