trackslash
VAULT-51 P2

Encryption 12: add duress slots to the encrypted store

0
Sub-issue of VAULT-23 P2 Add a duress vault that opens with an alternative app lock password

Description

The storage part of VAULT-23, from the on-device encryption design (VAULT-26, docs/on-device-encryption.md, "Duress vault").

The change:

  • Duress slots: a duressSlots list in each vault. Decided: N = 16 slots, L = 10 reserved, so the real vault is safe for eleven levels of nesting.
  • Making a duress database: "make duress database" creates it in a slot, from any vault.
  • Passwords: a new password is refused only if it matches the vault you're in. A password that opens another slot is accepted silently. If more than one slot opens, the most recently wrapped wins.
  • Per-vault settings: each vault gets its own settings section: backup password and its record, backup events, and auto-backup configuration and retention.

Tests:

  • the chain never targets the real vault within the safe depth
  • every vault's payload has the same shape
  • real and duress unlocks take the same time
  • auto-backup stays isolated between vaults

Depends on: encryption sub-issues 5–9.

Linked issues

0

GitHub

0

No branches or pull requests linked.

Comments

1
Bradley

Done in https://github.com/badbundle/vault-app/pull/648 (merged as 78cd21ba). This covers the slot mechanics. The per-vault backup settings were split into VAULT-70.

Making a duress database: EncryptedVaultStore.makeDuressVault(password:), plus a session version for the UI, creates an empty vault W in V.duressSlots[0].

  • W.duressSlots = V.duressSlots[1...] + [x], where x comes from the system random generator and is never V's or W's slot.
  • The file is replaced through the locked, verified write. V's slot isn't touched, and the steps are identical from the real vault or a duress vault.
  • VaultDuressSlots is the single source of L (10).

Same passwords:

  • V's own password is refused, checked against V's key box only.
  • A password that opens another slot is accepted silently, and takes the same steps as a fresh one.
  • At unlock, the most recently wrapped vault wins.

Wrap stamp: this closes a clock-rollback oracle found in review.

  • Recency now comes from VaultDeviceWrapStamper, a monotonic, device-local stamp: max(now, stamp + 1 ms, previous + 1 ms), held in the keychain on this device only.
  • It's used by every wrap.
  • It moves on every successful unlock too, so it shows only when the device was last used.

Other fixes: new vaults start at a random generation, and the design doc's residual limits were corrected: new slot nonces, key-box contents, and the stamp.

Tests:

  • Chains never target the real vault within 11 levels, checked through the store.
  • Payload shapes are equal.
  • Making a vault takes the same steps and time from either vault.
  • Unlocks with real, duress and wrong passwords do equal work.
  • A reused real password opens the newer vault.
  • Rolling the clock back doesn't change which vault opens.
  • Every failure step leaves the file unchanged.
  • A stale writer gets slotLost.