Skip to content

Commit

Permalink
Merge pull request #24 from Zondax/dev
Browse files Browse the repository at this point in the history
New release
  • Loading branch information
chcmedeiros authored Nov 29, 2024
2 parents 492e344 + c347914 commit a11b5f1
Show file tree
Hide file tree
Showing 568 changed files with 1,275 additions and 585 deletions.
12 changes: 7 additions & 5 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -138,11 +138,12 @@ file(GLOB_RECURSE LIB_SRC
${CMAKE_CURRENT_SOURCE_DIR}/app/src/parser_print_common.c
${CMAKE_CURRENT_SOURCE_DIR}/app/src/tx_cchain.c
${CMAKE_CURRENT_SOURCE_DIR}/app/src/tx_pchain.c
${CMAKE_CURRENT_SOURCE_DIR}/app/src/rlp.c
${CMAKE_CURRENT_SOURCE_DIR}/app/src/uint256.c
${CMAKE_CURRENT_SOURCE_DIR}/app/src/eth_erc20.c
${CMAKE_CURRENT_SOURCE_DIR}/app/src/parser_impl_eth.c
${CMAKE_CURRENT_SOURCE_DIR}/app/src/eth_utils.c
${CMAKE_CURRENT_SOURCE_DIR}/app/src/evm/rlp.c
${CMAKE_CURRENT_SOURCE_DIR}/app/src/evm/uint256.c
${CMAKE_CURRENT_SOURCE_DIR}/app/src/evm/eth_erc20.c
${CMAKE_CURRENT_SOURCE_DIR}/app/src/evm/parser_impl_eth.c
${CMAKE_CURRENT_SOURCE_DIR}/app/src/evm/parser_eth.c
${CMAKE_CURRENT_SOURCE_DIR}/app/src/evm/eth_utils.c
)

add_library(app_lib STATIC ${LIB_SRC})
Expand All @@ -152,6 +153,7 @@ target_include_directories(app_lib PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/deps/ledger-zxlib/app/common
${CMAKE_CURRENT_SOURCE_DIR}/app/src
${CMAKE_CURRENT_SOURCE_DIR}/app/src/lib
${CMAKE_CURRENT_SOURCE_DIR}/app/src/evm
${CMAKE_CURRENT_SOURCE_DIR}/app/src/common
${CMAKE_CURRENT_SOURCE_DIR}/deps/picohash/
${CMAKE_CURRENT_SOURCE_DIR}/deps/ripemd160
Expand Down
2 changes: 1 addition & 1 deletion app/Makefile.version
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This is the major version
APPVERSION_M=2
# This is the minor version
APPVERSION_N=3
APPVERSION_N=4
# This is the patch version
APPVERSION_P=0
192 changes: 11 additions & 181 deletions app/src/apdu_handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@

#include "actions.h"
#include "addr.h"
#include "apdu_handler_eth.h"
#include "app_main.h"
#include "app_mode.h"
#include "coin.h"
#include "coin_eth.h"
#include "crypto.h"
#include "crypto_helper.h"
#include "eth_addr.h"
Expand Down Expand Up @@ -70,36 +72,6 @@ uint8_t extractHRP(uint32_t rx, uint32_t offset) {
return bech32_hrp_len;
}

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

uint32_t path_len = *(G_io_apdu_buffer + offset);

if (path_len > MAX_BIP32_PATH || path_len < 1) THROW(APDU_CODE_WRONG_LENGTH);

if ((rx - offset - 1) < sizeof(uint32_t) * path_len) {
THROW(APDU_CODE_WRONG_LENGTH);
}

// first byte at OFFSET_DATA is the path len, so we skip this
uint8_t *path_data = G_io_apdu_buffer + offset + 1;

// hw-app-eth serializes path as BE numbers
for (uint8_t i = 0; i < path_len; i++) {
hdPath[i] = U4BE(path_data, 0);
path_data += sizeof(uint32_t);
}

const bool mainnet = hdPath[0] == HDPATH_ETH_0_DEFAULT && hdPath[1] == HDPATH_ETH_1_DEFAULT;

if (!mainnet) {
THROW(APDU_CODE_DATA_INVALID);
}

// set the hdPath len
hdPath_len = path_len;
}

__Z_INLINE bool process_chunk(__Z_UNUSED volatile uint32_t *tx, uint32_t rx) {
const uint8_t payloadType = G_io_apdu_buffer[OFFSET_PAYLOAD_TYPE];
if (rx < OFFSET_DATA) {
Expand All @@ -109,7 +81,7 @@ __Z_INLINE bool process_chunk(__Z_UNUSED volatile uint32_t *tx, uint32_t rx) {
uint32_t added;
switch (payloadType) {
case P1_INIT:
tx_initialize_flr();
tx_initialize();
tx_reset();
extractHDPath(rx, OFFSET_DATA);
tx_initialized = true;
Expand Down Expand Up @@ -141,103 +113,6 @@ __Z_INLINE bool process_chunk(__Z_UNUSED volatile uint32_t *tx, uint32_t rx) {
THROW(APDU_CODE_INVALIDP1P2);
}

__Z_INLINE bool process_chunk_eth(__Z_UNUSED volatile uint32_t *tx, uint32_t rx) {
const uint8_t payloadType = G_io_apdu_buffer[OFFSET_PAYLOAD_TYPE];

if (G_io_apdu_buffer[OFFSET_P2] != 0) {
THROW(APDU_CODE_INVALIDP1P2);
}

if (rx < OFFSET_DATA) {
THROW(APDU_CODE_WRONG_LENGTH);
}

uint64_t read = 0;
uint64_t to_read = 0;
uint64_t max_len = 0;

uint8_t *data = &(G_io_apdu_buffer[OFFSET_DATA]);
uint32_t len = rx - OFFSET_DATA;

uint64_t added;
switch (payloadType) {
case P1_ETH_FIRST:
tx_initialize_eth();
tx_reset();
extract_eth_path(rx, OFFSET_DATA);
// there is not warranties that the first chunk
// contains the serialized path only;
// so we need to offset the data to point to the first transaction
// byte
uint32_t path_len = sizeof(uint32_t) * hdPath_len;

// plus the first offset data containing the path len
data += path_len + 1;
if (len < path_len) {
THROW(APDU_CODE_WRONG_LENGTH);
}

// now process the chunk
len -= path_len + 1;
if (get_tx_rlp_len(data, len, &read, &to_read) != rlp_ok) {
THROW(APDU_CODE_DATA_INVALID);
}

// get remaining data len
max_len = saturating_add(read, to_read);
max_len = MIN(max_len, len);

added = tx_append(data, max_len);
if (added != max_len) {
THROW(APDU_CODE_OUTPUT_BUFFER_TOO_SMALL);
}

tx_initialized = true;

// if the number of bytes read and the number of bytes to read
// is the same as what we read...
if ((saturating_add(read, to_read) - len) == 0) {
return true;
}
return false;
case P1_ETH_MORE:
if (!tx_initialized) {
THROW(APDU_CODE_TX_NOT_INITIALIZED);
}

uint64_t buff_len = tx_get_buffer_length();
uint8_t *buff_data = tx_get_buffer();

if (get_tx_rlp_len(buff_data, buff_len, &read, &to_read) != rlp_ok) {
THROW(APDU_CODE_DATA_INVALID);
}

uint64_t rlp_read = buff_len - read;

// either the entire buffer of the remaining bytes we expect
uint64_t missing = to_read - rlp_read;
max_len = len;

if (missing < len) max_len = missing;

added = tx_append(data, max_len);

if (added != max_len) {
tx_initialized = false;
THROW(APDU_CODE_OUTPUT_BUFFER_TOO_SMALL);
}

// check if this chunk was the last one
if (missing - len == 0) {
tx_initialized = false;
return true;
}

return false;
}
THROW(APDU_CODE_INVALIDP1P2);
}

__Z_INLINE void handleGetAddr(volatile uint32_t *flags, volatile uint32_t *tx, uint32_t rx) {
zemu_log("handleGetAddr\n");
uint8_t len = extractHRP(rx, OFFSET_DATA);
Expand All @@ -262,31 +137,6 @@ __Z_INLINE void handleGetAddr(volatile uint32_t *flags, volatile uint32_t *tx, u
THROW(APDU_CODE_OK);
}

__Z_INLINE void handleGetAddrEth(volatile uint32_t *flags, volatile uint32_t *tx, uint32_t rx) {
extract_eth_path(rx, OFFSET_DATA);

uint8_t requireConfirmation = G_io_apdu_buffer[OFFSET_P1];
uint8_t with_code = G_io_apdu_buffer[OFFSET_P2];

if (with_code != P2_CHAINCODE && with_code != P2_NO_CHAINCODE) THROW(APDU_CODE_INVALIDP1P2);

flr_chain_code = with_code;

zxerr_t zxerr = app_fill_eth_address();
if (zxerr != zxerr_ok) {
*tx = 0;
THROW(APDU_CODE_DATA_INVALID);
}
if (requireConfirmation) {
view_review_init(eth_addr_getItem, eth_addr_getNumItems, app_reply_address);
view_review_show(REVIEW_ADDRESS);
*flags |= IO_ASYNCH_REPLY;
return;
}
*tx = action_addrResponseLen;
THROW(APDU_CODE_OK);
}

__Z_INLINE void handleSign(volatile uint32_t *flags, volatile uint32_t *tx, uint32_t rx) {
zemu_log("handleSign\n");
if (!process_chunk(tx, rx)) {
Expand Down Expand Up @@ -341,34 +191,6 @@ __Z_INLINE void handleSignHash(volatile uint32_t *flags, volatile uint32_t *tx,
*flags |= IO_ASYNCH_REPLY;
}

__Z_INLINE void handleSignEth(volatile uint32_t *flags, volatile uint32_t *tx, uint32_t rx) {
zemu_log_stack("handleSignEth");
if (!process_chunk_eth(tx, rx)) {
THROW(APDU_CODE_OK);
}

CHECK_APP_CANARY()
uint8_t error_code;
const char *error_msg = tx_parse(&error_code);
CHECK_APP_CANARY()

if (error_msg != NULL) {
const int error_msg_length = strnlen(error_msg, sizeof(G_io_apdu_buffer));
MEMCPY(G_io_apdu_buffer, error_msg, error_msg_length);
*tx += (error_msg_length);
if (error_code == parser_blindsign_required) {
*flags |= IO_ASYNCH_REPLY;
view_blindsign_error_show();
}
THROW(APDU_CODE_DATA_INVALID);
}

CHECK_APP_CANARY()
view_review_init(tx_getItem, tx_getNumItems, app_sign_eth);
view_review_show(REVIEW_TXN);
*flags |= IO_ASYNCH_REPLY;
}

__Z_INLINE void handle_getversion(__Z_UNUSED volatile uint32_t *flags, volatile uint32_t *tx) {
G_io_apdu_buffer[0] = 0;

Expand Down Expand Up @@ -449,6 +271,14 @@ void handleApdu(volatile uint32_t *flags, volatile uint32_t *tx, uint32_t rx) {
handleSignEth(flags, tx, rx);
break;
}
case INS_SIGN_PERSONAL_MESSAGE: {
CHECK_PIN_VALIDATED()
if (cla != CLA_ETH) {
THROW(APDU_CODE_COMMAND_NOT_ALLOWED);
}
handleSignEip191(flags, tx, rx);
break;
}
default:
THROW(APDU_CODE_INS_NOT_SUPPORTED);
}
Expand Down
13 changes: 0 additions & 13 deletions app/src/coin.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ extern "C" {
#endif

#define CLA 0x58
#define CLA_ETH 0xE0

typedef enum {
BECH32 = 0,
Expand All @@ -31,9 +30,6 @@ typedef enum {
#define MAX_BIP32_PATH 10
#define HDPATH_LEN_DEFAULT 5

#define HDPATH_ETH_0_DEFAULT (0x80000000u | 0x2cu)
#define HDPATH_ETH_1_DEFAULT (0x80000000u | 0x3cu)

#define HDPATH_2_DEFAULT (0x80000000u | 0u)
#define HDPATH_3_DEFAULT (0u)
#define HDPATH_4_DEFAULT (0u)
Expand All @@ -54,19 +50,10 @@ typedef enum {
#define COIN_AMOUNT_DECIMAL_PLACES 6
#define COIN_TICKER "FLR "

// transaction is sent as a blob of rlp encoded bytes,
#define P1_ETH_FIRST 0x00
#define P1_ETH_MORE 0x80
// eth address chain_code allowed valuec
#define P2_NO_CHAINCODE 0x00
#define P2_CHAINCODE 0x01

#define SECP256K1_SK_LEN 64u
#define SECP256K1_PK_LEN 65u
#define ETH_ADDR_LEN 20u

#define INS_SIGN_ETH 0x04
#define INS_GET_ADDR_ETH 0x02
#define COIN_AMOUNT_DECIMAL 18

#define MENU_MAIN_APP_LINE1 "Flare Network"
Expand Down
23 changes: 22 additions & 1 deletion app/src/common/actions.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
#include "apdu_codes.h"
#include "coin.h"
#include "crypto.h"
#include "crypto_eth.h"
#include "eth_eip191.h"
#include "tx.h"
#include "zxerror.h"

Expand Down Expand Up @@ -92,7 +94,7 @@ __Z_INLINE void app_sign_eth() {
uint16_t replyLen = 0;

MEMZERO(G_io_apdu_buffer, IO_APDU_BUFFER_SIZE);
zxerr_t err = crypto_sign_eth(G_io_apdu_buffer, IO_APDU_BUFFER_SIZE - 3, message, messageLength, &replyLen);
zxerr_t err = crypto_sign_eth(G_io_apdu_buffer, IO_APDU_BUFFER_SIZE - 3, message, messageLength, &replyLen, false);

if (err != zxerr_ok || replyLen == 0) {
set_code(G_io_apdu_buffer, 0, APDU_CODE_SIGN_VERIFY_ERROR);
Expand All @@ -103,6 +105,25 @@ __Z_INLINE void app_sign_eth() {
}
}

__Z_INLINE void app_sign_eip191() {
const uint8_t *message = tx_get_buffer();
const uint16_t messageLength = tx_get_buffer_length();
uint16_t replyLen = 0;
uint8_t hash[32] = {0};
MEMZERO(G_io_apdu_buffer, IO_APDU_BUFFER_SIZE);
zxerr_t err = eip191_hash_message(message, messageLength, hash);
if (err == zxerr_ok) {
err = crypto_sign_eth(G_io_apdu_buffer, IO_APDU_BUFFER_SIZE - 3, hash, 32, &replyLen, true);
}
if (err != zxerr_ok || replyLen == 0) {
set_code(G_io_apdu_buffer, 0, APDU_CODE_SIGN_VERIFY_ERROR);
io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, 2);
} else {
set_code(G_io_apdu_buffer, replyLen, APDU_CODE_OK);
io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, replyLen + 2);
}
}

__Z_INLINE void app_reject() {
MEMZERO(G_io_apdu_buffer, IO_APDU_BUFFER_SIZE);
set_code(G_io_apdu_buffer, 0, APDU_CODE_COMMAND_NOT_ALLOWED);
Expand Down
4 changes: 2 additions & 2 deletions app/src/common/parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ extern "C" {
const char *parser_getErrorDescription(parser_error_t err);
const char *parser_getMsgPackTypeDescription(uint8_t type);

parser_error_t parser_init_context(parser_context_t *ctx, const uint8_t *buffer, uint16_t bufferSize);

//// parses a tx buffer
parser_error_t parser_parse(parser_context_t *ctx, const uint8_t *data, size_t dataLen, parser_tx_t *tx_obj);

Expand All @@ -38,8 +40,6 @@ parser_error_t parser_getNumItems(const parser_context_t *ctx, uint8_t *num_item
parser_error_t parser_getItem(const parser_context_t *ctx, uint8_t displayIdx, char *outKey, uint16_t outKeyLen,
char *outVal, uint16_t outValLen, uint8_t pageIdx, uint8_t *pageCount);

parser_error_t parser_compute_eth_v(parser_context_t *ctx, unsigned int info, uint8_t *v);

parser_error_t cleanOutput(char *outKey, uint16_t outKeyLen, char *outVal, uint16_t outValLen);

parser_error_t checkSanity(uint8_t numItems, uint8_t displayIdx);
Expand Down
6 changes: 0 additions & 6 deletions app/src/common/parser_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,17 +73,11 @@ typedef enum {
parser_invalid_chain_id,
} parser_error_t;

typedef enum {
flr_tx = 0,
eth_tx,
} tx_type_t;

typedef struct {
const uint8_t *buffer;
uint16_t bufferLen;
uint16_t offset;
parser_tx_t *tx_obj;
tx_type_t tx_type;
} parser_context_t;

#ifdef __cplusplus
Expand Down
Loading

0 comments on commit a11b5f1

Please sign in to comment.