* Add Artis, Dexon, EWC, Thundercore, Volta, Webchain

* Switch to Flow API for Nano S 1.6.0
* Add extra U2F timeout guards for Windows
* Review application flow and parameters checks
* Refactor signature padding
This commit is contained in:
BTChip github
2020-01-18 12:47:53 +01:00
parent 658164ae18
commit 0e3c0f9263
44 changed files with 363 additions and 88 deletions

View File

@@ -24,10 +24,12 @@ DEFINES_LIB = USE_LIB_ETHEREUM
APP_LOAD_PARAMS= --curve secp256k1 $(COMMON_LOAD_PARAMS)
# Allow the app to use path 45 for multi-sig (see BIP45).
APP_LOAD_PARAMS += --path "45'"
# Samsung temporary implementation for wallet ID on 0xda7aba5e/0xc1a551c5
APP_LOAD_PARAMS += --path "1517992542'/1101353413'"
APPVERSION_M=1
APPVERSION_N=2
APPVERSION_P=3
APPVERSION_P=13
APPVERSION=$(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P)
APP_LOAD_FLAGS= --appFlags 0x240 --dep Ethereum:$(APPVERSION)
@@ -71,6 +73,14 @@ else ifeq ($(CHAIN),poa)
APP_LOAD_PARAMS += --path "44'/60'"
DEFINES += CHAINID_UPCASE=\"POA\" CHAINID_COINNAME=\"POA\" CHAIN_KIND=CHAIN_KIND_POA CHAIN_ID=99
APPNAME = "POA"
else ifeq ($(CHAIN),artis_sigma1)
APP_LOAD_PARAMS += --path "44'/246529'"
DEFINES += CHAINID_UPCASE=\"ARTISSIGMA1\" CHAINID_COINNAME=\"ATS\" CHAIN_KIND=CHAIN_KIND_ARTIS_SIGMA1 CHAIN_ID=246529
APPNAME = "ARTIS sigma1"
else ifeq ($(CHAIN),artis_tau1)
APP_LOAD_PARAMS += --path "44'/246785'"
DEFINES += CHAINID_UPCASE=\"ARTISTAU1\" CHAINID_COINNAME=\"ATS\" CHAIN_KIND=CHAIN_KIND_ARTIS_TAU1 CHAIN_ID=246785
APPNAME = "ARTIS tau1"
else ifeq ($(CHAIN),rsk)
APP_LOAD_PARAMS += --path "44'/137'" --path "44'/00'"
DEFINES += CHAINID_UPCASE=\"RSK\" CHAINID_COINNAME=\"RBTC\" CHAIN_KIND=CHAIN_KIND_RSK CHAIN_ID=30
@@ -135,9 +145,29 @@ else ifeq ($(CHAIN),tobalaba)
APP_LOAD_PARAMS += --path "44'/401697'"
DEFINES += CHAINID_UPCASE=\"TOBALABA\" CHAINID_COINNAME=\"TOBALABA\" CHAIN_KIND=CHAIN_KIND_TOBALABA CHAIN_ID=401697
APPNAME = "Tobalaba"
else ifeq ($(CHAIN),webchain)
APP_LOAD_PARAMS += --path "44'/227'"
DEFINES += CHAINID_UPCASE=\"WEBCHAIN\" CHAINID_COINNAME=\"WEB\" CHAIN_KIND=CHAIN_KIND_WEBCHAIN CHAIN_ID=24484
APPNAME = "Webchain"
else ifeq ($(CHAIN),dexon)
APP_LOAD_PARAMS += --path "44'/237'"
DEFINES += CHAINID_UPCASE=\"DEXON\" CHAINID_COINNAME=\"DXN\" CHAIN_KIND=CHAIN_KIND_DEXON CHAIN_ID=237
APPNAME = "DEXON"
else ifeq ($(CHAIN),volta)
APP_LOAD_PARAMS += --path "44'/73799'" --path "44'/60'"
DEFINES += CHAINID_UPCASE=\"VOLTA\" CHAINID_COINNAME=\"VOLTA\" CHAIN_KIND=CHAIN_KIND_VOLTA CHAIN_ID=73799
APPNAME = "Volta"
else ifeq ($(CHAIN),ewc)
APP_LOAD_PARAMS += --path "44'/246'" --path "44'/60'"
DEFINES += CHAINID_UPCASE=\"EWC\" CHAINID_COINNAME=\"EWC\" CHAIN_KIND=CHAIN_KIND_EWC CHAIN_ID=246
APPNAME = "EnergyWebChain"
else ifeq ($(CHAIN),thundercore)
APP_LOAD_PARAMS += --path "44'/1001'"
DEFINES += CHAINID_UPCASE=\"THUNDERCORE\" CHAINID_COINNAME=\"TT\" CHAIN_KIND=CHAIN_KIND_THUNDERCORE CHAIN_ID=108
APPNAME = "ThunderCore"
else
ifeq ($(filter clean,$(MAKECMDGOALS)),)
$(error Unsupported CHAIN - use ethereum, ethereum_classic, expanse, poa, rsk, rsk_testnet, ubiq, wanchain, kusd, musicoin, pirl, akroma, atheios, callisto, ethersocial, ellaism, ether1, ethergem, gochain, mix, reosc, hpb, tomochain, tobalaba)
$(error Unsupported CHAIN - use ethereum, ethereum_classic, expanse, poa, artis_sigma1, artis_tau1, rsk, rsk_testnet, ubiq, wanchain, kusd, musicoin, pirl, akroma, atheios, callisto, ethersocial, ellaism, ether1, ethergem, gochain, mix, reosc, hpb, tomochain, tobalaba, dexon, volta, ewc, webchain, thundercore)
endif
endif
@@ -164,10 +194,8 @@ all: default
# Platform #
############
DEFINES += OS_IO_SEPROXYHAL IO_SEPROXYHAL_BUFFER_SIZE_B=128
DEFINES += OS_IO_SEPROXYHAL
DEFINES += HAVE_BAGL HAVE_SPRINTF
#DEFINES += HAVE_PRINTF PRINTF=screen_printf
DEFINES += PRINTF\(...\)=
DEFINES += HAVE_IO_USB HAVE_L4_USBLIB IO_USB_MAX_ENDPOINTS=6 IO_HID_EP_LENGTH=64 HAVE_USB_APDU
DEFINES += LEDGER_MAJOR_VERSION=$(APPVERSION_M) LEDGER_MINOR_VERSION=$(APPVERSION_N) LEDGER_PATCH_VERSION=$(APPVERSION_P)
@@ -176,32 +204,47 @@ DEFINES += HAVE_U2F HAVE_IO_U2F
DEFINES += U2F_PROXY_MAGIC=\"w0w\"
DEFINES += USB_SEGMENT_SIZE=64
DEFINES += BLE_SEGMENT_SIZE=32 #max MTU, min 20
WEBUSB_URL = www.ledgerwallet.com
DEFINES += HAVE_WEBUSB WEBUSB_URL_SIZE_B=$(shell echo -n $(WEBUSB_URL) | wc -c) WEBUSB_URL=$(shell echo -n $(WEBUSB_URL) | sed -e "s/./\\\'\0\\\',/g")
DEFINES += UNUSED\(x\)=\(void\)x
DEFINES += APPVERSION=\"$(APPVERSION)\"
DEFINES += CX_COMPLIANCE_141
#WEBUSB_URL = www.ledgerwallet.com
#DEFINES += HAVE_WEBUSB WEBUSB_URL_SIZE_B=$(shell echo -n $(WEBUSB_URL) | wc -c) WEBUSB_URL=$(shell echo -n $(WEBUSB_URL) | sed -e "s/./\\\'\0\\\',/g")
DEFINES += HAVE_WEBUSB WEBUSB_URL_SIZE_B=0 WEBUSB_URL=""
ifeq ($(TARGET_NAME),TARGET_NANOX)
DEFINES += IO_SEPROXYHAL_BUFFER_SIZE_B=300
DEFINES += HAVE_BLE BLE_COMMAND_TIMEOUT_MS=2000
DEFINES += HAVE_BLE_APDU # basic ledger apdu transport over BLE
DEFINES += HAVE_GLO096 HAVE_UX_LEGACY
DEFINES += HAVE_GLO096
DEFINES += HAVE_BAGL BAGL_WIDTH=128 BAGL_HEIGHT=64
DEFINES += HAVE_BAGL_ELLIPSIS # long label truncation feature
DEFINES += HAVE_BAGL_FONT_OPEN_SANS_REGULAR_11PX
DEFINES += HAVE_BAGL_FONT_OPEN_SANS_EXTRABOLD_11PX
DEFINES += HAVE_BAGL_FONT_OPEN_SANS_LIGHT_16PX
DEFINES += HAVE_UX_FLOW
else
DEFINES += IO_SEPROXYHAL_BUFFER_SIZE_B=128
endif
# Enabling debug PRINTF
DEBUG = 0
ifneq ($(DEBUG),0)
ifeq ($(TARGET_NAME),TARGET_NANOX)
DEFINES += HAVE_PRINTF PRINTF=mcu_usb_printf
else
DEFINES += HAVE_PRINTF PRINTF=screen_printf
endif
else
DEFINES += PRINTF\(...\)=
endif
ifneq ($(NOCONSENT),)
DEFINES += NO_CONSENT
endif
DEFINES += HAVE_TOKENS_LIST # Do not activate external ERC-20 support yet
#DEFINES += HAVE_TOKENS_LIST # Do not activate external ERC-20 support yet
##############
# Compiler #
@@ -242,6 +285,18 @@ SDK_SOURCE_PATH += lib_blewbxx lib_blewbxx_impl
SDK_SOURCE_PATH += lib_ux
endif
# If the SDK supports Flow for Nano S, build for it
ifeq ($(TARGET_NAME),TARGET_NANOS)
ifneq "$(wildcard $(BOLOS_SDK)/lib_ux/src/ux_flow_engine.c)" ""
SDK_SOURCE_PATH += lib_ux
DEFINES += HAVE_UX_FLOW
DEFINES += HAVE_WALLET_ID_SDK
endif
endif
load: all
python -m ledgerblue.loadApp $(APP_LOAD_PARAMS)
@@ -255,4 +310,4 @@ include $(BOLOS_SDK)/Makefile.rules
dep/%.d: %.c Makefile
listvariants:
@echo VARIANTS CHAIN ethereum ethereum_classic expanse poa rsk rsk_testnet ubiq wanchain kusd pirl akroma atheios callisto ethersocial ether1 gochain musicoin ethergem mix ellaism reosc hpb tomochain tobalaba
@echo VARIANTS CHAIN ethereum ethereum_classic expanse poa artis_sigma1 artis_tau1 rsk rsk_testnet ubiq wanchain kusd pirl akroma atheios callisto ethersocial ether1 gochain musicoin ethergem mix ellaism reosc hpb tomochain tobalaba dexon volta ewc webchain thundercore

