# SecMem - Secretes Memory Protection
[](https://crates.io/crates/sec-mem)
[](https://docs.rs/sec-mem)
[](https://opensource.org/licenses/MIT)
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
| `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_shielding` feature 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 via `blake3` hashing. 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_mprotect` and `WRPKRU` thread-local register gating to grant zero-syscall hardware access, triggering a hardware `SIGSEGV` if any unauthorized thread attempts access.
* **Linux Memory Sealing (`mseal`)**: Embedding `mseal` to permanently lock guard pages and permissions. `SecMem` uses raw `MAP_ANONYMOUS | MAP_PRIVATE` syscalls to create discrete VMAs, strictly avoiding the global heap to guarantee it never permanently locks `malloc` memory or causes leaks.
* **Process Anti-Tracing & Anti-Forking**: Implements `PR_SET_DUMPABLE(0)` to block `ptrace` debuggers, and `MADV_DONTFORK` | `MADV_DONTDUMP` to 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 hardware `WRPKRU` lock 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 self` for *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 (via `libc::getrandom` or `RDRAND` at startup). Validation is strictly enforced using `read_volatile` to 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::Box` or heap allocation.
* **Anti-Duplication**: Actively disables the `Clone` trait to prevent cryptographic key scattering across dynamic RAM.
## Usage
```rust
use sec_mem::{SecMem, SecretBox};
use zeroize::Zeroize;
// 1. High-Assurance OS-Protected Memory (SecMem)
let master_key = [0xAAu8; 32];
let mut secure_key = SecMem::new(master_key);
// Secret is unlocked, unblinded, and Hardware MPK-accessed only inside this closure
}); // Memory is instantly hardware-locked and re-blinded here!
// 2. Portable Software-Hardened Box (SecretBox)
let mut portable_box = SecretBox::new(42u32);
}); // 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 reading `mprotect`ed pages via `/proc/self/mem` only yields encrypted ciphertext.
- **`attack_stack_corruption`**: Uses unsafe pointer arithmetic to artificially overflow the `SecretBox` stack, proving the canaries catch the exploit and panic.
- **`attack_mseal_guard_page_bypass`**: Attempts to forcefully unprotect guard pages, proving `mseal` successfully blocks it.
- **`attack_panic_during_access`**: Panics inside an unlocked closure to verify the `Drop` handler 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.
| 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.*