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/// Secure random generation.
16#[cfg(feature = "rand_core")]
17mod generate;
18
19pub use hybrid_array as array;
20pub use hybrid_array::typenum;
21
22#[cfg(feature = "rand_core")]
23pub use {generate::Generate, rand_core};
24#[cfg(feature = "getrandom")]
25pub use {generate::sys_rng::SysRng, getrandom::Error as RngError};
26
27use core::fmt;
28use hybrid_array::{
29    Array, ArraySize,
30    typenum::{Diff, Sum, Unsigned},
31};
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 a 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
183/// Types which can be initialized from a key and initialization vector (nonce).
184pub trait KeyIvInit: KeySizeUser + IvSizeUser + Sized {
185    /// Create new value from fixed length key and nonce.
186    fn new(key: &Key<Self>, iv: &Iv<Self>) -> Self;
187
188    /// Check if the key might be considered weak.
189    #[inline]
190    fn weak_key_test(_key: &Key<Self>) -> Result<(), WeakKeyError> {
191        Ok(())
192    }
193
194    /// Create new value from fixed length key and nonce after checking the key for weakness.
195    #[inline]
196    fn new_checked(key: &Key<Self>, iv: &Iv<Self>) -> Result<Self, WeakKeyError> {
197        Self::weak_key_test(key)?;
198        Ok(Self::new(key, iv))
199    }
200
201    /// Create new value from variable length key and nonce.
202    #[inline]
203    fn new_from_slices(key: &[u8], iv: &[u8]) -> Result<Self, InvalidLength> {
204        let key = <&Key<Self>>::try_from(key).map_err(|_| InvalidLength)?;
205        let iv = <&Iv<Self>>::try_from(iv).map_err(|_| InvalidLength)?;
206        Ok(Self::new(key, iv))
207    }
208}
209
210/// Types which can be fallibly initialized from a key.
211pub trait TryKeyInit: KeySizeUser + Sized {
212    /// Create new value from a fixed-size key.
213    ///
214    /// # Errors
215    /// - if the key is considered invalid according to rules specific to the implementing type
216    fn new(key: &Key<Self>) -> Result<Self, InvalidKey>;
217
218    /// Create new value from a variable size key.
219    ///
220    /// # Errors
221    /// - if the provided slice is the wrong length
222    /// - if the key is considered invalid by [`TryKeyInit::new`]
223    #[inline]
224    fn new_from_slice(key: &[u8]) -> Result<Self, InvalidKey> {
225        <&Key<Self>>::try_from(key)
226            .map_err(|_| InvalidKey)
227            .and_then(Self::new)
228    }
229}
230
231/// Types which can be initialized from another type (usually block ciphers).
232///
233/// Usually used for initializing types from block ciphers.
234pub trait InnerInit: InnerUser + Sized {
235    /// Initialize value from the `inner`.
236    fn inner_init(inner: Self::Inner) -> Self;
237}
238
239/// Types which can be initialized from another type and additional initialization
240/// vector/nonce.
241///
242/// Usually used for initializing types from block ciphers.
243pub trait InnerIvInit: InnerUser + IvSizeUser + Sized {
244    /// Initialize value using `inner` and `iv` array.
245    fn inner_iv_init(inner: Self::Inner, iv: &Iv<Self>) -> Self;
246
247    /// Initialize value using `inner` and `iv` slice.
248    #[inline]
249    fn inner_iv_slice_init(inner: Self::Inner, iv: &[u8]) -> Result<Self, InvalidLength> {
250        let iv = <&Iv<Self>>::try_from(iv).map_err(|_| InvalidLength)?;
251        Ok(Self::inner_iv_init(inner, iv))
252    }
253}
254
255/// Trait for loading current IV state.
256pub trait IvState: IvSizeUser {
257    /// Returns current IV state.
258    fn iv_state(&self) -> Iv<Self>;
259}
260
261impl<T> KeySizeUser for T
262where
263    T: InnerUser,
264    T::Inner: KeySizeUser,
265{
266    type KeySize = <T::Inner as KeySizeUser>::KeySize;
267}
268
269impl<T> KeyIvInit for T
270where
271    T: InnerIvInit,
272    T::Inner: KeyInit,
273{
274    #[inline]
275    fn new(key: &Key<Self>, iv: &Iv<Self>) -> Self {
276        Self::inner_iv_init(T::Inner::new(key), iv)
277    }
278
279    #[inline]
280    fn new_from_slices(key: &[u8], iv: &[u8]) -> Result<Self, InvalidLength> {
281        T::Inner::new_from_slice(key).and_then(|i| T::inner_iv_slice_init(i, iv))
282    }
283
284    #[inline]
285    fn weak_key_test(key: &Key<Self>) -> Result<(), WeakKeyError> {
286        T::Inner::weak_key_test(key)
287    }
288}
289
290impl<T> KeyInit for T
291where
292    T: InnerInit,
293    T::Inner: KeyInit,
294{
295    #[inline]
296    fn new(key: &Key<Self>) -> Self {
297        Self::inner_init(T::Inner::new(key))
298    }
299
300    #[inline]
301    fn new_from_slice(key: &[u8]) -> Result<Self, InvalidLength> {
302        T::Inner::new_from_slice(key)
303            .map_err(|_| InvalidLength)
304            .map(Self::inner_init)
305    }
306
307    #[inline]
308    fn weak_key_test(key: &Key<Self>) -> Result<(), WeakKeyError> {
309        T::Inner::weak_key_test(key)
310    }
311}
312
313// Unfortunately this blanket impl is impossible without mutually
314// exclusive traits, see: https://github.com/rust-lang/rfcs/issues/1053
315// or at the very least without: https://github.com/rust-lang/rust/issues/20400
316/*
317impl<T> KeyIvInit for T
318where
319    T: InnerInit,
320    T::Inner: KeyIvInit,
321{
322    #[inline]
323    fn new(key: &Key<Self>, iv: &Iv<Self>) -> Self {
324        Self::inner_init(T::Inner::new(key, iv))
325    }
326
327    #[inline]
328    fn new_from_slices(key: &[u8], iv: &[u8]) -> Result<Self, InvalidLength> {
329        T::Inner::new_from_slice(key)
330            .map_err(|_| InvalidLength)
331            .map(Self::inner_init)
332    }
333
334    #[inline]
335    fn weak_key_test(key: &Key<Self>) -> Result<(), WeakKeyError> {
336        T::Inner::weak_key_test(key)
337    }
338}
339*/
340
341/// Error type for [`TryKeyInit`] for cases where the provided bytes do not correspond to a
342/// valid key.
343#[derive(Copy, Clone, Eq, PartialEq, Debug)]
344pub struct InvalidKey;
345
346impl fmt::Display for InvalidKey {
347    #[inline]
348    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
349        f.write_str("WeakKey")
350    }
351}
352
353impl core::error::Error for InvalidKey {}
354
355/// The error type returned when key and/or IV used in the [`KeyInit`],
356/// [`KeyIvInit`], and [`InnerIvInit`] slice-based methods had
357/// an invalid length.
358#[derive(Copy, Clone, Eq, PartialEq, Debug)]
359pub struct InvalidLength;
360
361impl fmt::Display for InvalidLength {
362    #[inline]
363    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
364        f.write_str("Invalid Length")
365    }
366}
367
368impl core::error::Error for InvalidLength {}
369
370/// The error type returned when a key is found to be weak.
371#[derive(Copy, Clone, Eq, PartialEq, Debug)]
372pub struct WeakKeyError;
373
374impl fmt::Display for WeakKeyError {
375    #[inline]
376    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
377        f.write_str("WeakKey")
378    }
379}
380
381impl core::error::Error for WeakKeyError {}