Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
nicholasbishop committed Nov 5, 2024
1 parent 8a8054c commit 768fd0a
Show file tree
Hide file tree
Showing 6 changed files with 403 additions and 4 deletions.
1 change: 1 addition & 0 deletions uefi-raw/src/protocol/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ pub mod network;
pub mod rng;
pub mod shell_params;
pub mod string;
pub mod tcg;
44 changes: 44 additions & 0 deletions uefi-raw/src/protocol/tcg.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//! [TCG] (Trusted Computing Group) protocols.
//!
//! These protocols provide access to the [TPM][tpm] (Trusted Platform Module).
//!
//! There are two versions of the protocol. The original protocol is in
//! the [`v1`] module. It is used with TPM 1.1 and 1.2 devices. The
//! newer protocol in the [`v2`] module is generally provided for TPM
//! 2.0 devices, although the spec indicates it can be used for older
//! TPM versions as well.
//!
//! [TCG]: https://trustedcomputinggroup.org/
//! [TPM]: https://en.wikipedia.org/wiki/Trusted_Platform_Module

pub mod v1;
pub mod v2;

mod enums;
pub use enums::*;

use bitflags::bitflags;

bitflags! {
/// Hash algorithms the protocol can provide.
///
/// The [`v1`] protocol only supports SHA1.
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
#[repr(transparent)]
pub struct HashAlgorithm: u32 {
/// SHA-1 hash.
const SHA1 = 0x0000_0001;

/// SHA-256 hash.
const SHA256 = 0x0000_0002;

/// SHA-384 hash.
const SHA384 = 0x0000_0004;

/// SHA-512 hash.
const SHA512 = 0x0000_0008;

/// SM3-256 hash.
const SM3_256 = 0x0000_0010;
}
}
75 changes: 75 additions & 0 deletions uefi-raw/src/protocol/tcg/enums.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
newtype_enum! {
/// Algorithm identifiers.
///
/// These values are defined in the [TCG Algorithm Registry].
///
/// [TCG Algorithm Registry]: https://trustedcomputinggroup.org/resource/tcg-algorithm-registry/
pub enum AlgorithmId: u16 => {
ERROR = 0x0000,
RSA = 0x0001,
TDES = 0x0003,
SHA1 = 0x0004,
HMAC = 0x0005,
AES = 0x0006,
MGF1 = 0x0007,
KEYED_HASH = 0x0008,
XOR = 0x000a,
SHA256 = 0x000b,
SHA384 = 0x000c,
SHA512 = 0x000d,
NULL = 0x0010,
SM3_256 = 0x0012,
SM4 = 0x0013,
// TODO: there are a bunch more, but the above list is probably
// more than sufficient for real devices.
}
}

newtype_enum! {
/// Event types stored in the TPM event log. The event type defines
/// which structure type is stored in the event data.
///
/// For details of each variant, see the [TCG PC Client Platform
/// Firmware Protocol Specification][spec], in particular the Events
/// table in the Event Logging chapter.
///
/// [spec]: https://trustedcomputinggroup.org/resource/pc-client-specific-platform-firmware-profile-specification/
pub enum EventType: u32 => {
PREBOOT_CERT = 0x0000_0000,
POST_CODE = 0x0000_0001,
UNUSED = 0x0000_0002,
NO_ACTION = 0x0000_0003,
SEPARATOR = 0x0000_0004,
ACTION = 0x0000_0005,
EVENT_TAG = 0x0000_0006,
CRTM_CONTENTS = 0x0000_0007,
CRTM_VERSION = 0x0000_0008,
CPU_MICROCODE = 0x0000_0009,
PLATFORM_CONFIG_FLAGS = 0x0000_000a,
TABLE_OF_DEVICES = 0x0000_000b,
COMPACT_HASH = 0x0000_000c,
IPL = 0x0000_000d,
IPL_PARTITION_DATA = 0x0000_000e,
NONHOST_CODE = 0x0000_000f,
NONHOST_CONFIG = 0x0000_0010,
NONHOST_INFO = 0x0000_0011,
OMIT_BOOT_DEVICE_EVENTS = 0x0000_0012,
EFI_EVENT_BASE = 0x8000_0000,
EFI_VARIABLE_DRIVER_CONFIG = 0x8000_0001,
EFI_VARIABLE_BOOT = 0x8000_0002,
EFI_BOOT_SERVICES_APPLICATION = 0x8000_0003,
EFI_BOOT_SERVICES_DRIVER = 0x8000_0004,
EFI_RUNTIME_SERVICES_DRIVER = 0x8000_0005,
EFI_GPT_EVENT = 0x8000_0006,
EFI_ACTION = 0x8000_0007,
EFI_PLATFORM_FIRMWARE_BLOB = 0x8000_0008,
EFI_HANDOFF_TABLES = 0x8000_0009,
EFI_PLATFORM_FIRMWARE_BLOB2 = 0x8000_000a,
EFI_HANDOFF_TABLES2 = 0x8000_000b,
EFI_VARIABLE_BOOT2 = 0x8000_000c,
EFI_HCRTM_EVENT = 0x8000_0010,
EFI_VARIABLE_AUTHORITY = 0x8000_00e0,
EFI_SPDM_FIRMWARE_BLOB = 0x8000_00e1,
EFI_SPDM_FIRMWARE_CONFIG = 0x8000_00e2,
}
}
101 changes: 101 additions & 0 deletions uefi-raw/src/protocol/tcg/v1.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
//! [TCG] (Trusted Computing Group) protocol for [TPM] (Trusted Platform
//! Module) 1.1 and 1.2.
//!
//! This protocol is defined in the [TCG EFI Protocol Specification _for
//! TPM Family 1.1 or 1.2_][spec].
//!
//! [spec]: https://trustedcomputinggroup.org/resource/tcg-efi-protocol-specification/
//! [TCG]: https://trustedcomputinggroup.org/
//! [TPM]: https://en.wikipedia.org/wiki/Trusted_Platform_Module

use crate::{guid, Guid, PhysicalAddress, Status};
use core::ffi::c_void;

/// 20-byte SHA-1 digest.
pub type Sha1Digest = [u8; 20];

/// 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 {
pub size: u8,
pub structure_version: Version,
pub protocol_spec_version: Version,
pub hash_algorithm_bitmap: u8,
pub tpm_present_flag: u8,
pub tpm_deactivated_flag: u8,
}

/// 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,

pub rev_major: u8,
pub rev_minor: u8,
}

/// Protocol for interacting with TPM 1.1 and 1.2 devices.
///
/// The corresponding C type is `EFI_TCG_PROTOCOL`.
#[derive(Debug)]
#[repr(C)]
pub struct TcgProtocol {
pub status_check: unsafe extern "efiapi" fn(
this: *mut Self,
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.
pub hash_all: unsafe extern "efiapi" fn() -> Status,

pub log_event: unsafe extern "efiapi" fn(
this: *mut Self,
event: *const c_void,
event_number: *mut u32,
flags: u32,
) -> Status,

pub pass_through_to_tpm: unsafe extern "efiapi" fn(
this: *mut Self,
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,

pub hash_log_extend_event: unsafe extern "efiapi" fn(
this: *mut Self,
hash_data: PhysicalAddress,
hash_data_len: u64,
algorithm_id: u32,
event: *mut c_void,
event_number: *mut u32,
event_log_last_entry: *mut PhysicalAddress,
) -> Status,
}

impl TcgProtocol {
pub const GUID: Guid = guid!("f541796d-a62e-4954-a775-9584f61b9cdd");
}
Loading

0 comments on commit 768fd0a

Please sign in to comment.