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: ArraySize;
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/// Types which can process blocks in parallel.
80pub trait ParBlocksSizeUser: BlockSizeUser {
81    /// Number of blocks which can be processed in parallel.
82    type ParBlocksSize: ArraySize;
83}
84
85/// Types which return data with the given size.
86pub trait OutputSizeUser {
87    /// Size of the output in bytes.
88    type OutputSize: ArraySize;
89
90    /// Return output size in bytes.
91    #[inline(always)]
92    #[must_use]
93    fn output_size() -> usize {
94        Self::OutputSize::USIZE
95    }
96}
97
98/// Types which use key for initialization.
99///
100/// Generally it's used indirectly via [`KeyInit`] or [`KeyIvInit`].
101pub trait KeySizeUser {
102    /// Key size in bytes.
103    type KeySize: ArraySize;
104
105    /// Return key size in bytes.
106    #[inline(always)]
107    #[must_use]
108    fn key_size() -> usize {
109        Self::KeySize::USIZE
110    }
111}
112
113/// Types which use initialization vector (nonce) for initialization.
114///
115/// Generally it's used indirectly via [`KeyIvInit`] or [`InnerIvInit`].
116pub trait IvSizeUser {
117    /// Initialization vector size in bytes.
118    type IvSize: ArraySize;
119
120    /// Return IV size in bytes.
121    #[inline(always)]
122    #[must_use]
123    fn iv_size() -> usize {
124        Self::IvSize::USIZE
125    }
126}
127
128/// Types which use another type for initialization.
129///
130/// Generally it's used indirectly via [`InnerInit`] or [`InnerIvInit`].
131pub trait InnerUser {
132    /// Inner type.
133    type Inner;
134}
135
136/// Resettable types.
137pub trait Reset {
138    /// Reset state to its initial value.
139    fn reset(&mut self);
140}
141
142/// Trait which stores algorithm name constant, used in `Debug` implementations.
143pub trait AlgorithmName {
144    /// Write algorithm name into `f`.
145    ///
146    /// # Errors
147    /// `fmt::Result` is only intended for cases where an error occurs writing to the underlying
148    /// I/O stream.
149    fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result;
150}
151
152/// Serialize a key to a byte array.
153pub trait KeyExport: KeySizeUser {
154    /// Serialize this key as a byte array.
155    fn to_bytes(&self) -> Key<Self>;
156}
157
158/// Types which can be initialized from a key.
159pub trait KeyInit: KeySizeUser + Sized {
160    /// Create new value from fixed size key.
161    fn new(key: &Key<Self>) -> Self;
162
163    /// Create new value from variable size key.
164    ///
165    /// # Errors
166    /// Returns [`InvalidLength`] in the event the length of the provided slice is not equal to
167    /// `<Self as KeySizeUser>::KeySize::USIZE`.
168    #[inline]
169    fn new_from_slice(key: &[u8]) -> Result<Self, InvalidLength> {
170        <&Key<Self>>::try_from(key)
171            .map(Self::new)
172            .map_err(|_| InvalidLength)
173    }
174
175    /// DEPRECATED: generate random key using the provided [`CryptoRng`].
176    ///
177    /// Instead, you can now use the [`Generate`] trait directly with the [`Key`] type:
178    ///
179    /// ```ignore
180    /// let key = Key::generate_from_rng(rng);
181    /// ```
182    #[deprecated(
183        since = "0.2.0",
184        note = "use the `Generate` trait impl on `Key` instead"
185    )]
186    #[cfg(feature = "rand_core")]
187    fn generate_key<R: CryptoRng>(rng: &mut R) -> Key<Self> {
188        Key::<Self>::generate_from_rng(rng)
189    }
190}
191
192/// Types which can be initialized from a key and initialization vector (nonce).
193pub trait KeyIvInit: KeySizeUser + IvSizeUser + Sized {
194    /// Create new value from fixed length key and nonce.
195    fn new(key: &Key<Self>, iv: &Iv<Self>) -> Self;
196
197    /// Create new value from variable length key and nonce.
198    ///
199    /// # Errors
200    /// Returns [`InvalidLength`] in the event that `key` and/or `iv` are not the expected length.
201    #[inline]
202    fn new_from_slices(key: &[u8], iv: &[u8]) -> Result<Self, InvalidLength> {
203        let key = <&Key<Self>>::try_from(key).map_err(|_| InvalidLength)?;
204        let iv = <&Iv<Self>>::try_from(iv).map_err(|_| InvalidLength)?;
205        Ok(Self::new(key, iv))
206    }
207
208    /// DEPRECATED: generate random key using the provided [`CryptoRng`].
209    ///
210    /// Instead, you can now use the [`Generate`] trait directly with the [`Key`] type:
211    ///
212    /// ```ignore
213    /// let key = Key::generate_from_rng(rng);
214    /// ```
215    #[deprecated(
216        since = "0.2.0",
217        note = "use the `Generate` trait impl on `Key` instead"
218    )]
219    #[cfg(feature = "rand_core")]
220    fn generate_key<R: CryptoRng>(rng: &mut R) -> Key<Self> {
221        Key::<Self>::generate_from_rng(rng)
222    }
223
224    /// DEPRECATED: generate random IV using the provided [`CryptoRng`].
225    ///
226    /// Instead, you can now use the [`Generate`] trait directly with the [`Iv`] type:
227    ///
228    /// ```ignore
229    /// let iv = Iv::generate_from_rng(rng);
230    /// ```
231    #[deprecated(
232        since = "0.2.0",
233        note = "use the `Generate` trait impl on `Iv` instead"
234    )]
235    #[cfg(feature = "rand_core")]
236    fn generate_iv<R: CryptoRng>(rng: &mut R) -> Iv<Self> {
237        Iv::<Self>::generate_from_rng(rng)
238    }
239
240    /// DEPRECATED: generate random key and IV using the provided [`CryptoRng`].
241    ///
242    /// Instead, you can now use the [`Generate`] trait directly with the [`Key`] and [`Iv`] types:
243    ///
244    /// ```ignore
245    /// let key = Key::generate_from_rng(rng);
246    /// let iv = Iv::generate_from_rng(rng);
247    /// ```
248    #[deprecated(
249        since = "0.2.0",
250        note = "use the `Generate` trait impls on `Key` and `Iv` instead"
251    )]
252    #[cfg(feature = "rand_core")]
253    fn generate_key_iv<R: CryptoRng>(rng: &mut R) -> (Key<Self>, Iv<Self>) {
254        let key = Key::<Self>::generate_from_rng(rng);
255        let iv = Iv::<Self>::generate_from_rng(rng);
256        (key, iv)
257    }
258}
259
260/// Types which can be fallibly initialized from a key.
261pub trait TryKeyInit: KeySizeUser + Sized {
262    /// Create new value from a fixed-size key.
263    ///
264    /// # Errors
265    /// If the key is considered invalid according to rules specific to the implementing type.
266    fn new(key: &Key<Self>) -> Result<Self, InvalidKey>;
267
268    /// Create new value from a variable size key.
269    ///
270    /// # Errors
271    /// If the key is considered invalid according to rules specific to the implementing type.
272    #[inline]
273    fn new_from_slice(key: &[u8]) -> Result<Self, InvalidKey> {
274        <&Key<Self>>::try_from(key)
275            .map_err(|_| InvalidKey)
276            .and_then(Self::new)
277    }
278}
279
280/// Types which can be initialized from another type (usually block ciphers).
281///
282/// Usually used for initializing types from block ciphers.
283pub trait InnerInit: InnerUser + Sized {
284    /// Initialize value from the `inner`.
285    fn inner_init(inner: Self::Inner) -> Self;
286}
287
288/// Types which can be initialized from another type and additional initialization
289/// vector/nonce.
290///
291/// Usually used for initializing types from block ciphers.
292pub trait InnerIvInit: InnerUser + IvSizeUser + Sized {
293    /// Initialize value using `inner` and `iv` array.
294    fn inner_iv_init(inner: Self::Inner, iv: &Iv<Self>) -> Self;
295
296    /// Initialize value using `inner` and `iv` slice.
297    ///
298    /// # Errors
299    /// Returns [`InvalidLength`]  in the event that `iv` is not the expected length.
300    #[inline]
301    fn inner_iv_slice_init(inner: Self::Inner, iv: &[u8]) -> Result<Self, InvalidLength> {
302        let iv = <&Iv<Self>>::try_from(iv).map_err(|_| InvalidLength)?;
303        Ok(Self::inner_iv_init(inner, iv))
304    }
305}
306
307/// Trait for loading current IV state.
308pub trait IvState: IvSizeUser {
309    /// Returns current IV state.
310    fn iv_state(&self) -> Iv<Self>;
311}
312
313/// Trait for setting current IV state.
314// TODO: merge with `IvState` in the next breaking release
315pub trait SetIvState: IvState {
316    /// Set IV.
317    fn set_iv(&mut self, iv: &Iv<Self>);
318
319    /// Execute the `f` closure with the current state and reset it back
320    /// to the original state before the method returns.
321    fn peek<T>(&mut self, f: impl FnOnce(&mut Self) -> T) -> T {
322        let iv = self.iv_state();
323        let res = f(self);
324        self.set_iv(&iv);
325        res
326    }
327}
328
329impl<T> KeySizeUser for T
330where
331    T: InnerUser,
332    T::Inner: KeySizeUser,
333{
334    type KeySize = <T::Inner as KeySizeUser>::KeySize;
335}
336
337impl<T> KeyIvInit for T
338where
339    T: InnerIvInit,
340    T::Inner: KeyInit,
341{
342    #[inline]
343    fn new(key: &Key<Self>, iv: &Iv<Self>) -> Self {
344        Self::inner_iv_init(T::Inner::new(key), iv)
345    }
346
347    #[inline]
348    fn new_from_slices(key: &[u8], iv: &[u8]) -> Result<Self, InvalidLength> {
349        T::Inner::new_from_slice(key).and_then(|i| T::inner_iv_slice_init(i, iv))
350    }
351}
352
353impl<T> KeyInit for T
354where
355    T: InnerInit,
356    T::Inner: KeyInit,
357{
358    #[inline]
359    fn new(key: &Key<Self>) -> Self {
360        Self::inner_init(T::Inner::new(key))
361    }
362
363    #[inline]
364    fn new_from_slice(key: &[u8]) -> Result<Self, InvalidLength> {
365        T::Inner::new_from_slice(key)
366            .map_err(|_| InvalidLength)
367            .map(Self::inner_init)
368    }
369}
370
371/// Error type for [`TryKeyInit`] for cases where the provided bytes do not correspond to a
372/// valid key.
373#[derive(Copy, Clone, Eq, PartialEq, Debug)]
374pub struct InvalidKey;
375
376impl fmt::Display for InvalidKey {
377    #[inline]
378    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
379        f.write_str("InvalidKey")
380    }
381}
382
383impl core::error::Error for InvalidKey {}
384
385/// The error type returned when key and/or IV used in the [`KeyInit`],
386/// [`KeyIvInit`], and [`InnerIvInit`] slice-based methods had
387/// an invalid length.
388#[derive(Copy, Clone, Eq, PartialEq, Debug)]
389pub struct InvalidLength;
390
391impl fmt::Display for InvalidLength {
392    #[inline]
393    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
394        f.write_str("Invalid Length")
395    }
396}
397
398impl core::error::Error for InvalidLength {}