Migrated from ISSUES.md, which was retired in favour of GitHub issues. Original id I142, priority P3, from the 2026-06-29 on-disk encryption design.
The text below is the triaged entry verbatim, including the corrections triage made to the original finding.
Where: src/lib.rs, src/transaction/keys.rs, src/crypto/mod.rs
Problem: There are two distinct "key rotation" operations with very different costs:
-
Credential rotation (KEK re-wrap): derives a new KEK from a new passphrase or raw key and re-wraps the existing DEK into a key slot. This is O(1) — it touches only the superblock — and is fully implemented via add_key / rotate_key / remove_key.
-
Bulk DEK rotation (full re-encryption): generates a fresh DEK, re-encrypts every data page under the new DEK, and replaces the wrapped DEK in all active key slots. This is O(total_pages) — it must rewrite the entire database file — and is not yet implemented.
Bulk DEK rotation is only needed when the DEK itself is believed compromised (e.g., a process memory dump exposed the in-session DEK). Credential rotation — the far more common operational need (password change, key rollover, adding a second credential) — is already available and O(1). Because no production databases exist today and the DEK is not separately distributed, the risk of DEK compromise is low; the heavy whole-file cost makes this a poor default rotation path.
Direction of fix (when needed): Implement a rekey(old_key, new_key) or rekey_dek(key) API that (1) generates a fresh DEK, (2) reads, decrypts, re-encrypts, and writes back every non-superblock page in a single pass using the existing stride-aware PageIo, (3) re-wraps the new DEK into all currently-active key slots, and (4) commits an updated superblock. The operation must be crash-safe: either complete or leave the original file intact. A copy-then-atomic-rename strategy (write the new file alongside, then rename) is the simplest crash-safe approach for an embedded store; an in-place two-pass strategy is also possible but more complex. Reuse PageCipher::seal / PageCipher::open and CryptoHeader from the existing crypto layer.
Deep review 2026-07-02
Source: [deepdive 2026-07-02] — fresh-eyes Rust review at 581be36; full report at docs/reviews/review-20260702-001902.md. Every BUG/DESIGN finding here was confirmed by an independent adversarial verification pass (0 refuted). The four BUGs (I143–I146) are fixed in PR #89; the DESIGN/SMELL items are recorded for triage. Delta vs the prior two reviews: 0 regressions, 71 findings verified resolved.
Migrated from
ISSUES.md, which was retired in favour of GitHub issues. Original id I142, priority P3, from the 2026-06-29 on-disk encryption design.The text below is the triaged entry verbatim, including the corrections triage made to the original finding.
Where:
src/lib.rs,src/transaction/keys.rs,src/crypto/mod.rsProblem: There are two distinct "key rotation" operations with very different costs:
Credential rotation (KEK re-wrap): derives a new KEK from a new passphrase or raw key and re-wraps the existing DEK into a key slot. This is O(1) — it touches only the superblock — and is fully implemented via
add_key/rotate_key/remove_key.Bulk DEK rotation (full re-encryption): generates a fresh DEK, re-encrypts every data page under the new DEK, and replaces the wrapped DEK in all active key slots. This is O(total_pages) — it must rewrite the entire database file — and is not yet implemented.
Bulk DEK rotation is only needed when the DEK itself is believed compromised (e.g., a process memory dump exposed the in-session DEK). Credential rotation — the far more common operational need (password change, key rollover, adding a second credential) — is already available and O(1). Because no production databases exist today and the DEK is not separately distributed, the risk of DEK compromise is low; the heavy whole-file cost makes this a poor default rotation path.
Direction of fix (when needed): Implement a
rekey(old_key, new_key)orrekey_dek(key)API that (1) generates a fresh DEK, (2) reads, decrypts, re-encrypts, and writes back every non-superblock page in a single pass using the existing stride-awarePageIo, (3) re-wraps the new DEK into all currently-active key slots, and (4) commits an updated superblock. The operation must be crash-safe: either complete or leave the original file intact. A copy-then-atomic-rename strategy (write the new file alongside, then rename) is the simplest crash-safe approach for an embedded store; an in-place two-pass strategy is also possible but more complex. ReusePageCipher::seal/PageCipher::openandCryptoHeaderfrom the existing crypto layer.Deep review 2026-07-02
Source: [deepdive 2026-07-02] — fresh-eyes Rust review at
581be36; full report atdocs/reviews/review-20260702-001902.md. Every BUG/DESIGN finding here was confirmed by an independent adversarial verification pass (0 refuted). The four BUGs (I143–I146) are fixed in PR #89; the DESIGN/SMELL items are recorded for triage. Delta vs the prior two reviews: 0 regressions, 71 findings verified resolved.