Coverage Report

Created: 2025-10-10 07:05

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