fix(core): Fix Optiga signature masking.
What changed, and why it matters
This commit fixes a bug in how the Trezor hardware wallet's secure chip (Optiga) handles masked digital signatures. The fix changes two things: it now uses the actual returned signature length rather than the maximum buffer size when parsing the signature, and it explicitly uses the NIST P-256 curve instead of a variable curve parameter when removing the masking. The bug could potentially cause signature parsing to fail or behave incorrectly, especially if the returned signature was shorter than the maximum expected size. There is no public statement linking this to an active security vulnerability or attack.
Treat as a hardening/correctness fix. Review whether the prior code could have produced invalid signatures or signature failures under edge-case lengths, and verify that all Optiga-backed signing flows now use the corrected length and curve. No immediate incident response is indicated absent further evidence.
Security signals we found
Parsing DER signature using buffer capacity instead of actual returned length
Use of variable curve parameter for unmasking instead of fixed NIST P-256
Code path involves ECDSA signature unmasking in secure element interface
No CVE, advisory, or vendor security statement supplied
Evidence from the diff
In optiga_sign(), when is_masked is true, the code parses a DER-encoded ECDSA signature and then unmasks the s-component using a masking key. The patch corrects two arguments: (1) ecdsa_sig_from_der() now receives *der_signature_size (the actual length returned by Optiga) instead of max_der_signature_size (the caller-provided buffer capacity), and (2) ecdsa_unmask_scalar() now receives &nist256p1 directly instead of the curve variable. The first change prevents parsing from reading uninitialized or stale bytes beyond the real signature length, which could cause parsing failure or undefined behavior. The second change hardcodes the curve used for unmasking to NIST P-256, matching the Optiga key type and eliminating reliance on a possibly mismatched curve parameter. The commit message frames this only as a ‘fix’ with no security disclosure.
Changed components
core/embed/sec/optiga/optiga.coptiga_sign() functionOptiga secure element ECDSA signing with maskingInspect captured patch +2 / −2
diff --git a/core/embed/sec/optiga/optiga.c b/core/embed/sec/optiga/optiga.c
index 67ed7db7..e1ef63f4 100644
--- a/core/embed/sec/optiga/optiga.c
+++ b/core/embed/sec/optiga/optiga.c
@@ -169,9 +169,9 @@ optiga_sign_result optiga_sign(uint8_t index, const uint8_t *digest,
uint8_t raw_signature[ECDSA_RAW_SIGNATURE_SIZE] = {0};
if (is_masked) {
if (max_der_signature_size < MAX_DER_SIGNATURE_SIZE ||
- ecdsa_sig_from_der(der_signature, der_signature_size, raw_signature) !=
+ ecdsa_sig_from_der(der_signature, *der_signature_size, raw_signature) !=
0 ||
- ecdsa_unmask_scalar(curve, masking_key, &raw_signature[32],
+ ecdsa_unmask_scalar(&nist256p1, masking_key, &raw_signature[32],
&raw_signature[32]) != 0) {
ret = OPTIGA_SIGN_ERROR;
goto cleanup;
Why this scored 59/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.