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 = "rand_core")]
23pub use {generate::Generate, rand_core};
24#[cfg(feature = "getrandom")]
25pub use {getrandom::Error as RngError, getrandom::SysRng};
26
27use core::fmt;
28use hybrid_array::{
29 Array, ArraySize,
30 typenum::{Diff, Sum, Unsigned},
31};
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
183pub trait KeyIvInit: KeySizeUser + IvSizeUser + Sized {
185 fn new(key: &Key<Self>, iv: &Iv<Self>) -> Self;
187
188 #[inline]
190 fn weak_key_test(_key: &Key<Self>) -> Result<(), WeakKeyError> {
191 Ok(())
192 }
193
194 #[inline]
196 fn new_checked(key: &Key<Self>, iv: &Iv<Self>) -> Result<Self, WeakKeyError> {
197 Self::weak_key_test(key)?;
198 Ok(Self::new(key, iv))
199 }
200
201 #[inline]
203 fn new_from_slices(key: &[u8], iv: &[u8]) -> Result<Self, InvalidLength> {
204 let key = <&Key<Self>>::try_from(key).map_err(|_| InvalidLength)?;
205 let iv = <&Iv<Self>>::try_from(iv).map_err(|_| InvalidLength)?;
206 Ok(Self::new(key, iv))
207 }
208}
209
210pub trait TryKeyInit: KeySizeUser + Sized {
212 fn new(key: &Key<Self>) -> Result<Self, InvalidKey>;
217
218 #[inline]
224 fn new_from_slice(key: &[u8]) -> Result<Self, InvalidKey> {
225 <&Key<Self>>::try_from(key)
226 .map_err(|_| InvalidKey)
227 .and_then(Self::new)
228 }
229}
230
231pub trait InnerInit: InnerUser + Sized {
235 fn inner_init(inner: Self::Inner) -> Self;
237}
238
239pub trait InnerIvInit: InnerUser + IvSizeUser + Sized {
244 fn inner_iv_init(inner: Self::Inner, iv: &Iv<Self>) -> Self;
246
247 #[inline]
249 fn inner_iv_slice_init(inner: Self::Inner, iv: &[u8]) -> Result<Self, InvalidLength> {
250 let iv = <&Iv<Self>>::try_from(iv).map_err(|_| InvalidLength)?;
251 Ok(Self::inner_iv_init(inner, iv))
252 }
253}
254
255pub trait IvState: IvSizeUser {
257 fn iv_state(&self) -> Iv<Self>;
259}
260
261impl<T> KeySizeUser for T
262where
263 T: InnerUser,
264 T::Inner: KeySizeUser,
265{
266 type KeySize = <T::Inner as KeySizeUser>::KeySize;
267}
268
269impl<T> KeyIvInit for T
270where
271 T: InnerIvInit,
272 T::Inner: KeyInit,
273{
274 #[inline]
275 fn new(key: &Key<Self>, iv: &Iv<Self>) -> Self {
276 Self::inner_iv_init(T::Inner::new(key), iv)
277 }
278
279 #[inline]
280 fn new_from_slices(key: &[u8], iv: &[u8]) -> Result<Self, InvalidLength> {
281 T::Inner::new_from_slice(key).and_then(|i| T::inner_iv_slice_init(i, iv))
282 }
283
284 #[inline]
285 fn weak_key_test(key: &Key<Self>) -> Result<(), WeakKeyError> {
286 T::Inner::weak_key_test(key)
287 }
288}
289
290impl<T> KeyInit for T
291where
292 T: InnerInit,
293 T::Inner: KeyInit,
294{
295 #[inline]
296 fn new(key: &Key<Self>) -> Self {
297 Self::inner_init(T::Inner::new(key))
298 }
299
300 #[inline]
301 fn new_from_slice(key: &[u8]) -> Result<Self, InvalidLength> {
302 T::Inner::new_from_slice(key)
303 .map_err(|_| InvalidLength)
304 .map(Self::inner_init)
305 }
306
307 #[inline]
308 fn weak_key_test(key: &Key<Self>) -> Result<(), WeakKeyError> {
309 T::Inner::weak_key_test(key)
310 }
311}
312
313#[derive(Copy, Clone, Eq, PartialEq, Debug)]
344pub struct InvalidKey;
345
346impl fmt::Display for InvalidKey {
347 #[inline]
348 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
349 f.write_str("WeakKey")
350 }
351}
352
353impl core::error::Error for InvalidKey {}
354
355#[derive(Copy, Clone, Eq, PartialEq, Debug)]
359pub struct InvalidLength;
360
361impl fmt::Display for InvalidLength {
362 #[inline]
363 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
364 f.write_str("Invalid Length")
365 }
366}
367
368impl core::error::Error for InvalidLength {}
369
370#[derive(Copy, Clone, Eq, PartialEq, Debug)]
372pub struct WeakKeyError;
373
374impl fmt::Display for WeakKeyError {
375 #[inline]
376 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
377 f.write_str("WeakKey")
378 }
379}
380
381impl core::error::Error for WeakKeyError {}