Skip to content

Seed entropy and QR icon data not zeroized in mnemonic QR-export flow #318

Description

@popodai

Summary

In mnemonic_export_qr() (main/process/mnemonic.c), the raw mnemonic entropy (i.e. the seed) is converted into a CompactSeedQR and displayed as on-screen icons. Unlike every other seed-handling path in the codebase, none of this data is zeroized:

  • uint8_t entropy[BIP32_ENTROPY_LEN_256] (line 83) and qrbuffer[96] (line 91) are stack buffers holding the raw seed, and are never wrapped in SENSITIVE_PUSH/SENSITIVE_POP.
  • The QR icons (icons[i].data, qr_overview.data, allocated with JADE_CALLOC_PREFER_SPIRAM in qrcode.c) encode the full seed, but are released with plain free()qrcode_freeIcon() (main/qrcode.c:1076) performs no zeroization.

After the export flow the seed therefore remains readable in freed heap and on the stack. This contradicts the hardening added in 1.0.40 ("Clear secrets from memory more diligently after UI display") and the SENSITIVE_PUSH/SENSITIVE_POP discipline used everywhere else (e.g. mnemonic_new(), get_bip85_mnemonic(), import_compactseedqr()).

Related: #180

Suggested fix

  • Wrap entropy and qrbuffer with SENSITIVE_PUSH/SENSITIVE_POP.
  • Zeroize icon data before freeing — e.g. wally_bzero(icon->data, qrcode_get_icon_data_size(icon->width, icon->height)) inside qrcode_freeIcon() (would need #include <wally_crypto.h> added to qrcode.c), and the same for icons[i].data before free() in the cleanup path (mnemonic.c:225-229).

Verification

Confirmed still present on current master (as of 2026-08-04): main/process/mnemonic.c:83 and main/qrcode.c:1076 unchanged. qrcode_freeIcon() has a single caller, so the fix has no impact outside the QR-export flow.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions