summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNamyoon Woo <namyoon@google.com>2021-05-12 11:01:03 -0700
committerCommit Bot <commit-bot@chromium.org>2021-06-16 21:51:26 +0000
commit5fdf0294794606773b2403b708e3947a45e7b666 (patch)
treed1929f86a1f20c181e7a1e0b4798886f48e742b1
parent98e4da99997a020f8aba11b2cfc7edaf67376677 (diff)
downloadchrome-ec-5fdf0294794606773b2403b708e3947a45e7b666.tar.gz
cr50: support EC-EFS 2.1
This patch adds the codes that support EC-EFS 2.1. However, it is not enabled. EC-EFS 2.0 is still enabled as default. BUG=b:187953899 TEST=built cr50 image, and ran it on hatch with CONFIG_EC_EFS2_VERSION defined as 0 and 1 respectively. For both cases, CrOS booted good. Also checked CrOS recovery was done good with corrupted TPM secdata, and booted good at the end. > ec_comm corrupt > ecrst pulse Ran the unittest for both version as well. $ make run-ec_comm $ make run-ec_comm21 Signed-off-by: Namyoon Woo <namyoon@google.com> Change-Id: I7623fa56dd44a01002628685826105afe76e034f Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2891925 Tested-by: Namyoon Woo <namyoon@chromium.org> Reviewed-by: Mary Ruthven <mruthven@chromium.org> Commit-Queue: Namyoon Woo <namyoon@chromium.org>
-rw-r--r--board/cr50/board.h1
-rw-r--r--common/ec_efs.c81
-rw-r--r--include/config.h6
-rw-r--r--include/vboot.h9
-rw-r--r--test/build.mk2
-rw-r--r--test/ec_comm.c270
-rw-r--r--test/ec_comm21.tasklist9
-rw-r--r--test/test_config.h9
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)