SecMem - Secretes Memory Protection
SecMem is a high-assurance, attack-resistant cryptographic memory allocator for Rust. It provides two secure container types designed to aggressively protect sensitive data (cryptographic keys, passwords, PII) in memory from OS-level exploits, memory dumping, buffer overflows, and side-channel attacks.
Feature Flags
| Feature | Description | Default |
|---|---|---|
sec_mem |
Enables SecMem, the OS-level memory hardening container. Requires libc and Linux. |
Yes |
encryption |
Enables ChaCha20/XOR-blinded encrypt-at-rest for SecMem. Stores the master key in memfd_secret. |
Yes |
key_shielding |
Enables OpenSSH-style 16 KiB pre-key blake3 derivation to heavily defend against side-channels. |
No |
(Note: SecretBox is always available and fully no_std compatible, regardless of features).
Core Protections
1. SecMem<S> (Hardware-Accelerated OS Hardening)
The primary secure container leveraging deep OS integration and hardware capabilities for maximum security.
- XOR-Blinded Encrypt-at-Rest: Secrets are transparently ChaCha20 encrypted at rest in RAM using a 2-of-2 secret sharing scheme. The master key is stored in a pointerless kernel blind spot (
memfd_secret), making the ciphertext in RAM mathematically useless to an attacker even if they dump the process memory or read/proc/self/mem. - Key Shielding (Optional): If the
key_shieldingfeature is enabled, it implements OpenSSH-style Key Shielding by splitting a massive 16 KiB pre-key buffer into two XOR parts. During access, it dynamically reconstructs the 16 KiB buffer and derives the final key viablake3hashing. This mathematical complexity actively crushes side-channel read attacks (Spectre/Meltdown) and Rowhammer bit-flips, at the cost of performance (~10x slower over normal setup). - Intel MPK (Memory Protection Keys): Hardware-accelerated memory isolation. It utilizes
pkey_mprotectandWRPKRUthread-local register gating to grant zero-syscall hardware access, triggering a hardwareSIGSEGVif any unauthorized thread attempts access. - Linux Memory Sealing (
mseal): Embeddingmsealto permanently lock guard pages and permissions.SecMemuses rawMAP_ANONYMOUS | MAP_PRIVATEsyscalls to create discrete VMAs, strictly avoiding the global heap to guarantee it never permanently locksmallocmemory or causes leaks. - Process Anti-Tracing & Anti-Forking: Implements
PR_SET_DUMPABLE(0)to blockptracedebuggers, andMADV_DONTFORK|MADV_DONTDUMPto ensure secrets are strictly wiped in child processes and omitted from core dumps. - Memory Locks (
mlock): Actively prevents secrets from ever being swapped to unencrypted disk swap space. - Zero-Window Fail-Closed RAII: Cryptographic operations are locked behind strict closure boundaries (
.access()). Panics correctly trigger stack unwinding that engages the hardwareWRPKRUlock as the absolute first instruction in the drop phase, entirely eliminating the time-of-check to time-of-use unwind window before memory is zeroized, re-encrypted, and dropped.
2. SecretBox<S> (Software-Enforced Memory Hardening)
A highly portable, software-only wrapper that requires zero OS syscalls. Perfect for zero-allocator no_std or heavily constrained embedded environments.
- Strict Exclusive Access: Enforces
&mut selffor all access. This mathematically eliminates multi-threaded race conditions and ensures zero concurrent references can exist at the compiler level. - Dynamic Volatile Canaries: Implements a
#[repr(C)]layout enveloping the inner stack data with dynamically generated randomized canaries (vialibc::getrandomorRDRANDat startup). Validation is strictly enforced usingread_volatileto mathematically prevent LLVM from dead-code-eliminating the memory corruption checks. - Closure-Restricted Lifetimes: Completely removes
expose_secret(). Secrets are strictly injected into closures (.with_secret()), forcing the reference to automatically die the microsecond the closure finishes. - Pure Stack Native: Stores data purely inline, completely eliminating the need for
alloc::Boxor heap allocation. - Anti-Duplication: Actively disables the
Clonetrait to prevent cryptographic key scattering across dynamic RAM.
Usage
use ;
use Zeroize;
// 1. High-Assurance OS-Protected Memory (SecMem)
let master_key = ;
let mut secure_key = new;
// Secret is unlocked, unblinded, and Hardware MPK-accessed only inside this closure
secure_key.access_mut; // Memory is instantly hardware-locked and re-blinded here!
// 2. Portable Software-Hardened Box (SecretBox)
let mut portable_box = new;
portable_box.with_secret; // Stack canaries verified via volatile reads on access!
Advanced Security Testing
We hammer the library with 24 aggressive security tests designed to simulate raw exploit vectors, including:
attack_proc_self_mem_read: Proves kernel bypass readingmprotected pages via/proc/self/memonly yields encrypted ciphertext.attack_stack_corruption: Uses unsafe pointer arithmetic to artificially overflow theSecretBoxstack, proving the canaries catch the exploit and panic.attack_mseal_guard_page_bypass: Attempts to forcefully unprotect guard pages, provingmsealsuccessfully blocks it.attack_panic_during_access: Panics inside an unlocked closure to verify theDrophandler successfully executes during unwind to prevent memory leakage.
Performance Considerations
SecMem heavily trades performance for maximum security. Hardware-accelerated memory protection and encryption-at-rest requires expensive context switches, syscalls, cache flushes, and memory barriers.
It is NOT designed for raw-performance hot paths (e.g. encrypting a 10Gbps packet stream). However, it is perfectly suited for web servers, password managers, key management systems (KMS), or security-focused applications where long-term key protection is prioritized over nanosecond-level latency.
| Operation | Standard Memory / Box |
SecretBox (Stack) |
SecMem (Hardware) |
|---|---|---|---|
| Allocation | ~50 ns | ~2 ns | ~15,600 ns (15.6 µs) |
| Read Access | ~40 ns | < 1 ns | ~3,170 ns (3.17 µs) |
| Write Access | ~142 ns | < 1 ns | ~3,330 ns (3.33 µs) |
| Deallocation | ~40 ns | ~2 ns | ~5,000 ns (5.0 µs) |
Benchmarks are approximations representing the heavy toll of raw mmap, pkey_mprotect, mlock, cache flushing, and ChaCha20 encryption loops compared to standard heap allocations.