diff --git a/common/protob/messages-cardano.proto b/common/protob/messages-cardano.proto index caaae15e9..2c2fdee6f 100644 --- a/common/protob/messages-cardano.proto +++ b/common/protob/messages-cardano.proto @@ -538,6 +538,7 @@ message CardanoSignMessage { required CardanoDerivationType derivation_type = 3; required uint32 network_id = 4; // network id - mainnet or testnet optional CardanoAddressType address_type = 5; // one of the CardanoAddressType + optional uint32 protocol_magic = 6; // network's protocol magic - needed for Byron addresses on testnets } /** diff --git a/common/protob/messages-polkadot.proto b/common/protob/messages-polkadot.proto index ba3ff6bba..41252b676 100644 --- a/common/protob/messages-polkadot.proto +++ b/common/protob/messages-polkadot.proto @@ -36,6 +36,7 @@ message PolkadotSignTx { repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node required bytes raw_tx = 2; // serialized raw transaction required string network = 3; // Network name + optional uint32 prefix = 4; // SS58 address-type } /** diff --git a/common/protob/messages-tron.proto b/common/protob/messages-tron.proto index 77ec963fc..742f5c1ae 100644 --- a/common/protob/messages-tron.proto +++ b/common/protob/messages-tron.proto @@ -35,7 +35,7 @@ message TronSignTx { required bytes ref_block_bytes = 2; // Reference block number required bytes ref_block_hash = 3; // Reference block hash required uint64 expiration = 4; // Transaction expiration - optional string data = 5; // Extra transaction info + optional bytes data = 5; // Extra transaction info required TronContract contract = 6; // Contract messages required uint64 timestamp = 7; // UTC timestamp optional uint64 fee_limit = 8; // Fee limit for smartcontracts @@ -63,6 +63,7 @@ message TronSignTx { enum TronResourceCode { BANDWIDTH = 0x00; ENERGY = 0x01; + TRON_POWER = 0x02; } // Freeze TRX balance @@ -116,6 +117,9 @@ message TronSignTx { optional TronWithdrawExpireUnfreezeContract withdraw_expire_unfreeze_contract = 56; optional TronDelegateResourceContract delegate_resource_contract = 57; optional TronUnDelegateResourceContract undelegate_resource_contract = 58; + optional bytes provider = 3; + optional bytes contract_name = 5; + optional uint32 permission_id = 6; } } @@ -128,6 +132,11 @@ message TronSignedTx { optional bytes serialized_tx = 2; // Serialized transaction } +enum TronMessageType { + V1 = 1 [deprecated = true]; + V2 = 2; +} + /** * Request: Ask device to sign message * @next TronMessageSignature @@ -136,6 +145,7 @@ message TronSignedTx { message TronSignMessage { repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node required bytes message = 2; // message to be signed + optional TronMessageType message_type = 3[default = V1]; // message type } /** diff --git a/legacy/buttons.c b/legacy/buttons.c index dfdf2dc9b..da1f9b8bb 100644 --- a/legacy/buttons.c +++ b/legacy/buttons.c @@ -221,6 +221,9 @@ bool waitButtonResponse(uint8_t btn, uint32_t time_out) { timer_out_set(timer_out_oper, 0); return flag; } +#else +// stub implementations +void enableLongPress(bool on) { (void)on; } #endif void buttonUpdate() { diff --git a/legacy/firmware/ada.c b/legacy/firmware/ada.c index 1836596d0..0bbe74d38 100644 --- a/legacy/firmware/ada.c +++ b/legacy/firmware/ada.c @@ -1981,7 +1981,9 @@ bool ada_sign_messages(const CardanoSignMessage *msg, fsm_sendFailure(FailureType_Failure_ProcessError, "Deriving root failed"); return false; } - if (!derive_bytes(&address_params, msg->network_id, MAINNET_PROTOCOL_MAGIC, + if (!derive_bytes(&address_params, msg->network_id, + msg->has_protocol_magic ? msg->protocol_magic + : MAINNET_PROTOCOL_MAGIC, address_bytes, &address_bytes_len)) { return false; } diff --git a/legacy/firmware/config.c b/legacy/firmware/config.c index 61a0d8017..46ef46b31 100644 --- a/legacy/firmware/config.c +++ b/legacy/firmware/config.c @@ -467,6 +467,14 @@ void config_init(void) { config_upgrade_v10(); storage_init(&protectPinUiCallback, HW_ENTROPY_DATA, HW_ENTROPY_LEN); + // Restore safetyCheckLevel from soft reset if preserved + uint16_t preserved_level = soft_reset_get_preserved_data(); + if (preserved_level != PRESERVED_RESET_DATA_INVALID) { + if (preserved_level == SafetyCheckLevel_PromptTemporarily) { + safetyCheckLevel = (SafetyCheckLevel)preserved_level; + } + soft_reset_clear_preserved_data(); + } memzero(HW_ENTROPY_DATA, sizeof(HW_ENTROPY_DATA)); // get whether use se flag diff --git a/legacy/firmware/ethereum_onekey.c b/legacy/firmware/ethereum_onekey.c index 8710930b3..97d234002 100644 --- a/legacy/firmware/ethereum_onekey.c +++ b/legacy/firmware/ethereum_onekey.c @@ -55,7 +55,7 @@ static bool eip1559; static struct SHA3_CTX keccak_ctx = {0}; static uint32_t signing_access_list_count; -static EthereumAccessListOneKey signing_access_list[8]; +static EthereumAccessListOneKey signing_access_list[16]; _Static_assert(sizeof(signing_access_list) == sizeof(((EthereumSignTxEIP1559OneKey *)NULL)->access_list), "access_list buffer size mismatch"); diff --git a/legacy/firmware/fsm.c b/legacy/firmware/fsm.c index 1b125c69d..e6f1a94d8 100644 --- a/legacy/firmware/fsm.c +++ b/legacy/firmware/fsm.c @@ -301,9 +301,8 @@ static const CoinInfo *fsm_getCoin(bool has_name, const char *name) { return coin; } -static HDNode *fsm_getDerivedNode(const char *curve, const uint32_t *address_n, - size_t address_n_count, - uint32_t *fingerprint) { +HDNode *fsm_getDerivedNode(const char *curve, const uint32_t *address_n, + size_t address_n_count, uint32_t *fingerprint) { static CONFIDENTIAL HDNode node; if (fingerprint) { *fingerprint = 0; diff --git a/legacy/firmware/fsm_msg_ada.h b/legacy/firmware/fsm_msg_ada.h index 7ff8b3a37..82bafcd78 100644 --- a/legacy/firmware/fsm_msg_ada.h +++ b/legacy/firmware/fsm_msg_ada.h @@ -96,12 +96,12 @@ void fsm_msgCardanoGetAddress(CardanoGetAddress *msg) { if (msg->has_show_display && msg->show_display) { char desc[20] = {0}; char addr_type[32] = {0}; - snprintf(desc, 20, "Cardano %s", _("Address:")); + snprintf(desc, 20, "Cardano %s", _("Address")); if (msg->address_parameters.address_type == CardanoAddressType_BASE) { - snprintf(addr_type, 32, "Base %s", _("Address:")); + snprintf(addr_type, 32, "Base %s", _("Address")); } else if (msg->address_parameters.address_type == CardanoAddressType_REWARD) { - snprintf(addr_type, 32, "Reward %s", _("Address:")); + snprintf(addr_type, 32, "Reward %s", _("Address")); } if (msg->address_parameters.address_n_count > 0) { if (!fsm_layoutAddress(resp->address, addr_type, desc, false, 0, @@ -268,8 +268,9 @@ void fsm_msgCardanoSignMessage(CardanoSignMessage *msg) { "Invalid path"); CHECK_PIN - if ((msg->network_id != 0) && (msg->network_id != 1)) { - fsm_sendFailure(FailureType_Failure_ProcessError, "Invalid Networ ID"); + if (!msg->has_protocol_magic && (msg->network_id != 1)) { + fsm_sendFailure(FailureType_Failure_ProcessError, + "Invalid Network ID, need protocol magic provide"); return; } if (!ada_sign_messages(msg, resp)) { diff --git a/legacy/firmware/fsm_msg_algorand.h b/legacy/firmware/fsm_msg_algorand.h index a58d6490c..00d251caa 100644 --- a/legacy/firmware/fsm_msg_algorand.h +++ b/legacy/firmware/fsm_msg_algorand.h @@ -39,7 +39,7 @@ void fsm_msgAlgorandGetAddress(AlgorandGetAddress *msg) { if (msg->has_show_display && msg->show_display) { char desc[20] = {0}; - snprintf(desc, 20, "%s %s", "Algorand", _("Address:")); + snprintf(desc, 20, "%s %s", "Algorand", _("Address")); if (!fsm_layoutAddress(resp->address, NULL, desc, false, 0, msg->address_n, msg->address_n_count, true, NULL, 0, 0, NULL)) { return; diff --git a/legacy/firmware/fsm_msg_aptos.h b/legacy/firmware/fsm_msg_aptos.h index 90a4d104a..0ab7c7012 100644 --- a/legacy/firmware/fsm_msg_aptos.h +++ b/legacy/firmware/fsm_msg_aptos.h @@ -40,8 +40,8 @@ void fsm_msgAptosGetAddress(const AptosGetAddress *msg) { if (msg->has_show_display && msg->show_display) { char desc[16] = {0}; - strcat(desc, "Aptos"); - strcat(desc, _("Address:")); + strcat(desc, "Aptos "); + strcat(desc, _("Address")); if (!fsm_layoutAddress(resp->address, NULL, desc, false, 0, msg->address_n, msg->address_n_count, true, NULL, 0, 0, NULL)) { return; diff --git a/legacy/firmware/fsm_msg_coin.h b/legacy/firmware/fsm_msg_coin.h index e4a357225..b95ba2b08 100644 --- a/legacy/firmware/fsm_msg_coin.h +++ b/legacy/firmware/fsm_msg_coin.h @@ -308,7 +308,7 @@ void fsm_msgGetAddress(const GetAddress *msg) { } else { strcat(desc, coin->coin_name); strcat(desc, " "); - strlcpy(desc + strlen(desc), _("Address:"), sizeof(desc)); + strlcpy(desc + strlen(desc), _("Address"), sizeof(desc)); } uint32_t multisig_xpub_magic = coin->xpub_magic; diff --git a/legacy/firmware/fsm_msg_conflux.h b/legacy/firmware/fsm_msg_conflux.h index 74dbcfde0..804594856 100644 --- a/legacy/firmware/fsm_msg_conflux.h +++ b/legacy/firmware/fsm_msg_conflux.h @@ -66,7 +66,7 @@ void fsm_msgConfluxGetAddress(const ConfluxGetAddress *msg) { } if (msg->has_show_display && msg->show_display) { char desc[20] = {0}; - snprintf(desc, 20, "%s %s", "Conflux", _("Address:")); + snprintf(desc, 20, "%s %s", "Conflux", _("Address")); if (!fsm_layoutAddress(resp->address, NULL, desc, false, 0, msg->address_n, msg->address_n_count, false, NULL, 0, 0, NULL)) { return; diff --git a/legacy/firmware/fsm_msg_cosmos.h b/legacy/firmware/fsm_msg_cosmos.h index d25ff1768..da83ed3b5 100644 --- a/legacy/firmware/fsm_msg_cosmos.h +++ b/legacy/firmware/fsm_msg_cosmos.h @@ -59,7 +59,7 @@ void fsm_msgCosmosGetAddress(CosmosGetAddress *msg) { strcat(desc, "Cosmos"); } strcat(desc, " "); - strcat(desc, _("Address:")); + strcat(desc, _("Address")); if (!fsm_layoutAddress(resp->address, NULL, desc, false, 0, msg->address_n, msg->address_n_count, true, NULL, 0, 0, NULL)) { return; diff --git a/legacy/firmware/fsm_msg_dynex.h b/legacy/firmware/fsm_msg_dynex.h index db5d0cd81..007f999e9 100644 --- a/legacy/firmware/fsm_msg_dynex.h +++ b/legacy/firmware/fsm_msg_dynex.h @@ -34,8 +34,8 @@ void fsm_msgDnxGetAddress(const DnxGetAddress* msg) { resp->has_address = true; if (msg->has_show_display && msg->show_display) { char desc[12] = {0}; - strcat(desc, "Dnx"); - strcat(desc, _("Address:")); + strcat(desc, "Dnx "); + strcat(desc, _("Address")); if (!fsm_layoutAddress(resp->address, NULL, desc, false, 0, msg->address_n, msg->address_n_count, true, NULL, 0, 0, NULL)) { return; diff --git a/legacy/firmware/fsm_msg_ethereum.h b/legacy/firmware/fsm_msg_ethereum.h index 27069c3ca..366290f4e 100644 --- a/legacy/firmware/fsm_msg_ethereum.h +++ b/legacy/firmware/fsm_msg_ethereum.h @@ -228,12 +228,12 @@ void fsm_msgEthereumGetAddress(const EthereumGetAddress *msg) { if (msg->has_show_display && msg->show_display) { char desc[257] = {0}; const char *chain_name = NULL; - strlcpy(desc, "Address:", sizeof(desc)); + // strlcpy(desc, "Address:", sizeof(desc)); if (strlen(network->name) == 0) { ASSIGN_ETHEREUM_NAME(chain_name, network->chain_id) - snprintf(desc, 257, "%s %s", chain_name, _("Address:")); + snprintf(desc, 257, "%s %s", chain_name, _("Address")); } else { - snprintf(desc, 257, "%s %s", network->name, _("Address:")); + snprintf(desc, 257, "%s %s", network->name, _("Address")); } if (!fsm_layoutAddress(resp->address, NULL, desc, false, 0, msg->address_n, diff --git a/legacy/firmware/fsm_msg_ethereum_onekey.h b/legacy/firmware/fsm_msg_ethereum_onekey.h index 6455fde8d..e74ddd83e 100644 --- a/legacy/firmware/fsm_msg_ethereum_onekey.h +++ b/legacy/firmware/fsm_msg_ethereum_onekey.h @@ -185,7 +185,7 @@ void fsm_msgEthereumGetAddressOneKey(const EthereumGetAddressOneKey *msg) { } else { ASSIGN_ETHEREUM_NAME(chain_name, 0); // unknown chain } - snprintf(desc, 32, "%s %s", chain_name, _("Address:")); + snprintf(desc, 32, "%s %s", chain_name, _("Address")); if (!fsm_layoutAddress(resp->address, NULL, desc, false, 0, msg->address_n, msg->address_n_count, true, NULL, 0, 0, NULL)) { return; diff --git a/legacy/firmware/fsm_msg_filecoin.h b/legacy/firmware/fsm_msg_filecoin.h index 1af3c8da2..b00b30702 100644 --- a/legacy/firmware/fsm_msg_filecoin.h +++ b/legacy/firmware/fsm_msg_filecoin.h @@ -44,7 +44,7 @@ void fsm_msgFilecoinGetAddress(const FilecoinGetAddress *msg) { if (!get_filecoin_addr(pk, resp)) return; if (msg->has_show_display && msg->show_display) { char desc[20] = {0}; - snprintf(desc, 20, "%s %s", "Filecoin", _("Address:")); + snprintf(desc, 20, "%s %s", "Filecoin", _("Address")); if (!fsm_layoutAddress(resp->address, NULL, desc, false, 0, msg->address_n, msg->address_n_count, true, NULL, 0, 0, NULL)) { return; diff --git a/legacy/firmware/fsm_msg_kaspa.h b/legacy/firmware/fsm_msg_kaspa.h index 6072f8beb..89c369106 100644 --- a/legacy/firmware/fsm_msg_kaspa.h +++ b/legacy/firmware/fsm_msg_kaspa.h @@ -45,8 +45,8 @@ void fsm_msgKaspaGetAddress(const KaspaGetAddress *msg) { if (msg->has_show_display && msg->show_display) { char desc[16] = {0}; - strcat(desc, "Kaspa"); - strcat(desc, _("Address:")); + strcat(desc, "Kaspa "); + strcat(desc, _("Address")); if (!fsm_layoutAddress(resp->address, NULL, desc, false, 0, msg->address_n, msg->address_n_count, true, NULL, 0, 0, NULL)) { return; diff --git a/legacy/firmware/fsm_msg_near.h b/legacy/firmware/fsm_msg_near.h index 6091e63a0..a5066bad4 100644 --- a/legacy/firmware/fsm_msg_near.h +++ b/legacy/firmware/fsm_msg_near.h @@ -39,8 +39,8 @@ void fsm_msgNearGetAddress(NearGetAddress *msg) { if (msg->has_show_display && msg->show_display) { char desc[16] = {0}; - strcat(desc, "Near"); - strcat(desc, _("Address:")); + strcat(desc, "Near "); + strcat(desc, _("Address")); if (!fsm_layoutAddress(resp->address, NULL, desc, false, 0, msg->address_n, msg->address_n_count, true, NULL, 0, 0, NULL)) { return; diff --git a/legacy/firmware/fsm_msg_nem.h b/legacy/firmware/fsm_msg_nem.h index 3a4cac45e..64520b390 100755 --- a/legacy/firmware/fsm_msg_nem.h +++ b/legacy/firmware/fsm_msg_nem.h @@ -62,9 +62,7 @@ void fsm_msgNEMGetAddress(NEMGetAddress *msg) { if (msg->has_show_display && msg->show_display) { char desc[16]; - strlcpy(desc, network, sizeof(desc)); - strlcat(desc, ":", sizeof(desc)); - + snprintf(desc, 16, "%s %s", network, _("Address")); if (!fsm_layoutAddress(resp->address, NULL, desc, true, 0, msg->address_n, msg->address_n_count, false, NULL, 0, 0, NULL)) { return; diff --git a/legacy/firmware/fsm_msg_nervos.h b/legacy/firmware/fsm_msg_nervos.h index 6a1108494..d7f736804 100644 --- a/legacy/firmware/fsm_msg_nervos.h +++ b/legacy/firmware/fsm_msg_nervos.h @@ -39,8 +39,8 @@ void fsm_msgNervosGetAddress(const NervosGetAddress *msg) { msg->network); if (msg->has_show_display && msg->show_display) { char desc[16] = {0}; - strcat(desc, "Nervos"); - strcat(desc, _("Address:")); + strcat(desc, "Nervos "); + strcat(desc, _("Address")); if (!fsm_layoutAddress(resp->address, NULL, desc, false, 0, msg->address_n, msg->address_n_count, false, NULL, 0, 0, NULL)) { return; diff --git a/legacy/firmware/fsm_msg_nexa.h b/legacy/firmware/fsm_msg_nexa.h index 4fe246b9a..38f7d42e1 100644 --- a/legacy/firmware/fsm_msg_nexa.h +++ b/legacy/firmware/fsm_msg_nexa.h @@ -36,8 +36,8 @@ void fsm_msgNexaGetAddress(const NexaGetAddress *msg) { if (msg->has_show_display && msg->show_display) { char desc[16] = {0}; - strcat(desc, "Nexa"); - strcat(desc, _("Address:")); + strcat(desc, "Nexa "); + strcat(desc, _("Address")); if (!fsm_layoutAddress(resp->address, NULL, desc, false, 0, msg->address_n, msg->address_n_count, true, NULL, 0, 0, NULL)) { return; diff --git a/legacy/firmware/fsm_msg_polkadot.h b/legacy/firmware/fsm_msg_polkadot.h index 436d89a96..c523d8d4c 100644 --- a/legacy/firmware/fsm_msg_polkadot.h +++ b/legacy/firmware/fsm_msg_polkadot.h @@ -39,20 +39,20 @@ void fsm_msgPolkadotGetAddress(PolkadotGetAddress *msg) { res = secret_from_seed_cardano_ledger(seed, 64, ledger_secret); if (res != 1) { fsm_sendFailure(FailureType_Failure_ProcessError, - _("Unexpected failure in Ledger derivation")); + "Unexpected failure in Ledger derivation"); return; } res = hdnode_from_secret_cardano(ledger_secret, &node); if (res != 1) { fsm_sendFailure(FailureType_Failure_ProcessError, - _("Unexpected failure in constructing polkadot node")); + "Unexpected failure in constructing polkadot node"); return; } if (hdnode_private_ckd_cached(&node, msg->address_n, msg->address_n_count, NULL) == 0) { fsm_sendFailure(FailureType_Failure_ProcessError, - _("Failed to derive private key")); + "Failed to derive private key"); return; } ed25519_publickey(node.private_key, node.public_key + 1); @@ -68,7 +68,7 @@ void fsm_msgPolkadotGetAddress(PolkadotGetAddress *msg) { strcat(desc, msg->network); desc[0] = desc[0] - ('a' - 'A'); strcat(desc, " "); - strcat(desc, _("Address:")); + strcat(desc, _("Address")); if (!fsm_layoutAddress(resp->address, NULL, desc, false, 0, msg->address_n, msg->address_n_count, true, NULL, 0, 0, NULL)) { return; @@ -99,27 +99,27 @@ void fsm_msgPolkadotSignTx(const PolkadotSignTx *msg) { res = secret_from_seed_cardano_ledger(seed, 64, ledger_secret); if (res != 1) { fsm_sendFailure(FailureType_Failure_ProcessError, - _("Unexpected failure in Ledger derivation")); + "Unexpected failure in Ledger derivation"); return; } res = hdnode_from_secret_cardano(ledger_secret, &node); if (res != 1) { fsm_sendFailure(FailureType_Failure_ProcessError, - _("Unexpected failure in constructing Polkadot node")); + "Unexpected failure in constructing Polkadot node"); return; } if (hdnode_private_ckd_cached(&node, msg->address_n, msg->address_n_count, NULL) == 0) { fsm_sendFailure(FailureType_Failure_ProcessError, - _("Failed to derive private key")); + "Failed to derive private key"); return; } ed25519_publickey(node.private_key, node.public_key + 1); if (!polkadot_sign_tx(msg, &node, resp)) { - fsm_sendFailure(FailureType_Failure_DataError, _("Signing failed")); + fsm_sendFailure(FailureType_Failure_DataError, "Signing failed"); layoutHome(); return; } diff --git a/legacy/firmware/fsm_msg_ripple.h b/legacy/firmware/fsm_msg_ripple.h index b6ffad075..f4ba6ff02 100644 --- a/legacy/firmware/fsm_msg_ripple.h +++ b/legacy/firmware/fsm_msg_ripple.h @@ -43,8 +43,8 @@ void fsm_msgRippleGetAddress(RippleGetAddress *msg) { } if (msg->has_show_display && msg->show_display) { char desc[16] = {0}; - strcat(desc, "Ripple"); - strcat(desc, _("Address:")); + strcat(desc, "Ripple "); + strcat(desc, _("Address")); if (!fsm_layoutAddress(resp->address, NULL, desc, false, 0, msg->address_n, msg->address_n_count, false, NULL, 0, 0, NULL)) { return; diff --git a/legacy/firmware/fsm_msg_solana.h b/legacy/firmware/fsm_msg_solana.h index 6aa26c5c4..bded7bdda 100644 --- a/legacy/firmware/fsm_msg_solana.h +++ b/legacy/firmware/fsm_msg_solana.h @@ -36,8 +36,7 @@ void fsm_msgSolanaGetAddress(const SolanaGetAddress *msg) { if (msg->has_show_display && msg->show_display) { char desc[16] = {0}; - strcat(desc, "Solana"); - strcat(desc, _("Address:")); + snprintf(desc, 16, "%s %s", "Solana", _("Address")); if (!fsm_layoutAddress(resp->address, NULL, desc, false, 0, msg->address_n, msg->address_n_count, false, NULL, 0, 0, NULL)) { return; diff --git a/legacy/firmware/fsm_msg_starcoin.h b/legacy/firmware/fsm_msg_starcoin.h index 7e586df21..cc8557694 100644 --- a/legacy/firmware/fsm_msg_starcoin.h +++ b/legacy/firmware/fsm_msg_starcoin.h @@ -39,7 +39,7 @@ void fsm_msgStarcoinGetAddress(const StarcoinGetAddress *msg) { if (msg->has_show_display && msg->show_display) { char desc[20] = {0}; - snprintf(desc, 20, "%s %s", "Starcoin", _("Address:")); + snprintf(desc, 20, "%s %s", "Starcoin", _("Address")); if (!fsm_layoutAddress(resp->address, NULL, desc, false, 0, msg->address_n, msg->address_n_count, true, NULL, 0, 0, NULL)) { return; diff --git a/legacy/firmware/fsm_msg_stellar.h b/legacy/firmware/fsm_msg_stellar.h index 55f88e41c..9ae208dde 100644 --- a/legacy/firmware/fsm_msg_stellar.h +++ b/legacy/firmware/fsm_msg_stellar.h @@ -24,7 +24,7 @@ static bool fsm_stellarCheckPath(uint32_t address_n_count, } if (config_getSafetyCheckLevel() == SafetyCheckLevel_Strict) { - fsm_sendFailure(FailureType_Failure_DataError, _("Forbidden key path")); + fsm_sendFailure(FailureType_Failure_DataError, "Forbidden key path"); return false; } @@ -43,21 +43,22 @@ void fsm_msgStellarGetAddress(const StellarGetAddress *msg) { return; } - const HDNode *node = stellar_deriveNode(msg->address_n, msg->address_n_count); + HDNode *node = stellar_deriveNode(msg->address_n, msg->address_n_count); if (!node) { fsm_sendFailure(FailureType_Failure_ProcessError, - _("Failed to derive private key")); + "Failed to derive private key"); layoutHome(); return; } - + hdnode_fill_public_key(node); stellar_publicAddressAsStr(node->public_key + 1, resp->address, sizeof(resp->address)); if (msg->has_show_display && msg->show_display) { - if (!fsm_layoutAddress(resp->address, NULL, _("Public account ID"), false, - 0, msg->address_n, msg->address_n_count, true, NULL, - 0, 0, NULL)) { + char desc[16] = {0}; + snprintf(desc, 16, "%s %s", "XLM", _("Address")); + if (!fsm_layoutAddress(resp->address, NULL, desc, false, 0, msg->address_n, + msg->address_n_count, true, NULL, 0, 0, NULL)) { return; } } @@ -78,7 +79,7 @@ void fsm_msgStellarSignTx(const StellarSignTx *msg) { if (!stellar_signingInit(msg)) { fsm_sendFailure(FailureType_Failure_ProcessError, - _("Failed to derive private key")); + "Failed to derive private key"); layoutHome(); return; } @@ -92,24 +93,25 @@ void fsm_msgStellarSignTx(const StellarSignTx *msg) { msg_write(MessageType_MessageType_StellarTxOpRequest, resp); } +#define GO_AHEAD \ + do { \ + if (stellar_allOperationsConfirmed()) { \ + RESP_INIT(StellarSignedTx); \ + stellar_fillSignedTx(resp); \ + msg_write(MessageType_MessageType_StellarSignedTx, resp); \ + layoutHome(); \ + } else { \ + RESP_INIT(StellarTxOpRequest); \ + msg_write(MessageType_MessageType_StellarTxOpRequest, resp); \ + } \ + } while (0); + void fsm_msgStellarCreateAccountOp(const StellarCreateAccountOp *msg) { CHECK_UNLOCKED if (!stellar_confirmCreateAccountOp(msg)) return; - if (stellar_allOperationsConfirmed()) { - RESP_INIT(StellarSignedTx); - - stellar_fillSignedTx(resp); - msg_write(MessageType_MessageType_StellarSignedTx, resp); - layoutHome(); - } - // Request the next operation to sign - else { - RESP_INIT(StellarTxOpRequest); - - msg_write(MessageType_MessageType_StellarTxOpRequest, resp); - } + GO_AHEAD } void fsm_msgStellarPaymentOp(const StellarPaymentOp *msg) { @@ -119,19 +121,7 @@ void fsm_msgStellarPaymentOp(const StellarPaymentOp *msg) { if (!stellar_confirmPaymentOp(msg)) return; // Last operation was confirmed, send a StellarSignedTx - if (stellar_allOperationsConfirmed()) { - RESP_INIT(StellarSignedTx); - - stellar_fillSignedTx(resp); - msg_write(MessageType_MessageType_StellarSignedTx, resp); - layoutHome(); - } - // Request the next operation to sign - else { - RESP_INIT(StellarTxOpRequest); - - msg_write(MessageType_MessageType_StellarTxOpRequest, resp); - } + GO_AHEAD } void fsm_msgStellarPathPaymentStrictReceiveOp( @@ -140,19 +130,7 @@ void fsm_msgStellarPathPaymentStrictReceiveOp( if (!stellar_confirmPathPaymentStrictReceiveOp(msg)) return; - if (stellar_allOperationsConfirmed()) { - RESP_INIT(StellarSignedTx); - - stellar_fillSignedTx(resp); - msg_write(MessageType_MessageType_StellarSignedTx, resp); - layoutHome(); - } - // Request the next operation to sign - else { - RESP_INIT(StellarTxOpRequest); - - msg_write(MessageType_MessageType_StellarTxOpRequest, resp); - } + GO_AHEAD } void fsm_msgStellarPathPaymentStrictSendOp( @@ -161,19 +139,7 @@ void fsm_msgStellarPathPaymentStrictSendOp( if (!stellar_confirmPathPaymentStrictSendOp(msg)) return; - if (stellar_allOperationsConfirmed()) { - RESP_INIT(StellarSignedTx); - - stellar_fillSignedTx(resp); - msg_write(MessageType_MessageType_StellarSignedTx, resp); - layoutHome(); - } - // Request the next operation to sign - else { - RESP_INIT(StellarTxOpRequest); - - msg_write(MessageType_MessageType_StellarTxOpRequest, resp); - } + GO_AHEAD } void fsm_msgStellarManageBuyOfferOp(const StellarManageBuyOfferOp *msg) { @@ -181,19 +147,7 @@ void fsm_msgStellarManageBuyOfferOp(const StellarManageBuyOfferOp *msg) { if (!stellar_confirmManageBuyOfferOp(msg)) return; - if (stellar_allOperationsConfirmed()) { - RESP_INIT(StellarSignedTx); - - stellar_fillSignedTx(resp); - msg_write(MessageType_MessageType_StellarSignedTx, resp); - layoutHome(); - } - // Request the next operation to sign - else { - RESP_INIT(StellarTxOpRequest); - - msg_write(MessageType_MessageType_StellarTxOpRequest, resp); - } + GO_AHEAD } void fsm_msgStellarManageSellOfferOp(const StellarManageSellOfferOp *msg) { @@ -201,19 +155,7 @@ void fsm_msgStellarManageSellOfferOp(const StellarManageSellOfferOp *msg) { if (!stellar_confirmManageSellOfferOp(msg)) return; - if (stellar_allOperationsConfirmed()) { - RESP_INIT(StellarSignedTx); - - stellar_fillSignedTx(resp); - msg_write(MessageType_MessageType_StellarSignedTx, resp); - layoutHome(); - } - // Request the next operation to sign - else { - RESP_INIT(StellarTxOpRequest); - - msg_write(MessageType_MessageType_StellarTxOpRequest, resp); - } + GO_AHEAD } void fsm_msgStellarCreatePassiveSellOfferOp( @@ -222,19 +164,7 @@ void fsm_msgStellarCreatePassiveSellOfferOp( if (!stellar_confirmCreatePassiveSellOfferOp(msg)) return; - if (stellar_allOperationsConfirmed()) { - RESP_INIT(StellarSignedTx); - - stellar_fillSignedTx(resp); - msg_write(MessageType_MessageType_StellarSignedTx, resp); - layoutHome(); - } - // Request the next operation to sign - else { - RESP_INIT(StellarTxOpRequest); - - msg_write(MessageType_MessageType_StellarTxOpRequest, resp); - } + GO_AHEAD } void fsm_msgStellarSetOptionsOp(const StellarSetOptionsOp *msg) { @@ -242,19 +172,7 @@ void fsm_msgStellarSetOptionsOp(const StellarSetOptionsOp *msg) { if (!stellar_confirmSetOptionsOp(msg)) return; - if (stellar_allOperationsConfirmed()) { - RESP_INIT(StellarSignedTx); - - stellar_fillSignedTx(resp); - msg_write(MessageType_MessageType_StellarSignedTx, resp); - layoutHome(); - } - // Request the next operation to sign - else { - RESP_INIT(StellarTxOpRequest); - - msg_write(MessageType_MessageType_StellarTxOpRequest, resp); - } + GO_AHEAD } void fsm_msgStellarChangeTrustOp(const StellarChangeTrustOp *msg) { @@ -262,19 +180,7 @@ void fsm_msgStellarChangeTrustOp(const StellarChangeTrustOp *msg) { if (!stellar_confirmChangeTrustOp(msg)) return; - if (stellar_allOperationsConfirmed()) { - RESP_INIT(StellarSignedTx); - - stellar_fillSignedTx(resp); - msg_write(MessageType_MessageType_StellarSignedTx, resp); - layoutHome(); - } - // Request the next operation to sign - else { - RESP_INIT(StellarTxOpRequest); - - msg_write(MessageType_MessageType_StellarTxOpRequest, resp); - } + GO_AHEAD } void fsm_msgStellarAllowTrustOp(const StellarAllowTrustOp *msg) { @@ -282,19 +188,7 @@ void fsm_msgStellarAllowTrustOp(const StellarAllowTrustOp *msg) { if (!stellar_confirmAllowTrustOp(msg)) return; - if (stellar_allOperationsConfirmed()) { - RESP_INIT(StellarSignedTx); - - stellar_fillSignedTx(resp); - msg_write(MessageType_MessageType_StellarSignedTx, resp); - layoutHome(); - } - // Request the next operation to sign - else { - RESP_INIT(StellarTxOpRequest); - - msg_write(MessageType_MessageType_StellarTxOpRequest, resp); - } + GO_AHEAD } void fsm_msgStellarAccountMergeOp(const StellarAccountMergeOp *msg) { @@ -302,19 +196,7 @@ void fsm_msgStellarAccountMergeOp(const StellarAccountMergeOp *msg) { if (!stellar_confirmAccountMergeOp(msg)) return; - if (stellar_allOperationsConfirmed()) { - RESP_INIT(StellarSignedTx); - - stellar_fillSignedTx(resp); - msg_write(MessageType_MessageType_StellarSignedTx, resp); - layoutHome(); - } - // Request the next operation to sign - else { - RESP_INIT(StellarTxOpRequest); - - msg_write(MessageType_MessageType_StellarTxOpRequest, resp); - } + GO_AHEAD } void fsm_msgStellarManageDataOp(const StellarManageDataOp *msg) { @@ -322,19 +204,7 @@ void fsm_msgStellarManageDataOp(const StellarManageDataOp *msg) { if (!stellar_confirmManageDataOp(msg)) return; - if (stellar_allOperationsConfirmed()) { - RESP_INIT(StellarSignedTx); - - stellar_fillSignedTx(resp); - msg_write(MessageType_MessageType_StellarSignedTx, resp); - layoutHome(); - } - // Request the next operation to sign - else { - RESP_INIT(StellarTxOpRequest); - - msg_write(MessageType_MessageType_StellarTxOpRequest, resp); - } + GO_AHEAD } void fsm_msgStellarBumpSequenceOp(const StellarBumpSequenceOp *msg) { @@ -342,17 +212,5 @@ void fsm_msgStellarBumpSequenceOp(const StellarBumpSequenceOp *msg) { if (!stellar_confirmBumpSequenceOp(msg)) return; - if (stellar_allOperationsConfirmed()) { - RESP_INIT(StellarSignedTx); - - stellar_fillSignedTx(resp); - msg_write(MessageType_MessageType_StellarSignedTx, resp); - layoutHome(); - } - // Request the next operation to sign - else { - RESP_INIT(StellarTxOpRequest); - - msg_write(MessageType_MessageType_StellarTxOpRequest, resp); - } + GO_AHEAD } diff --git a/legacy/firmware/fsm_msg_sui.h b/legacy/firmware/fsm_msg_sui.h index 4f4a2a2c7..4de657eb1 100644 --- a/legacy/firmware/fsm_msg_sui.h +++ b/legacy/firmware/fsm_msg_sui.h @@ -38,8 +38,8 @@ void fsm_msgSuiGetAddress(const SuiGetAddress *msg) { if (msg->has_show_display && msg->show_display) { char desc[16] = {0}; - strcat(desc, "Sui"); - strcat(desc, _("Address:")); + strcat(desc, "Sui "); + strcat(desc, _("Address")); if (!fsm_layoutAddress(resp->address, NULL, desc, false, 0, msg->address_n, msg->address_n_count, true, NULL, 0, 0, NULL)) { return; diff --git a/legacy/firmware/fsm_msg_tron.h b/legacy/firmware/fsm_msg_tron.h index bd5057124..6818fcecf 100644 --- a/legacy/firmware/fsm_msg_tron.h +++ b/legacy/firmware/fsm_msg_tron.h @@ -68,8 +68,8 @@ void fsm_msgTronGetAddress(TronGetAddress *msg) { if (msg->has_show_display && msg->show_display) { char desc[16] = {0}; - strcat(desc, "Tron"); - strcat(desc, _("Address:")); + strcat(desc, "Tron "); + strcat(desc, _("Address")); if (!fsm_layoutAddress(resp->address, NULL, desc, false, 0, msg->address_n, msg->address_n_count, true, NULL, 0, 0, NULL)) { return; diff --git a/legacy/firmware/language.c b/legacy/firmware/language.c index bd8bb1b6d..f6aec5e28 100644 --- a/legacy/firmware/language.c +++ b/legacy/firmware/language.c @@ -57,6 +57,8 @@ const char *const languages[][2] = { {"Account:", "账号:"}, // layout2.c {"Active", "激活"}, + {"Add Trust:", "添加信任:"}, + {"Address", "地址"}, // fsm_msg_coin.h fsm_msg_lisk.h {"Address:", "地址:"}, // @@ -74,6 +76,7 @@ const char *const languages[][2] = { // u2f.c {"Already registered.", "已注册"}, {"Amount", "金额"}, + {"Amount:", "金额:"}, // u2f.c {"Another U2F device", "另外的U2F设备"}, // layout2.c @@ -94,6 +97,7 @@ const char *const languages[][2] = { {"Are you sure to reset?", "确定要重置吗?"}, // ada.c {"Asset Fingerprint:", "资产指纹:"}, + {"Asset Issuer:", "资产发行人:"}, // u2f.c {"Authenticate", "认证"}, {"Authenticate U2F Security\nKey?", "要认证 U2F 安全密钥吗?"}, @@ -430,6 +434,7 @@ const char *const languages[][2] = { // layout2.c {"Fee included:", "已包含手续费"}, {"Fee payer", "手续费支付方"}, + {"Fee:", "手续费:"}, // layout2.c {"Finish", "完成"}, // fsm.c @@ -526,6 +531,7 @@ const char *const languages[][2] = { {"Message", "消息"}, // ethereum.c {"Message Hash", "消息哈希值"}, + {"Missing Memo/Tag during exchange deposits may result in fund loss.", "向交易所充值时如未填写 Memo/Tag, 可能会导致资金丢失."}, // {"Mnemonic", "助记词"}, // cosmos.c @@ -649,6 +655,7 @@ const char *const languages[][2] = { {"Receiver:", "接收方:"}, // {"Recipient", "接收方"}, + {"Recipient is a known energy rental service provider address.", "收款地址是已知的能量租赁服务提供商."}, // {"Recovery Phrase ", "助记词"}, {"Recovery Phrase is the \nonly way to restore the \nprivate keys that own " @@ -670,6 +677,7 @@ const char *const languages[][2] = { {"Rekey to", "重新授权给"}, // layout2.c {"Remaining times:", "剩余次数"}, + {"Remove Trust:", "移除信任:"}, // {"Reset", "重置设备"}, // @@ -722,6 +730,7 @@ const char *const languages[][2] = { {"Send to:", "发送给:"}, // {"Sender", "发送方"}, + {"Sequence Number:", "序号:"}, // protect.c {"Set PIN", "设置 PIN 码"}, // layout2.c @@ -753,6 +762,7 @@ const char *const languages[][2] = { {"Skip pin check:", "免密支付"}, // {"Sleep Mode", "休眠模式"}, + {"Source Account:", "源账户:"}, // cosmos.c {"Source Address", "来源地址"}, {"Source Coins", "来源金额"}, @@ -772,6 +782,7 @@ const char *const languages[][2] = { {"Switch Input (Number)", "切换输入法 (数字)"}, {"Switch Input (Symbol)", "切换输入法 (符号)"}, {"Switch Input (Uppercase)", "切换输入法 (大写字母)"}, + {"TRON Energy Rental", "TRON 能量租赁"}, // protect.c {"The device is reset,\nrestart now!", "设备已重置, 请重启!"}, {"The following transaction output contains tokens.", @@ -824,8 +835,10 @@ const char *const languages[][2] = { // menu_list.c {"Trezor Compat", "Trezor 兼容性"}, {"Trezor Compatibility", "Trezor 兼容性"}, + {"Trust Account", "信认账户:"}, // {"Try again.", "请重试."}, + {"Tx Source:", "Tx 源:"}, // algo {"Txn type", "类型"}, // cosmos.c diff --git a/legacy/firmware/polkadot.c b/legacy/firmware/polkadot.c index 501716208..c0f12c58a 100644 --- a/legacy/firmware/polkadot.c +++ b/legacy/firmware/polkadot.c @@ -130,40 +130,18 @@ static bool layoutPolkadotSign(char *signer) { return result; } -static bool get_signer_address(const PolkadotSignTx *msg, const HDNode *node, - char *address) { - uint16_t addressType = 0; - if (!strncmp(msg->network, "polkadot", 8)) { - addressType = 0; - } else if (!strncmp(msg->network, "kusama", 6)) { - addressType = 2; - } else if (!strncmp(msg->network, "astar", 5)) { - addressType = 5; - } else if (!strncmp(msg->network, "westend", 7)) { - addressType = 42; - } else if (!strncmp(msg->network, "joystream", 9)) { - addressType = 126; - } else if (!strncmp(msg->network, "manta", 5)) { - addressType = 77; - } else { - return false; - } - polkadot_get_address_from_public_key(node->public_key + 1, address, - addressType); - return true; -} +extern uint16_t getAddressType(void); bool polkadot_sign_tx(const PolkadotSignTx *msg, const HDNode *node, PolkadotSignedTx *resp) { - char signer[64] = {0}; - if (!get_signer_address(msg, node, signer)) { - fsm_sendFailure(FailureType_Failure_ActionCancelled, "Signing cancelled"); - layoutHome(); - return false; - } - + memzero(polkadot_network, sizeof(polkadot_network)); memcpy(polkadot_network, msg->network, strlen(msg->network) + 1); - parser_error_t ret = polkadot_tx_parse(msg->raw_tx.bytes, msg->raw_tx.size); + parser_error_t ret = + polkadot_tx_parse(msg->raw_tx.bytes, msg->raw_tx.size, msg->has_prefix, + msg->has_prefix ? msg->prefix : 0); + char signer[64] = {0}; + polkadot_get_address_from_public_key(node->public_key + 1, signer, + getAddressType()); if (ret == parser_unexpected_callIndex) { polkadot_network[0] -= 32; if (!layoutBlindSign(polkadot_network, false, NULL, signer, diff --git a/legacy/firmware/polkadot/parser.c b/legacy/firmware/polkadot/parser.c index 0f95793bc..2bf87a607 100644 --- a/legacy/firmware/polkadot/parser.c +++ b/legacy/firmware/polkadot/parser.c @@ -41,7 +41,14 @@ static parser_error_t polkadot_parser_parse_dispatch(parser_context_t *ctx, parser_error_t polkadot_parser_parse(parser_context_t *ctx, const uint8_t *data, size_t dataLen, parser_tx_t *tx_obj) { - __address_type = _detectAddressType(ctx); + int8_t ret = detectNetworkMetadata(); + if (ret < 0) { + if (ctx->has_preset_address_type) { + setAddressType(ctx->preset_address_type); + } else { + setAddressType(42); + } + } parser_error_t err = POLKADOT_PARSER_PARSE_V26; if (err != parser_ok && err != parser_unexpected_callIndex) { err = POLKADOT_PARSER_PARSE_V25; diff --git a/legacy/firmware/polkadot/parser_common.h b/legacy/firmware/polkadot/parser_common.h index 1a990ed2a..114997981 100644 --- a/legacy/firmware/polkadot/parser_common.h +++ b/legacy/firmware/polkadot/parser_common.h @@ -43,6 +43,8 @@ typedef struct { uint16_t bufferLen; uint16_t offset; parser_tx_t *tx_obj; + bool has_preset_address_type; + uint16_t preset_address_type; } parser_context_t; #endif diff --git a/legacy/firmware/polkadot/parser_impl.c b/legacy/firmware/polkadot/parser_impl.c index a18f5ead1..6bf6da86e 100644 --- a/legacy/firmware/polkadot/parser_impl.c +++ b/legacy/firmware/polkadot/parser_impl.c @@ -19,6 +19,13 @@ parser_error_t _polkadot_readTx(parser_context_t *c, parser_tx_t *v, CHECK_ERROR(_readCompactIndex(c, &v->nonce)) CHECK_ERROR(_readCompactBalance(c, &v->tip)) if (mode_enabled) { + if (c->bufferLen - c->offset > + 74) { // 74 is the length without assetId but with mode + CHECK_ERROR(_readCompactInt(c, &v->assetId)) + // uint64_t assetId; + // CHECK_ERROR(_getValue(&v->assetId, &assetId)); + // TODO: when assetId is not 0, read XCM asset location + } CHECK_ERROR(_readu8(c, &v->mode)) } CHECK_ERROR(_readu32(c, &v->specVersion)) @@ -33,12 +40,5 @@ parser_error_t _polkadot_readTx(parser_context_t *c, parser_tx_t *v, return parser_unexpected_value; } } - if (c->offset < c->bufferLen) { - return parser_unexpected_unparsed_bytes; - } - - if (c->offset > c->bufferLen) { - return parser_unexpected_buffer_end; - } return parser_ok; } diff --git a/legacy/firmware/polkadot/parser_impl.h b/legacy/firmware/polkadot/parser_impl.h index 938f012f9..e5963347d 100644 --- a/legacy/firmware/polkadot/parser_impl.h +++ b/legacy/firmware/polkadot/parser_impl.h @@ -172,11 +172,11 @@ parser_error_t _polkadot_readTx(parser_context_t *c, parser_tx_t *v, bool mode_enabled); // parser_error_t _checkVersions(parser_context_t *c); -uint16_t _getAddressType(void); - +uint16_t getAddressType(void); +void setAddressType(uint16_t addressType); parser_error_t _readCompactIndex(parser_context_t *c, pd_CompactIndex_t *v); -uint16_t _detectAddressType(const parser_context_t *c); +int8_t detectNetworkMetadata(void); parser_error_t _toStringCompactInt(const compactInt_t *c, uint8_t decimalPlaces, bool trimTrailingZeros, char postfix[], diff --git a/legacy/firmware/polkadot/parser_impl_common.c b/legacy/firmware/polkadot/parser_impl_common.c index a3bbc335a..756fcd8bf 100644 --- a/legacy/firmware/polkadot/parser_impl_common.c +++ b/legacy/firmware/polkadot/parser_impl_common.c @@ -338,38 +338,51 @@ parser_error_t _toStringCompactBalance(const pd_CompactBalance_t *v, uint16_t __address_type; -uint16_t _getAddressType() { return __address_type; } +uint16_t getAddressType(void) { return __address_type; } +void setAddressType(uint16_t addressType) { __address_type = addressType; } -uint16_t _detectAddressType(const parser_context_t *c) { - (void)c; +int8_t detectNetworkMetadata(void) { memset(__polkadot_ticker, 0, sizeof(__polkadot_ticker)); - if (!strncmp(polkadot_network, "polkadot", 8)) { + if (!strcmp(polkadot_network, "polkadot")) { __polkadot_decimal = COIN_AMOUNT_DECIMAL_PLACES; memcpy(__polkadot_ticker, COIN_TICKER, 4); - return 0; - } else if (!strncmp(polkadot_network, "kusama", 6)) { + setAddressType(0); + } else if (!strcmp(polkadot_network, "kusama")) { __polkadot_decimal = COIN_AMOUNT_DECIMAL_PLACES_12; memcpy(__polkadot_ticker, KUSAMA_COIN_TICKER, 4); - return 2; - } else if (!strncmp(polkadot_network, "astar", 5)) { + setAddressType(2); + } else if (!strcmp(polkadot_network, "astar")) { __polkadot_decimal = COIN_AMOUNT_DECIMAL_PLACES_18; memcpy(__polkadot_ticker, ASTAR_COIN_TICKER, 5); - return 5; - } else if (!strncmp(polkadot_network, "westend", 7)) { + setAddressType(5); + } else if (!strcmp(polkadot_network, "westend")) { __polkadot_decimal = COIN_AMOUNT_DECIMAL_PLACES_12; memcpy(__polkadot_ticker, WESTEND_COIN_TICKER, 4); - return 42; - } else if (!strncmp(polkadot_network, "joystream", 9)) { + setAddressType(42); + } else if (!strcmp(polkadot_network, "joystream")) { __polkadot_decimal = COIN_AMOUNT_DECIMAL_PLACES; memcpy(__polkadot_ticker, JOY_COIN_TICKER, 4); - return 126; - } else if (!strncmp(polkadot_network, "manta", 5)) { + setAddressType(126); + } else if (!strcmp(polkadot_network, "manta")) { __polkadot_decimal = COIN_AMOUNT_DECIMAL_PLACES_18; memcpy(__polkadot_ticker, MANTA_COIN_TICKER, 6); - return 77; + setAddressType(77); + } else if (!strcmp(polkadot_network, "hydration")) { + __polkadot_decimal = COIN_AMOUNT_DECIMAL_PLACES_12; + memcpy(__polkadot_ticker, HYDRATION_COIN_TICKER, 4); + setAddressType(0); + } else if (!strcmp(polkadot_network, "bifrost") || + !strcmp(polkadot_network, "bifrost-ksm")) { + __polkadot_decimal = COIN_AMOUNT_DECIMAL_PLACES_12; + memcpy(__polkadot_ticker, BIFROST_COIN_TICKER, 4); + setAddressType(0); + } else { + __polkadot_decimal = 0; + memcpy(__polkadot_ticker, " UNKN", 5); + memcpy(polkadot_network, "unkn Chain", 11); + return -1; } - - return 42; + return 0; } //////////////////////////////////////////////////////////////// diff --git a/legacy/firmware/polkadot/parser_txdef.h b/legacy/firmware/polkadot/parser_txdef.h index b371cff11..897da5209 100644 --- a/legacy/firmware/polkadot/parser_txdef.h +++ b/legacy/firmware/polkadot/parser_txdef.h @@ -23,6 +23,8 @@ typedef struct { pd_Hash_t blockHash; pd_NestCallIdx_t nestCallIdx; + compactInt_t assetId; + // TODO: XCM asset location } parser_tx_t; #endif diff --git a/legacy/firmware/polkadot/substrate/substrate_coin.h b/legacy/firmware/polkadot/substrate/substrate_coin.h index 0970dac66..74bc395df 100644 --- a/legacy/firmware/polkadot/substrate/substrate_coin.h +++ b/legacy/firmware/polkadot/substrate/substrate_coin.h @@ -18,5 +18,6 @@ #define ASTAR_COIN_TICKER " ASTR" #define JOY_COIN_TICKER " JOY" #define MANTA_COIN_TICKER " MANTA" - +#define BIFROST_COIN_TICKER " BNC" +#define HYDRATION_COIN_TICKER " HDX" #endif diff --git a/legacy/firmware/polkadot/substrate/substrate_dispatch_V26.c b/legacy/firmware/polkadot/substrate/substrate_dispatch_V26.c index 42f2474a0..9dc056892 100644 --- a/legacy/firmware/polkadot/substrate/substrate_dispatch_V26.c +++ b/legacy/firmware/polkadot/substrate/substrate_dispatch_V26.c @@ -42,7 +42,9 @@ parser_error_t _readMethod_V26(parser_context_t* c, uint8_t moduleIdx, case 1031: // Kusama previous used version case 1280: /* module 5 call 0 */ // Polkadot/ joystream case 1287: /* module 5 call 7 */ // Polkadot previous used version - case 2560: /* module 10 call 0 */ // Manta + case 1792: /* module 7 call 0 */ // hydration + case 2560: /* module 10 call 0 */ // Manta, polkadot-assets-hub, + // kusama-assets-hub, bifrost/-ksm case 7936: /* module 31 call 0 */ // Astar case 7943: /* module 31 call 7 */ // Astar previous used version CHECK_ERROR(_readMethod_balances_transfer_allow_death_V26( @@ -50,21 +52,27 @@ parser_error_t _readMethod_V26(parser_context_t* c, uint8_t moduleIdx, break; case 1026: /* module 4 call 2 */ // kusama, westend case 1282: /* module 5 call 2 */ // Polkadot only - case 2562: /* module 10 call 2 */ // Manta + case 1794: /* module 7 call 2 */ // hydration + case 2562: /* module 10 call 2 */ // Manta, polkadot-assets-hub, + // kusama-assets-hub, bifrost/-ksm case 7938: /* module 31 call 2 */ // Astar CHECK_ERROR(_readMethod_balances_force_transfer_V26( c, &method->nested.balances_force_transfer_V26)) break; case 1027: /* module 4 call 3 */ // kusama, westend case 1283: /* module 5 call 3 */ // Polkadot/ joystream - case 2563: /* module 10 call 3 */ // Manta + case 1795: /* module 7 call 3 */ // hydration + case 2563: /* module 10 call 3 */ // Manta, polkadot-assets-hub, + // kusama-assets-hub, bifrost/-ksm case 7939: /* module 31 call 3 */ // Astar CHECK_ERROR(_readMethod_balances_transfer_keep_alive_V26( c, &method->nested.balances_transfer_keep_alive_V26)) break; case 1028: /* module 4 call 4 */ // kusama, westend case 1284: /* module 5 call 4 */ // Polkadot/ joystream - case 2564: /* module 10 call 4 */ // Manta + case 1796: /* module 7 call 4 */ // hydration + case 2564: /* module 10 call 4 */ // Manta, polkadot-assets-hub, + // kusama-assets-hub, bifrost/-ksm case 7940: /* module 31 call 4 */ // Astar CHECK_ERROR(_readMethod_balances_transfer_all_V26( c, &method->nested.balances_transfer_all_V26)) @@ -81,7 +89,8 @@ const char* _getMethod_ModuleName_V26(uint8_t moduleIdx) { switch (moduleIdx) { case 4: // Kusama / Westend case 5: // Polkadot / Joystream - case 10: // Manta + case 7: // Hydration + case 10: // Manta, polkadot-assets-hub, kusama-assets-hub, bifrost-p/k case 31: // Astar return STR_MO_BALANCES; default: @@ -99,22 +108,26 @@ const char* _getMethod_Name_V26(uint8_t moduleIdx, uint8_t callIdx) { case 1031: case 1280: case 1287: + case 1792: case 2560: case 7936: case 7943: return STR_ME_TRANSFER_ALLOW_DEATH; case 1026: case 1282: + case 1794: case 2562: case 7938: return STR_ME_FORCE_TRANSFER; case 1027: case 1283: + case 1795: case 2563: case 7939: return STR_ME_TRANSFER_KEEP_ALIVE; case 1028: case 1284: + case 1796: case 2564: case 7940: return STR_ME_TRANSFER_ALL; @@ -132,22 +145,26 @@ uint8_t _getMethod_NumItems_V26(uint8_t moduleIdx, uint8_t callIdx) { case 1031: case 1280: case 1287: + case 1792: case 2560: case 7936: case 7943: return 2; case 1026: case 1282: + case 1794: case 2562: case 7938: return 3; case 1027: case 1283: + case 1795: case 2563: case 7939: return 2; case 1028: case 1284: + case 1796: case 2564: case 7940: return 2; @@ -166,6 +183,7 @@ const char* _getMethod_ItemName_V26(uint8_t moduleIdx, uint8_t callIdx, case 1031: case 1280: case 1287: + case 1792: case 2560: case 7936: case 7943: @@ -178,6 +196,7 @@ const char* _getMethod_ItemName_V26(uint8_t moduleIdx, uint8_t callIdx, break; case 1026: case 1282: + case 1794: case 2562: case 7938: switch (itemIdx) { @@ -191,6 +210,7 @@ const char* _getMethod_ItemName_V26(uint8_t moduleIdx, uint8_t callIdx, break; case 1027: case 1283: + case 1795: case 2563: case 7939: switch (itemIdx) { @@ -202,6 +222,7 @@ const char* _getMethod_ItemName_V26(uint8_t moduleIdx, uint8_t callIdx, break; case 1028: case 1284: + case 1796: case 2564: case 7940: switch (itemIdx) { @@ -226,6 +247,7 @@ parser_error_t _getMethod_ItemValue_V26(pd_Method_V26_t* m, uint8_t moduleIdx, case 1031: case 1280: case 1287: + case 1792: case 2560: case 7936: case 7943: @@ -244,6 +266,7 @@ parser_error_t _getMethod_ItemValue_V26(pd_Method_V26_t* m, uint8_t moduleIdx, break; case 1026: case 1282: + case 1794: case 2562: case 7938: switch (itemIdx) { @@ -265,6 +288,7 @@ parser_error_t _getMethod_ItemValue_V26(pd_Method_V26_t* m, uint8_t moduleIdx, break; case 1027: case 1283: + case 1795: case 2563: case 7939: switch (itemIdx) { @@ -282,6 +306,7 @@ parser_error_t _getMethod_ItemValue_V26(pd_Method_V26_t* m, uint8_t moduleIdx, break; case 1028: case 1284: + case 1796: case 2564: case 7940: switch (itemIdx) { @@ -316,19 +341,23 @@ bool _getMethod_IsNestingSupported_V26(uint8_t moduleIdx, uint8_t callIdx) { case 1031: case 1280: case 1287: + case 1792: case 2560: case 7936: case 7943: case 1026: case 1282: + case 1794: case 2562: case 7938: case 1027: case 1283: + case 1795: case 2563: case 7939: case 1028: case 1284: + case 1796: case 2564: case 7940: return true; diff --git a/legacy/firmware/polkadot/substrate/substrate_types.c b/legacy/firmware/polkadot/substrate/substrate_types.c index 612f9c245..2a54c6f0a 100644 --- a/legacy/firmware/polkadot/substrate/substrate_types.c +++ b/legacy/firmware/polkadot/substrate/substrate_types.c @@ -665,10 +665,12 @@ parser_error_t _readTupleAccountIdData(parser_context_t* c, CHECK_ERROR(_readData(c, &v->data)); return parser_ok; } + parser_error_t _readAccountIdLookupOfT(parser_context_t* c, pd_AccountIdLookupOfT_t* v) { CHECK_INPUT() - if (strncmp(polkadot_network, "joystream", 9) != 0) { + if (!(strcmp(polkadot_network, "joystream") == 0 || + strcmp(polkadot_network, "hydration") == 0)) { CHECK_ERROR(_preadUInt8(c, &v->value)) } switch (v->value) { diff --git a/legacy/firmware/polkadot/tx.c b/legacy/firmware/polkadot/tx.c index a0fbdd52f..20a17797b 100644 --- a/legacy/firmware/polkadot/tx.c +++ b/legacy/firmware/polkadot/tx.c @@ -6,7 +6,11 @@ static parser_tx_t tx_obj = {0}; static parser_context_t ctx_parsed_tx = {0}; -parser_error_t polkadot_tx_parse(const uint8_t *data, size_t dataLen) { +parser_error_t polkadot_tx_parse(const uint8_t *data, size_t dataLen, + bool has_preset_address_type, + uint16_t preset_address_type) { + ctx_parsed_tx.has_preset_address_type = has_preset_address_type; + ctx_parsed_tx.preset_address_type = preset_address_type; uint8_t err = polkadot_parser_parse(&ctx_parsed_tx, data, dataLen, &tx_obj); if (err != parser_ok) { return err; diff --git a/legacy/firmware/polkadot/tx.h b/legacy/firmware/polkadot/tx.h index 41ce34bea..e741c7957 100644 --- a/legacy/firmware/polkadot/tx.h +++ b/legacy/firmware/polkadot/tx.h @@ -5,7 +5,9 @@ #include "common_defs.h" #include "parser_common.h" -parser_error_t polkadot_tx_parse(const uint8_t *data, size_t dataLen); +parser_error_t polkadot_tx_parse(const uint8_t *data, size_t dataLen, + bool has_preset_address_type, + uint16_t preset_address_type); /// Return the number of items in the transaction zxerr_t polkadot_tx_getNumItems(uint8_t *num_items); @@ -15,4 +17,4 @@ zxerr_t polkadot_tx_getItem(int8_t displayIdx, char *outKey, uint16_t outKeyLen, char *outValue, uint16_t outValueLen, uint8_t pageIdx, uint8_t *pageCount); -#endif \ No newline at end of file +#endif diff --git a/legacy/firmware/protect.h b/legacy/firmware/protect.h index de2bbee91..c3803accf 100644 --- a/legacy/firmware/protect.h +++ b/legacy/firmware/protect.h @@ -70,4 +70,14 @@ extern bool protectAbortedByInitialize; extern bool protectAbortedByInitializeOnboarding; extern bool protectAbortedByTimeout; extern bool protectAbortedBySleep; + +#define WAIT_KEY_OR_ABORT(timeout, mode, key) \ + do { \ + key = protectWaitKey(timeout, mode); \ + if (protectAbortedByInitialize || protectAbortedByCancel) { \ + enableLongPress(false); \ + return false; \ + } \ + } while (0) + #endif diff --git a/legacy/firmware/protob/messages-ethereum-onekey.options b/legacy/firmware/protob/messages-ethereum-onekey.options index aa6484be9..c2a06da8c 100755 --- a/legacy/firmware/protob/messages-ethereum-onekey.options +++ b/legacy/firmware/protob/messages-ethereum-onekey.options @@ -14,10 +14,10 @@ EthereumSignTxEIP1559OneKey.gas_limit max_size:32 EthereumSignTxEIP1559OneKey.to max_size:43 EthereumSignTxEIP1559OneKey.value max_size:32 EthereumSignTxEIP1559OneKey.data_initial_chunk max_size:1024 -EthereumSignTxEIP1559OneKey.access_list max_count:8 +EthereumSignTxEIP1559OneKey.access_list max_count:16 EthereumAccessListOneKey.address max_size:43 -EthereumAccessListOneKey.storage_keys max_count:8 max_size:32 +EthereumAccessListOneKey.storage_keys max_count:16 max_size:32 EthereumTxRequestOneKey.signature_r max_size:32 EthereumTxRequestOneKey.signature_s max_size:32 diff --git a/legacy/firmware/protob/messages-tron.options b/legacy/firmware/protob/messages-tron.options index bb64c219d..65ea94637 100644 --- a/legacy/firmware/protob/messages-tron.options +++ b/legacy/firmware/protob/messages-tron.options @@ -17,10 +17,10 @@ TronUnfreezeBalanceContract.receiver_address max_size:36 TronWithdrawBalanceContract.owner_address max_size:36 TronDelegateResourceContract.receiver_address max_size:36 TronUnDelegateResourceContract.receiver_address max_size:36 - - +TronContract.provider max_size: 64 +TronContract.contract_name max_size: 64 TronSignedTx.signature max_size:65 -TronSignedTx.serialized_tx max_size:2048 +TronSignedTx.serialized_tx max_size:2946 TronSignMessage.address_n max_count:8 TronSignMessage.message max_size:1024 diff --git a/legacy/firmware/startup.S b/legacy/firmware/startup.S index cf410fab8..03fcfe4e3 100644 --- a/legacy/firmware/startup.S +++ b/legacy/firmware/startup.S @@ -51,11 +51,19 @@ reset_handler: isb .setup_as_unprivileged: + // Preserve data across soft reset - load from fixed address before RAM clear + ldr r0, =_preserved_reset_data_addr // Address for preserved data (defined in linker script) + ldr r11, [r0] // r11 = preserve value in register (survives RAM clear) + ldr r0, =_ram_start // r0 - point to beginning of SRAM ldr r1, =_ram_end // r1 - point to byte after the end of SRAM ldr r2, =0 // r2 - the byte-sized value to be written bl memset_reg + // Restore preserved data after RAM clear + ldr r0, =_preserved_reset_data_addr // Address for preserved data + str r11, [r0] // Store preserved value back to memory + // copy .data section from flash to SRAM ldr r0, =_data // dst addr ldr r1, =_data_loadaddr // src addr diff --git a/legacy/firmware/stellar.c b/legacy/firmware/stellar.c old mode 100755 new mode 100644 index 5de84a742..c8b9a23da --- a/legacy/firmware/stellar.c +++ b/legacy/firmware/stellar.c @@ -35,8 +35,10 @@ #include "base32.h" #include "bignum.h" #include "bip32.h" +#include "buttons.h" #include "config.h" #include "crypto.h" +#include "curves.h" #include "fonts.h" #include "fsm.h" #include "gettext.h" @@ -50,13 +52,16 @@ static bool stellar_signing = false; static StellarTransaction stellar_activeTx; - +static bool memo_type_none = false; +static CONFIDENTIAL HDNode *stellar_node = NULL; +#define ARRAY_SIZE(arr) sizeof(arr) / sizeof(arr[0]) /* * Starts the signing process and parses the transaction header */ bool stellar_signingInit(const StellarSignTx *msg) { memzero(&stellar_activeTx, sizeof(StellarTransaction)); stellar_signing = true; + memo_type_none = false; // Initialize signing context sha256_Init(&(stellar_activeTx.sha256_ctx)); @@ -80,10 +85,12 @@ bool stellar_signingInit(const StellarSignTx *msg) { stellar_hashupdate_bytes(tx_type_bytes, sizeof(tx_type_bytes)); // Public key comes from deriving the specified account path - const HDNode *node = stellar_deriveNode(msg->address_n, msg->address_n_count); + HDNode *node = stellar_deriveNode(msg->address_n, msg->address_n_count); if (!node) { return false; } + hdnode_fill_public_key(node); + stellar_node = (HDNode *)node; memcpy(&(stellar_activeTx.signing_pubkey), node->public_key + 1, sizeof(stellar_activeTx.signing_pubkey)); @@ -134,7 +141,7 @@ bool stellar_signingInit(const StellarSignTx *msg) { break; default: fsm_sendFailure(FailureType_Failure_DataError, - _("Stellar invalid memo type")); + "Stellar invalid memo type"); return false; } @@ -158,13 +165,15 @@ bool stellar_signingInit(const StellarSignTx *msg) { void stellar_signingAbort(void) { if (stellar_signing) { stellar_signing = false; + stellar_node = NULL; + memo_type_none = false; layoutHome(); } } static void stellar_signingFail(const char *reason) { if (!reason) { - reason = _("Unknown error"); + reason = "Unknown error"; } fsm_sendFailure(FailureType_Failure_ProcessError, reason); @@ -184,16 +193,6 @@ bool stellar_confirmSourceAccount(bool has_source_account, return false; } - const char **str_addr_rows = stellar_lineBreakAddress(bytes); - - stellar_layoutTransactionDialog(_("Op src account OK?"), NULL, - str_addr_rows[0], str_addr_rows[1], - str_addr_rows[2]); - if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) { - stellar_signingFail(_("User canceled")); - return false; - } - // Hash: source account stellar_hashupdate_address(bytes); @@ -205,7 +204,7 @@ bool stellar_confirmCreateAccountOp(const StellarCreateAccountOp *msg) { if (!stellar_confirmSourceAccount(msg->has_source_account, msg->source_account)) { - stellar_signingFail(_("Source account error")); + stellar_signingFail("Source account error"); return false; } @@ -215,26 +214,24 @@ bool stellar_confirmCreateAccountOp(const StellarCreateAccountOp *msg) { // Validate new account and convert to bytes uint8_t new_account_bytes[STELLAR_KEY_SIZE] = {0}; if (!stellar_getAddressBytes(msg->new_account, new_account_bytes)) { - stellar_signingFail(_("Invalid new account address")); + stellar_signingFail("Invalid new account address"); return false; } - const char **str_addr_rows = stellar_lineBreakAddress(new_account_bytes); - // Amount being funded - char str_amount_line[32] = {0}; char str_amount[32] = {0}; stellar_format_stroops(msg->starting_balance, str_amount, sizeof(str_amount)); + strlcat(str_amount, " XLM", sizeof(str_amount)); - strlcpy(str_amount_line, _("With "), sizeof(str_amount_line)); - strlcat(str_amount_line, str_amount, sizeof(str_amount_line)); - strlcat(str_amount_line, _(" XLM"), sizeof(str_amount_line)); - - stellar_layoutTransactionDialog(_("Create account: "), str_addr_rows[0], - str_addr_rows[1], str_addr_rows[2], - str_amount_line); - if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) { - stellar_signingFail(_("User canceled")); + const char *const expeted_keys[] = { + msg->has_source_account ? "Source Account" : NULL, "New Account", + "Amount"}; + const char *const values[] = {msg->source_account, msg->new_account, + str_amount}; + stellar_activeTx.confirmed_operations++; + if (!stellar_layoutTransactionDialog(ARRAY_SIZE(expeted_keys), expeted_keys, + values)) { + stellar_signingFail("User canceled"); return false; } @@ -243,7 +240,6 @@ bool stellar_confirmCreateAccountOp(const StellarCreateAccountOp *msg) { // Hash: starting amount stellar_hashupdate_uint64(msg->starting_balance); - stellar_activeTx.confirmed_operations++; return true; } @@ -252,7 +248,7 @@ bool stellar_confirmPaymentOp(const StellarPaymentOp *msg) { if (!stellar_confirmSourceAccount(msg->has_source_account, msg->source_account)) { - stellar_signingFail(_("Source account error")); + stellar_signingFail("Source account error"); return false; } @@ -263,33 +259,44 @@ bool stellar_confirmPaymentOp(const StellarPaymentOp *msg) { uint8_t destination_account_bytes[STELLAR_KEY_SIZE] = {0}; if (!stellar_getAddressBytes(msg->destination_account, destination_account_bytes)) { - stellar_signingFail(_("Invalid destination account")); + stellar_signingFail("Invalid destination account"); return false; } - const char **str_addr_rows = - stellar_lineBreakAddress(destination_account_bytes); + char str_asset[32] = {0}; + memzero(str_asset, sizeof(str_asset)); + stellar_format_asset(&(msg->asset), str_asset, sizeof(str_asset)); - // To: G... - char str_to[32] = {0}; - strlcpy(str_to, _("To: "), sizeof(str_to)); - strlcat(str_to, str_addr_rows[0], sizeof(str_to)); - - char str_asset_row[32] = {0}; - memzero(str_asset_row, sizeof(str_asset_row)); - stellar_format_asset(&(msg->asset), str_asset_row, sizeof(str_asset_row)); - - char str_pay_amount[32] = {0}; + // char str_pay_amount[32] = {0}; char str_amount[32] = {0}; stellar_format_stroops(msg->amount, str_amount, sizeof(str_amount)); - - strlcpy(str_pay_amount, _("Pay "), sizeof(str_pay_amount)); - strlcat(str_pay_amount, str_amount, sizeof(str_pay_amount)); - - stellar_layoutTransactionDialog(str_pay_amount, str_asset_row, str_to, - str_addr_rows[1], str_addr_rows[2]); - if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) { - stellar_signingFail(_("User canceled")); + // strlcpy(str_pay_amount, __("Pay "), sizeof(str_pay_amount)); + strlcat(str_amount, " ", sizeof(str_amount)); + strlcat(str_amount, str_asset, sizeof(str_amount)); + bool display_issuer = + msg->asset.type != StellarAssetType_NATIVE && msg->asset.has_issuer; + if (memo_type_none) { + layoutDialogCenterAdapterV2(NULL, &bmp_icon_warning, &bmp_bottom_left_close, + &bmp_bottom_right_arrow, NULL, NULL, NULL, NULL, + NULL, NULL, + _("Missing Memo/Tag during exchange deposits " + "may result in fund loss.")); + if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) { + stellar_signingFail("User canceled"); + return false; + } + } + const char *const expeted_keys[] = { + _("Amount:"), _("Send to:"), + msg->has_source_account ? _("Source Account:") : NULL, + display_issuer ? _("Asset Issuer:") : NULL}; + const char *const values[] = {str_amount, msg->destination_account, + msg->source_account, msg->asset.issuer}; + // At this point, the operation is confirmed + stellar_activeTx.confirmed_operations++; + if (!stellar_layoutTransactionDialog(ARRAY_SIZE(expeted_keys), expeted_keys, + values)) { + stellar_signingFail("User canceled"); return false; } @@ -300,8 +307,6 @@ bool stellar_confirmPaymentOp(const StellarPaymentOp *msg) { // amount (even though amount is signed it doesn't matter for hashing) stellar_hashupdate_uint64(msg->amount); - // At this point, the operation is confirmed - stellar_activeTx.confirmed_operations++; return true; } @@ -311,7 +316,7 @@ bool stellar_confirmPathPaymentStrictReceiveOp( if (!stellar_confirmSourceAccount(msg->has_source_account, msg->source_account)) { - stellar_signingFail(_("Source account error")); + stellar_signingFail("Source account error"); return false; } @@ -322,16 +327,16 @@ bool stellar_confirmPathPaymentStrictReceiveOp( uint8_t destination_account_bytes[STELLAR_KEY_SIZE] = {0}; if (!stellar_getAddressBytes(msg->destination_account, destination_account_bytes)) { - stellar_signingFail(_("Invalid destination account")); + stellar_signingFail("Invalid destination account"); return false; } - const char **str_dest_rows = - stellar_lineBreakAddress(destination_account_bytes); + // const char **str_dest_rows = + // stellar_lineBreakAddress(destination_account_bytes); - // To: G... - char str_to[32] = {0}; - strlcpy(str_to, _("To: "), sizeof(str_to)); - strlcat(str_to, str_dest_rows[0], sizeof(str_to)); + // // To: G... + // char str_to[32] = {0}; + // strlcpy(str_to, __("To: "), sizeof(str_to)); + // strlcat(str_to, str_dest_rows[0], sizeof(str_to)); char str_send_asset[32] = {0}; char str_dest_asset[32] = {0}; @@ -341,42 +346,51 @@ bool stellar_confirmPathPaymentStrictReceiveOp( sizeof(str_dest_asset)); char str_pay_amount[32] = {0}; - char str_amount[32] = {0}; - stellar_format_stroops(msg->destination_amount, str_amount, - sizeof(str_amount)); + // char str_amount[32] = {0}; + stellar_format_stroops(msg->destination_amount, str_pay_amount, + sizeof(str_pay_amount)); - strlcpy(str_pay_amount, _("Path Pay "), sizeof(str_pay_amount)); - strlcat(str_pay_amount, str_amount, sizeof(str_pay_amount)); + // strlcpy(str_pay_amount, __("Path Pay "), sizeof(str_pay_amount)); + strlcat(str_pay_amount, " ", sizeof(str_pay_amount)); + strlcat(str_pay_amount, str_dest_asset, sizeof(str_pay_amount)); // Confirm what the receiver will get /* Path Pay 100 JPY (G1234ABCDEF) - To: G.... - .... - .... */ - stellar_layoutTransactionDialog(str_pay_amount, str_dest_asset, str_to, - str_dest_rows[1], str_dest_rows[2]); - if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) { - stellar_signingFail(_("User canceled")); - return false; - } // Confirm what the sender is using to pay char str_source_amount[32] = {0}; - char str_source_number[32] = {0}; - stellar_format_stroops(msg->send_max, str_source_number, - sizeof(str_source_number)); - - strlcpy(str_source_amount, _("Pay Using "), sizeof(str_source_amount)); - strlcat(str_source_amount, str_source_number, sizeof(str_source_amount)); - - stellar_layoutTransactionDialog(str_source_amount, str_send_asset, - _("This is the max"), - _("amount debited from your"), _("account.")); - if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) { - stellar_signingFail(_("User canceled")); + // char str_source_number[32] = {0}; + stellar_format_stroops(msg->send_max, str_source_amount, + sizeof(str_source_amount)); + + // strlcpy(str_source_amount, __("Pay Using "), sizeof(str_source_amount)); + strlcat(str_source_amount, " ", sizeof(str_source_amount)); + strlcat(str_source_amount, str_send_asset, sizeof(str_source_amount)); + bool display_source_asset_issuer = + msg->send_asset.type != StellarAssetType_NATIVE && + msg->send_asset.has_issuer; + bool display_des_asset_issuer = + msg->destination_asset.type != StellarAssetType_NATIVE && + msg->destination_asset.has_issuer; + const char *const expeted_keys[] = { + "To", + "Max Pay Amount", + display_source_asset_issuer ? "Asset Issuer" : NULL, + "Receive Amout", + display_des_asset_issuer ? "Asset Issuer" : NULL, + msg->has_source_account ? "Source Account" : NULL}; + const char *const values[] = { + msg->destination_account, str_source_amount, + msg->send_asset.issuer, str_pay_amount, + msg->destination_asset.issuer, msg->source_account}; + // At this point, the operation is confirmed + stellar_activeTx.confirmed_operations++; + if (!stellar_layoutTransactionDialog(ARRAY_SIZE(expeted_keys), expeted_keys, + values)) { + stellar_signingFail("User canceled"); return false; } // Note: no confirmation for intermediate steps since they don't impact the @@ -399,8 +413,6 @@ bool stellar_confirmPathPaymentStrictReceiveOp( stellar_hashupdate_asset(&(msg->paths[i])); } - // At this point, the operation is confirmed - stellar_activeTx.confirmed_operations++; return true; } @@ -410,7 +422,7 @@ bool stellar_confirmPathPaymentStrictSendOp( if (!stellar_confirmSourceAccount(msg->has_source_account, msg->source_account)) { - stellar_signingFail(_("Source account error")); + stellar_signingFail("Source account error"); return false; } @@ -421,16 +433,9 @@ bool stellar_confirmPathPaymentStrictSendOp( uint8_t destination_account_bytes[STELLAR_KEY_SIZE] = {0}; if (!stellar_getAddressBytes(msg->destination_account, destination_account_bytes)) { - stellar_signingFail(_("Invalid destination account")); + stellar_signingFail("Invalid destination account"); return false; } - const char **str_dest_rows = - stellar_lineBreakAddress(destination_account_bytes); - - // To: G... - char str_to[32] = {0}; - strlcpy(str_to, _("To: "), sizeof(str_to)); - strlcat(str_to, str_dest_rows[0], sizeof(str_to)); char str_send_asset[32] = {0}; char str_dest_asset[32] = {0}; @@ -440,41 +445,51 @@ bool stellar_confirmPathPaymentStrictSendOp( sizeof(str_dest_asset)); char str_pay_amount[32] = {0}; - char str_amount[32] = {0}; - stellar_format_stroops(msg->destination_min, str_amount, sizeof(str_amount)); - - strlcat(str_pay_amount, str_amount, sizeof(str_pay_amount)); + // char str_amount[32] = {0}; + stellar_format_stroops(msg->destination_min, str_pay_amount, + sizeof(str_pay_amount)); + strlcat(str_pay_amount, " ", sizeof(str_pay_amount)); + strlcat(str_pay_amount, str_dest_asset, sizeof(str_pay_amount)); // Confirm what the receiver will get /* Path Pay at least 100.0000000 JPY (G1234ABCDEF) - To: G.... - .... - .... */ - stellar_layoutTransactionDialog(_("Path Pay at least"), str_pay_amount, - str_dest_asset, str_to, str_dest_rows[1]); - if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) { - stellar_signingFail(_("User canceled")); - return false; - } // Confirm what the sender is using to pay char str_source_amount[32] = {0}; - char str_source_number[32] = {0}; - stellar_format_stroops(msg->send_amount, str_source_number, - sizeof(str_source_number)); - - strlcpy(str_source_amount, _("Pay Using "), sizeof(str_source_amount)); - strlcat(str_source_amount, str_source_number, sizeof(str_source_amount)); - - stellar_layoutTransactionDialog( - str_dest_rows[2], str_source_amount, str_send_asset, - _("This is the amount debited"), _("from your account.")); - if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) { - stellar_signingFail(_("User canceled")); + // char str_source_number[32] = {0}; + stellar_format_stroops(msg->send_amount, str_source_amount, + sizeof(str_source_amount)); + + // strlcpy(str_source_amount, __("Pay Using "), sizeof(str_source_amount)); + strlcat(str_source_amount, " ", sizeof(str_source_amount)); + strlcat(str_source_amount, str_send_asset, sizeof(str_source_amount)); + + bool display_source_asset_issuer = + msg->send_asset.type != StellarAssetType_NATIVE && + msg->send_asset.has_issuer; + bool display_des_asset_issuer = + msg->destination_asset.type != StellarAssetType_NATIVE && + msg->destination_asset.has_issuer; + const char *const expeted_keys[] = { + "To", + "Pay Amount", + display_source_asset_issuer ? "Asset Issuer" : NULL, + "Min Receive Amout", + display_des_asset_issuer ? "Asset Issuer" : NULL, + msg->has_source_account ? "Source Account" : NULL}; + const char *const values[] = { + msg->destination_account, str_source_amount, + msg->send_asset.issuer, str_pay_amount, + msg->destination_asset.issuer, msg->source_account}; + // At this point, the operation is confirmed + stellar_activeTx.confirmed_operations++; + if (!stellar_layoutTransactionDialog(ARRAY_SIZE(expeted_keys), expeted_keys, + values)) { + stellar_signingFail("User canceled"); return false; } // Note: no confirmation for intermediate steps since they don't impact the @@ -497,8 +512,6 @@ bool stellar_confirmPathPaymentStrictSendOp( stellar_hashupdate_asset(&(msg->paths[i])); } - // At this point, the operation is confirmed - stellar_activeTx.confirmed_operations++; return true; } @@ -507,7 +520,7 @@ bool stellar_confirmManageBuyOfferOp(const StellarManageBuyOfferOp *msg) { if (!stellar_confirmSourceAccount(msg->has_source_account, msg->source_account)) { - stellar_signingFail(_("Source account error")); + stellar_signingFail("Source account error"); return false; } @@ -517,39 +530,41 @@ bool stellar_confirmManageBuyOfferOp(const StellarManageBuyOfferOp *msg) { // New Offer / Delete #123 / Update #123 char str_offer[32] = {0}; if (msg->offer_id == 0) { - strlcpy(str_offer, _("New Offer"), sizeof(str_offer)); + strlcpy(str_offer, "New", sizeof(str_offer)); } else { char str_offer_id[20] = {0}; stellar_format_uint64(msg->offer_id, str_offer_id, sizeof(str_offer_id)); if (msg->amount == 0) { - strlcpy(str_offer, _("Delete #"), sizeof(str_offer)); + strlcpy(str_offer, "Delete #", sizeof(str_offer)); } else { - strlcpy(str_offer, _("Update #"), sizeof(str_offer)); + strlcpy(str_offer, "Update #", sizeof(str_offer)); } strlcat(str_offer, str_offer_id, sizeof(str_offer)); } - char str_buying[32] = {0}; - char str_buying_amount[32] = {0}; + char str_buying[64] = {0}; + // char str_buying_amount[32] = {0}; char str_buying_asset[32] = {0}; + // stellar_format_asset(&(msg->buying_asset), str_buying_asset, + // sizeof(str_buying_asset)); + stellar_format_stroops(msg->amount, str_buying, sizeof(str_buying)); stellar_format_asset(&(msg->buying_asset), str_buying_asset, sizeof(str_buying_asset)); - stellar_format_stroops(msg->amount, str_buying_amount, - sizeof(str_buying_amount)); /* Buy 200 XLM (Native Asset) */ - strlcpy(str_buying, _("Buy "), sizeof(str_buying)); - strlcat(str_buying, str_buying_amount, sizeof(str_buying)); + // strlcpy(str_buying, __("Buy "), sizeof(str_buying)); + strlcat(str_buying, " ", sizeof(str_buying)); + strlcat(str_buying, str_buying_asset, sizeof(str_buying)); - char str_selling[32] = {0}; + // char str_selling[32] = {0}; char str_selling_asset[32] = {0}; - char str_price[32] = {0}; + char str_price[64] = {0}; stellar_format_asset(&(msg->selling_asset), str_selling_asset, sizeof(str_selling_asset)); @@ -560,14 +575,34 @@ bool stellar_confirmManageBuyOfferOp(const StellarManageBuyOfferOp *msg) { For 0.675952 Per USD (G12345678) */ - strlcpy(str_selling, _("For "), sizeof(str_selling)); - strlcat(str_selling, str_price, sizeof(str_selling)); - strlcat(str_selling, _(" Per"), sizeof(str_selling)); - - stellar_layoutTransactionDialog(str_offer, str_buying, str_buying_asset, - str_selling, str_selling_asset); - if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) { - stellar_signingFail(_("User canceled")); + // strlcpy(str_selling, __("For "), sizeof(str_selling)); + strlcat(str_price, " /", sizeof(str_price)); + // strlcat(str_selling, __(" Per"), sizeof(str_selling)); + strlcat(str_price, str_selling_asset, sizeof(str_price)); + bool display_selling_asset_issuer = + msg->selling_asset.type != StellarAssetType_NATIVE && + msg->selling_asset.has_issuer; + bool display_buying_asset_issuer = + msg->buying_asset.type != StellarAssetType_NATIVE && + msg->buying_asset.has_issuer; + const char *const expeted_keys[] = { + "Offer Type", + "Buy", + display_buying_asset_issuer ? "Asset Issuer" : NULL, + "Price", + display_selling_asset_issuer ? "Asset Issuer" : NULL, + msg->has_source_account ? "Source Account" : NULL}; + const char *const values[] = {str_offer, + str_buying, + msg->buying_asset.issuer, + str_price, + msg->selling_asset.issuer, + msg->source_account}; + // At this point, the operation is confirmed + stellar_activeTx.confirmed_operations++; + if (!stellar_layoutTransactionDialog(ARRAY_SIZE(expeted_keys), expeted_keys, + values)) { + stellar_signingFail("User canceled"); return false; } @@ -584,8 +619,6 @@ bool stellar_confirmManageBuyOfferOp(const StellarManageBuyOfferOp *msg) { // offer ID stellar_hashupdate_uint64(msg->offer_id); - // At this point, the operation is confirmed - stellar_activeTx.confirmed_operations++; return true; } @@ -594,7 +627,7 @@ bool stellar_confirmManageSellOfferOp(const StellarManageSellOfferOp *msg) { if (!stellar_confirmSourceAccount(msg->has_source_account, msg->source_account)) { - stellar_signingFail(_("Source account error")); + stellar_signingFail("Source account error"); return false; } @@ -604,36 +637,37 @@ bool stellar_confirmManageSellOfferOp(const StellarManageSellOfferOp *msg) { // New Offer / Delete #123 / Update #123 char str_offer[32] = {0}; if (msg->offer_id == 0) { - strlcpy(str_offer, _("New Offer"), sizeof(str_offer)); + strlcpy(str_offer, "New", sizeof(str_offer)); } else { char str_offer_id[20] = {0}; stellar_format_uint64(msg->offer_id, str_offer_id, sizeof(str_offer_id)); if (msg->amount == 0) { - strlcpy(str_offer, _("Delete #"), sizeof(str_offer)); + strlcpy(str_offer, "Delete #", sizeof(str_offer)); } else { - strlcpy(str_offer, _("Update #"), sizeof(str_offer)); + strlcpy(str_offer, "Update #", sizeof(str_offer)); } strlcat(str_offer, str_offer_id, sizeof(str_offer)); } char str_selling[32] = {0}; - char str_sell_amount[32] = {0}; + // char str_sell_amount[32] = {0}; char str_selling_asset[32] = {0}; stellar_format_asset(&(msg->selling_asset), str_selling_asset, sizeof(str_selling_asset)); - stellar_format_stroops(msg->amount, str_sell_amount, sizeof(str_sell_amount)); + stellar_format_stroops(msg->amount, str_selling, sizeof(str_selling)); /* Sell 200 XLM (Native Asset) */ - strlcpy(str_selling, _("Sell "), sizeof(str_selling)); - strlcat(str_selling, str_sell_amount, sizeof(str_selling)); + // strlcpy(str_selling, __("Sell "), sizeof(str_selling)); + strlcat(str_selling, " ", sizeof(str_selling)); + strlcat(str_selling, str_selling_asset, sizeof(str_selling)); - char str_buying[32] = {0}; + // char str_buying[32] = {0}; char str_buying_asset[32] = {0}; char str_price[32] = {0}; @@ -646,17 +680,37 @@ bool stellar_confirmManageSellOfferOp(const StellarManageSellOfferOp *msg) { For 0.675952 Per USD (G12345678) */ - strlcpy(str_buying, _("For "), sizeof(str_buying)); - strlcat(str_buying, str_price, sizeof(str_buying)); - strlcat(str_buying, _(" Per"), sizeof(str_buying)); - - stellar_layoutTransactionDialog(str_offer, str_selling, str_selling_asset, - str_buying, str_buying_asset); - if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) { - stellar_signingFail(_("User canceled")); + // strlcpy(str_buying, __("For "), sizeof(str_buying)); + strlcat(str_price, " /", sizeof(str_price)); + // strlcat(str_buying, __(" Per"), sizeof(str_buying)); + strlcat(str_price, str_buying_asset, sizeof(str_price)); + + bool display_selling_asset_issuer = + msg->selling_asset.type != StellarAssetType_NATIVE && + msg->selling_asset.has_issuer; + bool display_buying_asset_issuer = + msg->buying_asset.type != StellarAssetType_NATIVE && + msg->buying_asset.has_issuer; + const char *const expeted_keys[] = { + "Offer Type", + "Sell", + display_selling_asset_issuer ? "Asset Issuer" : NULL, + "Price", + display_buying_asset_issuer ? "Asset Issuer" : NULL, + msg->has_source_account ? "Source Account" : NULL}; + const char *const values[] = {str_offer, + str_selling, + msg->selling_asset.issuer, + str_price, + msg->buying_asset.issuer, + msg->source_account}; + // At this point, the operation is confirmed + stellar_activeTx.confirmed_operations++; + if (!stellar_layoutTransactionDialog(ARRAY_SIZE(expeted_keys), expeted_keys, + values)) { + stellar_signingFail("User canceled"); return false; } - // Hash selling asset stellar_hashupdate_asset(&(msg->selling_asset)); // buying asset @@ -669,9 +723,6 @@ bool stellar_confirmManageSellOfferOp(const StellarManageSellOfferOp *msg) { stellar_hashupdate_uint32(msg->price_d); // offer ID stellar_hashupdate_uint64(msg->offer_id); - - // At this point, the operation is confirmed - stellar_activeTx.confirmed_operations++; return true; } @@ -681,7 +732,7 @@ bool stellar_confirmCreatePassiveSellOfferOp( if (!stellar_confirmSourceAccount(msg->has_source_account, msg->source_account)) { - stellar_signingFail(_("Source account error")); + stellar_signingFail("Source account error"); return false; } @@ -691,27 +742,28 @@ bool stellar_confirmCreatePassiveSellOfferOp( // New Offer / Delete #123 / Update #123 char str_offer[32] = {0}; if (msg->amount == 0) { - strlcpy(str_offer, _("Delete Passive Offer"), sizeof(str_offer)); + strlcpy(str_offer, "Delete Passive", sizeof(str_offer)); } else { - strlcpy(str_offer, _("New Passive Offer"), sizeof(str_offer)); + strlcpy(str_offer, "New Passive", sizeof(str_offer)); } char str_selling[32] = {0}; - char str_sell_amount[32] = {0}; + // char str_sell_amount[32] = {0}; char str_selling_asset[32] = {0}; stellar_format_asset(&(msg->selling_asset), str_selling_asset, sizeof(str_selling_asset)); - stellar_format_stroops(msg->amount, str_sell_amount, sizeof(str_sell_amount)); + stellar_format_stroops(msg->amount, str_selling, sizeof(str_selling)); /* Sell 200 XLM (Native Asset) */ - strlcpy(str_selling, _("Sell "), sizeof(str_selling)); - strlcat(str_selling, str_sell_amount, sizeof(str_selling)); + // strlcpy(str_selling, __("Sell "), sizeof(str_selling)); + strlcat(str_selling, " ", sizeof(str_selling)); + strlcat(str_selling, str_selling_asset, sizeof(str_selling)); - char str_buying[32] = {0}; + // char str_buying[32] = {0}; char str_buying_asset[32] = {0}; char str_price[32] = {0}; @@ -724,17 +776,43 @@ bool stellar_confirmCreatePassiveSellOfferOp( For 0.675952 Per USD (G12345678) */ - strlcpy(str_buying, _("For "), sizeof(str_buying)); - strlcat(str_buying, str_price, sizeof(str_buying)); - strlcat(str_buying, _(" Per"), sizeof(str_buying)); - - stellar_layoutTransactionDialog(str_offer, str_selling, str_selling_asset, - str_buying, str_buying_asset); - if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) { - stellar_signingFail(_("User canceled")); + // strlcpy(str_buying, __("For "), sizeof(str_buying)); + strlcat(str_price, " /", sizeof(str_price)); + // strlcat(str_buying, __(" Per"), sizeof(str_buying)); + strlcat(str_price, str_buying_asset, sizeof(str_price)); + + // stellar_layoutTransactionDialog(str_offer, str_selling, str_selling_asset, + // str_buying, str_buying_asset); + // if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) { + // stellar_signingFail("User canceled"); + // return false; + // } + bool display_selling_asset_issuer = + msg->selling_asset.type != StellarAssetType_NATIVE && + msg->selling_asset.has_issuer; + bool display_buying_asset_issuer = + msg->buying_asset.type != StellarAssetType_NATIVE && + msg->buying_asset.has_issuer; + const char *const expeted_keys[] = { + "Offer Type", + "Sell", + display_selling_asset_issuer ? "Asset Issuer" : NULL, + "Price", + display_buying_asset_issuer ? "Asset Issuer" : NULL, + msg->has_source_account ? "Source Account" : NULL}; + const char *const values[] = {str_offer, + str_selling, + msg->selling_asset.issuer, + str_price, + msg->buying_asset.issuer, + msg->source_account}; + // At this point, the operation is confirmed + stellar_activeTx.confirmed_operations++; + if (!stellar_layoutTransactionDialog(ARRAY_SIZE(expeted_keys), expeted_keys, + values)) { + stellar_signingFail("User canceled"); return false; } - // Hash selling asset stellar_hashupdate_asset(&(msg->selling_asset)); // buying asset @@ -745,9 +823,6 @@ bool stellar_confirmCreatePassiveSellOfferOp( stellar_hashupdate_uint32(msg->price_n); // denominator stellar_hashupdate_uint32(msg->price_d); - - // At this point, the operation is confirmed - stellar_activeTx.confirmed_operations++; return true; } @@ -756,7 +831,7 @@ bool stellar_confirmSetOptionsOp(const StellarSetOptionsOp *msg) { if (!stellar_confirmSourceAccount(msg->has_source_account, msg->source_account)) { - stellar_signingFail(_("Source account error")); + stellar_signingFail("Source account error"); return false; } @@ -764,30 +839,18 @@ bool stellar_confirmSetOptionsOp(const StellarSetOptionsOp *msg) { stellar_hashupdate_uint32(5); // Something like Set Inflation Destination - char str_title[32] = {0}; - char rows[4][32] = {0}; - int row_idx = 0; - memzero(rows, sizeof(rows)); + // char str_inflation_key[32] = {0}; // Inflation destination stellar_hashupdate_bool(msg->has_inflation_destination_account); if (msg->has_inflation_destination_account) { - strlcpy(str_title, _("Set Inflation Destination"), sizeof(str_title)); + // strlcpy(str_title, __("Set Inflation Destination"), sizeof(str_title)); // Validate account and convert to bytes uint8_t inflation_destination_account_bytes[STELLAR_KEY_SIZE] = {0}; if (!stellar_getAddressBytes(msg->inflation_destination_account, inflation_destination_account_bytes)) { - stellar_signingFail(_("Invalid inflation destination account")); - return false; - } - const char **str_addr_rows = - stellar_lineBreakAddress(inflation_destination_account_bytes); - - stellar_layoutTransactionDialog(str_title, NULL, str_addr_rows[0], - str_addr_rows[1], str_addr_rows[2]); - if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) { - stellar_signingFail(_("User canceled")); + stellar_signingFail("Invalid inflation destination account"); return false; } @@ -797,172 +860,142 @@ bool stellar_confirmSetOptionsOp(const StellarSetOptionsOp *msg) { // Clear flags stellar_hashupdate_bool(msg->has_clear_flags); + char str_cleared_flags[32] = {0}; if (msg->has_clear_flags) { - strlcpy(str_title, _("Clear Flag(s)"), sizeof(str_title)); + // strlcpy(str_title, __("Clear Flag(s)"), sizeof(str_title)); // Auth required if (msg->clear_flags > 7) { - stellar_signingFail(_("Invalid flags")); + stellar_signingFail("Invalid flags"); return false; } if (msg->clear_flags & 0x01) { - strlcpy(rows[row_idx], _("AUTH_REQUIRED"), sizeof(rows[row_idx])); - row_idx++; + strlcat(str_cleared_flags, "AUTH_REQUIRED\n", sizeof(str_cleared_flags)); + // row_idx++; } // Auth revocable if (msg->clear_flags & 0x02) { - strlcpy(rows[row_idx], _("AUTH_REVOCABLE"), sizeof(rows[row_idx])); - row_idx++; + strlcat(str_cleared_flags, "AUTH_REVOCABLE\n", sizeof(str_cleared_flags)); + // row_idx++; } // Auth immutable if (msg->clear_flags & 0x04) { - strlcpy(rows[row_idx], _("AUTH_IMMUTABLE"), sizeof(rows[row_idx])); - row_idx++; + strlcat(str_cleared_flags, "AUTH_IMMUTABLE", sizeof(str_cleared_flags)); + // row_idx++; } - stellar_layoutTransactionDialog(str_title, rows[0], rows[1], rows[2], - rows[3]); - if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) { - stellar_signingFail(_("User canceled")); - return false; - } - memzero(rows, sizeof(rows)); - row_idx = 0; - // Hash flags stellar_hashupdate_uint32(msg->clear_flags); } // Set flags stellar_hashupdate_bool(msg->has_set_flags); + char str_seted_flags[32] = {0}; if (msg->has_set_flags) { - strlcpy(str_title, _("Set Flag(s)"), sizeof(str_title)); + // strlcpy(str_title, __("Set Flag(s)"), sizeof(str_title)); // Auth required if (msg->set_flags > 7) { - stellar_signingFail(_("Invalid flags")); + stellar_signingFail("Invalid flags"); return false; } if (msg->set_flags & 0x01) { - strlcpy(rows[row_idx], _("AUTH_REQUIRED"), sizeof(rows[row_idx])); - row_idx++; + strlcat(str_seted_flags, "AUTH_REQUIRED\n", sizeof(str_seted_flags)); + // row_idx++; } // Auth revocable if (msg->set_flags & 0x02) { - strlcpy(rows[row_idx], _("AUTH_REVOCABLE"), sizeof(rows[row_idx])); - row_idx++; + strlcat(str_seted_flags, "AUTH_REVOCABLE\n", sizeof(str_seted_flags)); + // row_idx++; } // Auth immutable if (msg->set_flags & 0x04) { - strlcpy(rows[row_idx], _("AUTH_IMMUTABLE"), sizeof(rows[row_idx])); - row_idx++; + strlcat(str_seted_flags, "AUTH_IMMUTABLE", sizeof(str_seted_flags)); + // row_idx++; } - stellar_layoutTransactionDialog(str_title, rows[0], rows[1], rows[2], - rows[3]); - if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) { - stellar_signingFail(_("User canceled")); - return false; - } - memzero(rows, sizeof(rows)); - row_idx = 0; - // Hash flags stellar_hashupdate_uint32(msg->set_flags); } // Account thresholds - bool show_thresholds_confirm = false; - row_idx = 0; + // bool show_thresholds_confirm = false; + // row_idx = 0; stellar_hashupdate_bool(msg->has_master_weight); + char str_master_weight[10 + 1] = {0}; if (msg->has_master_weight) { - char str_master_weight[10 + 1] = {0}; - show_thresholds_confirm = true; + // show_thresholds_confirm = true; stellar_format_uint32(msg->master_weight, str_master_weight, sizeof(str_master_weight)); - strlcpy(rows[row_idx], _("Master Weight: "), sizeof(rows[row_idx])); - strlcat(rows[row_idx], str_master_weight, sizeof(rows[row_idx])); - row_idx++; + // strlcpy(rows[row_idx], __("Master Weight: "), sizeof(rows[row_idx])); + // strlcat(rows[row_idx], str_master_weight, sizeof(rows[row_idx])); + // row_idx++; // Hash master weight stellar_hashupdate_uint32(msg->master_weight); } stellar_hashupdate_bool(msg->has_low_threshold); + char str_low_threshold[10 + 1] = {0}; if (msg->has_low_threshold) { - char str_low_threshold[10 + 1] = {0}; - show_thresholds_confirm = true; + // show_thresholds_confirm = true; stellar_format_uint32(msg->low_threshold, str_low_threshold, sizeof(str_low_threshold)); - strlcpy(rows[row_idx], _("Low: "), sizeof(rows[row_idx])); - strlcat(rows[row_idx], str_low_threshold, sizeof(rows[row_idx])); - row_idx++; + // strlcpy(rows[row_idx], __("Low: "), sizeof(rows[row_idx])); + // strlcat(rows[row_idx], str_low_threshold, sizeof(rows[row_idx])); + // row_idx++; // Hash low threshold stellar_hashupdate_uint32(msg->low_threshold); } stellar_hashupdate_bool(msg->has_medium_threshold); + char str_med_threshold[10 + 1] = {0}; if (msg->has_medium_threshold) { - char str_med_threshold[10 + 1] = {0}; - show_thresholds_confirm = true; + // show_thresholds_confirm = true; stellar_format_uint32(msg->medium_threshold, str_med_threshold, sizeof(str_med_threshold)); - strlcpy(rows[row_idx], _("Medium: "), sizeof(rows[row_idx])); - strlcat(rows[row_idx], str_med_threshold, sizeof(rows[row_idx])); - row_idx++; + // strlcpy(rows[row_idx], __("Medium: "), sizeof(rows[row_idx])); + // strlcat(rows[row_idx], str_med_threshold, sizeof(rows[row_idx])); + // row_idx++; // Hash medium threshold stellar_hashupdate_uint32(msg->medium_threshold); } stellar_hashupdate_bool(msg->has_high_threshold); + char str_high_threshold[10 + 1] = {0}; if (msg->has_high_threshold) { - char str_high_threshold[10 + 1] = {0}; - show_thresholds_confirm = true; + // show_thresholds_confirm = true; stellar_format_uint32(msg->high_threshold, str_high_threshold, sizeof(str_high_threshold)); - strlcpy(rows[row_idx], _("High: "), sizeof(rows[row_idx])); - strlcat(rows[row_idx], str_high_threshold, sizeof(rows[row_idx])); - row_idx++; + // strlcpy(rows[row_idx], __("High: "), sizeof(rows[row_idx])); + // strlcat(rows[row_idx], str_high_threshold, sizeof(rows[row_idx])); + // row_idx++; // Hash high threshold stellar_hashupdate_uint32(msg->high_threshold); } - if (show_thresholds_confirm) { - strlcpy(str_title, _("Account Thresholds"), sizeof(str_title)); - stellar_layoutTransactionDialog(str_title, rows[0], rows[1], rows[2], - rows[3]); - if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) { - stellar_signingFail(_("User canceled")); - return false; - } - memzero(rows, sizeof(rows)); - row_idx = 0; - } + // if (show_thresholds_confirm) { + // strlcpy(str_title, __("Account Thresholds"), sizeof(str_title)); + // stellar_layoutTransactionDialog(str_title, rows[0], rows[1], rows[2], + // rows[3]); + // } // Home domain stellar_hashupdate_bool(msg->has_home_domain); if (msg->has_home_domain) { - strlcpy(str_title, _("Home Domain"), sizeof(str_title)); + // strlcpy(str_title, Home Domain"), sizeof(str_title)); // Split home domain if longer than 22 characters - int home_domain_len = strnlen(msg->home_domain, 32); - if (home_domain_len > 22) { - strlcpy(rows[0], msg->home_domain, 22); - strlcpy(rows[1], msg->home_domain + 21, sizeof(rows[1])); - } else { - strlcpy(rows[0], msg->home_domain, sizeof(rows[0])); - } - - stellar_layoutTransactionDialog(str_title, rows[0], rows[1], NULL, NULL); - if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) { - stellar_signingFail(_("User canceled")); - return false; - } - memzero(rows, sizeof(rows)); - row_idx = 0; + // int home_domain_len = strnlen(msg->home_domain, 32); + // if (home_domain_len > 22) { + // strlcpy(rows[0], msg->home_domain, 22); + // strlcpy(rows[1], msg->home_domain + 21, sizeof(rows[1])); + // } else { + // strlcpy(rows[0], msg->home_domain, sizeof(rows[0])); + // } stellar_hashupdate_string((unsigned char *)&(msg->home_domain), strnlen(msg->home_domain, 32)); @@ -970,86 +1003,91 @@ bool stellar_confirmSetOptionsOp(const StellarSetOptionsOp *msg) { // Signer stellar_hashupdate_bool(msg->has_signer_type); + // char signer_type_key[32] = {}; + char str_signer_weight[16] = {0}; + // Signer Weight + char str_signer_key[16] = {0}; + char str_signer_value[68] = {0}; if (msg->has_signer_type) { - if (msg->signer_weight > 0) { - strlcpy(str_title, _("Add Signer: "), sizeof(str_title)); - } else { - strlcpy(str_title, _("REMOVE Signer: "), sizeof(str_title)); - } + // if (msg->signer_weight > 0) { + // strlcpy(signer_type_key, "Add Signer", sizeof(signer_type_key)); + // } else { + // strlcpy(signer_type_key, "Remove Signer", sizeof(signer_type_key)); + // } // Format weight as a string - char str_weight[16] = {0}; - stellar_format_uint32(msg->signer_weight, str_weight, sizeof(str_weight)); - char str_weight_row[32] = {0}; - strlcpy(str_weight_row, _("Weight: "), sizeof(str_weight_row)); - strlcat(str_weight_row, str_weight, sizeof(str_weight_row)); + // char str_weight[16] = {0}; + stellar_format_uint32(msg->signer_weight, str_signer_weight, + sizeof(str_signer_weight)); + // char str_weight_row[32] = {0}; + // strlcpy(str_weight_row, __("Weight: "), sizeof(str_weight_row)); + // strlcat(str_weight_row, str_weight, sizeof(str_weight_row)); // 0 = account, 1 = pre-auth, 2 = hash(x) - char *str_signer_type = NULL; - bool needs_hash_confirm = false; + // char *str_signer_type = NULL; + // bool needs_hash_confirm = false; switch (msg->signer_type) { case StellarSignerType_ACCOUNT: - strlcat(str_title, _("account"), sizeof(str_title)); - - const char **str_addr_rows = - stellar_lineBreakAddress(msg->signer_key.bytes); - stellar_layoutTransactionDialog(str_title, str_weight_row, - str_addr_rows[0], str_addr_rows[1], - str_addr_rows[2]); - if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, - false)) { - stellar_signingFail(_("User canceled")); - return false; - } + strlcpy(str_signer_key, "Account", sizeof(str_signer_key)); + // Account: + // const char **str_addr_rows = + // stellar_lineBreakAddress(msg->signer_key.bytes); + stellar_publicAddressAsStr(msg->signer_key.bytes, str_signer_value, + sizeof(str_signer_value)); break; case StellarSignerType_PRE_AUTH: case StellarSignerType_HASH: - str_signer_type = - (msg->signer_type == 1) ? _("pre-auth hash") : _("hash(x)"); - needs_hash_confirm = true; - strlcat(str_title, str_signer_type, sizeof(str_title)); - - stellar_layoutTransactionDialog(str_title, str_weight_row, NULL, - _("(confirm hash on next"), - _("screen)")); - if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, - false)) { - stellar_signingFail(_("User canceled")); - return false; - } + // str_signe = + // (msg->signer_type == 1) ? __("pre-auth hash") : __("hash(x)"); + strlcpy(str_signer_key, + (msg->signer_type == 1) ? "Pre-auth Hash" : "Hash(x)", + sizeof(str_signer_key)); + strlcpy(str_signer_value, "0x", sizeof(str_signer_value)); + data2hex(msg->signer_key.bytes, msg->signer_key.size, + str_signer_value + 2); break; default: - stellar_signingFail(_("Stellar: invalid signer type")); + stellar_signingFail("Stellar: invalid signer type"); return false; } - - // Extra confirmation step for hash signers - if (needs_hash_confirm) { - data2hex(msg->signer_key.bytes + 0, 8, rows[row_idx++]); - data2hex(msg->signer_key.bytes + 8, 8, rows[row_idx++]); - data2hex(msg->signer_key.bytes + 16, 8, rows[row_idx++]); - data2hex(msg->signer_key.bytes + 24, 8, rows[row_idx++]); - - stellar_layoutTransactionDialog(_("Confirm Hash"), rows[0], rows[1], - rows[2], rows[3]); - if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) { - stellar_signingFail(_("User canceled")); - return false; - } - memzero(rows, sizeof(rows)); - row_idx = 0; - } - - // Hash: signer type - stellar_hashupdate_uint32(msg->signer_type); - // key - stellar_hashupdate_bytes(msg->signer_key.bytes, 32); - // weight - stellar_hashupdate_uint32(msg->signer_weight); } + const char *const expeted_keys[] = { + msg->has_inflation_destination_account ? "Inflation Account" : NULL, + msg->has_clear_flags ? "Clear Flag(s)" : NULL, + msg->has_set_flags ? "Set Flag(s)" : NULL, + msg->has_master_weight ? "Master Weight" : NULL, + msg->has_low_threshold ? "Thresholds Low" : NULL, + msg->has_medium_threshold ? "Thresholds Med" : NULL, + msg->has_high_threshold ? "Thresholds High" : NULL, + msg->has_home_domain ? "Home Domain" : NULL, + msg->has_signer_type ? "Signer Weight" : NULL, + msg->has_signer_type ? str_signer_key : NULL, + msg->has_source_account ? "Source Account" : NULL}; + const char *const values[] = {msg->inflation_destination_account, + str_cleared_flags, + str_seted_flags, + str_master_weight, + str_low_threshold, + str_med_threshold, + str_high_threshold, + msg->home_domain, + str_signer_weight, + str_signer_value, + msg->source_account}; // At this point, the operation is confirmed stellar_activeTx.confirmed_operations++; + if (!stellar_layoutTransactionDialog(ARRAY_SIZE(expeted_keys), expeted_keys, + values)) { + stellar_signingFail("User canceled"); + return false; + } + // Hash: signer type + stellar_hashupdate_uint32(msg->signer_type); + // key + stellar_hashupdate_bytes(msg->signer_key.bytes, 32); + // weight + stellar_hashupdate_uint32(msg->signer_weight); return true; } @@ -1058,7 +1096,7 @@ bool stellar_confirmChangeTrustOp(const StellarChangeTrustOp *msg) { if (!stellar_confirmSourceAccount(msg->has_source_account, msg->source_account)) { - stellar_signingFail(_("Source account error")); + stellar_signingFail("Source account error"); return false; } @@ -1066,52 +1104,58 @@ bool stellar_confirmChangeTrustOp(const StellarChangeTrustOp *msg) { stellar_hashupdate_uint32(6); // Add Trust: USD - char str_title[32] = {0}; - if (msg->limit == 0) { - strlcpy(str_title, _("DELETE Trust: "), sizeof(str_title)); - } else { - strlcpy(str_title, _("Add Trust: "), sizeof(str_title)); - } - strlcat(str_title, msg->asset.code, sizeof(str_title)); + // char str_op[32] = {0}; + // if (msg->limit == 0) { + // strlcpy(str_op, "Remove Trust: ", sizeof(str_op)); + // } else { + // strlcpy(str_op, "Add Trust: ", sizeof(str_op)); + // } + // strlcat(str_op, msg->asset.code, sizeof(str_op)); // Amount: MAX (or a number) - char str_amount_row[32] = {0}; - strlcpy(str_amount_row, _("Amount: "), sizeof(str_amount_row)); + char str_amount[32] = {0}; + // strlcpy(str_amount_row, __("Amount: "), sizeof(str_amount_row)); if (msg->limit == 9223372036854775807) { - strlcat(str_amount_row, _("[Maximum]"), sizeof(str_amount_row)); + strlcat(str_amount, "[Maximum]", sizeof(str_amount)); } else { - char str_amount[32] = {0}; + // char str_amount[32] = {0}; stellar_format_stroops(msg->limit, str_amount, sizeof(str_amount)); - strlcat(str_amount_row, str_amount, sizeof(str_amount_row)); + // strlcat(str_amount_row, str_amount, sizeof(str_amount_row)); } // Validate destination account and convert to bytes uint8_t asset_issuer_bytes[STELLAR_KEY_SIZE] = {0}; if (!stellar_getAddressBytes(msg->asset.issuer, asset_issuer_bytes)) { - stellar_signingFail(_("User canceled")); - fsm_sendFailure(FailureType_Failure_ProcessError, - _("Invalid asset issuer")); + stellar_signingFail("User canceled"); + fsm_sendFailure(FailureType_Failure_ProcessError, "Invalid asset issuer"); return false; } // Display full issuer address - const char **str_addr_rows = stellar_lineBreakAddress(asset_issuer_bytes); - - stellar_layoutTransactionDialog(str_title, str_amount_row, str_addr_rows[0], - str_addr_rows[1], str_addr_rows[2]); - if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) { - stellar_signingFail(_("User canceled")); + // const char **str_addr_rows = stellar_lineBreakAddress(asset_issuer_bytes); + + // stellar_layoutTransactionDialog(str_title, str_amount_row, + // str_addr_rows[0], + // str_addr_rows[1], str_addr_rows[2]); + const char *const expeted_keys[] = { + msg->limit == 0 ? _("Remove Trust:") : _("Add Trust:"), _("Amount:"), + _("Asset Issuer:"), + msg->has_source_account ? _("Source Account:") : NULL}; + const char *const values[] = {msg->asset.code, str_amount, msg->asset.issuer, + msg->source_account}; + // At this point, the operation is confirmed + stellar_activeTx.confirmed_operations++; + if (!stellar_layoutTransactionDialog(ARRAY_SIZE(expeted_keys), expeted_keys, + values)) { + stellar_signingFail("User canceled"); return false; } - // Hash: asset stellar_hashupdate_asset(&(msg->asset)); // limit stellar_hashupdate_uint64(msg->limit); - // At this point, the operation is confirmed - stellar_activeTx.confirmed_operations++; return true; } @@ -1120,7 +1164,7 @@ bool stellar_confirmAllowTrustOp(const StellarAllowTrustOp *msg) { if (!stellar_confirmSourceAccount(msg->has_source_account, msg->source_account)) { - stellar_signingFail(_("Source account error")); + stellar_signingFail("Source account error"); return false; } @@ -1128,39 +1172,45 @@ bool stellar_confirmAllowTrustOp(const StellarAllowTrustOp *msg) { stellar_hashupdate_uint32(7); // Add Trust: USD - char str_title[32] = {0}; - if (msg->is_authorized) { - strlcpy(str_title, _("Allow Trust of"), sizeof(str_title)); - } else { - strlcpy(str_title, _("REVOKE Trust of"), sizeof(str_title)); - } + // char str_title[32] = {0}; + // if (msg->is_authorized) { + // strlcpy(str_title, "Allow Trust", sizeof(str_title)); + // } else { + // strlcpy(str_title, "REVOKE Trust", sizeof(str_title)); + // } // Asset code - char str_asset_row[32] = {0}; - strlcpy(str_asset_row, msg->asset_code, sizeof(str_asset_row)); + // char str_asset[32] = {0}; + // strlcpy(str_asset, msg->asset_code, sizeof(str_asset)); - // Validate account and convert to bytes + // // Validate account and convert to bytes uint8_t trusted_account_bytes[STELLAR_KEY_SIZE] = {0}; if (!stellar_getAddressBytes(msg->trusted_account, trusted_account_bytes)) { - stellar_signingFail(_("Invalid trusted account")); + stellar_signingFail("Invalid trusted account"); return false; } - const char **str_trustor_rows = - stellar_lineBreakAddress(trusted_account_bytes); + // const char **str_trustor_rows = + // stellar_lineBreakAddress(trusted_account_bytes); - // By: G... - char str_by[32] = {0}; - strlcpy(str_by, _("By: "), sizeof(str_by)); - strlcat(str_by, str_trustor_rows[0], sizeof(str_by)); + // // By: G... + // char str_by[32] = {0}; + // strlcpy(str_by, __("By: "), sizeof(str_by)); + // strlcat(str_by, str_trustor_rows[0], sizeof(str_by)); - stellar_layoutTransactionDialog(str_title, str_asset_row, str_by, - str_trustor_rows[1], str_trustor_rows[2]); - if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) { - stellar_signingFail(_("User canceled")); + const char *const expeted_keys[] = { + msg->is_authorized ? _("Add Trust:") : _("Remove Trust:"), + _("Trust Account:"), + msg->has_source_account ? _("Source Account:") : NULL}; + const char *const values[] = {msg->asset_code, msg->trusted_account, + msg->source_account}; + // At this point, the operation is confirmed + stellar_activeTx.confirmed_operations++; + if (!stellar_layoutTransactionDialog(ARRAY_SIZE(expeted_keys), expeted_keys, + values)) { + stellar_signingFail("User canceled"); return false; } - // Hash: trustor account (the account being allowed to access the asset) stellar_hashupdate_address(trusted_account_bytes); // asset type @@ -1179,14 +1229,12 @@ bool stellar_confirmAllowTrustOp(const StellarAllowTrustOp *msg) { stellar_hashupdate_bytes((uint8_t *)padded_code, 12); break; default: - stellar_signingFail(_("Stellar: invalid asset type")); + stellar_signingFail("Stellar: invalid asset type"); return false; } // is authorized stellar_hashupdate_bool(msg->is_authorized); - // At this point, the operation is confirmed - stellar_activeTx.confirmed_operations++; return true; } @@ -1195,7 +1243,7 @@ bool stellar_confirmAccountMergeOp(const StellarAccountMergeOp *msg) { if (!stellar_confirmSourceAccount(msg->has_source_account, msg->source_account)) { - stellar_signingFail(_("Source account error")); + stellar_signingFail("Source account error"); return false; } @@ -1206,27 +1254,34 @@ bool stellar_confirmAccountMergeOp(const StellarAccountMergeOp *msg) { uint8_t destination_account_bytes[STELLAR_KEY_SIZE] = {0}; if (!stellar_getAddressBytes(msg->destination_account, destination_account_bytes)) { - stellar_signingFail(_("Invalid destination account")); + stellar_signingFail("Invalid destination account"); return false; } - const char **str_destination_rows = - stellar_lineBreakAddress(destination_account_bytes); - - stellar_layoutTransactionDialog( - _("Merge Account"), _("All XLM will be sent to:"), - str_destination_rows[0], str_destination_rows[1], - str_destination_rows[2]); + // const char **str_destination_rows = + // stellar_lineBreakAddress(destination_account_bytes); + layoutDialogCenterAdapterV2(NULL, &bmp_icon_warning, &bmp_bottom_left_close, + &bmp_bottom_right_arrow, NULL, NULL, NULL, NULL, + NULL, NULL, + "All XLM will be sent to destination account"); if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) { - stellar_signingFail(_("User canceled")); + stellar_signingFail("User canceled"); + return false; + } + const char *const expeted_keys[] = { + "Destination Account", msg->has_source_account ? "Source Account" : NULL}; + const char *const values[] = {msg->destination_account, msg->source_account}; + // At this point, the operation is confirmed + stellar_activeTx.confirmed_operations++; + if (!stellar_layoutTransactionDialog(ARRAY_SIZE(expeted_keys), expeted_keys, + values)) { + stellar_signingFail("User canceled"); return false; } // Hash: destination account stellar_hashupdate_address(destination_account_bytes); - // At this point, the operation is confirmed - stellar_activeTx.confirmed_operations++; return true; } @@ -1235,7 +1290,7 @@ bool stellar_confirmManageDataOp(const StellarManageDataOp *msg) { if (!stellar_confirmSourceAccount(msg->has_source_account, msg->source_account)) { - stellar_signingFail(_("Source account error")); + stellar_signingFail("Source account error"); return false; } @@ -1244,41 +1299,30 @@ bool stellar_confirmManageDataOp(const StellarManageDataOp *msg) { char str_title[32] = {0}; if (msg->has_value) { - strlcpy(str_title, _("Set data value key:"), sizeof(str_title)); + strlcpy(str_title, "Set Key", sizeof(str_title)); } else { - strlcpy(str_title, _("CLEAR data value key:"), sizeof(str_title)); - } - - // Confirm key - const char **str_key_lines = - split_message((const uint8_t *)(msg->key), strnlen(msg->key, 64), 16); - - stellar_layoutTransactionDialog(str_title, str_key_lines[0], str_key_lines[1], - str_key_lines[2], str_key_lines[3]); - if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) { - stellar_signingFail(_("User canceled")); - return false; + strlcpy(str_title, "Clear Key", sizeof(str_title)); } // Confirm value by displaying sha256 hash since this can contain // non-printable characters + char str_hash_digest[SHA256_DIGEST_STRING_LENGTH] = {0}; if (msg->has_value) { - strlcpy(str_title, _("Confirm sha256 of value:"), sizeof(str_title)); + // strlcpy(str_title, __("Confirm sha256 of value:"), sizeof(str_title)); - char str_hash_digest[SHA256_DIGEST_STRING_LENGTH] = {0}; sha256_Data(msg->value.bytes, msg->value.size, str_hash_digest); - const char **str_hash_lines = split_message( - (const uint8_t *)str_hash_digest, sizeof(str_hash_digest), 16); - - stellar_layoutTransactionDialog(str_title, str_hash_lines[0], - str_hash_lines[1], str_hash_lines[2], - str_hash_lines[3]); - if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) { - stellar_signingFail(_("User canceled")); - return false; - } } - + const char *const expeted_keys[] = { + str_title, msg->has_value ? "Hash Value" : NULL, + msg->has_source_account ? "Source Account" : NULL}; + const char *const values[] = {msg->key, str_hash_digest, msg->source_account}; + // At this point, the operation is confirmed + stellar_activeTx.confirmed_operations++; + if (!stellar_layoutTransactionDialog(ARRAY_SIZE(expeted_keys), expeted_keys, + values)) { + stellar_signingFail("User canceled"); + return false; + } // Hash: key stellar_hashupdate_string((unsigned char *)&(msg->key), strnlen(msg->key, 64)); @@ -1288,8 +1332,6 @@ bool stellar_confirmManageDataOp(const StellarManageDataOp *msg) { stellar_hashupdate_string(msg->value.bytes, msg->value.size); } - // At this point, the operation is confirmed - stellar_activeTx.confirmed_operations++; return true; } @@ -1298,7 +1340,7 @@ bool stellar_confirmBumpSequenceOp(const StellarBumpSequenceOp *msg) { if (!stellar_confirmSourceAccount(msg->has_source_account, msg->source_account)) { - stellar_signingFail(_("Source account error")); + stellar_signingFail("Source account error"); return false; } @@ -1308,18 +1350,19 @@ bool stellar_confirmBumpSequenceOp(const StellarBumpSequenceOp *msg) { char str_bump_to[20] = {0}; stellar_format_uint64(msg->bump_to, str_bump_to, sizeof(str_bump_to)); - stellar_layoutTransactionDialog(_("Bump Sequence"), _("Set sequence to:"), - str_bump_to, NULL, NULL); - if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) { - stellar_signingFail(_("User canceled")); + const char *const expeted_keys[] = { + "Bump Sequence To", msg->has_source_account ? "Source Account" : NULL}; + const char *const values[] = {str_bump_to, msg->source_account}; + // At this point, the operation is confirmed + stellar_activeTx.confirmed_operations++; + if (!stellar_layoutTransactionDialog(ARRAY_SIZE(expeted_keys), expeted_keys, + values)) { + stellar_signingFail("User canceled"); return false; } - // Hash: bump to stellar_hashupdate_uint64(msg->bump_to); - // At this point, the operation is confirmed - stellar_activeTx.confirmed_operations++; return true; } @@ -1354,22 +1397,13 @@ bool stellar_allOperationsConfirmed() { * Calculates and sets the signature for the active transaction */ void stellar_getSignatureForActiveTx(uint8_t *out_signature) { - const HDNode *node = stellar_deriveNode(stellar_activeTx.address_n, - stellar_activeTx.address_n_count); - if (!node) { - // return empty signature when we can't derive node - memzero(out_signature, 64); - return; - } - // Signature is the ed25519 detached signature of the sha256 of all the bytes // that have been read so far uint8_t to_sign[32] = {0}; sha256_Final(&(stellar_activeTx.sha256_ctx), to_sign); uint8_t signature[64] = {0}; - ed25519_sign(to_sign, sizeof(to_sign), node->private_key, signature); - + ed25519_sign(to_sign, sizeof(to_sign), stellar_node->private_key, signature); memcpy(out_signature, signature, sizeof(signature)); } @@ -1400,7 +1434,7 @@ void stellar_format_price(uint32_t numerator, uint32_t denominator, char *out, // early exit for invalid denominator if (denominator == 0) { - strlcpy(out, _("[Invalid Price]"), outlen); + strlcpy(out, "[Invalid Price]", outlen); return; } @@ -1475,46 +1509,27 @@ const char **stellar_lineBreakAddress(const uint8_t *addrbytes) { void stellar_format_asset(const StellarAsset *asset, char *str_formatted, size_t len) { char str_asset_code[12 + 1] = {0}; - // truncated asset issuer, final length depends on length of asset code - char str_asset_issuer_trunc[13 + 1] = {0}; - - memzero(str_formatted, len); - memzero(str_asset_code, sizeof(str_asset_code)); - memzero(str_asset_issuer_trunc, sizeof(str_asset_issuer_trunc)); // Validate issuer account for non-native assets if (asset->type != StellarAssetType_NATIVE && !stellar_validateAddress(asset->issuer)) { - stellar_signingFail(_("Invalid asset issuer")); + stellar_signingFail("Invalid asset issuer"); return; } // Native asset if (asset->type == StellarAssetType_NATIVE) { - strlcpy(str_formatted, _("XLM (native asset)"), len); + strlcpy(str_formatted, "XLM", len); } // 4-character custom if (asset->type == StellarAssetType_ALPHANUM4) { memcpy(str_asset_code, asset->code, 4); strlcpy(str_formatted, str_asset_code, len); - - // Truncate issuer to 13 chars - memcpy(str_asset_issuer_trunc, asset->issuer, 13); } // 12-character custom if (asset->type == StellarAssetType_ALPHANUM12) { memcpy(str_asset_code, asset->code, 12); strlcpy(str_formatted, str_asset_code, len); - - // Truncate issuer to 5 characters - memcpy(str_asset_issuer_trunc, asset->issuer, 5); - } - // Issuer is read the same way for both types of custom assets - if (asset->type == StellarAssetType_ALPHANUM4 || - asset->type == StellarAssetType_ALPHANUM12) { - strlcat(str_formatted, _(" ("), len); - strlcat(str_formatted, str_asset_issuer_trunc, len); - strlcat(str_formatted, _(")"), len); } } @@ -1638,25 +1653,12 @@ uint16_t stellar_crc16(uint8_t *bytes, uint32_t length) { * * All paths must be hardened */ -const HDNode *stellar_deriveNode(const uint32_t *address_n, - size_t address_n_count) { - static CONFIDENTIAL HDNode node; - const char *curve = "ed25519"; - - // Device not initialized, passphrase request cancelled, or unsupported curve - if (!config_getRootNode(&node, curve)) { - return 0; - } - // Failed to derive private key - if (hdnode_private_ckd_cached(&node, address_n, address_n_count, NULL) == 0) { - return 0; - } - - if (hdnode_fill_public_key(&node) != 0) { - return 0; - } - - return &node; +HDNode *stellar_deriveNode(const uint32_t *address_n, size_t address_n_count) { + // slip10 + extern HDNode *fsm_getDerivedNode( + const char *curve, const uint32_t *address_n, size_t address_n_count, + uint32_t *fingerprint); + return fsm_getDerivedNode(ED25519_NAME, address_n, address_n_count, NULL); } void stellar_hashupdate_uint32(uint32_t value) { @@ -1741,7 +1743,7 @@ void stellar_hashupdate_asset(const StellarAsset *asset) { uint8_t issuer_bytes[STELLAR_KEY_SIZE] = {0}; if (asset->type != StellarAssetType_NATIVE && !stellar_getAddressBytes(asset->issuer, issuer_bytes)) { - stellar_signingFail(_("Invalid asset issuer")); + stellar_signingFail("Invalid asset issuer"); return; } @@ -1774,249 +1776,204 @@ void stellar_hashupdate_bytes(const uint8_t *data, size_t len) { * Displays a summary of the overall transaction */ void stellar_layoutTransactionSummary(const StellarSignTx *msg) { - char str_lines[5][32] = {0}; - memzero(str_lines, sizeof(str_lines)); - - char str_fee[12] = {0}; - char str_num_ops[12] = {0}; - + char str_fee[32] = {0}; + // char str_num_ops[12] = {0}; + char str_seq_num[32] = {0}; // Will be set to true for some large hashes that don't fit on one screen uint8_t needs_memo_hash_confirm = 0; // Format the fee stellar_format_stroops(msg->fee, str_fee, sizeof(str_fee)); - - strlcpy(str_lines[0], _("Fee: "), sizeof(str_lines[0])); - strlcat(str_lines[0], str_fee, sizeof(str_lines[0])); - strlcat(str_lines[0], _(" XLM"), sizeof(str_lines[0])); - + strlcat(str_fee, " XLM", sizeof(str_fee)); + stellar_format_uint64(msg->sequence_number, str_seq_num, sizeof(str_seq_num)); // add in numOperations - stellar_format_uint32(msg->num_operations, str_num_ops, sizeof(str_num_ops)); - - strlcat(str_lines[0], _(" ("), sizeof(str_lines[0])); - strlcat(str_lines[0], str_num_ops, sizeof(str_lines[0])); - if (msg->num_operations == 1) { - strlcat(str_lines[0], _(" op)"), sizeof(str_lines[0])); - } else { - strlcat(str_lines[0], _(" ops)"), sizeof(str_lines[0])); - } + // strlcpy(str_num_ops, "(", sizeof(str_num_ops)); + // stellar_format_uint32(msg->num_operations, str_num_ops + 1, + // sizeof(str_num_ops) - 1); + + // strlcat(str_lines[0], __(" ("), sizeof(str_lines[0])); + // strlcat(str_lines[0], str_num_ops, sizeof(str_lines[0])); + // if (msg->num_operations == 1) { + // strlcat(str_num_ops, " op)", sizeof(str_num_ops)); + // } else { + // strlcat(str_num_ops, " ops)", sizeof(str_num_ops)); + // } // Display full address being used to sign transaction - const char **str_addr_rows = - stellar_lineBreakAddress(stellar_activeTx.signing_pubkey); - - stellar_layoutTransactionDialog(str_lines[0], _("Signing with:"), - str_addr_rows[0], str_addr_rows[1], - str_addr_rows[2]); - if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) { - stellar_signingFail(_("User canceled")); - return; - } + char signer_addr[56 + 1] = {0}; + // get full address string + stellar_publicAddressAsStr(stellar_activeTx.signing_pubkey, signer_addr, + sizeof(signer_addr)); // Reset lines for displaying memo - memzero(str_lines, sizeof(str_lines)); - + // memzero(str_lines, sizeof(str_lines)); // MEMO + char memo[65] = {0}; + char memo_key[64] = {0}; + // bool has_memo = false; + if (msg->memo_type != StellarMemoType_NONE) { + strlcpy(memo_key, _("Memo"), sizeof(memo_key)); + } switch (msg->memo_type) { case StellarMemoType_NONE: - strlcpy(str_lines[0], _("[No Memo Set]"), sizeof(str_lines[0])); - strlcpy(str_lines[1], _("Important:"), sizeof(str_lines[0])); - strlcpy(str_lines[2], _("Many exchanges require"), sizeof(str_lines[0])); - strlcpy(str_lines[3], _("a memo when depositing."), sizeof(str_lines[0])); + // strlcpy(str_lines[0], __("[No Memo Set]"), sizeof(str_lines[0])); + // strlcpy(str_lines[1], __("Important:"), sizeof(str_lines[0])); + // strlcpy(str_lines[2], __("Many exchanges require"), + // sizeof(str_lines[0])); strlcpy(str_lines[3], __("a memo when + // depositing."), + memo_type_none = true; break; case StellarMemoType_TEXT: - strlcpy(str_lines[0], _("Memo (TEXT)"), sizeof(str_lines[0])); - - // Split 28-character string into two lines of 19 / 9 - // todo: word wrap method? - strlcpy(str_lines[1], (const char *)msg->memo_text, 19 + 1); - strlcpy(str_lines[2], (const char *)(msg->memo_text + 19), 9 + 1); + // strlcpy(str_lines[0], __("Memo (TEXT)"), sizeof(str_lines[0])); + strlcat(memo_key, " (TEXT):", sizeof(memo_key)); + strlcpy(memo, (const char *)msg->memo_text, sizeof(memo)); break; case StellarMemoType_ID: - strlcpy(str_lines[0], _("Memo (ID)"), sizeof(str_lines[0])); - stellar_format_uint64(msg->memo_id, str_lines[1], sizeof(str_lines[1])); + strlcat(memo_key, " (ID):", sizeof(memo_key)); + // strlcpy(str_lines[0], __("Memo (ID)"), sizeof(str_lines[0])); + stellar_format_uint64(msg->memo_id, memo, sizeof(memo)); break; case StellarMemoType_HASH: needs_memo_hash_confirm = 1; - strlcpy(str_lines[0], _("Memo (HASH)"), sizeof(str_lines[0])); + strlcat(memo_key, " (HASH):", sizeof(memo_key)); + // strlcpy(str_lines[0], __("Memo (HASH)"), sizeof(str_lines[0])); break; case StellarMemoType_RETURN: needs_memo_hash_confirm = 1; - strlcpy(str_lines[0], _("Memo (RETURN)"), sizeof(str_lines[0])); + strlcat(memo_key, " (RETURN):", sizeof(memo_key)); + // strlcpy(str_lines[0], __("Memo (RETURN)"), sizeof(str_lines[0])); break; default: - stellar_signingFail(_("Stellar invalid memo type")); + stellar_signingFail("Stellar invalid memo type"); return; } if (needs_memo_hash_confirm) { - data2hex(msg->memo_hash.bytes + 0, 8, str_lines[1]); - data2hex(msg->memo_hash.bytes + 8, 8, str_lines[2]); - data2hex(msg->memo_hash.bytes + 16, 8, str_lines[3]); - data2hex(msg->memo_hash.bytes + 24, 8, str_lines[4]); - } - - stellar_layoutTransactionDialog(str_lines[0], str_lines[1], str_lines[2], - str_lines[3], str_lines[4]); - if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) { - stellar_signingFail(_("User canceled")); + data2hex(msg->memo_hash.bytes, 32, memo); + // data2hex(msg->memo_hash.bytes + 8, 8, str_lines[2]); + // data2hex(msg->memo_hash.bytes + 16, 8, str_lines[3]); + // data2hex(msg->memo_hash.bytes + 24, 8, str_lines[4]); + } + const char *const expeted_keys[] = {memo_type_none ? NULL : memo_key, + _("Tx Source:"), _("Sequence Number:"), + _("Fee:")}; + const char *const values[] = {memo, signer_addr, str_seq_num, str_fee}; + if (!stellar_layoutTransactionDialog(ARRAY_SIZE(expeted_keys), expeted_keys, + values)) { + stellar_signingFail("User canceled"); return; } // Verify timebounds, if present - memzero(str_lines, sizeof(str_lines)); - - // Timebound: lower - time_t timebound; - char str_timebound[32] = {0}; - const struct tm *tm = NULL; - - timebound = (time_t)msg->timebounds_start; - strlcpy(str_lines[0], _("Valid from:"), sizeof(str_lines[0])); - if (timebound) { - tm = gmtime(&timebound); - strftime(str_timebound, sizeof(str_timebound), "%F %T (UTC)", tm); - strlcpy(str_lines[1], str_timebound, sizeof(str_lines[1])); - } else { - strlcpy(str_lines[1], _("[no restriction]"), sizeof(str_lines[1])); - } - - // Reset for timebound_max - memzero(str_timebound, sizeof(str_timebound)); - - timebound = (time_t)msg->timebounds_end; - strlcpy(str_lines[2], _("Valid to:"), sizeof(str_lines[2])); - if (timebound) { - tm = gmtime(&timebound); - strftime(str_timebound, sizeof(str_timebound), "%F %T (UTC)", tm); - strlcpy(str_lines[3], str_timebound, sizeof(str_lines[3])); - } else { - strlcpy(str_lines[3], _("[no restriction]"), sizeof(str_lines[3])); - } - - stellar_layoutTransactionDialog(_("Confirm Time Bounds"), str_lines[0], - str_lines[1], str_lines[2], str_lines[3]); - if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) { - stellar_signingFail(_("User canceled")); - return; - } + // memzero(str_lines, sizeof(str_lines)); + + // // Timebound: lower + // time_t timebound; + // char str_timebound[32] = {0}; + // const struct tm *tm = NULL; + + // timebound = (time_t)msg->timebounds_start; + // strlcpy(str_lines[0], __("Valid from:"), sizeof(str_lines[0])); + // if (timebound) { + // tm = gmtime(&timebound); + // strftime(str_timebound, sizeof(str_timebound), "%F %T (UTC)", tm); + // strlcpy(str_lines[1], str_timebound, sizeof(str_lines[1])); + // } else { + // strlcpy(str_lines[1], __("[no restriction]"), sizeof(str_lines[1])); + // } + + // // Reset for timebound_max + // memzero(str_timebound, sizeof(str_timebound)); + + // timebound = (time_t)msg->timebounds_end; + // strlcpy(str_lines[2], __("Valid to:"), sizeof(str_lines[2])); + // if (timebound) { + // tm = gmtime(&timebound); + // strftime(str_timebound, sizeof(str_timebound), "%F %T (UTC)", tm); + // strlcpy(str_lines[3], str_timebound, sizeof(str_lines[3])); + // } else { + // strlcpy(str_lines[3], __("[no restriction]"), sizeof(str_lines[3])); + // } + + // stellar_layoutTransactionDialog(__("Confirm Time Bounds"), str_lines[0], + // str_lines[1], str_lines[2], str_lines[3]); + // if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) { + // stellar_signingFail("User canceled"); + // return; + // } } +extern bool button_request(const ButtonRequestType code); /* - * Most basic dialog used for signing - * - Header indicating which key is being used for signing - * - 5 rows for content - * - Cancel / Next buttons - * - Warning message can appear between cancel/next buttons + * Most basic dialog used for display properties */ -void stellar_layoutSigningDialog(const char *line1, const char *line2, - const char *line3, const char *line4, - const char *line5, uint32_t *address_n, - size_t address_n_count, const char *warning, +bool stellar_layoutSigningDialog(const char *title, size_t n, + const char *const keys[n], + const char *const values[n], bool is_final_step) { - // Start with some initial padding and use these to track position as - // rendering moves down the screen - int offset_x = 1; - int offset_y = 1; - int line_height = 9; - - const HDNode *node = stellar_deriveNode(address_n, address_n_count); - if (!node) { - // abort on error - return; + bool result = false; + int index = 0; + int y = 0; + uint8_t bubble_key; + uint8_t max_index = n; + int8_t first_nonull_index = -1; + // char title[64] = {0}; + const char **tx_msg = format_tx_message(title); + + if (!button_request(ButtonRequestType_ButtonRequest_SignTx)) { + return false; } - char str_pubaddr_truncated[12]; // G???? + null - memzero(str_pubaddr_truncated, sizeof(str_pubaddr_truncated)); - - layoutLast = layoutDialogSwipe; +refresh_menu: layoutSwipe(); - oledClear_ex(); - - // Load up public address - char str_pubaddr[56 + 1] = {0}; - memzero(str_pubaddr, sizeof(str_pubaddr)); - stellar_publicAddressAsStr(node->public_key + 1, str_pubaddr, - sizeof(str_pubaddr)); - memcpy(str_pubaddr_truncated, str_pubaddr, sizeof(str_pubaddr_truncated) - 1); - - // Header - // Ends up as: Signing with GABCDEFGHIJKL - char str_header[32] = {0}; - memzero(str_header, sizeof(str_header)); - strlcpy(str_header, _("Signing with "), sizeof(str_header)); - strlcat(str_header, str_pubaddr_truncated, sizeof(str_header)); - - oledDrawString(offset_x, offset_y, str_header, FONT_STANDARD); - offset_y += line_height; - // Invert color on header - oledInvert(0, 0, OLED_WIDTH, offset_y - 2); - - // Dialog contents begin - if (line1) { - oledDrawString(offset_x, offset_y, line1, FONT_STANDARD); - } - offset_y += line_height; - if (line2) { - oledDrawString(offset_x, offset_y, line2, FONT_STANDARD); - } - offset_y += line_height; - if (line3) { - oledDrawString(offset_x, offset_y, line3, FONT_STANDARD); - } - offset_y += line_height; - if (line4) { - oledDrawString(offset_x, offset_y, line4, FONT_STANDARD); - } - offset_y += line_height; - if (line5) { - oledDrawString(offset_x, offset_y, line5, FONT_STANDARD); - } - offset_y += line_height; - - // Cancel button - layoutButtonNoAdapter(_("Cancel"), &bmp_btn_cancel); - - // Warnings (drawn centered between the buttons - if (warning) { - oledDrawStringCenterAdapter(OLED_WIDTH / 2, OLED_HEIGHT - 8, warning, - FONT_STANDARD); - } - - // Next / sign button - char str_next_label[8] = {0}; - if (is_final_step) { - strlcpy(str_next_label, _("SIGN"), sizeof(str_next_label)); + oledClear(); + bubble_key = KEY_NULL; + y = 13; + if (index < first_nonull_index) { + return false; + } + while (index < max_index && (keys[index] == NULL || values[index] == NULL)) { + index++; + } + if (first_nonull_index == -1) { + first_nonull_index = index; + } + if (index < max_index) { + layoutHeader(tx_msg[0]); + oledDrawStringAdapter(0, y, keys[index], FONT_STANDARD); + oledDrawStringAdapter(0, y + 10, values[index], FONT_STANDARD); + layoutButtonNoAdapter(NULL, (index == first_nonull_index) + ? &bmp_bottom_left_close + : &bmp_bottom_left_arrow); + layoutButtonYesAdapter(NULL, &bmp_bottom_right_arrow); + } else if (is_final_step) { + layoutHeader(_("Sign Transaction")); + oledDrawStringAdapter(0, y, tx_msg[1], FONT_STANDARD); + layoutButtonNoAdapter(NULL, &bmp_bottom_left_close); + layoutButtonYesAdapter(NULL, &bmp_bottom_right_confirm); } else { - strlcpy(str_next_label, _("Next"), sizeof(str_next_label)); + return true; } - - layoutButtonYesAdapter(str_next_label, &bmp_btn_confirm); - oledRefresh(); + HANDLE_KEY(bubble_key); } /* - * Main dialog helper method. Allows displaying 5 lines. - * A title showing the account being used to sign is always displayed. + * Transaction Dialog with network info and various properties */ -void stellar_layoutTransactionDialog(const char *line1, const char *line2, - const char *line3, const char *line4, - const char *line5) { - char str_warning[16] = {0}; - memzero(str_warning, sizeof(str_warning)); - +bool stellar_layoutTransactionDialog(size_t n, const char *const keys[n], + const char *const values[n]) { + char network[16] = {0}; + strlcpy(network, "XLM", sizeof(network)); if (stellar_activeTx.network_type == 2) { // Warning: testnet - strlcpy(str_warning, _("WRN:TN"), sizeof(str_warning)); - } - if (stellar_activeTx.network_type == 3) { + strlcat(network, " TN ", sizeof(network)); + } else if (stellar_activeTx.network_type == 3) { // Warning: private network - strlcpy(str_warning, _("WRN:PN"), sizeof(str_warning)); + strlcat(network, " PN ", sizeof(network)); } - stellar_layoutSigningDialog( - line1, line2, line3, line4, line5, stellar_activeTx.address_n, - stellar_activeTx.address_n_count, str_warning, false); + return stellar_layoutSigningDialog(network, n, keys, values, + stellar_allOperationsConfirmed()); } bool stellar_path_check(uint32_t address_n_count, const uint32_t *address_n) { diff --git a/legacy/firmware/stellar.h b/legacy/firmware/stellar.h old mode 100755 new mode 100644 index f1aa5505e..f4775fa5d --- a/legacy/firmware/stellar.h +++ b/legacy/firmware/stellar.h @@ -75,19 +75,16 @@ bool stellar_confirmManageDataOp(const StellarManageDataOp *msg); bool stellar_confirmBumpSequenceOp(const StellarBumpSequenceOp *msg); // Layout -void stellar_layoutTransactionDialog(const char *line1, const char *line2, - const char *line3, const char *line4, - const char *line5); +bool stellar_layoutTransactionDialog(size_t n, const char *const keys[n], + const char *const values[n]); void stellar_layoutTransactionSummary(const StellarSignTx *msg); -void stellar_layoutSigningDialog(const char *line1, const char *line2, - const char *line3, const char *line4, - const char *line5, uint32_t *address_n, - size_t address_n_count, const char *warning, +bool stellar_layoutSigningDialog(const char *title, size_t n, + const char *const keys[n], + const char *const values[n], bool is_final_step); // Helpers -const HDNode *stellar_deriveNode(const uint32_t *address_n, - size_t address_n_count); +HDNode *stellar_deriveNode(const uint32_t *address_n, size_t address_n_count); size_t stellar_publicAddressAsStr(const uint8_t *bytes, char *out, size_t outlen); diff --git a/legacy/firmware/tron.c b/legacy/firmware/tron.c index 5bff85596..b9bb51cb0 100644 --- a/legacy/firmware/tron.c +++ b/legacy/firmware/tron.c @@ -16,7 +16,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with this library. If not, see . */ - +#include #include #include "address.h" @@ -38,6 +38,7 @@ #include +#include "tron_eng_rental.h" // PROTOBUF3 types #define PROTO_TYPE_VARINT 0 #define PROTO_TYPE_STRING 2 @@ -48,7 +49,10 @@ void tron_message_hash(const uint8_t *message, size_t message_len, uint8_t hash[32]) { struct SHA3_CTX ctx = {0}; sha3_256_Init(&ctx); - sha3_Update(&ctx, (const uint8_t *)"\x19" "TRON Signed Message:\n32", 24); + sha3_Update(&ctx, (const uint8_t *)"\x19" "TRON Signed Message:\n", 22); + char msg_len_str[11] = {0}; + snprintf(msg_len_str, sizeof(msg_len_str), "%" PRIu32, (uint32_t)message_len); + sha3_Update(&ctx, (const uint8_t *)msg_len_str, strlen(msg_len_str)); sha3_Update(&ctx, message, message_len); keccak_Final(&ctx, hash); } @@ -56,20 +60,23 @@ void tron_message_hash(const uint8_t *message, size_t message_len, void tron_message_sign(TronSignMessage *msg, const HDNode *node, TronMessageSignature *resp) { uint8_t hash[32]; - uint8_t msg_hash[32]; - // hash the message - struct SHA3_CTX ctx = {0}; - sha3_256_Init(&ctx); - sha3_Update(&ctx, msg->message.bytes, msg->message.size); - keccak_Final(&ctx, msg_hash); + if (msg->has_message_type && msg->message_type == TronMessageType_V2) { + tron_message_hash(msg->message.bytes, msg->message.size, hash); + } else { + uint8_t msg_hash[32]; + struct SHA3_CTX ctx = {0}; + sha3_256_Init(&ctx); + sha3_Update(&ctx, msg->message.bytes, msg->message.size); + keccak_Final(&ctx, msg_hash); - tron_message_hash(msg_hash, 32, hash); + tron_message_hash(msg_hash, 32, hash); + } uint8_t v; if (ecdsa_sign_digest(&secp256k1, node->private_key, hash, resp->signature.bytes, &v, ethereum_is_canonic) != 0) { - fsm_sendFailure(FailureType_Failure_ProcessError, _("Signing failed")); + fsm_sendFailure(FailureType_Failure_ProcessError, "Signing failed"); return; } @@ -158,7 +165,7 @@ int pack_contract(TronSignTx *msg, uint8_t *buf, int *index, int ret = *index, len = 0, cmessage_len = 0, cmessage_index = 0, capi_len = 0, capi_index = 0; - uint8_t cmessage[1024] = {0}; + uint8_t cmessage[2560] = {0}; uint8_t capi[64] = {0}; uint8_t addr_raw[MAX_ADDR_RAW_SIZE] = {0}; @@ -185,9 +192,7 @@ int pack_contract(TronSignTx *msg, uint8_t *buf, int *index, cmessage_len += add_field(cmessage, &cmessage_index, 3, PROTO_TYPE_VARINT); cmessage_len += write_varint(cmessage, &cmessage_index, msg->contract.transfer_contract.amount); - } - - if (msg->contract.has_trigger_smart_contract) { + } else if (msg->contract.has_trigger_smart_contract) { capi_len += add_field(capi, &capi_index, 1, PROTO_TYPE_STRING); capi_len += write_bytes_with_length( capi, &capi_index, @@ -234,9 +239,7 @@ int pack_contract(TronSignTx *msg, uint8_t *buf, int *index, write_varint(cmessage, &cmessage_index, msg->contract.trigger_smart_contract.asset_id); } - } - - if (msg->contract.has_freeze_balance_contract) { + } else if (msg->contract.has_freeze_balance_contract) { capi_len += add_field(capi, &capi_index, 1, PROTO_TYPE_STRING); capi_len += write_bytes_with_length( capi, &capi_index, @@ -275,9 +278,7 @@ int pack_contract(TronSignTx *msg, uint8_t *buf, int *index, cmessage_len += write_bytes_with_length(cmessage, &cmessage_index, receiver_raw, len); } - } - - if (msg->contract.has_unfreeze_balance_contract) { + } else if (msg->contract.has_unfreeze_balance_contract) { capi_len += add_field(capi, &capi_index, 1, PROTO_TYPE_STRING); capi_len += write_bytes_with_length( capi, &capi_index, @@ -308,9 +309,7 @@ int pack_contract(TronSignTx *msg, uint8_t *buf, int *index, cmessage_len += write_bytes_with_length(cmessage, &cmessage_index, receiver_raw, len); } - } - - if (msg->contract.has_withdraw_balance_contract) { + } else if (msg->contract.has_withdraw_balance_contract) { capi_len += add_field(capi, &capi_index, 1, PROTO_TYPE_STRING); capi_len += write_bytes_with_length( capi, &capi_index, @@ -322,9 +321,7 @@ int pack_contract(TronSignTx *msg, uint8_t *buf, int *index, MAX_ADDR_RAW_SIZE); cmessage_len += write_bytes_with_length(cmessage, &cmessage_index, addr_raw, len); - } - - if (msg->contract.has_freeze_balance_v2_contract) { + } else if (msg->contract.has_freeze_balance_v2_contract) { capi_len += add_field(capi, &capi_index, 1, PROTO_TYPE_STRING); capi_len += write_bytes_with_length( capi, &capi_index, @@ -350,9 +347,7 @@ int pack_contract(TronSignTx *msg, uint8_t *buf, int *index, write_varint(cmessage, &cmessage_index, msg->contract.freeze_balance_v2_contract.resource); } - } - - if (msg->contract.has_unfreeze_balance_v2_contract) { + } else if (msg->contract.has_unfreeze_balance_v2_contract) { capi_len += add_field(capi, &capi_index, 1, PROTO_TYPE_STRING); capi_len += write_bytes_with_length( capi, &capi_index, @@ -378,9 +373,7 @@ int pack_contract(TronSignTx *msg, uint8_t *buf, int *index, write_varint(cmessage, &cmessage_index, msg->contract.unfreeze_balance_v2_contract.resource); } - } - - if (msg->contract.has_withdraw_expire_unfreeze_contract) { + } else if (msg->contract.has_withdraw_expire_unfreeze_contract) { capi_len += add_field(capi, &capi_index, 1, PROTO_TYPE_STRING); capi_len += write_bytes_with_length( capi, &capi_index, @@ -394,9 +387,7 @@ int pack_contract(TronSignTx *msg, uint8_t *buf, int *index, MAX_ADDR_RAW_SIZE); cmessage_len += write_bytes_with_length(cmessage, &cmessage_index, addr_raw, len); - } - - if (msg->contract.has_delegate_resource_contract) { + } else if (msg->contract.has_delegate_resource_contract) { capi_len += add_field(capi, &capi_index, 1, PROTO_TYPE_STRING); capi_len += write_bytes_with_length( capi, &capi_index, @@ -443,9 +434,7 @@ int pack_contract(TronSignTx *msg, uint8_t *buf, int *index, write_varint(cmessage, &cmessage_index, msg->contract.delegate_resource_contract.lock_period); } - } - - if (msg->contract.has_undelegate_resource_contract) { + } else if (msg->contract.has_undelegate_resource_contract) { capi_len += add_field(capi, &capi_index, 1, PROTO_TYPE_STRING); capi_len += write_bytes_with_length( capi, &capi_index, @@ -493,6 +482,20 @@ int pack_contract(TronSignTx *msg, uint8_t *buf, int *index, write_varint(buf, index, cmessage_len); write_bytes_without_length(buf, index, cmessage, cmessage_len); + if (msg->contract.has_provider) { + add_field(buf, index, 3, PROTO_TYPE_STRING); + write_bytes_with_length(buf, index, msg->contract.provider.bytes, + msg->contract.provider.size); + } + if (msg->contract.has_contract_name) { + add_field(buf, index, 4, PROTO_TYPE_STRING); + write_bytes_with_length(buf, index, msg->contract.contract_name.bytes, + msg->contract.contract_name.size); + } + if (msg->contract.has_permission_id) { + add_field(buf, index, 5, PROTO_TYPE_VARINT); + write_varint(buf, index, msg->contract.permission_id); + } return *index - ret; } @@ -509,8 +512,7 @@ void serialize(TronSignTx *msg, uint8_t *buf, int *index, write_varint(buf, index, msg->expiration); if (msg->has_data) { add_field(buf, index, 10, PROTO_TYPE_STRING); - write_bytes_with_length(buf, index, (uint8_t *)msg->data, - strlen(msg->data)); + write_bytes_with_length(buf, index, msg->data.bytes, msg->data.size); } // add Contract @@ -1009,6 +1011,20 @@ bool tron_sign_tx(TronSignTx *msg, const char *owner_address, if (msg->contract.has_transfer_contract || msg->contract.has_trigger_smart_contract) { + bool is_transfer = msg->contract.has_transfer_contract || token != NULL; + if (is_transfer && is_energy_rental_provider((const uint8_t *)to_str)) { + layoutDialogCenterAdapterV2( + _("TRON Energy Rental"), NULL, &bmp_bottom_left_close, + &bmp_bottom_right_arrow, NULL, NULL, NULL, NULL, NULL, NULL, + _("Recipient is a known energy rental service provider address.")); + uint8_t key; + WAIT_KEY_OR_ABORT(0, 0, key); + if (key == KEY_CANCEL) { + fsm_sendFailure(FailureType_Failure_ActionCancelled, + "Signing cancelled"); + return false; + } + } char amount_str[60]; int to_len = strlen(to_str); if (0 == to_len) memcpy(to_str, _("to new contract?"), sizeof(to_str)); @@ -1083,7 +1099,7 @@ bool tron_sign_tx(TronSignTx *msg, const char *owner_address, // fill response resp->signature.bytes[64] = 27 + v; resp->signature.size = 65; - resp->has_serialized_tx = 1; + resp->has_serialized_tx = true; resp->serialized_tx.size = index; return true; diff --git a/legacy/firmware/tron_eng_rental.h b/legacy/firmware/tron_eng_rental.h new file mode 100644 index 000000000..0f2bf7318 --- /dev/null +++ b/legacy/firmware/tron_eng_rental.h @@ -0,0 +1,36 @@ +#ifndef __TRON_ENG_RENTAL_H__ +#define __TRON_ENG_RENTAL_H__ + +#include +#include +#include + +typedef struct { + const uint8_t address[35]; + const char *name; +} EnergyRentalProvider; + +static const EnergyRentalProvider energy_rental_providers[] = { + { + .address = "TLgTYgG5bD9crpYqVED3MGvWuAUvdoFYEa", + .name = "TrxRes", + }, +}; + +#define ENERGY_RENTAL_PROVIDERS_COUNT \ + (sizeof(energy_rental_providers) / sizeof(energy_rental_providers[0])) + +const EnergyRentalProvider *get_energy_rental_provider(const uint8_t *address) { + for (size_t i = 0; i < ENERGY_RENTAL_PROVIDERS_COUNT; i++) { + if (memcmp(energy_rental_providers[i].address, address, 35) == 0) { + return &energy_rental_providers[i]; + } + } + return NULL; +} + +bool is_energy_rental_provider(const uint8_t *address) { + return get_energy_rental_provider(address) != NULL; +} + +#endif // __TRON_ENG_RENTAL_H__ diff --git a/legacy/firmware/usb.c b/legacy/firmware/usb.c index de7efc30e..ae355a827 100644 --- a/legacy/firmware/usb.c +++ b/legacy/firmware/usb.c @@ -483,6 +483,7 @@ void usbPoll(void) { msg_write(MessageType_MessageType_Failure, &resp); } config_lockDevice(); + soft_reset_set_preserved_data((uint16_t)config_getSafetyCheckLevel()); svc_system_privileged(); vector_table_t *ivt = (vector_table_t *)FLASH_PTR(FLASH_APP_START); __asm__ volatile("msr msp, %0" ::"r"(ivt->initial_sp_value)); diff --git a/legacy/firmware/version.h b/legacy/firmware/version.h index c3b552a2d..482efb28f 100755 --- a/legacy/firmware/version.h +++ b/legacy/firmware/version.h @@ -6,5 +6,5 @@ #define FIX_VERSION_MINOR 99 #define FIX_VERSION_PATCH 99 -#define ONEKEY_VERSION "3.11.0" -#define ONEKEY_VERSION_HEX 0x3B00 +#define ONEKEY_VERSION "3.12.0" +#define ONEKEY_VERSION_HEX 0x3C00 diff --git a/legacy/memory_app_1.8.0.ld b/legacy/memory_app_1.8.0.ld index 80e94b62e..439f6ab31 100755 --- a/legacy/memory_app_1.8.0.ld +++ b/legacy/memory_app_1.8.0.ld @@ -25,6 +25,7 @@ _codelen = SIZEOF(.text) + SIZEOF(.data) + SIZEOF(.ARM.exidx); _ram_start = ORIGIN(ram); _ram_end = ORIGIN(ram) + LENGTH(ram); _stay_in_bootloader_flag_addr = ABSOLUTE(0x20010000); +_preserved_reset_data_addr = ABSOLUTE(0x20010004); /* Data to preserve across soft reset */ _stack = _ram_end - 8; __stack_chk_guard = _ram_end - 8; system_millis = _ram_end - 4; diff --git a/legacy/util.h b/legacy/util.h index 7dce5920b..469289a5f 100644 --- a/legacy/util.h +++ b/legacy/util.h @@ -82,10 +82,11 @@ int write_bytes(const uint8_t *src, size_t count, BufferWriter *writer); // defined in startup.s (or setup.c for emulator) extern void __attribute__((noreturn)) shutdown(void); +#define PRESERVED_RESET_DATA_INVALID 0xFFFF #if !EMULATOR // defined in memory.ld extern uint8_t _ram_start[], _ram_end[]; - +extern uint32_t _preserved_reset_data_addr; // defined in startup.s extern void memset_reg(void *start, void *stop, uint32_t val); @@ -132,10 +133,37 @@ static inline bool is_mode_unprivileged(void) { __asm__ volatile("mrs %0, control" : "=r"(r0)); return r0 & 1; } +#define PRESERVED_RESET_DATA_MAGIC 0xDCBA0000 +#define PRESERVED_RESET_DATA_MASK 0x0000FFFF + +#define PRESERVED_RESET_DATA_ADDR \ + ((volatile uint32_t *)&_preserved_reset_data_addr) +static inline void soft_reset_set_preserved_data(uint16_t data) { + uint32_t value = + PRESERVED_RESET_DATA_MAGIC | (data & PRESERVED_RESET_DATA_MASK); + *PRESERVED_RESET_DATA_ADDR = value; +} + +static inline uint16_t soft_reset_get_preserved_data(void) { + uint32_t value = *PRESERVED_RESET_DATA_ADDR; + if ((value & PRESERVED_RESET_DATA_MAGIC) == PRESERVED_RESET_DATA_MAGIC) { + return (uint16_t)(value & PRESERVED_RESET_DATA_MASK); + } + return PRESERVED_RESET_DATA_INVALID; +} + +static inline void soft_reset_clear_preserved_data(void) { + *PRESERVED_RESET_DATA_ADDR = 0; +} #else /* EMULATOR */ static inline bool is_mode_unprivileged(void) { return true; } +static inline void soft_reset_set_preserved_data(uint16_t data) { (void)data; } +static inline uint16_t soft_reset_get_preserved_data(void) { + return PRESERVED_RESET_DATA_INVALID; +} +static inline void soft_reset_clear_preserved_data(void) {} #endif #endif