zff/header/version2/
pbe_header.rs

1// STD
2use std::io::{Read,Cursor};
3
4// - internal
5use crate::{
6	Result,
7	HeaderCoding,
8	ValueEncoder,
9	ValueDecoder,
10	KDFScheme,
11	PBEScheme,
12	ZffError,
13	ZffErrorKind,
14};
15
16use crate::{
17	HEADER_IDENTIFIER_PBE_HEADER,
18	PBE_KDF_PARAMETERS_PBKDF2,
19	PBE_KDF_PARAMETERS_SCRYPT,
20	ERROR_HEADER_DECODER_MISMATCH_IDENTIFIER_KDF,
21	ERROR_HEADER_DECODER_UNKNOWN_PBE_SCHEME,
22	ERROR_HEADER_DECODER_UNKNOWN_KDF_SCHEME,
23};
24
25// - external
26use byteorder::{BigEndian, ReadBytesExt};
27
28/// The pbe header contains all informations for the encryption of the encryption key.\
29/// The encryption key, used for the chunk encryption, can be found at the [EncryptionHeader](struct.EncryptionHeader.html) -
30/// encrypted with an user password.\
31/// This encryption of the encryption key is done via a password-based encryption (PBE).\
32/// All metadata about this PBE can be found in this PBEHeader.\
33#[derive(Debug,Clone,PartialEq,Eq)]
34pub struct PBEHeader {
35	version: u8,
36	kdf_scheme: KDFScheme,
37	encryption_scheme: PBEScheme,
38	kdf_parameters: KDFParameters,
39	pbencryption_nonce: [u8; 16],
40}
41
42impl PBEHeader {
43	/// returns a new pbe header with the given values.
44	pub fn new(
45		version: u8,
46		kdf_scheme: KDFScheme,
47		encryption_scheme: PBEScheme,
48		kdf_parameters: KDFParameters,
49		pbencryption_nonce: [u8; 16],
50		) -> PBEHeader {
51		Self {
52			version,
53			kdf_scheme,
54			encryption_scheme,
55			kdf_parameters,
56			pbencryption_nonce,
57		}
58	}
59
60	/// returns the kdf scheme.
61	pub fn kdf_scheme(&self) -> &KDFScheme {
62		&self.kdf_scheme
63	}
64
65	/// returns the encryption scheme.
66	pub fn encryption_scheme(&self) -> &PBEScheme {
67		&self.encryption_scheme
68	}
69
70	/// returns the kdf parameters.
71	pub fn kdf_parameters(&self) -> &KDFParameters {
72		&self.kdf_parameters
73	}
74
75	/// returns the pbe nonce.
76	pub fn nonce(&self) -> &[u8; 16] {
77		&self.pbencryption_nonce
78	}
79}
80
81impl HeaderCoding for PBEHeader {
82	type Item = PBEHeader;
83
84	fn identifier() -> u32 {
85		HEADER_IDENTIFIER_PBE_HEADER
86	}
87
88	fn version(&self) -> u8 {
89		self.version
90	}
91
92	fn encode_header(&self) -> Vec<u8> {
93		let mut vec = vec![self.version, self.kdf_scheme.clone() as u8, self.encryption_scheme.clone() as u8];
94		vec.append(&mut self.kdf_parameters.encode_directly());
95		vec.append(&mut self.pbencryption_nonce.encode_directly());
96		vec
97	}
98
99	fn decode_content(data: Vec<u8>) -> Result<PBEHeader> {
100		let mut cursor = Cursor::new(data);
101		let header_version = u8::decode_directly(&mut cursor)?;
102		let kdf_scheme = match u8::decode_directly(&mut cursor)? {
103			0 => KDFScheme::PBKDF2SHA256,
104			1 => KDFScheme::Scrypt,
105			_ => return Err(ZffError::new_header_decode_error(ERROR_HEADER_DECODER_UNKNOWN_KDF_SCHEME))
106		};
107		let encryption_scheme = match u8::decode_directly(&mut cursor)? {
108			0 => PBEScheme::AES128CBC,
109			1 => PBEScheme::AES256CBC,
110			_ => return Err(ZffError::new_header_decode_error(ERROR_HEADER_DECODER_UNKNOWN_PBE_SCHEME)),
111		};
112		let kdf_params = KDFParameters::decode_directly(&mut cursor)?;
113		let mut encryption_nonce = [0; 16];
114		cursor.read_exact(&mut encryption_nonce)?;
115		Ok(PBEHeader::new(header_version, kdf_scheme, encryption_scheme, kdf_params, encryption_nonce))
116	}
117}
118
119/// enum to handle the stored parameters for the appropriate key deriavation function (KDF).
120#[repr(u8)]
121#[non_exhaustive]
122#[derive(Debug,Clone,Eq,PartialEq)]
123pub enum KDFParameters {
124	/// stores a struct [PBKDF2SHA256Parameters].
125	PBKDF2SHA256Parameters(PBKDF2SHA256Parameters),
126	/// stores a struct [ScryptParameters].
127	ScryptParameters(ScryptParameters)
128}
129
130impl ValueEncoder for KDFParameters {
131	fn encode_directly(&self) -> Vec<u8> {
132		match self {
133			KDFParameters::PBKDF2SHA256Parameters(params) => params.encode_directly(),
134			KDFParameters::ScryptParameters(params) => params.encode_directly(),
135		}
136	}
137	fn encode_for_key<K: Into<String>>(&self, key: K) -> Vec<u8> {
138		let mut vec = Vec::new();
139		let mut encoded_key = Self::encode_key(key);
140		vec.append(&mut encoded_key);
141		vec.append(&mut self.encode_directly());
142		vec
143	}
144}
145
146impl ValueDecoder for KDFParameters {
147	type Item = KDFParameters;
148
149	fn decode_directly<R: Read>(data: &mut R) -> Result<KDFParameters> {
150		let identifier = data.read_u32::<BigEndian>()?;
151		let size = u64::decode_directly(data)?;
152		let mut params = vec![0u8; (size-12) as usize];
153		data.read_exact(&mut params)?;
154		
155		let mut params_cursor = Cursor::new(params);
156
157		if identifier == PBKDF2SHA256Parameters::identifier() {
158			let iterations = u32::decode_directly(&mut params_cursor)?;
159			let mut salt = [0; 32];
160			params_cursor.read_exact(&mut salt)?;
161			let parameters = PBKDF2SHA256Parameters::new(iterations, salt);
162			Ok(KDFParameters::PBKDF2SHA256Parameters(parameters))
163		} else if identifier == ScryptParameters::identifier() {
164			let logn = u8::decode_directly(&mut params_cursor)?;
165			let r = u32::decode_directly(&mut params_cursor)?;
166			let p = u32::decode_directly(&mut params_cursor)?;
167			let mut salt = [0; 32];
168			params_cursor.read_exact(&mut salt)?;
169			let parameters = ScryptParameters::new(logn, r, p, salt);
170			Ok(KDFParameters::ScryptParameters(parameters))
171		} else {
172			Err(ZffError::new(ZffErrorKind::HeaderDecodeMismatchIdentifier, ERROR_HEADER_DECODER_MISMATCH_IDENTIFIER_KDF))
173		}
174	}
175}
176
177/// struct to store the parameters for the KDF PBKDF2-SHA256.
178#[derive(Debug,Clone,Eq,PartialEq)]
179pub struct PBKDF2SHA256Parameters {
180	iterations: u32,
181	salt: [u8; 32],
182}
183
184impl PBKDF2SHA256Parameters {
185	/// returns a new [PBKDF2SHA256Parameters] with the given values.
186	pub fn new(iterations: u32, salt: [u8; 32]) -> PBKDF2SHA256Parameters {
187		Self {
188			iterations,
189			salt,
190		}
191	}
192
193	/// returns the number of iterations
194	pub fn iterations(&self) -> u32 {
195		self.iterations
196	}
197
198	/// returns the salt
199	pub fn salt(&self) -> &[u8; 32] {
200		&self.salt
201	}
202}
203
204impl HeaderCoding for PBKDF2SHA256Parameters {
205	type Item = PBKDF2SHA256Parameters;
206
207	fn identifier() -> u32 {
208		PBE_KDF_PARAMETERS_PBKDF2
209	}
210
211	fn version(&self) -> u8 {
212		0
213	}
214
215	fn encode_header(&self) -> Vec<u8> {
216		let mut vec = Vec::new();
217		vec.append(&mut self.iterations.encode_directly());
218		vec.append(&mut self.salt.encode_directly());
219		vec
220	}
221
222	fn decode_content(data: Vec<u8>) -> Result<PBKDF2SHA256Parameters> {
223		let mut cursor = Cursor::new(data);
224
225		let iterations = u32::decode_directly(&mut cursor)?;
226		let mut salt = [0; 32];
227		cursor.read_exact(&mut salt)?;
228		let parameters = PBKDF2SHA256Parameters::new(iterations, salt);
229		Ok(parameters)
230	}
231
232}
233
234/// struct to store the parameters for the KDF Scrypt.
235#[derive(Debug,Clone,Eq,PartialEq)]
236pub struct ScryptParameters {
237	logn: u8,
238	r: u32,
239	p: u32,
240	salt: [u8; 32],
241}
242
243impl ScryptParameters {
244	/// returns a new [ScryptParameters] with the given values.
245	pub fn new(logn: u8, r: u32, p: u32, salt: [u8; 32]) -> ScryptParameters {
246		Self {
247			logn,
248			r,
249			p,
250			salt,
251		}
252	}
253
254	/// returns the logn
255	pub fn logn(&self) -> u8 {
256		self.logn
257	}
258
259	/// returns r
260	pub fn r(&self) -> u32 {
261		self.r
262	}
263
264	/// returns p
265	pub fn p(&self) -> u32 {
266		self.p
267	}
268
269	/// returns the salt
270	pub fn salt(&self) -> &[u8; 32] {
271		&self.salt
272	}
273}
274
275impl HeaderCoding for ScryptParameters {
276	type Item = ScryptParameters;
277
278	fn identifier() -> u32 {
279		PBE_KDF_PARAMETERS_SCRYPT
280	}
281
282	fn version(&self) -> u8 {
283		0
284	}
285
286	fn encode_header(&self) -> Vec<u8> {
287		let mut vec = Vec::new();
288		vec.append(&mut self.logn.encode_directly());
289		vec.append(&mut self.r.encode_directly());
290		vec.append(&mut self.p.encode_directly());
291		vec.append(&mut self.salt.encode_directly());
292		vec
293	}
294
295	fn decode_content(data: Vec<u8>) -> Result<ScryptParameters> {
296		let mut cursor = Cursor::new(data);
297
298		let logn = u8::decode_directly(&mut cursor)?;
299		let r = u32::decode_directly(&mut cursor)?;
300		let p = u32::decode_directly(&mut cursor)?;
301		let mut salt = [0; 32];
302		cursor.read_exact(&mut salt)?;
303		let parameters = ScryptParameters::new(logn, r, p, salt);
304		Ok(parameters)
305	}
306
307}