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 ),
182 not(feature = "force_runtime_detection"),
183 not(feature = "verification"),
184))]
185pub use backend::soft::{Aes128Ctr128, Aes128Ctr64, Aes256Ctr128, Aes256Ctr64};
186
187#[cfg(not(feature = "verification"))]
188mod implementation;
189
190#[cfg(feature = "verification")]
191#[doc(hidden)]
192pub mod verification;
193
194pub use traits::{Jump, Random};
195
196#[allow(unused)]
197pub(crate) mod constants {
198 pub(crate) const AES_RCON: [u32; 10] =
199 [0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36];
200 pub(crate) const AES_BLOCK_WORDS: usize = 4;
201 pub(crate) const AES_WORD_SIZE: usize = 4;
202 pub(crate) const AES_BLOCK_SIZE: usize = AES_WORD_SIZE * AES_BLOCK_WORDS;
203 pub(crate) const AES128_KEY_SIZE: usize = 16;
204 pub(crate) const AES256_KEY_SIZE: usize = 32;
205 pub(crate) const AES128_KEY_COUNT: usize = 11;
206 pub(crate) const AES256_KEY_COUNT: usize = 15;
207}
208
209#[cfg(feature = "getrandom")]
210pub(crate) fn secure_bytes<const N: usize>() -> [u8; N] {
211 let mut bytes = [0u8; N];
212 getrandom::fill(&mut bytes).expect("Can't get random bytes from OS");
213 bytes
214}
215
216#[cfg(all(test, not(feature = "verification")))]
217#[allow(unused)]
218mod tests {
219 use super::*;
220 use crate::constants::{
221 AES128_KEY_COUNT, AES128_KEY_SIZE, AES256_KEY_COUNT, AES256_KEY_SIZE, AES_BLOCK_SIZE,
222 };
223 use hex_literal::hex;
224
225 const TV_AES128_KEY: [u8; AES128_KEY_SIZE] = hex!("000102030405060708090a0b0c0d0e0f");
227 const TV_AES128_IV: [u8; AES_BLOCK_SIZE] = hex!("00112233445566778899aabbccddeeff");
228 const TV_AES128_ROUND_KEYS: [[u8; AES_BLOCK_SIZE]; AES128_KEY_COUNT] = [
229 hex!("000102030405060708090a0b0c0d0e0f"),
230 hex!("d6aa74fdd2af72fadaa678f1d6ab76fe"),
231 hex!("b692cf0b643dbdf1be9bc5006830b3fe"),
232 hex!("b6ff744ed2c2c9bf6c590cbf0469bf41"),
233 hex!("47f7f7bc95353e03f96c32bcfd058dfd"),
234 hex!("3caaa3e8a99f9deb50f3af57adf622aa"),
235 hex!("5e390f7df7a69296a7553dc10aa31f6b"),
236 hex!("14f9701ae35fe28c440adf4d4ea9c026"),
237 hex!("47438735a41c65b9e016baf4aebf7ad2"),
238 hex!("549932d1f08557681093ed9cbe2c974e"),
239 hex!("13111d7fe3944a17f307a78b4d2b30c5"),
240 ];
241 const TV_AES128_NEXT_0: [u8; AES_BLOCK_SIZE] = hex!("69c4e0d86a7b0430d8cdb78070b4c55a");
242 const TV_AES128_NEXT_1: [u8; AES_BLOCK_SIZE] = hex!("a556156c72876577f67f95a9d9e640a7");
243
244 const TV_AES256_KEY: [u8; AES256_KEY_SIZE] =
246 hex!("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f");
247 const TV_AES256_IV: [u8; AES_BLOCK_SIZE] = hex!("00112233445566778899aabbccddeeff");
248 const TV_AES256_ROUND_KEYS: [[u8; AES_BLOCK_SIZE]; AES256_KEY_COUNT] = [
249 hex!("000102030405060708090a0b0c0d0e0f"),
250 hex!("101112131415161718191a1b1c1d1e1f"),
251 hex!("a573c29fa176c498a97fce93a572c09c"),
252 hex!("1651a8cd0244beda1a5da4c10640bade"),
253 hex!("ae87dff00ff11b68a68ed5fb03fc1567"),
254 hex!("6de1f1486fa54f9275f8eb5373b8518d"),
255 hex!("c656827fc9a799176f294cec6cd5598b"),
256 hex!("3de23a75524775e727bf9eb45407cf39"),
257 hex!("0bdc905fc27b0948ad5245a4c1871c2f"),
258 hex!("45f5a66017b2d387300d4d33640a820a"),
259 hex!("7ccff71cbeb4fe5413e6bbf0d261a7df"),
260 hex!("f01afafee7a82979d7a5644ab3afe640"),
261 hex!("2541fe719bf500258813bbd55a721c0a"),
262 hex!("4e5a6699a9f24fe07e572baacdf8cdea"),
263 hex!("24fc79ccbf0979e9371ac23c6d68de36"),
264 ];
265 const TV_AES256_NEXT_0: [u8; AES_BLOCK_SIZE] = hex!("8ea2b7ca516745bfeafc49904b496089");
266 const TV_AES256_NEXT_1: [u8; AES_BLOCK_SIZE] = hex!("81ae7d5e4138bf730d2a8871fec2cd0c");
267
268 pub(crate) fn aes128_key_expansion_test<F>(expansion: F)
269 where
270 F: FnOnce([u8; AES128_KEY_SIZE]) -> [[u8; AES_BLOCK_SIZE]; AES128_KEY_COUNT],
271 {
272 let expanded = expansion(TV_AES128_KEY);
273
274 for (exp, act) in TV_AES128_ROUND_KEYS.iter().zip(expanded.iter()) {
275 assert_eq!(exp, act);
276 }
277 }
278
279 pub(crate) fn aes256_key_expansion_test<F>(expansion: F)
280 where
281 F: FnOnce([u8; AES256_KEY_SIZE]) -> [[u8; AES_BLOCK_SIZE]; AES256_KEY_COUNT],
282 {
283 let expanded = expansion(TV_AES256_KEY);
284
285 for (exp, act) in TV_AES256_ROUND_KEYS.iter().zip(expanded.iter()) {
286 assert_eq!(exp, act);
287 }
288 }
289
290 #[test]
291 fn test_aes128_64_ctr() {
292 let mut ctr = [0u8; 8];
293 let mut nonce = [0u8; 8];
294 ctr.copy_from_slice(&TV_AES128_IV[0..8]);
295 nonce.copy_from_slice(&TV_AES128_IV[8..16]);
296
297 let prng = unsafe { Aes128Ctr64::from_seed_impl(TV_AES128_KEY, nonce, ctr) };
298
299 assert_eq!(unsafe { prng.next_impl().to_le_bytes() }, TV_AES128_NEXT_0);
300 assert_eq!(unsafe { prng.next_impl().to_le_bytes() }, TV_AES128_NEXT_1);
301 }
302
303 #[test]
304 fn test_aes128_128_ctr() {
305 let prng = unsafe { Aes128Ctr128::from_seed_impl(TV_AES128_KEY, TV_AES128_IV) };
306
307 assert_eq!(unsafe { prng.next_impl().to_le_bytes() }, TV_AES128_NEXT_0);
308 assert_eq!(unsafe { prng.next_impl().to_le_bytes() }, TV_AES128_NEXT_1);
309 }
310
311 #[test]
312 fn test_aes256_64_ctr() {
313 let mut ctr = [0u8; 8];
314 let mut nonce = [0u8; 8];
315 ctr.copy_from_slice(&TV_AES256_IV[0..8]);
316 nonce.copy_from_slice(&TV_AES256_IV[8..16]);
317
318 let prng = unsafe { Aes256Ctr64::from_seed_impl(TV_AES256_KEY, nonce, ctr) };
319
320 assert_eq!(unsafe { prng.next_impl().to_le_bytes() }, TV_AES256_NEXT_0);
321 assert_eq!(unsafe { prng.next_impl().to_le_bytes() }, TV_AES256_NEXT_1);
322 }
323
324 #[test]
325 fn test_aes256_128_ctr() {
326 let prng = unsafe { Aes256Ctr128::from_seed_impl(TV_AES256_KEY, TV_AES256_IV) };
327
328 assert_eq!(unsafe { prng.next_impl().to_le_bytes() }, TV_AES256_NEXT_0);
329 assert_eq!(unsafe { prng.next_impl().to_le_bytes() }, TV_AES256_NEXT_1);
330 }
331}