Crates.io | memsecurity |
lib.rs | memsecurity |
version | 3.5.2 |
source | src |
created_at | 2023-05-19 10:05:42.20912 |
updated_at | 2024-01-05 11:18:48.534598 |
description | Securely hold secrets in memory and protect them against cross-protection-boundary readout via microarchitectural, via attacks on physical layout, and via coldboot attacks. |
homepage | https://github.com/448-engineering/MEMSECURITY |
repository | https://github.com/448-engineering/MEMSECURITY |
max_upload_size | |
id | 868705 |
size | 93,560 |
Securely hold secrets in memory and protect them against cross-protection-boundary readout via microarchitectural, via attacks on physical layout, and via coldboot attacks. mlock
is also used to prevent the operating system from swapping these secrets to RAM which offers some level of protection aganist cold boot attacks.
This algorithm was invented by OpenSSH. The given type of encryption secures sensitive data, such as secret keys, by encrypting them in memory while they are not in use and decrypting them on demand. This method provides protection against various types of attacks, including cross-protection-boundary readout via microarchitectural flaws like Spectre or Meltdown, attacks on physical layout like Rowbleed, and coldboot attacks. The key insight is that these attacks are imperfect, meaning that the recovered data contains bitflips or the attack only provides a probability for any given bit. When applied to cryptographic keys, these kinds of imperfect attacks are enough to recover the actual key.
However, this implementation derives a sealing key from a large area of memory called the "pre-key" using a key derivation function. Any single bitflip in the readout of the pre-key will avalanche through all the bits in the sealing key, rendering it unusable with no indication of where the error occurred.
This crate has not received an audit. Use at your own risk!!!
symm_asymm
- feature enables data types that can be used to securely zero out memory when they are dropped. They implement Zeroize
trait from zeroize
crate.
clonable_mem
- Allows the cloning of data types enabled by the symm_asymm
features.
encryption
- This enables encrypted memory with mlock
and munlock
and encrypts using Ascon128a cipher.
random
- This enables cryptographically secure random number generator which use rand_core
and rand_chacha
.
random
feature must be enabled.
use memsecurity::CsprngArray;
// Generate a 32 byte array of random bytes
let random_bytes = CsprngArray::<32>::gen();
// Assert that the random bytes are not zeroes
assert_ne!(random_bytes.expose_borrowed(), &[0u8; 32]);
// Use a simplified version of the random bytes generator.
use memsecurity::CsprngArraySimple;
// Generate one random byte
let random8_byte = CsprngArraySimple::gen_u8_byte();
// Generate 8 random bytes
let random8 = CsprngArraySimple::gen_u8_array();
assert_eq!(random8.expose_borrowed().len(), 8);
// Generate 16 random bytes
let random16 = CsprngArraySimple::gen_u16_array();
assert_eq!(random16.expose_borrowed().len(), 16);
// Generate 24 random bytes
let random24 = CsprngArraySimple::gen_u24_array();
assert_eq!(random24.expose_borrowed().len(), 24);
// Generate 32 random bytes
let random32 = CsprngArraySimple::gen_u32_array();
assert_eq!(random32.expose_borrowed().len(), 32);
// Generate 64 random bytes
let random64 = CsprngArraySimple::gen_u64_array();
assert_eq!(random64.expose_borrowed().len(), 64);
symm_asymm
feature must be enabled. The clonable_mem
feature can be enabled if they you need to clone these secrets (Use these with care). Most of these have the .expose_borrowed()
method which exposes the inner value if you want to use that value.
use memsecurity::{ZeroizeArray, ZeroizeBytes};
// Create an array of 4 bytes that will be zeroed out when dropped.
let array_like = ZeroizeArray::<4>::new([4u8, 3,2,1]);
// Use the value
array_like.expose_borrowed();
// Create a Vec like array using `BytesMut` from `bytes` crate that re-allocates when it's capacity is exceeded.
let mut vector_like = ZeroizeBytes::new();
// Insert a slice of bytes
vector_like.set(&[4u8, 5,6,7]); // Must be a byte (u8) type
// Use the value
vector_like.expose_borrowed();
encryption
feature to use the EncryptedMem
type. mlock
and munlock
are also implemented in this data.
The encryption key is generated afresh on each app run
use memsecurity::{EncryptedMem, CsprngArray};
// Initialize the struct with a random nonce (Nonce for Ascon128a)
let mut foo = EncryptedMem::new();
// Here a some random bytes are generated to simulate
// some secret you want to protect.
// Here the value must implement `Zeroize` trait
// and `impl From<AsRef<[u8]>>` trait so be accepted
// by the `encrypt()` and `decrypt()` methods of `EncryptedMem`.
let plaintext_bytes = CsprngArray::<32>::gen();
// Encrypt the secret in memory using the randomly
// generated encryption key that is `mlocked`
foo.encrypt(&plaintext_bytes).unwrap();
// Decrypt the secret using the `mlocked` key
let decrypted = foo.decrypt().unwrap();
assert_eq!(
plaintext_bytes.expose_borrowed(),
decrypted.expose_borrowed()
);
This crate is licensed under Apache license and all contributions and redistributions must bear the same license.
All conversations and contributions must obey the Rust Code of Conduct https://www.rust-lang.org/policies/code-of-conduct