From 82dd24d8257b2d66fb2f5b447e19c6493fb781a7 Mon Sep 17 00:00:00 2001 From: Jakub Date: Wed, 3 Aug 2022 17:38:47 +0200 Subject: [PATCH] tools/hci_throughput: testing over encrypted link Added option enable_encryption to run throughput tests over encrypted link. --- tools/hci_throughput/config.yaml.sample | 1 + tools/hci_throughput/hci.py | 37 +++++++++++ tools/hci_throughput/hci_commands.py | 84 +++++++++++++++++++++++++ tools/hci_throughput/hci_device.py | 7 ++- tools/hci_throughput/main.py | 8 ++- 5 files changed, 135 insertions(+), 2 deletions(-) diff --git a/tools/hci_throughput/config.yaml.sample b/tools/hci_throughput/config.yaml.sample index 7a8330075..68068e3e7 100644 --- a/tools/hci_throughput/config.yaml.sample +++ b/tools/hci_throughput/config.yaml.sample @@ -43,6 +43,7 @@ adv: peer_address: 00:00:00:00:00:00 advertising_channel_map: 7 advertising_filter_policy: 0 +enable_encryption: true conn: le_scan_interval: 2400 le_scan_window: 2400 diff --git a/tools/hci_throughput/hci.py b/tools/hci_throughput/hci.py index d0a0b8a1e..e5eb1179c 100644 --- a/tools/hci_throughput/hci.py +++ b/tools/hci_throughput/hci.py @@ -35,6 +35,7 @@ HCI_EVENT_PACKET = 0x04 L2CAP_HDR_BYTES = 4 HCI_EV_CODE_DISCONN_CMP = 0x05 +HCI_EV_CODE_ENCRYPTION_CHANGE = 0x08 HCI_EV_CODE_CMD_CMP = 0x0e HCI_EV_CODE_CMD_STATUS = 0x0f HCI_EV_CODE_LE_META_EVENT = 0x3e @@ -42,6 +43,7 @@ HCI_SUBEV_CODE_LE_ENHANCED_CONN_CMP = 0x0a HCI_SUBEV_CODE_LE_DATA_LEN_CHANGE = 0x07 HCI_SUBEV_CODE_LE_PHY_UPDATE_CMP = 0x0c HCI_SUBEV_CODE_LE_CHAN_SEL_ALG = 0x14 +HCI_SUBEV_CODE_LE_LONG_TERM_KEY_REQUEST = 0x05 HCI_EV_NUM_COMP_PKTS = 0x13 CONN_FAILED_TO_BE_ESTABLISHED = 0x3e @@ -66,6 +68,8 @@ OCF_LE_SET_ADVERTISE_ENABLE = 0x000a OCF_LE_SET_SCAN_PARAMETERS = 0x000b OCF_LE_SET_SCAN_ENABLE = 0x000c OCF_LE_CREATE_CONN = 0x000d +OCF_LE_ENABLE_ENCRYPTION = 0x0019 +OCF_LE_LONG_TERM_KEY_REQUEST_REPLY = 0x001A OCF_LE_SET_DATA_LEN = 0x0022 OCF_LE_READ_SUGGESTED_DFLT_DATA_LEN = 0x0023 OCF_LE_READ_MAX_DATA_LEN = 0x002f @@ -106,6 +110,7 @@ num_of_completed_packets_cnt = 0 num_of_completed_packets_time = 0 read_local_commands = None le_read_local_supported_features = None +ltk = None ############ # FUNCTIONS @@ -303,6 +308,21 @@ class HCI_Ev_Cmd_Status: self.opcode = opcode +@dataclass +class HCI_Ev_LE_Encryption_Change(): + status: int + connection_handle: int + encryption_enabled: int + + def __init__(self): + self.set() + + def set(self, status=0, connection_handle=0, encryption_enabled=0): + self.status = status + self.connection_handle = connection_handle + self.encryption_enabled = encryption_enabled + + @dataclass class HCI_Ev_LE_Meta: subevent_code: int @@ -374,6 +394,23 @@ class HCI_Ev_LE_Data_Length_Change(HCI_Ev_LE_Meta): self.triggered = triggered +@dataclass +class HCI_Ev_LE_Long_Term_Key_Request(HCI_Ev_LE_Meta): + conn_handle: int + random_number: int + encrypted_diversifier: int + + def __init__(self): + self.set() + + def set(self, subevent_code=0, conn_handle=0, random_number=0, + encrypted_diversifier=0): + super().set(subevent_code) + self.conn_handle = conn_handle + self.random_number = random_number + self.encrypted_diversifier = encrypted_diversifier + + @dataclass class HCI_Ev_LE_PHY_Update_Complete(HCI_Ev_LE_Meta): status: int diff --git a/tools/hci_throughput/hci_commands.py b/tools/hci_throughput/hci_commands.py index 83e6284f5..31bed375e 100644 --- a/tools/hci_throughput/hci_commands.py +++ b/tools/hci_throughput/hci_commands.py @@ -47,6 +47,7 @@ class HCI_Commands(): self.async_sem_cmd = asyncio.Semaphore() self.async_ev_cmd_end = asyncio.Event() self.async_ev_connected = asyncio.Event() + self.async_ev_encryption_change = asyncio.Event() self.async_ev_set_data_len = asyncio.Event() self.async_ev_update_phy = asyncio.Event() self.async_ev_num_cmp_pckts = asyncio.Event() @@ -219,6 +220,41 @@ class HCI_Commands(): await self.async_ev_cmd_end.wait() self.async_ev_cmd_end.clear() + async def cmd_le_enable_encryption(self, conn_handle: int, random_number: int, ediv: int, ltk: int): + async with self.async_sem_cmd: + hci.ltk = ltk + random_number_bytes = random_number.to_bytes(8, byteorder='little') + ltk_bytes = ltk.to_bytes(16, byteorder='little') + data_bytes = struct.pack(" dict: with open(args.init_file, "r") as file: init_file = yaml.safe_load(file) ini = init_file[args.mode] - global test_dir, transport_directory + global test_dir, transport_directory, ltk test_dir = init_file["test_dir"] transport_directory = init_file["transport_directory"] + hci.ltk = int(init_file["ltk"], 16) with open(args.config_file) as f: cfg = yaml.safe_load(f) diff --git a/tools/hci_throughput/main.py b/tools/hci_throughput/main.py index b00780a03..565cce426 100644 --- a/tools/hci_throughput/main.py +++ b/tools/hci_throughput/main.py @@ -29,6 +29,7 @@ import csv import util import os import math +import random PROCESS_TIMEOUT = 500 # seconds, adjust if necessary @@ -94,6 +95,10 @@ def change_config_var(filename: str, group: str, variable: str, yaml.safe_dump(cfg, file, indent=1, sort_keys=False, default_style=None, default_flow_style=False) +def generate_long_term_key(): + rand_val = random.getrandbits(128) + return rand_val.to_bytes(16, byteorder='little') + def get_init_dict(filename: str, args_list: list, modes: list, dir: str, transport_directory: str): @@ -115,7 +120,8 @@ def get_init_dict(filename: str, args_list: list, modes: list, dir: str, "peer_address": args_list[0][2] }, "test_dir": dir, - "transport_directory": transport_directory + "transport_directory": transport_directory, + "ltk": hex(random.getrandbits(128)) } with open(filename, 'w') as file: