summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVadim Bendebury <vbendeb@chromium.org>2022-11-22 20:31:36 -0800
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2022-12-01 17:39:53 +0000
commit06cbffbe5bbc289ccd41d70f9e6a013f4d23a634 (patch)
tree8df9fa5018e2f8b4e784a4fa48dd905f5f46b391
parent68d9ba190fe8a68f8cdd0fb0e20a38433def1984 (diff)
downloadvboot-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.c46
-rwxr-xr-xtests/futility/test_gscvd.sh19
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