1pub use aes_gcm::{
3 aead::{generic_array::GenericArray, rand_core::RngCore, AeadInPlace, KeyInit, OsRng},
4 Aes128Gcm, Aes256Gcm, Nonce, Tag, TagSize
5};
6use crate::exchange::KEY_LENGTH;
7use crate::errors::EncryptionErrors;
8use zeroize::Zeroize;
9
10pub type Result<T> = core::result::Result<T, EncryptionErrors>;
11pub type AesGcm128Enc = EncAlgo<Aes128Gcm>;
12pub type AesGcm256Enc = EncAlgo<Aes256Gcm>;
13
14pub const AES_GCM_NONCE_SIZE: usize = 12;
16pub const AES_GCM_TAG_SIZE: usize = 16;
17
18#[derive(Debug, PartialEq, Eq)]
19pub enum Algo {
20 Aes128,
21 Aes256,
22 Unknown,
23}
24
25impl From<&str> for Algo {
26 fn from(v: &str) -> Self {
27 match v {
28 "aes128" => Algo::Aes128,
29 "aes256" => Algo::Aes256,
30 _ => Algo::Unknown
31 }
32 }
33}
34
35impl From<&Algo> for &str {
36 fn from(v: &Algo) -> Self {
37 match v {
38 Algo::Aes128 => "aes128",
39 Algo::Aes256 => "aes256",
40 Algo::Unknown => "unknown"
41 }
42 }
43}
44
45
46macro_rules! create_aes_gcm_encryptor {
48 ($key:expr, $aesgcm:ident) => {{
49 let arr_key = GenericArray::from_slice($key);
50 $aesgcm::new(arr_key)
51 }};
52}
53
54#[macro_export]
55macro_rules! decrypt_aes_gcm {
57 ($encryptor:expr, $data:expr) => {
58 $encryptor.decrypt(
59 &$data[..$data.len()-AES_GCM_NONCE_SIZE], &$data[$data.len()-AES_GCM_NONCE_SIZE..])
60 .expect("Could not decrypt")
61 }
62} pub use decrypt_aes_gcm;
63
64pub trait EncryptorBase<CiAlgo>
65where
66 CiAlgo: AeadInPlace,
67{
68 fn encrypt(&self, data: &[u8]) -> Result<Vec<u8>> {
70 let mut encrypted_data = data.to_vec();
71 self.encrypt_in_place(&mut encrypted_data)?;
72
73 Ok(encrypted_data)
74 }
75
76 fn decrypt(&self, data: &[u8], nonce: &[u8]) -> Result<Vec<u8>> {
78 let mut decrypted_data = data.to_vec();
79 self.decrypt_in_place(&mut decrypted_data, nonce)?;
80
81 Ok(decrypted_data)
82 }
83
84 fn encrypt_in_place(&self, data: &mut Vec<u8>) -> Result<()> {
86 let mut nonce = vec![0; AES_GCM_NONCE_SIZE];
89 OsRng.fill_bytes(&mut nonce);
90
91 if self.get_encryptor().encrypt_in_place(Nonce::from_slice(&nonce), b"", data).is_err() {
93 return Err(EncryptionErrors::FailedEncrypt);
94 }
95
96 data.append(&mut nonce);
98
99 Ok(())
100 }
101
102 fn decrypt_in_place(&self, data: &mut Vec<u8>, nonce: &[u8]) -> Result<()> {
104 let nonce = Nonce::from_slice(nonce);
105 if self.get_encryptor().decrypt_in_place(nonce, b"", data).is_err() {
106 return Err(EncryptionErrors::FailedDecrypt);
107 }
108
109 Ok(())
110 }
111
112 fn decrypt_in_place_detached(&self, data: &mut [u8], nonce: &[u8]) -> Result<()> {
113 if data.len() < AES_GCM_TAG_SIZE {
114 return Err(EncryptionErrors::InvalidLength);
115 }
116
117 let tag_pos = data.len() - AES_GCM_TAG_SIZE;
118 let (d, tag) = data.as_mut().split_at_mut(tag_pos);
119 self.get_encryptor().
121 decrypt_in_place_detached(nonce.into(), b"", d, Tag::from_slice(tag)).expect("FailedDecrypting");
122
123 Ok(())
124 }
125
126 fn get_encryptor(&self) -> &CiAlgo;
127}
128
129pub struct EncAlgo<T> {
131 key: [u8; KEY_LENGTH],
132 encryptor_func: fn(&[u8]) -> T,
133 encryptor: T,
134}
135
136impl<T> EncAlgo<T> {
137 pub fn new(key: &[u8; KEY_LENGTH], encryptor_func: fn(&[u8]) -> T) -> Self {
138 Self {
139 key: *key,
140 encryptor_func,
141 encryptor: encryptor_func(key),
142 }
143 }
144}
145
146impl<T> Clone for EncAlgo<T> {
147 fn clone(&self) -> Self {
148 Self {
149 key: self.key.clone(),
150 encryptor_func: self.encryptor_func,
151 encryptor: (self.encryptor_func)(&self.key),
152 }
153 }
154}
155
156pub fn create_128_encryptor(key: &[u8]) -> Aes128Gcm {
159 create_aes_gcm_encryptor!(&key[..16], Aes128Gcm)
161}
162
163pub fn create_256_encryptor(key: &[u8]) -> Aes256Gcm {
166 create_aes_gcm_encryptor!(&key[..32], Aes256Gcm)
168}
169
170impl<CiAlgo> EncryptorBase<CiAlgo> for EncAlgo<CiAlgo>
171where
172 CiAlgo: AeadInPlace,
173{
174 fn get_encryptor(&self) -> &CiAlgo {
175 &self.encryptor
176 }
177}
178
179pub struct SData<T: Zeroize>(pub T);
181
182impl<T: Zeroize> Drop for SData<T> {
183 fn drop(&mut self) {
184 self.0.zeroize();
185 }
186}