workflow_encryption/
chacha20poly1305.rs1use crate::error::Error;
2use crate::imports::*;
3use chacha20poly1305::{
4 aead::{AeadCore, AeadInPlace, KeyInit, OsRng},
5 Key, XChaCha20Poly1305,
6};
7
8pub fn encrypt<T>(data: &T, secret: &Secret) -> Result<Vec<u8>>
10where
11 T: Serializer,
12{
13 let mut buffer = vec![];
14 data.serialize(&mut buffer)?;
15 encrypt_slice(&buffer, secret)
16}
17
18pub fn encrypt_slice(data: &[u8], secret: &Secret) -> Result<Vec<u8>> {
19 let private_key_bytes = argon2_sha256(secret.as_ref(), 32)?;
20 let key = Key::from_slice(private_key_bytes.as_ref());
21 let cipher = XChaCha20Poly1305::new(key);
22 let nonce = XChaCha20Poly1305::generate_nonce(&mut OsRng); let mut buffer = data.to_vec();
24 buffer.reserve(24);
25 cipher.encrypt_in_place(&nonce, &[], &mut buffer)?;
26 buffer.extend(nonce.iter().cloned());
27 Ok(buffer)
28}
29
30pub fn decrypt<T>(data: &[u8], secret: &Secret) -> Result<T>
31where
32 T: Deserializer,
33{
34 let data = decrypt_slice(data, secret)?;
35 Ok(T::try_from_slice(data.as_slice())?)
36}
37
38pub fn decrypt_slice(data: &[u8], secret: &Secret) -> Result<Secret> {
40 if data.len() < 24 {
41 return Err(Error::DecryptionDataLength);
42 }
43 let private_key_bytes = argon2_sha256(secret.as_ref(), 32)?;
44 let key = Key::from_slice(private_key_bytes.as_ref());
45 let cipher = XChaCha20Poly1305::new(key);
46 let len = data.len() - 24;
47 let nonce = &data[len..];
48 let mut buffer = data[..len].to_vec();
49 cipher.decrypt_in_place(nonce.into(), &[], &mut buffer)?;
50 Ok(Secret::new(buffer))
51}
52
53#[cfg(test)]
54mod tests {
55 use super::*;
56
57 #[test]
58 fn test_encrypt_decrypt() -> Result<()> {
59 use crate::imports::*;
60
61 println!("testing encrypt/decrypt");
62
63 let password = b"password";
64 let original = b"hello world".to_vec();
65 let password = Secret::new(password.to_vec());
67 let encrypted = encrypt_slice(&original, &password).unwrap();
68 let decrypted = decrypt_slice(&encrypted, &password).unwrap();
70 assert_eq!(decrypted.as_ref(), original);
72
73 Ok(())
74 }
75}