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::{IsLess, NonZero, True, U256, Unsigned};
83
84 pub trait BlockSizes {}
85
86 impl<T: Unsigned> BlockSizes for T where Self: IsLess<U256, Output = True> + NonZero {}
87}
88
89pub trait ParBlocksSizeUser: BlockSizeUser {
91 type ParBlocksSize: ArraySize;
93}
94
95pub trait OutputSizeUser {
97 type OutputSize: ArraySize;
99
100 #[inline(always)]
102 fn output_size() -> usize {
103 Self::OutputSize::USIZE
104 }
105}
106
107pub trait KeySizeUser {
111 type KeySize: ArraySize;
113
114 #[inline(always)]
116 fn key_size() -> usize {
117 Self::KeySize::USIZE
118 }
119}
120
121pub trait IvSizeUser {
125 type IvSize: ArraySize;
127
128 #[inline(always)]
130 fn iv_size() -> usize {
131 Self::IvSize::USIZE
132 }
133}
134
135pub trait InnerUser {
139 type Inner;
141}
142
143pub trait Reset {
145 fn reset(&mut self);
147}
148
149pub trait AlgorithmName {
151 fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result;
153}
154
155pub trait KeyInit: KeySizeUser + Sized {
157 fn new(key: &Key<Self>) -> Self;
159
160 #[inline]
162 fn weak_key_test(_key: &Key<Self>) -> Result<(), WeakKeyError> {
163 Ok(())
164 }
165
166 #[inline]
168 fn new_checked(key: &Key<Self>) -> Result<Self, WeakKeyError> {
169 Self::weak_key_test(key)?;
170 Ok(Self::new(key))
171 }
172
173 #[inline]
175 fn new_from_slice(key: &[u8]) -> Result<Self, InvalidLength> {
176 <&Key<Self>>::try_from(key)
177 .map(Self::new)
178 .map_err(|_| InvalidLength)
179 }
180
181 #[cfg(feature = "os_rng")]
183 #[inline]
184 fn generate_key() -> Result<Key<Self>, OsError> {
185 let mut key = Key::<Self>::default();
186 OsRng.try_fill_bytes(&mut key)?;
187 Ok(key)
188 }
189
190 #[cfg(feature = "rand_core")]
192 #[inline]
193 fn generate_key_with_rng<R: CryptoRng + ?Sized>(rng: &mut R) -> Key<Self> {
194 let mut key = Key::<Self>::default();
195 rng.fill_bytes(&mut key);
196 key
197 }
198
199 #[cfg(feature = "rand_core")]
201 #[inline]
202 fn try_generate_key_with_rng<R: TryCryptoRng + ?Sized>(
203 rng: &mut R,
204 ) -> Result<Key<Self>, R::Error> {
205 let mut key = Key::<Self>::default();
206 rng.try_fill_bytes(&mut key)?;
207 Ok(key)
208 }
209}
210
211pub trait KeyIvInit: KeySizeUser + IvSizeUser + Sized {
213 fn new(key: &Key<Self>, iv: &Iv<Self>) -> Self;
215
216 #[inline]
218 fn weak_key_test(_key: &Key<Self>) -> Result<(), WeakKeyError> {
219 Ok(())
220 }
221
222 #[inline]
224 fn new_checked(key: &Key<Self>, iv: &Iv<Self>) -> Result<Self, WeakKeyError> {
225 Self::weak_key_test(key)?;
226 Ok(Self::new(key, iv))
227 }
228
229 #[inline]
231 fn new_from_slices(key: &[u8], iv: &[u8]) -> Result<Self, InvalidLength> {
232 let key = <&Key<Self>>::try_from(key).map_err(|_| InvalidLength)?;
233 let iv = <&Iv<Self>>::try_from(iv).map_err(|_| InvalidLength)?;
234 Ok(Self::new(key, iv))
235 }
236
237 #[cfg(feature = "os_rng")]
239 #[inline]
240 fn generate_key() -> Result<Key<Self>, OsError> {
241 let mut key = Key::<Self>::default();
242 OsRng.try_fill_bytes(&mut key)?;
243 Ok(key)
244 }
245
246 #[cfg(feature = "rand_core")]
248 #[inline]
249 fn generate_key_with_rng<R: CryptoRng + ?Sized>(rng: &mut R) -> Key<Self> {
250 let mut key = Key::<Self>::default();
251 rng.fill_bytes(&mut key);
252 key
253 }
254
255 #[cfg(feature = "rand_core")]
257 #[inline]
258 fn try_generate_key_with_rng<R: TryCryptoRng + ?Sized>(
259 rng: &mut R,
260 ) -> Result<Key<Self>, R::Error> {
261 let mut key = Key::<Self>::default();
262 rng.try_fill_bytes(&mut key)?;
263 Ok(key)
264 }
265
266 #[cfg(feature = "os_rng")]
268 #[inline]
269 fn generate_iv() -> Result<Iv<Self>, OsError> {
270 let mut iv = Iv::<Self>::default();
271 OsRng.try_fill_bytes(&mut iv)?;
272 Ok(iv)
273 }
274
275 #[cfg(feature = "rand_core")]
277 #[inline]
278 fn generate_iv_with_rng<R: CryptoRng + ?Sized>(rng: &mut R) -> Iv<Self> {
279 let mut iv = Iv::<Self>::default();
280 rng.fill_bytes(&mut iv);
281 iv
282 }
283
284 #[cfg(feature = "rand_core")]
286 #[inline]
287 fn try_generate_iv_with_rng<R: TryCryptoRng + ?Sized>(
288 rng: &mut R,
289 ) -> 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 + ?Sized>(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 + ?Sized>(
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 + ?Sized>(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 + ?Sized>(
370 rng: &mut R,
371 ) -> Result<Iv<Self>, R::Error> {
372 let mut iv = Iv::<Self>::default();
373 rng.try_fill_bytes(&mut iv)?;
374 Ok(iv)
375 }
376}
377
378pub trait IvState: IvSizeUser {
380 fn iv_state(&self) -> Iv<Self>;
382}
383
384impl<T> KeySizeUser for T
385where
386 T: InnerUser,
387 T::Inner: KeySizeUser,
388{
389 type KeySize = <T::Inner as KeySizeUser>::KeySize;
390}
391
392impl<T> KeyIvInit for T
393where
394 T: InnerIvInit,
395 T::Inner: KeyInit,
396{
397 #[inline]
398 fn new(key: &Key<Self>, iv: &Iv<Self>) -> Self {
399 Self::inner_iv_init(T::Inner::new(key), iv)
400 }
401
402 #[inline]
403 fn new_from_slices(key: &[u8], iv: &[u8]) -> Result<Self, InvalidLength> {
404 T::Inner::new_from_slice(key).and_then(|i| T::inner_iv_slice_init(i, iv))
405 }
406
407 #[inline]
408 fn weak_key_test(key: &Key<Self>) -> Result<(), WeakKeyError> {
409 T::Inner::weak_key_test(key)
410 }
411}
412
413impl<T> KeyInit for T
414where
415 T: InnerInit,
416 T::Inner: KeyInit,
417{
418 #[inline]
419 fn new(key: &Key<Self>) -> Self {
420 Self::inner_init(T::Inner::new(key))
421 }
422
423 #[inline]
424 fn new_from_slice(key: &[u8]) -> Result<Self, InvalidLength> {
425 T::Inner::new_from_slice(key)
426 .map_err(|_| InvalidLength)
427 .map(Self::inner_init)
428 }
429
430 #[inline]
431 fn weak_key_test(key: &Key<Self>) -> Result<(), WeakKeyError> {
432 T::Inner::weak_key_test(key)
433 }
434}
435
436#[derive(Copy, Clone, Eq, PartialEq, Debug)]
468pub struct InvalidLength;
469
470impl fmt::Display for InvalidLength {
471 #[inline]
472 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
473 f.write_str("Invalid Length")
474 }
475}
476
477impl core::error::Error for InvalidLength {}
478
479#[derive(Copy, Clone, Eq, PartialEq, Debug)]
481pub struct WeakKeyError;
482
483impl fmt::Display for WeakKeyError {
484 #[inline]
485 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
486 f.write_str("WeakKey")
487 }
488}
489
490impl core::error::Error for WeakKeyError {}