Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 | /* 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; |