seed_keeper_core/wrap.rs
1//! Encrypt by wrapping a key with AES Key Wrap Algorithm (RFC 3394)
2//!
3//! See: https://docs.rs/aes-kw/0.2.1/aes_kw/
4use std::ops::Deref;
5
6use crate::error::Error;
7use aes_kw::Kek;
8pub use zeroize::Zeroize;
9use zeroize::{ZeroizeOnDrop, Zeroizing};
10
11/// Encrypt data with a key. The key can be any type that derefs to a slice of 32 bytes.
12/// Types should impl [Zeroize] so that the memory is zeroized after use.
13///
14/// # Example
15/// ```
16/// use seed_keeper_core::wrap::{encrypt, decrypt};
17/// use zeroize::Zeroizing;
18///
19/// let key = Zeroizing::new([1u8; 32]);
20/// let data = Zeroizing::new(vec![2u8; 32]);
21/// let encrypted = encrypt(key.clone(), data.clone()).unwrap();
22/// let decrypted = decrypt(key, &encrypted).unwrap();
23/// assert_eq!(data, decrypted.into());
24/// ```
25pub fn encrypt(
26 key: impl Deref<Target = [u8; 32]> + Zeroize + ZeroizeOnDrop,
27 data: impl Deref<Target = impl AsRef<[u8]>> + Zeroize + ZeroizeOnDrop,
28) -> Result<Vec<u8>, Error> {
29 let kek = Kek::from(*key);
30 Ok(kek.wrap_vec(&data.as_ref())?)
31}
32
33/// Decrypt data using a key. The decryption key should impl [Zeroize].
34///
35/// # Example
36/// ```
37/// use seed_keeper_core::wrap::{encrypt, decrypt};
38/// use zeroize::Zeroizing;
39///
40/// let key = Zeroizing::new([1u8; 32]);
41/// let data = Zeroizing::new(vec![2u8; 32]);
42/// let encrypted = encrypt(key.clone(), data.clone()).unwrap();
43/// let decrypted = decrypt(key, &encrypted).unwrap();
44/// assert_eq!(data, decrypted.into());
45/// ```
46pub fn decrypt(
47 key: impl Deref<Target = [u8; 32]> + Zeroize + ZeroizeOnDrop,
48 data: impl AsRef<[u8]>,
49) -> Result<Zeroizing<Vec<u8>>, Error> {
50 let kek = Kek::from(*key);
51 Ok(Zeroizing::new(kek.unwrap_vec(data.as_ref())?))
52}
53
54#[cfg(test)]
55mod tests {
56 use super::*;
57
58 #[test]
59 fn it_works() -> Result<(), Error> {
60 let key = Zeroizing::new([1u8; 32]);
61 let data = Zeroizing::new(vec![2u8; 32]);
62 let encrypted = encrypt(key.clone(), data.clone())?;
63 let decrypted = decrypt(key, &encrypted)?;
64 assert_eq!(data, decrypted.into());
65 Ok(())
66 }
67}