use crate::signatures::common::{SignatureError, SignatureResult, CONFIDENCE_MEDIUM};
use crate::structures::uefi::{parse_uefi_capsule_header, parse_uefi_volume_header};
pub const VOLUME_DESCRIPTION: &str = "UEFI PI firmware volume";
pub const CAPSULE_DESCRIPTION: &str = "UEFI capsule image";
pub fn uefi_volume_magic() -> Vec<Vec<u8>> {
vec![b"_FVH".to_vec()]
}
pub fn uefi_capsule_magic() -> Vec<Vec<u8>> {
vec![
b"\xBD\x86\x66\x3B\x76\x0D\x30\x40\xB7\x0E\xB5\x51\x9E\x2F\xC5\xA0".to_vec(), b"\x8B\xA6\x3C\x4A\x23\x77\xFB\x48\x80\x3D\x57\x8C\xC1\xFE\xC4\x4D".to_vec(), b"\xB9\x82\x91\x53\xB5\xAB\x91\x43\xB6\x9A\xE3\xA9\x43\xF7\x2F\xCC".to_vec(), ]
}
pub fn uefi_volume_parser(
file_data: &[u8],
offset: usize,
) -> Result<SignatureResult, SignatureError> {
const UEFI_MAGIC_OFFSET: usize = 40;
let mut result = SignatureResult {
size: 0,
offset: 0,
description: VOLUME_DESCRIPTION.to_string(),
confidence: CONFIDENCE_MEDIUM,
..Default::default()
};
if offset >= UEFI_MAGIC_OFFSET {
result.offset = offset - UEFI_MAGIC_OFFSET;
if let Ok(uefi_volume_header) = parse_uefi_volume_header(&file_data[result.offset..]) {
if file_data.len() >= (result.offset + uefi_volume_header.volume_size) {
result.size = uefi_volume_header.volume_size;
result.description = format!(
"{}, header CRC: {:#X}, header size: {} bytes, total size: {} bytes",
result.description,
uefi_volume_header.header_crc as u32,
uefi_volume_header.header_size,
uefi_volume_header.volume_size
);
return Ok(result);
}
}
}
Err(SignatureError)
}
pub fn uefi_capsule_parser(
file_data: &[u8],
offset: usize,
) -> Result<SignatureResult, SignatureError> {
let mut result = SignatureResult {
description: CAPSULE_DESCRIPTION.to_string(),
offset,
size: 0,
confidence: CONFIDENCE_MEDIUM,
..Default::default()
};
let available_data: usize = file_data.len() - offset;
if let Ok(capsule_header) = parse_uefi_capsule_header(&file_data[offset..]) {
if capsule_header.total_size >= available_data {
result.size = capsule_header.total_size;
result.description = format!(
"{}, header size: {} bytes, total size: {} bytes",
result.description, capsule_header.header_size, capsule_header.total_size
);
return Ok(result);
}
}
Err(SignatureError)
}