Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stax support for Exchange #108

Merged
merged 17 commits into from
Sep 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
19 changes: 0 additions & 19 deletions .github/workflows/ci-workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,3 @@ jobs:
uses: ./.github/workflows/reusable_swap_functional_tests.yml
with:
branch_for_exchange: ${{ github.ref }}

job_scan_build:
name: Clang Static Analyzer
runs-on: ubuntu-latest
container:
image: ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder:latest
steps:
- uses: actions/checkout@v3
with:
submodules: recursive
- name: Build with Clang Static Analyzer
run: |
git config --global --add safe.directory "$GITHUB_WORKSPACE"
scan-build --use-cc=clang -analyze-headers -enable-checker security -enable-checker unix -enable-checker valist -o scan-build --status-bugs make default
- uses: actions/upload-artifact@v3
if: failure()
with:
name: scan-build
path: scan-build
2 changes: 0 additions & 2 deletions .github/workflows/guidelines_enforcer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,3 @@ jobs:
guidelines_enforcer:
name: Call Ledger guidelines_enforcer
uses: LedgerHQ/ledger-app-workflows/.github/workflows/reusable_guidelines_enforcer.yml@v1
with:
run_for_devices: '["nanos", "nanox", "nanosp"]'
3 changes: 0 additions & 3 deletions .github/workflows/reusable_swap_functional_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@ jobs:
flags: "COIN=${{ matrix.coin.name }} CHAIN=${{ matrix.coin.name }} DEBUG=1"
upload_app_binaries_artifact: libraries_binaries
upload_as_lib_artifact: ${{ matrix.coin.name }}
run_for_devices: '["nanos", "nanox", "nanosp"]'

build_exchange_application:
name: Build application using the reusable workflow
Expand All @@ -107,7 +106,6 @@ jobs:
app_branch_name: ${{ inputs.branch_for_exchange }}
flags: "TESTING=1 TEST_PUBLIC_KEY=1 DEBUG=1"
upload_app_binaries_artifact: exchange_binaries
run_for_devices: '["nanos", "nanox", "nanosp"]'

ragger_tests:
name: Run ragger tests using the reusable workflow
Expand All @@ -122,7 +120,6 @@ jobs:
lib_binaries_artifact: libraries_binaries
test_dir: test/python
test_filter: ${{ inputs.test_filter }}
run_for_devices: '["nanos", "nanox", "nanosp"]'

# Legacy
zemu_tests:
Expand Down
73 changes: 41 additions & 32 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,23 @@
ifeq ($(BOLOS_SDK),)
$(error Environment variable BOLOS_SDK is not set)
endif

include $(BOLOS_SDK)/Makefile.defines

APP_LOAD_PARAMS = --curve ed25519 --curve secp256k1 --curve secp256r1 --path "" $(COMMON_LOAD_PARAMS)
APP_LOAD_PARAMS = --curve ed25519 --curve secp256k1 --curve secp256r1

# Permissions: DERIVE_MASTER, GLOBAL_PIN, APPLICATION_FLAG_BOLOS_SETTINGS
# DERIVE_MASTER is needed to compute the master key fingerprint in app-bitcoin-new
APP_LOAD_PARAMS += --appFlags 0x250

APPVERSION_M=2
APPVERSION_N=0
APPVERSION_P=14
APPVERSION=$(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P)-dev
APPNAME = "Exchange"
APP_LOAD_PARAMS += --path ""
APP_LOAD_PARAMS += $(COMMON_LOAD_PARAMS)

DEFINES += $(DEFINES_LIB)
APPNAME = "Exchange"
APPVERSION_M = 3
APPVERSION_N = 0
APPVERSION_P = 1
APPVERSION = $(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P)-dev

ifdef TESTING
$(info [INFO] TESTING enabled)
Expand All @@ -45,9 +47,11 @@ ifdef TEST_PUBLIC_KEY
endif

ifeq ($(TARGET_NAME),TARGET_NANOS)
ICONNAME=icons/nanos_app_exchange.gif
ICONNAME=icons/nanos_app_exchange.gif
else ifeq ($(TARGET_NAME),TARGET_STAX)
ICONNAME=icons/stax_app_exchange.gif
else
ICONNAME=icons/nanox_app_exchange.gif
ICONNAME=icons/nanox_app_exchange.gif
endif

