mirror of
https://github.com/edera-dev/sprout.git
synced 2025-12-19 15:50:18 +00:00
feat(tpm): implement basic measurement of the bootloader configuration
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
use crate::config::{RootConfiguration, latest_version};
|
use crate::config::{RootConfiguration, latest_version};
|
||||||
use crate::options::SproutOptions;
|
use crate::options::SproutOptions;
|
||||||
|
use crate::platform::tpm::PlatformTpm;
|
||||||
use crate::utils;
|
use crate::utils;
|
||||||
use anyhow::{Context, Result, bail};
|
use anyhow::{Context, Result, bail};
|
||||||
use log::info;
|
use log::info;
|
||||||
@@ -21,6 +22,11 @@ fn load_raw_config(options: &SproutOptions) -> Result<Vec<u8>> {
|
|||||||
// Read the contents of the sprout config file.
|
// Read the contents of the sprout config file.
|
||||||
let content = utils::read_file_contents(Some(&path), &options.config)
|
let content = utils::read_file_contents(Some(&path), &options.config)
|
||||||
.context("unable to read sprout config file")?;
|
.context("unable to read sprout config file")?;
|
||||||
|
|
||||||
|
// Measure the sprout.toml into the TPM, if needed and possible.
|
||||||
|
PlatformTpm::log_event(PlatformTpm::PCR_BOOT_LOADER_CONFIG, &content, "sprout.toml")
|
||||||
|
.context("unable to measure the sprout.toml file into the TPM")?;
|
||||||
|
|
||||||
// Return the contents of the sprout config file.
|
// Return the contents of the sprout config file.
|
||||||
Ok(content)
|
Ok(content)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
use crate::utils;
|
use crate::utils;
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{Context, Result};
|
||||||
use uefi::boot::ScopedProtocol;
|
use uefi::boot::ScopedProtocol;
|
||||||
use uefi::proto::tcg::v2::Tcg;
|
use uefi::proto::tcg::PcrIndex;
|
||||||
use uefi_raw::protocol::tcg::v2::{Tcg2Protocol, Tcg2Version};
|
use uefi::proto::tcg::v2::{PcrEventInputs, Tcg};
|
||||||
|
use uefi_raw::protocol::tcg::EventType;
|
||||||
|
use uefi_raw::protocol::tcg::v2::{Tcg2HashLogExtendEventFlags, Tcg2Protocol, Tcg2Version};
|
||||||
|
|
||||||
/// Represents the platform TPM.
|
/// Represents the platform TPM.
|
||||||
pub struct PlatformTpm;
|
pub struct PlatformTpm;
|
||||||
@@ -33,6 +35,9 @@ impl TpmProtocolHandle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl PlatformTpm {
|
impl PlatformTpm {
|
||||||
|
/// The PCR for measuring the bootloader configuration into.
|
||||||
|
pub const PCR_BOOT_LOADER_CONFIG: PcrIndex = PcrIndex(5);
|
||||||
|
|
||||||
/// Acquire access to the TPM protocol handle, if possible.
|
/// Acquire access to the TPM protocol handle, if possible.
|
||||||
/// Returns None if TPM is not available.
|
/// Returns None if TPM is not available.
|
||||||
fn protocol() -> Result<Option<TpmProtocolHandle>> {
|
fn protocol() -> Result<Option<TpmProtocolHandle>> {
|
||||||
@@ -93,4 +98,32 @@ impl PlatformTpm {
|
|||||||
// Return the number of active PCR banks.
|
// Return the number of active PCR banks.
|
||||||
Ok(banks.bits())
|
Ok(banks.bits())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Log an event into the TPM pcr `pcr_index` with `buffer` as data. The `description`
|
||||||
|
/// is used to describe what the event is.
|
||||||
|
///
|
||||||
|
/// If a TPM is not available, this will do nothing.
|
||||||
|
pub fn log_event(pcr_index: PcrIndex, buffer: &[u8], description: &str) -> Result<()> {
|
||||||
|
// Acquire access to the TPM protocol handle.
|
||||||
|
let Some(mut handle) = PlatformTpm::protocol()? else {
|
||||||
|
return Ok(());
|
||||||
|
};
|
||||||
|
|
||||||
|
// Encode the description as a UTF-16 little endian string.
|
||||||
|
let description = description
|
||||||
|
.encode_utf16()
|
||||||
|
.flat_map(|c| c.to_le_bytes())
|
||||||
|
.collect::<Vec<u8>>();
|
||||||
|
|
||||||
|
// Construct an event input for the TPM.
|
||||||
|
let event = PcrEventInputs::new_in_box(pcr_index, EventType::IPL, &description)
|
||||||
|
.context("unable to construct pcr event inputs")?;
|
||||||
|
|
||||||
|
// Log the event into the TPM.
|
||||||
|
handle
|
||||||
|
.protocol()
|
||||||
|
.hash_log_extend_event(Tcg2HashLogExtendEventFlags::empty(), buffer, &event)
|
||||||
|
.context("unable to log event to tpm")?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user