Skip to main content

hkdf/
hmac_impl.rs

1use hmac::digest::{
2    Digest, FixedOutput, KeyInit, Output, Update,
3    block_api::{BlockSizeUser, OutputSizeUser},
4};
5use hmac::{EagerHash, Hmac, SimpleHmac};
6
7/// Trait representing a HMAC implementation.
8///
9/// Most users should use [`Hmac`] or [`SimpleHmac`].
10pub trait HmacImpl: Clone + OutputSizeUser {
11    /// Create new HMAC state with the given key.
12    fn new_from_slice(key: &[u8]) -> Self;
13
14    /// Update HMAC state.
15    fn update(&mut self, data: &[u8]);
16
17    /// Finalize the HMAC state and get generated tag.
18    fn finalize(self) -> Output<Self>;
19}
20
21impl<H: EagerHash> HmacImpl for Hmac<H> {
22    #[inline(always)]
23    fn new_from_slice(key: &[u8]) -> Self {
24        KeyInit::new_from_slice(key).expect("HMAC can take a key of any size")
25    }
26
27    #[inline(always)]
28    fn update(&mut self, data: &[u8]) {
29        Update::update(self, data);
30    }
31
32    #[inline(always)]
33    fn finalize(self) -> Output<Self> {
34        self.finalize_fixed()
35    }
36}
37
38impl<H> HmacImpl for SimpleHmac<H>
39where
40    H: Digest + BlockSizeUser + Clone,
41{
42    #[inline(always)]
43    fn new_from_slice(key: &[u8]) -> Self {
44        KeyInit::new_from_slice(key).expect("HMAC can take a key of any size")
45    }
46
47    #[inline(always)]
48    fn update(&mut self, data: &[u8]) {
49        Update::update(self, data);
50    }
51
52    #[inline(always)]
53    fn finalize(self) -> Output<H> {
54        self.finalize_fixed()
55    }
56}