crypto_common/
lib.rs

1//! Common cryptographic traits.
2
3#![no_std]
4#![cfg_attr(docsrs, feature(doc_auto_cfg))]
5#![doc(
6    html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg",
7    html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg"
8)]
9#![forbid(unsafe_code)]
10#![warn(missing_docs, rust_2018_idioms, missing_debug_implementations)]
11
12/// Hazardous materials.
13pub mod hazmat;
14
15#[cfg(feature = "rand_core")]
16pub use rand_core;
17
18pub use hybrid_array as array;
19pub use hybrid_array::typenum;
20
21use core::fmt;
22use hybrid_array::{
23    Array, ArraySize,
24    typenum::{Diff, Sum, Unsigned},
25};
26
27#[cfg(feature = "rand_core")]
28use rand_core::{CryptoRng, TryCryptoRng};
29#[cfg(feature = "os_rng")]
30use rand_core::{OsError, OsRng, TryRngCore};
31
32/// Block on which [`BlockSizeUser`] implementors operate.
33pub type Block<B> = Array<u8, <B as BlockSizeUser>::BlockSize>;
34
35/// Parallel blocks on which [`ParBlocksSizeUser`] implementors operate.
36pub type ParBlocks<T> = Array<Block<T>, <T as ParBlocksSizeUser>::ParBlocksSize>;
37
38/// Output array of [`OutputSizeUser`] implementors.
39pub type Output<T> = Array<u8, OutputSize<T>>;
40
41/// Alias for the output size of [`OutputSizeUser`] implementors.
42pub type OutputSize<T> = <T as OutputSizeUser>::OutputSize;
43
44/// Key used by [`KeySizeUser`] implementors.
45pub type Key<B> = Array<u8, <B as KeySizeUser>::KeySize>;
46
47/// Initialization vector (nonce) used by [`IvSizeUser`] implementors.
48pub type Iv<B> = Array<u8, <B as IvSizeUser>::IvSize>;
49
50/// Alias for `AddBlockSize<A, B> = Sum<T, B::BlockSize>`
51pub type AddBlockSize<T, B> = Sum<T, <B as BlockSizeUser>::BlockSize>;
52
53/// Alias for `SubBlockSize<A, B> = Diff<T, B::BlockSize>`
54pub type SubBlockSize<T, B> = Diff<T, <B as BlockSizeUser>::BlockSize>;
55
56/// Types which process data in blocks.
57pub trait BlockSizeUser {
58    /// Size of the block in bytes.
59    type BlockSize: BlockSizes;
60
61    /// Return block size in bytes.
62    #[inline(always)]
63    fn block_size() -> usize {
64        Self::BlockSize::USIZE
65    }
66}
67
68impl<T: BlockSizeUser> BlockSizeUser for &T {
69    type BlockSize = T::BlockSize;
70}
71
72impl<T: BlockSizeUser> BlockSizeUser for &mut T {
73    type BlockSize = T::BlockSize;
74}
75
76/// Trait implemented for supported block sizes, i.e. for types from `U1` to `U255`.
77pub trait BlockSizes: ArraySize + sealed::BlockSizes {}
78
79impl<T: ArraySize + sealed::BlockSizes> BlockSizes for T {}
80
81mod sealed {
82    use crate::typenum::{Gr, IsGreater, IsLess, Le, NonZero, U0, U256, Unsigned};
83
84    pub trait BlockSizes {}
85
86    impl<T: Unsigned> BlockSizes for T
87    where
88        Self: IsLess<U256> + IsGreater<U0>,
89        Le<Self, U256>: NonZero,
90        Gr<Self, U0>: NonZero,
91    {
92    }
93}
94
95/// Types which can process blocks in parallel.
96pub trait ParBlocksSizeUser: BlockSizeUser {
97    /// Number of blocks which can be processed in parallel.
98    type ParBlocksSize: ArraySize;
99}
100
101/// Types which return data with the given size.
102pub trait OutputSizeUser {
103    /// Size of the output in bytes.
104    type OutputSize: ArraySize;
105
106    /// Return output size in bytes.
107    #[inline(always)]
108    fn output_size() -> usize {
109        Self::OutputSize::USIZE
110    }
111}
112
113/// Types which use key for initialization.
114///
115/// Generally it's used indirectly via [`KeyInit`] or [`KeyIvInit`].
116pub trait KeySizeUser {
117    /// Key size in bytes.
118    type KeySize: ArraySize;
119
120    /// Return key size in bytes.
121    #[inline(always)]
122    fn key_size() -> usize {
123        Self::KeySize::USIZE
124    }
125}
126
127/// Types which use initialization vector (nonce) for initialization.
128///
129/// Generally it's used indirectly via [`KeyIvInit`] or [`InnerIvInit`].
130pub trait IvSizeUser {
131    /// Initialization vector size in bytes.
132    type IvSize: ArraySize;
133
134    /// Return IV size in bytes.
135    #[inline(always)]
136    fn iv_size() -> usize {
137        Self::IvSize::USIZE
138    }
139}
140
141/// Types which use another type for initialization.
142///
143/// Generally it's used indirectly via [`InnerInit`] or [`InnerIvInit`].
144pub trait InnerUser {
145    /// Inner type.
146    type Inner;
147}
148
149/// Resettable types.
150pub trait Reset {
151    /// Reset state to its initial value.
152    fn reset(&mut self);
153}
154
155/// Trait which stores algorithm name constant, used in `Debug` implementations.
156pub trait AlgorithmName {
157    /// Write algorithm name into `f`.
158    fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result;
159}
160
161/// Types which can be initialized from key.
162pub trait KeyInit: KeySizeUser + Sized {
163    /// Create new value from fixed size key.
164    fn new(key: &Key<Self>) -> Self;
165
166    /// Check if the key might be considered weak.
167    #[inline]
168    fn weak_key_test(_key: &Key<Self>) -> Result<(), WeakKeyError> {
169        Ok(())
170    }
171
172    /// Create new value from fixed size key after checking it for weakness.
173    #[inline]
174    fn new_checked(key: &Key<Self>) -> Result<Self, WeakKeyError> {
175        Self::weak_key_test(key)?;
176        Ok(Self::new(key))
177    }
178
179    /// Create new value from variable size key.
180    #[inline]
181    fn new_from_slice(key: &[u8]) -> Result<Self, InvalidLength> {
182        <&Key<Self>>::try_from(key)
183            .map(Self::new)
184            .map_err(|_| InvalidLength)
185    }
186
187    /// Generate random key using the operating system's secure RNG.
188    #[cfg(feature = "os_rng")]
189    #[inline]
190    fn generate_key() -> Result<Key<Self>, OsError> {
191        let mut key = Key::<Self>::default();
192        OsRng.try_fill_bytes(&mut key)?;
193        Ok(key)
194    }
195
196    /// Generate random key using the provided [`CryptoRng`].
197    #[cfg(feature = "rand_core")]
198    #[inline]
199    fn generate_key_with_rng<R: CryptoRng>(rng: &mut R) -> Key<Self> {
200        let mut key = Key::<Self>::default();
201        rng.fill_bytes(&mut key);
202        key
203    }
204
205    /// Generate random key using the provided [`TryCryptoRng`].
206    #[cfg(feature = "rand_core")]
207    #[inline]
208    fn try_generate_key_with_rng<R: TryCryptoRng>(rng: &mut R) -> Result<Key<Self>, R::Error> {
209        let mut key = Key::<Self>::default();
210        rng.try_fill_bytes(&mut key)?;
211        Ok(key)
212    }
213}
214
215/// Types which can be initialized from key and initialization vector (nonce).
216pub trait KeyIvInit: KeySizeUser + IvSizeUser + Sized {
217    /// Create new value from fixed length key and nonce.
218    fn new(key: &Key<Self>, iv: &Iv<Self>) -> Self;
219
220    /// Check if the key might be considered weak.
221    #[inline]
222    fn weak_key_test(_key: &Key<Self>) -> Result<(), WeakKeyError> {
223        Ok(())
224    }
225
226    /// Create new value from fixed length key and nonce after checking the key for weakness.
227    #[inline]
228    fn new_checked(key: &Key<Self>, iv: &Iv<Self>) -> Result<Self, WeakKeyError> {
229        Self::weak_key_test(key)?;
230        Ok(Self::new(key, iv))
231    }
232
233    /// Create new value from variable length key and nonce.
234    #[inline]
235    fn new_from_slices(key: &[u8], iv: &[u8]) -> Result<Self, InvalidLength> {
236        let key = <&Key<Self>>::try_from(key).map_err(|_| InvalidLength)?;
237        let iv = <&Iv<Self>>::try_from(iv).map_err(|_| InvalidLength)?;
238        Ok(Self::new(key, iv))
239    }
240
241    /// Generate random key using the operating system's secure RNG.
242    #[cfg(feature = "os_rng")]
243    #[inline]
244    fn generate_key() -> Result<Key<Self>, OsError> {
245        let mut key = Key::<Self>::default();
246        OsRng.try_fill_bytes(&mut key)?;
247        Ok(key)
248    }
249
250    /// Generate random key using the provided [`CryptoRng`].
251    #[cfg(feature = "rand_core")]
252    #[inline]
253    fn generate_key_with_rng<R: CryptoRng>(rng: &mut R) -> Key<Self> {
254        let mut key = Key::<Self>::default();
255        rng.fill_bytes(&mut key);
256        key
257    }
258
259    /// Generate random key using the provided [`TryCryptoRng`].
260    #[cfg(feature = "rand_core")]
261    #[inline]
262    fn try_generate_key_with_rng<R: TryCryptoRng>(rng: &mut R) -> Result<Key<Self>, R::Error> {
263        let mut key = Key::<Self>::default();
264        rng.try_fill_bytes(&mut key)?;
265        Ok(key)
266    }
267
268    /// Generate random IV using the operating system's secure RNG.
269    #[cfg(feature = "os_rng")]
270    #[inline]
271    fn generate_iv() -> Result<Iv<Self>, OsError> {
272        let mut iv = Iv::<Self>::default();
273        OsRng.try_fill_bytes(&mut iv)?;
274        Ok(iv)
275    }
276
277    /// Generate random IV using the provided [`CryptoRng`].
278    #[cfg(feature = "rand_core")]
279    #[inline]
280    fn generate_iv_with_rng<R: CryptoRng>(rng: &mut R) -> Iv<Self> {
281        let mut iv = Iv::<Self>::default();
282        rng.fill_bytes(&mut iv);
283        iv
284    }
285
286    /// Generate random IV using the provided [`TryCryptoRng`].
287    #[cfg(feature = "rand_core")]
288    #[inline]
289    fn try_generate_iv_with_rng<R: TryCryptoRng>(rng: &mut R) -> Result<Iv<Self>, R::Error> {
290        let mut iv = Iv::<Self>::default();
291        rng.try_fill_bytes(&mut iv)?;
292        Ok(iv)
293    }
294
295    /// Generate random key and IV using the operating system's secure RNG.
296    #[cfg(feature = "os_rng")]
297    #[inline]
298    fn generate_key_iv() -> Result<(Key<Self>, Iv<Self>), OsError> {
299        let key = Self::generate_key()?;
300        let iv = Self::generate_iv()?;
301        Ok((key, iv))
302    }
303
304    /// Generate random key and IV using the provided [`CryptoRng`].
305    #[cfg(feature = "rand_core")]
306    #[inline]
307    fn generate_key_iv_with_rng<R: CryptoRng>(rng: &mut R) -> (Key<Self>, Iv<Self>) {
308        let key = Self::generate_key_with_rng(rng);
309        let iv = Self::generate_iv_with_rng(rng);
310        (key, iv)
311    }
312
313    /// Generate random key and IV using the provided [`TryCryptoRng`].
314    #[cfg(feature = "rand_core")]
315    #[inline]
316    fn try_generate_key_iv_with_rng<R: TryCryptoRng>(
317        rng: &mut R,
318    ) -> Result<(Key<Self>, Iv<Self>), R::Error> {
319        let key = Self::try_generate_key_with_rng(rng)?;
320        let iv = Self::try_generate_iv_with_rng(rng)?;
321        Ok((key, iv))
322    }
323}
324
325/// Types which can be initialized from another type (usually block ciphers).
326///
327/// Usually used for initializing types from block ciphers.
328pub trait InnerInit: InnerUser + Sized {
329    /// Initialize value from the `inner`.
330    fn inner_init(inner: Self::Inner) -> Self;
331}
332
333/// Types which can be initialized from another type and additional initialization
334/// vector/nonce.
335///
336/// Usually used for initializing types from block ciphers.
337pub trait InnerIvInit: InnerUser + IvSizeUser + Sized {
338    /// Initialize value using `inner` and `iv` array.
339    fn inner_iv_init(inner: Self::Inner, iv: &Iv<Self>) -> Self;
340
341    /// Initialize value using `inner` and `iv` slice.
342    #[inline]
343    fn inner_iv_slice_init(inner: Self::Inner, iv: &[u8]) -> Result<Self, InvalidLength> {
344        let iv = <&Iv<Self>>::try_from(iv).map_err(|_| InvalidLength)?;
345        Ok(Self::inner_iv_init(inner, iv))
346    }
347
348    /// Generate random IV using the operating system's secure RNG.
349    #[cfg(feature = "os_rng")]
350    #[inline]
351    fn generate_iv() -> Result<Iv<Self>, OsError> {
352        let mut iv = Iv::<Self>::default();
353        OsRng.try_fill_bytes(&mut iv)?;
354        Ok(iv)
355    }
356
357    /// Generate random IV using the provided [`CryptoRng`].
358    #[cfg(feature = "rand_core")]
359    #[inline]
360    fn generate_iv_with_rng<R: CryptoRng>(rng: &mut R) -> Iv<Self> {
361        let mut iv = Iv::<Self>::default();
362        rng.fill_bytes(&mut iv);
363        iv
364    }
365
366    /// Generate random IV using the provided [`TryCryptoRng`].
367    #[cfg(feature = "rand_core")]
368    #[inline]
369    fn try_generate_iv_with_rng<R: TryCryptoRng>(rng: &mut R) -> Result<Iv<Self>, R::Error> {
370        let mut iv = Iv::<Self>::default();
371        rng.try_fill_bytes(&mut iv)?;
372        Ok(iv)
373    }
374}
375
376/// Trait for loading current IV state.
377pub trait IvState: IvSizeUser {
378    /// Returns current IV state.
379    fn iv_state(&self) -> Iv<Self>;
380}
381
382impl<T> KeySizeUser for T
383where
384    T: InnerUser,
385    T::Inner: KeySizeUser,
386{
387    type KeySize = <T::Inner as KeySizeUser>::KeySize;
388}
389
390impl<T> KeyIvInit for T
391where
392    T: InnerIvInit,
393    T::Inner: KeyInit,
394{
395    #[inline]
396    fn new(key: &Key<Self>, iv: &Iv<Self>) -> Self {
397        Self::inner_iv_init(T::Inner::new(key), iv)
398    }
399
400    #[inline]
401    fn new_from_slices(key: &[u8], iv: &[u8]) -> Result<Self, InvalidLength> {
402        T::Inner::new_from_slice(key).and_then(|i| T::inner_iv_slice_init(i, iv))
403    }
404
405    #[inline]
406    fn weak_key_test(key: &Key<Self>) -> Result<(), WeakKeyError> {
407        T::Inner::weak_key_test(key)
408    }
409}
410
411impl<T> KeyInit for T
412where
413    T: InnerInit,
414    T::Inner: KeyInit,
415{
416    #[inline]
417    fn new(key: &Key<Self>) -> Self {
418        Self::inner_init(T::Inner::new(key))
419    }
420
421    #[inline]
422    fn new_from_slice(key: &[u8]) -> Result<Self, InvalidLength> {
423        T::Inner::new_from_slice(key)
424            .map_err(|_| InvalidLength)
425            .map(Self::inner_init)
426    }
427
428    #[inline]
429    fn weak_key_test(key: &Key<Self>) -> Result<(), WeakKeyError> {
430        T::Inner::weak_key_test(key)
431    }
432}
433
434// Unfortunately this blanket impl is impossible without mutually
435// exclusive traits, see: https://github.com/rust-lang/rfcs/issues/1053
436// or at the very least without: https://github.com/rust-lang/rust/issues/20400
437/*
438impl<T> KeyIvInit for T
439where
440    T: InnerInit,
441    T::Inner: KeyIvInit,
442{
443    #[inline]
444    fn new(key: &Key<Self>, iv: &Iv<Self>) -> Self {
445        Self::inner_init(T::Inner::new(key, iv))
446    }
447
448    #[inline]
449    fn new_from_slices(key: &[u8], iv: &[u8]) -> Result<Self, InvalidLength> {
450        T::Inner::new_from_slice(key)
451            .map_err(|_| InvalidLength)
452            .map(Self::inner_init)
453    }
454
455    #[inline]
456    fn weak_key_test(key: &Key<Self>) -> Result<(), WeakKeyError> {
457        T::Inner::weak_key_test(key)
458    }
459}
460*/
461
462/// The error type returned when key and/or IV used in the [`KeyInit`],
463/// [`KeyIvInit`], and [`InnerIvInit`] slice-based methods had
464/// an invalid length.
465#[derive(Copy, Clone, Eq, PartialEq, Debug)]
466pub struct InvalidLength;
467
468impl fmt::Display for InvalidLength {
469    #[inline]
470    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
471        f.write_str("Invalid Length")
472    }
473}
474
475impl core::error::Error for InvalidLength {}
476
477/// The error type returned when a key is found to be weak.
478#[derive(Copy, Clone, Eq, PartialEq, Debug)]
479pub struct WeakKeyError;
480
481impl fmt::Display for WeakKeyError {
482    #[inline]
483    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
484        f.write_str("WeakKey")
485    }
486}
487
488impl core::error::Error for WeakKeyError {}