diff options
-rw-r--r-- | board/cr50/ap_state.c | 4 | ||||
-rw-r--r-- | common/ap_ro_integrity_check.c | 41 | ||||
-rw-r--r-- | common/extension.c | 1 | ||||
-rw-r--r-- | common/tpm_registers.c | 5 | ||||
-rw-r--r-- | include/ap_ro_integrity_check.h | 11 | ||||
-rw-r--r-- | include/tpm_registers.h | 3 | ||||
-rw-r--r-- | include/tpm_vendor_cmds.h | 2 |
7 files changed, 67 insertions, 0 deletions
diff --git a/board/cr50/ap_state.c b/board/cr50/ap_state.c index 1224818f5b..18cad12254 100644 --- a/board/cr50/ap_state.c +++ b/board/cr50/ap_state.c @@ -4,6 +4,7 @@ * * AP state machine */ +#include "ap_ro_integrity_check.h" #include "ec_commands.h" #include "gpio.h" #include "hooks.h" @@ -110,6 +111,9 @@ void tpm_rst_asserted(enum gpio_signal unused) { CPRINTS("%s", __func__); + /* Clear AP RO verification state since this is a new boot. */ + if (!tpm_reset_in_progress()) + ap_ro_device_reset(); /* * It's possible the signal is being pulsed. Wait 1 second to disable * functionality, so it's more likely the AP is fully off and not being diff --git a/common/ap_ro_integrity_check.c b/common/ap_ro_integrity_check.c index f2339ddb86..584c9ca36d 100644 --- a/common/ap_ro_integrity_check.c +++ b/common/ap_ro_integrity_check.c @@ -80,6 +80,19 @@ struct ap_ro_check { static const struct ap_ro_check *p_chk = (const struct ap_ro_check *)AP_RO_DATA_SPACE_ADDR; +/* + * Track if the AP RO hash was validated this boot. Must be cleared every AP + * reset. + */ +static uint8_t validated_ap_ro_boot; + +void ap_ro_device_reset(void) +{ + if (validated_ap_ro_boot) + CPRINTS("%s: clear validated state", __func__); + validated_ap_ro_boot = 0; +} + static int ap_ro_erase_hash(void) { int rv; @@ -289,6 +302,7 @@ int validate_ap_ro(void) } else { ap_ro_add_flash_event(APROF_CHECK_SUCCEEDED); rv = EC_SUCCESS; + validated_ap_ro_boot = 1; CPRINTS("AP RO verification SUCCEEDED!"); } disable_ap_spi_hash_shortcut(); @@ -356,6 +370,7 @@ static int ap_ro_info_cmd(int argc, char **argv) if (rv) return EC_SUCCESS; + ccprintf("boot validated: %s\n", validated_ap_ro_boot ? "yes" : "no"); ccprintf("sha256 hash %ph\n", HEX_BUF(p_chk->payload.digest, sizeof(p_chk->payload.digest))); ccprintf("Covered ranges:\n"); @@ -375,3 +390,29 @@ DECLARE_SAFE_CONSOLE_COMMAND(ap_ro_info, ap_ro_info_cmd, "", "Display AP RO check space" #endif ); + +static enum vendor_cmd_rc vc_get_ap_ro_status(enum vendor_cmd_cc code, + void *buf, size_t input_size, + size_t *response_size) +{ + uint8_t rv = AP_RO_NOT_RUN; + uint8_t *response = buf; + + CPRINTS("Check AP RO status"); + + *response_size = 0; + if (input_size) + return VENDOR_RC_BOGUS_ARGS; + + if (ap_ro_check_unsupported(false)) + rv = AP_RO_UNSUPPORTED; + else if (ec_rst_override()) + rv = AP_RO_FAIL; + else if (validated_ap_ro_boot) + rv = AP_RO_PASS; + + *response_size = 1; + response[0] = rv; + return VENDOR_RC_SUCCESS; +} +DECLARE_VENDOR_COMMAND(VENDOR_CC_GET_AP_RO_STATUS, vc_get_ap_ro_status); diff --git a/common/extension.c b/common/extension.c index 22c707b270..fb08c0bc3f 100644 --- a/common/extension.c +++ b/common/extension.c @@ -39,6 +39,7 @@ uint32_t extension_route_command(struct vendor_cmd_params *p) case EXTENSION_POST_RESET: /* Always need to reset. */ case VENDOR_CC_CCD: case VENDOR_CC_GET_AP_RO_HASH: + case VENDOR_CC_GET_AP_RO_STATUS: case VENDOR_CC_GET_BOARD_ID: case VENDOR_CC_GET_BOOT_MODE: case VENDOR_CC_RMA_CHALLENGE_RESPONSE: diff --git a/common/tpm_registers.c b/common/tpm_registers.c index db974f05b9..6ef281b313 100644 --- a/common/tpm_registers.c +++ b/common/tpm_registers.c @@ -779,6 +779,11 @@ static __preserved int wipe_result; */ static int wipe_requested __attribute__((section(".bss.Tpm2_common"))); +int tpm_reset_in_progress(void) +{ + return reset_in_progress; +} + int tpm_reset_request(int wait_until_done, int wipe_nvmem_first) { uint32_t evt; diff --git a/include/ap_ro_integrity_check.h b/include/ap_ro_integrity_check.h index 30181289e6..b07e4b71c7 100644 --- a/include/ap_ro_integrity_check.h +++ b/include/ap_ro_integrity_check.h @@ -8,6 +8,12 @@ #include "flash_log.h" +enum ap_ro_status { + AP_RO_NOT_RUN = 0, + AP_RO_PASS, + AP_RO_FAIL, + AP_RO_UNSUPPORTED, +}; /* * validate_ap_ro: based on information saved in an H1 RO flash page verify * contents of the AP flash. @@ -33,4 +39,9 @@ void ap_ro_add_flash_event(enum ap_ro_verification_ev event); */ int ap_ro_board_id_blocked(void); +/* + * ap_ro_device_reset: Clear AP RO verification state on a new boot. + */ +void ap_ro_device_reset(void); + #endif /* ! __CR50_INCLUDE_AP_RO_INTEGRITY_CHECK_H */ diff --git a/include/tpm_registers.h b/include/tpm_registers.h index d35824dfce..45c9910ded 100644 --- a/include/tpm_registers.h +++ b/include/tpm_registers.h @@ -46,6 +46,9 @@ void tpm_register_interface(interface_control_func interface_start, */ int tpm_reset_request(int wait_until_done, int wipe_nvmem_first); +/* Returns True if successive TPM_RST_L pulses are being debounced. */ +int tpm_reset_in_progress(void); + /* * Tell the TPM task to re-enable nvmem commits. * diff --git a/include/tpm_vendor_cmds.h b/include/tpm_vendor_cmds.h index 40c1849e86..83a0f700f5 100644 --- a/include/tpm_vendor_cmds.h +++ b/include/tpm_vendor_cmds.h @@ -153,6 +153,8 @@ enum vendor_cmd_cc { VENDOR_CC_GET_AP_RO_HASH = 56, + VENDOR_CC_GET_AP_RO_STATUS = 57, + LAST_VENDOR_COMMAND = 65535, }; |