Skip to content

I142: Bulk DEK rotation (full re-encryption under a new DEK) is not implemented #140

Description

@Xof

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:

  1. 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.

  2. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requesttype:securityTrust boundary, unsafe, hostile-input handling

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions