diff --git a/src/handle_swap_sign_transaction.c b/src/handle_swap_sign_transaction.c index 16c8b7f..604b8a2 100644 --- a/src/handle_swap_sign_transaction.c +++ b/src/handle_swap_sign_transaction.c @@ -5,9 +5,12 @@ #include "shared_context.h" #include "utils.h" #ifdef HAVE_NBGL -#include "utils.h" +#include "nbgl_use_case.h" #endif // HAVE_NBGL +// 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, chain_config_t* config) { // first copy parameters to stack, and then to global data. @@ -49,11 +52,21 @@ bool copy_transaction_parameters(create_transaction_parameters_t* sign_transacti stack_data.maxFee, sizeof(stack_data.maxFee)); + // Full reset the global variables 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; + // Commit the values read from exchange to the clean global space + memcpy(&strings.common, &stack_data, sizeof(stack_data)); return true; } +void __attribute__((noreturn)) finalize_exchange_sign_transaction(bool is_success) { + *G_swap_sign_return_value_address = is_success; + os_lib_end(); +} + void handle_swap_sign_transaction(chain_config_t* config) { UX_INIT(); #ifdef HAVE_NBGL diff --git a/src/handle_swap_sign_transaction.h b/src/handle_swap_sign_transaction.h index 21b52c3..d34a6d8 100644 --- a/src/handle_swap_sign_transaction.h +++ b/src/handle_swap_sign_transaction.h @@ -1,5 +1,4 @@ -#ifndef _HANDLE_SWAP_SIGN_TRANSACTION_H_ -#define _HANDLE_SWAP_SIGN_TRANSACTION_H_ +#pragma once #include "swap_lib_calls.h" #include "chainConfig.h" @@ -9,4 +8,4 @@ bool copy_transaction_parameters(create_transaction_parameters_t* sign_transacti void handle_swap_sign_transaction(chain_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); diff --git a/src/swap_lib_calls.h b/src/swap_lib_calls.h index 4fd0284..2870347 100644 --- a/src/swap_lib_calls.h +++ b/src/swap_lib_calls.h @@ -1,9 +1,15 @@ -#ifndef _SWAP_LIB_CALLS_H_ -#define _SWAP_LIB_CALLS_H_ +#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 "chainConfig.h" #include "shared_context.h" +#include "stdint.h" #define RUN_APPLICATION 1 @@ -13,19 +19,27 @@ #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 - const unsigned char* const coin_configuration; - const 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 - const unsigned char* const address_parameters; - const unsigned char address_parameters_length; - const char* const address_to_check; - const char* const extra_id_to_check; + // 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 int result; } check_address_parameters_t; @@ -33,37 +47,37 @@ 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 - const unsigned char* const coin_configuration; - const unsigned char coin_configuration_length; - const unsigned char* const amount; - const unsigned char amount_length; - const bool is_fee; + uint8_t *coin_configuration; + uint8_t coin_configuration_length; + uint8_t *amount; + uint8_t amount_length; + bool is_fee; // OUT char printable_amount[MAX_PRINTABLE_AMOUNT_SIZE]; - // int result; } get_printable_amount_parameters_t; typedef struct create_transaction_parameters_s { - const unsigned char* const coin_configuration; - const unsigned char coin_configuration_length; - const unsigned char* const amount; - const unsigned char amount_length; - const unsigned char* const fee_amount; - const unsigned char fee_amount_length; - const char* const destination_address; - const char* const destination_address_extra_id; + // 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; typedef struct libargs_s { unsigned int id; unsigned int command; - chain_config_t* chain_config; + chain_config_t *chain_config; union { - check_address_parameters_t* check_address; - create_transaction_parameters_t* create_transaction; - get_printable_amount_parameters_t* get_printable_amount; - caller_app_t* caller_app; + check_address_parameters_t *check_address; + create_transaction_parameters_t *create_transaction; + get_printable_amount_parameters_t *get_printable_amount; + caller_app_t *caller_app; }; } libargs_t; - -#endif // _SWAP_LIB_CALLS_H_ diff --git a/src_features/signTx/ui_common_signTx.c b/src_features/signTx/ui_common_signTx.c index fec6ca8..e57bb21 100644 --- a/src_features/signTx/ui_common_signTx.c +++ b/src_features/signTx/ui_common_signTx.c @@ -2,12 +2,14 @@ #include "shared_context.h" #include "utils.h" #include "common_ui.h" +#include "handle_swap_sign_transaction.h" unsigned int io_seproxyhal_touch_tx_ok(__attribute__((unused)) const bagl_element_t *e) { uint8_t privateKeyData[INT256_LENGTH]; uint8_t signature[100]; cx_ecfp_private_key_t privateKey; uint32_t tx = 0; + int err; io_seproxyhal_io_heartbeat(); os_perso_derive_node_bip32(CX_CURVE_256K1, tmpCtx.transactionContext.bip32.path, @@ -59,10 +61,19 @@ unsigned int io_seproxyhal_touch_tx_ok(__attribute__((unused)) const bagl_elemen tx = 65; G_io_apdu_buffer[tx++] = 0x90; G_io_apdu_buffer[tx++] = 0x00; + // Send back the response, do not restart the event loop - io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, tx); + err = io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, tx); if (G_called_from_swap) { - os_sched_exit(0); + PRINTF("G_called_from_swap\n"); + + // If we are in swap mode and have validated a TX, we send it and immediately quit + if (err == 0) { + finalize_exchange_sign_transaction(true); + } else { + PRINTF("Unrecoverable\n"); + os_sched_exit(-1); + } } reset_app_context(); // Display back the original UX