crypto_common/
lib.rs

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