diff options
author | Vadim Bendebury <vbendeb@chromium.org> | 2022-09-19 22:18:06 -0700 |
---|---|---|
committer | Chromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2022-09-27 01:58:35 +0000 |
commit | 5790c0aa73e2ddc8460f66e27859716f3682c5bc (patch) | |
tree | 4ebe0394d032f653bc61e17db9a10715b364216d | |
parent | 499e57432df60047fba53f49b267139831855d59 (diff) | |
download | vboot-5790c0aa73e2ddc8460f66e27859716f3682c5bc.tar.gz |
gscvd: add support for reading ranges from the image
It has been decided to communicate the list of ranges to cover by the
signature through a preset ranges array in the RO_GSCVD FMAP section
of the AP firmware image.
This patch adds the ability to retrieve ranges from the image in case
the -R command line parameter is not given on the command line when
invoking 'futility gsvd'.
BRANCH=none
BUG=b:247653513
TEST=verified that both forms of invocation, with and without -R work
as expected, as well as GSCVD verification invocations with and
without the root public key hash
without passing in the ranges:
$ utility gscvd \
-k nivviksSigning-MP/arv_platform.keyblock \
-p nivviksSigning-MP/arv_platform.vbprivk \
-b 52435a5a \
-r nivviksSigning-MP/root_key_arv_root.vbpubk \
--outfile ~/tmp/bios/image-nivviks.signed.bin \
~/tmp/bios/image-nivviks.serial.bin
Will sign the following 3 ranges:
01fe4e00:0001b200
01c07000:00000030
01c07180:00002000
Root key body sha256 hash:
b3dba1f89e943d53206e2950e06c3764fe230ef883bb8fd2932a9fb21c281ba1
with passing in the ranges:
$ futility gscvd \
-R 1c77000:200,1c07000:400,1c16800:100,1c06000:1000,1c08000:100 \
-k nivviksSigning-MP/arv_platform.keyblock \
-p nivviksSigning-MP/arv_platform.vbprivk \
-b 52435a5a \
-r nivviksSigning-MP/root_key_arv_root.vbpubk \
--outfile ~/tmp/bios/image-nivviks.signed.bin \
~/tmp/bios/image-nivviks.serial.bin
Root key body sha256 hash:
b3dba1f89e943d53206e2950e06c3764fe230ef883bb8fd2932a9fb21c281ba1
validate signed image without pub key hash:
futility gscvd ~/tmp/bios/image-nivviks.signed.bin
validate signed image with pub key hash:
$ futility gscvd ~/tmp/bios/image-nivviks.signed.bin \
b3dba1f89e943d53206e2950e06c3764fe230ef883bb8fd2932a9fb21c281ba1
try validating signed image with a corrupted pub key hash:
$ futility gscvd ~/tmp/bios/image-nivviks.signed.bin \
b3dba1f89e943d53206e2950e06c3764fe230ef883bb8fd2932a9fb21c281ba0
ERROR: validate_gscvd_or_read_ranges: Sha256 mismatch
validate proper processing of uninitialized GVD:
$ futility gscvd -k nivviksSigning-MP/arv_platform.keyblock \
-p nivviksSigning-MP/arv_platform.vbprivk \
-b 52435a5a \
-r nivviksSigning-MP/root_key_arv_root.vbpubk \
--outfile ~/tmp/bios/image-nivviks.signed.bin \
~/tmp/bios/image-guybrush.serial.bin
ERROR: validate_gvd: Incorrect gscvd magic ffffffff
ERROR: do_gscvd: Missing --ranges argument and no ranges in...
Change-Id: I586f97083f6d77fdddddd7327c61891197c3cc58
Signed-off-by: Vadim Bendebury <vbendeb@google.com>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/3905178
Commit-Queue: Vadim Bendebury <vbendeb@chromium.org>
Tested-by: Vadim Bendebury <vbendeb@chromium.org>
Reviewed-by: Julius Werner <jwerner@chromium.org>
Reviewed-by: Alyssa Haroldsen <kupiakos@google.com>
-rw-r--r-- | futility/cmd_gscvd.c | 82 |
1 files changed, 65 insertions, 17 deletions
diff --git a/futility/cmd_gscvd.c b/futility/cmd_gscvd.c index 6101173f..1671e1b7 100644 --- a/futility/cmd_gscvd.c +++ b/futility/cmd_gscvd.c @@ -1,5 +1,5 @@ /* - * Copyright 2021 The Chromium OS Authors. All rights reserved. + * Copyright 2021 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -79,15 +79,6 @@ static const char usage[] = "Usage: " MYNAME " gscvd PARAMS <AP FIRMWARE FILE> [<root key hash>]\n" "\n\nCreation of RO Verification space:\n\n" "Required PARAMS:\n" - " -R|--ranges STRING Comma separated colon delimited\n" - " hex tuples <offset>:<size>, the\n" - " areas of the RO covered by the\n" - " signature\n" - " -G|--add_gbb Add the `GBB` FMAP section to the\n" - " ranges covered by the signature.\n" - " This option takes special care\n" - " to exclude the HWID (and its\n" - " digest) from this range.\n" " -b|--board_id <string|hex> The Board ID of the board for\n" " which the image is signed.\n" " Can be passed as a 4-letter\n" @@ -102,6 +93,18 @@ static const char usage[] = " format, used for signing RO\n" " verification data\n" "Optional PARAMS:\n" + " -G|--add_gbb Add the `GBB` FMAP section to the\n" + " ranges covered by the signature.\n" + " This option takes special care\n" + " to exclude the HWID (and its\n" + " digest) from this range.\n" + " -R|--ranges STRING Comma separated colon delimited\n" + " hex tuples <offset>:<size>, the\n" + " areas of the RO covered by the\n" + " signature, if omitted the\n" + " ranges are expected to be\n" + " present in the GSCVD section\n" + " of the input file\n" " [--outfile] OUTFILE Output firmware image containing\n" " RO verification information\n" "\n\n" @@ -845,6 +848,46 @@ static int validate_gvd_signature(struct gsc_verification_data *gvd, } /* + * Try retrieving GVD ranges from the passed in AP firmware file. + * + * The passed in ranges structure is set to the set of ranges retrieved from + * the firmware file, if any. + */ +static void try_retrieving_ranges_from_the_image(const char *file_name, + struct gscvd_ro_ranges *ranges, + struct file_buf + *ap_firmware_file) +{ + struct gsc_verification_data *gvd; + size_t i; + + ranges->range_count = 0; + + /* Look for ranges in GVD and copy them if found. */ + gvd = (struct gsc_verification_data + *)(ap_firmware_file->data + + ap_firmware_file->ro_gscvd->area_offset); + + if (validate_gvd(gvd, ap_firmware_file)) + return; + + if (copy_ranges(ap_firmware_file, gvd, ranges)) + return; + + if (!ranges->range_count) { + printf("No ranges found in the input file\n"); + } else { + printf("Will re-sign the following %zd ranges:\n", + ranges->range_count); + for (i = 0; i < ranges->range_count; i++) { + printf("%08x:%08x\n", + ranges->ranges[i].offset, + ranges->ranges[i].size); + } + } +} + +/* * 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 @@ -1074,6 +1117,8 @@ static int do_gscvd(int argc, char *argv[]) goto usage_out; } + infile = argv[optind]; + if (errorcount) /* Error message(s) should have been printed by now. */ goto usage_out; @@ -1097,13 +1142,6 @@ static int do_gscvd(int argc, char *argv[]) goto usage_out; } - if (!ranges.range_count && !do_gbb) { - ERROR("Missing --ranges argument\n"); - goto usage_out; - } - - infile = argv[optind]; - if (outfile) { futil_copy_file_or_die(infile, outfile); work_file = outfile; @@ -1123,6 +1161,16 @@ static int do_gscvd(int argc, char *argv[]) if (load_ap_firmware(work_file, &ap_firmware_file, FILE_RW)) break; + if (!ranges.range_count) + try_retrieving_ranges_from_the_image(infile, + &ranges, + &ap_firmware_file); + + if (!ranges.range_count && !do_gbb) { + ERROR("Missing --ranges argument and no ranges in the input file\n"); + break; + } + if (do_gbb && add_gbb(&ranges, &ap_firmware_file)) break; |