dcrypt_algorithms/mac/
mod.rs1use crate::error::Result;
7use dcrypt_internal::constant_time::ConstantTimeEq;
8use dcrypt_internal::zeroing::Zeroize;
9
10pub mod hmac;
11pub mod poly1305;
12
13pub use hmac::Hmac;
15pub use poly1305::{Poly1305, POLY1305_KEY_SIZE, POLY1305_TAG_SIZE};
16
17pub trait MacAlgorithm {
19 const KEY_SIZE: usize;
21
22 const TAG_SIZE: usize;
24
25 const BLOCK_SIZE: usize;
27
28 fn name() -> &'static str;
30}
31
32pub trait Mac: Sized {
34 type Key: AsRef<[u8]> + AsMut<[u8]> + Clone + Zeroize;
36
37 type Tag: AsRef<[u8]> + AsMut<[u8]> + Clone;
39
40 fn new(key: &[u8]) -> Result<Self>;
42
43 fn update(&mut self, data: &[u8]) -> Result<&mut Self>;
45
46 fn finalize(&mut self) -> Result<Self::Tag>;
48
49 fn reset(&mut self) -> Result<()>;
51
52 fn compute_tag(key: &[u8], data: &[u8]) -> Result<Self::Tag> {
54 let mut mac = Self::new(key)?;
55 mac.update(data)?;
56 mac.finalize()
57 }
58
59 fn verify_tag(key: &[u8], data: &[u8], tag: &[u8]) -> Result<bool> {
65 let computed = Self::compute_tag(key, data)?;
66
67 if computed.as_ref().len() != tag.len() {
68 return Ok(false);
69 }
70
71 Ok(computed.as_ref().ct_eq(tag).into())
72 }
73}
74
75pub trait MacBuilder<'a, M: Mac>: Sized {
77 fn update(self, data: &'a [u8]) -> Result<Self>;
79
80 fn update_multi(self, data: &[&'a [u8]]) -> Result<Self>;
82
83 fn finalize(self) -> Result<M::Tag>;
85
86 fn verify(self, expected: &'a [u8]) -> Result<bool>;
88}
89
90pub struct GenericMacBuilder<'a, M: Mac> {
92 mac: &'a mut M,
94}
95
96impl<'a, M: Mac> MacBuilder<'a, M> for GenericMacBuilder<'a, M> {
97 fn update(self, data: &'a [u8]) -> Result<Self> {
98 self.mac.update(data)?;
99 Ok(self)
100 }
101
102 fn update_multi(self, data: &[&'a [u8]]) -> Result<Self> {
103 for chunk in data {
104 self.mac.update(chunk)?;
105 }
106 Ok(self)
107 }
108
109 fn finalize(self) -> Result<M::Tag> {
110 self.mac.finalize()
111 }
112
113 fn verify(self, expected: &'a [u8]) -> Result<bool> {
114 let tag = self.mac.finalize()?;
115
116 if tag.as_ref().len() != expected.len() {
117 return Ok(false);
118 }
119
120 Ok(tag.as_ref().ct_eq(expected).into())
121 }
122}
123
124pub trait MacExt: Mac {
126 fn builder(&mut self) -> GenericMacBuilder<'_, Self>;
128}
129
130impl<T: Mac> MacExt for T {
131 fn builder(&mut self) -> GenericMacBuilder<'_, Self> {
132 GenericMacBuilder { mac: self }
133 }
134}