embassy-rs/embassy · error
Output buffer length must match input length.
Error message
Output buffer length must match input length.
What it means
The CRYP payload call requires the output buffer to be at least as long as the input; hardware writes one block per input block, so a shorter output would be overrun. It panics when input.len() > output.len().
Solutions
- Size the output buffer to be at least input.len() (same length for streaming modes).
- For padded block modes, allocate output covering the padded length as the driver requires.
- If the destination is smaller, process the input in chunks that fit it.
Example fix
// before let mut out = [0u8; 8]; ctx.payload(&ciphertext16, &mut out, true); // panics // after let mut out = [0u8; 16]; ctx.payload(&ciphertext16, &mut out, true);
Defensive patterns
Strategy: validation
Validate before calling
assert!(output.len() >= input.len(), "output buffer too small for CRYP payload");
Prevention
- Derive output buffer size from input length, never hardcode
- Double-check padded-mode buffer requirements
- Unit-test buffer sizing at edge lengths (0, block size +/- 1)
When it happens
Trigger: Calling payload()/encrypt/decrypt with an output slice shorter than the input — e.g. decrypting 16 bytes of ciphertext into an 8-byte buffer, or a mis-sized scratch buffer.
Common situations: Hardcoded buffer sizes not matching input length; in-place buffers reused with wrong slice bounds; porting from APIs that return an owned buffer to this caller-buffer API.
Related errors
- Message is too large for given IV size.
- Cannot update AAD after starting payload!
- Additional associated data must be processed first!
- The last block has already been processed!
- Input length must be a multiple of
AI-assisted analysis of embassy-rs/embassy@463a07b963 (2026-09-10).
Data as JSON: /api/errors/16f677dafba0cffc.
Report an issue: GitHub.
Appendix: source
Thrown at embassy-stm32/src/cryp/mod.rs:1419
// Perform checks for correctness.
if !ctx.aad_complete && ctx.header_len > 0 {
panic!("Additional associated data must be processed first!");
} else if !ctx.aad_complete {
#[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
{
ctx.aad_complete = true;
T::regs().cr().modify(|w| w.set_crypen(false));
T::regs().cr().modify(|w| w.set_gcm_ccmph(2));
T::regs().cr().modify(|w| w.set_fflush(true));
T::regs().cr().modify(|w| w.set_crypen(true));
}
}
if ctx.last_block_processed {
panic!("The last block has already been processed!");
}
if input.len() > output.len() {
panic!("Output buffer length must match input length.");
}
if !last_block {
if last_block_remainder != 0 {
panic!("Input length must be a multiple of {} bytes.", C::BLOCK_SIZE);
}
}
if C::REQUIRES_PADDING {
if last_block_remainder != 0 {
panic!(
"Input must be a multiple of {} bytes in ECB and CBC modes. Consider padding or ciphertext stealing.",
C::BLOCK_SIZE
);
}
}
if last_block {
ctx.last_block_processed = true;
}
View on GitHub (pinned to 463a07b963)