#![no_std]
extern crate alloc;
use alloc::vec::Vec;
#[cfg(not(feature = "expose-hacl"))]
mod hacl {
pub(crate) mod hmac;
}
#[cfg(feature = "expose-hacl")]
pub mod hacl {
pub mod hmac;
}
mod impl_hacl;
mod incremental;
pub use impl_hacl::*;
pub use incremental::*;
pub trait HmacState<const OUTLEN: usize> {
fn new(key: &[u8]) -> Result<Self, Error>
where
Self: Sized;
fn update(&mut self, data: &[u8]) -> Result<(), Error>;
fn finalize(self, dst: &mut [u8; OUTLEN]);
}
#[derive(Debug)]
pub enum Error {
InvalidInputLength,
}
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum Algorithm {
Sha256,
Sha384,
Sha512,
}
pub const fn tag_size(alg: Algorithm) -> usize {
match alg {
Algorithm::Sha256 => 32,
Algorithm::Sha384 => 48,
Algorithm::Sha512 => 64,
}
}
pub fn hmac(alg: Algorithm, key: &[u8], data: &[u8], tag_length: Option<usize>) -> Vec<u8> {
let native_tag_length = tag_size(alg);
let tag_length = match tag_length {
Some(v) => v,
None => native_tag_length,
};
let mut dst: Vec<_> = match alg {
Algorithm::Sha256 => wrap_bufalloc(|buf| hmac_sha2_256(buf, key, data)),
Algorithm::Sha384 => wrap_bufalloc(|buf| hmac_sha2_384(buf, key, data)),
Algorithm::Sha512 => wrap_bufalloc(|buf| hmac_sha2_512(buf, key, data)),
};
dst.truncate(tag_length);
dst
}
#[inline(always)]
fn wrap_bufalloc<const N: usize, F: Fn(&mut [u8; N])>(f: F) -> Vec<u8> {
let mut buf = [0u8; N];
f(&mut buf);
buf.to_vec()
}