Coverage Report

Created: 2026-02-14 06:35

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/aes-0.8.4/src/ni.rs
Line
Count
Source
1
//! AES block ciphers implementation using AES-NI instruction set.
2
//!
3
//! Ciphers functionality is accessed using `BlockCipher` trait from the
4
//! [`cipher`](https://docs.rs/cipher) crate.
5
//!
6
//! # Vulnerability
7
//! Lazy FP state restory vulnerability can allow local process to leak content
8
//! of the FPU register, in which round keys are stored. This vulnerability
9
//! can be mitigated at the operating system level by installing relevant
10
//! patches. (i.e. keep your OS updated!) More info:
11
//! - [Intel advisory](https://www.intel.com/content/www/us/en/security-center/advisory/intel-sa-00145.html)
12
//! - [Wikipedia](https://en.wikipedia.org/wiki/Lazy_FP_state_restore)
13
//!
14
//! # Related documents
15
//! - [Intel AES-NI whitepaper](https://software.intel.com/sites/default/files/article/165683/aes-wp-2012-09-22-v01.pdf)
16
//! - [Use of the AES Instruction Set](https://www.cosic.esat.kuleuven.be/ecrypt/AESday/slides/Use_of_the_AES_Instruction_Set.pdf)
17
18
#[macro_use]
19
mod utils;
20
21
mod aes128;
22
mod aes192;
23
mod aes256;
24
25
#[cfg(test)]
26
mod test_expand;
27
28
#[cfg(feature = "hazmat")]
29
pub(crate) mod hazmat;
30
31
#[cfg(target_arch = "x86")]
32
use core::arch::x86 as arch;
33
#[cfg(target_arch = "x86_64")]
34
use core::arch::x86_64 as arch;
35
36
use crate::{Block, Block8};
37
use cipher::{
38
    consts::{U16, U24, U32, U8},
39
    inout::InOut,
40
    AlgorithmName, BlockBackend, BlockCipher, BlockClosure, BlockDecrypt, BlockEncrypt,
41
    BlockSizeUser, Key, KeyInit, KeySizeUser, ParBlocksSizeUser,
42
};
43
use core::fmt;
44
45
macro_rules! define_aes_impl {
46
    (
47
        $name:tt,
48
        $name_enc:ident,
49
        $name_dec:ident,
50
        $name_back_enc:ident,
51
        $name_back_dec:ident,
52
        $module:tt,
53
        $key_size:ty,
54
        $doc:expr $(,)?
55
    ) => {
56
        #[doc=$doc]
57
        #[doc = "block cipher"]
58
        #[derive(Clone)]
59
        pub struct $name {
60
            encrypt: $name_enc,
61
            decrypt: $name_dec,
62
        }
63
64
        impl $name {
65
            #[inline(always)]
66
28.0k
            pub(crate) fn get_enc_backend(&self) -> $name_back_enc<'_> {
67
28.0k
                self.encrypt.get_enc_backend()
68
28.0k
            }
<aes::ni::Aes256>::get_enc_backend
Line
Count
Source
66
28.0k
            pub(crate) fn get_enc_backend(&self) -> $name_back_enc<'_> {
67
28.0k
                self.encrypt.get_enc_backend()
68
28.0k
            }
Unexecuted instantiation: <aes::ni::Aes128>::get_enc_backend
Unexecuted instantiation: <aes::ni::Aes192>::get_enc_backend
69
70
            #[inline(always)]
71
0
            pub(crate) fn get_dec_backend(&self) -> $name_back_dec<'_> {
72
0
                self.decrypt.get_dec_backend()
73
0
            }
Unexecuted instantiation: <aes::ni::Aes256>::get_dec_backend
Unexecuted instantiation: <aes::ni::Aes128>::get_dec_backend
Unexecuted instantiation: <aes::ni::Aes192>::get_dec_backend
74
        }
75
76
        impl BlockCipher for $name {}
77
78
        impl KeySizeUser for $name {
79
            type KeySize = $key_size;
80
        }
