secrets
is a library to help Rust programmers safely held cryptographic
secrets in memory.
It is mostly an ergonomic wrapper around the memory-protection utilities provided by [libsodium].
Fixed-size buffers allocated on the stack gain the following protections:
mlock(2)
is called on the underlying memoryDebug
Clone
dFixed and variable-sized buffers can be allocated on the heap and gain the following protections:
mprotect(2)
unless an active borrow is in scopemlock(2)
is called on the allocated memoryThis library is explicitly not panic-safe. To ensure the safety of protected memory space, this library can and will panic if it is unable to enforce its advertised guarantees.
Similarly, this library will cause segmentation faults if (and only if) it detects certain safety violations. For example, this can happen if a process attempts to directly read or write to the contents of memory that hasn't been properly unlocked, or if canaries have been overwritten. This library has been written to ensure that such violations should be impossible to cause through well-formed Rust, and so should only occur as a result of a security vulnerability.
rust
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
});
```rust use std::fs::File; use std::io::Read;
use libsodium_sys as sodium; use secrets::SecretBox;
const KEYLEN : usize = sodium::cryptokdfKEYBYTES as _; const CTXLEN : usize = sodium::cryptokdfCONTEXTBYTES as _;
const CONTEXT : &[u8; CTX_LEN] = b"example\0";
fn derivesubkey( key: &[u8; KEYLEN], context: &[u8; CTXLEN], subkeyid: u64, subkey: &mut [u8], ) { unsafe { libsodiumsys::cryptokdfderivefromkey( subkey.asmutptr(), subkey.len(), subkeyid, context.asptr().cast(), key.asptr() ); } }
let masterkey = SecretBox::<[u8; KEYLEN]>::trynew(|mut s| { File::open("example/masterkey/key")?.read_exact(s) })?;
let subkey0 = SecretBox::<[u8; 16]>::new(|mut s| { derivesubkey(&master_key.borrow(), CONTEXT, 0, s); });
let subkey1 = SecretBox::<[u8; 16]>::new(|mut s| { derivesubkey(&master_key.borrow(), CONTEXT, 1, s); });
assertne!( subkey0.borrow(), subkey_1.borrow(), ); ```
```rust use std::fs::File; use std::io::Read;
use libsodium_sys as sodium; use secrets::{SecretBox, SecretVec};
const KEYLEN : usize = sodium::cryptosecretboxKEYBYTES as _; const NONCELEN : usize = sodium::cryptosecretboxNONCEBYTES as ; const MACLEN : usize = sodium::cryptosecretboxMACBYTES as _;
let mut key = SecretBox::<[u8; KEYLEN]>::zero(); let mut nonce = [0; NONCELEN]; let mut ciphertext = Vec::new();
File::open("example/decryptedciphertext/key")? .readexact(key.borrowmut().asmut())?;
File::open("example/decryptedciphertext/nonce")? .readexact(&mut nonce)?;
File::open("example/decryptedciphertext/ciphertext")? .readto_end(&mut ciphertext)?;
let plaintext = SecretVec::
assert_eq!( *b"attack at dawn", *plaintext.borrow(), ); ```
Licensed under either of
at your option.