Skip to content

Commit

Permalink
Merge pull request #201 from Zondax/fix_swap
Browse files Browse the repository at this point in the history
fix swap
  • Loading branch information
ftheirs authored Oct 13, 2023
2 parents d98f2eb + 3aeeba4 commit 6fa4193
Show file tree
Hide file tree
Showing 27 changed files with 504 additions and 432 deletions.
2 changes: 1 addition & 1 deletion app/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ endif

APP_LOAD_PARAMS = --curve ed25519 $(COMMON_LOAD_PARAMS) --path $(APPPATH)

NANOS_STACK_SIZE := 3136
NANOS_STACK_SIZE := 3128

include $(CURDIR)/../deps/ledger-zxlib/makefiles/Makefile.devices

Expand Down
2 changes: 1 addition & 1 deletion app/Makefile.version
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ APPVERSION_M=24
# This is the `spec_version` field of `Runtime`
APPVERSION_N=9430
# This is the patch version of this release
APPVERSION_P=2
APPVERSION_P=3
14 changes: 11 additions & 3 deletions app/src/apdu_handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@

static bool tx_initialized = false;

void extractHDPath(uint32_t rx, uint32_t offset) {
static void extractHDPath(uint32_t rx, uint32_t offset) {
tx_initialized = false;

if ((rx - offset) < sizeof(uint32_t) * HDPATH_LEN_DEFAULT) {
Expand Down Expand Up @@ -175,7 +175,6 @@ __Z_INLINE void handleSign(volatile uint32_t *flags, volatile uint32_t *tx, uint
switch (key_type) {
case key_ed25519: {
if (G_swap_state.called_from_swap) {
G_swap_state.should_exit = 1;
app_sign_ed25519();
} else {
view_review_init(tx_getItem, tx_getNumItems, app_sign_ed25519);
Expand All @@ -191,7 +190,6 @@ __Z_INLINE void handleSign(volatile uint32_t *flags, volatile uint32_t *tx, uint
THROW(APDU_CODE_DATA_INVALID);
}
if (G_swap_state.called_from_swap) {
G_swap_state.should_exit = 1;
app_return_sr25519();
} else {
view_review_init(tx_getItem, tx_getNumItems, app_return_sr25519);
Expand Down Expand Up @@ -329,6 +327,16 @@ void handleApdu(volatile uint32_t *flags, volatile uint32_t *tx, uint32_t rx) {
}
FINALLY
{
#ifdef HAVE_SWAP
if (G_swap_state.called_from_swap && G_swap_state.should_exit) {
// Swap checking failed, send reply now and exit, don't wait next cycle
if (sw != 0) {
io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, *tx);
}
// Go back to exchange and report our status
finalize_exchange_sign_transaction(sw == 0);
}
#endif
}
}
END_TRY;
Expand Down
94 changes: 73 additions & 21 deletions app/src/common/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,15 @@
#include "app_main.h"
#include "view.h"
#include "swap.h"
#include "lib_standard_app/swap_lib_calls.h"

#include <os_io_seproxyhal.h>

#ifdef HAVE_NBGL
#include "nbgl_use_case.h"
#endif

// Helper to quit the application in a limited THROW context
static void app_exit(void) {
BEGIN_TRY_L(exit) {
TRY_L(exit) {
Expand All @@ -31,38 +37,84 @@ static void app_exit(void) {
END_TRY_L(exit);
}

// Helper to handle the different library commands
static void library_main(libargs_t *args) {
BEGIN_TRY {
TRY {
switch (args->command) {
case SIGN_TRANSACTION: {
// Backup up transaction parameters and wipe BSS to avoid collusion with
// app-exchange BSS data.
bool success = copy_transaction_parameters(args->create_transaction);
if (success) {
// BSS was wiped, we can now init these globals
G_swap_state.called_from_swap = true;
G_swap_state.should_exit = false;

#ifdef HAVE_NBGL
// On Stax, display a modal
nbgl_useCaseSpinner("Signing");
#endif // HAVE_NBGL

view_init();
app_init();
app_main();
}
break;
}
case CHECK_ADDRESS:
handle_check_address(args->check_address);
break;
case GET_PRINTABLE_AMOUNT:
handle_get_printable_amount(args->get_printable_amount);
break;
default:
break;
}
}
CATCH_OTHER(e)
{
}
FINALLY
{
os_lib_end();
}
}
END_TRY;
}

__attribute__((section(".boot"))) int
main(int arg0) {
// exit critical section
__asm volatile("cpsie i");

view_init();
os_boot();

if (arg0) {
libargs_s *args = (libargs_s *) arg0;
if (arg0 != 0) {
// The app has been started in library mode
libargs_t *args = (libargs_t *) arg0;
if (args->id != 0x100) {
// Invalid mode ID
app_exit();
return 0;
}

swap_handle_command(args);
if (!G_swap_state.called_from_swap) {
os_lib_end();
} else {
library_main(args);
}
}

BEGIN_TRY
{
TRY
} else {
// The app has been launched from the dashboard
G_swap_state.called_from_swap = false;
BEGIN_TRY
{
app_init();
app_main();
TRY
{
view_init();
app_init();
app_main();
}
CATCH_OTHER(e)
{}
FINALLY
{}
}
CATCH_OTHER(e)
{}
FINALLY
{}
END_TRY;
}
END_TRY;
}
9 changes: 9 additions & 0 deletions app/src/common/tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,15 @@ const char *tx_parse() {

// If in swap mode, compare swap tx parameters with stored info.
if (G_swap_state.called_from_swap) {
if (G_swap_state.should_exit == 1) {
// Safety against trying to make the app sign multiple TX
// This panic quit is a failsafe that should never trigger, as the app is supposed to
// exit after the first send when started in swap mode
os_sched_exit(-1);
} else {
// We will quit the app after this transaction, whether it succeeds or fails
G_swap_state.should_exit = 1;
}
err = check_swap_conditions(&ctx_parsed_tx);
CHECK_APP_CANARY()
if (err != parser_ok) {
Expand Down
30 changes: 26 additions & 4 deletions app/src/crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "base58.h"
#include "coin.h"
#include "cx.h"
#include "swap.h"
#include "zxmacros.h"
#include "ristretto.h"
#include "crypto_helper.h"
Expand All @@ -28,7 +29,7 @@

uint32_t hdPath[HDPATH_LEN_DEFAULT];

static zxerr_t crypto_extractPublicKey(key_kind_e addressKind, uint8_t *pubKey, uint16_t pubKeyLen) {
static zxerr_t crypto_extractPublicKey(key_kind_e addressKind, uint8_t *pubKey, uint16_t pubKeyLen, uint32_t *hdPath_to_use) {
if (pubKey == NULL || pubKeyLen < PK_LEN_25519) {
return zxerr_invalid_crypto_settings;
}
Expand All @@ -41,7 +42,7 @@ static zxerr_t crypto_extractPublicKey(key_kind_e addressKind, uint8_t *pubKey,
// Generate keys
CATCH_CXERROR(os_derive_bip32_with_seed_no_throw(HDW_NORMAL,
CX_CURVE_Ed25519,
hdPath,
hdPath_to_use,
HDPATH_LEN_DEFAULT,
privateKeyData,
NULL,
Expand Down Expand Up @@ -215,12 +216,13 @@ zxerr_t crypto_sign_sr25519(const uint8_t *message, size_t messageLen) {
}
#endif

zxerr_t crypto_fillAddress(key_kind_e addressKind, uint8_t *buffer, uint16_t bufferLen, uint16_t *addrResponseLen) {
// Helper function to fill a crypto address using a given hdPath
static zxerr_t crypto_fillAddress_helper(key_kind_e addressKind, uint8_t *buffer, uint16_t bufferLen, uint16_t *addrResponseLen, uint32_t *hdPath_to_use) {
if (bufferLen < PK_LEN_25519 + SS58_ADDRESS_MAX_LEN) {
return zxerr_unknown;
}
MEMZERO(buffer, bufferLen);
CHECK_ZXERR(crypto_extractPublicKey(addressKind, buffer, bufferLen))
CHECK_ZXERR(crypto_extractPublicKey(addressKind, buffer, bufferLen, hdPath_to_use))

size_t outLen = crypto_SS58EncodePubkey(buffer + PK_LEN_25519,
bufferLen - PK_LEN_25519,
Expand All @@ -233,3 +235,23 @@ zxerr_t crypto_fillAddress(key_kind_e addressKind, uint8_t *buffer, uint16_t buf
*addrResponseLen = PK_LEN_25519 + outLen;
return zxerr_ok;
}

// fill a crypto address using the global hdpath
zxerr_t crypto_fillAddress(key_kind_e addressKind, uint8_t *buffer, uint16_t bufferLen, uint16_t *addrResponseLen) {
return crypto_fillAddress_helper(addressKind, buffer, bufferLen, addrResponseLen, hdPath);
}

// fill a crypto address using a locally computed hdpath
zxerr_t crypto_fillAddress_standalone(uint8_t* params, uint8_t paramsSize, key_kind_e addressKind, uint8_t *buffer, uint16_t bufferLen, uint16_t *addrResponseLen) {
uint32_t local_hdPath[HDPATH_LEN_DEFAULT];

if (paramsSize != (sizeof(uint32_t) * HDPATH_LEN_DEFAULT)) {
return zxerr_invalid_crypto_settings;
}

for (uint32_t i = 0; i < HDPATH_LEN_DEFAULT; i++) {
CHECK_ZXERR(readU32BE(params + (i * 4), &local_hdPath[i]))
}

return crypto_fillAddress_helper(addressKind, buffer, bufferLen, addrResponseLen, local_hdPath);
}
2 changes: 2 additions & 0 deletions app/src/crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ uint8_t crypto_SS58EncodePubkey(uint8_t *buffer, uint16_t buffer_len,

zxerr_t crypto_fillAddress(key_kind_e addressKind, uint8_t *buffer, uint16_t bufferLen, uint16_t *addrResponseLen);

zxerr_t crypto_fillAddress_standalone(uint8_t* params, uint8_t paramsSize, key_kind_e addressKind, uint8_t *buffer, uint16_t bufferLen, uint16_t *addrResponseLen);

zxerr_t crypto_sign_ed25519(uint8_t *signature, uint16_t signatureMaxlen, const uint8_t *message, uint16_t messageLen);

#ifdef SUPPORT_SR25519
Expand Down
Loading

0 comments on commit 6fa4193

Please sign in to comment.