embassy-rs/embassy · error
Invalid key size
Error message
Invalid key size
What it means
The CRYP driver maps a Rust key buffer length onto the hardware KeySize register setting. Only 16 bytes (AES-128) and 32 bytes (AES-256) are supported here; any other key length panics with 'Invalid key size'. Notably, 24-byte AES-192 keys are not handled by this match.
Solutions
- Provide a 16-byte key for AES-128 (pad/derive with SHA-256 if necessary) or a 32-byte key for AES-256.
- If you have an AES-192 key, derive a 256-bit key (e.g. SHA-256 of the 192-bit key) or use a software AES implementation supporting 192-bit keys.
- Assert or log the key length before constructing the cipher to catch encoding mistakes early.
Example fix
// before let key = [0u8; 24]; // AES-192: not supported cipher.set_key(&key); // panics // after let key = [0u8; 32]; // AES-256 cipher.set_key(&key);
Defensive patterns
Strategy: validation
Validate before calling
assert!(matches!(key.len(), 16 | 32), "CRYP key must be 16 (AES-128) or 32 (AES-256) bytes, got {}", key.len()); Type guard
fn is_valid_key(key: &[u8]) -> bool {
key.len() == 16 || key.len() == 32
} Prevention
- Store keys as fixed-size arrays ([u8; 16] or [u8; 32]) instead of slices so length is enforced at compile time.
- Never use AES-192 (24-byte) keys with this driver.
- Verify key decoding (hex/base64) produces the expected byte count before constructing the cipher.
- Keep keys and IVs in separate buffers; never concatenate them.
When it happens
Trigger: Constructing a cipher (e.g. Cipher::new with an AES key) whose key() slice is not exactly 16 or 32 bytes when key_size() is called — e.g. a 24-byte AES-192 key, an empty key, or a key with an extra header/IV byte concatenated.
Common situations: Using a 24-byte AES-192 key that the driver does not support; accidentally passing a hex-decoded half-length key; concatenating key and IV into one buffer; copying example code with a variable-length key from a KMS/file.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Input must be a multiple of
- Additional associated data must be processed first!
- Cannot update AAD after starting payload!
- Input length must be a multiple of
- Message is too large for given IV size.
AI-assisted analysis of embassy-rs/embassy@463a07b963 (2026-09-10).
Data as JSON: /api/errors/17f8b9aeb40645a8.
Report an issue: GitHub.
Appendix: source
Thrown at embassy-stm32/src/crypto.rs:75
pub trait Cipher<'c> {
/// Processing block size (always 16 bytes for AES).
const BLOCK_SIZE: usize = AES_BLOCK_SIZE;
/// Indicates whether the cipher requires the application to provide padding.
const REQUIRES_PADDING: bool = false;
/// Returns the symmetric key.
fn key(&self) -> &[u8];
/// Returns the initialization vector.
fn iv(&self) -> &[u8];
/// Returns the key size.
fn key_size(&self) -> KeySize {
match self.key().len() {
16 => KeySize::Bits128,
32 => KeySize::Bits256,
_ => panic!("Invalid key size"),
}
}
/// Returns the data type setting for this cipher mode.
///
/// The drivers use NO_SWAP (0) consistently with big-endian byte
/// conversion (`from_be_bytes`/`to_be_bytes`) for direct NIST test-vector
/// compatibility.
fn datatype(&self) -> u8 {
0
}
/// Returns the raw `CHMOD` field value for this cipher mode.
fn chmod_bits(&self) -> u8 {
0 // ECB default
}
/// Indicates whether this cipher mode uses GCM/CCM phases (init, header, payload, final).View on GitHub (pinned to 463a07b963)