diff --git a/local/recipes/drivers/redbear-btusb/source/src/btintel.rs b/local/recipes/drivers/redbear-btusb/source/src/btintel.rs index e11cbfbe92..bd6502d700 100644 --- a/local/recipes/drivers/redbear-btusb/source/src/btintel.rs +++ b/local/recipes/drivers/redbear-btusb/source/src/btintel.rs @@ -176,14 +176,23 @@ pub fn firmware_download_commands(fw_data: &[u8]) -> Vec { commands.extend(secure_send_commands(FRAGMENT_TYPE_PAYLOAD, payload)); } CssKeyType::Ecdsa => { - if fw_data.len() < 644 { - warn!("btintel: ECDSA firmware too short ({} bytes)", fw_data.len()); + // ECDSA firmware layout: CSS @ 644..772, PKEY @ 772..868, + // SIG @ 868..964. Payload starts at 964. Without the full + // bounds check, a 645..963 byte blob would panic on the + // PKEY/SIG slices. + const ECDSA_FULL_LEN: usize = ECDSA_HEADER_LEN + 128 + 96 + 96; + if fw_data.len() < ECDSA_FULL_LEN { + warn!( + "btintel: ECDSA firmware too short ({} bytes, need {})", + fw_data.len(), + ECDSA_FULL_LEN + ); return commands; } commands.extend(secure_send_commands(FRAGMENT_TYPE_CSS, &fw_data[644..644 + 128])); commands.extend(secure_send_commands(FRAGMENT_TYPE_PKEY, &fw_data[644 + 128..644 + 224])); commands.extend(secure_send_commands(FRAGMENT_TYPE_SIGNATURE, &fw_data[644 + 224..644 + 320])); - let payload = &fw_data[644 + 320..]; + let payload = &fw_data[ECDSA_FULL_LEN..]; commands.extend(secure_send_commands(FRAGMENT_TYPE_PAYLOAD, payload)); } CssKeyType::Hybrid => {