vboot_nvstorage.h revision 782300d093a2fbf2ca24e446fb6d65f9f28e56a6
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
6/* Non-volatile storage routines for verified boot. */
7
8#ifndef VBOOT_REFERENCE_NVSTORAGE_H_
9#define VBOOT_REFERENCE_NVSTORAGE_H_
10#include <stdint.h>
11
12#define VBNV_BLOCK_SIZE 16  /* Size of NV storage block in bytes */
13
14typedef struct VbNvContext {
15	/* Raw NV data.  Caller must fill this before calling VbNvSetup(). */
16	uint8_t raw[VBNV_BLOCK_SIZE];
17	/*
18	 * Flag indicating whether raw data has changed.  Set by VbNvTeardown()
19	 * if the raw data has changed and needs to be stored to the underlying
20	 * non-volatile data store.
21	 */
22	int raw_changed;
23
24	/*
25	 * Internal data for NV storage routines.  Caller should not touch
26	 * these fields.
27	 */
28	int regenerate_crc;
29} VbNvContext;
30
31/* Parameter type for VbNvGet(), VbNvSet(). */
32typedef enum VbNvParam {
33	/*
34	 * Parameter values have been reset to defaults (flag for firmware).
35	 * 0=clear; 1=set.
36	 */
37	VBNV_FIRMWARE_SETTINGS_RESET = 0,
38	/*
39	 * Parameter values have been reset to defaults (flag for kernel).
40	 * 0=clear; 1=set.
41	 */
42	VBNV_KERNEL_SETTINGS_RESET,
43	/* Request debug reset on next S3->S0 transition.  0=clear; 1=set. */
44	VBNV_DEBUG_RESET_MODE,
45	/*
46	 * Number of times to try booting RW firmware slot B before slot A.
47	 * Valid range: 0-15.
48	 *
49	 * Vboot2: Number of times to try the firmware in VBNV_FW_TRY_NEXT.
50	 *
51	 * These refer to the same field, but have different enum values so
52	 * case statement don't complain about duplicates.
53	 */
54	VBNV_TRY_B_COUNT,
55	VBNV_FW_TRY_COUNT,
56	/*
57	 * Request recovery mode on next boot; see VBNB_RECOVERY_* below for
58	 * currently defined reason codes.  8-bit value.
59	 */
60	VBNV_RECOVERY_REQUEST,
61	/*
62	 * Localization index for screen bitmaps displayed by firmware.
63	 * 8-bit value.
64	 */
65	VBNV_LOCALIZATION_INDEX,
66	/* Field reserved for kernel/user-mode use; 32-bit value. */
67	VBNV_KERNEL_FIELD,
68	/* Allow booting from USB in developer mode.  0=no, 1=yes. */
69	VBNV_DEV_BOOT_USB,
70	/* Allow booting of legacy OSes in developer mode.  0=no, 1=yes. */
71	VBNV_DEV_BOOT_LEGACY,
72	/* Only boot Google-signed images in developer mode.  0=no, 1=yes. */
73	VBNV_DEV_BOOT_SIGNED_ONLY,
74	/*
75	 * Set by userspace to request that RO firmware disable dev-mode on the
76	 * next boot. This is likely only possible if the dev-switch is
77	 * virtual.
78	 */
79	VBNV_DISABLE_DEV_REQUEST,
80	/*
81	 * Set and cleared by vboot to request that the video Option ROM be
82	 * loaded at boot time, so that BIOS screens can be displayed. 0=no,
83	 * 1=yes.
84	 */
85	VBNV_OPROM_NEEDED,
86	/* Request that the firmware clear the TPM owner on the next boot. */
87	VBNV_CLEAR_TPM_OWNER_REQUEST,
88	/* Flag that TPM owner was cleared on request. */
89	VBNV_CLEAR_TPM_OWNER_DONE,
90	/* More details on recovery reason */
91	VBNV_RECOVERY_SUBCODE,
92	/* Request that NVRAM be backed up at next boot if possible. */
93	VBNV_BACKUP_NVRAM_REQUEST,
94
95	/* Vboot2: Firmware slot to try next.  0=A, 1=B */
96	VBNV_FW_TRY_NEXT,
97	/* Vboot2: Firmware slot tried this boot (0=A, 1=B) */
98	VBNV_FW_TRIED,
99	/* Vboot2: Result of trying that firmware (see vb2_fw_result) */
100	VBNV_FW_RESULT,
101	/* Firmware slot tried previous boot (0=A, 1=B) */
102	VBNV_FW_PREV_TRIED,
103	/* Result of trying that firmware (see vb2_fw_result) */
104	VBNV_FW_PREV_RESULT,
105
106} VbNvParam;
107
108/* Result of trying the firmware in VBNV_FW_TRIED */
109typedef enum VbFwResult {
110	/* Unknown */
111	VBNV_FW_RESULT_UNKNOWN = 0,
112
113	/* Trying a new slot, but haven't reached success/failure */
114	VBNV_FW_RESULT_TRYING = 1,
115
116	/* Successfully booted to the OS */
117	VBNV_FW_RESULT_SUCCESS = 2,
118
119	/* Known failure */
120	VBNV_FW_RESULT_FAILURE = 3,
121
122} VbFwResult;
123
124/* Recovery reason codes for VBNV_RECOVERY_REQUEST */
125/* Recovery not requested. */
126#define VBNV_RECOVERY_NOT_REQUESTED   0x00
127/*
128 * Recovery requested from legacy utility.  (Prior to the NV storage spec,
129 * recovery mode was a single bitfield; this value is reserved so that scripts
130 * which wrote 1 to the recovery field are distinguishable from scripts whch
131 * use the recovery reasons listed here.
132 */
133#define VBNV_RECOVERY_LEGACY          0x01
134/* User manually requested recovery via recovery button */
135#define VBNV_RECOVERY_RO_MANUAL       0x02
136/* RW firmware failed signature check (neither RW firmware slot was valid) */
137#define VBNV_RECOVERY_RO_INVALID_RW   0x03
138/* S3 resume failed */
139#define VBNV_RECOVERY_RO_S3_RESUME    0x04
140/* TPM error in read-only firmware (deprecated) */
141#define VBNV_RECOVERY_DEP_RO_TPM_ERROR    0x05
142/* Shared data error in read-only firmware */
143#define VBNV_RECOVERY_RO_SHARED_DATA  0x06
144/* Test error from S3Resume() */
145#define VBNV_RECOVERY_RO_TEST_S3      0x07
146/* Test error from LoadFirmwareSetup() */
147#define VBNV_RECOVERY_RO_TEST_LFS     0x08
148/* Test error from LoadFirmware() */
149#define VBNV_RECOVERY_RO_TEST_LF      0x09
150/*
151 * RW firmware failed signature check (neither RW firmware slot was valid).
152 * Recovery reason is VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN + the check value
153 * for the slot which came closest to validating; see VBSD_LF_CHECK_* in
154 * vboot_struct.h.
155 */
156#define VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN  0x10
157#define VBNV_RECOVERY_RO_INVALID_RW_CHECK_MAX  0x1F
158/*
159 * Firmware boot failure outside of verified boot (RAM init, missing SSD,
160 * etc.).
161 */
162#define VBNV_RECOVERY_RO_FIRMWARE     0x20
163/*
164 * Recovery mode TPM initialization requires a system reboot.  The system was
165 * already in recovery mode for some other reason when this happened.
166 */
167#define VBNV_RECOVERY_RO_TPM_REBOOT   0x21
168/* EC software sync - other error */
169#define VBNV_RECOVERY_EC_SOFTWARE_SYNC 0x22
170/* EC software sync - unable to determine active EC image */
171#define VBNV_RECOVERY_EC_UNKNOWN_IMAGE 0x23
172/* EC software sync - error obtaining EC image hash (deprecated) */
173#define VBNV_RECOVERY_DEP_EC_HASH         0x24
174/* EC software sync - error obtaining expected EC image */
175#define VBNV_RECOVERY_EC_EXPECTED_IMAGE 0x25
176/* EC software sync - error updating EC */
177#define VBNV_RECOVERY_EC_UPDATE       0x26
178/* EC software sync - unable to jump to EC-RW */
179#define VBNV_RECOVERY_EC_JUMP_RW      0x27
180/* EC software sync - unable to protect / unprotect EC-RW */
181#define VBNV_RECOVERY_EC_PROTECT      0x28
182/* EC software sync - error obtaining expected EC hash */
183#define VBNV_RECOVERY_EC_EXPECTED_HASH 0x29
184/* EC software sync - expected EC image doesn't match hash */
185#define VBNV_RECOVERY_EC_HASH_MISMATCH 0x2A
186/* Unspecified/unknown error in read-only firmware */
187#define VBNV_RECOVERY_RO_UNSPECIFIED  0x3F
188/*
189 * User manually requested recovery by pressing a key at developer
190 * warning screen
191 */
192#define VBNV_RECOVERY_RW_DEV_SCREEN   0x41
193/* No OS kernel detected */
194#define VBNV_RECOVERY_RW_NO_OS        0x42
195/* OS kernel failed signature check */
196#define VBNV_RECOVERY_RW_INVALID_OS   0x43
197/* TPM error in rewritable firmware (deprecated) */
198#define VBNV_RECOVERY_DEP_RW_TPM_ERROR    0x44
199/* RW firmware in dev mode, but dev switch is off */
200#define VBNV_RECOVERY_RW_DEV_MISMATCH 0x45
201/* Shared data error in rewritable firmware */
202#define VBNV_RECOVERY_RW_SHARED_DATA  0x46
203/* Test error from LoadKernel() */
204#define VBNV_RECOVERY_RW_TEST_LK      0x47
205/* No bootable disk found (deprecated)*/
206#define VBNV_RECOVERY_DEP_RW_NO_DISK      0x48
207/* Rebooting did not correct TPM_E_FAIL or TPM_E_FAILEDSELFTEST  */
208#define VBNV_RECOVERY_TPM_E_FAIL      0x49
209/* TPM setup error in read-only firmware */
210#define VBNV_RECOVERY_RO_TPM_S_ERROR  0x50
211/* TPM write error in read-only firmware */
212#define VBNV_RECOVERY_RO_TPM_W_ERROR  0x51
213/* TPM lock error in read-only firmware */
214#define VBNV_RECOVERY_RO_TPM_L_ERROR  0x52
215/* TPM update error in read-only firmware */
216#define VBNV_RECOVERY_RO_TPM_U_ERROR  0x53
217/* TPM read error in rewritable firmware */
218#define VBNV_RECOVERY_RW_TPM_R_ERROR  0x54
219/* TPM write error in rewritable firmware */
220#define VBNV_RECOVERY_RW_TPM_W_ERROR  0x55
221/* TPM lock error in rewritable firmware */
222#define VBNV_RECOVERY_RW_TPM_L_ERROR  0x56
223/* EC software sync unable to get EC image hash */
224#define VBNV_RECOVERY_EC_HASH_FAILED  0x57
225/* EC software sync invalid image hash size */
226#define VBNV_RECOVERY_EC_HASH_SIZE    0x58
227/* Unspecified error while trying to load kernel */
228#define VBNV_RECOVERY_LK_UNSPECIFIED  0x59
229/* No bootable storage device in system */
230#define VBNV_RECOVERY_RW_NO_DISK      0x5A
231/* No bootable kernel found on disk */
232#define VBNV_RECOVERY_RW_NO_KERNEL    0x5B
233/* Unspecified/unknown error in rewritable firmware */
234#define VBNV_RECOVERY_RW_UNSPECIFIED  0x7F
235/* DM-verity error */
236#define VBNV_RECOVERY_KE_DM_VERITY    0x81
237/* Unspecified/unknown error in kernel */
238#define VBNV_RECOVERY_KE_UNSPECIFIED  0xBF
239/* Recovery mode test from user-mode */
240#define VBNV_RECOVERY_US_TEST         0xC1
241/* Unspecified/unknown error in user-mode */
242#define VBNV_RECOVERY_US_UNSPECIFIED  0xFF
243
244/**
245 * Initialize the NV storage library.
246 *
247 * This must be called before any other functions in this library.  Returns 0
248 * if success, non-zero if error.
249 *
250 * Proper calling procedure:
251 *    1) Allocate a context struct.
252 *    2) If multi-threaded/multi-process, acquire a lock to prevent
253 *       other processes from modifying the underlying storage.
254 *    3) Read underlying storage and fill in context->raw.
255 *    4) Call VbNvSetup().
256 *
257 * If you have access to global variables, you may want to wrap all that in
258 * your own VbNvOpen() function.  We don't do that in here because there are no
259 * global variables in UEFI BIOS during the PEI phase (that's also why we have
260 * to pass around a context pointer).
261 */
262int VbNvSetup(VbNvContext *context);
263
264/**
265 * Clean up and flush changes back to the raw data.
266 *
267 * This must be called after other functions in this library.  Returns 0 if
268 * success, non-zero if error.
269 *
270 * Proper calling procedure:
271 *    1) Call VbNvExit().
272 *    2) If context.raw_changed, write data back to underlying storage.
273 *    3) Release any lock you acquired before calling VbNvSetup().
274 *    4) Free the context struct.
275 *
276 * If you have access to global variables, you may want to wrap this
277 * in your own VbNvClose() function.
278 */
279int VbNvTeardown(VbNvContext *context);
280
281/**
282 * Read a NV storage parameter into *dest.
283 *
284 * Returns 0 if success, non-zero if error.
285 *
286 * This may only be called between VbNvSetup() and VbNvTeardown().
287 */
288int VbNvGet(VbNvContext *context, VbNvParam param, uint32_t *dest);
289
290/**
291 * Set a NV storage param to a new value.
292 *
293 * Returns 0 if success, non-zero if error.
294 *
295 * This may only be called between VbNvSetup() and VbNvTeardown().
296 */
297int VbNvSet(VbNvContext *context, VbNvParam param, uint32_t value);
298
299/**
300 * Attempt to restore some fields of a lost VbNvContext from a backup area.
301 * The rest of the fields are unchanged, so they'd need to be set to their
302 * appropriate defaults by calling VbNvSetup() first (which is usually how we
303 * know the fields have been lost).
304 *
305 * Returns 0 if success, non-zero if error.
306 *
307 * This may only be called between VbNvSetup() and VbNvTeardown().
308 */
309int RestoreNvFromBackup(VbNvContext *vnc);
310
311/**
312 * Attempt to save some fields of the VbNvContext to a backup area.
313 *
314 * Returns 0 if success, non-zero if error. If it succeeds, it will clear the
315 * VBNV_BACKUP_NVRAM_REQUEST flag in the VbNvContext.
316 *
317 * This may only be called when the backup area is writable.
318 */
319int SaveNvToBackup(VbNvContext *vnc);
320
321#endif  /* VBOOT_REFERENCE_NVSTORAGE_H_ */
322