81
82
        impl KeyInit for $name {
83
            #[inline]
84
2.33k
            fn new(key: &Key<Self>) -> Self {
85
2.33k
                let encrypt = $name_enc::new(key);
86
2.33k
                let decrypt = $name_dec::from(&encrypt);
87
2.33k
                Self { encrypt, decrypt }
88
2.33k
            }
<aes::ni::Aes256 as crypto_common::KeyInit>::new
Line
Count
Source
84
2.33k
            fn new(key: &Key<Self>) -> Self {
85
2.33k
                let encrypt = $name_enc::new(key);
86
2.33k
                let decrypt = $name_dec::from(&encrypt);
87
2.33k
                Self { encrypt, decrypt }
88
2.33k
            }
Unexecuted instantiation: <aes::ni::Aes128 as crypto_common::KeyInit>::new
Unexecuted instantiation: <aes::ni::Aes256 as crypto_common::KeyInit>::new
Unexecuted instantiation: <aes::ni::Aes192 as crypto_common::KeyInit>::new
89
        }
90
91
        impl From<$name_enc> for $name {
92
            #[inline]
93
0
            fn from(encrypt: $name_enc) -> $name {
94
0
                let decrypt = (&encrypt).into();
95
0
                Self { encrypt, decrypt }
96
0
            }
Unexecuted instantiation: <aes::ni::Aes256 as core::convert::From<aes::ni::Aes256Enc>>::from
Unexecuted instantiation: <aes::ni::Aes128 as core::convert::From<aes::ni::Aes128Enc>>::from
Unexecuted instantiation: <aes::ni::Aes192 as core::convert::From<aes::ni::Aes192Enc>>::from
97
        }
98
99
        impl From<&$name_enc> for $name {
100
            #[inline]
101
0
            fn from(encrypt: &$name_enc) -> $name {
102
0
                let decrypt = encrypt.into();
103
0
                let encrypt = encrypt.clone();
104
0
                Self { encrypt, decrypt }
105
0
            }
Unexecuted instantiation: <aes::ni::Aes256 as core::convert::From<&aes::ni::Aes256Enc>>::from
Unexecuted instantiation: <aes::ni::Aes128 as core::convert::From<&aes::ni::Aes128Enc>>::from
Unexecuted instantiation: <aes::ni::Aes192 as core::convert::From<&aes::ni::Aes192Enc>>::from
106
        }
107
108
        impl BlockSizeUser for $name {
109
            type BlockSize = U16;
110
        }
111
112
        impl BlockEncrypt for $name {
113
0
            fn encrypt_with_backend(&self, f: impl BlockClosure<BlockSize = U16>) {
114
0
                self.encrypt.encrypt_with_backend(f)
115
0
            }
Unexecuted instantiation: <aes::ni::Aes256 as cipher::block::BlockEncrypt>::encrypt_with_backend::<_>
Unexecuted instantiation: <aes::ni::Aes128 as cipher::block::BlockEncrypt>::encrypt_with_backend::<_>
Unexecuted instantiation: <aes::ni::Aes192 as cipher::block::BlockEncrypt>::encrypt_with_backend::<_>
116
        }
117
118
        impl BlockDecrypt for $name {
119
0
            fn decrypt_with_backend(&self, f: impl BlockClosure<BlockSize = U16>) {
120
0
                self.decrypt.decrypt_with_backend(f)
121
0
            }
Unexecuted instantiation: <aes::ni::Aes256 as cipher::block::BlockDecrypt>::decrypt_with_backend::<_>
Unexecuted instantiation: <aes::ni::Aes128 as cipher::block::BlockDecrypt>::decrypt_with_backend::<_>
Unexecuted instantiation: <aes::ni::Aes192 as cipher::block::BlockDecrypt>::decrypt_with_backend::<_>
122
        }
123
124
        impl fmt::Debug for $name {
125
0
            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
126
0
                f.write_str(concat!(stringify!($name), " { .. }"))
127
0
            }
