summaryrefslogtreecommitdiff
path: root/firmware/2lib/include
diff options
context:
space:
mode:
authorJoel Kitching <kitching@google.com>2019-07-25 18:26:18 +0800
committerCommit Bot <commit-bot@chromium.org>2019-11-13 06:14:05 +0000
commitecdca931ae0637d1a9498f64862939bd5bb99e0b (patch)
treefac935a23124d281c72b765333cedaca446bb1e4 /firmware/2lib/include
parent87276ffed46b3c64ff62153ac8599a79b9bcb683 (diff)
downloadvboot-ecdca931ae0637d1a9498f64862939bd5bb99e0b.tar.gz
vboot: move vb2_context inside vb2_shared_data (persistent context)
Move vb2_context to live inside of vb2_shared_data, instead of in a separate memory space allocated by the caller. See design doc: http://go/vboot2-persistent-context BUG=b:124141368, chromium:994060 TEST=make clean && make runtests BRANCH=none Change-Id: If2421756572a43ba58b9da9f00e56a8f26ad3ad5 Signed-off-by: Joel Kitching <kitching@google.com> Cq-Depend: chromium:1874753, chromium:1902339 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/1716351 Tested-by: Joel Kitching <kitching@chromium.org> Commit-Queue: Julius Werner <jwerner@chromium.org> Reviewed-by: Joel Kitching <kitching@chromium.org> Reviewed-by: Julius Werner <jwerner@chromium.org>
Diffstat (limited to 'firmware/2lib/include')
-rw-r--r--firmware/2lib/include/2api.h109
-rw-r--r--firmware/2lib/include/2misc.h18
-rw-r--r--firmware/2lib/include/2return_codes.h11
-rw-r--r--firmware/2lib/include/2struct.h27
4 files changed, 109 insertions, 56 deletions
diff --git a/firmware/2lib/include/2api.h b/firmware/2lib/include/2api.h
index 9aa031a9..0a713265 100644
--- a/firmware/2lib/include/2api.h
+++ b/firmware/2lib/include/2api.h
@@ -196,29 +196,33 @@ enum vb2_context_flags {
VB2_CONTEXT_NO_SECDATA_FWMP = (1 << 21),
};
+/* Helper for aligning fields in vb2_context. */
+#define VB2_PAD_STRUCT3(size, align, count) \
+ uint8_t _pad##count[align - (((size - 1) % align) + 1)]
+#define VB2_PAD_STRUCT2(size, align, count) VB2_PAD_STRUCT3(size, align, count)
+#define VB2_PAD_STRUCT(size, align) VB2_PAD_STRUCT2(size, align, __COUNTER__)
+
/*
* Context for firmware verification. Pass this to all vboot APIs.
*
- * Caller may relocate this between calls to vboot APIs.
+ * Context is stored as part of vb2_shared_data, initialized with vb2api_init().
+ * Subsequent retrieval of the context object should be done by calling
+ * vb2api_reinit(), e.g. if switching firmware applications.
+ *
+ * The context struct can be seen as the "publicly accessible" portion of
+ * vb2_shared_data, and thus does not require its own magic and version fields.
*/
struct vb2_context {
+
/**********************************************************************
- * Fields which must be initialized by caller.
+ * Fields caller must initialize before calling any API functions.
*/
/*
* Flags; see vb2_context_flags. Some flags may only be set by caller
* prior to calling vboot functions.
*/
- uint32_t flags;
-
- /*
- * Work buffer, and length in bytes. Caller may relocate this between
- * calls to vboot APIs; it contains no internal pointers. Caller must
- * not examine the contents of this work buffer directly.
- */
- uint8_t *workbuf;
- uint32_t workbuf_size;
+ uint64_t flags;
/*
* Non-volatile data. Caller must fill this from some non-volatile
@@ -228,6 +232,7 @@ struct vb2_context {
* and then clear the flag.
*/
uint8_t nvdata[VB2_NVDATA_SIZE_V2];
+ VB2_PAD_STRUCT(VB2_NVDATA_SIZE_V2, 8);
/*
* Secure data for firmware verification stage. Caller must fill this
@@ -237,26 +242,7 @@ struct vb2_context {
* secure non-volatile location and then clear the flag.
*/
uint8_t secdata_firmware[VB2_SECDATA_FIRMWARE_SIZE];
-
- /*
- * Context pointer for use by caller. Verified boot never looks at
- * this. Put context here if you need it for APIs that verified boot
- * may call (vb2ex_...() functions).
- */
- void *non_vboot_context;
-
- /**********************************************************************
- * Fields caller may examine after calling vb2api_fw_phase1(). Caller
- * must set these fields to 0 before calling any vboot functions.
- */
-
- /*
- * Amount of work buffer used so far. Verified boot sub-calls use
- * this to know where the unused work area starts. Caller may use
- * this between calls to vboot APIs to know how much data must be
- * copied when relocating the work buffer.
- */
- uint32_t workbuf_used;
+ VB2_PAD_STRUCT(VB2_SECDATA_FIRMWARE_SIZE, 8);
/**********************************************************************
* Fields caller must initialize before calling vb2api_kernel_phase1().
@@ -270,6 +256,7 @@ struct vb2_context {
* to the secure non-volatile location and then clear the flag.
*/
uint8_t secdata_kernel[VB2_SECDATA_KERNEL_SIZE];
+ VB2_PAD_STRUCT(VB2_SECDATA_KERNEL_SIZE, 8);
/*
* Firmware management parameters (FWMP) secure data. Caller must fill
@@ -282,6 +269,7 @@ struct vb2_context {
* location and then clear the flag.
*/
uint8_t secdata_fwmp[VB2_SECDATA_FWMP_MAX_SIZE];
+ VB2_PAD_STRUCT(VB2_SECDATA_FWMP_MAX_SIZE, 8);
};
/* Resource index for vb2ex_read_resource() */
@@ -426,6 +414,65 @@ enum vb2_pcr_digest {
*/
/**
+ * Initialize verified boot data structures.
+ *
+ * Needs to be called once per boot, before using any API functions that
+ * accept a vb2_context object. Sets up the vboot work buffer, as well as
+ * vb2_shared_data and vb2_context. A pointer to the context object is
+ * written to ctxptr. After transitioning between different firmware
+ * applications, or any time the context pointer is lost, vb2api_reinit()
+ * should be used to restore access to the context and data on the workbuf.
+ *
+ * If the workbuf needs to be relocated, call vb2api_relocate() instead
+ * of copying memory manually.
+ *
+ * @param workbuf Workbuf memory location to initialize
+ * @param size Size of workbuf being initialized
+ * @param ctxptr Pointer to a context pointer to be filled in
+ * @return VB2_SUCCESS, or non-zero error code.
+ */
+vb2_error_t vb2api_init(void *workbuf, uint32_t size,
+ struct vb2_context **ctxptr);
+
+/**
+ * Reinitialize vboot data structures.
+ *
+ * After transitioning between different firmware applications, or any time the
+ * context pointer is lost, this function should be called to restore access to
+ * the workbuf. A pointer to the context object is written to ctxptr. Returns
+ * an error if the vboot work buffer is inconsistent.
+ *
+ * If the workbuf needs to be relocated, call vb2api_relocate() instead
+ * of copying memory manually.
+ *
+ * @param workbuf Workbuf memory location to check
+ * @param ctxptr Pointer to a context pointer to be filled in
+ * @return VB2_SUCCESS, or non-zero error code.
+ */
+vb2_error_t vb2api_reinit(void *workbuf, struct vb2_context **ctxptr);
+
+/**
+ * Relocate vboot data structures.
+ *
+ * Move the vboot work buffer from one memory location to another, and expand
+ * or contract the workbuf to fit. The target memory location may be the same
+ * as the original (used for a "resize" operation), and it is safe to call this
+ * function with overlapping memory regions.
+ *
+ * A pointer to the context object is written to ctxptr. Returns an error if
+ * the vboot work buffer is inconsistent, or if the new memory space is too
+ * small to contain the work buffer.
+ *
+ * @param new_workbuf Target workbuf memory location
+ * @param cur_workbuf Original workbuf memory location to relocate
+ * @param size Target size of relocated workbuf
+ * @param ctxptr Pointer to a context pointer to be filled in
+ * @return VB2_SUCCESS, or non-zero error code.
+ */
+vb2_error_t vb2api_relocate(void *new_workbuf, void *cur_workbuf, uint32_t size,
+ struct vb2_context **ctxptr);
+
+/**
* Check the validity of firmware secure storage context.
*
* Checks version and CRC.
diff --git a/firmware/2lib/include/2misc.h b/firmware/2lib/include/2misc.h
index 5ce10705..d9be9730 100644
--- a/firmware/2lib/include/2misc.h
+++ b/firmware/2lib/include/2misc.h
@@ -14,6 +14,10 @@
struct vb2_gbb_header;
struct vb2_workbuf;
+#define vb2_container_of(ptr, type, member) ({ \
+ const typeof(((type *)0)->member) *__mptr = (ptr); \
+ (type *)((uint8_t *)__mptr - offsetof(type, member) );}) \
+
/**
* Get the shared data pointer from the vboot context
*
@@ -22,7 +26,7 @@ struct vb2_workbuf;
*/
static inline struct vb2_shared_data *vb2_get_sd(struct vb2_context *ctx)
{
- return (struct vb2_shared_data *)ctx->workbuf;
+ return vb2_container_of(ctx, struct vb2_shared_data, ctx);
}
/**
@@ -73,18 +77,6 @@ vb2_error_t vb2_read_gbb_header(struct vb2_context *ctx,
struct vb2_gbb_header *gbb);
/**
- * Set up the verified boot context data, if not already set up.
- *
- * This uses ctx->workbuf_used=0 as a flag to indicate that the data has not
- * yet been set up. Caller must set that before calling any vboot functions;
- * see 2api.h.
- *
- * @param ctx Vboot context to initialize
- * @return VB2_SUCCESS, or error code on error.
- */
-vb2_error_t vb2_init_context(struct vb2_context *ctx);
-
-/**
* Check for recovery reasons we can determine early in the boot process.
*
* On exit, check ctx->flags for VB2_CONTEXT_RECOVERY_MODE; if present, jump to
diff --git a/firmware/2lib/include/2return_codes.h b/firmware/2lib/include/2return_codes.h
index 49ee50ab..9f6a54cd 100644
--- a/firmware/2lib/include/2return_codes.h
+++ b/firmware/2lib/include/2return_codes.h
@@ -454,11 +454,11 @@ enum vb2_return_code {
*/
VB2_ERROR_MISC = VB2_ERROR_BASE + 0x080000,
- /* Work buffer too small in vb2_init_context() */
- VB2_ERROR_INITCTX_WORKBUF_SMALL,
+ /* Work buffer too small (see vb2api_init and vb2api_reinit) */
+ VB2_ERROR_WORKBUF_SMALL,
- /* Work buffer unaligned in vb2_init_context() */
- VB2_ERROR_INITCTX_WORKBUF_ALIGN,
+ /* Work buffer unaligned (see vb2api_init and vb2api_reinit) */
+ VB2_ERROR_WORKBUF_ALIGN,
/* Work buffer too small in GBB-related function */
VB2_ERROR_GBB_WORKBUF,
@@ -608,6 +608,9 @@ enum vb2_return_code {
/* Invalid parameter */
VB2_ERROR_INVALID_PARAMETER,
+ /* Problem with workbuf validity (see vb2api_init and vb2api_reinit) */
+ VB2_ERROR_WORKBUF_INVALID,
+
/**********************************************************************
* API-level errors
*/
diff --git a/firmware/2lib/include/2struct.h b/firmware/2lib/include/2struct.h
index 8fa0254b..a7bd481b 100644
--- a/firmware/2lib/include/2struct.h
+++ b/firmware/2lib/include/2struct.h
@@ -16,17 +16,11 @@
#ifndef VBOOT_REFERENCE_2STRUCT_H_
#define VBOOT_REFERENCE_2STRUCT_H_
+#include "2api.h"
#include "2constants.h"
#include "2crypto.h"
#include "2sysincludes.h"
-/* "V2CT" = vb2_context.magic */
-#define VB2_CONTEXT_MAGIC 0x54433256
-
-/* Current version of vb2_context struct */
-#define VB2_CONTEXT_VERSION_MAJOR 1
-#define VB2_CONTEXT_VERSION_MINOR 0
-
/* Flags for vb2_shared_data.flags */
enum vb2_shared_data_flags {
/* User has explicitly and physically requested recovery */
@@ -81,9 +75,11 @@ enum vb2_shared_data_status {
#define VB2_SHARED_DATA_MAGIC 0x44533256
/* Current version of vb2_shared_data struct */
-#define VB2_SHARED_DATA_VERSION_MAJOR 1
+#define VB2_SHARED_DATA_VERSION_MAJOR 2
#define VB2_SHARED_DATA_VERSION_MINOR 0
+#define VB2_CONTEXT_MAX_SIZE 192
+
/*
* Data shared between vboot API calls. Stored at the start of the work
* buffer.
@@ -96,6 +92,21 @@ struct vb2_shared_data {
uint16_t struct_version_major;
uint16_t struct_version_minor;
+ /* Public fields are stored in the context object */
+ struct vb2_context ctx;
+
+ /* Padding for adding future vb2_context fields */
+ uint8_t padding[VB2_CONTEXT_MAX_SIZE - sizeof(struct vb2_context)];
+
+ /* Work buffer length in bytes. */
+ uint32_t workbuf_size;
+
+ /*
+ * Amount of work buffer used so far. Verified boot sub-calls use
+ * this to know where the unused work area starts.
+ */
+ uint32_t workbuf_used;
+
/* Flags; see enum vb2_shared_data_flags */
uint32_t flags;