TDISP (TEE Device Interface Security Protocol) Support
Caliptra Subsystem supports handling of TDISP messages by processing them as VENDOR_DEFINED_REQUEST/VENDOR_DEFINED_RESPONSE message payloads. These messages are transported and processed within the secure session established between the host and the TDISP device as specified by Secured CMA/SPDM.
To facilitate the TDISP protocol, devices provide a platform implementation of the TdispDriver trait from caliptra-mcu-spdm-vdm-handler::pci_sig::tdisp. The responder owns the TDISP wire-format handling, command dispatch, and protocol state; the driver supplies device-specific operations such as capabilities, interface state transitions, nonce generation, and interface report contents.
The relevant public driver API is summarized below.
#![allow(unused)] fn main() { #[derive(Clone, Copy, Debug, PartialEq, Eq)] #[repr(u8)] pub enum TdispDriverError { InvalidArgument = 0x01, NoMemory = 0x02, GetTdispCapabilitiesFail = 0x03, GetDeviceInterfaceStateFail = 0x04, LockInterfaceReqFail = 0x05, StartInterfaceReqFail = 0x06, StopInterfaceReqFail = 0x07, GetInterfaceReportFail = 0x08, GetMmioRangesFail = 0x09, FunctionNotImplemented = 0x0A, } pub type TdispDriverResult<T> = Result<T, TdispDriverError>; #[derive(Clone, Copy, Debug, Default, PartialEq, Eq)] pub struct FunctionId(pub u32); #[derive(Clone, Copy, Debug, Default, PartialEq, Eq)] pub struct TdispReqCapabilities { pub tsm_caps: u32, } #[derive(Clone, Copy, Debug, Default, PartialEq, Eq)] pub struct TdispRespCapabilities { pub dsm_capabilities: u32, pub req_msgs_supported: [u8; 16], pub lock_interface_flags_supported: u16, pub dev_addr_width: u8, pub num_req_this: u8, pub num_req_all: u8, } #[derive(Clone, Copy, Debug, Default, PartialEq, Eq)] pub struct TdispLockInterfaceFlags(pub u16); #[derive(Clone, Copy, Debug, Default, PartialEq, Eq)] pub struct TdispLockInterfaceParam { pub flags: TdispLockInterfaceFlags, pub default_stream_id: u8, pub reserved: u8, pub mmio_reporting_offset: [u8; 8], pub bind_p2p_addr_mask: [u8; 8], } #[derive(Clone, Copy, Debug, Default, PartialEq, Eq)] #[repr(u8)] pub enum TdiStatus { #[default] ConfigUnlocked = 0, ConfigLocked = 1, Run = 2, Error = 3, Reserved = 0xff, } #[allow(async_fn_in_trait)] pub trait TdispDriver { /// Fills `out` with a START_INTERFACE nonce. async fn generate_start_interface_nonce<Alloc>( &self, scratch: &Alloc, out: &mut [u8; START_INTERFACE_NONCE_SIZE], ) -> TdispDriverResult<()> where Alloc: SpdmPalAlloc; /// Gets responder capabilities. async fn get_capabilities<Alloc>( &self, req_caps: TdispReqCapabilities, scratch: &Alloc, resp_caps: &mut TdispRespCapabilities, ) -> TdispDriverResult<u32> where Alloc: SpdmPalAlloc; /// Locks an interface. async fn lock_interface<Alloc>( &self, function_id: FunctionId, param: TdispLockInterfaceParam, scratch: &Alloc, ) -> TdispDriverResult<u32> where Alloc: SpdmPalAlloc; /// Returns the total device interface report length. async fn get_device_interface_report_len<Alloc>( &self, function_id: FunctionId, scratch: &Alloc, intf_report_len: &mut u16, ) -> TdispDriverResult<u32> where Alloc: SpdmPalAlloc; /// Copies a device interface report portion. async fn get_device_interface_report<Alloc>( &self, function_id: FunctionId, offset: u16, scratch: &Alloc, report: &mut [u8], copied: &mut usize, ) -> TdispDriverResult<u32> where Alloc: SpdmPalAlloc; /// Gets the current device interface state. async fn get_device_interface_state<Alloc>( &self, function_id: FunctionId, scratch: &Alloc, tdi_state: &mut TdiStatus, ) -> TdispDriverResult<u32> where Alloc: SpdmPalAlloc; /// Starts an interface. async fn start_interface<Alloc>( &self, function_id: FunctionId, scratch: &Alloc, ) -> TdispDriverResult<u32> where Alloc: SpdmPalAlloc; /// Stops an interface. async fn stop_interface<Alloc>( &self, function_id: FunctionId, scratch: &Alloc, ) -> TdispDriverResult<u32> where Alloc: SpdmPalAlloc; } }