sare_core/encryption/
mod.rs1pub mod error;
2
3use crate::encryption::error::*;
4use rand::RngCore;
5use serde::{Deserialize, Serialize};
6
7use aead::stream;
8use aes_kw::KekAes256;
9use chacha20poly1305::KeyInit;
10use chacha20poly1305::XChaCha20Poly1305;
11use secrecy::{ExposeSecret, SecretVec};
12use std::io::{Read, Write};
13use std::vec;
14
15const AEAD_BUFFER_LEN: usize = 2048;
16
17#[derive(Copy, Debug, Clone, Serialize, Deserialize)]
18pub enum EncryptionAlgorithm {
19 AES256GCM,
20 AES256KW,
21 XCHACHA20POLY1305,
22}
23
24pub struct KeyWrap {
25 input_key: SecretVec<u8>,
26}
27
28impl KeyWrap {
29 pub fn new(input_key: SecretVec<u8>) -> Result<Self, EncryptionError> {
30 if input_key.expose_secret().len() != 32 {
31 return Err(EncryptionError::InvalidKeyLength);
32 }
33
34 Ok(KeyWrap { input_key })
35 }
36
37 pub fn wrap(&self, data: &SecretVec<u8>) -> Result<Vec<u8>, EncryptionError> {
38 let mut output: Vec<u8> = vec![0; data.expose_secret().len() + 8];
39
40 let input_key = <[u8; 32]>::try_from(self.input_key.expose_secret().as_slice()).unwrap();
41
42 let kek = KekAes256::from(input_key);
43
44 kek.wrap_with_padding(data.expose_secret(), &mut output)?;
45
46 Ok(output)
47 }
48
49 pub fn dewrap(&self, wrapped_data: &SecretVec<u8>) -> Result<SecretVec<u8>, EncryptionError> {
50 let mut output: Vec<u8> = vec![0; wrapped_data.expose_secret().len() - 8];
51
52 let input_key = <[u8; 32]>::try_from(self.input_key.expose_secret().as_slice()).unwrap();
53
54 let kek = KekAes256::from(input_key);
55
56 kek.unwrap_with_padding(wrapped_data.expose_secret(), &mut output)?;
57
58 Ok(SecretVec::from(output))
59 }
60}
61
62pub struct Encryptor {
63 input_key: SecretVec<u8>,
64 pub nonce: Vec<u8>,
65 algorithm: EncryptionAlgorithm,
66}
67
68impl Encryptor {
69 pub fn new(input_key: SecretVec<u8>, algorithm: EncryptionAlgorithm) -> Self {
70 let mut nonce = vec![0; 19];
72 let mut rng = rand::thread_rng();
73 rng.fill_bytes(&mut nonce);
74
75 Encryptor {
76 input_key,
77 nonce,
78 algorithm,
79 }
80 }
81
82 pub fn encrypt<R: Read, W: Write>(
83 &self,
84 mut data: R,
85 mut output: W,
86 ) -> Result<(), EncryptionError> {
87 match self.algorithm {
88 EncryptionAlgorithm::XCHACHA20POLY1305 => {
89 self.encrypt_xchacha20poly1305(&mut data, &mut output)
90 }
91 _ => unimplemented!(),
92 }
93 }
94
95 pub fn encrypt_xchacha20poly1305<R: Read, W: Write>(
97 &self,
98 mut data: R,
99 mut output: W,
100 ) -> Result<(), EncryptionError> {
101 let input_key = <[u8; 32]>::try_from(self.input_key.expose_secret().as_slice()).unwrap();
102 let nonce = self.nonce.as_slice();
103
104 let aead = XChaCha20Poly1305::new(input_key.as_ref().into());
105 let mut stream_aead = stream::EncryptorBE32::from_aead(aead, nonce.as_ref().into());
106 let mut data_buffer = [0u8; AEAD_BUFFER_LEN];
107
108 loop {
109 let read_count = data.read(&mut data_buffer)?;
110
111 if read_count == AEAD_BUFFER_LEN {
112 let encrypted_data = stream_aead.encrypt_next(data_buffer.as_slice()).unwrap();
113
114 output.write_all(&encrypted_data)?;
115 } else {
116 let encrypted_data = stream_aead
117 .encrypt_last(&data_buffer[..read_count])
118 .unwrap();
119
120 output.write_all(&encrypted_data)?;
121 break;
122 }
123 }
124 Ok(())
125 }
126}
127
128pub struct Decryptor {
129 input_key: SecretVec<u8>,
130 nonce: Vec<u8>,
131 algorithm: EncryptionAlgorithm,
132}
133
134impl Decryptor {
135 pub fn new(input_key: SecretVec<u8>, nonce: Vec<u8>, algorithm: EncryptionAlgorithm) -> Self {
136 Decryptor {
137 input_key,
138 nonce,
139 algorithm,
140 }
141 }
142
143 pub fn decrypt<R: Read, W: Write>(
144 &self,
145 mut encrypted_data: R,
146 mut output: W,
147 ) -> Result<(), EncryptionError> {
148 match self.algorithm {
149 EncryptionAlgorithm::XCHACHA20POLY1305 => {
150 self.decrypt_xchacha20poly1305(&mut encrypted_data, &mut output)
151 }
152 _ => unimplemented!(),
153 }
154 }
155
156 pub fn decrypt_xchacha20poly1305<R: Read, W: Write>(
158 &self,
159 mut encrypted_data: R,
160 mut output: W,
161 ) -> Result<(), EncryptionError> {
162 let input_key = <[u8; 32]>::try_from(self.input_key.expose_secret().as_slice()).unwrap();
163 let nonce = self.nonce.as_slice();
164
165 let aead = XChaCha20Poly1305::new(input_key.as_ref().into());
166 let mut stream_aead = stream::DecryptorBE32::from_aead(aead, nonce.as_ref().into());
167 let mut encrypted_buffer = [0u8; AEAD_BUFFER_LEN + 16]; loop {
170 let read_count = encrypted_data.read(&mut encrypted_buffer)?;
171
172 if read_count == AEAD_BUFFER_LEN {
173 let decrypted_data = stream_aead
174 .decrypt_next(encrypted_buffer.as_slice())
175 .unwrap();
176
177 output.write(&decrypted_data)?;
178 } else {
179 let decrypted_data = stream_aead
180 .decrypt_last(&encrypted_buffer[..read_count])
181 .unwrap();
182
183 output.write(&decrypted_data)?;
184 break;
185 }
186 }
187
188 Ok(())
189 }
190}