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

Fbe/swap error helpers #730

Merged
merged 3 commits into from
Feb 20, 2025
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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ __version__.py
# Fuzzing
tests/fuzzing/corpus/
tests/fuzzing/out/
tests/fuzzing/CMakeFiles/
default.profraw
default.profdata
fuzz-*.log
Expand Down
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ HAVE_APPLICATION_FLAG_LIBRARY = 1
# Application communication interfaces #
########################################
ENABLE_BLUETOOTH = 1
ENABLE_SWAP = 1
#ENABLE_NFC = 1

########################################
Expand Down
15 changes: 3 additions & 12 deletions src/handle_swap_sign_transaction.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,6 @@
#include "nbgl_use_case.h"
#endif // HAVE_NBGL

// Remember if we have been started by the Exchange application or not
bool G_called_from_swap;

// Set this boolean when a transaction is signed in Swap mode. Safety against double sign
bool G_swap_response_ready;

// Save the BSS address where we will write the return value when finished
static uint8_t* G_swap_sign_return_value_address;

// Standard or crosschain swap type
swap_mode_t G_swap_mode;

Expand Down Expand Up @@ -144,16 +135,16 @@ bool copy_transaction_parameters(create_transaction_parameters_t* sign_transacti
// 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;
G_swap_signing_return_value_address = &sign_transaction_params->result;
// Commit the values read from exchange to the clean global space
G_swap_mode = swap_mode;
memcpy(G_swap_crosschain_hash, swap_crosschain_hash, sizeof(G_swap_crosschain_hash));
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;
void __attribute__((noreturn)) swap_finalize_exchange_sign_transaction(bool is_success) {
*G_swap_signing_return_value_address = is_success;
os_lib_end();
}

Expand Down
2 changes: 1 addition & 1 deletion src/handle_swap_sign_transaction.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ bool copy_transaction_parameters(create_transaction_parameters_t* sign_transacti

void __attribute__((noreturn)) handle_swap_sign_transaction(const chain_config_t* config);

void __attribute__((noreturn)) finalize_exchange_sign_transaction(bool is_success);
void __attribute__((noreturn)) swap_finalize_exchange_sign_transaction(bool is_success);
3 changes: 2 additions & 1 deletion src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "handle_swap_sign_transaction.h"
#include "handle_get_printable_amount.h"
#include "handle_check_address.h"
#include "swap_entrypoints.h"
#include "commands_712.h"
#include "challenge.h"
#include "trusted_name.h"
Expand Down Expand Up @@ -341,7 +342,7 @@ void app_main(void) {
if (io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, tx) == 0) {
// In case of success, the apdu is sent immediately and eth exits
// Reaching this code means we encountered an error
finalize_exchange_sign_transaction(false);
swap_finalize_exchange_sign_transaction(false);
} else {
PRINTF("Unrecoverable\n");
app_exit();
Expand Down
4 changes: 2 additions & 2 deletions src/shared_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
#include "tx_content.h"
#include "chainConfig.h"
#include "asset_info.h"
#include "swap_utils.h"

#ifdef HAVE_NBGL
#include "nbgl_types.h"
#endif
Expand Down Expand Up @@ -172,8 +174,6 @@ typedef enum swap_mode_e {
SWAP_MODE_ERROR,
} swap_mode_t;

extern bool G_called_from_swap;
extern bool G_swap_response_ready;
extern swap_mode_t G_swap_mode;
extern uint8_t G_swap_crosschain_hash[CX_SHA256_SIZE];

Expand Down
5 changes: 4 additions & 1 deletion src_features/signTx/cmd_signTx.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "feature_signTx.h"
#include "eth_plugin_interface.h"
#include "apdu_constants.h"
#include "swap_error_code_helpers.h"
#ifdef HAVE_GENERIC_TX_PARSER
#include "gtp_tx_info.h"
#endif
Expand Down Expand Up @@ -84,7 +85,9 @@ uint16_t handle_parsing_status(parserStatus_e status) {
// We have encountered an error while trying to sign a SWAP type transaction
// Return dedicated error code and flag an early exit back to Exchange
G_swap_response_ready = true;
send_swap_error(ERROR_GENERIC, APP_CODE_CALLDATA_ISSUE, NULL, NULL);
send_swap_error_simple(APDU_RESPONSE_MODE_CHECK_FAILED,
SWAP_EC_ERROR_GENERIC,
APP_CODE_CALLDATA_ISSUE);
// unreachable
os_sched_exit(0);
}
Expand Down
11 changes: 0 additions & 11 deletions src_features/signTx/feature_signTx.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,6 @@
#include <stdbool.h>
#include "ethUstream.h"

// Error codes for swap, to be moved in SDK?
#define ERROR_WRONG_AMOUNT 0x01
#define ERROR_WRONG_DESTINATION 0x02
#define ERROR_WRONG_FEES 0x03
#define ERROR_WRONG_METHOD 0x04
#define ERROR_CROSSCHAIN_WRONG_MODE 0x05
#define ERROR_CROSSCHAIN_WRONG_METHOD 0x06
#define ERROR_GENERIC 0xFF

// App codes for detail.
typedef enum {
APP_CODE_DEFAULT = 0x00,
Expand All @@ -33,8 +24,6 @@ uint16_t finalize_parsing(const txContext_t *context);
void ux_approve_tx(bool fromPlugin);
void start_signature_flow(void);

void send_swap_error(uint8_t error_code, app_code_t app_code, const char *str1, const char *str2);

uint16_t handle_parsing_status(parserStatus_e status);

uint16_t get_public_key(uint8_t *out, uint8_t outLength);
Expand Down
92 changes: 28 additions & 64 deletions src_features/signTx/logic_signTx.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "handle_swap_sign_transaction.h"
#include "os_math.h"
#include "calldata.h"
#include "swap_error_code_helpers.h"

static bool g_use_standard_ui;

Expand Down Expand Up @@ -338,56 +339,6 @@ static int strcasecmp_workaround(const char *str1, const char *str2) {
return 0;
}

__attribute__((noreturn)) void send_swap_error(uint8_t error_code,
app_code_t app_code,
const char *str1,
const char *str2) {
uint32_t tx = 0;
size_t len = 0;
PRINTF("APDU_RESPONSE_MODE_CHECK_FAILED: 0x%x\n", error_code);
// Set RAPDU error codes
G_io_apdu_buffer[tx++] = error_code;
G_io_apdu_buffer[tx++] = app_code;
// Set RAPDU error message
if (str1 != NULL) {
PRINTF("Expected %s\n", str1);
// If the string is too long, truncate it
len = MIN(strlen((const char *) str1), sizeof(G_io_apdu_buffer) - tx - 2);
memmove(G_io_apdu_buffer + tx, str1, len);
tx += len;
if (len < strlen((const char *) str1)) {
PRINTF("Truncated %s to %d bytes\n", str1, len);
G_io_apdu_buffer[tx - 1] = '*';
}
}
if (str2 != NULL) {
PRINTF("Received %s\n", str2);
// Do we have enough space to add a separator?
if ((tx + 1 + 2) < sizeof(G_io_apdu_buffer)) {
G_io_apdu_buffer[tx++] = '#';
}
// Do we have enough space to add at least one character?
if ((tx + 1 + 2) < sizeof(G_io_apdu_buffer)) {
// If the string is too long, truncate it
len = MIN(strlen((const char *) str2), sizeof(G_io_apdu_buffer) - tx - 2);
memmove(G_io_apdu_buffer + tx, str2, len);
tx += len;
if (len < strlen((const char *) str2)) {
PRINTF("Truncated %s to %d bytes\n", str2, len);
G_io_apdu_buffer[tx - 1] = '*';
}
}
}
// Set RAPDU status word, with previous check we are sure there is at least 2 bytes left
U2BE_ENCODE(G_io_apdu_buffer, tx, APDU_RESPONSE_MODE_CHECK_FAILED);
tx += 2;
// Send RAPDU
io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, tx);
// In case of success, the apdu is sent immediately and eth exits
// Reaching this code means we encountered an error
finalize_exchange_sign_transaction(false);
}

__attribute__((noinline)) static uint16_t finalize_parsing_helper(const txContext_t *context) {
char displayBuffer[50];
uint8_t decimals = WEI_TO_ETHER;
Expand Down Expand Up @@ -523,14 +474,18 @@ __attribute__((noinline)) static uint16_t finalize_parsing_helper(const txContex
// User has just validated a swap but ETH received apdus about a non standard plugin /
// contract
if (!g_use_standard_ui) {
send_swap_error(ERROR_WRONG_METHOD, APP_CODE_NO_STANDARD_UI, NULL, NULL);
send_swap_error_simple(APDU_RESPONSE_MODE_CHECK_FAILED,
SWAP_EC_ERROR_WRONG_METHOD,
APP_CODE_NO_STANDARD_UI);
// unreachable
os_sched_exit(0);
}
// Two success cases: we are in standard mode and no calldata was received
// We are in crosschain mode and the correct calldata has been received
if (G_swap_mode != SWAP_MODE_STANDARD && G_swap_mode != SWAP_MODE_CROSSCHAIN_SUCCESS) {
send_swap_error(ERROR_CROSSCHAIN_WRONG_MODE, APP_CODE_DEFAULT, NULL, NULL);
send_swap_error_simple(APDU_RESPONSE_MODE_CHECK_FAILED,
SWAP_EC_ERROR_CROSSCHAIN_WRONG_MODE,
APP_CODE_DEFAULT);
// unreachable
os_sched_exit(0);
}
Expand Down Expand Up @@ -565,10 +520,13 @@ __attribute__((noinline)) static uint16_t finalize_parsing_helper(const txContex
if (G_called_from_swap) {
// Ensure the values are the same that the ones that have been previously validated
if (strcasecmp_workaround(strings.common.toAddress, displayBuffer) != 0) {
send_swap_error(ERROR_WRONG_DESTINATION,
APP_CODE_DEFAULT,
strings.common.toAddress,
displayBuffer);
PRINTF("Error comparing destination addresses\n");
send_swap_error_with_string(APDU_RESPONSE_MODE_CHECK_FAILED,
SWAP_EC_ERROR_WRONG_DESTINATION,
APP_CODE_DEFAULT,
"%s != %s",
strings.common.toAddress,
displayBuffer);
// unreachable
os_sched_exit(0);
}
Expand All @@ -592,10 +550,13 @@ __attribute__((noinline)) static uint16_t finalize_parsing_helper(const txContex
if (G_called_from_swap) {
// Ensure the values are the same that the ones that have been previously validated
if (strcmp(strings.common.fullAmount, displayBuffer) != 0) {
send_swap_error(ERROR_WRONG_AMOUNT,
APP_CODE_DEFAULT,
strings.common.fullAmount,
displayBuffer);
PRINTF("Error comparing amounts\n");
send_swap_error_with_string(APDU_RESPONSE_MODE_CHECK_FAILED,
SWAP_EC_ERROR_WRONG_AMOUNT,
APP_CODE_DEFAULT,
"%s != %s",
strings.common.fullAmount,
displayBuffer);
// unreachable
os_sched_exit(0);
}
Expand All @@ -616,10 +577,13 @@ __attribute__((noinline)) static uint16_t finalize_parsing_helper(const txContex
if (G_called_from_swap) {
// Ensure the values are the same that the ones that have been previously validated
if (strcmp(strings.common.maxFee, displayBuffer) != 0) {
send_swap_error(ERROR_WRONG_FEES,
APP_CODE_DEFAULT,
strings.common.maxFee,
displayBuffer);
PRINTF("Error comparing fees\n");
send_swap_error_with_string(APDU_RESPONSE_MODE_CHECK_FAILED,
SWAP_EC_ERROR_WRONG_FEES,
APP_CODE_DEFAULT,
"%s != %s",
strings.common.maxFee,
displayBuffer);
// unreachable
os_sched_exit(0);
}
Expand Down
3 changes: 2 additions & 1 deletion src_features/signTx/ui_common_signTx.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include "swap_entrypoints.h"
#include "crypto_helpers.h"
#include "os_io_seproxyhal.h"
#include "shared_context.h"
Expand Down Expand Up @@ -58,7 +59,7 @@ uint32_t io_seproxyhal_touch_tx_ok(void) {

// 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);
swap_finalize_exchange_sign_transaction(true);
} else {
PRINTF("Unrecoverable\n");
app_exit();
Expand Down
14 changes: 14 additions & 0 deletions tests/fuzzing/src/mock.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "cx_errors.h"
#include "cx_sha256.h"
#include "cx_sha3.h"
#include "buffer.h"

/** MemorySanitizer does not wrap explicit_bzero https://github.com/google/sanitizers/issues/1507
* which results in false positives when running MemorySanitizer.
Expand Down Expand Up @@ -167,3 +168,16 @@ size_t cx_hash_sha256(const uint8_t *in, size_t in_len, uint8_t *out, size_t out
if (in_len > 0 && out_len > 0) out[out_len - 1] = in[in_len - 1];
return CX_OK;
}

typedef unsigned char bolos_task_status_t;

void os_sched_exit(__attribute__((unused)) bolos_task_status_t exit_code) {
return;
}

int io_send_response_buffers(const buffer_t *rdatalist, size_t count, uint16_t sw) {
UNUSED(rdatalist);
UNUSED(count);
UNUSED(sw);
return 0;
}
Loading