Coverage Report

Created: 2026-11-12 06:16

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/crypto-common-0.2.2/src/lib.rs
Line
Count
Source
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.
11
pub mod hazmat;
12
13
/// Secure random generation.
14
#[cfg(feature = "rand_core")]
15
mod generate;
16
17
pub use hybrid_array as array;
18
pub use hybrid_array::typenum;
19
20
#[cfg(feature = "getrandom")]
21
pub use getrandom;
22
#[cfg(feature = "rand_core")]
23
pub use {generate::Generate, rand_core};
24
25
use core::fmt;
26
use hybrid_array::{
27
    Array, ArraySize,
28
    typenum::{Diff, Sum, Unsigned},
29
};
30
31
#[cfg(feature = "rand_core")]
32
use rand_core::CryptoRng;
33
34
/// Block on which [`BlockSizeUser`] implementors operate.
35
pub type Block<B> = Array<u8, <B as BlockSizeUser>::BlockSize>;
36
37
/// Parallel blocks on which [`ParBlocksSizeUser`] implementors operate.
38
pub type ParBlocks<T> = Array<Block<T>, <T as ParBlocksSizeUser>::ParBlocksSize>;
39
40
/// Output array of [`OutputSizeUser`] implementors.
41
pub type Output<T> = Array<u8, OutputSize<T>>;
42
43
/// Alias for the output size of [`OutputSizeUser`] implementors.
44
pub type OutputSize<T> = <T as OutputSizeUser>::OutputSize;
45
46
/// Key used by [`KeySizeUser`] implementors.
47
pub type Key<B> = Array<u8, <B as KeySizeUser>::KeySize>;
48
49
/// Initialization vector (nonce) used by [`IvSizeUser`] implementors.
50
pub type Iv<B> = Array<u8, <B as IvSizeUser>::IvSize>;
51
52
/// Alias for `AddBlockSize<A, B> = Sum<T, B::BlockSize>`
53
pub type AddBlockSize<T, B> = Sum<T, <B as BlockSizeUser>::BlockSize>;
54
55
/// Alias for `SubBlockSize<A, B> = Diff<T, B::BlockSize>`
56
pub type SubBlockSize<T, B> = Diff<T, <B as BlockSizeUser>::BlockSize>;
57
58
/// Types which process data in blocks.
59
pub 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
71
impl<T: BlockSizeUser> BlockSizeUser for &T {
72
    type BlockSize = T::BlockSize;
73
}
74
75
impl<T: BlockSizeUser> BlockSizeUser for &mut T {
76
    type BlockSize = T::BlockSize;
77
}
78
79
/// Types which can process blocks in parallel.
80
pub 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.
86
pub 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`].
101
pub 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`].
116
pub 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`].
131
pub trait InnerUser {
132
    /// Inner type.
133
    type Inner;
134
}
135
136
/// Resettable types.
137
pub 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.
143
pub 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.
153
pub 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.
159
pub 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
1.53k
    fn new_from_slice(key: &[u8]) -> Result<Self, InvalidLength> {
170
1.53k
        <&Key<Self>>::try_from(key)
171
1.53k
            .map(Self::new)
172
1.53k
            .map_err(|_| InvalidLength)
173
1.53k
    }
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).
193
pub 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.
261
pub 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.
283
pub 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.
292
pub 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
1.53k
    fn inner_iv_slice_init(inner: Self::Inner, iv: &[u8]) -> Result<Self, InvalidLength> {
302
1.53k
        let iv = <&Iv<Self>>::try_from(iv).map_err(|_| InvalidLength)?;
303
1.53k
        Ok(Self::inner_iv_init(inner, iv))
304
1.53k
    }
<cbc::encrypt::Encryptor<aes::Aes256> as crypto_common::InnerIvInit>::inner_iv_slice_init
Line
Count
Source
301
1.53k
    fn inner_iv_slice_init(inner: Self::Inner, iv: &[u8]) -> Result<Self, InvalidLength> {
302
1.53k
        let iv = <&Iv<Self>>::try_from(iv).map_err(|_| InvalidLength)?;
303
1.53k
        Ok(Self::inner_iv_init(inner, iv))
304
1.53k
    }
Unexecuted instantiation: <cbc::decrypt::Decryptor<aes::Aes256> as crypto_common::InnerIvInit>::inner_iv_slice_init
305
}
306
307
/// Trait for loading current IV state.
308
pub 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
315
pub 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
329
impl<T> KeySizeUser for T
330
where
331
    T: InnerUser,
332
    T::Inner: KeySizeUser,
333
{
334
    type KeySize = <T::Inner as KeySizeUser>::KeySize;
335
}
336
337
impl<T> KeyIvInit for T
338
where
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
1.53k
    fn new_from_slices(key: &[u8], iv: &[u8]) -> Result<Self, InvalidLength> {
349
1.53k
        T::Inner::new_from_slice(key).and_then(|i| T::inner_iv_slice_init(i, iv))
Unexecuted instantiation: <cbc::decrypt::Decryptor<aes::Aes256> as crypto_common::KeyIvInit>::new_from_slices::{closure#0}
<cbc::encrypt::Encryptor<aes::Aes256> as crypto_common::KeyIvInit>::new_from_slices::{closure#0}
Line
Count
Source
349
1.53k
        T::Inner::new_from_slice(key).and_then(|i| T::inner_iv_slice_init(i, iv))
350
1.53k
    }
<cbc::encrypt::Encryptor<aes::Aes256> as crypto_common::KeyIvInit>::new_from_slices
Line
Count
Source
348
1.53k
    fn new_from_slices(key: &[u8], iv: &[u8]) -> Result<Self, InvalidLength> {
349
1.53k
        T::Inner::new_from_slice(key).and_then(|i| T::inner_iv_slice_init(i, iv))
350
1.53k
    }
Unexecuted instantiation: <cbc::decrypt::Decryptor<aes::Aes256> as crypto_common::KeyIvInit>::new_from_slices
351
}
352
353
impl<T> KeyInit for T
354
where
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)]
374
pub struct InvalidKey;
375
376
impl 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
383
impl 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)]
389
pub struct InvalidLength;
390
391
impl 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
398
impl core::error::Error for InvalidLength {}