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}