1#![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
12pub mod hazmat;
14
15#[cfg(feature = "getrandom")]
16pub use getrandom;
17
18#[cfg(feature = "rand_core")]
19pub use rand_core;
20
21pub use hybrid_array as array;
22pub use hybrid_array::typenum;
23
24use core::fmt;
25use hybrid_array::{
26 Array, ArraySize,
27 typenum::{Diff, Sum, Unsigned},
28};
29
30#[cfg(feature = "rand_core")]
31use rand_core::{CryptoRng, TryCryptoRng};
32
33pub type Block<B> = Array<u8, <B as BlockSizeUser>::BlockSize>;
35
36pub type ParBlocks<T> = Array<Block<T>, <T as ParBlocksSizeUser>::ParBlocksSize>;
38
39pub type Output<T> = Array<u8, OutputSize<T>>;
41
42pub type OutputSize<T> = <T as OutputSizeUser>::OutputSize;
44
45pub type Key<B> = Array<u8, <B as KeySizeUser>::KeySize>;
47
48pub type Iv<B> = Array<u8, <B as IvSizeUser>::IvSize>;
50
51pub type AddBlockSize<T, B> = Sum<T, <B as BlockSizeUser>::BlockSize>;
53
54pub type SubBlockSize<T, B> = Diff<T, <B as BlockSizeUser>::BlockSize>;
56
57pub trait BlockSizeUser {
59 type BlockSize: BlockSizes;
61
62 #[inline(always)]
64 fn block_size() -> usize {
65 Self::BlockSize::USIZE
66 }
67}
68
69impl<T: BlockSizeUser> BlockSizeUser for &T {
70 type BlockSize = T::BlockSize;
71}
72
73impl<T: BlockSizeUser> BlockSizeUser for &mut T {
74 type BlockSize = T::BlockSize;
75}
76
77pub trait BlockSizes: ArraySize + sealed::BlockSizes {}
79
80impl<T: ArraySize + sealed::BlockSizes> BlockSizes for T {}
81
82mod sealed {
83 use crate::typenum::{IsLess, NonZero, True, U256, Unsigned};
84
85 pub trait BlockSizes {}
86
87 impl<T: Unsigned> BlockSizes for T where Self: IsLess<U256, Output = True> + NonZero {}
88}
89
90pub trait ParBlocksSizeUser: BlockSizeUser {
92 type ParBlocksSize: ArraySize;
94}
95
96pub trait OutputSizeUser {
98 type OutputSize: ArraySize;
100
101 #[inline(always)]
103 fn output_size() -> usize {
104 Self::OutputSize::USIZE
105 }
106}
107
108pub trait KeySizeUser {
112 type KeySize: ArraySize;
114
115 #[inline(always)]
117 fn key_size() -> usize {
118 Self::KeySize::USIZE
119 }
120}
121
122pub trait IvSizeUser {
126 type IvSize: ArraySize;
128
129 #[inline(always)]
131 fn iv_size() -> usize {
132 Self::IvSize::USIZE
133 }
134}
135
136pub trait InnerUser {
140 type Inner;
142}
143
144pub trait Reset {
146 fn reset(&mut self);
148}
149
150pub trait AlgorithmName {
152 fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result;
154}
155
156pub trait KeyInit: KeySizeUser + Sized {
158 fn new(key: &Key<Self>) -> Self;
160
161 #[inline]
163 fn weak_key_test(_key: &Key<Self>) -> Result<(), WeakKeyError> {
164 Ok(())
165 }
166
167 #[inline]
169 fn new_checked(key: &Key<Self>) -> Result<Self, WeakKeyError> {
170 Self::weak_key_test(key)?;
171 Ok(Self::new(key))
172 }
173
174 #[inline]
176 fn new_from_slice(key: &[u8]) -> Result<Self, InvalidLength> {
177 <&Key<Self>>::try_from(key)
178 .map(Self::new)
179 .map_err(|_| InvalidLength)
180 }
181
182 #[cfg(feature = "getrandom")]
184 #[inline]
185 fn generate_key() -> Result<Key<Self>, getrandom::Error> {
186 let mut key = Key::<Self>::default();
187 getrandom::fill(&mut key)?;
188 Ok(key)
189 }
190
191 #[cfg(feature = "rand_core")]
193 #[inline]
194 fn generate_key_with_rng<R: CryptoRng + ?Sized>(rng: &mut R) -> Key<Self> {
195 let mut key = Key::<Self>::default();
196 rng.fill_bytes(&mut key);
197 key
198 }
199
200 #[cfg(feature = "rand_core")]
202 #[inline]
203 fn try_generate_key_with_rng<R: TryCryptoRng + ?Sized>(
204 rng: &mut R,
205 ) -> Result<Key<Self>, R::Error> {
206 let mut key = Key::<Self>::default();
207 rng.try_fill_bytes(&mut key)?;
208 Ok(key)
209 }
210}
211
212pub trait KeyIvInit: KeySizeUser + IvSizeUser + Sized {
214 fn new(key: &Key<Self>, iv: &Iv<Self>) -> Self;
216
217 #[inline]
219 fn weak_key_test(_key: &Key<Self>) -> Result<(), WeakKeyError> {
220 Ok(())
221 }
222
223 #[inline]
225 fn new_checked(key: &Key<Self>, iv: &Iv<Self>) -> Result<Self, WeakKeyError> {
226 Self::weak_key_test(key)?;
227 Ok(Self::new(key, iv))
228 }
229
230 #[inline]
232 fn new_from_slices(key: &[u8], iv: &[u8]) -> Result<Self, InvalidLength> {
233 let key = <&Key<Self>>::try_from(key).map_err(|_| InvalidLength)?;
234 let iv = <&Iv<Self>>::try_from(iv).map_err(|_| InvalidLength)?;
235 Ok(Self::new(key, iv))
236 }
237
238 #[cfg(feature = "getrandom")]
240 #[inline]
241 fn generate_key() -> Result<Key<Self>, getrandom::Error> {
242 let mut key = Key::<Self>::default();
243 getrandom::fill(&mut key)?;
244 Ok(key)
245 }
246
247 #[cfg(feature = "rand_core")]
249 #[inline]
250 fn generate_key_with_rng<R: CryptoRng + ?Sized>(rng: &mut R) -> Key<Self> {
251 let mut key = Key::<Self>::default();
252 rng.fill_bytes(&mut key);
253 key
254 }
255
256 #[cfg(feature = "rand_core")]
258 #[inline]
259 fn try_generate_key_with_rng<R: TryCryptoRng + ?Sized>(
260 rng: &mut R,
261 ) -> Result<Key<Self>, R::Error> {
262 let mut key = Key::<Self>::default();
263 rng.try_fill_bytes(&mut key)?;
264 Ok(key)
265 }
266
267 #[cfg(feature = "getrandom")]
269 #[inline]
270 fn generate_iv() -> Result<Iv<Self>, getrandom::Error> {
271 let mut iv = Iv::<Self>::default();
272 getrandom::fill(&mut iv)?;
273 Ok(iv)
274 }
275
276 #[cfg(feature = "rand_core")]
278 #[inline]
279 fn generate_iv_with_rng<R: CryptoRng + ?Sized>(rng: &mut R) -> Iv<Self> {
280 let mut iv = Iv::<Self>::default();
281 rng.fill_bytes(&mut iv);
282 iv
283 }
284
285 #[cfg(feature = "rand_core")]
287 #[inline]
288 fn try_generate_iv_with_rng<R: TryCryptoRng + ?Sized>(
289 rng: &mut R,
290 ) -> Result<Iv<Self>, R::Error> {
291 let mut iv = Iv::<Self>::default();
292 rng.try_fill_bytes(&mut iv)?;
293 Ok(iv)
294 }
295
296 #[cfg(feature = "getrandom")]
298 #[inline]
299 fn generate_key_iv() -> Result<(Key<Self>, Iv<Self>), getrandom::Error> {
300 let key = Self::generate_key()?;
301 let iv = Self::generate_iv()?;
302 Ok((key, iv))
303 }
304
305 #[cfg(feature = "rand_core")]
307 #[inline]
308 fn generate_key_iv_with_rng<R: CryptoRng + ?Sized>(rng: &mut R) -> (Key<Self>, Iv<Self>) {
309 let key = Self::generate_key_with_rng(rng);
310 let iv = Self::generate_iv_with_rng(rng);
311 (key, iv)
312 }
313
314 #[cfg(feature = "rand_core")]
316 #[inline]
317 fn try_generate_key_iv_with_rng<R: TryCryptoRng + ?Sized>(
318 rng: &mut R,
319 ) -> Result<(Key<Self>, Iv<Self>), R::Error> {
320 let key = Self::try_generate_key_with_rng(rng)?;
321 let iv = Self::try_generate_iv_with_rng(rng)?;
322 Ok((key, iv))
323 }
324}
325
326pub trait InnerInit: InnerUser + Sized {
330 fn inner_init(inner: Self::Inner) -> Self;
332}
333
334pub trait InnerIvInit: InnerUser + IvSizeUser + Sized {
339 fn inner_iv_init(inner: Self::Inner, iv: &Iv<Self>) -> Self;
341
342 #[inline]
344 fn inner_iv_slice_init(inner: Self::Inner, iv: &[u8]) -> Result<Self, InvalidLength> {
345 let iv = <&Iv<Self>>::try_from(iv).map_err(|_| InvalidLength)?;
346 Ok(Self::inner_iv_init(inner, iv))
347 }
348
349 #[cfg(feature = "getrandom")]
351 #[inline]
352 fn generate_iv() -> Result<Iv<Self>, getrandom::Error> {
353 let mut iv = Iv::<Self>::default();
354 getrandom::fill(&mut iv)?;
355 Ok(iv)
356 }
357
358 #[cfg(feature = "rand_core")]
360 #[inline]
361 fn generate_iv_with_rng<R: CryptoRng + ?Sized>(rng: &mut R) -> Iv<Self> {
362 let mut iv = Iv::<Self>::default();
363 rng.fill_bytes(&mut iv);
364 iv
365 }
366
367 #[cfg(feature = "rand_core")]
369 #[inline]
370 fn try_generate_iv_with_rng<R: TryCryptoRng + ?Sized>(
371 rng: &mut R,
372 ) -> Result<Iv<Self>, R::Error> {
373 let mut iv = Iv::<Self>::default();
374 rng.try_fill_bytes(&mut iv)?;
375 Ok(iv)
376 }
377}
378
379pub trait IvState: IvSizeUser {
381 fn iv_state(&self) -> Iv<Self>;
383}
384
385impl<T> KeySizeUser for T
386where
387 T: InnerUser,
388 T::Inner: KeySizeUser,
389{
390 type KeySize = <T::Inner as KeySizeUser>::KeySize;
391}
392
393impl<T> KeyIvInit for T
394where
395 T: InnerIvInit,
396 T::Inner: KeyInit,
397{
398 #[inline]
399 fn new(key: &Key<Self>, iv: &Iv<Self>) -> Self {
400 Self::inner_iv_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).and_then(|i| T::inner_iv_slice_init(i, iv))
406 }
407
408 #[inline]
409 fn weak_key_test(key: &Key<Self>) -> Result<(), WeakKeyError> {
410 T::Inner::weak_key_test(key)
411 }
412}
413
414impl<T> KeyInit for T
415where
416 T: InnerInit,
417 T::Inner: KeyInit,
418{
419 #[inline]
420 fn new(key: &Key<Self>) -> Self {
421 Self::inner_init(T::Inner::new(key))
422 }
423
424 #[inline]
425 fn new_from_slice(key: &[u8]) -> Result<Self, InvalidLength> {
426 T::Inner::new_from_slice(key)
427 .map_err(|_| InvalidLength)
428 .map(Self::inner_init)
429 }
430
431 #[inline]
432 fn weak_key_test(key: &Key<Self>) -> Result<(), WeakKeyError> {
433 T::Inner::weak_key_test(key)
434 }
435}
436
437#[derive(Copy, Clone, Eq, PartialEq, Debug)]
469pub struct InvalidLength;
470
471impl fmt::Display for InvalidLength {
472 #[inline]
473 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
474 f.write_str("Invalid Length")
475 }
476}
477
478impl core::error::Error for InvalidLength {}
479
480#[derive(Copy, Clone, Eq, PartialEq, Debug)]
482pub struct WeakKeyError;
483
484impl fmt::Display for WeakKeyError {
485 #[inline]
486 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
487 f.write_str("WeakKey")
488 }
489}
490
491impl core::error::Error for WeakKeyError {}