Skip to content

Commit

Permalink
Swap tests ok with Flex
Browse files Browse the repository at this point in the history
  • Loading branch information
yogh333 committed Feb 24, 2025
1 parent 9d68776 commit ec85600
Show file tree
Hide file tree
Showing 6 changed files with 135 additions and 53 deletions.
5 changes: 4 additions & 1 deletion src/app_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

#include "os.h"
#include "ux.h"
#include "swap.h"

#include "types.h"
#include "globals.h"
Expand All @@ -43,7 +44,9 @@ void app_main() {

io_init();

ui_menu_main();
if (!G_called_from_swap) {
ui_menu_main();
}

// Reset context
explicit_bzero(&G_context, sizeof(G_context));
Expand Down
30 changes: 27 additions & 3 deletions src/handler/sign_tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,16 @@
#include "os.h"
#include "cx.h"
#include "buffer.h"
#include "swap.h"

#include "sign_tx.h"
#include "sw.h"
#include "globals.h"
#include "display.h"
#include "tx_types.h"
#include "deserialize.h"
#include "handle_swap.h"
#include "validate.h"

int handler_sign_tx(buffer_t *cdata, uint8_t chunk, bool more) {
if (chunk == 0) { // first APDU, parse BIP32 path
Expand Down Expand Up @@ -98,10 +101,31 @@ int handler_sign_tx(buffer_t *cdata, uint8_t chunk, bool more) {
return ui_display_transaction();
#endif
} else {
return ui_display_transaction();
// If we are in swap context, do not redisplay the message data
// Instead, ensure they are identical with what was previously displayed
if (G_called_from_swap) {
if (G_swap_response_ready) {
// Safety against trying to make the app sign multiple TX
// This code should never be triggered as the app is supposed to exit after
// sending the signed transaction
PRINTF("Safety against double signing triggered\n");
os_sched_exit(-1);
} else {
// We will quit the app after this transaction, whether it succeeds or fails
PRINTF("Swap response is ready, the app will quit after the next send\n");
// This boolean will make the io_send_sw family instant reply + return to exchange
G_swap_response_ready = true;
}
if (swap_check_validity()) {
PRINTF("Swap response validated\n");
validate_transaction(true);
}
return 0;
} else {
return ui_display_transaction();
}
}
}
}

}
return 0;
}
8 changes: 8 additions & 0 deletions src/sw.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,11 @@
* Status word for signature fail.
*/
#define SW_SIGNATURE_FAIL 0xB008
/**
* Status word for swap failure
*/
#define SW_SWAP_FAIL 0xC000
/**
* Application specific swap error code
*/
#define SWAP_ERROR_CODE 0x00
6 changes: 3 additions & 3 deletions src/swap/handle_check_address.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
#include "types.h"
#include "format.h"
#include "address.h"
#include "tx_types.h"

#include "handle_swap.h"
#include <string.h>

