{"record":{"id":"694c442c8ededa39","repo":"embassy-rs/embassy","slug":"digest-buffer-must-be-at-least-bytes-long","errorCode":null,"errorMessage":"Digest buffer must be at least {} bytes long.","messagePattern":"Digest buffer must be at least (.+?) bytes long\\.","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"embassy-stm32/src/hash/mod.rs","lineNumber":611,"sourceCode":"        // For HMAC, after message digest the peripheral waits for the outer key.\n        if let Some(key) = H::key_ref(&ctx.key) {\n            while !T::regs().sr().read().dinis() {}\n            self.accumulate_blocking::<A>(key);\n            T::regs().str().write(|w| w.set_dcal(true));\n        }\n        // Block until digest computation is complete.\n        while !T::regs().sr().read().dcis() {}\n\n        // The hardware no longer holds a resumable context. Clones of `ctx`\n        // share its id, so they must not skip the restore in `load_context`.\n        self.current_id = None;\n\n        // Return the digest.\n        let digest_words = A::DIGEST_WORDS;\n        let digest_len_bytes = digest_words * 4;\n        // Panics if the supplied digest buffer is too short.\n        if digest.len() < digest_len_bytes {\n            panic!(\"Digest buffer must be at least {} bytes long.\", digest_len_bytes);\n        }\n\n        let mut hr = [0u32; 16];\n        for i in 0..digest_words {\n            hr[i] = T::regs().hr(i).read();\n        }\n        for i in 0..digest_words {\n            let word = hr[i];\n            digest[(i * 4)..((i * 4) + 4)].copy_from_slice(word.to_be_bytes().as_slice());\n        }\n\n        digest_len_bytes\n    }\n\n    /// HMAC of an empty message.\n    ///\n    /// The core ignores the message-phase DCAL when no data was written after\n    /// the key phase, so it cannot compute this on its own (the ST HAL rejects","sourceCodeStart":593,"sourceCodeEnd":629,"githubUrl":"https://github.com/embassy-rs/embassy/blob/463a07b963419a1bfe61d5d597c44acb810afb8b/embassy-stm32/src/hash/mod.rs#L593-L629","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nlet mut digest = [0u8; 20];\nhasher.finish_blocking(&mut digest); // panics for SHA-256\n// after\nlet mut digest = [0u8; <MyHash as DigestAlgorithm>::DIGEST_WORDS * 4];\nhasher.finish_blocking(&mut digest);","handlingStrategy":"validation","validationCode":"// Validate the digest buffer before calling finish_blocking\nlet required = <A as DigestAlgorithm>::DIGEST_WORDS * 4;\nif digest.len() < required {\n    return Err(DigestBufferTooSmall { required, actual: digest.len() });\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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"],"tags":["embedded","stm32","hash","buffer-size","panic"],"backgroundTag":"argument-out-of-range","analyzedSha":"463a07b963419a1bfe61d5d597c44acb810afb8b","analyzedAt":"2026-09-10T13:38:26.660Z","contentChangedAt":"2026-09-10T13:38:26.660Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}