9 stable releases
1.4.0 | May 23, 2023 |
---|---|
1.3.3 | May 23, 2023 |
1.2.2 | May 22, 2023 |
1.0.0 | May 19, 2023 |
0.2.0-alpha1 | May 19, 2023 |
#78 in Memory management
302 downloads per month
40KB
727 lines
MEMSECURITY
Securely hold secrets in memory and protect them against cross-protection-boundary readout via microarchitectural, via attacks on physical layout, and via coldboot attacks.
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!!!
-
The Arrays can be used without the need to import other crates for encryption by simple adding the crate with no extra features.
[dependencies] memsecurity = "1.0.0"
-
To enable crating of arrays with CSPRNG random bytes that can be zeroed out use the
random
feature[dependencies] memsecurity = { version = "1.0.0", features = ["random"] }
-
To enable encryption of memory secrets, add this crate with the
encryption
feature. This feature automatically enables random bytes generation from the featurerandom
.[dependencies] memsecurity = { version = "1.0.0", features = ["encryption"] }
EXAMPLE
use memsecurity::*;
fn main() {
let mut foo = EncryptedMem::<32>::new();
let plaintext_bytes = ZeroizeBytesArray::csprng();
println!(" PLAINTEXT: {:?}", plaintext_bytes); //WARNING: THIS IS AN EXAMPLE, DO NOT PRINT SECRETS IN CODE
foo.encrypt(&plaintext_bytes).unwrap();
println!("CIPHERTEXT: {:?}", foo.ciphertext());
println!(" XNONCE: {:?}", foo.xnonce());
let decrypted = foo.decrypt().unwrap();
println!(" DECRYPTED:{:?}", decrypted);
assert_eq!(plaintext_bytes, decrypted);
}
Dependencies
~1.5–2MB
~49K SLoC