use blake2b_simd::Params; use hmac::{Hmac, Mac}; use serde::{Deserialize, Serialize}; use sha2::Sha256; #[cfg(feature = "profile")] use flamer::*; type HmacSha256 = Hmac; /// Tag for the HMAC algorithim used by a particular chunk #[derive(Deserialize, Serialize, Copy, Clone, Debug)] pub enum HMAC { SHA256, Blake2b, } impl HMAC { #[cfg_attr(feature = "profile", flame)] /// Produces a MAC for the given data with the given key, using the /// algorthim specified in the tag. pub fn mac(self, data: &[u8], key: &[u8]) -> Vec { match self { HMAC::SHA256 => { let mut mac = HmacSha256::new_varkey(key).unwrap(); mac.input(data); mac.result().code().to_vec() } HMAC::Blake2b => Params::new() .hash_length(64) .key(key) .hash(data) .as_bytes() .to_vec(), } } #[cfg_attr(feature = "profile", flame)] /// Produces a MAC for the data using the algorthim specified in the tag, /// and verfies it against the supplied MAC pub fn verify(self, input_mac: &[u8], data: &[u8], key: &[u8]) -> bool { match self { HMAC::SHA256 => { let mut mac = HmacSha256::new_varkey(key).unwrap(); mac.input(data); let result = mac.verify(input_mac); result.is_ok() } HMAC::Blake2b => { let hash = Params::new().hash_length(64).key(key).hash(data); hash.eq(input_mac) } } } }