/rust/registry/src/index.crates.io-1949cf8c6b5b557f/aes-0.7.5/src/autodetect.rs
Line | Count | Source |
1 | | //! Autodetection support for hardware accelerated AES backends with fallback |
2 | | //! to the fixsliced "soft" implementation. |
3 | | |
4 | | use crate::{soft, Block, ParBlocks}; |
5 | | use cipher::{ |
6 | | consts::{U16, U24, U32, U8}, |
7 | | generic_array::GenericArray, |
8 | | BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher, |
9 | | }; |
10 | | use core::mem::ManuallyDrop; |
11 | | |
12 | | #[cfg(all(target_arch = "aarch64", feature = "armv8"))] |
13 | | use crate::armv8 as intrinsics; |
14 | | |
15 | | #[cfg(any(target_arch = "x86_64", target_arch = "x86"))] |
16 | | use crate::ni as intrinsics; |
17 | | |
18 | | cpufeatures::new!(aes_intrinsics, "aes"); |
19 | | |
20 | | macro_rules! define_aes_impl { |
21 | | ( |
22 | | $name:tt, |
23 | | $module:tt, |
24 | | $key_size:ty, |
25 | | $doc:expr |
26 | | ) => { |
27 | | #[doc=$doc] |
28 | | pub struct $name { |
29 | | inner: $module::Inner, |
30 | | token: aes_intrinsics::InitToken, |
31 | | } |
32 | | |
33 | | mod $module { |
34 | | use super::{intrinsics, soft}; |
35 | | use core::mem::ManuallyDrop; |
36 | | |
37 | | pub(super) union Inner { |
38 | | pub(super) intrinsics: ManuallyDrop<intrinsics::$name>, |
39 | | pub(super) soft: ManuallyDrop<soft::$name>, |
40 | | } |
41 | | } |
42 | | |
43 | | impl NewBlockCipher for $name { |
44 | | type KeySize = $key_size; |
45 | | |
46 | | #[inline] |
47 | 560 | fn new(key: &GenericArray<u8, $key_size>) -> Self { |
48 | 560 | let (token, aesni_present) = aes_intrinsics::init_get(); |
49 | | |
50 | 560 | let inner = if aesni_present { |
51 | 560 | $module::Inner { |
52 | 560 | intrinsics: ManuallyDrop::new(intrinsics::$name::new(key)), |
53 | 0 | } |
54 | | } else { |
55 | 0 | $module::Inner { |
56 | 0 | soft: ManuallyDrop::new(soft::$name::new(key)), |
57 | 0 | } |
58 | | }; |
59 | | |
60 | 560 | Self { inner, token } |
61 | 560 | } <aes::autodetect::Aes128 as cipher::block::NewBlockCipher>::new Line | Count | Source | 47 | 560 | fn new(key: &GenericArray<u8, $key_size>) -> Self { | 48 | 560 | let (token, aesni_present) = aes_intrinsics::init_get(); | 49 | | | 50 | 560 | let inner = if aesni_present { | 51 | 560 | $module::Inner { | 52 | 560 | intrinsics: ManuallyDrop::new(intrinsics::$name::new(key)), | 53 | 560 | } | 54 | | } else { | 55 | 0 | $module::Inner { | 56 | 0 | soft: ManuallyDrop::new(soft::$name::new(key)), | 57 | 0 | } | 58 | | }; | 59 | | | 60 | 560 | Self { inner, token } | 61 | 560 | } |
Unexecuted instantiation: <aes::autodetect::Aes192 as cipher::block::NewBlockCipher>::new Unexecuted instantiation: <aes::autodetect::Aes256 as cipher::block::NewBlockCipher>::new |
62 | | } |
63 | | |
64 | | impl Clone for $name { |
65 | 0 | fn clone(&self) -> Self { |
66 | 0 | let inner = if self.token.get() { |
67 | 0 | $module::Inner { |
68 | 0 | intrinsics: unsafe { self.inner.intrinsics.clone() }, |
69 | 0 | } |
70 | | } else { |
71 | 0 | $module::Inner { |
72 | 0 | soft: unsafe { self.inner.soft.clone() }, |
73 | 0 | } |
74 | | }; |
75 | | |
76 | 0 | Self { |
77 | 0 | inner, |
78 | 0 | token: self.token, |
79 | 0 | } |
80 | 0 | } Unexecuted instantiation: <aes::autodetect::Aes192 as core::clone::Clone>::clone Unexecuted instantiation: <aes::autodetect::Aes128 as core::clone::Clone>::clone Unexecuted instantiation: <aes::autodetect::Aes256 as core::clone::Clone>::clone |
81 | | } |
82 | | |
83 | | impl BlockCipher for $name { |
84 | | type BlockSize = U16; |
85 | | type ParBlocks = U8; |
86 | | } |
87 | | |
88 | | impl BlockEncrypt for $name { |
89 | | #[inline] |
90 | 596 | fn encrypt_block(&self, block: &mut Block) { |
91 | 596 | if self.token.get() { |
92 | 596 | unsafe { self.inner.intrinsics.encrypt_block(block) } |
93 | | } else { |
94 | 0 | unsafe { self.inner.soft.encrypt_block(block) } |
95 | | } |
96 | 596 | } <aes::autodetect::Aes128 as cipher::block::BlockEncrypt>::encrypt_block Line | Count | Source | 90 | 596 | fn encrypt_block(&self, block: &mut Block) { | 91 | 596 | if self.token.get() { | 92 | 596 | unsafe { self.inner.intrinsics.encrypt_block(block) } | 93 | | } else { | 94 | 0 | unsafe { self.inner.soft.encrypt_block(block) } | 95 | | } | 96 | 596 | } |
Unexecuted instantiation: <aes::autodetect::Aes192 as cipher::block::BlockEncrypt>::encrypt_block Unexecuted instantiation: <aes::autodetect::Aes256 as cipher::block::BlockEncrypt>::encrypt_block |
97 | | |
98 | | #[inline] |
99 | 4 | fn encrypt_par_blocks(&self, blocks: &mut ParBlocks) { |
100 | 4 | if self.token.get() { |
101 | 4 | unsafe { self.inner.intrinsics.encrypt_par_blocks(blocks) } |
102 | | } else { |
103 | 0 | unsafe { self.inner.soft.encrypt_par_blocks(blocks) } |
104 | | } |
105 | 4 | } <aes::autodetect::Aes128 as cipher::block::BlockEncrypt>::encrypt_par_blocks Line | Count | Source | 99 | 4 | fn encrypt_par_blocks(&self, blocks: &mut ParBlocks) { | 100 | 4 | if self.token.get() { | 101 | 4 | unsafe { self.inner.intrinsics.encrypt_par_blocks(blocks) } | 102 | | } else { | 103 | 0 | unsafe { self.inner.soft.encrypt_par_blocks(blocks) } | 104 | | } | 105 | 4 | } |
Unexecuted instantiation: <aes::autodetect::Aes192 as cipher::block::BlockEncrypt>::encrypt_par_blocks Unexecuted instantiation: <aes::autodetect::Aes256 as cipher::block::BlockEncrypt>::encrypt_par_blocks |
106 | | } |
107 | | |
108 | | impl BlockDecrypt for $name { |
109 | | #[inline] |
110 | 0 | fn decrypt_block(&self, block: &mut Block) { |
111 | 0 | if self.token.get() { |
112 | 0 | unsafe { self.inner.intrinsics.decrypt_block(block) } |
113 | | } else { |
114 | 0 | unsafe { self.inner.soft.decrypt_block(block) } |
115 | | } |
116 | 0 | } Unexecuted instantiation: <aes::autodetect::Aes128 as cipher::block::BlockDecrypt>::decrypt_block Unexecuted instantiation: <aes::autodetect::Aes192 as cipher::block::BlockDecrypt>::decrypt_block Unexecuted instantiation: <aes::autodetect::Aes256 as cipher::block::BlockDecrypt>::decrypt_block |
117 | | |
118 | | #[inline] |
119 | 0 | fn decrypt_par_blocks(&self, blocks: &mut ParBlocks) { |
120 | 0 | if self.token.get() { |
121 | 0 | unsafe { self.inner.intrinsics.decrypt_par_blocks(blocks) } |
122 | | } else { |
123 | 0 | unsafe { self.inner.soft.decrypt_par_blocks(blocks) } |
124 | | } |
125 | 0 | } Unexecuted instantiation: <aes::autodetect::Aes128 as cipher::block::BlockDecrypt>::decrypt_par_blocks Unexecuted instantiation: <aes::autodetect::Aes192 as cipher::block::BlockDecrypt>::decrypt_par_blocks Unexecuted instantiation: <aes::autodetect::Aes256 as cipher::block::BlockDecrypt>::decrypt_par_blocks |
126 | | } |
127 | | |
128 | | opaque_debug::implement!($name); |
129 | | }; |
130 | | } |
131 | | |
132 | | define_aes_impl!(Aes128, aes128, U16, "AES-128 block cipher instance"); |
133 | | define_aes_impl!(Aes192, aes192, U24, "AES-192 block cipher instance"); |
134 | | define_aes_impl!(Aes256, aes256, U32, "AES-256 block cipher instance"); |
135 | | |
136 | | #[cfg(all(feature = "ctr", target_arch = "aarch64"))] |
137 | | pub(crate) mod ctr { |
138 | | use super::{Aes128, Aes192, Aes256}; |
139 | | |
140 | | /// AES-128 in CTR mode |
141 | | pub type Aes128Ctr = ::ctr::Ctr64BE<Aes128>; |
142 | | |
143 | | /// AES-192 in CTR mode |
144 | | pub type Aes192Ctr = ::ctr::Ctr64BE<Aes192>; |
145 | | |
146 | | /// AES-256 in CTR mode |
147 | | pub type Aes256Ctr = ::ctr::Ctr64BE<Aes256>; |
148 | | } |
149 | | |
150 | | #[cfg(all(feature = "ctr", any(target_arch = "x86_64", target_arch = "x86")))] |
151 | | pub(crate) mod ctr { |
152 | | use super::{Aes128, Aes192, Aes256}; |
153 | | use crate::{ni, soft}; |
154 | | use cipher::{ |
155 | | errors::{LoopError, OverflowError}, |
156 | | generic_array::GenericArray, |
157 | | BlockCipher, FromBlockCipher, SeekNum, StreamCipher, StreamCipherSeek, |
158 | | }; |
159 | | use core::mem::ManuallyDrop; |
160 | | |
161 | | cpufeatures::new!(aes_ssse3_cpuid, "aes", "ssse3"); |
162 | | |
163 | | macro_rules! define_aes_ctr_impl { |
164 | | ( |
165 | | $name:tt, |
166 | | $cipher:ident, |
167 | | $module:tt, |
168 | | $doc:expr |
169 | | ) => { |
170 | | #[doc=$doc] |
171 | | #[cfg_attr(docsrs, doc(cfg(feature = "ctr")))] |
172 | | pub struct $name { |
173 | | inner: $module::Inner, |
174 | | token: aes_ssse3_cpuid::InitToken, |
175 | | } |
176 | | |
177 | | mod $module { |
178 | | use crate::{ni, soft}; |
179 | | use core::mem::ManuallyDrop; |
180 | | |
181 | | pub(super) union Inner { |
182 | | pub(super) ni: ManuallyDrop<ni::$name>, |
183 | | pub(super) soft: ManuallyDrop<soft::$name>, |
184 | | } |
185 | | } |
186 | | |
187 | | impl FromBlockCipher for $name { |
188 | | type BlockCipher = $cipher; |
189 | | type NonceSize = <$cipher as BlockCipher>::BlockSize; |
190 | | |
191 | | fn from_block_cipher( |
192 | | cipher: $cipher, |
193 | | nonce: &GenericArray<u8, Self::NonceSize>, |
194 | | ) -> Self { |
195 | | let (token, aesni_present) = aes_ssse3_cpuid::init_get(); |
196 | | |
197 | | let inner = if aesni_present { |
198 | | let ni = ni::$name::from_block_cipher( |
199 | | unsafe { (*cipher.inner.intrinsics).clone() }, |
200 | | nonce, |
201 | | ); |
202 | | |
203 | | $module::Inner { |
204 | | ni: ManuallyDrop::new(ni), |
205 | | } |
206 | | } else { |
207 | | let soft = soft::$name::from_block_cipher( |
208 | | unsafe { (*cipher.inner.soft).clone() }, |
209 | | nonce, |
210 | | ); |
211 | | |
212 | | $module::Inner { |
213 | | soft: ManuallyDrop::new(soft), |
214 | | } |
215 | | }; |
216 | | |
217 | | Self { inner, token } |
218 | | } |
219 | | } |
220 | | |
221 | | impl StreamCipher for $name { |
222 | | #[inline] |
223 | | fn try_apply_keystream(&mut self, data: &mut [u8]) -> Result<(), LoopError> { |
224 | | if self.token.get() { |
225 | | unsafe { (*self.inner.ni).try_apply_keystream(data) } |
226 | | } else { |
227 | | unsafe { (*self.inner.soft).try_apply_keystream(data) } |
228 | | } |
229 | | } |
230 | | } |
231 | | |
232 | | impl StreamCipherSeek for $name { |
233 | | #[inline] |
234 | | fn try_current_pos<T: SeekNum>(&self) -> Result<T, OverflowError> { |
235 | | if self.token.get() { |
236 | | unsafe { (*self.inner.ni).try_current_pos() } |
237 | | } else { |
238 | | unsafe { (*self.inner.soft).try_current_pos() } |
239 | | } |
240 | | } |
241 | | |
242 | | #[inline] |
243 | | fn try_seek<T: SeekNum>(&mut self, pos: T) -> Result<(), LoopError> { |
244 | | if self.token.get() { |
245 | | unsafe { (*self.inner.ni).try_seek(pos) } |
246 | | } else { |
247 | | unsafe { (*self.inner.soft).try_seek(pos) } |
248 | | } |
249 | | } |
250 | | } |
251 | | |
252 | | opaque_debug::implement!($name); |
253 | | }; |
254 | | } |
255 | | |
256 | | define_aes_ctr_impl!(Aes128Ctr, Aes128, aes128ctr, "AES-128 in CTR mode"); |
257 | | define_aes_ctr_impl!(Aes192Ctr, Aes192, aes192ctr, "AES-192 in CTR mode"); |
258 | | define_aes_ctr_impl!(Aes256Ctr, Aes256, aes256ctr, "AES-256 in CTR mode"); |
259 | | } |