From fcd3ecbc223a7b0df1a5955f66fa1b9aafbe8a34 Mon Sep 17 00:00:00 2001 From: Andrey Pronin Date: Fri, 24 Feb 2023 11:05:39 -0800 Subject: cr50: support antirollback spaces in _plat__NvUpdateAllowed This CL allows kernel & firmware antirollback spaces update only in certain board states by adding the appropriate checks to _plat__NvUpdateAllowed(). BUG=b:270243270 TEST=set specific PCR0 values using https://crrev.com/c/2494503, verify that can update antirollback for normal/dev/recovery values, cannot update for recovery+dev value only when block_devmode is set. Change-Id: I979e3e07a877bf5604e99184c9b60eaaa1abf6b4 Signed-off-by: Andrey Pronin Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/4290246 Tested-by: Andrey Pronin Reviewed-by: Vadim Bendebury Auto-Submit: Andrey Pronin Commit-Queue: Vadim Bendebury --- board/cr50/board.h | 1 + board/cr50/tpm2/platform.c | 24 +++++++++++++++-------- board/cr50/wp.c | 47 +++++++++++++++++++++++++++++++++++----------- 3 files changed, 53 insertions(+), 19 deletions(-) diff --git a/board/cr50/board.h b/board/cr50/board.h index a98295d7ff..062ba4c48a 100644 --- a/board/cr50/board.h +++ b/board/cr50/board.h @@ -387,6 +387,7 @@ void power_button_release_enable_interrupt(int enable); /* Functions needed by CCD config */ int board_battery_is_present(void); +int board_fwmp_allows_boot_policy_update(void); int board_fwmp_allows_unlock(void); int board_vboot_dev_mode_enabled(void); void board_reboot_ap(void); diff --git a/board/cr50/tpm2/platform.c b/board/cr50/tpm2/platform.c index e02b95e445..6ee80edbb2 100644 --- a/board/cr50/tpm2/platform.c +++ b/board/cr50/tpm2/platform.c @@ -19,10 +19,10 @@ #define CPRINTF(format, args...) cprintf(CC_EXTENSION, format, ## args) /* - * PCR0 values for the states when FWMP updates are allowed. + * PCR0 values for the states when FWMP/antirollback updates are allowed. * For the source of the specific values see b/140958855#comment25. */ -static const uint8_t allowed_states_for_fwmp[][SHA256_DIGEST_SIZE] = { +static const uint8_t pcr_boot_policy_update_allowed[][SHA256_DIGEST_SIZE] = { /* normal mode (rec=0, dev=0) */ { 0x89, 0xEA, 0xF3, 0x51, 0x34, 0xB4, 0xB3, 0xC6, @@ -141,8 +141,10 @@ void _plat__OwnerClearCallback(void) CPRINTF("%s: failed (%d)\n", __func__, rv); } -/* Returns TRUE if FWMP is allowed to be updated in the current state */ -static BOOL fwmp_update_allowed(void) +/* Returns TRUE if FWMP/antirollback is allowed to be updated + * with the current PCR state. + */ +static BOOL pcr_allows_boot_policy_update(void) { uint8_t pcr0_value[SHA256_DIGEST_SIZE]; int i; @@ -150,9 +152,9 @@ static BOOL fwmp_update_allowed(void) if (!get_tpm_pcr_value(0, pcr0_value)) return FALSE; /* something went wrong, let's be strict */ - for (i = 0; i < ARRAY_SIZE(allowed_states_for_fwmp); ++i) { + for (i = 0; i < ARRAY_SIZE(pcr_boot_policy_update_allowed); ++i) { if (memcmp(pcr0_value, - allowed_states_for_fwmp[i], + pcr_boot_policy_update_allowed[i], SHA256_DIGEST_SIZE) == 0) return TRUE; } @@ -162,8 +164,14 @@ static BOOL fwmp_update_allowed(void) BOOL _plat__NvUpdateAllowed(uint32_t handle) { - if (handle == HR_NV_INDEX + FWMP_NV_INDEX) - return fwmp_update_allowed(); + switch (handle) { + case HR_NV_INDEX + FWMP_NV_INDEX: + return pcr_allows_boot_policy_update(); + case HR_NV_INDEX + FIRMWARE_NV_INDEX: + case HR_NV_INDEX + KERNEL_NV_INDEX: + return pcr_allows_boot_policy_update() + || board_fwmp_allows_boot_policy_update(); + } return TRUE; } diff --git a/board/cr50/wp.c b/board/cr50/wp.c index 0f9a650524..fe0dc2da29 100644 --- a/board/cr50/wp.c +++ b/board/cr50/wp.c @@ -23,6 +23,11 @@ #define CPRINTS(format, args...) cprints(CC_RBOX, format, ## args) #define CPRINTF(format, args...) cprintf(CC_RBOX, format, ## args) +enum fwmp_controlled_action_t { + CCD_UNLOCK, + BOOT_POLICY_UPDATE, +}; + uint8_t bp_connect; uint8_t bp_forced; /** @@ -386,6 +391,7 @@ int board_wipe_tpm(int reset_required) */ #define FWMP_HASH_SIZE 32 #define FWMP_DEV_DISABLE_CCD_UNLOCK BIT(6) +#define FWMP_DEV_DISABLE_BOOT BIT(0) #define FIRMWARE_FLAG_DEV_MODE 0x02 struct RollbackSpaceFirmware { @@ -418,7 +424,8 @@ struct RollbackSpaceFwmp { } __packed; #ifndef CR50_DEV -static int lock_enforced(const struct RollbackSpaceFwmp *fwmp) +static int lock_enforced(const struct RollbackSpaceFwmp *fwmp, + enum fwmp_controlled_action_t action) { uint8_t crc; @@ -436,39 +443,57 @@ static int lock_enforced(const struct RollbackSpaceFwmp *fwmp) return 1; } - return !!(fwmp->flags & FWMP_DEV_DISABLE_CCD_UNLOCK); + switch (action) { + case CCD_UNLOCK: + return !!(fwmp->flags & FWMP_DEV_DISABLE_CCD_UNLOCK); + case BOOT_POLICY_UPDATE: + return !!(fwmp->flags & FWMP_DEV_DISABLE_BOOT); + } + return 0; } #endif -int board_fwmp_allows_unlock(void) +static int fwmp_allows(enum fwmp_controlled_action_t action) { #ifdef CR50_DEV return 1; #else - /* Let's see if FWMP disables console activation. */ + /* Let's see if FWMP allows the requested action. */ struct RollbackSpaceFwmp fwmp; - int allows_unlock; + int allows; switch (read_tpm_nvmem(FWMP_NV_INDEX, sizeof(struct RollbackSpaceFwmp), &fwmp)) { default: - /* Something is messed up, let's not allow console unlock. */ - allows_unlock = 0; + /* Something is messed up, let's not allow. */ + allows = 0; break; case TPM_READ_NOT_FOUND: - allows_unlock = 1; + allows = 1; break; case TPM_READ_SUCCESS: - allows_unlock = !lock_enforced(&fwmp); + allows = !lock_enforced(&fwmp, action); break; } - CPRINTS("Console unlock %sallowed", allows_unlock ? "" : "not "); + return allows; +#endif +} - return allows_unlock; +int board_fwmp_allows_unlock(void) +{ + int allows_unlock = fwmp_allows(CCD_UNLOCK); +#ifndef CR50_DEV + CPRINTS("Console unlock %sallowed", allows_unlock ? "" : "not "); #endif + return allows_unlock; +} + +int board_fwmp_allows_boot_policy_update(void) +{ + return fwmp_allows(BOOT_POLICY_UPDATE); } int board_vboot_dev_mode_enabled(void) -- cgit v1.2.1