/* SPDX-License-Identifier: BSD-3-Clause */ /* * Taken from https://chromium.googlesource.com/chromiumos/platform/vboot * * 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. */ /* * Size of non-volatile data used by vboot. * * If you only support non-volatile data format V1, then use VB2_NVDATA_SIZE. * If you support V2, use VB2_NVDATA_SIZE_V2 and set context flag * VB2_CONTEXT_NVDATA_V2. */ #define VB2_NVDATA_SIZE 16 #define VB2_NVDATA_SIZE_V2 64 /* Size of secure data spaces used by vboot */ #define VB2_SECDATA_FIRMWARE_SIZE 10 #define VB2_SECDATA_KERNEL_SIZE_V02 13 #define VB2_SECDATA_KERNEL_SIZE_V10 40 #define VB2_SECDATA_KERNEL_MIN_SIZE 13 #define VB2_SECDATA_KERNEL_MAX_SIZE 64 #define VB2_SECDATA_FWMP_MIN_SIZE 40 #define VB2_SECDATA_FWMP_MAX_SIZE 64 /* Helper for aligning fields in vb2_context. */ #define VB2_PAD_STRUCT3(size, align, count) \ u8 _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__) /* MAX_SIZE should not be changed without bumping up DATA_VERSION_MAJOR. */ #define VB2_CONTEXT_MAX_SIZE 384 /* * Context for firmware verification. Pass this to all 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 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. */ u64 flags; /* * Non-volatile data. Caller must fill this from some non-volatile * location before calling vb2api_fw_phase1. If the * VB2_CONTEXT_NVDATA_CHANGED flag is set when a vb2api function * returns, caller must save the data back to the non-volatile location * and then clear the flag. */ u8 nvdata[VB2_NVDATA_SIZE_V2]; VB2_PAD_STRUCT(VB2_NVDATA_SIZE_V2, 8); /* * Secure data for firmware verification stage. Caller must fill this * from some secure non-volatile location before calling * vb2api_fw_phase1. If the VB2_CONTEXT_SECDATA_FIRMWARE_CHANGED flag * is set when a function returns, caller must save the data back to the * secure non-volatile location and then clear the flag. */ u8 secdata_firmware[VB2_SECDATA_FIRMWARE_SIZE]; VB2_PAD_STRUCT(VB2_SECDATA_FIRMWARE_SIZE, 8); /********************************************************************** * Fields caller must initialize before calling vb2api_kernel_phase1(). */ /* * Secure data for kernel verification stage. Caller must fill this * from some secure non-volatile location before calling * vb2api_kernel_phase1. If the VB2_CONTEXT_SECDATA_KERNEL_CHANGED * flag is set when a function returns, caller must save the data back * to the secure non-volatile location and then clear the flag. */ u8 secdata_kernel[VB2_SECDATA_KERNEL_MAX_SIZE]; VB2_PAD_STRUCT(VB2_SECDATA_KERNEL_MAX_SIZE, 8); /* * Firmware management parameters (FWMP) secure data. Caller must fill * this from some secure non-volatile location before calling * vb2api_kernel_phase1. Since FWMP is a variable-size space, caller * should initially fill in VB2_SECDATA_FWMP_MIN_SIZE bytes, and call * vb2_secdata_fwmp_check() to see whether more should be read. If the * VB2_CONTEXT_SECDATA_FWMP_CHANGED flag is set when a function * returns, caller must save the data back to the secure non-volatile * location and then clear the flag. */ u8 secdata_fwmp[VB2_SECDATA_FWMP_MAX_SIZE]; VB2_PAD_STRUCT(VB2_SECDATA_FWMP_MAX_SIZE, 8); /* * 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; }; /* * Data shared between vboot API calls. Stored at the start of the work * buffer. */ struct vb2_shared_data { /* Magic number for struct (VB2_SHARED_DATA_MAGIC) */ u32 magic; /* Version of this structure */ u16 struct_version_major; u16 struct_version_minor; /* Public fields are stored in the context object */ struct vb2_context ctx; /* Padding for adding future vb2_context fields */ u8 padding[VB2_CONTEXT_MAX_SIZE - sizeof(struct vb2_context)]; /* Work buffer length in bytes. */ u32 workbuf_size; /* * Amount of work buffer used so far. Verified boot sub-calls use * this to know where the unused work area starts. */ u32 workbuf_used; /* Flags; see enum vb2_shared_data_flags */ u32 flags; /* * Reason we are in recovery mode this boot (enum vb2_nv_recovery), or * 0 if we aren't. */ u32 recovery_reason; /* Firmware slot used last boot (0=A, 1=B) */ u32 last_fw_slot; /* Result of last boot (enum vb2_fw_result) */ u32 last_fw_result; /* Firmware slot used this boot */ u32 fw_slot; /* * Version for this slot (top 16 bits = key, lower 16 bits = firmware). * * TODO: Make this a union to allow getting/setting those versions * separately? */ u32 fw_version; /* Version from secdata_firmware (must be <= fw_version to boot). */ u32 fw_version_secdata; /* * Status flags for this boot; see enum vb2_shared_data_status. Status * is "what we've done"; flags above are "decisions we've made". */ u32 status; /* Offset from start of this struct to GBB header */ u32 gbb_offset; /********************************************************************** * Data from kernel verification stage. * * TODO: shouldn't be part of the main struct, since that needlessly * uses more memory during firmware verification. */ /* * Version for the current kernel (top 16 bits = key, lower 16 bits = * kernel preamble). * * TODO: Make this a union to allow getting/setting those versions * separately? */ u32 kernel_version; /* Version from secdata_kernel (must be <= kernel_version to boot) */ u32 kernel_version_secdata; /********************************************************************** * Temporary variables used during firmware verification. These don't * really need to persist through to the OS, but there's nowhere else * we can put them. */ /* Offset of preamble from start of vblock */ u32 vblock_preamble_offset; /* * Offset and size of packed data key in work buffer. Size is 0 if * data key is not stored in the work buffer. */ u32 data_key_offset; u32 data_key_size; /* * Offset and size of firmware preamble in work buffer. Size is 0 if * preamble is not stored in the work buffer. */ u32 preamble_offset; u32 preamble_size; /* * Offset and size of hash context in work buffer. Size is 0 if * hash context is not stored in the work buffer. */ u32 hash_offset; u32 hash_size; /* * Current tag we're hashing * * For new structs, this is the offset of the vb2_signature struct * in the work buffer. * * TODO: rename to hash_sig_offset when vboot1 structs are deprecated. */ u32 hash_tag; /* Amount of data we still expect to hash */ u32 hash_remaining_size; /********************************************************************** * Temporary variables used during kernel verification. These don't * really need to persist through to the OS, but there's nowhere else * we can put them. * * TODO: make a union with the firmware verification temp variables, * or make both of them workbuf-allocated sub-structs, so that we can * overlap them so kernel variables don't bloat firmware verification * stage memory requirements. */ /* * Formerly a pointer to vboot1 shared data header ("VBSD"). Caller * may now export a copy of VBSD via vb2api_export_vbsd(). * TODO: Remove this field and bump struct_version_major. */ uintptr_t reserved0; /* * Offset and size of packed kernel key in work buffer. Size is 0 if * subkey is not stored in the work buffer. Note that kernel key may * be inside the firmware preamble. */ u32 kernel_key_offset; u32 kernel_key_size; } __packed;