From 116042d1fe393187bd1918d43b8554b7d4a5a54d Mon Sep 17 00:00:00 2001 From: Mary Ruthven Date: Wed, 9 Jun 2021 15:10:16 -0500 Subject: ap_ro_integrity_check: skip verify based on RLZ Some factories programmed hashes into devices that don't support reading from AP flash while EC_RST_L is asserted. Skip AP RO verification on these devices if the RLZ is blocked. BUG=b:185783841 TEST=manual Set board id to YVRQ:0x10 Verify AP RO verification can be triggered Set board id to VYRC:0x10 Verify AP RO verification is skipped even if the hash is stored. Change-Id: I7ef5ceafd55ae5e90b4a754d1e92317a9a745ef9 Signed-off-by: Mary Ruthven Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2950313 Reviewed-by: Vadim Bendebury (cherry picked from commit b231b059c0947522e4a0c9815eab1a5c2601718f) Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3004080 Reviewed-by: Andrey Pronin (cherry picked from commit 68b4cd20416f6bb019605ce5ba24c48c327aa067) Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3059210 --- board/cr50/board.c | 69 +++++++++++++++++++++++++++++++++++++++++ common/ap_ro_integrity_check.c | 11 +++++-- include/ap_ro_integrity_check.h | 6 ++++ include/tpm_vendor_cmds.h | 1 + 4 files changed, 84 insertions(+), 3 deletions(-) diff --git a/board/cr50/board.c b/board/cr50/board.c index 9025dd9963..3198177acf 100644 --- a/board/cr50/board.c +++ b/board/cr50/board.c @@ -760,6 +760,75 @@ static void check_board_id_mismatch(void) system_reset(0); } +/*****************************************************************************/ +/* + * Certain boards need to skip AP RO verification even when the hash is saved. + * Block AP RO verification based on the board id type. + */ +#define BLOCKED_BID_COUNT 7 +/* + * This contains the ap ro verification board id blocklist. Skip AP RO + * verification if the board id is found in the blocklist. + */ +const uint32_t ap_ro_board_id_blocklist[] = { + /* b/185783841 block verification on unsupported devices. */ + 0x54514155, /* TQAU */ + 0x524c4745, /* RLGE */ + 0x56595243, /* VYRC */ + 0x44554b49, /* DUKI */ + 0x4346554c, /* CFUL */ + 0x5248444e, /* RHDN */ + 0x454b574c /* EKWL */ +}; +BUILD_ASSERT(ARRAY_SIZE(ap_ro_board_id_blocklist) == BLOCKED_BID_COUNT); + + +#define AP_RO_ALLOW_BID 1 +#define AP_RO_BLOCK_BID 2 + +int ap_ro_board_id_blocked(void) +{ + static int checked_ap_ro_bid; + struct board_id id; + int i; + + /* + * Don't allow ap ro verification if the image board id is mismatched. + * This ensures the device can boot to get an update. + */ + if (board_id_is_mismatched()) + return 1; + + if (checked_ap_ro_bid) + return checked_ap_ro_bid == AP_RO_BLOCK_BID; + + /* + * If cr50 can't read the board id for some reason, return 1 just to + * be safe. + */ + if (read_board_id(&id) != EC_SUCCESS) { + CPRINTS("%s: BID read error", __func__); + return 1; + } + + if (board_id_is_blank(&id)) + return 0; + + /* + * Cache the board id block state, so cr50 doesn't need to keep reading + * and checking the RLZ. The board id can't change if it's already set. + */ + checked_ap_ro_bid = AP_RO_ALLOW_BID; + for (i = 0; i < ARRAY_SIZE(ap_ro_board_id_blocklist); i++) { + if (id.type == ap_ro_board_id_blocklist[i]) { + checked_ap_ro_bid = AP_RO_BLOCK_BID; + break; + } + } + return checked_ap_ro_bid == AP_RO_BLOCK_BID; +} +/*****************************************************************************/ + /* * Check if ITE SYNC sequence generation was requested before the reset, if so * - clear the request and call the function to generate the sequence. diff --git a/common/ap_ro_integrity_check.c b/common/ap_ro_integrity_check.c index 86bfbbea23..f2339ddb86 100644 --- a/common/ap_ro_integrity_check.c +++ b/common/ap_ro_integrity_check.c @@ -226,10 +226,16 @@ static int verify_ap_ro_check_space(void) * ARCVE_OK if AP RO verification is supported. * ARCVE_NOT_PROGRAMMED if the hash is not programmed. * ARCVE_FLASH_READ_FAILED if there was an error reading the hash. + * ARCVE_BOARD_ID_BLOCKED if ap ro verification is disabled for the board's rlz */ static enum ap_ro_check_vc_errors ap_ro_check_unsupported(int add_flash_event) { + if (ap_ro_board_id_blocked()) { + CPRINTS("%s: BID blocked", __func__); + return ARCVE_BOARD_ID_BLOCKED; + } + if (p_chk->header.num_ranges == (uint16_t)~0) { CPRINTS("%s: RO verification not programmed", __func__); if (add_flash_event) @@ -344,12 +350,11 @@ static int ap_ro_info_cmd(int argc, char **argv) } #endif rv = ap_ro_check_unsupported(false); - if (rv == ARCVE_NOT_PROGRAMMED) - return EC_SUCCESS; if (rv == ARCVE_FLASH_READ_FAILED) return EC_ERROR_CRC; /* No verification possible. */ + /* All other AP RO verificaiton unsupported reasons are fine */ if (rv) - return EC_ERROR_UNKNOWN; + return EC_SUCCESS; ccprintf("sha256 hash %ph\n", HEX_BUF(p_chk->payload.digest, sizeof(p_chk->payload.digest))); diff --git a/include/ap_ro_integrity_check.h b/include/ap_ro_integrity_check.h index 0edc477c88..30181289e6 100644 --- a/include/ap_ro_integrity_check.h +++ b/include/ap_ro_integrity_check.h @@ -27,4 +27,10 @@ int validate_ap_ro(void); */ void ap_ro_add_flash_event(enum ap_ro_verification_ev event); +/* + * ap_ro_board_id_blocked: Returns True if AP RO verification is disabled for + * the board's RLZ. + */ +int ap_ro_board_id_blocked(void); + #endif /* ! __CR50_INCLUDE_AP_RO_INTEGRITY_CHECK_H */ diff --git a/include/tpm_vendor_cmds.h b/include/tpm_vendor_cmds.h index a697d1cdd9..eada7e6568 100644 --- a/include/tpm_vendor_cmds.h +++ b/include/tpm_vendor_cmds.h @@ -261,6 +261,7 @@ enum ap_ro_check_vc_errors { ARCVE_TOO_MANY_RANGES = 9, ARCVE_NOT_PROGRAMMED = 10, ARCVE_FLASH_READ_FAILED = 11, + ARCVE_BOARD_ID_BLOCKED = 12, }; /* Structure for VENDOR_CC_SPI_HASH request which follows tpm_header */ -- cgit v1.2.1