embassy-rs/embassy · error
Digest buffer must be at least
Error message
Digest buffer must be at least {} bytes long. What it means
The blocking HASH peripheral driver panics in finish_blocking when the caller-supplied digest output slice is shorter than the algorithm's digest length (DIGEST_WORDS * 4 bytes, e.g. 32 bytes for SHA-256). The library cannot partially write a digest, so it fails fast instead of silently truncating.
Solutions
- Size the digest buffer to at least A::DIGEST_WORDS * 4 bytes for the algorithm in use (e.g. [u8; 32] for SHA-256, [u8; 64] for SHA-512)
- Before the call, check digest.len() >= expected digest length and return a Result error instead of panicking
- Derive the buffer size from the algorithm's associated constants rather than hardcoding
Example fix
// before let mut digest = [0u8; 20]; hasher.finish_blocking(&mut digest); // panics for SHA-256 // after let mut digest = [0u8; <MyHash as DigestAlgorithm>::DIGEST_WORDS * 4]; hasher.finish_blocking(&mut digest);
Defensive patterns
Strategy: validation
Validate before calling
// Validate the digest buffer before calling finish_blocking
let required = <A as DigestAlgorithm>::DIGEST_WORDS * 4;
if digest.len() < required {
return Err(DigestBufferTooSmall { required, actual: digest.len() });
} Prevention
- Derive buffer size from A::DIGEST_WORDS * 4, never from a hardcoded number
- Use a fixed-size array type ([u8; 32]) so the compiler enforces the size
- Add a debug assertion or unit test per algorithm verifying buffer sizing
When it happens
Trigger: Calling Hash::finish_blocking (or new_blocking/start/finish flows ending in finish_blocking) with a digest buffer smaller than digest_len_bytes for the selected algorithm — e.g. a [u8; 16] buffer for SHA-256 which needs 32 bytes.
Common situations: Buffer sized for MD5/SHA-1 (16/20 bytes) reused with a SHA-256 algorithm type; generic code that sizes the output buffer from a wrong constant; switching the hash algorithm type parameter without resizing the output array.
Related errors
AI-assisted analysis of embassy-rs/embassy@463a07b963 (2026-09-10).
Data as JSON: /api/errors/694c442c8ededa39.
Report an issue: GitHub.
Appendix: source
Thrown at embassy-stm32/src/hash/mod.rs:611
// For HMAC, after message digest the peripheral waits for the outer key.
if let Some(key) = H::key_ref(&ctx.key) {
while !T::regs().sr().read().dinis() {}
self.accumulate_blocking::<A>(key);
T::regs().str().write(|w| w.set_dcal(true));
}
// Block until digest computation is complete.
while !T::regs().sr().read().dcis() {}
// The hardware no longer holds a resumable context. Clones of `ctx`
// share its id, so they must not skip the restore in `load_context`.
self.current_id = None;
// Return the digest.
let digest_words = A::DIGEST_WORDS;
let digest_len_bytes = digest_words * 4;
// Panics if the supplied digest buffer is too short.
if digest.len() < digest_len_bytes {
panic!("Digest buffer must be at least {} bytes long.", digest_len_bytes);
}
let mut hr = [0u32; 16];
for i in 0..digest_words {
hr[i] = T::regs().hr(i).read();
}
for i in 0..digest_words {
let word = hr[i];
digest[(i * 4)..((i * 4) + 4)].copy_from_slice(word.to_be_bytes().as_slice());
}
digest_len_bytes
}
/// HMAC of an empty message.
///
/// The core ignores the message-phase DCAL when no data was written after
/// the key phase, so it cannot compute this on its own (the ST HAL rejectsView on GitHub (pinned to 463a07b963)