diff options
author | Joel Kitching <kitching@google.com> | 2019-06-09 12:37:55 +0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-02-09 11:59:26 +0000 |
commit | a32d8d67587ec2cfdb4598ef69d8d8763b34f6e8 (patch) | |
tree | 29a65094ffea26d52ffa73a67fb4fd4d2156bad6 /firmware/lib20 | |
parent | 58229e2c77f949976d051387fe17f572802fd708 (diff) | |
download | vboot-a32d8d67587ec2cfdb4598ef69d8d8763b34f6e8.tar.gz |
vboot: update vb2api_kernel_phase1 to use GBB interface
vb2api_kernel_phase1 was previously written to read the GBB
headers, locate the recovery key, and then load it. GBB headers
are now saved directly on workbuf in firmware phase. Simply use
the vb2_gbb_read_recovery_key function to retrieve the key.
Update LoadKernel to read kernel subkey from vboot2 workbuf.
Update tests/verify_kernel.c to write subkey to vboot2 workbuf.
BUG=b:124141368, chromium:954774, chromium:1038260
TEST=make clean && make runtests
BRANCH=none
Change-Id: Ia85013da34bdab68bf486014a3401d48c95b3472
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/1651221
Tested-by: Joel Kitching <kitching@chromium.org>
Reviewed-by: Julius Werner <jwerner@chromium.org>
Commit-Queue: Joel Kitching <kitching@chromium.org>
Diffstat (limited to 'firmware/lib20')
-rw-r--r-- | firmware/lib20/api_kernel.c | 102 |
1 files changed, 36 insertions, 66 deletions
diff --git a/firmware/lib20/api_kernel.c b/firmware/lib20/api_kernel.c index 3a4da4ce..3748420f 100644 --- a/firmware/lib20/api_kernel.c +++ b/firmware/lib20/api_kernel.c @@ -14,63 +14,59 @@ #include "2sha.h" #include "2sysincludes.h" #include "vb2_common.h" +#include "vboot_struct.h" vb2_error_t vb2api_kernel_phase1(struct vb2_context *ctx) { struct vb2_shared_data *sd = vb2_get_sd(ctx); struct vb2_workbuf wb; - uint8_t *key_data; - uint32_t key_size; + struct vb2_packed_key *packed_key; vb2_error_t rv; vb2_workbuf_from_ctx(ctx, &wb); - /* Initialize secure kernel data and read version */ + /* + * Init secdata_kernel and secdata_fwmp spaces. No need to init + * secdata_firmware, since it was already read during firmware + * verification. Ignore errors in recovery mode. + */ rv = vb2_secdata_kernel_init(ctx); if (rv && !(ctx->flags & VB2_CONTEXT_RECOVERY_MODE)) { + VB2_DEBUG("TPM: init secdata_kernel returned %#x\n", rv); vb2api_fail(ctx, VB2_RECOVERY_SECDATA_KERNEL_INIT, rv); return rv; } + rv = vb2_secdata_fwmp_init(ctx); + if (rv && !(ctx->flags & VB2_CONTEXT_RECOVERY_MODE)) { + VB2_DEBUG("TPM: init secdata_fwmp returned %#x\n", rv); + vb2api_fail(ctx, VB2_RECOVERY_SECDATA_FWMP_INIT, rv); + return rv; + } + + /* Read kernel version from secdata. */ sd->kernel_version_secdata = vb2_secdata_kernel_get(ctx, VB2_SECDATA_KERNEL_VERSIONS); + sd->vbsd->kernel_version_tpm = sd->kernel_version_secdata; + sd->vbsd->kernel_version_tpm_start = sd->kernel_version_secdata; /* Find the key to use to verify the kernel keyblock */ - if (ctx->flags & VB2_CONTEXT_RECOVERY_MODE) { - /* Recovery key from GBB */ - struct vb2_gbb_header *gbb; - uint32_t key_offset; - - /* Read GBB header into next chunk of work buffer */ - gbb = vb2_workbuf_alloc(&wb, sizeof(*gbb)); - if (!gbb) - return VB2_ERROR_GBB_WORKBUF; - - rv = vb2_read_gbb_header(ctx, gbb); - if (rv) - return rv; - - /* Only need the recovery key position and size */ - key_offset = gbb->recovery_key_offset; - key_size = gbb->recovery_key_size; - - /* Free the GBB header */ - vb2_workbuf_free(&wb, sizeof(*gbb)); - - /* Load the recovery key itself */ - key_data = vb2_workbuf_alloc(&wb, key_size); - if (!key_data) - return VB2_ERROR_API_KPHASE1_WORKBUF_REC_KEY; - - rv = vb2ex_read_resource(ctx, VB2_RES_GBB, key_offset, - key_data, key_size); - if (rv) - return rv; - - sd->kernel_key_offset = vb2_offset_of(sd, key_data); + if ((ctx->flags & VB2_CONTEXT_RECOVERY_MODE)) { + /* Load recovery key from GBB. */ + rv = vb2_gbb_read_recovery_key(ctx, &packed_key, NULL, &wb); + if (rv) { + if (vb2_allow_recovery(ctx)) + VB2_DIE("GBB read recovery key failed.\n"); + else + /* + * If we're headed for the BROKEN screen, + * we won't need the recovery key. Just + * short-circuit with success. + */ + return VB2_SUCCESS; + } } else { /* Kernel subkey from firmware preamble */ struct vb2_fw_preamble *pre; - struct vb2_packed_key *pre_key, *packed_key; /* Make sure we have a firmware preamble loaded */ if (!sd->preamble_size) @@ -78,39 +74,13 @@ vb2_error_t vb2api_kernel_phase1(struct vb2_context *ctx) pre = (struct vb2_fw_preamble *) vb2_member_of(sd, sd->preamble_offset); - pre_key = &pre->kernel_subkey; - - /* - * At this point, we no longer need the packed firmware - * data key, firmware preamble, or hash data. So move the - * kernel key from the preamble down after the shared data. - */ - sd->kernel_key_offset = vb2_wb_round_up(sizeof(*sd)); - key_data = vb2_member_of(sd, sd->kernel_key_offset); - packed_key = (struct vb2_packed_key *)key_data; - memmove(packed_key, pre_key, sizeof(*packed_key)); - packed_key->key_offset = sizeof(*packed_key); - memmove(key_data + packed_key->key_offset, - (uint8_t *)pre_key + pre_key->key_offset, - pre_key->key_size); - - key_size = packed_key->key_offset + packed_key->key_size; + packed_key = &pre->kernel_subkey; } - /* Firmware stage structs are no longer present */ - sd->data_key_size = 0; - sd->preamble_size = 0; - sd->hash_size = 0; + sd->kernel_key_offset = vb2_offset_of(sd, packed_key); + sd->kernel_key_size = packed_key->key_offset + packed_key->key_size; - /* - * Kernel key will persist in the workbuf after we return. - * - * Work buffer now contains: - * - vb2_shared_data - * - kernel key - */ - sd->kernel_key_size = key_size; - vb2_set_workbuf_used(ctx, sd->kernel_key_offset + sd->kernel_key_size); + vb2_set_workbuf_used(ctx, vb2_offset_of(sd, wb.buf)); return VB2_SUCCESS; } |