summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
Diffstat (limited to 'firmware')
-rw-r--r--firmware/2lib/include/2return_codes.h5
-rw-r--r--firmware/lib/vboot_api_kernel.c34
-rw-r--r--firmware/lib/vboot_kernel.c18
-rw-r--r--firmware/lib20/api_kernel.c102
4 files changed, 51 insertions, 108 deletions
diff --git a/firmware/2lib/include/2return_codes.h b/firmware/2lib/include/2return_codes.h
index 0394feed..64b375d1 100644
--- a/firmware/2lib/include/2return_codes.h
+++ b/firmware/2lib/include/2return_codes.h
@@ -684,8 +684,9 @@ enum vb2_return_code {
/* Buffer size for the digest is too small for vb2api_get_pcr_digest */
VB2_ERROR_API_PCR_DIGEST_BUF,
- /* Work buffer too small for recovery key in vb2api_kernel_phase1() */
- VB2_ERROR_API_KPHASE1_WORKBUF_REC_KEY,
+ /* Work buffer too small for recovery key in vb2api_kernel_phase1();
+ * Deprecated: use vb2_gbb_read_recovery_key return values */
+ VB2_ERROR_DEPRECATED_API_KPHASE1_WORKBUF_REC_KEY,
/* Firmware preamble not present for vb2api_kernel_phase1() */
VB2_ERROR_API_KPHASE1_PREAMBLE,
diff --git a/firmware/lib/vboot_api_kernel.c b/firmware/lib/vboot_api_kernel.c
index d6fab619..0e2e8fb3 100644
--- a/firmware/lib/vboot_api_kernel.c
+++ b/firmware/lib/vboot_api_kernel.c
@@ -227,7 +227,6 @@ static vb2_error_t vb2_kernel_setup(struct vb2_context *ctx,
VbSelectAndLoadKernelParams *kparams)
{
struct vb2_shared_data *sd = vb2_get_sd(ctx);
- vb2_error_t rv;
/* Set selected boot mode in context object.
TODO: Confirm that this can be removed with persistent context. */
@@ -251,8 +250,6 @@ static vb2_error_t vb2_kernel_setup(struct vb2_context *ctx,
if (sd->flags & VB2_SD_FLAG_MANUAL_RECOVERY)
shared->flags |= VBSD_BOOT_REC_SWITCH_ON;
- vb2_nv_init(ctx);
-
/*
* Save a pointer to the old vboot1 shared data, since we haven't
* finished porting the library to use the new vb2 context and shared
@@ -275,29 +272,6 @@ static vb2_error_t vb2_kernel_setup(struct vb2_context *ctx,
kparams->flags = 0;
memset(kparams->partition_guid, 0, sizeof(kparams->partition_guid));
- /*
- * 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 the TPM. */
- shared->kernel_version_tpm =
- vb2_secdata_kernel_get(ctx, VB2_SECDATA_KERNEL_VERSIONS);
- shared->kernel_version_tpm_start = shared->kernel_version_tpm;
-
return VB2_SUCCESS;
}
@@ -367,10 +341,18 @@ vb2_error_t VbSelectAndLoadKernel(struct vb2_context *ctx,
struct vb2_shared_data *sd = vb2_get_sd(ctx);
vb2_error_t rv, call_rv;
+ /* Init nvstorage space. TODO(kitching): Remove once we add assertions
+ to vb2_nv_get and vb2_nv_set. */
+ vb2_nv_init(ctx);
+
rv = vb2_kernel_setup(ctx, shared, kparams);
if (rv)
goto VbSelectAndLoadKernel_exit;
+ rv = vb2api_kernel_phase1(ctx);
+ if (rv)
+ goto VbSelectAndLoadKernel_exit;
+
VB2_DEBUG("GBB flags are %#x\n", vb2_get_gbb(ctx)->flags);
/*
diff --git a/firmware/lib/vboot_kernel.c b/firmware/lib/vboot_kernel.c
index 72ea0ebc..9ca14bac 100644
--- a/firmware/lib/vboot_kernel.c
+++ b/firmware/lib/vboot_kernel.c
@@ -466,19 +466,10 @@ vb2_error_t LoadKernel(struct vb2_context *ctx, LoadKernelParams *params)
shcall->sector_count = params->streaming_lba_count;
shared->lk_call_count++;
- /* Choose key to verify kernel */
- struct vb2_packed_key *kernel_subkey;
- if (kBootRecovery == shcall->boot_mode) {
- /* Use the recovery key to verify the kernel */
- rv = vb2_gbb_read_recovery_key(ctx, &kernel_subkey, NULL, &wb);
- if (VB2_SUCCESS != rv) {
- VB2_DEBUG("GBB read recovery key failed.\n");
- goto load_kernel_exit;
- }
- } else {
- /* Use the kernel subkey passed from firmware verification */
- kernel_subkey = (struct vb2_packed_key *)&shared->kernel_subkey;
- }
+ /* Locate key to verify kernel. This will either be a recovery key, or
+ a kernel subkey passed from firmware verification. */
+ struct vb2_packed_key *kernel_subkey =
+ vb2_member_of(sd, sd->kernel_key_offset);
/* Read GPT data */
GptData gpt;
@@ -658,7 +649,6 @@ gpt_done:
rv = VB2_ERROR_LK_NO_KERNEL_FOUND;
}
-load_kernel_exit:
shcall->return_code = (uint8_t)rv;
return rv;
}
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;
}