1#![no_std]
2#![allow(dead_code)]
3
4use digest::Digest;
5use heapless::Vec;
6use hmac::{Hmac, Mac, NewMac};
7pub struct HmacSha<'a, T: Digest> {
8    key: &'a [u8],
9    message: &'a [u8],
10    sha_type: T,
11}
12
13impl<'a, T> HmacSha<'a, T>
14where
15    T: Digest
16        + Clone
17        + Default
18        + digest::Update
19        + digest::FixedOutput
20        + digest::Reset
21        + digest::BlockInput,
22{
23    #[must_use]
24    pub fn new(key: &'a [u8], message: &'a [u8], sha_type: T) -> Self {
25        Self {
26            key,
27            message,
28            sha_type,
29        }
30    }
31
32    #[must_use]
33    pub fn from(key: &'a str, message: &'a str, sha_type: T) -> Self {
34        Self {
35            key: key.as_bytes(),
36            message: message.as_bytes(),
37            sha_type,
38        }
39    }
40
41    pub fn compute_digest(&mut self) -> Vec<u8, 64> {
42        let mut mac = Hmac::<T>::new_from_slice(self.key).expect("HMAC can take key of any size");
43        mac.update(self.message);
44        let bytes = mac.finalize().into_bytes();
45        let bytes = bytes.as_slice();
46        Vec::from_slice(bytes).expect("Failed to compute the digest")
47    }
48}
49
50#[cfg(test)]
51mod tests {
52
53    use super::HmacSha;
54    use sha1::Sha1;
55    use sha2::{Sha256, Sha512};
56    use sha3::Sha3_256;
57
58    #[test]
59    fn test_vector1() {
60        let data = b"Hi There";
62        let key = &[0x0b; 20];
63        let expected = "b617318655057264e28bc0b6fb378c8ef146be00";
64        let mut hash = HmacSha::new(key, data, Sha1::default());
65        let buf = hash.compute_digest();
66        assert_eq!(hex::encode(buf), expected);
67    }
68
69    #[test]
70    fn test_vector2() {
71        let data = b"what do ya want for nothing?";
73        let key = b"Jefe";
74        let expected = "effcdf6ae5eb2fa2d27416d5f184df9c259a7c79";
75        let mut hash = HmacSha::new(key, data, Sha1::default());
76        let buf = hash.compute_digest();
77        assert_eq!(hex::encode(buf), expected);
78    }
79
80    #[test]
81    fn test_vector3() {
82        let data = &[0xdd; 50];
84        let key = &[0xaa; 20];
85        let expected = "125d7342b9ac11cd91a39af48aa17b4f63f175d3";
86        let mut hash = HmacSha::new(key, data, Sha1::default());
87        let buf = hash.compute_digest();
88        assert_eq!(hex::encode(buf), expected);
89    }
90
91    #[test]
92    fn test_vector4() {
93        let data = &[0xcd; 50];
95        let key = &[
96            1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
97            25,
98        ];
99        let expected = "4c9007f4026250c6bc8414f9bf50c86c2d7235da";
100        let mut hasher = HmacSha::new(key, data, Sha1::default());
101        let result = hasher.compute_digest();
102        assert_eq!(hex::encode(result), expected);
103    }
104
105    #[test]
106    fn test_readme() {
107        let secret_key = "A very strong secret";
108        let message = "My secret message";
109        let expected = "bc192ba8d968e0c705eecd406c74299ca83d05e6";
110        let mut hasher = HmacSha::from(secret_key, message, Sha1::default());
111        let result = hasher.compute_digest();
112        assert_eq!(hex::encode(result), expected);
113    }
114
115    #[test]
116    fn test_readme_sha2() {
117        let secret_key = "A very strong secret";
118        let message = "My secret message";
119        let expected = "4134aad013bd12a6d7b0a5b5e78e3b1a76cb095cf5b7ceb6ac0717e433f56133";
120        let mut hasher = HmacSha::from(secret_key, message, Sha256::default());
121        let result = hasher.compute_digest();
122        assert_eq!(hex::encode(result), expected);
123    }
124
125    #[test]
126    fn test_readme_sha3() {
127        let secret_key = "A very strong secret";
128        let message = "My secret message";
129        let expected = "92b41d5b7e665a81faa9c18e25657107ad8f174cdc7558a15b6990c2c47c7bfe";
130        let mut hasher = HmacSha::from(secret_key, message, Sha3_256::default());
131        let result = hasher.compute_digest();
132        assert_eq!(hex::encode(result), expected);
133    }
134
135    #[test]
136    fn test_readme_sha2_512() {
137        let secret_key = "A very strong secret";
138        let message = "My secret message";
139        let expected = "e9a33f07f9d14e95efda67889e015c73b8c71c1372976c1d247c0e1d1aad7822427f113d8d8f0a5fbb33c7a547491867346d19e2a02bf02349118ff6c6eba51a";
140        let mut hasher = HmacSha::from(secret_key, message, Sha512::default());
141        let result = hasher.compute_digest();
142        assert_eq!(hex::encode(result), expected);
143    }
144}