|
1 | 1 | use crate::utils; |
2 | 2 | use anyhow::{Context, Result}; |
3 | 3 | use uefi::boot::ScopedProtocol; |
4 | | -use uefi::proto::tcg::v2::Tcg; |
5 | | -use uefi_raw::protocol::tcg::v2::{Tcg2Protocol, Tcg2Version}; |
| 4 | +use uefi::proto::tcg::PcrIndex; |
| 5 | +use uefi::proto::tcg::v2::{PcrEventInputs, Tcg}; |
| 6 | +use uefi_raw::protocol::tcg::EventType; |
| 7 | +use uefi_raw::protocol::tcg::v2::{Tcg2HashLogExtendEventFlags, Tcg2Protocol, Tcg2Version}; |
6 | 8 |
|
7 | 9 | /// Represents the platform TPM. |
8 | 10 | pub struct PlatformTpm; |
@@ -33,6 +35,9 @@ impl TpmProtocolHandle { |
33 | 35 | } |
34 | 36 |
|
35 | 37 | impl PlatformTpm { |
| 38 | + /// The PCR for measuring the bootloader configuration into. |
| 39 | + pub const PCR_BOOT_LOADER_CONFIG: PcrIndex = PcrIndex(5); |
| 40 | + |
36 | 41 | /// Acquire access to the TPM protocol handle, if possible. |
37 | 42 | /// Returns None if TPM is not available. |
38 | 43 | fn protocol() -> Result<Option<TpmProtocolHandle>> { |
@@ -93,4 +98,32 @@ impl PlatformTpm { |
93 | 98 | // Return the number of active PCR banks. |
94 | 99 | Ok(banks.bits()) |
95 | 100 | } |
| 101 | + |
| 102 | + /// Log an event into the TPM pcr `pcr_index` with `buffer` as data. The `description` |
| 103 | + /// is used to describe what the event is. |
| 104 | + /// |
| 105 | + /// If a TPM is not available, this will do nothing. |
| 106 | + pub fn log_event(pcr_index: PcrIndex, buffer: &[u8], description: &str) -> Result<()> { |
| 107 | + // Acquire access to the TPM protocol handle. |
| 108 | + let Some(mut handle) = PlatformTpm::protocol()? else { |
| 109 | + return Ok(()); |
| 110 | + }; |
| 111 | + |
| 112 | + // Encode the description as a UTF-16 little endian string. |
| 113 | + let description = description |
| 114 | + .encode_utf16() |
| 115 | + .flat_map(|c| c.to_le_bytes()) |
| 116 | + .collect::<Vec<u8>>(); |
| 117 | + |
| 118 | + // Construct an event input for the TPM. |
| 119 | + let event = PcrEventInputs::new_in_box(pcr_index, EventType::IPL, &description) |
| 120 | + .context("unable to construct pcr event inputs")?; |
| 121 | + |
| 122 | + // Log the event into the TPM. |
| 123 | + handle |
| 124 | + .protocol() |
| 125 | + .hash_log_extend_event(Tcg2HashLogExtendEventFlags::empty(), buffer, &event) |
| 126 | + .context("unable to log event to tpm")?; |
| 127 | + Ok(()) |
| 128 | + } |
96 | 129 | } |
0 commit comments