aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib/cbfs.c47
-rw-r--r--src/security/tpm/tspi.h2
-rw-r--r--src/security/tpm/tspi/crtm.c57
-rw-r--r--src/security/tpm/tspi/crtm.h16
-rw-r--r--src/security/tpm/tspi/tspi.c34
5 files changed, 59 insertions, 97 deletions
diff --git a/src/lib/cbfs.c b/src/lib/cbfs.c
index b4b6eb1324..0b5891378d 100644
--- a/src/lib/cbfs.c
+++ b/src/lib/cbfs.c
@@ -81,10 +81,6 @@ cb_err_t _cbfs_boot_lookup(const char *name, bool force_ro,
if (rdev_chain(rdev, &cbd->rdev, data_offset, be32toh(mdata->h.len)))
return CB_ERR;
- if (tspi_measure_cbfs_hook(rdev, name, be32toh(mdata->h.type))) {
- printk(BIOS_ERR, "CBFS ERROR: error when measuring '%s'\n", name);
- }
-
return CB_SUCCESS;
}
@@ -134,9 +130,8 @@ int cbfs_locate_file_in_region(struct cbfsf *fh, const char *region_name,
type = &dummy_type;
ret = cbfs_locate(fh, &rdev, name, type);
- if (!ret)
- if (tspi_measure_cbfs_hook(&rdev, name, *type))
- LOG("error measuring %s in region %s\n", name, region_name);
+ /* No more measuring here, this function will be removed next patch. */
+
return ret;
}
@@ -193,19 +188,36 @@ static inline bool cbfs_lzma_enabled(void)
static bool cbfs_file_hash_mismatch(const void *buffer, size_t size,
const union cbfs_mdata *mdata, bool skip_verification)
{
- /* Avoid linking hash functions when verification is disabled. */
- if (!CONFIG(CBFS_VERIFICATION) || skip_verification)
+ /* Avoid linking hash functions when verification and measurement are disabled. */
+ if (!CONFIG(CBFS_VERIFICATION) && !CONFIG(TPM_MEASURED_BOOT))
return false;
- const struct vb2_hash *hash = cbfs_file_hash(mdata);
- if (!hash) {
- ERROR("'%s' does not have a file hash!\n", mdata->h.filename);
- return true;
+ const struct vb2_hash *hash = NULL;
+
+ if (CONFIG(CBFS_VERIFICATION) && !skip_verification) {
+ hash = cbfs_file_hash(mdata);
+ if (!hash) {
+ ERROR("'%s' does not have a file hash!\n", mdata->h.filename);
+ return true;
+ }
+ if (vb2_hash_verify(buffer, size, hash) != VB2_SUCCESS) {
+ ERROR("'%s' file hash mismatch!\n", mdata->h.filename);
+ return true;
+ }
}
- if (vb2_hash_verify(buffer, size, hash) != VB2_SUCCESS) {
- ERROR("'%s' file hash mismatch!\n", mdata->h.filename);
- return true;
+ if (CONFIG(TPM_MEASURED_BOOT) && !ENV_SMM) {
+ struct vb2_hash calculated_hash;
+
+ /* No need to re-hash file if we already have it from verification. */
+ if (!hash || hash->algo != TPM_MEASURE_ALGO) {
+ vb2_hash_calculate(buffer, size, TPM_MEASURE_ALGO, &calculated_hash);
+ hash = &calculated_hash;
+ }
+
+ if (tspi_cbfs_measurement(mdata->h.filename, be32toh(mdata->h.type), hash))
+ ERROR("failed to measure '%s' into TCPA log\n", mdata->h.filename);
+ /* We intentionally continue to boot on measurement errors. */
}
return false;
@@ -528,9 +540,6 @@ void *_cbfs_unverified_area_alloc(const char *area, const char *name,
if (rdev_chain(&file_rdev, &area_rdev, data_offset, be32toh(mdata.h.len)))
return NULL;
- if (tspi_measure_cbfs_hook(&file_rdev, name, be32toh(mdata.h.type)))
- ERROR("error measuring '%s' in '%s'\n", name, area);
-
return do_alloc(&mdata, &file_rdev, allocator, arg, size_out, true);
}
diff --git a/src/security/tpm/tspi.h b/src/security/tpm/tspi.h
index ed642c33b5..7157b4d730 100644
--- a/src/security/tpm/tspi.h
+++ b/src/security/tpm/tspi.h
@@ -51,7 +51,7 @@ void tcpa_log_dump(void *unused);
* @return TPM_SUCCESS on success. If not a tpm error is returned
*/
uint32_t tpm_extend_pcr(int pcr, enum vb2_hash_algorithm digest_algo,
- uint8_t *digest, size_t digest_len,
+ const uint8_t *digest, size_t digest_len,
const char *name);
/**
diff --git a/src/security/tpm/tspi/crtm.c b/src/security/tpm/tspi/crtm.c
index b64bbbf6c6..8cd0793779 100644
--- a/src/security/tpm/tspi/crtm.c
+++ b/src/security/tpm/tspi/crtm.c
@@ -6,37 +6,6 @@
#include "crtm.h"
#include <string.h>
-/*
- * This function sets the TCPA log namespace
- * for the cbfs file (region) lookup.
- */
-static int create_tcpa_metadata(const struct region_device *rdev,
- const char *cbfs_name, char log_string[TCPA_PCR_HASH_NAME])
-{
- int i;
- struct region_device fmap;
- static const char *const fmap_cbfs_names[] = {
- "COREBOOT",
- "FW_MAIN_A",
- "FW_MAIN_B",
- "RW_LEGACY"
- };
-
- for (i = 0; i < ARRAY_SIZE(fmap_cbfs_names); i++) {
- if (fmap_locate_area_as_rdev(fmap_cbfs_names[i], &fmap) == 0) {
- if (region_is_subregion(region_device_region(&fmap),
- region_device_region(rdev))) {
- snprintf(log_string, TCPA_PCR_HASH_NAME,
- "FMAP: %s CBFS: %s",
- fmap_cbfs_names[i], cbfs_name);
- return 0;
- }
- }
- }
-
- return -1;
-}
-
static int tcpa_log_initialized;
static inline int tcpa_log_available(void)
{
@@ -64,8 +33,6 @@ static inline int tcpa_log_available(void)
*/
static uint32_t tspi_init_crtm(void)
{
- struct prog bootblock = PROG_INIT(PROG_BOOTBLOCK, "bootblock");
-
/* Initialize TCPA PRERAM log. */
if (!tcpa_log_available()) {
tcpa_preram_log_clear();
@@ -87,7 +54,6 @@ static uint32_t tspi_init_crtm(void)
}
/* measure bootblock from RO */
- struct cbfsf bootblock_data;
struct region_device bootblock_fmap;
if (fmap_locate_area_as_rdev("BOOTBLOCK", &bootblock_fmap) == 0) {
if (tpm_measure_region(&bootblock_fmap,
@@ -95,16 +61,16 @@ static uint32_t tspi_init_crtm(void)
"FMAP: BOOTBLOCK"))
return VB2_ERROR_UNKNOWN;
} else {
- if (cbfs_boot_locate(&bootblock_data,
- prog_name(&bootblock), NULL)) {
- /*
- * measurement is done in
- * tspi_measure_cbfs_hook()
- */
+ /* Mapping measures the file. We know we can safely map here because
+ bootblock-as-a-file is only used on x86, where we don't need cache to map. */
+ enum cbfs_type type = CBFS_TYPE_BOOTBLOCK;
+ void *mapping = cbfs_ro_type_map("bootblock", NULL, &type);
+ if (!mapping) {
printk(BIOS_INFO,
"TSPI: Couldn't measure bootblock into CRTM!\n");
return VB2_ERROR_UNKNOWN;
}
+ cbfs_unmap(mapping);
}
return VB2_SUCCESS;
@@ -129,8 +95,7 @@ static bool is_runtime_data(const char *name)
return !strcmp(allowlist, name);
}
-uint32_t tspi_measure_cbfs_hook(const struct region_device *rdev, const char *name,
- uint32_t cbfs_type)
+uint32_t tspi_cbfs_measurement(const char *name, uint32_t type, const struct vb2_hash *hash)
{
uint32_t pcr_index;
char tcpa_metadata[TCPA_PCR_HASH_NAME];
@@ -144,7 +109,7 @@ uint32_t tspi_measure_cbfs_hook(const struct region_device *rdev, const char *na
printk(BIOS_DEBUG, "CRTM initialized.\n");
}
- switch (cbfs_type) {
+ switch (type) {
case CBFS_TYPE_MRC_CACHE:
pcr_index = TPM_RUNTIME_DATA_PCR;
break;
@@ -166,10 +131,10 @@ uint32_t tspi_measure_cbfs_hook(const struct region_device *rdev, const char *na
break;
}
- if (create_tcpa_metadata(rdev, name, tcpa_metadata) < 0)
- return VB2_ERROR_UNKNOWN;
+ snprintf(tcpa_metadata, TCPA_PCR_HASH_NAME, "CBFS: %s", name);
- return tpm_measure_region(rdev, pcr_index, tcpa_metadata);
+ return tpm_extend_pcr(pcr_index, hash->algo, hash->raw, vb2_digest_size(hash->algo),
+ tcpa_metadata);
}
int tspi_measure_cache_to_pcr(void)
diff --git a/src/security/tpm/tspi/crtm.h b/src/security/tpm/tspi/crtm.h
index 011fa26ad7..8ebb661130 100644
--- a/src/security/tpm/tspi/crtm.h
+++ b/src/security/tpm/tspi/crtm.h
@@ -7,6 +7,7 @@
#include <program_loading.h>
#include <security/tpm/tspi.h>
#include <types.h>
+#include <vb2_sha.h>
/* CRTM */
#define TPM_CRTM_PCR 2
@@ -16,21 +17,16 @@
*/
#define TPM_RUNTIME_DATA_PCR 3
+#define TPM_MEASURE_ALGO (CONFIG(TPM1) ? VB2_HASH_SHA1 : VB2_HASH_SHA256)
+
/**
* Measure digests cached in TCPA log entries into PCRs
*/
int tspi_measure_cache_to_pcr(void);
-#if !ENV_SMM && CONFIG(TPM_MEASURED_BOOT)
-/*
- * Measures cbfs data via hook (cbfs)
- * rdev covers the file data (not metadata)
- * return 0 if successful, else an error
+/**
+ * Extend a measurement hash taken for a CBFS file into the appropriate PCR.
*/
-uint32_t tspi_measure_cbfs_hook(const struct region_device *rdev,
- const char *name, uint32_t cbfs_type);
-#else
-#define tspi_measure_cbfs_hook(rdev, name, cbfs_type) 0
-#endif
+uint32_t tspi_cbfs_measurement(const char *name, uint32_t type, const struct vb2_hash *hash);
#endif /* __SECURITY_TSPI_CRTM_H__ */
diff --git a/src/security/tpm/tspi/tspi.c b/src/security/tpm/tspi/tspi.c
index b1bea4160d..e2d6d1e56e 100644
--- a/src/security/tpm/tspi/tspi.c
+++ b/src/security/tpm/tspi/tspi.c
@@ -220,7 +220,7 @@ uint32_t tpm_clear_and_reenable(void)
}
uint32_t tpm_extend_pcr(int pcr, enum vb2_hash_algorithm digest_algo,
- uint8_t *digest, size_t digest_len, const char *name)
+ const uint8_t *digest, size_t digest_len, const char *name)
{
uint32_t result;
@@ -234,16 +234,22 @@ uint32_t tpm_extend_pcr(int pcr, enum vb2_hash_algorithm digest_algo,
return result;
}
- printk(BIOS_DEBUG, "TPM: Extending digest for %s into PCR %d\n", name, pcr);
+ printk(BIOS_DEBUG, "TPM: Extending digest for `%s` into PCR %d\n", name, pcr);
result = tlcl_extend(pcr, digest, NULL);
- if (result != TPM_SUCCESS)
+ if (result != TPM_SUCCESS) {
+ printk(BIOS_ERR, "TPM: Extending hash for `%s` into PCR %d failed.\n",
+ name, pcr);
return result;
+ }
}
if (CONFIG(TPM_MEASURED_BOOT))
tcpa_log_add_table_entry(name, pcr, digest_algo,
digest, digest_len);
+ printk(BIOS_DEBUG, "TPM: Digest of `%s` to PCR %d %s\n",
+ name, pcr, tspi_tpm_is_setup() ? "measured" : "logged");
+
return TPM_SUCCESS;
}
@@ -253,23 +259,16 @@ uint32_t tpm_measure_region(const struct region_device *rdev, uint8_t pcr,
{
uint8_t digest[TPM_PCR_MAX_LEN], digest_len;
uint8_t buf[HASH_DATA_CHUNK_SIZE];
- uint32_t result, offset;
+ uint32_t offset;
size_t len;
struct vb2_digest_context ctx;
- enum vb2_hash_algorithm hash_alg;
if (!rdev || !rname)
return TPM_E_INVALID_ARG;
- if (CONFIG(TPM1)) {
- hash_alg = VB2_HASH_SHA1;
- } else { /* CONFIG_TPM2 */
- hash_alg = VB2_HASH_SHA256;
- }
-
- digest_len = vb2_digest_size(hash_alg);
+ digest_len = vb2_digest_size(TPM_MEASURE_ALGO);
assert(digest_len <= sizeof(digest));
- if (vb2_digest_init(&ctx, hash_alg)) {
+ if (vb2_digest_init(&ctx, TPM_MEASURE_ALGO)) {
printk(BIOS_ERR, "TPM: Error initializing hash.\n");
return TPM_E_HASH_ERROR;
}
@@ -294,13 +293,6 @@ uint32_t tpm_measure_region(const struct region_device *rdev, uint8_t pcr,
printk(BIOS_ERR, "TPM: Error finalizing hash.\n");
return TPM_E_HASH_ERROR;
}
- result = tpm_extend_pcr(pcr, hash_alg, digest, digest_len, rname);
- if (result != TPM_SUCCESS) {
- printk(BIOS_ERR, "TPM: Extending hash into PCR failed.\n");
- return result;
- }
- printk(BIOS_DEBUG, "TPM: Digest of %s to PCR %d %s\n",
- rname, pcr, tspi_tpm_is_setup() ? "measured" : "logged");
- return TPM_SUCCESS;
+ return tpm_extend_pcr(pcr, TPM_MEASURE_ALGO, digest, digest_len, rname);
}
#endif /* VBOOT_LIB */