From 0cf7f80c29caabde358f41041341b84636d134a5 Mon Sep 17 00:00:00 2001 From: Charles-Edouard de la Vergne Date: Wed, 9 Oct 2024 14:21:44 +0200 Subject: [PATCH] Improve error message returned in swap --- src_features/signTx/logic_signTx.c | 70 ++++++++++++++++++++++-------- 1 file changed, 51 insertions(+), 19 deletions(-) diff --git a/src_features/signTx/logic_signTx.c b/src_features/signTx/logic_signTx.c index 55690e5fc2..13405d486d 100644 --- a/src_features/signTx/logic_signTx.c +++ b/src_features/signTx/logic_signTx.c @@ -11,6 +11,7 @@ #include "crypto_helpers.h" #include "format.h" #include "manage_asset_info.h" +#include "handle_swap_sign_transaction.h" static bool g_use_standard_ui; @@ -322,6 +323,42 @@ static int strcasecmp_workaround(const char *str1, const char *str2) { return 0; } +#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 + +static void send_swap_error(uint8_t error_code, const char *str1, const char *str2) { + uint32_t tx = 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++] = 0x00; + // Set RAPDU error message + if (str1 != NULL) { + PRINTF("Expected %s\n", str1); + memmove(G_io_apdu_buffer + tx, str1, strlen((const char *) str1)); + tx += strlen((const char *) str1); + } + if (str2 != NULL) { + PRINTF("Received %s\n", str2); + G_io_apdu_buffer[tx++] = '#'; + memmove(G_io_apdu_buffer + tx, str2, strlen((const char *) str2)); + tx += strlen((const char *) str2); + } + // Set RAPDU status word + 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(void) { char displayBuffer[50]; uint8_t decimals = WEI_TO_ETHER; @@ -452,19 +489,18 @@ __attribute__((noinline)) static uint16_t finalize_parsing_helper(void) { G_swap_response_ready = true; } - // User has just validated a swap but ETH received apdus about a non standard plugin / contract - if (G_called_from_swap && !g_use_standard_ui) { - PRINTF("APDU_RESPONSE_MODE_CHECK_FAILED, G_called_from_swap\n"); - return APDU_RESPONSE_MODE_CHECK_FAILED; - } - - // Specific calldata check when in swap mode if (G_called_from_swap) { + // 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_GENERIC, "No Standard UI", NULL); + return 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) { - PRINTF("Error: G_swap_mode %d refused\n", G_swap_mode); - return APDU_RESPONSE_MODE_CHECK_FAILED; + send_swap_error(ERROR_CROSSCHAIN_WRONG_MODE, "Wrong swap mode", NULL); + return APDU_NO_RESPONSE; } } @@ -490,8 +526,8 @@ __attribute__((noinline)) static uint16_t finalize_parsing_helper(void) { 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) { - PRINTF("APDU_RESPONSE_MODE_CHECK_FAILED, address check failed\n"); - return APDU_RESPONSE_MODE_CHECK_FAILED; + send_swap_error(ERROR_WRONG_DESTINATION, strings.common.toAddress, displayBuffer); + return APDU_NO_RESPONSE; } } else { strlcpy(strings.common.toAddress, displayBuffer, sizeof(strings.common.toAddress)); @@ -513,10 +549,8 @@ __attribute__((noinline)) static uint16_t finalize_parsing_helper(void) { 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) { - PRINTF("APDU_RESPONSE_MODE_CHECK_FAILED, amount check failed\n"); - PRINTF("Expected %s\n", strings.common.fullAmount); - PRINTF("Received %s\n", displayBuffer); - return APDU_RESPONSE_MODE_CHECK_FAILED; + send_swap_error(ERROR_WRONG_AMOUNT, strings.common.fullAmount, displayBuffer); + return APDU_NO_RESPONSE; } } else { strlcpy(strings.common.fullAmount, displayBuffer, sizeof(strings.common.fullAmount)); @@ -535,10 +569,8 @@ __attribute__((noinline)) static uint16_t finalize_parsing_helper(void) { 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) { - PRINTF("APDU_RESPONSE_MODE_CHECK_FAILED, fees check failed\n"); - PRINTF("Expected %s\n", strings.common.maxFee); - PRINTF("Received %s\n", displayBuffer); - return APDU_RESPONSE_MODE_CHECK_FAILED; + send_swap_error(ERROR_WRONG_FEES, strings.common.maxFee, displayBuffer); + return APDU_NO_RESPONSE; } } else { strlcpy(strings.common.maxFee, displayBuffer, sizeof(strings.common.maxFee));