zff/header/version1/
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::version1::{
17	HEADER_IDENTIFIER_PBE_HEADER,
18	PBE_KDF_PARAMETERS_PBKDF2,
19	ERROR_HEADER_DECODER_MISMATCH_IDENTIFIER_KDF,
20	ERROR_HEADER_DECODER_UNKNOWN_PBE_SCHEME,
21	ERROR_HEADER_DECODER_UNKNOWN_KDF_SCHEME,
22};
23
24/// The pbe header contains all informations for the encryption of the encryption key.\
25/// The encryption key, used for the chunk encryption, can be found at the [EncryptionHeader](struct.EncryptionHeader.html) -
26/// encrypted with an user password.\
27/// This encryption of the encryption key is done via a password-based encryption (PBE).\
28/// All metadata about this PBE can be found in this PBEHeader.\
29#[derive(Debug,Clone,PartialEq,Eq)]
30pub struct PBEHeader {
31	version: u8,
32	kdf_scheme: KDFScheme,
33	encryption_scheme: PBEScheme,
34	kdf_parameters: KDFParameters,
35	pbencryption_nonce: [u8; 16],
36}
37
38impl PBEHeader {
39	/// returns a new pbe header with the given values.
40	pub fn new(
41		version: u8,
42		kdf_scheme: KDFScheme,
43		encryption_scheme: PBEScheme,
44		kdf_parameters: KDFParameters,
45		pbencryption_nonce: [u8; 16],
46		) -> PBEHeader {
47		Self {
48			version,
49			kdf_scheme,
50			encryption_scheme,
51			kdf_parameters,
52			pbencryption_nonce,
53		}
54	}
55
56	/// returns the kdf scheme.
57	pub fn kdf_scheme(&self) -> &KDFScheme {
58		&self.kdf_scheme
59	}
60
61	/// returns the encryption scheme.
62	pub fn encryption_scheme(&self) -> &PBEScheme {
63		&self.encryption_scheme
64	}
65
66	/// returns the kdf parameters.
67	pub fn kdf_parameters(&self) -> &KDFParameters {
68		&self.kdf_parameters
69	}
70
71	/// returns the pbe nonce.
72	pub fn nonce(&self) -> &[u8; 16] {
73		&self.pbencryption_nonce
74	}
75}
76
77impl HeaderCoding for PBEHeader {
78	type Item = PBEHeader;
79
80	fn identifier() -> u32 {
81		HEADER_IDENTIFIER_PBE_HEADER
82	}
83
84	fn version(&self) -> u8 {
85		self.version
86	}
87
88	fn encode_header(&self) -> Vec<u8> {
89		let mut vec = vec![self.version, self.kdf_scheme.clone() as u8, self.encryption_scheme.clone() as u8];
90		vec.append(&mut self.kdf_parameters.encode_directly());
91		vec.append(&mut self.pbencryption_nonce.encode_directly());
92		vec
93	}
94
95	fn decode_content(data: Vec<u8>) -> Result<PBEHeader> {
96		let mut cursor = Cursor::new(data);
97
98		let header_version = u8::decode_directly(&mut cursor)?;
99		let kdf_scheme = match u8::decode_directly(&mut cursor)? {
100			0 => KDFScheme::PBKDF2SHA256,
101			_ => return Err(ZffError::new_header_decode_error(ERROR_HEADER_DECODER_UNKNOWN_KDF_SCHEME))
102		};
103		let encryption_scheme = match u8::decode_directly(&mut cursor)? {
104			0 => PBEScheme::AES128CBC,
105			1 => PBEScheme::AES256CBC,
106			_ => return Err(ZffError::new_header_decode_error(ERROR_HEADER_DECODER_UNKNOWN_PBE_SCHEME)),
107		};
108		let kdf_params = KDFParameters::decode_directly(&mut cursor)?;
109		let mut encryption_nonce = [0; 16];
110		cursor.read_exact(&mut encryption_nonce)?;
111		Ok(PBEHeader::new(header_version, kdf_scheme, encryption_scheme, kdf_params, encryption_nonce))
112	}
113}
114
115/// enum to handle the stored parameters for the appropriate key deriavation function (KDF).
116#[repr(u8)]
117#[non_exhaustive]
118#[derive(Debug,Clone,Eq,PartialEq)]
119pub enum KDFParameters {
120	/// stores a struct [PBKDF2SHA256Parameters].
121	PBKDF2SHA256Parameters(PBKDF2SHA256Parameters),
122}
123
124impl ValueEncoder for KDFParameters {
125	fn encode_directly(&self) -> Vec<u8> {
126		match self {
127			KDFParameters::PBKDF2SHA256Parameters(params) => params.encode_directly(),
128		}
129	}
130	fn encode_for_key<K: Into<String>>(&self, key: K) -> Vec<u8> {
131		let mut vec = Vec::new();
132		let mut encoded_key = Self::encode_key(key);
133		vec.append(&mut encoded_key);
134		vec.append(&mut self.encode_directly());
135		vec
136	}
137}
138
139impl ValueDecoder for KDFParameters {
140	type Item = KDFParameters;
141
142	fn decode_directly<R: Read>(data: &mut R) -> Result<KDFParameters> {
143		if let Ok(params) = PBKDF2SHA256Parameters::decode_directly(data) {
144			return Ok(KDFParameters::PBKDF2SHA256Parameters(params));
145		};
146		Err(ZffError::new(ZffErrorKind::HeaderDecodeMismatchIdentifier, ERROR_HEADER_DECODER_MISMATCH_IDENTIFIER_KDF))
147	}
148}
149
150/// struct to store the parameters for the KDF PBKDF2-SHA256.
151#[derive(Debug,Clone,Eq,PartialEq)]
152pub struct PBKDF2SHA256Parameters {
153	iterations: u16,
154	salt: [u8; 32],
155}
156
157impl PBKDF2SHA256Parameters {
158	/// returns a new [PBKDF2SHA256Parameters] with the given values.
159	pub fn new(iterations: u16, salt: [u8; 32]) -> PBKDF2SHA256Parameters {
160		Self {
161			iterations,
162			salt,
163		}
164	}
165
166	/// returns the number of iterations
167	pub fn iterations(&self) -> u16 {
168		self.iterations
169	}
170
171	/// returns the salt
172	pub fn salt(&self) -> &[u8; 32] {
173		&self.salt
174	}
175}
176
177impl HeaderCoding for PBKDF2SHA256Parameters {
178	type Item = PBKDF2SHA256Parameters;
179
180	fn identifier() -> u32 {
181		PBE_KDF_PARAMETERS_PBKDF2
182	}
183
184	fn version(&self) -> u8 {
185		0
186	}
187
188	fn encode_header(&self) -> Vec<u8> {
189		let mut vec = Vec::new();
190		vec.append(&mut self.iterations.encode_directly());
191		vec.append(&mut self.salt.encode_directly());
192		vec
193	}
194
195	fn decode_content(data: Vec<u8>) -> Result<PBKDF2SHA256Parameters> {
196		let mut cursor = Cursor::new(data);
197
198		let iterations = u16::decode_directly(&mut cursor)?;
199		let mut salt = [0; 32];
200		cursor.read_exact(&mut salt)?;
201		let parameters = PBKDF2SHA256Parameters::new(iterations, salt);
202		Ok(parameters)
203	}
204
205}