1use crate::error::{CryptoError, CryptoResult};
4use hmac::{Hmac, Mac as _};
5use sha1::Sha1;
6use sha2::{Sha256, Sha384, Sha512};
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10pub enum HmacAlgorithm {
11 SHA1,
13 SHA256,
15 SHA384,
17 SHA512,
19}
20
21pub fn hmac_sign(algorithm: HmacAlgorithm, secret: &[u8], data: &[u8]) -> CryptoResult<Vec<u8>> {
23 match algorithm {
24 HmacAlgorithm::SHA1 => {
25 let mut mac = Hmac::<Sha1>::new_from_slice(secret).map_err(|_| CryptoError::KeyError)?;
26 mac.update(data);
27 Ok(mac.finalize().into_bytes().to_vec())
28 }
29 HmacAlgorithm::SHA256 => {
30 let mut mac = Hmac::<Sha256>::new_from_slice(secret).map_err(|_| CryptoError::KeyError)?;
31 mac.update(data);
32 Ok(mac.finalize().into_bytes().to_vec())
33 }
34 HmacAlgorithm::SHA384 => {
35 let mut mac = Hmac::<Sha384>::new_from_slice(secret).map_err(|_| CryptoError::KeyError)?;
36 mac.update(data);
37 Ok(mac.finalize().into_bytes().to_vec())
38 }
39 HmacAlgorithm::SHA512 => {
40 let mut mac = Hmac::<Sha512>::new_from_slice(secret).map_err(|_| CryptoError::KeyError)?;
41 mac.update(data);
42 Ok(mac.finalize().into_bytes().to_vec())
43 }
44 }
45}
46
47pub fn hmac_verify(algorithm: HmacAlgorithm, secret: &[u8], data: &[u8], signature: &[u8]) -> CryptoResult<bool> {
49 match algorithm {
50 HmacAlgorithm::SHA1 => {
51 let mut mac = Hmac::<Sha1>::new_from_slice(secret).map_err(|_| CryptoError::KeyError)?;
52 mac.update(data);
53 mac.verify_slice(signature).map_err(|_| CryptoError::InvalidSignature)?;
54 Ok(true)
55 }
56 HmacAlgorithm::SHA256 => {
57 let mut mac = Hmac::<Sha256>::new_from_slice(secret).map_err(|_| CryptoError::KeyError)?;
58 mac.update(data);
59 mac.verify_slice(signature).map_err(|_| CryptoError::InvalidSignature)?;
60 Ok(true)
61 }
62 HmacAlgorithm::SHA384 => {
63 let mut mac = Hmac::<Sha384>::new_from_slice(secret).map_err(|_| CryptoError::KeyError)?;
64 mac.update(data);
65 mac.verify_slice(signature).map_err(|_| CryptoError::InvalidSignature)?;
66 Ok(true)
67 }
68 HmacAlgorithm::SHA512 => {
69 let mut mac = Hmac::<Sha512>::new_from_slice(secret).map_err(|_| CryptoError::KeyError)?;
70 mac.update(data);
71 mac.verify_slice(signature).map_err(|_| CryptoError::InvalidSignature)?;
72 Ok(true)
73 }
74 }
75}