feat(core): re-enable THP ACK piggybacking
What changed, and why it matters
This commit re-enables a feature called 'THP ACK piggybacking' in Trezor firmware. It is a feature change, not a security patch. The commit message and diff do not describe any security vulnerability or fix. The change was previously disabled due to an unrelated issue (#6506) that is now apparently resolved. Without additional references, there is no direct evidence this commit fixes a security problem.
No immediate security action required. Review the related issue #6506 and THP protocol documentation to confirm the feature is safe to re-enable. Monitor for any follow-up security advisories from Trezor.
Security signals we found
No security-relevant keywords in commit title or message
No CVE, advisory, or security disclosure references present
Change is a feature re-enablement, not a vulnerability fix
Prior disabling was linked to issue #6506, not a security bug
Evidence from the diff
The commit reverts a prior change that disabled THP ACK piggybacking. It bumps the protocol minor version from 0 to 1 and re-enables the handshake callback logic that calls ABP.allow_ack_piggybacking() when the ACK bit is set in handshake_init_req. The remaining changes are UI test fixture hash updates for THP pairing tests across multiple languages, reflecting expected behavior changes due to the re-enabled feature.
Changed components
core/src/trezor/wire/thp/__init__.pycore/src/trezor/wire/thp/received_message_handler.pytests/ui_tests/fixtures.jsonInspect captured patch +30 / −31
diff --git a/core/.changelog.d/6202.added b/core/.changelog.d/6202.added
new file mode 100644
index 00000000..c50964dc
--- /dev/null
+++ b/core/.changelog.d/6202.added
@@ -0,0 +1 @@
+Support receive-side THP ACK piggybacking.
diff --git a/core/src/trezor/wire/thp/__init__.py b/core/src/trezor/wire/thp/__init__.py
index 201b433f..0945178f 100644
--- a/core/src/trezor/wire/thp/__init__.py
+++ b/core/src/trezor/wire/thp/__init__.py
@@ -210,8 +210,7 @@ def _get_device_properties(iface: WireInterface) -> ThpDeviceProperties:
internal_model=utils.INTERNAL_MODEL,
model_variant=model_variant,
protocol_version_major=2,
- # TODO: re-enable THP ACK piggybacking after #6506 is fixed
- protocol_version_minor=0,
+ protocol_version_minor=1,
)
diff --git a/core/src/trezor/wire/thp/received_message_handler.py b/core/src/trezor/wire/thp/received_message_handler.py
index bd17f8f1..b0b6e310 100644
--- a/core/src/trezor/wire/thp/received_message_handler.py
+++ b/core/src/trezor/wire/thp/received_message_handler.py
@@ -106,11 +106,10 @@ async def _handle_state_handshake(
def _handshake_callback(ctrl_byte: int) -> bool:
success = control_byte.is_handshake_init_req(ctrl_byte)
- # TODO: re-enable THP ACK piggybacking after #6506 is fixed
- # if success and control_byte.get_ack_bit(ctrl_byte) == 1:
- # # Newer Suite versions will send `handshake_init_req` with a non-zero ACK bit.
- # # The device should not use ACK piggybacking with older Suite versions.
- # ABP.allow_ack_piggybacking(ctx.channel_cache)
+ if success and control_byte.get_ack_bit(ctrl_byte) == 1:
+ # Newer Suite versions will send `handshake_init_req` with a non-zero ACK bit.
+ # The device should not use ACK piggybacking with older Suite versions.
+ ABP.allow_ack_piggybacking(ctx.channel_cache)
if __debug__:
ctx._log(
diff --git a/tests/ui_tests/fixtures.json b/tests/ui_tests/fixtures.json
index d1ac7cb0..ffd55758 100644
--- a/tests/ui_tests/fixtures.json
+++ b/tests/ui_tests/fixtures.json
@@ -32483,10 +32483,10 @@
"T3W1_cs_thp-test_pairing.py::test_credential_request_in_encrypted_transport_phase": "ede6dc76d2ee23cc259ed15bf605fdf708a25763eb122690ff4595aa05d038cf",
"T3W1_cs_thp-test_pairing.py::test_pairing_cancel_1": "1483b32f7c93c627e805fdfa620ff95018d1f99c0d141e670077ceb240b1243d",
"T3W1_cs_thp-test_pairing.py::test_pairing_cancel_2": "a5cac060747b4be07468c92002563e15b0f6dbb6b65ea3d741a3321c12a4460d",
-"T3W1_cs_thp-test_pairing.py::test_pairing_code_entry": "a9ab222f5370b7633e53e85bb2da3b23872d3bf2f8d30460d8d4a7e5ba2e3fce",
-"T3W1_cs_thp-test_pairing.py::test_pairing_code_entry_cancel": "a9ab222f5370b7633e53e85bb2da3b23872d3bf2f8d30460d8d4a7e5ba2e3fce",
-"T3W1_cs_thp-test_pairing.py::test_pairing_code_entry_invalid_cpace_key": "a9ab222f5370b7633e53e85bb2da3b23872d3bf2f8d30460d8d4a7e5ba2e3fce",
-"T3W1_cs_thp-test_pairing.py::test_pairing_code_entry_invalid_cpace_key_length": "a9ab222f5370b7633e53e85bb2da3b23872d3bf2f8d30460d8d4a7e5ba2e3fce",
+"T3W1_cs_thp-test_pairing.py::test_pairing_code_entry": "fb03da526ea6178dbd7f71427b83855d2b3d9bd1ccfde8cd054d43027b556bbb",
+"T3W1_cs_thp-test_pairing.py::test_pairing_code_entry_cancel": "fb03da526ea6178dbd7f71427b83855d2b3d9bd1ccfde8cd054d43027b556bbb",
+"T3W1_cs_thp-test_pairing.py::test_pairing_code_entry_invalid_cpace_key": "fb03da526ea6178dbd7f71427b83855d2b3d9bd1ccfde8cd054d43027b556bbb",
+"T3W1_cs_thp-test_pairing.py::test_pairing_code_entry_invalid_cpace_key_length": "fb03da526ea6178dbd7f71427b83855d2b3d9bd1ccfde8cd054d43027b556bbb",
"T3W1_cs_thp-test_pairing.py::test_pairing_nfc": "afa15d57cb1468770f25eae097e94274450dd94f485df56e7639a7e935a32300",
"T3W1_cs_thp-test_pairing.py::test_pairing_qr_code": "c24521e569c08e3605b164212c876f8ac57c5eef6cca6f2ca53a635a883ebc4b",
"T3W1_cs_tron-test_get_address.py::test_get_address[parameters0-result0]": "19b788b7a912d17e96a80098fb8630d5f4a566c8b7933626e699080af95ab9cf",
@@ -34069,10 +34069,10 @@
"T3W1_de_thp-test_pairing.py::test_credential_request_in_encrypted_transport_phase": "1d7e055331fd9994a7beb712b9e3686103665fe26ab4d3a2a1a146c4928d63ce",
"T3W1_de_thp-test_pairing.py::test_pairing_cancel_1": "2ea3113e2b18f5b0406e4c0fe786fa6b2779c07ff20836e3b9bebaaf03825357",
"T3W1_de_thp-test_pairing.py::test_pairing_cancel_2": "ce831bcba5b6a76c6e502c67e6f7c6729fe5ce79ab67b4f6dcd5e4d1cec29e03",
-"T3W1_de_thp-test_pairing.py::test_pairing_code_entry": "249ca1cb4a5d3371b801bc5cf66e4eed663d2d1078939d750548fbb3d681b2c6",
-"T3W1_de_thp-test_pairing.py::test_pairing_code_entry_cancel": "249ca1cb4a5d3371b801bc5cf66e4eed663d2d1078939d750548fbb3d681b2c6",
-"T3W1_de_thp-test_pairing.py::test_pairing_code_entry_invalid_cpace_key": "249ca1cb4a5d3371b801bc5cf66e4eed663d2d1078939d750548fbb3d681b2c6",
-"T3W1_de_thp-test_pairing.py::test_pairing_code_entry_invalid_cpace_key_length": "249ca1cb4a5d3371b801bc5cf66e4eed663d2d1078939d750548fbb3d681b2c6",
+"T3W1_de_thp-test_pairing.py::test_pairing_code_entry": "99f9bcd2cc6c3e28cf254b39dcf5146a126fdcd6aaf74b918823ad36236fefaf",
+"T3W1_de_thp-test_pairing.py::test_pairing_code_entry_cancel": "99f9bcd2cc6c3e28cf254b39dcf5146a126fdcd6aaf74b918823ad36236fefaf",
+"T3W1_de_thp-test_pairing.py::test_pairing_code_entry_invalid_cpace_key": "99f9bcd2cc6c3e28cf254b39dcf5146a126fdcd6aaf74b918823ad36236fefaf",
+"T3W1_de_thp-test_pairing.py::test_pairing_code_entry_invalid_cpace_key_length": "99f9bcd2cc6c3e28cf254b39dcf5146a126fdcd6aaf74b918823ad36236fefaf",
"T3W1_de_thp-test_pairing.py::test_pairing_nfc": "c9d8b8ebec7e69bfb96c7e31d1004a1eb8071c9dbe44f342a96f44c19aced663",
"T3W1_de_thp-test_pairing.py::test_pairing_qr_code": "b3ce10e1620297758d6f2b235127f1dd0d61804c8cc32bc6664db5c3a9d81dde",
"T3W1_de_tron-test_get_address.py::test_get_address[parameters0-result0]": "f6a09c86d1148cc99368d88613de58cffae7133a586ccbf6e4fcc4300b838341",
@@ -35655,10 +35655,10 @@
"T3W1_en_thp-test_pairing.py::test_credential_request_in_encrypted_transport_phase": "60fee0d11e9f4aba0e9196783956d5447fb1985dac3172a5975eb3d9373188f1",
"T3W1_en_thp-test_pairing.py::test_pairing_cancel_1": "cd8b89c41f1fa45320970832327c3626a281f2f9c37f8d043e48878d63f7553a",
"T3W1_en_thp-test_pairing.py::test_pairing_cancel_2": "554f7a5c9236a8ec9f1cebbaa0e56e057c862f1e37b3b796879c54b5f4f60db9",
-"T3W1_en_thp-test_pairing.py::test_pairing_code_entry": "3c099eaf1cb1f994b77a9fafbb262a50ca0d5205443731a4836168136473cf1f",
-"T3W1_en_thp-test_pairing.py::test_pairing_code_entry_cancel": "3c099eaf1cb1f994b77a9fafbb262a50ca0d5205443731a4836168136473cf1f",
-"T3W1_en_thp-test_pairing.py::test_pairing_code_entry_invalid_cpace_key": "3c099eaf1cb1f994b77a9fafbb262a50ca0d5205443731a4836168136473cf1f",
-"T3W1_en_thp-test_pairing.py::test_pairing_code_entry_invalid_cpace_key_length": "3c099eaf1cb1f994b77a9fafbb262a50ca0d5205443731a4836168136473cf1f",
+"T3W1_en_thp-test_pairing.py::test_pairing_code_entry": "3acb03148d99e387a2554eb8045dda9a815750f092c74e5f61d47a849d41f31d",
+"T3W1_en_thp-test_pairing.py::test_pairing_code_entry_cancel": "3acb03148d99e387a2554eb8045dda9a815750f092c74e5f61d47a849d41f31d",
+"T3W1_en_thp-test_pairing.py::test_pairing_code_entry_invalid_cpace_key": "3acb03148d99e387a2554eb8045dda9a815750f092c74e5f61d47a849d41f31d",
+"T3W1_en_thp-test_pairing.py::test_pairing_code_entry_invalid_cpace_key_length": "3acb03148d99e387a2554eb8045dda9a815750f092c74e5f61d47a849d41f31d",
"T3W1_en_thp-test_pairing.py::test_pairing_nfc": "4cd2cdb1fd6fba47a2a01a720da7d7f70d2add224a25ec6e1180f06d5586bb35",
"T3W1_en_thp-test_pairing.py::test_pairing_qr_code": "931d9afceb0ba1e4faae891775819277242d889644d5c0c5863fc8c9fcf859b1",
"T3W1_en_tron-test_get_address.py::test_get_address[parameters0-result0]": "ec0f1dff9cd732d228d23ea478c885e75478af957378d9db37d9c1a64ee3e363",
@@ -37241,10 +37241,10 @@
"T3W1_es_thp-test_pairing.py::test_credential_request_in_encrypted_transport_phase": "bf8984a242d2a5eb4f868afbd3248e92d4c505228ab0eba435bb73167a712def",
"T3W1_es_thp-test_pairing.py::test_pairing_cancel_1": "663da295593101456095d4e9a500f20113ce51c8864a47bbe6c5b440a8460371",
"T3W1_es_thp-test_pairing.py::test_pairing_cancel_2": "86c4f60834e05acf3bba979a15b1025d261f30ca5354fc9d0037c86214ea037d",
-"T3W1_es_thp-test_pairing.py::test_pairing_code_entry": "31216cce67e1499e6c931d7d2b45aa2ca49094774fd35a07cb93431ab640e8d5",
-"T3W1_es_thp-test_pairing.py::test_pairing_code_entry_cancel": "31216cce67e1499e6c931d7d2b45aa2ca49094774fd35a07cb93431ab640e8d5",
-"T3W1_es_thp-test_pairing.py::test_pairing_code_entry_invalid_cpace_key": "31216cce67e1499e6c931d7d2b45aa2ca49094774fd35a07cb93431ab640e8d5",
-"T3W1_es_thp-test_pairing.py::test_pairing_code_entry_invalid_cpace_key_length": "31216cce67e1499e6c931d7d2b45aa2ca49094774fd35a07cb93431ab640e8d5",
+"T3W1_es_thp-test_pairing.py::test_pairing_code_entry": "36427182368a02b2250c3f3789c5500cb8167452440f48075bc3a6b523d43516",
+"T3W1_es_thp-test_pairing.py::test_pairing_code_entry_cancel": "36427182368a02b2250c3f3789c5500cb8167452440f48075bc3a6b523d43516",
+"T3W1_es_thp-test_pairing.py::test_pairing_code_entry_invalid_cpace_key": "36427182368a02b2250c3f3789c5500cb8167452440f48075bc3a6b523d43516",
+"T3W1_es_thp-test_pairing.py::test_pairing_code_entry_invalid_cpace_key_length": "36427182368a02b2250c3f3789c5500cb8167452440f48075bc3a6b523d43516",
"T3W1_es_thp-test_pairing.py::test_pairing_nfc": "d0f15a0a492fd6e0cfaa46981426cc76297dd18d4b6e151f5df35973e3b49de5",
"T3W1_es_thp-test_pairing.py::test_pairing_qr_code": "56536ae9cd7c4ff8022def4ec3350031d3614064d961f53a2850f2be425af201",
"T3W1_es_tron-test_get_address.py::test_get_address[parameters0-result0]": "d30e60e12c61ea40b076838de12cda7b71df668d5c1b59709d5eb129a7ce8b1a",
@@ -38827,10 +38827,10 @@
"T3W1_fr_thp-test_pairing.py::test_credential_request_in_encrypted_transport_phase": "c35ee2e1d842f96a816f62b1322575c70001e4786dc15983d7b52d93d2f95bbf",
"T3W1_fr_thp-test_pairing.py::test_pairing_cancel_1": "12004ca1108ea84b42936d997a4be243bcd8459a35a3618f9aaa59c7b9682e83",
"T3W1_fr_thp-test_pairing.py::test_pairing_cancel_2": "b9fd29996cf8fcd33cac4a3c8577454109b49a831c485ffa6c2adbb0bad928bb",
-"T3W1_fr_thp-test_pairing.py::test_pairing_code_entry": "e73b027b647cfa33c81fa068db6af1ebfd3a1c06b50d285548505aa23968495f",
-"T3W1_fr_thp-test_pairing.py::test_pairing_code_entry_cancel": "e73b027b647cfa33c81fa068db6af1ebfd3a1c06b50d285548505aa23968495f",
-"T3W1_fr_thp-test_pairing.py::test_pairing_code_entry_invalid_cpace_key": "e73b027b647cfa33c81fa068db6af1ebfd3a1c06b50d285548505aa23968495f",
-"T3W1_fr_thp-test_pairing.py::test_pairing_code_entry_invalid_cpace_key_length": "e73b027b647cfa33c81fa068db6af1ebfd3a1c06b50d285548505aa23968495f",
+"T3W1_fr_thp-test_pairing.py::test_pairing_code_entry": "b77cc3269e640c403105b819579786c97cb9e0fb25a8fc785da1134edacb2165",
+"T3W1_fr_thp-test_pairing.py::test_pairing_code_entry_cancel": "b77cc3269e640c403105b819579786c97cb9e0fb25a8fc785da1134edacb2165",
+"T3W1_fr_thp-test_pairing.py::test_pairing_code_entry_invalid_cpace_key": "b77cc3269e640c403105b819579786c97cb9e0fb25a8fc785da1134edacb2165",
+"T3W1_fr_thp-test_pairing.py::test_pairing_code_entry_invalid_cpace_key_length": "b77cc3269e640c403105b819579786c97cb9e0fb25a8fc785da1134edacb2165",
"T3W1_fr_thp-test_pairing.py::test_pairing_nfc": "6c2ac9baf1372c4381187aea1d18fd362449a95980ec1a41a22f7eab425196ad",
"T3W1_fr_thp-test_pairing.py::test_pairing_qr_code": "e8156cf4eda1d29060f05b4a18d50032b0b344230609b7de7cababfe0a86b20b",
"T3W1_fr_tron-test_get_address.py::test_get_address[parameters0-result0]": "1974ee4f7614f89cbb8577006a77995ecf61baabe11fef3b7bb6ef04a5411274",
@@ -40418,10 +40418,10 @@
"T3W1_pt_thp-test_pairing.py::test_credential_request_in_encrypted_transport_phase": "2a71d0a154438a39e193c446b893ac45e9677ceb7065afb91704c47f1bc498a5",
"T3W1_pt_thp-test_pairing.py::test_pairing_cancel_1": "df151c844f9ad2500231de9b092621802026184f6e2bde831f65ec2512d46e1d",
"T3W1_pt_thp-test_pairing.py::test_pairing_cancel_2": "a16fdba151a20b4ccb73e6c5b2413a2ccb7653a78a7cec8750b5d1c5cea926f4",
-"T3W1_pt_thp-test_pairing.py::test_pairing_code_entry": "ffc7fe1a1dbdbb5b02c17836a592fe76c2c87533ff80c9c9c211cdd6d59b5a42",
-"T3W1_pt_thp-test_pairing.py::test_pairing_code_entry_cancel": "ffc7fe1a1dbdbb5b02c17836a592fe76c2c87533ff80c9c9c211cdd6d59b5a42",
-"T3W1_pt_thp-test_pairing.py::test_pairing_code_entry_invalid_cpace_key": "ffc7fe1a1dbdbb5b02c17836a592fe76c2c87533ff80c9c9c211cdd6d59b5a42",
-"T3W1_pt_thp-test_pairing.py::test_pairing_code_entry_invalid_cpace_key_length": "ffc7fe1a1dbdbb5b02c17836a592fe76c2c87533ff80c9c9c211cdd6d59b5a42",
+"T3W1_pt_thp-test_pairing.py::test_pairing_code_entry": "5479d37528b591b3793482da11d4bf9180e3dcf87c0721d1b6432cdd5095b723",
+"T3W1_pt_thp-test_pairing.py::test_pairing_code_entry_cancel": "5479d37528b591b3793482da11d4bf9180e3dcf87c0721d1b6432cdd5095b723",
+"T3W1_pt_thp-test_pairing.py::test_pairing_code_entry_invalid_cpace_key": "5479d37528b591b3793482da11d4bf9180e3dcf87c0721d1b6432cdd5095b723",
+"T3W1_pt_thp-test_pairing.py::test_pairing_code_entry_invalid_cpace_key_length": "5479d37528b591b3793482da11d4bf9180e3dcf87c0721d1b6432cdd5095b723",
"T3W1_pt_thp-test_pairing.py::test_pairing_nfc": "f1a4bf60d2fa355b34b73a4f85fcb112b65160b24adff00ea2de4ec3279f6320",
"T3W1_pt_thp-test_pairing.py::test_pairing_qr_code": "1c74667c078e25e7e0d37c7b2aa35f7c8ab02cd88e74695ecb355c82a293b0cc",
"T3W1_pt_tron-test_get_address.py::test_get_address[parameters0-result0]": "be9dd1bf9b95958f2eb25a1423a41e587b3a3233d01323128b256b067694d311",
Why this scored 27/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.