Home | History | Annotate | Download | only in include
      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