diff options
Diffstat (limited to 'firmware/lib')
-rw-r--r-- | firmware/lib/include/load_kernel_fw.h | 4 | ||||
-rw-r--r-- | firmware/lib/include/secdata_tpm.h | 168 | ||||
-rw-r--r-- | firmware/lib/include/vboot_kernel.h | 28 | ||||
-rw-r--r-- | firmware/lib/mocked_secdata_tpm.c | 26 | ||||
-rw-r--r-- | firmware/lib/secdata_tpm.c | 263 | ||||
-rw-r--r-- | firmware/lib/vboot_api_kernel.c | 205 | ||||
-rw-r--r-- | firmware/lib/vboot_display.c | 4 | ||||
-rw-r--r-- | firmware/lib/vboot_kernel.c | 19 | ||||
-rw-r--r-- | firmware/lib/vboot_ui.c | 17 | ||||
-rw-r--r-- | firmware/lib/vboot_ui_common.c | 5 | ||||
-rw-r--r-- | firmware/lib/vboot_ui_menu.c | 17 |
11 files changed, 295 insertions, 461 deletions
diff --git a/firmware/lib/include/load_kernel_fw.h b/firmware/lib/include/load_kernel_fw.h index b2841e17..9e4db8e6 100644 --- a/firmware/lib/include/load_kernel_fw.h +++ b/firmware/lib/include/load_kernel_fw.h @@ -19,8 +19,6 @@ struct vb2_context; /* GPT is external */ #define BOOT_FLAG_EXTERNAL_GPT (0x04ULL) -struct RollbackSpaceFwmp; - typedef struct LoadKernelParams { /* Inputs to LoadKernel() */ /* Disk handle for current device */ @@ -37,8 +35,6 @@ typedef struct LoadKernelParams { uint64_t kernel_buffer_size; /* Boot flags */ uint64_t boot_flags; - /* Firmware management parameters; may be NULL if not present. */ - const struct RollbackSpaceFwmp *fwmp; /* * Outputs from LoadKernel(); valid only if LoadKernel() returns diff --git a/firmware/lib/include/secdata_tpm.h b/firmware/lib/include/secdata_tpm.h index 6e31e71c..3cf1ae75 100644 --- a/firmware/lib/include/secdata_tpm.h +++ b/firmware/lib/include/secdata_tpm.h @@ -9,165 +9,25 @@ #ifndef VBOOT_REFERENCE_SECDATA_TPM_H_ #define VBOOT_REFERENCE_SECDATA_TPM_H_ -#include "2return_codes.h" -#include "2sysincludes.h" -#include "tss_constants.h" +#include "2api.h" /* TPM NVRAM location indices. */ -#define FIRMWARE_NV_INDEX 0x1007 -#define KERNEL_NV_INDEX 0x1008 -/* This is just an opaque space for backup purposes */ -#define BACKUP_NV_INDEX 0x1009 -#define BACKUP_NV_SIZE 16 -#define FWMP_NV_INDEX 0x100a -#define FWMP_NV_MAX_SIZE 128 -#define REC_HASH_NV_INDEX 0x100b -#define REC_HASH_NV_SIZE VB2_SHA256_DIGEST_SIZE +#define FIRMWARE_NV_INDEX 0x1007 +#define KERNEL_NV_INDEX 0x1008 +/* BACKUP_NV_INDEX (size 16) used to live at 0x1009; now deprecated */ +#define FWMP_NV_INDEX 0x100a +#define REC_HASH_NV_INDEX 0x100b +#define REC_HASH_NV_SIZE VB2_SHA256_DIGEST_SIZE /* Space to hold a temporary SHA256 digest of a public key for USB autoconfig; * see crbug.com/845589. */ -#define OOBE_USB_AUTOCONFIG_KEY_DIGEST_NV_INDEX 0x100c -#define OOBE_USB_AUTOCONFIG_KEY_DIGEST_NV_SIZE VB2_SHA256_DIGEST_SIZE - -/* Structure definitions for TPM spaces */ - -/* Kernel space - KERNEL_NV_INDEX, locked with physical presence. */ -#define ROLLBACK_SPACE_KERNEL_VERSION 2 -#define ROLLBACK_SPACE_KERNEL_UID 0x4752574C /* 'GRWL' */ - -typedef struct RollbackSpaceKernel { - /* Struct version, for backwards compatibility */ - uint8_t struct_version; - /* Unique ID to detect space redefinition */ - uint32_t uid; - /* Kernel versions */ - uint32_t kernel_versions; - /* Reserved for future expansion */ - uint8_t reserved[3]; - /* Checksum (v2 and later only) */ - uint8_t crc8; -} __attribute__((packed)) RollbackSpaceKernel; - -/* Flags for firmware space */ -/* - * Last boot was developer mode. TPM ownership is cleared when transitioning - * to/from developer mode. - */ -#define FLAG_LAST_BOOT_DEVELOPER 0x01 -/* - * Some systems may not have a dedicated dev-mode switch, but enter and leave - * dev-mode through some recovery-mode magic keypresses. For those systems, the - * dev-mode "switch" state is in this bit (0=normal, 1=dev). To make it work, a - * new flag is passed to VbInit(), indicating that the system lacks a physical - * dev-mode switch. If a physical switch is present, this bit is ignored. - */ -#define FLAG_VIRTUAL_DEV_MODE_ON 0x02 - -/* Firmware space - FIRMWARE_NV_INDEX, locked with global lock. */ -#define ROLLBACK_SPACE_FIRMWARE_VERSION 2 - -typedef struct RollbackSpaceFirmware { - /* Struct version, for backwards compatibility */ - uint8_t struct_version; - /* Flags (see FLAG_* above) */ - uint8_t flags; - /* Firmware versions */ - uint32_t fw_versions; - /* Reserved for future expansion */ - uint8_t reserved[3]; - /* Checksum (v2 and later only) */ - uint8_t crc8; -} __attribute__((packed)) RollbackSpaceFirmware; - -#define FWMP_HASH_SIZE 32 /* Enough for SHA-256 */ - -/* Firmware management parameters */ -struct RollbackSpaceFwmp { - /* CRC-8 of fields following struct_size */ - uint8_t crc; - /* Structure size in bytes */ - uint8_t struct_size; - /* Structure version */ - uint8_t struct_version; - /* Reserved; ignored by current reader */ - uint8_t reserved0; - /* Flags; see enum fwmp_flags */ - uint32_t flags; - /* Hash of developer kernel key */ - uint8_t dev_key_hash[FWMP_HASH_SIZE]; -} __attribute__((packed)); - -#define ROLLBACK_SPACE_FWMP_VERSION 0x10 /* 1.0 */ - -enum fwmp_flags { - FWMP_DEV_DISABLE_BOOT = (1 << 0), - FWMP_DEV_DISABLE_RECOVERY = (1 << 1), - FWMP_DEV_ENABLE_USB = (1 << 2), - FWMP_DEV_ENABLE_LEGACY = (1 << 3), - FWMP_DEV_ENABLE_OFFICIAL_ONLY = (1 << 4), - FWMP_DEV_USE_KEY_HASH = (1 << 5), - /* CCD = case-closed debugging on cr50; flag implemented on cr50 */ - FWMP_DEV_DISABLE_CCD_UNLOCK = (1 << 6), -}; +#define OOBE_USB_AUTOCONFIG_KEY_DIGEST_NV_INDEX 0x100c +#define OOBE_USB_AUTOCONFIG_KEY_DIGEST_NV_SIZE VB2_SHA256_DIGEST_SIZE /* All functions return TPM_SUCCESS (zero) if successful, non-zero if error */ - -/* - * These functions are callable from VbSelectAndLoadKernel(). They may use - * global variables. - */ - -uint32_t ReadSpaceFirmware(RollbackSpaceFirmware *rsf); -uint32_t WriteSpaceFirmware(RollbackSpaceFirmware *rsf); -uint32_t ReadSpaceKernel(RollbackSpaceKernel *rsk); -uint32_t WriteSpaceKernel(RollbackSpaceKernel *rsk); - -/** - * Read stored kernel version. - */ -uint32_t RollbackKernelRead(uint32_t *version); - -/** - * Write stored kernel version. - */ -uint32_t RollbackKernelWrite(uint32_t version); - -/** - * Lock must be called. Internally, it's ignored in recovery mode. - */ -uint32_t RollbackKernelLock(int recovery_mode); - -/** - * Read and validate firmware management parameters. - * - * Absence of a FWMP is not an error; in this case, fwmp will be cleared. - * - * Returns non-zero if error. - */ -uint32_t RollbackFwmpRead(struct RollbackSpaceFwmp *fwmp); - -/****************************************************************************/ - -/* - * The following functions are internal apis, listed here for use by unit tests - * only. - */ - -/** - * Issue a TPM_Clear and reenable/reactivate the TPM. - */ -uint32_t TPMClearAndReenable(void); - -/** - * Like TlclWrite(), but checks for write errors due to hitting the 64-write - * limit and clears the TPM when that happens. This can only happen when the - * TPM is unowned, so it is OK to clear it (and we really have no choice). - * This is not expected to happen frequently, but it could happen. - */ -uint32_t SafeWrite(uint32_t index, const void *data, uint32_t length); - -/** - * Utility function to turn the virtual dev-mode flag on or off. 0=off, 1=on. - */ -vb2_error_t SetVirtualDevMode(int val); +uint32_t secdata_firmware_write(struct vb2_context *ctx); +uint32_t secdata_kernel_read(struct vb2_context *ctx); +uint32_t secdata_kernel_write(struct vb2_context *ctx); +uint32_t secdata_kernel_lock(struct vb2_context *ctx); +uint32_t secdata_fwmp_read(struct vb2_context *ctx); #endif /* VBOOT_REFERENCE_SECDATA_TPM_H_ */ diff --git a/firmware/lib/include/vboot_kernel.h b/firmware/lib/include/vboot_kernel.h index cf3c4bb3..28c6cc9a 100644 --- a/firmware/lib/include/vboot_kernel.h +++ b/firmware/lib/include/vboot_kernel.h @@ -80,22 +80,32 @@ vb2_error_t VbBootDeveloperMenu(struct vb2_context *ctx); vb2_error_t VbBootRecoveryMenu(struct vb2_context *ctx); /** - * Return the current FWMP flags. Valid only inside VbSelectAndLoadKernel(). + * Reinitialize global state. This should only need to be called by init tests. */ -uint32_t vb2_get_fwmp_flags(void); +void vb2_init_ui(void); /** - * Commit NvStorage. + * Locks secdata_kernel. * - * This may be called by UI functions which need to save settings before they - * sit in an infinite loop waiting for shutdown (this is, by a UI state which - * will never return). + * Should be used right before attempting to leave vboot (by booting + * an OS or chainloading to another firmware). + * + * @param ctx Vboot context + * @returns VB2_SUCCESS, or non-zero error code. */ -void vb2_nv_commit(struct vb2_context *ctx); +vb2_error_t vb2_secdata_kernel_lock(struct vb2_context *ctx); /** - * Reinitialize global state. This should only need to be called by init tests. + * Writes modified secdata spaces and nvdata. + * + * This is a temporary wrapper around vb2ex_commit_data, until secdata-writing + * functions are relocated into depthcharge. + * + * (See chromium:972956, chromium:1006689.) + * + * @param ctx Vboot context + * @returns VB2_SUCCESS, or non-zero error code. */ -void vb2_init_ui(void); +vb2_error_t vb2_commit_data(struct vb2_context *ctx); #endif /* VBOOT_REFERENCE_VBOOT_KERNEL_H_ */ diff --git a/firmware/lib/mocked_secdata_tpm.c b/firmware/lib/mocked_secdata_tpm.c index dc9f16c6..373c4940 100644 --- a/firmware/lib/mocked_secdata_tpm.c +++ b/firmware/lib/mocked_secdata_tpm.c @@ -3,36 +3,42 @@ * found in the LICENSE file. * * Functions for querying, manipulating and locking secure data spaces - * stored in the TPM NVRAM. + * stored in the TPM NVRAM (mock versions). */ +#include "2api.h" +#include "2secdata.h" #include "secdata_tpm.h" #include "tss_constants.h" -#include "utility.h" -vb2_error_t SetVirtualDevMode(int val) +int secdata_kernel_locked = 0; + +uint32_t secdata_firmware_write(struct vb2_context *ctx) { - return VB2_SUCCESS; + ctx->flags &= ~VB2_CONTEXT_SECDATA_FIRMWARE_CHANGED; + return TPM_SUCCESS; } -uint32_t RollbackKernelRead(uint32_t *version) +uint32_t secdata_kernel_read(struct vb2_context *ctx) { - *version = 0; + vb2api_secdata_kernel_create(ctx); return TPM_SUCCESS; } -uint32_t RollbackKernelWrite(uint32_t version) +uint32_t secdata_kernel_write(struct vb2_context *ctx) { + ctx->flags &= ~VB2_CONTEXT_SECDATA_KERNEL_CHANGED; return TPM_SUCCESS; } -uint32_t RollbackKernelLock(int recovery_mode) +uint32_t secdata_kernel_lock(struct vb2_context *ctx) { + secdata_kernel_locked = 1; return TPM_SUCCESS; } -uint32_t RollbackFwmpRead(struct RollbackSpaceFwmp *fwmp) +uint32_t secdata_fwmp_read(struct vb2_context *ctx) { - memset(fwmp, 0, sizeof(*fwmp)); + ctx->flags |= VB2_CONTEXT_NO_SECDATA_FWMP; return TPM_SUCCESS; } diff --git a/firmware/lib/secdata_tpm.c b/firmware/lib/secdata_tpm.c index 6b77ba55..b8f3522c 100644 --- a/firmware/lib/secdata_tpm.c +++ b/firmware/lib/secdata_tpm.c @@ -6,15 +6,12 @@ * stored in the TPM NVRAM. */ +#include "2api.h" #include "2common.h" -#include "2crc8.h" -#include "2nvstorage.h" -#include "2secdata.h" -#include "2sysincludes.h" #include "secdata_tpm.h" #include "tlcl.h" #include "tss_constants.h" -#include "vboot_api.h" +#include "vboot_test.h" #define RETURN_ON_FAILURE(tpm_command) do { \ uint32_t result_; \ @@ -34,9 +31,15 @@ VB2_DEBUG_RAW("\n"); \ } while (0) -uint32_t TPMClearAndReenable(void) +/* Keeps track of whether the kernel space has already been locked or not. */ +int secdata_kernel_locked = 0; + +/** + * Issue a TPM_Clear and reenable/reactivate the TPM. + */ +uint32_t tlcl_clear_and_reenable(void) { - VB2_DEBUG("TPM: clear and re-enable\n"); + VB2_DEBUG("TPM: clear_and_reenable\n"); RETURN_ON_FAILURE(TlclForceClear()); RETURN_ON_FAILURE(TlclSetEnable()); RETURN_ON_FAILURE(TlclSetDeactivated(0)); @@ -44,11 +47,17 @@ uint32_t TPMClearAndReenable(void) return TPM_SUCCESS; } -uint32_t SafeWrite(uint32_t index, const void *data, uint32_t length) +/** + * Like TlclWrite(), but checks for write errors due to hitting the 64-write + * limit and clears the TPM when that happens. This can only happen when the + * TPM is unowned, so it is OK to clear it (and we really have no choice). + * This is not expected to happen frequently, but it could happen. + */ +uint32_t tlcl_safe_write(uint32_t index, const void *data, uint32_t length) { uint32_t result = TlclWrite(index, data, length); if (result == TPM_E_MAXNVWRITES) { - RETURN_ON_FAILURE(TPMClearAndReenable()); + RETURN_ON_FAILURE(tlcl_clear_and_reenable()); return TlclWrite(index, data, length); } else { return result; @@ -56,73 +65,30 @@ uint32_t SafeWrite(uint32_t index, const void *data, uint32_t length) } /* Functions to read and write firmware and kernel spaces. */ -uint32_t ReadSpaceFirmware(RollbackSpaceFirmware *rsf) -{ - uint32_t r; - r = TlclRead(FIRMWARE_NV_INDEX, rsf, sizeof(RollbackSpaceFirmware)); - if (TPM_SUCCESS != r) { - VB2_DEBUG("TPM: read secdata_firmware returned %#x\n", r); - return r; +uint32_t secdata_firmware_write(struct vb2_context *ctx) +{ + if (!(ctx->flags & VB2_CONTEXT_SECDATA_FIRMWARE_CHANGED)) { + VB2_DEBUG("TPM: secdata_firmware unchanged\n"); + return TPM_SUCCESS; } - PRINT_BYTES("TPM: read secdata_firmware", rsf); - - if (rsf->struct_version < ROLLBACK_SPACE_FIRMWARE_VERSION) - return TPM_E_STRUCT_VERSION; - if (rsf->crc8 != vb2_crc8(rsf, offsetof(RollbackSpaceFirmware, crc8))) { - VB2_DEBUG("TPM: bad secdata_firmware CRC\n"); - return TPM_E_CORRUPTED_STATE; + if (!(ctx->flags & VB2_CONTEXT_RECOVERY_MODE)) { + VB2_DEBUG("Error: secdata_firmware modified " + "in non-recovery mode?\n"); + return TPM_E_AREA_LOCKED; } - return TPM_SUCCESS; -} - -uint32_t WriteSpaceFirmware(RollbackSpaceFirmware *rsf) -{ - uint32_t r; - - rsf->crc8 = vb2_crc8(rsf, offsetof(RollbackSpaceFirmware, crc8)); - - PRINT_BYTES("TPM: write secdata", rsf); - r = SafeWrite(FIRMWARE_NV_INDEX, rsf, sizeof(RollbackSpaceFirmware)); - if (TPM_SUCCESS != r) { - VB2_DEBUG("TPM: write secdata_firmware failure\n"); - return r; - } + PRINT_BYTES("TPM: write secdata_firmware", &ctx->secdata_firmware); + RETURN_ON_FAILURE(tlcl_safe_write(FIRMWARE_NV_INDEX, + ctx->secdata_firmware, + VB2_SECDATA_FIRMWARE_SIZE)); + ctx->flags &= ~VB2_CONTEXT_SECDATA_FIRMWARE_CHANGED; return TPM_SUCCESS; } -vb2_error_t SetVirtualDevMode(int val) -{ - RollbackSpaceFirmware rsf; - - VB2_DEBUG("Enabling developer mode...\n"); - - if (TPM_SUCCESS != ReadSpaceFirmware(&rsf)) - return VBERROR_TPM_FIRMWARE_SETUP; - - VB2_DEBUG("TPM: flags were 0x%02x\n", rsf.flags); - if (val) - rsf.flags |= FLAG_VIRTUAL_DEV_MODE_ON; - else - rsf.flags &= ~FLAG_VIRTUAL_DEV_MODE_ON; - /* - * NOTE: This doesn't update the FLAG_LAST_BOOT_DEVELOPER bit. That - * will be done on the next boot. - */ - VB2_DEBUG("TPM: flags are now 0x%02x\n", rsf.flags); - - if (TPM_SUCCESS != WriteSpaceFirmware(&rsf)) - return VBERROR_TPM_SET_BOOT_MODE_STATE; - - VB2_DEBUG("Mode change will take effect on next reboot\n"); - - return VB2_SUCCESS; -} - -uint32_t ReadSpaceKernel(RollbackSpaceKernel *rsk) +uint32_t secdata_kernel_read(struct vb2_context *ctx) { #ifndef TPM2_MODE /* @@ -135,158 +101,89 @@ uint32_t ReadSpaceKernel(RollbackSpaceKernel *rsk) uint32_t perms; RETURN_ON_FAILURE(TlclGetPermissions(KERNEL_NV_INDEX, &perms)); - - if (perms != TPM_NV_PER_PPWRITE) + if (perms != TPM_NV_PER_PPWRITE) { + VB2_DEBUG("TPM: invalid secdata_kernel permissions: %#x\n", + perms); return TPM_E_CORRUPTED_STATE; -#endif - - uint32_t r; - - r = TlclRead(KERNEL_NV_INDEX, rsk, sizeof(RollbackSpaceKernel)); - if (TPM_SUCCESS != r) { - VB2_DEBUG("TPM: read secdata_kernel returned %#x\n", r); - return r; } - PRINT_BYTES("TPM: read secdata_kernel", rsk); +#endif - if (rsk->struct_version < ROLLBACK_SPACE_FIRMWARE_VERSION) - return TPM_E_STRUCT_VERSION; + RETURN_ON_FAILURE(TlclRead(KERNEL_NV_INDEX, ctx->secdata_kernel, + VB2_SECDATA_KERNEL_SIZE)); - if (rsk->uid != ROLLBACK_SPACE_KERNEL_UID) - return TPM_E_CORRUPTED_STATE; + PRINT_BYTES("TPM: read secdata_kernel", &ctx->secdata_kernel); - if (rsk->crc8 != vb2_crc8(rsk, offsetof(RollbackSpaceKernel, crc8))) { - VB2_DEBUG("TPM: bad secdata_kernel CRC\n"); + if (vb2api_secdata_kernel_check(ctx)) { + VB2_DEBUG("TPM: secdata_kernel invalid (corrupted?)\n"); return TPM_E_CORRUPTED_STATE; } return TPM_SUCCESS; } -uint32_t WriteSpaceKernel(RollbackSpaceKernel *rsk) +uint32_t secdata_kernel_write(struct vb2_context *ctx) { - uint32_t r; - - rsk->crc8 = vb2_crc8(rsk, offsetof(RollbackSpaceKernel, crc8)); - - PRINT_BYTES("TPM: write secdata_kernel", rsk); - r = SafeWrite(KERNEL_NV_INDEX, rsk, sizeof(RollbackSpaceKernel)); - if (TPM_SUCCESS != r) { - VB2_DEBUG("TPM: write secdata_kernel failure\n"); - return r; + if (!(ctx->flags & VB2_CONTEXT_SECDATA_KERNEL_CHANGED)) { + VB2_DEBUG("TPM: secdata_kernel unchanged\n"); + return TPM_SUCCESS; } - return TPM_SUCCESS; -} + PRINT_BYTES("TPM: write secdata_kernel", &ctx->secdata_kernel); -uint32_t RollbackKernelRead(uint32_t* version) -{ - RollbackSpaceKernel rsk; - RETURN_ON_FAILURE(ReadSpaceKernel(&rsk)); - memcpy(version, &rsk.kernel_versions, sizeof(*version)); - VB2_DEBUG("TPM: RollbackKernelRead %#x\n", (int)*version); - return TPM_SUCCESS; -} + RETURN_ON_FAILURE(tlcl_safe_write(KERNEL_NV_INDEX, ctx->secdata_kernel, + VB2_SECDATA_KERNEL_SIZE)); -uint32_t RollbackKernelWrite(uint32_t version) -{ - RollbackSpaceKernel rsk; - uint32_t old_version; - RETURN_ON_FAILURE(ReadSpaceKernel(&rsk)); - memcpy(&old_version, &rsk.kernel_versions, sizeof(old_version)); - VB2_DEBUG("TPM: RollbackKernelWrite %#x --> %#x\n", - (int)old_version, (int)version); - memcpy(&rsk.kernel_versions, &version, sizeof(version)); - return WriteSpaceKernel(&rsk); + ctx->flags &= ~VB2_CONTEXT_SECDATA_KERNEL_CHANGED; + return TPM_SUCCESS; } -uint32_t RollbackKernelLock(int recovery_mode) +uint32_t secdata_kernel_lock(struct vb2_context *ctx) { - static int kernel_locked = 0; - uint32_t r; - - if (recovery_mode || kernel_locked) + /* Skip if already locked */ + if (secdata_kernel_locked) { + VB2_DEBUG("TPM: secdata_kernel already locked; skipping\n"); return TPM_SUCCESS; + } - r = TlclLockPhysicalPresence(); - if (TPM_SUCCESS == r) - kernel_locked = 1; + RETURN_ON_FAILURE(TlclLockPhysicalPresence()); - VB2_DEBUG("TPM: lock secdata_kernel returned %#x\n", r); - return r; + VB2_DEBUG("TPM: secdata_kernel locked\n"); + secdata_kernel_locked = 1; + return TPM_SUCCESS; } -uint32_t RollbackFwmpRead(struct RollbackSpaceFwmp *fwmp) +uint32_t secdata_fwmp_read(struct vb2_context *ctx) { - union { - /* - * Use a union for buf and fwmp, rather than making fwmp a - * pointer to a bare uint8_t[] buffer. This ensures fwmp will - * be aligned if necesssary for the target platform. - */ - uint8_t buf[FWMP_NV_MAX_SIZE]; - struct RollbackSpaceFwmp fwmp; - } u; + vb2_error_t rv; + uint8_t size = VB2_SECDATA_FWMP_MIN_SIZE; uint32_t r; - /* Clear destination in case error or FWMP not present */ - memset(fwmp, 0, sizeof(*fwmp)); - /* Try to read entire 1.0 struct */ - r = TlclRead(FWMP_NV_INDEX, u.buf, sizeof(u.fwmp)); + r = TlclRead(FWMP_NV_INDEX, ctx->secdata_fwmp, size); if (TPM_E_BADINDEX == r) { - /* Missing space is not an error; use defaults */ - VB2_DEBUG("TPM: no FWMP space\n"); + /* Missing space is not an error; tell vboot */ + VB2_DEBUG("TPM: no secdata_fwmp space\n"); + ctx->flags |= VB2_CONTEXT_NO_SECDATA_FWMP; return TPM_SUCCESS; } else if (TPM_SUCCESS != r) { - VB2_DEBUG("TPM: read FWMP returned %#x\n", r); + VB2_DEBUG("TPM: read secdata_fwmp returned %#x\n", r); return r; } - /* - * Struct must be at least big enough for 1.0, but not bigger - * than our buffer size. - */ - if (u.fwmp.struct_size < sizeof(u.fwmp) || - u.fwmp.struct_size > sizeof(u.buf)) { - VB2_DEBUG("TPM: FWMP size invalid: %#x\n", u.fwmp.struct_size); - return TPM_E_STRUCT_SIZE; - } - - /* - * If space is bigger than we expect, re-read so we properly - * compute the CRC. - */ - if (u.fwmp.struct_size > sizeof(u.fwmp)) { - r = TlclRead(FWMP_NV_INDEX, u.buf, u.fwmp.struct_size); - if (TPM_SUCCESS != r) { - VB2_DEBUG("TPM: re-read FWMP returned %#x\n", r); - return r; - } - } + /* Re-read more data if necessary */ + rv = vb2api_secdata_fwmp_check(ctx, &size); + if (rv == VB2_SUCCESS) + return VB2_SUCCESS; - /* Verify CRC */ - if (u.fwmp.crc != vb2_crc8(u.buf + 2, u.fwmp.struct_size - 2)) { - VB2_DEBUG("TPM: bad FWMP CRC\n"); - return TPM_E_CORRUPTED_STATE; - } + if (rv == VB2_ERROR_SECDATA_FWMP_INCOMPLETE) { + RETURN_ON_FAILURE(TlclRead(FWMP_NV_INDEX, ctx->secdata_fwmp, + size)); - /* Verify major version is compatible */ - if ((u.fwmp.struct_version >> 4) != - (ROLLBACK_SPACE_FWMP_VERSION >> 4)) { - VB2_DEBUG("TPM: FWMP major version incompatible\n"); - return TPM_E_STRUCT_VERSION; + /* Check one more time */ + if (vb2api_secdata_fwmp_check(ctx, &size) == VB2_SUCCESS) + return VB2_SUCCESS; } - /* - * Copy to destination. Note that if the space is bigger than - * we expect (due to a minor version change), we only copy the - * part of the FWMP that we know what to do with. - * - * If this were a 1.1+ reader and the source was a 1.0 struct, - * we would need to take care of initializing the extra fields - * added in 1.1+. But that's not an issue yet. - */ - memcpy(fwmp, &u.fwmp, sizeof(*fwmp)); - return TPM_SUCCESS; + VB2_DEBUG("TPM: secdata_fwmp invalid (corrupted?)\n"); + return TPM_E_CORRUPTED_STATE; } diff --git a/firmware/lib/vboot_api_kernel.c b/firmware/lib/vboot_api_kernel.c index 5408c5a3..308a3275 100644 --- a/firmware/lib/vboot_api_kernel.c +++ b/firmware/lib/vboot_api_kernel.c @@ -22,36 +22,20 @@ #include "vboot_test.h" /* Global variables */ -static struct RollbackSpaceFwmp fwmp; static LoadKernelParams lkp; #ifdef CHROMEOS_ENVIRONMENT -/* Global variable accessors for unit tests */ - -struct RollbackSpaceFwmp *VbApiKernelGetFwmp(void) -{ - return &fwmp; -} - +/* Global variable accessor for unit tests */ struct LoadKernelParams *VbApiKernelGetParams(void) { return &lkp; } - #endif -void vb2_nv_commit(struct vb2_context *ctx) -{ - /* Exit if nothing has changed */ - if (!(ctx->flags & VB2_CONTEXT_NVDATA_CHANGED)) - return; - - ctx->flags &= ~VB2_CONTEXT_NVDATA_CHANGED; - VbExNvStorageWrite(ctx->nvdata); -} - static vb2_error_t handle_battery_cutoff(struct vb2_context *ctx) { + vb2_error_t rv; + /* * Check if we need to cut-off battery. This should be done after EC * FW and Aux FW are updated, and before the kernel is started. This @@ -61,8 +45,12 @@ static vb2_error_t handle_battery_cutoff(struct vb2_context *ctx) if (vb2_nv_get(ctx, VB2_NV_BATTERY_CUTOFF_REQUEST)) { VB2_DEBUG("Request to cut-off battery\n"); vb2_nv_set(ctx, VB2_NV_BATTERY_CUTOFF_REQUEST, 0); + /* May lose power immediately, so commit our update now. */ - vb2_nv_commit(ctx); + rv = vb2_commit_data(ctx); + if (rv) + return rv; + vb2ex_ec_battery_cutoff(); return VBERROR_SHUTDOWN_REQUESTED; } @@ -70,11 +58,6 @@ static vb2_error_t handle_battery_cutoff(struct vb2_context *ctx) return VB2_SUCCESS; } -uint32_t vb2_get_fwmp_flags(void) -{ - return fwmp.flags; -} - vb2_error_t VbTryLoadKernel(struct vb2_context *ctx, uint32_t get_info_flags) { vb2_error_t rv = VBERROR_NO_DISK_FOUND; @@ -82,7 +65,6 @@ vb2_error_t VbTryLoadKernel(struct vb2_context *ctx, uint32_t get_info_flags) uint32_t disk_count = 0; uint32_t i; - lkp.fwmp = &fwmp; lkp.disk_handle = NULL; /* Find disks */ @@ -234,13 +216,8 @@ vb2_error_t VbBootNormal(struct vb2_context *ctx) } if (shared->kernel_version_tpm > shared->kernel_version_tpm_start) { - uint32_t tpm_rv = - RollbackKernelWrite(shared->kernel_version_tpm); - if (tpm_rv) { - VB2_DEBUG("Error writing kernel versions to TPM.\n"); - vb2api_fail(ctx, VB2_RECOVERY_RW_TPM_W_ERROR, tpm_rv); - return VBERROR_TPM_WRITE_KERNEL; - } + vb2_secdata_kernel_set(ctx, VB2_SECDATA_KERNEL_VERSIONS, + shared->kernel_version_tpm); } return rv; @@ -251,6 +228,7 @@ static vb2_error_t vb2_kernel_setup(struct vb2_context *ctx, VbSelectAndLoadKernelParams *kparams) { uint32_t tpm_rv; + vb2_error_t rv; /* Translate vboot1 flags back to vboot2 */ if (shared->recovery_reason) @@ -274,11 +252,9 @@ static vb2_error_t vb2_kernel_setup(struct vb2_context *ctx, if (shared->flags & VBSD_NVDATA_V2) ctx->flags |= VB2_CONTEXT_NVDATA_V2; - VbExNvStorageRead(ctx->nvdata); vb2_nv_init(ctx); struct vb2_shared_data *sd = vb2_get_sd(ctx); - struct vb2_gbb_header *gbb = vb2_get_gbb(ctx); sd->recovery_reason = shared->recovery_reason; /* @@ -312,41 +288,53 @@ static vb2_error_t vb2_kernel_setup(struct vb2_context *ctx, kparams->flags = 0; memset(kparams->partition_guid, 0, sizeof(kparams->partition_guid)); - /* Read kernel version from the TPM. Ignore errors in recovery mode. */ - tpm_rv = RollbackKernelRead(&shared->kernel_version_tpm); - if (tpm_rv) { - VB2_DEBUG("Unable to get kernel versions from TPM\n"); - if (!(ctx->flags & VB2_CONTEXT_RECOVERY_MODE)) { - vb2api_fail(ctx, VB2_RECOVERY_RW_TPM_R_ERROR, tpm_rv); - return VBERROR_TPM_READ_KERNEL; - } + /* + * Read secdata_kernel and secdata_fwmp spaces. No need to read + * secdata_firmware, since it was already read during firmware + * verification. Ignore errors in recovery mode. + */ + tpm_rv = secdata_kernel_read(ctx); + if (tpm_rv && !(ctx->flags & VB2_CONTEXT_RECOVERY_MODE)) { + VB2_DEBUG("TPM: read secdata_kernel returned %#x\n", tpm_rv); + vb2api_fail(ctx, VB2_RECOVERY_RW_TPM_R_ERROR, tpm_rv); + return VB2_ERROR_SECDATA_KERNEL_READ; } - - shared->kernel_version_tpm_start = shared->kernel_version_tpm; - - /* Read FWMP. Ignore errors in recovery mode. */ - if (gbb->flags & VB2_GBB_FLAG_DISABLE_FWMP) { - memset(&fwmp, 0, sizeof(fwmp)); - return VB2_SUCCESS; + tpm_rv = secdata_fwmp_read(ctx); + if (tpm_rv && !(ctx->flags & VB2_CONTEXT_RECOVERY_MODE)) { + VB2_DEBUG("TPM: read secdata_fwmp returned %#x\n", tpm_rv); + vb2api_fail(ctx, VB2_RECOVERY_RW_TPM_R_ERROR, tpm_rv); + return VB2_ERROR_SECDATA_FWMP_READ; } - tpm_rv = RollbackFwmpRead(&fwmp); - if (tpm_rv) { - VB2_DEBUG("Unable to get FWMP from TPM\n"); - if (!(ctx->flags & VB2_CONTEXT_RECOVERY_MODE)) { - vb2api_fail(ctx, VB2_RECOVERY_RW_TPM_R_ERROR, tpm_rv); - return VBERROR_TPM_READ_FWMP; - } + /* + * Init secdata_kernel and secdata_fwmp spaces. No need to init + * secdata_firmware, since it was already read during firmware + * verification. Ignore errors in recovery mode. + */ + rv = vb2_secdata_kernel_init(ctx); + if (rv && !(ctx->flags & VB2_CONTEXT_RECOVERY_MODE)) { + VB2_DEBUG("TPM: init secdata_kernel returned %#x\n", rv); + vb2api_fail(ctx, VB2_RECOVERY_SECDATA_KERNEL_INIT, rv); + return rv; } + rv = vb2_secdata_fwmp_init(ctx); + if (rv && !(ctx->flags & VB2_CONTEXT_RECOVERY_MODE)) { + VB2_DEBUG("TPM: init secdata_fwmp returned %#x\n", rv); + vb2api_fail(ctx, VB2_RECOVERY_SECDATA_FWMP_INIT, rv); + return rv; + } + + /* Read kernel version from the TPM. */ + shared->kernel_version_tpm = + vb2_secdata_kernel_get(ctx, VB2_SECDATA_KERNEL_VERSIONS); + shared->kernel_version_tpm_start = shared->kernel_version_tpm; return VB2_SUCCESS; } -static vb2_error_t vb2_kernel_phase4(struct vb2_context *ctx, - VbSelectAndLoadKernelParams *kparams) +static void vb2_kernel_fill_kparams(struct vb2_context *ctx, + VbSelectAndLoadKernelParams *kparams) { - struct vb2_shared_data *sd = vb2_get_sd(ctx); - /* Save disk parameters */ kparams->disk_handle = lkp.disk_handle; kparams->partition_number = lkp.partition_number; @@ -357,30 +345,89 @@ static vb2_error_t vb2_kernel_phase4(struct vb2_context *ctx, kparams->kernel_buffer_size = lkp.kernel_buffer_size; memcpy(kparams->partition_guid, lkp.partition_guid, sizeof(kparams->partition_guid)); +} - /* Lock the kernel versions if not in recovery mode */ - if (!(ctx->flags & VB2_CONTEXT_RECOVERY_MODE)) { - uint32_t tpm_rv = RollbackKernelLock(sd->recovery_reason); - if (tpm_rv) { - VB2_DEBUG("Error locking kernel versions.\n"); - vb2api_fail(ctx, VB2_RECOVERY_RW_TPM_L_ERROR, tpm_rv); - return VBERROR_TPM_LOCK_KERNEL; - } +vb2_error_t vb2_secdata_kernel_lock(struct vb2_context *ctx) +{ + uint32_t tpm_rv; + + /* Skip if in recovery mode. */ + if (ctx->flags & VB2_CONTEXT_RECOVERY_MODE) + return VB2_SUCCESS; + + tpm_rv = secdata_kernel_lock(ctx); + if (tpm_rv) { + VB2_DEBUG("TPM: lock secdata_kernel returned %#x\n", tpm_rv); + vb2api_fail(ctx, VB2_RECOVERY_RW_TPM_L_ERROR, tpm_rv); + return VB2_ERROR_SECDATA_KERNEL_LOCK; } return VB2_SUCCESS; } -static void vb2_kernel_cleanup(struct vb2_context *ctx) +vb2_error_t vb2_commit_data(struct vb2_context *ctx) { - vb2_nv_commit(ctx); + vb2_error_t call_rv; + vb2_error_t rv = VB2_SUCCESS; + uint32_t tpm_rv; + + /* Write secdata spaces. vboot never writes back to secdata_fwmp. */ + tpm_rv = secdata_firmware_write(ctx); + if (tpm_rv && !(ctx->flags & VB2_CONTEXT_RECOVERY_MODE)) { + VB2_DEBUG("TPM: write secdata_firmware returned %#x\n", tpm_rv); + vb2api_fail(ctx, VB2_RECOVERY_RW_TPM_W_ERROR, tpm_rv); + rv = VB2_ERROR_SECDATA_FIRMWARE_WRITE; + } + + tpm_rv = secdata_kernel_write(ctx); + if (tpm_rv && !(ctx->flags & VB2_CONTEXT_RECOVERY_MODE)) { + VB2_DEBUG("TPM: write secdata_kernel returned %#x\n", tpm_rv); + vb2api_fail(ctx, VB2_RECOVERY_RW_TPM_W_ERROR, tpm_rv); + if (rv == VB2_SUCCESS) + rv = VB2_ERROR_SECDATA_KERNEL_WRITE; + } + + /* Always try to write nvdata, since it may have been changed by + setting a recovery reason above. */ + + /* TODO(chromium:972956, chromium:1006689): Currently only commits + nvdata, but should eventually also commit secdata. */ + call_rv = vb2ex_commit_data(ctx); + switch (call_rv) { + case VB2_ERROR_NV_WRITE: + /* Don't bother with vb2api_fail since we can't write + nvdata anyways. */ + if (ctx->flags & VB2_CONTEXT_RECOVERY_MODE) { + VB2_DEBUG("write nvdata failed\n"); + if (rv == VB2_SUCCESS) + rv = call_rv; + } else { + /* Impossible to enter recovery mode */ + VB2_DIE("write nvdata failed\n"); + } + break; + + case VB2_SUCCESS: + break; + + default: + VB2_DEBUG("unknown commit error: %#x\n", call_rv); + if (!(ctx->flags & VB2_CONTEXT_RECOVERY_MODE) && + rv == VB2_SUCCESS) + rv = call_rv; + break; + } + + return rv; } vb2_error_t VbSelectAndLoadKernel(struct vb2_context *ctx, VbSharedDataHeader *shared, VbSelectAndLoadKernelParams *kparams) { - vb2_error_t rv = vb2_kernel_setup(ctx, shared, kparams); + vb2_error_t rv, call_rv; + + rv = vb2_kernel_setup(ctx, shared, kparams); if (rv) goto VbSelectAndLoadKernel_exit; @@ -441,10 +488,18 @@ vb2_error_t VbSelectAndLoadKernel(struct vb2_context *ctx, VbSelectAndLoadKernel_exit: - if (VB2_SUCCESS == rv) - rv = vb2_kernel_phase4(ctx, kparams); + if (rv == VB2_SUCCESS) + vb2_kernel_fill_kparams(ctx, kparams); + + /* Commit data, but retain any previous errors */ + call_rv = vb2_commit_data(ctx); + if (rv == VB2_SUCCESS) + rv = call_rv; - vb2_kernel_cleanup(ctx); + /* Lock secdata_kernel, but retain any previous errors */ + call_rv = vb2_secdata_kernel_lock(ctx); + if (rv == VB2_SUCCESS) + rv = call_rv; /* Pass through return value from boot path */ VB2_DEBUG("Returning %#x\n", rv); diff --git a/firmware/lib/vboot_display.c b/firmware/lib/vboot_display.c index d3daf658..0c62a86d 100644 --- a/firmware/lib/vboot_display.c +++ b/firmware/lib/vboot_display.c @@ -383,11 +383,11 @@ vb2_error_t VbCheckDisplayKey(struct vb2_context *ctx, uint32_t key, /* * Non-manual recovery mode is meant to be left via three-finger * salute (into manual recovery mode). Need to commit nvdata - * changes immediately. + * changes immediately. Ignore commit errors in recovery mode. */ if ((ctx->flags & VB2_CONTEXT_RECOVERY_MODE) && !vb2_allow_recovery(ctx)) - vb2_nv_commit(ctx); + vb2_commit_data(ctx); /* Force redraw of current screen */ return VbDisplayScreen(ctx, disp_current_screen, 1, data); diff --git a/firmware/lib/vboot_kernel.c b/firmware/lib/vboot_kernel.c index 351044b3..1f1647cc 100644 --- a/firmware/lib/vboot_kernel.c +++ b/firmware/lib/vboot_kernel.c @@ -63,8 +63,8 @@ static int require_official_os(struct vb2_context *ctx, return 1; /* FWMP can require developer mode to use official OS */ - if (params->fwmp && - (params->fwmp->flags & FWMP_DEV_ENABLE_OFFICIAL_ONLY)) + if (vb2_secdata_fwmp_get_flag( + ctx, VB2_SECDATA_FWMP_DEV_ENABLE_OFFICIAL_ONLY)) return 1; /* Developer can request official OS via nvstorage */ @@ -210,7 +210,7 @@ static vb2_error_t vb2_verify_kernel_vblock( /* If in developer mode and using key hash, check it */ if ((kBootDev == boot_mode) && - params->fwmp && (params->fwmp->flags & FWMP_DEV_USE_KEY_HASH)) { + vb2_secdata_fwmp_get_flag(ctx, VB2_SECDATA_FWMP_DEV_USE_KEY_HASH)) { struct vb2_packed_key *key = &keyblock->data_key; uint8_t *buf = ((uint8_t *)key) + key->key_offset; uint32_t buflen = key->key_size; @@ -219,15 +219,22 @@ static vb2_error_t vb2_verify_kernel_vblock( VB2_DEBUG("Checking developer key hash.\n"); vb2_digest_buffer(buf, buflen, VB2_HASH_SHA256, digest, sizeof(digest)); - if (0 != vb2_safe_memcmp(digest, params->fwmp->dev_key_hash, + + uint8_t *fwmp_dev_key_hash = + vb2_secdata_fwmp_get_dev_key_hash(ctx); + if (fwmp_dev_key_hash == NULL) { + VB2_DEBUG("Couldn't retrieve developer key hash.\n"); + return VB2_ERROR_VBLOCK_DEV_KEY_HASH; + } + + if (0 != vb2_safe_memcmp(digest, fwmp_dev_key_hash, VB2_SHA256_DIGEST_SIZE)) { int i; VB2_DEBUG("Wrong developer key hash.\n"); VB2_DEBUG("Want: "); for (i = 0; i < VB2_SHA256_DIGEST_SIZE; i++) - VB2_DEBUG("%02x", - params->fwmp->dev_key_hash[i]); + VB2_DEBUG("%02x", fwmp_dev_key_hash[i]); VB2_DEBUG("\nGot: "); for (i = 0; i < VB2_SHA256_DIGEST_SIZE; i++) VB2_DEBUG("%02x", digest[i]); diff --git a/firmware/lib/vboot_ui.c b/firmware/lib/vboot_ui.c index f7e82a99..306e22da 100644 --- a/firmware/lib/vboot_ui.c +++ b/firmware/lib/vboot_ui.c @@ -477,10 +477,10 @@ static vb2_error_t vb2_diagnostics_ui(struct vb2_context *ctx) /* * The following helps avoid use of the TPM after * it's disabled (e.g., when vb2_run_altfw() calls - * RollbackKernelLock() ). + * secdata_kernel_lock() ). */ - if (RollbackKernelLock(0)) { + if (secdata_kernel_lock(ctx)) { VB2_DEBUG("Failed to lock TPM PP\n"); vb2api_fail(ctx, VB2_RECOVERY_TPM_DISABLE_FAILED, 0); } else if (vb2ex_tpm_set_mode(VB2_TPM_MODE_DISABLED) != @@ -542,12 +542,11 @@ static vb2_error_t vb2_developer_ui(struct vb2_context *ctx) } /* Handle FWMP override */ - uint32_t fwmp_flags = vb2_get_fwmp_flags(); - if (fwmp_flags & FWMP_DEV_ENABLE_USB) + if (vb2_secdata_fwmp_get_flag(ctx, VB2_SECDATA_FWMP_DEV_ENABLE_USB)) allow_usb = 1; - if (fwmp_flags & FWMP_DEV_ENABLE_LEGACY) + if (vb2_secdata_fwmp_get_flag(ctx, VB2_SECDATA_FWMP_DEV_ENABLE_LEGACY)) allow_legacy = 1; - if (fwmp_flags & FWMP_DEV_DISABLE_BOOT) { + if (vb2_secdata_fwmp_get_flag(ctx, VB2_SECDATA_FWMP_DEV_DISABLE_BOOT)) { if (gbb->flags & VB2_GBB_FLAG_FORCE_DEV_SWITCH_ON) { VB2_DEBUG("FWMP_DEV_DISABLE_BOOT rejected by " "FORCE_DEV_SWITCH_ON\n"); @@ -819,9 +818,9 @@ static vb2_error_t recovery_ui(struct vb2_context *ctx) /* * Non-manual recovery mode is meant to be left via three-finger * salute (into manual recovery mode). Need to commit nvdata - * changes immediately. + * changes immediately. Ignore commit errors in recovery mode. */ - vb2_nv_commit(ctx); + vb2_commit_data(ctx); VbDisplayScreen(ctx, VB_SCREEN_OS_BROKEN, 0, NULL); VB2_DEBUG("VbBootRecovery() waiting for manual recovery\n"); @@ -885,7 +884,7 @@ static vb2_error_t recovery_ui(struct vb2_context *ctx) switch (VbUserConfirms(ctx, vbc_flags)) { case 1: VB2_DEBUG("Enabling dev-mode...\n"); - if (VB2_SUCCESS != SetVirtualDevMode(1)) + if (VB2_SUCCESS != vb2_enable_developer_mode(ctx)) return VBERROR_TPM_SET_BOOT_MODE_STATE; VB2_DEBUG("Reboot so it will take effect\n"); if (VbExGetSwitches diff --git a/firmware/lib/vboot_ui_common.c b/firmware/lib/vboot_ui_common.c index 1e956576..5f51f530 100644 --- a/firmware/lib/vboot_ui_common.c +++ b/firmware/lib/vboot_ui_common.c @@ -43,11 +43,12 @@ void vb2_error_notify(const char *print_msg, void vb2_run_altfw(struct vb2_context *ctx, enum VbAltFwIndex_t altfw_num) { - if (RollbackKernelLock(0)) { + if (secdata_kernel_lock(ctx)) { vb2_error_notify("Error locking kernel versions on legacy " "boot.\n", NULL, VB_BEEP_FAILED); } else { - vb2_nv_commit(ctx); + /* TODO: Figure out what to do on commit error in altfw. */ + vb2_commit_data(ctx); VbExLegacy(altfw_num); /* will not return if found */ vb2_error_notify("Legacy boot failed. Missing BIOS?\n", NULL, VB_BEEP_FAILED); diff --git a/firmware/lib/vboot_ui_menu.c b/firmware/lib/vboot_ui_menu.c index 89ac6323..bc3d882c 100644 --- a/firmware/lib/vboot_ui_menu.c +++ b/firmware/lib/vboot_ui_menu.c @@ -181,7 +181,7 @@ static vb2_error_t boot_usb_action(struct vb2_context *ctx) if (!vb2_nv_get(ctx, VB2_NV_DEV_BOOT_USB) && !(vb2_get_gbb(ctx)->flags & VB2_GBB_FLAG_FORCE_DEV_BOOT_USB) && - !(vb2_get_fwmp_flags() & FWMP_DEV_ENABLE_USB)) { + !vb2_secdata_fwmp_get_flag(ctx, VB2_SECDATA_FWMP_DEV_ENABLE_USB)) { vb2_flash_screen(ctx); vb2_error_notify("WARNING: Booting from external media " "(USB/SD) has not been enabled. Refer " @@ -313,11 +313,11 @@ static vb2_error_t language_action(struct vb2_context *ctx) /* * Non-manual recovery mode is meant to be left via three-finger * salute (into manual recovery mode). Need to commit nvdata - * changes immediately. + * changes immediately. Ignore commit errors in recovery mode. */ if ((ctx->flags & VB2_CONTEXT_RECOVERY_MODE) && !vb2_allow_recovery(ctx)) - vb2_nv_commit(ctx); + vb2_commit_data(ctx); /* Return to previous menu. */ switch (prev_menu) { @@ -360,7 +360,7 @@ static vb2_error_t to_dev_action(struct vb2_context *ctx) return VBERROR_KEEP_LOOPING; VB2_DEBUG("Enabling dev-mode...\n"); - if (VB2_SUCCESS != SetVirtualDevMode(1)) + if (VB2_SUCCESS != vb2_enable_developer_mode(ctx)) return VBERROR_TPM_SET_BOOT_MODE_STATE; /* This was meant for headless devices, shouldn't really matter here. */ @@ -744,7 +744,7 @@ static vb2_error_t vb2_developer_menu(struct vb2_context *ctx) /* Check if developer mode is disabled by FWMP */ disable_dev_boot = 0; - if (vb2_get_fwmp_flags() & FWMP_DEV_DISABLE_BOOT) { + if (vb2_secdata_fwmp_get_flag(ctx, VB2_SECDATA_FWMP_DEV_DISABLE_BOOT)) { if (gbb->flags & VB2_GBB_FLAG_FORCE_DEV_SWITCH_ON) { VB2_DEBUG("FWMP_DEV_DISABLE_BOOT rejected by" "FORCE_DEV_SWITCH_ON\n"); @@ -754,9 +754,10 @@ static vb2_error_t vb2_developer_menu(struct vb2_context *ctx) VB2_DEBUG("dev_disable_boot is set.\n"); } } + altfw_allowed = vb2_nv_get(ctx, VB2_NV_DEV_BOOT_LEGACY) || (gbb->flags & VB2_GBB_FLAG_FORCE_DEV_BOOT_LEGACY) || - (vb2_get_fwmp_flags() & FWMP_DEV_ENABLE_LEGACY); + vb2_secdata_fwmp_get_flag(ctx, VB2_SECDATA_FWMP_DEV_ENABLE_LEGACY); /* Show appropriate initial menu */ if (disable_dev_boot) @@ -849,7 +850,9 @@ static vb2_error_t broken_ui(struct vb2_context *ctx) */ VB2_DEBUG("saving recovery reason (%#x)\n", vbsd->recovery_reason); vb2_nv_set(ctx, VB2_NV_RECOVERY_SUBCODE, vbsd->recovery_reason); - vb2_nv_commit(ctx); + + /* Ignore commit errors in recovery mode. */ + vb2_commit_data(ctx); enter_recovery_base_screen(ctx); |