deadbolt_crypto/
encryption.rs1use std::error::Error;
2
3use aes_gcm::{
4 aead::{generic_array::GenericArray, Aead, KeyInit},
5 aes::cipher::ArrayLength,
6 Aes256Gcm, Nonce,
7};
8
9use chacha20::ChaCha8;
10use chacha20::{
11 cipher::{KeyIvInit, StreamCipher, StreamCipherSeek},
12 ChaCha20,
13};
14
15use chacha20poly1305::ChaCha20Poly1305;
16use rand::Rng;
17use secrecy::{ExposeSecret, SecretVec};
18pub struct Encryption {
19 aes_cipher: Aes256Gcm,
20 chacha_cipher: ChaCha20Poly1305,
21}
22
23pub struct EncryptionPayload {
24 pub data: Vec<u8>,
25 pub nonce: [u8; 12],
26}
27
28impl Encryption {
29 pub fn new(master_key: &SecretVec<u8>) -> Encryption {
30 Encryption {
31 aes_cipher: Aes256Gcm::new(GenericArray::from_slice(master_key.expose_secret())),
32 chacha_cipher: ChaCha20Poly1305::new(GenericArray::from_slice(
33 master_key.expose_secret(),
34 )),
35 }
36 }
37
38 pub fn encrypt(
39 &mut self,
40 plaintext: Vec<u8>,
41 algorithm: u8,
42 ) -> Result<EncryptionPayload, Box<dyn Error>> {
43 let mut nonce: [u8; 12] = [0; 12];
44 let mut rng = rand::thread_rng();
45 rng.fill(&mut nonce);
46
47 match algorithm {
48 1 => {
49 let encryption_result = self
50 .aes_cipher
51 .encrypt(GenericArray::from_slice(&nonce), plaintext.as_ref());
52
53 match encryption_result {
54 Ok(ciphertext) => Ok(EncryptionPayload {
55 data: ciphertext,
56 nonce,
57 }),
58 Err(e) => Err(e.to_string().into()),
59 }
60 }
61 2 => {
62 let encryption_result = self
63 .chacha_cipher
64 .encrypt(GenericArray::from_slice(&nonce), plaintext.as_ref());
65
66 match encryption_result {
67 Ok(ciphertext) => Ok(EncryptionPayload {
68 data: ciphertext,
69 nonce,
70 }),
71 Err(e) => Err(e.to_string().into()),
72 }
73 }
74 _ => Err("Unknown algorithm".to_string().into()),
75 }
76 }
77
78 pub fn decrypt(
79 &mut self,
80 nonce: [u8; 12],
81 ciphertext: Vec<u8>,
82 algorithm: u8,
83 ) -> Result<EncryptionPayload, Box<dyn Error>> {
84 match algorithm {
85 1 => {
86 let decryption_result = self.aes_cipher.decrypt(
87 GenericArray::from_slice(nonce.as_ref()),
88 ciphertext.as_ref(),
89 );
90
91 match decryption_result {
92 Ok(plaintext) => Ok(EncryptionPayload {
93 data: plaintext,
94 nonce,
95 }),
96 Err(e) => Err(e.to_string().into()),
97 }
98 }
99 2 => {
100 let decryption_result = self.chacha_cipher.decrypt(
101 GenericArray::from_slice(nonce.as_ref()),
102 ciphertext.as_ref(),
103 );
104
105 match decryption_result {
106 Ok(plaintext) => Ok(EncryptionPayload {
107 data: plaintext,
108 nonce,
109 }),
110 Err(e) => Err(e.to_string().into()),
111 }
112 }
113 _ => Err("Unknown algorithm".to_string().into()),
114 }
115 }
116}
117
118pub struct StreamEncryption {}
119
120impl StreamEncryption {
121 pub fn encrypt(child_key: &SecretVec<u8>, plaintext: &[u8]) -> Vec<u8> {
122 let mut nonce: [u8; 12] = [0; 12];
123 let mut rng = rand::thread_rng();
124 rng.fill(&mut nonce);
125
126 let key = GenericArray::from_slice(child_key.expose_secret());
127
128 let mut cipher = ChaCha8::new(key, &nonce.into());
129 let mut buffer = plaintext.to_owned();
130
131 cipher.apply_keystream(&mut buffer);
132
133 let mut ciphertext: Vec<u8> = nonce.to_vec();
134 ciphertext.extend(buffer);
135
136 ciphertext
137 }
138
139 pub fn decrypt(child_key: &SecretVec<u8>, ciphertext: &[u8]) -> Vec<u8> {
140 let key = GenericArray::from_slice(child_key.expose_secret());
141
142 let mut cipher = ChaCha8::new(key, ciphertext[..12].try_into().unwrap());
143 let mut buffer = ciphertext[12..].to_vec();
144
145 cipher.apply_keystream(&mut buffer);
146
147 buffer
148 }
149}