Skip to content

7.14.3 reset/recovery abort paths retain mnemonic material and armed state #617

Description

@BitHighlander

Summary

Reset and recovery abort paths do not wipe all mnemonic material, and one recovery finalization error leaves the ceremony armed.

Found while auditing PR #604 at exact head 1d446ccbc9cf32a6e499990e65bcf7b358f1325b.

Evidence

Reset mnemonic survives cancellation

  • lib/firmware/reset.c:394 calls mnemonic_from_data().
  • deps/crypto/trezor-firmware/crypto/bip39.c:65-100 stores the result in static CONFIDENTIAL char mnemo[...]; only mnemonic_clear() wipes it.
  • lib/firmware/reset.c:405-416, :448-452, and :493-499 abort after mnemonic creation without calling mnemonic_clear().
  • The exit: cleanup at reset.c:509-518 wipes display-format buffers, not the BIP-39 static.

Recovery fragments survive cancellation

  • lib/firmware/recovery_cipher.c:426-427 declares function-static confidential coded_word and decoded_word buffers.
  • recovery_cipher_reset() at :64-72, called by setup_abort(), wipes the global mnemonic and cipher but cannot reach those function statics.
  • They are wiped only on the next word's local control flow (:429-434, :467-469).

Invalid final word count stays armed

  • recovery_cipher_finalize() at :548-556 returns on an invalid inferred word count without calling recovery_cipher_abort() / setup_abort().

Impact

Medium — confidential seed material and ceremony authorization outlive cancel/error boundaries. Exploiting the residual bytes for disclosure requires another memory-read primitive, but the armed-state error is directly host reachable and violates the ceremony isolation contract.

Acceptance criteria

  • Call mnemonic_clear() on every reset exit after mnemonic_from_data(), including direct-return cancellation.
  • Move recovery word fragments into reset-owned state or expose a wipe routine called by recovery_cipher_reset().
  • Route every recovery finalize error through setup_abort().
  • Add cancel/error tests that assert all seed buffers are zero and setup_isArmed() is false.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions