redoubt-zero-core 0.1.0-rc.1

Core zeroization primitives: guards, sentinels, and RAII wrappers
Documentation

RedoubtZero-core

RAII guards and systematic zeroization primitives for protecting sensitive data in memory.

RedoubtZero-core provides composable building blocks for secure memory handling:

  • [ZeroizeOnDropSentinel]: Runtime verification that zeroization happened before drop
  • [ZeroizingMutGuard]: RAII guard for mutable references (auto-zeroizes on drop)
  • Traits: [FastZeroizable], [ZeroizationProbe], [AssertZeroizeOnDrop], [MutGuarded]
  • Derive macro: #[derive(RedoubtZero)] for automatic trait implementations

Design Principles

  1. Systematic zeroization: Guards auto-zeroize on drop (impossible to forget)
  2. Runtime verification: [ZeroizeOnDropSentinel] ensures zeroization happened
  3. API safety: High-level wrappers can prevent direct access to sensitive data
  4. Composability: Traits work with collections, nested types, custom structs

Quick Start

Using ZeroizingMutGuard

use redoubt_zero_core::{ZeroizingMutGuard, ZeroizationProbe};

let mut sensitive: u64 = 12345;

{
    // Guard zeroizes `sensitive` when dropped
    let mut guard = ZeroizingMutGuard::from(&mut sensitive);
    *guard = 67890;
} // guard drops here → sensitive is zeroized

assert!(sensitive.is_zeroized());

Manual Implementation

use redoubt_zero_core::{ZeroizeOnDropSentinel, FastZeroizable, ZeroizationProbe, AssertZeroizeOnDrop, collections};

struct Credentials {
    username: Vec<u8>,
    password: Vec<u8>,
    __sentinel: ZeroizeOnDropSentinel,
}

impl Drop for Credentials {
    fn drop(&mut self) {
        self.fast_zeroize();
    }
}

impl FastZeroizable for Credentials {
    fn fast_zeroize(&mut self) {
        self.username.fast_zeroize();
        self.password.fast_zeroize();
        self.__sentinel.fast_zeroize();
    }
}

impl ZeroizationProbe for Credentials {
    fn is_zeroized(&self) -> bool {
        let fields: [&dyn ZeroizationProbe; 2] = [
            collections::to_zeroization_probe_dyn_ref(&self.username),
            collections::to_zeroization_probe_dyn_ref(&self.password),
        ];
        collections::collection_zeroed(&mut fields.into_iter())
    }
}

impl AssertZeroizeOnDrop for Credentials {
    fn clone_sentinel(&self) -> ZeroizeOnDropSentinel {
        self.__sentinel.clone()
    }
    fn assert_zeroize_on_drop(self) {
        redoubt_zero_core::assert::assert_zeroize_on_drop(self);
    }
}

let creds = Credentials {
    username: b"admin".to_vec(),
    password: b"secret".to_vec(),
    __sentinel: ZeroizeOnDropSentinel::default(),
};

// Verify zeroization happens on drop
creds.assert_zeroize_on_drop(); // ✅ Passes

Safety

This crate uses #![warn(unsafe_op_in_unsafe_fn)] and minimizes unsafe usage. All guards rely on RAII (Drop trait) for safety guarantees.

License

GPL-3.0-only