# Implementation Plan: PIN Storage Security Remediation ## Overview Replace the persisted Argon2id/PIN-derived vault-key wrapper with a hardware-backed Android Keystore envelope. Keep the existing 4–12 ASCII-digit PIN UX only when the device can enforce limited-use Keystore keys in secure hardware; prefer StrongBox and fall back to a verified TEE key. Record the investigation evidence and the device-tier guarantees plainly. ## Architecture Decisions - The vault key is encrypted directly by a non-exportable Keystore AES-256 key; ordinary app storage contains only the ciphertext and IV. - PIN verification uses Argon2id followed by an HMAC under a non-exportable Keystore key. Ordinary storage cannot validate guesses without the device Keystore key. - Each PIN attempt first consumes one hardware-limited, single-use HMAC gate. The app exposes PIN setup only when Android reports hardware support for limited-use keys. - StrongBox is requested where available; `StrongBoxUnavailableException` falls back to a hardware-backed TEE key. Key security level is checked after generation. - Legacy `peach_pin_salt` / `peach_pin_wrapped_key` material is removed when the new store is initialized; users re-enable PIN with the master password on supported hardware. ## Task List ### Phase 1: Investigation and design - [x] Confirm the current PIN storage, KDF, PIN policy, Keystore inventory, and vault-key path. - [x] Measure the current Argon2id cost and calculate the 4–12 digit offline search space. - [x] Verify StrongBox, hardware security-level, authentication, and limited-use-key APIs against official Android documentation. ### Phase 2: Remediation - [x] Replace the ordinary-storage PIN wrapper with the hardware-backed envelope and attempt gates. - [x] Add migration behavior, support gating, and user-facing lockout/recovery behavior. - [x] Add focused tests for policy and storage shape; device-only gate behavior remains part of real-device validation. ### Checkpoint: Remediation - [x] Focused tests pass. - [x] Debug lint has no new errors. - [x] Release builds for arm64-v8a and x86_64 succeed. - [x] Code review confirms no PIN-derived decryptable vault-key wrapper remains. ### Phase 3: Validation and documentation - [ ] Validate StrongBox and TEE-only behavior on real supported hardware. - [ ] Validate unsupported/no-limited-use behavior on a representative device. - [x] Document actual device-tier guarantees and the remaining pre-upgrade-copy limitation. ### Checkpoint: Complete - [ ] Real-device evidence is captured for StrongBox, TEE-only, and unsupported tiers. - [x] Version, continuity notes, and security documentation are updated. - [x] Koh diff reviewed and the complete logical change saved. ## Risks and Mitigations | Risk | Impact | Mitigation | |---|---|---| | App PIN is not an Android Keystore authentication type | PIN could not be hardware-authenticated directly | Use Keystore-only vault wrapping plus hardware-limited attempt gates; do not claim system-auth lockout for the app PIN | | StrongBox is unavailable or lacks the requested primitive | PIN setup could fail on some devices | Prefer StrongBox, then verify and fall back to TEE; reject software-only keys | | Limited-use keys are exhausted or unsupported | PIN UX could lock out or be unavailable | Bound attempts, require master password to regenerate gates, and disable new PIN setup when hardware support is absent | | Existing storage was copied before upgrade | That historical copy remains vulnerable | State this limitation; the upgrade removes legacy material from the live app store but cannot revoke prior copies | ## Open Questions - Real hardware device models and OS versions for StrongBox, TEE-only, and unsupported-tier validation are UNCONFIRMED.