/rust/registry/src/index.crates.io-1949cf8c6b5b557f/hmac-0.12.1/src/optim.rs
Line | Count | Source |
1 | | use super::{get_der_key, IPAD, OPAD}; |
2 | | use core::{fmt, slice}; |
3 | | #[cfg(feature = "reset")] |
4 | | use digest::Reset; |
5 | | use digest::{ |
6 | | block_buffer::Eager, |
7 | | core_api::{ |
8 | | AlgorithmName, Block, BlockSizeUser, Buffer, BufferKindUser, CoreProxy, CoreWrapper, |
9 | | FixedOutputCore, OutputSizeUser, UpdateCore, |
10 | | }, |
11 | | crypto_common::{Key, KeySizeUser}, |
12 | | generic_array::typenum::{IsLess, Le, NonZero, U256}, |
13 | | HashMarker, InvalidLength, KeyInit, MacMarker, Output, |
14 | | }; |
15 | | |
16 | | /// Generic HMAC instance. |
17 | | pub type Hmac<D> = CoreWrapper<HmacCore<D>>; |
18 | | |
19 | | /// Generic core HMAC instance, which operates over blocks. |
20 | | pub struct HmacCore<D> |
21 | | where |
22 | | D: CoreProxy, |
23 | | D::Core: HashMarker |
24 | | + UpdateCore |
25 | | + FixedOutputCore |
26 | | + BufferKindUser<BufferKind = Eager> |
27 | | + Default |
28 | | + Clone, |
29 | | <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>, |
30 | | Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero, |
31 | | { |
32 | | digest: D::Core, |
33 | | opad_digest: D::Core, |
34 | | #[cfg(feature = "reset")] |
35 | | ipad_digest: D::Core, |
36 | | } |
37 | | |
38 | | impl<D> Clone for HmacCore<D> |
39 | | where |
40 | | D: CoreProxy, |
41 | | D::Core: HashMarker |
42 | | + UpdateCore |
43 | | + FixedOutputCore |
44 | | + BufferKindUser<BufferKind = Eager> |
45 | | + Default |
46 | | + Clone, |
47 | | <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>, |
48 | | Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero, |
49 | | { |
50 | 0 | fn clone(&self) -> Self { |
51 | 0 | Self { |
52 | 0 | digest: self.digest.clone(), |
53 | 0 | opad_digest: self.opad_digest.clone(), |
54 | 0 | #[cfg(feature = "reset")] |
55 | 0 | ipad_digest: self.ipad_digest.clone(), |
56 | 0 | } |
57 | 0 | } |
58 | | } |
59 | | |
60 | | impl<D> MacMarker for HmacCore<D> |
61 | | where |
62 | | D: CoreProxy, |
63 | | D::Core: HashMarker |
64 | | + UpdateCore |
65 | | + FixedOutputCore |
66 | | + BufferKindUser<BufferKind = Eager> |
67 | | + Default |
68 | | + Clone, |
69 | | <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>, |
70 | | Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero, |
71 | | { |
72 | | } |
73 | | |
74 | | impl<D> BufferKindUser for HmacCore<D> |
75 | | where |
76 | | D: CoreProxy, |
77 | | D::Core: HashMarker |
78 | | + UpdateCore |
79 | | + FixedOutputCore |
80 | | + BufferKindUser<BufferKind = Eager> |
81 | | + Default |
82 | | + Clone, |
83 | | <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>, |
84 | | Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero, |
85 | | { |
86 | | type BufferKind = Eager; |
87 | | } |
88 | | |
89 | | impl<D> KeySizeUser for HmacCore<D> |
90 | | where |
91 | | D: CoreProxy, |
92 | | D::Core: HashMarker |
93 | | + UpdateCore |
94 | | + FixedOutputCore |
95 | | + BufferKindUser<BufferKind = Eager> |
96 | | + Default |
97 | | + Clone, |
98 | | <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>, |
99 | | Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero, |
100 | | { |
101 | | type KeySize = <<D as CoreProxy>::Core as BlockSizeUser>::BlockSize; |
102 | | } |
103 | | |
104 | | impl<D> BlockSizeUser for HmacCore<D> |
105 | | where |
106 | | D: CoreProxy, |
107 | | D::Core: HashMarker |
108 | | + UpdateCore |
109 | | + FixedOutputCore |
110 | | + BufferKindUser<BufferKind = Eager> |
111 | | + Default |
112 | | + Clone, |
113 | | <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>, |
114 | | Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero, |
115 | | { |
116 | | type BlockSize = <<D as CoreProxy>::Core as BlockSizeUser>::BlockSize; |
117 | | } |
118 | | |
119 | | impl<D> OutputSizeUser for HmacCore<D> |
120 | | where |
121 | | D: CoreProxy, |
122 | | D::Core: HashMarker |
123 | | + UpdateCore |
124 | | + FixedOutputCore |
125 | | + BufferKindUser<BufferKind = Eager> |
126 | | + Default |
127 | | + Clone, |
128 | | <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>, |
129 | | Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero, |
130 | | { |
131 | | type OutputSize = <<D as CoreProxy>::Core as OutputSizeUser>::OutputSize; |
132 | | } |
133 | | |
134 | | impl<D> KeyInit for HmacCore<D> |
135 | | where |
136 | | D: CoreProxy, |
137 | | D::Core: HashMarker |
138 | | + UpdateCore |
139 | | + FixedOutputCore |
140 | | + BufferKindUser<BufferKind = Eager> |
141 | | + Default |
142 | | + Clone, |
143 | | <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>, |
144 | | Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero, |
145 | | { |
146 | | #[inline(always)] |
147 | | fn new(key: &Key<Self>) -> Self { |
148 | | Self::new_from_slice(key.as_slice()).unwrap() |
149 | | } |
150 | | |
151 | | #[inline(always)] |
152 | 0 | fn new_from_slice(key: &[u8]) -> Result<Self, InvalidLength> { |
153 | 0 | let mut buf = get_der_key::<CoreWrapper<D::Core>>(key); |
154 | 0 | for b in buf.iter_mut() { |
155 | 0 | *b ^= IPAD; |
156 | 0 | } |
157 | 0 | let mut digest = D::Core::default(); |
158 | 0 | digest.update_blocks(slice::from_ref(&buf)); |
159 | | |
160 | 0 | for b in buf.iter_mut() { |
161 | 0 | *b ^= IPAD ^ OPAD; |
162 | 0 | } |
163 | | |
164 | 0 | let mut opad_digest = D::Core::default(); |
165 | 0 | opad_digest.update_blocks(slice::from_ref(&buf)); |
166 | | |
167 | 0 | Ok(Self { |
168 | 0 | #[cfg(feature = "reset")] |
169 | 0 | ipad_digest: digest.clone(), |
170 | 0 | opad_digest, |
171 | 0 | digest, |
172 | 0 | }) |
173 | 0 | } |
174 | | } |
175 | | |
176 | | impl<D> UpdateCore for HmacCore<D> |
177 | | where |
178 | | D: CoreProxy, |
179 | | D::Core: HashMarker |
180 | | + UpdateCore |
181 | | + FixedOutputCore |
182 | | + BufferKindUser<BufferKind = Eager> |
183 | | + Default |
184 | | + Clone, |
185 | | <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>, |
186 | | Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero, |
187 | | { |
188 | | #[inline(always)] |
189 | 0 | fn update_blocks(&mut self, blocks: &[Block<Self>]) { |
190 | 0 | self.digest.update_blocks(blocks); |
191 | 0 | } |
192 | | } |
193 | | |
194 | | impl<D> FixedOutputCore for HmacCore<D> |
195 | | where |
196 | | D: CoreProxy, |
197 | | D::Core: HashMarker |
198 | | + UpdateCore |
199 | | + FixedOutputCore |
200 | | + BufferKindUser<BufferKind = Eager> |
201 | | + Default |
202 | | + Clone, |
203 | | <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>, |
204 | | Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero, |
205 | | { |
206 | | #[inline(always)] |
207 | 0 | fn finalize_fixed_core(&mut self, buffer: &mut Buffer<Self>, out: &mut Output<Self>) { |
208 | 0 | let mut hash = Output::<D::Core>::default(); |
209 | 0 | self.digest.finalize_fixed_core(buffer, &mut hash); |
210 | | // finalize_fixed_core should reset the buffer as well, but |
211 | | // to be extra safe we reset it explicitly again. |
212 | 0 | buffer.reset(); |
213 | | #[cfg(not(feature = "reset"))] |
214 | | let h = &mut self.opad_digest; |
215 | | #[cfg(feature = "reset")] |
216 | 0 | let mut h = self.opad_digest.clone(); |
217 | 0 | buffer.digest_blocks(&hash, |b| h.update_blocks(b)); |
218 | 0 | h.finalize_fixed_core(buffer, out); |
219 | 0 | } |
220 | | } |
221 | | |
222 | | #[cfg(feature = "reset")] |
223 | | #[cfg_attr(docsrs, doc(cfg(feature = "reset")))] |
224 | | impl<D> Reset for HmacCore<D> |
225 | | where |
226 | | D: CoreProxy, |
227 | | D::Core: HashMarker |
228 | | + UpdateCore |
229 | | + FixedOutputCore |
230 | | + BufferKindUser<BufferKind = Eager> |
231 | | + Default |
232 | | + Clone, |
233 | | <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>, |
234 | | Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero, |
235 | | { |
236 | | #[inline(always)] |
237 | 0 | fn reset(&mut self) { |
238 | 0 | self.digest = self.ipad_digest.clone(); |
239 | 0 | } |
240 | | } |
241 | | |
242 | | impl<D> AlgorithmName for HmacCore<D> |
243 | | where |
244 | | D: CoreProxy, |
245 | | D::Core: HashMarker |
246 | | + AlgorithmName |
247 | | + UpdateCore |
248 | | + FixedOutputCore |
249 | | + BufferKindUser<BufferKind = Eager> |
250 | | + Default |
251 | | + Clone, |
252 | | <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>, |
253 | | Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero, |
254 | | { |
255 | | fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { |
256 | | f.write_str("Hmac<")?; |
257 | | <D::Core as AlgorithmName>::write_alg_name(f)?; |
258 | | f.write_str(">") |
259 | | } |
260 | | } |
261 | | |
262 | | impl<D> fmt::Debug for HmacCore<D> |
263 | | where |
264 | | D: CoreProxy, |
265 | | D::Core: HashMarker |
266 | | + AlgorithmName |
267 | | + UpdateCore |
268 | | + FixedOutputCore |
269 | | + BufferKindUser<BufferKind = Eager> |
270 | | + Default |
271 | | + Clone, |
272 | | <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>, |
273 | | Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero, |
274 | | { |
275 | | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
276 | | f.write_str("HmacCore<")?; |
277 | | <D::Core as AlgorithmName>::write_alg_name(f)?; |
278 | | f.write_str("> { ... }") |
279 | | } |
280 | | } |