wasmium_securemem/lib.rs
1//! ### `wasmium-securemem`
2//! This crate is used to securely store in memory the `Ed25519 Keypair` of a Wasmium wallet.
3//! The keys are encrypted when they are not being used and decrypted when they need to be used
4//! to sign some bytes of any length.
5//!
6//! This is inspired by [sequoia-openpgp's Encrypted data structure](https://docs.rs/sequoia-openpgp/).
7//! #### An excerpt from their documentation:
8//!
9//!
10//! This type encrypts sensitive data, such as secret keys, in memory
11//! while they are unused, and decrypts them on demand. This protects
12//! against cross-protection-boundary readout via microarchitectural
13//! flaws like Spectre or Meltdown, via attacks on physical layout
14//! like Rowbleed, and even via coldboot attacks.
15//!
16//! The key insight is that these kinds of attacks are imperfect,
17//! i.e. the recovered data contains bitflips, or the attack only
18//! provides a probability for any given bit. Applied to
19//! cryptographic keys, these kind of imperfect attacks are enough to
20//! recover the actual key.
21//!
22//! This implementation on the other hand, derives a sealing key from
23//! a large area of memory, the "pre-key", using a key derivation
24//! function. Now, any single bitflip in the readout of the pre-key
25//! will avalanche through all the bits in the sealing key, rendering
26//! it unusable with no indication of where the error occurred.
27//!
28//! This kind of protection was pioneered by OpenSSH. The commit
29//! adding it can be found
30//! [here](https://marc.info/?l=openbsd-cvs&m=156109087822676).
31//!
32//!
33mod prekey_vault;
34pub use prekey_vault::*;
35mod vault;
36pub use vault::*;
37mod memvault;
38pub use memvault::*;
39mod protected_keypair;
40pub use protected_keypair::*;
41
42#[cfg(test)]
43mod correctness_tests {
44 use crate::{EncryptedVault, ProtectedEd25519KeyPair};
45
46 #[test]
47 fn eq_between_original_and_encrypted() {
48 use ed25519_dalek::Keypair;
49 use ed25519_dalek::Signature;
50 use rand::rngs::OsRng;
51
52 let mut csprng = OsRng {};
53 let keypair: Keypair = Keypair::generate(&mut csprng);
54
55 use ed25519_dalek::Signer;
56 let message: &[u8] = b"This is a test of the tsunami alert system.";
57 let signature: Signature = keypair.sign(message);
58
59 let vault =
60 EncryptedVault::encrypt_secret(&mut ProtectedEd25519KeyPair::new(keypair)).unwrap();
61
62 let vault_signed = vault.decrypt_and_sign(message).unwrap();
63
64 assert_eq!(signature, vault_signed);
65 }
66}