· 7 years ago · Mar 22, 2018, 01:00 PM
1pub struct Hkdf {
2 pub salt: Vec<u8>,
3 pub data: Vec<u8>,
4 pub info: Vec<u8>,
5 pub hmac: usize,
6 pub length: usize,
7}
8
9impl Drop for Hkdf {
10 fn drop(&mut self) {
11 //println!("DROPPING");
12 self.salt.clear();
13 self.data.clear();
14 self.info.clear()
15 }
16}
17
18impl Hkdf {
19 /// Return HMAC matching argument passsed to Hkdf.
20 pub fn hkdf_extract(&self, data: &[u8], salt: &[u8]) -> Vec<u8> {
21 let hmac_res = Hmac {
22 secret_key: salt.to_vec(),
23 message: data.to_vec(),
24 sha2: self.hmac
25 };
26
27 hmac_res.hmac_compute()
28 }
29
30 /// The HKDF Expand step. Returns an HKDF.
31 pub fn hkdf_compute(&self) -> Vec<u8> {
32 // Check that the selected key length is within the limit.
33 if self.length as f32 > 255_f32 * (self.hmac / 8) as f32 {
34 panic!("Derived key length above max. 255 * (HMAC OUTPUT LENGTH IN BYTES)");
35 }
36
37 let n_iter = (self.length as f32 / (self.hmac / 8) as f32).ceil() as usize;
38
39 let mut con_step: Vec<u8> = vec![];
40 let mut t_step: Vec<u8> = vec![];
41 let mut hkdf_final: Vec<u8> = vec![];
42
43 for x in 1..n_iter+1 {
44 con_step.append(&mut t_step);
45 con_step.extend_from_slice(&self.info);
46 con_step.push(x as u8);
47 t_step.extend_from_slice(&self.hkdf_extract(
48 &con_step,
49 &self.hkdf_extract(&self.data, &self.salt))
50 );
51 con_step.clear();
52
53 hkdf_final.extend_from_slice(&t_step);
54 }
55
56 hkdf_final.truncate(self.length);
57
58 hkdf_final
59 }
60}
61
62#[inline(never)]
63/// Comparison in constant time.
64pub fn compare_ct(x: &[u8], y: &[u8]) -> bool {
65
66 let length = x.len();
67
68 if length != y.len() {
69 false;
70 }
71
72 let mut result: u8 = 0;
73
74 for n in 0..length {
75 result |= x[n] ^ y[n];
76 }
77
78 result == 0
79}