From a89f7d0c4b2d8a5739939887cf70b595b3b6684b Mon Sep 17 00:00:00 2001 From: Yves Richard Date: Mon, 16 Oct 2023 15:24:39 +0200 Subject: [PATCH] Add functions to lock/unlock the APDU source to a specific media --- include/os_io_seproxyhal.h | 21 ++++++++++++++++++++- lib_blewbxx_impl/src/ledger_ble.c | 11 +++++++---- lib_stusb_impl/usbd_impl.c | 6 ++++-- src/os_io_seproxyhal.c | 27 ++++++++++++++++++++++----- 4 files changed, 53 insertions(+), 12 deletions(-) diff --git a/include/os_io_seproxyhal.h b/include/os_io_seproxyhal.h index 3fcb86fa5..7a79f95c5 100644 --- a/include/os_io_seproxyhal.h +++ b/include/os_io_seproxyhal.h @@ -233,6 +233,7 @@ typedef struct io_seph_s { unsigned short apdu_length; // total length to be received unsigned short io_flags; // flags to be set when calling io_exchange io_apdu_media_t apdu_media; + io_apdu_media_t apdu_media_lock; unsigned int ms; @@ -272,11 +273,29 @@ extern io_seph_app_t G_io_app; */ void io_task(void); /** - * IO task initializez + * IO task initialize */ void io_start(void); #endif // HAVE_IO_TASK +/** + * Lock apdu source to a media + * After this function is called, all subsequent apdus + * that come from any other media will be refused + */ +void io_apdu_media_lock(io_apdu_media_t media); +/** + * Unlock apdu source. + * After this function is called, apdus any media will be processed + */ +void io_apdu_media_unlock(void); +/** + * Check if an Apdu media shall be accepted. + * Return true if source media is not locked or if the media corresponds to the current lock + * Return false if media doesn't correspond to the current lock + */ +bool io_apdu_is_media_accepted(io_apdu_media_t media); + void io_seproxyhal_setup_ticker(unsigned int interval_ms); void io_seproxyhal_power_off(bool criticalBattery); void io_seproxyhal_se_reset(void); diff --git a/lib_blewbxx_impl/src/ledger_ble.c b/lib_blewbxx_impl/src/ledger_ble.c index 7f1dbe363..f2fdd3b05 100644 --- a/lib_blewbxx_impl/src/ledger_ble.c +++ b/lib_blewbxx_impl/src/ledger_ble.c @@ -511,7 +511,8 @@ static void hci_evt_cmd_complete(const uint8_t *buffer, uint16_t length) if (ledger_ble_data.transfer_mode_enable) { if ((ledger_protocol_data.rx_apdu_length) && (ledger_protocol_data.rx_apdu_status == APDU_STATUS_COMPLETE)) { - if (G_io_app.apdu_state == APDU_IDLE) { + if (G_io_app.apdu_state == APDU_IDLE + && io_apdu_is_media_accepted(IO_APDU_MEDIA_BLE)) { copy_apdu_to_app(false); } else { @@ -886,7 +887,8 @@ static void attribute_modified(const uint8_t *buffer, uint16_t length) LOG_BLE("Transfer failed 0x%04x\n", U2BE(ledger_ble_data.resp, 0)); G_io_app.transfer_mode = 0; check_transfer_mode(G_io_app.transfer_mode); - if (G_io_app.apdu_state == APDU_IDLE) { + if (G_io_app.apdu_state == APDU_IDLE + && io_apdu_is_media_accepted(IO_APDU_MEDIA_BLE)) { copy_apdu_to_app(true); } else { @@ -907,7 +909,8 @@ static void attribute_modified(const uint8_t *buffer, uint16_t length) } else { // Nominal case for apdu reception - if (G_io_app.apdu_state == APDU_IDLE) { + if (G_io_app.apdu_state == APDU_IDLE + && io_apdu_is_media_accepted(IO_APDU_MEDIA_BLE)) { copy_apdu_to_app(true); } else { @@ -954,7 +957,7 @@ static void write_permit_request(const uint8_t *buffer, uint16_t length) data_length, &buffer[3]); if (ledger_protocol_data.rx_apdu_status == APDU_STATUS_COMPLETE) { - if (G_io_app.apdu_state == APDU_IDLE) { + if (G_io_app.apdu_state == APDU_IDLE && io_apdu_is_media_accepted(IO_APDU_MEDIA_BLE)) { copy_apdu_to_app(true); } else { diff --git a/lib_stusb_impl/usbd_impl.c b/lib_stusb_impl/usbd_impl.c index 1f9709f2b..520b020f0 100644 --- a/lib_stusb_impl/usbd_impl.c +++ b/lib_stusb_impl/usbd_impl.c @@ -1082,7 +1082,8 @@ uint8_t USBD_HID_DataOut_impl(USBD_HandleTypeDef *pdev, #ifndef HAVE_USB_HIDKBD // avoid troubles when an apdu has not been replied yet - if (G_io_app.apdu_state == APDU_IDLE) { + if (G_io_app.apdu_state == APDU_IDLE + && io_apdu_is_media_accepted(IO_APDU_MEDIA_USB_HID)) { // add to the hid transport switch (io_usb_hid_receive(io_usb_send_apdu_data, buffer, @@ -1170,7 +1171,8 @@ uint8_t USBD_WEBUSB_DataOut(USBD_HandleTypeDef *pdev, USBD_LL_PrepareReceive(pdev, WEBUSB_EPOUT_ADDR, WEBUSB_EPOUT_SIZE); // avoid troubles when an apdu has not been replied yet - if (G_io_app.apdu_state == APDU_IDLE) { + if (G_io_app.apdu_state == APDU_IDLE + && io_apdu_is_media_accepted(IO_APDU_MEDIA_USB_WEBUSB)) { // add to the hid transport switch (io_usb_hid_receive(io_usb_send_apdu_data_ep0x83, buffer, diff --git a/src/os_io_seproxyhal.c b/src/os_io_seproxyhal.c index bf08d2bbc..1ae8e160f 100644 --- a/src/os_io_seproxyhal.c +++ b/src/os_io_seproxyhal.c @@ -231,7 +231,7 @@ void io_usb_send_apdu_data_ep0x83(unsigned char *buffer, unsigned short length) void io_seproxyhal_handle_capdu_event(void) { - if (G_io_app.apdu_state == APDU_IDLE) { + if (G_io_app.apdu_state == APDU_IDLE && io_apdu_is_media_accepted(IO_APDU_MEDIA_RAW)) { size_t max = MIN(sizeof(G_io_apdu_buffer) - 3, sizeof(G_io_seproxyhal_spi_buffer) - 3); size_t size = U2BE(G_io_seproxyhal_spi_buffer, 1); @@ -254,7 +254,7 @@ void io_seproxyhal_handle_capdu_event(void) #ifdef HAVE_NFC void io_seproxyhal_handle_nfc_recv_event(void) { - if (G_io_app.apdu_state == APDU_IDLE) { + if (G_io_app.apdu_state == APDU_IDLE && io_apdu_is_media_accepted(IO_APDU_MEDIA_NFC)) { size_t max = MIN(sizeof(G_io_apdu_buffer), sizeof(G_io_seproxyhal_spi_buffer) - 3); size_t size = U2BE(G_io_seproxyhal_spi_buffer, 1); @@ -464,9 +464,10 @@ void io_seproxyhal_init(void) G_io_app.plane_mode = plane; #endif // HAVE_BLE - G_io_app.apdu_state = APDU_IDLE; - G_io_app.apdu_length = 0; - G_io_app.apdu_media = IO_APDU_MEDIA_NONE; + G_io_app.apdu_state = APDU_IDLE; + G_io_app.apdu_length = 0; + G_io_app.apdu_media = IO_APDU_MEDIA_NONE; + G_io_app.apdu_media_lock = IO_APDU_MEDIA_NONE; G_io_app.ms = 0; @@ -489,6 +490,22 @@ void io_seproxyhal_init(void) #endif // !defined(HAVE_BOLOS) && defined(HAVE_PENDING_REVIEW_SCREEN) } +void io_apdu_media_lock(io_apdu_media_t media) +{ + G_io_app.apdu_media_lock = media; +} +void io_apdu_media_unlock(void) +{ + G_io_app.apdu_media_lock = IO_APDU_MEDIA_NONE; +} +bool io_apdu_is_media_accepted(io_apdu_media_t media) +{ + if (G_io_app.apdu_media_lock == IO_APDU_MEDIA_NONE) { + return true; + } + return (G_io_app.apdu_media_lock == media); +} + #ifdef HAVE_PIEZO_SOUND void io_seproxyhal_play_tune(tune_index_e tune_index) {