Summary
Signing an arbitrary contract call displays only the first chunk of the payload, while the signature covers all of it.
lib/firmware/ethereum.c, in ethereum_signing_init():
layoutEthereumData(msg->data_initial_chunk.bytes,
msg->data_initial_chunk.size, data_total,
confirm_body_message, sizeof(confirm_body_message));
if (!confirm(ButtonRequestType_ButtonRequest_ConfirmOutput,
"Confirm Ethereum Data", "%s", confirm_body_message)) {
data_total may be far larger than data_initial_chunk.size (the remainder streams in via EthereumTxAck), and confirm_body_message is a fixed char[121]. The user approves a window onto the payload and signs the whole thing.
There is a blind-signing warning first (suppressed once AdvancedMode is enabled), so this is disclosed rather than hidden — but the warning is generic and the displayed data is not what is signed.
Relationship to other work
#393 converted several sites to confirm_bytes(), which pages every byte of a length-delimited payload (Bitcoin/Ethereum SignMessage, both VerifyMessage paths, the SignIdentity challenge). This site was not converted, because the payload is streamed rather than held in one buffer — paging it requires buffering or incremental display, which is a design question rather than a mechanical substitution.
Acceptance criteria
Summary
Signing an arbitrary contract call displays only the first chunk of the payload, while the signature covers all of it.
lib/firmware/ethereum.c, inethereum_signing_init():data_totalmay be far larger thandata_initial_chunk.size(the remainder streams in viaEthereumTxAck), andconfirm_body_messageis a fixedchar[121]. The user approves a window onto the payload and signs the whole thing.There is a blind-signing warning first (suppressed once
AdvancedModeis enabled), so this is disclosed rather than hidden — but the warning is generic and the displayed data is not what is signed.Relationship to other work
#393 converted several sites to
confirm_bytes(), which pages every byte of a length-delimited payload (Bitcoin/Ethereum SignMessage, both VerifyMessage paths, the SignIdentity challenge). This site was not converted, because the payload is streamed rather than held in one buffer — paging it requires buffering or incremental display, which is a design question rather than a mechanical substitution.Acceptance criteria
AdvancedModewarning as the only mitigation