Expand description
Protected-access memory for cryptographic secrets.
Provides a convenient way to allocate and access memory for secret data. Data is protected from being read from and/or written to outside of limited scopes, where it may be accessed through pointer semantics or slice semantics.
Memory allocations are protected by guard pages before after the allocation, an underflow canary (to catch underflows before a guard page), and are zeroed out when freed.
§Core dumps
This library explicitly disables core dumps in release builds that
target UNIX systems. This is done to avoid retrival of a secret
from it. You can still opt-in on allowing code dumps with
allow-coredumps
feature flag.
§Example: generating crytographic keys
use secrets::Secret;
Secret::<[u8; 16]>::random(|s| {
// use `s` as if it were a `&mut [u8; 16]`
//
// the memory is `mlock(2)`ed and will be zeroed when this closure
// exits
});
§Example: load a master key from disk and generate subkeys from it
use std::fs::File;
use std::io::Read;
use libsodium_sys as sodium;
use secrets::SecretBox;
const KEY_LEN : usize = sodium::crypto_kdf_KEYBYTES as _;
const CTX_LEN : usize = sodium::crypto_kdf_CONTEXTBYTES as _;
const CONTEXT : &[u8; CTX_LEN] = b"example\0";
fn derive_subkey(
key: &[u8; KEY_LEN],
context: &[u8; CTX_LEN],
subkey_id: u64,
subkey: &mut [u8],
) {
unsafe {
libsodium_sys::crypto_kdf_derive_from_key(
subkey.as_mut_ptr(),
subkey.len(),
subkey_id,
context.as_ptr() as *const i8,
key.as_ptr()
);
}
}
let master_key = SecretBox::<[u8; KEY_LEN]>::try_new(|mut s| {
File::open("example/master_key/key")?.read_exact(s)
})?;
let subkey_0 = SecretBox::<[u8; 16]>::new(|mut s| {
derive_subkey(&master_key.borrow(), CONTEXT, 0, s);
});
let subkey_1 = SecretBox::<[u8; 16]>::new(|mut s| {
derive_subkey(&master_key.borrow(), CONTEXT, 1, s);
});
assert_ne!(
subkey_0.borrow(),
subkey_1.borrow(),
);
§Example: securely storing a decrypted ciphertext in memory
use std::fs::File;
use std::io::Read;
use libsodium_sys as sodium;
use secrets::{SecretBox, SecretVec};
const KEY_LEN : usize = sodium::crypto_secretbox_KEYBYTES as _;
const NONCE_LEN : usize = sodium::crypto_secretbox_NONCEBYTES as _;
const MAC_LEN : usize = sodium::crypto_secretbox_MACBYTES as _;
let mut key = SecretBox::<[u8; KEY_LEN]>::zero();
let mut nonce = [0; NONCE_LEN];
let mut ciphertext = Vec::new();
File::open("example/decrypted_ciphertext/key")?
.read_exact(key.borrow_mut().as_mut())?;
File::open("example/decrypted_ciphertext/nonce")?
.read_exact(&mut nonce)?;
File::open("example/decrypted_ciphertext/ciphertext")?
.read_to_end(&mut ciphertext)?;
let plaintext = SecretVec::<u8>::new(ciphertext.len() - MAC_LEN, |mut s| {
if -1 == unsafe {
sodium::crypto_secretbox_open_easy(
s.as_mut_ptr(),
ciphertext.as_ptr(),
ciphertext.len() as _,
nonce.as_ptr(),
key.borrow().as_ptr(),
)
} {
panic!("failed to authenticate ciphertext during decryption");
}
});
assert_eq!(
*b"attack at dawn",
*plaintext.borrow(),
);
Modules§
- Marker traits to allow types to be contained as secrets.
Structs§
- A type for protecting secrets allocated on the stack.
- A type for protecting fixed-length secrets allocated on the heap.
- A type for protecting variable-length secrets allocated on the heap.