summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
Diffstat (limited to 'firmware')
-rw-r--r--firmware/2lib/include/2api.h16
-rw-r--r--firmware/2lib/include/2misc.h2
-rw-r--r--firmware/lib21/api.c167
-rw-r--r--firmware/lib21/common.c138
-rw-r--r--firmware/lib21/include/vb21_common.h32
-rw-r--r--firmware/lib21/include/vb21_struct.h120
-rw-r--r--firmware/lib21/misc.c245
7 files changed, 1 insertions, 719 deletions
diff --git a/firmware/2lib/include/2api.h b/firmware/2lib/include/2api.h
index e8ce89da..5470b308 100644
--- a/firmware/2lib/include/2api.h
+++ b/firmware/2lib/include/2api.h
@@ -587,11 +587,6 @@ vb2_error_t vb2api_fw_phase2(struct vb2_context *ctx);
vb2_error_t vb2api_fw_phase3(struct vb2_context *ctx);
/**
- * Same, but for new-style structs.
- */
-vb2_error_t vb21api_fw_phase3(struct vb2_context *ctx);
-
-/**
* Initialize hashing data for the specified tag.
*
* @param ctx Vboot context
@@ -601,12 +596,6 @@ vb2_error_t vb21api_fw_phase3(struct vb2_context *ctx);
vb2_error_t vb2api_init_hash(struct vb2_context *ctx, uint32_t tag);
/**
- * Same, but for new-style structs.
- */
-vb2_error_t vb21api_init_hash(struct vb2_context *ctx, const struct vb2_id *id,
- uint32_t *size);
-
-/**
* Extend the hash started by vb2api_init_hash() with additional data.
*
* (This is the same for both old and new style structs.)
@@ -628,11 +617,6 @@ vb2_error_t vb2api_extend_hash(struct vb2_context *ctx, const void *buf,
int vb2api_check_hash(struct vb2_context *ctx);
/**
- * Same, but for new-style structs.
- */
-vb2_error_t vb21api_check_hash(struct vb2_context *ctx);
-
-/**
* Check the hash value started by vb2api_init_hash() while retrieving
* calculated digest.
*
diff --git a/firmware/2lib/include/2misc.h b/firmware/2lib/include/2misc.h
index 6400bfa6..6a61f9e5 100644
--- a/firmware/2lib/include/2misc.h
+++ b/firmware/2lib/include/2misc.h
@@ -130,7 +130,6 @@ vb2_error_t vb2_select_fw_slot(struct vb2_context *ctx);
* @return VB2_SUCCESS, or error code on error.
*/
vb2_error_t vb2_load_fw_keyblock(struct vb2_context *ctx);
-vb2_error_t vb21_load_fw_keyblock(struct vb2_context *ctx);
/**
* Verify the firmware preamble using the data subkey from the keyblock.
@@ -141,7 +140,6 @@ vb2_error_t vb21_load_fw_keyblock(struct vb2_context *ctx);
* @return VB2_SUCCESS, or error code on error.
*/
vb2_error_t vb2_load_fw_preamble(struct vb2_context *ctx);
-vb2_error_t vb21_load_fw_preamble(struct vb2_context *ctx);
/**
* Verify the kernel keyblock using the previously-loaded kernel key.
diff --git a/firmware/lib21/api.c b/firmware/lib21/api.c
deleted file mode 100644
index b9fc5e4c..00000000
--- a/firmware/lib21/api.c
+++ /dev/null
@@ -1,167 +0,0 @@
-/* Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- *
- * Externally-callable APIs
- * (Firmware portion)
- */
-
-#include "2api.h"
-#include "2common.h"
-#include "2misc.h"
-#include "2nvstorage.h"
-#include "2rsa.h"
-#include "2secdata.h"
-#include "2sha.h"
-#include "2sysincludes.h"
-#include "vb21_common.h"
-
-vb2_error_t vb21api_fw_phase3(struct vb2_context *ctx)
-{
- vb2_error_t rv;
-
- /* Verify firmware keyblock */
- rv = vb21_load_fw_keyblock(ctx);
- if (rv) {
- vb2api_fail(ctx, VB2_RECOVERY_RO_INVALID_RW, rv);
- return rv;
- }
-
- /* Verify firmware preamble */
- rv = vb21_load_fw_preamble(ctx);
- if (rv) {
- vb2api_fail(ctx, VB2_RECOVERY_RO_INVALID_RW, rv);
- return rv;
- }
-
- return VB2_SUCCESS;
-}
-
-vb2_error_t vb21api_init_hash(struct vb2_context *ctx,
- const struct vb2_id *id,
- uint32_t *size)
-{
- struct vb2_shared_data *sd = vb2_get_sd(ctx);
- const struct vb21_fw_preamble *pre;
- const struct vb21_signature *sig = NULL;
- struct vb2_digest_context *dc;
- struct vb2_workbuf wb;
- uint32_t hash_offset;
- int i, rv;
-
- vb2_workbuf_from_ctx(ctx, &wb);
-
- /* Get preamble pointer */
- if (!sd->preamble_size)
- return VB2_ERROR_API_INIT_HASH_PREAMBLE;
- pre = (const struct vb21_fw_preamble *)
- vb2_member_of(sd, sd->preamble_offset);
-
- /* Find the matching signature */
- hash_offset = pre->hash_offset;
- for (i = 0; i < pre->hash_count; i++) {
- sig = (const struct vb21_signature *)
- ((uint8_t *)pre + hash_offset);
-
- if (!memcmp(id, &sig->id, sizeof(*id)))
- break;
-
- hash_offset += sig->c.total_size;
- }
- if (i >= pre->hash_count)
- return VB2_ERROR_API_INIT_HASH_ID; /* No match */
-
- /* Allocate workbuf space for the hash */
- if (sd->hash_size) {
- dc = (struct vb2_digest_context *)
- vb2_member_of(sd, sd->hash_offset);
- } else {
- uint32_t dig_size = sizeof(*dc);
-
- dc = vb2_workbuf_alloc(&wb, dig_size);
- if (!dc)
- return VB2_ERROR_API_INIT_HASH_WORKBUF;
-
- sd->hash_offset = vb2_offset_of(sd, dc);
- sd->hash_size = dig_size;
- vb2_set_workbuf_used(ctx, sd->hash_offset + dig_size);
- }
-
- sd->hash_tag = vb2_offset_of(sd, sig);
- sd->hash_remaining_size = sig->data_size;
-
- if (size)
- *size = sig->data_size;
-
- if (!(pre->flags & VB21_FIRMWARE_PREAMBLE_DISALLOW_HWCRYPTO)) {
- rv = vb2ex_hwcrypto_digest_init(sig->hash_alg, sig->data_size);
- if (!rv) {
- VB2_DEBUG("Using HW crypto engine for hash_alg %d\n",
- sig->hash_alg);
- dc->hash_alg = sig->hash_alg;
- dc->using_hwcrypto = 1;
- return VB2_SUCCESS;
- }
- if (rv != VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED)
- return rv;
- VB2_DEBUG("HW crypto for hash_alg %d not supported, using SW\n",
- sig->hash_alg);
- } else {
- VB2_DEBUG("HW crypto forbidden by preamble, using SW\n");
- }
-
- return vb2_digest_init(dc, sig->hash_alg);
-}
-
-vb2_error_t vb21api_check_hash(struct vb2_context *ctx)
-{
- struct vb2_shared_data *sd = vb2_get_sd(ctx);
- struct vb2_digest_context *dc = (struct vb2_digest_context *)
- vb2_member_of(sd, sd->hash_offset);
- struct vb2_workbuf wb;
-
- uint8_t *digest;
- uint32_t digest_size = vb2_digest_size(dc->hash_alg);
-
- const struct vb21_signature *sig;
-
- vb2_error_t rv;
-
- vb2_workbuf_from_ctx(ctx, &wb);
-
- /* Get signature pointer */
- if (!sd->hash_tag)
- return VB2_ERROR_API_CHECK_HASH_TAG;
- sig = vb2_member_of(sd, sd->hash_tag);
-
- /* Must have initialized hash digest work area */
- if (!sd->hash_size)
- return VB2_ERROR_API_CHECK_HASH_WORKBUF;
-
- /* Should have hashed the right amount of data */
- if (sd->hash_remaining_size)
- return VB2_ERROR_API_CHECK_HASH_SIZE;
-
- /* Allocate the digest */
- digest = vb2_workbuf_alloc(&wb, digest_size);
- if (!digest)
- return VB2_ERROR_API_CHECK_HASH_WORKBUF_DIGEST;
-
- /* Finalize the digest */
- if (dc->using_hwcrypto)
- rv = vb2ex_hwcrypto_digest_finalize(digest, digest_size);
- else
- rv = vb2_digest_finalize(dc, digest, digest_size);
- if (rv)
- return rv;
-
- /* Compare with the signature */
- if (vb2_safe_memcmp(digest, (const uint8_t *)sig + sig->sig_offset,
- digest_size))
- return VB2_ERROR_API_CHECK_HASH_SIG;
-
- /* TODO: The old check-hash function called vb2api_fail() on any
- mismatch. I don't think it should do that; the caller should. */
-
- return VB2_SUCCESS;
-}
diff --git a/firmware/lib21/common.c b/firmware/lib21/common.c
index 89367ba3..19f07bce 100644
--- a/firmware/lib21/common.c
+++ b/firmware/lib21/common.c
@@ -301,141 +301,3 @@ vb2_error_t vb21_verify_data(const void *data, uint32_t size,
return vb21_verify_digest(key, sig, digest, &wblocal);
}
-
-vb2_error_t vb21_verify_keyblock(struct vb21_keyblock *block, uint32_t size,
- const struct vb2_public_key *key,
- const struct vb2_workbuf *wb)
-{
- uint32_t min_offset = 0, sig_offset;
- vb2_error_t rv, i;
-
- /* Check magic number */
- if (block->c.magic != VB21_MAGIC_KEYBLOCK)
- return VB2_ERROR_KEYBLOCK_MAGIC;
-
- /* Make sure common header is good */
- rv = vb21_verify_common_header(block, size);
- if (rv)
- return rv;
-
- /*
- * Check for compatible version. No need to check minor version, since
- * that's compatible across readers matching the major version, and we
- * haven't added any new fields.
- */
- if (block->c.struct_version_major != VB21_KEYBLOCK_VERSION_MAJOR)
- return VB2_ERROR_KEYBLOCK_HEADER_VERSION;
-
- /* Make sure header is big enough */
- if (block->c.fixed_size < sizeof(*block))
- return VB2_ERROR_KEYBLOCK_SIZE;
-
- /* Make sure data key is inside */
- rv = vb21_verify_common_subobject(block, &min_offset,
- block->key_offset);
- if (rv)
- return rv;
-
- /* Loop over signatures */
- sig_offset = block->sig_offset;
- for (i = 0; i < block->sig_count; i++, sig_offset = min_offset) {
- struct vb21_signature *sig;
-
- /* Make sure signature is inside keyblock */
- rv = vb21_verify_common_subobject(block, &min_offset,
- sig_offset);
- if (rv)
- return rv;
-
- sig = (struct vb21_signature *)((uint8_t *)block + sig_offset);
-
- /* Verify the signature integrity */
- rv = vb21_verify_signature(sig,
- block->c.total_size - sig_offset);
- if (rv)
- return rv;
-
- /* Skip signature if it doesn't match the key ID */
- if (memcmp(&sig->id, key->id, VB2_ID_NUM_BYTES))
- continue;
-
- /* Make sure we signed the right amount of data */
- if (sig->data_size != block->sig_offset)
- return VB2_ERROR_KEYBLOCK_SIGNED_SIZE;
-
- return vb21_verify_data(block, block->sig_offset, sig, key, wb);
- }
-
- /* If we're still here, no signature matched the key ID */
- return VB2_ERROR_KEYBLOCK_SIG_ID;
-}
-
-vb2_error_t vb21_verify_fw_preamble(struct vb21_fw_preamble *preamble,
- uint32_t size,
- const struct vb2_public_key *key,
- const struct vb2_workbuf *wb)
-{
- struct vb21_signature *sig;
- uint32_t min_offset = 0, hash_offset;
- vb2_error_t rv, i;
-
- /* Check magic number */
- if (preamble->c.magic != VB21_MAGIC_FW_PREAMBLE)
- return VB2_ERROR_PREAMBLE_MAGIC;
-
- /* Make sure common header is good */
- rv = vb21_verify_common_header(preamble, size);
- if (rv)
- return rv;
-
- /*
- * Check for compatible version. No need to check minor version, since
- * that's compatible across readers matching the major version, and we
- * haven't added any new fields.
- */
- if (preamble->c.struct_version_major != VB21_FW_PREAMBLE_VERSION_MAJOR)
- return VB2_ERROR_PREAMBLE_HEADER_VERSION;
-
- /* Make sure header is big enough */
- if (preamble->c.fixed_size < sizeof(*preamble))
- return VB2_ERROR_PREAMBLE_SIZE;
-
- /* Make sure all hash signatures are inside */
- hash_offset = preamble->hash_offset;
- for (i = 0; i < preamble->hash_count; i++, hash_offset = min_offset) {
- /* Make sure signature is inside preamble */
- rv = vb21_verify_common_subobject(preamble, &min_offset,
- hash_offset);
- if (rv)
- return rv;
-
- sig = (struct vb21_signature *)
- ((uint8_t *)preamble + hash_offset);
-
- /* Verify the signature integrity */
- rv = vb21_verify_signature(
- sig, preamble->c.total_size - hash_offset);
- if (rv)
- return rv;
-
- /* Hashes must all be unsigned */
- if (sig->sig_alg != VB2_SIG_NONE)
- return VB2_ERROR_PREAMBLE_HASH_SIGNED;
- }
-
- /* Make sure signature is inside preamble */
- rv = vb21_verify_common_subobject(preamble, &min_offset,
- preamble->sig_offset);
- if (rv)
- return rv;
-
- /* Verify preamble signature */
- sig = (struct vb21_signature *)((uint8_t *)preamble +
- preamble->sig_offset);
-
- rv = vb21_verify_data(preamble, preamble->sig_offset, sig, key, wb);
- if (rv)
- return rv;
-
- return VB2_SUCCESS;
-}
diff --git a/firmware/lib21/include/vb21_common.h b/firmware/lib21/include/vb21_common.h
index 6362a150..442ccb07 100644
--- a/firmware/lib21/include/vb21_common.h
+++ b/firmware/lib21/include/vb21_common.h
@@ -144,38 +144,6 @@ vb2_error_t vb21_verify_data(const void *data, uint32_t size,
const struct vb2_public_key *key,
const struct vb2_workbuf *wb);
-/**
- * Check the sanity of a keyblock using a public key.
- *
- * Header fields are also checked for sanity. Does not verify key index or key
- * block flags. Signature inside block is destroyed during check.
- *
- * @param block Keyblock to verify
- * @param size Size of keyblock buffer
- * @param key Key to use to verify block
- * @param wb Work buffer
- * @return VB2_SUCCESS, or non-zero error code if error.
- */
-vb2_error_t vb21_verify_keyblock(struct vb21_keyblock *block, uint32_t size,
- const struct vb2_public_key *key,
- const struct vb2_workbuf *wb);
-
-/**
- * Check the sanity of a firmware preamble using a public key.
- *
- * The signature in the preamble is destroyed during the check.
- *
- * @param preamble Preamble to verify
- * @param size Size of preamble buffer
- * @param key Key to use to verify preamble
- * @param wb Work buffer
- * @return VB2_SUCCESS, or non-zero error code if error.
- */
-vb2_error_t vb21_verify_fw_preamble(struct vb21_fw_preamble *preamble,
- uint32_t size,
- const struct vb2_public_key *key,
- const struct vb2_workbuf *wb);
-
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/firmware/lib21/include/vb21_struct.h b/firmware/lib21/include/vb21_struct.h
index 18cfb8dd..6f91e36c 100644
--- a/firmware/lib21/include/vb21_struct.h
+++ b/firmware/lib21/include/vb21_struct.h
@@ -11,9 +11,8 @@
#ifndef VBOOT_REFERENCE_VB21_STRUCT_H_
#define VBOOT_REFERENCE_VB21_STRUCT_H_
-#include <stdint.h>
-
#include "2id.h"
+#include "2sysincludes.h"
#ifdef __cplusplus
extern "C" {
@@ -28,18 +27,9 @@ extern "C" {
* structs as invalid.
*/
enum vb21_struct_common_magic {
- /* "Vb2B" = vb21_keyblock.c.magic */
- VB21_MAGIC_KEYBLOCK = 0x42326256,
-
- /* "Vb2F" = vb21_fw_preamble.c.magic */
- VB21_MAGIC_FW_PREAMBLE = 0x46326256,
-
/* "Vb2I" = vb21_packed_private_key.c.magic */
VB21_MAGIC_PACKED_PRIVATE_KEY = 0x49326256,
- /* "Vb2K" = vb2_kernel_preamble.c.magic */
- VB21_MAGIC_KERNEL_PREAMBLE = 0x4b326256,
-
/* "Vb2P" = vb21_packed_key.c.magic */
VB21_MAGIC_PACKED_KEY = 0x50326256,
@@ -236,114 +226,6 @@ struct vb21_signature {
#define EXPECTED_VB21_SIGNATURE_SIZE \
(EXPECTED_VB21_STRUCT_COMMON_SIZE + 16 + EXPECTED_ID_SIZE)
-
-/* Current version of vb21_keyblock struct */
-#define VB21_KEYBLOCK_VERSION_MAJOR 3
-#define VB21_KEYBLOCK_VERSION_MINOR 0
-
-/*
- * Keyblock. This contains a signed, versioned key for use in the next stage
- * of verified boot.
- *
- * The keyblock data must be arranged like this:
- * 1) vb21_keyblock header struct h
- * 2) Keyblock description (pointed to by h.c.fixed_size)
- * 3) Data key (pointed to by h.data_key_offset)
- * 4) Signatures (first signature pointed to by h.sig_offset)
- *
- * The signatures from 4) must cover all the data from 1), 2), 3). That is,
- * signatures must sign all data up to sig_offset.
- */
-struct vb21_keyblock {
- /* Common header fields */
- struct vb21_struct_common c;
-
- /* Flags (VB2_KEYBLOCK_FLAG_*) */
- uint32_t flags;
-
- /*
- * Offset of key (struct vb21_packed_key) to use in next stage of
- * verification, from start of the keyblock.
- */
- uint32_t key_offset;
-
- /* Number of keyblock signatures which follow */
- uint32_t sig_count;
-
- /*
- * Offset of the first signature (struct vb21_signature) from the start
- * of the keyblock.
- *
- * Signatures sign the contents of this struct and the data pointed to
- * by data_key_offset, but not themselves or other signatures.
- *
- * For the firmware, there may be only one signature.
- *
- * Kernels often have at least two signatures - one using the kernel
- * subkey from the RW firmware (for signed kernels) and one which is
- * simply a SHA-512 hash (for unsigned developer kernels).
- *
- * The ID for each signature indicates which key was used to generate
- * the signature.
- */
- uint32_t sig_offset;
-} __attribute__((packed));
-
-#define EXPECTED_VB21_KEYBLOCK_SIZE (EXPECTED_VB21_STRUCT_COMMON_SIZE + 16)
-
-
-/* Current version of vb21_fw_preamble struct */
-#define VB21_FW_PREAMBLE_VERSION_MAJOR 3
-#define VB21_FW_PREAMBLE_VERSION_MINOR 0
-
-/* Flags for vb21_fw_preamble.flags */
-/* Reserved; do not use */
-#define VB21_FIRMWARE_PREAMBLE_RESERVED0 0x00000001
-/* Do not allow use of any hardware crypto accelerators. */
-#define VB21_FIRMWARE_PREAMBLE_DISALLOW_HWCRYPTO 0x00000002
-
-/*
- * Firmware preamble
- *
- * The preamble data must be arranged like this:
- * 1) vb21_fw_preamble header struct h
- * 2) Preamble description (pointed to by h.c.fixed_size)
- * 3) Hashes (pointed to by h.hash_offset)
- * 4) Signature (pointed to by h.sig_offset)
- *
- * The signature 4) must cover all the data from 1), 2), 3).
- */
-struct vb21_fw_preamble {
- /* Common header fields */
- struct vb21_struct_common c;
-
- /* Flags; see VB21_FIRMWARE_PREAMBLE_* */
- uint32_t flags;
-
- /* Firmware version */
- uint32_t fw_version;
-
- /* Offset of signature (struct vb21_signature) for this preamble */
- uint32_t sig_offset;
-
- /*
- * The preamble contains a list of hashes (struct vb21_signature) for
- * the various firmware components. These have sig_alg=VB2_SIG_NONE,
- * and the ID for each hash identifies the component being hashed.
- * The calling firmware is responsible for knowing where to find those
- * components, which may be on a different storage device than this
- * preamble.
- */
-
- /* Number of hash entries */
- uint32_t hash_count;
-
- /* Offset of first hash entry from start of preamble */
- uint32_t hash_offset;
-} __attribute__((packed));
-
-#define EXPECTED_VB21_FW_PREAMBLE_SIZE (EXPECTED_VB21_STRUCT_COMMON_SIZE + 20)
-
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/firmware/lib21/misc.c b/firmware/lib21/misc.c
deleted file mode 100644
index ca1a012f..00000000
--- a/firmware/lib21/misc.c
+++ /dev/null
@@ -1,245 +0,0 @@
-/* Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- *
- * Misc functions which need access to vb2_context but are not public APIs
- */
-
-#include "2api.h"
-#include "2common.h"
-#include "2misc.h"
-#include "2nvstorage.h"
-#include "2rsa.h"
-#include "2secdata.h"
-#include "2sha.h"
-#include "2sysincludes.h"
-#include "vb21_common.h"
-
-/**
- * Read an object with a common struct header from a verified boot resource.
- *
- * On success, an object buffer will be allocated in the work buffer, the
- * object will be stored into the buffer, and *buf_ptr will point to the
- * object.
- *
- * @param ctx Vboot context
- * @param index Resource index to read
- * @param offset Byte offset within resource to start at
- * @param buf_ptr Destination for object pointer
- * @return VB2_SUCCESS, or error code on error.
- */
-static vb2_error_t vb21_read_resource_object(struct vb2_context *ctx,
- enum vb2_resource_index index,
- uint32_t offset,
- struct vb2_workbuf *wb,
- void **buf_ptr)
-{
- struct vb21_struct_common c;
- void *buf;
- vb2_error_t rv;
-
- *buf_ptr = NULL;
-
- /* Read the common header */
- rv = vb2ex_read_resource(ctx, index, offset, &c, sizeof(c));
- if (rv)
- return rv;
-
- /* Allocate a buffer for the object, now that we know how big it is */
- buf = vb2_workbuf_alloc(wb, c.total_size);
- if (!buf)
- return VB2_ERROR_READ_RESOURCE_OBJECT_BUF;
-
- /* Read the object */
- rv = vb2ex_read_resource(ctx, index, offset, buf, c.total_size);
- if (rv) {
- vb2_workbuf_free(wb, c.total_size);
- return rv;
- }
-
- /* Save the pointer */
- *buf_ptr = buf;
- return VB2_SUCCESS;
-}
-
-vb2_error_t vb21_load_fw_keyblock(struct vb2_context *ctx)
-{
- struct vb2_shared_data *sd = vb2_get_sd(ctx);
- struct vb2_gbb_header *gbb = vb2_get_gbb(ctx);
- struct vb2_workbuf wb;
-
- uint8_t *key_data;
- uint32_t key_size;
- struct vb21_packed_key *packed_key;
- struct vb2_public_key root_key;
- struct vb21_keyblock *kb;
-
- vb2_error_t rv;
-
- vb2_workbuf_from_ctx(ctx, &wb);
-
- /* Read the root key */
- key_size = gbb->rootkey_size;
- key_data = vb2_workbuf_alloc(&wb, key_size);
- if (!key_data)
- return VB2_ERROR_FW_KEYBLOCK_WORKBUF_ROOT_KEY;
-
- rv = vb2ex_read_resource(ctx, VB2_RES_GBB, gbb->rootkey_offset,
- key_data, key_size);
- if (rv)
- return rv;
-
- /* Unpack the root key */
- rv = vb21_unpack_key(&root_key, key_data, key_size);
- if (rv)
- return rv;
-
- /*
- * Load the firmware keyblock common header into the work buffer after
- * the root key.
- */
- rv = vb21_read_resource_object(ctx, VB2_RES_FW_VBLOCK, 0, &wb,
- (void **)&kb);
- if (rv)
- return rv;
-
- /* Verify the keyblock */
- rv = vb21_verify_keyblock(kb, kb->c.total_size, &root_key, &wb);
- if (rv) {
- vb2api_fail(ctx, VB2_RECOVERY_FW_KEYBLOCK, rv);
- return rv;
- }
-
- /* Preamble follows the keyblock in the vblock */
- sd->vblock_preamble_offset = kb->c.total_size;
-
- packed_key = (struct vb21_packed_key *)((uint8_t *)kb + kb->key_offset);
-
- /* Key version is the upper 16 bits of the composite firmware version */
- if (packed_key->key_version > 0xffff)
- rv = VB2_ERROR_FW_KEYBLOCK_VERSION_RANGE;
- if (!rv && packed_key->key_version < (sd->fw_version_secdata >> 16)) {
- if (gbb->flags & VB2_GBB_FLAG_DISABLE_FW_ROLLBACK_CHECK)
- VB2_DEBUG("Ignoring FW key rollback due to GBB flag\n");
- else
- rv = VB2_ERROR_FW_KEYBLOCK_VERSION_ROLLBACK;
- }
- if (rv) {
- vb2api_fail(ctx, VB2_RECOVERY_FW_KEY_ROLLBACK, rv);
- return rv;
- }
-
- sd->fw_version = packed_key->key_version << 16;
-
- /*
- * Save the data key in the work buffer. This overwrites the root key
- * we read above. That's ok, because now that we have the data key we
- * no longer need the root key.
- *
- * Use memmove() instead of memcpy(). In theory, the destination will
- * never overlap with the source because the root key is likely to be
- * at least as large as the data key, but there's no harm here in being
- * paranoid.
- */
- memmove(key_data, packed_key, packed_key->c.total_size);
- packed_key = (struct vb21_packed_key *)key_data;
-
- /* Save the packed key offset and size */
- sd->data_key_offset = vb2_offset_of(sd, key_data);
- sd->data_key_size = packed_key->c.total_size;
-
- /* Data key will persist in the workbuf after we return */
- vb2_set_workbuf_used(ctx, sd->data_key_offset + sd->data_key_size);
-
- return VB2_SUCCESS;
-}
-
-vb2_error_t vb21_load_fw_preamble(struct vb2_context *ctx)
-{
- struct vb2_shared_data *sd = vb2_get_sd(ctx);
- struct vb2_gbb_header *gbb = vb2_get_gbb(ctx);
- struct vb2_workbuf wb;
-
- uint8_t *key_data = vb2_member_of(sd, sd->data_key_offset);
- uint32_t key_size = sd->data_key_size;
- struct vb2_public_key data_key;
-
- /* Preamble goes in the next unused chunk of work buffer */
- struct vb21_fw_preamble *pre;
-
- vb2_error_t rv;
-
- vb2_workbuf_from_ctx(ctx, &wb);
-
- /* Unpack the firmware data key */
- if (!sd->data_key_size)
- return VB2_ERROR_FW_PREAMBLE2_DATA_KEY;
-
- rv = vb21_unpack_key(&data_key, key_data, key_size);
- if (rv)
- return rv;
-
- /* Load the firmware preamble */
- rv = vb21_read_resource_object(ctx, VB2_RES_FW_VBLOCK,
- sd->vblock_preamble_offset, &wb,
- (void **)&pre);
- if (rv)
- return rv;
-
- /* Work buffer now contains the data subkey data and the preamble */
-
- /* Verify the preamble */
- rv = vb21_verify_fw_preamble(pre, pre->c.total_size, &data_key, &wb);
- if (rv) {
- vb2api_fail(ctx, VB2_RECOVERY_FW_PREAMBLE, rv);
- return rv;
- }
-
- /* Move the preamble down now that the data key is no longer used */
- memmove(key_data, pre, pre->c.total_size);
- pre = (struct vb21_fw_preamble *)key_data;
-
- /* Data key is now gone */
- sd->data_key_offset = sd->data_key_size = 0;
-
- /*
- * Firmware version is the lower 16 bits of the composite firmware
- * version.
- */
- if (pre->fw_version > 0xffff)
- rv = VB2_ERROR_FW_PREAMBLE_VERSION_RANGE;
- /* Combine with the key version from vb2_load_fw_keyblock() */
- sd->fw_version |= pre->fw_version;
- if (!rv && sd->fw_version < sd->fw_version_secdata) {
- if (gbb->flags & VB2_GBB_FLAG_DISABLE_FW_ROLLBACK_CHECK)
- VB2_DEBUG("Ignoring FW rollback due to GBB flag\n");
- else
- rv = VB2_ERROR_FW_PREAMBLE_VERSION_ROLLBACK;
- }
- if (rv) {
- vb2api_fail(ctx, VB2_RECOVERY_FW_ROLLBACK, rv);
- return rv;
- }
-
- /*
- * If this is a newer version than in secure storage, and we
- * successfully booted the same slot last boot, roll forward the
- * version in secure storage.
- */
- if (sd->fw_version > sd->fw_version_secdata &&
- sd->last_fw_slot == sd->fw_slot &&
- sd->last_fw_result == VB2_FW_RESULT_SUCCESS) {
- sd->fw_version_secdata = sd->fw_version;
- vb2_secdata_firmware_set(ctx, VB2_SECDATA_FIRMWARE_VERSIONS,
- sd->fw_version);
- }
-
- /* Keep track of where we put the preamble */
- sd->preamble_offset = vb2_offset_of(sd, pre);
- sd->preamble_size = pre->c.total_size;
-
- /* Preamble will persist in work buffer after we return */
- vb2_set_workbuf_used(ctx, sd->preamble_offset + sd->preamble_size);
-
- return VB2_SUCCESS;
-}