vboot_nvstorage.h revision 17b8224ea582b2ba90b30a3e8e2d913e49c7818a
1/* Copyright (c) 2012 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
9#ifndef VBOOT_REFERENCE_NVSTORAGE_H_
10#define VBOOT_REFERENCE_NVSTORAGE_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  /* Flag indicating whether raw data has changed.  Set by VbNvTeardown() if
18   * the raw data has changed and needs to be stored to the underlying
19   * non-volatile data store. */
20  int raw_changed;
21
22  /* Internal data for NV storage routines.  Caller should not touch
23   * these fields. */
24  int regenerate_crc;
25
26} VbNvContext;
27
28
29/* Parameter type for VbNvGet(), VbNvSet(). */
30typedef enum VbNvParam {
31  /* Parameter values have been reset to defaults (flag for firmware).
32   * 0=clear; 1=set. */
33  VBNV_FIRMWARE_SETTINGS_RESET = 0,
34  /* Parameter values have been reset to defaults (flag for kernel).
35   * 0=clear; 1=set. */
36  VBNV_KERNEL_SETTINGS_RESET,
37  /* Request debug reset on next S3->S0 transition.  0=clear; 1=set. */
38  VBNV_DEBUG_RESET_MODE,
39  /* Number of times to try booting RW firmware slot B before slot A.
40   * Valid range: 0-15. */
41  VBNV_TRY_B_COUNT,
42  /* Request recovery mode on next boot; see VBNB_RECOVERY_* below for
43   * currently defined reason codes.  8-bit value. */
44  VBNV_RECOVERY_REQUEST,
45  /* Localization index for screen bitmaps displayed by firmware.
46   * 8-bit value. */
47  VBNV_LOCALIZATION_INDEX,
48  /* Field reserved for kernel/user-mode use; 32-bit value. */
49  VBNV_KERNEL_FIELD,
50  /* Allow booting from USB in developer mode.  0=no, 1=yes. */
51  VBNV_DEV_BOOT_USB,
52  /* Only boot Google-signed images in developer mode.  0=no, 1=yes. */
53  VBNV_DEV_BOOT_SIGNED_ONLY,
54  /* Set by userspace to request that RO firmware disable dev-mode on the next
55   * boot. This is likely only possible if the dev-switch is virtual. */
56  VBNV_DISABLE_DEV_REQUEST,
57  /* Set and cleared by vboot to request that the video Option ROM be loaded at
58   * boot time, so that BIOS screens can be displayed. 0=no, 1=yes. */
59  VBNV_OPROM_NEEDED,
60} VbNvParam;
61
62
63/* Recovery reason codes for VBNV_RECOVERY_REQUEST */
64/* Recovery not requested. */
65#define VBNV_RECOVERY_NOT_REQUESTED   0x00
66/* Recovery requested from legacy utility.  (Prior to the NV storage
67 * spec, recovery mode was a single bitfield; this value is reserved
68 * so that scripts which wrote 1 to the recovery field are
69 * distinguishable from scripts whch use the recovery reasons listed
70 * here. */
71#define VBNV_RECOVERY_LEGACY          0x01
72/* User manually requested recovery via recovery button */
73#define VBNV_RECOVERY_RO_MANUAL       0x02
74/* RW firmware failed signature check (neither RW firmware slot was valid) */
75#define VBNV_RECOVERY_RO_INVALID_RW   0x03
76/* S3 resume failed */
77#define VBNV_RECOVERY_RO_S3_RESUME    0x04
78/* TPM error in read-only firmware */
79#define VBNV_RECOVERY_RO_TPM_ERROR    0x05
80/* Shared data error in read-only firmware */
81#define VBNV_RECOVERY_RO_SHARED_DATA  0x06
82/* Test error from S3Resume() */
83#define VBNV_RECOVERY_RO_TEST_S3      0x07
84/* Test error from LoadFirmwareSetup() */
85#define VBNV_RECOVERY_RO_TEST_LFS     0x08
86/* Test error from LoadFirmware() */
87#define VBNV_RECOVERY_RO_TEST_LF      0x09
88/* RW firmware failed signature check (neither RW firmware slot was valid).
89 * Recovery reason is VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN + the check value
90 * for the slot which came closest to validating; see VBSD_LF_CHECK_* in
91 * vboot_struct.h. */
92#define VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN  0x10
93#define VBNV_RECOVERY_RO_INVALID_RW_CHECK_MAX  0x1F
94/* Firmware boot failure outside of verified boot (RAM init, missing SSD,
95 * etc.). */
96#define VBNV_RECOVERY_RO_FIRMWARE     0x20
97/* Recovery mode TPM initialization requires a system reboot.  The system was
98 * already in recovery mode for some other reason when this happened. */
99#define VBNV_RECOVERY_RO_TPM_REBOOT   0x21
100/* Unspecified/unknown error in read-only firmware */
101#define VBNV_RECOVERY_RO_UNSPECIFIED  0x3F
102/* User manually requested recovery by pressing a key at developer
103 * warning screen */
104#define VBNV_RECOVERY_RW_DEV_SCREEN   0x41
105/* No OS kernel detected */
106#define VBNV_RECOVERY_RW_NO_OS        0x42
107/* OS kernel failed signature check */
108#define VBNV_RECOVERY_RW_INVALID_OS   0x43
109/* TPM error in rewritable firmware */
110#define VBNV_RECOVERY_RW_TPM_ERROR    0x44
111/* RW firmware in dev mode, but dev switch is off */
112#define VBNV_RECOVERY_RW_DEV_MISMATCH 0x45
113/* Shared data error in rewritable firmware */
114#define VBNV_RECOVERY_RW_SHARED_DATA  0x46
115/* Test error from LoadKernel() */
116#define VBNV_RECOVERY_RW_TEST_LK      0x47
117/* No bootable disk found */
118#define VBNV_RECOVERY_RW_NO_DISK      0x48
119/* Unspecified/unknown error in rewritable firmware */
120#define VBNV_RECOVERY_RW_UNSPECIFIED  0x7F
121/* DM-verity error */
122#define VBNV_RECOVERY_KE_DM_VERITY    0x81
123/* Unspecified/unknown error in kernel */
124#define VBNV_RECOVERY_KE_UNSPECIFIED  0xBF
125/* Recovery mode test from user-mode */
126#define VBNV_RECOVERY_US_TEST         0xC1
127/* Unspecified/unknown error in user-mode */
128#define VBNV_RECOVERY_US_UNSPECIFIED  0xFF
129
130
131/* Initialize the NV storage library.  This must be called before any
132 * other functions in this library.  Returns 0 if success, non-zero if
133 * error.
134 *
135 * Proper calling procedure:
136 *    1) Allocate a context struct.
137 *    2) If multi-threaded/multi-process, acquire a lock to prevent
138 *       other processes from modifying the underlying storage.
139 *    3) Read underlying storage and fill in context->raw.
140 *    4) Call VbNvSetup().
141 *
142 * If you have access to global variables, you may want to wrap all
143 * that in your own VbNvOpen() function.  We don't do that in here
144 * because there are no global variables in UEFI BIOS during the PEI
145 * phase (that's also why we have to pass around a context pointer). */
146int VbNvSetup(VbNvContext* context);
147
148/* Clean up and flush changes back to the raw data.  This must be
149 * called after other functions in this library.  Returns 0 if
150 * success, non-zero if error.
151 *
152 * Proper calling procedure:
153 *    1) Call VbNvExit().
154 *    2) If context.raw_changed, write data back to underlying storage.
155 *    3) Release any lock you acquired before calling VbNvSetup().
156 *    4) Free the context struct.
157 *
158 * If you have access to global variables, you may want to wrap this
159 * in your own VbNvClose() function. */
160int VbNvTeardown(VbNvContext* context);
161
162/* Read a NV storage parameter into *dest.  Returns 0 if success,
163 * non-zero if error.
164 *
165 * This may only be called between VbNvSetup() and VbNvTeardown(). */
166int VbNvGet(VbNvContext* context, VbNvParam param, uint32_t* dest);
167
168/* Set a NV storage param to a new value.  Returns 0 if success,
169 * non-zero if error.
170 *
171 * This may only be called between VbNvSetup() and VbNvTeardown(). */
172int VbNvSet(VbNvContext* context, VbNvParam param, uint32_t value);
173
174
175#endif  /* VBOOT_REFERENCE_NVSTORAGE_H_ */
176