void swap_handle_check_address(check_address_parameters_t *params) {
Expand All @@ -30,9 +30,9 @@ void swap_handle_check_address(check_address_parameters_t *params) {
return;
}
PRINTF("Address to check %s\n", params->address_to_check);
if (strlen(params->address_to_check) != (ADDRESS_LENGTH * 2)) {
if (strlen(params->address_to_check) != (ADDRESS_LEN * 2)) {
PRINTF("Address to check expected length %d, not %d\n",
ADDRESS_LENGTH * 2,
ADDRESS_LEN * 2,
strlen(params->address_to_check));
return;
}
Expand Down
5 changes: 5 additions & 0 deletions src/swap/handle_swap.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#pragma once

#define ADDRESS_LENGTH 20

bool swap_check_validity();
134 changes: 88 additions & 46 deletions src/swap/handle_swap_sign_transaction.c
Original file line number Diff line number Diff line change
@@ -1,43 +1,39 @@
#ifdef HAVE_SWAP
#include "swap.h"
#include "swap_error_code_helpers.h"
#include "os.h"
#include "format.h"

#include "sw.h"
#include "globals.h"
#include "tx_types.h"
#include "handle_swap.h"

#include <stdint.h>

typedef struct swap_validated_s {
bool initialized;
uint8_t amount_length;
uint8_t amount[30];
uint8_t fee_length;
uint8_t fee[30];
char recipient[ADDRESS_LENGTH + 1];
uint64_t amount;
uint64_t fee;
char recipient[ADDRESS_LEN * 2 + 1];
} swap_validated_t;

static swap_validated_t G_swap_validated;

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

bool swap_copy_transaction_parameters(create_transaction_parameters_t* params){
PRINTF("Inside swap_copy_transaction_parameters\n");

// Ensure no extraid
// if (params->destination_address_extra_id == NULL) {
// PRINTF("destination_address_extra_id expected\n");
// return false;
// } else if (params->destination_address_extra_id[0] != '\0') {
// PRINTF("destination_address_extra_id expected empty, not '%s'\n",
// params->destination_address_extra_id);
// return false;
// }
PRINTF("Inside swap_copy_transaction_parameters %s\n", params->destination_address);

if (params->destination_address == NULL) {
PRINTF("Destination address expected\n");
return false;
}

if (strlen(params->destination_address) != (ADDRESS_LEN * 2)) {
PRINTF("Destination address wrong length\n");
return false;
}

if (params->amount == NULL) {
PRINTF("Amount expected\n");
return false;
Expand All @@ -52,50 +48,96 @@ bool swap_copy_transaction_parameters(create_transaction_parameters_t* params){
swap_validated_t swap_validated;
memset(&swap_validated, 0, sizeof(swap_validated));

// Parse config and save decimals and ticker
// If there is no coin_configuration, consider that we are doing a TRX swap
// if (params->coin_configuration == NULL) {
// memcpy(swap_validated.ticker, "TON", sizeof("TON"));
// swap_validated.decimals = EXPONENT_SMALLEST_UNIT;
// } else {
// if (!swap_parse_config(params->coin_configuration,
// params->coin_configuration_length,
// swap_validated.ticker,
// sizeof(swap_validated.ticker),
// &swap_validated.decimals)) {
// PRINTF("Fail to parse coin_configuration\n");
// return false;
// }
// }

// Save recipient
strlcpy(swap_validated.recipient,
params->destination_address,
sizeof(swap_validated.recipient));
if (swap_validated.recipient[sizeof(swap_validated.recipient) - 1] != '\0') {
PRINTF("Address copy error\n");
return false;
// Save recipient as an uppercase string
for (int i = 0; i < ADDRESS_LENGTH * 2; i++) {
if (params->destination_address[i] >= 'a' && params->destination_address[i] <= 'z') {
swap_validated.recipient[i] = params->destination_address[i] - 'a' + 'A';
} else {
swap_validated.recipient[i] = params->destination_address[i];
}
}

// Save amount
if (params->amount_length > sizeof(swap_validated.amount)) {
PRINTF("Amount too big\n");
return false;
} else {
swap_validated.amount_length = params->amount_length;
memcpy(swap_validated.amount, params->amount, params->amount_length);
buffer_t buf = {
.ptr = params->amount,
.size = params->amount_length,
.offset = 0
};
uint8_t byte;
while (buf.offset < buf.size) {
buffer_read_u8(&buf, &byte);
swap_validated.amount = (swap_validated.amount << 8) | byte;
}
}

// Save fee
if (params->fee_amount_length > sizeof(swap_validated.fee)) {
PRINTF("Fee too big\n");
return false;
} else {
buffer_t buf = {
.ptr = params->fee_amount,
.size = params->fee_amount_length,
.offset = 0
};
uint8_t byte;
while (buf.offset < buf.size) {
buffer_read_u8(&buf, &byte);
swap_validated.fee = (swap_validated.fee << 8) | byte;
}
}

swap_validated.initialized = true;

// 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 = &params->result;

// Commit from stack to global data, params becomes tainted but we won't access it anymore
memcpy(&G_swap_validated, &swap_validated, sizeof(swap_validated));

PRINTF("Out of swap_copy_transaction_parameters\n");

return true;
}

bool swap_check_validity() {
PRINTF("Inside swap_check_validity\n");

if (!G_swap_validated.initialized) {
PRINTF("Swap structure is not initialized\n");
send_swap_error_simple(SW_SWAP_FAIL, SWAP_EC_ERROR_GENERIC, SWAP_ERROR_CODE);
// unreachable
os_sched_exit(0);
}

if (G_swap_validated.amount != G_context.tx_info.transaction.value) {
PRINTF("Amount does not match, promised %lld, received %lld\n",
G_swap_validated.amount,
G_context.tx_info.transaction.value);
send_swap_error_simple(SW_SWAP_FAIL, SWAP_EC_ERROR_WRONG_AMOUNT, SWAP_ERROR_CODE);
// unreachable
os_sched_exit(0);
} else {
PRINTF("Amounts match \n");
}

char to[ADDRESS_LEN * 2 + 1] = {0};
format_hex(G_context.tx_info.transaction.to, ADDRESS_LEN, to, sizeof(to));
if (strcmp(G_swap_validated.recipient, to) != 0) {
PRINTF("Destination does not match\n");
PRINTF("Validated: %s\n", G_swap_validated.recipient);
PRINTF("Received: %s \n", to);
send_swap_error_simple(SW_SWAP_FAIL, SWAP_EC_ERROR_WRONG_DESTINATION, SWAP_ERROR_CODE);
// unreachable
os_sched_exit(0);
} else {
PRINTF("Destination is valid\n");
}
return true;
}

#endif // HAVE_SWAP

0 comments on commit ec85600

Please sign in to comment.