secure-gate
Zero-cost, no_std-compatible wrappers for handling sensitive data in memory.
Fixed<T>– stack-allocated, zero-cost wrapper.Dynamic<T>– heap-allocated wrapper that forwards to the inner type.- When the
zeroizefeature is enabled,FixedZeroizing<T>andDynamicZeroizing<T>provide automatic zeroing on drop.
Installation
[]
= "0.5.2"
With automatic zeroing (recommended for most use cases):
= { = "0.5.2", = ["zeroize"] }
Features
| Feature | Description |
|---|---|
zeroize |
Enables zeroize integration (Zeroizing, SecretBox) |
serde |
Optional serialization support |
alloc |
Required for Dynamic<T> (enabled by default) |
std |
Not required – works in no_std environments |
Quick Start
use ;
// Type aliases
fixed_alias!;
fixed_alias!;
dynamic_alias!;
// Construction
let key = from; // clean and explicit
let key2: Aes256Key = rng.gen.into; // natural .into()
let key3 = new; // classic style
let nonce = from;
let nonce2: Nonce12 = rng.gen.into;
let mut password: Password = secure!;
password.push;
password.finish_mut; // shrink_to_fit() on String/Vec<u8>
// Auto-zeroing variants (requires `zeroize` feature)
let temp_key = secure_zeroizing!;
let secret_vec = secure_zeroizing!;
Memory Guarantees (zeroize feature enabled)
| Type | Allocation | Auto-zero on drop | Full capacity wiped | Slack memory eliminated | Notes |
|---|---|---|---|---|---|
Fixed<T> |
Stack | Yes (via Zeroizing) |
Yes | Yes (no heap) | No allocation |
Dynamic<T> |
Heap | Yes (via SecretBox) |
Yes | No (until drop) | Use finish_mut() to shrink |
FixedZeroizing<T> |
Stack | Yes | Yes | Yes | RAII wrapper |
DynamicZeroizing<T> |
Heap | Yes | Yes | No (until drop) | SecretBox prevents copies |
- All zeroing uses
zeroize::Zeroize(volatile writes + compiler fence). Vec<u8>andStringhave their full current capacity zeroed and are truncated to length zero.- The underlying allocation is freed on drop (standard Rust behavior); capacity is not forcibly reduced unless
finish_mut()/shrink_to_fit()is called. - Past reallocations may leave copies of data elsewhere in memory. Pre-allocate with the final expected size to avoid reallocations.
Important: DynamicZeroizing<T> (i.e. SecretBox<T>) is accessed via .expose_secret() and .expose_secret_mut() — it does not implement Deref.
Macros
secure! // Fixed<[u8; 32]>
secure! // Dynamic<String>
secure! // Dynamic<Vec<u8>>
secure_zeroizing! // FixedZeroizing<[u8; 32]> (zeroize feature)
secure_zeroizing! // DynamicZeroizing<Vec<u8>>
fixed_alias!
dynamic_alias!
Example Aliases
fixed_alias!;
fixed_alias!;
fixed_alias!;
dynamic_alias!;
dynamic_alias!;
// Usage
let key = from;
let key2: Aes256Key = rng.gen.into;
Migration from v0.4.x
SecureGate<T>→Fixed<T>(stack) orDynamic<T>(heap).expose_secret()→ direct deref (&*valueor&mut *value) forFixed/Dynamic- Automatic zeroing →
FixedZeroizing<T>orDynamicZeroizing<T>(withzeroizefeature)
Changelog
See CHANGELOG.md
License
MIT OR Apache-2.0