diff --git a/Makefile b/Makefile index bef30d6c..e5fc639a 100644 --- a/Makefile +++ b/Makefile @@ -24,7 +24,7 @@ APP_PATH = "" APP_LOAD_PARAMS= --curve secp256k1 $(COMMON_LOAD_PARAMS) APPVERSION_M=2 -APPVERSION_N=1 +APPVERSION_N=2 APPVERSION_P=0 APPVERSION=$(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P) APP_LOAD_FLAGS=--appFlags 0xa50 diff --git a/include/swap_lib_calls.h b/include/swap_lib_calls.h index 378b93c8..0f59a452 100644 --- a/include/swap_lib_calls.h +++ b/include/swap_lib_calls.h @@ -1,7 +1,14 @@ -#ifndef SWAP_LIB_CALLS -#define SWAP_LIB_CALLS +#pragma once + +/* This file is the shared API between Exchange and the apps started in Library mode for Exchange + * + * DO NOT MODIFY THIS FILE IN APPLICATIONS OTHER THAN EXCHANGE + * On modification in Exchange, forward the changes to all applications supporting Exchange + */ #include "stdbool.h" +#include "stdint.h" +#include "btchip_context.h" #define RUN_APPLICATION 1 @@ -11,15 +18,25 @@ #define GET_PRINTABLE_AMOUNT 4 +/* + * Amounts are stored as bytes, with a max size of 16 (see protobuf + * specifications). Max 16B integer is 340282366920938463463374607431768211455 + * in decimal, which is a 32-long char string. + * The printable amount also contains spaces, the ticker symbol (with variable + * size, up to 12 in Ethereum for instance) and a terminating null byte, so 50 + * bytes total should be a fair maximum. + */ +#define MAX_PRINTABLE_AMOUNT_SIZE 50 + // structure that should be send to specific coin application to get address typedef struct check_address_parameters_s { // IN - unsigned char* coin_configuration; - unsigned char coin_configuration_length; + uint8_t *coin_configuration; + uint8_t coin_configuration_length; // serialized path, segwit, version prefix, hash used, dictionary etc. - // fields and serialization format depends on spesific coin app - unsigned char* address_parameters; - unsigned char address_parameters_length; + // fields and serialization format depends on specific coin app + uint8_t *address_parameters; + uint8_t address_parameters_length; char *address_to_check; char *extra_id_to_check; // OUT @@ -29,25 +46,36 @@ typedef struct check_address_parameters_s { // structure that should be send to specific coin application to get printable amount typedef struct get_printable_amount_parameters_s { // IN - unsigned char* coin_configuration; - unsigned char coin_configuration_length; - unsigned char* amount; - unsigned char amount_length; + uint8_t *coin_configuration; + uint8_t coin_configuration_length; + uint8_t *amount; + uint8_t amount_length; bool is_fee; // OUT - char printable_amount[30]; - // int result; + char printable_amount[MAX_PRINTABLE_AMOUNT_SIZE]; } get_printable_amount_parameters_t; typedef struct create_transaction_parameters_s { - unsigned char* coin_configuration; - unsigned char coin_configuration_length; - unsigned char* amount; - unsigned char amount_length; - unsigned char* fee_amount; - unsigned char fee_amount_length; + // IN + uint8_t *coin_configuration; + uint8_t coin_configuration_length; + uint8_t *amount; + uint8_t amount_length; + uint8_t *fee_amount; + uint8_t fee_amount_length; char *destination_address; char *destination_address_extra_id; + // OUT + uint8_t result; } create_transaction_parameters_t; -#endif +typedef struct libargs_s { + unsigned int id; + unsigned int command; + btchip_altcoin_config_t *coin_config; + union { + check_address_parameters_t *check_address; + create_transaction_parameters_t *create_transaction; + get_printable_amount_parameters_t *get_printable_amount; + }; +} libargs_t; diff --git a/src/btchip.c b/src/btchip.c index 9b40a012..7e7ef173 100644 --- a/src/btchip.c +++ b/src/btchip.c @@ -24,6 +24,8 @@ #include "btchip_apdu_constants.h" #include "btchip_display_variables.h" +#include "handle_swap_sign_transaction.h" + #define BTCHIP_TECHNICAL_NOT_IMPLEMENTED 0x99 #define COMMON_CLA 0xB0 @@ -167,7 +169,7 @@ void app_main(void) { btchip_context_D.outLength); if (btchip_context_D.called_from_swap && vars.swap_data.should_exit) { - os_sched_exit(0); + finalize_exchange_sign_transaction(btchip_context_D.sw == BTCHIP_SW_OK); } PRINTF("New APDU received:\n%.*H\n", btchip_context_D.inLength, G_io_apdu_buffer); diff --git a/src/handle_swap_sign_transaction.c b/src/handle_swap_sign_transaction.c index 40479c4f..1c2dc971 100644 --- a/src/handle_swap_sign_transaction.c +++ b/src/handle_swap_sign_transaction.c @@ -6,6 +6,12 @@ #include "usbd_core.h" #include "ux.h" +#ifdef HAVE_NBGL +#include "nbgl_use_case.h" +#endif + +// Save the BSS address where we will write the return value when finished +static uint8_t *G_swap_sign_return_value_address; bool copy_transaction_parameters(create_transaction_parameters_t* sign_transaction_params) { // first copy parameters to stack, and then to global data. @@ -22,6 +28,14 @@ bool copy_transaction_parameters(create_transaction_parameters_t* sign_transacti // input {0xEE, 0x00, 0xFF} should be stored like {0x00, 0x00, 0x00, 0x00, 0x00, 0xEE, 0x00, 0xFF} memcpy(stack_data.amount + 8 - sign_transaction_params->amount_length, sign_transaction_params->amount, sign_transaction_params->amount_length); memcpy(stack_data.fees + 8 - sign_transaction_params->fee_amount_length, sign_transaction_params->fee_amount, sign_transaction_params->fee_amount_length); + + // Erase values inherited from Exchange app + os_explicit_zero_BSS_segment(); + + // Keep the address at which we'll reply the signing status + G_swap_sign_return_value_address = &sign_transaction_params->result; + + // Copy from stack back to global data segment memcpy(&vars.swap_data, &stack_data, sizeof(stack_data)); return true; } @@ -32,6 +46,9 @@ void handle_swap_sign_transaction(btchip_altcoin_config_t *config) { btchip_context_D.called_from_swap = 1; io_seproxyhal_init(); UX_INIT(); +#ifdef HAVE_NBGL + nbgl_useCaseSpinner("Signing"); +#endif // HAVE_BAGL USB_power(0); USB_power(1); //ui_idle(); @@ -45,4 +62,9 @@ void handle_swap_sign_transaction(btchip_altcoin_config_t *config) { BLE_power(1, "Nano X"); #endif // HAVE_BLE app_main(); -} \ No newline at end of file +} + +void __attribute__((noreturn)) finalize_exchange_sign_transaction(bool is_success) { + *G_swap_sign_return_value_address = is_success; + os_lib_end(); +} diff --git a/src/handle_swap_sign_transaction.h b/src/handle_swap_sign_transaction.h index 46262601..85f5bd86 100644 --- a/src/handle_swap_sign_transaction.h +++ b/src/handle_swap_sign_transaction.h @@ -8,4 +8,6 @@ bool copy_transaction_parameters(create_transaction_parameters_t* sign_transacti void handle_swap_sign_transaction(btchip_altcoin_config_t *config); -#endif // _HANDLE_SWAP_SIGN_TRANSACTION_H_ \ No newline at end of file +void __attribute__((noreturn)) finalize_exchange_sign_transaction(bool is_success); + +#endif // _HANDLE_SWAP_SIGN_TRANSACTION_H_ diff --git a/src/main.c b/src/main.c index 2436858e..449eea21 100644 --- a/src/main.c +++ b/src/main.c @@ -1225,19 +1225,7 @@ void coin_main(btchip_altcoin_config_t *coin_config) { app_exit(); } -struct libargs_s { - unsigned int id; - unsigned int command; - btchip_altcoin_config_t *coin_config; - union { - check_address_parameters_t *check_address; - create_transaction_parameters_t *create_transaction; - get_printable_amount_parameters_t *get_printable_amount; - }; -}; - -static void library_main_helper(struct libargs_s *args) { - check_api_level(CX_COMPAT_APILEVEL); +static void library_main_helper(libargs_t *args) { PRINTF("Inside a library \n"); switch (args->command) { case CHECK_ADDRESS: @@ -1253,10 +1241,6 @@ static void library_main_helper(struct libargs_s *args) { } break; case GET_PRINTABLE_AMOUNT: - // ensure result is zero if an exception is thrown (compatibility breaking, disabled - // until LL is ready) - // args->get_printable_amount->result = 0; - // args->get_printable_amount->result = handle_get_printable_amount(args->get_printable_amount, args->coin_config); break; default: @@ -1264,7 +1248,7 @@ static void library_main_helper(struct libargs_s *args) { } } -void library_main(struct libargs_s *args) { +void library_main(libargs_t *args) { btchip_altcoin_config_t coin_config; if (args->coin_config == NULL) { init_coin_config(&coin_config); @@ -1333,7 +1317,7 @@ __attribute__((section(".boot"))) int main(int arg0) { coin_main(NULL); return 0; } - struct libargs_s *args = (struct libargs_s *) arg0; + libargs_t *args = (libargs_t *) arg0; if (args->id != 0x100) { app_exit(); return 0;