################
Expand All @@ -59,42 +63,44 @@ all: default
# Platform #
############

DEFINES += $(DEFINES_LIB)
DEFINES += APPNAME=\"$(APPNAME)\"
DEFINES += APPVERSION=\"$(APPVERSION)\"
DEFINES += LEDGER_MAJOR_VERSION=$(APPVERSION_M) LEDGER_MINOR_VERSION=$(APPVERSION_N) LEDGER_PATCH_VERSION=$(APPVERSION_P)
DEFINES += OS_IO_SEPROXYHAL
DEFINES += HAVE_BAGL HAVE_SPRINTF
DEFINES += HAVE_SPRINTF
DEFINES += HAVE_IO_USB HAVE_L4_USBLIB IO_USB_MAX_ENDPOINTS=4 IO_HID_EP_LENGTH=64 HAVE_USB_APDU
DEFINES += LEDGER_MAJOR_VERSION=$(APPVERSION_M) LEDGER_MINOR_VERSION=$(APPVERSION_N) LEDGER_PATCH_VERSION=$(APPVERSION_P)

DEFINES += USB_SEGMENT_SIZE=64
DEFINES += BLE_SEGMENT_SIZE=32 #max MTU, min 20

DEFINES += UNUSED\(x\)=\(void\)x
DEFINES += APPVERSION=\"$(APPVERSION)\"

ifeq ($(TARGET_NAME),TARGET_NANOX)
DEFINES += HAVE_BLE BLE_COMMAND_TIMEOUT_MS=2000
DEFINES += HAVE_BLE_APDU # basic ledger apdu transport over BLE
ifeq ($(TARGET_NAME),$(filter $(TARGET_NAME),TARGET_NANOX TARGET_STAX))
DEFINES += HAVE_BLE BLE_COMMAND_TIMEOUT_MS=2000 HAVE_BLE_APDU
endif

ifeq ($(TARGET_NAME),TARGET_NANOS)
DEFINES += IO_SEPROXYHAL_BUFFER_SIZE_B=128
DEFINES += IO_SEPROXYHAL_BUFFER_SIZE_B=128
else
DEFINES += IO_SEPROXYHAL_BUFFER_SIZE_B=300
DEFINES += HAVE_GLO096
DEFINES += HAVE_BAGL BAGL_WIDTH=128 BAGL_HEIGHT=64
DEFINES += HAVE_BAGL_ELLIPSIS # long label truncation feature
DEFINES += HAVE_BAGL_FONT_OPEN_SANS_REGULAR_11PX
DEFINES += HAVE_BAGL_FONT_OPEN_SANS_EXTRABOLD_11PX
DEFINES += HAVE_BAGL_FONT_OPEN_SANS_LIGHT_16PX
DEFINES += IO_SEPROXYHAL_BUFFER_SIZE_B=300
endif

DEFINES += HAVE_UX_FLOW
DEFINES += HAVE_STACK_OVERFLOW_CHECK
# Enabling debug PRINTF

ifndef DEBUG
DEBUG = 0
ifneq ($(TARGET_NAME),TARGET_STAX)
DEFINES += HAVE_BAGL HAVE_UX_FLOW
ifneq ($(TARGET_NAME),TARGET_NANOS)
DEFINES += HAVE_GLO096
DEFINES += BAGL_WIDTH=128 BAGL_HEIGHT=64
DEFINES += HAVE_BAGL_ELLIPSIS # long label truncation feature
DEFINES += HAVE_BAGL_FONT_OPEN_SANS_REGULAR_11PX
DEFINES += HAVE_BAGL_FONT_OPEN_SANS_EXTRABOLD_11PX
DEFINES += HAVE_BAGL_FONT_OPEN_SANS_LIGHT_16PX
endif
endif


# Enabling debug PRINTF
DEBUG ?= 0
ifneq ($(DEBUG),0)
DEFINES += HAVE_STACK_OVERFLOW_CHECK
ifeq ($(TARGET_NAME),TARGET_NANOS)
Expand All @@ -121,10 +127,13 @@ include $(BOLOS_SDK)/Makefile.glyphs
### variables processed by the common makefile.rules of the SDK to grab source files and include dirs
APP_SOURCE_PATH += src
SDK_SOURCE_PATH += lib_stusb lib_stusb_impl
SDK_SOURCE_PATH += lib_ux

ifeq ($(TARGET_NAME),TARGET_NANOX)
SDK_SOURCE_PATH += lib_blewbxx lib_blewbxx_impl
ifneq ($(TARGET_NAME),TARGET_STAX)
SDK_SOURCE_PATH += lib_ux
endif

ifeq ($(TARGET_NAME),$(filter $(TARGET_NAME),TARGET_NANOX TARGET_STAX))
SDK_SOURCE_PATH += lib_blewbxx lib_blewbxx_impl
endif

.PHONY: proto
Expand Down
Binary file removed glyphs/boilerplate_logo.gif
Binary file not shown.
Binary file added glyphs/icon_exchange_64x64.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added icons/stax_app_exchange.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
29 changes: 24 additions & 5 deletions src/currency_lib_calls.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include "os_io_seproxyhal.h"
#include "os.h"
#include "globals.h"

#include "currency_lib_calls.h"

Expand Down Expand Up @@ -119,27 +120,45 @@ int check_address(buf_t *coin_config,
return lib_in_out_params.result;
}

int create_payin_transaction(char *application_name,
create_transaction_parameters_t *lib_in_out_params) {
int create_payin_transaction(create_transaction_parameters_t *lib_in_out_params) {
unsigned int libcall_params[5];

// Initialize result with error value.
// This might be used in case the called app catch a throw and call os_lib_end()
// before setting the result value.
lib_in_out_params->result = 0;

libcall_params[0] = (unsigned int) application_name;
libcall_params[0] = (unsigned int) G_swap_ctx.payin_binary_name;
libcall_params[1] = 0x100;
libcall_params[2] = SIGN_TRANSACTION;
libcall_params[3] = 0;
libcall_params[4] = (unsigned int) lib_in_out_params;

PRINTF("Exchange will call '%s' as library for SIGN_TRANSACTION\n", application_name);
PRINTF("Exchange will call '%s' as library for SIGN_TRANSACTION\n",
G_swap_ctx.payin_binary_name);
USB_power(0);

#ifdef HAVE_NBGL
// Save appname in stack to keep it from being erased
// We'll need it later for the failure modale on Stax
char appanme[BOLOS_APPNAME_MAX_SIZE_B];
strlcpy(appanme, G_swap_ctx.payin_binary_name, sizeof(appanme));
#endif

os_lib_call(libcall_params);
// From now our BSS is corrupted and unusable. Return to main loop start ASAP

// From now on our BSS is corrupted and unusable. Return to main loop to start a new cycle ASAP
PRINTF("Back in Exchange, the app finished the library command SIGN_TRANSACTION\n");
PRINTF("Returned code %d\n", lib_in_out_params->result);

#ifdef HAVE_NBGL
// Retrieve the appname from the stack and put it back in the BSS
strlcpy(G_previous_cycle_data.appname_last_cycle,
appanme,
sizeof(G_previous_cycle_data.appname_last_cycle));
// Remember if this sign was successful
G_previous_cycle_data.was_successful = (lib_in_out_params->result == 1);
#endif

return lib_in_out_params->result;
}
2 changes: 1 addition & 1 deletion src/currency_lib_calls.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ int get_printable_amount(buf_t *coin_config,
unsigned char printable_amount_size,
bool is_fee);

int create_payin_transaction(char *application_name, create_transaction_parameters_t *params);
int create_payin_transaction(create_transaction_parameters_t *params);
11 changes: 11 additions & 0 deletions src/globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,14 @@ typedef struct swap_app_context_s {
} swap_app_context_t;

extern swap_app_context_t G_swap_ctx;

#ifdef HAVE_NBGL
// On Stax, remember some data from the previous cycle if applicable to display a status screen
typedef struct previous_cycle_data_s {
bool had_previous_cycle;
bool was_successful;
char appname_last_cycle[BOLOS_APPNAME_MAX_SIZE_B + 1];
} previous_cycle_data_t;

extern previous_cycle_data_t G_previous_cycle_data;
#endif
53 changes: 48 additions & 5 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "apdu_offsets.h"
#include "swap_errors.h"
#include "apdu_parser.h"
#include "validate_transaction.h"

#include "usbd_core.h"

Expand Down Expand Up @@ -87,18 +88,41 @@ void app_exit(void) {
END_TRY_L(exit);
}

// On Stax, remember some data from the previous cycle if applicable to display a status screen
#ifdef HAVE_NBGL
previous_cycle_data_t G_previous_cycle_data;
#endif

__attribute__((section(".boot"))) int main(__attribute__((unused)) int arg0) {
// exit critical section
__asm volatile("cpsie i");

#ifdef HAVE_NBGL
G_previous_cycle_data.had_previous_cycle = false;
#endif

// ensure exception will work as planned
os_boot();

for (;;) {
// Fully reset the global space, as it may be corrupted if we come back from an app started
// for signing
PRINTF("Exchange new cycle, reset BSS\n");
os_explicit_zero_BSS_segment();
// If we are back from a lib app in signing mode, clean our BSS
if (G_swap_ctx.state == SIGN_FINISHED) {
#ifdef HAVE_NBGL
G_previous_cycle_data.had_previous_cycle = true;
// We have saved some data for the status screen in the BSS
// Let's avoid them being erased by doing a stack save
previous_cycle_data_t tmp_previous_cycle_data;
memcpy(&tmp_previous_cycle_data, &G_previous_cycle_data, sizeof(G_previous_cycle_data));
#endif

// Fully reset the global space, as it is was corrupted by the signing app
PRINTF("Exchange new cycle, reset BSS\n");
os_explicit_zero_BSS_segment();

#ifdef HAVE_NBGL
memcpy(&G_previous_cycle_data, &tmp_previous_cycle_data, sizeof(G_previous_cycle_data));
#endif
}

UX_INIT();

Expand All @@ -114,11 +138,30 @@ __attribute__((section(".boot"))) int main(__attribute__((unused)) int arg0) {
USB_power(0);
USB_power(1);

#ifdef HAVE_NBGL
// If last cycle had signing related activities,
// display it before displaying the main menu.
// We can't do it earlier because :
// - we need to shadow the ui_idle() call
// - we need a BSS reset + UX_INIT
if (G_previous_cycle_data.had_previous_cycle) {
G_previous_cycle_data.had_previous_cycle = false;
if (G_previous_cycle_data.was_successful) {
display_signing_success();
} else {
display_signing_failure(G_previous_cycle_data.appname_last_cycle);
}
} else {
ui_idle();
}
#else // HAVE_BAGL
// No "Ledger Moment" modal, sad
ui_idle();
#endif

#ifdef HAVE_BLE
BLE_power(0, NULL);
BLE_power(1, "Nano X");
BLE_power(1, NULL);
#endif

app_main();
Expand Down
7 changes: 7 additions & 0 deletions src/start_new_transaction.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,19 @@
#include "init.h"
#include "io.h"
#include "globals.h"
#include "menu.h"

int start_new_transaction(const command_t *cmd) {
// prepare size for device_transaction_id + 0x9000
uint8_t output_buffer[sizeof(G_swap_ctx.device_transaction_id) + 2];
size_t output_buffer_size = 0;

// Force a UI reset if we are currently displaying a modal
if (G_swap_ctx.state == WAITING_SIGNING) {
PRINTF("Dismissing the modal and forcing the main menu\n");
ui_idle();
}
xchapron-ledger marked this conversation as resolved.
Show resolved Hide resolved

if (init_application_context() != 0) {
PRINTF("Error: init_application_context failed\n");
return reply_error(INTERNAL_ERROR);
Expand Down
8 changes: 3 additions & 5 deletions src/start_signing_transaction.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
#include "io.h"

int start_signing_transaction(const command_t *cmd) {
int ret = 0;

// Inform the caller that we will call the lib app
if (instant_reply_success() < 0) {
PRINTF("Error: failed to send\n");
Expand Down Expand Up @@ -51,9 +49,9 @@ int start_signing_transaction(const command_t *cmd) {
lib_in_out_params.destination_address_extra_id = G_swap_ctx.fund_transaction_extra_id;
}

ret = create_payin_transaction(G_swap_ctx.payin_binary_name, &lib_in_out_params);
// Write G_swap_ctx.state AFTER coming back to exchange to avoid erasure by the app
create_payin_transaction(&lib_in_out_params);
G_swap_ctx.state = SIGN_FINISHED;

return ret;
// The called app refusing to sign is NOT an handler error, we report a success
return 0;
}
Loading
Loading