{"record":{"id":"db222acdfd8989cc","repo":"embassy-rs/embassy","slug":"additional-associated-data-must-be-processed-first","errorCode":null,"errorMessage":"Additional associated data must be processed first!","messagePattern":"Additional associated data must be processed first!","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"embassy-stm32/src/cryp/mod.rs","lineNumber":1404,"sourceCode":"    /// This function panics under various mismatches of parameters.\n    /// Output buffer must be at least as long as the input buffer.\n    /// Data must be a multiple of block size (128-bits for AES, 64-bits for DES) for CBC and ECB modes.\n    /// Padding or ciphertext stealing must be managed by the application for these modes.\n    /// Data must also be a multiple of block size unless `last_block` is `true`.\n    pub fn payload_blocking<'c, C: Cipher<'c> + CipherSized + IVSized>(\n        &self,\n        ctx: &mut Context<'c, C>,\n        input: &[u8],\n        output: &mut [u8],\n        last_block: bool,\n    ) {\n        self.load_context(ctx);\n\n        let last_block_remainder = input.len() % C::BLOCK_SIZE;\n\n        // Perform checks for correctness.\n        if !ctx.aad_complete && ctx.header_len > 0 {\n            panic!(\"Additional associated data must be processed first!\");\n        } else if !ctx.aad_complete {\n            #[cfg(any(cryp_v2, cryp_v3, cryp_v4))]\n            {\n                ctx.aad_complete = true;\n                T::regs().cr().modify(|w| w.set_crypen(false));\n                T::regs().cr().modify(|w| w.set_gcm_ccmph(2));\n                T::regs().cr().modify(|w| w.set_fflush(true));\n                T::regs().cr().modify(|w| w.set_crypen(true));\n            }\n        }\n        if ctx.last_block_processed {\n            panic!(\"The last block has already been processed!\");\n        }\n        if input.len() > output.len() {\n            panic!(\"Output buffer length must match input length.\");\n        }\n        if !last_block {\n            if last_block_remainder != 0 {","sourceCodeStart":1386,"sourceCodeEnd":1422,"githubUrl":"https://github.com/embassy-rs/embassy/blob/463a07b963419a1bfe61d5d597c44acb810afb8b/embassy-stm32/src/cryp/mod.rs#L1386-L1422","documentation":"During the payload phase, if AAD was supplied but not finalized (aad_complete false, header_len > 0), the driver panics: payload processing started while pending AAD is unfinished. The pending AAD's last block must be processed before payload blocks.","triggerScenarios":"Calling payload()/decrypt when header_len > 0 and aad_complete == false — e.g. additional_header() was called with last_aad_block=false and never finalized, then the payload phase starts.","commonSituations":"Forgetting last=true on the final additional_header() call; AAD not a block multiple with no final block; streaming AAD asynchronously and racing with payload start.","solutions":["Pass last_aad_block=true on the final additional_header() call (or make AAD length a block multiple) before starting the payload.","Verify every AAD byte was written — check header_len equals total AAD length.","Restart with a fresh context if the phase state is already inconsistent."],"exampleFix":"// before\nctx.additional_header(aad, false); // never finalized\nctx.payload(data, &mut out, false);\n// after\nctx.additional_header(aad, true);\nctx.payload(data, &mut out, false);","handlingStrategy":"type-guard","validationCode":"if ctx.header_len > 0 && !ctx.aad_complete { /* finalize AAD before payload */ }","typeGuard":"fn aad_ready_for_payload(ctx: &CipherContext) -> bool { ctx.aad_complete || ctx.header_len == 0 }","tryCatchPattern":null,"preventionTips":["Always mark the final AAD block with last=true","Assert AAD totals match expected header length in protocol code","Wrap header+payload phases in a helper that enforces ordering"],"tags":["embedded","crypto","aead","gcm","cryp","panic"],"backgroundTag":"invalid-state-transition","analyzedSha":"463a07b963419a1bfe61d5d597c44acb810afb8b","analyzedAt":"2026-09-10T13:38:26.660Z","contentChangedAt":"2026-09-10T13:38:26.660Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}