Skip to content

PIN brick counts storage corruption as failed attempts (availability footgun) #142

Description

@kwsantiago

The PIN brick counter cannot distinguish a wrong PIN from a corrupted share, so storage corruption can brick a legitimate device.

In storage_load_share (main/storage.c), a failed storage_crypto_decrypt (AES-GCM auth) calls storage_crypto_record_attempt(false), incrementing the failure counter toward the 21-attempt brick-and-lockout. But GCM auth-decrypt fails identically for a wrong PIN and for a corrupted/bit-flipped ciphertext or tag — the log line even says "tampered or wrong PIN" because the code cannot tell them apart.

Consequence: a single corrupted share slot, read repeatedly for the right group, increments the brick counter on every attempt. ~21 reads of one bad slot can brick the whole device even though the user knows the correct PIN. On a fund-custody device this is an availability footgun: storage wear/bit-rot, not an attacker, triggers an irreversible-ish lockout.

Options to consider:

  • Distinguish transient/corruption failures from authentication failures (e.g. a separate integrity check, or only counting failures when the PIN-derived key is provably the variable) so corruption does not advance the brick counter.
  • Require the same slot to fail across a re-read before counting, or cap corruption-driven increments.
  • At minimum, surface a distinct error for likely-corruption so the user is not silently marched toward a brick.

Also relevant: this is the most safety-critical path in the feature and is currently verified only in native tests, never on hardware. An on-device test of the full fail -> lockout -> brick flow, and that a correct PIN resets the counter before 21, is recommended before relying on brick-at-21.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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