hardware_rust_crypto/lib.rs
1//! Hardware-only AES-256-GCM and key/nonce generation.
2//!
3//! Every AES round and every GF(2^128) multiply executes as a CPU instruction
4//! (`AES-NI`/`PCLMULQDQ` on `x86_64`, `ARMv8` AES/`PMULL` on `aarch64`); no
5//! software cipher is compiled in. If the required hardware is absent,
6//! construction fails with a typed error rather than degrading to table-based
7//! AES.
8//!
9//! The crate exposes two modules:
10//!
11//! - [`aes_gcm`]: AES-256-GCM. [`aes_gcm::HardwareAes256Gcm`] owns boxed key
12//! state; [`aes_gcm::HardwareAes256GcmKeyState`] owns allocation-free inline
13//! key state; [`aes_gcm::HardwareAes256GcmIn`] places the key state in
14//! caller-provided memory so the caller controls where keys and key-equivalent
15//! state live (use [`aes_gcm::HardwareAes256Gcm::key_state_layout`] to size
16//! and align the storage, [`aes_gcm::UninitKeyStateSlot`] to hand it over).
17//! Default encryption generates a nonce and returns `ciphertext || tag ||
18//! nonce`; default decryption parses the nonce from that envelope. All
19//! handles zeroize key state on drop. The same module also provides
20//! nonce-misuse-resistant AES-256-GCM-SIV (RFC 8452) through the parallel
21//! [`aes_gcm::HardwareAes256GcmSiv`],
22//! [`aes_gcm::HardwareAes256GcmSivKeyState`], and
23//! [`aes_gcm::HardwareAes256GcmSivIn`] types (placed via
24//! [`aes_gcm::SivUninitKeyStateSlot`]), built on the same hardware AES and
25//! carryless-multiply backends with POLYVAL authentication and the same
26//! default envelope API.
27//! - [`random`]: a hardware AES-256-CTR key and nonce generator
28//! ([`random::AesCtrKeyGenerator`]) with fork detection and CPU hardware-RNG
29//! (`RDSEED`/`RNDRRS`) reseeding.
30//!
31//! Implementation details (the AES, GHASH, CTR, and fork-detection internals)
32//! are private; only the high-level types above are part of the public API.
33
34pub mod aes_gcm;
35// The `hax` cfg excludes the RNG module from hax/F* extraction: its `RDSEED`/
36// `RNDRRS` inline asm and `pthread_atfork` fn pointer are outside hax's
37// importable subset, and it is independent of the AEAD composition being
38// extracted. Normal builds and all other tooling compile it as usual.
39#[cfg(not(hax))]
40pub mod random;