Unexecuted instantiation: <aes::ni::Aes256 as core::fmt::Debug>::fmt
Unexecuted instantiation: <aes::ni::Aes128 as core::fmt::Debug>::fmt
Unexecuted instantiation: <aes::ni::Aes192 as core::fmt::Debug>::fmt
128
        }
129
130
        impl AlgorithmName for $name {
131
0
            fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result {
132
0
                f.write_str(stringify!($name))
133
0
            }
Unexecuted instantiation: <aes::ni::Aes256 as crypto_common::AlgorithmName>::write_alg_name
Unexecuted instantiation: <aes::ni::Aes128 as crypto_common::AlgorithmName>::write_alg_name
Unexecuted instantiation: <aes::ni::Aes192 as crypto_common::AlgorithmName>::write_alg_name
134
        }
135
136
        #[cfg(feature = "zeroize")]
137
        impl zeroize::ZeroizeOnDrop for $name {}
138
139
        #[doc=$doc]
140
        #[doc = "block cipher (encrypt-only)"]
141
        #[derive(Clone)]
142
        pub struct $name_enc {
143
            round_keys: $module::RoundKeys,
144
        }
145
146
        impl $name_enc {
147
            #[inline(always)]
148
28.0k
            pub(crate) fn get_enc_backend(&self) -> $name_back_enc<'_> {
149
28.0k
                $name_back_enc(self)
150
28.0k
            }
<aes::ni::Aes256Enc>::get_enc_backend
Line
Count
Source
148
28.0k
            pub(crate) fn get_enc_backend(&self) -> $name_back_enc<'_> {
149
28.0k
                $name_back_enc(self)
150
28.0k
            }
Unexecuted instantiation: <aes::ni::Aes128Enc>::get_enc_backend
Unexecuted instantiation: <aes::ni::Aes192Enc>::get_enc_backend
151
        }
152
153
        impl BlockCipher for $name_enc {}
154
155
        impl KeySizeUser for $name_enc {
156
            type KeySize = $key_size;
157
        }
158
159
        impl KeyInit for $name_enc {
160
2.33k
            fn new(key: &Key<Self>) -> Self {
161
                // SAFETY: we enforce that this code is called only when
162
                // target features required by `expand` were properly checked.
163
2.33k
                Self {
164
2.33k
                    round_keys: unsafe { $module::expand_key(key.as_ref()) },
165
2.33k
                }
166
2.33k
            }
<aes::ni::Aes256Enc as crypto_common::KeyInit>::new
Line
Count
Source
160
2.33k
            fn new(key: &Key<Self>) -> Self {
161
                // SAFETY: we enforce that this code is called only when
162
                // target features required by `expand` were properly checked.
163
2.33k
                Self {
164
2.33k
                    round_keys: unsafe { $module::expand_key(key.as_ref()) },
165
2.33k
                }
166
2.33k
            }
Unexecuted instantiation: <aes::ni::Aes192Enc as crypto_common::KeyInit>::new
Unexecuted instantiation: <aes::ni::Aes128Enc as crypto_common::KeyInit>::new
167
        }
168
169
        impl BlockSizeUser for $name_enc {
170
            type BlockSize = U16;
171
        }
172
173
        impl BlockEncrypt for $name_enc {
174
0
            fn encrypt_with_backend(&self, f: impl BlockClosure<BlockSize = U16>) {
175
0
                f.call(&mut self.get_enc_backend())
176
0
            }
Unexecuted instantiation: <aes::ni::Aes256Enc as cipher::block::BlockEncrypt>::encrypt_with_backend::<_>
Unexecuted instantiation: <aes::ni::Aes192Enc as cipher::block::BlockEncrypt>::encrypt_with_backend::<_>
Unexecuted instantiation: <aes::ni::Aes128Enc as cipher::block::BlockEncrypt>::encrypt_with_backend::<_>
177
        }
178
179
        impl fmt::Debug for $name_enc {
180
0
            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
181
0
                f.write_str(concat!(stringify!($name_enc), " { .. }"))
182
0
            }
