summaryrefslogtreecommitdiff
path: root/firmware/lib20
diff options
context:
space:
mode:
authorJoel Kitching <kitching@google.com>2019-06-09 12:37:55 +0800
committerCommit Bot <commit-bot@chromium.org>2020-02-09 11:59:26 +0000
commita32d8d67587ec2cfdb4598ef69d8d8763b34f6e8 (patch)
tree29a65094ffea26d52ffa73a67fb4fd4d2156bad6 /firmware/lib20
parent58229e2c77f949976d051387fe17f572802fd708 (diff)
downloadvboot-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.c102
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;
}