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/* VB2: Secure data inititalization error */ 187#define VBNV_RECOVERY_VB2_SECDATA_INIT 0x2B 188/* VB2: GBB header is bad */ 189#define VBNV_RECOVERY_VB2_GBB_HEADER 0x2C 190/* VB2: Unable to clear TPM owner */ 191#define VBNV_RECOVERY_VB2_TPM_CLEAR_OWNER 0x2D 192/* VB2: Error determining/updating virtual dev switch */ 193#define VBNV_RECOVERY_VB2_DEV_SWITCH 0x2E 194/* VB2: Error determining firmware slot */ 195#define VBNV_RECOVERY_VB2_FW_SLOT 0x2F 196/* Unspecified/unknown error in read-only firmware */ 197#define VBNV_RECOVERY_RO_UNSPECIFIED 0x3F 198/* 199 * User manually requested recovery by pressing a key at developer 200 * warning screen 201 */ 202#define VBNV_RECOVERY_RW_DEV_SCREEN 0x41 203/* No OS kernel detected */ 204#define VBNV_RECOVERY_RW_NO_OS 0x42 205/* OS kernel failed signature check */ 206#define VBNV_RECOVERY_RW_INVALID_OS 0x43 207/* TPM error in rewritable firmware (deprecated) */ 208#define VBNV_RECOVERY_DEP_RW_TPM_ERROR 0x44 209/* RW firmware in dev mode, but dev switch is off */ 210#define VBNV_RECOVERY_RW_DEV_MISMATCH 0x45 211/* Shared data error in rewritable firmware */ 212#define VBNV_RECOVERY_RW_SHARED_DATA 0x46 213/* Test error from LoadKernel() */ 214#define VBNV_RECOVERY_RW_TEST_LK 0x47 215/* No bootable disk found (deprecated)*/ 216#define VBNV_RECOVERY_DEP_RW_NO_DISK 0x48 217/* Rebooting did not correct TPM_E_FAIL or TPM_E_FAILEDSELFTEST */ 218#define VBNV_RECOVERY_TPM_E_FAIL 0x49 219/* TPM setup error in read-only firmware */ 220#define VBNV_RECOVERY_RO_TPM_S_ERROR 0x50 221/* TPM write error in read-only firmware */ 222#define VBNV_RECOVERY_RO_TPM_W_ERROR 0x51 223/* TPM lock error in read-only firmware */ 224#define VBNV_RECOVERY_RO_TPM_L_ERROR 0x52 225/* TPM update error in read-only firmware */ 226#define VBNV_RECOVERY_RO_TPM_U_ERROR 0x53 227/* TPM read error in rewritable firmware */ 228#define VBNV_RECOVERY_RW_TPM_R_ERROR 0x54 229/* TPM write error in rewritable firmware */ 230#define VBNV_RECOVERY_RW_TPM_W_ERROR 0x55 231/* TPM lock error in rewritable firmware */ 232#define VBNV_RECOVERY_RW_TPM_L_ERROR 0x56 233/* EC software sync unable to get EC image hash */ 234#define VBNV_RECOVERY_EC_HASH_FAILED 0x57 235/* EC software sync invalid image hash size */ 236#define VBNV_RECOVERY_EC_HASH_SIZE 0x58 237/* Unspecified error while trying to load kernel */ 238#define VBNV_RECOVERY_LK_UNSPECIFIED 0x59 239/* No bootable storage device in system */ 240#define VBNV_RECOVERY_RW_NO_DISK 0x5A 241/* No bootable kernel found on disk */ 242#define VBNV_RECOVERY_RW_NO_KERNEL 0x5B 243/* Unspecified/unknown error in rewritable firmware */ 244#define VBNV_RECOVERY_RW_UNSPECIFIED 0x7F 245/* DM-verity error */ 246#define VBNV_RECOVERY_KE_DM_VERITY 0x81 247/* Unspecified/unknown error in kernel */ 248#define VBNV_RECOVERY_KE_UNSPECIFIED 0xBF 249/* Recovery mode test from user-mode */ 250#define VBNV_RECOVERY_US_TEST 0xC1 251/* Unspecified/unknown error in user-mode */ 252#define VBNV_RECOVERY_US_UNSPECIFIED 0xFF 253 254/** 255 * Initialize the NV storage library. 256 * 257 * This must be called before any other functions in this library. Returns 0 258 * if success, non-zero if error. 259 * 260 * Proper calling procedure: 261 * 1) Allocate a context struct. 262 * 2) If multi-threaded/multi-process, acquire a lock to prevent 263 * other processes from modifying the underlying storage. 264 * 3) Read underlying storage and fill in context->raw. 265 * 4) Call VbNvSetup(). 266 * 267 * If you have access to global variables, you may want to wrap all that in 268 * your own VbNvOpen() function. We don't do that in here because there are no 269 * global variables in UEFI BIOS during the PEI phase (that's also why we have 270 * to pass around a context pointer). 271 */ 272int VbNvSetup(VbNvContext *context); 273 274/** 275 * Clean up and flush changes back to the raw data. 276 * 277 * This must be called after other functions in this library. Returns 0 if 278 * success, non-zero if error. 279 * 280 * Proper calling procedure: 281 * 1) Call VbNvExit(). 282 * 2) If context.raw_changed, write data back to underlying storage. 283 * 3) Release any lock you acquired before calling VbNvSetup(). 284 * 4) Free the context struct. 285 * 286 * If you have access to global variables, you may want to wrap this 287 * in your own VbNvClose() function. 288 */ 289int VbNvTeardown(VbNvContext *context); 290 291/** 292 * Read a NV storage parameter into *dest. 293 * 294 * Returns 0 if success, non-zero if error. 295 * 296 * This may only be called between VbNvSetup() and VbNvTeardown(). 297 */ 298int VbNvGet(VbNvContext *context, VbNvParam param, uint32_t *dest); 299 300/** 301 * Set a NV storage param to a new value. 302 * 303 * Returns 0 if success, non-zero if error. 304 * 305 * This may only be called between VbNvSetup() and VbNvTeardown(). 306 */ 307int VbNvSet(VbNvContext *context, VbNvParam param, uint32_t value); 308 309/** 310 * Attempt to restore some fields of a lost VbNvContext from a backup area. 311 * The rest of the fields are unchanged, so they'd need to be set to their 312 * appropriate defaults by calling VbNvSetup() first (which is usually how we 313 * know the fields have been lost). 314 * 315 * Returns 0 if success, non-zero if error. 316 * 317 * This may only be called between VbNvSetup() and VbNvTeardown(). 318 */ 319int RestoreNvFromBackup(VbNvContext *vnc); 320 321/** 322 * Attempt to save some fields of the VbNvContext to a backup area. 323 * 324 * Returns 0 if success, non-zero if error. If it succeeds, it will clear the 325 * VBNV_BACKUP_NVRAM_REQUEST flag in the VbNvContext. 326 * 327 * This may only be called when the backup area is writable. 328 */ 329int SaveNvToBackup(VbNvContext *vnc); 330 331#endif /* VBOOT_REFERENCE_NVSTORAGE_H_ */ 332