vboot_nvstorage.h revision 9e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1
1b944534edd3799b3353f73bcb8ee90161d640c2bRandall Spangler/* Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
2b944534edd3799b3353f73bcb8ee90161d640c2bRandall Spangler * Use of this source code is governed by a BSD-style license that can be
3b944534edd3799b3353f73bcb8ee90161d640c2bRandall Spangler * found in the LICENSE file.
4b944534edd3799b3353f73bcb8ee90161d640c2bRandall Spangler */
5b944534edd3799b3353f73bcb8ee90161d640c2bRandall Spangler
69e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler/* Non-volatile storage routines for verified boot.
7b944534edd3799b3353f73bcb8ee90161d640c2bRandall Spangler */
8b944534edd3799b3353f73bcb8ee90161d640c2bRandall Spangler
9b944534edd3799b3353f73bcb8ee90161d640c2bRandall Spangler#ifndef VBOOT_REFERENCE_NVSTORAGE_H_
10b944534edd3799b3353f73bcb8ee90161d640c2bRandall Spangler#define VBOOT_REFERENCE_NVSTORAGE_H_
11b944534edd3799b3353f73bcb8ee90161d640c2bRandall Spangler
129e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler#define VBNV_BLOCK_SIZE 16  /* Size of NV storage block in bytes */
13b944534edd3799b3353f73bcb8ee90161d640c2bRandall Spangler
14b944534edd3799b3353f73bcb8ee90161d640c2bRandall Spanglertypedef struct VbNvContext {
15b944534edd3799b3353f73bcb8ee90161d640c2bRandall Spangler  /* Raw NV data.  Caller must fill this before calling VbNvSetup(). */
169e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler  uint8_t raw[VBNV_BLOCK_SIZE];
17b944534edd3799b3353f73bcb8ee90161d640c2bRandall Spangler  /* Flag indicating whether raw data has changed.  Set by VbNvTeardown() if
18b944534edd3799b3353f73bcb8ee90161d640c2bRandall Spangler   * the raw data has changed and needs to be stored to the underlying
19b944534edd3799b3353f73bcb8ee90161d640c2bRandall Spangler   * non-volatile data store. */
20b944534edd3799b3353f73bcb8ee90161d640c2bRandall Spangler  int raw_changed;
21b944534edd3799b3353f73bcb8ee90161d640c2bRandall Spangler
22b944534edd3799b3353f73bcb8ee90161d640c2bRandall Spangler  /* Internal data for NV storage routines.  Caller should not touch
23b944534edd3799b3353f73bcb8ee90161d640c2bRandall Spangler   * these fields. */
24b944534edd3799b3353f73bcb8ee90161d640c2bRandall Spangler  int regenerate_crc;
25b944534edd3799b3353f73bcb8ee90161d640c2bRandall Spangler
26b944534edd3799b3353f73bcb8ee90161d640c2bRandall Spangler} VbNvContext;
27b944534edd3799b3353f73bcb8ee90161d640c2bRandall Spangler
28b944534edd3799b3353f73bcb8ee90161d640c2bRandall Spangler
29b944534edd3799b3353f73bcb8ee90161d640c2bRandall Spangler/* Parameter type for VbNvGet(), VbNvSet(). */
30b944534edd3799b3353f73bcb8ee90161d640c2bRandall Spanglertypedef enum VbNvParam {
319e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler  /* Parameter values have been reset to defaults (flag for firmware).
329e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler   * 0=clear; 1=set. */
33b944534edd3799b3353f73bcb8ee90161d640c2bRandall Spangler  VBNV_FIRMWARE_SETTINGS_RESET = 0,
349e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler  /* Parameter values have been reset to defaults (flag for kernel).
359e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler   * 0=clear; 1=set. */
36b944534edd3799b3353f73bcb8ee90161d640c2bRandall Spangler  VBNV_KERNEL_SETTINGS_RESET,
379e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler  /* Request debug reset on next S3->S0 transition.  0=clear; 1=set. */
38b944534edd3799b3353f73bcb8ee90161d640c2bRandall Spangler  VBNV_DEBUG_RESET_MODE,
399e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler  /* Number of times to try booting RW firmware slot B before slot A.
409e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler   * Valid range: 0-15. */
41b944534edd3799b3353f73bcb8ee90161d640c2bRandall Spangler  VBNV_TRY_B_COUNT,
429e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler  /* Request recovery mode on next boot; see VBNB_RECOVERY_* below for
439e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler   * currently defined reason codes.  8-bit value. */
44b944534edd3799b3353f73bcb8ee90161d640c2bRandall Spangler  VBNV_RECOVERY_REQUEST,
459e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler  /* Localization index for screen bitmaps displayed by firmware.
469e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler   * 8-bit value. */
47b944534edd3799b3353f73bcb8ee90161d640c2bRandall Spangler  VBNV_LOCALIZATION_INDEX,
489e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler  /* Field reserved for kernel/user-mode use; 32-bit value. */
49b944534edd3799b3353f73bcb8ee90161d640c2bRandall Spangler  VBNV_KERNEL_FIELD,
50b944534edd3799b3353f73bcb8ee90161d640c2bRandall Spangler} VbNvParam;
51b944534edd3799b3353f73bcb8ee90161d640c2bRandall Spangler
52b944534edd3799b3353f73bcb8ee90161d640c2bRandall Spangler
539e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler/* Recovery reason codes for VBNV_RECOVERY_REQUEST */
549e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler/* Recovery not requested. */
559e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler#define VBNV_RECOVERY_NOT_REQUESTED   0x00
569e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler/* Recovery requested from legacy utility.  (Prior to the NV storage
579e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler * spec, recovery mode was a single bitfield; this value is reserved
589e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler * so that scripts which wrote 1 to the recovery field are
599e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler * distinguishable from scripts whch use the recovery reasons listed
609e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler * here. */
619e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler#define VBNV_RECOVERY_LEGACY          0x01
629e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler/* User manually requested recovery via recovery button */
639e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler#define VBNV_RECOVERY_RO_MANUAL       0x02
649e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler/* RW firmware failed signature check (neither RW firmware slot was valid) */
659e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler#define VBNV_RECOVERY_RO_INVALID_RW   0x03
669e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler/* S3 resume failed */
679e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler#define VBNV_RECOVERY_RO_S3_RESUME    0x04
689e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler/* TPM error in read-only firmware */
699e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler#define VBNV_RECOVERY_RO_TPM_ERROR    0x05
709e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler/* Unspecified/unknown error in read-only firmware */
719e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler#define VBNV_RECOVERY_RO_UNSPECIFIED  0x3F
729e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler/* User manually requested recovery by pressing a key at developer
739e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler * warning screen */
749e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler#define VBNV_RECOVERY_RW_DEV_SCREEN   0x41
759e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler/* No OS kernel detected */
769e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler#define VBNV_RECOVERY_RW_NO_OS        0x42
779e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler/* OS kernel failed signature check */
789e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler#define VBNV_RECOVERY_RW_INVALID_OS   0x43
799e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler/* TPM error in rewritable firmware */
809e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler#define VBNV_RECOVERY_RW_TPM_ERROR    0x44
819e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler/* Unspecified/unknown error in rewritable firmware */
829e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler#define VBNV_RECOVERY_RW_UNSPECIFIED  0x7F
839e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler/* DM-verity error */
849e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler#define VBNV_RECOVERY_KE_DM_VERITY    0x81
859e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler/* Unspecified/unknown error in kernel */
869e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler#define VBNV_RECOVERY_KE_UNSPECIFIED  0xBF
879e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler/* Recovery mode test from user-mode */
889e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler#define VBNV_RECOVERY_US_TEST         0xC1
899e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler/* Unspecified/unknown error in user-mode */
909e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler#define VBNV_RECOVERY_US_UNSPECIFIED  0xFF
919e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler
929e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler
93b944534edd3799b3353f73bcb8ee90161d640c2bRandall Spangler/* Initialize the NV storage library.  This must be called before any
949e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler * other functions in this library.  Returns 0 if success, non-zero if
95b944534edd3799b3353f73bcb8ee90161d640c2bRandall Spangler * error.
96b944534edd3799b3353f73bcb8ee90161d640c2bRandall Spangler *
979e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler * Proper calling procedure:
989e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler *    1) Allocate a context struct.
999e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler *    2) If multi-threaded/multi-process, acquire a lock to prevent
1009e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler *       other processes from modifying the underlying storage.
1019e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler *    3) Read underlying storage and fill in context->raw.
1029e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler *    4) Call VbNvSetup().
1039e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler *
1049e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler * If you have access to global variables, you may want to wrap all
1059e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler * that in your own VbNvOpen() function.  We don't do that in here
1069e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler * because there are no global variables in UEFI BIOS during the PEI
1079e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler * phase (that's also why we have to pass around a context pointer). */
108b944534edd3799b3353f73bcb8ee90161d640c2bRandall Spanglerint VbNvSetup(VbNvContext* context);
109b944534edd3799b3353f73bcb8ee90161d640c2bRandall Spangler
110b944534edd3799b3353f73bcb8ee90161d640c2bRandall Spangler/* Clean up and flush changes back to the raw data.  This must be
1119e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler * called after other functions in this library.  Returns 0 if
112b944534edd3799b3353f73bcb8ee90161d640c2bRandall Spangler * success, non-zero if error.
113b944534edd3799b3353f73bcb8ee90161d640c2bRandall Spangler *
1149e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler * Proper calling procedure:
1159e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler *    1) Call VbNvExit().
1169e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler *    2) If context.raw_changed, write data back to underlying storage.
1179e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler *    3) Release any lock you acquired before calling VbNvSetup().
1189e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler *    4) Free the context struct.
1199e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler *
120b944534edd3799b3353f73bcb8ee90161d640c2bRandall Spangler * If you have access to global variables, you may want to wrap this
1219e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler * in your own VbNvClose() function. */
122b944534edd3799b3353f73bcb8ee90161d640c2bRandall Spanglerint VbNvTeardown(VbNvContext* context);
123b944534edd3799b3353f73bcb8ee90161d640c2bRandall Spangler
124b944534edd3799b3353f73bcb8ee90161d640c2bRandall Spangler/* Read a NV storage parameter into *dest.  Returns 0 if success,
1259e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler * non-zero if error.
1269e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler *
1279e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler * This may only be called between VbNvSetup() and VbNvTeardown(). */
128b944534edd3799b3353f73bcb8ee90161d640c2bRandall Spanglerint VbNvGet(VbNvContext* context, VbNvParam param, uint32_t* dest);
129b944534edd3799b3353f73bcb8ee90161d640c2bRandall Spangler
130b944534edd3799b3353f73bcb8ee90161d640c2bRandall Spangler/* Set a NV storage param to a new value.  Returns 0 if success,
1319e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler * non-zero if error.
1329e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler *
1339e162cdaa7433dff01d3e47ba3a47cb8b39ff3a1Randall Spangler * This may only be called between VbNvSetup() and VbNvTeardown(). */
134b944534edd3799b3353f73bcb8ee90161d640c2bRandall Spanglerint VbNvSet(VbNvContext* context, VbNvParam param, uint32_t value);
135b944534edd3799b3353f73bcb8ee90161d640c2bRandall Spangler
136b944534edd3799b3353f73bcb8ee90161d640c2bRandall Spangler
137b944534edd3799b3353f73bcb8ee90161d640c2bRandall Spangler#endif  /* VBOOT_REFERENCE_NVSTORAGE_H_ */
138