Skip to content

Commit

Permalink
Merge branch 'LedgerHQ:develop' into 7702-phase1
Browse files Browse the repository at this point in the history
  • Loading branch information
btchip authored Feb 23, 2025
2 parents a10e36f + c6bea2e commit 10585bf
Show file tree
Hide file tree
Showing 17 changed files with 91 additions and 131 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build_and_functional_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,5 @@ jobs:
download_app_binaries_artifact: "ragger_elfs"
additional_app_binaries_artifact: "clone_elfs"
additional_app_binaries_artifact_dir: ./tests/ragger/.test_dependencies/clone/build/
test_options: "--with_lib_mode"
test_options: "--setup lib_mode"
regenerate_snapshots: ${{ inputs.golden_run == 'Open a PR' }}
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
4 changes: 4 additions & 0 deletions pytest.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[pytest]
testpaths = tests/ragger
pythonpath = tests/ragger
addopts = tests/ragger
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 @@ -346,7 +347,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 @@ -181,8 +183,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
4 changes: 2 additions & 2 deletions src/tlv.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "tlv.h"
#include "os_print.h" // PRINTF
#include "read.h" // read_u32_be
#include "utils.h" // buf_shrink_expand

typedef enum { TLV_STATE_TAG, TLV_STATE_LENGTH, TLV_STATE_VALUE } e_tlv_state;

Expand Down Expand Up @@ -30,8 +31,7 @@ static bool parse_der_value(const uint8_t *payload,
PRINTF("Unexpectedly long DER-encoded value (%u bytes)\n", byte_length);
return false;
}
memset(buf, 0, (sizeof(buf) - byte_length));
memcpy(buf + (sizeof(buf) - byte_length), &payload[*offset], byte_length);
buf_shrink_expand(&payload[*offset], byte_length, buf, sizeof(buf));
*value = read_u32_be(buf, 0);
*offset += byte_length;
} else { // short form
Expand Down
27 changes: 17 additions & 10 deletions src/tlv_apdu.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,19 @@

#ifdef HAVE_DYN_MEM_ALLOC
static uint8_t *g_tlv_payload = NULL;
static uint16_t g_tlv_size;
static uint16_t g_tlv_pos;
static bool g_dyn;
static uint16_t g_tlv_size = 0;
static uint16_t g_tlv_pos = 0;
static bool g_dyn = false;

static void reset_state(void) {
if (g_tlv_payload != NULL) {
mem_dealloc(g_tlv_size);
}
g_tlv_payload = NULL;
g_tlv_size = 0;
g_tlv_pos = 0;
g_dyn = false;
}
#endif

bool tlv_from_apdu(bool first_chunk,
Expand All @@ -36,8 +46,7 @@ bool tlv_from_apdu(bool first_chunk,
#ifdef HAVE_DYN_MEM_ALLOC
if (g_tlv_payload != NULL) {
PRINTF("Error: remnants from an incomplete TLV payload!\n");
mem_dealloc(g_tlv_size);
g_tlv_payload = NULL;
reset_state();
return false;
}

Expand All @@ -55,17 +64,15 @@ bool tlv_from_apdu(bool first_chunk,
}
#ifdef HAVE_DYN_MEM_ALLOC
if (g_dyn && (g_tlv_payload == NULL)) {
reset_state();
return false;
}
#endif
chunk_length = lc - offset;
if ((g_tlv_pos + chunk_length) > g_tlv_size) {
PRINTF("TLV payload bigger than expected!\n");
#ifdef HAVE_DYN_MEM_ALLOC
if (g_dyn) {
mem_dealloc(g_tlv_size);
g_tlv_payload = NULL;
}
reset_state();
#endif
return false;
}
Expand All @@ -81,7 +88,7 @@ bool tlv_from_apdu(bool first_chunk,
if (g_tlv_pos == g_tlv_size) {
#ifdef HAVE_DYN_MEM_ALLOC
ret = (*handler)(g_dyn ? g_tlv_payload : &payload[offset], g_tlv_size, g_dyn);
g_tlv_payload = NULL;
reset_state();
#else
ret = (*handler)(&payload[offset], g_tlv_size, false);
#endif
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 @@ -85,7 +86,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 @@ -339,56 +340,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 @@ -524,14 +475,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 @@ -566,10 +521,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 @@ -593,10 +551,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 @@ -617,10 +578,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
Loading

0 comments on commit 10585bf

Please sign in to comment.