1#![no_std]
5
6extern crate alloc;
7
8use alloc::vec::Vec;
9
10#[cfg(not(feature = "expose-hacl"))]
11mod hacl {
12 pub(crate) mod hash_sha1;
13 pub(crate) mod hmac;
14}
15
16#[cfg(feature = "expose-hacl")]
17pub mod hacl {
18 pub mod hash_sha1;
19 pub mod hmac;
20}
21
22mod impl_hacl;
23
24pub use impl_hacl::*;
25
26#[derive(Copy, Clone, Debug, PartialEq)]
28pub enum Algorithm {
29 Sha1,
30 Sha256,
33 Sha384,
34 Sha512,
35}
36
37pub const fn tag_size(alg: Algorithm) -> usize {
39 match alg {
40 Algorithm::Sha1 => 20,
41 Algorithm::Sha256 => 32,
42 Algorithm::Sha384 => 48,
43 Algorithm::Sha512 => 64,
44 }
45}
46
47pub fn hmac(alg: Algorithm, key: &[u8], data: &[u8], tag_length: Option<usize>) -> Vec<u8> {
52 let native_tag_length = tag_size(alg);
53 let tag_length = match tag_length {
54 Some(v) => v,
55 None => native_tag_length,
56 };
57 let mut dst: Vec<_> = match alg {
58 Algorithm::Sha1 => wrap_bufalloc(|buf| hmac_sha1(buf, key, data)),
59 Algorithm::Sha256 => wrap_bufalloc(|buf| hmac_sha2_256(buf, key, data)),
60 Algorithm::Sha384 => wrap_bufalloc(|buf| hmac_sha2_384(buf, key, data)),
61 Algorithm::Sha512 => wrap_bufalloc(|buf| hmac_sha2_512(buf, key, data)),
62 };
63 dst.truncate(tag_length);
64 dst
65}
66
67#[inline(always)]
68fn wrap_bufalloc<const N: usize, F: Fn(&mut [u8; N])>(f: F) -> Vec<u8> {
69 let mut buf = [0u8; N];
70 f(&mut buf);
71 buf.to_vec()
72}