zff/
encryption.rs

1// - STD
2use std::borrow::Borrow;
3
4// - internal
5use crate::version1::{
6	Result,
7};
8
9// - external
10use pkcs5::{
11	EncryptionScheme,
12	pbes2::Parameters as PBES2Parameters,
13};
14use scrypt::Params as ScryptParams;
15use aes_gcm_siv::{
16	Aes256GcmSiv, Aes128GcmSiv, Nonce, Key,
17	aead::{Aead, NewAead},
18};
19use byteorder::{LittleEndian, WriteBytesExt};
20use rand::{rngs::OsRng, RngCore};
21
22/// Defines all encryption algorithms (for use in data and header encryption), which are implemented in zff.
23#[repr(u8)]
24#[non_exhaustive]
25#[derive(Debug,Clone,Eq,PartialEq)]
26pub enum EncryptionAlgorithm {
27	/// AES (128-Bit) in Galois/Counter Mode operation with misuse resistance in the event of the reuse of a cryptographic nonce.\
28	/// Encoded with value 0.
29	AES128GCMSIV = 0,
30	/// AES (256-Bit) in Galois/Counter Mode operation with misuse resistance in the event of the reuse of a cryptographic nonce.\
31	/// Encoded with value 1.
32	AES256GCMSIV = 1,
33}
34
35/// Defines all KDF schemes, which are implemented in zff.
36#[repr(u8)]
37#[non_exhaustive]
38#[derive(Debug,Clone,Eq,PartialEq)]
39pub enum KDFScheme {
40	/// KDF scheme PBKDF2-SHA256, with encoding value 0.
41	PBKDF2SHA256 = 0,
42	/// KDF scheme scrypt, with encoding value 1.
43	Scrypt = 1,
44}
45
46/// Defines all encryption algorithms (for use in PBE only!), which are implemented in zff.
47#[repr(u8)]
48#[non_exhaustive]
49#[derive(Debug,Clone,Eq,PartialEq)]
50pub enum PBEScheme {
51	/// AES128-CBC encryption scheme used in pbe with the encoding value 0.
52	AES128CBC = 0,
53	/// AES128-CBC encryption scheme used in pbe with the encoding value 1.
54	AES256CBC = 1,
55}
56
57/// structure contains serveral methods to handle encryption
58pub struct Encryption;
59
60impl Encryption {
61	/// encrypts the given plaintext with the given values with PBKDF2-SHA256-AES128CBC, defined in PKCS#5.
62	/// Returns the ciphertext as ```Vec<u8>```.
63	/// # Error
64	/// if the encryption fails, or the given parameters are false.
65	pub fn encrypt_pbkdf2sha256_aes128cbc(
66		iterations: u32,
67		salt: &[u8; 32],
68		aes_iv: &[u8; 16],
69		password: impl AsRef<[u8]>,
70		plaintext: &[u8]) -> Result<Vec<u8>> {
71		let params = PBES2Parameters::pbkdf2_sha256_aes128cbc(iterations, salt, aes_iv)?;
72		let encryption_scheme = EncryptionScheme::Pbes2(params);
73		Ok(encryption_scheme.encrypt(password, plaintext)?)
74	}
75
76	// encrypts the given plaintext with the given values with PBKDF2-SHA256-AES256CBC, defined in PKCS#5.
77	/// Returns the ciphertext as ```Vec<u8>```.
78	/// # Error
79	/// if the encryption fails, or the given parameters are false.
80	pub fn encrypt_pbkdf2sha256_aes256cbc(
81		iterations: u32,
82		salt: &[u8; 32],
83		aes_iv: &[u8; 16],
84		password: impl AsRef<[u8]>,
85		plaintext: &[u8]) -> Result<Vec<u8>> {
86		let params = PBES2Parameters::pbkdf2_sha256_aes256cbc(iterations, salt, aes_iv)?;
87		let encryption_scheme = EncryptionScheme::Pbes2(params);
88		let cipher = encryption_scheme.encrypt(password, plaintext)?;
89		Ok(cipher)
90	}
91
92	/// decrypts the given ciphertext from the given values with PBKDF2-SHA256-AES128CBC, defined in PKCS#5.
93	/// Returns the plaintext as ```Vec<u8>```.
94	/// # Error
95	/// if the decryption fails, or the given parameters are false.
96	pub fn decrypt_pbkdf2sha256_aes128cbc(
97		iterations: u32,
98		salt: &[u8; 32],
99		aes_iv: &[u8; 16],
100		password: impl AsRef<[u8]>,
101		ciphertext: &[u8]) -> Result<Vec<u8>> {
102		let params = PBES2Parameters::pbkdf2_sha256_aes128cbc(iterations, salt, aes_iv)?;
103		let encryption_scheme = EncryptionScheme::Pbes2(params);
104		Ok(encryption_scheme.decrypt(password, ciphertext)?)
105	}
106
107	/// decrypts the given ciphertext from the given values with PBKDF2-SHA256-AES256CBC, defined in PKCS#5.
108	/// Returns the plaintext as ```Vec<u8>```.
109	/// # Error
110	/// if the decryption fails, or the given parameters are false.
111	pub fn decrypt_pbkdf2sha256_aes256cbc(
112		iterations: u32,
113		salt: &[u8; 32],
114		aes_iv: &[u8; 16],
115		password: impl AsRef<[u8]>,
116		ciphertext: &[u8]) -> Result<Vec<u8>> {
117		let params = PBES2Parameters::pbkdf2_sha256_aes256cbc(iterations, salt, aes_iv)?;
118		let encryption_scheme = EncryptionScheme::Pbes2(params);
119		Ok(encryption_scheme.decrypt(password, ciphertext)?)
120	}
121
122	/// encrypts the given plaintext with the given values with Scrypt-AES128CBC.
123	/// Returns the ciphertext as ```Vec<u8>```.
124	/// # Error
125	/// if the encryption fails, or the given parameters are false.
126	pub fn encrypt_scrypt_aes128cbc(
127		logn: u8,
128		r: u32,
129		p: u32,
130		salt: &[u8; 32],
131		aes_iv: &[u8; 16],
132		password: impl AsRef<[u8]>,
133		plaintext: &[u8]) -> Result<Vec<u8>> {
134		let params = PBES2Parameters::scrypt_aes128cbc(ScryptParams::new(logn, r, p)?, salt, aes_iv)?;
135		let encryption_scheme = EncryptionScheme::Pbes2(params);
136		Ok(encryption_scheme.encrypt(password, plaintext)?)
137	}
138
139	/// encrypts the given plaintext with the given values with Scrypt-AES256CBC.
140	/// Returns the ciphertext as ```Vec<u8>```.
141	/// # Error
142	/// if the encryption fails, or the given parameters are false.
143	pub fn encrypt_scrypt_aes256cbc(
144		logn: u8,
145		r: u32,
146		p: u32,
147		salt: &[u8; 32],
148		aes_iv: &[u8; 16],
149		password: impl AsRef<[u8]>,
150		plaintext: &[u8]) -> Result<Vec<u8>> {
151		let params = PBES2Parameters::scrypt_aes256cbc(ScryptParams::new(logn, r, p)?, salt, aes_iv)?;
152		let encryption_scheme = EncryptionScheme::Pbes2(params);
153		Ok(encryption_scheme.encrypt(password, plaintext)?)
154	}
155
156	/// decrypts the given ciphertext with the given values with Scrypt-AES128CBC.
157	/// Returns the plaintext as ```Vec<u8>```.
158	/// # Error
159	/// if the encryption fails, or the given parameters are false.
160	pub fn decrypt_scrypt_aes128cbc(
161		logn: u8,
162		r: u32,
163		p: u32,
164		salt: &[u8; 32],
165		aes_iv: &[u8; 16],
166		password: impl AsRef<[u8]>,
167		plaintext: &[u8]) -> Result<Vec<u8>> {
168		let params = PBES2Parameters::scrypt_aes128cbc(ScryptParams::new(logn, r, p)?, salt, aes_iv)?;
169		let encryption_scheme = EncryptionScheme::Pbes2(params);
170		Ok(encryption_scheme.decrypt(password, plaintext)?)
171	}
172
173	/// decrypts the given ciphertext with the given values with Scrypt-AES256CBC.
174	/// Returns the plaintext as ```Vec<u8>```.
175	/// # Error
176	/// if the encryption fails, or the given parameters are false.
177	pub fn decrypt_scrypt_aes256cbc(
178		logn: u8,
179		r: u32,
180		p: u32,
181		salt: &[u8; 32],
182		aes_iv: &[u8; 16],
183		password: impl AsRef<[u8]>,
184		plaintext: &[u8]) -> Result<Vec<u8>> {
185		let params = PBES2Parameters::scrypt_aes256cbc(ScryptParams::new(logn, r, p)?, salt, aes_iv)?;
186		let encryption_scheme = EncryptionScheme::Pbes2(params);
187		Ok(encryption_scheme.decrypt(password, plaintext)?)
188	}
189
190	/// method to encrypt a message with a key and and the given chunk number. This method should primary used to encrypt
191	/// the given chunk data (if selected, then **after the compression**).
192	/// Returns a the cipthertext as ```Vec<u8>```.
193	/// # Example
194	/// ```
195	/// use zff::*;
196	/// use hex::ToHex;
197	///
198	/// fn main() -> Result<()> {
199	///        let key = "01234567890123456789012345678912"; // 32Byte/256Bit Key
200	///        let chunk_no = 1; // 12Byte/96Bit Key
201	///        let message = "My message";
202	/// 
203	///        let ciphertext = Encryption::encrypt_message(key, message, chunk_no, EncryptionAlgorithm::AES256GCMSIV)?;
204	/// 
205	///        assert_eq!(ciphertext.encode_hex::<String>(), "32f1c2f8ff6594a07eda5a4eca6d198f4cda8935f171d2345888".to_string());
206	///        Ok(())
207	/// }
208	/// ```
209	/// # Error
210	/// This method will fail, if the encryption fails.
211	pub fn encrypt_message<K, M, A>(key: K, message: M, chunk_no: u64, algorithm: A) -> Result<Vec<u8>>
212	where
213		K: AsRef<[u8]>,
214		M: AsRef<[u8]>,
215		A: Borrow<EncryptionAlgorithm>,
216	{
217		let nonce = Encryption::chunk_as_crypto_nonce(chunk_no)?;
218		match algorithm.borrow() {
219			EncryptionAlgorithm::AES256GCMSIV => {
220				let cipher = Aes256GcmSiv::new(Key::from_slice(key.as_ref()));
221				Ok(cipher.encrypt(&nonce, message.as_ref())?)
222			},
223			EncryptionAlgorithm::AES128GCMSIV => {
224				let cipher = Aes128GcmSiv::new(Key::from_slice(key.as_ref()));
225				Ok(cipher.encrypt(&nonce, message.as_ref())?)
226			},
227		}
228	}
229
230	/// method to decrypt a message with a key and and the given chunk number. This method should primary used to decrypt
231	/// the given chunk data (if selected, then **before the decompression**).
232	/// Returns a the plaintext as ```Vec<u8>``` of the given ciphertext.
233	/// # Error
234	/// This method will fail, if the decryption fails.
235	pub fn decrypt_message<K, M, A>(key: K, message: M, chunk_no: u64, algorithm: A) -> Result<Vec<u8>>
236	where
237		K: AsRef<[u8]>,
238		M: AsRef<[u8]>,
239		A: Borrow<EncryptionAlgorithm>,
240	{
241		let nonce = Encryption::chunk_as_crypto_nonce(chunk_no)?;
242		match algorithm.borrow() {
243			EncryptionAlgorithm::AES256GCMSIV => {
244				let cipher = Aes256GcmSiv::new(Key::from_slice(key.as_ref()));
245				Ok(cipher.decrypt(&nonce, message.as_ref())?)
246			},
247			EncryptionAlgorithm::AES128GCMSIV => {
248				let cipher = Aes128GcmSiv::new(Key::from_slice(key.as_ref()));
249				Ok(cipher.decrypt(&nonce, message.as_ref())?)
250			},
251		}
252	}
253
254	/// encrypts the given header with the given nonce.
255	/// This method should primary used to encrypt the given header.
256	/// Returns a the cipthertext as ```Vec<u8>```.
257	/// # Error
258	/// This method will fail, if the encryption fails.
259	pub(crate) fn encrypt_header<K, M, A>(key: K, message: M, nonce: &[u8; 12], algorithm: A) -> Result<Vec<u8>>
260	where
261		K: AsRef<[u8]>,
262		M: AsRef<[u8]>,
263		A: Borrow<EncryptionAlgorithm>,
264	{
265		let nonce = Nonce::from_slice(nonce);
266		match algorithm.borrow() {
267			EncryptionAlgorithm::AES256GCMSIV => {
268				let cipher = Aes256GcmSiv::new(Key::from_slice(key.as_ref()));
269				Ok(cipher.encrypt(nonce, message.as_ref())?)
270			},
271			EncryptionAlgorithm::AES128GCMSIV => {
272				let cipher = Aes128GcmSiv::new(Key::from_slice(key.as_ref()));
273				Ok(cipher.encrypt(nonce, message.as_ref())?)
274			},
275		}
276	}
277
278	/// decrypts the given header with the given nonce and encryption key.
279	/// This method should primary used to decrypt the given header.
280	/// Returns a the plaintext as ```Vec<u8>```.
281	pub(crate) fn decrypt_header<K, C, A>(key: K, ciphertext: C, nonce: &[u8; 12], algorithm: A) -> Result<Vec<u8>>
282	where
283		K: AsRef<[u8]>,
284		C: AsRef<[u8]>,
285		A: Borrow<EncryptionAlgorithm>,
286	{
287		let nonce = Nonce::from_slice(nonce);
288		match *algorithm.borrow() {
289			EncryptionAlgorithm::AES256GCMSIV => {
290				let cipher = Aes256GcmSiv::new(Key::from_slice(key.as_ref()));
291				Ok(cipher.decrypt(nonce, ciphertext.as_ref())?)
292			},
293			EncryptionAlgorithm::AES128GCMSIV => {
294				let cipher = Aes128GcmSiv::new(Key::from_slice(key.as_ref()));
295				Ok(cipher.decrypt(nonce, ciphertext.as_ref())?)
296			},
297		}
298	}
299
300	/// Generates a new random key, with the given key size.
301	/// # Example
302	/// ```no_run
303	/// use zff::*;
304	/// 
305	/// let keysize = 256; //(e.g. for use as 256-Bit-AES-Key).
306	/// let my_new_random_super_secret_key = Encryption::gen_random_key(keysize);
307	/// //...
308	/// ```
309	pub fn gen_random_key(length: usize) -> Vec<u8> {
310		let mut key = vec!(0u8; length/8);
311		let mut rng = OsRng;
312		rng.fill_bytes(&mut key);
313		key
314	}
315
316	/// Generates a new random IV/Nonce as ```[u8; 16]``` for use in PBE header.
317	pub fn gen_random_iv() -> [u8; 16] {
318		let mut iv = [0; 16];
319		let mut rng = OsRng;
320		rng.fill_bytes(&mut iv);
321		iv
322	}
323
324	/// Generates a new random salt as ```[u8; 32]``` for use in PBE header.
325	pub fn gen_random_salt() -> [u8; 32] {
326		let mut salt = [0; 32];
327		let mut rng = OsRng;
328		rng.fill_bytes(&mut salt);
329		salt
330	}
331
332	/// Generates a new random IV/Nonce as ```[u8; 12]``` for use in encryption header.
333	pub fn gen_random_header_nonce() -> [u8; 12] {
334		let mut nonce = [0; 12];
335		let mut rng = OsRng;
336		rng.fill_bytes(&mut nonce);
337		nonce
338	}
339
340	fn chunk_as_crypto_nonce(chunk_no: u64) -> Result<Nonce> {
341		let mut buffer = vec![];
342		buffer.write_u64::<LittleEndian>(chunk_no)?;
343		buffer.append(&mut vec!(0u8; 4));
344		Ok(*Nonce::from_slice(&buffer))
345	}
346}