diff options
-rw-r--r-- | board/cr50/board.h | 1 | ||||
-rw-r--r-- | common/ec_efs.c | 81 | ||||
-rw-r--r-- | include/config.h | 6 | ||||
-rw-r--r-- | include/vboot.h | 9 | ||||
-rw-r--r-- | test/build.mk | 2 | ||||
-rw-r--r-- | test/ec_comm.c | 270 | ||||
-rw-r--r-- | test/ec_comm21.tasklist | 9 | ||||
-rw-r--r-- | test/test_config.h | 9 |
8 files changed, 341 insertions, 46 deletions
diff --git a/board/cr50/board.h b/board/cr50/board.h index 8ebe3086e6..1e83a30340 100644 --- a/board/cr50/board.h +++ b/board/cr50/board.h @@ -525,6 +525,7 @@ enum nvmem_users { #define CONFIG_RNG #define CONFIG_EC_EFS_SUPPORT +#define CONFIG_EC_EFS2_VERSION 0 #define CONFIG_ENABLE_H1_ALERTS diff --git a/common/ec_efs.c b/common/ec_efs.c index e3e2cf2d50..cf28844fee 100644 --- a/common/ec_efs.c +++ b/common/ec_efs.c @@ -29,6 +29,14 @@ #define CPRINTS(format, args...) do { } while (0) #endif +#if CONFIG_EC_EFS2_VERSION == 0 +#define EC_EFS_BOOT_MODE_INITIAL EC_EFS_BOOT_MODE_NORMAL +#elif CONFIG_EC_EFS2_VERSION == 1 +#define EC_EFS_BOOT_MODE_INITIAL EC_EFS_BOOT_MODE_TRUSTED_RO +#else +#error "NOT SUPPORTED EFS2 VERSION" +#endif + /* * Context of EC-EFS */ @@ -40,11 +48,22 @@ static struct ec_efs_context_ { uint32_t secdata_error_code; uint8_t hash[SHA256_DIGEST_SIZE]; /* EC-RW digest */ -} ec_efs_ctx; +} ec_efs_ctx = { + .boot_mode = EC_EFS_BOOT_MODE_INITIAL, + .hash_is_loaded = 0, + .secdata_error_code = 0, + .hash = { 0, }, +}; static const char * const boot_mode_name_[] = { +#if CONFIG_EC_EFS2_VERSION == 0 "NORMAL", "NO_BOOT", +#elif CONFIG_EC_EFS2_VERSION == 1 + "VERIFIED", + "NO_BOOT", + "TRUSTED_RO", +#endif }; /* @@ -166,7 +185,13 @@ DECLARE_VENDOR_COMMAND_P(VENDOR_CC_RESET_EC, vc_reset_ec_); void ec_efs_reset(void) { - set_boot_mode_(EC_EFS_BOOT_MODE_NORMAL); + set_boot_mode_( +#if CONFIG_EC_EFS2_VERSION == 0 + EC_EFS_BOOT_MODE_NORMAL +#elif CONFIG_EC_EFS2_VERSION == 1 + EC_EFS_BOOT_MODE_TRUSTED_RO +#endif + ); } /* @@ -188,6 +213,7 @@ uint16_t ec_efs_set_boot_mode(const char * const data, const uint8_t size) boot_mode = data[0]; switch (boot_mode) { +#if CONFIG_EC_EFS2_VERSION == 0 case EC_EFS_BOOT_MODE_NORMAL: /* * Per EC-EFS2 design, CR50 accepts the repeating commands @@ -203,12 +229,47 @@ uint16_t ec_efs_set_boot_mode(const char * const data, const uint8_t size) */ board_reboot_ec_deferred(0); return 0; - +#elif CONFIG_EC_EFS2_VERSION == 1 + case EC_EFS_BOOT_MODE_TRUSTED_RO: + switch (ec_efs_ctx.boot_mode) { + case EC_EFS_BOOT_MODE_TRUSTED_RO: + /* + * Per EC-EFS2 design, CR50 accepts the repeating + * commands as long as the result is the same. + * It is to be tolerant against CR50 response loss, + * so that EC can resend the same command. + */ + return CR50_COMM_SUCCESS; + case EC_EFS_BOOT_MODE_NO_BOOT: + /* fall through */ + case EC_EFS_BOOT_MODE_VERIFIED: + /* + * Once the boot mode is NO_BOOT, then it must not be + * set to RO mode without resetting EC. + */ + board_reboot_ec_deferred(0); + return 0; + default: + /* + * This case should not happen. + * However, should it happen, reset EC and EFS-context. + */ + cprints(CC_SYSTEM, + "ERROR: EFS boot_mode is corrupted: %x", + ec_efs_ctx.boot_mode); + board_reboot_ec_deferred(0); + return 0; + } + break; +#else +#error "Not-supported EC-EFS2 version" +#endif /* CONFIG_EC_EFS2_VERSION == 1 */ case EC_EFS_BOOT_MODE_NO_BOOT: break; default: - return CR50_COMM_ERROR_BAD_PAYLOAD; + /* Reject changing to all other BOOT_MODEs. */ + return CR50_COMM_ERROR_BAD_PARAM; } set_boot_mode_(boot_mode); @@ -246,14 +307,20 @@ uint16_t ec_efs_verify_hash(const char *hash_data, const uint8_t size) } /* - * Once the boot mode is not NORMAL, (i.e. it is NO_BOOT), then CR50 + * Once the boot mode is NO_BOOT, then CR50 * should not approve the hash verification, but reset EC. */ - if (ec_efs_ctx.boot_mode != EC_EFS_BOOT_MODE_NORMAL) { + if (ec_efs_ctx.boot_mode == EC_EFS_BOOT_MODE_NO_BOOT) { board_reboot_ec_deferred(0); return 0; } - +#if CONFIG_EC_EFS2_VERSION == 1 + /* + * Changing BOOT_MODE_VERIFIED does not break a backward compatibility + * to EFS2.0 in AP-FW, because AP-FW accepts all boot_modes but NO_BOOT. + */ + set_boot_mode_(EC_EFS_BOOT_MODE_VERIFIED); +#endif return CR50_COMM_SUCCESS; } diff --git a/include/config.h b/include/config.h index 7008774812..8f7abdec59 100644 --- a/include/config.h +++ b/include/config.h @@ -1322,6 +1322,12 @@ #undef CONFIG_EC_EFS_SUPPORT /* + * Version of EC-EFS: 0 (for 2.0) or 1 (for 2.1). + * This is for CR50 config only + */ +#undef CONFIG_EC_EFS2_VERSION + +/* * Enable the experimental console. * * NOTE: If you enable this experimental console, you will need to run the diff --git a/include/vboot.h b/include/vboot.h index ba924508c7..a9eb8692ae 100644 --- a/include/vboot.h +++ b/include/vboot.h @@ -59,14 +59,13 @@ struct cr50_comm_packet { #define CR50_COMM_ERROR_BAD_PAYLOAD CR50_COMM_RESPONSE(0x07) #define CR50_COMM_ERROR_STRUCT_VERSION CR50_COMM_RESPONSE(0x08) #define CR50_COMM_ERROR_NVMEM CR50_COMM_RESPONSE(0x09) +#define CR50_COMM_ERROR_BAD_PARAM CR50_COMM_RESPONSE(0x0a) -/* - * BIT(0) : NO_BOOT flag - * BIT(1) : RECOVERY flag - */ enum ec_efs_boot_mode { - EC_EFS_BOOT_MODE_NORMAL = 0x00, + EC_EFS_BOOT_MODE_NORMAL = 0x00, /* in 2.0 */ + EC_EFS_BOOT_MODE_VERIFIED = 0x00, /* in 2.1 */ EC_EFS_BOOT_MODE_NO_BOOT = 0x01, + EC_EFS_BOOT_MODE_TRUSTED_RO = 0x02, /* in 2.1 */ /* boot_mode is uint8_t */ EC_EFS_BOOT_MODE_LIMIT = 255, diff --git a/test/build.mk b/test/build.mk index ec51ab4bf9..7555778e70 100644 --- a/test/build.mk +++ b/test/build.mk @@ -18,6 +18,7 @@ test-list-host += cec test-list-host += console_edit test-list-host += crc32 test-list-host += ec_comm +test-list-host += ec_comm21 test-list-host += entropy test-list-host += flash test-list-host += flash_log @@ -63,6 +64,7 @@ cec-y=cec.o console_edit-y=console_edit.o crc32-y=crc32.o ec_comm-y=ec_comm.o +ec_comm21-y=ec_comm.o entropy-y=entropy.o flash-y=flash.o flash_log-y=flash_log.o diff --git a/test/ec_comm.c b/test/ec_comm.c index ba92e3132d..c24f968442 100644 --- a/test/ec_comm.c +++ b/test/ec_comm.c @@ -51,6 +51,14 @@ union cr50_test_packet sample_packet_cmd_verify_hash = { .ph.size = SHA256_DIGEST_SIZE, }; +#if CONFIG_EC_EFS2_VERSION == 0 +#define EXPECTED_BOOT_MODE_AFTER_EC_RST EC_EFS_BOOT_MODE_NORMAL +#define EXPECTED_BOOT_MODE_AFTER_VERIFY EC_EFS_BOOT_MODE_NORMAL +#elif CONFIG_EC_EFS2_VERSION == 1 +#define EXPECTED_BOOT_MODE_AFTER_EC_RST EC_EFS_BOOT_MODE_TRUSTED_RO +#define EXPECTED_BOOT_MODE_AFTER_VERIFY EC_EFS_BOOT_MODE_VERIFIED +#endif + /* EC Reset Count. It is used to see if ec has been reset. */ static int ec_reset_count_; @@ -185,7 +193,7 @@ static int test_ec_comm_packet_failure(void) ec_has_reset(); - TEST_ASSERT(ec_efs_get_boot_mode() == EC_EFS_BOOT_MODE_NORMAL); + TEST_ASSERT(ec_efs_get_boot_mode() == EXPECTED_BOOT_MODE_AFTER_EC_RST); /* Test 1: Test with less preambles than required. */ calculate_crc8(&pk); @@ -227,7 +235,7 @@ static int test_ec_comm_packet_failure(void) /* Check if ec has ever been reset during these tests */ TEST_ASSERT(!ec_has_reset()); - TEST_ASSERT(ec_efs_get_boot_mode() == EC_EFS_BOOT_MODE_NORMAL); + TEST_ASSERT(ec_efs_get_boot_mode() == EXPECTED_BOOT_MODE_AFTER_EC_RST); return EC_SUCCESS; } @@ -240,52 +248,97 @@ static int test_ec_comm_set_boot_mode(void) /* Copy the sample packet to buffer. */ union cr50_test_packet pk = sample_packet_cmd_set_mode; int preambles; + uint8_t boot_mode_expected; ec_has_reset(); - /* Test 1: Attempt to set boot mode to NORMAL. */ - pk.ph.data[0] = EC_EFS_BOOT_MODE_NORMAL; + boot_mode_expected = EXPECTED_BOOT_MODE_AFTER_EC_RST; + TEST_ASSERT(ec_efs_get_boot_mode() == boot_mode_expected); + + /* + * Test 1-1: Attempt to set boot mode to EXPECTED_BOOT_MODE_AFTER_EC_RST + * NORMAL -> NORMAL (in 2.0) or RO -> RO (in 2.1) + */ + boot_mode_expected = EXPECTED_BOOT_MODE_AFTER_EC_RST; + pk.ph.data[0] = boot_mode_expected; calculate_crc8(&pk); preambles = MIN_LENGTH_PREAMBLE * 2; TEST_ASSERT(!test_ec_comm(&pk, preambles, CR50_COMM_SUCCESS)); TEST_ASSERT(!ec_has_reset()); /* EC must not be reset. */ - TEST_ASSERT(ec_efs_get_boot_mode() == EC_EFS_BOOT_MODE_NORMAL); + TEST_ASSERT(ec_efs_get_boot_mode() == boot_mode_expected); - /* Test 2: Attempt to set boot mode to NORMAL again. */ + /* + * Test 1-1: Attempt to set boot mode to EXPECTED_BOOT_MODE_AFTER_EC_RST + * NORMAL -> NORMAL (in 2.0) or RO -> RO (in 2.1) + */ + boot_mode_expected = EXPECTED_BOOT_MODE_AFTER_EC_RST; preambles = MIN_LENGTH_PREAMBLE; TEST_ASSERT(!test_ec_comm(&pk, preambles, CR50_COMM_SUCCESS)); TEST_ASSERT(!ec_has_reset()); /* EC must not be reset. */ - TEST_ASSERT(ec_efs_get_boot_mode() == EC_EFS_BOOT_MODE_NORMAL); + TEST_ASSERT(ec_efs_get_boot_mode() == boot_mode_expected); +#if CONFIG_EC_EFS2_VERSION == 1 /* - * Test 3: Attempt to set boot mode to NO BOOT. - * EC should not be reset with this boot mode change from NORMAL - * to NO_BOOT. + * Test 1-3: Attempt to set boot mode to BOOT_MODE_VERIFIED. + * It should fail. + * RO -> VERIFIED (x) RO (o) */ - pk.ph.data[0] = EC_EFS_BOOT_MODE_NO_BOOT; + boot_mode_expected = EC_EFS_BOOT_MODE_TRUSTED_RO; + pk.ph.data[0] = EC_EFS_BOOT_MODE_VERIFIED; + calculate_crc8(&pk); + TEST_ASSERT(!test_ec_comm(&pk, preambles, CR50_COMM_ERROR_BAD_PARAM)); + TEST_ASSERT(!ec_has_reset()); /* EC must not be reset. */ + TEST_ASSERT(ec_efs_get_boot_mode() == boot_mode_expected); +#endif + + /* + * Test 2-1: Attempt to set boot mode to NO BOOT. + * EC should not be reset with this boot mode change from + * BOOT_MODE_TRUSTED_RO to BOOT_MODE_NO_BOOT. + * INITIAL(RO or NORMAL) -> NO_BOOT + */ + boot_mode_expected = EC_EFS_BOOT_MODE_NO_BOOT; + pk.ph.data[0] = boot_mode_expected; calculate_crc8(&pk); TEST_ASSERT(!test_ec_comm(&pk, preambles, CR50_COMM_SUCCESS)); TEST_ASSERT(!ec_has_reset()); /* EC must not be reset. */ - TEST_ASSERT(ec_efs_get_boot_mode() == EC_EFS_BOOT_MODE_NO_BOOT); + TEST_ASSERT(ec_efs_get_boot_mode() == boot_mode_expected); /* - * Test 4: Attempt to set boot mode to NO BOOT again. - * EC should not be reset since it is a repeating command. + * Test 2-2: Attempt to set boot mode to NO BOOT again. + * EC should not be reset since it is a repeating command. + * NO_BOOT -> NO_BOOT */ + boot_mode_expected = EC_EFS_BOOT_MODE_NO_BOOT; TEST_ASSERT(!test_ec_comm(&pk, preambles, CR50_COMM_SUCCESS)); TEST_ASSERT(!ec_has_reset()); /* EC must not be reset. */ - TEST_ASSERT(ec_efs_get_boot_mode() == EC_EFS_BOOT_MODE_NO_BOOT); + TEST_ASSERT(ec_efs_get_boot_mode() == boot_mode_expected); + +#if CONFIG_EC_EFS2_VERSION == 1 + /* + * Test 2-3: Attempt to set boot mode to VERIFIED. It should fail. + * NO_BOOT -> VERIFIED (x) NO_BOOT(o) + */ + boot_mode_expected = EC_EFS_BOOT_MODE_NO_BOOT; + pk.ph.data[0] = EC_EFS_BOOT_MODE_VERIFIED; + calculate_crc8(&pk); + TEST_ASSERT(!test_ec_comm(&pk, preambles, CR50_COMM_ERROR_BAD_PARAM)); + TEST_ASSERT(!ec_has_reset()); /* EC must not be reset. */ + TEST_ASSERT(ec_efs_get_boot_mode() == boot_mode_expected); +#endif /* - * Test 5: Attempt to set boot mode to NORMAL. - * EC should be reset with this boot mode change from NO_BOOT - * to NORMAL. + * Test 2-4: Attempt to set boot mode to BOOT_MODE_TRUSTED_RO. + * EC should be reset with this boot mode change from + * BOOT_MODE_NO_BOOT to BOOT_MODE_TRUSTED_RO. + * NO_BOOT -> NORMAL (in 2.0) or RO (in 2.1) */ - pk.ph.data[0] = EC_EFS_BOOT_MODE_NORMAL; + boot_mode_expected = EXPECTED_BOOT_MODE_AFTER_EC_RST; + pk.ph.data[0] = EXPECTED_BOOT_MODE_AFTER_EC_RST; calculate_crc8(&pk); TEST_ASSERT(!test_ec_comm(&pk, preambles, 0)); TEST_ASSERT(ec_has_reset()); /* EC must be reset. */ - TEST_ASSERT(ec_efs_get_boot_mode() == EC_EFS_BOOT_MODE_NORMAL); + TEST_ASSERT(ec_efs_get_boot_mode() == boot_mode_expected); return EC_SUCCESS; } @@ -298,51 +351,185 @@ static int test_ec_comm_verify_hash(void) /* Copy the sample packet to buffer. */ union cr50_test_packet pk = sample_packet_cmd_verify_hash; int preambles = MIN_LENGTH_PREAMBLE; + uint8_t boot_mode_expected; ec_has_reset(); - TEST_ASSERT(ec_efs_get_boot_mode() == EC_EFS_BOOT_MODE_NORMAL); + boot_mode_expected = EXPECTED_BOOT_MODE_AFTER_EC_RST; + TEST_ASSERT(ec_efs_get_boot_mode() == boot_mode_expected); - /* Test 1: Attempt to verify EC Hash. */ + /* + * Test 1: Attempt to verify EC Hash. + * NORMAL -> NORMAL (in 2.0) + * RO -> VERIFIED (in 2.1) + */ + boot_mode_expected = EXPECTED_BOOT_MODE_AFTER_VERIFY; calculate_crc8(&pk); preambles = MIN_LENGTH_PREAMBLE * 2; TEST_ASSERT(!test_ec_comm(&pk, preambles, CR50_COMM_SUCCESS)); TEST_ASSERT(!ec_has_reset()); - TEST_ASSERT(ec_efs_get_boot_mode() == EC_EFS_BOOT_MODE_NORMAL); + TEST_ASSERT(ec_efs_get_boot_mode() == boot_mode_expected); - /* Test 2: Attempt to verify EC Hash again. */ + /* + * Test 2: Attempt to verify EC Hash again. + * NORMAL -> NORMAL (in 2.0) + * VERIFIED -> VERIFIED (in 2.1) + */ + boot_mode_expected = EXPECTED_BOOT_MODE_AFTER_VERIFY; preambles = MIN_LENGTH_PREAMBLE; TEST_ASSERT(!test_ec_comm(&pk, preambles, CR50_COMM_SUCCESS)); TEST_ASSERT(!ec_has_reset()); - TEST_ASSERT(ec_efs_get_boot_mode() == EC_EFS_BOOT_MODE_NORMAL); + TEST_ASSERT(ec_efs_get_boot_mode() == boot_mode_expected); - /* Test 3: Attempt to verify a wrong EC Hash. */ + /* + * Test 3: Attempt to verify a wrong EC Hash. + * NORMAL -> NO_BOOT (in 2.0) + * VERIFIED -> NO_BOOT (in 2.1) + */ + boot_mode_expected = EC_EFS_BOOT_MODE_NO_BOOT; pk.ph.data[0] ^= 0xff; /* corrupt the payload */ calculate_crc8(&pk); TEST_ASSERT(!test_ec_comm(&pk, preambles, CR50_COMM_ERROR_BAD_PAYLOAD)); TEST_ASSERT(!ec_has_reset()); /* EC should not be reset though. */ - TEST_ASSERT(ec_efs_get_boot_mode() == EC_EFS_BOOT_MODE_NO_BOOT); + TEST_ASSERT(ec_efs_get_boot_mode() == boot_mode_expected); - /* Test 4: Attempt to verify a wrong EC Hash again. */ - TEST_ASSERT(!test_ec_comm(&pk, preambles, CR50_COMM_ERROR_BAD_PAYLOAD)); + /* + * Test 4: Attempt to verify a wrong EC Hash again. + * NO_BOOT -> NO_BOOT + */ + boot_mode_expected = EC_EFS_BOOT_MODE_NO_BOOT; + TEST_ASSERT(!test_ec_comm(&pk, preambles, + CR50_COMM_ERROR_BAD_PAYLOAD)); TEST_ASSERT(!ec_has_reset()); /* EC should not be reset though. */ - TEST_ASSERT(ec_efs_get_boot_mode() == EC_EFS_BOOT_MODE_NO_BOOT); + TEST_ASSERT(ec_efs_get_boot_mode() == boot_mode_expected); /* * Test 5: Attempt to verify the correct EC Hash. * EC should be reset because EC Boot mode is NO BOOT. + * NO_BOOT -> INITIAL */ + boot_mode_expected = EXPECTED_BOOT_MODE_AFTER_EC_RST; pk = sample_packet_cmd_verify_hash; calculate_crc8(&pk); preambles = MIN_LENGTH_PREAMBLE * 2; TEST_ASSERT(!test_ec_comm(&pk, preambles, 0)); TEST_ASSERT(ec_has_reset()); /* EC must be reset. */ - TEST_ASSERT(ec_efs_get_boot_mode() == EC_EFS_BOOT_MODE_NORMAL); + TEST_ASSERT(ec_efs_get_boot_mode() == boot_mode_expected); + + /* Check if ec has ever been reset during these tests */ + return EC_SUCCESS; +} + +/* + * Test cases for verify_hash command failure case. + */ +static int test_ec_comm_verify_hash_fail(void) +{ + /* Copy the sample packet to buffer. */ + union cr50_test_packet pk = sample_packet_cmd_verify_hash; + int preambles = MIN_LENGTH_PREAMBLE; + uint8_t boot_mode_expected; + + ec_has_reset(); + + boot_mode_expected = EXPECTED_BOOT_MODE_AFTER_EC_RST; + TEST_ASSERT(ec_efs_get_boot_mode() == boot_mode_expected); + + /* + * Test 1: Attempt to verify a wrong EC Hash. + * RO -> NO_BOOT + */ + boot_mode_expected = EC_EFS_BOOT_MODE_NO_BOOT; + pk.ph.data[0] ^= 0xff; /* corrupt the payload */ + calculate_crc8(&pk); + TEST_ASSERT(!test_ec_comm(&pk, preambles, CR50_COMM_ERROR_BAD_PAYLOAD)); + TEST_ASSERT(!ec_has_reset()); /* EC should not be reset though. */ + TEST_ASSERT(ec_efs_get_boot_mode() == boot_mode_expected); + /* Check if ec has ever been reset during these tests */ return EC_SUCCESS; } +#if CONFIG_EC_EFS2_VERSION == 1 +/* + * Test cases for EC-EFS 2.1 protocols + */ +static int test_ec_comm_verify_efs2_1(void) +{ + /* Copy the sample packet to buffer. */ + union cr50_test_packet pk_verify = sample_packet_cmd_verify_hash; + union cr50_test_packet pk_set_bootmode = sample_packet_cmd_set_mode; + int preambles = MIN_LENGTH_PREAMBLE; + uint8_t boot_mode_expected; + + ec_has_reset(); + + boot_mode_expected = EC_EFS_BOOT_MODE_TRUSTED_RO; + TEST_ASSERT(ec_efs_get_boot_mode() == boot_mode_expected); + + /* + * Test 1-1: Attempt to verify EC Hash while RO. + * RO -> VERIFIED + */ + boot_mode_expected = EC_EFS_BOOT_MODE_VERIFIED; + calculate_crc8(&pk_verify); + TEST_ASSERT(!test_ec_comm(&pk_verify, preambles, CR50_COMM_SUCCESS)); + TEST_ASSERT(!ec_has_reset()); + TEST_ASSERT(ec_efs_get_boot_mode() == EC_EFS_BOOT_MODE_VERIFIED); + + /* + * Test 1-2: Attempt to change BOOT_MODE to RO. Should fail. + * VERIFIED -> RO, EC Reset + */ + boot_mode_expected = EC_EFS_BOOT_MODE_TRUSTED_RO; + pk_set_bootmode.ph.data[0] = boot_mode_expected; + calculate_crc8(&pk_set_bootmode); + TEST_ASSERT(!test_ec_comm(&pk_set_bootmode, preambles, 0)); + TEST_ASSERT(ec_has_reset()); /* EC must not be reset. */ + TEST_ASSERT(ec_efs_get_boot_mode() == boot_mode_expected); + + /* + * Test 1-3: Attempt to change BOOT_MODE to VERIFIED. + * Should fail, since VERIFIED is not allowed + * as a parameter of SET_BOOT_MODE command. + * RO -> VERIFIED (x) RO(o) + */ + boot_mode_expected = EC_EFS_BOOT_MODE_TRUSTED_RO; + pk_set_bootmode.ph.data[0] = EC_EFS_BOOT_MODE_VERIFIED; + calculate_crc8(&pk_set_bootmode); + TEST_ASSERT(!test_ec_comm(&pk_set_bootmode, preambles, + CR50_COMM_ERROR_BAD_PARAM)); + TEST_ASSERT(!ec_has_reset()); /* EC must not be reset. */ + TEST_ASSERT(ec_efs_get_boot_mode() == boot_mode_expected); + + /* + * Test 1-4: Attempt to change BOOT_MODE to NO_BOOT. + * Should succeed + * VERIFIED -> NO_BOOT + */ + boot_mode_expected = EC_EFS_BOOT_MODE_NO_BOOT; + pk_set_bootmode.ph.data[0] = boot_mode_expected; + calculate_crc8(&pk_set_bootmode); + TEST_ASSERT(!test_ec_comm(&pk_set_bootmode, preambles, + CR50_COMM_SUCCESS)); + TEST_ASSERT(!ec_has_reset()); /* EC must not be reset. */ + TEST_ASSERT(ec_efs_get_boot_mode() == boot_mode_expected); + + /* + * Test 1-5: Attempt to verify EC Hash while NO_BOOT + * NO_BOOT -> RO + */ + boot_mode_expected = EC_EFS_BOOT_MODE_TRUSTED_RO; + TEST_ASSERT(!test_ec_comm(&pk_verify, preambles, 0)); + TEST_ASSERT(ec_has_reset()); + TEST_ASSERT(ec_efs_get_boot_mode() == boot_mode_expected); + + /* Check if ec has ever been reset during these tests */ + return EC_SUCCESS; +} +#endif /* CONFIG_EC_EFS2_VERSION == 1 */ + void run_test(void) { uint8_t size_to_crc; @@ -359,16 +546,31 @@ void run_test(void) test_secdata.crc8 = crc8((uint8_t *)&test_secdata.reserved0, size_to_crc); - /* Module init */ - board_reboot_ec_deferred(0); - ec_efs_refresh(); /* Start test */ test_reset(); + board_reboot_ec_deferred(0); + ec_efs_refresh(); RUN_TEST(test_ec_comm_packet_failure); + + board_reboot_ec_deferred(0); + ec_efs_refresh(); RUN_TEST(test_ec_comm_set_boot_mode); + + board_reboot_ec_deferred(0); + ec_efs_refresh(); RUN_TEST(test_ec_comm_verify_hash); + board_reboot_ec_deferred(0); + ec_efs_refresh(); + RUN_TEST(test_ec_comm_verify_hash_fail); + +#if CONFIG_EC_EFS2_VERSION == 1 + board_reboot_ec_deferred(0); + ec_efs_refresh(); + RUN_TEST(test_ec_comm_verify_efs2_1); +#endif + test_print_result(); } diff --git a/test/ec_comm21.tasklist b/test/ec_comm21.tasklist new file mode 100644 index 0000000000..52c0d390ef --- /dev/null +++ b/test/ec_comm21.tasklist @@ -0,0 +1,9 @@ +/* Copyright 2020 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/** + * See CONFIG_TASK_LIST in config.h for details. + */ +#define CONFIG_TEST_TASK_LIST /* No test task */ diff --git a/test/test_config.h b/test/test_config.h index 0a66429ef1..33c65322c6 100644 --- a/test/test_config.h +++ b/test/test_config.h @@ -135,8 +135,17 @@ int ncp15wb_calculate_temp(uint16_t adc); #endif #ifdef TEST_EC_COMM +/* Test EC-EFS2.0 */ #define CONFIG_CRC8 #define CONFIG_EC_EFS_SUPPORT +#define CONFIG_EC_EFS2_VERSION 0 +#endif + +#ifdef TEST_EC_COMM21 +/* Test EC-EFS2.1 */ +#define CONFIG_CRC8 +#define CONFIG_EC_EFS_SUPPORT +#define CONFIG_EC_EFS2_VERSION 1 #endif #if defined(TEST_NVMEM) || defined(TEST_NVMEM_VARS) |