chore(core): adjust thp credential validation
What changed, and why it matters
This commit fixes a timing weakness in how a Trezor hardware wallet checks the authenticity of a 'credential' used in its Trezor Host Protocol (THP). Previously, the device compared two secret codes with a standard equality check, which can leak information through tiny timing differences. The patch switches to a constant-time comparison function and adds a length check first. This is a defensive hardening change against side-channel attacks, but the commit message does not frame it as a security fix and no exploit is described.
Treat as a low-to-moderate defensive-security hardening patch. Include in routine firmware updates. No immediate incident response is warranted unless THP is actively used in your deployment and local attackers are a concern. Consider whether other HMAC comparisons in the THP stack use consteq consistently.
Security signals we found
Replacement of standard equality comparison with constant-time comparison (consteq)
Addition of explicit length check before constant-time comparison
HMAC verification code path changed
No changelog entry and commit titled as chore
Evidence from the diff
In core/src/apps/thp/credential_manager.py, validate_credential() previously compared the computed HMAC-SHA256 digest (mac) to credential.mac using Python’s ==. The patch adds a length check and replaces == with utils.consteq, a constant-time comparison. This mitigates a potential timing side-channel that could allow an attacker with local timing measurement capability to iteratively guess the valid MAC byte-by-byte. The change is narrow and applies only to THP credential validation.
Changed components
core/src/apps/thp/credential_manager.pyTrezor Host Protocol (THP) credential validationInspect captured patch +5 / −2
diff --git a/core/src/apps/thp/credential_manager.py b/core/src/apps/thp/credential_manager.py
index 39a37385..497e52d0 100644
--- a/core/src/apps/thp/credential_manager.py
+++ b/core/src/apps/thp/credential_manager.py
@@ -1,6 +1,6 @@
from typing import TYPE_CHECKING
-from trezor import protobuf
+from trezor import protobuf, utils
from trezor.crypto import hmac
from trezor.messages import (
ThpAuthenticatedCredentialData,
@@ -92,7 +92,10 @@ def validate_credential(
)
authenticated_credential_data = _encode_message_into_new_buffer(proto_msg)
mac = hmac(hmac.SHA256, cred_auth_key, authenticated_credential_data).digest()
- return mac == credential.mac
+
+ if len(mac) != len(credential.mac):
+ return False
+ return utils.consteq(mac, credential.mac)
def decode_and_validate_credential(
Why this scored 51/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.