ate_crypto/crypto/
encrypt_key.rs

1use crate::utils::b16_deserialize;
2use crate::utils::b16_serialize;
3use crate::utils::b24_deserialize;
4use crate::utils::b24_serialize;
5use crate::utils::b32_deserialize;
6use crate::utils::b32_serialize;
7use crate::utils::vec_deserialize;
8use crate::utils::vec_serialize;
9use serde::{Deserialize, Serialize};
10use sha3::Digest;
11use std::convert::TryInto;
12use std::io::ErrorKind;
13use std::result::Result;
14#[allow(unused_imports)]
15use tracing::{debug, error, info, instrument, span, trace, warn, Level};
16
17#[cfg(feature = "use_openssl")]
18use openssl::symm::Cipher;
19
20#[cfg(not(feature = "enable_openssl"))]
21use ctr::cipher::*;
22#[cfg(not(feature = "enable_openssl"))]
23type Aes128Ctr = ctr::Ctr128BE<aes::Aes128>;
24#[cfg(not(feature = "enable_openssl"))]
25type Aes192Ctr = ctr::Ctr128BE<aes::Aes192>;
26#[cfg(not(feature = "enable_openssl"))]
27type Aes256Ctr = ctr::Ctr128BE<aes::Aes256>;
28
29use super::*;
30
31/// Represents an encryption key that will give confidentiality to
32/// data stored within the redo-log. Note this does not give integrity
33/// which comes from the `PrivateKey` crypto instead.
34#[derive(Serialize, Deserialize, Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
35pub enum EncryptKey {
36    Aes128(
37        #[serde(serialize_with = "b16_serialize", deserialize_with = "b16_deserialize")] [u8; 16],
38    ),
39    Aes192(
40        #[serde(serialize_with = "b24_serialize", deserialize_with = "b24_deserialize")] [u8; 24],
41    ),
42    Aes256(
43        #[serde(serialize_with = "b32_serialize", deserialize_with = "b32_deserialize")] [u8; 32],
44    ),
45}
46
47impl EncryptKey {
48    pub fn generate(size: KeySize) -> EncryptKey {
49        RandomGeneratorAccessor::generate_encrypt_key(size)
50    }
51
52    pub fn resize(&self, size: KeySize) -> EncryptKey {
53        // Pad the current key out to 256 bytes (with zeros)
54        let mut bytes = self.value().iter().map(|a| *a).collect::<Vec<_>>();
55        while bytes.len() < 32 {
56            bytes.push(0u8);
57        }
58
59        // Build a new key from the old key using these bytes
60        match size {
61            KeySize::Bit128 => {
62                let aes_key: [u8; 16] = bytes
63                    .into_iter()
64                    .take(16)
65                    .collect::<Vec<_>>()
66                    .try_into()
67                    .unwrap();
68                EncryptKey::Aes128(aes_key)
69            }
70            KeySize::Bit192 => {
71                let aes_key: [u8; 24] = bytes
72                    .into_iter()
73                    .take(24)
74                    .collect::<Vec<_>>()
75                    .try_into()
76                    .unwrap();
77                EncryptKey::Aes192(aes_key)
78            }
79            KeySize::Bit256 => {
80                let aes_key: [u8; 32] = bytes
81                    .into_iter()
82                    .take(32)
83                    .collect::<Vec<_>>()
84                    .try_into()
85                    .unwrap();
86                EncryptKey::Aes256(aes_key)
87            }
88        }
89    }
90
91    pub fn size(&self) -> KeySize {
92        match self {
93            EncryptKey::Aes128(_) => KeySize::Bit128,
94            EncryptKey::Aes192(_) => KeySize::Bit192,
95            EncryptKey::Aes256(_) => KeySize::Bit256,
96        }
97    }
98
99    pub fn value(&self) -> &[u8] {
100        match self {
101            EncryptKey::Aes128(a) => a,
102            EncryptKey::Aes192(a) => a,
103            EncryptKey::Aes256(a) => a,
104        }
105    }
106
107    #[cfg(feature = "enable_openssl")]
108    pub fn cipher(&self) -> Cipher {
109        match self.size() {
110            KeySize::Bit128 => Cipher::aes_128_ctr(),
111            KeySize::Bit192 => Cipher::aes_192_ctr(),
112            KeySize::Bit256 => Cipher::aes_256_ctr(),
113        }
114    }
115
116    #[cfg(feature = "enable_openssl")]
117    pub fn encrypt_with_iv(&self, iv: &InitializationVector, data: &[u8]) -> Vec<u8> {
118        let mut iv_store;
119        let iv = match iv.bytes.len() {
120            16 => iv,
121            _ => {
122                iv_store = InitializationVector {
123                    bytes: iv.bytes.clone().into_iter().take(16).collect::<Vec<_>>(),
124                };
125                while iv_store.bytes.len() < 16 {
126                    iv_store.bytes.push(0u8);
127                }
128                &iv_store
129            }
130        };
131        openssl::symm::encrypt(self.cipher(), self.value(), Some(&iv.bytes[..]), data).unwrap()
132    }
133
134    #[cfg(not(feature = "enable_openssl"))]
135    pub fn encrypt_with_iv(&self, iv: &InitializationVector, data: &[u8]) -> Vec<u8> {
136        let mut iv_store;
137        let iv = match iv.bytes.len() {
138            16 => iv,
139            _ => {
140                iv_store = InitializationVector {
141                    bytes: iv.bytes.clone().into_iter().take(16).collect::<Vec<_>>(),
142                };
143                while iv_store.bytes.len() < 16 {
144                    iv_store.bytes.push(0u8);
145                }
146                &iv_store
147            }
148        };
149
150        let mut data = data.to_vec();
151
152        match self.size() {
153            KeySize::Bit128 => {
154                let mut cipher = Aes128Ctr::new(self.value().into(), (&iv.bytes[..]).into());
155                cipher.apply_keystream(data.as_mut_slice());
156            }
157            KeySize::Bit192 => {
158                let mut cipher = Aes192Ctr::new(self.value().into(), (&iv.bytes[..]).into());
159                cipher.apply_keystream(data.as_mut_slice());
160            }
161            KeySize::Bit256 => {
162                let mut cipher = Aes256Ctr::new(self.value().into(), (&iv.bytes[..]).into());
163                cipher.apply_keystream(data.as_mut_slice());
164            }
165        }
166
167        data
168    }
169
170    #[cfg(not(feature = "enable_openssl"))]
171    pub fn encrypt_with_hash_iv(&self, hash: &AteHash, data: &[u8]) -> Vec<u8> {
172        let iv: &[u8; 16] = hash.as_bytes();
173        
174        let mut data = data.to_vec();
175        match self.size() {
176            KeySize::Bit128 => {
177                let mut cipher = Aes128Ctr::new(self.value().into(), iv.into());
178                cipher.apply_keystream(data.as_mut_slice());
179            }
180            KeySize::Bit192 => {
181                let mut cipher = Aes192Ctr::new(self.value().into(), iv.into());
182                cipher.apply_keystream(data.as_mut_slice());
183            }
184            KeySize::Bit256 => {
185                let mut cipher = Aes256Ctr::new(self.value().into(), iv.into());
186                cipher.apply_keystream(data.as_mut_slice());
187            }
188        }
189
190        data
191    }
192
193    #[cfg(not(feature = "enable_openssl"))]
194    pub fn encrypt_with_hash_iv_with_capacity(&self, hash: &AteHash, data: &[u8], capacity: usize) -> Vec<u8> {
195        let iv: &[u8; 16] = hash.as_bytes();
196        
197        let mut ret: Vec<u8> = Vec::with_capacity(capacity);
198        ret.extend_from_slice(hash.as_bytes());
199        let s = ret.len();
200        ret.extend_from_slice(data);
201
202        let data = &mut ret[s..];
203        match self.size() {
204            KeySize::Bit128 => {
205                let mut cipher = Aes128Ctr::new(self.value().into(), iv.into());
206                cipher.apply_keystream(data);
207            }
208            KeySize::Bit192 => {
209                let mut cipher = Aes192Ctr::new(self.value().into(), iv.into());
210                cipher.apply_keystream(data);
211            }
212            KeySize::Bit256 => {
213                let mut cipher = Aes256Ctr::new(self.value().into(), iv.into());
214                cipher.apply_keystream(data);
215            }
216        }
217        ret
218    }
219
220    #[cfg(not(feature = "enable_openssl"))]
221    pub fn encrypt_with_hash_iv_with_capacity_and_prefix(&self, hash: &AteHash, data: &[u8], capacity: usize, prefix: &[u8]) -> Vec<u8> {
222        let iv: &[u8; 16] = hash.as_bytes();
223
224        let mut ret: Vec<u8> = Vec::with_capacity(capacity);
225        ret.extend_from_slice(prefix);
226        ret.extend_from_slice(hash.as_bytes());
227        let s = ret.len();
228        ret.extend_from_slice(data);
229        
230        let data = &mut ret[s..];
231        match self.size() {
232            KeySize::Bit128 => {
233                let mut cipher = Aes128Ctr::new(self.value().into(), iv.into());
234                cipher.apply_keystream(data);
235            }
236            KeySize::Bit192 => {
237                let mut cipher = Aes192Ctr::new(self.value().into(), iv.into());
238                cipher.apply_keystream(data);
239            }
240            KeySize::Bit256 => {
241                let mut cipher = Aes256Ctr::new(self.value().into(), iv.into());
242                cipher.apply_keystream(data);
243            }
244        }
245        ret
246    }
247
248    pub fn encrypt(&self, data: &[u8]) -> EncryptResult {
249        let iv = InitializationVector::generate();
250        let data = self.encrypt_with_iv(&iv, data);
251        EncryptResult { iv: iv, data: data }
252    }
253
254    #[cfg(feature = "enable_openssl")]
255    pub fn decrypt(&self, iv: &InitializationVector, data: &[u8]) -> Vec<u8> {
256        let mut iv_store;
257        let iv = match iv.bytes.len() {
258            16 => iv,
259            _ => {
260                iv_store = InitializationVector {
261                    bytes: iv.bytes.clone().into_iter().take(16).collect::<Vec<_>>(),
262                };
263                while iv_store.bytes.len() < 16 {
264                    iv_store.bytes.push(0u8);
265                }
266                &iv_store
267            }
268        };
269        openssl::symm::decrypt(self.cipher(), self.value(), Some(&iv.bytes[..]), data).unwrap()
270    }
271
272    #[cfg(not(feature = "enable_openssl"))]
273    pub fn decrypt(&self, iv: &InitializationVector, data: &[u8]) -> Vec<u8> {
274        let mut iv_store;
275        let iv = match iv.bytes.len() {
276            16 => iv,
277            _ => {
278                iv_store = InitializationVector {
279                    bytes: iv.bytes.clone().into_iter().take(16).collect::<Vec<_>>(),
280                };
281                while iv_store.bytes.len() < 16 {
282                    iv_store.bytes.push(0u8);
283                }
284                &iv_store
285            }
286        };
287
288        let mut data = data.to_vec();
289
290        match self.size() {
291            KeySize::Bit128 => {
292                let mut cipher = Aes128Ctr::new(self.value().into(), (&iv.bytes[..]).into());
293                cipher.apply_keystream(data.as_mut_slice());
294            }
295            KeySize::Bit192 => {
296                let mut cipher = Aes192Ctr::new(self.value().into(), (&iv.bytes[..]).into());
297                cipher.apply_keystream(data.as_mut_slice());
298            }
299            KeySize::Bit256 => {
300                let mut cipher = Aes256Ctr::new(self.value().into(), (&iv.bytes[..]).into());
301                cipher.apply_keystream(data.as_mut_slice());
302            }
303        }
304
305        data
306    }
307
308    #[cfg(not(feature = "enable_openssl"))]
309    pub fn decrypt_with_hash_iv(&self, hash: &AteHash, data: &[u8]) -> Vec<u8> {
310        let iv: &[u8; 16] = hash.as_bytes();
311
312        let mut data = data.to_vec();
313
314        match self.size() {
315            KeySize::Bit128 => {
316                let mut cipher = Aes128Ctr::new(self.value().into(), iv.into());
317                cipher.apply_keystream(data.as_mut_slice());
318            }
319            KeySize::Bit192 => {
320                let mut cipher = Aes192Ctr::new(self.value().into(), iv.into());
321                cipher.apply_keystream(data.as_mut_slice());
322            }
323            KeySize::Bit256 => {
324                let mut cipher = Aes256Ctr::new(self.value().into(), iv.into());
325                cipher.apply_keystream(data.as_mut_slice());
326            }
327        }
328
329        data
330    }
331
332    #[allow(dead_code)]
333    pub fn as_bytes(&self) -> Vec<u8> {
334        Vec::from(self.value())
335    }
336
337    #[allow(dead_code)]
338    pub fn from_bytes(bytes: &[u8]) -> Result<EncryptKey, std::io::Error> {
339        let bytes: Vec<u8> = Vec::from(bytes);
340        match bytes.len() {
341            16 => {
342                Ok(EncryptKey::Aes128(bytes.try_into().expect(
343                    "Internal error while deserializing the Encryption Key",
344                )))
345            }
346            24 => {
347                Ok(EncryptKey::Aes192(bytes.try_into().expect(
348                    "Internal error while deserializing the Encryption Key",
349                )))
350            }
351            32 => {
352                Ok(EncryptKey::Aes256(bytes.try_into().expect(
353                    "Internal error while deserializing the Encryption Key",
354                )))
355            }
356            _ => Result::Err(std::io::Error::new(
357                ErrorKind::Other,
358                format!(
359                    "The encryption key bytes are the incorrect length ({}).",
360                    bytes.len()
361                ),
362            )),
363        }
364    }
365
366    pub fn hash(&self) -> AteHash {
367        match &self {
368            EncryptKey::Aes128(a) => AteHash::from_bytes(a),
369            EncryptKey::Aes192(a) => AteHash::from_bytes(a),
370            EncryptKey::Aes256(a) => AteHash::from_bytes(a),
371        }
372    }
373
374    pub fn short_hash(&self) -> ShortHash {
375        match &self {
376            EncryptKey::Aes128(a) => ShortHash::from_bytes(a),
377            EncryptKey::Aes192(a) => ShortHash::from_bytes(a),
378            EncryptKey::Aes256(a) => ShortHash::from_bytes(a),
379        }
380    }
381
382    pub fn from_seed_string(str: String, size: KeySize) -> EncryptKey {
383        EncryptKey::from_seed_bytes(str.as_bytes(), size)
384    }
385
386    pub fn from_seed_bytes(seed_bytes: &[u8], size: KeySize) -> EncryptKey {
387        let mut hasher = sha3::Keccak384::new();
388        hasher.update(seed_bytes);
389        let result = hasher.finalize();
390
391        match size {
392            KeySize::Bit128 => {
393                let aes_key: [u8; 16] = result
394                    .into_iter()
395                    .take(16)
396                    .collect::<Vec<_>>()
397                    .try_into()
398                    .unwrap();
399                EncryptKey::Aes128(aes_key)
400            }
401            KeySize::Bit192 => {
402                let aes_key: [u8; 24] = result
403                    .into_iter()
404                    .take(24)
405                    .collect::<Vec<_>>()
406                    .try_into()
407                    .unwrap();
408                EncryptKey::Aes192(aes_key)
409            }
410            KeySize::Bit256 => {
411                let aes_key: [u8; 32] = result
412                    .into_iter()
413                    .take(32)
414                    .collect::<Vec<_>>()
415                    .try_into()
416                    .unwrap();
417                EncryptKey::Aes256(aes_key)
418            }
419        }
420    }
421
422    pub fn xor(ek1: &EncryptKey, ek2: &EncryptKey) -> EncryptKey {
423        let mut ek1_bytes = ek1.as_bytes();
424        let ek2_bytes = ek2.as_bytes();
425
426        ek1_bytes
427            .iter_mut()
428            .zip(ek2_bytes.iter())
429            .for_each(|(x1, x2)| *x1 ^= *x2);
430
431        EncryptKey::from_bytes(&ek1_bytes[..])
432            .expect("Internal error while attempting to XOR encryption keys")
433    }
434}
435
436impl std::fmt::Display for EncryptKey {
437    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
438        match self {
439            EncryptKey::Aes128(a) => write!(f, "aes-128:{}", hex::encode(a)),
440            EncryptKey::Aes192(a) => write!(f, "aes-192:{}", hex::encode(a)),
441            EncryptKey::Aes256(a) => write!(f, "aes-256:{}", hex::encode(a)),
442        }
443    }
444}
445
446#[derive(Serialize, Deserialize, Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
447pub struct EncryptResult {
448    pub iv: InitializationVector,
449    #[serde(serialize_with = "vec_serialize", deserialize_with = "vec_deserialize")]
450    pub data: Vec<u8>,
451}