diff options
author | Vadim Bendebury <vbendeb@chromium.org> | 2022-11-22 20:31:36 -0800 |
---|---|---|
committer | Chromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2022-12-01 17:39:53 +0000 |
commit | 06cbffbe5bbc289ccd41d70f9e6a013f4d23a634 (patch) | |
tree | 8df9fa5018e2f8b4e784a4fa48dd905f5f46b391 | |
parent | 68d9ba190fe8a68f8cdd0fb0e20a38433def1984 (diff) | |
download | vboot-06cbffbe5bbc289ccd41d70f9e6a013f4d23a634.tar.gz |
futility: try ignoring GBB flags when validating GSCVD
GBB flags contents are ignored when AP RO ranges hash is calculated.
The embedded verification will succeed only if the flags are cleared,
but the command line tool should not fail because of nonzero GBB
flags.
This patch adds add additional pass when validating to see if
validation succeeds with GBB flags zeroed.
Also adding a debug printout to allow the user to see ranges covered
by the signature when validating an image and modifying the tests to
accommodate passing when GBB flags are non-zero.
BRANCH=none
BUG=none
TEST=successfully validated AP RO signature with the same image with
and without cleared gbb flags. When checking the image with
nonzero flags the 'Ranges digest matches with zeroed GBB flags'
warning message is printed.
invoking 'make runtests' succeeds.
Signed-off-by: Vadim Bendebury <vbendeb@chromium.org>
Change-Id: I3e38924f14697a3efd058286f9579d89e5161910
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/4049934
Commit-Queue: Yu-Ping Wu <yupingso@chromium.org>
Reviewed-by: Yu-Ping Wu <yupingso@chromium.org>
-rw-r--r-- | futility/cmd_gscvd.c | 46 | ||||
-rwxr-xr-x | tests/futility/test_gscvd.sh | 19 |
2 files changed, 50 insertions, 15 deletions
diff --git a/futility/cmd_gscvd.c b/futility/cmd_gscvd.c index 5d860452..e68faf9c 100644 --- a/futility/cmd_gscvd.c +++ b/futility/cmd_gscvd.c @@ -474,6 +474,8 @@ static vb2_error_t extend_digest(const struct file_buf *ap_firmware_file, /* Define it as array to simplify calling vb2_digest_extend() below. */ const uint8_t flags[sizeof(vb2_gbb_flags_t)] = {0}; + VB2_DEBUG("%s: %#x..+%#x\n", __func__, offset, size); + if (flags_offset && (flags_offset >= offset) && (flags_offset < (offset + size))) { @@ -993,6 +995,29 @@ static void try_retrieving_ranges_from_the_image(const char *file_name, } /* + * Calculate ranges digest and compare it with the value stored in gvd, with + * or without ignoring GBB flags, as requested by the caller. + * + * @return zero on success, nonzero on failure. + */ +static int validate_digest(struct file_buf *ap_firmware_file, + const struct gscvd_ro_ranges *ranges, + const struct gsc_verification_data *gvd, + bool override_gbb_flags) +{ + uint8_t digest[sizeof(gvd->ranges_digest)]; + + if (calculate_ranges_digest(ap_firmware_file, ranges, + gvd->hash_alg, digest, + sizeof(digest), + override_gbb_flags)) { + return 1; + } + + return memcmp(digest, gvd->ranges_digest, sizeof(digest)); +} + +/* * Validate GVD of the passed in AP firmware file and possibly the root key hash * * The input parameters are the subset of the command line, the first argv @@ -1000,7 +1025,7 @@ static void try_retrieving_ranges_from_the_image(const char *file_name, * hash of the root public key included in the RO_GSCVD area of the AP * firmware file. * - * @return zero on success, -1 on failure. + * @return zero on success, nonzero on failure. */ static int validate_gscvd(int argc, char *argv[]) { @@ -1009,7 +1034,6 @@ static int validate_gscvd(int argc, char *argv[]) struct gscvd_ro_ranges ranges; struct gsc_verification_data *gvd; const char *file_name; - uint8_t digest[sizeof(gvd->ranges_digest)]; struct vb2_hash root_key_digest = { .algo = VB2_HASH_SHA256 }; /* Guaranteed to be available. */ @@ -1039,15 +1063,15 @@ static int validate_gscvd(int argc, char *argv[]) if (copy_ranges(&ap_firmware_file, gvd, &ranges)) break; - if (calculate_ranges_digest(&ap_firmware_file, &ranges, - gvd->hash_alg, digest, - sizeof(digest), - false)) - break; - - if (memcmp(digest, gvd->ranges_digest, sizeof(digest))) { - ERROR("Ranges digest mismatch\n"); - break; + /* First try validating without ignoring GBB flags. */ + if (validate_digest(&ap_firmware_file, &ranges, gvd, false)) { + /* It failed, maybe GBB flags are not cleared yet. */ + if (validate_digest(&ap_firmware_file, &ranges, + gvd, true)) { + ERROR("Ranges digest mismatch\n"); + break; + } + WARN("Ranges digest matches with zeroed GBB flags\n"); } /* Find the keyblock. */ diff --git a/tests/futility/test_gscvd.sh b/tests/futility/test_gscvd.sh index 54d48479..d489437f 100755 --- a/tests/futility/test_gscvd.sh +++ b/tests/futility/test_gscvd.sh @@ -28,10 +28,12 @@ FMAP_OFFSET_K=28696 main() { local bios_blob local command_args + local warn local fmap_blob local hwid local pubkhash local section + local stderr_output cd "${SCRIPT_DIR}/futility" @@ -72,10 +74,19 @@ main() { pubkhash="$( "${FUTILITY}" gscvd --root_pub_key \ "${KEYS_DIR}"/arv_root.vbpubk | tail -1)" - # Run verification, this one is expected to fail because GBB flags are not - # zero. - if "${FUTILITY}" gscvd "${bios_blob}" "${pubkhash}" 2>/dev/null ; then - echo "Unexpected signature match!" >&2 + # Message printed on stderr in case signature matches only after zeroing GBB + # flags. + warn="WARNING: validate_gscvd: Ranges digest matches with zeroed GBB flags" + + # Run verification, this one is expected to succeed but report GBB flags + # mismatch. + stderr_output=$("${FUTILITY}" gscvd "${bios_blob}" "${pubkhash}" 2>&1) + if [[ $? != 0 ]] ; then + echo "Unexpected failure with nonzero GBB!" >&2 + exit 1 + fi + if [[ ${stderr_output} != "${warn}" ]]; then + echo "Unexpected error message \"${stderr_output}\" with nonzero GBB!" exit 1 fi |