chronogrid/docs/ARCHITECTURE/ADR/0002-crypto-argon2id-keycha...

2.4 KiB
Raw Blame History

ADR-0002: chronogrid_crypto – Argon2id KDF & OS Keychain Strategy

  • Status: Accepted
  • Date: 2026-08-09
  • Deciders: Michael Kell

Context & Problem Statement

Task 1.2 requires implementing a chronogrid_crypto crate that provides:

  1. A master-key derivation function using Argon2id with parameters mandated by docs/ARCHITECTURE/02-security-and-crypto.md.
  2. Cross-platform OS keychain bindings for secure credential persistence (Windows, Linux). Android is deferred to the Flutter KeyStore bridge.

Options Considered

  1. Hand-roll Argon2id via raw blake2 + memory-hard loop — maximum control but high risk of implementation bugs in a security-critical path.
  2. Use the argon2 crate (RustCrypto) — well-audited, widely used, supports Argon2id with configurable parameters out of the box.
  3. Use ring or sodiumoxide — neither provides Argon2id natively; would still need the argon2 crate.

For keychain:

  1. Direct Win32 / libsecret FFI — full control, but significant per-platform maintenance burden.
  2. keyring crate — abstracts Windows Credential Manager, Linux SecretService, and macOS Keychain behind a single API.

Decision Outcome

Chosen Options:

  • argon2 crate v0.5 (RustCrypto) for KDF — spec-compliant, zero-copy output, and widely audited.
  • keyring crate v3 for cross-platform OS keychain — minimal code, covers Windows + Linux targets. Android is excluded via cfg(not(target_os = "android")) and will be handled by the Flutter KeyStore bridge.

Key design choices:

  • Argon2id parameters: memory = 65 536 KiB (64 MiB), time_cost = 3, parallelism = 4, salt = 16 bytes, output = 32 bytes.
  • DerivedKey struct wraps key + salt and implements Zeroize + Drop for automatic memory scrubbing.
  • Debug impl on DerivedKey redacts key material to prevent accidental log leaks.
  • Raw bytes are Base64-encoded before keychain insertion for UTF-8 credential backend compatibility, using inline encode/decode helpers (no extra dependency).

Consequences & Trade-offs

  • Positive: Spec-compliant crypto with secure memory handling; single cross-platform keychain API; 8 unit tests + 1 doc-test provide baseline confidence.
  • Negative: keyring v3 does not support Android — Android keychain must be wired separately via Flutter platform channels (planned for Task 1.5). Inline Base64 is minimal but could be replaced by base64 crate if other crates need it later.