Unexecuted instantiation: <aes::ni::Aes256Enc as core::fmt::Debug>::fmt
Unexecuted instantiation: <aes::ni::Aes192Enc as core::fmt::Debug>::fmt
Unexecuted instantiation: <aes::ni::Aes128Enc as core::fmt::Debug>::fmt
183
        }
184
185
        impl AlgorithmName for $name_enc {
186
0
            fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result {
187
0
                f.write_str(stringify!($name_enc))
188
0
            }
Unexecuted instantiation: <aes::ni::Aes256Enc as crypto_common::AlgorithmName>::write_alg_name
Unexecuted instantiation: <aes::ni::Aes192Enc as crypto_common::AlgorithmName>::write_alg_name
Unexecuted instantiation: <aes::ni::Aes128Enc as crypto_common::AlgorithmName>::write_alg_name
189
        }
190
191
        impl Drop for $name_enc {
192
            #[inline]
193
2.33k
            fn drop(&mut self) {
194
                #[cfg(feature = "zeroize")]
195
                zeroize::Zeroize::zeroize(&mut self.round_keys);
196
2.33k
            }
<aes::ni::Aes256Enc as core::ops::drop::Drop>::drop
Line
Count
Source
193
2.33k
            fn drop(&mut self) {
194
                #[cfg(feature = "zeroize")]
195
                zeroize::Zeroize::zeroize(&mut self.round_keys);
196
2.33k
            }
Unexecuted instantiation: <aes::ni::Aes192Enc as core::ops::drop::Drop>::drop
Unexecuted instantiation: <aes::ni::Aes128Enc as core::ops::drop::Drop>::drop
197
        }
198
199
        #[cfg(feature = "zeroize")]
200
        impl zeroize::ZeroizeOnDrop for $name_enc {}
201
202
        #[doc=$doc]
203
        #[doc = "block cipher (decrypt-only)"]
204
        #[derive(Clone)]
205
        pub struct $name_dec {
206
            round_keys: $module::RoundKeys,
207
        }
208
209
        impl $name_dec {
210
            #[inline(always)]
211
0
            pub(crate) fn get_dec_backend(&self) -> $name_back_dec<'_> {
212
0
                $name_back_dec(self)
213
0
            }
Unexecuted instantiation: <aes::ni::Aes256Dec>::get_dec_backend
Unexecuted instantiation: <aes::ni::Aes192Dec>::get_dec_backend
Unexecuted instantiation: <aes::ni::Aes128Dec>::get_dec_backend
214
        }
215
216
        impl BlockCipher for $name_dec {}
217
218
        impl KeySizeUser for $name_dec {
219
            type KeySize = $key_size;
220
        }
221
222
        impl KeyInit for $name_dec {
223
0
            fn new(key: &Key<Self>) -> Self {
224
0
                $name_enc::new(key).into()
225
0
            }
Unexecuted instantiation: <aes::ni::Aes256Dec as crypto_common::KeyInit>::new
Unexecuted instantiation: <aes::ni::Aes192Dec as crypto_common::KeyInit>::new
Unexecuted instantiation: <aes::ni::Aes128Dec as crypto_common::KeyInit>::new
226
        }
227
228
        impl From<$name_enc> for $name_dec {
229
            #[inline]
230
0
            fn from(enc: $name_enc) -> $name_dec {
231
0
                Self::from(&enc)
232
0
            }
Unexecuted instantiation: <aes::ni::Aes192Dec as core::convert::From<aes::ni::Aes192Enc>>::from
Unexecuted instantiation: <aes::ni::Aes256Dec as core::convert::From<aes::ni::Aes256Enc>>::from
Unexecuted instantiation: <aes::ni::Aes128Dec as core::convert::From<aes::ni::Aes128Enc>>::from
233
        }
