From 5c8ade7593e2072f775a3bb5c6e98bea5969eec8 Mon Sep 17 00:00:00 2001 From: Xavier Chapron Date: Mon, 28 Aug 2023 17:36:55 +0200 Subject: [PATCH 1/6] os: Compute usable THROW LR value and allow app to access it (cherry picked from commit 294d28ecd247f861e864d0f1e5189cb68005e02f) --- src/os.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/os.c b/src/os.c index aafa186d5..ab1296b8b 100644 --- a/src/os.c +++ b/src/os.c @@ -79,12 +79,29 @@ char os_secure_memcmp(const void *src1, const void* src2, size_t length) { } #ifndef HAVE_BOLOS +#define MAIN_LINKER_SCRIPT_LOCATION 0xC0DE0000 +int main(void); + +// This function can be used to declare a callback to THROW in the application +__attribute((weak)) void app_throw_info(unsigned int exception, unsigned int lr_val) { + UNUSED(exception); + UNUSED(lr_val); +} + void os_longjmp(unsigned int exception) { -#ifdef HAVE_PRINTF unsigned int lr_val; __asm volatile("mov %0, lr" :"=r"(lr_val)); + + // Compute location before relocation (sort of anti PIC) + lr_val = lr_val - (unsigned int)main + MAIN_LINKER_SCRIPT_LOCATION; + +#ifdef HAVE_PRINTF PRINTF("exception[%d]: LR=0x%08X\n", exception, lr_val); #endif // HAVE_PRINTF + + // Send to the app the info of exception and LR for debug purpose + app_throw_info(exception, lr_val); + longjmp(try_context_get()->jmp_buf, exception); } #endif // HAVE_BOLOS From 8ea10b1fa5977e4bd8278f6aeae06180d586ec01 Mon Sep 17 00:00:00 2001 From: Xavier Chapron Date: Mon, 28 Aug 2023 17:40:11 +0200 Subject: [PATCH 2/6] lib_standard_app: Add a mecanism to display a debug screen upon Throw reception (cherry picked from commit 854a0ab963c43070dd26cc13791b8d5174011a68) --- lib_standard_app/debug.c | 76 ++++++++++++++++++++++++++++++++++++++++ lib_standard_app/debug.h | 3 ++ lib_standard_app/main.c | 20 +++++++++++ 3 files changed, 99 insertions(+) create mode 100644 lib_standard_app/debug.c create mode 100644 lib_standard_app/debug.h diff --git a/lib_standard_app/debug.c b/lib_standard_app/debug.c new file mode 100644 index 000000000..60ba8d7b4 --- /dev/null +++ b/lib_standard_app/debug.c @@ -0,0 +1,76 @@ +/***************************************************************************** + * (c) 2020 Ledger SAS. + * + * 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. + *****************************************************************************/ + +#include // uint*_t +#include // memset, explicit_bzero + +#include "os.h" +#include "io.h" + +#ifdef HAVE_NBGL +#include "nbgl_use_case.h" +#endif + +#ifdef HAVE_DEBUG_THROWS +static char errordata[20]; + +WEAK void app_throw_info(unsigned int exception, unsigned int lr_val) { + snprintf(errordata, + sizeof(errordata), + "n%d, LR=0x%08X", + exception, + lr_val); +} + +static void review_choice(bool confirm) { + UNUSED(confirm); + os_sched_exit(-1); +} + +#ifdef HAVE_BAGL +UX_STEP_CB(ux_error, + bnnn_paging, + review_choice(true), + { + .title = "App error", + .text = errordata, + }); +UX_FLOW(ux_error_flow, &ux_error); +#endif + +WEAK void __attribute__((noreturn)) debug_display_throw_error(int exception) { + UNUSED(exception); + +#ifdef HAVE_BAGL + ux_flow_init(0, ux_error_flow, NULL); +#endif + +#ifdef HAVE_NBGL + nbgl_useCaseChoice(&C_round_warning_64px, + "App error", + errordata, + "Exit app", + "Exit app", + review_choice); +#endif + + // Block until the user approve and the app is quit + while (1) { + io_seproxyhal_io_heartbeat(); + } +} + +#endif diff --git a/lib_standard_app/debug.h b/lib_standard_app/debug.h new file mode 100644 index 000000000..0987417fc --- /dev/null +++ b/lib_standard_app/debug.h @@ -0,0 +1,3 @@ +#pragma once + +WEAK void __attribute__((noreturn)) debug_display_throw_error(int exception); diff --git a/lib_standard_app/main.c b/lib_standard_app/main.c index c4fa902d3..cd4bf6f81 100644 --- a/lib_standard_app/main.c +++ b/lib_standard_app/main.c @@ -19,6 +19,7 @@ #include "os.h" #include "io.h" +#include "debug.h" #ifdef HAVE_SWAP #include "swap.h" @@ -62,6 +63,25 @@ static void standalone_app_main(void) { } CATCH_OTHER(e) { PRINTF("Exiting following exception: %d\n", e); + +#ifdef HAVE_DEBUG_THROWS + // Disable USB and BLE, the app have crashed and is going to be exited + // This is necessary to avoid device freeze while displaying throw error + // in a specific case: + // - the app receives an APDU + // - the app throws before replying + // - the app displays the error on screen + // - the user unplug the NanoX instead of confirming the screen + // - the NanoX goes on battery power and display the lock screen + // - the user plug the NanoX instead of entering its pin + // - the device is frozen, battery should be removed + USB_power(0); +#ifdef HAVE_BLE + BLE_power(0, NULL); +#endif + // Display crash info on screen for debug purpose + debug_display_throw_error(e); +#endif } FINALLY { } From d7c3cd0e18f221e835fe911db1fda193f9ba6703 Mon Sep 17 00:00:00 2001 From: Alexandre Paillier Date: Thu, 31 Aug 2023 16:23:42 +0200 Subject: [PATCH 3/6] Force enable seproxyhal in case of a debug build in the standard app Makefile Just like USB on devices other than the LNS (cherry picked from commit 88b9a5fa9af517c152a666e6078ebd08ed89dbfe) --- Makefile.standard_app | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Makefile.standard_app b/Makefile.standard_app index 37edb57de..a0d6dc8b8 100644 --- a/Makefile.standard_app +++ b/Makefile.standard_app @@ -91,11 +91,12 @@ ifneq ($(DISABLE_STANDARD_SNPRINTF), 1) DEFINES += HAVE_SPRINTF HAVE_SNPRINTF_FORMAT_U endif -ifneq ($(TARGET_NAME),TARGET_NANOS) +ifneq ($(DEBUG), 0) # Since the PRINTF implementation uses the USB code - ifneq ($(DEBUG), 0) + ifneq ($(TARGET_NAME),TARGET_NANOS) DISABLE_STANDARD_USB = 0 endif + DISABLE_SEPROXYHAL = 0 endif ifneq ($(DISABLE_STANDARD_USB), 1) From 2d5fef506e78ec0ddf3f8b1bb3e20a3b564b1ad2 Mon Sep 17 00:00:00 2001 From: Alexandre Paillier Date: Thu, 31 Aug 2023 16:45:42 +0200 Subject: [PATCH 4/6] Fix APPNAME handling in standard app Makefile (cherry picked from commit 5f7f084d93b9ca2182c3677875f5600b4da3f17c) --- Makefile.standard_app | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile.standard_app b/Makefile.standard_app index a0d6dc8b8..573e41cd6 100644 --- a/Makefile.standard_app +++ b/Makefile.standard_app @@ -75,7 +75,8 @@ endif # STANDARD DEFINES # ##################################################################### DEFINES += $(DEFINES_LIB) -DEFINES += APPNAME=\"$(APPNAME)\" +# Added directly as a CFLAG because it might contain spaces +CFLAGS += -DAPPNAME=\"$(APPNAME)\" DEFINES += APPVERSION=\"$(APPVERSION)\" DEFINES += MAJOR_VERSION=$(APPVERSION_M) MINOR_VERSION=$(APPVERSION_N) PATCH_VERSION=$(APPVERSION_P) DEFINES += IO_HID_EP_LENGTH=64 From dba106b02be469b9d1f50305ed4e2cda6e08394a Mon Sep 17 00:00:00 2001 From: Xavier Chapron Date: Thu, 31 Aug 2023 14:24:29 +0200 Subject: [PATCH 5/6] lib_standard_app: Remove write on BSS variable when app is called in swap mode Writing these varable is not needed and might collide with app-exchange BSS. Therefore they should be init only if: - the app is in standalone mode - the app is in lib mode, for a SIGN_TRANSACTION command and the params from exchange have already been retrieved. (cherry picked from commit 3c8206b68d17623c410e6d3f51a760e6c97dcff2) --- lib_standard_app/main.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lib_standard_app/main.c b/lib_standard_app/main.c index cd4bf6f81..9c80220a2 100644 --- a/lib_standard_app/main.c +++ b/lib_standard_app/main.c @@ -94,9 +94,6 @@ static void standalone_app_main(void) { #ifdef HAVE_SWAP static void library_app_main(libargs_t *args) { - G_called_from_swap = true; - G_swap_response_ready = false; - BEGIN_TRY { TRY { PRINTF("Inside library\n"); @@ -107,7 +104,7 @@ static void library_app_main(libargs_t *args) { // BSS data. bool success = swap_copy_transaction_parameters(args->create_transaction); if (success) { - // BSS was wiped, so init these global again + // BSS was wiped, we can now init these globals G_called_from_swap = true; G_swap_response_ready = false; From 3b263516ac161fe06eb7c8627f376fd2b70bc006 Mon Sep 17 00:00:00 2001 From: Xavier Chapron Date: Fri, 1 Sep 2023 09:58:17 +0200 Subject: [PATCH 6/6] lib_standard_app: Add spinner screen for stax exchange SIGN_TRANSACTION command (cherry picked from commit 47532e96c959b22afaba3050ad27a183137e6040) --- lib_standard_app/main.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib_standard_app/main.c b/lib_standard_app/main.c index 9c80220a2..e2e2ea1d4 100644 --- a/lib_standard_app/main.c +++ b/lib_standard_app/main.c @@ -23,6 +23,10 @@ #ifdef HAVE_SWAP #include "swap.h" + +#ifdef HAVE_NBGL +#include "nbgl_use_case.h" +#endif // HAVE_NBGL #endif // HAVE_SWAP ux_state_t G_ux; @@ -110,6 +114,10 @@ static void library_app_main(libargs_t *args) { common_app_init(); +#ifdef HAVE_NBGL + nbgl_useCaseSpinner("Signing"); +#endif // HAVE_NBGL + app_main(); } break;