Done in https://github.com/badbundle/vault-app/pull/633 (merged as e8346a84).
What it adds: VaultSlotFile, a pure bytes-in, bytes-out type in VaultFeed, as designed in docs/on-device-encryption.md. It covers:
- the 128-byte header and 16 equal slots;
- password and device-key wraps, with separate HKDF labels;
- the key box holding
K_i, body length, generation and wrap time; - a padded body sealed with AES-256-GCM, with a fresh random nonce every time;
- growth by doubling, with random fill;
- AAD binding to the header, slot index and slot nonce. The slot size is zeroed in the AAD so growth doesn't break slots the app can't open.
Other changes:
Argon2idKeyDeriver.withKeyByteshandsK_pwstraight to aSymmetricKey, so it never sits in unwipedData.- The design doc now spells out the format details it left open.
Tests: 47 slot file tests cover:
- round trips and wrong passwords;
- a slot moved to another index or file;
- single-byte tampering;
- stale-slot conflicts, growth and rewraps;
- equal lengths;
- no plaintext or keys in the file.
Review follow-ups:
- A stronger header-AAD test, buffer wiping, a documented growth-length residual and memory bounds are going into VAULT-45.
- Rotating
K_ion every password rewrap, so an old password plus an old file copy can't read newer copies, goes into VAULT-48.