1#![no_std]
4#![cfg_attr(docsrs, feature(doc_auto_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
12pub mod hazmat;
14
15#[cfg(feature = "rand_core")]
16pub use rand_core;
17
18pub use hybrid_array as array;
19pub use hybrid_array::typenum;
20
21use core::fmt;
22use hybrid_array::{
23 Array, ArraySize,
24 typenum::{Diff, Sum, Unsigned},
25};
26
27#[cfg(feature = "rand_core")]
28use rand_core::{CryptoRng, TryCryptoRng};
29#[cfg(feature = "os_rng")]
30use rand_core::{OsError, OsRng, TryRngCore};
31
32pub type Block<B> = Array<u8, <B as BlockSizeUser>::BlockSize>;
34
35pub type ParBlocks<T> = Array<Block<T>, <T as ParBlocksSizeUser>::ParBlocksSize>;
37
38pub type Output<T> = Array<u8, OutputSize<T>>;
40
41pub type OutputSize<T> = <T as OutputSizeUser>::OutputSize;
43
44pub type Key<B> = Array<u8, <B as KeySizeUser>::KeySize>;
46
47pub type Iv<B> = Array<u8, <B as IvSizeUser>::IvSize>;
49
50pub type AddBlockSize<T, B> = Sum<T, <B as BlockSizeUser>::BlockSize>;
52
53pub type SubBlockSize<T, B> = Diff<T, <B as BlockSizeUser>::BlockSize>;
55
56pub trait BlockSizeUser {
58 type BlockSize: BlockSizes;
60
61 #[inline(always)]
63 fn block_size() -> usize {
64 Self::BlockSize::USIZE
65 }
66}
67
68impl<T: BlockSizeUser> BlockSizeUser for &T {
69 type BlockSize = T::BlockSize;
70}
71
72impl<T: BlockSizeUser> BlockSizeUser for &mut T {
73 type BlockSize = T::BlockSize;
74}
75
76pub trait BlockSizes: ArraySize + sealed::BlockSizes {}
78
79impl<T: ArraySize + sealed::BlockSizes> BlockSizes for T {}
80
81mod sealed {
82 use crate::typenum::{Gr, IsGreater, IsLess, Le, NonZero, U0, U256, Unsigned};
83
84 pub trait BlockSizes {}
85
86 impl<T: Unsigned> BlockSizes for T
87 where
88 Self: IsLess<U256> + IsGreater<U0>,
89 Le<Self, U256>: NonZero,
90 Gr<Self, U0>: NonZero,
91 {
92 }
93}
94
95pub trait ParBlocksSizeUser: BlockSizeUser {
97 type ParBlocksSize: ArraySize;
99}
100
101pub trait OutputSizeUser {
103 type OutputSize: ArraySize;
105
106 #[inline(always)]
108 fn output_size() -> usize {
109 Self::OutputSize::USIZE
110 }
111}
112
113pub trait KeySizeUser {
117 type KeySize: ArraySize;
119
120 #[inline(always)]
122 fn key_size() -> usize {
123 Self::KeySize::USIZE
124 }
125}
126
127pub trait IvSizeUser {
131 type IvSize: ArraySize;
133
134 #[inline(always)]
136 fn iv_size() -> usize {
137 Self::IvSize::USIZE
138 }
139}
140
141pub trait InnerUser {
145 type Inner;
147}
148
149pub trait Reset {
151 fn reset(&mut self);
153}
154
155pub trait AlgorithmName {
157 fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result;
159}
160
161pub trait KeyInit: KeySizeUser + Sized {
163 fn new(key: &Key<Self>) -> Self;
165
166 #[inline]
168 fn weak_key_test(_key: &Key<Self>) -> Result<(), WeakKeyError> {
169 Ok(())
170 }
171
172 #[inline]
174 fn new_checked(key: &Key<Self>) -> Result<Self, WeakKeyError> {
175 Self::weak_key_test(key)?;
176 Ok(Self::new(key))
177 }
178
179 #[inline]
181 fn new_from_slice(key: &[u8]) -> Result<Self, InvalidLength> {
182 <&Key<Self>>::try_from(key)
183 .map(Self::new)
184 .map_err(|_| InvalidLength)
185 }
186
187 #[cfg(feature = "os_rng")]
189 #[inline]
190 fn generate_key() -> Result<Key<Self>, OsError> {
191 let mut key = Key::<Self>::default();
192 OsRng.try_fill_bytes(&mut key)?;
193 Ok(key)
194 }
195
196 #[cfg(feature = "rand_core")]
198 #[inline]
199 fn generate_key_with_rng<R: CryptoRng>(rng: &mut R) -> Key<Self> {
200 let mut key = Key::<Self>::default();
201 rng.fill_bytes(&mut key);
202 key
203 }
204
205 #[cfg(feature = "rand_core")]
207 #[inline]
208 fn try_generate_key_with_rng<R: TryCryptoRng>(rng: &mut R) -> Result<Key<Self>, R::Error> {
209 let mut key = Key::<Self>::default();
210 rng.try_fill_bytes(&mut key)?;
211 Ok(key)
212 }
213}
214
215pub trait KeyIvInit: KeySizeUser + IvSizeUser + Sized {
217 fn new(key: &Key<Self>, iv: &Iv<Self>) -> Self;
219
220 #[inline]
222 fn weak_key_test(_key: &Key<Self>) -> Result<(), WeakKeyError> {
223 Ok(())
224 }
225
226 #[inline]
228 fn new_checked(key: &Key<Self>, iv: &Iv<Self>) -> Result<Self, WeakKeyError> {
229 Self::weak_key_test(key)?;
230 Ok(Self::new(key, iv))
231 }
232
233 #[inline]
235 fn new_from_slices(key: &[u8], iv: &[u8]) -> Result<Self, InvalidLength> {
236 let key = <&Key<Self>>::try_from(key).map_err(|_| InvalidLength)?;
237 let iv = <&Iv<Self>>::try_from(iv).map_err(|_| InvalidLength)?;
238 Ok(Self::new(key, iv))
239 }
240
241 #[cfg(feature = "os_rng")]
243 #[inline]
244 fn generate_key() -> Result<Key<Self>, OsError> {
245 let mut key = Key::<Self>::default();
246 OsRng.try_fill_bytes(&mut key)?;
247 Ok(key)
248 }
249
250 #[cfg(feature = "rand_core")]
252 #[inline]
253 fn generate_key_with_rng<R: CryptoRng>(rng: &mut R) -> Key<Self> {
254 let mut key = Key::<Self>::default();
255 rng.fill_bytes(&mut key);
256 key
257 }
258
259 #[cfg(feature = "rand_core")]
261 #[inline]
262 fn try_generate_key_with_rng<R: TryCryptoRng>(rng: &mut R) -> Result<Key<Self>, R::Error> {
263 let mut key = Key::<Self>::default();
264 rng.try_fill_bytes(&mut key)?;
265 Ok(key)
266 }
267
268 #[cfg(feature = "os_rng")]
270 #[inline]
271 fn generate_iv() -> Result<Iv<Self>, OsError> {
272 let mut iv = Iv::<Self>::default();
273 OsRng.try_fill_bytes(&mut iv)?;
274 Ok(iv)
275 }
276
277 #[cfg(feature = "rand_core")]
279 #[inline]
280 fn generate_iv_with_rng<R: CryptoRng>(rng: &mut R) -> Iv<Self> {
281 let mut iv = Iv::<Self>::default();
282 rng.fill_bytes(&mut iv);
283 iv
284 }
285
286 #[cfg(feature = "rand_core")]
288 #[inline]
289 fn try_generate_iv_with_rng<R: TryCryptoRng>(rng: &mut R) -> Result<Iv<Self>, R::Error> {
290 let mut iv = Iv::<Self>::default();
291 rng.try_fill_bytes(&mut iv)?;
292 Ok(iv)
293 }
294
295 #[cfg(feature = "os_rng")]
297 #[inline]
298 fn generate_key_iv() -> Result<(Key<Self>, Iv<Self>), OsError> {
299 let key = Self::generate_key()?;
300 let iv = Self::generate_iv()?;
301 Ok((key, iv))
302 }
303
304 #[cfg(feature = "rand_core")]
306 #[inline]
307 fn generate_key_iv_with_rng<R: CryptoRng>(rng: &mut R) -> (Key<Self>, Iv<Self>) {
308 let key = Self::generate_key_with_rng(rng);
309 let iv = Self::generate_iv_with_rng(rng);
310 (key, iv)
311 }
312
313 #[cfg(feature = "rand_core")]
315 #[inline]
316 fn try_generate_key_iv_with_rng<R: TryCryptoRng>(
317 rng: &mut R,
318 ) -> Result<(Key<Self>, Iv<Self>), R::Error> {
319 let key = Self::try_generate_key_with_rng(rng)?;
320 let iv = Self::try_generate_iv_with_rng(rng)?;
321 Ok((key, iv))
322 }
323}
324
325pub trait InnerInit: InnerUser + Sized {
329 fn inner_init(inner: Self::Inner) -> Self;
331}
332
333pub trait InnerIvInit: InnerUser + IvSizeUser + Sized {
338 fn inner_iv_init(inner: Self::Inner, iv: &Iv<Self>) -> Self;
340
341 #[inline]
343 fn inner_iv_slice_init(inner: Self::Inner, iv: &[u8]) -> Result<Self, InvalidLength> {
344 let iv = <&Iv<Self>>::try_from(iv).map_err(|_| InvalidLength)?;
345 Ok(Self::inner_iv_init(inner, iv))
346 }
347
348 #[cfg(feature = "os_rng")]
350 #[inline]
351 fn generate_iv() -> Result<Iv<Self>, OsError> {
352 let mut iv = Iv::<Self>::default();
353 OsRng.try_fill_bytes(&mut iv)?;
354 Ok(iv)
355 }
356
357 #[cfg(feature = "rand_core")]
359 #[inline]
360 fn generate_iv_with_rng<R: CryptoRng>(rng: &mut R) -> Iv<Self> {
361 let mut iv = Iv::<Self>::default();
362 rng.fill_bytes(&mut iv);
363 iv
364 }
365
366 #[cfg(feature = "rand_core")]
368 #[inline]
369 fn try_generate_iv_with_rng<R: TryCryptoRng>(rng: &mut R) -> Result<Iv<Self>, R::Error> {
370 let mut iv = Iv::<Self>::default();
371 rng.try_fill_bytes(&mut iv)?;
372 Ok(iv)
373 }
374}
375
376pub trait IvState: IvSizeUser {
378 fn iv_state(&self) -> Iv<Self>;
380}
381
382impl<T> KeySizeUser for T
383where
384 T: InnerUser,
385 T::Inner: KeySizeUser,
386{
387 type KeySize = <T::Inner as KeySizeUser>::KeySize;
388}
389
390impl<T> KeyIvInit for T
391where
392 T: InnerIvInit,
393 T::Inner: KeyInit,
394{
395 #[inline]
396 fn new(key: &Key<Self>, iv: &Iv<Self>) -> Self {
397 Self::inner_iv_init(T::Inner::new(key), iv)
398 }
399
400 #[inline]
401 fn new_from_slices(key: &[u8], iv: &[u8]) -> Result<Self, InvalidLength> {
402 T::Inner::new_from_slice(key).and_then(|i| T::inner_iv_slice_init(i, iv))
403 }
404
405 #[inline]
406 fn weak_key_test(key: &Key<Self>) -> Result<(), WeakKeyError> {
407 T::Inner::weak_key_test(key)
408 }
409}
410
411impl<T> KeyInit for T
412where
413 T: InnerInit,
414 T::Inner: KeyInit,
415{
416 #[inline]
417 fn new(key: &Key<Self>) -> Self {
418 Self::inner_init(T::Inner::new(key))
419 }
420
421 #[inline]
422 fn new_from_slice(key: &[u8]) -> Result<Self, InvalidLength> {
423 T::Inner::new_from_slice(key)
424 .map_err(|_| InvalidLength)
425 .map(Self::inner_init)
426 }
427
428 #[inline]
429 fn weak_key_test(key: &Key<Self>) -> Result<(), WeakKeyError> {
430 T::Inner::weak_key_test(key)
431 }
432}
433
434#[derive(Copy, Clone, Eq, PartialEq, Debug)]
466pub struct InvalidLength;
467
468impl fmt::Display for InvalidLength {
469 #[inline]
470 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
471 f.write_str("Invalid Length")
472 }
473}
474
475impl core::error::Error for InvalidLength {}
476
477#[derive(Copy, Clone, Eq, PartialEq, Debug)]
479pub struct WeakKeyError;
480
481impl fmt::Display for WeakKeyError {
482 #[inline]
483 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
484 f.write_str("WeakKey")
485 }
486}
487
488impl core::error::Error for WeakKeyError {}