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.
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 failedstorage_crypto_decrypt(AES-GCM auth) callsstorage_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:
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.