summaryrefslogtreecommitdiff
path: root/firmware/include/vboot_nvstorage.h
blob: 8748a5c5078f219ee64fd32e98bc65fa373f2f04 (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
/* Copyright (c) 2012 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.
 */

/* Non-volatile storage routines for verified boot.
 */

#ifndef VBOOT_REFERENCE_NVSTORAGE_H_
#define VBOOT_REFERENCE_NVSTORAGE_H_

#define VBNV_BLOCK_SIZE 16  /* Size of NV storage block in bytes */

typedef struct VbNvContext {
  /* Raw NV data.  Caller must fill this before calling VbNvSetup(). */
  uint8_t raw[VBNV_BLOCK_SIZE];
  /* Flag indicating whether raw data has changed.  Set by VbNvTeardown() if
   * the raw data has changed and needs to be stored to the underlying
   * non-volatile data store. */
  int raw_changed;

  /* Internal data for NV storage routines.  Caller should not touch
   * these fields. */
  int regenerate_crc;

} VbNvContext;


/* Parameter type for VbNvGet(), VbNvSet(). */
typedef enum VbNvParam {
  /* Parameter values have been reset to defaults (flag for firmware).
   * 0=clear; 1=set. */
  VBNV_FIRMWARE_SETTINGS_RESET = 0,
  /* Parameter values have been reset to defaults (flag for kernel).
   * 0=clear; 1=set. */
  VBNV_KERNEL_SETTINGS_RESET,
  /* Request debug reset on next S3->S0 transition.  0=clear; 1=set. */
  VBNV_DEBUG_RESET_MODE,
  /* Number of times to try booting RW firmware slot B before slot A.
   * Valid range: 0-15. */
  VBNV_TRY_B_COUNT,
  /* Request recovery mode on next boot; see VBNB_RECOVERY_* below for
   * currently defined reason codes.  8-bit value. */
  VBNV_RECOVERY_REQUEST,
  /* Localization index for screen bitmaps displayed by firmware.
   * 8-bit value. */
  VBNV_LOCALIZATION_INDEX,
  /* Field reserved for kernel/user-mode use; 32-bit value. */
  VBNV_KERNEL_FIELD,
  /* Allow booting from USB in developer mode.  0=no, 1=yes. */
  VBNV_DEV_BOOT_USB,
  /* Only boot Google-signed images in developer mode.  0=no, 1=yes. */
  VBNV_DEV_BOOT_SIGNED_ONLY,
  /* Set by userspace to request that RO firmware disable dev-mode on the next
   * boot. This is likely only possible if the dev-switch is virtual. */
  VBNV_DISABLE_DEV_REQUEST,
  /* Set and cleared by vboot to request that the video Option ROM be loaded at
   * boot time, so that BIOS screens can be displayed. 0=no, 1=yes. */
  VBNV_OPROM_NEEDED,
  /* Request that the firmware clear the TPM owner on the next boot. */
  VBNV_CLEAR_TPM_OWNER_REQUEST,
  /* Flag that TPM owner was cleared on request. */
  VBNV_CLEAR_TPM_OWNER_DONE,
} VbNvParam;


/* Recovery reason codes for VBNV_RECOVERY_REQUEST */
/* Recovery not requested. */
#define VBNV_RECOVERY_NOT_REQUESTED   0x00
/* Recovery requested from legacy utility.  (Prior to the NV storage
 * spec, recovery mode was a single bitfield; this value is reserved
 * so that scripts which wrote 1 to the recovery field are
 * distinguishable from scripts whch use the recovery reasons listed
 * here. */
#define VBNV_RECOVERY_LEGACY          0x01
/* User manually requested recovery via recovery button */
#define VBNV_RECOVERY_RO_MANUAL       0x02
/* RW firmware failed signature check (neither RW firmware slot was valid) */
#define VBNV_RECOVERY_RO_INVALID_RW   0x03
/* S3 resume failed */
#define VBNV_RECOVERY_RO_S3_RESUME    0x04
/* TPM error in read-only firmware */
#define VBNV_RECOVERY_RO_TPM_ERROR    0x05
/* Shared data error in read-only firmware */
#define VBNV_RECOVERY_RO_SHARED_DATA  0x06
/* Test error from S3Resume() */
#define VBNV_RECOVERY_RO_TEST_S3      0x07
/* Test error from LoadFirmwareSetup() */
#define VBNV_RECOVERY_RO_TEST_LFS     0x08
/* Test error from LoadFirmware() */
#define VBNV_RECOVERY_RO_TEST_LF      0x09
/* RW firmware failed signature check (neither RW firmware slot was valid).
 * Recovery reason is VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN + the check value
 * for the slot which came closest to validating; see VBSD_LF_CHECK_* in
 * vboot_struct.h. */
#define VBNV_RECOVERY_RO_INVALID_RW_CHECK_MIN  0x10
#define VBNV_RECOVERY_RO_INVALID_RW_CHECK_MAX  0x1F
/* Firmware boot failure outside of verified boot (RAM init, missing SSD,
 * etc.). */
#define VBNV_RECOVERY_RO_FIRMWARE     0x20
/* Recovery mode TPM initialization requires a system reboot.  The system was
 * already in recovery mode for some other reason when this happened. */
#define VBNV_RECOVERY_RO_TPM_REBOOT   0x21
/* EC software sync - other error */
#define VBNV_RECOVERY_EC_SOFTWARE_SYNC 0x22
/* EC software sync - unable to determine active EC image */
#define VBNV_RECOVERY_EC_UNKNOWN_IMAGE 0x23
/* EC software sync - error obtaining EC image hash */
#define VBNV_RECOVERY_EC_HASH         0x24
/* EC software sync - error obtaining expected EC image */
#define VBNV_RECOVERY_EC_EXPECTED_IMAGE 0x25
/* EC software sync - error updating EC */
#define VBNV_RECOVERY_EC_UPDATE       0x26
/* EC software sync - unable to jump to EC-RW */
#define VBNV_RECOVERY_EC_JUMP_RW      0x27
/* EC software sync - unable to protect / unprotect EC-RW */
#define VBNV_RECOVERY_EC_PROTECT      0x28
/* Unspecified/unknown error in read-only firmware */
#define VBNV_RECOVERY_RO_UNSPECIFIED  0x3F
/* User manually requested recovery by pressing a key at developer
 * warning screen */
#define VBNV_RECOVERY_RW_DEV_SCREEN   0x41
/* No OS kernel detected */
#define VBNV_RECOVERY_RW_NO_OS        0x42
/* OS kernel failed signature check */
#define VBNV_RECOVERY_RW_INVALID_OS   0x43
/* TPM error in rewritable firmware */
#define VBNV_RECOVERY_RW_TPM_ERROR    0x44
/* RW firmware in dev mode, but dev switch is off */
#define VBNV_RECOVERY_RW_DEV_MISMATCH 0x45
/* Shared data error in rewritable firmware */
#define VBNV_RECOVERY_RW_SHARED_DATA  0x46
/* Test error from LoadKernel() */
#define VBNV_RECOVERY_RW_TEST_LK      0x47
/* No bootable disk found */
#define VBNV_RECOVERY_RW_NO_DISK      0x48
/* Unspecified/unknown error in rewritable firmware */
#define VBNV_RECOVERY_RW_UNSPECIFIED  0x7F
/* DM-verity error */
#define VBNV_RECOVERY_KE_DM_VERITY    0x81
/* Unspecified/unknown error in kernel */
#define VBNV_RECOVERY_KE_UNSPECIFIED  0xBF
/* Recovery mode test from user-mode */
#define VBNV_RECOVERY_US_TEST         0xC1
/* Unspecified/unknown error in user-mode */
#define VBNV_RECOVERY_US_UNSPECIFIED  0xFF


/* Initialize the NV storage library.  This must be called before any
 * other functions in this library.  Returns 0 if success, non-zero if
 * error.
 *
 * Proper calling procedure:
 *    1) Allocate a context struct.
 *    2) If multi-threaded/multi-process, acquire a lock to prevent
 *       other processes from modifying the underlying storage.
 *    3) Read underlying storage and fill in context->raw.
 *    4) Call VbNvSetup().
 *
 * If you have access to global variables, you may want to wrap all
 * that in your own VbNvOpen() function.  We don't do that in here
 * because there are no global variables in UEFI BIOS during the PEI
 * phase (that's also why we have to pass around a context pointer). */
int VbNvSetup(VbNvContext* context);

/* Clean up and flush changes back to the raw data.  This must be
 * called after other functions in this library.  Returns 0 if
 * success, non-zero if error.
 *
 * Proper calling procedure:
 *    1) Call VbNvExit().
 *    2) If context.raw_changed, write data back to underlying storage.
 *    3) Release any lock you acquired before calling VbNvSetup().
 *    4) Free the context struct.
 *
 * If you have access to global variables, you may want to wrap this
 * in your own VbNvClose() function. */
int VbNvTeardown(VbNvContext* context);

/* Read a NV storage parameter into *dest.  Returns 0 if success,
 * non-zero if error.
 *
 * This may only be called between VbNvSetup() and VbNvTeardown(). */
int VbNvGet(VbNvContext* context, VbNvParam param, uint32_t* dest);

/* Set a NV storage param to a new value.  Returns 0 if success,
 * non-zero if error.
 *
 * This may only be called between VbNvSetup() and VbNvTeardown(). */
int VbNvSet(VbNvContext* context, VbNvParam param, uint32_t value);


#endif  /* VBOOT_REFERENCE_NVSTORAGE_H_ */