digest/buffer_macros/
fixed.rs

1/// Creates a buffered wrapper around block-level "core" type which implements fixed output size traits.
2#[macro_export]
3macro_rules! buffer_fixed {
4    (
5        $(#[$attr:meta])*
6        $v:vis struct $name:ident
7        $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)?
8        ($core_ty:ty);
9        impl: $($trait_name:ident)*;
10    ) => {
11        $(#[$attr])*
12        $v struct $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? {
13            core: $core_ty,
14            buffer: $crate::block_api::Buffer<$core_ty>,
15        }
16
17        $crate::buffer_fixed!(
18            impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty);
19            $($trait_name)*;
20        );
21    };
22
23    (
24        $(#[$attr:meta])*
25        $v:vis struct $name:ident
26        $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)?
27        ($core_ty:ty);
28        oid: $oid:literal;
29        impl: $($trait_name:ident)*;
30    ) => {
31        $crate::buffer_fixed!(
32            $(#[$attr])*
33            $v struct $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty);
34            impl: $($trait_name)*;
35        );
36
37        #[cfg(feature = "oid")]
38        impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::const_oid::AssociatedOid for $name$(< $( $lt ),+ >)? {
39            const OID: $crate::const_oid::ObjectIdentifier =
40                $crate::const_oid::ObjectIdentifier::new_unwrap($oid);
41        }
42    };
43
44    // Terminates `impl_inner` sequences.
45    (
46        impl_inner: $name:ident
47        $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)?
48        ($core_ty:ty);
49        ;
50    ) => {};
51
52    // Implements the set of traits common for fixed output hashes:
53    // `Default`, `Clone`, `HashMarker`, `Reset`, `FixedOutputReset`, `SerializableState`
54    (
55        impl_inner: $name:ident
56        $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)?
57        ($core_ty:ty);
58        FixedHashTraits $($trait_name:ident)*;
59    ) => {
60        $crate::buffer_fixed!(
61            impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty);
62            BaseFixedTraits AlgorithmName Default Clone HashMarker
63            Reset FixedOutputReset SerializableState ZeroizeOnDrop $($trait_name)*;
64        );
65    };
66
67    // Implements the set of traits common for MAC functions:
68    // `Debug`, `BlockSizeUser`, `OutputSizeUser`, `CoreProxy`, `Update`, `FixedOutput`, `MacMarker`
69    (
70        impl_inner: $name:ident
71        $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)?
72        ($core_ty:ty);
73        MacTraits $($trait_name:ident)*;
74    ) => {
75        $crate::buffer_fixed!(
76            impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty);
77            BaseFixedTraits MacMarker $($trait_name)*;
78        );
79    };
80
81    // Implements the set of traits common for resettable MAC functions:
82    // `Debug`, `BlockSizeUser`, `OutputSizeUser`, `CoreProxy`, `Update`, `FixedOutput`,
83    // `MacMarker`, `Reset`, `FixedOutputReset`.
84    (
85        impl_inner: $name:ident
86        $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)?
87        ($core_ty:ty);
88        ResetMacTraits $($trait_name:ident)*;
89    ) => {
90        $crate::buffer_fixed!(
91            impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty);
92            MacTraits Reset FixedOutputReset $($trait_name)*;
93        );
94    };
95
96    // Implements basic fixed traits:
97    // `Debug`, `BlockSizeUser`, `OutputSizeUser`, `CoreProxy`, `Update`, and `FixedOutput`.
98    (
99        impl_inner: $name:ident
100        $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)?
101        ($core_ty:ty);
102        BaseFixedTraits $($trait_name:ident)*;
103    ) => {
104        $crate::buffer_fixed!(
105            impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty);
106            Debug BlockSizeUser OutputSizeUser CoreProxy Update FixedOutput $($trait_name)*;
107        );
108    };
109
110    // Implements `Debug`
111    (
112        impl_inner: $name:ident
113        $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)?
114        ($core_ty:ty);
115        Debug $($trait_name:ident)*;
116    ) => {
117        impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? core::fmt::Debug for $name$(< $( $lt ),+ >)? {
118            #[inline]
119            fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
120                f.write_str(concat!(stringify!($name), " { ... }"))
121            }
122        }
123
124        $crate::buffer_fixed!(impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); $($trait_name)*;);
125    };
126
127    // Implements `AlgorithmName`
128    (
129        impl_inner: $name:ident
130        $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)?
131        ($core_ty:ty);
132        AlgorithmName $($trait_name:ident)*;
133    ) => {
134        impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::common::AlgorithmName for $name$(< $( $lt ),+ >)? {
135            #[inline]
136            fn write_alg_name(f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
137                <$core_ty as $crate::common::AlgorithmName>::write_alg_name(f)
138            }
139        }
140
141        $crate::buffer_fixed!(impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); $($trait_name)*;);
142    };
143
144    // Implements `BlockSizeUser`
145    (
146        impl_inner: $name:ident
147        $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)?
148        ($core_ty:ty);
149        BlockSizeUser $($trait_name:ident)*;
150    ) => {
151        impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::block_api::BlockSizeUser for $name$(< $( $lt ),+ >)? {
152            type BlockSize = <$core_ty as $crate::common::BlockSizeUser>::BlockSize;
153        }
154
155        $crate::buffer_fixed!(impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); $($trait_name)*;);
156    };
157
158    // Implements `OutputSizeUser`
159    (
160        impl_inner: $name:ident
161        $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)?
162        ($core_ty:ty);
163        OutputSizeUser $($trait_name:ident)*;
164    ) => {
165        impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::OutputSizeUser for $name$(< $( $lt ),+ >)? {
166            type OutputSize = <$core_ty as $crate::block_api::OutputSizeUser>::OutputSize;
167        }
168
169        $crate::buffer_fixed!(impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); $($trait_name)*;);
170    };
171
172    // Implements `CoreProxy`
173    (
174        impl_inner: $name:ident
175        $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)?
176        ($core_ty:ty);
177        CoreProxy $($trait_name:ident)*;
178    ) => {
179        impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::block_api::CoreProxy for $name$(< $( $lt ),+ >)? {
180            type Core = $core_ty;
181            fn compose(core: Self::Core, buffer: $crate::block_api::Buffer<Self::Core>) -> Self {
182                Self { core, buffer }
183            }
184            fn decompose(self) -> (Self::Core, $crate::block_api::Buffer<Self::Core>) {
185                let Self { core, buffer } = self;
186                (core, buffer)
187            }
188        }
189
190        $crate::buffer_fixed!(impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); $($trait_name)*;);
191    };
192
193    // Implements `Update`
194    (
195        impl_inner: $name:ident
196        $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)?
197        ($core_ty:ty);
198        Update $($trait_name:ident)*;
199    ) => {
200        impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::Update for $name$(< $( $lt ),+ >)? {
201            #[inline]
202            fn update(&mut self, data: &[u8]) {
203                let Self { core, buffer } = self;
204                buffer.digest_blocks(data, |blocks| {
205                    $crate::block_api::UpdateCore::update_blocks(core, blocks)
206                });
207            }
208        }
209
210        $crate::buffer_fixed!(impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); $($trait_name)*;);
211    };
212
213    // Implements `FixedOutput`
214    (
215        impl_inner: $name:ident
216        $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)?
217        ($core_ty:ty);
218        FixedOutput $($trait_name:ident)*;
219    ) => {
220        impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::FixedOutput for $name$(< $( $lt ),+ >)? {
221            #[inline]
222            fn finalize_into(mut self, out: &mut $crate::Output<Self>) {
223                let Self { core, buffer } = &mut self;
224                $crate::block_api::FixedOutputCore::finalize_fixed_core(core, buffer, out);
225            }
226        }
227
228        $crate::buffer_fixed!(impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); $($trait_name)*;);
229    };
230
231    // Implements `Default`
232    (
233        impl_inner: $name:ident
234        $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)?
235        ($core_ty:ty);
236        Default $($trait_name:ident)*;
237    ) => {
238        impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? Default for $name$(< $( $lt ),+ >)? {
239            #[inline]
240            fn default() -> Self {
241                Self {
242                    core: Default::default(),
243                    buffer: Default::default(),
244                }
245            }
246        }
247
248        $crate::buffer_fixed!(impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); $($trait_name)*;);
249    };
250
251    // Implements `CustomizedInit`
252    (
253        impl_inner: $name:ident
254        $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)?
255        ($core_ty:ty);
256        CustomizedInit $($trait_name:ident)*;
257    ) => {
258        impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::CustomizedInit for $name$(< $( $lt ),+ >)? {
259            #[inline]
260            fn new_customized(customization: &[u8]) -> Self {
261                Self {
262                    core: $crate::CustomizedInit::new_customized(customization),
263                    buffer: Default::default(),
264                }
265            }
266        }
267
268        $crate::buffer_fixed!(impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); $($trait_name)*;);
269    };
270
271    // Implements `Clone`
272    (
273        impl_inner: $name:ident
274        $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)?
275        ($core_ty:ty);
276        Clone $($trait_name:ident)*;
277    ) => {
278        impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? Clone for $name$(< $( $lt ),+ >)? {
279            #[inline]
280            fn clone(&self) -> Self {
281                Self {
282                    core: Clone::clone(&self.core),
283                    buffer: Clone::clone(&self.buffer),
284                }
285            }
286        }
287
288        $crate::buffer_fixed!(impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); $($trait_name)*;);
289    };
290
291    // Implements `HashMarker` and asserts that `$core_ty` implements it
292    (
293        impl_inner: $name:ident
294        $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)?
295        ($core_ty:ty);
296        HashMarker $($trait_name:ident)*;
297    ) => {
298        impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::HashMarker for $name$(< $( $lt ),+ >)? {}
299
300        // Verify that `$core_ty` implements `HashMarker`
301        const _: () = {
302            fn check$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?(v: &$core_ty) {
303                v as &dyn $crate::HashMarker;
304            }
305        };
306
307        $crate::buffer_fixed!(impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); $($trait_name)*;);
308    };
309
310    // Implements `MacMarker` and asserts that `$core_ty` implements it
311    (
312        impl_inner: $name:ident
313        $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)?
314        ($core_ty:ty);
315        MacMarker $($trait_name:ident)*;
316    ) => {
317        impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::MacMarker for $name$(< $( $lt ),+ >)? {}
318
319        // Verify that `$core_ty` implements `MacMarker`
320        const _: () = {
321            fn check$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?(v: &$core_ty) {
322                v as &dyn $crate::MacMarker;
323            }
324        };
325
326        $crate::buffer_fixed!(impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); $($trait_name)*;);
327    };
328
329    // Implements `InnerUser` and `InnerInit`
330    (
331        impl_inner: $name:ident
332        $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)?
333        ($core_ty:ty);
334        InnerInit $($trait_name:ident)*;
335    ) => {
336        impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::common::InnerUser for $name$(< $( $lt ),+ >)? {
337            type Inner = <$core_ty as $crate::common::InnerUser>::Inner;
338        }
339
340        impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::common::InnerInit for $name$(< $( $lt ),+ >)? {
341            #[inline]
342            fn inner_init(inner: Self::Inner) -> Self {
343                Self {
344                    core: <$core_ty as $crate::common::InnerInit>::inner_init(inner),
345                    buffer: Default::default(),
346                }
347            }
348        }
349
350        $crate::buffer_fixed!(impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); $($trait_name)*;);
351    };
352
353    // Implements `KeySizeUser` and `KeyInit`
354    (
355        impl_inner: $name:ident
356        $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)?
357        ($core_ty:ty);
358        KeyInit $($trait_name:ident)*;
359    ) => {
360        impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::common::KeySizeUser for $name$(< $( $lt ),+ >)? {
361            type KeySize = <$core_ty as $crate::common::KeySizeUser>::KeySize;
362        }
363
364        impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::KeyInit for $name$(< $( $lt ),+ >)? {
365            #[inline]
366            fn new(key: &$crate::Key<Self>) -> Self {
367                Self {
368                    core: <$core_ty as $crate::KeyInit>::new(key),
369                    buffer: Default::default(),
370                }
371            }
372
373            #[inline]
374            fn new_from_slice(key: &[u8]) -> Result<Self, $crate::InvalidLength> {
375                <$core_ty as $crate::KeyInit>::new_from_slice(key).map(|core|
376                    Self { core, buffer: Default::default() }
377                )
378            }
379        }
380
381        $crate::buffer_fixed!(impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); $($trait_name)*;);
382    };
383
384    // Implements `Reset`
385    (
386        impl_inner: $name:ident
387        $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)?
388        ($core_ty:ty);
389        Reset $($trait_name:ident)*;
390    ) => {
391        impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::Reset for $name$(< $( $lt ),+ >)? {
392            #[inline]
393            fn reset(&mut self) {
394                $crate::Reset::reset(&mut self.core);
395                self.buffer.reset();
396            }
397        }
398
399        $crate::buffer_fixed!(impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); $($trait_name)*;);
400    };
401
402    // Implements `FixedOutputReset`
403    (
404        impl_inner: $name:ident
405        $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)?
406        ($core_ty:ty);
407        FixedOutputReset $($trait_name:ident)*;
408    ) => {
409        impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::FixedOutputReset for $name$(< $( $lt ),+ >)? {
410            #[inline]
411            fn finalize_into_reset(&mut self, out: &mut $crate::Output<Self>) {
412                let Self { core, buffer } = self;
413                $crate::block_api::FixedOutputCore::finalize_fixed_core(core, buffer, out);
414                $crate::Reset::reset(self);
415            }
416        }
417
418        $crate::buffer_fixed!(impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); $($trait_name)*;);
419    };
420
421    // Implements `SerializableState`
422    (
423        impl_inner: $name:ident
424        $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)?
425        ($core_ty:ty);
426        SerializableState $($trait_name:ident)*;
427    ) => {
428        impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::common::hazmat::SerializableState for $name$(< $( $lt ),+ >)? {
429            type SerializedStateSize = $crate::typenum::Sum<
430                <$core_ty as $crate::common::hazmat::SerializableState>::SerializedStateSize,
431                $crate::block_buffer::SerializedBufferSize<
432                    <$core_ty as $crate::block_api::BlockSizeUser>::BlockSize,
433                    <$core_ty as $crate::block_api::BufferKindUser>::BufferKind,
434                >
435            >;
436
437            #[inline]
438            fn serialize(&self) -> $crate::common::hazmat::SerializedState<Self> {
439                let serialized_core = self.core.serialize();
440                let serialized_buf = self.buffer.serialize();
441                serialized_core.concat(serialized_buf)
442            }
443
444            #[inline]
445            fn deserialize(
446                serialized_state: &$crate::common::hazmat::SerializedState<Self>,
447            ) -> Result<Self, $crate::common::hazmat::DeserializeStateError> {
448                use $crate::common::hazmat::{SerializableState, DeserializeStateError};
449
450                let (serialized_core, serialized_buf) = serialized_state
451                    .split_ref::<<$core_ty as SerializableState>::SerializedStateSize>();
452
453                let core = SerializableState::deserialize(serialized_core)?;
454                let buffer = $crate::block_buffer::BlockBuffer::deserialize(serialized_buf)
455                    .map_err(|_| DeserializeStateError)?;
456
457                Ok(Self { core, buffer })
458            }
459        }
460
461        $crate::buffer_fixed!(impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); $($trait_name)*;);
462    };
463
464    // Implements `ZeroizeOnDrop`
465    (
466        impl_inner: $name:ident
467        $(< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)?
468        ($core_ty:ty);
469        ZeroizeOnDrop $($trait_name:ident)*;
470    ) => {
471        // Verify that `$core_ty` and `Buffer<$core_ty>` implement `ZeroizeOnDrop`
472        #[cfg(feature = "zeroize")]
473        const _: () = {
474            fn check_core$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?(v: &$core_ty) {
475                v as &dyn $crate::zeroize::ZeroizeOnDrop;
476            }
477
478            fn check_buffer$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?(v: &$crate::block_api::Buffer<$core_ty>) {
479                v as &dyn $crate::zeroize::ZeroizeOnDrop;
480            }
481        };
482
483        #[cfg(feature = "zeroize")]
484        impl$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $crate::zeroize::ZeroizeOnDrop for $name$(< $( $lt ),+ >)? {}
485
486        $crate::buffer_fixed!(impl_inner: $name$(< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)?($core_ty); $($trait_name)*;);
487    };
488}