summaryrefslogtreecommitdiff
path: root/firmware/lib20/api_kernel.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/lib20/api_kernel.c')
-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;
}