1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-02-24 13:22:05 +00:00

Fix bug in THP not clearing already read report

This commit is contained in:
M1nd3r 2024-03-04 16:33:59 +01:00 committed by M1nd3r
parent 94278d5c01
commit 014cca8bac

View File

@ -27,7 +27,7 @@ _HANDSHAKE_INIT = 0x00
_PLAINTEXT = 0x01 _PLAINTEXT = 0x01
ENCRYPTED_TRANSPORT = 0x02 ENCRYPTED_TRANSPORT = 0x02
_ENCODED_PROTOBUF_DEVICE_PROPERTIES = ( _ENCODED_PROTOBUF_DEVICE_PROPERTIES = (
b"\x0A\x04\x54\x33\x57\x31\x10\x05\x18\x00\x20\x01\x28\x01\x28\x02" b"\x0a\x04\x54\x33\x57\x31\x10\x05\x18\x00\x20\x01\x28\x01\x28\x02"
) )
_UNALLOCATED_SESSION_ERROR = ( _UNALLOCATED_SESSION_ERROR = (
b"\x55\x4e\x41\x4c\x4c\x4f\x43\x41\x54\x45\x44\x5f\x53\x45\x53\x53\x49\x4f\x4e" b"\x55\x4e\x41\x4c\x4c\x4f\x43\x41\x54\x45\x44\x5f\x53\x45\x53\x53\x49\x4f\x4e"
@ -83,18 +83,18 @@ async def read_message(iface: WireInterface, buffer: utils.BufferType) -> Messag
async def read_message_or_init_packet( async def read_message_or_init_packet(
iface: WireInterface, buffer: utils.BufferType, firstReport=None iface: WireInterface, buffer: utils.BufferType, firstReport=None
) -> Message | InterruptingInitPacket: ) -> Message | InterruptingInitPacket:
report = firstReport
while True: while True:
# Wait for an initial report # Wait for an initial report
if firstReport is None: if firstReport is None:
report = await _get_loop_wait_read(iface) report = await _get_loop_wait_read(iface)
else:
report = firstReport
# Channel multiplexing # Channel multiplexing
ctrl_byte, cid = ustruct.unpack(">BH", report) ctrl_byte, cid = ustruct.unpack(">BH", report)
if cid == BROADCAST_CHANNEL_ID: if cid == BROADCAST_CHANNEL_ID:
_handle_broadcast(iface, ctrl_byte, report) _handle_broadcast(iface, ctrl_byte, report)
report = None
continue continue
# We allow for only one message to be read simultaneously. We do not # We allow for only one message to be read simultaneously. We do not
@ -102,6 +102,7 @@ async def read_message_or_init_packet(
# the sole exception of cid_request which can be handled independently. # the sole exception of cid_request which can be handled independently.
if _is_ctrl_byte_continuation(ctrl_byte): if _is_ctrl_byte_continuation(ctrl_byte):
# continuation packet is not expected - ignore # continuation packet is not expected - ignore
report = None
continue continue
payload_length = ustruct.unpack(">H", report[3:])[0] payload_length = ustruct.unpack(">H", report[3:])[0]
@ -116,6 +117,7 @@ async def read_message_or_init_packet(
# Check CRC # Check CRC
if not _is_checksum_valid(payload[-4:], header.to_bytes() + payload[:-4]): if not _is_checksum_valid(payload[-4:], header.to_bytes() + payload[:-4]):
# checksum is not valid -> ignore message # checksum is not valid -> ignore message
report = None
continue continue
session = THP.get_session(iface, cid) session = THP.get_session(iface, cid)
@ -127,15 +129,18 @@ async def read_message_or_init_packet(
# unallocated should not return regular message, TODO, but it might change # unallocated should not return regular message, TODO, but it might change
if message is not None: if message is not None:
return message return message
report = None
continue continue
# Note: In the Host, the UNALLOCATED_CHANNEL error should be handled here # Note: In the Host, the UNALLOCATED_CHANNEL error should be handled here
# Synchronization process # Synchronization process
sync_bit = (ctrl_byte & 0x10) >> 4 sync_bit = (ctrl_byte & 0x10) >> 4
# 1: Handle ACKs # 1: Handle ACKs
if _is_ctrl_byte_ack(ctrl_byte): if _is_ctrl_byte_ack(ctrl_byte):
_handle_received_ACK(session, sync_bit) _handle_received_ACK(session, sync_bit)
report = None
continue continue
# 2: Handle message with unexpected synchronization bit # 2: Handle message with unexpected synchronization bit
@ -145,6 +150,7 @@ async def read_message_or_init_packet(
# but it might change with the cancelation message # but it might change with the cancelation message
if message is not None: if message is not None:
return message return message
report = None
continue continue
# 3: Send ACK in response # 3: Send ACK in response