td_shim_interface/
loader.rs1extern crate alloc;
5
6use crate::metadata::{
7 self, TdxMetadataDescriptor, TdxMetadataGuid, TdxMetadataSection, TDX_METADATA_DESCRIPTOR_LEN,
8 TDX_METADATA_GUID_LEN, TDX_METADATA_OFFSET, TDX_METADATA_SECTION_LEN,
9};
10use alloc::vec::Vec;
11use core::convert::TryInto;
12use log::error;
13use scroll::Pread;
14
15pub struct TdShimLoader;
16
17impl TdShimLoader {
18 pub fn parse(binary_file: &[u8]) -> Option<(TdxMetadataDescriptor, Vec<TdxMetadataSection>)> {
24 let file_size = binary_file.len();
25 let metadata_offset_addr = file_size - TDX_METADATA_OFFSET as usize;
28 let buffer = &binary_file[metadata_offset_addr..metadata_offset_addr + 4];
29 let mut metadata_offset = ((buffer[3] as u32) << 24)
30 | ((buffer[2] as u32) << 16)
31 | ((buffer[1] as u32) << 8)
32 | (buffer[0] as u32);
33 if metadata_offset > file_size as u32 - TDX_METADATA_OFFSET - TDX_METADATA_DESCRIPTOR_LEN {
34 error!("The metadata offset is invalid. {}", metadata_offset);
35 error!("{:X?}", buffer);
36 return None;
37 }
38
39 metadata_offset -= TDX_METADATA_GUID_LEN;
41 let buffer = &binary_file
42 [metadata_offset as usize..(metadata_offset + TDX_METADATA_GUID_LEN) as usize]
43 .try_into()
44 .unwrap();
45 let metadata_guid = TdxMetadataGuid::from_bytes(buffer);
46 if metadata_guid.is_none() {
47 error!("Invalid TdxMetadataGuid");
48 error!("{:X?}", &buffer);
49 return None;
50 }
51
52 metadata_offset += TDX_METADATA_GUID_LEN;
54 let buffer = &binary_file
55 [metadata_offset as usize..(metadata_offset + TDX_METADATA_DESCRIPTOR_LEN) as usize];
56 let metadata_descriptor: TdxMetadataDescriptor =
57 buffer.pread::<TdxMetadataDescriptor>(0).unwrap();
58 if !metadata_descriptor.is_valid() {
59 error!("Invalid TdxMetadata Descriptor: {:?}", metadata_descriptor);
60 return None;
61 }
62
63 let metadata_len = metadata_descriptor.number_of_section_entry * TDX_METADATA_SECTION_LEN
65 + TDX_METADATA_GUID_LEN
66 + TDX_METADATA_DESCRIPTOR_LEN;
67 if metadata_offset + metadata_len + TDX_METADATA_GUID_LEN + TDX_METADATA_DESCRIPTOR_LEN
68 > file_size as u32
69 {
70 error!("Invalid TdxMetadata length {}", metadata_len);
71 return None;
72 }
73
74 let mut metadata_sections: Vec<TdxMetadataSection> = Vec::new();
76 let mut i = 0;
77 metadata_offset += TDX_METADATA_DESCRIPTOR_LEN;
78
79 loop {
80 let buffer = &binary_file
81 [metadata_offset as usize..(metadata_offset + TDX_METADATA_SECTION_LEN) as usize];
82
83 let section = buffer.pread::<TdxMetadataSection>(0).unwrap();
84 metadata_sections.push(section);
85
86 i += 1;
87 if i == metadata_descriptor.number_of_section_entry {
88 break;
89 }
90 metadata_offset += TDX_METADATA_SECTION_LEN;
91 }
92
93 if i != metadata_descriptor.number_of_section_entry {
94 error!("Invalid number of sections.");
95 return None;
96 }
97
98 if metadata::validate_sections(&metadata_sections).is_err() {
100 error!("Invalid metadata sections.");
101 return None;
102 }
103
104 Some((metadata_descriptor, metadata_sections))
105 }
106}