1#![deny(unsafe_code)]
10
11cpubits::cpubits! {
12 16 | 32 => {
13 #[path = "soft/fixslice32.rs"]
14 pub(crate) mod fixslice;
15 }
16 64 => {
17 #[path = "soft/fixslice64.rs"]
18 pub(crate) mod fixslice;
19 }
20}
21
22use crate::Block;
23use cipher::{
24 AlgorithmName, BlockCipherDecBackend, BlockCipherDecClosure, BlockCipherDecrypt,
25 BlockCipherEncBackend, BlockCipherEncClosure, BlockCipherEncrypt, BlockSizeUser, Key, KeyInit,
26 KeySizeUser, ParBlocksSizeUser,
27 consts::{U16, U24, U32},
28 inout::InOut,
29};
30use core::fmt;
31use fixslice::{BatchBlocks, FixsliceBlocks, FixsliceKeys128, FixsliceKeys192, FixsliceKeys256};
32
33macro_rules! define_aes_impl {
34 (
35 $name:tt,
36 $name_enc:ident,
37 $name_dec:ident,
38 $name_back_enc:ident,
39 $name_back_dec:ident,
40 $key_size:ty,
41 $fixslice_keys:ty,
42 $fixslice_key_schedule:path,
43 $fixslice_decrypt:path,
44 $fixslice_encrypt:path,
45 $doc:expr $(,)?
46 ) => {
47 #[doc=$doc]
48 #[doc = "block cipher"]
49 #[derive(Clone)]
50 pub struct $name {
51 keys: $fixslice_keys,
52 }
53
54 impl KeySizeUser for $name {
55 type KeySize = $key_size;
56 }
57
58 impl KeyInit for $name {
59 #[inline]
60 fn new(key: &Key<Self>) -> Self {
61 Self {
62 keys: $fixslice_key_schedule(key.into()),
63 }
64 }
65 }
66
67 impl BlockSizeUser for $name {
68 type BlockSize = U16;
69 }
70
71 impl BlockCipherEncrypt for $name {
72 fn encrypt_with_backend(&self, f: impl BlockCipherEncClosure<BlockSize = U16>) {
73 f.call(&$name_back_enc(self))
74 }
75 }
76
77 impl BlockCipherDecrypt for $name {
78 fn decrypt_with_backend(&self, f: impl BlockCipherDecClosure<BlockSize = U16>) {
79 f.call(&$name_back_dec(self))
80 }
81 }
82
83 impl From<$name_enc> for $name {
84 #[inline]
85 fn from(enc: $name_enc) -> $name {
86 enc.inner
87 }
88 }
89
90 impl From<&$name_enc> for $name {
91 #[inline]
92 fn from(enc: &$name_enc) -> $name {
93 enc.inner.clone()
94 }
95 }
96
97 impl fmt::Debug for $name {
98 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
99 f.write_str(concat!(stringify!($name), " { .. }"))
100 }
101 }
102
103 impl AlgorithmName for $name {
104 fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result {
105 f.write_str(stringify!($name))
106 }
107 }
108
109 impl Drop for $name {
110 #[inline]
111 fn drop(&mut self) {
112 #[cfg(feature = "zeroize")]
113 zeroize::Zeroize::zeroize(&mut self.keys);
114 }
115 }
116
117 #[cfg(feature = "zeroize")]
118 impl zeroize::ZeroizeOnDrop for $name {}
119
120 #[doc=$doc]
121 #[doc = "block cipher (encrypt-only)"]
122 #[derive(Clone)]
123 pub struct $name_enc {
124 inner: $name,
125 }
126
127 impl KeySizeUser for $name_enc {
128 type KeySize = $key_size;
129 }
130
131 impl KeyInit for $name_enc {
132 #[inline(always)]
133 fn new(key: &Key<Self>) -> Self {
134 let inner = $name::new(key);
135 Self { inner }
136 }
137 }
138
139 impl BlockSizeUser for $name_enc {
140 type BlockSize = U16;
141 }
142
143 impl BlockCipherEncrypt for $name_enc {
144 fn encrypt_with_backend(&self, f: impl BlockCipherEncClosure<BlockSize = U16>) {
145 f.call(&mut $name_back_enc(&self.inner))
146 }
147 }
148
149 impl fmt::Debug for $name_enc {
150 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
151 f.write_str(concat!(stringify!($name_enc), " { .. }"))
152 }
153 }
154
155 impl AlgorithmName for $name_enc {
156 fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result {
157 f.write_str(stringify!($name_enc))
158 }
159 }
160
161 #[cfg(feature = "zeroize")]
162 impl zeroize::ZeroizeOnDrop for $name_enc {}
163
164 #[doc=$doc]
165 #[doc = "block cipher (decrypt-only)"]
166 #[derive(Clone)]
167 pub struct $name_dec {
168 inner: $name,
169 }
170
171 impl KeySizeUser for $name_dec {
172 type KeySize = $key_size;
173 }
174
175 impl KeyInit for $name_dec {
176 #[inline(always)]
177 fn new(key: &Key<Self>) -> Self {
178 let inner = $name::new(key);
179 Self { inner }
180 }
181 }
182
183 impl From<$name_enc> for $name_dec {
184 #[inline]
185 fn from(enc: $name_enc) -> $name_dec {
186 Self { inner: enc.inner }
187 }
188 }
189
190 impl From<&$name_enc> for $name_dec {
191 #[inline]
192 fn from(enc: &$name_enc) -> $name_dec {
193 Self {
194 inner: enc.inner.clone(),
195 }
196 }
197 }
198
199 impl BlockSizeUser for $name_dec {
200 type BlockSize = U16;
201 }
202
203 impl BlockCipherDecrypt for $name_dec {
204 fn decrypt_with_backend(&self, f: impl BlockCipherDecClosure<BlockSize = U16>) {
205 f.call(&$name_back_dec(&self.inner));
206 }
207 }
208
209 impl fmt::Debug for $name_dec {
210 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
211 f.write_str(concat!(stringify!($name_dec), " { .. }"))
212 }
213 }
214
215 impl AlgorithmName for $name_dec {
216 fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result {
217 f.write_str(stringify!($name_dec))
218 }
219 }
220
221 #[cfg(feature = "zeroize")]
222 impl zeroize::ZeroizeOnDrop for $name_dec {}
223
224 pub(crate) struct $name_back_enc<'a>(&'a $name);
225
226 impl<'a> BlockSizeUser for $name_back_enc<'a> {
227 type BlockSize = U16;
228 }
229
230 impl<'a> ParBlocksSizeUser for $name_back_enc<'a> {
231 type ParBlocksSize = FixsliceBlocks;
232 }
233
234 impl<'a> BlockCipherEncBackend for $name_back_enc<'a> {
235 #[inline(always)]
236 fn encrypt_block(&self, mut block: InOut<'_, '_, Block>) {
237 let mut blocks = BatchBlocks::default();
238 blocks[0] = block.clone_in().into();
239 let res = $fixslice_encrypt(&self.0.keys, &blocks);
240 *block.get_out() = res[0].into();
241 }
242
243 #[inline(always)]
244 fn encrypt_par_blocks(&self, mut blocks: InOut<'_, '_, BatchBlocks>) {
245 let res = $fixslice_encrypt(&self.0.keys, blocks.get_in());
246 *blocks.get_out() = res;
247 }
248 }
249
250 pub(crate) struct $name_back_dec<'a>(&'a $name);
251
252 impl<'a> BlockSizeUser for $name_back_dec<'a> {
253 type BlockSize = U16;
254 }
255
256 impl<'a> ParBlocksSizeUser for $name_back_dec<'a> {
257 type ParBlocksSize = FixsliceBlocks;
258 }
259
260 impl<'a> BlockCipherDecBackend for $name_back_dec<'a> {
261 #[inline(always)]
262 fn decrypt_block(&self, mut block: InOut<'_, '_, Block>) {
263 let mut blocks = BatchBlocks::default();
264 blocks[0] = block.clone_in();
265 let res = $fixslice_decrypt(&self.0.keys, &blocks);
266 *block.get_out() = res[0];
267 }
268
269 #[inline(always)]
270 fn decrypt_par_blocks(&self, mut blocks: InOut<'_, '_, BatchBlocks>) {
271 let res = $fixslice_decrypt(&self.0.keys, blocks.get_in());
272 *blocks.get_out() = res;
273 }
274 }
275 };
276}
277
278define_aes_impl!(
279 Aes128,
280 Aes128Enc,
281 Aes128Dec,
282 Aes128BackEnc,
283 Aes128BackDec,
284 U16,
285 FixsliceKeys128,
286 fixslice::aes128_key_schedule,
287 fixslice::aes128_decrypt,
288 fixslice::aes128_encrypt,
289 "AES-128",
290);
291
292define_aes_impl!(
293 Aes192,
294 Aes192Enc,
295 Aes192Dec,
296 Aes192BackEnc,
297 Aes192BackDec,
298 U24,
299 FixsliceKeys192,
300 fixslice::aes192_key_schedule,
301 fixslice::aes192_decrypt,
302 fixslice::aes192_encrypt,
303 "AES-192",
304);
305
306define_aes_impl!(
307 Aes256,
308 Aes256Enc,
309 Aes256Dec,
310 Aes256BackEnc,
311 Aes256BackDec,
312 U32,
313 FixsliceKeys256,
314 fixslice::aes256_key_schedule,
315 fixslice::aes256_decrypt,
316 fixslice::aes256_encrypt,
317 "AES-256",
318);