From 1ccaaf9b772d1b3d7d6f4da48d57772ec5648ba6 Mon Sep 17 00:00:00 2001 From: tdejoigny-ledger Date: Mon, 20 Nov 2023 16:19:57 +0100 Subject: [PATCH 01/14] Update workflow to be able to build some apps on Stax (cherry picked from commit a6e057fccf37f39cbe3fdc8e0b8db2257980db0a) --- .github/workflows/build_all_apps.yml | 84 ++++++++++++++++++++++++++-- 1 file changed, 79 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build_all_apps.yml b/.github/workflows/build_all_apps.yml index 2faef6792..938133e02 100644 --- a/.github/workflows/build_all_apps.yml +++ b/.github/workflows/build_all_apps.yml @@ -55,6 +55,73 @@ env: \"app-thorchain\" : \"./app\" , \"app-xxnetwork\" : \"./app\" } " + + build_for_stax_list: ' +{\"app-solana\", +\"app-hedera\", +\"app-acala\", +\"app-bitcoin-new\", +\"app-mina\", +\"app-tezos\", +\"app-plugin-nested\", +\"app-plugin-staderlabs\", +\"app-plugin-lido\", +\"app-plugin-paraswap\", +\"app-plugin-1inch\", +\"app-plugin-yearn\", +\"app-plugin-quickswap\", +\"app-plugin-cometh\", +\"app-plugin-stakedao\", +\"app-plugin-ricochet\", +\"app-plugin-poap\", +\"app-plugin-angle\", +\"app-plugin-kiln\", +\"app-plugin-alkemi\", +\"app-plugin-nft\", +\"app-plugin-harvest\", +\"app-plugin-opensea-new\", +\"app-plugin-rarible\", +\"app-plugin-cbridge\", +\"app-plugin-ribbon\", +\"app-plugin-art-blocks\", +\"app-plugin-boilerplate\", +\"app-stellar\", +\"app-exchange\", +\"app-ssh-agent\", +\"app-neo\", +\"app-boilerplate\", +\"app-xrp\", +\"app-recovery-check\", +\"app-near\", +\"app-nervos\", +\"app-cardano\", +\"app-kusama\", +\"app-polymesh\", +\"app-monero\", +\"app-celo-spender\", +\"app-cosmos\", +\"app-statemine\", +\"app-polkadot\", +\"app-zilliqa\", +\"app-nem\", +\"app-eos\", +\"app-u2f\", +\"app-fantom\", +\"app-multiversx\", +\"app-symbol\", +\"app-vechain\", +\"app-decred\", +\"app-cryptocom\", +\"app-icp\", +\"app-tron\", +\"app-bitcoin\", +\"app-flow\", +\"app-passwords\", +\"app-secret\", +\"app-binance\"} +' +# App-Ethereum to add in the previous list + repo_list: ' {\"repo_name\":[ \"app-velas\", @@ -138,7 +205,6 @@ env: \"app-filecoin\", \"app-algorand\", \"app-dock\", -\"app-plugin-opensea\", \"app-ton-new\", \"app-tron\", \"app-khala\", @@ -205,13 +271,14 @@ env: \"app-ark\", \"app-ardor\", \"app-aion\", +\"app-neo3\", ]} ' # Failing apps -#\"app-starknet\", #\"app-avalanche\", #\"app-kadena\", - +#\"app-security-key\", +#\"app-starknet\", #\"app-panacea\", #\"app-insolar\", #\"app-dgld\", @@ -226,7 +293,6 @@ env: #\"app-equilibrium\", #\"app-revealer\", #\"app-rise\", -#\"app-neo3\", #\"app-keepass\", #\"app-bitsong\", @@ -262,6 +328,14 @@ jobs: build_path=$(echo '${{ env.build_path_list}}' | sed -n 's/.*"${{ matrix.repo_name }}"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p') echo "build_path=$build_path" >> $GITHUB_ENV + - name: Build for Stax + run: | + if echo "${{ env.build_for_stax_list }}" | grep -q "${{ matrix.repo_name }}" || [[ "${{ inputs.run_stax }}" ]]; then + echo "build_for_stax=true" >> $GITHUB_ENV + else + echo "build_for_stax=false" >> $GITHUB_ENV + fi + - name: Clone SDK uses: actions/checkout@v3 with: @@ -284,7 +358,7 @@ jobs: TARGET=nanos2 BOLOS_SDK=$GITHUB_WORKSPACE/sdk make - name: Build Stax - if: ${{ inputs.run_stax == true }} + if: ${{ env.build_for_stax == 'true' }} run: | [ -n '${{ env.build_path }}' ] && cd ${{ env.build_path }} TARGET=stax BOLOS_SDK=$GITHUB_WORKSPACE/sdk make From b74a7923b8fe62daca1692227cb2a4b8dbfdddb2 Mon Sep 17 00:00:00 2001 From: tdejoigny-ledger Date: Wed, 22 Nov 2023 13:34:46 +0100 Subject: [PATCH 02/14] Add Eth app in the list of apps to build on Stax target (cherry picked from commit b00bc924014d26935eed03f133be9086f6451b89) --- .github/workflows/build_all_apps.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build_all_apps.yml b/.github/workflows/build_all_apps.yml index 938133e02..e18ccc1b4 100644 --- a/.github/workflows/build_all_apps.yml +++ b/.github/workflows/build_all_apps.yml @@ -118,9 +118,9 @@ env: \"app-flow\", \"app-passwords\", \"app-secret\", -\"app-binance\"} +\"app-binance\", +\"app-ethereum\"} ' -# App-Ethereum to add in the previous list repo_list: ' {\"repo_name\":[ From e73f53bed33d131c77baf1ada18412db05db97c0 Mon Sep 17 00:00:00 2001 From: Thomas Joly Date: Tue, 28 Nov 2023 13:36:10 +0100 Subject: [PATCH 03/14] [nbgl] PIC some addr (cherry picked from commit 3346f4d9b1f761803392e59c5bf4bd3cd3b3fd89) --- lib_nbgl/src/nbgl_serialize.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/lib_nbgl/src/nbgl_serialize.c b/lib_nbgl/src/nbgl_serialize.c index 80e97fb71..535b1d76b 100644 --- a/lib_nbgl/src/nbgl_serialize.c +++ b/lib_nbgl/src/nbgl_serialize.c @@ -3,6 +3,7 @@ #include "nbgl_obj.h" #include "nbgl_serialize.h" #include "nbgl_image_utils.h" +#include "os_pic.h" // Utility functions @@ -173,7 +174,8 @@ static void nbgl_serializeIcon(const nbgl_icon_details_t *icon, size = nbgl_bpp_get_window_size(icon->width, icon->height, icon->bpp); } else { - size = GET_IMAGE_FILE_BUFFER_LEN(icon->bitmap) + IMAGE_FILE_HEADER_SIZE; + size = GET_IMAGE_FILE_BUFFER_LEN(((uint8_t *) PIC(icon->bitmap))) + + IMAGE_FILE_HEADER_SIZE; } } nbgl_appendU32(size, out, w_cnt, max_len); @@ -199,7 +201,7 @@ static void nbgl_serializeTextArea(nbgl_text_area_t *obj, nbgl_appendU8((uint8_t) obj->autoHideLongLine, out, w_cnt, max_len); nbgl_appendU16((uint16_t) obj->len, out, w_cnt, max_len); - nbgl_serializeText(obj->text, obj->len, out, w_cnt, max_len); + nbgl_serializeText(PIC(obj->text), obj->len, out, w_cnt, max_len); } static void nbgl_serializeLine(nbgl_line_t *obj, uint8_t *out, size_t *w_cnt, size_t max_len) @@ -218,7 +220,7 @@ static void nbgl_serializeQrCode(nbgl_qrcode_t *obj, uint8_t *out, size_t *w_cnt nbgl_appendU8((uint8_t) obj->foregroundColor, out, w_cnt, max_len); nbgl_appendU8((uint8_t) obj->version, out, w_cnt, max_len); - nbgl_serializeText(obj->text, 0, out, w_cnt, max_len); + nbgl_serializeText(PIC(obj->text), 0, out, w_cnt, max_len); } static void nbgl_serializeRadio(nbgl_radio_t *obj, uint8_t *out, size_t *w_cnt, size_t max_len) @@ -271,14 +273,14 @@ static void nbgl_serializeButton(nbgl_button_t *obj, uint8_t *out, size_t *w_cnt nbgl_appendU8((uint8_t) obj->radius, out, w_cnt, max_len); nbgl_appendU8((uint8_t) obj->fontId, out, w_cnt, max_len); nbgl_appendU8((uint8_t) obj->localized, out, w_cnt, max_len); - nbgl_serializeText(obj->text, 0, out, w_cnt, max_len); - nbgl_serializeIcon(obj->icon, out, w_cnt, max_len); + nbgl_serializeText(PIC(obj->text), 0, out, w_cnt, max_len); + nbgl_serializeIcon(PIC(obj->icon), out, w_cnt, max_len); } static void nbgl_serializeImage(nbgl_image_t *obj, uint8_t *out, size_t *w_cnt, size_t max_len) { nbgl_serializeObj((nbgl_obj_t *) &obj->obj, out, w_cnt, max_len); - nbgl_serializeIcon(obj->buffer, out, w_cnt, max_len); + nbgl_serializeIcon(PIC(obj->buffer), out, w_cnt, max_len); nbgl_appendU8((uint8_t) obj->foregroundColor, out, w_cnt, max_len); } From c3164b263a5c4c307db9bf44d9c004a10594b9b4 Mon Sep 17 00:00:00 2001 From: Xavier Chapron Date: Tue, 28 Nov 2023 16:03:06 +0100 Subject: [PATCH 04/14] lib_ux/include/ux.h: Fix LNX and LNSP version of UX_WAIT_DISPLAYED() On devices where the SE drives the screen, there is no need for seph exchanges to control the screen. The previous version was assuming UX_DISPLAY_NEXT_ELEMENT() was changing the state of the MCU <-> SE exchanges, which is false, this was leading to a deadlock on Speculos. (cherry picked from commit 1b75b439278c93d4cd1428dc6ed5b9d5e3215f16) --- lib_ux/include/ux.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib_ux/include/ux.h b/lib_ux/include/ux.h index 7c86f1b40..b655eb322 100644 --- a/lib_ux/include/ux.h +++ b/lib_ux/include/ux.h @@ -580,6 +580,12 @@ extern bolos_ux_params_t G_ux_params; * Macro to process sequentially display a screen. The call finishes when the UX is completely * displayed, and the state of the MCU <-> SE exchanges is the same as before this macro call. */ +#ifdef HAVE_SE_SCREEN +#define UX_WAIT_DISPLAYED() \ + while (!UX_DISPLAYED()) { \ + UX_DISPLAY_NEXT_ELEMENT(); \ + } +#else #define UX_WAIT_DISPLAYED() \ while (!UX_DISPLAYED()) { \ /* We wait for the MCU event (should indicate display processed for a bagl element) */ \ @@ -594,6 +600,7 @@ extern bolos_ux_params_t G_ux_params; io_seproxyhal_general_status(); \ /* We wait for an ack of the MCU. */ \ io_seproxyhal_spi_recv(G_io_seproxyhal_spi_buffer, sizeof(G_io_seproxyhal_spi_buffer), 0); +#endif /** * Process button push events. Application's button event handler is called only if the ux app does From 20b32f3dd6cc861f32a416a986d18c73d4949260 Mon Sep 17 00:00:00 2001 From: Xavier Chapron Date: Wed, 29 Nov 2023 17:22:33 +0100 Subject: [PATCH 05/14] workflows/build_all_apps.yml: Remove apps repos that are archived (cherry picked from commit c5e41dbbff61645d201a342f1021a45d70b42544) --- .github/workflows/build_all_apps.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/build_all_apps.yml b/.github/workflows/build_all_apps.yml index e18ccc1b4..9326330c7 100644 --- a/.github/workflows/build_all_apps.yml +++ b/.github/workflows/build_all_apps.yml @@ -195,9 +195,7 @@ env: \"app-terra\", \"app-symbol\", \"app-arweave\", -\"app-ravencoin\", \"app-vechain\", -\"app-avalanche-legacy\", \"app-decred\", \"app-cryptocom\", \"app-icp\", From 2742dc30fedd26a4e4acc085a69f1074f10e91f0 Mon Sep 17 00:00:00 2001 From: Nicolas Roggeman Date: Fri, 1 Dec 2023 08:32:19 +0100 Subject: [PATCH 06/14] Fix nbgl_getTextMaxLenInNbLines() computing wrong len for non wrappable text (cherry picked from commit b218dce4187396d1c56dc810421df8e95e9028d1) --- lib_nbgl/src/nbgl_fonts.c | 1 + 1 file changed, 1 insertion(+) diff --git a/lib_nbgl/src/nbgl_fonts.c b/lib_nbgl/src/nbgl_fonts.c index e457405eb..ad33b5fb8 100644 --- a/lib_nbgl/src/nbgl_fonts.c +++ b/lib_nbgl/src/nbgl_fonts.c @@ -585,6 +585,7 @@ bool nbgl_getTextMaxLenInNbLines(nbgl_font_id_e fontId, textLen = lenAtLastDelimiter; } else { + textLen += text - previousText; text = previousText; } width = 0; From 013d3f12e91b697757e39b2a71e3ab40a886ff31 Mon Sep 17 00:00:00 2001 From: Xavier Chapron Date: Wed, 29 Nov 2023 17:29:18 +0100 Subject: [PATCH 07/14] Makefile.rules_generic: Stop allowing app custom SCRIPT_LD (cherry picked from commit 1a4217665fbe5ee30ce0c028b373d47cdffb0b94) --- Makefile.rules_generic | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Makefile.rules_generic b/Makefile.rules_generic index 352b1ed9c..b82baf444 100644 --- a/Makefile.rules_generic +++ b/Makefile.rules_generic @@ -88,7 +88,14 @@ $(OBJ_DIR)/%.o: %.S $(BUILD_DEPENDENCIES) prepare @echo "[AS] $@" $(L)$(call as_cmdline,$(INCLUDES_PATH), $(DEFINES),$<,$@) -ifeq ($(SCRIPT_LD),) +ifeq (,$(filter $(DEFINES),BOLOS_OS_UPGRADER_APP)) +ifneq ($(SCRIPT_LD),) +ifneq ($(ENABLE_SDK_WERROR),0) +$(error Deprecated SCRIPT_LD setting) +else +$(warning Deprecated SCRIPT_LD setting) +endif +endif LDFLAGS += -L$(BOLOS_SDK)/target/$(TARGET) ifeq ($(IS_PLUGIN),) SCRIPT_LD := $(BOLOS_SDK)/target/$(TARGET)/script.ld @@ -96,8 +103,6 @@ else SCRIPT_LD := $(BOLOS_SDK)/target/$(TARGET)/plugin_script.ld $(info Using plugin link script: $(SCRIPT_LD)) endif -else -$(info Using custom link script: $(SCRIPT_LD)) endif LDFLAGS += -T$(SCRIPT_LD) From 768edd856f7523771c746aaddf4b0c045c4fc4d4 Mon Sep 17 00:00:00 2001 From: Alexis Grojean Date: Thu, 5 Oct 2023 11:44:42 +0200 Subject: [PATCH 08/14] Update the way ELF metadata sections are added. Update metadata to keep the exact same values (cherry picked from commit 536c84d82f689503d24dd3709b164a2f0d686d2f) --- Makefile.defines | 13 ++++++-- Makefile.rules_generic | 17 ---------- Makefile.standard_app | 3 -- src/app_metadata.c | 71 +++++++++++++++++++++++++++++++++++++++++ target/nanos/script.ld | 10 ++++++ target/nanos2/script.ld | 10 ++++++ target/nanox/script.ld | 10 ++++++ target/stax/script.ld | 10 ++++++ 8 files changed, 121 insertions(+), 23 deletions(-) create mode 100644 src/app_metadata.c diff --git a/Makefile.defines b/Makefile.defines index 10f774ca2..6b9a0f2f1 100644 --- a/Makefile.defines +++ b/Makefile.defines @@ -48,10 +48,17 @@ endif ifeq ($(SDK_HASH),) SDK_HASH := "None" endif -# Expose API_LEVEL, SDK_VERSION and SDK_HASH to the app. + +# APPNAME exposed to the app as a CFLAG because it might contain spaces +CFLAGS += -DAPPNAME=\"$(APPNAME)\" + +# API_LEVEL exposed to the app as an integer DEFINES += API_LEVEL=$(API_LEVEL) -DEFINES += SDK_VERSION=\"$(SDK_VERSION)\" -DEFINES += SDK_HASH=\"$(SDK_HASH)\" + +# Define list of other items to be exposed to the app as strings +# TARGET_ID is not in this list: it is already defined in bolos_target.h. +APP_METADATA_LIST := TARGET TARGET_NAME APPVERSION SDK_NAME SDK_VERSION SDK_HASH +DEFINES += $(foreach item,$(APP_METADATA_LIST), $(item)=\"$($(item))\") # extra load parameters for loadApp script ifneq ($(SCP_PRIVKEY),) diff --git a/Makefile.rules_generic b/Makefile.rules_generic index b82baf444..f074367d8 100644 --- a/Makefile.rules_generic +++ b/Makefile.rules_generic @@ -116,15 +116,6 @@ $(BIN_DIR)/app.elf: $(LINK_DEPENDENCIES) $(L)$(call link_cmdline,$(OBJECT_FILES) $(LDLIBS),$(BIN_DIR)/app.elf) $(L)$(GCCPATH)arm-none-eabi-objcopy -O ihex -S $(BIN_DIR)/app.elf $(BIN_DIR)/app.hex $(L)$(GCCPATH)arm-none-eabi-objdump -S -d $(BIN_DIR)/app.elf > $(DBG_DIR)/app.asm - $(L)$(call objcopy_add_section_cmdline,$(TARGET), ledger.target) - $(L)$(call objcopy_add_section_cmdline,$(TARGET_NAME), ledger.target_name) - $(L)$(call objcopy_add_section_cmdline,$(TARGET_ID), ledger.target_id) - $(L)$(call objcopy_add_section_cmdline,$(APPNAME), ledger.app_name) - $(L)$(call objcopy_add_section_cmdline,$(APPVERSION), ledger.app_version) - $(L)$(call objcopy_add_section_cmdline,$(API_LEVEL), ledger.api_level) - $(L)$(call objcopy_add_section_cmdline,$(SDK_NAME), ledger.sdk_name) - $(L)$(call objcopy_add_section_cmdline,$(SDK_VERSION), ledger.sdk_version) - $(L)$(call objcopy_add_section_cmdline,$(SDK_HASH), ledger.sdk_hash) # This targets are generated along $(OBJ_DIR)/app.elf but we can't make them co-target # otherwise building with `make -j` fails due to multiple threads running simultaneously @@ -172,14 +163,6 @@ cc_cmdline = $(CC) -c $(CFLAGS) -MMD -MT $(OBJ_DIR)/$(basename $(notdir $(4))).o as_cmdline = $(AS) -c $(AFLAGS) $(addprefix -D,$(2)) $(addprefix -I,$(1)) -o $(4) $(3) -# objcopy_add_section_cmdline(data,section_name) -TMPFILE := $(shell mktemp) -objcopy_add_section_cmdline = echo $(1) > $(TMPFILE) && \ - $(GCCPATH)arm-none-eabi-objcopy --add-section $(2)="$(TMPFILE)" \ - --set-section-flags $(2)=noload,readonly \ - $(BIN_DIR)/app.elf $(BIN_DIR)/app.elf && \ - rm $(TMPFILE) - ### END GCC COMPILER RULES # Run Clang Static Analyzer diff --git a/Makefile.standard_app b/Makefile.standard_app index 4199a179a..950ea792d 100644 --- a/Makefile.standard_app +++ b/Makefile.standard_app @@ -75,9 +75,6 @@ endif # STANDARD DEFINES # ##################################################################### DEFINES += $(DEFINES_LIB) -# 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 diff --git a/src/app_metadata.c b/src/app_metadata.c new file mode 100644 index 000000000..b46a4dd99 --- /dev/null +++ b/src/app_metadata.c @@ -0,0 +1,71 @@ +/******************************************************************************* + * Ledger - Secure firmware + * (c) 2023 Ledger + * + * 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. + ********************************************************************************/ + +#if !defined(HAVE_BOLOS) + +#include + +#include "bolos_target.h" + +#define STR_IMPL_(x) #x +#define STRINGIFY(x) STR_IMPL_(x) + +#define CREATE_METADATA_STRING_ITEM(ITEM_NAME, section_name) \ + __attribute__((section("ledger." #section_name))) \ + const char section_name[sizeof(ITEM_NAME) - 1] \ + = ITEM_NAME; + +#define CREATE_METADATA_STRING_ITEM_FROM_INT(ITEM_NAME, section_name) \ + CREATE_METADATA_STRING_ITEM(STRINGIFY(ITEM_NAME), section_name) + +#if defined(TARGET) +CREATE_METADATA_STRING_ITEM(TARGET, target) +#endif + +#if defined(TARGET_NAME) +CREATE_METADATA_STRING_ITEM(TARGET_NAME, target_name) +#endif + +#if defined(TARGET_ID) +CREATE_METADATA_STRING_ITEM_FROM_INT(TARGET_ID, target_id) +#endif + +#if defined(APPNAME) +CREATE_METADATA_STRING_ITEM(APPNAME, app_name) +#endif + +#if defined(APPVERSION) +CREATE_METADATA_STRING_ITEM(APPVERSION, app_version) +#endif + +#if defined(API_LEVEL) +CREATE_METADATA_STRING_ITEM_FROM_INT(API_LEVEL, api_level) +#endif + +#if defined(SDK_NAME) +CREATE_METADATA_STRING_ITEM(SDK_NAME, sdk_name) +#endif + +#if defined(SDK_VERSION) +CREATE_METADATA_STRING_ITEM(SDK_VERSION, sdk_version) +#endif + +#if defined(SDK_HASH) +CREATE_METADATA_STRING_ITEM(SDK_HASH, sdk_hash) +#endif + +#endif diff --git a/target/nanos/script.ld b/target/nanos/script.ld index f9446822d..aeb948b34 100644 --- a/target/nanos/script.ld +++ b/target/nanos/script.ld @@ -191,6 +191,16 @@ SECTIONS .debug_funcnames 0 : { *(.debug_funcnames) } .debug_typenames 0 : { *(.debug_typenames) } .debug_varnames 0 : { *(.debug_varnames) } + + ledger.target (INFO): { KEEP(*(ledger.target)) } + ledger.target_name (INFO): { KEEP(*(ledger.target_name)) } + ledger.target_id (INFO): { KEEP(*(ledger.target_id)) } + ledger.app_name (INFO): { KEEP(*(ledger.app_name)) } + ledger.app_version (INFO): { KEEP(*(ledger.app_version)) } + ledger.api_level (INFO): { KEEP(*(ledger.api_level)) } + ledger.sdk_name (INFO): { KEEP(*(ledger.sdk_name)) } + ledger.sdk_version (INFO): { KEEP(*(ledger.sdk_version)) } + ledger.sdk_hash (INFO): { KEEP(*(ledger.sdk_hash)) } } PROVIDE(_nvram = ABSOLUTE(_nvram_start)); diff --git a/target/nanos2/script.ld b/target/nanos2/script.ld index 8f9b2f308..e89c97749 100644 --- a/target/nanos2/script.ld +++ b/target/nanos2/script.ld @@ -168,6 +168,16 @@ SECTIONS .debug_funcnames 0 : { *(.debug_funcnames) } .debug_typenames 0 : { *(.debug_typenames) } .debug_varnames 0 : { *(.debug_varnames) } + + ledger.target (INFO): { KEEP(*(ledger.target)) } + ledger.target_name (INFO): { KEEP(*(ledger.target_name)) } + ledger.target_id (INFO): { KEEP(*(ledger.target_id)) } + ledger.app_name (INFO): { KEEP(*(ledger.app_name)) } + ledger.app_version (INFO): { KEEP(*(ledger.app_version)) } + ledger.api_level (INFO): { KEEP(*(ledger.api_level)) } + ledger.sdk_name (INFO): { KEEP(*(ledger.sdk_name)) } + ledger.sdk_version (INFO): { KEEP(*(ledger.sdk_version)) } + ledger.sdk_hash (INFO): { KEEP(*(ledger.sdk_hash)) } } PROVIDE(_nvram = ABSOLUTE(_nvram_start)); diff --git a/target/nanox/script.ld b/target/nanox/script.ld index 8c42cc4c2..fb850ad0e 100644 --- a/target/nanox/script.ld +++ b/target/nanox/script.ld @@ -179,6 +179,16 @@ SECTIONS .debug_funcnames 0 : { *(.debug_funcnames) } .debug_typenames 0 : { *(.debug_typenames) } .debug_varnames 0 : { *(.debug_varnames) } + + ledger.target (INFO): { KEEP(*(ledger.target)) } + ledger.target_name (INFO): { KEEP(*(ledger.target_name)) } + ledger.target_id (INFO): { KEEP(*(ledger.target_id)) } + ledger.app_name (INFO): { KEEP(*(ledger.app_name)) } + ledger.app_version (INFO): { KEEP(*(ledger.app_version)) } + ledger.api_level (INFO): { KEEP(*(ledger.api_level)) } + ledger.sdk_name (INFO): { KEEP(*(ledger.sdk_name)) } + ledger.sdk_version (INFO): { KEEP(*(ledger.sdk_version)) } + ledger.sdk_hash (INFO): { KEEP(*(ledger.sdk_hash)) } } PROVIDE(_nvram = ABSOLUTE(_nvram_start)); diff --git a/target/stax/script.ld b/target/stax/script.ld index 806a7861a..f23457928 100644 --- a/target/stax/script.ld +++ b/target/stax/script.ld @@ -169,6 +169,16 @@ SECTIONS .debug_funcnames 0 : { *(.debug_funcnames) } .debug_typenames 0 : { *(.debug_typenames) } .debug_varnames 0 : { *(.debug_varnames) } + + ledger.target (INFO): { KEEP(*(ledger.target)) } + ledger.target_name (INFO): { KEEP(*(ledger.target_name)) } + ledger.target_id (INFO): { KEEP(*(ledger.target_id)) } + ledger.app_name (INFO): { KEEP(*(ledger.app_name)) } + ledger.app_version (INFO): { KEEP(*(ledger.app_version)) } + ledger.api_level (INFO): { KEEP(*(ledger.api_level)) } + ledger.sdk_name (INFO): { KEEP(*(ledger.sdk_name)) } + ledger.sdk_version (INFO): { KEEP(*(ledger.sdk_version)) } + ledger.sdk_hash (INFO): { KEEP(*(ledger.sdk_hash)) } } PROVIDE(_nvram = ABSOLUTE(_nvram_start)); From fdcb9fefad49dad5f0e83fc6011955a3c6f22f9f Mon Sep 17 00:00:00 2001 From: Xavier Chapron Date: Wed, 22 Nov 2023 18:48:52 +0100 Subject: [PATCH 09/14] Makefile: Improve app _install_parameters generation This includes: - Generation before build time and inclusion in the binary at build time whereas it was previously done only during sideloading. This allows: * to have a proper app size when using arm-none-eabi-size bin/app.elf, taking into account the size of the install_parameters * to have complete artifacts app.elf, app.hex, app.map, app.asm which can be used for debug * to have a proper Speculos emulation on install_parameters interactions. - Parsing of APP_LOAD_PARAMS variable so that its differents fields can be used cleanly - New symbols in the linker script to expose the start and the end of install_parameters, allowing to retrieve its size. - A small change in src/pic.c to avoid application sha256 change in this commit. The change will be removed in the next commit. This commit as been tested without modification on the application sha256 (which includes install_parameters generated at build time or as previously by ledgerblue.loadapp script) on numerous applications. (cherry picked from commit 34448c2bd8627bba8d53cbb5ed39420f7e1e4bf6) --- Makefile.app_params | 126 ++++++++++++++++++++++++++ Makefile.defines | 20 ----- Makefile.rules_generic | 4 + Makefile.standard_app | 14 +-- extract_param.py | 20 +++++ install_params.py | 192 ++++++++++++++++++++++++++++++++++++++++ src/app_metadata.c | 5 ++ src/pic.c | 6 +- target/nanos/script.ld | 3 + target/nanos2/script.ld | 3 + target/nanox/script.ld | 3 + target/stax/script.ld | 3 + 12 files changed, 365 insertions(+), 34 deletions(-) create mode 100644 Makefile.app_params create mode 100644 extract_param.py create mode 100644 install_params.py diff --git a/Makefile.app_params b/Makefile.app_params new file mode 100644 index 000000000..be6b3b4a6 --- /dev/null +++ b/Makefile.app_params @@ -0,0 +1,126 @@ +#******************************************************************************* +# Ledger SDK +# (c) 2023 Ledger +# +# 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. +#******************************************************************************* + +# Command to print ICONNAME hexadecimal bitmap on stdout according to the +# hardware target. +ifneq ($(TARGET),nanos) +#inverse B&W for non Stax +ifneq ($(TARGET_NAME),TARGET_STAX) +ICONHEX_CMD=python3 $(BOLOS_SDK)/lib_nbgl/tools/icon2glyph.py --reverse --hexbitmaponly $(ICONNAME) +else +ICONHEX_CMD=python3 $(BOLOS_SDK)/lib_nbgl/tools/icon2glyph.py --hexbitmaponly $(ICONNAME) +endif +else +ICONHEX_CMD=python3 $(BOLOS_SDK)/icon3.py --hexbitmaponly $(ICONNAME) +endif + + +######################################### +# Parse APP_LOAD_PARAMS # +######################################### +# This is necessary when makefile.standard_app is not completely used. +# Correctly implemented apps should not set anything in APP_LOAD_PARAMS anymore +# Potential presents info are: +# --appFlags +# --curve +# --path +# --path_slip21 +# --tlvraw +# --dep +# --nocrc +# Other info are considered an error and will be silently discarded. + +ifneq ($(APP_LOAD_PARAMS),) + EXTRACTED_APP_FLAGS := $(shell python3 $(BOLOS_SDK)/extract_param.py --appFlags $(APP_LOAD_PARAMS)) + APP_FLAGS_APP_LOAD_PARAMS += $(EXTRACTED_APP_FLAGS) + + EXTRACTED_CURVE := $(shell python3 $(BOLOS_SDK)/extract_param.py --curve $(APP_LOAD_PARAMS)) + CURVE_APP_LOAD_PARAMS += $(EXTRACTED_CURVE) + + EXTRACTED_PATH := $(shell python3 $(BOLOS_SDK)/extract_param.py --path $(APP_LOAD_PARAMS)) + PATH_APP_LOAD_PARAMS += $(EXTRACTED_PATH) + + EXTRACTED_PATH_SLIP21 := $(shell python3 $(BOLOS_SDK)/extract_param.py --path_slip21 $(APP_LOAD_PARAMS)) + PATH_SLIP21_APP_LOAD_PARAMS += $(EXTRACTED_PATH_SLIP21) + + EXTRACTED_TLVRAW := $(shell python3 $(BOLOS_SDK)/extract_param.py --tlvraw $(APP_LOAD_PARAMS)) + TLVRAW_APP_LOAD_PARAMS += $(EXTRACTED_TLVRAW) + + EXTRACTED_DEP := $(shell python3 $(BOLOS_SDK)/extract_param.py --dep $(APP_LOAD_PARAMS)) + DEP_APP_LOAD_PARAMS += $(EXTRACTED_DEP) + + ifneq ($(findstring --nocrc,$(APP_LOAD_PARAMS)),) + ENABLE_NOCRC_APP_LOAD_PARAMS = 1 + endif +endif + + +######################################### +# Generate install_params # +######################################### +# Compute params to call install_params.py +# Consider only one path_slip21 can be added, whereas LedgerBlue seems to +# support multiple, but has the path can hold a " " in it, it mess with the +# foreach, so we choose to restrict to only one path_slip21. +APP_INSTALL_PARAMS = --appName $(APPNAME) +APP_INSTALL_PARAMS += --appVersion $(APPVERSION) +APP_INSTALL_PARAMS += `ICONHEX=\`$(ICONHEX_CMD) 2>/dev/null\` ; [ ! -z "$$ICONHEX" ] && echo "--icon $$ICONHEX"` +APP_INSTALL_PARAMS += $(foreach curve, $(CURVE_APP_LOAD_PARAMS), --curve $(curve)) +APP_INSTALL_PARAMS += $(foreach path, $(PATH_APP_LOAD_PARAMS), --path $(path)) +ifneq ($(PATH_SLIP21_APP_LOAD_PARAMS),) + APP_INSTALL_PARAMS += --path_slip21 $(PATH_SLIP21_APP_LOAD_PARAMS) +endif +APP_INSTALL_PARAMS += $(foreach tlvraw, $(TLVRAW_APP_LOAD_PARAMS), --tlvraw $(tlvraw)) +APP_INSTALL_PARAMS += $(foreach dep, $(DEP_APP_LOAD_PARAMS), --dep $(dep)) + +# Compute install_params tlv binary blob then expose it via a define to +# src/app_metadata.c so that it is inserted in the binary at link time +APP_INSTALL_PARAMS_DATA := $(shell python3 $(BOLOS_SDK)/install_params.py $(APP_INSTALL_PARAMS)) +DEFINES += APP_INSTALL_PARAMS_DATA=$(APP_INSTALL_PARAMS_DATA) + +######################################### +# Generate APP_LOAD_PARAMS # +######################################### +# Rewrite APP_LOAD_PARAMS with params needed for generating the sideloading +# APDUs. +# This variable is then used in some Makefiles target as Ledgerblue.loadapp +# script parameters. +APP_LOAD_PARAMS = --targetId $(TARGET_ID) +APP_LOAD_PARAMS += --targetVersion="$(TARGET_VERSION)" +APP_LOAD_PARAMS += --apiLevel $(API_LEVEL) +APP_LOAD_PARAMS += --fileName bin/app.hex +APP_LOAD_PARAMS += --appName $(APPNAME) +ifneq ($(APP_FLAGS_APP_LOAD_PARAMS),) + APP_LOAD_PARAMS += --appFlags $(APP_FLAGS_APP_LOAD_PARAMS) +endif +APP_LOAD_PARAMS += --delete +APP_LOAD_PARAMS += --tlv +APP_LOAD_PARAMS += --dataSize $$((0x`cat debug/app.map | grep _envram_data | tr -s ' ' | cut -f2 -d' ' |cut -f2 -d'x' ` - 0x`cat debug/app.map | grep _nvram_data | tr -s ' ' | cut -f2 -d' ' | cut -f2 -d'x'`)) +APP_LOAD_PARAMS += --installparamsSize $$((0x`cat debug/app.map | grep _einstall_parameters | tr -s ' ' | cut -f2 -d' ' |cut -f2 -d'x'` - 0x`cat debug/app.map | grep _install_parameters | tr -s ' ' | cut -f2 -d' ' |cut -f2 -d'x'`)) + +ifeq ($(ENABLE_NOCRC_APP_LOAD_PARAMS), 1) + APP_LOAD_PARAMS += --nocrc +endif + +COMMON_DELETE_PARAMS = --targetId $(TARGET_ID) --appName $(APPNAME) + +# Extra load parameters for loadApp script +ifneq ($(SCP_PRIVKEY),) + PARAM_SCP += --rootPrivateKey $(SCP_PRIVKEY) + APP_LOAD_PARAMS += $(PARAM_SCP) + COMMON_DELETE_PARAMS += $(PARAM_SCP) +endif diff --git a/Makefile.defines b/Makefile.defines index 6b9a0f2f1..1d5754600 100644 --- a/Makefile.defines +++ b/Makefile.defines @@ -60,26 +60,6 @@ DEFINES += API_LEVEL=$(API_LEVEL) APP_METADATA_LIST := TARGET TARGET_NAME APPVERSION SDK_NAME SDK_VERSION SDK_HASH DEFINES += $(foreach item,$(APP_METADATA_LIST), $(item)=\"$($(item))\") -# extra load parameters for loadApp script -ifneq ($(SCP_PRIVKEY),) -PARAM_SCP+=--rootPrivateKey $(SCP_PRIVKEY) -endif - -# Command to print ICONNAME hexadecimal bitmap on stdout -# according to the hardware target. -ifneq ($(TARGET),nanos) -#inverse B&W for non Stax -ifneq ($(TARGET_NAME),TARGET_STAX) -ICONHEX_CMD=python3 $(BOLOS_SDK)/lib_nbgl/tools/icon2glyph.py --reverse --hexbitmaponly $(ICONNAME) -else -ICONHEX_CMD=python3 $(BOLOS_SDK)/lib_nbgl/tools/icon2glyph.py --hexbitmaponly $(ICONNAME) -endif -else -ICONHEX_CMD=python3 $(BOLOS_SDK)/icon3.py --hexbitmaponly $(ICONNAME) -endif - -COMMON_LOAD_PARAMS=--tlv --targetId $(TARGET_ID) --targetVersion="$(TARGET_VERSION)" --apiLevel $(API_LEVEL) --delete --fileName bin/app.hex --appName $(APPNAME) --appVersion $(APPVERSION) --dataSize $$((0x`cat debug/app.map |grep _envram_data | tr -s ' ' | cut -f2 -d' '|cut -f2 -d'x'` - 0x`cat debug/app.map |grep _nvram_data | tr -s ' ' | cut -f2 -d' '|cut -f2 -d'x'`)) `ICONHEX=\`$(ICONHEX_CMD) 2>/dev/null\` ; [ ! -z "$$ICONHEX" ] && echo "--icon $$ICONHEX"` $(PARAM_SCP) -COMMON_DELETE_PARAMS=--targetId $(TARGET_ID) --appName $(APPNAME) $(PARAM_SCP) BUILD_DIR := build TARGET_BUILD_DIR := $(BUILD_DIR)/$(TARGET) diff --git a/Makefile.rules_generic b/Makefile.rules_generic index f074367d8..584fe343e 100644 --- a/Makefile.rules_generic +++ b/Makefile.rules_generic @@ -15,6 +15,10 @@ # limitations under the License. #******************************************************************************* +# Include Makefile.app_params here so that it is: +# - included on all apps Makefile, without changing them +# - included after apps Makefile changes on APP_LOAD_PARAMS +include $(BOLOS_SDK)/Makefile.app_params # consider every intermediate target as final to avoid deleting intermediate files .SECONDARY: diff --git a/Makefile.standard_app b/Makefile.standard_app index 950ea792d..461f3f08f 100644 --- a/Makefile.standard_app +++ b/Makefile.standard_app @@ -165,22 +165,14 @@ ifeq ($(HAVE_APPLICATION_FLAG_LIBRARY), 1) STANDARD_APP_FLAGS := $(shell echo $$(($(STANDARD_APP_FLAGS) + 0x800))) endif -APP_FLAGS = $(shell printf '0x%x' $$(( $(STANDARD_APP_FLAGS) + $(CUSTOM_APP_FLAGS) )) ) - -APP_LOAD_PARAMS += --appFlags $(APP_FLAGS) - -APP_LOAD_PARAMS += $(foreach curve, $(CURVE_APP_LOAD_PARAMS), --curve $(curve)) - -APP_LOAD_PARAMS += $(foreach path, $(PATH_APP_LOAD_PARAMS), --path $(path)) - -APP_LOAD_PARAMS += $(COMMON_LOAD_PARAMS) - # Pending review flag ifeq ($(ENABLE_PENDING_REVIEW_SCREEN), 1) - APP_LOAD_PARAMS += --tlvraw 9F:01 + TLVRAW_APP_LOAD_PARAMS += 9F:01 DEFINES += HAVE_PENDING_REVIEW_SCREEN endif +APP_FLAGS_APP_LOAD_PARAMS = $(shell printf '0x%x' $$(( $(STANDARD_APP_FLAGS) + $(CUSTOM_APP_FLAGS) )) ) + ##################################################################### # COMPILER SETTINGS # ##################################################################### diff --git a/extract_param.py b/extract_param.py new file mode 100644 index 000000000..0dc614a5f --- /dev/null +++ b/extract_param.py @@ -0,0 +1,20 @@ +""" +Helper to extract APP_LOAD_PARAMS parameters values. +It takes as a first parameter the parameter name to be search and output the +corresponding values from the rest of the script parameters. +""" + +from sys import argv + +if __name__ == '__main__': + + assert len(argv) > 2 + searching = argv[1] + + res = [] + args = argv[2:] + + for i, arg in enumerate(args): + if arg == searching and len(args) > i: + res.append(repr(args[i + 1])) + print(" ".join(res)) diff --git a/install_params.py b/install_params.py new file mode 100644 index 000000000..3110d9238 --- /dev/null +++ b/install_params.py @@ -0,0 +1,192 @@ +""" +/******************************************************************************* + * Ledger - Secure firmware + * (c) 2023 Ledger + * + * 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. + ********************************************************************************/ +""" + +import struct +import argparse +import binascii + + +BOLOS_TAG_APPNAME = 1 +BOLOS_TAG_APPVERSION = 2 +BOLOS_TAG_ICON = 3 +BOLOS_TAG_DERIVEPATH = 4 +BOLOS_TAG_DEPENDENCY = 6 + + +CURVE_SECP256K1 = 1 << 0 +CURVE_PRIME256R1 = 1 << 1 +CURVE_ED25519 = 1 << 2 +CURVE_SLIP21 = 1 << 3 +CURVE_BLS12381G1 = 1 << 4 + + +def auto_int(x): + return int(x, 0) + + +def string_to_bytes(x): + return bytes(x, 'ascii') + + +def encodelv(value): + length = len(value) + res = b"" + if length < 128: + res += struct.pack(">B", length) + elif length < 256: + res += struct.pack(">B", 0x81) + res += struct.pack(">B", length) + elif length < 65536: + res += struct.pack(">B", 0x82) + res += struct.pack(">H", length) + else: + raise Exception("Unimplemented LV encoding") + res += value + return res + + +def encodetlv(tag, value): + res = struct.pack(">B", tag) + res += encodelv(value) + return res + + +def get_curve_mask(curves, slip21_paths): + if curves: + curve_mask = 0x00 + for curve in curves: + if curve == 'secp256k1': + curve_mask |= CURVE_SECP256K1 + elif curve == 'secp256r1': + curve_mask |= CURVE_PRIME256R1 + elif curve == 'ed25519': + curve_mask |= CURVE_ED25519 + elif curve == 'bls12381g1': + curve_mask |= CURVE_BLS12381G1 + else: + raise Exception("Unknown curve " + curve) + + if slip21_paths: + curve_mask |= CURVE_SLIP21 + else: + curve_mask = 0xff + + return curve_mask + + +def parse_bip32_path(path): + elements = path.split('/') + result = struct.pack('>B', len(elements)) + for element in elements: + if element.endswith("\'"): + value = 0x80000000 | int(element[:-1]) + else: + value = int(element) + result += struct.pack(">I", value) + return result + + +def parse_slip21_path(path): + result = struct.pack('>B', 0x80 | (len(path) + 1)) + result = result + b'\x00' + string_to_bytes(path) + return result + + +def get_serialized_path(curves, bip32_paths, slip21_paths): + curve_mask = get_curve_mask(args.curve, args.path_slip21) + serialized_path = struct.pack('>B', curve_mask) + + serialized_bip32_paths = b"" + if bip32_paths: + for path in bip32_paths: + if path: + serialized_bip32_paths += parse_bip32_path(path) + serialized_path += serialized_bip32_paths + + serialized_slip21_path = b"" + if slip21_paths: + for path in slip21_paths: + if path: + serialized_slip21_path += parse_slip21_path(path) + if not serialized_bip32_paths: + # Unrestricted, authorize all paths for regular derivation + serialized_slip21_path += struct.pack('>B', 0) + serialized_path += serialized_slip21_path + + return serialized_path + + +def get_argparser(): + parser = argparse.ArgumentParser(description="Generate application install_params TLV bytes.") + parser.add_argument("--appName", help="The name to give the application after loading it", required=True) + parser.add_argument("--appVersion", help="The application version (as a string)") + parser.add_argument("--icon", help="The icon content to use (hex encoded)") + parser.add_argument("--curve", help="""A curve on which BIP 32 derivation is locked ("secp256k1", "secp256r1", +"ed25519" or "bls12381g1"), can be repeated""", action='append') + parser.add_argument("--path", help="""A BIP 32 path to which derivation is locked (format decimal a'/b'/c), can be +repeated""", action='append') + parser.add_argument("--path_slip21", help="""A SLIP 21 path to which derivation is locked""", action='append') + parser.add_argument("--tlvraw", help="Add a custom install param with the hextag:hexvalue encoding", action='append') + parser.add_argument("--dep", help="Add a dependency over an appname[:appversion]", action='append') + + return parser + + +if __name__ == '__main__': + + args = get_argparser().parse_args() + + # Build install parameters + install_params = b"" + + # express dependency + if args.dep: + for dep in args.dep: + app_name, app_version = dep, None + + # split if version is specified + if ":" in dep: + app_name, app_version = dep.split(":") + + dep_value = encodelv(string_to_bytes(app_name)) + if app_version: + dep_value += encodelv(string_to_bytes(app_version)) + install_params += encodetlv(BOLOS_TAG_DEPENDENCY, dep_value) + + # Add raw install parameters as requested + if args.tlvraw: + for tlvraw in args.tlvraw: + hextag, hexvalue = tlvraw.split(":") + install_params += encodetlv(int(hextag, 16), binascii.unhexlify(hexvalue)) + + # App name is mandatory + install_params += encodetlv(BOLOS_TAG_APPNAME, string_to_bytes(args.appName)) + + if args.appVersion: + install_params += encodetlv(BOLOS_TAG_APPVERSION, string_to_bytes(args.appVersion)) + + if args.icon: + install_params += encodetlv(BOLOS_TAG_ICON, bytes.fromhex(args.icon)) + + serialized_path = get_serialized_path(args.curve, args.path, args.path_slip21) + if len(serialized_path) > 0: + install_params += encodetlv(BOLOS_TAG_DERIVEPATH, serialized_path) + + output = ",".join(f"0x{i:02x}" for i in install_params) + print(output) diff --git a/src/app_metadata.c b/src/app_metadata.c index b46a4dd99..ab2abf277 100644 --- a/src/app_metadata.c +++ b/src/app_metadata.c @@ -68,4 +68,9 @@ CREATE_METADATA_STRING_ITEM(SDK_VERSION, sdk_version) CREATE_METADATA_STRING_ITEM(SDK_HASH, sdk_hash) #endif +#ifdef APP_INSTALL_PARAMS_DATA +__attribute__((section(".install_parameters"))) const uint8_t install_parameters[] + = {APP_INSTALL_PARAMS_DATA}; +#endif + #endif diff --git a/src/pic.c b/src/pic.c index aee063083..8bfb56cd2 100644 --- a/src/pic.c +++ b/src/pic.c @@ -20,14 +20,14 @@ __attribute__((naked, no_instrument_function)) void *pic_internal(void *link_add // only apply PIC conversion if link_address is in linked code (over 0xC0D00000 in our example) // this way, PIC call are armless if the address is not meant to be converted extern void _nvram; -extern void _envram; +extern void _install_parameters; #if defined(ST31) void *pic(void *link_address) { // check if in the LINKED TEXT zone - if (link_address >= &_nvram && link_address < &_envram) { + if (link_address >= &_nvram && link_address < &_install_parameters) { link_address = pic_internal(link_address); } @@ -45,7 +45,7 @@ void *pic(void *link_address) // check if in the LINKED TEXT zone __asm volatile("ldr %0, =_nvram" : "=r"(n)); - __asm volatile("ldr %0, =_envram" : "=r"(en)); + __asm volatile("ldr %0, =_install_parameters" : "=r"(en)); if (link_address >= n && link_address <= en) { link_address = pic_internal(link_address); } diff --git a/target/nanos/script.ld b/target/nanos/script.ld index aeb948b34..447f13ff6 100644 --- a/target/nanos/script.ld +++ b/target/nanos/script.ld @@ -81,6 +81,9 @@ SECTIONS _envram_data = .; _install_parameters = .; + *(.install_parameters) + KEEP(*(.install_parameters)) + _einstall_parameters = .; _nvram_end = .; } > FLASH = 0x00 diff --git a/target/nanos2/script.ld b/target/nanos2/script.ld index e89c97749..62d995fa7 100644 --- a/target/nanos2/script.ld +++ b/target/nanos2/script.ld @@ -75,6 +75,9 @@ SECTIONS _envram_data = .; _install_parameters = .; + *(.install_parameters) + KEEP(*(.install_parameters)) + _einstall_parameters = .; _nvram_end = .; } > FLASH = 0x00 diff --git a/target/nanox/script.ld b/target/nanox/script.ld index fb850ad0e..aaca967eb 100644 --- a/target/nanox/script.ld +++ b/target/nanox/script.ld @@ -77,6 +77,9 @@ SECTIONS _envram_data = .; _install_parameters = .; + *(.install_parameters) + KEEP(*(.install_parameters)) + _einstall_parameters = .; _nvram_end = .; } > FLASH diff --git a/target/stax/script.ld b/target/stax/script.ld index f23457928..ae52569cf 100644 --- a/target/stax/script.ld +++ b/target/stax/script.ld @@ -76,6 +76,9 @@ SECTIONS _envram_data = .; _install_parameters = .; + *(.install_parameters) + KEEP(*(.install_parameters)) + _einstall_parameters = .; _nvram_end = .; } > FLASH = 0x00 From b93ca1c8e5c2004da7b7a69ad84fba631d0dc68a Mon Sep 17 00:00:00 2001 From: Xavier Chapron Date: Fri, 24 Nov 2023 18:26:36 +0100 Subject: [PATCH 10/14] src/pic.c: Restore PIC functionnality on all linked text zone Following previous commit, this now included the install_parameters that are added during the build process. (cherry picked from commit 2a823e5e7c0fa4223384fc5aea36a72149aaa743) --- src/pic.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pic.c b/src/pic.c index 8bfb56cd2..aee063083 100644 --- a/src/pic.c +++ b/src/pic.c @@ -20,14 +20,14 @@ __attribute__((naked, no_instrument_function)) void *pic_internal(void *link_add // only apply PIC conversion if link_address is in linked code (over 0xC0D00000 in our example) // this way, PIC call are armless if the address is not meant to be converted extern void _nvram; -extern void _install_parameters; +extern void _envram; #if defined(ST31) void *pic(void *link_address) { // check if in the LINKED TEXT zone - if (link_address >= &_nvram && link_address < &_install_parameters) { + if (link_address >= &_nvram && link_address < &_envram) { link_address = pic_internal(link_address); } @@ -45,7 +45,7 @@ void *pic(void *link_address) // check if in the LINKED TEXT zone __asm volatile("ldr %0, =_nvram" : "=r"(n)); - __asm volatile("ldr %0, =_install_parameters" : "=r"(en)); + __asm volatile("ldr %0, =_envram" : "=r"(en)); if (link_address >= n && link_address <= en) { link_address = pic_internal(link_address); } From ad53b2b84ea430f1783ddcd53a90a02b322ee21e Mon Sep 17 00:00:00 2001 From: Xavier Chapron Date: Mon, 27 Nov 2023 16:16:59 +0100 Subject: [PATCH 11/14] src/checks.c: Use correct install_parameters length (cherry picked from commit db83c5cbe26895cbecc028bee705c7cc1d6bff4b) --- include/checks.h | 1 - src/checks.c | 7 +++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/include/checks.h b/include/checks.h index f0e9851af..157e44003 100644 --- a/include/checks.h +++ b/include/checks.h @@ -23,7 +23,6 @@ #define CHECK_NOT_AUDITED_TLV_TAG 0x9F #define CHECK_NOT_AUDITED_TLV_VAL 0x01 -#define CHECK_NOT_AUDITED_MAX_LEN 0x40 void check_audited_app(void); #endif // !defined(HAVE_BOLOS) && defined(HAVE_PENDING_REVIEW_SCREEN) diff --git a/src/checks.c b/src/checks.c index ae253f2fb..1ae993961 100644 --- a/src/checks.c +++ b/src/checks.c @@ -28,6 +28,7 @@ // This label ultimately comes from the application link. extern unsigned int const _install_parameters; +extern unsigned int const _einstall_parameters; #ifdef HAVE_BAGL @@ -173,8 +174,10 @@ void check_audited_app(void) { unsigned char data = BOLOS_FALSE; unsigned char *buffer = &data; - unsigned int length = os_parse_bertlv((unsigned char *) (&_install_parameters), - CHECK_NOT_AUDITED_MAX_LEN, + unsigned int install_parameters_len + = (unsigned char *) &_einstall_parameters - (unsigned char *) &_install_parameters; + unsigned int length = os_parse_bertlv((unsigned char *) &_install_parameters, + install_parameters_len, NULL, CHECK_NOT_AUDITED_TLV_TAG, 0x00, From 6a0940f4d8c0fa33aaba0507e88ac0b1eae86f9c Mon Sep 17 00:00:00 2001 From: Sarah GLINER Date: Fri, 24 Nov 2023 18:49:11 +0100 Subject: [PATCH 12/14] ledger_assert: add LEDGER_ASSERT macro with debug capacities (cherry picked from commit 9ae87d95c42b880f14badd9352ea4ad9680cec9c) --- Makefile.standard_app | 7 ++ include/ledger_assert.h | 156 +++++++++++++++++++++++++++++++++++++++ include/os.h | 4 + lib_standard_app/debug.c | 71 ------------------ lib_standard_app/debug.h | 3 - lib_standard_app/main.c | 10 +-- src/ledger_assert.c | 145 ++++++++++++++++++++++++++++++++++++ src/os.c | 28 ++++--- 8 files changed, 330 insertions(+), 94 deletions(-) create mode 100644 include/ledger_assert.h delete mode 100644 lib_standard_app/debug.c delete mode 100644 lib_standard_app/debug.h create mode 100644 src/ledger_assert.c diff --git a/Makefile.standard_app b/Makefile.standard_app index 461f3f08f..29cd89b8d 100644 --- a/Makefile.standard_app +++ b/Makefile.standard_app @@ -56,6 +56,13 @@ ifneq ($(DEBUG), 0) else DEFINES += PRINTF=mcu_usb_printf endif + ifneq ($(DISABLE_DEBUG_LEDGER_ASSERT), 1) + DEFINES += HAVE_LEDGER_ASSERT_DISPLAY + DEFINES += LEDGER_ASSERT_CONFIG_FILE_INFO + endif + ifneq ($(DISABLE_DEBUG_THROW), 1) + DEFINES += HAVE_DEBUG_THROWS + endif else DEFINES += PRINTF\(...\)= endif diff --git a/include/ledger_assert.h b/include/ledger_assert.h new file mode 100644 index 000000000..15387e5c4 --- /dev/null +++ b/include/ledger_assert.h @@ -0,0 +1,156 @@ +#pragma once + +#include + +#ifdef LEDGER_ASSERT_CONFIG_FILE_INFO +#define LEDGER_ASSERT_CONFIG_MESSAGE_INFO 1 +#define LEDGER_ASSERT_CONFIG_LR_AND_PC_INFO 1 +#endif + +#ifdef LEDGER_ASSERT_CONFIG_MESSAGE_INFO +#define LEDGER_ASSERT_CONFIG_LR_AND_PC_INFO 1 +#endif + +#if defined(LEDGER_ASSERT_CONFIG_LR_AND_PC_INFO) && defined(HAVE_LEDGER_ASSERT_DISPLAY) +#define LR_AND_PC_SIZE 30 +void assert_display_lr_and_pc(int lr, int pc); +#define ASSERT_DISPLAY_LR_AND_PC(lr, pc) assert_display_lr_and_pc(lr, pc) +#else +#define LR_AND_PC_SIZE 0 +#define ASSERT_DISPLAY_LR_AND_PC(lr, pc) \ + do { \ + } while (0) +#endif + +#if defined(LEDGER_ASSERT_CONFIG_MESSAGE_INFO) && defined(HAVE_LEDGER_ASSERT_DISPLAY) +#define MESSAGE_SIZE 20 +void assert_display_message(const char *message); +#define ASSERT_DISPLAY_MESSAGE(message) assert_display_message(message) +#else +#define MESSAGE_SIZE 0 +#define ASSERT_DISPLAY_MESSAGE(message) \ + do { \ + } while (0) +#endif + +#if defined(LEDGER_ASSERT_CONFIG_FILE_INFO) && defined(HAVE_LEDGER_ASSERT_DISPLAY) +#define FILE_SIZE 50 +void assert_display_file_info(const char *file, unsigned int line); +#define ASSERT_DISPLAY_FILE_INFO(file, line) assert_display_file_info(file, line) +#else +#define FILE_SIZE 0 +#define ASSERT_DISPLAY_FILE_INFO(file, line) \ + do { \ + } while (0) +#endif + +#ifdef HAVE_LEDGER_ASSERT_DISPLAY +#define ASSERT_BUFFER_LEN LR_AND_PC_SIZE + MESSAGE_SIZE + FILE_SIZE +void __attribute__((noreturn)) assert_display_exit(void); + +#define LEDGER_ASSERT_EXIT() assert_display_exit() +#else +void assert_exit(bool confirm); +#define LEDGER_ASSERT_EXIT() assert_exit(true) +#endif + +#if defined(LEDGER_ASSERT_CONFIG_LR_AND_PC_INFO) && defined(HAVE_PRINTF) +void assert_print_lr_and_pc(int lr, int pc); +#define ASSERT_PRINT_LR_AND_PC(lr, pc) assert_print_lr_and_pc(lr, pc) +#else +#define ASSERT_PRINT_LR_AND_PC(lr, pc) \ + do { \ + } while (0) +#endif + +#if defined(LEDGER_ASSERT_CONFIG_MESSAGE_INFO) && defined(HAVE_PRINTF) +void assert_print_message(const char *message); +#define ASSERT_PRINT_MESSAGE(message) assert_print_message(message) +#else +#define ASSERT_PRINT_MESSAGE(message) \ + do { \ + } while (0) +#endif + +#if defined(LEDGER_ASSERT_CONFIG_FILE_INFO) && defined(HAVE_PRINTF) +void assert_print_file_info(const char *file, int line); +#define ASSERT_PRINT_FILE_INFO(file, line) assert_print_file_info(file, line) +#else +#define ASSERT_PRINT_FILE_INFO(file, line) \ + do { \ + } while (0) +#endif + +#ifdef LEDGER_ASSERT_CONFIG_LR_AND_PC_INFO +#define LEDGER_ASSERT_LR_AND_PC() \ + do { \ + int _lr_address = 0; \ + int _pc_address = 0; \ + \ + __asm volatile("mov %0, lr" : "=r"(_lr_address)); \ + __asm volatile("mov %0, pc" : "=r"(_pc_address)); \ + ASSERT_PRINT_LR_AND_PC(_lr_address, _pc_address); \ + ASSERT_DISPLAY_LR_AND_PC(_lr_address, _pc_address); \ + } while (0) +#elif defined(HAVE_PRINTF) +#define LEDGER_ASSERT_LR_AND_PC() PRINTF("LEDGER_ASSERT FAILED\n") +#else +#define LEDGER_ASSERT_LR_AND_PC() \ + do { \ + } while (0) +#endif + +#ifdef LEDGER_ASSERT_CONFIG_MESSAGE_INFO +#define LEDGER_ASSERT_MESSAGE(message) \ + do { \ + ASSERT_PRINT_MESSAGE(message); \ + ASSERT_DISPLAY_MESSAGE(message); \ + } while (0) +#else +#define LEDGER_ASSERT_MESSAGE(message) \ + do { \ + } while (0) +#endif + +#ifdef LEDGER_ASSERT_CONFIG_FILE_INFO +#define LEDGER_ASSERT_FILE_INFO() \ + do { \ + ASSERT_PRINT_FILE_INFO(__FILE__, __LINE__); \ + ASSERT_DISPLAY_FILE_INFO(__FILE__, __LINE__); \ + } while (0) +#else +#define LEDGER_ASSERT_FILE_INFO() \ + do { \ + } while (0) +#endif + +#define LEDGER_ASSERT(test, message) \ + do { \ + if (!(test)) { \ + LEDGER_ASSERT_LR_AND_PC(); \ + LEDGER_ASSERT_MESSAGE(message); \ + LEDGER_ASSERT_FILE_INFO(); \ + LEDGER_ASSERT_EXIT(); \ + } \ + } while (0) + +#if defined(HAVE_DEBUG_THROWS) && defined(HAVE_PRINTF) +void throw_print_lr(int e, int lr); +#define THROW_PRINT_LR(e, lr_val) throw_print_lr(e, lr_val) +#else +#define THROW_PRINT_LR(e, lr_val) \ + do { \ + } while (0) +#endif + +#if defined(HAVE_DEBUG_THROWS) +void __attribute__((noreturn)) assert_display_exit(void); +void throw_display_lr(int e, int lr); +#define DEBUG_THROW(e) \ + do { \ + unsigned int lr_val; \ + __asm volatile("mov %0, lr" : "=r"(lr_val)); \ + throw_display_lr(e, lr_val); \ + THROW_PRINT_LR(e, lr_val); \ + } while (0) +#endif diff --git a/include/os.h b/include/os.h index 0a6ae4d9d..27633c383 100644 --- a/include/os.h +++ b/include/os.h @@ -131,6 +131,10 @@ int snprintf(char *str, size_t str_size, const char *format, ...); #endif // APPLE #endif // HAVE_SPRINTF +#ifndef HAVE_BOLOS +int compute_address_location(int address); +#endif + // syscall test // SYSCALL void dummy_1(unsigned int* p PLENGTH(2+len+15+ len + 16 + sizeof(io_send_t) + 1 ), // unsigned int len); diff --git a/lib_standard_app/debug.c b/lib_standard_app/debug.c deleted file mode 100644 index ea1a396cb..000000000 --- a/lib_standard_app/debug.c +++ /dev/null @@ -1,71 +0,0 @@ -/***************************************************************************** - * (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 deleted file mode 100644 index 0987417fc..000000000 --- a/lib_standard_app/debug.h +++ /dev/null @@ -1,3 +0,0 @@ -#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 80cf336c7..e82647eac 100644 --- a/lib_standard_app/main.c +++ b/lib_standard_app/main.c @@ -19,7 +19,7 @@ #include "os.h" #include "io.h" -#include "debug.h" +#include "ledger_assert.h" #ifdef HAVE_SWAP #include "swap.h" @@ -72,8 +72,6 @@ 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 @@ -90,7 +88,9 @@ static void standalone_app_main(void) BLE_power(0, NULL); #endif // Display crash info on screen for debug purpose - debug_display_throw_error(e); + assert_display_exit(); +#else + PRINTF("Exiting following exception: 0x%04X\n", e); #endif } FINALLY {} @@ -141,7 +141,7 @@ static void library_app_main(libargs_t *args) } CATCH_OTHER(e) { - PRINTF("Exiting following exception: %d\n", e); + PRINTF("Exiting following exception: 0x%04X\n", e); } FINALLY { diff --git a/src/ledger_assert.c b/src/ledger_assert.c new file mode 100644 index 000000000..baea1f46f --- /dev/null +++ b/src/ledger_assert.c @@ -0,0 +1,145 @@ +/******************************************************************************* + * (c) 2023 Ledger + * + * 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 + +#include "ledger_assert.h" +#include "os.h" +#include "ux.h" +#include "os_io_seproxyhal.h" + +#ifdef HAVE_NBGL +#include "nbgl_use_case.h" +#endif + +#ifndef ASSERT_BUFFER_LEN +#define ASSERT_BUFFER_LEN 24 +#endif + +#if defined(HAVE_LEDGER_ASSERT_DISPLAY) || defined(HAVE_DEBUG_THROWS) +static char assert_buffer[ASSERT_BUFFER_LEN]; +#endif + +#if defined(HAVE_LEDGER_ASSERT_DISPLAY) && defined(LEDGER_ASSERT_CONFIG_LR_AND_PC_INFO) +void assert_display_lr_and_pc(int lr, int pc) +{ + char buff[LR_AND_PC_SIZE]; + + lr = compute_address_location(lr); + pc = compute_address_location(pc); + snprintf(buff, LR_AND_PC_SIZE, "LR=0x%08X\n PC=0x%08X\n", lr, pc); + strncat(assert_buffer, buff, LR_AND_PC_SIZE); +} +#endif + +#if defined(HAVE_LEDGER_ASSERT_DISPLAY) && defined(LEDGER_ASSERT_CONFIG_MESSAGE_INFO) +void assert_display_message(const char *message) +{ + char buff[MESSAGE_SIZE]; + + snprintf(buff, MESSAGE_SIZE, "%s\n", message); + strncat(assert_buffer, buff, MESSAGE_SIZE); +} +#endif + +#if defined(HAVE_LEDGER_ASSERT_DISPLAY) && defined(LEDGER_ASSERT_CONFIG_FILE_INFO) +void assert_display_file_info(const char *file, unsigned int line) +{ + char buff[FILE_SIZE]; + + snprintf(buff, FILE_SIZE, "%s::%d\n", file, line); + strncat(assert_buffer, buff, FILE_SIZE); +} +#endif + +#if defined(HAVE_PRINTF) && defined(LEDGER_ASSERT_CONFIG_LR_AND_PC_INFO) +void assert_print_lr_and_pc(int lr, int pc) +{ + lr = compute_address_location(lr); + pc = compute_address_location(pc); + PRINTF("LEDGER_ASSERT FAILED\n"); + PRINTF("=> LR: 0x%08X \n", lr); + PRINTF("=> PC: 0x%08X \n", pc); +} +#endif + +#if defined(HAVE_PRINTF) && defined(LEDGER_ASSERT_CONFIG_FILE_INFO) +void assert_print_file_info(const char *file, int line) +{ + PRINTF("%s::%d \n", file, line); +} +#endif + +#if defined(HAVE_PRINTF) && defined(LEDGER_ASSERT_CONFIG_MESSAGE_INFO) +void assert_print_message(const char *message) +{ + if (message) { + PRINTF("%s\n", message); + } +} +#endif + +#if defined(HAVE_DEBUG_THROWS) +void throw_display_lr(int e, int lr) +{ + lr = compute_address_location(lr); + snprintf(assert_buffer, ASSERT_BUFFER_LEN, "e=0x%04X\n LR=0x%08X\n", e, lr); +} +#endif + +#if defined(HAVE_PRINTF) && defined(HAVE_DEBUG_THROWS) +void throw_print_lr(int e, int lr) +{ + lr = compute_address_location(lr); + PRINTF("exception[0x%04X]: LR=0x%08X\n", e, lr); +} +#endif + +void assert_exit(bool confirm) +{ + UNUSED(confirm); + os_sched_exit(-1); +} + +#if defined(HAVE_LEDGER_ASSERT_DISPLAY) || defined(HAVE_DEBUG_THROWS) +#ifdef HAVE_BAGL +UX_STEP_CB(ux_error, + bnnn_paging, + assert_exit(true), + { + .title = "App error", + .text = assert_buffer, + }); +UX_FLOW(ux_error_flow, &ux_error); +#endif + +void __attribute__((noreturn)) assert_display_exit(void) +{ +#ifdef HAVE_BAGL + ux_flow_init(0, ux_error_flow, NULL); +#endif + +#ifdef HAVE_NBGL + nbgl_useCaseChoice( + &C_round_warning_64px, "App error", assert_buffer, "Exit app", "Exit app", assert_exit); +#endif + + // Block until the user approve and the app is quit + while (1) { + io_seproxyhal_io_heartbeat(); + } +} +#endif diff --git a/src/os.c b/src/os.c index 232b82375..a88e3001d 100644 --- a/src/os.c +++ b/src/os.c @@ -85,30 +85,28 @@ char os_secure_memcmp(const void *src1, const void *src2, size_t length) } #ifndef HAVE_BOLOS -#define MAIN_LINKER_SCRIPT_LOCATION 0xC0DE0000 +#include "ledger_assert.h" 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) +#define MAIN_LINKER_SCRIPT_LOCATION 0xC0DE0000 +int compute_address_location(int address) { - UNUSED(exception); - UNUSED(lr_val); + // Compute location before relocation (sort of anti PIC) + return address - (unsigned int) main + MAIN_LINKER_SCRIPT_LOCATION; } void os_longjmp(unsigned int exception) { - unsigned int lr_val; +#ifdef HAVE_DEBUG_THROWS + // Send to the app the info of exception and LR for debug purpose + DEBUG_THROW(exception); +#elif defined(HAVE_PRINTF) + int lr_val; __asm volatile("mov %0, lr" : "=r"(lr_val)); + lr_val = compute_address_location(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); + PRINTF("exception[0x%04X]: LR=0x%08X\n", exception, lr_val); +#endif longjmp(try_context_get()->jmp_buf, exception); } From 7bae08826575a9cf9b3309b561d68a260cbed931 Mon Sep 17 00:00:00 2001 From: Alexandre Paillier Date: Tue, 5 Dec 2023 17:21:09 +0100 Subject: [PATCH 13/14] Fix ledger_assert compatibility with DISABLE_UI (cherry picked from commit a4cb18ba078ebc7bdfb68a85588a15fbc7e9d1cf) --- src/ledger_assert.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ledger_assert.c b/src/ledger_assert.c index baea1f46f..d39b76811 100644 --- a/src/ledger_assert.c +++ b/src/ledger_assert.c @@ -18,7 +18,9 @@ #include "ledger_assert.h" #include "os.h" +#if defined(HAVE_BAGL) || defined(HAVE_NBGL) #include "ux.h" +#endif #include "os_io_seproxyhal.h" #ifdef HAVE_NBGL From 5e533432175b4f1f772f61939d93d6f1b4d69668 Mon Sep 17 00:00:00 2001 From: Xavier Chapron Date: Thu, 30 Nov 2023 18:15:32 +0100 Subject: [PATCH 14/14] nbgl: Add nbgl_useCaseForwardOnlyReviewNoSkip() (cherry picked from commit 40d6a685d5692badcc85c9d46a40916dee28a350) --- lib_nbgl/include/nbgl_use_case.h | 4 +++ lib_nbgl/src/nbgl_use_case.c | 45 +++++++++++++++++++++++++++++++- 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/lib_nbgl/include/nbgl_use_case.h b/lib_nbgl/include/nbgl_use_case.h index 7bae356a7..bd4ca3073 100644 --- a/lib_nbgl/include/nbgl_use_case.h +++ b/lib_nbgl/include/nbgl_use_case.h @@ -177,6 +177,10 @@ void nbgl_useCaseForwardOnlyReview(const char *rejectText, nbgl_layoutTouchCallback_t buttonCallback, nbgl_navCallback_t navCallback, nbgl_choiceCallback_t choiceCallback); +void nbgl_useCaseForwardOnlyReviewNoSkip(const char *rejectText, + nbgl_layoutTouchCallback_t buttonCallback, + nbgl_navCallback_t navCallback, + nbgl_choiceCallback_t choiceCallback); void nbgl_useCaseStaticReview(const nbgl_layoutTagValueList_t *tagValueList, const nbgl_pageInfoLongPress_t *infoLongPress, const char *rejectText, diff --git a/lib_nbgl/src/nbgl_use_case.c b/lib_nbgl/src/nbgl_use_case.c index a8910331f..15e52aed9 100644 --- a/lib_nbgl/src/nbgl_use_case.c +++ b/lib_nbgl/src/nbgl_use_case.c @@ -1209,7 +1209,9 @@ void nbgl_useCaseRegularReview(uint8_t initPage, * @brief Draws a flow of pages of a review, without back key. * It is possible to go to next page thanks to "tap to continue". * For each page, the given navCallback will be called to get the content. Only 'type' and - * union has to be set in this content + * union has to be set in this content. + * Note that this is not a standard use case, it should only be used on very specific + * situations. * * @param rejectText text to use in footer * @param buttonCallback callback called when a potential button (details or long press) in the @@ -1245,6 +1247,47 @@ void nbgl_useCaseForwardOnlyReview(const char *rejectText, displayReviewPage(0, false); } +/** + * @brief Draws a flow of pages of a review, without back key. + * It is possible to go to next page thanks to "tap to continue". + * For each page, the given navCallback will be called to get the content. Only 'type' and + * union has to be set in this content. + * Note that this is not a standard use case, it should only be used on very specific + * situations. + * + * @param rejectText text to use in footer + * @param buttonCallback callback called when a potential button (details or long press) in the + * content is touched + * @param navCallback callback called when navigation "tap to continue" is touched, to get the + * content of next page + * @param choiceCallback callback called when either long_press or footer is called (param is true + * for long press) + */ +void nbgl_useCaseForwardOnlyReviewNoSkip(const char *rejectText, + nbgl_layoutTouchCallback_t buttonCallback, + nbgl_navCallback_t navCallback, + nbgl_choiceCallback_t choiceCallback) +{ + // memorize context + onChoice = choiceCallback; + onNav = navCallback; + onControls = buttonCallback; + forwardNavOnly = true; + + // fill navigation structure + navInfo.nbPages = 0; + navInfo.navType = NAV_WITH_TAP; + navInfo.quitToken = REJECT_TOKEN; + navInfo.navWithTap.nextPageToken = NEXT_TOKEN; + navInfo.navWithTap.quitText = rejectText; + navInfo.navWithTap.backToken = BACK_TOKEN; + navInfo.navWithTap.skipText = NULL; + navInfo.progressIndicator = true; + navInfo.tuneId = TUNE_TAP_CASUAL; + + displayReviewPage(0, false); +} + /** * @brief Draws a flow of pages of a review. A back key is available on top-left of the screen, * except in first page It is possible to go to next page thanks to "tap to continue".