1extern crate alloc;
6
7use crate::td_uefi_pi::pi::guid::Guid;
8use alloc::string::String;
9use core::{ptr::slice_from_raw_parts, str::FromStr};
10use scroll::{Pread, Pwrite};
11
12pub const TDX_METADATA_GUID_STR: &str = "E9EAF9F3-168E-44D5-A8EB-7F4D8738F6AE";
14pub const TDX_METADATA_GUID: Guid = Guid::from_fields(
15 0xE9EAF9F3,
16 0x168E,
17 0x44D5,
18 [0xA8, 0xEB, 0x7F, 0x4D, 0x87, 0x38, 0xF6, 0xAE],
19);
20
21pub const TDX_METADATA_SIGNATURE: u32 = 0x46564454;
23pub const TDX_METADATA_VERSION: u32 = 1;
25pub const TDX_METADATA_OFFSET: u32 = 0x20;
27pub const TDX_METADATA_GUID_LEN: u32 = 16;
29pub const TDX_METADATA_DESCRIPTOR_LEN: u32 = 16;
31pub const TDX_METADATA_SECTION_LEN: u32 = 32;
33
34pub const TDX_METADATA_SECTION_TYPE_BFV: u32 = 0;
36pub const TDX_METADATA_SECTION_TYPE_CFV: u32 = 1;
38pub const TDX_METADATA_SECTION_TYPE_TD_HOB: u32 = 2;
40pub const TDX_METADATA_SECTION_TYPE_TEMP_MEM: u32 = 3;
42pub const TDX_METADATA_SECTION_TYPE_PERM_MEM: u32 = 4;
44pub const TDX_METADATA_SECTION_TYPE_PAYLOAD: u32 = 5;
46pub const TDX_METADATA_SECTION_TYPE_PAYLOAD_PARAM: u32 = 6;
48pub const TDX_METADATA_SECTION_TYPE_TD_INFO: u32 = 7;
50pub const TDX_METADATA_SECTION_TYPE_MAX: u32 = 8;
52
53pub const TDX_METADATA_SECTION_TYPE_STRS: [&str; TDX_METADATA_SECTION_TYPE_MAX as usize] = [
54 "BFV",
55 "CFV",
56 "TD_HOB",
57 "TempMem",
58 "PermMem",
59 "Payload",
60 "PayloadParam",
61 "TdInfo",
62];
63
64pub const TDX_METADATA_ATTRIBUTES_EXTENDMR: u32 = 0x00000001;
66pub const TDX_METADATA_ATTRIBUTES_PAGE_AUG: u32 = 0x00000002;
67
68#[repr(C)]
69#[derive(Debug, Pread, Pwrite)]
70pub struct TdxMetadataDescriptor {
71 pub signature: u32,
72 pub length: u32,
73 pub version: u32,
74 pub number_of_section_entry: u32,
75}
76
77impl Default for TdxMetadataDescriptor {
78 fn default() -> Self {
79 TdxMetadataDescriptor {
80 signature: TDX_METADATA_SIGNATURE,
81 length: 16,
82 version: 1,
83 number_of_section_entry: 0,
84 }
85 }
86}
87
88impl TdxMetadataDescriptor {
89 pub fn set_sections(&mut self, sections: u32) {
90 assert!(sections < 0x10000);
93 self.number_of_section_entry = sections;
94 self.length = 16 + sections * 32;
95 }
96
97 pub fn is_valid(&self) -> bool {
98 let len = self.length;
99
100 !(self.signature != TDX_METADATA_SIGNATURE
101 || self.version != 1
102 || self.number_of_section_entry == 0
103 || len < 16
104 || (len - 16) % 32 != 0
105 || (len - 16) / 32 != self.number_of_section_entry)
106 }
107
108 pub fn as_bytes(&self) -> &[u8] {
109 unsafe {
110 core::slice::from_raw_parts(
111 self as *const TdxMetadataDescriptor as *const u8,
112 core::mem::size_of::<Self>(),
113 )
114 }
115 }
116}
117
118#[repr(C)]
119#[derive(Clone, Copy, Debug, Default, Pwrite, Pread)]
120pub struct TdxMetadataSection {
121 pub data_offset: u32,
122 pub raw_data_size: u32,
123 pub memory_address: u64,
124 pub memory_data_size: u64,
125 pub r#type: u32,
126 pub attributes: u32,
127}
128
129impl TdxMetadataSection {
130 pub fn get_type_name(r#type: u32) -> Option<String> {
131 if r#type >= TDX_METADATA_SECTION_TYPE_MAX {
132 None
133 } else {
134 Some(String::from(
135 TDX_METADATA_SECTION_TYPE_STRS[r#type as usize],
136 ))
137 }
138 }
139
140 pub fn as_bytes(&self) -> &[u8] {
141 unsafe {
142 core::slice::from_raw_parts(
143 self as *const TdxMetadataSection as *const u8,
144 core::mem::size_of::<Self>(),
145 )
146 }
147 }
148}
149
150#[repr(C)]
151#[derive(Pwrite, Pread)]
152pub struct TdxMetadataGuid {
153 pub guid: Guid,
154}
155
156impl TdxMetadataGuid {
157 pub fn is_valid(&self) -> bool {
159 let metadata_guid = Guid::from_str(TDX_METADATA_GUID_STR).unwrap();
160 metadata_guid == self.guid
161 }
162
163 pub fn as_bytes(&self) -> &[u8; 16] {
164 self.guid.as_bytes()
165 }
166
167 pub fn from_bytes(buffer: &[u8; 16]) -> Option<TdxMetadataGuid> {
173 let guid = Guid::from_bytes(buffer);
174 let metadata_guid = TdxMetadataGuid { guid };
175 if metadata_guid.is_valid() {
176 Some(metadata_guid)
177 } else {
178 None
179 }
180 }
181}
182
183impl Default for TdxMetadataGuid {
184 fn default() -> Self {
185 TdxMetadataGuid {
186 guid: Guid::from_str(TDX_METADATA_GUID_STR).unwrap(),
187 }
188 }
189}
190
191#[derive(Debug)]
192pub enum TdxMetadataError {
193 InvalidSection,
194}
195
196pub fn validate_sections(sections: &[TdxMetadataSection]) -> Result<(), TdxMetadataError> {
197 let mut bfv_cnt = 0;
198 let mut bfv_start = 0;
199 let mut bfv_end = 0;
200 let mut hob_cnt = 0;
201 let mut perm_mem_cnt = 0;
202 let mut payload_cnt = 0;
203 let mut payload_param_cnt = 0;
204 let mut td_info_cnt = 0;
205 let mut td_info_start = 0;
206 let mut td_info_end = 0;
207 let check_data_memory_fields =
208 |data_offset: u32, data_size: u32, memory_address: u64, memory_size: u64| -> bool {
209 if data_size == 0 && data_offset != 0 {
210 return false;
211 }
212 if data_size != 0 && memory_size < data_size as u64 {
213 return false;
214 }
215 if (memory_address & 0xfff) != 0 {
216 return false;
217 }
218 true
219 };
220 for section in sections.iter() {
221 match section.r#type {
222 TDX_METADATA_SECTION_TYPE_BFV => {
223 if bfv_cnt == i32::MAX {
226 return Err(TdxMetadataError::InvalidSection);
227 }
228 bfv_cnt += 1;
229 if section.raw_data_size == 0 {
230 return Err(TdxMetadataError::InvalidSection);
231 }
232 if section.attributes != TDX_METADATA_ATTRIBUTES_EXTENDMR {
233 return Err(TdxMetadataError::InvalidSection);
234 }
235 if !check_data_memory_fields(
236 section.data_offset,
237 section.raw_data_size,
238 section.memory_address,
239 section.memory_data_size,
240 ) {
241 return Err(TdxMetadataError::InvalidSection);
242 } else {
243 bfv_start = section.data_offset;
244 bfv_end = bfv_start + section.raw_data_size;
245 }
246 }
247
248 TDX_METADATA_SECTION_TYPE_CFV => {
249 if section.raw_data_size == 0 {
252 return Err(TdxMetadataError::InvalidSection);
253 }
254 if section.attributes != 0 {
255 return Err(TdxMetadataError::InvalidSection);
256 }
257 if !check_data_memory_fields(
258 section.data_offset,
259 section.raw_data_size,
260 section.memory_address,
261 section.memory_data_size,
262 ) {
263 return Err(TdxMetadataError::InvalidSection);
264 }
265 }
266
267 TDX_METADATA_SECTION_TYPE_TD_HOB => {
268 if hob_cnt == i32::MAX {
272 return Err(TdxMetadataError::InvalidSection);
273 }
274 hob_cnt += 1;
275 if hob_cnt > 1 {
276 return Err(TdxMetadataError::InvalidSection);
277 }
278 if section.raw_data_size != 0 || section.data_offset != 0 {
279 return Err(TdxMetadataError::InvalidSection);
280 }
281 if section.attributes != 0 {
282 return Err(TdxMetadataError::InvalidSection);
283 }
284 if !check_data_memory_fields(
285 section.data_offset,
286 section.raw_data_size,
287 section.memory_address,
288 section.memory_data_size,
289 ) {
290 return Err(TdxMetadataError::InvalidSection);
291 }
292 }
293
294 TDX_METADATA_SECTION_TYPE_TEMP_MEM => {
295 if section.raw_data_size != 0 || section.data_offset != 0 {
297 return Err(TdxMetadataError::InvalidSection);
298 }
299 if section.attributes != 0 {
300 return Err(TdxMetadataError::InvalidSection);
301 }
302 if !check_data_memory_fields(
303 section.data_offset,
304 section.raw_data_size,
305 section.memory_address,
306 section.memory_data_size,
307 ) {
308 return Err(TdxMetadataError::InvalidSection);
309 }
310 }
311
312 TDX_METADATA_SECTION_TYPE_PERM_MEM => {
313 if perm_mem_cnt == i32::MAX {
319 return Err(TdxMetadataError::InvalidSection);
320 }
321 perm_mem_cnt += 1;
322 if section.raw_data_size != 0 || section.data_offset != 0 {
323 return Err(TdxMetadataError::InvalidSection);
324 }
325 if section.attributes != TDX_METADATA_ATTRIBUTES_PAGE_AUG {
326 return Err(TdxMetadataError::InvalidSection);
327 }
328 if !check_data_memory_fields(
329 section.data_offset,
330 section.raw_data_size,
331 section.memory_address,
332 section.memory_data_size,
333 ) {
334 return Err(TdxMetadataError::InvalidSection);
335 }
336 }
337
338 TDX_METADATA_SECTION_TYPE_PAYLOAD => {
339 if payload_cnt == i32::MAX {
343 return Err(TdxMetadataError::InvalidSection);
344 }
345 payload_cnt += 1;
346 if payload_cnt > 1 {
347 return Err(TdxMetadataError::InvalidSection);
348 }
349 if section.attributes & (!TDX_METADATA_ATTRIBUTES_EXTENDMR) != 0 {
350 return Err(TdxMetadataError::InvalidSection);
351 }
352 if !check_data_memory_fields(
353 section.data_offset,
354 section.raw_data_size,
355 section.memory_address,
356 section.memory_data_size,
357 ) {
358 return Err(TdxMetadataError::InvalidSection);
359 }
360 }
361
362 TDX_METADATA_SECTION_TYPE_PAYLOAD_PARAM => {
363 if payload_param_cnt == i32::MAX {
366 return Err(TdxMetadataError::InvalidSection);
367 }
368 payload_param_cnt += 1;
369 if payload_param_cnt > 1 {
370 return Err(TdxMetadataError::InvalidSection);
371 }
372 if section.attributes != 0 {
373 return Err(TdxMetadataError::InvalidSection);
374 }
375 if !check_data_memory_fields(
376 section.data_offset,
377 section.raw_data_size,
378 section.memory_address,
379 section.memory_data_size,
380 ) {
381 return Err(TdxMetadataError::InvalidSection);
382 }
383 }
384
385 TDX_METADATA_SECTION_TYPE_TD_INFO => {
386 if td_info_cnt == i32::MAX {
388 return Err(TdxMetadataError::InvalidSection);
389 }
390 td_info_cnt += 1;
391 if td_info_cnt > 1 {
392 return Err(TdxMetadataError::InvalidSection);
393 }
394 if section.attributes != 0 {
395 return Err(TdxMetadataError::InvalidSection);
396 }
397 if section.raw_data_size == 0 {
398 return Err(TdxMetadataError::InvalidSection);
399 } else {
400 td_info_start = section.data_offset;
401 td_info_end = td_info_start + section.raw_data_size;
402 }
403
404 if section.memory_address != 0 || section.memory_data_size != 0 {
406 return Err(TdxMetadataError::InvalidSection);
407 }
408 }
409
410 _ => {
411 return Err(TdxMetadataError::InvalidSection);
412 }
413 }
414 }
415
416 if bfv_cnt == 0 {
418 return Err(TdxMetadataError::InvalidSection);
419 }
420 if hob_cnt == 0 && perm_mem_cnt == 0 {
423 return Err(TdxMetadataError::InvalidSection);
424 }
425 if payload_cnt == 0 && payload_param_cnt != 0 {
427 return Err(TdxMetadataError::InvalidSection);
428 }
429
430 if td_info_cnt != 0
432 && (td_info_start < bfv_start || td_info_start >= bfv_end || td_info_end > bfv_end)
433 {
434 return Err(TdxMetadataError::InvalidSection);
435 }
436
437 Ok(())
438}
439
440#[repr(C)]
441#[derive(Default, Pwrite, Pread)]
442pub struct TdxMetadataPtr {
443 pub ptr: u32,
444}
445
446impl TdxMetadataPtr {
447 pub fn as_bytes(&self) -> &[u8] {
448 unsafe {
449 &*slice_from_raw_parts(
450 self as *const TdxMetadataPtr as *const u8,
451 core::mem::size_of::<Self>(),
452 )
453 }
454 }
455}
456
457#[cfg(test)]
458mod tests {
459 use super::*;
460 use scroll::export::mem::size_of;
461
462 #[test]
463 fn ensure_data_struct_size() {
464 assert_eq!(size_of::<TdxMetadataDescriptor>(), 16);
465 assert_eq!(size_of::<TdxMetadataSection>(), 32);
466 assert_eq!(size_of::<TdxMetadataGuid>(), 16);
467 assert_eq!(size_of::<TdxMetadataPtr>(), 4);
468 }
469
470 #[test]
471 fn test_tdx_metadata_descriptor() {
472 let mut desc = TdxMetadataDescriptor::default();
473
474 assert_eq!(desc.signature, TDX_METADATA_SIGNATURE);
475 assert_eq!(desc.length, 16);
476 assert_eq!(desc.version, 1);
477 assert_eq!(desc.number_of_section_entry, 0);
478 assert_eq!(desc.is_valid(), false);
479
480 desc.set_sections(1);
481 assert_eq!(desc.signature, TDX_METADATA_SIGNATURE);
482 assert_eq!(desc.length, 48);
483 assert_eq!(desc.version, 1);
484 assert_eq!(desc.number_of_section_entry, 1);
485 assert_eq!(desc.is_valid(), true);
486 }
487
488 #[test]
489 fn test_tdx_metadata_guid() {
490 let tdx_metadata_guid: [u8; 16] = [
491 0xF3, 0xF9, 0xEA, 0xE9, 0x8e, 0x16, 0xD5, 0x44, 0xA8, 0xEB, 0x7F, 0x4D, 0x87, 0x38,
492 0xF6, 0xAE,
493 ];
494 let invalid_tdx_metadata_guid: [u8; 16] = [
495 0xE9, 0xEA, 0xF9, 0xF3, 0x16, 0x8e, 0x44, 0xD5, 0xA8, 0xEB, 0x7F, 0x4D, 0x87, 0x38,
496 0xF6, 0xAE,
497 ];
498 let guid = TdxMetadataGuid::default();
499
500 assert_eq!(&tdx_metadata_guid, guid.as_bytes());
501 assert_eq!(&tdx_metadata_guid, TDX_METADATA_GUID.as_bytes());
502 assert_eq!(guid.is_valid(), true);
503
504 let guid_pread: TdxMetadataGuid = tdx_metadata_guid.pread(0).unwrap();
505 assert_eq!(guid_pread.as_bytes(), guid.as_bytes());
506
507 let guid = TdxMetadataGuid::from_bytes(&tdx_metadata_guid).unwrap();
508 assert_eq!(guid.as_bytes(), &tdx_metadata_guid);
509
510 assert!(TdxMetadataGuid::from_bytes(&invalid_tdx_metadata_guid).is_none());
511 }
512
513 #[test]
514 fn test_tdx_metadata_section() {
515 assert_eq!(TdxMetadataSection::get_type_name(0).unwrap(), "BFV");
516 assert_eq!(TdxMetadataSection::get_type_name(1).unwrap(), "CFV");
517 assert_eq!(TdxMetadataSection::get_type_name(2).unwrap(), "TD_HOB");
518 assert_eq!(TdxMetadataSection::get_type_name(3).unwrap(), "TempMem");
519 assert_eq!(TdxMetadataSection::get_type_name(4).unwrap(), "PermMem");
520 assert_eq!(TdxMetadataSection::get_type_name(5).unwrap(), "Payload");
521 assert_eq!(
522 TdxMetadataSection::get_type_name(6).unwrap(),
523 "PayloadParam"
524 );
525 assert_eq!(TdxMetadataSection::get_type_name(7).unwrap(), "TdInfo");
526
527 assert!(TdxMetadataSection::get_type_name(8).is_none());
528 }
529
530 #[test]
531 fn test_validate_sections() {
532 let sections = [];
534 assert!(!validate_sections(§ions).is_ok());
535
536 let mut sections: [TdxMetadataSection; 7] = [TdxMetadataSection::default(); 7];
538 sections[0] = TdxMetadataSection {
540 data_offset: 0,
541 raw_data_size: 0xf7e000,
542 memory_address: 0xff082000,
543 memory_data_size: 0xf7e000,
544 attributes: 1,
545 r#type: TDX_METADATA_SECTION_TYPE_BFV,
546 };
547 sections[1] = TdxMetadataSection {
549 data_offset: 0,
550 raw_data_size: 0x40000,
551 memory_address: 0xff000000,
552 memory_data_size: 0x40000,
553 attributes: 0,
554 r#type: TDX_METADATA_SECTION_TYPE_CFV,
555 };
556 sections[2] = TdxMetadataSection {
558 data_offset: 0,
559 raw_data_size: 0,
560 memory_address: 0x820000,
561 memory_data_size: 0x20000,
562 attributes: 0,
563 r#type: TDX_METADATA_SECTION_TYPE_TD_HOB,
564 };
565 sections[3] = TdxMetadataSection {
567 data_offset: 0,
568 raw_data_size: 0,
569 memory_address: 0xFF040000,
570 memory_data_size: 0x1000,
571 attributes: 0,
572 r#type: TDX_METADATA_SECTION_TYPE_TEMP_MEM,
573 };
574 sections[4] = TdxMetadataSection {
576 data_offset: 0,
577 raw_data_size: 0,
578 memory_address: 0x1200000,
579 memory_data_size: 0x8000000,
580 attributes: 0,
581 r#type: TDX_METADATA_SECTION_TYPE_PAYLOAD,
582 };
583 sections[5] = TdxMetadataSection {
585 data_offset: 0,
586 raw_data_size: 0,
587 memory_address: 0x1100000,
588 memory_data_size: 0x100000,
589 attributes: 0,
590 r#type: TDX_METADATA_SECTION_TYPE_PAYLOAD_PARAM,
591 };
592 sections[6] = TdxMetadataSection {
594 data_offset: 0,
595 raw_data_size: 0x1000,
596 memory_address: 0,
597 memory_data_size: 0,
598 attributes: 0,
599 r#type: TDX_METADATA_SECTION_TYPE_TD_INFO,
600 };
601
602 assert!(validate_sections(§ions).is_ok());
603
604 sections[0].raw_data_size = 0;
607 assert!(!validate_sections(§ions).is_ok());
608 sections[0].raw_data_size = 0xf7e000;
609 sections[0].attributes = 0;
611 assert!(!validate_sections(§ions).is_ok());
612 sections[0].attributes = TDX_METADATA_ATTRIBUTES_EXTENDMR;
613 sections[0].memory_data_size = sections[0].raw_data_size as u64 - 1;
615 assert!(!validate_sections(§ions).is_ok());
616 sections[0].memory_data_size += 1;
617 sections[0].memory_address += 1;
619 assert!(!validate_sections(§ions).is_ok());
620 sections[0].memory_address -= 1;
621 sections[3].r#type = TDX_METADATA_SECTION_TYPE_BFV;
623 sections[3].attributes = TDX_METADATA_ATTRIBUTES_EXTENDMR;
624 sections[3].raw_data_size = sections[3].memory_data_size as u32;
625 assert!(validate_sections(§ions).is_ok());
626 sections[3].r#type = TDX_METADATA_SECTION_TYPE_TEMP_MEM;
627 sections[3].attributes = 0;
628 sections[3].raw_data_size = 0;
629
630 sections[1].r#type = TDX_METADATA_SECTION_TYPE_TEMP_MEM;
633 sections[1].raw_data_size = 0;
634 assert!(validate_sections(§ions).is_ok());
635 sections[1].r#type = TDX_METADATA_SECTION_TYPE_CFV;
636 assert!(!validate_sections(§ions).is_ok());
638 sections[1].raw_data_size = 0x40000;
639 sections[1].attributes = 1;
641 assert!(!validate_sections(§ions).is_ok());
642 sections[1].attributes = 0;
643 sections[1].memory_data_size = sections[1].raw_data_size as u64 - 1;
645 assert!(!validate_sections(§ions).is_ok());
646 sections[1].memory_data_size += 1;
647 sections[1].memory_address += 1;
649 assert!(!validate_sections(§ions).is_ok());
650 sections[1].memory_address -= 1;
651 sections[3].r#type = TDX_METADATA_SECTION_TYPE_CFV;
653 sections[3].raw_data_size = sections[3].memory_data_size as u32;
654 assert!(validate_sections(§ions).is_ok());
655 sections[3].r#type = TDX_METADATA_SECTION_TYPE_TEMP_MEM;
656 sections[3].raw_data_size = 0;
657
658 sections[2].r#type = TDX_METADATA_SECTION_TYPE_TEMP_MEM;
661 assert!(!validate_sections(§ions).is_ok());
662 sections[2].r#type = TDX_METADATA_SECTION_TYPE_TD_HOB;
663 sections[2].raw_data_size = 1;
665 assert!(!validate_sections(§ions).is_ok());
666 sections[2].raw_data_size = 0;
667 sections[2].data_offset = 1;
669 assert!(!validate_sections(§ions).is_ok());
670 sections[2].data_offset = 0;
671 sections[2].attributes = 1;
673 assert!(!validate_sections(§ions).is_ok());
674 sections[2].attributes = 0;
675 sections[2].memory_address += 1;
677 assert!(!validate_sections(§ions).is_ok());
678 sections[2].memory_address -= 1;
679 sections[3].r#type = TDX_METADATA_SECTION_TYPE_TD_HOB;
681 assert!(!validate_sections(§ions).is_ok());
682 sections[3].r#type = TDX_METADATA_SECTION_TYPE_TEMP_MEM;
683
684 sections[3].raw_data_size = 1;
689 assert!(!validate_sections(§ions).is_ok());
690 sections[3].raw_data_size = 0;
691 sections[3].data_offset = 1;
693 assert!(!validate_sections(§ions).is_ok());
694 sections[3].data_offset = 0;
695 sections[3].attributes = 1;
697 assert!(!validate_sections(§ions).is_ok());
698 sections[3].attributes = 0;
699 sections[3].memory_address += 1;
701 assert!(!validate_sections(§ions).is_ok());
702 sections[3].memory_address -= 1;
703 sections[2].r#type = TDX_METADATA_SECTION_TYPE_PERM_MEM;
708 sections[2].attributes = TDX_METADATA_ATTRIBUTES_PAGE_AUG;
709 assert!(validate_sections(§ions).is_ok());
710 sections[2].raw_data_size = 1;
712 assert!(!validate_sections(§ions).is_ok());
713 sections[2].raw_data_size = 0;
714 sections[2].data_offset = 1;
716 assert!(!validate_sections(§ions).is_ok());
717 sections[2].data_offset = 0;
718 sections[2].attributes = 0;
720 assert!(!validate_sections(§ions).is_ok());
721 sections[2].attributes = TDX_METADATA_ATTRIBUTES_EXTENDMR;
722 assert!(!validate_sections(§ions).is_ok());
723 sections[2].attributes = TDX_METADATA_ATTRIBUTES_PAGE_AUG;
724 sections[2].memory_address += 1;
726 assert!(!validate_sections(§ions).is_ok());
727 sections[2].memory_address -= 1;
728 sections[3].r#type = TDX_METADATA_SECTION_TYPE_TD_HOB;
730 assert!(validate_sections(§ions).is_ok());
731 sections[3].r#type = TDX_METADATA_SECTION_TYPE_TEMP_MEM;
732 sections[3].r#type = TDX_METADATA_SECTION_TYPE_PERM_MEM;
734 sections[3].attributes = TDX_METADATA_ATTRIBUTES_PAGE_AUG;
735 assert!(validate_sections(§ions).is_ok());
736 sections[3].r#type = TDX_METADATA_SECTION_TYPE_TEMP_MEM;
737 sections[3].attributes = 0;
738
739 sections[4].r#type = TDX_METADATA_SECTION_TYPE_TEMP_MEM;
742 assert!(!validate_sections(§ions).is_ok());
743 sections[5].r#type = TDX_METADATA_SECTION_TYPE_TEMP_MEM;
745 assert!(validate_sections(§ions).is_ok());
746 sections[4].r#type = TDX_METADATA_SECTION_TYPE_PAYLOAD;
747 sections[5].r#type = TDX_METADATA_SECTION_TYPE_PAYLOAD_PARAM;
748 sections[4].attributes = 1;
750 assert!(validate_sections(§ions).is_ok());
751 sections[4].attributes = 2;
753 assert!(!validate_sections(§ions).is_ok());
754 sections[4].attributes = 0;
755 sections[4].data_offset = 1;
757 assert!(!validate_sections(§ions).is_ok());
758 sections[4].data_offset = 0;
759 sections[4].memory_address += 1;
761 assert!(!validate_sections(§ions).is_ok());
762 sections[4].memory_address -= 1;
763 sections[5].r#type = TDX_METADATA_SECTION_TYPE_PAYLOAD;
765 assert!(!validate_sections(§ions).is_ok());
766 sections[5].r#type = TDX_METADATA_SECTION_TYPE_PAYLOAD_PARAM;
767
768 sections[5].r#type = TDX_METADATA_SECTION_TYPE_TEMP_MEM;
770 assert!(validate_sections(§ions).is_ok());
771 sections[5].r#type = TDX_METADATA_SECTION_TYPE_PAYLOAD_PARAM;
772 sections[5].attributes = 1;
774 assert!(!validate_sections(§ions).is_ok());
775 sections[5].attributes = 0;
776 sections[5].memory_address += 1;
778 assert!(!validate_sections(§ions).is_ok());
779 sections[5].memory_address -= 1;
780 sections[3].r#type = TDX_METADATA_SECTION_TYPE_PAYLOAD_PARAM;
782 assert!(!validate_sections(§ions).is_ok());
783
784 sections[5].r#type = TDX_METADATA_SECTION_TYPE_MAX;
786 assert!(!validate_sections(§ions).is_ok());
787 }
788
789 #[test]
790 fn test_tdxmetadataptr() {
791 let ptr = TdxMetadataPtr { ptr: 0x1000 };
792
793 assert_eq!(ptr.as_bytes(), 0x1000_i32.to_le_bytes())
794 }
795}