Home | History | Annotate | Download | only in include
      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 
     14 typedef 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(). */
     32 typedef 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 */
    109 typedef 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  */
    272 int 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  */
    289 int 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  */
    298 int 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  */
    307 int 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  */
    319 int 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  */
    329 int SaveNvToBackup(VbNvContext *vnc);
    330 
    331 #endif  /* VBOOT_REFERENCE_NVSTORAGE_H_ */
    332