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 KeyExport: KeySizeUser {
161 fn to_bytes(&self) -> Key<Self>;
163}
164
165pub trait KeyInit: KeySizeUser + Sized {
167 fn new(key: &Key<Self>) -> Self;
169
170 #[inline]
172 fn weak_key_test(_key: &Key<Self>) -> Result<(), WeakKeyError> {
173 Ok(())
174 }
175
176 #[inline]
178 fn new_checked(key: &Key<Self>) -> Result<Self, WeakKeyError> {
179 Self::weak_key_test(key)?;
180 Ok(Self::new(key))
181 }
182
183 #[inline]
185 fn new_from_slice(key: &[u8]) -> Result<Self, InvalidLength> {
186 <&Key<Self>>::try_from(key)
187 .map(Self::new)
188 .map_err(|_| InvalidLength)
189 }
190
191 #[deprecated(
199 since = "0.2.0",
200 note = "use the `Generate` trait impl on `Key` instead"
201 )]
202 #[cfg(feature = "rand_core")]
203 fn generate_key<R: CryptoRng>(rng: &mut R) -> Key<Self> {
204 Key::<Self>::generate_from_rng(rng)
205 }
206}
207
208pub trait KeyIvInit: KeySizeUser + IvSizeUser + Sized {
210 fn new(key: &Key<Self>, iv: &Iv<Self>) -> Self;
212
213 #[inline]
215 fn weak_key_test(_key: &Key<Self>) -> Result<(), WeakKeyError> {
216 Ok(())
217 }
218
219 #[inline]
221 fn new_checked(key: &Key<Self>, iv: &Iv<Self>) -> Result<Self, WeakKeyError> {
222 Self::weak_key_test(key)?;
223 Ok(Self::new(key, iv))
224 }
225
226 #[inline]
228 fn new_from_slices(key: &[u8], iv: &[u8]) -> Result<Self, InvalidLength> {
229 let key = <&Key<Self>>::try_from(key).map_err(|_| InvalidLength)?;
230 let iv = <&Iv<Self>>::try_from(iv).map_err(|_| InvalidLength)?;
231 Ok(Self::new(key, iv))
232 }
233
234 #[deprecated(
242 since = "0.2.0",
243 note = "use the `Generate` trait impl on `Key` instead"
244 )]
245 #[cfg(feature = "rand_core")]
246 fn generate_key<R: CryptoRng>(rng: &mut R) -> Key<Self> {
247 Key::<Self>::generate_from_rng(rng)
248 }
249
250 #[deprecated(
258 since = "0.2.0",
259 note = "use the `Generate` trait impl on `Iv` instead"
260 )]
261 #[cfg(feature = "rand_core")]
262 fn generate_iv<R: CryptoRng>(rng: &mut R) -> Iv<Self> {
263 Iv::<Self>::generate_from_rng(rng)
264 }
265
266 #[deprecated(
275 since = "0.2.0",
276 note = "use the `Generate` trait impls on `Key` and `Iv` instead"
277 )]
278 #[cfg(feature = "rand_core")]
279 fn generate_key_iv<R: CryptoRng>(rng: &mut R) -> (Key<Self>, Iv<Self>) {
280 let key = Key::<Self>::generate_from_rng(rng);
281 let iv = Iv::<Self>::generate_from_rng(rng);
282 (key, iv)
283 }
284}
285
286pub trait TryKeyInit: KeySizeUser + Sized {
288 fn new(key: &Key<Self>) -> Result<Self, InvalidKey>;
293
294 #[inline]
300 fn new_from_slice(key: &[u8]) -> Result<Self, InvalidKey> {
301 <&Key<Self>>::try_from(key)
302 .map_err(|_| InvalidKey)
303 .and_then(Self::new)
304 }
305}
306
307pub trait InnerInit: InnerUser + Sized {
311 fn inner_init(inner: Self::Inner) -> Self;
313}
314
315pub trait InnerIvInit: InnerUser + IvSizeUser + Sized {
320 fn inner_iv_init(inner: Self::Inner, iv: &Iv<Self>) -> Self;
322
323 #[inline]
325 fn inner_iv_slice_init(inner: Self::Inner, iv: &[u8]) -> Result<Self, InvalidLength> {
326 let iv = <&Iv<Self>>::try_from(iv).map_err(|_| InvalidLength)?;
327 Ok(Self::inner_iv_init(inner, iv))
328 }
329}
330
331pub trait IvState: IvSizeUser {
333 fn iv_state(&self) -> Iv<Self>;
335}
336
337impl<T> KeySizeUser for T
338where
339 T: InnerUser,
340 T::Inner: KeySizeUser,
341{
342 type KeySize = <T::Inner as KeySizeUser>::KeySize;
343}
344
345impl<T> KeyIvInit for T
346where
347 T: InnerIvInit,
348 T::Inner: KeyInit,
349{
350 #[inline]
351 fn new(key: &Key<Self>, iv: &Iv<Self>) -> Self {
352 Self::inner_iv_init(T::Inner::new(key), iv)
353 }
354
355 #[inline]
356 fn new_from_slices(key: &[u8], iv: &[u8]) -> Result<Self, InvalidLength> {
357 T::Inner::new_from_slice(key).and_then(|i| T::inner_iv_slice_init(i, iv))
358 }
359
360 #[inline]
361 fn weak_key_test(key: &Key<Self>) -> Result<(), WeakKeyError> {
362 T::Inner::weak_key_test(key)
363 }
364}
365
366impl<T> KeyInit for T
367where
368 T: InnerInit,
369 T::Inner: KeyInit,
370{
371 #[inline]
372 fn new(key: &Key<Self>) -> Self {
373 Self::inner_init(T::Inner::new(key))
374 }
375
376 #[inline]
377 fn new_from_slice(key: &[u8]) -> Result<Self, InvalidLength> {
378 T::Inner::new_from_slice(key)
379 .map_err(|_| InvalidLength)
380 .map(Self::inner_init)
381 }
382
383 #[inline]
384 fn weak_key_test(key: &Key<Self>) -> Result<(), WeakKeyError> {
385 T::Inner::weak_key_test(key)
386 }
387}
388
389#[derive(Copy, Clone, Eq, PartialEq, Debug)]
420pub struct InvalidKey;
421
422impl fmt::Display for InvalidKey {
423 #[inline]
424 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
425 f.write_str("WeakKey")
426 }
427}
428
429impl core::error::Error for InvalidKey {}
430
431#[derive(Copy, Clone, Eq, PartialEq, Debug)]
435pub struct InvalidLength;
436
437impl fmt::Display for InvalidLength {
438 #[inline]
439 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
440 f.write_str("Invalid Length")
441 }
442}
443
444impl core::error::Error for InvalidLength {}
445
446#[derive(Copy, Clone, Eq, PartialEq, Debug)]
448pub struct WeakKeyError;
449
450impl fmt::Display for WeakKeyError {
451 #[inline]
452 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
453 f.write_str("WeakKey")
454 }
455}
456
457impl core::error::Error for WeakKeyError {}