Skip to main content

crypto_common/
lib.rs

1#![no_std]
2#![cfg_attr(docsrs, feature(doc_cfg))]
3#![doc = include_str!("../README.md")]
4#![doc(
5    html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg",
6    html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg"
7)]
8#![forbid(unsafe_code)]
9
10/// Hazardous materials.
11pub mod hazmat;
12
13/// Secure random generation.
14#[cfg(feature = "rand_core")]
15mod generate;
16
17pub use hybrid_array as array;
18pub use hybrid_array::typenum;
19
20#[cfg(feature = "getrandom")]
21pub use getrandom;
22#[cfg(feature = "rand_core")]
23pub use {generate::Generate, rand_core};
24
25use core::fmt;
26use hybrid_array::{
27    Array, ArraySize,
28    typenum::{Diff, Sum, Unsigned},
29};
30
31#[cfg(feature = "rand_core")]
32use rand_core::CryptoRng;
33
34/// Block on which [`BlockSizeUser`] implementors operate.
35pub type Block<B> = Array<u8, <B as BlockSizeUser>::BlockSize>;
36
37/// Parallel blocks on which [`ParBlocksSizeUser`] implementors operate.
38pub type ParBlocks<T> = Array<Block<T>, <T as ParBlocksSizeUser>::ParBlocksSize>;
39
40/// Output array of [`OutputSizeUser`] implementors.
41pub type Output<T> = Array<u8, OutputSize<T>>;
42
43/// Alias for the output size of [`OutputSizeUser`] implementors.
44pub type OutputSize<T> = <T as OutputSizeUser>::OutputSize;
45
46/// Key used by [`KeySizeUser`] implementors.
47pub type Key<B> = Array<u8, <B as KeySizeUser>::KeySize>;
48
49/// Initialization vector (nonce) used by [`IvSizeUser`] implementors.
50pub type Iv<B> = Array<u8, <B as IvSizeUser>::IvSize>;
51
52/// Alias for `AddBlockSize<A, B> = Sum<T, B::BlockSize>`
53pub type AddBlockSize<T, B> = Sum<T, <B as BlockSizeUser>::BlockSize>;
54
55/// Alias for `SubBlockSize<A, B> = Diff<T, B::BlockSize>`
56pub type SubBlockSize<T, B> = Diff<T, <B as BlockSizeUser>::BlockSize>;
57
58/// Types which process data in blocks.
59pub trait BlockSizeUser {
60    /// Size of the block in bytes.
61    type BlockSize: BlockSizes;
62
63    /// Return block size in bytes.
64    #[inline(always)]
65    #[must_use]
66    fn block_size() -> usize {
67        Self::BlockSize::USIZE
68    }
69}
70
71impl<T: BlockSizeUser> BlockSizeUser for &T {
72    type BlockSize = T::BlockSize;
73}
74
75impl<T: BlockSizeUser> BlockSizeUser for &mut T {
76    type BlockSize = T::BlockSize;
77}
78
79/// Trait implemented for supported block sizes, i.e. for types from `U1` to `U255`.
80pub trait BlockSizes: ArraySize + sealed::BlockSizes {}
81
82impl<T: ArraySize + sealed::BlockSizes> BlockSizes for T {}
83
84mod sealed {
85    use crate::typenum::{IsLess, NonZero, True, U256, Unsigned};
86
87    pub trait BlockSizes {}
88
89    impl<T: Unsigned> BlockSizes for T where Self: IsLess<U256, Output = True> + NonZero {}
90}
91
92/// Types which can process blocks in parallel.
93pub trait ParBlocksSizeUser: BlockSizeUser {
94    /// Number of blocks which can be processed in parallel.
95    type ParBlocksSize: ArraySize;
96}
97
98/// Types which return data with the given size.
99pub trait OutputSizeUser {
100    /// Size of the output in bytes.
101    type OutputSize: ArraySize;
102
103    /// Return output size in bytes.
104    #[inline(always)]
105    #[must_use]
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    #[must_use]
121    fn key_size() -> usize {
122        Self::KeySize::USIZE
123    }
124}
125
126/// Types which use initialization vector (nonce) for initialization.
127///
128/// Generally it's used indirectly via [`KeyIvInit`] or [`InnerIvInit`].
129pub trait IvSizeUser {
130    /// Initialization vector size in bytes.
131    type IvSize: ArraySize;
132
133    /// Return IV size in bytes.
134    #[inline(always)]
135    #[must_use]
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    ///
159    /// # Errors
160    /// `fmt::Result` is only intended for cases where an error occurs writing to the underlying
161    /// I/O stream.
162    fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result;
163}
164
165/// Serialize a key to a byte array.
166pub trait KeyExport: KeySizeUser {
167    /// Serialize this key as a byte array.
168    fn to_bytes(&self) -> Key<Self>;
169}
170
171/// Types which can be initialized from a key.
172pub trait KeyInit: KeySizeUser + Sized {
173    /// Create new value from fixed size key.
174    fn new(key: &Key<Self>) -> Self;
175
176    /// Create new value from variable size key.
177    ///
178    /// # Errors
179    /// Returns [`InvalidLength`] in the event the length of the provided slice is not equal to
180    /// `<Self as KeySizeUser>::KeySize::USIZE`.
181    #[inline]
182    fn new_from_slice(key: &[u8]) -> Result<Self, InvalidLength> {
183        <&Key<Self>>::try_from(key)
184            .map(Self::new)
185            .map_err(|_| InvalidLength)
186    }
187
188    /// DEPRECATED: generate random key using the provided [`CryptoRng`].
189    ///
190    /// Instead, you can now use the [`Generate`] trait directly with the [`Key`] type:
191    ///
192    /// ```ignore
193    /// let key = Key::generate_from_rng(rng);
194    /// ```
195    #[deprecated(
196        since = "0.2.0",
197        note = "use the `Generate` trait impl on `Key` instead"
198    )]
199    #[cfg(feature = "rand_core")]
200    fn generate_key<R: CryptoRng>(rng: &mut R) -> Key<Self> {
201        Key::<Self>::generate_from_rng(rng)
202    }
203}
204
205/// Types which can be initialized from a key and initialization vector (nonce).
206pub trait KeyIvInit: KeySizeUser + IvSizeUser + Sized {
207    /// Create new value from fixed length key and nonce.
208    fn new(key: &Key<Self>, iv: &Iv<Self>) -> Self;
209
210    /// Create new value from variable length key and nonce.
211    ///
212    /// # Errors
213    /// Returns [`InvalidLength`] in the event that `key` and/or `iv` are not the expected length.
214    #[inline]
215    fn new_from_slices(key: &[u8], iv: &[u8]) -> Result<Self, InvalidLength> {
216        let key = <&Key<Self>>::try_from(key).map_err(|_| InvalidLength)?;
217        let iv = <&Iv<Self>>::try_from(iv).map_err(|_| InvalidLength)?;
218        Ok(Self::new(key, iv))
219    }
220
221    /// DEPRECATED: generate random key using the provided [`CryptoRng`].
222    ///
223    /// Instead, you can now use the [`Generate`] trait directly with the [`Key`] type:
224    ///
225    /// ```ignore
226    /// let key = Key::generate_from_rng(rng);
227    /// ```
228    #[deprecated(
229        since = "0.2.0",
230        note = "use the `Generate` trait impl on `Key` instead"
231    )]
232    #[cfg(feature = "rand_core")]
233    fn generate_key<R: CryptoRng>(rng: &mut R) -> Key<Self> {
234        Key::<Self>::generate_from_rng(rng)
235    }
236
237    /// DEPRECATED: generate random IV using the provided [`CryptoRng`].
238    ///
239    /// Instead, you can now use the [`Generate`] trait directly with the [`Iv`] type:
240    ///
241    /// ```ignore
242    /// let iv = Iv::generate_from_rng(rng);
243    /// ```
244    #[deprecated(
245        since = "0.2.0",
246        note = "use the `Generate` trait impl on `Iv` instead"
247    )]
248    #[cfg(feature = "rand_core")]
249    fn generate_iv<R: CryptoRng>(rng: &mut R) -> Iv<Self> {
250        Iv::<Self>::generate_from_rng(rng)
251    }
252
253    /// DEPRECATED: generate random key and IV using the provided [`CryptoRng`].
254    ///
255    /// Instead, you can now use the [`Generate`] trait directly with the [`Key`] and [`Iv`] types:
256    ///
257    /// ```ignore
258    /// let key = Key::generate_from_rng(rng);
259    /// let iv = Iv::generate_from_rng(rng);
260    /// ```
261    #[deprecated(
262        since = "0.2.0",
263        note = "use the `Generate` trait impls on `Key` and `Iv` instead"
264    )]
265    #[cfg(feature = "rand_core")]
266    fn generate_key_iv<R: CryptoRng>(rng: &mut R) -> (Key<Self>, Iv<Self>) {
267        let key = Key::<Self>::generate_from_rng(rng);
268        let iv = Iv::<Self>::generate_from_rng(rng);
269        (key, iv)
270    }
271}
272
273/// Types which can be fallibly initialized from a key.
274pub trait TryKeyInit: KeySizeUser + Sized {
275    /// Create new value from a fixed-size key.
276    ///
277    /// # Errors
278    /// If the key is considered invalid according to rules specific to the implementing type.
279    fn new(key: &Key<Self>) -> Result<Self, InvalidKey>;
280
281    /// Create new value from a variable size key.
282    ///
283    /// # Errors
284    /// If the key is considered invalid according to rules specific to the implementing type.
285    #[inline]
286    fn new_from_slice(key: &[u8]) -> Result<Self, InvalidKey> {
287        <&Key<Self>>::try_from(key)
288            .map_err(|_| InvalidKey)
289            .and_then(Self::new)
290    }
291}
292
293/// Types which can be initialized from another type (usually block ciphers).
294///
295/// Usually used for initializing types from block ciphers.
296pub trait InnerInit: InnerUser + Sized {
297    /// Initialize value from the `inner`.
298    fn inner_init(inner: Self::Inner) -> Self;
299}
300
301/// Types which can be initialized from another type and additional initialization
302/// vector/nonce.
303///
304/// Usually used for initializing types from block ciphers.
305pub trait InnerIvInit: InnerUser + IvSizeUser + Sized {
306    /// Initialize value using `inner` and `iv` array.
307    fn inner_iv_init(inner: Self::Inner, iv: &Iv<Self>) -> Self;
308
309    /// Initialize value using `inner` and `iv` slice.
310    ///
311    /// # Errors
312    /// Returns [`InvalidLength`]  in the event that `iv` is not the expected length.
313    #[inline]
314    fn inner_iv_slice_init(inner: Self::Inner, iv: &[u8]) -> Result<Self, InvalidLength> {
315        let iv = <&Iv<Self>>::try_from(iv).map_err(|_| InvalidLength)?;
316        Ok(Self::inner_iv_init(inner, iv))
317    }
318}
319
320/// Trait for loading current IV state.
321pub trait IvState: IvSizeUser {
322    /// Returns current IV state.
323    fn iv_state(&self) -> Iv<Self>;
324}
325
326impl<T> KeySizeUser for T
327where
328    T: InnerUser,
329    T::Inner: KeySizeUser,
330{
331    type KeySize = <T::Inner as KeySizeUser>::KeySize;
332}
333
334impl<T> KeyIvInit for T
335where
336    T: InnerIvInit,
337    T::Inner: KeyInit,
338{
339    #[inline]
340    fn new(key: &Key<Self>, iv: &Iv<Self>) -> Self {
341        Self::inner_iv_init(T::Inner::new(key), iv)
342    }
343
344    #[inline]
345    fn new_from_slices(key: &[u8], iv: &[u8]) -> Result<Self, InvalidLength> {
346        T::Inner::new_from_slice(key).and_then(|i| T::inner_iv_slice_init(i, iv))
347    }
348}
349
350impl<T> KeyInit for T
351where
352    T: InnerInit,
353    T::Inner: KeyInit,
354{
355    #[inline]
356    fn new(key: &Key<Self>) -> Self {
357        Self::inner_init(T::Inner::new(key))
358    }
359
360    #[inline]
361    fn new_from_slice(key: &[u8]) -> Result<Self, InvalidLength> {
362        T::Inner::new_from_slice(key)
363            .map_err(|_| InvalidLength)
364            .map(Self::inner_init)
365    }
366}
367
368/// Error type for [`TryKeyInit`] for cases where the provided bytes do not correspond to a
369/// valid key.
370#[derive(Copy, Clone, Eq, PartialEq, Debug)]
371pub struct InvalidKey;
372
373impl fmt::Display for InvalidKey {
374    #[inline]
375    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
376        f.write_str("InvalidKey")
377    }
378}
379
380impl core::error::Error for InvalidKey {}
381
382/// The error type returned when key and/or IV used in the [`KeyInit`],
383/// [`KeyIvInit`], and [`InnerIvInit`] slice-based methods had
384/// an invalid length.
385#[derive(Copy, Clone, Eq, PartialEq, Debug)]
386pub struct InvalidLength;
387
388impl fmt::Display for InvalidLength {
389    #[inline]
390    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
391        f.write_str("Invalid Length")
392    }
393}
394
395impl core::error::Error for InvalidLength {}