1#![no_std]
5
6#[cfg(not(feature = "expose-hacl"))]
7mod hacl {
8 pub(crate) mod hmac;
9}
10
11#[cfg(feature = "expose-hacl")]
12pub mod hacl {
13 pub mod hmac;
14}
15
16mod impl_hacl;
17mod incremental;
18
19pub use impl_hacl::*;
20pub use incremental::*;
21
22pub trait HmacState<const OUTLEN: usize> {
31 fn new(key: &[u8]) -> Result<Self, Error>
33 where
34 Self: Sized;
35
36 fn update(&mut self, data: &[u8]) -> Result<(), Error>;
38
39 fn finalize(self, dst: &mut [u8; OUTLEN]);
41}
42
43#[derive(Debug)]
45pub enum Error {
46 InvalidInputLength,
47}
48
49#[derive(Copy, Clone, Debug, PartialEq)]
54pub enum Algorithm {
55 Sha256,
58 Sha384,
59 Sha512,
60 Sha3_224,
61 Sha3_256,
62 Sha3_384,
63 Sha3_512,
64}
65
66const SHA256_TAG_SIZE: usize = 32;
67const SHA384_TAG_SIZE: usize = 48;
68const SHA512_TAG_SIZE: usize = 64;
69const SHA3_224_TAG_SIZE: usize = 28;
70const SHA3_256_TAG_SIZE: usize = 32;
71const SHA3_384_TAG_SIZE: usize = 48;
72const SHA3_512_TAG_SIZE: usize = 64;
73
74pub const fn tag_size(alg: Algorithm) -> usize {
76 match alg {
77 Algorithm::Sha256 => SHA256_TAG_SIZE,
78 Algorithm::Sha384 => SHA384_TAG_SIZE,
79 Algorithm::Sha512 => SHA512_TAG_SIZE,
80 Algorithm::Sha3_224 => SHA3_224_TAG_SIZE,
81 Algorithm::Sha3_256 => SHA3_256_TAG_SIZE,
82 Algorithm::Sha3_384 => SHA3_384_TAG_SIZE,
83 Algorithm::Sha3_512 => SHA3_512_TAG_SIZE,
84 }
85}
86
87pub fn hmac(alg: Algorithm, key: &[u8], data: &[u8], tag: &mut [u8]) {
97 let tag_len = core::cmp::min(tag.len(), tag_size(alg));
98 match alg {
99 Algorithm::Sha256 => {
100 let mut buf = [0u8; SHA256_TAG_SIZE];
101 hmac_sha2_256(&mut buf, key, data);
102 tag[..tag_len].copy_from_slice(&buf[..tag_len]);
103 }
104 Algorithm::Sha384 => {
105 let mut buf = [0u8; SHA384_TAG_SIZE];
106 hmac_sha2_384(&mut buf, key, data);
107 tag[..tag_len].copy_from_slice(&buf[..tag_len]);
108 }
109 Algorithm::Sha512 => {
110 let mut buf = [0u8; SHA512_TAG_SIZE];
111 hmac_sha2_512(&mut buf, key, data);
112 tag[..tag_len].copy_from_slice(&buf[..tag_len]);
113 }
114 Algorithm::Sha3_224 => {
115 let mut buf = [0u8; SHA3_224_TAG_SIZE];
116 hmac_sha3_224(&mut buf, key, data).expect("HMAC-SHA3 input too long");
117 tag[..tag_len].copy_from_slice(&buf[..tag_len]);
118 }
119 Algorithm::Sha3_256 => {
120 let mut buf = [0u8; SHA3_256_TAG_SIZE];
121 hmac_sha3_256(&mut buf, key, data).expect("HMAC-SHA3 input too long");
122 tag[..tag_len].copy_from_slice(&buf[..tag_len]);
123 }
124 Algorithm::Sha3_384 => {
125 let mut buf = [0u8; SHA3_384_TAG_SIZE];
126 hmac_sha3_384(&mut buf, key, data).expect("HMAC-SHA3 input too long");
127 tag[..tag_len].copy_from_slice(&buf[..tag_len]);
128 }
129 Algorithm::Sha3_512 => {
130 let mut buf = [0u8; SHA3_512_TAG_SIZE];
131 hmac_sha3_512(&mut buf, key, data).expect("HMAC-SHA3 input too long");
132 tag[..tag_len].copy_from_slice(&buf[..tag_len]);
133 }
134 };
135}