summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVadim Bendebury <vbendeb@chromium.org>2022-10-14 12:57:03 -0700
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2022-10-22 11:09:00 +0000
commit0b0aee9c0d1ef86833a07a0adabdfdc07d1d500b (patch)
treed568c6db053bbfdd06b418800d1becff67d50a89
parentff1749cb9a3da80bb9f2783d7ac4efaf0b99da98 (diff)
downloadvboot-0b0aee9c0d1ef86833a07a0adabdfdc07d1d500b.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>
-rw-r--r--futility/cmd_gscvd.c81
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;