extrapaytr_crypto/
hmac_sha.rs1use hmac::{Hmac, Mac};
2use sha2::{Sha256, Sha512};
3
4#[derive(Debug, Clone, Copy, PartialEq, Eq, thiserror::Error)]
5pub enum CryptoError {
6 #[error("HMAC key has an invalid length")]
7 InvalidKeyLength,
8}
9
10pub fn hmac_sha256(key: &[u8], message: &[u8]) -> Result<[u8; 32], CryptoError> {
12 let mut mac =
13 <Hmac<Sha256> as Mac>::new_from_slice(key).map_err(|_| CryptoError::InvalidKeyLength)?;
14 mac.update(message);
15 Ok(mac.finalize().into_bytes().into())
16}
17
18pub fn hmac_sha512(key: &[u8], message: &[u8]) -> Result<[u8; 64], CryptoError> {
20 let mut mac =
21 <Hmac<Sha512> as Mac>::new_from_slice(key).map_err(|_| CryptoError::InvalidKeyLength)?;
22 mac.update(message);
23 Ok(mac.finalize().into_bytes().into())
24}
25
26#[cfg(test)]
27mod tests {
28 use super::*;
29
30 #[test]
32 fn hmac_sha256_rfc4231_case1() {
33 let key = [0x0bu8; 20];
34 let data = b"Hi There";
35 let expected =
36 hex::decode("b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7")
37 .unwrap();
38 assert_eq!(hmac_sha256(&key, data).unwrap().to_vec(), expected);
39 }
40
41 #[test]
43 fn hmac_sha256_rfc4231_case2() {
44 let key = b"Jefe";
45 let data = b"what do ya want for nothing?";
46 let expected =
47 hex::decode("5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843")
48 .unwrap();
49 assert_eq!(hmac_sha256(key, data).unwrap().to_vec(), expected);
50 }
51
52 #[test]
54 fn hmac_sha256_rfc4231_case6() {
55 let key = [0xaau8; 131];
56 let data = b"Test Using Larger Than Block-Size Key - Hash Key First";
57 let expected =
58 hex::decode("60e431591ee0b67f0d8a26aacbf5b77f8e0bc6213728c5140546040f0ee37f54")
59 .unwrap();
60 assert_eq!(hmac_sha256(&key, data).unwrap().to_vec(), expected);
61 }
62
63 #[test]
65 fn hmac_sha512_rfc4231_case1() {
66 let key = [0x0bu8; 20];
67 let data = b"Hi There";
68 let expected = hex::decode(
69 "87aa7cdea5ef619d4ff0b4241a1d6cb02379f4e2ce4ec2787ad0b30545e17cdedaa833b7d6b8a702038b274eaea3f4e4be9d914eeb61f1702e696c203a126854",
70 )
71 .unwrap();
72 assert_eq!(hmac_sha512(&key, data).unwrap().to_vec(), expected);
73 }
74
75 #[test]
76 fn empty_key_is_accepted_per_hmac_semantics() {
77 assert!(hmac_sha256(&[], b"message").is_ok());
80 }
81}