diff options
author | Vadim Bendebury <vbendeb@chromium.org> | 2022-10-14 12:57:03 -0700 |
---|---|---|
committer | Chromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2022-12-02 01:09:40 +0000 |
commit | 2e51fa6b21d5deec723bd5cc3e80c6bd345ec745 (patch) | |
tree | 7e084ca9159c52c2a7974031eed5b3ff647c0524 | |
parent | c3644966c7e5d8186ea815c29ad4fa8ac84765f1 (diff) | |
download | vboot-2e51fa6b21d5deec723bd5cc3e80c6bd345ec745.tar.gz |
gscvd: refactor discovering GBB in the image
Separate GBB discovery into a function and cache GBB information in
the ap_firmware_file structure for future use.
BRANCH=none
BUG=b:245799496
TEST=ran the following command
./build/futility/futility gscvd -G -R 00000000:00001000 \
--keyblock tests/devkeys/arv_platform.keyblock \
--platform_priv tests/devkeys/arv_platform.vbprivk \
--board_id XYZ1 \
--root_pub_key tests/devkeys/arv_root.vbpubk "${BIOS_FILE}"
using 'futility' compiled before and after this patch was applied,
verified that the resulting file is the same.
Signed-off-by: Vadim Bendebury <vbendeb@chromium.org>
Change-Id: I3ab59536cfa75a303be3e9271d9b44b1de851f5c
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/3958580
Reviewed-by: Julius Werner <jwerner@chromium.org>
(cherry picked from commit 0b0aee9c0d1ef86833a07a0adabdfdc07d1d500b)
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/4063102
Commit-Queue: Knox Chiou <knoxchiou@chromium.org>
Tested-by: Knox Chiou <knoxchiou@chromium.org>
Reviewed-by: Yu-Ping Wu <yupingso@chromium.org>
-rw-r--r-- | futility/cmd_gscvd.c | 81 |
1 files changed, 52 insertions, 29 deletions
diff --git a/futility/cmd_gscvd.c b/futility/cmd_gscvd.c index fa14b125..f7dc73b6 100644 --- a/futility/cmd_gscvd.c +++ b/futility/cmd_gscvd.c @@ -126,6 +126,9 @@ struct file_buf { uint8_t *data; int fd; FmapAreaHeader *ro_gscvd; + /* Cached GBB information. */ + const FmapAreaHeader *gbb_area; + uint32_t gbb_maxlen; }; /* @@ -159,6 +162,8 @@ struct gscvd_ro_ranges { static int load_ap_firmware(const char *file_name, struct file_buf *file, int mode) { + memset(file, 0, sizeof(*file)); + if (futil_open_and_map_file(file_name, &file->fd, mode, &file->data, &file->len)) return 1; @@ -174,6 +179,43 @@ static int load_ap_firmware(const char *file_name, struct file_buf *file, return 1; } + /* + * Try finding FMAP gbb area and validating the GBB. It's not a + * failure if GBB is not found, it might not be required after all. + */ + FmapAreaHeader *area; + while (fmap_find_by_name(file->data, file->len, NULL, "GBB", &area)) { + struct vb2_gbb_header *gbb; + uint32_t maxlen; + + gbb = (void *)(file->data + area->area_offset); + + if (!futil_valid_gbb_header(gbb, area->area_size, &maxlen)) { + ERROR("GBB is invalid.\n"); + break; + } + + /* + * This implementation relies on the fact that no meaningful + * fields come after the `hwid_digest` field in the header. If + * we ever make new GBB versions that add more fields, the + * code below and in add_gbb() needs to be adapted. Older + * versions than 1.2 or GBBs with a bmpblk are not expected + * with GSCVD images. + */ + if (gbb->major_version != 1 || gbb->minor_version != 2 || + gbb->bmpfv_size != 0) { + ERROR("Unsupported GBB version.\n"); + break; + } + + + file->gbb_area = area; + file->gbb_maxlen = maxlen; + + break; + } + return 0; } @@ -370,34 +412,13 @@ static int parse_ranges(const char *input, struct gscvd_ro_ranges *output) */ static int add_gbb(struct gscvd_ro_ranges *ranges, const struct file_buf *file) { - FmapAreaHeader *area; - - if (!fmap_find_by_name(file->data, file->len, NULL, "GBB", &area)) { + if (!file->gbb_area) { ERROR("Could not find a GBB area in the FMAP.\n"); return 1; } - struct vb2_gbb_header *gbb = (void *)file->data + area->area_offset; - uint32_t maxlen; - - if (!futil_valid_gbb_header(gbb, area->area_size, &maxlen)) { - ERROR("GBB is invalid.\n"); - return 1; - } - - /* - * This implementation relies on the fact that no meaningful fields come - * after the `hwid_digest` field in the header. If we ever make new GBB - * versions that add more fields, the code below needs to be adapted. - * Older versions than 1.2 or GBBs with a bmpblk are not expected with - * GSCVD images. - */ - if (gbb->major_version != 1 || gbb->minor_version != 2 || - gbb->bmpfv_size != 0) { - ERROR("Unsupported GBB version.\n"); - return 1; - } - + const struct vb2_gbb_header *gbb = (void *)(file->data + + file->gbb_area->area_offset); uint32_t lower_key_offset = VB2_MIN(gbb->rootkey_offset, gbb->recovery_key_offset); if (gbb->hwid_offset > lower_key_offset) { @@ -410,14 +431,16 @@ static int add_gbb(struct gscvd_ro_ranges *ranges, const struct file_buf *file) return 1; } - ranges->ranges[ranges->range_count].offset = area->area_offset; + ranges->ranges[ranges->range_count].offset = + file->gbb_area->area_offset; ranges->ranges[ranges->range_count].size = - offsetof(struct vb2_gbb_header, hwid_digest); + offsetof(struct vb2_gbb_header, hwid_digest); ranges->range_count++; - ranges->ranges[ranges->range_count].offset = area->area_offset + - lower_key_offset; - ranges->ranges[ranges->range_count].size = maxlen - lower_key_offset; + ranges->ranges[ranges->range_count].offset = + file->gbb_area->area_offset + lower_key_offset; + ranges->ranges[ranges->range_count].size = + file->gbb_maxlen - lower_key_offset; ranges->range_count++; return 0; |