From b96e853e6d2e960e5a60c717b1ca84100c7bccc8 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Thu, 2 Mar 2023 22:05:04 +0100 Subject: [PATCH] Added support for Fido emulation to automatize tests. Signed-off-by: Pol Henarejos --- pico_hsm_sdk_import.cmake | 16 +++++------ src/usb/emulation/emulation.c | 54 ++++++++++++++++++++++++++++++++--- src/usb/hid/hid.c | 21 +++++++++++++- 3 files changed, 78 insertions(+), 13 deletions(-) diff --git a/pico_hsm_sdk_import.cmake b/pico_hsm_sdk_import.cmake index d8e4427..e7dc7f0 100644 --- a/pico_hsm_sdk_import.cmake +++ b/pico_hsm_sdk_import.cmake @@ -126,6 +126,14 @@ function(add_impl_library target) string(TOUPPER ${target} TARGET_UPPER) target_compile_definitions(${target} INTERFACE LIB_${TARGET_UPPER}=1) endfunction() +if(${USB_ITF_HID}) + set(SOURCES ${SOURCES} + ${CMAKE_CURRENT_LIST_DIR}/src/usb/hid/hid.c + ) + set(INCLUDES ${INCLUDES} + ${CMAKE_CURRENT_LIST_DIR}/src/usb/hid + ) +endif() if (ENABLE_EMULATION) if(APPLE) set(CMAKE_OSX_SYSROOT "/Library/Developer/CommandLineTools//SDKs/MacOSX11.3.sdk") @@ -151,14 +159,6 @@ if (ENABLE_EMULATION) ) endif() else() - if(${USB_ITF_HID}) - set(SOURCES ${SOURCES} - ${CMAKE_CURRENT_LIST_DIR}/src/usb/hid/hid.c - ) - set(INCLUDES ${INCLUDES} - ${CMAKE_CURRENT_LIST_DIR}/src/usb/hid - ) - endif() if (${USB_ITF_CCID}) set(SOURCES ${SOURCES} diff --git a/src/usb/emulation/emulation.c b/src/usb/emulation/emulation.c index 1baadee..badc5ab 100644 --- a/src/usb/emulation/emulation.c +++ b/src/usb/emulation/emulation.c @@ -35,6 +35,11 @@ int ccid_sock = 0; int hid_server_sock = 0; int hid_client_sock = -1; +extern uint8_t thread_type; +extern const uint8_t *cbor_data; +extern size_t cbor_len; +extern uint8_t cmd; +extern int cbor_parse(uint8_t cmd, const uint8_t *data, size_t len); int msleep(long msec) { struct timespec ts; @@ -140,7 +145,13 @@ int get_sock_itf(uint8_t itf) { return -1; } -int driver_write_emul(uint8_t itf, const uint8_t *buffer, size_t buffer_size) { +extern void tud_hid_report_complete_cb(uint8_t instance, uint8_t const *report, uint16_t len); +const uint8_t *complete_report = NULL; +uint16_t complete_len = 0; +extern bool last_write_result; +extern uint16_t send_buffer_size; +int driver_write_emul(uint8_t itf, const uint8_t *buffer, size_t buffer_size) +{ uint16_t size = htons(buffer_size); int sock = get_sock_itf(itf); // DEBUG_PAYLOAD(buffer,buffer_size); @@ -157,6 +168,11 @@ int driver_write_emul(uint8_t itf, const uint8_t *buffer, size_t buffer_size) { msleep(10); } } while (ret <= 0); + if (itf == ITF_HID) { + last_write_result = true; + complete_report = buffer; + complete_len = buffer_size; + } return buffer_size; } @@ -173,7 +189,12 @@ uint32_t emul_write(uint8_t itf, uint16_t size) { } void driver_exec_finished_cont_emul(uint8_t itf, size_t size_next, size_t offset) { - emul_write_offset(itf, size_next, offset); + if (itf == ITF_HID) { + driver_exec_finished_cont_hid(size_next, offset); + } + else { + emul_write_offset(itf, size_next, offset); + } } int driver_process_usb_packet_emul(uint8_t itf, uint16_t len) { @@ -201,7 +222,21 @@ int driver_process_usb_packet_emul(uint8_t itf, uint16_t len) { } } else if (itf == ITF_HID) { + if (driver_process_usb_packet_hid(len) > 0) { + if (thread_type == 1) { + process_apdu(); + apdu_finish(); + finished_data_size = apdu_next(); + } + else if (thread_type == 2) { + apdu.sw = cbor_parse(cmd, cbor_data, cbor_len); + if (apdu.sw == 0) + DEBUG_DATA(res_APDU + 1, res_APDU_size); + finished_data_size = res_APDU_size+1; + } + driver_exec_finished_hid(finished_data_size); + } } } usb_clear_rx(itf); @@ -210,7 +245,7 @@ int driver_process_usb_packet_emul(uint8_t itf, uint16_t len) { uint16_t emul_read(uint8_t itf) { /* First we look for a client */ - if (itf == ITF_HID && hid_client_sock == -1) { + if (itf == ITF_HID) { struct sockaddr_in client_sockaddr; socklen_t client_socklen = sizeof client_sockaddr; @@ -226,11 +261,20 @@ uint16_t emul_read(uint8_t itf) { if (poll(&pfd, 1, timeout) == -1) return 0; - if(pfd.revents & POLLIN) + if(pfd.revents & POLLIN) { + if (hid_client_sock > 0) + close(hid_client_sock); hid_client_sock = accept(hid_server_sock, (struct sockaddr *) &client_sockaddr, &client_socklen); + printf("hid_client connected!\n"); + } + } + if (itf == ITF_HID && send_buffer_size > 0) { + last_write_result = true; + tud_hid_report_complete_cb(ITF_HID, complete_report, complete_len); } int sock = get_sock_itf(itf); + //printf("get_sockt itf %d - %d\n", itf, sock); uint16_t len = 0; fd_set input; FD_ZERO(&input); @@ -259,5 +303,7 @@ uint16_t emul_read(uint8_t itf) { } } } + //else + // printf("no input for sock %d - %d\n", itf, sock); return 0; } diff --git a/src/usb/hid/hid.c b/src/usb/hid/hid.c index bae9389..a2172f2 100644 --- a/src/usb/hid/hid.c +++ b/src/usb/hid/hid.c @@ -15,13 +15,15 @@ * along with this program. If not, see . */ +#ifndef ENABLE_EMULATION #include "tusb.h" +#include "bsp/board.h" +#endif #include "ctap_hid.h" #include "hsm.h" #include "hsm_version.h" #include "apdu.h" #include "usb.h" -#include "bsp/board.h" static bool mounted = false; extern int cbor_process(uint8_t, const uint8_t *, size_t); @@ -46,7 +48,9 @@ bool driver_mounted_hid() { CTAPHID_FRAME *ctap_req = NULL, *ctap_resp = NULL; int driver_init_hid() { +#ifndef ENABLE_EMULATION tud_init(BOARD_TUD_RHPORT); +#endif ctap_req = (CTAPHID_FRAME *) usb_get_rx(ITF_HID); apdu.header = ctap_req->init.data; @@ -62,6 +66,7 @@ int driver_init_hid() { // USB HID //--------------------------------------------------------------------+ +#ifndef ENABLE_EMULATION // Invoked when received GET_REPORT control request // Application must fill buffer report's content and return its length. // Return zero will cause the stack to STALL request @@ -83,6 +88,7 @@ uint16_t tud_hid_get_report_cb(uint8_t itf, return reqlen; } +#endif uint32_t hid_write_offset(uint16_t size, uint16_t offset) { if (*usb_get_tx(ITF_HID) != 0x81) { @@ -98,6 +104,7 @@ uint32_t hid_write(uint16_t size) { uint16_t send_buffer_size = 0; bool last_write_result = false; +#ifndef ENABLE_EMULATION static uint8_t keyboard_buffer[256]; static uint8_t keyboard_buffer_len = 0; static const uint8_t conv_table[128][2] = { HID_ASCII_TO_KEYCODE }; @@ -135,6 +142,7 @@ static void send_hid_report(uint8_t report_id) { NULL) == true) { keyboard_w++; sent_key = false; + } } } @@ -166,6 +174,7 @@ void hid_task(void) { send_hid_report(REPORT_ID_KEYBOARD); } } +#endif void tud_hid_report_complete_cb(uint8_t instance, uint8_t const *report, uint16_t len) { if (send_buffer_size > 0 && instance == ITF_HID) { @@ -181,6 +190,7 @@ void tud_hid_report_complete_cb(uint8_t instance, uint8_t const *report, uint16_ } } +#ifndef ENABLE_EMULATION int driver_write_hid(const uint8_t *buffer, size_t buffer_size) { last_write_result = tud_hid_n_report(ITF_HID, 0, buffer, buffer_size); printf("result %d\n", last_write_result); @@ -189,11 +199,13 @@ int driver_write_hid(const uint8_t *buffer, size_t buffer_size) { } return MIN(64, buffer_size); } +#endif size_t driver_read_hid(uint8_t *buffer, size_t buffer_size) { return 0; } +#ifndef ENABLE_EMULATION // Invoked when received SET_REPORT control request or // received data on OUT endpoint ( Report ID = 0, Type = 0 ) void tud_hid_set_report_cb(uint8_t itf, @@ -211,6 +223,7 @@ void tud_hid_set_report_cb(uint8_t itf, } usb_rx(itf, buffer, bufsize); } +#endif uint32_t last_cmd_time = 0, last_packet_time = 0; int ctap_error(uint8_t error) { @@ -334,7 +347,9 @@ int driver_process_usb_packet_hid(uint16_t read) { } ctap_resp = (CTAPHID_FRAME *) usb_get_tx(ITF_HID); memcpy(ctap_resp, ctap_req, sizeof(CTAPHID_FRAME)); +#ifndef ENABLE_EMULATION sleep_ms(1000); //For blinking the device during 1 seg +#endif hid_write(64); msg_packet.len = msg_packet.current_len = 0; last_packet_time = 0; @@ -388,7 +403,9 @@ int driver_process_usb_packet_hid(uint16_t read) { } } //if (thread_type != 1) +#ifndef ENABLE_EMULATION card_start(apdu_thread); +#endif thread_type = 1; if (msg_packet.current_len == msg_packet.len && msg_packet.len > 0) { @@ -407,7 +424,9 @@ int driver_process_usb_packet_hid(uint16_t read) { (msg_packet.len == msg_packet.current_len && msg_packet.len > 0))) { //if (thread_type != 2) +#ifndef ENABLE_EMULATION card_start(cbor_thread); +#endif thread_type = 2; if (msg_packet.current_len == msg_packet.len && msg_packet.len > 0) { apdu_sent = cbor_process(last_cmd, msg_packet.data, msg_packet.len);