diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000000..f617a72f1c --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "files.associations": { + "string.h": "c", + "queue.h": "c" + } +} \ No newline at end of file diff --git a/py/send_message.py b/py/send_message.py index a56f66487c..59bce3e9c6 100755 --- a/py/send_message.py +++ b/py/send_message.py @@ -41,6 +41,7 @@ FirmwareVersionOutdatedException, u2fhid, bitbox_api_protocol, + PhysicalLayer, ) import u2f @@ -1555,6 +1556,31 @@ def run(self) -> int: self._device.close() return 0 +def connect_to_simulator_bitbox(debug: bool) -> int: + class Simulator(PhysicalLayer): + def write(self, data: bytes) -> None: + raise Exception(f"TODO: write {data.hex()} to simulator") + + def read(self, size: int, timeout_ms: int) -> bytes: + raise Exception(f"TODO: read {size} bytes from simulator") + + simulator = Simulator() + + device_info = { + "serial_number": "v9.15.0", + "path": "", + "product_string": "BitBox02BTC", + } + noise_config = bitbox_api_protocol.BitBoxNoiseConfig() + bitbox_connection = bitbox02.BitBox02( + transport=u2fhid.U2FHid(simulator), device_info=device_info, noise_config=noise_config, + ) + try: + bitbox_connection.check_min_version() + except FirmwareVersionOutdatedException as exc: + print("WARNING: ", exc) + + return SendMessage(bitbox_connection, debug).run() def connect_to_usb_bitbox(debug: bool, use_cache: bool) -> int: """ @@ -1643,6 +1669,7 @@ def main() -> int: parser = argparse.ArgumentParser(description="Tool for communicating with bitbox device") parser.add_argument("--debug", action="store_true", help="Print messages sent and received") parser.add_argument("--u2f", action="store_true", help="Use u2f menu instead") + parser.add_argument("--simulator", action="store_true", help="Connect to the BitBox02 simulator instead of a real BitBox02") parser.add_argument( "--no-cache", action="store_true", help="Don't use cached or store noise keys" ) @@ -1663,6 +1690,9 @@ def main() -> int: return u2fapp.run() return 1 + if args.simulator: + return connect_to_simulator_bitbox(args.debug) + return connect_to_usb_bitbox(args.debug, not args.no_cache) diff --git a/test/unit-test/simulator b/test/unit-test/simulator new file mode 100755 index 0000000000..21dfa588d2 Binary files /dev/null and b/test/unit-test/simulator differ diff --git a/test/unit-test/simulator.c b/test/unit-test/simulator.c new file mode 100644 index 0000000000..427a498e64 --- /dev/null +++ b/test/unit-test/simulator.c @@ -0,0 +1,72 @@ +// Copyright 2023 Shift Cryptosecurity AG +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +/* +infinite loop reading stdin line by line +each line is e.g. a hex encoded string containing the USB message that is sent by the host (e.g. the USB msgs that is sent by the bitbox-api-rs client library) +process the usb message +print the response usb messages to stdout, again one message per line, hex encoded + +somehow expose a usb connection to this c program. There read the messages from stdin and write the responses to stdout. +When read the message, call the message handling function of the firmware so that it takes care of everything and returns the output +*/ + +#include +#include "../../src/usb/usb_processing.h" + +#define USB_DESC_HID_EP_SIZE 0x40 +#define USB_REPORT_SIZE USB_DESC_HID_EP_SIZE +#define USB_HID_REPORT_IN_SIZE USB_REPORT_SIZE +#define USB_HID_REPORT_OUT_SIZE USB_REPORT_SIZE + +char* get_usb_message(char* input) { + char* res = fgets(input, sizeof(input), stdin); + input[strcspn(input, "\n\r")] = 0; + return res; +} + +void simulate_firmware_execution(char* input) { + //u2f_packet_process + + //usb_processing_process + //chain of call: firmware_main_loop -> usb_processing_process -> _usb_consume_incoming_packets -> + // _usb_execute_packet + //usb_processing_process(usb_processing_hww()); + /* First, process all the incoming USB traffic. */ + //usb_processing_process(usb_processing_hww()); + /* + * If USB has generated events at the application level, + * process them now. + */ + //hww_process(); + + //usb_packet_process but it puts the packet into queue + //chain of call: usb_packet_process -> usb_processing_enqueue -> _build_packet + static uint8_t _out_report[USB_HID_REPORT_OUT_SIZE]; + memccpy(_out_report, input, 0, sizeof(_out_report)); + usb_packet_process((const USB_FRAME*)_out_report); +} + +int main(void) { + char buffer[4096]; + while (get_usb_message(buffer)) { + if (strcmp(buffer, "") == 0) { + break; + } + printf("received: %s\n", buffer); + simulate_firmware_execution(buffer); + } + return 0; +} \ No newline at end of file