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 = "rand_core")]
17mod generate;
18
19pub use hybrid_array as array;
20pub use hybrid_array::typenum;
21
22#[cfg(feature = "getrandom")]
23pub use getrandom;
24#[cfg(feature = "rand_core")]
25pub use {generate::Generate, rand_core};
26
27use core::fmt;
28use hybrid_array::{
29 Array, ArraySize,
30 typenum::{Diff, Sum, Unsigned},
31};
32
33#[cfg(feature = "rand_core")]
34use rand_core::CryptoRng;
35
36pub type Block<B> = Array<u8, <B as BlockSizeUser>::BlockSize>;
38
39pub type ParBlocks<T> = Array<Block<T>, <T as ParBlocksSizeUser>::ParBlocksSize>;
41
42pub type Output<T> = Array<u8, OutputSize<T>>;
44
45pub type OutputSize<T> = <T as OutputSizeUser>::OutputSize;
47
48pub type Key<B> = Array<u8, <B as KeySizeUser>::KeySize>;
50
51pub type Iv<B> = Array<u8, <B as IvSizeUser>::IvSize>;
53
54pub type AddBlockSize<T, B> = Sum<T, <B as BlockSizeUser>::BlockSize>;
56
57pub type SubBlockSize<T, B> = Diff<T, <B as BlockSizeUser>::BlockSize>;
59
60pub trait BlockSizeUser {
62 type BlockSize: BlockSizes;
64
65 #[inline(always)]
67 fn block_size() -> usize {
68 Self::BlockSize::USIZE
69 }
70}
71
72impl<T: BlockSizeUser> BlockSizeUser for &T {
73 type BlockSize = T::BlockSize;
74}
75
76impl<T: BlockSizeUser> BlockSizeUser for &mut T {
77 type BlockSize = T::BlockSize;
78}
79
80pub trait BlockSizes: ArraySize + sealed::BlockSizes {}
82
83impl<T: ArraySize + sealed::BlockSizes> BlockSizes for T {}
84
85mod sealed {
86 use crate::typenum::{IsLess, NonZero, True, U256, Unsigned};
87
88 pub trait BlockSizes {}
89
90 impl<T: Unsigned> BlockSizes for T where Self: IsLess<U256, Output = True> + NonZero {}
91}
92
93pub trait ParBlocksSizeUser: BlockSizeUser {
95 type ParBlocksSize: ArraySize;
97}
98
99pub trait OutputSizeUser {
101 type OutputSize: ArraySize;
103
104 #[inline(always)]
106 fn output_size() -> usize {
107 Self::OutputSize::USIZE
108 }
109}
110
111pub trait KeySizeUser {
115 type KeySize: ArraySize;
117
118 #[inline(always)]
120 fn key_size() -> usize {
121 Self::KeySize::USIZE
122 }
123}
124
125pub trait IvSizeUser {
129 type IvSize: ArraySize;
131
132 #[inline(always)]
134 fn iv_size() -> usize {
135 Self::IvSize::USIZE
136 }
137}
138
139pub trait InnerUser {
143 type Inner;
145}
146
147pub trait Reset {
149 fn reset(&mut self);
151}
152
153pub trait AlgorithmName {
155 fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result;
157}
158
159pub trait KeyInit: KeySizeUser + Sized {
161 fn new(key: &Key<Self>) -> Self;
163
164 #[inline]
166 fn weak_key_test(_key: &Key<Self>) -> Result<(), WeakKeyError> {
167 Ok(())
168 }
169
170 #[inline]
172 fn new_checked(key: &Key<Self>) -> Result<Self, WeakKeyError> {
173 Self::weak_key_test(key)?;
174 Ok(Self::new(key))
175 }
176
177 #[inline]
179 fn new_from_slice(key: &[u8]) -> Result<Self, InvalidLength> {
180 <&Key<Self>>::try_from(key)
181 .map(Self::new)
182 .map_err(|_| InvalidLength)
183 }
184
185 #[deprecated(
193 since = "0.2.0",
194 note = "use the `Generate` trait impl on `Key` instead"
195 )]
196 #[cfg(feature = "rand_core")]
197 fn generate_key<R: CryptoRng>(rng: &mut R) -> Key<Self> {
198 Key::<Self>::generate_from_rng(rng)
199 }
200}
201
202pub trait KeyIvInit: KeySizeUser + IvSizeUser + Sized {
204 fn new(key: &Key<Self>, iv: &Iv<Self>) -> Self;
206
207 #[inline]
209 fn weak_key_test(_key: &Key<Self>) -> Result<(), WeakKeyError> {
210 Ok(())
211 }
212
213 #[inline]
215 fn new_checked(key: &Key<Self>, iv: &Iv<Self>) -> Result<Self, WeakKeyError> {
216 Self::weak_key_test(key)?;
217 Ok(Self::new(key, iv))
218 }
219
220 #[inline]
222 fn new_from_slices(key: &[u8], iv: &[u8]) -> Result<Self, InvalidLength> {
223 let key = <&Key<Self>>::try_from(key).map_err(|_| InvalidLength)?;
224 let iv = <&Iv<Self>>::try_from(iv).map_err(|_| InvalidLength)?;
225 Ok(Self::new(key, iv))
226 }
227
228 #[deprecated(
236 since = "0.2.0",
237 note = "use the `Generate` trait impl on `Key` instead"
238 )]
239 #[cfg(feature = "rand_core")]
240 fn generate_key<R: CryptoRng>(rng: &mut R) -> Key<Self> {
241 Key::<Self>::generate_from_rng(rng)
242 }
243
244 #[deprecated(
252 since = "0.2.0",
253 note = "use the `Generate` trait impl on `Iv` instead"
254 )]
255 #[cfg(feature = "rand_core")]
256 fn generate_iv<R: CryptoRng>(rng: &mut R) -> Iv<Self> {
257 Iv::<Self>::generate_from_rng(rng)
258 }
259
260 #[deprecated(
269 since = "0.2.0",
270 note = "use the `Generate` trait impls on `Key` and `Iv` instead"
271 )]
272 #[cfg(feature = "rand_core")]
273 fn generate_key_iv<R: CryptoRng>(rng: &mut R) -> (Key<Self>, Iv<Self>) {
274 let key = Key::<Self>::generate_from_rng(rng);
275 let iv = Iv::<Self>::generate_from_rng(rng);
276 (key, iv)
277 }
278}
279
280pub trait TryKeyInit: KeySizeUser + Sized {
282 fn new(key: &Key<Self>) -> Result<Self, InvalidKey>;
287
288 #[inline]
294 fn new_from_slice(key: &[u8]) -> Result<Self, InvalidKey> {
295 <&Key<Self>>::try_from(key)
296 .map_err(|_| InvalidKey)
297 .and_then(Self::new)
298 }
299}
300
301pub trait InnerInit: InnerUser + Sized {
305 fn inner_init(inner: Self::Inner) -> Self;
307}
308
309pub trait InnerIvInit: InnerUser + IvSizeUser + Sized {
314 fn inner_iv_init(inner: Self::Inner, iv: &Iv<Self>) -> Self;
316
317 #[inline]
319 fn inner_iv_slice_init(inner: Self::Inner, iv: &[u8]) -> Result<Self, InvalidLength> {
320 let iv = <&Iv<Self>>::try_from(iv).map_err(|_| InvalidLength)?;
321 Ok(Self::inner_iv_init(inner, iv))
322 }
323}
324
325pub trait IvState: IvSizeUser {
327 fn iv_state(&self) -> Iv<Self>;
329}
330
331impl<T> KeySizeUser for T
332where
333 T: InnerUser,
334 T::Inner: KeySizeUser,
335{
336 type KeySize = <T::Inner as KeySizeUser>::KeySize;
337}
338
339impl<T> KeyIvInit for T
340where
341 T: InnerIvInit,
342 T::Inner: KeyInit,
343{
344 #[inline]
345 fn new(key: &Key<Self>, iv: &Iv<Self>) -> Self {
346 Self::inner_iv_init(T::Inner::new(key), iv)
347 }
348
349 #[inline]
350 fn new_from_slices(key: &[u8], iv: &[u8]) -> Result<Self, InvalidLength> {
351 T::Inner::new_from_slice(key).and_then(|i| T::inner_iv_slice_init(i, iv))
352 }
353
354 #[inline]
355 fn weak_key_test(key: &Key<Self>) -> Result<(), WeakKeyError> {
356 T::Inner::weak_key_test(key)
357 }
358}
359
360impl<T> KeyInit for T
361where
362 T: InnerInit,
363 T::Inner: KeyInit,
364{
365 #[inline]
366 fn new(key: &Key<Self>) -> Self {
367 Self::inner_init(T::Inner::new(key))
368 }
369
370 #[inline]
371 fn new_from_slice(key: &[u8]) -> Result<Self, InvalidLength> {
372 T::Inner::new_from_slice(key)
373 .map_err(|_| InvalidLength)
374 .map(Self::inner_init)
375 }
376
377 #[inline]
378 fn weak_key_test(key: &Key<Self>) -> Result<(), WeakKeyError> {
379 T::Inner::weak_key_test(key)
380 }
381}
382
383#[derive(Copy, Clone, Eq, PartialEq, Debug)]
414pub struct InvalidKey;
415
416impl fmt::Display for InvalidKey {
417 #[inline]
418 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
419 f.write_str("WeakKey")
420 }
421}
422
423impl core::error::Error for InvalidKey {}
424
425#[derive(Copy, Clone, Eq, PartialEq, Debug)]
429pub struct InvalidLength;
430
431impl fmt::Display for InvalidLength {
432 #[inline]
433 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
434 f.write_str("Invalid Length")
435 }
436}
437
438impl core::error::Error for InvalidLength {}
439
440#[derive(Copy, Clone, Eq, PartialEq, Debug)]
442pub struct WeakKeyError;
443
444impl fmt::Display for WeakKeyError {
445 #[inline]
446 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
447 f.write_str("WeakKey")
448 }
449}
450
451impl core::error::Error for WeakKeyError {}