Skip to main content
This is unreleased documentation for the main (development) branch of crypto-glue.

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