summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2015-09-17 12:54:51 -0700
committerChromeOS bot <3su6n15k.default@developer.gserviceaccount.com>2015-09-18 00:37:45 +0000
commit5f6e7e4bda30229cbfb8accb770890d57e081e7a (patch)
tree2267184202380993563451b21f1ea9d0e8e26d7d /tests
parent20ea5cf4d35da435283f852059fe7dcd4341988b (diff)
downloadvboot-5f6e7e4bda30229cbfb8accb770890d57e081e7a.tar.gz
vboot2: Support reboot requested by secdata
When a TPM goes from the disabled state to the enabled state, it must reboot after being enabled, before it can be initialized. In vboot1, TLCL was part of vboot and this was handled internally. In vboot2, the caller must set a context flag, so that vboot can decide whether to allow the reboot, or whether to go directly to recovery mode. This check is necessary to handle the following cases: 1) The device is booting normally, but the TPM needs a reboot. This should simply reboot, without going to recovery mode. 2) The device is booting in recovery mode, but the TPM needs a reboot. If this is the first time it asked us, allow the reboot. 3) The TPM asked for a reboot last time, so we did. And it's still asking. Don't reboot, because that runs the risk that whatever is wrong won't be fixed next boot either, and we'll get stuck in a reboot loop that will prevent recovery. Boot into recovery mode. Add a new NvStorage bit to track whether the TPM requested a reboot on the previous boot. That's better than what we did in vboot1, where we used a special recovery request. Vboot1 couldn't track getting stuck in a reboot loop in normal mode, only in recovery mode. The new code can catch both. BUG=chrome-os-partner:45462 BRANCH=ryu TEST=make runtests Change-Id: I2ee54af107275ccf64a6cb41132b7a0fc02bb983 Signed-off-by: Randall Spangler <rspangler@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/300607 Reviewed-by: Furquan Shaikh <furquan@chromium.org> Commit-Queue: Furquan Shaikh <furquan@chromium.org> Trybot-Ready: Furquan Shaikh <furquan@chromium.org> Tested-by: Furquan Shaikh <furquan@chromium.org>
Diffstat (limited to 'tests')
-rw-r--r--tests/vb2_api_tests.c81
-rw-r--r--tests/vb2_nvstorage_tests.c1
-rw-r--r--tests/vboot_nvstorage_test.c1
3 files changed, 82 insertions, 1 deletions
diff --git a/tests/vb2_api_tests.c b/tests/vb2_api_tests.c
index 2978c3fd..adc536b6 100644
--- a/tests/vb2_api_tests.c
+++ b/tests/vb2_api_tests.c
@@ -131,7 +131,6 @@ static void phase1_tests(void)
TEST_NEQ(cc.flags & VB2_CONTEXT_RECOVERY_MODE, 0, " recovery flag");
TEST_NEQ(cc.flags & VB2_CONTEXT_CLEAR_RAM, 0, " clear ram flag");
-
reset_common_data(FOR_MISC);
retval_vb2_check_dev_switch = VB2_ERROR_MOCK;
TEST_EQ(vb2api_fw_phase1(&cc), VB2_ERROR_API_PHASE1_RECOVERY,
@@ -149,6 +148,86 @@ static void phase1_tests(void)
" recovery reason");
TEST_NEQ(cc.flags & VB2_CONTEXT_RECOVERY_MODE, 0, " recovery flag");
TEST_NEQ(cc.flags & VB2_CONTEXT_CLEAR_RAM, 0, " clear ram flag");
+
+ /* Test secdata-requested reboot */
+ reset_common_data(FOR_MISC);
+ cc.flags |= VB2_CONTEXT_SECDATA_WANTS_REBOOT;
+ TEST_EQ(vb2api_fw_phase1(&cc), VB2_ERROR_API_PHASE1_SECDATA_REBOOT,
+ "phase1 secdata reboot normal");
+ TEST_EQ(sd->recovery_reason, 0, " recovery reason");
+ TEST_EQ(vb2_nv_get(&cc, VB2_NV_TPM_REQUESTED_REBOOT),
+ 1, " tpm reboot request");
+ TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST),
+ 0, " recovery request");
+
+ reset_common_data(FOR_MISC);
+ vb2_nv_set(&cc, VB2_NV_TPM_REQUESTED_REBOOT, 1);
+ TEST_SUCC(vb2api_fw_phase1(&cc), "phase1 secdata reboot back normal");
+ TEST_EQ(sd->recovery_reason, 0, " recovery reason");
+ TEST_EQ(vb2_nv_get(&cc, VB2_NV_TPM_REQUESTED_REBOOT),
+ 0, " tpm reboot request");
+ TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST),
+ 0, " recovery request");
+
+ reset_common_data(FOR_MISC);
+ cc.flags |= VB2_CONTEXT_SECDATA_WANTS_REBOOT;
+ memset(cc.secdata, 0, sizeof(cc.secdata));
+ TEST_EQ(vb2api_fw_phase1(&cc), VB2_ERROR_API_PHASE1_SECDATA_REBOOT,
+ "phase1 secdata reboot normal, secdata blank");
+ TEST_EQ(sd->recovery_reason, 0, " recovery reason");
+ TEST_EQ(vb2_nv_get(&cc, VB2_NV_TPM_REQUESTED_REBOOT),
+ 1, " tpm reboot request");
+ TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST),
+ 0, " recovery request");
+
+ reset_common_data(FOR_MISC);
+ cc.flags |= VB2_CONTEXT_SECDATA_WANTS_REBOOT;
+ vb2_nv_set(&cc, VB2_NV_TPM_REQUESTED_REBOOT, 1);
+ TEST_EQ(vb2api_fw_phase1(&cc), VB2_ERROR_API_PHASE1_RECOVERY,
+ "phase1 secdata reboot normal again");
+ TEST_EQ(sd->recovery_reason, VB2_RECOVERY_RO_TPM_REBOOT,
+ " recovery reason");
+ TEST_EQ(vb2_nv_get(&cc, VB2_NV_TPM_REQUESTED_REBOOT),
+ 1, " tpm reboot request");
+ TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST),
+ 0, " recovery request");
+
+ reset_common_data(FOR_MISC);
+ cc.flags |= VB2_CONTEXT_SECDATA_WANTS_REBOOT;
+ vb2_nv_set(&cc, VB2_NV_RECOVERY_REQUEST, VB2_RECOVERY_RO_UNSPECIFIED);
+ TEST_EQ(vb2api_fw_phase1(&cc), VB2_ERROR_API_PHASE1_SECDATA_REBOOT,
+ "phase1 secdata reboot recovery");
+ /* Recovery reason isn't set this boot because we're rebooting first */
+ TEST_EQ(sd->recovery_reason, 0, " recovery reason not set THIS boot");
+ TEST_EQ(vb2_nv_get(&cc, VB2_NV_TPM_REQUESTED_REBOOT),
+ 1, " tpm reboot request");
+ TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST),
+ VB2_RECOVERY_RO_UNSPECIFIED, " recovery request not cleared");
+
+ reset_common_data(FOR_MISC);
+ vb2_nv_set(&cc, VB2_NV_TPM_REQUESTED_REBOOT, 1);
+ vb2_nv_set(&cc, VB2_NV_RECOVERY_REQUEST, VB2_RECOVERY_RO_UNSPECIFIED);
+ TEST_EQ(vb2api_fw_phase1(&cc), VB2_ERROR_API_PHASE1_RECOVERY,
+ "phase1 secdata reboot back recovery");
+ TEST_EQ(sd->recovery_reason, VB2_RECOVERY_RO_UNSPECIFIED,
+ " recovery reason");
+ TEST_EQ(vb2_nv_get(&cc, VB2_NV_TPM_REQUESTED_REBOOT),
+ 0, " tpm reboot request");
+ TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST), 0,
+ " recovery request cleared");
+
+ reset_common_data(FOR_MISC);
+ cc.flags |= VB2_CONTEXT_SECDATA_WANTS_REBOOT;
+ vb2_nv_set(&cc, VB2_NV_TPM_REQUESTED_REBOOT, 1);
+ vb2_nv_set(&cc, VB2_NV_RECOVERY_REQUEST, VB2_RECOVERY_RO_UNSPECIFIED);
+ TEST_EQ(vb2api_fw_phase1(&cc), VB2_ERROR_API_PHASE1_RECOVERY,
+ "phase1 secdata reboot recovery again");
+ TEST_EQ(sd->recovery_reason, VB2_RECOVERY_RO_UNSPECIFIED,
+ " recovery reason");
+ TEST_EQ(vb2_nv_get(&cc, VB2_NV_TPM_REQUESTED_REBOOT),
+ 1, " tpm reboot request");
+ TEST_EQ(vb2_nv_get(&cc, VB2_NV_RECOVERY_REQUEST), 0,
+ " recovery request cleared");
}
static void phase2_tests(void)
diff --git a/tests/vb2_nvstorage_tests.c b/tests/vb2_nvstorage_tests.c
index 02c8acc8..0bf58b61 100644
--- a/tests/vb2_nvstorage_tests.c
+++ b/tests/vb2_nvstorage_tests.c
@@ -47,6 +47,7 @@ static struct nv_field nvfields[] = {
{VB2_NV_DISABLE_DEV_REQUEST, 0, 1, 0, "disable dev request"},
{VB2_NV_CLEAR_TPM_OWNER_REQUEST, 0, 1, 0, "clear tpm owner request"},
{VB2_NV_CLEAR_TPM_OWNER_DONE, 0, 1, 0, "clear tpm owner done"},
+ {VB2_NV_TPM_REQUESTED_REBOOT, 0, 1, 0, "tpm requested reboot"},
{VB2_NV_OPROM_NEEDED, 0, 1, 0, "oprom needed"},
{VB2_NV_BACKUP_NVRAM_REQUEST, 0, 1, 0, "backup nvram request"},
{VB2_NV_FASTBOOT_UNLOCK_IN_FW, 0, 1, 0, "fastboot unlock in fw"},
diff --git a/tests/vboot_nvstorage_test.c b/tests/vboot_nvstorage_test.c
index bbded635..a82a7429 100644
--- a/tests/vboot_nvstorage_test.c
+++ b/tests/vboot_nvstorage_test.c
@@ -37,6 +37,7 @@ static VbNvField nvfields[] = {
{VBNV_DISABLE_DEV_REQUEST, 0, 1, 0, "disable dev request"},
{VBNV_CLEAR_TPM_OWNER_REQUEST, 0, 1, 0, "clear tpm owner request"},
{VBNV_CLEAR_TPM_OWNER_DONE, 0, 1, 0, "clear tpm owner done"},
+ {VBNV_TPM_REQUESTED_REBOOT, 0, 1, 0, "tpm requested reboot"},
{VBNV_OPROM_NEEDED, 0, 1, 0, "oprom needed"},
{VBNV_FW_TRY_COUNT, 0, 8, 15, "try count"},
{VBNV_FW_TRY_NEXT, 0, 1, 0, "try next"},