• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
2  * Use of this source code is governed by a BSD-style license that can be
3  * found in the LICENSE file.
4  *
5  * Data structure definitions for verified boot, for on-disk / in-eeprom
6  * data.
7  */
8 
9 #ifndef VBOOT_REFERENCE_VBOOT_STRUCT_H_
10 #define VBOOT_REFERENCE_VBOOT_STRUCT_H_
11 #include <stdint.h>
12 
13 /* Public key data */
14 typedef struct VbPublicKey {
15 	/* Offset of key data from start of this struct */
16 	uint64_t key_offset;
17 	/* Size of key data in bytes (NOT strength of key in bits) */
18 	uint64_t key_size;
19 	/* Signature algorithm used by the key */
20 	uint64_t algorithm;
21 	/* Key version */
22 	uint64_t key_version;
23 } __attribute__((packed)) VbPublicKey;
24 
25 #define EXPECTED_VBPUBLICKEY_SIZE 32
26 
27 /* Signature data (a secure hash, possibly signed) */
28 typedef struct VbSignature {
29 	/* Offset of signature data from start of this struct */
30 	uint64_t sig_offset;
31 	/* Size of signature data in bytes */
32 	uint64_t sig_size;
33 	/* Size of the data block which was signed in bytes */
34 	uint64_t data_size;
35 } __attribute__((packed)) VbSignature;
36 
37 #define EXPECTED_VBSIGNATURE_SIZE 24
38 
39 #define KEY_BLOCK_MAGIC "CHROMEOS"
40 #define KEY_BLOCK_MAGIC_SIZE 8
41 
42 #define KEY_BLOCK_HEADER_VERSION_MAJOR 2
43 #define KEY_BLOCK_HEADER_VERSION_MINOR 1
44 
45 /* Flags for key_block_flags */
46 /* The following flags set where the key is valid */
47 #define KEY_BLOCK_FLAG_DEVELOPER_0  (0x01ULL) /* Developer switch off */
48 #define KEY_BLOCK_FLAG_DEVELOPER_1  (0x02ULL) /* Developer switch on */
49 #define KEY_BLOCK_FLAG_RECOVERY_0   (0x04ULL) /* Not recovery mode */
50 #define KEY_BLOCK_FLAG_RECOVERY_1   (0x08ULL) /* Recovery mode */
51 
52 /*
53  * Key block, containing the public key used to sign some other chunk of data.
54  *
55  * This should be followed by:
56  *   1) The data_key key data, pointed to by data_key.key_offset.
57  *   2) The checksum data for (VBKeyBlockHeader + data_key data), pointed to
58  *      by key_block_checksum.sig_offset.
59  *   3) The signature data for (VBKeyBlockHeader + data_key data), pointed to
60  *      by key_block_signature.sig_offset.
61  */
62 typedef struct VbKeyBlockHeader {
63 	/* Magic number */
64 	uint8_t magic[KEY_BLOCK_MAGIC_SIZE];
65 	/* Version of this header format */
66 	uint32_t header_version_major;
67 	/* Version of this header format */
68 	uint32_t header_version_minor;
69 	/*
70 	 * Length of this entire key block, including keys, signatures, and
71 	 * padding, in bytes
72 	 */
73 	uint64_t key_block_size;
74 	/*
75 	 * Signature for this key block (header + data pointed to by data_key)
76 	 * For use with signed data keys
77 	 */
78 	VbSignature key_block_signature;
79 	/*
80 	 * SHA-512 checksum for this key block (header + data pointed to by
81 	 * data_key) For use with unsigned data keys
82 	 */
83 	VbSignature key_block_checksum;
84 	/* Flags for key (KEY_BLOCK_FLAG_*) */
85 	uint64_t key_block_flags;
86 	/* Key to verify the chunk of data */
87 	VbPublicKey data_key;
88 } __attribute__((packed)) VbKeyBlockHeader;
89 
90 #define EXPECTED_VBKEYBLOCKHEADER_SIZE 112
91 
92 /****************************************************************************/
93 
94 #define FIRMWARE_PREAMBLE_HEADER_VERSION_MAJOR 2
95 #define FIRMWARE_PREAMBLE_HEADER_VERSION_MINOR 1
96 
97 /*
98  * Preamble block for rewritable firmware, version 2.0.  All 2.x versions of
99  * this struct must start with the same data, to be compatible with version 2.0
100  * readers.
101  */
102 typedef struct VbFirmwarePreambleHeader2_0 {
103 	/*
104 	 * Size of this preamble, including keys, signatures, and padding, in
105 	 * bytes
106 	 */
107 	uint64_t preamble_size;
108 	/*
109 	 * Signature for this preamble (header + kernel subkey + body
110 	 * signature)
111 	 */
112 	VbSignature preamble_signature;
113 	/* Version of this header format (= 2) */
114 	uint32_t header_version_major;
115 	/* Version of this header format (= 0) */
116 	uint32_t header_version_minor;
117 
118 	/* Firmware version */
119 	uint64_t firmware_version;
120 	/* Key to verify kernel key block */
121 	VbPublicKey kernel_subkey;
122 	/* Signature for the firmware body */
123 	VbSignature body_signature;
124 } __attribute__((packed)) VbFirmwarePreambleHeader2_0;
125 
126 #define EXPECTED_VBFIRMWAREPREAMBLEHEADER2_0_SIZE 104
127 
128 /* Flags for VbFirmwarePreambleHeader.flags */
129 /*
130  * Use the normal/dev boot path from the read-only firmware, instead of
131  * verifying the body signature.
132  */
133 #define VB_FIRMWARE_PREAMBLE_USE_RO_NORMAL 0x00000001
134 
135 /* Premable block for rewritable firmware, version 2.1.
136  *
137  * The firmware preamble header should be followed by:
138  *   1) The kernel_subkey key data, pointed to by kernel_subkey.key_offset.
139  *   2) The signature data for the firmware body, pointed to by
140  *      body_signature.sig_offset.
141  *   3) The signature data for (header + kernel_subkey data + body signature
142  *      data), pointed to by preamble_signature.sig_offset.
143  */
144 typedef struct VbFirmwarePreambleHeader {
145 	/*
146 	 * Size of this preamble, including keys, signatures, and padding, in
147 	 * bytes
148 	 */
149 	uint64_t preamble_size;
150 	/*
151 	 * Signature for this preamble (header + kernel subkey + body
152 	 * signature)
153 	 */
154 	VbSignature preamble_signature;
155 	/* Version of this header format */
156 	uint32_t header_version_major;
157 	/* Version of this header format */
158 	uint32_t header_version_minor;
159 
160 	/* Firmware version */
161 	uint64_t firmware_version;
162 	/* Key to verify kernel key block */
163 	VbPublicKey kernel_subkey;
164 	/* Signature for the firmware body */
165 	VbSignature body_signature;
166 
167 	/*
168 	 * Fields added in header version 2.1.  You must verify the header
169 	 * version before reading these fields!
170 	 */
171 	/*
172 	 * Flags; see VB_FIRMWARE_PREAMBLE_*.  Readers should return 0 for
173 	 * header version < 2.1.
174 	 */
175 	uint32_t flags;
176 } __attribute__((packed)) VbFirmwarePreambleHeader;
177 
178 #define EXPECTED_VBFIRMWAREPREAMBLEHEADER2_1_SIZE 108
179 
180 /****************************************************************************/
181 
182 #define KERNEL_PREAMBLE_HEADER_VERSION_MAJOR 2
183 #define KERNEL_PREAMBLE_HEADER_VERSION_MINOR 2
184 
185 /* Preamble block for kernel, version 2.0
186  *
187  * This should be followed by:
188  *   1) The signature data for the kernel body, pointed to by
189  *      body_signature.sig_offset.
190  *   2) The signature data for (VBFirmwarePreambleHeader + body signature
191  *      data), pointed to by preamble_signature.sig_offset.
192  */
193 typedef struct VbKernelPreambleHeader2_0 {
194 	/*
195 	 * Size of this preamble, including keys, signatures, and padding, in
196 	 * bytes
197 	 */
198 	uint64_t preamble_size;
199 	/* Signature for this preamble (header + body signature) */
200 	VbSignature preamble_signature;
201 	/* Version of this header format */
202 	uint32_t header_version_major;
203 	/* Version of this header format */
204 	uint32_t header_version_minor;
205 
206 	/* Kernel version */
207 	uint64_t kernel_version;
208 	/* Load address for kernel body */
209 	uint64_t body_load_address;
210 	/* Address of bootloader, after body is loaded at body_load_address */
211 	uint64_t bootloader_address;
212 	/* Size of bootloader in bytes */
213 	uint64_t bootloader_size;
214 	/* Signature for the kernel body */
215 	VbSignature body_signature;
216 } __attribute__((packed)) VbKernelPreambleHeader2_0;
217 
218 #define EXPECTED_VBKERNELPREAMBLEHEADER2_0_SIZE 96
219 
220 /* Preamble block for kernel, version 2.1
221  *
222  * This should be followed by:
223  *   1) The signature data for the kernel body, pointed to by
224  *      body_signature.sig_offset.
225  *   2) The signature data for (VBFirmwarePreambleHeader + body signature
226  *      data), pointed to by preamble_signature.sig_offset.
227  *   3) The 16-bit vmlinuz header, which is used for reconstruction of
228  *      vmlinuz image.
229  */
230 typedef struct VbKernelPreambleHeader {
231 	/*
232 	 * Size of this preamble, including keys, signatures, vmlinuz header,
233 	 * and padding, in bytes
234 	 */
235 	uint64_t preamble_size;
236 	/* Signature for this preamble (header + body signature) */
237 	VbSignature preamble_signature;
238 	/* Version of this header format */
239 	uint32_t header_version_major;
240 	/* Version of this header format */
241 	uint32_t header_version_minor;
242 
243 	/* Kernel version */
244 	uint64_t kernel_version;
245 	/* Load address for kernel body */
246 	uint64_t body_load_address;
247 	/* Address of bootloader, after body is loaded at body_load_address */
248 	uint64_t bootloader_address;
249 	/* Size of bootloader in bytes */
250 	uint64_t bootloader_size;
251 	/* Signature for the kernel body */
252 	VbSignature body_signature;
253 	/*
254 	 * Fields added in header version 2.1.  You must verify the header
255 	 * version before reading these fields!
256 	 */
257 	/* Address of 16-bit header for vmlinuz reassembly.  Readers should
258 	   return 0 for header version < 2.1 */
259 	uint64_t vmlinuz_header_address;
260 	/* Size of 16-bit header for vmlinuz in bytes.  Readers should return 0
261 	   for header version < 2.1 */
262 	uint64_t vmlinuz_header_size;
263 	/*
264 	 * Flags passed in by the signer. Readers should return 0 for header
265 	 * version < 2.2. Flags field is currently defined as:
266 	 * [31:2] - Reserved (for future use)
267 	 * [1:0]  - Kernel image type (0b00 - CrOS, 0b01 - bootimg)
268 	 */
269 	uint32_t flags;
270 } __attribute__((packed)) VbKernelPreambleHeader;
271 
272 #define EXPECTED_VBKERNELPREAMBLEHEADER2_1_SIZE 112
273 #define EXPECTED_VBKERNELPREAMBLEHEADER2_2_SIZE 116
274 
275 /****************************************************************************/
276 
277 /* Constants and sub-structures for VbSharedDataHeader */
278 
279 /* Magic number for recognizing VbSharedDataHeader ("VbSD") */
280 #define VB_SHARED_DATA_MAGIC 0x44536256
281 
282 /* Minimum and recommended size of shared_data_blob in bytes. */
283 #define VB_SHARED_DATA_MIN_SIZE 3072
284 #define VB_SHARED_DATA_REC_SIZE 16384
285 
286 /* Flags for VbSharedDataHeader */
287 /* LoadFirmware() tried firmware B because of VbNvStorage firmware B tries */
288 #define VBSD_FWB_TRIED                  0x00000001
289 /*
290  * LoadKernel() verified the good kernel keyblock using the kernel subkey from
291  * the firmware.  If this flag is not present, it just used the hash of the
292  * kernel keyblock.
293  */
294 #define VBSD_KERNEL_KEY_VERIFIED         0x00000002
295 /* LoadFirmware() was told the developer switch was on */
296 #define VBSD_LF_DEV_SWITCH_ON            0x00000004
297 /* LoadFirmware() is requesting the read only normal/dev code path */
298 #define VBSD_LF_USE_RO_NORMAL            0x00000008
299 /* Developer switch was enabled at boot time */
300 #define VBSD_BOOT_DEV_SWITCH_ON          0x00000010
301 /* Recovery switch was enabled at boot time */
302 #define VBSD_BOOT_REC_SWITCH_ON          0x00000020
303 /* Firmware write protect was enabled at boot time */
304 #define VBSD_BOOT_FIRMWARE_WP_ENABLED    0x00000040
305 /* Boot is a S3->S0 resume, not a S5->S0 normal boot */
306 #define VBSD_BOOT_S3_RESUME              0x00000100
307 /* Read-only firmware supports the normal/developer code path */
308 #define VBSD_BOOT_RO_NORMAL_SUPPORT      0x00000200
309 /* VbInit() was told that the system has a virtual dev-switch */
310 #define VBSD_HONOR_VIRT_DEV_SWITCH       0x00000400
311 /* VbInit() was told the system supports EC software sync */
312 #define VBSD_EC_SOFTWARE_SYNC            0x00000800
313 /* VbInit() was told that the EC firmware is slow to update */
314 #define VBSD_EC_SLOW_UPDATE              0x00001000
315 /* Firmware software write protect was enabled at boot time */
316 #define VBSD_BOOT_FIRMWARE_SW_WP_ENABLED 0x00002000
317 /* VbInit() was told that the recovery button is a virtual one */
318 #define VBSD_BOOT_REC_SWITCH_VIRTUAL     0x00004000
319 /* Firmware used vboot2 for firmware selection */
320 #define VBSD_BOOT_FIRMWARE_VBOOT2        0x00008000
321 /* Firmware needs VGA Option ROM to display screens */
322 #define VBSD_OPROM_MATTERS               0x00010000
323 /* Firmware has loaded the VGA Option ROM */
324 #define VBSD_OPROM_LOADED                0x00020000
325 
326 /*
327  * Supported flags by header version.  It's ok to add new flags while keeping
328  * struct version 2 as long as flag-NOT-present is the correct value for
329  * existing hardware (Stumpy/Lumpy).
330  */
331 #define VBSD_FLAGS_VERSION_1            0x00000007  /* Alex, ZGB */
332 #define VBSD_FLAGS_VERSION_2            0x00000F7F
333 
334 /* Result codes for VbSharedDataHeader.check_fw_a_result (and b_result) */
335 #define VBSD_LF_CHECK_NOT_DONE          0
336 #define VBSD_LF_CHECK_DEV_MISMATCH      1
337 #define VBSD_LF_CHECK_REC_MISMATCH      2
338 #define VBSD_LF_CHECK_VERIFY_KEYBLOCK   3
339 #define VBSD_LF_CHECK_KEY_ROLLBACK      4
340 #define VBSD_LF_CHECK_DATA_KEY_PARSE    5
341 #define VBSD_LF_CHECK_VERIFY_PREAMBLE   6
342 #define VBSD_LF_CHECK_FW_ROLLBACK       7
343 #define VBSD_LF_CHECK_HEADER_VALID      8
344 #define VBSD_LF_CHECK_GET_FW_BODY       9
345 #define VBSD_LF_CHECK_HASH_WRONG_SIZE   10
346 #define VBSD_LF_CHECK_VERIFY_BODY       11
347 #define VBSD_LF_CHECK_VALID             12
348 /*
349  * Read-only normal path requested by firmware preamble, but unsupported by
350  * firmware.
351  */
352 #define VBSD_LF_CHECK_NO_RO_NORMAL      13
353 
354 /* Boot mode for VbSharedDataHeader.lk_boot_mode */
355 #define VBSD_LK_BOOT_MODE_RECOVERY      0
356 #define VBSD_LK_BOOT_MODE_NORMAL        1
357 #define VBSD_LK_BOOT_MODE_DEVELOPER     2
358 
359 /* Flags for VbSharedDataKernelPart.flags */
360 #define VBSD_LKP_FLAG_KEY_BLOCK_VALID   0x01
361 
362 /* Result codes for VbSharedDataKernelPart.check_result */
363 #define VBSD_LKP_CHECK_NOT_DONE           0
364 #define VBSD_LKP_CHECK_TOO_SMALL          1
365 #define VBSD_LKP_CHECK_READ_START         2
366 #define VBSD_LKP_CHECK_KEY_BLOCK_SIG      3
367 #define VBSD_LKP_CHECK_KEY_BLOCK_HASH     4
368 #define VBSD_LKP_CHECK_DEV_MISMATCH       5
369 #define VBSD_LKP_CHECK_REC_MISMATCH       6
370 #define VBSD_LKP_CHECK_KEY_ROLLBACK       7
371 #define VBSD_LKP_CHECK_DATA_KEY_PARSE     8
372 #define VBSD_LKP_CHECK_VERIFY_PREAMBLE    9
373 #define VBSD_LKP_CHECK_KERNEL_ROLLBACK    10
374 #define VBSD_LKP_CHECK_PREAMBLE_VALID     11
375 /*
376  * Body load address check is omitted; this result code is deprecated and not
377  * used anywhere in the codebase.
378  */
379 #define VBSD_LKP_CHECK_BODY_ADDRESS       12
380 #define VBSD_LKP_CHECK_BODY_OFFSET        13
381 #define VBSD_LKP_CHECK_SELF_SIGNED        14
382 #define VBSD_LKP_CHECK_BODY_EXCEEDS_MEM   15
383 #define VBSD_LKP_CHECK_BODY_EXCEEDS_PART  16
384 #define VBSD_LKP_CHECK_READ_DATA          17
385 #define VBSD_LKP_CHECK_VERIFY_DATA        18
386 #define VBSD_LKP_CHECK_KERNEL_GOOD        19
387 
388 /* Information about a single kernel partition check in LoadKernel() */
389 typedef struct VbSharedDataKernelPart {
390 	uint64_t sector_start;     /* Start sector of partition */
391 	uint64_t sector_count;     /* Sector count of partition */
392 	uint32_t combined_version; /* Combined key+kernel version */
393 	uint8_t gpt_index;         /* Index of partition in GPT */
394 	uint8_t check_result;      /* Check result; see VBSD_LKP_CHECK_* */
395 	uint8_t flags;             /* Flags (see VBSD_LKP_FLAG_* */
396 	uint8_t reserved0;         /* Reserved for padding */
397 } VbSharedDataKernelPart;
398 
399 /* Number of kernel partitions to track per call.  Must be power of 2. */
400 #define VBSD_MAX_KERNEL_PARTS 8
401 
402 /* Flags for VbSharedDataKernelCall.flags */
403 /* Error initializing TPM in recovery mode */
404 #define VBSD_LK_FLAG_REC_TPM_INIT_ERROR 0x00000001
405 
406 /* Result codes for VbSharedDataKernelCall.check_result */
407 #define VBSD_LKC_CHECK_NOT_DONE            0
408 #define VBSD_LKC_CHECK_DEV_SWITCH_MISMATCH 1
409 #define VBSD_LKC_CHECK_GPT_READ_ERROR      2
410 #define VBSD_LKC_CHECK_GPT_PARSE_ERROR     3
411 #define VBSD_LKC_CHECK_GOOD_PARTITION      4
412 #define VBSD_LKC_CHECK_INVALID_PARTITIONS  5
413 #define VBSD_LKC_CHECK_NO_PARTITIONS       6
414 
415 /* Information about a single call to LoadKernel() */
416 typedef struct VbSharedDataKernelCall {
417 	/* Bottom 32 bits of flags passed in LoadKernelParams.boot_flags */
418 	uint32_t boot_flags;
419 	/* Debug flags; see VBSD_LK_FLAG_* */
420 	uint32_t flags;
421 	/* Number of sectors on drive */
422 	uint64_t sector_count;
423 	/* Sector size in bytes */
424 	uint32_t sector_size;
425 	/* Check result; see VBSD_LKC_CHECK_* */
426 	uint8_t check_result;
427 	/* Boot mode for LoadKernel(); see VBSD_LK_BOOT_MODE_* constants */
428 	uint8_t boot_mode;
429 	/* Test error number, if non-zero */
430 	uint8_t test_error_num;
431 	/* Return code from LoadKernel() */
432 	uint8_t return_code;
433 	/* Number of kernel partitions found */
434 	uint8_t kernel_parts_found;
435 	/* Reserved for padding */
436 	uint8_t reserved0[7];
437 	/* Data on kernels */
438 	VbSharedDataKernelPart parts[VBSD_MAX_KERNEL_PARTS];
439 } VbSharedDataKernelCall;
440 
441 /* Number of kernel calls to track.  Must be power of 2. */
442 #define VBSD_MAX_KERNEL_CALLS 4
443 
444 /*
445  * Data shared between LoadFirmware(), LoadKernel(), and OS.
446  *
447  * The boot process is:
448  *   1) Caller allocates buffer, at least VB_SHARED_DATA_MIN bytes, ideally
449  *      VB_SHARED_DATA_REC_SIZE bytes.
450  *   2) If non-recovery boot, this is passed to LoadFirmware(), which
451  *      initializes the buffer, adding this header and some data.
452  *   3) Buffer is passed to LoadKernel().  If this is a recovery boot,
453  *      LoadKernel() initializes the buffer, adding this header.  Regardless
454  *      of boot type, LoadKernel() adds some data to the buffer.
455  *   4) Caller makes data available to the OS in a platform-dependent manner.
456  *      For example, via ACPI or ATAGs.
457  */
458 typedef struct VbSharedDataHeader {
459 	/* Fields present in version 1 */
460 	/* Magic number for struct (VB_SHARED_DATA_MAGIC) */
461 	uint32_t magic;
462 	/* Version of this structure */
463 	uint32_t struct_version;
464 	/* Size of this structure in bytes */
465 	uint64_t struct_size;
466 	/* Size of shared data buffer in bytes */
467 	uint64_t data_size;
468 	/* Amount of shared data used so far */
469 	uint64_t data_used;
470 	/* Flags */
471 	uint32_t flags;
472 	/* Reserved for padding */
473 	uint32_t reserved0;
474 	/* Kernel subkey, from firmware */
475 	VbPublicKey kernel_subkey;
476 	/* Offset of kernel subkey data from start of this struct */
477 	uint64_t kernel_subkey_data_offset;
478 	/* Size of kernel subkey data */
479 	uint64_t kernel_subkey_data_size;
480 
481 	/*
482 	 * Timer values from VbExGetTimer().  Unused values are set to 0.  Note
483 	 * that these are now the enter/exit times for the wrapper API entry
484 	 * points; see crosbug.com/17018. */
485 	/* VbInit() enter/exit */
486 	uint64_t timer_vb_init_enter;
487 	uint64_t timer_vb_init_exit;
488 	/* VbSelectFirmware() enter/exit */
489 	uint64_t timer_vb_select_firmware_enter;
490 	uint64_t timer_vb_select_firmware_exit;
491 	/* VbSelectAndLoadKernel() enter/exit */
492 	uint64_t timer_vb_select_and_load_kernel_enter;
493 	uint64_t timer_vb_select_and_load_kernel_exit;
494 
495 	/* Information stored in TPM, as retrieved by firmware */
496 	/* Current firmware version in TPM */
497 	uint32_t fw_version_tpm;
498 	/* Current kernel version in TPM */
499 	uint32_t kernel_version_tpm;
500 
501 	/* Debugging information from LoadFirmware() */
502 	/* Result of checking RW firmware A and B */
503 	uint8_t check_fw_a_result;
504 	uint8_t check_fw_b_result;
505 	/* Firmware index returned by LoadFirmware() or 0xFF if failure */
506 	uint8_t firmware_index;
507 	/* Reserved for padding */
508 	uint8_t reserved1;
509 	/* Firmware TPM version at start of VbSelectFirmware() */
510 	uint32_t fw_version_tpm_start;
511 	/* Firmware lowest version found */
512 	uint32_t fw_version_lowest;
513 
514 	/* Debugging information from LoadKernel() */
515 	/* Number of times LoadKernel() called */
516 	uint32_t lk_call_count;
517 	/* Info on calls */
518 	VbSharedDataKernelCall lk_calls[VBSD_MAX_KERNEL_CALLS];
519 
520 	/*
521 	 * Offset and size of supplemental kernel data.  Reserve space for
522 	 * these fields now, so that future LoadKernel() versions can store
523 	 * information there without needing to shift down whatever data the
524 	 * original LoadFirmware() might have put immediately following its
525 	 * VbSharedDataHeader.
526 	 */
527 	uint64_t kernel_supplemental_offset;
528 	uint64_t kernel_supplemental_size;
529 
530 	/*
531 	 * Fields added in version 2.  Before accessing, make sure that
532 	 * struct_version >= 2
533 	 */
534 	/* Recovery reason for current boot */
535 	uint8_t recovery_reason;
536 	/* Reserved for padding */
537 	uint8_t reserved2[7];
538 	/* Flags from firmware keyblock */
539 	uint64_t fw_keyblock_flags;
540 	/* Kernel TPM version at start of VbSelectAndLoadKernel() */
541 	uint32_t kernel_version_tpm_start;
542 	/* Kernel lowest version found */
543 	uint32_t kernel_version_lowest;
544 
545 	/*
546 	 * After read-only firmware which uses version 2 is released, any
547 	 * additional fields must be added below, and the struct version must
548 	 * be increased.  Before reading/writing those fields, make sure that
549 	 * the struct being accessed is at least version 3.
550 	 *
551 	 * It's always ok for an older firmware to access a newer struct, since
552 	 * all the fields it knows about are present.  Newer firmware needs to
553 	 * use reasonable defaults when accessing older structs.
554 	 */
555 } __attribute__((packed)) VbSharedDataHeader;
556 
557 /*
558  * Size of VbSharedDataheader for each version
559  *
560  * TODO: crossystem needs not to fail if called on a v1 system where
561  * sizeof(VbSharedDataHeader) was smaller
562  */
563 #define VB_SHARED_DATA_HEADER_SIZE_V1 1072
564 #define VB_SHARED_DATA_HEADER_SIZE_V2 1096
565 
566 #define VB_SHARED_DATA_VERSION 2      /* Version for struct_version */
567 
568 #endif  /* VBOOT_REFERENCE_VBOOT_STRUCT_H_ */
569