mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-01-27 15:51:02 +00:00
feat(legacy/ethereum): support for EIP-1559 transactions
This commit is contained in:
parent
b2ff86ff3a
commit
076c5b9cbe
1
legacy/firmware/.changelog.d/1834.added
Normal file
1
legacy/firmware/.changelog.d/1834.added
Normal file
@ -0,0 +1 @@
|
||||
Support for Ethereum EIP-1559 transactions.
|
@ -41,15 +41,34 @@
|
||||
uint32). chain_ids larger than this will only return one bit and the caller must
|
||||
recalculate the full value: v = 2 * chain_id + 35 + v_bit */
|
||||
#define MAX_CHAIN_ID ((0xFFFFFFFF - 36) >> 1)
|
||||
#define EIP1559_TX_TYPE 2
|
||||
|
||||
static bool ethereum_signing = false;
|
||||
static uint32_t data_total, data_left;
|
||||
static EthereumTxRequest msg_tx_request;
|
||||
static CONFIDENTIAL uint8_t privkey[32];
|
||||
static uint64_t chain_id;
|
||||
static uint32_t tx_type;
|
||||
static bool eip1559;
|
||||
struct SHA3_CTX keccak_ctx = {0};
|
||||
|
||||
struct signing_params {
|
||||
bool pubkeyhash_set;
|
||||
uint8_t pubkeyhash[20];
|
||||
uint64_t chain_id;
|
||||
|
||||
uint32_t data_length;
|
||||
uint32_t data_initial_chunk_size;
|
||||
const uint8_t *data_initial_chunk_bytes;
|
||||
|
||||
bool has_to;
|
||||
const char *to;
|
||||
|
||||
const TokenType *token;
|
||||
|
||||
uint32_t value_size;
|
||||
const uint8_t *value_bytes;
|
||||
};
|
||||
|
||||
static inline void hash_data(const uint8_t *buf, size_t size) {
|
||||
sha3_Update(&keccak_ctx, buf, size);
|
||||
}
|
||||
@ -192,11 +211,15 @@ static void send_signature(void) {
|
||||
uint8_t v = 0;
|
||||
layoutProgress(_("Signing"), 1000);
|
||||
|
||||
/* eip-155 replay protection */
|
||||
/* hash v=chain_id, r=0, s=0 */
|
||||
hash_rlp_number(chain_id);
|
||||
hash_rlp_length(0, 0);
|
||||
hash_rlp_length(0, 0);
|
||||
if (eip1559) {
|
||||
hash_rlp_list_length(0);
|
||||
} else {
|
||||
/* eip-155 replay protection */
|
||||
/* hash v=chain_id, r=0, s=0 */
|
||||
hash_rlp_number(chain_id);
|
||||
hash_rlp_length(0, 0);
|
||||
hash_rlp_length(0, 0);
|
||||
}
|
||||
|
||||
keccak_Final(&keccak_ctx, hash);
|
||||
if (ecdsa_sign_digest(&secp256k1, privkey, hash, sig, &v,
|
||||
@ -212,7 +235,7 @@ static void send_signature(void) {
|
||||
msg_tx_request.has_data_length = false;
|
||||
|
||||
msg_tx_request.has_signature_v = true;
|
||||
if (chain_id > MAX_CHAIN_ID) {
|
||||
if (eip1559 || chain_id > MAX_CHAIN_ID) {
|
||||
msg_tx_request.signature_v = v;
|
||||
} else {
|
||||
msg_tx_request.signature_v = v + 2 * chain_id + 35;
|
||||
@ -375,6 +398,34 @@ static void layoutEthereumFee(const uint8_t *value, uint32_t value_len,
|
||||
_("for gas?"), NULL);
|
||||
}
|
||||
|
||||
static void layoutEthereumFeeEIP1559(const char *description,
|
||||
const uint8_t *amount_bytes,
|
||||
uint32_t amount_len,
|
||||
const uint8_t *multiplier_bytes,
|
||||
uint32_t multiplier_len) {
|
||||
bignum256 amount_val = {0};
|
||||
uint8_t padded[32] = {0};
|
||||
char amount_str[32] = {0};
|
||||
|
||||
memcpy(padded + (32 - amount_len), amount_bytes, amount_len);
|
||||
bn_read_be(padded, &amount_val);
|
||||
|
||||
if (multiplier_len > 0) {
|
||||
bignum256 multiplier_val = {0};
|
||||
|
||||
memzero(padded, sizeof(padded));
|
||||
memcpy(padded + (32 - multiplier_len), multiplier_bytes, multiplier_len);
|
||||
bn_read_be(padded, &multiplier_val);
|
||||
bn_multiply(&multiplier_val, &amount_val, &secp256k1.prime);
|
||||
}
|
||||
|
||||
ethereumFormatAmount(&amount_val, NULL, amount_str, sizeof(amount_str));
|
||||
|
||||
layoutDialogSwipe(&bmp_icon_question, _("Cancel"), _("Confirm"), NULL,
|
||||
_("Confirm fee"), description, amount_str, NULL, NULL,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* RLP fields:
|
||||
* - nonce (0 .. 32)
|
||||
@ -385,54 +436,136 @@ static void layoutEthereumFee(const uint8_t *value, uint32_t value_len,
|
||||
* - data (0 ..)
|
||||
*/
|
||||
|
||||
static bool ethereum_signing_check(const EthereumSignTx *msg) {
|
||||
size_t tolen = msg->has_to ? strlen(msg->to) : 0;
|
||||
static bool ethereum_signing_init_common(struct signing_params *params) {
|
||||
ethereum_signing = true;
|
||||
sha3_256_Init(&keccak_ctx);
|
||||
|
||||
if (tolen != 42 && tolen != 40 && tolen != 0) {
|
||||
/* Address has wrong length */
|
||||
data_total = data_left = 0;
|
||||
chain_id = 0;
|
||||
|
||||
memzero(&msg_tx_request, sizeof(EthereumTxRequest));
|
||||
|
||||
/* eip-155 chain id */
|
||||
if (params->chain_id < 1) {
|
||||
fsm_sendFailure(FailureType_Failure_DataError, _("Chain ID out of bounds"));
|
||||
return false;
|
||||
}
|
||||
chain_id = params->chain_id;
|
||||
|
||||
if (params->data_length > 0) {
|
||||
if (params->data_initial_chunk_size == 0) {
|
||||
fsm_sendFailure(FailureType_Failure_DataError,
|
||||
_("Data length provided, but no initial chunk"));
|
||||
return false;
|
||||
}
|
||||
/* Our encoding only supports transactions up to 2^24 bytes. To
|
||||
* prevent exceeding the limit we use a stricter limit on data length.
|
||||
*/
|
||||
if (params->data_length > 16000000) {
|
||||
fsm_sendFailure(FailureType_Failure_DataError,
|
||||
_("Data length exceeds limit"));
|
||||
return false;
|
||||
}
|
||||
data_total = params->data_length;
|
||||
} else {
|
||||
data_total = 0;
|
||||
}
|
||||
if (params->data_initial_chunk_size > data_total) {
|
||||
fsm_sendFailure(FailureType_Failure_DataError,
|
||||
_("Invalid size of initial chunk"));
|
||||
return false;
|
||||
}
|
||||
|
||||
// safety checks
|
||||
|
||||
size_t tolen = params->has_to ? strlen(params->to) : 0;
|
||||
/* Address has wrong length */
|
||||
bool wrong_length = (tolen != 42 && tolen != 40 && tolen != 0);
|
||||
|
||||
// sending transaction to address 0 (contract creation) without a data field
|
||||
if (tolen == 0 && (!msg->has_data_length || msg->data_length == 0)) {
|
||||
return false;
|
||||
}
|
||||
bool contract_without_data = (tolen == 0 && params->data_length == 0);
|
||||
|
||||
if (msg->gas_price.size + msg->gas_limit.size > 30) {
|
||||
// sanity check that fee doesn't overflow
|
||||
if (wrong_length || contract_without_data) {
|
||||
fsm_sendFailure(FailureType_Failure_DataError, _("Safety check failed"));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ethereum_signing_init(EthereumSignTx *msg, const HDNode *node) {
|
||||
ethereum_signing = true;
|
||||
sha3_256_Init(&keccak_ctx);
|
||||
|
||||
memzero(&msg_tx_request, sizeof(EthereumTxRequest));
|
||||
/* set fields to 0, to avoid conditions later */
|
||||
if (!msg->has_value) msg->value.size = 0;
|
||||
if (!msg->has_data_initial_chunk) msg->data_initial_chunk.size = 0;
|
||||
bool toset;
|
||||
uint8_t pubkeyhash[20] = {0};
|
||||
if (msg->has_to && ethereum_parse(msg->to, pubkeyhash)) {
|
||||
toset = true;
|
||||
static void ethereum_signing_handle_erc20(struct signing_params *params) {
|
||||
if (params->has_to && ethereum_parse(params->to, params->pubkeyhash)) {
|
||||
params->pubkeyhash_set = true;
|
||||
} else {
|
||||
msg->to[0] = 0;
|
||||
toset = false;
|
||||
memzero(pubkeyhash, sizeof(pubkeyhash));
|
||||
params->pubkeyhash_set = false;
|
||||
memzero(params->pubkeyhash, sizeof(params->pubkeyhash));
|
||||
}
|
||||
if (!msg->has_nonce) msg->nonce.size = 0;
|
||||
|
||||
/* eip-155 chain id */
|
||||
if (msg->chain_id < 1) {
|
||||
fsm_sendFailure(FailureType_Failure_DataError, _("Chain ID out of bounds"));
|
||||
// detect ERC-20 token
|
||||
if (params->pubkeyhash_set && params->value_size == 0 && data_total == 68 &&
|
||||
params->data_initial_chunk_size == 68 &&
|
||||
memcmp(params->data_initial_chunk_bytes,
|
||||
"\xa9\x05\x9c\xbb\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
|
||||
16) == 0) {
|
||||
params->token = tokenByChainAddress(chain_id, params->pubkeyhash);
|
||||
}
|
||||
}
|
||||
|
||||
static bool ethereum_signing_confirm_common(
|
||||
const struct signing_params *params) {
|
||||
if (params->token != NULL) {
|
||||
layoutEthereumConfirmTx(params->data_initial_chunk_bytes + 16, 20,
|
||||
params->data_initial_chunk_bytes + 36, 32,
|
||||
params->token);
|
||||
} else {
|
||||
layoutEthereumConfirmTx(params->pubkeyhash, 20, params->value_bytes,
|
||||
params->value_size, NULL);
|
||||
}
|
||||
|
||||
if (!protectButton(ButtonRequestType_ButtonRequest_SignTx, false)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (params->token == NULL && data_total > 0) {
|
||||
layoutEthereumData(params->data_initial_chunk_bytes,
|
||||
params->data_initial_chunk_size, data_total);
|
||||
if (!protectButton(ButtonRequestType_ButtonRequest_SignTx, false)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ethereum_signing_init(const EthereumSignTx *msg, const HDNode *node) {
|
||||
struct signing_params params = {
|
||||
.chain_id = msg->chain_id,
|
||||
|
||||
.data_length = msg->data_length,
|
||||
.data_initial_chunk_size = msg->data_initial_chunk.size,
|
||||
.data_initial_chunk_bytes = msg->data_initial_chunk.bytes,
|
||||
|
||||
.has_to = msg->has_to,
|
||||
.to = msg->to,
|
||||
|
||||
.value_size = msg->value.size,
|
||||
.value_bytes = msg->value.bytes,
|
||||
};
|
||||
|
||||
eip1559 = false;
|
||||
if (!ethereum_signing_init_common(¶ms)) {
|
||||
ethereum_signing_abort();
|
||||
return;
|
||||
}
|
||||
chain_id = msg->chain_id;
|
||||
|
||||
// sanity check that fee doesn't overflow
|
||||
if (msg->gas_price.size + msg->gas_limit.size > 30) {
|
||||
fsm_sendFailure(FailureType_Failure_DataError, _("Safety check failed"));
|
||||
ethereum_signing_abort();
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t tx_type = 0;
|
||||
/* Wanchain txtype */
|
||||
if (msg->has_tx_type) {
|
||||
if (msg->tx_type == 1 || msg->tx_type == 6) {
|
||||
@ -442,82 +575,19 @@ void ethereum_signing_init(EthereumSignTx *msg, const HDNode *node) {
|
||||
ethereum_signing_abort();
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
tx_type = 0;
|
||||
}
|
||||
|
||||
if (msg->has_data_length && msg->data_length > 0) {
|
||||
if (!msg->has_data_initial_chunk || msg->data_initial_chunk.size == 0) {
|
||||
fsm_sendFailure(FailureType_Failure_DataError,
|
||||
_("Data length provided, but no initial chunk"));
|
||||
ethereum_signing_abort();
|
||||
return;
|
||||
}
|
||||
/* Our encoding only supports transactions up to 2^24 bytes. To
|
||||
* prevent exceeding the limit we use a stricter limit on data length.
|
||||
*/
|
||||
if (msg->data_length > 16000000) {
|
||||
fsm_sendFailure(FailureType_Failure_DataError,
|
||||
_("Data length exceeds limit"));
|
||||
ethereum_signing_abort();
|
||||
return;
|
||||
}
|
||||
data_total = msg->data_length;
|
||||
} else {
|
||||
data_total = 0;
|
||||
}
|
||||
if (msg->data_initial_chunk.size > data_total) {
|
||||
fsm_sendFailure(FailureType_Failure_DataError,
|
||||
_("Invalid size of initial chunk"));
|
||||
ethereum_signing_abort();
|
||||
return;
|
||||
}
|
||||
ethereum_signing_handle_erc20(¶ms);
|
||||
|
||||
// safety checks
|
||||
if (!ethereum_signing_check(msg)) {
|
||||
fsm_sendFailure(FailureType_Failure_DataError, _("Safety check failed"));
|
||||
ethereum_signing_abort();
|
||||
return;
|
||||
}
|
||||
|
||||
const TokenType *token = NULL;
|
||||
|
||||
// detect ERC-20 token
|
||||
if (toset && msg->value.size == 0 && data_total == 68 &&
|
||||
msg->data_initial_chunk.size == 68 &&
|
||||
memcmp(msg->data_initial_chunk.bytes,
|
||||
"\xa9\x05\x9c\xbb\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
|
||||
16) == 0) {
|
||||
token = tokenByChainAddress(chain_id, pubkeyhash);
|
||||
}
|
||||
|
||||
if (token != NULL) {
|
||||
layoutEthereumConfirmTx(msg->data_initial_chunk.bytes + 16, 20,
|
||||
msg->data_initial_chunk.bytes + 36, 32, token);
|
||||
} else {
|
||||
layoutEthereumConfirmTx(pubkeyhash, 20, msg->value.bytes, msg->value.size,
|
||||
NULL);
|
||||
}
|
||||
|
||||
if (!protectButton(ButtonRequestType_ButtonRequest_SignTx, false)) {
|
||||
if (!ethereum_signing_confirm_common(¶ms)) {
|
||||
fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL);
|
||||
ethereum_signing_abort();
|
||||
return;
|
||||
}
|
||||
|
||||
if (token == NULL && data_total > 0) {
|
||||
layoutEthereumData(msg->data_initial_chunk.bytes,
|
||||
msg->data_initial_chunk.size, data_total);
|
||||
if (!protectButton(ButtonRequestType_ButtonRequest_SignTx, false)) {
|
||||
fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL);
|
||||
ethereum_signing_abort();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
layoutEthereumFee(msg->value.bytes, msg->value.size, msg->gas_price.bytes,
|
||||
msg->gas_price.size, msg->gas_limit.bytes,
|
||||
msg->gas_limit.size, token != NULL);
|
||||
msg->gas_limit.size, params.token != NULL);
|
||||
if (!protectButton(ButtonRequestType_ButtonRequest_SignTx, false)) {
|
||||
fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL);
|
||||
ethereum_signing_abort();
|
||||
@ -534,10 +604,11 @@ void ethereum_signing_init(EthereumSignTx *msg, const HDNode *node) {
|
||||
rlp_calculate_length(msg->gas_price.size, msg->gas_price.bytes[0]);
|
||||
rlp_length +=
|
||||
rlp_calculate_length(msg->gas_limit.size, msg->gas_limit.bytes[0]);
|
||||
rlp_length += rlp_calculate_length(toset ? 20 : 0, pubkeyhash[0]);
|
||||
rlp_length += rlp_calculate_length(msg->value.size, msg->value.bytes[0]);
|
||||
rlp_length += rlp_calculate_length(params.pubkeyhash_set ? 20 : 0,
|
||||
params.pubkeyhash[0]);
|
||||
rlp_length += rlp_calculate_length(params.value_size, params.value_bytes[0]);
|
||||
rlp_length +=
|
||||
rlp_calculate_length(data_total, msg->data_initial_chunk.bytes[0]);
|
||||
rlp_calculate_length(data_total, params.data_initial_chunk_bytes[0]);
|
||||
if (tx_type) {
|
||||
rlp_length += rlp_calculate_number_length(tx_type);
|
||||
}
|
||||
@ -556,11 +627,122 @@ void ethereum_signing_init(EthereumSignTx *msg, const HDNode *node) {
|
||||
hash_rlp_field(msg->nonce.bytes, msg->nonce.size);
|
||||
hash_rlp_field(msg->gas_price.bytes, msg->gas_price.size);
|
||||
hash_rlp_field(msg->gas_limit.bytes, msg->gas_limit.size);
|
||||
hash_rlp_field(pubkeyhash, toset ? 20 : 0);
|
||||
hash_rlp_field(msg->value.bytes, msg->value.size);
|
||||
hash_rlp_length(data_total, msg->data_initial_chunk.bytes[0]);
|
||||
hash_data(msg->data_initial_chunk.bytes, msg->data_initial_chunk.size);
|
||||
data_left = data_total - msg->data_initial_chunk.size;
|
||||
hash_rlp_field(params.pubkeyhash, params.pubkeyhash_set ? 20 : 0);
|
||||
hash_rlp_field(params.value_bytes, params.value_size);
|
||||
hash_rlp_length(data_total, params.data_initial_chunk_bytes[0]);
|
||||
hash_data(params.data_initial_chunk_bytes, params.data_initial_chunk_size);
|
||||
data_left = data_total - params.data_initial_chunk_size;
|
||||
|
||||
memcpy(privkey, node->private_key, 32);
|
||||
|
||||
if (data_left > 0) {
|
||||
send_request_chunk();
|
||||
} else {
|
||||
send_signature();
|
||||
}
|
||||
}
|
||||
|
||||
void ethereum_signing_init_eip1559(const EthereumSignTxEIP1559 *msg,
|
||||
const HDNode *node) {
|
||||
struct signing_params params = {
|
||||
.chain_id = msg->chain_id,
|
||||
|
||||
.data_length = msg->data_length,
|
||||
.data_initial_chunk_size = msg->data_initial_chunk.size,
|
||||
.data_initial_chunk_bytes = msg->data_initial_chunk.bytes,
|
||||
|
||||
.has_to = msg->has_to,
|
||||
.to = msg->to,
|
||||
|
||||
.value_size = msg->value.size,
|
||||
.value_bytes = msg->value.bytes,
|
||||
};
|
||||
|
||||
eip1559 = true;
|
||||
if (!ethereum_signing_init_common(¶ms)) {
|
||||
ethereum_signing_abort();
|
||||
return;
|
||||
}
|
||||
|
||||
// sanity check that fee doesn't overflow
|
||||
if (msg->max_gas_fee.size + msg->gas_limit.size > 30 ||
|
||||
msg->max_priority_fee.size + msg->gas_limit.size > 30) {
|
||||
fsm_sendFailure(FailureType_Failure_DataError, _("Safety check failed"));
|
||||
ethereum_signing_abort();
|
||||
return;
|
||||
}
|
||||
|
||||
ethereum_signing_handle_erc20(¶ms);
|
||||
|
||||
if (!ethereum_signing_confirm_common(¶ms)) {
|
||||
fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL);
|
||||
ethereum_signing_abort();
|
||||
return;
|
||||
}
|
||||
|
||||
layoutEthereumFeeEIP1559(_("Maximum fee per gas"), msg->max_gas_fee.bytes,
|
||||
msg->max_gas_fee.size, NULL, 0);
|
||||
if (!protectButton(ButtonRequestType_ButtonRequest_SignTx, false)) {
|
||||
fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL);
|
||||
ethereum_signing_abort();
|
||||
return;
|
||||
}
|
||||
|
||||
layoutEthereumFeeEIP1559(_("Priority fee per gas"),
|
||||
msg->max_priority_fee.bytes,
|
||||
msg->max_priority_fee.size, NULL, 0);
|
||||
if (!protectButton(ButtonRequestType_ButtonRequest_SignTx, false)) {
|
||||
fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL);
|
||||
ethereum_signing_abort();
|
||||
return;
|
||||
}
|
||||
|
||||
layoutEthereumFeeEIP1559(_("Maximum fee"), msg->gas_limit.bytes,
|
||||
msg->gas_limit.size, msg->max_gas_fee.bytes,
|
||||
msg->max_gas_fee.size);
|
||||
if (!protectButton(ButtonRequestType_ButtonRequest_SignTx, false)) {
|
||||
fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL);
|
||||
ethereum_signing_abort();
|
||||
return;
|
||||
}
|
||||
|
||||
/* Stage 1: Calculate total RLP length */
|
||||
uint32_t rlp_length = 0;
|
||||
|
||||
layoutProgress(_("Signing"), 0);
|
||||
|
||||
rlp_length += rlp_calculate_number_length(chain_id);
|
||||
rlp_length += rlp_calculate_length(msg->nonce.size, msg->nonce.bytes[0]);
|
||||
rlp_length += rlp_calculate_length(msg->max_priority_fee.size,
|
||||
msg->max_priority_fee.bytes[0]);
|
||||
rlp_length +=
|
||||
rlp_calculate_length(msg->max_gas_fee.size, msg->max_gas_fee.bytes[0]);
|
||||
rlp_length +=
|
||||
rlp_calculate_length(msg->gas_limit.size, msg->gas_limit.bytes[0]);
|
||||
rlp_length += rlp_calculate_length(params.pubkeyhash_set ? 20 : 0,
|
||||
params.pubkeyhash[0]);
|
||||
rlp_length += rlp_calculate_length(params.value_size, params.value_bytes[0]);
|
||||
rlp_length +=
|
||||
rlp_calculate_length(data_total, params.data_initial_chunk_bytes[0]);
|
||||
|
||||
rlp_length += rlp_calculate_length(0, 0xff);
|
||||
|
||||
/* Stage 2: Store header fields */
|
||||
hash_rlp_number(EIP1559_TX_TYPE);
|
||||
hash_rlp_list_length(rlp_length);
|
||||
|
||||
layoutProgress(_("Signing"), 100);
|
||||
|
||||
hash_rlp_number(chain_id);
|
||||
hash_rlp_field(msg->nonce.bytes, msg->nonce.size);
|
||||
hash_rlp_field(msg->max_priority_fee.bytes, msg->max_priority_fee.size);
|
||||
hash_rlp_field(msg->max_gas_fee.bytes, msg->max_gas_fee.size);
|
||||
hash_rlp_field(msg->gas_limit.bytes, msg->gas_limit.size);
|
||||
hash_rlp_field(params.pubkeyhash, params.pubkeyhash_set ? 20 : 0);
|
||||
hash_rlp_field(params.value_bytes, params.value_size);
|
||||
hash_rlp_length(data_total, params.data_initial_chunk_bytes[0]);
|
||||
hash_data(params.data_initial_chunk_bytes, params.data_initial_chunk_size);
|
||||
data_left = data_total - params.data_initial_chunk_size;
|
||||
|
||||
memcpy(privkey, node->private_key, 32);
|
||||
|
||||
|
@ -25,7 +25,9 @@
|
||||
#include "bip32.h"
|
||||
#include "messages-ethereum.pb.h"
|
||||
|
||||
void ethereum_signing_init(EthereumSignTx *msg, const HDNode *node);
|
||||
void ethereum_signing_init(const EthereumSignTx *msg, const HDNode *node);
|
||||
void ethereum_signing_init_eip1559(const EthereumSignTxEIP1559 *msg,
|
||||
const HDNode *node);
|
||||
void ethereum_signing_abort(void);
|
||||
void ethereum_signing_txack(const EthereumTxAck *msg);
|
||||
|
||||
|
@ -99,9 +99,7 @@ void fsm_msgDebugLinkFlashErase(const DebugLinkFlashErase *msg);
|
||||
// ethereum
|
||||
void fsm_msgEthereumGetAddress(const EthereumGetAddress *msg);
|
||||
void fsm_msgEthereumGetPublicKey(const EthereumGetPublicKey *msg);
|
||||
void fsm_msgEthereumSignTx(
|
||||
EthereumSignTx
|
||||
*msg); // not const because we mutate transaction during validation
|
||||
void fsm_msgEthereumSignTx(const EthereumSignTx *msg);
|
||||
void fsm_msgEthereumSignTxEIP1559(const EthereumSignTxEIP1559 *msg);
|
||||
void fsm_msgEthereumTxAck(const EthereumTxAck *msg);
|
||||
void fsm_msgEthereumSignMessage(const EthereumSignMessage *msg);
|
||||
|
@ -60,7 +60,7 @@ void fsm_msgEthereumGetPublicKey(const EthereumGetPublicKey *msg) {
|
||||
layoutHome();
|
||||
}
|
||||
|
||||
void fsm_msgEthereumSignTx(EthereumSignTx *msg) {
|
||||
void fsm_msgEthereumSignTx(const EthereumSignTx *msg) {
|
||||
CHECK_INITIALIZED
|
||||
|
||||
CHECK_PIN
|
||||
@ -72,13 +72,20 @@ void fsm_msgEthereumSignTx(EthereumSignTx *msg) {
|
||||
ethereum_signing_init(msg, node);
|
||||
}
|
||||
|
||||
void fsm_msgEthereumTxAck(const EthereumTxAck *msg) {
|
||||
ethereum_signing_txack(msg);
|
||||
void fsm_msgEthereumSignTxEIP1559(const EthereumSignTxEIP1559 *msg) {
|
||||
CHECK_INITIALIZED
|
||||
|
||||
CHECK_PIN
|
||||
|
||||
const HDNode *node = fsm_getDerivedNode(SECP256K1_NAME, msg->address_n,
|
||||
msg->address_n_count, NULL);
|
||||
if (!node) return;
|
||||
|
||||
ethereum_signing_init_eip1559(msg, node);
|
||||
}
|
||||
|
||||
void fsm_msgEthereumSignTxEIP1559(const EthereumSignTxEIP1559 *msg) {
|
||||
(void)msg;
|
||||
fsm_sendFailure(FailureType_Failure_UnexpectedMessage, _("Not implemented"));
|
||||
void fsm_msgEthereumTxAck(const EthereumTxAck *msg) {
|
||||
ethereum_signing_txack(msg);
|
||||
}
|
||||
|
||||
void fsm_msgEthereumGetAddress(const EthereumGetAddress *msg) {
|
||||
|
@ -57,7 +57,6 @@ def test_signtx(client, parameters, result):
|
||||
|
||||
|
||||
@parametrize_using_common_fixtures("ethereum/sign_tx_eip1559.json")
|
||||
@pytest.mark.skip_t1
|
||||
def test_signtx_eip1559(client, parameters, result):
|
||||
with client:
|
||||
sig_v, sig_r, sig_s = ethereum.sign_tx_eip1559(
|
||||
@ -213,7 +212,6 @@ def test_signtx_eip1559_access_list(client):
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.skip_t1
|
||||
def test_signtx_eip1559_access_list_larger(client):
|
||||
with client:
|
||||
|
||||
@ -267,7 +265,6 @@ def test_signtx_eip1559_access_list_larger(client):
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.skip_t1
|
||||
def test_sanity_checks_eip1559(client):
|
||||
"""Is not vectorized because these are internal-only tests that do not
|
||||
need to be exposed to the public.
|
||||
|
Loading…
Reference in New Issue
Block a user