BIN
artis_sigma1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

BIN
artis_tau1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

BIN
blue_app_artis_sigma1.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 671 B

BIN
blue_app_artis_tau1.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 663 B

BIN
blue_app_dexon.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
blue_app_ewc.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
blue_app_thundercore.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 557 B

BIN
blue_app_volta.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
blue_app_webchain.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
blue_badge_thundercore.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 271 B

BIN
dexon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
ewc.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

BIN
glyphs/blue_badge_dexon.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 823 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 271 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 791 B

BIN
glyphs/icon_back_x.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
glyphs/icon_dashboard_x.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 B

BIN
nanos_app_artis_sigma1.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 B

BIN
nanos_app_artis_tau1.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 B

BIN
nanos_app_dexon.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 B

BIN
nanos_app_ewc.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
nanos_app_thundercore.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 B

BIN
nanos_app_volta.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
nanos_app_webchain.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 B

BIN
nanox_app_artis_sigma1.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 B

BIN
nanox_app_artis_tau1.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 B

BIN
nanox_app_dexon.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 B

BIN
nanox_app_ewc.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 B

BIN
nanox_app_thundercore.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 B

BIN
nanox_app_volta.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 B

BIN
nanox_app_webchain.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 B

View File

@@ -45,7 +45,14 @@ typedef enum chain_kind_e {
CHAIN_KIND_REOSC,
CHAIN_KIND_HPB,
CHAIN_KIND_TOMOCHAIN,
CHAIN_KIND_TOBALABA
CHAIN_KIND_TOBALABA,
CHAIN_KIND_DEXON,
CHAIN_KIND_VOLTA,
CHAIN_KIND_EWC,
CHAIN_KIND_ARTIS_SIGMA1,
CHAIN_KIND_ARTIS_TAU1,
CHAIN_KIND_WEBCHAIN,
CHAIN_KIND_THUNDERCORE
} chain_kind_t;
typedef struct chain_config_s {

View File

@@ -67,6 +67,9 @@ void finalizeParsing(bool);
#define P1_FIRST 0x00
#define P1_MORE 0x80
#define COMMON_CLA 0xB0
#define COMMON_INS_GET_WALLET_ID 0x04
#define OFFSET_CLA 0
#define OFFSET_INS 1
#define OFFSET_P1 2
@@ -144,8 +147,16 @@ union {
rawDataContext_t rawDataContext;
} dataContext;
typedef enum {
APP_STATE_IDLE,
APP_STATE_SIGNING_TX,
APP_STATE_SIGNING_MESSAGE
} app_state_t;
volatile uint8_t dataAllowed;
volatile uint8_t contractDetails;
volatile uint8_t appState;
volatile char addressSummary[32];
volatile bool dataPresent;
volatile bool tokenProvisioned;
@@ -153,17 +164,17 @@ volatile bool currentTokenSet;
bagl_element_t tmp_element;
#ifdef TARGET_NANOX
#ifdef HAVE_UX_FLOW
#include "ux.h"
ux_state_t G_ux;
bolos_ux_params_t G_ux_params;
#else // TARGET_NANOX
#else // HAVE_UX_FLOW
ux_state_t ux;
// display stepped screens
unsigned int ux_step;
unsigned int ux_step_count;
#endif // TARGET_NANOX
#endif // HAVE_UX_FLOW
typedef struct internalStorage_t {
@@ -204,6 +215,13 @@ const bagl_element_t* ui_menu_item_out_over(const bagl_element_t* e) {
return e;
}
void reset_app_context() {
appState = APP_STATE_IDLE;
currentTokenSet = false;
os_memset((uint8_t*)&txContext, 0, sizeof(txContext));
os_memset((uint8_t*)&tmpContent, 0, sizeof(tmpContent));
}
#define BAGL_FONT_OPEN_SANS_LIGHT_16_22PX_AVG_WIDTH 10
#define BAGL_FONT_OPEN_SANS_REGULAR_10_13PX_AVG_WIDTH 8
@@ -267,7 +285,7 @@ unsigned int ui_idle_blue_button(unsigned int button_mask, unsigned int button_m
#endif // #if defined(TARGET_BLUE)
#if defined(TARGET_NANOS)
#if defined(TARGET_NANOS) && !defined(HAVE_UX_FLOW)
const ux_menu_entry_t menu_main[];
@@ -338,7 +356,7 @@ const ux_menu_entry_t menu_main[] = {
UX_MENU_END
};
#endif // #if defined(TARGET_NANOS)
#endif // #if defined(TARGET_NANOS) && !defined(HAVE_UX_FLOW)
#if defined(TARGET_BLUE)
const bagl_element_t * ui_settings_blue_toggle_data(const bagl_element_t * e) {
@@ -741,7 +759,8 @@ unsigned int ui_address_blue_button(unsigned int button_mask, unsigned int butto
}
#endif // #if defined(TARGET_BLUE)
#if defined(TARGET_NANOS)
#if defined(TARGET_NANOS) && !defined(HAVE_UX_FLOW)
const bagl_element_t ui_address_nanos[] = {
// type userid x y w h str rad fill fg bg fid iid txt touchparams... ]
{{BAGL_RECTANGLE , 0x00, 0, 0, 128, 32, 0, 0, BAGL_FILL, 0x000000, 0xFFFFFF, 0, 0}, NULL, 0, 0, 0, NULL, NULL, NULL},
@@ -776,11 +795,10 @@ unsigned int ui_address_prepro(const bagl_element_t* element) {
}
unsigned int ui_address_nanos_button(unsigned int button_mask, unsigned int button_mask_counter);
#endif // #if defined(TARGET_NANOS)
#endif // #if defined(TARGET_NANOS) && !defined(HAVE_UX_FLOW)
#if defined(TARGET_NANOS)
#if defined(TARGET_NANOS) && !defined(HAVE_UX_FLOW)
const bagl_element_t ui_approval_nanos[] = {
// type userid x y w h str rad fill fg bg fid iid txt touchparams... ]
{{BAGL_RECTANGLE , 0x00, 0, 0, 128, 32, 0, 0, BAGL_FILL, 0x000000, 0xFFFFFF, 0, 0}, NULL, 0, 0, 0, NULL, NULL, NULL},
@@ -875,7 +893,7 @@ unsigned int ui_approval_signMessage_prepro(const bagl_element_t *element) {
return 1;
}
#endif // #if defined(TARGET_NANOS)
#endif // #if defined(TARGET_NANOS) && !defined(HAVE_UX_FLOW)
#if defined(TARGET_BLUE)
const bagl_element_t ui_data_selector_blue[] = {
@@ -921,7 +939,7 @@ unsigned int ui_data_selector_blue_button(unsigned int button_mask, unsigned int
#endif // #if defined(TARGET_BLUE)
#if defined(TARGET_NANOS)
#if defined(TARGET_NANOS) && !defined(HAVE_UX_FLOW)
const bagl_element_t ui_data_selector_nanos[] = {
// type userid x y w h str rad
// fill fg bg fid iid txt touchparams... ]
@@ -956,7 +974,7 @@ unsigned int ui_data_selector_prepro(const bagl_element_t *element) {
unsigned int ui_data_selector_nanos_button(unsigned int button_mask,
unsigned int button_mask_counter);
#endif // #if defined(TARGET_NANOS)
#endif // #if defined(TARGET_NANOS) && !defined(HAVE_UX_FLOW)
#if defined(TARGET_BLUE)
const bagl_element_t ui_data_parameter_blue[] = {
@@ -1017,7 +1035,7 @@ unsigned int ui_data_parameter_blue_button(unsigned int button_mask, unsigned in
#endif // #if defined(TARGET_BLUE)
#if defined(TARGET_NANOS)
#if defined(TARGET_NANOS) && !defined(HAVE_UX_FLOW)
const bagl_element_t ui_data_parameter_nanos[] = {
// type userid x y w h str rad
// fill fg bg fid iid txt touchparams... ]
@@ -1054,9 +1072,9 @@ unsigned int ui_data_parameter_prepro(const bagl_element_t *element) {
unsigned int ui_data_parameter_nanos_button(unsigned int button_mask,
unsigned int button_mask_counter);
#endif // #if defined(TARGET_NANOS)
#endif // #if defined(TARGET_NANOS) && !defined(HAVE_UX_FLOW)
#if defined(TARGET_NANOX)
#if defined(HAVE_UX_FLOW)
void display_settings(void);
void switch_settings_contract_data(void);
@@ -1065,9 +1083,9 @@ void switch_settings_display_data(void);
//////////////////////////////////////////////////////////////////////
UX_FLOW_DEF_NOCB(
ux_idle_flow_1_step,
bnn, //pnn,
nn, //pnn,
{
"", //&C_icon_dashboard,
//"", //&C_icon_dashboard,
"Application",
"is ready",
});
@@ -1091,7 +1109,7 @@ UX_FLOW_DEF_VALID(
pb,
os_sched_exit(-1),
{
&C_icon_dashboard,
&C_icon_dashboard_x,
"Quit",
});
const ux_flow_step_t * const ux_idle_flow [] = {
@@ -1102,6 +1120,28 @@ const ux_flow_step_t * const ux_idle_flow [] = {
FLOW_END_STEP,
};
#if defined(TARGET_NANOS)
UX_FLOW_DEF_VALID(
ux_settings_flow_1_step,
bnnn_paging,
switch_settings_contract_data(),
{
.title = "Contract data",
.text = strings.common.fullAddress,
});
UX_FLOW_DEF_VALID(
ux_settings_flow_2_step,
bnnn_paging,
switch_settings_display_data(),
{
.title = "Debug data",
.text = strings.common.fullAddress + 20
});
#else
UX_FLOW_DEF_VALID(
ux_settings_flow_1_step,
bnnn,
@@ -1118,18 +1158,20 @@ UX_FLOW_DEF_VALID(
bnnn,
switch_settings_display_data(),
{
"Display data",
"Debug data",
"Display contract data",
"details",
strings.common.fullAddress + 20
});
#endif
UX_FLOW_DEF_VALID(
ux_settings_flow_3_step,
pb,
ui_idle(),
{
&C_icon_back,
&C_icon_back_x,
"Back",
});
@@ -1403,20 +1445,20 @@ const ux_flow_step_t * const ux_sign_flow [] = {
};
#endif // #if defined(TARGET_NANOX)
#endif // #if defined(HAVE_UX_FLOW)
void ui_idle(void) {
#if defined(TARGET_BLUE)
UX_DISPLAY(ui_idle_blue, ui_idle_blue_prepro);
#elif defined(TARGET_NANOS)
UX_MENU_DISPLAY(0, menu_main, NULL);
#elif defined(TARGET_NANOX)
#elif defined(HAVE_UX_FLOW)
// reserve a display stack slot if none yet
if(G_ux.stack_count == 0) {
ux_stack_push();
}
ux_flow_init(0, ux_idle_flow, NULL);
#elif defined(TARGET_NANOS)
UX_MENU_DISPLAY(0, menu_main, NULL);
#endif // #if TARGET_ID
}
@@ -1437,6 +1479,7 @@ unsigned int io_seproxyhal_touch_address_ok(const bagl_element_t *e) {
uint32_t tx = set_result_get_publicKey();
G_io_apdu_buffer[tx++] = 0x90;
G_io_apdu_buffer[tx++] = 0x00;
reset_app_context();
// Send back the response, do not restart the event loop
io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, tx);
// Display back the original UX
@@ -1447,6 +1490,7 @@ unsigned int io_seproxyhal_touch_address_ok(const bagl_element_t *e) {
unsigned int io_seproxyhal_touch_address_cancel(const bagl_element_t *e) {
G_io_apdu_buffer[0] = 0x69;
G_io_apdu_buffer[1] = 0x85;
reset_app_context();
// Send back the response, do not restart the event loop
io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, 2);
// Display back the original UX
@@ -1476,14 +1520,36 @@ void io_seproxyhal_send_status(uint32_t sw) {
io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, 2);
}
void format_signature_out(const uint8_t* signature) {
os_memset(G_io_apdu_buffer + 1, 0x00, 64);
uint8_t offset = 1;
uint8_t xoffset = 4; //point to r value
//copy r
uint8_t xlength = signature[xoffset-1];
if (xlength == 33) {
xlength = 32;
xoffset ++;
}
memmove(G_io_apdu_buffer+offset+32-xlength, signature+xoffset, xlength);
offset += 32;
xoffset += xlength +2; //move over rvalue and TagLEn
//copy s value
xlength = signature[xoffset-1];
if (xlength == 33) {
xlength = 32;
xoffset ++;
}
memmove(G_io_apdu_buffer+offset+32-xlength, signature+xoffset, xlength);
}
unsigned int io_seproxyhal_touch_tx_ok(const bagl_element_t *e) {
uint8_t privateKeyData[32];
uint8_t signature[100];
uint8_t signatureLength;
cx_ecfp_private_key_t privateKey;
uint32_t tx = 0;
uint8_t rLength, sLength, rOffset, sOffset;
uint32_t v = getV(&tmpContent.txContent);
io_seproxyhal_io_heartbeat();
os_perso_derive_node_bip32(CX_CURVE_256K1, tmpCtx.transactionContext.bip32Path,
tmpCtx.transactionContext.pathLength,
privateKeyData, NULL);
@@ -1491,10 +1557,11 @@ unsigned int io_seproxyhal_touch_tx_ok(const bagl_element_t *e) {
&privateKey);
os_memset(privateKeyData, 0, sizeof(privateKeyData));
unsigned int info = 0;
io_seproxyhal_io_heartbeat();
signatureLength =
cx_ecdsa_sign(&privateKey, CX_RND_RFC6979 | CX_LAST, CX_SHA256,
tmpCtx.transactionContext.hash,
sizeof(tmpCtx.transactionContext.hash), signature, &info);
sizeof(tmpCtx.transactionContext.hash), signature, sizeof(signature), &info);
os_memset(&privateKey, 0, sizeof(privateKey));
// Parity is present in the sequence tag in the legacy API
if (tmpContent.txContent.vLength == 0) {
@@ -1512,17 +1579,11 @@ unsigned int io_seproxyhal_touch_tx_ok(const bagl_element_t *e) {
if (info & CX_ECCINFO_xGTn) {
G_io_apdu_buffer[0] += 2;
}
rLength = signature[3];
sLength = signature[4 + rLength + 1];
rOffset = (rLength == 33 ? 1 : 0);
sOffset = (sLength == 33 ? 1 : 0);
os_memmove(G_io_apdu_buffer + 1, signature + 4 + rOffset, 32);
os_memmove(G_io_apdu_buffer + 1 + 32, signature + 4 + rLength + 2 + sOffset,
32);
format_signature_out(signature);
tx = 65;
G_io_apdu_buffer[tx++] = 0x90;
G_io_apdu_buffer[tx++] = 0x00;
reset_app_context();
// Send back the response, do not restart the event loop
io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, tx);
// Display back the original UX
@@ -1531,6 +1592,7 @@ unsigned int io_seproxyhal_touch_tx_ok(const bagl_element_t *e) {
}
unsigned int io_seproxyhal_touch_tx_cancel(const bagl_element_t *e) {
reset_app_context();
G_io_apdu_buffer[0] = 0x69;
G_io_apdu_buffer[1] = 0x85;
// Send back the response, do not restart the event loop
@@ -1547,17 +1609,19 @@ unsigned int io_seproxyhal_touch_signMessage_ok(const bagl_element_t *e) {
uint8_t signatureLength;
cx_ecfp_private_key_t privateKey;
uint32_t tx = 0;
uint8_t rLength, sLength, rOffset, sOffset;
io_seproxyhal_io_heartbeat();
os_perso_derive_node_bip32(
CX_CURVE_256K1, tmpCtx.messageSigningContext.bip32Path,
tmpCtx.messageSigningContext.pathLength, privateKeyData, NULL);
io_seproxyhal_io_heartbeat();
cx_ecfp_init_private_key(CX_CURVE_256K1, privateKeyData, 32, &privateKey);
os_memset(privateKeyData, 0, sizeof(privateKeyData));
unsigned int info = 0;
io_seproxyhal_io_heartbeat();
signatureLength =
cx_ecdsa_sign(&privateKey, CX_RND_RFC6979 | CX_LAST, CX_SHA256,
tmpCtx.messageSigningContext.hash,
sizeof(tmpCtx.messageSigningContext.hash), signature, &info);
sizeof(tmpCtx.messageSigningContext.hash), signature, sizeof(signature), &info);
os_memset(&privateKey, 0, sizeof(privateKey));
G_io_apdu_buffer[0] = 27;
if (info & CX_ECCINFO_PARITY_ODD) {
@@ -1566,16 +1630,11 @@ unsigned int io_seproxyhal_touch_signMessage_ok(const bagl_element_t *e) {
if (info & CX_ECCINFO_xGTn) {
G_io_apdu_buffer[0] += 2;
}
rLength = signature[3];
sLength = signature[4 + rLength + 1];
rOffset = (rLength == 33 ? 1 : 0);
sOffset = (sLength == 33 ? 1 : 0);
os_memmove(G_io_apdu_buffer + 1, signature + 4 + rOffset, 32);
os_memmove(G_io_apdu_buffer + 1 + 32, signature + 4 + rLength + 2 + sOffset,
32);
format_signature_out(signature);
tx = 65;
G_io_apdu_buffer[tx++] = 0x90;
G_io_apdu_buffer[tx++] = 0x00;
reset_app_context();
// Send back the response, do not restart the event loop
io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, tx);
// Display back the original UX
@@ -1584,6 +1643,7 @@ unsigned int io_seproxyhal_touch_signMessage_ok(const bagl_element_t *e) {
}
unsigned int io_seproxyhal_touch_signMessage_cancel(const bagl_element_t *e) {
reset_app_context();
G_io_apdu_buffer[0] = 0x69;
G_io_apdu_buffer[1] = 0x85;
// Send back the response, do not restart the event loop
@@ -1606,11 +1666,13 @@ unsigned int io_seproxyhal_touch_data_ok(const bagl_element_t *e) {
ui_idle();
break;
case USTREAM_FAULT:
reset_app_context();
io_seproxyhal_send_status(0x6A80);
ui_idle();
break;
default:
PRINTF("Unexpected parser status\n");
reset_app_context();
io_seproxyhal_send_status(0x6A80);
ui_idle();
}
@@ -1624,6 +1686,7 @@ unsigned int io_seproxyhal_touch_data_ok(const bagl_element_t *e) {
unsigned int io_seproxyhal_touch_data_cancel(const bagl_element_t *e) {
reset_app_context();
io_seproxyhal_send_status(0x6985);
// Display back the original UX
ui_idle();
@@ -1798,6 +1861,12 @@ tokenDefinition_t* getKnownToken() {
case CHAIN_KIND_POA:
numTokens = NUM_TOKENS_POA;
break;
case CHAIN_KIND_ARTIS_SIGMA1:
numTokens = NUM_TOKENS_ARTIS_SIGMA1;
break;
case CHAIN_KIND_ARTIS_TAU1:
numTokens = NUM_TOKENS_ARTIS_TAU1;
break;
case CHAIN_KIND_RSK:
numTokens = NUM_TOKENS_RSK;
break;
@@ -1852,6 +1921,21 @@ tokenDefinition_t* getKnownToken() {
case CHAIN_KIND_TOBALABA:
numTokens = NUM_TOKENS_TOBALABA;
break;
case CHAIN_KIND_DEXON:
numTokens = NUM_TOKENS_DEXON;
break;
case CHAIN_KIND_VOLTA:
numTokens = NUM_TOKENS_VOLTA;
break;
case CHAIN_KIND_EWC:
numTokens = NUM_TOKENS_EWC;
break;
case CHAIN_KIND_WEBCHAIN:
numTokens = NUM_TOKENS_WEBCHAIN;
break;
case CHAIN_KIND_THUNDERCORE:
numTokens = NUM_TOKENS_THUNDERCORE;
break;
}
for (i=0; i<numTokens; i++) {
switch(chainConfig->kind) {
@@ -1868,8 +1952,14 @@ tokenDefinition_t* getKnownToken() {
currentToken = (tokenDefinition_t *)PIC(&TOKENS_PIRL[i]);
break;
case CHAIN_KIND_POA:
currentToken = (tokenDefinition_t *)PIC(&TOKENS_POA[i]);
break;
currentToken = (tokenDefinition_t *)PIC(&TOKENS_POA[i]);
break;
case CHAIN_KIND_ARTIS_SIGMA1:
currentToken = (tokenDefinition_t *)PIC(&TOKENS_ARTIS_SIGMA1[i]);
break;
case CHAIN_KIND_ARTIS_TAU1:
currentToken = (tokenDefinition_t *)PIC(&TOKENS_ARTIS_TAU1[i]);
break;
case CHAIN_KIND_RSK:
currentToken = (tokenDefinition_t *)PIC(&TOKENS_RSK[i]);
break;
@@ -1924,6 +2014,21 @@ tokenDefinition_t* getKnownToken() {
case CHAIN_KIND_TOBALABA:
currentToken = (tokenDefinition_t *)PIC(&TOKENS_TOBALABA[i]);
break;
case CHAIN_KIND_DEXON:
currentToken = (tokenDefinition_t *)PIC(&TOKENS_DEXON[i]);
break;
case CHAIN_KIND_VOLTA:
currentToken = (tokenDefinition_t *)PIC(&TOKENS_VOLTA[i]);
break;
case CHAIN_KIND_EWC:
currentToken = (tokenDefinition_t *)PIC(&TOKENS_EWC[i]);
break;
case CHAIN_KIND_WEBCHAIN:
currentToken = (tokenDefinition_t *)PIC(&TOKENS_WEBCHAIN[i]);
break;
case CHAIN_KIND_THUNDERCORE:
currentToken = (tokenDefinition_t *)PIC(&TOKENS_THUNDERCORE[i]);
break
}
if (os_memcmp(currentToken->address, tmpContent.txContent.destination, 20) == 0) {
return currentToken;
@@ -2028,12 +2133,12 @@ customStatus_e customProcessor(txContext_t *context) {
array_hexstr(strings.tmp.tmp, dataContext.rawDataContext.data, 4);
#if defined(TARGET_BLUE)
UX_DISPLAY(ui_data_selector_blue, ui_data_selector_blue_prepro);
#elif defined(HAVE_UX_FLOW)
ux_flow_init(0, ux_confirm_selector_flow, NULL);
#elif defined(TARGET_NANOS)
ux_step = 0;
ux_step_count = 2;
UX_DISPLAY(ui_data_selector_nanos, ui_data_selector_prepro);
#elif defined(TARGET_NANOX)
ux_flow_init(0, ux_confirm_selector_flow, NULL);
#endif // #if TARGET_ID
}
else {
@@ -2048,12 +2153,12 @@ customStatus_e customProcessor(txContext_t *context) {
}
#if defined(TARGET_BLUE)
UX_DISPLAY(ui_data_parameter_blue, ui_data_parameter_blue_prepro);
#elif defined(HAVE_UX_FLOW)
ux_flow_init(0, ux_confirm_parameter_flow, NULL);
#elif defined(TARGET_NANOS)
ux_step = 0;
ux_step_count = 2;
UX_DISPLAY(ui_data_parameter_nanos, ui_data_parameter_prepro);
#elif defined(TARGET_NANOX)
ux_flow_init(0, ux_confirm_parameter_flow, NULL);
#endif // #if TARGET_ID
}
}
@@ -2067,6 +2172,31 @@ customStatus_e customProcessor(txContext_t *context) {
return CUSTOM_NOT_HANDLED;
}
unsigned int const U_os_perso_seed_cookie[] = {
0xda7aba5e,
0xc1a551c5,
};
#ifndef HAVE_WALLET_ID_SDK
void handleGetWalletId(volatile unsigned int *tx) {
unsigned char t[64];
cx_ecfp_256_private_key_t priv;
cx_ecfp_256_public_key_t pub;
// seed => priv key
os_perso_derive_node_bip32(CX_CURVE_256K1, U_os_perso_seed_cookie, 2, t, NULL);
// priv key => pubkey
cx_ecdsa_init_private_key(CX_CURVE_256K1, t, 32, &priv);
cx_ecfp_generate_pair(CX_CURVE_256K1, &pub, &priv, 1);
// pubkey -> sha512
cx_hash_sha512(pub.W, sizeof(pub.W), t, sizeof(t));
// ! cookie !
os_memmove(G_io_apdu_buffer, t, 64);
*tx = 64;
THROW(0x9000);
}
#endif
void handleGetPublicKey(uint8_t p1, uint8_t p2, uint8_t *dataBuffer, uint16_t dataLength, volatile unsigned int *flags, volatile unsigned int *tx) {
UNUSED(dataLength);
@@ -2075,7 +2205,7 @@ void handleGetPublicKey(uint8_t p1, uint8_t p2, uint8_t *dataBuffer, uint16_t da
uint32_t i;
uint8_t bip32PathLength = *(dataBuffer++);
cx_ecfp_private_key_t privateKey;
reset_app_context();
if ((bip32PathLength < 0x01) ||
(bip32PathLength > MAX_BIP32_PATH)) {
PRINTF("Invalid path\n");
@@ -2092,11 +2222,14 @@ void handleGetPublicKey(uint8_t p1, uint8_t p2, uint8_t *dataBuffer, uint16_t da
dataBuffer += 4;
}
tmpCtx.publicKeyContext.getChaincode = (p2 == P2_CHAINCODE);
io_seproxyhal_io_heartbeat();
os_perso_derive_node_bip32(CX_CURVE_256K1, bip32Path, bip32PathLength, privateKeyData, (tmpCtx.publicKeyContext.getChaincode ? tmpCtx.publicKeyContext.chainCode : NULL));
cx_ecfp_init_private_key(CX_CURVE_256K1, privateKeyData, 32, &privateKey);
io_seproxyhal_io_heartbeat();
cx_ecfp_generate_pair(CX_CURVE_256K1, &tmpCtx.publicKeyContext.publicKey, &privateKey, 1);
os_memset(&privateKey, 0, sizeof(privateKey));
os_memset(privateKeyData, 0, sizeof(privateKeyData));
io_seproxyhal_io_heartbeat();
getEthAddressStringFromKey(&tmpCtx.publicKeyContext.publicKey, tmpCtx.publicKeyContext.address, &sha3);
#ifndef NO_CONSENT
if (p1 == P1_NON_CONFIRM)
@@ -2121,14 +2254,14 @@ void handleGetPublicKey(uint8_t p1, uint8_t p2, uint8_t *dataBuffer, uint16_t da
#if defined(TARGET_BLUE)
snprintf(strings.common.fullAddress, sizeof(strings.common.fullAddress), "0x%.*s", 40, tmpCtx.publicKeyContext.address);
UX_DISPLAY(ui_address_blue, ui_address_blue_prepro);
#elif defined(HAVE_UX_FLOW)
snprintf(strings.common.fullAddress, sizeof(strings.common.fullAddress), "0x%.*s", 40, tmpCtx.publicKeyContext.address);
ux_flow_init(0, ux_display_public_flow, NULL);
#elif defined(TARGET_NANOS)
snprintf(strings.common.fullAddress, sizeof(strings.common.fullAddress), "0x%.*s", 40, tmpCtx.publicKeyContext.address);
ux_step = 0;
ux_step_count = 2;
UX_DISPLAY(ui_address_nanos, ui_address_prepro);
#elif defined(TARGET_NANOX)
snprintf(strings.common.fullAddress, sizeof(strings.common.fullAddress), "0x%.*s", 40, tmpCtx.publicKeyContext.address);
ux_flow_init(0, ux_display_public_flow, NULL);
#endif // #if TARGET_ID
*flags |= IO_ASYNCH_REPLY;
@@ -2149,6 +2282,7 @@ void finalizeParsing(bool direct) {
if (chainConfig->chainId != 0) {
uint32_t v = getV(&tmpContent.txContent);
if (chainConfig->chainId != v) {
reset_app_context();
PRINTF("Invalid chainId %d expected %d\n", v, chainConfig->chainId);
if (direct) {
THROW(0x6A80);
@@ -2161,7 +2295,7 @@ void finalizeParsing(bool direct) {
}
}
// Store the hash
cx_hash((cx_hash_t *)&sha3, CX_LAST, tmpCtx.transactionContext.hash, 0, tmpCtx.transactionContext.hash);
cx_hash((cx_hash_t *)&sha3, CX_LAST, tmpCtx.transactionContext.hash, 0, tmpCtx.transactionContext.hash, 32);
// If there is a token to process, check if it is well known
if (tokenProvisioned) {
tokenDefinition_t *currentToken = getKnownToken();
@@ -2177,6 +2311,7 @@ void finalizeParsing(bool direct) {
}
else {
if (dataPresent && !N_storage.dataAllowed) {
reset_app_context();
PRINTF("Data field forbidden\n");
if (direct) {
THROW(0x6A80);
@@ -2257,14 +2392,14 @@ void finalizeParsing(bool direct) {
#else // NO_CONSENT
#if defined(TARGET_BLUE)
ui_approval_transaction_blue_init();
#elif defined(HAVE_UX_FLOW)
ux_flow_init(0,
((dataPresent && !N_storage.contractDetails) ? ux_approval_tx_data_warning_flow : ux_approval_tx_flow),
NULL);
#elif defined(TARGET_NANOS)
ux_step = 0;
ux_step_count = 5;
UX_DISPLAY(ui_approval_nanos, ui_approval_prepro);
#elif defined(TARGET_NANOX)
ux_flow_init(0,
((dataPresent && !N_storage.contractDetails) ? ux_approval_tx_data_warning_flow : ux_approval_tx_flow),
NULL);
#endif // #if TARGET_ID
#endif // NO_CONSENT
}
@@ -2289,10 +2424,10 @@ void handleProvideErc20TokenInformation(uint8_t p1, uint8_t p2, uint8_t *workBuf
if (dataLength < tickerLength + 20 + 4 + 4) {
THROW(0x6A80);
}
cx_hash_sha256(workBuffer + offset, tickerLength + 20 + 4 + 4, hash);
cx_hash_sha256(workBuffer + offset, tickerLength + 20 + 4 + 4, hash, 32);
os_memmove(tmpCtx.transactionContext.currentToken.ticker, workBuffer + offset, tickerLength);
tmpCtx.transactionContext.currentToken.ticker[tickerLength] = ' ';
tmpCtx.transactionContext.currentToken.ticker[tickerLength + 1] = '\0';
tmpCtx.transactionContext.currentToken.ticker[tickerLength + 1] = '\0';
offset += tickerLength;
dataLength -= tickerLength;
os_memmove(tmpCtx.transactionContext.currentToken.address, workBuffer + offset, 20);
@@ -2322,6 +2457,14 @@ void handleSign(uint8_t p1, uint8_t p2, uint8_t *workBuffer, uint16_t dataLength
parserStatus_e txResult;
uint32_t i;
if (p1 == P1_FIRST) {
if (dataLength < 1) {
PRINTF("Invalid data\n");
THROW(0x6a80);
}
if (appState != APP_STATE_IDLE) {
reset_app_context();
}
appState = APP_STATE_SIGNING_TX;
tmpCtx.transactionContext.pathLength = workBuffer[0];
if ((tmpCtx.transactionContext.pathLength < 0x01) ||
(tmpCtx.transactionContext.pathLength > MAX_BIP32_PATH)) {
@@ -2331,6 +2474,10 @@ void handleSign(uint8_t p1, uint8_t p2, uint8_t *workBuffer, uint16_t dataLength
workBuffer++;
dataLength--;
for (i = 0; i < tmpCtx.transactionContext.pathLength; i++) {
if (dataLength < 4) {
PRINTF("Invalid data\n");
THROW(0x6a80);
}
tmpCtx.transactionContext.bip32Path[i] = U4BE(workBuffer, 0);
workBuffer += 4;
dataLength -= 4;
@@ -2346,6 +2493,10 @@ void handleSign(uint8_t p1, uint8_t p2, uint8_t *workBuffer, uint16_t dataLength
if (p2 != 0) {
THROW(0x6B00);
}
if ((p1 == P1_MORE) && (appState != APP_STATE_SIGNING_TX)) {
PRINTF("Signature not initialized\n");
THROW(0x6985);
}
if (txContext.currentField == TX_RLP_NONE) {
PRINTF("Parser not initialized\n");
THROW(0x6985);
@@ -2398,6 +2549,14 @@ void handleSignPersonalMessage(uint8_t p1, uint8_t p2, uint8_t *workBuffer, uint
uint32_t base = 10;
uint8_t pos = 0;
uint32_t i;
if (dataLength < 1) {
PRINTF("Invalid data\n");
THROW(0x6a80);
}
if (appState != APP_STATE_IDLE) {
reset_app_context();
}
appState = APP_STATE_SIGNING_MESSAGE;
tmpCtx.messageSigningContext.pathLength = workBuffer[0];
if ((tmpCtx.messageSigningContext.pathLength < 0x01) ||
(tmpCtx.messageSigningContext.pathLength > MAX_BIP32_PATH)) {
@@ -2407,16 +2566,24 @@ void handleSignPersonalMessage(uint8_t p1, uint8_t p2, uint8_t *workBuffer, uint
workBuffer++;
dataLength--;
for (i = 0; i < tmpCtx.messageSigningContext.pathLength; i++) {
if (dataLength < 4) {
PRINTF("Invalid data\n");
THROW(0x6a80);
}
tmpCtx.messageSigningContext.bip32Path[i] = U4BE(workBuffer, 0);
workBuffer += 4;
dataLength -= 4;
}
if (dataLength < 4) {
PRINTF("Invalid data\n");
THROW(0x6a80);
}
tmpCtx.messageSigningContext.remainingLength = U4BE(workBuffer, 0);
workBuffer += 4;
dataLength -= 4;
// Initialize message header + length
cx_keccak_init(&sha3, 256);
cx_hash((cx_hash_t *)&sha3, 0, SIGN_MAGIC, sizeof(SIGN_MAGIC) - 1, NULL);
cx_hash((cx_hash_t *)&sha3, 0, (uint8_t*)SIGN_MAGIC, sizeof(SIGN_MAGIC) - 1, NULL, 0);
for (index = 1; (((index * base) <= tmpCtx.messageSigningContext.remainingLength) &&
(((index * base) / base) == index));
index *= base);
@@ -2424,7 +2591,7 @@ void handleSignPersonalMessage(uint8_t p1, uint8_t p2, uint8_t *workBuffer, uint
tmp[pos++] = '0' + ((tmpCtx.messageSigningContext.remainingLength / index) % base);
}
tmp[pos] = '\0';
cx_hash((cx_hash_t *)&sha3, 0, tmp, pos, NULL);
cx_hash((cx_hash_t *)&sha3, 0, (uint8_t*)tmp, pos, NULL, 0);
cx_sha256_init(&tmpContent.sha2);
}
else if (p1 != P1_MORE) {
@@ -2433,15 +2600,19 @@ void handleSignPersonalMessage(uint8_t p1, uint8_t p2, uint8_t *workBuffer, uint
if (p2 != 0) {
THROW(0x6B00);
}
if ((p1 == P1_MORE) && (appState != APP_STATE_SIGNING_MESSAGE)) {
PRINTF("Signature not initialized\n");
THROW(0x6985);
}
if (dataLength > tmpCtx.messageSigningContext.remainingLength) {
THROW(0x6A80);
}
cx_hash((cx_hash_t *)&sha3, 0, workBuffer, dataLength, NULL);
cx_hash((cx_hash_t *)&tmpContent.sha2, 0, workBuffer, dataLength, NULL);
cx_hash((cx_hash_t *)&sha3, 0, workBuffer, dataLength, NULL, 0);
cx_hash((cx_hash_t *)&tmpContent.sha2, 0, workBuffer, dataLength, NULL, 0);
tmpCtx.messageSigningContext.remainingLength -= dataLength;
if (tmpCtx.messageSigningContext.remainingLength == 0) {
cx_hash((cx_hash_t *)&sha3, CX_LAST, workBuffer, 0, tmpCtx.messageSigningContext.hash);
cx_hash((cx_hash_t *)&tmpContent.sha2, CX_LAST, workBuffer, 0, hashMessage);
cx_hash((cx_hash_t *)&sha3, CX_LAST, workBuffer, 0, tmpCtx.messageSigningContext.hash, 32);
cx_hash((cx_hash_t *)&tmpContent.sha2, CX_LAST, workBuffer, 0, hashMessage, 32);
#define HASH_LENGTH 4
array_hexstr(strings.common.fullAddress, hashMessage, HASH_LENGTH / 2);
@@ -2455,13 +2626,13 @@ void handleSignPersonalMessage(uint8_t p1, uint8_t p2, uint8_t *workBuffer, uint
#else NO_CONSENT
#if defined(TARGET_BLUE)
ui_approval_message_sign_blue_init();
#elif defined(HAVE_UX_FLOW)
ux_flow_init(0, ux_sign_flow, NULL);
#elif defined(TARGET_NANOS)
ux_step = 0;
ux_step_count = 2;
UX_DISPLAY(ui_approval_signMessage_nanos,
ui_approval_signMessage_prepro);
#elif defined(TARGET_NANOX)
ux_flow_init(0, ux_sign_flow, NULL);
#endif // #if TARGET_ID
#endif // NO_CONSENT
@@ -2477,6 +2648,16 @@ void handleApdu(volatile unsigned int *flags, volatile unsigned int *tx) {
BEGIN_TRY {
TRY {
#ifndef HAVE_WALLET_ID_SDK
if ((G_io_apdu_buffer[OFFSET_CLA] == COMMON_CLA) && (G_io_apdu_buffer[OFFSET_INS] == COMMON_INS_GET_WALLET_ID)) {
handleGetWalletId(tx);
return;
}
#endif
if (G_io_apdu_buffer[OFFSET_CLA] != CLA) {
THROW(0x6E00);
}
@@ -2523,7 +2704,7 @@ void handleApdu(volatile unsigned int *flags, volatile unsigned int *tx) {
case 0x6000:
// Wipe the transaction context and report the exception
sw = e;
os_memset(&txContext, 0, sizeof(txContext));
reset_app_context();
break;
case 0x9000:
// All is well
@@ -2532,6 +2713,7 @@ void handleApdu(volatile unsigned int *flags, volatile unsigned int *tx) {
default:
// Internal error
sw = 0x6800 | (e & 0x7FF);
reset_app_context();
break;
}
// Unexpected exception => report
@@ -2573,6 +2755,8 @@ void sample_main(void) {
THROW(0x6982);
}
PRINTF("New APDU received:\n%.*H\n", rx, G_io_apdu_buffer);
handleApdu(&flags, &tx);
}
CATCH(EXCEPTION_IO_RESET) {
@@ -2583,7 +2767,7 @@ void sample_main(void) {
case 0x6000:
// Wipe the transaction context and report the exception
sw = e;
os_memset(&txContext, 0, sizeof(txContext));
reset_app_context();
break;
case 0x9000:
// All is well
@@ -2592,6 +2776,7 @@ void sample_main(void) {
default:
// Internal error
sw = 0x6800 | (e & 0x7FF);
reset_app_context();
break;
}
if (e != 0x9000) {
@@ -2647,7 +2832,7 @@ unsigned char io_event(unsigned char channel) {
case SEPROXYHAL_TAG_TICKER_EVENT:
UX_TICKER_EVENT(G_io_seproxyhal_spi_buffer,
{
#ifndef TARGET_NANOX
#ifndef HAVE_UX_FLOW
if (UX_ALLOWED) {
if (ux_step_count) {
// prepare next screen
@@ -2656,7 +2841,7 @@ unsigned char io_event(unsigned char channel) {
UX_REDISPLAY();
}
}
#endif // TARGET_NANOX
#endif // HAVE_UX_FLOW
});
break;
}
@@ -2736,7 +2921,7 @@ __attribute__((section(".boot"))) int main(int arg0) {
chainConfig = (chain_config_t *)PIC(&C_chain_config);
}
os_memset(&txContext, 0, sizeof(txContext));
reset_app_context();
// ensure exception will work as planned
os_boot();

View File

@@ -1182,4 +1182,18 @@ const tokenDefinition_t const TOKENS_TOMOCHAIN[NUM_TOKENS_TOMOCHAIN] = {};
const tokenDefinition_t const TOKENS_TOBALABA[NUM_TOKENS_TOBALABA] = {};
const tokenDefinition_t const TOKENS_DEXON[NUM_TOKENS_DEXON] = {};
const tokenDefinition_t const TOKENS_VOLTA[NUM_TOKENS_VOLTA] = {};
const tokenDefinition_t const TOKENS_EWC[NUM_TOKENS_EWC] = {};
const tokenDefinition_t const TOKENS_ARTIS_SIGMA1[NUM_TOKENS_ARTIS_SIGMA1] = {};
const tokenDefinition_t const TOKENS_ARTIS_TAU1[NUM_TOKENS_ARTIS_TAU1] = {};
const tokenDefinition_t const TOKENS_WEBCHAIN[NUM_TOKENS_WEBCHAIN] = {};
const tokenDefinition_t const TOKENS_THUNDERCORE[NUM_TOKENS_THUNDERCORE] = {};
#endif

View File

@@ -51,6 +51,13 @@ typedef struct tokenDefinition_t {
#define NUM_TOKENS_HPB 0
#define NUM_TOKENS_TOMOCHAIN 0
#define NUM_TOKENS_TOBALABA 0
#define NUM_TOKENS_DEXON 0
#define NUM_TOKENS_VOLTA 0
#define NUM_TOKENS_EWC 0
#define NUM_TOKENS_ARTIS_SIGMA1 0
#define NUM_TOKENS_ARTIS_TAU1 0
#define NUM_TOKENS_WEBCHAIN 0
#define NUM_TOKENS_THUNDERCORE 0
extern tokenDefinition_t const TOKENS_AKROMA[NUM_TOKENS_AKROMA];
extern tokenDefinition_t const TOKENS_ELLAISM[NUM_TOKENS_ELLAISM];
@@ -75,7 +82,14 @@ extern tokenDefinition_t const TOKENS_REOSC[NUM_TOKENS_REOSC];
extern tokenDefinition_t const TOKENS_HPB[NUM_TOKENS_HPB];
extern tokenDefinition_t const TOKENS_TOMOCHAIN[NUM_TOKENS_TOMOCHAIN];
extern tokenDefinition_t const TOKENS_TOBALABA[NUM_TOKENS_TOBALABA];
extern tokenDefinition_t const TOKENS_DEXON[NUM_TOKENS_DEXON];
extern tokenDefinition_t const TOKENS_VOLTA[NUM_TOKENS_VOLTA];
extern tokenDefinition_t const TOKENS_EWC[NUM_TOKENS_EWC];
extern tokenDefinition_t const TOKENS_ARTIS_SIGMA1[NUM_TOKENS_ARTIS_SIGMA1];
extern tokenDefinition_t const TOKENS_ARTIS_TAU1[NUM_TOKENS_ARTIS_TAU1];
extern tokenDefinition_t const TOKENS_WEBCHAIN[NUM_TOKENS_WEBCHAIN];
extern tokenDefinition_t const TOKENS_THUNDERCORE[NUM_TOKENS_THUNDERCORE];
#endif
#endif /* HAVE_TOKENS_LIST */
#endif /* _TOKENS_H_ */

BIN
thundercore.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
volta.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

BIN
webchain.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB