summaryrefslogtreecommitdiff
path: root/common/cmd_tpm_test.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/cmd_tpm_test.c')
-rw-r--r--common/cmd_tpm_test.c564
1 files changed, 0 insertions, 564 deletions
diff --git a/common/cmd_tpm_test.c b/common/cmd_tpm_test.c
deleted file mode 100644
index 65332d1..0000000
--- a/common/cmd_tpm_test.c
+++ /dev/null
@@ -1,564 +0,0 @@
-/*
- * Copyright (c) 2015 Google, Inc
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-#include <common.h>
-#include <command.h>
-#include <environment.h>
-#include <tpm.h>
-
-/* Prints error and returns on failure */
-#define TPM_CHECK(tpm_command) do { \
- uint32_t result; \
- \
- result = (tpm_command); \
- if (result != TPM_SUCCESS) { \
- printf("TEST FAILED: line %d: " #tpm_command ": 0x%x\n", \
- __LINE__, result); \
- return result; \
- } \
-} while (0)
-
-#define INDEX0 0xda70
-#define INDEX1 0xda71
-#define INDEX2 0xda72
-#define INDEX3 0xda73
-#define INDEX_INITIALISED 0xda80
-#define PHYS_PRESENCE 4
-#define PRESENCE 8
-
-static uint32_t TlclStartupIfNeeded(void)
-{
- uint32_t result = tpm_startup(TPM_ST_CLEAR);
-
- return result == TPM_INVALID_POSTINIT ? TPM_SUCCESS : result;
-}
-
-static int test_timer(void)
-{
- printf("get_timer(0) = %lu\n", get_timer(0));
- return 0;
-}
-
-static uint32_t tpm_get_flags(uint8_t *disable, uint8_t *deactivated,
- uint8_t *nvlocked)
-{
- struct tpm_permanent_flags pflags;
- uint32_t result;
-
- result = tpm_get_permanent_flags(&pflags);
- if (result)
- return result;
- if (disable)
- *disable = pflags.disable;
- if (deactivated)
- *deactivated = pflags.deactivated;
- if (nvlocked)
- *nvlocked = pflags.nv_locked;
- debug("TPM: Got flags disable=%d, deactivated=%d, nvlocked=%d\n",
- pflags.disable, pflags.deactivated, pflags.nv_locked);
-
- return 0;
-}
-
-static uint32_t tpm_set_global_lock(void)
-{
- uint32_t x;
-
- debug("TPM: Set global lock\n");
- return tpm_nv_write_value(INDEX0, (uint8_t *)&x, 0);
-}
-
-static uint32_t tpm_nv_write_value_lock(uint32_t index)
-{
- debug("TPM: Write lock 0x%x\n", index);
-
- return tpm_nv_write_value(index, NULL, 0);
-}
-
-static uint32_t tpm_nv_set_locked(void)
-{
- debug("TPM: Set NV locked\n");
-
- return tpm_nv_define_space(TPM_NV_INDEX_LOCK, 0, 0);
-}
-
-static int tpm_is_owned(void)
-{
- uint8_t response[TPM_PUBEK_SIZE];
- uint32_t result;
-
- result = tpm_read_pubek(response, sizeof(response));
-
- return result != TPM_SUCCESS;
-}
-
-static int test_early_extend(void)
-{
- uint8_t value_in[20];
- uint8_t value_out[20];
-
- printf("Testing earlyextend ...");
- tpm_init();
- TPM_CHECK(tpm_startup(TPM_ST_CLEAR));
- TPM_CHECK(tpm_continue_self_test());
- TPM_CHECK(tpm_extend(1, value_in, value_out));
- printf("done\n");
- return 0;
-}
-
-static int test_early_nvram(void)
-{
- uint32_t x;
-
- printf("Testing earlynvram ...");
- tpm_init();
- TPM_CHECK(tpm_startup(TPM_ST_CLEAR));
- TPM_CHECK(tpm_continue_self_test());
- TPM_CHECK(tpm_tsc_physical_presence(PRESENCE));
- TPM_CHECK(tpm_nv_read_value(INDEX0, (uint8_t *)&x, sizeof(x)));
- printf("done\n");
- return 0;
-}
-
-static int test_early_nvram2(void)
-{
- uint32_t x;
-
- printf("Testing earlynvram2 ...");
- tpm_init();
- TPM_CHECK(tpm_startup(TPM_ST_CLEAR));
- TPM_CHECK(tpm_continue_self_test());
- TPM_CHECK(tpm_tsc_physical_presence(PRESENCE));
- TPM_CHECK(tpm_nv_write_value(INDEX0, (uint8_t *)&x, sizeof(x)));
- printf("done\n");
- return 0;
-}
-
-static int test_enable(void)
-{
- uint8_t disable = 0, deactivated = 0;
-
- printf("Testing enable ...\n");
- tpm_init();
- TPM_CHECK(TlclStartupIfNeeded());
- TPM_CHECK(tpm_self_test_full());
- TPM_CHECK(tpm_tsc_physical_presence(PRESENCE));
- TPM_CHECK(tpm_get_flags(&disable, &deactivated, NULL));
- printf("\tdisable is %d, deactivated is %d\n", disable, deactivated);
- TPM_CHECK(tpm_physical_enable());
- TPM_CHECK(tpm_physical_set_deactivated(0));
- TPM_CHECK(tpm_get_flags(&disable, &deactivated, NULL));
- printf("\tdisable is %d, deactivated is %d\n", disable, deactivated);
- if (disable == 1 || deactivated == 1)
- printf("\tfailed to enable or activate\n");
- printf("\tdone\n");
- return 0;
-}
-
-#define reboot() do { \
- printf("\trebooting...\n"); \
- reset_cpu(0); \
-} while (0)
-
-static int test_fast_enable(void)
-{
- uint8_t disable = 0, deactivated = 0;
- int i;
-
- printf("Testing fastenable ...\n");
- tpm_init();
- TPM_CHECK(TlclStartupIfNeeded());
- TPM_CHECK(tpm_self_test_full());
- TPM_CHECK(tpm_tsc_physical_presence(PRESENCE));
- TPM_CHECK(tpm_get_flags(&disable, &deactivated, NULL));
- printf("\tdisable is %d, deactivated is %d\n", disable, deactivated);
- for (i = 0; i < 2; i++) {
- TPM_CHECK(tpm_force_clear());
- TPM_CHECK(tpm_get_flags(&disable, &deactivated, NULL));
- printf("\tdisable is %d, deactivated is %d\n", disable,
- deactivated);
- assert(disable == 1 && deactivated == 1);
- TPM_CHECK(tpm_physical_enable());
- TPM_CHECK(tpm_physical_set_deactivated(0));
- TPM_CHECK(tpm_get_flags(&disable, &deactivated, NULL));
- printf("\tdisable is %d, deactivated is %d\n", disable,
- deactivated);
- assert(disable == 0 && deactivated == 0);
- }
- printf("\tdone\n");
- return 0;
-}
-
-static int test_global_lock(void)
-{
- uint32_t zero = 0;
- uint32_t result;
- uint32_t x;
-
- printf("Testing globallock ...\n");
- tpm_init();
- TPM_CHECK(TlclStartupIfNeeded());
- TPM_CHECK(tpm_self_test_full());
- TPM_CHECK(tpm_tsc_physical_presence(PRESENCE));
- TPM_CHECK(tpm_nv_read_value(INDEX0, (uint8_t *)&x, sizeof(x)));
- TPM_CHECK(tpm_nv_write_value(INDEX0, (uint8_t *)&zero,
- sizeof(uint32_t)));
- TPM_CHECK(tpm_nv_read_value(INDEX1, (uint8_t *)&x, sizeof(x)));
- TPM_CHECK(tpm_nv_write_value(INDEX1, (uint8_t *)&zero,
- sizeof(uint32_t)));
- TPM_CHECK(tpm_set_global_lock());
- /* Verifies that write to index0 fails */
- x = 1;
- result = tpm_nv_write_value(INDEX0, (uint8_t *)&x, sizeof(x));
- assert(result == TPM_AREA_LOCKED);
- TPM_CHECK(tpm_nv_read_value(INDEX0, (uint8_t *)&x, sizeof(x)));
- assert(x == 0);
- /* Verifies that write to index1 is still possible */
- x = 2;
- TPM_CHECK(tpm_nv_write_value(INDEX1, (uint8_t *)&x, sizeof(x)));
- TPM_CHECK(tpm_nv_read_value(INDEX1, (uint8_t *)&x, sizeof(x)));
- assert(x == 2);
- /* Turns off PP */
- tpm_tsc_physical_presence(PHYS_PRESENCE);
- /* Verifies that write to index1 fails */
- x = 3;
- result = tpm_nv_write_value(INDEX1, (uint8_t *)&x, sizeof(x));
- assert(result == TPM_BAD_PRESENCE);
- TPM_CHECK(tpm_nv_read_value(INDEX1, (uint8_t *)&x, sizeof(x)));
- assert(x == 2);
- printf("\tdone\n");
- return 0;
-}
-
-static int test_lock(void)
-{
- printf("Testing lock ...\n");
- tpm_init();
- tpm_startup(TPM_ST_CLEAR);
- tpm_self_test_full();
- tpm_tsc_physical_presence(PRESENCE);
- tpm_nv_write_value_lock(INDEX0);
- printf("\tLocked 0x%x\n", INDEX0);
- printf("\tdone\n");
- return 0;
-}
-
-static void initialise_spaces(void)
-{
- uint32_t zero = 0;
- uint32_t perm = TPM_NV_PER_WRITE_STCLEAR | TPM_NV_PER_PPWRITE;
-
- printf("\tInitialising spaces\n");
- tpm_nv_set_locked(); /* useful only the first time */
- tpm_nv_define_space(INDEX0, perm, 4);
- tpm_nv_write_value(INDEX0, (uint8_t *)&zero, 4);
- tpm_nv_define_space(INDEX1, perm, 4);
- tpm_nv_write_value(INDEX1, (uint8_t *)&zero, 4);
- tpm_nv_define_space(INDEX2, perm, 4);
- tpm_nv_write_value(INDEX2, (uint8_t *)&zero, 4);
- tpm_nv_define_space(INDEX3, perm, 4);
- tpm_nv_write_value(INDEX3, (uint8_t *)&zero, 4);
- perm = TPM_NV_PER_READ_STCLEAR | TPM_NV_PER_WRITE_STCLEAR |
- TPM_NV_PER_PPWRITE;
- tpm_nv_define_space(INDEX_INITIALISED, perm, 1);
-}
-
-static int test_readonly(void)
-{
- uint8_t c;
- uint32_t index_0, index_1, index_2, index_3;
- int read0, read1, read2, read3;
-
- printf("Testing readonly ...\n");
- tpm_init();
- tpm_startup(TPM_ST_CLEAR);
- tpm_self_test_full();
- tpm_tsc_physical_presence(PRESENCE);
- /*
- * Checks if initialisation has completed by trying to read-lock a
- * space that's created at the end of initialisation
- */
- if (tpm_nv_read_value(INDEX_INITIALISED, &c, 0) == TPM_BADINDEX) {
- /* The initialisation did not complete */
- initialise_spaces();
- }
-
- /* Checks if spaces are OK or messed up */
- read0 = tpm_nv_read_value(INDEX0, (uint8_t *)&index_0, sizeof(index_0));
- read1 = tpm_nv_read_value(INDEX1, (uint8_t *)&index_1, sizeof(index_1));
- read2 = tpm_nv_read_value(INDEX2, (uint8_t *)&index_2, sizeof(index_2));
- read3 = tpm_nv_read_value(INDEX3, (uint8_t *)&index_3, sizeof(index_3));
- if (read0 || read1 || read2 || read3) {
- printf("Invalid contents\n");
- return 0;
- }
-
- /*
- * Writes space, and locks it. Then attempts to write again.
- * I really wish I could use the imperative.
- */
- index_0 += 1;
- if (tpm_nv_write_value(INDEX0, (uint8_t *)&index_0, sizeof(index_0) !=
- TPM_SUCCESS)) {
- error("\tcould not write index 0\n");
- }
- tpm_nv_write_value_lock(INDEX0);
- if (tpm_nv_write_value(INDEX0, (uint8_t *)&index_0, sizeof(index_0)) ==
- TPM_SUCCESS)
- error("\tindex 0 is not locked\n");
-
- printf("\tdone\n");
- return 0;
-}
-
-static int test_redefine_unowned(void)
-{
- uint32_t perm;
- uint32_t result;
- uint32_t x;
-
- printf("Testing redefine_unowned ...");
- tpm_init();
- TPM_CHECK(TlclStartupIfNeeded());
- TPM_CHECK(tpm_self_test_full());
- TPM_CHECK(tpm_tsc_physical_presence(PRESENCE));
- assert(!tpm_is_owned());
-
- /* Ensures spaces exist. */
- TPM_CHECK(tpm_nv_read_value(INDEX0, (uint8_t *)&x, sizeof(x)));
- TPM_CHECK(tpm_nv_read_value(INDEX1, (uint8_t *)&x, sizeof(x)));
-
- /* Redefines spaces a couple of times. */
- perm = TPM_NV_PER_PPWRITE | TPM_NV_PER_GLOBALLOCK;
- TPM_CHECK(tpm_nv_define_space(INDEX0, perm, 2 * sizeof(uint32_t)));
- TPM_CHECK(tpm_nv_define_space(INDEX0, perm, sizeof(uint32_t)));
- perm = TPM_NV_PER_PPWRITE;
- TPM_CHECK(tpm_nv_define_space(INDEX1, perm, 2 * sizeof(uint32_t)));
- TPM_CHECK(tpm_nv_define_space(INDEX1, perm, sizeof(uint32_t)));
-
- /* Sets the global lock */
- tpm_set_global_lock();
-
- /* Verifies that index0 cannot be redefined */
- result = tpm_nv_define_space(INDEX0, perm, sizeof(uint32_t));
- assert(result == TPM_AREA_LOCKED);
-
- /* Checks that index1 can */
- TPM_CHECK(tpm_nv_define_space(INDEX1, perm, 2 * sizeof(uint32_t)));
- TPM_CHECK(tpm_nv_define_space(INDEX1, perm, sizeof(uint32_t)));
-
- /* Turns off PP */
- tpm_tsc_physical_presence(PHYS_PRESENCE);
-
- /* Verifies that neither index0 nor index1 can be redefined */
- result = tpm_nv_define_space(INDEX0, perm, sizeof(uint32_t));
- assert(result == TPM_BAD_PRESENCE);
- result = tpm_nv_define_space(INDEX1, perm, sizeof(uint32_t));
- assert(result == TPM_BAD_PRESENCE);
-
- printf("done\n");
- return 0;
-}
-
-#define PERMPPGL (TPM_NV_PER_PPWRITE | TPM_NV_PER_GLOBALLOCK)
-#define PERMPP TPM_NV_PER_PPWRITE
-
-static int test_space_perm(void)
-{
- uint32_t perm;
-
- printf("Testing spaceperm ...");
- tpm_init();
- TPM_CHECK(TlclStartupIfNeeded());
- TPM_CHECK(tpm_continue_self_test());
- TPM_CHECK(tpm_tsc_physical_presence(PRESENCE));
- TPM_CHECK(tpm_get_permissions(INDEX0, &perm));
- assert((perm & PERMPPGL) == PERMPPGL);
- TPM_CHECK(tpm_get_permissions(INDEX1, &perm));
- assert((perm & PERMPP) == PERMPP);
- printf("done\n");
- return 0;
-}
-
-static int test_startup(void)
-{
- uint32_t result;
- printf("Testing startup ...\n");
-
- tpm_init();
- result = tpm_startup(TPM_ST_CLEAR);
- if (result != 0 && result != TPM_INVALID_POSTINIT)
- printf("\ttpm startup failed with 0x%x\n", result);
- result = tpm_get_flags(NULL, NULL, NULL);
- if (result != 0)
- printf("\ttpm getflags failed with 0x%x\n", result);
- printf("\texecuting SelfTestFull\n");
- tpm_self_test_full();
- result = tpm_get_flags(NULL, NULL, NULL);
- if (result != 0)
- printf("\ttpm getflags failed with 0x%x\n", result);
- printf("\tdone\n");
- return 0;
-}
-
-/*
- * Runs [op] and ensures it returns success and doesn't run longer than
- * [time_limit] in milliseconds.
- */
-#define TTPM_CHECK(op, time_limit) do { \
- ulong start, time; \
- uint32_t __result; \
- \
- start = get_timer(0); \
- __result = op; \
- if (__result != TPM_SUCCESS) { \
- printf("\t" #op ": error 0x%x\n", __result); \
- return -1; \
- } \
- time = get_timer(start); \
- printf("\t" #op ": %lu ms\n", time); \
- if (time > (ulong)time_limit) { \
- printf("\t" #op " exceeded " #time_limit " ms\n"); \
- } \
-} while (0)
-
-
-static int test_timing(void)
-{
- uint32_t x;
- uint8_t in[20], out[20];
-
- printf("Testing timing ...");
- tpm_init();
- TTPM_CHECK(TlclStartupIfNeeded(), 50);
- TTPM_CHECK(tpm_continue_self_test(), 100);
- TTPM_CHECK(tpm_self_test_full(), 1000);
- TTPM_CHECK(tpm_tsc_physical_presence(PRESENCE), 100);
- TTPM_CHECK(tpm_nv_write_value(INDEX0, (uint8_t *)&x, sizeof(x)), 100);
- TTPM_CHECK(tpm_nv_read_value(INDEX0, (uint8_t *)&x, sizeof(x)), 100);
- TTPM_CHECK(tpm_extend(0, in, out), 200);
- TTPM_CHECK(tpm_set_global_lock(), 50);
- TTPM_CHECK(tpm_tsc_physical_presence(PHYS_PRESENCE), 100);
- printf("done\n");
- return 0;
-}
-
-#define TPM_MAX_NV_WRITES_NOOWNER 64
-
-static int test_write_limit(void)
-{
- printf("Testing writelimit ...\n");
- int i;
- uint32_t result;
-
- tpm_init();
- TPM_CHECK(TlclStartupIfNeeded());
- TPM_CHECK(tpm_self_test_full());
- TPM_CHECK(tpm_tsc_physical_presence(PRESENCE));
- TPM_CHECK(tpm_force_clear());
- TPM_CHECK(tpm_physical_enable());
- TPM_CHECK(tpm_physical_set_deactivated(0));
-
- for (i = 0; i < TPM_MAX_NV_WRITES_NOOWNER + 2; i++) {
- printf("\twriting %d\n", i);
- result = tpm_nv_write_value(INDEX0, (uint8_t *)&i, sizeof(i));
- switch (result) {
- case TPM_SUCCESS:
- break;
- case TPM_MAXNVWRITES:
- assert(i >= TPM_MAX_NV_WRITES_NOOWNER);
- default:
- error("\tunexpected error code %d (0x%x)\n",
- result, result);
- }
- }
-
- /* Reset write count */
- TPM_CHECK(tpm_force_clear());
- TPM_CHECK(tpm_physical_enable());
- TPM_CHECK(tpm_physical_set_deactivated(0));
-
- /* Try writing again. */
- TPM_CHECK(tpm_nv_write_value(INDEX0, (uint8_t *)&i, sizeof(i)));
- printf("\tdone\n");
- return 0;
-}
-
-#define VOIDTEST(XFUNC) \
- int do_test_##XFUNC(cmd_tbl_t *cmd_tbl, int flag, int argc, \
- char * const argv[]) \
- { \
- return test_##XFUNC(); \
- }
-
-#define VOIDENT(XNAME) \
- U_BOOT_CMD_MKENT(XNAME, 0, 1, do_test_##XNAME, "", ""),
-
-VOIDTEST(early_extend)
-VOIDTEST(early_nvram)
-VOIDTEST(early_nvram2)
-VOIDTEST(enable)
-VOIDTEST(fast_enable)
-VOIDTEST(global_lock)
-VOIDTEST(lock)
-VOIDTEST(readonly)
-VOIDTEST(redefine_unowned)
-VOIDTEST(space_perm)
-VOIDTEST(startup)
-VOIDTEST(timing)
-VOIDTEST(write_limit)
-VOIDTEST(timer)
-
-static cmd_tbl_t cmd_cros_tpm_sub[] = {
- VOIDENT(early_extend)
- VOIDENT(early_nvram)
- VOIDENT(early_nvram2)
- VOIDENT(enable)
- VOIDENT(fast_enable)
- VOIDENT(global_lock)
- VOIDENT(lock)
- VOIDENT(readonly)
- VOIDENT(redefine_unowned)
- VOIDENT(space_perm)
- VOIDENT(startup)
- VOIDENT(timing)
- VOIDENT(write_limit)
- VOIDENT(timer)
-};
-
-static int do_tpmtest(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
-{
- cmd_tbl_t *c;
-
- printf("argc = %d, argv = ", argc);
- do {
- int i = 0;
-
- for (i = 0; i < argc; i++)
- printf(" %s", argv[i]);
- printf("\n------\n");
- } while (0);
- argc--;
- argv++;
- c = find_cmd_tbl(argv[0], cmd_cros_tpm_sub,
- ARRAY_SIZE(cmd_cros_tpm_sub));
- return c ? c->cmd(cmdtp, flag, argc, argv) : cmd_usage(cmdtp);
-}
-
-U_BOOT_CMD(tpmtest, 2, 1, do_tpmtest, "TPM tests",
- "\n\tearly_extend\n"
- "\tearly_nvram\n"
- "\tearly_nvram2\n"
- "\tenable\n"
- "\tfast_enable\n"
- "\tglobal_lock\n"
- "\tlock\n"
- "\treadonly\n"
- "\tredefine_unowned\n"
- "\tspace_perm\n"
- "\tstartup\n"
- "\ttiming\n"
- "\twrite_limit\n");