Add support for EIP2718 (enveloppe) and EIP2930 (acess list tx); Display chain ID when different from 1 (ethereum mainnet)

This commit is contained in:
pscott
2021-04-21 16:56:17 +02:00
parent 5dd99c3d48
commit 970f0355dd
14 changed files with 419 additions and 146 deletions

View File

@@ -44,10 +44,8 @@ void handleSign(uint8_t p1,
// EIP 2718: TransactionType might be present before the TransactionPayload.
uint8_t txType = *workBuffer;
if (txType >= MIN_TX_TYPE && txType <= MAX_TX_TYPE) {
PRINTF("Transaction type: %u\n", txType);
// Enumerate through all supported txTypes here...
if (txType == LEGACY_TX) {
if (txType == EIP2930) {
txContext.txType = txType;
workBuffer++;
dataLength--;
@@ -55,6 +53,8 @@ void handleSign(uint8_t p1,
PRINTF("Transaction type not supported\n");
THROW(0x6501);
}
} else {
txContext.txType = LEGACY;
}
initTx(&txContext, &global_sha3, &tmpContent.txContent, customProcessor, NULL);
} else if (p1 != P1_MORE) {
@@ -67,7 +67,7 @@ void handleSign(uint8_t p1,
PRINTF("Signature not initialized\n");
THROW(0x6985);
}
if (txContext.currentField == TX_RLP_NONE) {
if (txContext.currentField == RLP_NONE) {
PRINTF("Parser not initialized\n");
THROW(0x6985);
}

View File

@@ -28,12 +28,18 @@ uint32_t splitBinaryParameterPart(char *result, uint8_t *parameter) {
}
customStatus_e customProcessor(txContext_t *context) {
if ((context->currentField == TX_RLP_DATA) && (context->currentFieldLength != 0)) {
if (((context->txType == LEGACY && context->currentField == LEGACY_RLP_DATA) ||
(context->txType == EIP2930 && context->currentField == EIP2930_RLP_DATA)) &&
(context->currentFieldLength != 0)) {
dataPresent = true;
// If handling a new contract rather than a function call, abort immediately
if (tmpContent.txContent.destinationLength == 0) {
return CUSTOM_NOT_HANDLED;
}
// If data field is less than 4 bytes long, do not try to use a plugin.
if (context->currentFieldLength < 4) {
return CUSTOM_NOT_HANDLED;
}
if (context->currentFieldPos == 0) {
ethPluginInitContract_t pluginInit;
// If handling the beginning of the data field, assume that the function selector is
@@ -51,6 +57,7 @@ customStatus_e customProcessor(txContext_t *context) {
context->currentFieldLength);
dataContext.tokenContext.pluginAvailable =
eth_plugin_perform_init(tmpContent.txContent.destination, &pluginInit);
PRINTF("a\n");
}
PRINTF("pluginAvailable %d\n", dataContext.tokenContext.pluginAvailable);
if (dataContext.tokenContext.pluginAvailable) {
@@ -238,10 +245,21 @@ void finalizeParsing(bool direct) {
// Verify the chain
if (chainConfig->chainId != 0) {
uint32_t v = getV(&tmpContent.txContent);
if (chainConfig->chainId != v) {
uint32_t id = 0;
if (txContext.txType == LEGACY) {
id = u32_from_BE(txContext.content->v, txContext.content->vLength);
} else if (txContext.txType == EIP2930) {
id = u32_from_BE(txContext.content->chainID.value, txContext.content->chainID.length);
} else {
PRINTF("TxType `%u` not supported while checking for chainID\n", txContext.txType);
return;
}
PRINTF("OFFICIAL: %u, RECEIVED: %u\n", chainConfig->chainId, id);
if (chainConfig->chainId != id) {
PRINTF("Invalid chainID %u expected %u\n", id, chainConfig->chainId);
reset_app_context();
PRINTF("Invalid chainId %d expected %d\n", v, chainConfig->chainId);
reportFinalizeError(direct);
if (!direct) {
return;
@@ -323,7 +341,6 @@ void finalizeParsing(bool direct) {
}
if (dataPresent && !N_storage.dataAllowed) {
PRINTF("Data field forbidden\n");
reportFinalizeError(direct);
if (!direct) {
return;
@@ -368,6 +385,24 @@ void finalizeParsing(bool direct) {
compareOrCopy(strings.common.maxFee, displayBuffer, called_from_swap);
}
// Prepare chainID field
if (genericUI) {
if (txContext.txType == LEGACY) {
uint32_t id = u32_from_BE(txContext.content->v, txContext.content->vLength);
u32_to_str((char *) strings.common.chainID, sizeof(strings.common.chainID), id);
} else if (txContext.txType == EIP2930) {
uint256_t chainID;
convertUint256BE(tmpContent.txContent.chainID.value,
tmpContent.txContent.chainID.length,
&chainID);
tostring256(&chainID, 10, displayBuffer, sizeof(displayBuffer));
strncpy(strings.common.chainID, displayBuffer, sizeof(strings.common.chainID));
} else {
PRINTF("Txtype `%u` not supported while generating chainID\n", txContext.txType);
return;
}
}
bool no_consent = false;
no_consent = called_from_swap;

View File

@@ -8,7 +8,7 @@ unsigned int io_seproxyhal_touch_tx_ok(const bagl_element_t *e) {
uint8_t signatureLength;
cx_ecfp_private_key_t privateKey;
uint32_t tx = 0;
uint32_t v = getV(&tmpContent.txContent);
uint32_t v = u32_from_BE(tmpContent.txContent.v, tmpContent.txContent.vLength);
io_seproxyhal_io_heartbeat();
os_perso_derive_node_bip32(CX_CURVE_256K1,
tmpCtx.transactionContext.bip32Path,

View File

@@ -1,5 +1,7 @@
#include "shared_context.h"
#include "ui_callbacks.h"
#include "chainConfig.h"
#include "utils.h"
// clang-format off
UX_STEP_NOCB(
@@ -85,7 +87,7 @@ UX_FLOW(ux_confirm_parameter_flow,
//////////////////////////////////////////////////////////////////////
// clang-format off
UX_STEP_NOCB(ux_approval_tx_1_step,
UX_STEP_NOCB(ux_approval_review_step,
pnn,
{
&C_icon_eye,
@@ -93,28 +95,35 @@ UX_STEP_NOCB(ux_approval_tx_1_step,
"transaction",
});
UX_STEP_NOCB(
ux_approval_tx_2_step,
ux_approval_amount_step,
bnnn_paging,
{
.title = "Amount",
.text = strings.common.fullAmount
});
UX_STEP_NOCB(
ux_approval_tx_3_step,
ux_approval_address_step,
bnnn_paging,
{
.title = "Address",
.text = strings.common.fullAddress,
});
UX_STEP_NOCB(
ux_approval_tx_4_step,
ux_approval_fees_step,
bnnn_paging,
{
.title = "Max Fees",
.text = strings.common.maxFee,
});
UX_STEP_NOCB(
ux_approval_chainid_step,
bnnn_paging,
{
.title = "Chain ID",
.text = strings.common.chainID,
});
UX_STEP_CB(
ux_approval_tx_5_step,
ux_approval_accept_step,
pbb,
io_seproxyhal_touch_tx_ok(NULL),
{
@@ -123,7 +132,7 @@ UX_STEP_CB(
"and send",
});
UX_STEP_CB(
ux_approval_tx_6_step,
ux_approval_reject_step,
pb,
io_seproxyhal_touch_tx_cancel(NULL),
{
@@ -132,14 +141,14 @@ UX_STEP_CB(
});
UX_STEP_NOCB(
ux_approval_tx_display_nonce_step,
ux_approval_nonce_step,
bnnn_paging,
{
.title = "Nonce",
.text = strings.common.nonce,
});
UX_STEP_NOCB(ux_approval_tx_data_warning_step,
UX_STEP_NOCB(ux_approval_data_warning_step,
pbb,
{
&C_icon_warning,
@@ -148,22 +157,35 @@ UX_STEP_NOCB(ux_approval_tx_data_warning_step,
});
// clang-format on
const ux_flow_step_t *ux_approval_tx_flow_[9];
const ux_flow_step_t *ux_approval_tx_flow_[10];
void ux_approve_tx(bool dataPresent) {
int step = 0;
ux_approval_tx_flow_[step++] = &ux_approval_tx_1_step;
ux_approval_tx_flow_[step++] = &ux_approval_review_step;
if (dataPresent && !N_storage.contractDetails) {
ux_approval_tx_flow_[step++] = &ux_approval_tx_data_warning_step;
ux_approval_tx_flow_[step++] = &ux_approval_data_warning_step;
}
ux_approval_tx_flow_[step++] = &ux_approval_tx_2_step;
ux_approval_tx_flow_[step++] = &ux_approval_tx_3_step;
ux_approval_tx_flow_[step++] = &ux_approval_amount_step;
ux_approval_tx_flow_[step++] = &ux_approval_address_step;
if (N_storage.displayNonce) {
ux_approval_tx_flow_[step++] = &ux_approval_tx_display_nonce_step;
ux_approval_tx_flow_[step++] = &ux_approval_nonce_step;
}
ux_approval_tx_flow_[step++] = &ux_approval_tx_4_step;
ux_approval_tx_flow_[step++] = &ux_approval_tx_5_step;
ux_approval_tx_flow_[step++] = &ux_approval_tx_6_step;
uint32_t id;
if (txContext.txType == LEGACY) {
id = u32_from_BE(txContext.content->v, txContext.content->vLength);
} else if (txContext.txType == EIP2930) {
id = u32_from_BE(txContext.content->chainID.value, txContext.content->chainID.length);
} else {
PRINTF("TxType `%u` not supported while preparing to approve tx\n", txContext.txType);
THROW(0x6501);
}
if (id != ETHEREUM_MAINNET_CHAINID) {
ux_approval_tx_flow_[step++] = &ux_approval_chainid_step;
}
ux_approval_tx_flow_[step++] = &ux_approval_fees_step;
ux_approval_tx_flow_[step++] = &ux_approval_accept_step;
ux_approval_tx_flow_[step++] = &ux_approval_reject_step;
ux_approval_tx_flow_[step++] = FLOW_END_STEP;
ux_flow_init(0, ux_approval_tx_flow_, NULL);