diff options
author | Joel Kitching <kitching@google.com> | 2019-07-25 18:26:18 +0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2019-11-13 06:14:05 +0000 |
commit | ecdca931ae0637d1a9498f64862939bd5bb99e0b (patch) | |
tree | fac935a23124d281c72b765333cedaca446bb1e4 /firmware/2lib/include | |
parent | 87276ffed46b3c64ff62153ac8599a79b9bcb683 (diff) | |
download | vboot-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.h | 109 | ||||
-rw-r--r-- | firmware/2lib/include/2misc.h | 18 | ||||
-rw-r--r-- | firmware/2lib/include/2return_codes.h | 11 | ||||
-rw-r--r-- | firmware/2lib/include/2struct.h | 27 |
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; |