summaryrefslogtreecommitdiff
path: root/firmware/include/vboot_struct.h
blob: 5d76ece704ecbb35274d0d29c1524c98ed9fc1e9 (plain)
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
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
/* Copyright (c) 2013 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.
 *
 * Data structure definitions for verified boot, for on-disk / in-eeprom
 * data.
 */

#ifndef VBOOT_REFERENCE_VBOOT_STRUCT_H_
#define VBOOT_REFERENCE_VBOOT_STRUCT_H_

#include <stdint.h>

/*
 * Needed for vb2_packed_key.  Use relative path to place nicely with
 * depthcharge and coreboot.
 * TODO(kitching): This include should disappear once everything in
 * this file has either been deprecated or has found a better home.
 */
#include "../2lib/include/2struct.h"

#ifdef __cplusplus
extern "C" {
#endif  /* __cplusplus */

/* Constants and sub-structures for VbSharedDataHeader */

/* Magic number for recognizing VbSharedDataHeader ("VbSD") */
#define VB_SHARED_DATA_MAGIC 0x44536256

/* Minimum and recommended size of shared_data_blob in bytes. */
#define VB_SHARED_DATA_MIN_SIZE 3072
#define VB_SHARED_DATA_REC_SIZE 16384

/*
 * Flags for VbSharedDataHeader
 *
 * TODO(b:124141368): Move these constants into crossystem once they are
 * no longer needed in vboot2 code.
 */

/* LoadFirmware() tried firmware B because of VbNvStorage firmware B tries;
   Deprecated as part of chromium:1010389. */
#define VBSD_DEPRECATED_FWB_TRIED        0x00000001
/*
 * LoadKernel() verified the good kernel keyblock using the kernel subkey from
 * the firmware.  If this flag is not present, it just used the hash of the
 * kernel keyblock.
 */
#define VBSD_KERNEL_KEY_VERIFIED         0x00000002
/* LoadFirmware() was told the developer switch was on;
   Deprecated as part of chromium:1038260 */
#define VBSD_DEPRECATED_LF_DEV_SWITCH_ON 0x00000004
/*
 * LoadFirmware() is requesting the read only normal/dev code path.  This is
 * deprecated and unsupported by current firmware.
 */
#define VBSD_DEPRECATED_LF_USE_RO_NORMAL 0x00000008
/* Developer switch was enabled at boot time */
#define VBSD_BOOT_DEV_SWITCH_ON          0x00000010
/* Recovery switch was enabled at boot time */
#define VBSD_BOOT_REC_SWITCH_ON          0x00000020
/* Firmware write protect was enabled at boot time */
#define VBSD_BOOT_FIRMWARE_WP_ENABLED    0x00000040
/* Boot is a S3->S0 resume, not a S5->S0 normal boot;
   Deprecated as part of CL:347257. */
#define VBSD_DEPRECATED_BOOT_S3_RESUME   0x00000100
/* Read-only firmware supports the normal/developer code path;
   Deprecated as part of CL:347257. */
#define VBSD_DEPRECATED_BOOT_RO_NORMAL_SUPPORT 0x00000200
/* VbInit() was told that the system has a virtual dev-switch;
   Deprecated as part of chromium:942901. */
#define VBSD_DEPRECATED_HONOR_VIRT_DEV_SWITCH 0x00000400
/* VbInit() was told the system supports EC software sync */
#define VBSD_EC_SOFTWARE_SYNC            0x00000800
/* VbInit() was told that the EC firmware is slow to update
   Deprecated as part of chromium:1038259 */
#define VBSD_DEPRECATED_EC_SLOW_UPDATE   0x00001000
/* Firmware software write protect was enabled at boot time.
   Crossystem support deprecated as part of CL:575389. */
#define VBSD_DEPRECATED_BOOT_FIRMWARE_SW_WP_ENABLED 0x00002000
/* VbInit() was told that the recovery button is a virtual one */
#define VBSD_BOOT_REC_SWITCH_VIRTUAL     0x00004000
/* Firmware used vboot2 for firmware selection */
#define VBSD_BOOT_FIRMWARE_VBOOT2        0x00008000
/* Firmware needs VGA Option ROM to display screens;
   Deprecated as part of chromium:948529 */
#define VBSD_DEPRECATED_OPROM_MATTERS    0x00010000
/* Firmware has loaded the VGA Option ROM;
   Deprecated as part of chromium:948529 */
#define VBSD_DEPRECATED_OPROM_LOADED     0x00020000
/* Don't try for boot failures;
 * Deprecated as part of chromium:1038260 */
#define VBSD_DEPRECATED_NOFAIL_BOOT      0x00040000
/* VbInit() was told that the EC firmware supports EFS
   Deprecated as part of chromium:1038259 */
#define VBSD_DEPRECATED_EC_EFS           0x00080000
/* NvStorage uses 64-byte record, not 16-byte */
#define VBSD_NVDATA_V2                   0x00100000

/* Result codes for VbSharedDataHeader.check_fw_a_result (and b_result) */
#define VBSD_LF_CHECK_NOT_DONE          0
#define VBSD_LF_CHECK_DEV_MISMATCH      1
#define VBSD_LF_CHECK_REC_MISMATCH      2
#define VBSD_LF_CHECK_VERIFY_KEYBLOCK   3
#define VBSD_LF_CHECK_KEY_ROLLBACK      4
#define VBSD_LF_CHECK_DATA_KEY_PARSE    5
#define VBSD_LF_CHECK_VERIFY_PREAMBLE   6
#define VBSD_LF_CHECK_FW_ROLLBACK       7
#define VBSD_LF_CHECK_HEADER_VALID      8
#define VBSD_LF_CHECK_GET_FW_BODY       9
#define VBSD_LF_CHECK_HASH_WRONG_SIZE   10
#define VBSD_LF_CHECK_VERIFY_BODY       11
#define VBSD_LF_CHECK_VALID             12
/*
 * Read-only normal path requested by firmware preamble, but unsupported by
 * firmware.
 */
#define VBSD_LF_CHECK_NO_RO_NORMAL      13

/* Boot mode for VbSharedDataHeader.lk_boot_mode */
#define VBSD_LK_BOOT_MODE_RECOVERY      0
#define VBSD_LK_BOOT_MODE_NORMAL        1
#define VBSD_LK_BOOT_MODE_DEVELOPER     2

/* Flags for VbSharedDataKernelPart.flags */
#define VBSD_LKP_FLAG_KEYBLOCK_VALID   0x01

/* Result codes for VbSharedDataKernelPart.check_result */
#define VBSD_LKP_CHECK_NOT_DONE           0
#define VBSD_LKP_CHECK_TOO_SMALL          1
#define VBSD_LKP_CHECK_READ_START         2
#define VBSD_LKP_CHECK_KEYBLOCK_SIG      3
#define VBSD_LKP_CHECK_KEYBLOCK_HASH     4
#define VBSD_LKP_CHECK_DEV_MISMATCH       5
#define VBSD_LKP_CHECK_REC_MISMATCH       6
#define VBSD_LKP_CHECK_KEY_ROLLBACK       7
#define VBSD_LKP_CHECK_DATA_KEY_PARSE     8
#define VBSD_LKP_CHECK_VERIFY_PREAMBLE    9
#define VBSD_LKP_CHECK_KERNEL_ROLLBACK    10
#define VBSD_LKP_CHECK_PREAMBLE_VALID     11
/*
 * Body load address check is omitted; this result code is deprecated and not
 * used anywhere in the codebase.
 */
#define VBSD_LKP_CHECK_BODY_ADDRESS       12
#define VBSD_LKP_CHECK_BODY_OFFSET        13
#define VBSD_LKP_CHECK_SELF_SIGNED        14
#define VBSD_LKP_CHECK_BODY_EXCEEDS_MEM   15
#define VBSD_LKP_CHECK_BODY_EXCEEDS_PART  16
#define VBSD_LKP_CHECK_READ_DATA          17
#define VBSD_LKP_CHECK_VERIFY_DATA        18
#define VBSD_LKP_CHECK_KERNEL_GOOD        19

/* Information about a single kernel partition check in LoadKernel() */
typedef struct VbSharedDataKernelPart {
	uint64_t sector_start;     /* Start sector of partition */
	uint64_t sector_count;     /* Sector count of partition */
	uint32_t combined_version; /* Combined key+kernel version */
	uint8_t gpt_index;         /* Index of partition in GPT */
	uint8_t check_result;      /* Check result; see VBSD_LKP_CHECK_* */
	uint8_t flags;             /* Flags (see VBSD_LKP_FLAG_* */
	uint8_t reserved0;         /* Reserved for padding */
} VbSharedDataKernelPart;

/* Number of kernel partitions to track per call.  Must be power of 2. */
#define VBSD_MAX_KERNEL_PARTS 8

/* Result codes for VbSharedDataKernelCall.check_result */
#define VBSD_LKC_CHECK_NOT_DONE            0
#define VBSD_LKC_CHECK_DEV_SWITCH_MISMATCH 1
#define VBSD_LKC_CHECK_GPT_READ_ERROR      2
#define VBSD_LKC_CHECK_GPT_PARSE_ERROR     3
#define VBSD_LKC_CHECK_GOOD_PARTITION      4
#define VBSD_LKC_CHECK_INVALID_PARTITIONS  5
#define VBSD_LKC_CHECK_NO_PARTITIONS       6

/* Information about a single call to LoadKernel() */
typedef struct VbSharedDataKernelCall {
	/* Bottom 32 bits of flags passed in LoadKernelParams.boot_flags */
	uint32_t boot_flags;
	/* Debug flags; see VBSD_LK_FLAG_* */
	uint32_t flags;
	/* Number of sectors on drive */
	uint64_t sector_count;
	/* Sector size in bytes */
	uint32_t sector_size;
	/* Check result; see VBSD_LKC_CHECK_* */
	uint8_t check_result;
	/* Boot mode for LoadKernel(); see VBSD_LK_BOOT_MODE_* constants */
	uint8_t boot_mode;
	/* Test error number, if non-zero */
	uint8_t test_error_num;
	/* Return code from LoadKernel() */
	uint8_t return_code;
	/* Number of kernel partitions found */
	uint8_t kernel_parts_found;
	/* Reserved for padding */
	uint8_t reserved0[7];
	/* Data on kernels */
	VbSharedDataKernelPart parts[VBSD_MAX_KERNEL_PARTS];
} VbSharedDataKernelCall;

/* Number of kernel calls to track.  Must be power of 2. */
#define VBSD_MAX_KERNEL_CALLS 4

/*
 * Data shared between LoadFirmware(), LoadKernel(), and OS.
 *
 * The boot process is:
 *   1) Caller allocates buffer, at least VB_SHARED_DATA_MIN bytes, ideally
 *      VB_SHARED_DATA_REC_SIZE bytes.
 *   2) If non-recovery boot, this is passed to LoadFirmware(), which
 *      initializes the buffer, adding this header and some data.
 *   3) Buffer is passed to LoadKernel().  If this is a recovery boot,
 *      LoadKernel() initializes the buffer, adding this header.  Regardless
 *      of boot type, LoadKernel() adds some data to the buffer.
 *   4) Caller makes data available to the OS in a platform-dependent manner.
 *      For example, via ACPI or ATAGs.
 */
typedef struct VbSharedDataHeader {
	/* Fields present in version 1 */
	/* Magic number for struct (VB_SHARED_DATA_MAGIC) */
	uint32_t magic;
	/* Version of this structure */
	uint32_t struct_version;
	/* Size of this structure in bytes */
	uint64_t struct_size;
	/* Size of shared data buffer in bytes */
	uint64_t data_size;
	/* Amount of shared data used so far */
	uint64_t data_used;
	/* Flags */
	uint32_t flags;
	/* Reserved for padding */
	uint32_t reserved0;
	/* Kernel subkey, from firmware */
	struct vb2_packed_key kernel_subkey;
	/* Offset of kernel subkey data from start of this struct */
	uint64_t kernel_subkey_data_offset;
	/* Size of kernel subkey data */
	uint64_t kernel_subkey_data_size;

	/*
	 * These timer values are all deprecated.  coreboot tstamp_table should
	 * be used instead.  See crosbug.com/1014102.
	 */
	/* VbInit() enter/exit */
	uint64_t timer_vb_init_enter;
	uint64_t timer_vb_init_exit;
	/* VbSelectFirmware() enter/exit */
	uint64_t timer_vb_select_firmware_enter;
	uint64_t timer_vb_select_firmware_exit;
	/* VbSelectAndLoadKernel() enter/exit */
	uint64_t timer_vb_select_and_load_kernel_enter;
	uint64_t timer_vb_select_and_load_kernel_exit;

	/* Information stored in TPM, as retrieved by firmware */
	/* Current firmware version in TPM */
	uint32_t fw_version_tpm;
	/* Current kernel version in TPM */
	uint32_t kernel_version_tpm;

	/* Debugging information from LoadFirmware() */
	/* Result of checking RW firmware A and B */
	uint8_t check_fw_a_result;
	uint8_t check_fw_b_result;
	/* Firmware index returned by LoadFirmware() or 0xFF if failure */
	uint8_t firmware_index;
	/* Reserved for padding */
	uint8_t reserved1;
	/* Firmware TPM version at start of VbSelectFirmware() */
	uint32_t fw_version_tpm_start;
	/* Firmware lowest version found */
	uint32_t fw_version_lowest;

	/* Debugging information from LoadKernel() */
	/* Number of times LoadKernel() called */
	uint32_t lk_call_count;
	/* Info on calls */
	VbSharedDataKernelCall lk_calls[VBSD_MAX_KERNEL_CALLS];

	/*
	 * Offset and size of supplemental kernel data.  Reserve space for
	 * these fields now, so that future LoadKernel() versions can store
	 * information there without needing to shift down whatever data the
	 * original LoadFirmware() might have put immediately following its
	 * VbSharedDataHeader.
	 */
	uint64_t kernel_supplemental_offset;
	uint64_t kernel_supplemental_size;

	/*
	 * Fields added in version 2.  Before accessing, make sure that
	 * struct_version >= 2
	 */
	/* Recovery reason for current boot */
	uint8_t recovery_reason;
	/* Reserved for padding */
	uint8_t reserved2[7];
	/* Flags from firmware keyblock */
	uint64_t fw_keyblock_flags;
	/* Kernel TPM version at start of VbSelectAndLoadKernel() */
	uint32_t kernel_version_tpm_start;
	/* Kernel lowest version found */
	uint32_t kernel_version_lowest;

	/*
	 * After read-only firmware which uses version 2 is released, any
	 * additional fields must be added below, and the struct version must
	 * be increased.  Before reading/writing those fields, make sure that
	 * the struct being accessed is at least version 3.
	 *
	 * It's always ok for an older firmware to access a newer struct, since
	 * all the fields it knows about are present.  Newer firmware needs to
	 * use reasonable defaults when accessing older structs.
	 */
} __attribute__((packed)) VbSharedDataHeader;

/* Size of VbSharedDataheader for each version */
#define VB_SHARED_DATA_HEADER_SIZE_V1 1072
#define VB_SHARED_DATA_HEADER_SIZE_V2 1096

_Static_assert(VB_SHARED_DATA_HEADER_SIZE_V1
	       == offsetof(VbSharedDataHeader, recovery_reason),
	       "VB_SHARED_DATA_HEADER_SIZE_V1 incorrect");

_Static_assert(VB_SHARED_DATA_HEADER_SIZE_V2 == sizeof(VbSharedDataHeader),
	       "VB_SHARED_DATA_HEADER_SIZE_V2 incorrect");

#define VB_SHARED_DATA_VERSION 2  /* Version for struct_version */

#ifdef __cplusplus
}
#endif  /* __cplusplus */

#endif  /* VBOOT_REFERENCE_VBOOT_STRUCT_H_ */