From b5581d556bf15bf5e064875ea6ba0d61895e0096 Mon Sep 17 00:00:00 2001 From: Ivan Kuzneczov Date: Mon, 16 Dec 2024 12:44:25 +0000 Subject: [PATCH] drivers/mrc_cache: Measure MRC cache as runtime data MRC cache used to be measured as runtime data when it was resided in CBFS before commit 82aa8338c74 ("drivers/mrc_cache: Always generate an FMAP region"). This patch will restore this behavior for MRC cache stored in FMAP region outside of CBFS. Now, MRC cache will be measured at the end of mrc_cache_load_current(), mrc_cache_current_mmap_leak() and update_mrc_cache_by_type(), to guarantee that a tamper with the memory (like https://badram.eu/ ) will be detected, controlled by Kconfig option TPM_MEASURE_MRC_CACHE. TEST=On Ivy Bridge platforms, Empty MRC cache is not measured. Changing DIMM causes both the old cache and new cache being measured, thus the runtime data measurement is changed, which could be used as an alarm for memory tampering. Starting from the second boot after changing DIMM, the runtime data measurement becomes stable. Signed-off-by: Ivan Kuzneczov Change-Id: I0d82642c24de1b317851d0afd44985195e92c104 Reviewed-on: https://review.coreboot.org/c/coreboot/+/85605 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier --- src/drivers/mrc_cache/mrc_cache.c | 23 +++++++++++++++++++++++ src/security/tpm/Kconfig | 11 +++++++++++ 2 files changed, 34 insertions(+) diff --git a/src/drivers/mrc_cache/mrc_cache.c b/src/drivers/mrc_cache/mrc_cache.c index 17f5fee727..a066fa8f3a 100644 --- a/src/drivers/mrc_cache/mrc_cache.c +++ b/src/drivers/mrc_cache/mrc_cache.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -248,6 +249,19 @@ static int mrc_data_valid(int type, const struct mrc_metadata *md, return 0; } +static tpm_result_t mrc_measure_cache(int type, struct region_device *cache_region) +{ + tpm_result_t rc = TPM_SUCCESS; + char rname[TPM_CB_LOG_PCR_HASH_NAME]; + snprintf(rname, sizeof(rname), "MRC: %s cache", + (type == MRC_VARIABLE_DATA) ? "variable" : "training"); + rc = tpm_measure_region(cache_region, CONFIG_PCR_RUNTIME_DATA, rname); + if (rc) + printk(BIOS_ERR, "MRC: Couldn't measure %s! rc %#x\n", rname, rc); + + return rc; +} + static int mrc_cache_get_latest_slot_info(const char *name, const struct region_device *backing_rdev, struct mrc_metadata *md, @@ -346,6 +360,9 @@ ssize_t mrc_cache_load_current(int type, uint32_t version, void *buffer, if (mrc_data_valid(type, &md, buffer, data_size) < 0) return -1; + if (CONFIG(TPM_MEASURE_MRC_CACHE)) + mrc_measure_cache(type, &rdev); + return data_size; } @@ -373,6 +390,9 @@ void *mrc_cache_current_mmap_leak(int type, uint32_t version, if (mrc_data_valid(type, &md, data, region_device_size) < 0) return NULL; + if (CONFIG(TPM_MEASURE_MRC_CACHE)) + mrc_measure_cache(type, &rdev); + return data; } @@ -509,6 +529,9 @@ static void update_mrc_cache_by_type(int type, hash_idx = cr->tpm_hash_index; if (hash_idx && CONFIG(MRC_SAVE_HASH_IN_TPM)) mrc_cache_update_hash(hash_idx, new_data, new_data_size); + if (CONFIG(TPM_MEASURE_MRC_CACHE) && + !rdev_chain_mem(&read_rdev, new_data, new_data_size)) + mrc_measure_cache(type, &read_rdev); } } diff --git a/src/security/tpm/Kconfig b/src/security/tpm/Kconfig index 377d6dcb88..c8eb446839 100644 --- a/src/security/tpm/Kconfig +++ b/src/security/tpm/Kconfig @@ -78,6 +78,17 @@ config TPM_MEASURED_BOOT help Enables measured boot (experimental) +config TPM_MEASURE_MRC_CACHE + bool "Measure MRC cache" + default n + depends on TPM_MEASURED_BOOT + depends on CACHE_MRC_SETTINGS + help + Measures MRC cache as runtime data to guarantee that a + tamper with the memory will be detected. The runtime data + measurement becomes stable after the second boot after + changing DIMM. + choice prompt "TPM event log format" depends on TPM_MEASURED_BOOT