234
235
        impl From<&$name_enc> for $name_dec {
236
            #[inline]
237
2.33k
            fn from(enc: &$name_enc) -> $name_dec {
238
2.33k
                let round_keys = unsafe { $module::inv_expanded_keys(&enc.round_keys) };
239
2.33k
                Self { round_keys }
240
2.33k
            }
<aes::ni::Aes256Dec as core::convert::From<&aes::ni::Aes256Enc>>::from
Line
Count
Source
237
2.33k
            fn from(enc: &$name_enc) -> $name_dec {
238
2.33k
                let round_keys = unsafe { $module::inv_expanded_keys(&enc.round_keys) };
239
2.33k
                Self { round_keys }
240
2.33k
            }
Unexecuted instantiation: <aes::ni::Aes192Dec as core::convert::From<&aes::ni::Aes192Enc>>::from
Unexecuted instantiation: <aes::ni::Aes256Dec as core::convert::From<&aes::ni::Aes256Enc>>::from
Unexecuted instantiation: <aes::ni::Aes128Dec as core::convert::From<&aes::ni::Aes128Enc>>::from
241
        }
242
243
        impl BlockSizeUser for $name_dec {
244
            type BlockSize = U16;
245
        }
246
247
        impl BlockDecrypt for $name_dec {
248
0
            fn decrypt_with_backend(&self, f: impl BlockClosure<BlockSize = U16>) {
249
0
                f.call(&mut self.get_dec_backend());
250
0
            }
Unexecuted instantiation: <aes::ni::Aes192Dec as cipher::block::BlockDecrypt>::decrypt_with_backend::<_>
Unexecuted instantiation: <aes::ni::Aes256Dec as cipher::block::BlockDecrypt>::decrypt_with_backend::<_>
Unexecuted instantiation: <aes::ni::Aes128Dec as cipher::block::BlockDecrypt>::decrypt_with_backend::<_>
251
        }
252
253
        impl fmt::Debug for $name_dec {
254
0
            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
255
0
                f.write_str(concat!(stringify!($name_dec), " { .. }"))
256
0
            }
Unexecuted instantiation: <aes::ni::Aes192Dec as core::fmt::Debug>::fmt
Unexecuted instantiation: <aes::ni::Aes256Dec as core::fmt::Debug>::fmt
Unexecuted instantiation: <aes::ni::Aes128Dec as core::fmt::Debug>::fmt
257
        }
258
259
        impl AlgorithmName for $name_dec {
260
0
            fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result {
261
0
                f.write_str(stringify!($name_dec))
262
0
            }
Unexecuted instantiation: <aes::ni::Aes192Dec as crypto_common::AlgorithmName>::write_alg_name
Unexecuted instantiation: <aes::ni::Aes256Dec as crypto_common::AlgorithmName>::write_alg_name
Unexecuted instantiation: <aes::ni::Aes128Dec as crypto_common::AlgorithmName>::write_alg_name
263
        }
264
265
        impl Drop for $name_dec {
266
            #[inline]
267
2.33k
            fn drop(&mut self) {
268
                #[cfg(feature = "zeroize")]
269
                zeroize::Zeroize::zeroize(&mut self.round_keys);
270
2.33k
            }
Unexecuted instantiation: <aes::ni::Aes192Dec as core::ops::drop::Drop>::drop
<aes::ni::Aes256Dec as core::ops::drop::Drop>::drop
Line
Count
Source
267
2.33k
            fn drop(&mut self) {
268
                #[cfg(feature = "zeroize")]
269
                zeroize::Zeroize::zeroize(&mut self.round_keys);
270
2.33k
            }
Unexecuted instantiation: <aes::ni::Aes128Dec as core::ops::drop::Drop>::drop
271
        }
272
273
        #[cfg(feature = "zeroize")]
274
        impl zeroize::ZeroizeOnDrop for $name_dec {}
275
276
        pub(crate) struct $name_back_enc<'a>(&'a $name_enc);
277
278
        impl<'a> BlockSizeUser for $name_back_enc<'a> {
279
            type BlockSize = U16;
280
        }
281
282
        impl<'a> ParBlocksSizeUser for $name_back_enc<'a> {
283
            type ParBlocksSize = U8;
284
        }
