Skip to main content

reddb_crypto/
lib.rs

1//! # reddb-io-crypto
2//!
3//! RedDB's cryptographic authority crate. It owns the **canonical
4//! per-page encryption-at-rest envelope** (AES-256-GCM), the
5//! **mandatory encrypt parameters**, and **key parsing** — paralleling
6//! the `reddb-io-file` (on-disk artifacts) and `reddb-io-wire`
7//! (protocol contracts) authority crates under ADR 0046 / 0054.
8//!
9//! ## Scope and boundary
10//!
11//! - **This crate owns** the per-page envelope byte-format
12//!   ([`encrypt_page`] / [`decrypt_page`]), the fixed crypto
13//!   parameters ([`params`]), and key parsing ([`key::parse_key`]).
14//! - **`reddb-io-file` owns** the page-0 paged-encryption header
15//!   (`PAGED_ENCRYPTION_MARKER` = `b"RDBE"` / `PagedEncryptionHeader`):
16//!   the file-level marker, salt, and key-check slot. That is the
17//!   self-describing "is this database encrypted, under what salt"
18//!   authority and is intentionally out of this crate's scope.
19//! - **`reddb-server` orchestrates**: it binds a key, decides policy
20//!   (`RED_ENCRYPTION_KEY[_FILE]`), and routes pager reads/writes
21//!   through this envelope. It introduces no second envelope format.
22//!
23//! ## History (#1053)
24//!
25//! Two dormant, byte-incompatible envelopes existed for the same
26//! not-yet-shipped feature. This crate consolidates them: the leaner
27//! magic-less frame survives as canonical (it was already embedded in
28//! the page-0 `key_check` and wired into the dormant pager); the
29//! self-describing `RDEP` frame is retired, with its typed errors,
30//! OS-CSPRNG nonce source, and key parser carried forward here. See
31//! ADR 0054 for the full rationale.
32
33#![allow(clippy::unwrap_used)]
34
35pub mod aes_gcm;
36pub mod key;
37pub mod os_random;
38pub mod page_envelope;
39
40/// Mandatory encrypt parameters for the canonical page envelope.
41///
42/// These are the fixed knobs every encrypted page agrees on. They are
43/// constants, not configuration: changing any of them is an on-disk
44/// format change that must go through a format-version bump in the
45/// page-0 header (`reddb_file`), never a silent edit here.
46pub mod params {
47    /// AES-256 key length in bytes.
48    pub const KEY_SIZE: usize = 32;
49    /// AES-GCM nonce (IV) length in bytes.
50    pub const NONCE_SIZE: usize = 12;
51    /// AES-GCM authentication tag length in bytes.
52    pub const TAG_SIZE: usize = 16;
53    /// Fixed envelope overhead per page: nonce (12) + tag (16) = 28.
54    /// Plaintext expands by exactly this many bytes. This is the value
55    /// the page-0 `key_check` slot (`reddb_file`) is sized against:
56    /// `PAGED_ENCRYPTION_KEY_CHECK_BLOB_SIZE` = 32 (plaintext) + 28.
57    pub const PAGE_ENVELOPE_OVERHEAD: usize = NONCE_SIZE + TAG_SIZE;
58    /// AEAD algorithm name, for diagnostics/logging.
59    pub const AEAD_ALGORITHM: &str = "AES-256-GCM";
60}
61
62pub use key::parse_key;
63pub use page_envelope::{decrypt_page, encrypt_page, PageEnvelopeError};
64pub use params::{AEAD_ALGORITHM, KEY_SIZE, NONCE_SIZE, PAGE_ENVELOPE_OVERHEAD, TAG_SIZE};