obg/aescbc/
kd.rs

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}
214// impl FromStr for DerivationScheme {
215//     fn from_str(s: &str) -> Result<Self, std::err::Error> {
216
217//     }
218// }
219impl 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        // XXX: https://www.one-tab.com/page/zT-wGbjAS_aXz6eV9_u9Ig
281        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}