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 82aa8338c7 ("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 <ivan.kuzneczov@hardenedvault.net>
Change-Id: I0d82642c24de1b317851d0afd44985195e92c104
Reviewed-on: https://review.coreboot.org/c/coreboot/+/85605
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Matt DeVillier <matt.devillier@gmail.com>
This commit is contained in:
Ivan Kuzneczov 2024-12-16 12:44:25 +00:00 committed by Matt DeVillier
commit b5581d556b
2 changed files with 34 additions and 0 deletions

View file

@ -9,6 +9,7 @@
#include <elog.h>
#include <fmap.h>
#include <region_file.h>
#include <security/tpm/tspi.h>
#include <security/vboot/antirollback.h>
#include <security/vboot/mrc_cache_hash_tpm.h>
#include <security/vboot/vboot_common.h>
@ -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);
}
}

View file

@ -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