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