attestation: ensure attestation provision signature is correctly sized
What changed, and why it matters
This update fixes a check in the Blockstream Jade hardware wallet's attestation setup. Before the fix, the code did not verify that an externally-provided signature was small enough to fit into its storage buffer. A too-large signature could overflow that buffer during verification, potentially corrupting memory or crashing the device. The patch adds a size check before calling the signature verification routine.
Treat as a security fix and include in the next firmware release. Review whether verify_signature itself has additional internal length checks, and audit other callers that pass external length-prefixed data into fixed buffers. No immediate user action is required beyond updating firmware once available.
Security signals we found
Missing length check before fixed-size buffer use
Potential stack/buffer overflow in signature verification path
Attestation/trust-anchor initialization code modified
Suggested-by external researcher Jordan Mecom
Evidence from the diff
In main/attestation/attestation.c, attestation_initialise() receives ext_signature and ext_signature_len from a caller and passes them to verify_signature(), which copies the signature into attestation_data.ext_signature (a fixed-size buffer). The original code asserted ext_signature and ext_signature_len were non-zero but never compared ext_signature_len against sizeof(attestation_data.ext_signature). The patch adds that bounds check: if ext_signature_len exceeds the destination buffer, verification fails before the copy/verify occurs. The remaining changes merely collapse adjacent JADE_ASSERT calls into single expressions and are cosmetic.
Changed components
main/attestation/attestation.cattestation_initialise()verify_signature() callersInspect captured patch +5 / −7
diff --git a/main/attestation/attestation.c b/main/attestation/attestation.c
index c230f66..0eaf807 100644
--- a/main/attestation/attestation.c
+++ b/main/attestation/attestation.c
@@ -476,14 +476,11 @@ bool attestation_initialised(void)
bool attestation_initialise(const char* privkey_pem, const size_t privkey_pem_len, const char* ext_pubkey_pem,
const size_t ext_pubkey_pem_len, const uint8_t* ext_signature, const size_t ext_signature_len)
{
- JADE_ASSERT(privkey_pem);
- JADE_ASSERT(privkey_pem_len);
+ JADE_ASSERT(privkey_pem && privkey_pem_len);
JADE_ASSERT(privkey_pem[privkey_pem_len] == '\0');
- JADE_ASSERT(ext_pubkey_pem);
- JADE_ASSERT(ext_pubkey_pem_len);
+ JADE_ASSERT(ext_pubkey_pem && ext_pubkey_pem_len);
JADE_ASSERT(ext_pubkey_pem[ext_pubkey_pem_len] == '\0');
- JADE_ASSERT(ext_signature);
- JADE_ASSERT(ext_signature_len);
+ JADE_ASSERT(ext_signature && ext_signature_len);
// Check parameters initialised
if (!attestation_can_be_initialised()) {
@@ -549,7 +546,8 @@ bool attestation_initialise(const char* privkey_pem, const size_t privkey_pem_le
JADE_LOGE("Failed to import valid RSA public (external authority) key");
goto cleanup;
}
- if (!verify_signature(&pk, (const uint8_t*)attestation_data.pubkey_pem, attestation_data.pubkey_pem_len,
+ if (ext_signature_len > sizeof(attestation_data.ext_signature)
+ || !verify_signature(&pk, (const uint8_t*)attestation_data.pubkey_pem, attestation_data.pubkey_pem_len,
ext_signature, ext_signature_len)) {
JADE_LOGE("Failed to validate external signature over signer public key");
goto cleanup;
Why this scored 58/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.