Skip to content

Commit 61500a6

Browse files
authored
fix(core): fix the safe transaction detection issue when the call dat… (#369)
fix(core): fix the safe transaction detection issue when the call data size large than 1024
1 parent 01ea1e3 commit 61500a6

File tree

3 files changed

+63
-16
lines changed

3 files changed

+63
-16
lines changed

core/src/apps/ethereum/onekey/sign_tx.py

Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@
4141
# the full value: v = 2 * chain_id + 35 + v_bit
4242
MAX_CHAIN_ID = (0xFFFF_FFFF - 36) // 2
4343

44+
DATA_LEFT: bytearray | None = None
45+
4446

4547
@with_keychain_from_chain_id
4648
async def sign_tx(
@@ -217,10 +219,15 @@ async def sign_tx(
217219
rlp.write_header(sha, data_total, rlp.STRING_HEADER_BYTE, data)
218220
sha.extend(data)
219221

220-
while data_left > 0:
221-
resp = await send_request_chunk(ctx, data_left)
222-
data_left -= len(resp.data_chunk)
223-
sha.extend(resp.data_chunk)
222+
global DATA_LEFT
223+
if DATA_LEFT is not None:
224+
sha.extend(DATA_LEFT)
225+
DATA_LEFT = None
226+
else:
227+
while data_left > 0:
228+
resp = await send_request_chunk(ctx, data_left)
229+
data_left -= len(resp.data_chunk)
230+
sha.extend(resp.data_chunk)
224231

225232
# eip 155 replay protection
226233
rlp.write(sha, msg.chain_id)
@@ -360,7 +367,7 @@ def is_safe_exec_transaction(msg: EthereumSignTxAny) -> bool:
360367
if (
361368
len(msg.to) in (40, 42)
362369
and len(msg.value) == 0
363-
and 437 <= msg.data_length <= 1024
370+
and 437 <= msg.data_length
364371
and msg.data_initial_chunk[:16]
365372
== b"\x6a\x76\x12\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
366373
# 0x6a761202 == keccak("execTransaction(address,uint256,bytes,uint8,uint256,uint256,uint256,address,address,bytes)")[:4].hex()
@@ -369,6 +376,15 @@ def is_safe_exec_transaction(msg: EthereumSignTxAny) -> bool:
369376
return False
370377

371378

379+
def get_remaining_data() -> bytearray | None:
380+
return DATA_LEFT
381+
382+
383+
def reset_data_left() -> None:
384+
global DATA_LEFT
385+
DATA_LEFT = None
386+
387+
372388
async def handle_safe_tx(
373389
ctx: wire.Context, msg: EthereumSignTxAny, from_addr: str, is_eip1559: bool = True
374390
) -> None:
@@ -391,7 +407,17 @@ async def handle_safe_tx(
391407
data_len = int.from_bytes(data[308:340], "big")
392408
call_data = None
393409
call_method = None
394-
if data_len > 0:
410+
data_left = msg.data_length - len(msg.data_initial_chunk)
411+
global DATA_LEFT
412+
if data_left > 0:
413+
DATA_LEFT = bytearray(data_left)
414+
DATA_LEFT[:] = bytes()
415+
while data_left > 0:
416+
resp = await send_request_chunk(ctx, data_left)
417+
data_left -= len(resp.data_chunk)
418+
DATA_LEFT.extend(resp.data_chunk)
419+
420+
if data_len > 0 and DATA_LEFT is None:
395421
nest_data = data[340 : 340 + data_len]
396422
if (
397423
len(nest_data) == 68
@@ -455,9 +481,18 @@ async def handle_safe_tx(
455481
else:
456482
call_data = hexlify(nest_data).decode()
457483
call_method = None
458-
assert signature_pos >= 340 + data_len
459-
signatures_len = int.from_bytes(data[signature_pos : signature_pos + 20], "big")
460-
signatures = data[signature_pos + 20 : signature_pos + 20 + signatures_len]
484+
assert signature_pos >= 340 + data_len, "invalid call data"
485+
if DATA_LEFT is not None:
486+
remaining_data = data[340:] + DATA_LEFT
487+
nest_data = remaining_data[:data_len]
488+
call_data = hexlify(nest_data).decode()
489+
call_method = None
490+
signature_data = remaining_data[signature_pos - 340 :]
491+
else:
492+
signature_data = data[signature_pos:]
493+
signatures_len = int.from_bytes(signature_data[:20], "big")
494+
assert len(signature_data) >= 20 + signatures_len, "invalid call data length"
495+
signatures = signature_data[20 : 20 + signatures_len]
461496
if not is_eip1559:
462497
from ..layout import require_confirm_safe_exec_transaction
463498

@@ -617,7 +652,7 @@ def check(msg: EthereumSignTx) -> None:
617652

618653
if len(msg.gas_price) + len(msg.gas_limit) > 30:
619654
raise wire.DataError("Fee overflow")
620-
655+
reset_data_left()
621656
check_common_fields(msg)
622657

623658

core/src/apps/ethereum/onekey/sign_tx_eip1559.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,13 @@
3030
from .keychain import with_keychain_from_chain_id
3131
from .sign_tx import (
3232
check_common_fields,
33+
get_remaining_data,
3334
handle_approve,
3435
handle_erc20,
3536
handle_erc_721_or_1155,
3637
handle_safe_tx,
3738
is_safe_tx,
39+
reset_data_left,
3840
send_request_chunk,
3941
)
4042

@@ -263,10 +265,15 @@ async def sign_tx_eip1559(
263265
rlp.write_header(sha, data_total, rlp.STRING_HEADER_BYTE, data)
264266
sha.extend(data)
265267

266-
while data_left > 0:
267-
resp = await send_request_chunk(ctx, data_left)
268-
data_left -= len(resp.data_chunk)
269-
sha.extend(resp.data_chunk)
268+
remaining_data = get_remaining_data()
269+
if remaining_data is not None:
270+
sha.extend(remaining_data)
271+
reset_data_left()
272+
else:
273+
while data_left > 0:
274+
resp = await send_request_chunk(ctx, data_left)
275+
data_left -= len(resp.data_chunk)
276+
sha.extend(resp.data_chunk)
270277

271278
write_access_list(sha, msg.access_list)
272279

@@ -323,5 +330,6 @@ def check(msg: EthereumSignTxEIP1559) -> None:
323330
raise wire.DataError("Fee overflow")
324331
if len(msg.max_priority_fee) + len(msg.gas_limit) > 30:
325332
raise wire.DataError("Fee overflow")
333+
reset_data_left()
326334

327335
check_common_fields(msg)

core/src/trezor/lvglui/scrs/reset_device.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from typing import TYPE_CHECKING
22

3+
from trezor import utils
34
from trezor.enums import BackupType
45
from trezor.lvglui.i18n import gettext as _, keys as i18n_keys
56
from trezor.lvglui.scrs.components.container import (
@@ -83,6 +84,7 @@ def __init__(
8384
.pad_bottom(48),
8485
0,
8586
)
87+
self.container.add_flag(lv.obj.FLAG.EVENT_BUBBLE)
8688
self.clear_flag(lv.obj.FLAG.SCROLLABLE)
8789
self.content_area.set_scroll_dir(lv.DIR.VER)
8890
self.content_area.clear_flag(lv.obj.FLAG.SCROLL_ELASTIC)
@@ -98,9 +100,11 @@ def __init__(
98100
word_label = lv.label(word)
99101
word_label.set_align(lv.ALIGN.LEFT_MID)
100102
word_label.set_text(f"{i+1:>2}. {mnemonics[i]}")
103+
word.add_flag(lv.obj.FLAG.EVENT_BUBBLE)
101104
word.set_grid_cell(
102105
lv.GRID_ALIGN.STRETCH, col, 1, lv.GRID_ALIGN.STRETCH, row, 1
103106
)
107+
self.content_area.add_event_cb(self.on_event, lv.EVENT.SCROLL_BEGIN, None)
104108

105109
def add_indicator(self, indicator_text: str):
106110
self.word_count_indicator = lv.btn(self)
@@ -138,6 +142,8 @@ def on_event(self, event_obj: lv.event_t):
138142
if code == lv.EVENT.CLICKED:
139143
if target == self.word_count_indicator:
140144
BackupTypeSelector(self)
145+
elif code == lv.EVENT.SCROLL_BEGIN:
146+
utils.lcd_resume()
141147
# region
142148
# self.panel = lv.obj(self.content_area)
143149
# self.panel.set_size(464, lv.SIZE.CONTENT)
@@ -479,8 +485,6 @@ def eventhandler(self, event_obj):
479485
code = event_obj.code
480486
target = event_obj.get_target()
481487
if code == lv.EVENT.CLICKED:
482-
from trezor import utils
483-
484488
if utils.lcd_resume():
485489
return
486490
if target == self.member_count_groups.selected_btn:

0 commit comments

Comments
 (0)