Skip to main content

redoubt_zero/
lib.rs

1// Copyright (c) 2025-2026 Federico Hoerth <memparanoid@gmail.com>
2// SPDX-License-Identifier: GPL-3.0-only
3// See LICENSE in the repository root for full license text.
4
5//! Systematic memory zeroization with compile-time and runtime guarantees.
6//!
7//! # Overview
8//!
9//! **redoubt-zero** provides RAII guards and derive macros for automatic, verifiable zeroization.
10//! Zeroization happens automatically on drop with runtime verification that it actually occurred.
11//!
12//! This is a convenience re-export crate combining [`redoubt-zero-core`] and [`redoubt-zero-derive`].
13//!
14//! # Quick Start
15//!
16//! ```rust
17//! use redoubt_zero::{RedoubtZero, ZeroizeOnDropSentinel, AssertZeroizeOnDrop};
18//!
19//! #[derive(RedoubtZero)]
20//! #[fast_zeroize(drop)]
21//! struct TempBuffer {
22//!     data: Vec<u8>,
23//!     capacity: usize,
24//!     __sentinel: ZeroizeOnDropSentinel,
25//! }
26//!
27//! let mut buffer = TempBuffer {
28//!     data: vec![1, 2, 3, 4],
29//!     capacity: 1024,
30//!     __sentinel: ZeroizeOnDropSentinel::default(),
31//! };
32//!
33//! // Use buffer...
34//!
35//! // Automatically zeroized on drop
36//! drop(buffer);
37//! ```
38//!
39//! # How It Works
40//!
41//! ## 1. The Sentinel Pattern
42//!
43//! Every struct includes a [`ZeroizeOnDropSentinel`] field. This sentinel:
44//! - Flips a flag on drop
45//! - Can be cloned to verify the original was zeroized
46//! - Provides runtime proof of zeroization
47//!
48//! ## 2. Automatic Trait Implementation
49//!
50//! The `#[derive(RedoubtZero)]` macro generates:
51//!
52//! - **[`FastZeroizable`]**: Implements `fast_zeroize(&mut self)` to zero all fields
53//! - **[`ZeroizationProbe`]**: Implements `is_zeroized(&self)` to check if data is zeroed
54//! - **[`AssertZeroizeOnDrop`]**: Test helper to verify drop behavior
55//! - **Optional Drop impl**: With `#[fast_zeroize(drop)]`, generates `Drop` that calls `fast_zeroize()`
56//!
57//! ## 3. Field Skipping
58//!
59//! Fields can be excluded from zeroization with `#[fast_zeroize(skip)]`:
60//!
61//! ```rust
62//! # use redoubt_zero::{RedoubtZero, ZeroizeOnDropSentinel};
63//! #[derive(RedoubtZero)]
64//! struct SessionData {
65//!     token: Vec<u8>,        // Zeroized
66//!     #[fast_zeroize(skip)]
67//!     id: u64,               // Not zeroized (just metadata)
68//!     __sentinel: ZeroizeOnDropSentinel,
69//! }
70//! ```
71//!
72//! # Core Types
73//!
74//! - **[`ZeroizeOnDropSentinel`]**: Drop sentinel for verifiable zeroization
75//! - **[`ZeroizingGuard<T>`]**: RAII wrapper that zeroizes on drop (owned)
76//! - **[`ZeroizingMutGuard<'a, T>`]**: RAII wrapper that zeroizes on drop (borrowed)
77//!
78//! # Traits
79//!
80//! - **[`FastZeroizable`]**: Provides `fast_zeroize(&mut self)` for efficient zeroization
81//! - **[`ZeroizationProbe`]**: Provides `is_zeroized(&self)` to check if data is zeroed
82//! - **[`AssertZeroizeOnDrop`]**: Test helper to verify drop zeroization
83//! - **[`ZeroizeMetadata`]**: Field count metadata for verification
84//!
85//! # Testing Zeroization
86//!
87//! Use [`AssertZeroizeOnDrop::assert_zeroize_on_drop()`] in tests to verify behavior:
88//!
89//! ```rust
90//! # use redoubt_zero::{RedoubtZero, ZeroizeOnDropSentinel, AssertZeroizeOnDrop};
91//! #[derive(RedoubtZero)]
92//! #[fast_zeroize(drop)]
93//! struct Workspace {
94//!     buffer: Vec<u8>,
95//!     __sentinel: ZeroizeOnDropSentinel,
96//! }
97//!
98//! #[test]
99//! fn test_workspace_zeroizes() {
100//!     let ws = Workspace {
101//!         buffer: vec![1, 2, 3, 4],
102//!         __sentinel: ZeroizeOnDropSentinel::default(),
103//!     };
104//!     ws.assert_zeroize_on_drop();  // Panics if not zeroized
105//! }
106//! ```
107//!
108//! # Design Rationale
109//!
110//! ## The Sentinel Pattern
111//!
112//! The sentinel enables runtime verification without unsafe code:
113//! - Clone the sentinel before drop
114//! - Drop the original
115//! - Check the sentinel's flag flipped
116//!
117//! This proves `Drop` ran and zeroization occurred.
118//!
119//! ## FastZeroizable Implementation
120//!
121//! `FastZeroizable` uses compiler fences for zeroization:
122//! - Matches LLVM's optimization model
123//! - Allows vectorization and unrolling
124//! - Prevents dead store elimination
125//!
126//! See [`redoubt-zero-core`](redoubt_zero_core) for implementation details.
127//!
128//! # Use Cases
129//!
130//! Useful for any data that needs guaranteed cleanup:
131//!
132//! - **Cryptographic material**: Keys, nonces, IVs
133//! - **Temporary buffers**: Workspace memory, intermediate results
134//! - **Session data**: Tokens, cookies, auth state
135//! - **Parser state**: Untrusted input, partial parses
136//! - **Any heap allocation** you want cleaned up reliably
137//!
138//! # Crate Structure
139//!
140//! This crate re-exports:
141//! - [`redoubt-zero-core`](redoubt_zero_core): Core types and traits
142//! - [`redoubt-zero-derive`](redoubt_zero_derive): `#[derive(RedoubtZero)]` macro
143//!
144//! [`ZeroizeOnDropSentinel`]: redoubt_zero_core::ZeroizeOnDropSentinel
145//! [`ZeroizingGuard<T>`]: redoubt_zero_core::ZeroizingGuard
146//! [`ZeroizingMutGuard<'a, T>`]: redoubt_zero_core::ZeroizingMutGuard
147//! [`FastZeroizable`]: redoubt_zero_core::FastZeroizable
148//! [`ZeroizationProbe`]: redoubt_zero_core::ZeroizationProbe
149//! [`AssertZeroizeOnDrop`]: redoubt_zero_core::AssertZeroizeOnDrop
150//! [`ZeroizeMetadata`]: redoubt_zero_core::ZeroizeMetadata
151//! [`AssertZeroizeOnDrop::assert_zeroize_on_drop()`]: redoubt_zero_core::AssertZeroizeOnDrop::assert_zeroize_on_drop
152//!
153//! ## License
154//!
155//! GPL-3.0-only
156
157#![cfg_attr(not(test), no_std)]
158#![allow(clippy::test_attr_in_doctest)]
159
160#[cfg(test)]
161mod tests;
162
163pub use redoubt_zero_core::*;
164pub use redoubt_zero_derive::*;