summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.inc7
-rw-r--r--util/cbfstool/cbfstool.c37
2 files changed, 36 insertions, 8 deletions
diff --git a/Makefile.inc b/Makefile.inc
index da1458a1e532..91c32ffe1b41 100644
--- a/Makefile.inc
+++ b/Makefile.inc
@@ -1162,6 +1162,13 @@ endif # CONFIG_CPU_INTEL_FIRMWARE_INTERFACE_TABLE
$(CBFSTOOL) $@ layout
@printf " CBFSPRINT $(subst $(obj)/,,$(@))\n\n"
$(CBFSTOOL) $@ print -r $(subst $(spc),$(comma),$(all-regions))
+ifeq ($(CONFIG_CBFS_VERIFICATION),y)
+ line=$$($(CBFSTOOL) $@ print -kv 2>/dev/null | grep -F '[CBFS VERIFICATION (COREBOOT)]') ;\
+ if ! printf "$$line" | grep -q 'fully valid'; then \
+ echo "CBFS verification error: $$line" ;\
+ exit 1 ;\
+ fi
+endif # CONFIG_CBFS_VERIFICATION
cbfs-files-y += $(CONFIG_CBFS_PREFIX)/romstage
$(CONFIG_CBFS_PREFIX)/romstage-file := $(objcbfs)/romstage.elf
diff --git a/util/cbfstool/cbfstool.c b/util/cbfstool/cbfstool.c
index 71c8911ede21..ff10131e4744 100644
--- a/util/cbfstool/cbfstool.c
+++ b/util/cbfstool/cbfstool.c
@@ -1499,6 +1499,23 @@ static int cbfs_layout(void)
return 0;
}
+static enum cb_err verify_walker(__unused cbfs_dev_t dev, size_t offset,
+ const union cbfs_mdata *mdata, size_t already_read, void *arg)
+{
+ uint32_t type = be32toh(mdata->h.type);
+ uint32_t data_offset = be32toh(mdata->h.offset);
+ if (verification_exclude(type))
+ return CB_CBFS_NOT_FOUND;
+ assert(already_read == data_offset);
+ const struct vb2_hash *hash = cbfs_file_hash(mdata);
+ if (!hash)
+ return CB_ERR;
+ void *file_data = arg + offset + data_offset;
+ if (vb2_hash_verify(file_data, be32toh(mdata->h.len), hash) != VB2_SUCCESS)
+ return CB_CBFS_HASH_MISMATCH;
+ return CB_CBFS_NOT_FOUND;
+}
+
static int cbfs_print(void)
{
struct cbfs_image image;
@@ -1515,29 +1532,33 @@ static int cbfs_print(void)
}
if (verbose) {
+ const char *verification_state = "fully valid";
struct mh_cache *mhc = get_mh_cache();
if (mhc->cbfs_hash.algo == VB2_HASH_INVALID)
return 0;
struct vb2_hash real_hash = { .algo = mhc->cbfs_hash.algo };
- enum cb_err err = cbfs_walk(&image, NULL, NULL, &real_hash,
- CBFS_WALK_WRITEBACK_HASH);
- if (err != CB_CBFS_NOT_FOUND) {
- ERROR("Unexpected cbfs_walk() error %d\n", err);
- return 1;
- }
+ enum cb_err err = cbfs_walk(&image, verify_walker, buffer_get(&image.buffer),
+ &real_hash, CBFS_WALK_WRITEBACK_HASH);
+ if (err == CB_CBFS_HASH_MISMATCH)
+ verification_state = "invalid file hashes";
+ else if (err != CB_CBFS_NOT_FOUND)
+ verification_state = "missing file hashes";
char *hash_str = bintohex(real_hash.raw,
vb2_digest_size(real_hash.algo));
printf("[METADATA HASH]\t%s:%s",
vb2_get_hash_algorithm_name(real_hash.algo), hash_str);
if (!strcmp(param.region_name, SECTION_NAME_PRIMARY_CBFS)) {
if (!memcmp(mhc->cbfs_hash.raw, real_hash.raw,
- vb2_digest_size(real_hash.algo)))
+ vb2_digest_size(real_hash.algo))) {
printf(":valid");
- else
+ } else {
printf(":invalid");
+ verification_state = "invalid metadata hash";
+ }
}
printf("\n");
+ printf("[CBFS VERIFICATION (%s)]\t%s\n", param.region_name, verification_state);
free(hash_str);
}