Expand description
AES-128, AES-192 and AES-256 single-block encryption and decryption.
Import BlockCipherInit to install a key
and BlockCipher to process a block.
Keys must contain 16, 24 or 32 bytes; the block size is always 16 bytes.
§Choosing an engine
AesEngine chooses a backend for you. Enable the rustcrypto Cargo
feature for a constant-time backend even without AES-NI. Without that feature
it uses AES-NI when available, otherwise the variable-time AesTableEngine.
For explicit selection, AesX86Engine is available on x86/x86-64 and
AesRustCryptoEngine with the rustcrypto feature. AesTableEngine
and AesLightEngine are portable but use secret-dependent lookups;
neither is suitable when cache-timing attacks are in scope.
§Encrypting and decrypting one block
This example uses the AES-128 known-answer vector from FIPS 197.
use tc_aes::{AesEngine, ALGO_NAME, BLOCK_BYTES};
use tc_block_cipher::{BlockCipher, BlockCipherInit, CipherDirection, KeyRef};
let key: [u8; 16] = core::array::from_fn(|i| i as u8);
let plaintext: [u8; 16] = core::array::from_fn(|i| (i as u8) * 0x11);
let mut engine = AesEngine::new();
engine.init(CipherDirection::Encrypt, &KeyRef::new(&key))?;
let mut ciphertext = [0; BLOCK_BYTES];
assert_eq!(engine.process_block(&plaintext, &mut ciphertext)?, BLOCK_BYTES);
assert_eq!(ciphertext, [
0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30,
0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a,
]);
engine.init(CipherDirection::Decrypt, &KeyRef::new(&key))?;
let mut recovered = [0; BLOCK_BYTES];
engine.process_block(&ciphertext, &mut recovered)?;
assert_eq!(recovered, plaintext);
assert_eq!(engine.to_string(), ALGO_NAME);§Buffer and key handling
Processing before initialization returns BlockError::NotInitialised.
Buffers shorter than 16 bytes return BlockError::BufferTooShort; longer
buffers process only their first block, leaving the output tail intact.
An invalid key length returns InitError::InvalidKeyLength and preserves
the previous key and direction. Engines retain an expanded key rather than
borrowing the input key; callers remain responsible for their key buffers.
Stored key schedules are wiped on drop, not caller buffers or every temporary.
This is a block-cipher primitive, not a message-encryption format. It supplies no padding, nonce management, mode of operation or authentication. Do not encrypt a message by independently encrypting each block; use an appropriate authenticated-encryption construction.
Structs§
- AesEngine
- AES on the safest engine available:
AesRustCryptoEnginewhen therustcryptofeature is on, otherwiseAesX86Enginewhere the processor has AES-NI, andAesTableEngineas the last resort. The table engine is variable time, so without the feature a processor lacking AES-NI leaks through cache timing; enablerustcryptoto rule that out. - AesLight
Engine - AES in the small-footprint representation: four
u32words of state, only the 256-byte S-box and its inverse, and MixColumns computed rather than looked up. - AesRust
Crypto Engine - AES backed by the RustCrypto
aescrate, which picks AES-NI, VAES or ARMv8 at runtime and otherwise a bitsliced software implementation with no table lookups. Constant time on every backend; its round keys are wiped on drop. - AesTable
Engine - AES with a 1 KiB forward and a 1 KiB inverse T-table: the fastest of the portable engines.
- AesX86
Engine - AES on the AES-NI instructions, where the processor has them.
Constants§
- ALGO_
NAME - Algorithm name returned by every engine’s
Displayimplementation. - BLOCK_
BYTES - AES block length in bytes (128 bits).
- KEY_
BYTES - Accepted key lengths in bytes (128, 192, and 256 bits).