eventlog_rs/
bios_eventlog.rs1use crate::enums::EVENTLOG_TYPES;
5use anyhow::*;
6use byteorder::{LittleEndian, ReadBytesExt};
7use core::fmt;
8use std::convert::TryFrom;
9
10const SHA1_DIGEST_SIZE: usize = 20;
11
12#[derive(Clone)]
13pub struct BiosEventlog {
14 pub log: Vec<BiosEventlogEntry>,
15}
16
17impl fmt::Display for BiosEventlog {
18 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
19 let mut parsed_el = String::default();
20 for event_entry in self.log.clone() {
21 parsed_el = format!(
22 "{}\nEvent Entry:\n\tPCR: {}\n\tEvent Type: {}\n\tDigest: {}\n\tEvent Data: {}\n",
23 parsed_el,
24 event_entry.pcr_index,
25 event_entry.event_type,
26 hex::encode(event_entry.digest.clone()),
27 String::from_utf8(event_entry.event_data.clone())
28 .unwrap_or_else(|_| hex::encode(event_entry.event_data.clone())),
29 );
30 }
31
32 write!(f, "{parsed_el}")
33 }
34}
35
36#[derive(Clone)]
37pub struct BiosEventlogEntry {
38 pub pcr_index: u32,
39 pub event_type: String,
40 pub digest: Vec<u8>,
41 pub event_data: Vec<u8>,
42}
43
44impl TryFrom<Vec<u8>> for BiosEventlog {
45 type Error = anyhow::Error;
46
47 fn try_from(data: Vec<u8>) -> Result<Self, Self::Error> {
48 let mut index = 0;
49 let mut event_log: Vec<BiosEventlogEntry> = Vec::new();
50
51 while index < data.len() as usize {
52 let stop_flag = (&data[index..(index + 8)]).read_u64::<LittleEndian>()?;
53 let pcr_index = (&data[index..(index + 4)]).read_u32::<LittleEndian>()?;
54 index += 4;
55
56 let event_type_num = (&data[index..(index + 4)]).read_u32::<LittleEndian>()?;
57 index += 4;
58 let event_type = match EVENTLOG_TYPES.get(&event_type_num) {
59 Some(type_name) => type_name.to_string(),
60 None => format!("UNKOWN_TYPE: {:x}", &event_type_num),
61 };
62
63 if stop_flag == 0xFFFFFFFFFFFFFFFF || stop_flag == 0x0000000000000000 {
64 break;
65 }
66
67 let digest = data[index..(index + SHA1_DIGEST_SIZE)].to_vec();
68 index += SHA1_DIGEST_SIZE;
69
70 let event_data_size = (&data[index..(index + 4)]).read_u32::<LittleEndian>()? as usize;
71 index += 4;
72 let event_data = data[index..(index + event_data_size)].to_vec();
73 index += event_data_size;
74
75 let eventlog_entry = BiosEventlogEntry {
76 pcr_index,
77 event_type,
78 digest,
79 event_data,
80 };
81
82 event_log.push(eventlog_entry)
83 }
84
85 Ok(BiosEventlog { log: event_log })
86 }
87}