summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Pronin <apronin@google.com>2023-02-24 11:05:39 -0800
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2023-02-25 01:53:32 +0000
commitfcd3ecbc223a7b0df1a5955f66fa1b9aafbe8a34 (patch)
tree2079c5961f563701880b4deaaf3bf8256cceeb8f
parented9c50d5e63079aa12499e1f9495b4457995bdce (diff)
downloadchrome-ec-fcd3ecbc223a7b0df1a5955f66fa1b9aafbe8a34.tar.gz
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 <apronin@google.com> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/4290246 Tested-by: Andrey Pronin <apronin@chromium.org> Reviewed-by: Vadim Bendebury <vbendeb@chromium.org> Auto-Submit: Andrey Pronin <apronin@chromium.org> Commit-Queue: Vadim Bendebury <vbendeb@chromium.org>
-rw-r--r--board/cr50/board.h1
-rw-r--r--board/cr50/tpm2/platform.c24
-rw-r--r--board/cr50/wp.c47
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)