1pub use crate::aescbc::config::Pbkdf2HashingAlgo;
2use crate::aescbc::tp::B128;
3use crate::aescbc::tp::B256;
4use crate::errors::Error;
5use crate::hashis::{gcrc128, gcrc256, CrcAlgo};
6use crate::serial::YamlFile;
7use clap::builder::PossibleValue;
8use clap::ValueEnum;
9use pbkdf2::pbkdf2_hmac;
10use serde::{self, Deserialize, Serialize};
11use sha3::Sha3_256 as Sha256;
12use sha3::Sha3_384 as Sha384;
13use sha3::Sha3_512 as Sha512;
14use std::fmt;
15
16pub fn pbkdf2_sha256(data: &[u8], st: &[u8], it: u32, length: usize) -> Vec<u8> {
17 let mut key: Vec<u8> = Vec::with_capacity(length);
18 key.resize(length, 0x00);
19 let mut key = key.as_mut_slice();
20 pbkdf2_hmac::<Sha256>(data, st, it, &mut key);
21 key.to_vec()
22}
23
24pub fn pbkdf2_sha256_128bits(data: &[u8], st: &[u8], it: u32) -> B128 {
25 let mut result: B128 = [0x0; 16];
26 let key = pbkdf2_sha256(data, st, it, 256);
27 for chunk in key.chunks(16) {
28 for (pos, v) in chunk.iter().enumerate() {
29 result[pos] = result[pos] ^ v;
30 }
31 }
32 result
33}
34
35pub fn pbkdf2_sha256_256bits(data: &[u8], st: &[u8], it: u32) -> B256 {
36 let mut result: B256 = [0x0; 32];
37 let key = pbkdf2_sha256(data, st, it, 256);
38 for chunk in key.chunks(32) {
39 for (pos, v) in chunk.iter().enumerate() {
40 result[pos] = result[pos] ^ v;
41 }
42 }
43 result
44}
45
46pub fn pbkdf2_sha384(data: &[u8], st: &[u8], it: u32, length: usize) -> Vec<u8> {
47 let mut key: Vec<u8> = Vec::with_capacity(length);
48 key.resize(length, 0x00);
49 let mut key = key.as_mut_slice();
50 pbkdf2_hmac::<Sha384>(data, st, it, &mut key);
51 key.to_vec()
52}
53
54pub fn pbkdf2_sha384_128bits(data: &[u8], st: &[u8], it: u32) -> B128 {
55 let mut result: B128 = [0x0; 16];
56 let key = pbkdf2_sha384(data, st, it, 256);
57 for chunk in key.chunks(16) {
58 for (pos, v) in chunk.iter().enumerate() {
59 result[pos] = result[pos] ^ v;
60 }
61 }
62 result
63}
64
65pub fn pbkdf2_sha384_256bits(data: &[u8], st: &[u8], it: u32) -> B256 {
66 let mut result: B256 = [0x0; 32];
67 let key = pbkdf2_sha384(data, st, it, 256);
68 for chunk in key.chunks(32) {
69 for (pos, v) in chunk.iter().enumerate() {
70 result[pos] = result[pos] ^ v;
71 }
72 }
73 result
74}
75
76pub fn pbkdf2_sha512(data: &[u8], st: &[u8], it: u32, length: usize) -> Vec<u8> {
77 let mut key: Vec<u8> = Vec::with_capacity(length);
78 key.resize(length, 0x00);
79 let mut key = key.as_mut_slice();
80 pbkdf2_hmac::<Sha512>(data, st, it, &mut key);
81 key.to_vec()
82}
83
84pub fn pbkdf2_sha512_128bits(data: &[u8], st: &[u8], it: u32) -> B128 {
85 let mut result: B128 = [0x0; 16];
86 let key = pbkdf2_sha512(data, st, it, 256);
87 for chunk in key.chunks(16) {
88 for (pos, v) in chunk.iter().enumerate() {
89 result[pos] = result[pos] ^ v;
90 }
91 }
92 result
93}
94
95pub fn pbkdf2_sha512_256bits(data: &[u8], st: &[u8], it: u32) -> B256 {
96 let mut result: B256 = [0x0; 32];
97 let key = pbkdf2_sha512(data, st, it, 256);
98 for chunk in key.chunks(32) {
99 for (pos, v) in chunk.iter().enumerate() {
100 result[pos] = result[pos] ^ v;
101 }
102 }
103 result
104}
105
106#[derive(PartialEq, Clone, Serialize, Deserialize, Debug)]
107#[serde(untagged)]
108pub enum DerivationScheme {
109 #[serde(rename = "pbkdf2")]
110 Pbkdf2(Pbkdf2HashingAlgo),
111 #[serde(rename = "crc")]
112 Crc(CrcAlgo),
113}
114impl DerivationScheme {
115 pub fn derive(&self, data: &[u8], st: &[u8], it: u32) -> Vec<u8> {
116 match self {
117 DerivationScheme::Pbkdf2(Pbkdf2HashingAlgo::Sha3_256) => {
118 pbkdf2_sha256(data, st, it, 32)
119 }
120 DerivationScheme::Pbkdf2(Pbkdf2HashingAlgo::Sha3_384) => {
121 pbkdf2_sha384(data, st, it, 32)
122 }
123 DerivationScheme::Pbkdf2(Pbkdf2HashingAlgo::Sha3_512) => {
124 pbkdf2_sha512(data, st, it, 32)
125 }
126 DerivationScheme::Crc(CrcAlgo::GcRc128) => gcrc128(data).to_vec(),
127 DerivationScheme::Crc(CrcAlgo::GcRc256) => gcrc256(data).to_vec(),
128 }
129 }
130}
131impl ValueEnum for DerivationScheme {
132 fn value_variants<'a>() -> &'a [Self] {
133 &[
134 DerivationScheme::Pbkdf2(Pbkdf2HashingAlgo::Sha3_256),
135 DerivationScheme::Pbkdf2(Pbkdf2HashingAlgo::Sha3_384),
136 DerivationScheme::Pbkdf2(Pbkdf2HashingAlgo::Sha3_512),
137 DerivationScheme::Crc(CrcAlgo::GcRc128),
138 DerivationScheme::Crc(CrcAlgo::GcRc256),
139 ]
140 }
141 fn to_possible_value(&self) -> Option<PossibleValue> {
142 match &self {
143 DerivationScheme::Pbkdf2(Pbkdf2HashingAlgo::Sha3_256) => {
144 Some(PossibleValue::new("ds_pbkdf2_sha3_256"))
145 }
146 DerivationScheme::Pbkdf2(Pbkdf2HashingAlgo::Sha3_384) => {
147 Some(PossibleValue::new("ds_pbkdf2_sha3_384"))
148 }
149 DerivationScheme::Pbkdf2(Pbkdf2HashingAlgo::Sha3_512) => {
150 Some(PossibleValue::new("ds_pbkdf2_sha3_512"))
151 }
152 DerivationScheme::Crc(CrcAlgo::GcRc128) => Some(PossibleValue::new("ds_crc_gcrc128")),
153 DerivationScheme::Crc(CrcAlgo::GcRc256) => Some(PossibleValue::new("ds_crc_gcrc256")),
154 }
155 }
156 fn from_str(input: &str, ignore_case: bool) -> Result<DerivationScheme, String> {
157 let input = if ignore_case {
158 input.to_lowercase()
159 } else {
160 input.to_string()
161 };
162 let input = input.trim();
163
164 match input {
165 "pbkdf2_sha3_256" => Ok(DerivationScheme::Pbkdf2(Pbkdf2HashingAlgo::Sha3_256)),
166 "pbkdf2_sha3_384" => Ok(DerivationScheme::Pbkdf2(Pbkdf2HashingAlgo::Sha3_384)),
167 "pbkdf2_sha3_512" => Ok(DerivationScheme::Pbkdf2(Pbkdf2HashingAlgo::Sha3_512)),
168 "crc_gcrc128" => Ok(DerivationScheme::Crc(CrcAlgo::GcRc128)),
169 "crc_gcrc256" => Ok(DerivationScheme::Crc(CrcAlgo::GcRc256)),
170 otherwise => Err(otherwise.to_string()),
171 }
172 }
173}
174#[cfg(test)]
175mod derivation_scheme_serialization_tests {
176 use crate::aescbc::config::Pbkdf2HashingAlgo;
177 use crate::aescbc::kd::DerivationScheme;
178 use crate::errors::Error;
179 use crate::hashis::CrcAlgo;
180
181 use k9::assert_equal;
182
183 #[test]
184 pub fn test_pbkdf2_sha3_256() -> Result<(), Error> {
185 let ds = DerivationScheme::Pbkdf2(Pbkdf2HashingAlgo::Sha3_256);
186 assert_equal!(serde_yaml::to_string(&ds)?, format!("pbkdf2_sha3_256\n"));
187 Ok(())
188 }
189 #[test]
190 pub fn test_pbkdf2_sha3_384() -> Result<(), Error> {
191 let ds = DerivationScheme::Pbkdf2(Pbkdf2HashingAlgo::Sha3_384);
192 assert_equal!(serde_yaml::to_string(&ds)?, format!("pbkdf2_sha3_384\n"));
193 Ok(())
194 }
195 #[test]
196 pub fn test_pbkdf2_sha3_512() -> Result<(), Error> {
197 let ds = DerivationScheme::Pbkdf2(Pbkdf2HashingAlgo::Sha3_512);
198 assert_equal!(serde_yaml::to_string(&ds)?, format!("pbkdf2_sha3_512\n"));
199 Ok(())
200 }
201 #[test]
202 pub fn test_crc_gcrc128() -> Result<(), Error> {
203 let ds = DerivationScheme::Crc(CrcAlgo::GcRc128);
204 assert_equal!(serde_yaml::to_string(&ds)?, format!("crc_gcrc128\n"));
205 Ok(())
206 }
207 #[test]
208 pub fn test_crc_gcrc256() -> Result<(), Error> {
209 let ds = DerivationScheme::Crc(CrcAlgo::GcRc256);
210 assert_equal!(serde_yaml::to_string(&ds)?, format!("crc_gcrc256\n"));
211 Ok(())
212 }
213}
214impl YamlFile for DerivationScheme {
220 fn default() -> Result<DerivationScheme, Error> {
221 Ok(DerivationScheme::Pbkdf2(Pbkdf2HashingAlgo::Sha3_512))
222 }
223}
224
225impl fmt::Display for DerivationScheme {
226 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
227 write!(
228 f,
229 "ds_{}",
230 match self {
231 DerivationScheme::Crc(a) => format!("{}", a),
232 DerivationScheme::Pbkdf2(a) => format!("{}", a),
233 }
234 )
235 }
236}
237
238#[cfg(test)]
239mod pbkdf2_sha256_tests {
240 use crate::aescbc::kd::pbkdf2_sha256;
241 use crate::aescbc::kd::pbkdf2_sha256_128bits;
242 use crate::aescbc::kd::pbkdf2_sha256_256bits;
243 use k9::assert_equal;
244
245 #[test]
246 pub fn test_pbkdf2_sha256() {
247 let password =
248 b"Cras quis luctus tellus. Curabitur consectetur eu neque nec auctor. Curabitur.";
249 let salt = b"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris sed finibus.";
250 let iterations = 0x53;
251
252 let dhmac = pbkdf2_sha256(password, salt, iterations, 16);
253
254 assert_equal!(dhmac.len(), 16);
255 assert_equal!(
256 dhmac,
257 [84, 189, 114, 48, 88, 140, 144, 188, 30, 178, 172, 167, 173, 15, 72, 229,].to_vec()
258 );
259 }
260 #[test]
261 pub fn test_pbkdf2_sha256_128bits() {
262 let password =
263 b"Cras quis luctus tellus. Curabitur consectetur eu neque nec auctor. Curabitur.";
264 let salt = b"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris sed finibus.";
265 let iterations = 0x53;
266
267 let dhmac = pbkdf2_sha256_128bits(password, salt, iterations);
268
269 assert_equal!(dhmac.len(), 16);
270 assert_equal!(
271 dhmac.to_vec(),
272 [75, 123, 63, 147, 158, 155, 204, 202, 159, 127, 253, 225, 5, 149, 70, 119,].to_vec()
273 );
274 }
275 #[test]
276 pub fn test_pbkdf2_sha256_256bits() {
277 let password =
278 b"Cras quis luctus tellus. Curabitur consectetur eu neque nec auctor. Curabitur.";
279 let salt = b"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris sed finibus.";
280 let iterations = 0x53;
282
283 let dhmac = pbkdf2_sha256_256bits(password, salt, iterations);
284
285 assert_equal!(dhmac.len(), 32);
286 assert_equal!(
287 dhmac.to_vec(),
288 [
289 91, 24, 54, 211, 113, 54, 159, 162, 131, 93, 207, 241, 44, 38, 220, 17, 16, 99, 9,
290 64, 239, 173, 83, 104, 28, 34, 50, 16, 41, 179, 154, 102,
291 ]
292 .to_vec()
293 );
294 }
295}
296
297#[cfg(test)]
298mod pbkdf2_sha384_tests {
299 use crate::aescbc::kd::pbkdf2_sha384;
300 use crate::aescbc::kd::pbkdf2_sha384_128bits;
301 use crate::aescbc::kd::pbkdf2_sha384_256bits;
302 use k9::assert_equal;
303
304 #[test]
305 pub fn test_pbkdf2_sha384() {
306 let password =
307 b"Cras quis luctus tellus. Curabitur consectetur eu neque nec auctor. Curabitur.";
308 let salt = b"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris sed finibus.";
309 let iterations = 0x53;
310
311 let dhmac = pbkdf2_sha384(password, salt, iterations, 24);
312
313 assert_equal!(dhmac.len(), 24);
314 assert_equal!(
315 dhmac,
316 [
317 93, 54, 175, 45, 68, 96, 125, 7, 49, 146, 221, 87, 219, 228, 6, 0, 128, 221, 20,
318 87, 97, 169, 129, 27,
319 ]
320 .to_vec()
321 );
322 }
323 #[test]
324 pub fn test_pbkdf2_sha384_128bits() {
325 let password =
326 b"Cras quis luctus tellus. Curabitur consectetur eu neque nec auctor. Curabitur.";
327 let salt = b"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris sed finibus.";
328 let iterations = 0x53;
329
330 let dhmac = pbkdf2_sha384_128bits(password, salt, iterations);
331
332 assert_equal!(dhmac.len(), 16);
333 assert_equal!(
334 dhmac.to_vec(),
335 [109, 164, 181, 139, 65, 152, 214, 206, 218, 47, 184, 138, 80, 55, 51, 119,].to_vec()
336 );
337 }
338 #[test]
339 pub fn test_pbkdf2_sha384_256bits() {
340 let password =
341 b"Cras quis luctus tellus. Curabitur consectetur eu neque nec auctor. Curabitur.";
342 let salt = b"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris sed finibus.";
343 let iterations = 0x53;
344
345 let dhmac = pbkdf2_sha384_256bits(password, salt, iterations);
346
347 assert_equal!(dhmac.len(), 32);
348 assert_equal!(
349 dhmac.to_vec(),
350 [
351 56, 255, 253, 85, 18, 209, 194, 89, 130, 57, 3, 250, 221, 102, 61, 59, 85, 91, 72,
352 222, 83, 73, 20, 151, 88, 22, 187, 112, 141, 81, 14, 76,
353 ]
354 .to_vec()
355 );
356 }
357}
358
359#[cfg(test)]
360mod pbkdf2_sha512_tests {
361 use crate::aescbc::kd::pbkdf2_sha512;
362 use crate::aescbc::kd::pbkdf2_sha512_128bits;
363 use crate::aescbc::kd::pbkdf2_sha512_256bits;
364 use k9::assert_equal;
365
366 #[test]
367 pub fn test_pbkdf2_sha512() {
368 let password =
369 b"Cras quis luctus tellus. Curabitur consectetur eu neque nec auctor. Curabitur.";
370 let salt = b"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris sed finibus.";
371 let iterations = 0x53;
372
373 let dhmac = pbkdf2_sha512(password, salt, iterations, 24);
374
375 assert_equal!(dhmac.len(), 24);
376 assert_equal!(
377 dhmac,
378 [
379 184, 99, 158, 94, 97, 151, 140, 231, 108, 96, 184, 54, 220, 203, 203, 67, 132, 16,
380 88, 226, 230, 174, 32, 237,
381 ]
382 .to_vec()
383 );
384 }
385 #[test]
386 pub fn test_pbkdf2_sha512_128bits() {
387 let password =
388 b"Cras quis luctus tellus. Curabitur consectetur eu neque nec auctor. Curabitur.";
389 let salt = b"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris sed finibus.";
390 let iterations = 0x53;
391
392 let dhmac = pbkdf2_sha512_128bits(password, salt, iterations);
393
394 assert_equal!(dhmac.len(), 16);
395 assert_equal!(
396 dhmac.to_vec(),
397 [156, 156, 3, 166, 110, 7, 99, 128, 90, 0, 187, 86, 215, 93, 116, 123,].to_vec()
398 );
399 }
400 #[test]
401 pub fn test_pbkdf2_sha512_256bits() {
402 let password =
403 b"Cras quis luctus tellus. Curabitur consectetur eu neque nec auctor. Curabitur.";
404 let salt = b"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris sed finibus.";
405 let iterations = 0x53;
406
407 let dhmac = pbkdf2_sha512_256bits(password, salt, iterations);
408
409 assert_equal!(dhmac.len(), 32);
410 assert_equal!(
411 dhmac.to_vec(),
412 [
413 47, 66, 192, 225, 237, 29, 47, 172, 203, 194, 0, 95, 190, 53, 191, 28, 179, 222,
414 195, 71, 131, 26, 76, 44, 145, 194, 187, 9, 105, 104, 203, 103,
415 ]
416 .to_vec()
417 );
418 }
419}