#![no_std]
#[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,
Sha3_224,
Sha3_256,
Sha3_384,
Sha3_512,
}
const SHA256_TAG_SIZE: usize = 32;
const SHA384_TAG_SIZE: usize = 48;
const SHA512_TAG_SIZE: usize = 64;
const SHA3_224_TAG_SIZE: usize = 28;
const SHA3_256_TAG_SIZE: usize = 32;
const SHA3_384_TAG_SIZE: usize = 48;
const SHA3_512_TAG_SIZE: usize = 64;
pub const fn tag_size(alg: Algorithm) -> usize {
match alg {
Algorithm::Sha256 => SHA256_TAG_SIZE,
Algorithm::Sha384 => SHA384_TAG_SIZE,
Algorithm::Sha512 => SHA512_TAG_SIZE,
Algorithm::Sha3_224 => SHA3_224_TAG_SIZE,
Algorithm::Sha3_256 => SHA3_256_TAG_SIZE,
Algorithm::Sha3_384 => SHA3_384_TAG_SIZE,
Algorithm::Sha3_512 => SHA3_512_TAG_SIZE,
}
}
pub fn hmac(alg: Algorithm, key: &[u8], data: &[u8], tag: &mut [u8]) {
let tag_len = core::cmp::min(tag.len(), tag_size(alg));
match alg {
Algorithm::Sha256 => {
let mut buf = [0u8; SHA256_TAG_SIZE];
hmac_sha2_256(&mut buf, key, data);
tag[..tag_len].copy_from_slice(&buf[..tag_len]);
}
Algorithm::Sha384 => {
let mut buf = [0u8; SHA384_TAG_SIZE];
hmac_sha2_384(&mut buf, key, data);
tag[..tag_len].copy_from_slice(&buf[..tag_len]);
}
Algorithm::Sha512 => {
let mut buf = [0u8; SHA512_TAG_SIZE];
hmac_sha2_512(&mut buf, key, data);
tag[..tag_len].copy_from_slice(&buf[..tag_len]);
}
Algorithm::Sha3_224 => {
let mut buf = [0u8; SHA3_224_TAG_SIZE];
hmac_sha3_224(&mut buf, key, data).expect("HMAC-SHA3 input too long");
tag[..tag_len].copy_from_slice(&buf[..tag_len]);
}
Algorithm::Sha3_256 => {
let mut buf = [0u8; SHA3_256_TAG_SIZE];
hmac_sha3_256(&mut buf, key, data).expect("HMAC-SHA3 input too long");
tag[..tag_len].copy_from_slice(&buf[..tag_len]);
}
Algorithm::Sha3_384 => {
let mut buf = [0u8; SHA3_384_TAG_SIZE];
hmac_sha3_384(&mut buf, key, data).expect("HMAC-SHA3 input too long");
tag[..tag_len].copy_from_slice(&buf[..tag_len]);
}
Algorithm::Sha3_512 => {
let mut buf = [0u8; SHA3_512_TAG_SIZE];
hmac_sha3_512(&mut buf, key, data).expect("HMAC-SHA3 input too long");
tag[..tag_len].copy_from_slice(&buf[..tag_len]);
}
};
}