1#![no_std]
2#![cfg_attr(docsrs, feature(doc_cfg))]
3#![doc = include_str!("../README.md")]
4#![doc(
5 html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg",
6 html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg"
7)]
8#![forbid(unsafe_code)]
9
10pub mod hazmat;
12
13#[cfg(feature = "rand_core")]
15mod generate;
16
17pub use hybrid_array as array;
18pub use hybrid_array::typenum;
19
20#[cfg(feature = "getrandom")]
21pub use getrandom;
22#[cfg(feature = "rand_core")]
23pub use {generate::Generate, rand_core};
24
25use core::fmt;
26use hybrid_array::{
27 Array, ArraySize,
28 typenum::{Diff, Sum, Unsigned},
29};
30
31#[cfg(feature = "rand_core")]
32use rand_core::CryptoRng;
33
34pub type Block<B> = Array<u8, <B as BlockSizeUser>::BlockSize>;
36
37pub type ParBlocks<T> = Array<Block<T>, <T as ParBlocksSizeUser>::ParBlocksSize>;
39
40pub type Output<T> = Array<u8, OutputSize<T>>;
42
43pub type OutputSize<T> = <T as OutputSizeUser>::OutputSize;
45
46pub type Key<B> = Array<u8, <B as KeySizeUser>::KeySize>;
48
49pub type Iv<B> = Array<u8, <B as IvSizeUser>::IvSize>;
51
52pub type AddBlockSize<T, B> = Sum<T, <B as BlockSizeUser>::BlockSize>;
54
55pub type SubBlockSize<T, B> = Diff<T, <B as BlockSizeUser>::BlockSize>;
57
58pub trait BlockSizeUser {
60 type BlockSize: ArraySize;
62
63 #[inline(always)]
65 #[must_use]
66 fn block_size() -> usize {
67 Self::BlockSize::USIZE
68 }
69}
70
71impl<T: BlockSizeUser> BlockSizeUser for &T {
72 type BlockSize = T::BlockSize;
73}
74
75impl<T: BlockSizeUser> BlockSizeUser for &mut T {
76 type BlockSize = T::BlockSize;
77}
78
79pub trait ParBlocksSizeUser: BlockSizeUser {
81 type ParBlocksSize: ArraySize;
83}
84
85pub trait OutputSizeUser {
87 type OutputSize: ArraySize;
89
90 #[inline(always)]
92 #[must_use]
93 fn output_size() -> usize {
94 Self::OutputSize::USIZE
95 }
96}
97
98pub trait KeySizeUser {
102 type KeySize: ArraySize;
104
105 #[inline(always)]
107 #[must_use]
108 fn key_size() -> usize {
109 Self::KeySize::USIZE
110 }
111}
112
113pub trait IvSizeUser {
117 type IvSize: ArraySize;
119
120 #[inline(always)]
122 #[must_use]
123 fn iv_size() -> usize {
124 Self::IvSize::USIZE
125 }
126}
127
128pub trait InnerUser {
132 type Inner;
134}
135
136pub trait Reset {
138 fn reset(&mut self);
140}
141
142pub trait AlgorithmName {
144 fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result;
150}
151
152pub trait KeyExport: KeySizeUser {
154 fn to_bytes(&self) -> Key<Self>;
156}
157
158pub trait KeyInit: KeySizeUser + Sized {
160 fn new(key: &Key<Self>) -> Self;
162
163 #[inline]
169 fn new_from_slice(key: &[u8]) -> Result<Self, InvalidLength> {
170 <&Key<Self>>::try_from(key)
171 .map(Self::new)
172 .map_err(|_| InvalidLength)
173 }
174
175 #[deprecated(
183 since = "0.2.0",
184 note = "use the `Generate` trait impl on `Key` instead"
185 )]
186 #[cfg(feature = "rand_core")]
187 fn generate_key<R: CryptoRng>(rng: &mut R) -> Key<Self> {
188 Key::<Self>::generate_from_rng(rng)
189 }
190}
191
192pub trait KeyIvInit: KeySizeUser + IvSizeUser + Sized {
194 fn new(key: &Key<Self>, iv: &Iv<Self>) -> Self;
196
197 #[inline]
202 fn new_from_slices(key: &[u8], iv: &[u8]) -> Result<Self, InvalidLength> {
203 let key = <&Key<Self>>::try_from(key).map_err(|_| InvalidLength)?;
204 let iv = <&Iv<Self>>::try_from(iv).map_err(|_| InvalidLength)?;
205 Ok(Self::new(key, iv))
206 }
207
208 #[deprecated(
216 since = "0.2.0",
217 note = "use the `Generate` trait impl on `Key` instead"
218 )]
219 #[cfg(feature = "rand_core")]
220 fn generate_key<R: CryptoRng>(rng: &mut R) -> Key<Self> {
221 Key::<Self>::generate_from_rng(rng)
222 }
223
224 #[deprecated(
232 since = "0.2.0",
233 note = "use the `Generate` trait impl on `Iv` instead"
234 )]
235 #[cfg(feature = "rand_core")]
236 fn generate_iv<R: CryptoRng>(rng: &mut R) -> Iv<Self> {
237 Iv::<Self>::generate_from_rng(rng)
238 }
239
240 #[deprecated(
249 since = "0.2.0",
250 note = "use the `Generate` trait impls on `Key` and `Iv` instead"
251 )]
252 #[cfg(feature = "rand_core")]
253 fn generate_key_iv<R: CryptoRng>(rng: &mut R) -> (Key<Self>, Iv<Self>) {
254 let key = Key::<Self>::generate_from_rng(rng);
255 let iv = Iv::<Self>::generate_from_rng(rng);
256 (key, iv)
257 }
258}
259
260pub trait TryKeyInit: KeySizeUser + Sized {
262 fn new(key: &Key<Self>) -> Result<Self, InvalidKey>;
267
268 #[inline]
273 fn new_from_slice(key: &[u8]) -> Result<Self, InvalidKey> {
274 <&Key<Self>>::try_from(key)
275 .map_err(|_| InvalidKey)
276 .and_then(Self::new)
277 }
278}
279
280pub trait InnerInit: InnerUser + Sized {
284 fn inner_init(inner: Self::Inner) -> Self;
286}
287
288pub trait InnerIvInit: InnerUser + IvSizeUser + Sized {
293 fn inner_iv_init(inner: Self::Inner, iv: &Iv<Self>) -> Self;
295
296 #[inline]
301 fn inner_iv_slice_init(inner: Self::Inner, iv: &[u8]) -> Result<Self, InvalidLength> {
302 let iv = <&Iv<Self>>::try_from(iv).map_err(|_| InvalidLength)?;
303 Ok(Self::inner_iv_init(inner, iv))
304 }
305}
306
307pub trait IvState: IvSizeUser {
309 fn iv_state(&self) -> Iv<Self>;
311}
312
313impl<T> KeySizeUser for T
314where
315 T: InnerUser,
316 T::Inner: KeySizeUser,
317{
318 type KeySize = <T::Inner as KeySizeUser>::KeySize;
319}
320
321impl<T> KeyIvInit for T
322where
323 T: InnerIvInit,
324 T::Inner: KeyInit,
325{
326 #[inline]
327 fn new(key: &Key<Self>, iv: &Iv<Self>) -> Self {
328 Self::inner_iv_init(T::Inner::new(key), iv)
329 }
330
331 #[inline]
332 fn new_from_slices(key: &[u8], iv: &[u8]) -> Result<Self, InvalidLength> {
333 T::Inner::new_from_slice(key).and_then(|i| T::inner_iv_slice_init(i, iv))
334 }
335}
336
337impl<T> KeyInit for T
338where
339 T: InnerInit,
340 T::Inner: KeyInit,
341{
342 #[inline]
343 fn new(key: &Key<Self>) -> Self {
344 Self::inner_init(T::Inner::new(key))
345 }
346
347 #[inline]
348 fn new_from_slice(key: &[u8]) -> Result<Self, InvalidLength> {
349 T::Inner::new_from_slice(key)
350 .map_err(|_| InvalidLength)
351 .map(Self::inner_init)
352 }
353}
354
355#[derive(Copy, Clone, Eq, PartialEq, Debug)]
358pub struct InvalidKey;
359
360impl fmt::Display for InvalidKey {
361 #[inline]
362 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
363 f.write_str("InvalidKey")
364 }
365}
366
367impl core::error::Error for InvalidKey {}
368
369#[derive(Copy, Clone, Eq, PartialEq, Debug)]
373pub struct InvalidLength;
374
375impl fmt::Display for InvalidLength {
376 #[inline]
377 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
378 f.write_str("Invalid Length")
379 }
380}
381
382impl core::error::Error for InvalidLength {}