td_shim_interface/
lib.rs

1// Copyright (c) 2022 Alibaba Cloud
2//
3// SPDX-License-Identifier: BSD-2-Clause-Patent
4
5#![no_std]
6
7use scroll::{Pread, Pwrite};
8
9pub mod acpi;
10pub mod loader;
11pub mod metadata;
12pub mod td_uefi_pi;
13
14use td_uefi_pi::pi::{self, guid};
15
16// This GUID is used for ACPI GUID Extension HOB
17// Please refer to:
18// https://github.com/confidential-containers/td-shim/blob/main/doc/tdshim_spec.md#acpi-guid-extension-hob
19pub const TD_ACPI_TABLE_HOB_GUID: guid::Guid = guid::Guid::from_fields(
20    0x6a0c5870,
21    0xd4ed,
22    0x44f4,
23    [0xa1, 0x35, 0xdd, 0x23, 0x8b, 0x6f, 0xc, 0x8d],
24);
25
26// This GUID is used for TD Payload Info GUID Extension HOB
27// Please refer to:
28// https://github.com/confidential-containers/td-shim/blob/main/doc/tdshim_spec.md#td-payload-info-guid-extension-hob
29pub const TD_PAYLOAD_INFO_HOB_GUID: guid::Guid = guid::Guid::from_fields(
30    0xb96fa412,
31    0x461f,
32    0x4be3,
33    [0x8c, 0xd, 0xad, 0x80, 0x5a, 0x49, 0x7a, 0xc0],
34);
35
36// This GUID is used for E820 Memory Map GUID Extension HOB
37// Please refer to:
38// https://github.com/confidential-containers/td-shim/blob/main/doc/tdshim_spec.md#e820-memory-map-guid-extension-hob
39pub const TD_E820_TABLE_HOB_GUID: pi::guid::Guid = pi::guid::Guid::from_fields(
40    0x8f8072ea,
41    0x3486,
42    0x4b47,
43    [0x86, 0xa7, 0x23, 0x53, 0xb8, 0x8a, 0x87, 0x73],
44);
45
46#[repr(u32)]
47#[derive(Clone, Copy, Debug, Eq, PartialEq)]
48pub enum TdPayloadInfoHobType {
49    ///  Payload Binary is a PE/COFF or ELF executable image as payload.
50    ///
51    /// Entrypoint can be found by parsing the image header. This type image does not follow
52    /// Linux boot protocol. A payload HOB is used to pass data from TdShim to payload.
53    ExecutablePayload = 0,
54
55    /// Payload Binary is bzImage, follow Linux boot protocol.
56    ///
57    /// The first 512 bytes are boot_param. (zero page). The entrypoint is start address of loaded
58    /// 64bit Linux kernel plus 0x200
59    BzImage,
60
61    /// Payload Binary is VMM loaded vmLinux, follow Linux boot protocol.
62    ///
63    /// The entrypoint is defined at HOB_PAYLOAD_INFO_TABLE.Entrypoint.
64    RawVmLinux,
65
66    /// Unknown Image type
67    UnknownImage = u32::MAX,
68}
69
70impl From<&TdPayloadInfoHobType> for u32 {
71    fn from(v: &TdPayloadInfoHobType) -> Self {
72        *v as u32
73    }
74}
75
76impl From<u32> for TdPayloadInfoHobType {
77    fn from(v: u32) -> Self {
78        match v {
79            0 => TdPayloadInfoHobType::ExecutablePayload,
80            1 => TdPayloadInfoHobType::BzImage,
81            2 => TdPayloadInfoHobType::RawVmLinux,
82            _ => TdPayloadInfoHobType::UnknownImage,
83        }
84    }
85}
86
87#[repr(C)]
88#[derive(Default, Clone, Copy, Pread, Pwrite)]
89pub struct PayloadInfo {
90    pub image_type: u32,
91    pub reserved: u32,
92    pub entry_point: u64,
93}
94
95/// Write three bytes from an integer value into the buffer.
96pub fn write_u24(data: u32, buf: &mut [u8; 3]) {
97    assert!(data <= 0xffffff);
98    buf[0] = (data & 0xFF) as u8;
99    buf[1] = ((data >> 8) & 0xFF) as u8;
100    buf[2] = ((data >> 16) & 0xFF) as u8;
101}
102
103// To protect against speculative attacks, place the LFENCE instruction after the range
104// check and branch, but before any code that consumes the checked value.
105pub fn speculation_barrier() {
106    unsafe { core::arch::asm!("lfence") }
107}
108
109#[cfg(test)]
110mod test {
111    use super::*;
112
113    #[test]
114    fn test_tdpayload_info_hob_type() {
115        assert_eq!(
116            TdPayloadInfoHobType::from(0),
117            TdPayloadInfoHobType::ExecutablePayload
118        );
119        assert_eq!(TdPayloadInfoHobType::from(1), TdPayloadInfoHobType::BzImage);
120        assert_eq!(
121            TdPayloadInfoHobType::from(2),
122            TdPayloadInfoHobType::RawVmLinux
123        );
124        assert_eq!(
125            TdPayloadInfoHobType::from(3),
126            TdPayloadInfoHobType::UnknownImage
127        );
128    }
129
130    #[test]
131    fn test_write_u24() {
132        let mut buf: [u8; 3] = [0; 3];
133        write_u24(0xffffff, &mut buf);
134    }
135}