#!/usr/bin/env python3 # # Copyright (c) 2016, The OpenThread Authors. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # 3. Neither the name of the copyright holder nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. # import io import random import struct import unittest import ipaddress import common import net_crypto network_key = bytearray( [0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff]) def convert_aux_sec_hdr_to_bytearray(aux_sec_hdr): data = bytearray([aux_sec_hdr.security_level | ((aux_sec_hdr.key_id_mode & 0x03) << 3)]) data += struct.pack("L", frame_counter), nonce_bytes.read(4)) self.assertEqual(security_level, ord(nonce_bytes.read(1))) def test_should_create_authenticated_data_when_create_authenticated_data_method_is_called(self): """ Only Key id mode 2. Length of the Auxiliary Security Header is constantly equal 10. """ # GIVEN source_address = any_ip_address() destination_address = any_ip_address() auxiliary_security_header_bytes = convert_aux_sec_hdr_to_bytearray(any_auxiliary_security_header()) creator = net_crypto.MleCryptoMaterialCreator(network_key) # WHEN authenticated_data = creator._create_authenticated_data(source_address, destination_address, auxiliary_security_header_bytes) # THEN authenticated_data_bytes = io.BytesIO(authenticated_data) self.assertEqual(source_address.packed, authenticated_data_bytes.read(16)) self.assertEqual(destination_address.packed, authenticated_data_bytes.read(16)) self.assertEqual(auxiliary_security_header_bytes, authenticated_data_bytes.read(10)) def test_should_create_key_and_nonce_and_auth_data_when_create_key_and_nonce_and_auth_data_is_called(self): # GIVEN message_info = common.MessageInfo() message_info.source_mac_address = common.MacAddress.from_eui64(any_eui64()) message_info.source_ipv6 = any_ip_address() message_info.destination_ipv6 = any_ip_address() message_info.aux_sec_hdr = any_auxiliary_security_header() message_info.aux_sec_hdr_bytes = convert_aux_sec_hdr_to_bytearray(message_info.aux_sec_hdr) creator = net_crypto.MleCryptoMaterialCreator(network_key) # WHEN key, nonce, auth_data = creator.create_key_and_nonce_and_authenticated_data(message_info) # THEN self.assertEqual( message_info.source_mac_address.mac_address + struct.pack(">LB", message_info.aux_sec_hdr.frame_counter, message_info.aux_sec_hdr.security_level), nonce) self.assertEqual( message_info.source_ipv6.packed + message_info.destination_ipv6.packed + message_info.aux_sec_hdr_bytes, auth_data) class TestAuxiliarySecurityHeader(unittest.TestCase): def test_should_return_key_id_mode_value_when_key_id_mode_property_is_called(self): # GIVEN key_id_mode = any_key_id_mode() aux_sec_hdr_obj = net_crypto.AuxiliarySecurityHeader(key_id_mode, any_security_level(), any_frame_counter(), any_key_id(key_id_mode)) # WHEN actual_key_id_mode = aux_sec_hdr_obj.key_id_mode # THEN self.assertEqual(key_id_mode, actual_key_id_mode) def test_should_return_security_level_value_when_security_level_property_is_called(self): # GIVEN security_level = any_security_level() key_id_mode = any_key_id_mode() aux_sec_hdr_obj = net_crypto.AuxiliarySecurityHeader(key_id_mode, security_level, any_frame_counter(), any_key_id(key_id_mode)) # WHEN actual_security_level = aux_sec_hdr_obj.security_level # THEN self.assertEqual(security_level, actual_security_level) def test_should_return_frame_counter_value_when_frame_counter_property_is_called(self): # GIVEN frame_counter = any_frame_counter() key_id_mode = any_key_id_mode() aux_sec_hdr_obj = net_crypto.AuxiliarySecurityHeader(key_id_mode, any_security_level(), frame_counter, any_key_id(key_id_mode)) # WHEN actual_frame_counter = aux_sec_hdr_obj.frame_counter # THEN self.assertEqual(frame_counter, actual_frame_counter) def test_should_return_key_id_value_when_key_id_property_is_called(self): # GIVEN key_id_mode = any_key_id_mode() key_id = any_key_id(key_id_mode) aux_sec_hdr_obj = net_crypto.AuxiliarySecurityHeader(key_id_mode, any_security_level(), any_frame_counter(), key_id) # WHEN actual_key_id = aux_sec_hdr_obj.key_id # THEN self.assertEqual(key_id, actual_key_id) def test_should_return_sequence_counter_value_when_sequence_counter_property_is_called(self): # GIVEN key_id_mode = 2 key_id = any_key_id(key_id_mode) aux_sec_hdr_obj = net_crypto.AuxiliarySecurityHeader(key_id_mode, any_security_level(), any_frame_counter(), key_id) # WHEN actual_sequence_counter = aux_sec_hdr_obj.sequence_counter # THEN self.assertEqual(struct.unpack(">I", key_id[:4])[0], actual_sequence_counter) class TestAuxiliarySecurityHeaderFactory(unittest.TestCase): def test_should_create_AuxiliarySecurityHeader_from_bytearray_when_parse_method_is_called(self): # GIVEN key_id_mode = any_key_id_mode() sec_lvl = any_security_level() frame_counter = any_frame_counter() key_id = any_key_id(key_id_mode) factory = net_crypto.AuxiliarySecurityHeaderFactory() data = bytearray([sec_lvl | key_id_mode << 3]) + struct.pack("