1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
//! Pure Rust implementation of the Advanced Encryption Standard //! (a.k.a. Rijndael) //! //! # Supported platforms //! This crate provides two different backends based on what target features //! are available: //! //! - "soft" portable constant-time implementation based on [fixslicing]. //! Enabling the `compact` Cargo feature will reduce the code size of this //! backend at the cost of decreased performance (using a modified form of //! the fixslicing technique called "semi-fixslicing"). //! - [AES-NI] accelerated implementation for `i686`/`x86_64` target //! architectures with `target-feature=+aes`, as well as an accelerated //! AES-CTR implementation with `target-feature=+aes,+ssse3` //! //! ## ARMv8 intrinsics (nightly-only) //! On `aarch64` targets including `aarch64-apple-darwin` (Apple M1) and Linux //! targets such as `aarch64-unknown-linux-gnu` and `aarch64-unknown-linux-musl`, //! support for using AES intrinsics provided by the ARMv8 Cryptography Extensions //! is available when using the nightly compiler, and can be enabled using the //! `armv8` crate feature. //! //! On Linux and macOS, when the `armv8` feature is enabled support for AES //! intrinsics is autodetected at runtime. On other platforms the `crypto` //! target feature must be enabled via RUSTFLAGS. //! //! ## `x86`/`x86_64` intrinsics (AES-NI) //! By default this crate uses runtime detection on `i686`/`x86_64` targets //! in order to determine if AES-NI is available, and if it is not, it will //! fallback to using a constant-time software implementation. //! //! Passing `RUSTFLAGS=-Ctarget-feature=+aes,+ssse3` explicitly at compile-time //! will override runtime detection and ensure that AES-NI is always used. //! Programs built in this manner will crash with an illegal instruction on //! CPUs which do not have AES-NI enabled. //! //! # Usage example //! ``` //! use aes::Aes128; //! use aes::cipher::{ //! BlockCipher, BlockEncrypt, BlockDecrypt, NewBlockCipher, //! generic_array::GenericArray, //! }; //! //! let key = GenericArray::from_slice(&[0u8; 16]); //! let mut block = GenericArray::clone_from_slice(&[0u8; 16]); //! let mut block8 = GenericArray::clone_from_slice(&[block; 8]); //! //! // Initialize cipher //! let cipher = Aes128::new(&key); //! //! let block_copy = block.clone(); //! //! // Encrypt block in-place //! cipher.encrypt_block(&mut block); //! //! // And decrypt it back //! cipher.decrypt_block(&mut block); //! assert_eq!(block, block_copy); //! //! // We can encrypt 8 blocks simultaneously using //! // instruction-level parallelism //! let block8_copy = block8.clone(); //! cipher.encrypt_par_blocks(&mut block8); //! cipher.decrypt_par_blocks(&mut block8); //! assert_eq!(block8, block8_copy); //! ``` //! //! For implementations of block cipher modes of operation see //! [`block-modes`] crate. //! //! [fixslicing]: https://eprint.iacr.org/2020/1123.pdf //! [AES-NI]: https://en.wikipedia.org/wiki/AES_instruction_set //! [`block-modes`]: https://docs.rs/block-modes #![no_std] #![cfg_attr(docsrs, feature(doc_cfg))] #![cfg_attr(feature = "armv8", feature(stdsimd, aarch64_target_feature))] #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg" )] #![warn(missing_docs, rust_2018_idioms)] use cfg_if::cfg_if; cfg_if! { if #[cfg(all(target_arch = "aarch64", feature = "armv8", not(feature = "force-soft")))] { mod armv8; mod autodetect; mod soft; pub use autodetect::{Aes128, Aes192, Aes256}; #[cfg(feature = "ctr")] pub use autodetect::ctr::{Aes128Ctr, Aes192Ctr, Aes256Ctr}; } else if #[cfg(all( any(target_arch = "x86_64", target_arch = "x86"), not(feature = "force-soft") ))] { mod autodetect; mod ni; mod soft; pub use autodetect::{Aes128, Aes192, Aes256}; #[cfg(feature = "ctr")] pub use autodetect::ctr::{Aes128Ctr, Aes192Ctr, Aes256Ctr}; } else { mod soft; pub use soft::{Aes128, Aes192, Aes256}; #[cfg(feature = "ctr")] pub use soft::{Aes128Ctr, Aes192Ctr, Aes256Ctr}; } } pub use cipher::{self, BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher}; /// 128-bit AES block pub type Block = cipher::generic_array::GenericArray<u8, cipher::consts::U16>; /// 8 x 128-bit AES blocks to be processed in parallel pub type ParBlocks = cipher::generic_array::GenericArray<Block, cipher::consts::U8>;