Skip to content

Commit b21a146

Browse files
committed
feat(tdx): add a helper function to parse TDVF
Signed-off-by: Changyuan Lyu <changyuanl@google.com>
1 parent 19ea039 commit b21a146

File tree

2 files changed

+64
-3
lines changed

2 files changed

+64
-3
lines changed

alioth/src/firmware/firmware.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,26 @@ pub mod acpi;
1919
pub mod dt;
2020
#[path = "ovmf/ovmf.rs"]
2121
pub mod ovmf;
22+
23+
use snafu::Snafu;
24+
25+
use crate::errors::{DebugTrace, trace_error};
26+
27+
#[cfg(target_arch = "x86_64")]
28+
use self::ovmf::tdx::{TDVF_SIGNATURE, TDVF_VERSION};
29+
30+
#[trace_error]
31+
#[derive(Snafu, DebugTrace)]
32+
#[snafu(module, context(suffix(false)))]
33+
pub enum Error {
34+
#[snafu(display("Firmware missing {name}"))]
35+
MissingMetadata { name: &'static str },
36+
#[snafu(display("Firmware missing TDVF signature {TDVF_SIGNATURE:08x}, got {got:08x}"))]
37+
MissingTdvfSignature { got: u32 },
38+
#[snafu(display("Firmware missing TDVF version {TDVF_VERSION}, got {got}"))]
39+
MissingTdvfVersion { got: u32 },
40+
#[snafu(display("Invalid firmware data layout"))]
41+
InvalidLayout,
42+
}
43+
44+
type Result<T, E = Error> = std::result::Result<T, E>;

alioth/src/firmware/ovmf/ovmf_x86_64/tdx.rs

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
1717
use crate::firmware::ovmf::x86_64::GUID_SIZE;
1818
use crate::{bitflags, consts};
1919

20+
use crate::firmware::ovmf::x86_64::parse_data;
21+
use crate::firmware::{Result, error};
22+
2023
pub const GUID_TDX_METADATA_OFFSET: [u8; GUID_SIZE] = [
2124
0x35, 0x65, 0x7a, 0xe4, 0x4a, 0x98, 0x98, 0x47, 0x86, 0x5e, 0x46, 0x85, 0xa7, 0xbf, 0x8e, 0xc2,
2225
];
@@ -44,19 +47,54 @@ consts! {
4447

4548
bitflags! {
4649
#[derive(Default, KnownLayout, Immutable, FromBytes, IntoBytes)]
47-
pub struct TdvfSectionAttribute(u32) {
50+
pub struct TdvfSectionAttr(u32) {
4851
MR_EXTEND = 1 << 0;
4952
PAGE_AUG = 1 << 1;
5053
}
5154
}
5255

5356
#[repr(C)]
5457
#[derive(Debug, Clone, Default, KnownLayout, Immutable, FromBytes, IntoBytes)]
55-
pub struct TdxMetadataSection {
58+
pub struct TdvfSectionEntry {
5659
pub data_offset: u32,
5760
pub raw_data_size: u32,
5861
pub memory_address: u64,
5962
pub memory_data_size: u64,
6063
pub r#type: TdvfSectionType,
61-
pub attributes: TdvfSectionAttribute,
64+
pub attributes: TdvfSectionAttr,
65+
}
66+
67+
pub fn parse_entries(data: &[u8]) -> Result<&[TdvfSectionEntry]> {
68+
let Some(offset_r) = parse_data(data, &GUID_TDX_METADATA_OFFSET) else {
69+
return error::MissingMetadata {
70+
name: "TdvfMetadata",
71+
}
72+
.fail();
73+
};
74+
let Ok(offset_r) = u32::read_from_bytes(offset_r) else {
75+
return error::InvalidLayout.fail();
76+
};
77+
let offset = data.len() - offset_r as usize;
78+
let Ok((metadata, remain)) = TdvfMetadata::ref_from_prefix(&data[offset..]) else {
79+
return error::InvalidLayout.fail();
80+
};
81+
if metadata.signature != TDVF_SIGNATURE {
82+
return error::MissingTdvfSignature {
83+
got: metadata.signature,
84+
}
85+
.fail();
86+
}
87+
if metadata.version != TDVF_VERSION {
88+
return error::MissingTdvfVersion {
89+
got: metadata.version,
90+
}
91+
.fail();
92+
}
93+
let Ok((entries, _)) = <[TdvfSectionEntry]>::ref_from_prefix_with_elems(
94+
remain,
95+
metadata.number_of_entries as usize,
96+
) else {
97+
return error::InvalidLayout.fail();
98+
};
99+
Ok(entries)
62100
}

0 commit comments

Comments
 (0)