1use crate::utils::{IPAD, OPAD, get_der_key};
2use core::fmt;
3use digest::{
4 Digest, FixedOutput, KeyInit, MacMarker, Output, OutputSizeUser, Update,
5 common::{Block, BlockSizeUser, InvalidLength, Key, KeySizeUser},
6};
7
8#[derive(Clone)]
12pub struct SimpleHmac<D: Digest + BlockSizeUser> {
13 digest: D,
14 opad_key: Block<D>,
15}
16
17impl<D: Digest + BlockSizeUser> KeySizeUser for SimpleHmac<D> {
18 type KeySize = D::BlockSize;
19}
20
21impl<D: Digest + BlockSizeUser> MacMarker for SimpleHmac<D> {}
22
23impl<D: Digest + BlockSizeUser> KeyInit for SimpleHmac<D> {
24 fn new(key: &Key<Self>) -> Self {
25 Self::new_from_slice(key.as_slice()).unwrap()
26 }
27
28 #[inline]
29 fn new_from_slice(key: &[u8]) -> Result<Self, InvalidLength> {
30 let mut buf = get_der_key::<D>(key);
31 buf.iter_mut().for_each(|b: &mut u8| *b ^= IPAD);
32
33 let mut digest = D::new();
34 digest.update(&buf);
35
36 buf.iter_mut().for_each(|b: &mut u8| *b ^= OPAD ^ IPAD);
37
38 Ok(Self {
39 digest,
40 opad_key: buf,
41 })
42 }
43}
44
45impl<D: Digest + BlockSizeUser> Update for SimpleHmac<D> {
46 #[inline(always)]
47 fn update(&mut self, data: &[u8]) {
48 self.digest.update(data);
49 }
50}
51
52impl<D: Digest + BlockSizeUser> OutputSizeUser for SimpleHmac<D> {
53 type OutputSize = D::OutputSize;
54}
55
56impl<D: Digest + BlockSizeUser> FixedOutput for SimpleHmac<D> {
57 fn finalize_into(self, out: &mut Output<Self>) {
58 let mut h = D::new();
59 h.update(&self.opad_key);
60 h.update(self.digest.finalize());
61 h.finalize_into(out);
62 }
63}
64
65impl<D: Digest + BlockSizeUser + fmt::Debug> fmt::Debug for SimpleHmac<D> {
66 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
67 f.write_str("SimpleHmac { ... }")
68 }
69}