Skip to content

Commit

Permalink
uefi: Use uefi_raw for the TCG v1 protocol
Browse files Browse the repository at this point in the history
  • Loading branch information
nicholasbishop committed Nov 9, 2024
1 parent 32b148f commit 50ba817
Showing 1 changed file with 23 additions and 99 deletions.
122 changes: 23 additions & 99 deletions uefi/src/proto/tcg/v1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,89 +17,60 @@ 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};

#[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.
#[must_use]
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`.
Expand Down Expand Up @@ -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)]
Expand All @@ -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<StatusCheck> {
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,
Expand All @@ -461,7 +383,7 @@ impl Tcg {
};

Ok(StatusCheck {
protocol_capability,
protocol_capability: BootServiceCapability(protocol_capability),
feature_flags,
event_log,
})
Expand All @@ -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.
Expand Down Expand Up @@ -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(),
Expand Down Expand Up @@ -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,
Expand Down

0 comments on commit 50ba817

Please sign in to comment.