1#![cfg_attr(docsrs, feature(doc_cfg))]
63#![cfg_attr(feature = "verification", allow(unused))]
64#![cfg_attr(not(feature = "std"), no_std)]
65
66pub mod seeds;
67
68#[cfg(all(feature = "tls", not(feature = "verification")))]
69#[cfg_attr(docsrs, doc(cfg(feature = "tls")))]
70pub mod tls;
71
72mod traits;
73
74mod backend;
75
76#[cfg(all(
77 feature = "force_runtime_detection",
78 not(any(
79 all(target_arch = "riscv64", feature = "experimental_riscv"),
80 target_arch = "aarch64",
81 target_arch = "x86_64",
82 target_arch = "x86",
83 ))
84))]
85compile_error!("The hardware AES implementation is not available for this platform. Remove the `force_runtime_detection` feature");
86
87#[cfg(all(feature = "force_runtime_detection", not(feature = "std")))]
88compile_error!("The runtime detection is not supported in `no_std`");
89
90#[cfg(all(
91 feature = "std",
92 any(
93 target_arch = "x86_64",
94 target_arch = "x86",
95 target_arch = "aarch64",
96 all(target_arch = "riscv64", feature = "experimental_riscv"),
97 ),
98 any(
99 not(any(
100 all(
101 any(target_arch = "x86_64", target_arch = "x86"),
102 target_feature = "sse2",
103 target_feature = "aes",
104 ),
105 all(
106 target_arch = "aarch64",
107 target_feature = "neon",
108 target_feature = "aes",
109 ),
110 all(target_arch = "riscv64", feature = "experimental_riscv"),
111 )),
112 feature = "force_runtime_detection",
113 ),
114))]
115pub(crate) mod runtime;
116
117#[cfg(all(
118 feature = "std",
119 any(
120 target_arch = "x86_64",
121 target_arch = "x86",
122 target_arch = "aarch64",
123 all(target_arch = "riscv64", feature = "experimental_riscv"),
124 ),
125 any(
126 not(any(
127 all(
128 any(target_arch = "x86_64", target_arch = "x86"),
129 target_feature = "sse2",
130 target_feature = "aes",
131 ),
132 all(
133 target_arch = "aarch64",
134 target_feature = "neon",
135 target_feature = "aes",
136 ),
137 all(target_arch = "riscv64", feature = "experimental_riscv"),
138 )),
139 feature = "force_runtime_detection",
140 ),
141))]
142pub use runtime::{Aes128Ctr128, Aes128Ctr64, Aes256Ctr128, Aes256Ctr64};
143
144#[cfg(all(
145 target_arch = "aarch64",
146 target_feature = "neon",
147 target_feature = "aes",
148 not(feature = "force_runtime_detection"),
149 not(feature = "force_software"),
150 not(feature = "verification"),
151))]
152pub use backend::aarch64::{Aes128Ctr128, Aes128Ctr64, Aes256Ctr128, Aes256Ctr64};
153
154#[cfg(all(
155 target_arch = "riscv64",
156 feature = "experimental_riscv",
157 not(feature = "force_runtime_detection"),
158 not(feature = "force_software"),
159 not(feature = "verification"),
160))]
161pub use backend::riscv64::{Aes128Ctr128, Aes128Ctr64, Aes256Ctr128, Aes256Ctr64};
162
163#[cfg(all(
164 any(target_arch = "x86_64", target_arch = "x86"),
165 target_feature = "sse2",
166 target_feature = "aes",
167 not(feature = "force_runtime_detection"),
168 not(feature = "force_software"),
169 not(feature = "verification"),
170))]
171pub use backend::x86::{Aes128Ctr128, Aes128Ctr64, Aes256Ctr128, Aes256Ctr64};
172
173#[cfg(all(
174 any(
175 not(any(
176 target_arch = "aarch64",
177 all(target_arch = "riscv64", feature = "experimental_riscv"),
178 any(target_arch = "x86_64", target_arch = "x86"),
179 )),
180 feature = "force_software",
181 all(
182 any(target_arch = "x86_64", target_arch = "x86"),
183 not(all(target_feature = "sse2", target_feature = "aes")),
184 not(feature = "std"),
185 ),
186 all(
187 target_arch = "aarch64",
188 not(all(target_feature = "neon", target_feature = "aes")),
189 not(feature = "std"),
190 ),
191 all(
192 target_arch = "riscv64",
193 feature = "experimental_riscv",
194 not(feature = "std"),
195 ),
196 ),
197 not(feature = "force_runtime_detection"),
198 not(feature = "verification"),
199))]
200pub use backend::soft::{Aes128Ctr128, Aes128Ctr64, Aes256Ctr128, Aes256Ctr64};
201
202#[cfg(not(feature = "verification"))]
203mod implementation;
204
205#[cfg(feature = "verification")]
206#[doc(hidden)]
207pub mod verification;
208
209pub use traits::{Jump, Random};
210
211#[allow(unused)]
212pub(crate) mod constants {
213 pub(crate) const AES_RCON: [u32; 10] =
214 [0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36];
215 pub(crate) const AES_BLOCK_WORDS: usize = 4;
216 pub(crate) const AES_WORD_SIZE: usize = 4;
217 pub(crate) const AES_BLOCK_SIZE: usize = AES_WORD_SIZE * AES_BLOCK_WORDS;
218 pub(crate) const AES128_KEY_SIZE: usize = 16;
219 pub(crate) const AES256_KEY_SIZE: usize = 32;
220 pub(crate) const AES128_KEY_COUNT: usize = 11;
221 pub(crate) const AES256_KEY_COUNT: usize = 15;
222}
223
224#[cfg(feature = "getrandom")]
225pub(crate) fn secure_bytes<const N: usize>() -> [u8; N] {
226 let mut bytes = [0u8; N];
227 getrandom::fill(&mut bytes).expect("Can't get random bytes from OS");
228 bytes
229}
230
231#[cfg(all(test, not(feature = "verification")))]
232#[allow(unused)]
233mod tests {
234 use super::*;
235 use crate::constants::{
236 AES128_KEY_COUNT, AES128_KEY_SIZE, AES256_KEY_COUNT, AES256_KEY_SIZE, AES_BLOCK_SIZE,
237 };
238 use hex_literal::hex;
239
240 const TV_AES128_KEY: [u8; AES128_KEY_SIZE] = hex!("000102030405060708090a0b0c0d0e0f");
242 const TV_AES128_IV: [u8; AES_BLOCK_SIZE] = hex!("00112233445566778899aabbccddeeff");
243 const TV_AES128_ROUND_KEYS: [[u8; AES_BLOCK_SIZE]; AES128_KEY_COUNT] = [
244 hex!("000102030405060708090a0b0c0d0e0f"),
245 hex!("d6aa74fdd2af72fadaa678f1d6ab76fe"),
246 hex!("b692cf0b643dbdf1be9bc5006830b3fe"),
247 hex!("b6ff744ed2c2c9bf6c590cbf0469bf41"),
248 hex!("47f7f7bc95353e03f96c32bcfd058dfd"),
249 hex!("3caaa3e8a99f9deb50f3af57adf622aa"),
250 hex!("5e390f7df7a69296a7553dc10aa31f6b"),
251 hex!("14f9701ae35fe28c440adf4d4ea9c026"),
252 hex!("47438735a41c65b9e016baf4aebf7ad2"),
253 hex!("549932d1f08557681093ed9cbe2c974e"),
254 hex!("13111d7fe3944a17f307a78b4d2b30c5"),
255 ];
256 const TV_AES128_NEXT_0: [u8; AES_BLOCK_SIZE] = hex!("69c4e0d86a7b0430d8cdb78070b4c55a");
257 const TV_AES128_NEXT_1: [u8; AES_BLOCK_SIZE] = hex!("a556156c72876577f67f95a9d9e640a7");
258
259 const TV_AES256_KEY: [u8; AES256_KEY_SIZE] =
261 hex!("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f");
262 const TV_AES256_IV: [u8; AES_BLOCK_SIZE] = hex!("00112233445566778899aabbccddeeff");
263 const TV_AES256_ROUND_KEYS: [[u8; AES_BLOCK_SIZE]; AES256_KEY_COUNT] = [
264 hex!("000102030405060708090a0b0c0d0e0f"),
265 hex!("101112131415161718191a1b1c1d1e1f"),
266 hex!("a573c29fa176c498a97fce93a572c09c"),
267 hex!("1651a8cd0244beda1a5da4c10640bade"),
268 hex!("ae87dff00ff11b68a68ed5fb03fc1567"),
269 hex!("6de1f1486fa54f9275f8eb5373b8518d"),
270 hex!("c656827fc9a799176f294cec6cd5598b"),
271 hex!("3de23a75524775e727bf9eb45407cf39"),
272 hex!("0bdc905fc27b0948ad5245a4c1871c2f"),
273 hex!("45f5a66017b2d387300d4d33640a820a"),
274 hex!("7ccff71cbeb4fe5413e6bbf0d261a7df"),
275 hex!("f01afafee7a82979d7a5644ab3afe640"),
276 hex!("2541fe719bf500258813bbd55a721c0a"),
277 hex!("4e5a6699a9f24fe07e572baacdf8cdea"),
278 hex!("24fc79ccbf0979e9371ac23c6d68de36"),
279 ];
280 const TV_AES256_NEXT_0: [u8; AES_BLOCK_SIZE] = hex!("8ea2b7ca516745bfeafc49904b496089");
281 const TV_AES256_NEXT_1: [u8; AES_BLOCK_SIZE] = hex!("81ae7d5e4138bf730d2a8871fec2cd0c");
282
283 pub(crate) fn aes128_key_expansion_test<F>(expansion: F)
284 where
285 F: FnOnce([u8; AES128_KEY_SIZE]) -> [[u8; AES_BLOCK_SIZE]; AES128_KEY_COUNT],
286 {
287 let expanded = expansion(TV_AES128_KEY);
288
289 for (exp, act) in TV_AES128_ROUND_KEYS.iter().zip(expanded.iter()) {
290 assert_eq!(exp, act);
291 }
292 }
293
294 pub(crate) fn aes256_key_expansion_test<F>(expansion: F)
295 where
296 F: FnOnce([u8; AES256_KEY_SIZE]) -> [[u8; AES_BLOCK_SIZE]; AES256_KEY_COUNT],
297 {
298 let expanded = expansion(TV_AES256_KEY);
299
300 for (exp, act) in TV_AES256_ROUND_KEYS.iter().zip(expanded.iter()) {
301 assert_eq!(exp, act);
302 }
303 }
304
305 #[test]
306 fn test_aes128_64_ctr() {
307 let mut ctr = [0u8; 8];
308 let mut nonce = [0u8; 8];
309 ctr.copy_from_slice(&TV_AES128_IV[0..8]);
310 nonce.copy_from_slice(&TV_AES128_IV[8..16]);
311
312 let prng = unsafe { Aes128Ctr64::from_seed_impl(TV_AES128_KEY, nonce, ctr) };
313
314 assert_eq!(unsafe { prng.next_impl().to_le_bytes() }, TV_AES128_NEXT_0);
315 assert_eq!(unsafe { prng.next_impl().to_le_bytes() }, TV_AES128_NEXT_1);
316 }
317
318 #[test]
319 fn test_aes128_128_ctr() {
320 let prng = unsafe { Aes128Ctr128::from_seed_impl(TV_AES128_KEY, TV_AES128_IV) };
321
322 assert_eq!(unsafe { prng.next_impl().to_le_bytes() }, TV_AES128_NEXT_0);
323 assert_eq!(unsafe { prng.next_impl().to_le_bytes() }, TV_AES128_NEXT_1);
324 }
325
326 #[test]
327 fn test_aes256_64_ctr() {
328 let mut ctr = [0u8; 8];
329 let mut nonce = [0u8; 8];
330 ctr.copy_from_slice(&TV_AES256_IV[0..8]);
331 nonce.copy_from_slice(&TV_AES256_IV[8..16]);
332
333 let prng = unsafe { Aes256Ctr64::from_seed_impl(TV_AES256_KEY, nonce, ctr) };
334
335 assert_eq!(unsafe { prng.next_impl().to_le_bytes() }, TV_AES256_NEXT_0);
336 assert_eq!(unsafe { prng.next_impl().to_le_bytes() }, TV_AES256_NEXT_1);
337 }
338
339 #[test]
340 fn test_aes256_128_ctr() {
341 let prng = unsafe { Aes256Ctr128::from_seed_impl(TV_AES256_KEY, TV_AES256_IV) };
342
343 assert_eq!(unsafe { prng.next_impl().to_le_bytes() }, TV_AES256_NEXT_0);
344 assert_eq!(unsafe { prng.next_impl().to_le_bytes() }, TV_AES256_NEXT_1);
345 }
346}