From 50ba81738938f3733047653b53cf06606302d10c Mon Sep 17 00:00:00 2001 From: Nicholas Bishop Date: Sat, 9 Nov 2024 15:50:15 -0500 Subject: [PATCH] uefi: Use uefi_raw for the TCG v1 protocol --- uefi/src/proto/tcg/v1.rs | 122 ++++++++------------------------------- 1 file changed, 23 insertions(+), 99 deletions(-) diff --git a/uefi/src/proto/tcg/v1.rs b/uefi/src/proto/tcg/v1.rs index 40ddf6731..801cc7bac 100644 --- a/uefi/src/proto/tcg/v1.rs +++ b/uefi/src/proto/tcg/v1.rs @@ -17,6 +17,7 @@ use core::fmt::{self, Debug, Formatter}; use core::marker::PhantomData; use core::{mem, ptr}; use ptr_meta::Pointee; +use uefi_raw::protocol::tcg::v1::{TcgBootServiceCapability, TcgProtocol}; #[cfg(feature = "alloc")] use {crate::mem::make_boxed, alloc::boxed::Box}; @@ -24,39 +25,29 @@ use {crate::mem::make_boxed, alloc::boxed::Box}; #[cfg(all(feature = "unstable", feature = "alloc"))] use alloc::alloc::Global; +pub use uefi_raw::protocol::tcg::v1::TcgVersion as Version; + /// 20-byte SHA-1 digest. pub type Sha1Digest = [u8; 20]; -/// This corresponds to the `AlgorithmId` enum, but in the v1 spec it's `u32` -/// instead of `u16`. -#[allow(non_camel_case_types)] -type TCG_ALGORITHM_ID = u32; - /// Information about the protocol and the TPM device. /// /// Layout compatible with the C type `TCG_EFI_BOOT_SERVICE_CAPABILITY`. #[repr(C)] #[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Ord, PartialOrd)] -pub struct BootServiceCapability { - size: u8, - structure_version: Version, - protocol_spec_version: Version, - hash_algorithm_bitmap: u8, - tpm_present_flag: u8, - tpm_deactivated_flag: u8, -} +pub struct BootServiceCapability(TcgBootServiceCapability); impl BootServiceCapability { /// Version of the `BootServiceCapability` structure. #[must_use] pub const fn structure_version(&self) -> Version { - self.structure_version + self.0.structure_version } /// Version of the `Tcg` protocol. #[must_use] pub const fn protocol_spec_version(&self) -> Version { - self.protocol_spec_version + self.0.protocol_spec_version } /// Supported hash algorithms. @@ -64,42 +55,22 @@ impl BootServiceCapability { pub fn hash_algorithm(&self) -> HashAlgorithm { // Safety: the value should always be 0x1 (indicating SHA-1), but // we don't care if it's some unexpected value. - HashAlgorithm::from_bits_retain(u32::from(self.hash_algorithm_bitmap)) + HashAlgorithm::from_bits_retain(u32::from(self.0.hash_algorithm_bitmap)) } /// Whether the TPM device is present. #[must_use] pub const fn tpm_present(&self) -> bool { - self.tpm_present_flag != 0 + self.0.tpm_present_flag != 0 } /// Whether the TPM device is deactivated. #[must_use] pub const fn tpm_deactivated(&self) -> bool { - self.tpm_deactivated_flag != 0 + self.0.tpm_deactivated_flag != 0 } } -/// Version information. -/// -/// Layout compatible with the C type `TCG_VERSION`. -#[repr(C)] -#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Ord, PartialOrd)] -pub struct Version { - /// Major version. - pub major: u8, - /// Minor version. - pub minor: u8, - - // Leave these two fields undocumented since it's not clear what - // they are for. The spec doesn't say, and they were removed in the - // v2 spec. - #[allow(missing_docs)] - pub rev_major: u8, - #[allow(missing_docs)] - pub rev_minor: u8, -} - /// Entry in the [`EventLog`]. /// /// Layout compatible with the C type `TCG_PCR_EVENT`. @@ -362,58 +333,9 @@ impl<'a> Iterator for EventLogIter<'a> { /// /// The corresponding C type is `EFI_TCG_PROTOCOL`. #[derive(Debug)] -#[repr(C)] -#[unsafe_protocol("f541796d-a62e-4954-a775-9584f61b9cdd")] -pub struct Tcg { - status_check: unsafe extern "efiapi" fn( - this: *mut Tcg, - protocol_capability: *mut BootServiceCapability, - feature_flags: *mut u32, - event_log_location: *mut PhysicalAddress, - event_log_last_entry: *mut PhysicalAddress, - ) -> Status, - - // Note: we do not currently expose this function because the spec - // for this is not well written. The function allocates memory, but - // the spec doesn't say how to free it. Most likely - // `EFI_BOOT_SERVICES.FreePool` would work, but this is not - // mentioned in the spec so it is unsafe to rely on. - // - // Also, this function is not that useful in practice for a couple - // reasons. First, it takes an algorithm ID, but only SHA-1 is - // supported with TPM v1. Second, TPMs are not cryptographic - // accelerators, so it is very likely faster to calculate the hash - // on the CPU, e.g. with the `sha1` crate. - hash_all: unsafe extern "efiapi" fn() -> Status, - - log_event: unsafe extern "efiapi" fn( - this: *mut Tcg, - // The spec does not guarantee that the `event` will not be mutated - // through the pointer, but it seems reasonable to assume and makes the - // public interface clearer, so use a const pointer. - event: *const FfiPcrEvent, - event_number: *mut u32, - flags: u32, - ) -> Status, - - pass_through_to_tpm: unsafe extern "efiapi" fn( - this: *mut Tcg, - tpm_input_parameter_block_size: u32, - tpm_input_parameter_block: *const u8, - tpm_output_parameter_block_size: u32, - tpm_output_parameter_block: *mut u8, - ) -> Status, - - hash_log_extend_event: unsafe extern "efiapi" fn( - this: *mut Tcg, - hash_data: PhysicalAddress, - hash_data_len: u64, - algorithm_id: TCG_ALGORITHM_ID, - event: *mut FfiPcrEvent, - event_number: *mut u32, - event_log_last_entry: *mut PhysicalAddress, - ) -> Status, -} +#[repr(transparent)] +#[unsafe_protocol(TcgProtocol::GUID)] +pub struct Tcg(TcgProtocol); /// Return type of [`Tcg::status_check`]. #[derive(Debug)] @@ -433,14 +355,14 @@ impl Tcg { /// Get information about the protocol and TPM device, as well as /// the TPM event log. pub fn status_check(&mut self) -> Result { - let mut protocol_capability = BootServiceCapability::default(); + let mut protocol_capability = TcgBootServiceCapability::default(); let mut feature_flags = 0; let mut event_log_location = 0; let mut event_log_last_entry = 0; let status = unsafe { - (self.status_check)( - self, + (self.0.status_check)( + &mut self.0, &mut protocol_capability, &mut feature_flags, &mut event_log_location, @@ -461,7 +383,7 @@ impl Tcg { }; Ok(StatusCheck { - protocol_capability, + protocol_capability: BootServiceCapability(protocol_capability), feature_flags, event_log, }) @@ -487,7 +409,9 @@ impl Tcg { let event_ptr: *const PcrEvent = event; - unsafe { (self.log_event)(self, event_ptr.cast(), &mut event_number, flags).to_result() } + unsafe { + (self.0.log_event)(&mut self.0, event_ptr.cast(), &mut event_number, flags).to_result() + } } /// Extend a PCR and add an entry to the event log. @@ -517,8 +441,8 @@ impl Tcg { let event_ptr: *mut PcrEvent = event; unsafe { - (self.hash_log_extend_event)( - self, + (self.0.hash_log_extend_event)( + &mut self.0, hash_data, hash_data_len, AlgorithmId::SHA1.0.into(), @@ -550,8 +474,8 @@ impl Tcg { .map_err(|_| Error::from(Status::BAD_BUFFER_SIZE))?; unsafe { - (self.pass_through_to_tpm)( - self, + (self.0.pass_through_to_tpm)( + &mut self.0, input_parameter_block_len, input_parameter_block.as_ptr(), output_parameter_block_len,