Skip to content

Anti-phishing device verification: design requirements (secret source, replay resistance, integration) #143

Description

@kwsantiago

The anti-phishing primitive in #134 (derive two BIP-39 words from a PIN prefix + device secret via HMAC-SHA256) is well-implemented, but security review found the approach does not yet achieve its goal. Capturing the requirements before wiring anything up.

Blocking design problems (not code fixes):

  1. No viable secret source without a secure element. The guarantee "only the real device produces the right words" needs a secret only the genuine device knows, available before the full PIN is entered. Without a provisioned secure element, the only device-unique material is the public factory eFuse MAC (printed on the label, derivable from WiFi/BLE MACs). Keyed with that, a cloned device reproduces the identical words and the check gives false assurance. The eventual caller MUST key this exclusively from the SE-backed random secret and MUST refuse to display words (and the UX must treat "no words" as "do not trust") when no SE is provisioned. Depends on Secure Element Phase 3: Production Lock Configuration #89 (Secure Element Phase 3).

  2. Record-and-replay defeats it even with a perfect secret. The words are a static, deterministic function of a tiny prefix space (2-4 digits = 100-10,000 values) with no freshness/nonce. An attacker with brief physical access to the real device enumerates every prefix->word mapping (and since words are shown before PIN entry, this does not consume a PIN attempt or trip lockout), then builds a clone that replays them perfectly without ever learning the secret. A static visual challenge cannot be keyed out of this; the design needs a freshness/challenge mechanism, or the threat model must be explicitly narrowed and documented.

  3. Partial-PIN fingerprint. Because prefix->words is a fixed per-device mapping, an attacker who has enumerated the device can invert observed on-screen words back to the entered PIN prefix digits (shoulder-surf leaks PIN digits).

Integration + mechanical items (needed whenever it does land):

  • It is currently dead code: no RPC/UX caller invokes pin_prefix_*. It must be wired into the PIN-entry/verification UX.
  • test_pin_prefix is built but not run by CI (.github/workflows/ci.yml) or just test (Justfile).
  • Add a known-answer test: current tests only check determinism/uniqueness/range, so a broken-but-consistent bit extraction (wrong shift/byte-order/swapped words) would still pass.
  • License headers on the new files say AGPL-3.0-or-later; the repo moved to MIT (Switch license from AGPL-3.0 to MIT #139).

Recommendation: hold #134 (converted to draft) until (a) #89 provides an SE-backed secret, (b) a replay-resistant verification design is chosen, and (c) it is actually integrated into the PIN-entry flow. Relates to #86, #134.

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