xref: /aosp_15_r20/external/openthread/tests/scripts/thread-cert/test_crypto.py (revision cfb92d1480a9e65faed56933e9c12405f45898b4)
1*cfb92d14SAndroid Build Coastguard Worker#!/usr/bin/env python3
2*cfb92d14SAndroid Build Coastguard Worker#
3*cfb92d14SAndroid Build Coastguard Worker#  Copyright (c) 2016, The OpenThread Authors.
4*cfb92d14SAndroid Build Coastguard Worker#  All rights reserved.
5*cfb92d14SAndroid Build Coastguard Worker#
6*cfb92d14SAndroid Build Coastguard Worker#  Redistribution and use in source and binary forms, with or without
7*cfb92d14SAndroid Build Coastguard Worker#  modification, are permitted provided that the following conditions are met:
8*cfb92d14SAndroid Build Coastguard Worker#  1. Redistributions of source code must retain the above copyright
9*cfb92d14SAndroid Build Coastguard Worker#     notice, this list of conditions and the following disclaimer.
10*cfb92d14SAndroid Build Coastguard Worker#  2. Redistributions in binary form must reproduce the above copyright
11*cfb92d14SAndroid Build Coastguard Worker#     notice, this list of conditions and the following disclaimer in the
12*cfb92d14SAndroid Build Coastguard Worker#     documentation and/or other materials provided with the distribution.
13*cfb92d14SAndroid Build Coastguard Worker#  3. Neither the name of the copyright holder nor the
14*cfb92d14SAndroid Build Coastguard Worker#     names of its contributors may be used to endorse or promote products
15*cfb92d14SAndroid Build Coastguard Worker#     derived from this software without specific prior written permission.
16*cfb92d14SAndroid Build Coastguard Worker#
17*cfb92d14SAndroid Build Coastguard Worker#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18*cfb92d14SAndroid Build Coastguard Worker#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19*cfb92d14SAndroid Build Coastguard Worker#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20*cfb92d14SAndroid Build Coastguard Worker#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21*cfb92d14SAndroid Build Coastguard Worker#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22*cfb92d14SAndroid Build Coastguard Worker#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23*cfb92d14SAndroid Build Coastguard Worker#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24*cfb92d14SAndroid Build Coastguard Worker#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25*cfb92d14SAndroid Build Coastguard Worker#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26*cfb92d14SAndroid Build Coastguard Worker#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27*cfb92d14SAndroid Build Coastguard Worker#  POSSIBILITY OF SUCH DAMAGE.
28*cfb92d14SAndroid Build Coastguard Worker#
29*cfb92d14SAndroid Build Coastguard Worker
30*cfb92d14SAndroid Build Coastguard Workerimport io
31*cfb92d14SAndroid Build Coastguard Workerimport random
32*cfb92d14SAndroid Build Coastguard Workerimport struct
33*cfb92d14SAndroid Build Coastguard Workerimport unittest
34*cfb92d14SAndroid Build Coastguard Workerimport ipaddress
35*cfb92d14SAndroid Build Coastguard Worker
36*cfb92d14SAndroid Build Coastguard Workerimport common
37*cfb92d14SAndroid Build Coastguard Workerimport net_crypto
38*cfb92d14SAndroid Build Coastguard Worker
39*cfb92d14SAndroid Build Coastguard Workernetwork_key = bytearray(
40*cfb92d14SAndroid Build Coastguard Worker    [0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff])
41*cfb92d14SAndroid Build Coastguard Worker
42*cfb92d14SAndroid Build Coastguard Worker
43*cfb92d14SAndroid Build Coastguard Workerdef convert_aux_sec_hdr_to_bytearray(aux_sec_hdr):
44*cfb92d14SAndroid Build Coastguard Worker    data = bytearray([aux_sec_hdr.security_level | ((aux_sec_hdr.key_id_mode & 0x03) << 3)])
45*cfb92d14SAndroid Build Coastguard Worker    data += struct.pack("<L", aux_sec_hdr.frame_counter)
46*cfb92d14SAndroid Build Coastguard Worker    data += aux_sec_hdr.key_id
47*cfb92d14SAndroid Build Coastguard Worker    return data
48*cfb92d14SAndroid Build Coastguard Worker
49*cfb92d14SAndroid Build Coastguard Worker
50*cfb92d14SAndroid Build Coastguard Workerdef any_eui64():
51*cfb92d14SAndroid Build Coastguard Worker    return bytearray([random.getrandbits(8) for _ in range(8)])
52*cfb92d14SAndroid Build Coastguard Worker
53*cfb92d14SAndroid Build Coastguard Worker
54*cfb92d14SAndroid Build Coastguard Workerdef any_security_level():
55*cfb92d14SAndroid Build Coastguard Worker    return random.getrandbits(3)
56*cfb92d14SAndroid Build Coastguard Worker
57*cfb92d14SAndroid Build Coastguard Worker
58*cfb92d14SAndroid Build Coastguard Workerdef any_key_id_mode():
59*cfb92d14SAndroid Build Coastguard Worker    """
60*cfb92d14SAndroid Build Coastguard Worker    Only key id mode 2.
61*cfb92d14SAndroid Build Coastguard Worker    """
62*cfb92d14SAndroid Build Coastguard Worker    return 2
63*cfb92d14SAndroid Build Coastguard Worker
64*cfb92d14SAndroid Build Coastguard Worker
65*cfb92d14SAndroid Build Coastguard Workerdef any_key_id(key_id_mode):
66*cfb92d14SAndroid Build Coastguard Worker    if key_id_mode == 2:
67*cfb92d14SAndroid Build Coastguard Worker        length = 5
68*cfb92d14SAndroid Build Coastguard Worker
69*cfb92d14SAndroid Build Coastguard Worker    return bytearray([random.getrandbits(8) for _ in range(length)])
70*cfb92d14SAndroid Build Coastguard Worker
71*cfb92d14SAndroid Build Coastguard Worker
72*cfb92d14SAndroid Build Coastguard Workerdef any_auxiliary_security_header():
73*cfb92d14SAndroid Build Coastguard Worker    key_id_mode = any_key_id_mode()
74*cfb92d14SAndroid Build Coastguard Worker    key_id = any_key_id(key_id_mode)
75*cfb92d14SAndroid Build Coastguard Worker
76*cfb92d14SAndroid Build Coastguard Worker    return net_crypto.AuxiliarySecurityHeader(key_id_mode, any_security_level(), any_frame_counter(), key_id)
77*cfb92d14SAndroid Build Coastguard Worker
78*cfb92d14SAndroid Build Coastguard Worker
79*cfb92d14SAndroid Build Coastguard Workerdef any_frame_counter():
80*cfb92d14SAndroid Build Coastguard Worker    return random.getrandbits(32)
81*cfb92d14SAndroid Build Coastguard Worker
82*cfb92d14SAndroid Build Coastguard Worker
83*cfb92d14SAndroid Build Coastguard Workerdef any_ip_address():
84*cfb92d14SAndroid Build Coastguard Worker    ip_address_bytes = bytearray([random.getrandbits(8) for _ in range(16)])
85*cfb92d14SAndroid Build Coastguard Worker    return ipaddress.ip_address(bytes(ip_address_bytes))
86*cfb92d14SAndroid Build Coastguard Worker
87*cfb92d14SAndroid Build Coastguard Worker
88*cfb92d14SAndroid Build Coastguard Workerdef any_data(length=None):
89*cfb92d14SAndroid Build Coastguard Worker    length = length if length is not None else random.randint(0, 128)
90*cfb92d14SAndroid Build Coastguard Worker    return bytearray([random.getrandbits(8) for _ in range(length)])
91*cfb92d14SAndroid Build Coastguard Worker
92*cfb92d14SAndroid Build Coastguard Worker
93*cfb92d14SAndroid Build Coastguard Workerdef any_network_key():
94*cfb92d14SAndroid Build Coastguard Worker    return bytearray([random.getrandbits(8) for _ in range(16)])
95*cfb92d14SAndroid Build Coastguard Worker
96*cfb92d14SAndroid Build Coastguard Worker
97*cfb92d14SAndroid Build Coastguard Workerclass TestCryptoEngine(unittest.TestCase):
98*cfb92d14SAndroid Build Coastguard Worker
99*cfb92d14SAndroid Build Coastguard Worker    def test_should_decrypt_bytearray_to_mle_message_when_decrypt_method_is_called(self):
100*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
101*cfb92d14SAndroid Build Coastguard Worker        message_info = common.MessageInfo()
102*cfb92d14SAndroid Build Coastguard Worker        message_info.source_mac_address = common.MacAddress.from_eui64(
103*cfb92d14SAndroid Build Coastguard Worker            bytearray([0x00, 0x35, 0xcc, 0x94, 0xd7, 0x7a, 0x07, 0xe8]))
104*cfb92d14SAndroid Build Coastguard Worker
105*cfb92d14SAndroid Build Coastguard Worker        message_info.source_ipv6 = "fe80::235:cc94:d77a:07e8"
106*cfb92d14SAndroid Build Coastguard Worker        message_info.destination_ipv6 = "ff02::2"
107*cfb92d14SAndroid Build Coastguard Worker
108*cfb92d14SAndroid Build Coastguard Worker        message_info.aux_sec_hdr = net_crypto.AuxiliarySecurityHeader(key_id_mode=2,
109*cfb92d14SAndroid Build Coastguard Worker                                                                      security_level=5,
110*cfb92d14SAndroid Build Coastguard Worker                                                                      frame_counter=262165,
111*cfb92d14SAndroid Build Coastguard Worker                                                                      key_id=bytearray([0x00, 0x00, 0x00, 0x00, 0x01]))
112*cfb92d14SAndroid Build Coastguard Worker        message_info.aux_sec_hdr_bytes = convert_aux_sec_hdr_to_bytearray(message_info.aux_sec_hdr)
113*cfb92d14SAndroid Build Coastguard Worker
114*cfb92d14SAndroid Build Coastguard Worker        data = bytearray([
115*cfb92d14SAndroid Build Coastguard Worker            0x9a, 0x5a, 0x9a, 0x5b, 0xba, 0x25, 0x9c, 0x5e, 0x58, 0xa2, 0x7e, 0x75, 0x74, 0xef, 0x79, 0xbc, 0x4f, 0xa3,
116*cfb92d14SAndroid Build Coastguard Worker            0xf9, 0xae, 0xa8, 0x34, 0xf6, 0xf2, 0x37, 0x21, 0x93, 0x60
117*cfb92d14SAndroid Build Coastguard Worker        ])
118*cfb92d14SAndroid Build Coastguard Worker
119*cfb92d14SAndroid Build Coastguard Worker        mic = bytearray([0xe1, 0xb5, 0xa2, 0x53])
120*cfb92d14SAndroid Build Coastguard Worker
121*cfb92d14SAndroid Build Coastguard Worker        net_crypto_engine = net_crypto.CryptoEngine(net_crypto.MleCryptoMaterialCreator(network_key))
122*cfb92d14SAndroid Build Coastguard Worker
123*cfb92d14SAndroid Build Coastguard Worker        # WHEN
124*cfb92d14SAndroid Build Coastguard Worker        mle_msg = net_crypto_engine.decrypt(data, mic, message_info)
125*cfb92d14SAndroid Build Coastguard Worker
126*cfb92d14SAndroid Build Coastguard Worker        # THEN
127*cfb92d14SAndroid Build Coastguard Worker        expected_mle_msg = bytearray([
128*cfb92d14SAndroid Build Coastguard Worker            0x04, 0x00, 0x02, 0x00, 0x00, 0x09, 0x0b, 0x8f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x01, 0xf1,
129*cfb92d14SAndroid Build Coastguard Worker            0x0b, 0x08, 0x65, 0x5e, 0x0f, 0x83, 0x40, 0xc7, 0x83, 0x31
130*cfb92d14SAndroid Build Coastguard Worker        ])
131*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(expected_mle_msg, mle_msg)
132*cfb92d14SAndroid Build Coastguard Worker
133*cfb92d14SAndroid Build Coastguard Worker    def test_should_encrypt_mle_message_to_bytearray_when_encrypt_method_is_called(self):
134*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
135*cfb92d14SAndroid Build Coastguard Worker        message_info = common.MessageInfo()
136*cfb92d14SAndroid Build Coastguard Worker        message_info.source_mac_address = common.MacAddress.from_eui64(
137*cfb92d14SAndroid Build Coastguard Worker            bytearray([0x00, 0x35, 0xcc, 0x94, 0xd7, 0x7a, 0x07, 0xe8]))
138*cfb92d14SAndroid Build Coastguard Worker
139*cfb92d14SAndroid Build Coastguard Worker        message_info.source_ipv6 = "fe80::235:cc94:d77a:07e8"
140*cfb92d14SAndroid Build Coastguard Worker        message_info.destination_ipv6 = "ff02::2"
141*cfb92d14SAndroid Build Coastguard Worker
142*cfb92d14SAndroid Build Coastguard Worker        message_info.aux_sec_hdr = net_crypto.AuxiliarySecurityHeader(key_id_mode=2,
143*cfb92d14SAndroid Build Coastguard Worker                                                                      security_level=5,
144*cfb92d14SAndroid Build Coastguard Worker                                                                      frame_counter=262165,
145*cfb92d14SAndroid Build Coastguard Worker                                                                      key_id=bytearray([0x00, 0x00, 0x00, 0x00, 0x01]))
146*cfb92d14SAndroid Build Coastguard Worker        message_info.aux_sec_hdr_bytes = convert_aux_sec_hdr_to_bytearray(message_info.aux_sec_hdr)
147*cfb92d14SAndroid Build Coastguard Worker
148*cfb92d14SAndroid Build Coastguard Worker        mle_msg = bytearray([
149*cfb92d14SAndroid Build Coastguard Worker            0x04, 0x00, 0x02, 0x00, 0x00, 0x09, 0x0b, 0x8f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x01, 0xf1,
150*cfb92d14SAndroid Build Coastguard Worker            0x0b, 0x08, 0x65, 0x5e, 0x0f, 0x83, 0x40, 0xc7, 0x83, 0x31
151*cfb92d14SAndroid Build Coastguard Worker        ])
152*cfb92d14SAndroid Build Coastguard Worker
153*cfb92d14SAndroid Build Coastguard Worker        net_crypto_engine = net_crypto.CryptoEngine(net_crypto.MleCryptoMaterialCreator(network_key))
154*cfb92d14SAndroid Build Coastguard Worker
155*cfb92d14SAndroid Build Coastguard Worker        # WHEN
156*cfb92d14SAndroid Build Coastguard Worker        encrypted_data, mic = net_crypto_engine.encrypt(mle_msg, message_info)
157*cfb92d14SAndroid Build Coastguard Worker
158*cfb92d14SAndroid Build Coastguard Worker        # THEN
159*cfb92d14SAndroid Build Coastguard Worker        expected_encrypted_data = bytearray([
160*cfb92d14SAndroid Build Coastguard Worker            0x9a, 0x5a, 0x9a, 0x5b, 0xba, 0x25, 0x9c, 0x5e, 0x58, 0xa2, 0x7e, 0x75, 0x74, 0xef, 0x79, 0xbc, 0x4f, 0xa3,
161*cfb92d14SAndroid Build Coastguard Worker            0xf9, 0xae, 0xa8, 0x34, 0xf6, 0xf2, 0x37, 0x21, 0x93, 0x60, 0xe1, 0xb5, 0xa2, 0x53
162*cfb92d14SAndroid Build Coastguard Worker        ])
163*cfb92d14SAndroid Build Coastguard Worker
164*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(expected_encrypted_data, encrypted_data + mic)
165*cfb92d14SAndroid Build Coastguard Worker
166*cfb92d14SAndroid Build Coastguard Worker    def test_should_encrypt_and_decrypt_random_data_content_when_proper_methods_are_called(self):
167*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
168*cfb92d14SAndroid Build Coastguard Worker        data = any_data()
169*cfb92d14SAndroid Build Coastguard Worker
170*cfb92d14SAndroid Build Coastguard Worker        network_key = any_network_key()
171*cfb92d14SAndroid Build Coastguard Worker
172*cfb92d14SAndroid Build Coastguard Worker        key_id_mode = 2
173*cfb92d14SAndroid Build Coastguard Worker        security_level = 5
174*cfb92d14SAndroid Build Coastguard Worker
175*cfb92d14SAndroid Build Coastguard Worker        message_info = common.MessageInfo()
176*cfb92d14SAndroid Build Coastguard Worker        message_info.source_mac_address = common.MacAddress.from_eui64(any_eui64())
177*cfb92d14SAndroid Build Coastguard Worker
178*cfb92d14SAndroid Build Coastguard Worker        message_info.source_ipv6 = any_ip_address()
179*cfb92d14SAndroid Build Coastguard Worker        message_info.destination_ipv6 = any_ip_address()
180*cfb92d14SAndroid Build Coastguard Worker
181*cfb92d14SAndroid Build Coastguard Worker        message_info.aux_sec_hdr = net_crypto.AuxiliarySecurityHeader(key_id_mode=key_id_mode,
182*cfb92d14SAndroid Build Coastguard Worker                                                                      security_level=security_level,
183*cfb92d14SAndroid Build Coastguard Worker                                                                      frame_counter=any_frame_counter(),
184*cfb92d14SAndroid Build Coastguard Worker                                                                      key_id=any_key_id(key_id_mode))
185*cfb92d14SAndroid Build Coastguard Worker        message_info.aux_sec_hdr_bytes = convert_aux_sec_hdr_to_bytearray(message_info.aux_sec_hdr)
186*cfb92d14SAndroid Build Coastguard Worker
187*cfb92d14SAndroid Build Coastguard Worker        net_crypto_engine = net_crypto.CryptoEngine(net_crypto.MleCryptoMaterialCreator(network_key))
188*cfb92d14SAndroid Build Coastguard Worker
189*cfb92d14SAndroid Build Coastguard Worker        # WHEN
190*cfb92d14SAndroid Build Coastguard Worker        enc_data, mic = net_crypto_engine.encrypt(data, message_info)
191*cfb92d14SAndroid Build Coastguard Worker        dec_data = net_crypto_engine.decrypt(enc_data, mic, message_info)
192*cfb92d14SAndroid Build Coastguard Worker
193*cfb92d14SAndroid Build Coastguard Worker        # THEN
194*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(data, dec_data)
195*cfb92d14SAndroid Build Coastguard Worker
196*cfb92d14SAndroid Build Coastguard Worker
197*cfb92d14SAndroid Build Coastguard Workerclass TestCryptoMaterialCreator(unittest.TestCase):
198*cfb92d14SAndroid Build Coastguard Worker    """ Key generation was described in Thread specification.
199*cfb92d14SAndroid Build Coastguard Worker
200*cfb92d14SAndroid Build Coastguard Worker    Read more: Thread 1.1.0 Specification Candidate Final - 7.1.4 Key Generation
201*cfb92d14SAndroid Build Coastguard Worker
202*cfb92d14SAndroid Build Coastguard Worker    Test vectors was taken from thread specification.
203*cfb92d14SAndroid Build Coastguard Worker    """
204*cfb92d14SAndroid Build Coastguard Worker
205*cfb92d14SAndroid Build Coastguard Worker    def test_should_generate_mle_and_mac_key_when_generate_keys_method_is_called_with_sequence_counter_equal_0(self):
206*cfb92d14SAndroid Build Coastguard Worker        """
207*cfb92d14SAndroid Build Coastguard Worker        7.1.4.1 Test Vector 1
208*cfb92d14SAndroid Build Coastguard Worker        """
209*cfb92d14SAndroid Build Coastguard Worker
210*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
211*cfb92d14SAndroid Build Coastguard Worker        sequence_counter = 0
212*cfb92d14SAndroid Build Coastguard Worker
213*cfb92d14SAndroid Build Coastguard Worker        creator = net_crypto.CryptoMaterialCreator(network_key)
214*cfb92d14SAndroid Build Coastguard Worker
215*cfb92d14SAndroid Build Coastguard Worker        # WHEN
216*cfb92d14SAndroid Build Coastguard Worker        mle_key, mac_key = creator._generate_keys(sequence_counter)
217*cfb92d14SAndroid Build Coastguard Worker
218*cfb92d14SAndroid Build Coastguard Worker        # THEN
219*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(
220*cfb92d14SAndroid Build Coastguard Worker            mle_key,
221*cfb92d14SAndroid Build Coastguard Worker            bytearray([0x54, 0x45, 0xf4, 0x15, 0x8f, 0xd7, 0x59, 0x12, 0x17, 0x58, 0x09, 0xf8, 0xb5, 0x7a, 0x66,
222*cfb92d14SAndroid Build Coastguard Worker                       0xa4]))
223*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(
224*cfb92d14SAndroid Build Coastguard Worker            mac_key,
225*cfb92d14SAndroid Build Coastguard Worker            bytearray([0xde, 0x89, 0xc5, 0x3a, 0xf3, 0x82, 0xb4, 0x21, 0xe0, 0xfd, 0xe5, 0xa9, 0xba, 0xe3, 0xbe,
226*cfb92d14SAndroid Build Coastguard Worker                       0xf0]))
227*cfb92d14SAndroid Build Coastguard Worker
228*cfb92d14SAndroid Build Coastguard Worker    def test_should_generate_mle_and_mac_key_when_generate_keys_method_is_called_with_sequence_counter_equal_1(self):
229*cfb92d14SAndroid Build Coastguard Worker        """
230*cfb92d14SAndroid Build Coastguard Worker        7.1.4.2 Test Vector 2
231*cfb92d14SAndroid Build Coastguard Worker        """
232*cfb92d14SAndroid Build Coastguard Worker
233*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
234*cfb92d14SAndroid Build Coastguard Worker        sequence_counter = 1
235*cfb92d14SAndroid Build Coastguard Worker
236*cfb92d14SAndroid Build Coastguard Worker        creator = net_crypto.CryptoMaterialCreator(network_key)
237*cfb92d14SAndroid Build Coastguard Worker
238*cfb92d14SAndroid Build Coastguard Worker        # WHEN
239*cfb92d14SAndroid Build Coastguard Worker        mle_key, mac_key = creator._generate_keys(sequence_counter)
240*cfb92d14SAndroid Build Coastguard Worker
241*cfb92d14SAndroid Build Coastguard Worker        # THEN
242*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(
243*cfb92d14SAndroid Build Coastguard Worker            mle_key,
244*cfb92d14SAndroid Build Coastguard Worker            bytearray([0x8f, 0x4c, 0xd1, 0xa2, 0x7d, 0x95, 0xc0, 0x7d, 0x12, 0xdb, 0x89, 0x74, 0xbd, 0x61, 0x5c,
245*cfb92d14SAndroid Build Coastguard Worker                       0x13]))
246*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(
247*cfb92d14SAndroid Build Coastguard Worker            mac_key,
248*cfb92d14SAndroid Build Coastguard Worker            bytearray([0x9b, 0xe0, 0xd1, 0xaf, 0x7b, 0xd8, 0x73, 0x50, 0xde, 0xab, 0xcd, 0xd0, 0x7f, 0xeb, 0xb9,
249*cfb92d14SAndroid Build Coastguard Worker                       0xd5]))
250*cfb92d14SAndroid Build Coastguard Worker
251*cfb92d14SAndroid Build Coastguard Worker    def test_should_generate_mle_and_mac_key_when_generate_keys_method_is_called_with_sequence_counter_equal_2(self):
252*cfb92d14SAndroid Build Coastguard Worker        """
253*cfb92d14SAndroid Build Coastguard Worker        7.1.4.3 Test Vector 3
254*cfb92d14SAndroid Build Coastguard Worker        """
255*cfb92d14SAndroid Build Coastguard Worker
256*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
257*cfb92d14SAndroid Build Coastguard Worker        sequence_counter = 2
258*cfb92d14SAndroid Build Coastguard Worker
259*cfb92d14SAndroid Build Coastguard Worker        creator = net_crypto.CryptoMaterialCreator(network_key)
260*cfb92d14SAndroid Build Coastguard Worker
261*cfb92d14SAndroid Build Coastguard Worker        # WHEN
262*cfb92d14SAndroid Build Coastguard Worker        mle_key, mac_key = creator._generate_keys(sequence_counter)
263*cfb92d14SAndroid Build Coastguard Worker
264*cfb92d14SAndroid Build Coastguard Worker        # THEN
265*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(
266*cfb92d14SAndroid Build Coastguard Worker            mle_key,
267*cfb92d14SAndroid Build Coastguard Worker            bytearray([0x01, 0x6e, 0x2a, 0xb8, 0xec, 0x88, 0x87, 0x96, 0x87, 0xa7, 0x2e, 0x0a, 0x35, 0x7e, 0xcf,
268*cfb92d14SAndroid Build Coastguard Worker                       0x2a]))
269*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(
270*cfb92d14SAndroid Build Coastguard Worker            mac_key,
271*cfb92d14SAndroid Build Coastguard Worker            bytearray([0x56, 0x41, 0x09, 0xe9, 0xd2, 0xaa, 0xd7, 0xf7, 0x23, 0xec, 0x3b, 0x96, 0x11, 0x0e, 0xef,
272*cfb92d14SAndroid Build Coastguard Worker                       0xa3]))
273*cfb92d14SAndroid Build Coastguard Worker
274*cfb92d14SAndroid Build Coastguard Worker
275*cfb92d14SAndroid Build Coastguard Workerclass TestMleCryptoMaterialCreator(unittest.TestCase):
276*cfb92d14SAndroid Build Coastguard Worker
277*cfb92d14SAndroid Build Coastguard Worker    def test_should_create_nonce_when_create_nonce_method_is_called(self):
278*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
279*cfb92d14SAndroid Build Coastguard Worker        source_eui64 = any_eui64()
280*cfb92d14SAndroid Build Coastguard Worker        frame_counter = any_frame_counter()
281*cfb92d14SAndroid Build Coastguard Worker        security_level = any_security_level()
282*cfb92d14SAndroid Build Coastguard Worker
283*cfb92d14SAndroid Build Coastguard Worker        creator = net_crypto.MleCryptoMaterialCreator(network_key)
284*cfb92d14SAndroid Build Coastguard Worker
285*cfb92d14SAndroid Build Coastguard Worker        # WHEN
286*cfb92d14SAndroid Build Coastguard Worker        nonce = creator._create_nonce(source_eui64, frame_counter, security_level)
287*cfb92d14SAndroid Build Coastguard Worker
288*cfb92d14SAndroid Build Coastguard Worker        # THEN
289*cfb92d14SAndroid Build Coastguard Worker        nonce_bytes = io.BytesIO(nonce)
290*cfb92d14SAndroid Build Coastguard Worker
291*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(source_eui64, nonce_bytes.read(8))
292*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(struct.pack(">L", frame_counter), nonce_bytes.read(4))
293*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(security_level, ord(nonce_bytes.read(1)))
294*cfb92d14SAndroid Build Coastguard Worker
295*cfb92d14SAndroid Build Coastguard Worker    def test_should_create_authenticated_data_when_create_authenticated_data_method_is_called(self):
296*cfb92d14SAndroid Build Coastguard Worker        """
297*cfb92d14SAndroid Build Coastguard Worker        Only Key id mode 2.
298*cfb92d14SAndroid Build Coastguard Worker        Length of the Auxiliary Security Header is constantly equal 10.
299*cfb92d14SAndroid Build Coastguard Worker        """
300*cfb92d14SAndroid Build Coastguard Worker
301*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
302*cfb92d14SAndroid Build Coastguard Worker        source_address = any_ip_address()
303*cfb92d14SAndroid Build Coastguard Worker        destination_address = any_ip_address()
304*cfb92d14SAndroid Build Coastguard Worker        auxiliary_security_header_bytes = convert_aux_sec_hdr_to_bytearray(any_auxiliary_security_header())
305*cfb92d14SAndroid Build Coastguard Worker
306*cfb92d14SAndroid Build Coastguard Worker        creator = net_crypto.MleCryptoMaterialCreator(network_key)
307*cfb92d14SAndroid Build Coastguard Worker
308*cfb92d14SAndroid Build Coastguard Worker        # WHEN
309*cfb92d14SAndroid Build Coastguard Worker        authenticated_data = creator._create_authenticated_data(source_address, destination_address,
310*cfb92d14SAndroid Build Coastguard Worker                                                                auxiliary_security_header_bytes)
311*cfb92d14SAndroid Build Coastguard Worker
312*cfb92d14SAndroid Build Coastguard Worker        # THEN
313*cfb92d14SAndroid Build Coastguard Worker        authenticated_data_bytes = io.BytesIO(authenticated_data)
314*cfb92d14SAndroid Build Coastguard Worker
315*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(source_address.packed, authenticated_data_bytes.read(16))
316*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(destination_address.packed, authenticated_data_bytes.read(16))
317*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(auxiliary_security_header_bytes, authenticated_data_bytes.read(10))
318*cfb92d14SAndroid Build Coastguard Worker
319*cfb92d14SAndroid Build Coastguard Worker    def test_should_create_key_and_nonce_and_auth_data_when_create_key_and_nonce_and_auth_data_is_called(self):
320*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
321*cfb92d14SAndroid Build Coastguard Worker        message_info = common.MessageInfo()
322*cfb92d14SAndroid Build Coastguard Worker        message_info.source_mac_address = common.MacAddress.from_eui64(any_eui64())
323*cfb92d14SAndroid Build Coastguard Worker
324*cfb92d14SAndroid Build Coastguard Worker        message_info.source_ipv6 = any_ip_address()
325*cfb92d14SAndroid Build Coastguard Worker        message_info.destination_ipv6 = any_ip_address()
326*cfb92d14SAndroid Build Coastguard Worker
327*cfb92d14SAndroid Build Coastguard Worker        message_info.aux_sec_hdr = any_auxiliary_security_header()
328*cfb92d14SAndroid Build Coastguard Worker        message_info.aux_sec_hdr_bytes = convert_aux_sec_hdr_to_bytearray(message_info.aux_sec_hdr)
329*cfb92d14SAndroid Build Coastguard Worker
330*cfb92d14SAndroid Build Coastguard Worker        creator = net_crypto.MleCryptoMaterialCreator(network_key)
331*cfb92d14SAndroid Build Coastguard Worker
332*cfb92d14SAndroid Build Coastguard Worker        # WHEN
333*cfb92d14SAndroid Build Coastguard Worker        key, nonce, auth_data = creator.create_key_and_nonce_and_authenticated_data(message_info)
334*cfb92d14SAndroid Build Coastguard Worker
335*cfb92d14SAndroid Build Coastguard Worker        # THEN
336*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(
337*cfb92d14SAndroid Build Coastguard Worker            message_info.source_mac_address.mac_address +
338*cfb92d14SAndroid Build Coastguard Worker            struct.pack(">LB", message_info.aux_sec_hdr.frame_counter, message_info.aux_sec_hdr.security_level), nonce)
339*cfb92d14SAndroid Build Coastguard Worker
340*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(
341*cfb92d14SAndroid Build Coastguard Worker            message_info.source_ipv6.packed + message_info.destination_ipv6.packed + message_info.aux_sec_hdr_bytes,
342*cfb92d14SAndroid Build Coastguard Worker            auth_data)
343*cfb92d14SAndroid Build Coastguard Worker
344*cfb92d14SAndroid Build Coastguard Worker
345*cfb92d14SAndroid Build Coastguard Workerclass TestAuxiliarySecurityHeader(unittest.TestCase):
346*cfb92d14SAndroid Build Coastguard Worker
347*cfb92d14SAndroid Build Coastguard Worker    def test_should_return_key_id_mode_value_when_key_id_mode_property_is_called(self):
348*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
349*cfb92d14SAndroid Build Coastguard Worker        key_id_mode = any_key_id_mode()
350*cfb92d14SAndroid Build Coastguard Worker
351*cfb92d14SAndroid Build Coastguard Worker        aux_sec_hdr_obj = net_crypto.AuxiliarySecurityHeader(key_id_mode, any_security_level(), any_frame_counter(),
352*cfb92d14SAndroid Build Coastguard Worker                                                             any_key_id(key_id_mode))
353*cfb92d14SAndroid Build Coastguard Worker
354*cfb92d14SAndroid Build Coastguard Worker        # WHEN
355*cfb92d14SAndroid Build Coastguard Worker        actual_key_id_mode = aux_sec_hdr_obj.key_id_mode
356*cfb92d14SAndroid Build Coastguard Worker
357*cfb92d14SAndroid Build Coastguard Worker        # THEN
358*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(key_id_mode, actual_key_id_mode)
359*cfb92d14SAndroid Build Coastguard Worker
360*cfb92d14SAndroid Build Coastguard Worker    def test_should_return_security_level_value_when_security_level_property_is_called(self):
361*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
362*cfb92d14SAndroid Build Coastguard Worker        security_level = any_security_level()
363*cfb92d14SAndroid Build Coastguard Worker        key_id_mode = any_key_id_mode()
364*cfb92d14SAndroid Build Coastguard Worker
365*cfb92d14SAndroid Build Coastguard Worker        aux_sec_hdr_obj = net_crypto.AuxiliarySecurityHeader(key_id_mode, security_level, any_frame_counter(),
366*cfb92d14SAndroid Build Coastguard Worker                                                             any_key_id(key_id_mode))
367*cfb92d14SAndroid Build Coastguard Worker
368*cfb92d14SAndroid Build Coastguard Worker        # WHEN
369*cfb92d14SAndroid Build Coastguard Worker        actual_security_level = aux_sec_hdr_obj.security_level
370*cfb92d14SAndroid Build Coastguard Worker
371*cfb92d14SAndroid Build Coastguard Worker        # THEN
372*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(security_level, actual_security_level)
373*cfb92d14SAndroid Build Coastguard Worker
374*cfb92d14SAndroid Build Coastguard Worker    def test_should_return_frame_counter_value_when_frame_counter_property_is_called(self):
375*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
376*cfb92d14SAndroid Build Coastguard Worker        frame_counter = any_frame_counter()
377*cfb92d14SAndroid Build Coastguard Worker        key_id_mode = any_key_id_mode()
378*cfb92d14SAndroid Build Coastguard Worker
379*cfb92d14SAndroid Build Coastguard Worker        aux_sec_hdr_obj = net_crypto.AuxiliarySecurityHeader(key_id_mode, any_security_level(), frame_counter,
380*cfb92d14SAndroid Build Coastguard Worker                                                             any_key_id(key_id_mode))
381*cfb92d14SAndroid Build Coastguard Worker
382*cfb92d14SAndroid Build Coastguard Worker        # WHEN
383*cfb92d14SAndroid Build Coastguard Worker        actual_frame_counter = aux_sec_hdr_obj.frame_counter
384*cfb92d14SAndroid Build Coastguard Worker
385*cfb92d14SAndroid Build Coastguard Worker        # THEN
386*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(frame_counter, actual_frame_counter)
387*cfb92d14SAndroid Build Coastguard Worker
388*cfb92d14SAndroid Build Coastguard Worker    def test_should_return_key_id_value_when_key_id_property_is_called(self):
389*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
390*cfb92d14SAndroid Build Coastguard Worker        key_id_mode = any_key_id_mode()
391*cfb92d14SAndroid Build Coastguard Worker        key_id = any_key_id(key_id_mode)
392*cfb92d14SAndroid Build Coastguard Worker
393*cfb92d14SAndroid Build Coastguard Worker        aux_sec_hdr_obj = net_crypto.AuxiliarySecurityHeader(key_id_mode, any_security_level(), any_frame_counter(),
394*cfb92d14SAndroid Build Coastguard Worker                                                             key_id)
395*cfb92d14SAndroid Build Coastguard Worker
396*cfb92d14SAndroid Build Coastguard Worker        # WHEN
397*cfb92d14SAndroid Build Coastguard Worker        actual_key_id = aux_sec_hdr_obj.key_id
398*cfb92d14SAndroid Build Coastguard Worker
399*cfb92d14SAndroid Build Coastguard Worker        # THEN
400*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(key_id, actual_key_id)
401*cfb92d14SAndroid Build Coastguard Worker
402*cfb92d14SAndroid Build Coastguard Worker    def test_should_return_sequence_counter_value_when_sequence_counter_property_is_called(self):
403*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
404*cfb92d14SAndroid Build Coastguard Worker        key_id_mode = 2
405*cfb92d14SAndroid Build Coastguard Worker        key_id = any_key_id(key_id_mode)
406*cfb92d14SAndroid Build Coastguard Worker
407*cfb92d14SAndroid Build Coastguard Worker        aux_sec_hdr_obj = net_crypto.AuxiliarySecurityHeader(key_id_mode, any_security_level(), any_frame_counter(),
408*cfb92d14SAndroid Build Coastguard Worker                                                             key_id)
409*cfb92d14SAndroid Build Coastguard Worker
410*cfb92d14SAndroid Build Coastguard Worker        # WHEN
411*cfb92d14SAndroid Build Coastguard Worker        actual_sequence_counter = aux_sec_hdr_obj.sequence_counter
412*cfb92d14SAndroid Build Coastguard Worker
413*cfb92d14SAndroid Build Coastguard Worker        # THEN
414*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(struct.unpack(">I", key_id[:4])[0], actual_sequence_counter)
415*cfb92d14SAndroid Build Coastguard Worker
416*cfb92d14SAndroid Build Coastguard Worker
417*cfb92d14SAndroid Build Coastguard Workerclass TestAuxiliarySecurityHeaderFactory(unittest.TestCase):
418*cfb92d14SAndroid Build Coastguard Worker
419*cfb92d14SAndroid Build Coastguard Worker    def test_should_create_AuxiliarySecurityHeader_from_bytearray_when_parse_method_is_called(self):
420*cfb92d14SAndroid Build Coastguard Worker        # GIVEN
421*cfb92d14SAndroid Build Coastguard Worker        key_id_mode = any_key_id_mode()
422*cfb92d14SAndroid Build Coastguard Worker        sec_lvl = any_security_level()
423*cfb92d14SAndroid Build Coastguard Worker        frame_counter = any_frame_counter()
424*cfb92d14SAndroid Build Coastguard Worker        key_id = any_key_id(key_id_mode)
425*cfb92d14SAndroid Build Coastguard Worker
426*cfb92d14SAndroid Build Coastguard Worker        factory = net_crypto.AuxiliarySecurityHeaderFactory()
427*cfb92d14SAndroid Build Coastguard Worker
428*cfb92d14SAndroid Build Coastguard Worker        data = bytearray([sec_lvl | key_id_mode << 3]) + struct.pack("<I", frame_counter) + key_id
429*cfb92d14SAndroid Build Coastguard Worker
430*cfb92d14SAndroid Build Coastguard Worker        # WHEN
431*cfb92d14SAndroid Build Coastguard Worker        aux_sec_hdr = factory.parse(io.BytesIO(data), common.MessageInfo())
432*cfb92d14SAndroid Build Coastguard Worker
433*cfb92d14SAndroid Build Coastguard Worker        # THEN
434*cfb92d14SAndroid Build Coastguard Worker        self.assertTrue(isinstance(aux_sec_hdr, net_crypto.AuxiliarySecurityHeader))
435*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(key_id_mode, aux_sec_hdr.key_id_mode)
436*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(sec_lvl, aux_sec_hdr.security_level)
437*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual(frame_counter, aux_sec_hdr.frame_counter)
438*cfb92d14SAndroid Build Coastguard Worker
439*cfb92d14SAndroid Build Coastguard Worker
440*cfb92d14SAndroid Build Coastguard Workerif __name__ == "__main__":
441*cfb92d14SAndroid Build Coastguard Worker    unittest.main()
442