evidence 0.1.0

Type-level tags for cryptographic primitives
Documentation
//! HMAC implementations.

use super::MacPrimitive;
use hmac::digest::CtOutput;
use hmac::{Hmac, Mac as HmacMac};

/// HMAC-SHA256 MAC primitive (32-byte tag).
#[derive(Debug, Clone, Copy)]
pub enum HmacSha256 {}

impl MacPrimitive for HmacSha256 {
    type Key = hmac::digest::Key<Hmac<sha2::Sha256>>;
    type Tag = [u8; 32];
    type Error = hmac::digest::MacError;

    fn mac(key: &Self::Key, message: &[u8]) -> Self::Tag {
        let mut mac = <Hmac<sha2::Sha256> as hmac::digest::KeyInit>::new(key);
        hmac::digest::Update::update(&mut mac, message);
        let result: CtOutput<Hmac<sha2::Sha256>> = mac.finalize();
        let bytes: [u8; 32] = result.into_bytes().into();
        bytes
    }

    fn verify(key: &Self::Key, message: &[u8], tag: &Self::Tag) -> Result<(), Self::Error> {
        let mut mac = <Hmac<sha2::Sha256> as hmac::digest::KeyInit>::new(key);
        hmac::digest::Update::update(&mut mac, message);
        mac.verify_slice(tag)
    }
}

/// HMAC-SHA384 MAC primitive (48-byte tag).
#[derive(Debug, Clone, Copy)]
pub enum HmacSha384 {}

impl MacPrimitive for HmacSha384 {
    type Key = hmac::digest::Key<Hmac<sha2::Sha384>>;
    type Tag = [u8; 48];
    type Error = hmac::digest::MacError;

    fn mac(key: &Self::Key, message: &[u8]) -> Self::Tag {
        let mut mac = <Hmac<sha2::Sha384> as hmac::digest::KeyInit>::new(key);
        hmac::digest::Update::update(&mut mac, message);
        let result: CtOutput<Hmac<sha2::Sha384>> = mac.finalize();
        let bytes: [u8; 48] = result.into_bytes().into();
        bytes
    }

    fn verify(key: &Self::Key, message: &[u8], tag: &Self::Tag) -> Result<(), Self::Error> {
        let mut mac = <Hmac<sha2::Sha384> as hmac::digest::KeyInit>::new(key);
        hmac::digest::Update::update(&mut mac, message);
        mac.verify_slice(tag)
    }
}

/// HMAC-SHA512 MAC primitive (64-byte tag).
#[derive(Debug, Clone, Copy)]
pub enum HmacSha512 {}

impl MacPrimitive for HmacSha512 {
    type Key = hmac::digest::Key<Hmac<sha2::Sha512>>;
    type Tag = [u8; 64];
    type Error = hmac::digest::MacError;

    fn mac(key: &Self::Key, message: &[u8]) -> Self::Tag {
        let mut mac = <Hmac<sha2::Sha512> as hmac::digest::KeyInit>::new(key);
        hmac::digest::Update::update(&mut mac, message);
        let result: CtOutput<Hmac<sha2::Sha512>> = mac.finalize();
        let bytes: [u8; 64] = result.into_bytes().into();
        bytes
    }

    fn verify(key: &Self::Key, message: &[u8], tag: &Self::Tag) -> Result<(), Self::Error> {
        let mut mac = <Hmac<sha2::Sha512> as hmac::digest::KeyInit>::new(key);
        hmac::digest::Update::update(&mut mac, message);
        mac.verify_slice(tag)
    }
}