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}