Skip to main content

hmac_serialiser/
hkdf.rs

1use crate::algorithm::Algorithm;
2
3#[cfg(not(feature = "ring"))]
4use hkdf::Hkdf;
5
6#[cfg(feature = "ring")]
7use ring::hkdf;
8
9pub struct HkdfWrapper {
10    algo: Algorithm,
11}
12
13#[cfg(not(feature = "ring"))]
14macro_rules! hkdf_expand {
15    ($self:ident, $ikm:ident, $salt:ident, $info:ident, $D:ty) => {{
16        let hk = Hkdf::<$D>::new(Some($salt), $ikm);
17        let mut okm = vec![0u8; $self.algo.output_length()];
18        hk.expand($info, &mut okm)
19            .expect("could not expand key due to possibly invalid length");
20        okm
21    }};
22}
23
24impl HkdfWrapper {
25    pub fn new(algo: Algorithm) -> Self {
26        Self { algo }
27    }
28
29    #[cfg(not(feature = "ring"))]
30    pub fn expand(&self, ikm: &[u8], salt: &[u8], info: &[u8]) -> Vec<u8> {
31        match self.algo {
32            Algorithm::SHA1 => hkdf_expand!(self, ikm, salt, info, sha1::Sha1),
33            Algorithm::SHA256 => hkdf_expand!(self, ikm, salt, info, sha2::Sha256),
34            Algorithm::SHA384 => hkdf_expand!(self, ikm, salt, info, sha2::Sha384),
35            Algorithm::SHA512 => hkdf_expand!(self, ikm, salt, info, sha2::Sha512),
36        }
37    }
38
39    #[cfg(feature = "ring")]
40    pub fn expand(&self, ikm: &[u8], salt: &[u8], info: &[u8]) -> Vec<u8> {
41        let hkdf_algo = self.algo.to_hkdf();
42        let prk = hkdf::Salt::new(hkdf_algo, salt).extract(ikm);
43
44        let mut okm = vec![0u8; self.algo.output_length()];
45        let okm_slice = &mut okm[..];
46        prk.expand(&[info], self.algo.to_hmac())
47            .expect("could not expand key due to possibly invalid length")
48            .fill(okm_slice)
49            .expect("could not fill key due to possibly invalid length");
50        okm
51    }
52}