285
286
        impl<'a> BlockBackend for $name_back_enc<'a> {
287
            #[inline(always)]
288
28.0k
            fn proc_block(&mut self, block: InOut<'_, '_, Block>) {
289
28.0k
                unsafe {
290
28.0k
                    $module::encrypt1(&self.0.round_keys, block);
291
28.0k
                }
292
28.0k
            }
<aes::ni::Aes256BackEnc as cipher::block::BlockBackend>::proc_block
Line
Count
Source
288
28.0k
            fn proc_block(&mut self, block: InOut<'_, '_, Block>) {
289
28.0k
                unsafe {
290
28.0k
                    $module::encrypt1(&self.0.round_keys, block);
291
28.0k
                }
292
28.0k
            }
Unexecuted instantiation: <aes::ni::Aes192BackEnc as cipher::block::BlockBackend>::proc_block
Unexecuted instantiation: <aes::ni::Aes128BackEnc as cipher::block::BlockBackend>::proc_block
293
294
            #[inline(always)]
295
0
            fn proc_par_blocks(&mut self, blocks: InOut<'_, '_, Block8>) {
296
0
                unsafe {
297
0
                    $module::encrypt8(&self.0.round_keys, blocks);
298
0
                }
299
0
            }
Unexecuted instantiation: <aes::ni::Aes192BackEnc as cipher::block::BlockBackend>::proc_par_blocks
Unexecuted instantiation: <aes::ni::Aes256BackEnc as cipher::block::BlockBackend>::proc_par_blocks
Unexecuted instantiation: <aes::ni::Aes128BackEnc as cipher::block::BlockBackend>::proc_par_blocks
300
        }
301
302
        pub(crate) struct $name_back_dec<'a>(&'a $name_dec);
303
304
        impl<'a> BlockSizeUser for $name_back_dec<'a> {
305
            type BlockSize = U16;
306
        }
307
308
        impl<'a> ParBlocksSizeUser for $name_back_dec<'a> {
309
            type ParBlocksSize = U8;
310
        }
311
312
        impl<'a> BlockBackend for $name_back_dec<'a> {
313
            #[inline(always)]
314
0
            fn proc_block(&mut self, block: InOut<'_, '_, Block>) {
315
0
                unsafe {
316
0
                    $module::decrypt1(&self.0.round_keys, block);
317
0
                }
318
0
            }
Unexecuted instantiation: <aes::ni::Aes256BackDec as cipher::block::BlockBackend>::proc_block
Unexecuted instantiation: <aes::ni::Aes192BackDec as cipher::block::BlockBackend>::proc_block
Unexecuted instantiation: <aes::ni::Aes128BackDec as cipher::block::BlockBackend>::proc_block
319
320
            #[inline(always)]
321
0
            fn proc_par_blocks(&mut self, blocks: InOut<'_, '_, Block8>) {
322
0
                unsafe {
323
0
                    $module::decrypt8(&self.0.round_keys, blocks);
324
0
                }
325
0
            }
Unexecuted instantiation: <aes::ni::Aes256BackDec as cipher::block::BlockBackend>::proc_par_blocks
Unexecuted instantiation: <aes::ni::Aes192BackDec as cipher::block::BlockBackend>::proc_par_blocks
Unexecuted instantiation: <aes::ni::Aes128BackDec as cipher::block::BlockBackend>::proc_par_blocks
326
        }
327
    };
328
}
329
330
define_aes_impl!(
331
    Aes128,
332
    Aes128Enc,
333
    Aes128Dec,
334
    Aes128BackEnc,
335
    Aes128BackDec,
336
    aes128,
337
    U16,
338
    "AES-128",
339
);
340
341
define_aes_impl!(
342
    Aes192,
343
    Aes192Enc,
344
    Aes192Dec,
345
    Aes192BackEnc,
346
    Aes192BackDec,
347
    aes192,
348
    U24,
349
    "AES-192",
350
);
351
352
define_aes_impl!(
353
    Aes256,
354
    Aes256Enc,
355
    Aes256Dec,
356
    Aes256BackEnc,
357
    Aes256BackDec,
358
    aes256,
359
    U32,
360
    "AES-256",
361
);