1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright (c) 2015 Google, Inc 4 */ 5 6#include <common.h> 7#include <command.h> 8#include <cpu_func.h> 9#include <log.h> 10#include <tpm-v1.h> 11#include <linux/printk.h> 12#include "tpm-user-utils.h" 13#include <tpm_api.h> 14 15/* Prints error and returns on failure */ 16#define TPM_CHECK(tpm_command) do { \ 17 uint32_t result; \ 18 \ 19 result = (tpm_command); \ 20 if (result != TPM_SUCCESS) { \ 21 printf("TEST FAILED: line %d: " #tpm_command ": 0x%x\n", \ 22 __LINE__, result); \ 23 return result; \ 24 } \ 25} while (0) 26 27#define INDEX0 0xda70 28#define INDEX1 0xda71 29#define INDEX2 0xda72 30#define INDEX3 0xda73 31#define INDEX_INITIALISED 0xda80 32#define PHYS_PRESENCE 4 33#define PRESENCE 8 34 35static uint32_t TlclStartupIfNeeded(struct udevice *dev) 36{ 37 uint32_t result = tpm_startup(dev, TPM_ST_CLEAR); 38 39 return result == TPM_INVALID_POSTINIT ? TPM_SUCCESS : result; 40} 41 42static int test_timer(struct udevice *dev) 43{ 44 printf("get_timer(0) = %lu\n", get_timer(0)); 45 return 0; 46} 47 48static uint32_t tpm_get_flags(struct udevice *dev, uint8_t *disable, 49 uint8_t *deactivated, uint8_t *nvlocked) 50{ 51 struct tpm_permanent_flags pflags; 52 uint32_t result; 53 54 result = tpm1_get_permanent_flags(dev, &pflags); 55 if (result) 56 return result; 57 if (disable) 58 *disable = pflags.disable; 59 if (deactivated) 60 *deactivated = pflags.deactivated; 61 if (nvlocked) 62 *nvlocked = pflags.nv_locked; 63 debug("TPM: Got flags disable=%d, deactivated=%d, nvlocked=%d\n", 64 pflags.disable, pflags.deactivated, pflags.nv_locked); 65 66 return 0; 67} 68 69static uint32_t tpm_nv_write_value_lock(struct udevice *dev, uint32_t index) 70{ 71 debug("TPM: Write lock 0x%x\n", index); 72 73 return tpm_nv_write_value(dev, index, NULL, 0); 74} 75 76static int tpm_is_owned(struct udevice *dev) 77{ 78 uint8_t response[TPM_PUBEK_SIZE]; 79 uint32_t result; 80 81 result = tpm_read_pubek(dev, response, sizeof(response)); 82 83 return result != TPM_SUCCESS; 84} 85 86static int test_early_extend(struct udevice *dev) 87{ 88 uint8_t value_in[20]; 89 uint8_t value_out[20]; 90 91 printf("Testing earlyextend ..."); 92 tpm_init(dev); 93 TPM_CHECK(tpm_startup(dev, TPM_ST_CLEAR)); 94 TPM_CHECK(tpm_continue_self_test(dev)); 95 TPM_CHECK(tpm_pcr_extend(dev, 1, value_in, sizeof(value_in), value_out, 96 "test")); 97 printf("done\n"); 98 return 0; 99} 100 101static int test_early_nvram(struct udevice *dev) 102{ 103 uint32_t x; 104 105 printf("Testing earlynvram ..."); 106 tpm_init(dev); 107 TPM_CHECK(tpm_startup(dev, TPM_ST_CLEAR)); 108 TPM_CHECK(tpm_continue_self_test(dev)); 109 TPM_CHECK(tpm_tsc_physical_presence(dev, PRESENCE)); 110 TPM_CHECK(tpm_nv_read_value(dev, INDEX0, (uint8_t *)&x, sizeof(x))); 111 printf("done\n"); 112 return 0; 113} 114 115static int test_early_nvram2(struct udevice *dev) 116{ 117 uint32_t x; 118 119 printf("Testing earlynvram2 ..."); 120 tpm_init(dev); 121 TPM_CHECK(tpm_startup(dev, TPM_ST_CLEAR)); 122 TPM_CHECK(tpm_continue_self_test(dev)); 123 TPM_CHECK(tpm_tsc_physical_presence(dev, PRESENCE)); 124 TPM_CHECK(tpm_nv_write_value(dev, INDEX0, (uint8_t *)&x, sizeof(x))); 125 printf("done\n"); 126 return 0; 127} 128 129static int test_enable(struct udevice *dev) 130{ 131 uint8_t disable = 0, deactivated = 0; 132 133 printf("Testing enable ...\n"); 134 tpm_init(dev); 135 TPM_CHECK(TlclStartupIfNeeded(dev)); 136 TPM_CHECK(tpm_self_test_full(dev)); 137 TPM_CHECK(tpm_tsc_physical_presence(dev, PRESENCE)); 138 TPM_CHECK(tpm_get_flags(dev, &disable, &deactivated, NULL)); 139 printf("\tdisable is %d, deactivated is %d\n", disable, deactivated); 140 TPM_CHECK(tpm_physical_enable(dev)); 141 TPM_CHECK(tpm_physical_set_deactivated(dev, 0)); 142 TPM_CHECK(tpm_get_flags(dev, &disable, &deactivated, NULL)); 143 printf("\tdisable is %d, deactivated is %d\n", disable, deactivated); 144 if (disable == 1 || deactivated == 1) 145 printf("\tfailed to enable or activate\n"); 146 printf("\tdone\n"); 147 return 0; 148} 149 150#define reboot() do { \ 151 printf("\trebooting...\n"); \ 152 reset_cpu(); \ 153} while (0) 154 155static int test_fast_enable(struct udevice *dev) 156{ 157 uint8_t disable = 0, deactivated = 0; 158 int i; 159 160 printf("Testing fastenable ...\n"); 161 tpm_init(dev); 162 TPM_CHECK(TlclStartupIfNeeded(dev)); 163 TPM_CHECK(tpm_self_test_full(dev)); 164 TPM_CHECK(tpm_tsc_physical_presence(dev, PRESENCE)); 165 TPM_CHECK(tpm_get_flags(dev, &disable, &deactivated, NULL)); 166 printf("\tdisable is %d, deactivated is %d\n", disable, deactivated); 167 for (i = 0; i < 2; i++) { 168 TPM_CHECK(tpm_force_clear(dev)); 169 TPM_CHECK(tpm_get_flags(dev, &disable, &deactivated, NULL)); 170 printf("\tdisable is %d, deactivated is %d\n", disable, 171 deactivated); 172 assert(disable == 1 && deactivated == 1); 173 TPM_CHECK(tpm_physical_enable(dev)); 174 TPM_CHECK(tpm_physical_set_deactivated(dev, 0)); 175 TPM_CHECK(tpm_get_flags(dev, &disable, &deactivated, NULL)); 176 printf("\tdisable is %d, deactivated is %d\n", disable, 177 deactivated); 178 assert(disable == 0 && deactivated == 0); 179 } 180 printf("\tdone\n"); 181 return 0; 182} 183 184static int test_global_lock(struct udevice *dev) 185{ 186 uint32_t zero = 0; 187 uint32_t result; 188 uint32_t x; 189 190 printf("Testing globallock ...\n"); 191 tpm_init(dev); 192 TPM_CHECK(TlclStartupIfNeeded(dev)); 193 TPM_CHECK(tpm_self_test_full(dev)); 194 TPM_CHECK(tpm_tsc_physical_presence(dev, PRESENCE)); 195 TPM_CHECK(tpm_nv_read_value(dev, INDEX0, (uint8_t *)&x, sizeof(x))); 196 TPM_CHECK(tpm_nv_write_value(dev, INDEX0, (uint8_t *)&zero, 197 sizeof(uint32_t))); 198 TPM_CHECK(tpm_nv_read_value(dev, INDEX1, (uint8_t *)&x, sizeof(x))); 199 TPM_CHECK(tpm_nv_write_value(dev, INDEX1, (uint8_t *)&zero, 200 sizeof(uint32_t))); 201 TPM_CHECK(tpm_set_global_lock(dev)); 202 /* Verifies that write to index0 fails */ 203 x = 1; 204 result = tpm_nv_write_value(dev, INDEX0, (uint8_t *)&x, sizeof(x)); 205 assert(result == TPM_AREA_LOCKED); 206 TPM_CHECK(tpm_nv_read_value(dev, INDEX0, (uint8_t *)&x, sizeof(x))); 207 assert(x == 0); 208 /* Verifies that write to index1 is still possible */ 209 x = 2; 210 TPM_CHECK(tpm_nv_write_value(dev, INDEX1, (uint8_t *)&x, sizeof(x))); 211 TPM_CHECK(tpm_nv_read_value(dev, INDEX1, (uint8_t *)&x, sizeof(x))); 212 assert(x == 2); 213 /* Turns off PP */ 214 tpm_tsc_physical_presence(dev, PHYS_PRESENCE); 215 /* Verifies that write to index1 fails */ 216 x = 3; 217 result = tpm_nv_write_value(dev, INDEX1, (uint8_t *)&x, sizeof(x)); 218 assert(result == TPM_BAD_PRESENCE); 219 TPM_CHECK(tpm_nv_read_value(dev, INDEX1, (uint8_t *)&x, sizeof(x))); 220 assert(x == 2); 221 printf("\tdone\n"); 222 return 0; 223} 224 225static int test_lock(struct udevice *dev) 226{ 227 printf("Testing lock ...\n"); 228 tpm_init(dev); 229 tpm_startup(dev, TPM_ST_CLEAR); 230 tpm_self_test_full(dev); 231 tpm_tsc_physical_presence(dev, PRESENCE); 232 tpm_nv_write_value_lock(dev, INDEX0); 233 printf("\tLocked 0x%x\n", INDEX0); 234 printf("\tdone\n"); 235 return 0; 236} 237 238static void initialise_spaces(struct udevice *dev) 239{ 240 uint32_t zero = 0; 241 uint32_t perm = TPM_NV_PER_WRITE_STCLEAR | TPM_NV_PER_PPWRITE; 242 243 printf("\tInitialising spaces\n"); 244 tpm1_nv_set_locked(dev); /* useful only the first time */ 245 tpm1_nv_define_space(dev, INDEX0, perm, 4); 246 tpm_nv_write_value(dev, INDEX0, (uint8_t *)&zero, 4); 247 tpm1_nv_define_space(dev, INDEX1, perm, 4); 248 tpm_nv_write_value(dev, INDEX1, (uint8_t *)&zero, 4); 249 tpm1_nv_define_space(dev, INDEX2, perm, 4); 250 tpm_nv_write_value(dev, INDEX2, (uint8_t *)&zero, 4); 251 tpm1_nv_define_space(dev, INDEX3, perm, 4); 252 tpm_nv_write_value(dev, INDEX3, (uint8_t *)&zero, 4); 253 perm = TPM_NV_PER_READ_STCLEAR | TPM_NV_PER_WRITE_STCLEAR | 254 TPM_NV_PER_PPWRITE; 255 tpm1_nv_define_space(dev, INDEX_INITIALISED, perm, 1); 256} 257 258static int test_readonly(struct udevice *dev) 259{ 260 uint8_t c; 261 uint32_t index_0, index_1, index_2, index_3; 262 int read0, read1, read2, read3; 263 264 printf("Testing readonly ...\n"); 265 tpm_init(dev); 266 tpm_startup(dev, TPM_ST_CLEAR); 267 tpm_self_test_full(dev); 268 tpm_tsc_physical_presence(dev, PRESENCE); 269 /* 270 * Checks if initialisation has completed by trying to read-lock a 271 * space that's created at the end of initialisation 272 */ 273 if (tpm_nv_read_value(dev, INDEX_INITIALISED, &c, 0) == TPM_BADINDEX) { 274 /* The initialisation did not complete */ 275 initialise_spaces(dev); 276 } 277 278 /* Checks if spaces are OK or messed up */ 279 read0 = tpm_nv_read_value(dev, INDEX0, (uint8_t *)&index_0, 280 sizeof(index_0)); 281 read1 = tpm_nv_read_value(dev, INDEX1, (uint8_t *)&index_1, 282 sizeof(index_1)); 283 read2 = tpm_nv_read_value(dev, INDEX2, (uint8_t *)&index_2, 284 sizeof(index_2)); 285 read3 = tpm_nv_read_value(dev, INDEX3, (uint8_t *)&index_3, 286 sizeof(index_3)); 287 if (read0 || read1 || read2 || read3) { 288 printf("Invalid contents\n"); 289 return 0; 290 } 291 292 /* 293 * Writes space, and locks it. Then attempts to write again. 294 * I really wish I could use the imperative. 295 */ 296 index_0 += 1; 297 if (tpm_nv_write_value(dev, INDEX0, (uint8_t *)&index_0, 298 sizeof(index_0)) != 299 TPM_SUCCESS) { 300 pr_err("\tcould not write index 0\n"); 301 } 302 tpm_nv_write_value_lock(dev, INDEX0); 303 if (tpm_nv_write_value(dev, INDEX0, (uint8_t *)&index_0, 304 sizeof(index_0)) == 305 TPM_SUCCESS) 306 pr_err("\tindex 0 is not locked\n"); 307 308 printf("\tdone\n"); 309 return 0; 310} 311 312static int test_redefine_unowned(struct udevice *dev) 313{ 314 uint32_t perm; 315 uint32_t result; 316 uint32_t x; 317 318 printf("Testing redefine_unowned ..."); 319 tpm_init(dev); 320 TPM_CHECK(TlclStartupIfNeeded(dev)); 321 TPM_CHECK(tpm_self_test_full(dev)); 322 TPM_CHECK(tpm_tsc_physical_presence(dev, PRESENCE)); 323 assert(!tpm_is_owned(dev)); 324 325 /* Ensures spaces exist. */ 326 TPM_CHECK(tpm_nv_read_value(dev, INDEX0, (uint8_t *)&x, sizeof(x))); 327 TPM_CHECK(tpm_nv_read_value(dev, INDEX1, (uint8_t *)&x, sizeof(x))); 328 329 /* Redefines spaces a couple of times. */ 330 perm = TPM_NV_PER_PPWRITE | TPM_NV_PER_GLOBALLOCK; 331 TPM_CHECK(tpm1_nv_define_space(dev, INDEX0, perm, 332 2 * sizeof(uint32_t))); 333 TPM_CHECK(tpm1_nv_define_space(dev, INDEX0, perm, sizeof(uint32_t))); 334 perm = TPM_NV_PER_PPWRITE; 335 TPM_CHECK(tpm1_nv_define_space(dev, INDEX1, perm, 336 2 * sizeof(uint32_t))); 337 TPM_CHECK(tpm1_nv_define_space(dev, INDEX1, perm, sizeof(uint32_t))); 338 339 /* Sets the global lock */ 340 tpm_set_global_lock(dev); 341 342 /* Verifies that index0 cannot be redefined */ 343 result = tpm1_nv_define_space(dev, INDEX0, perm, sizeof(uint32_t)); 344 assert(result == TPM_AREA_LOCKED); 345 346 /* Checks that index1 can */ 347 TPM_CHECK(tpm1_nv_define_space(dev, INDEX1, perm, 348 2 * sizeof(uint32_t))); 349 TPM_CHECK(tpm1_nv_define_space(dev, INDEX1, perm, sizeof(uint32_t))); 350 351 /* Turns off PP */ 352 tpm_tsc_physical_presence(dev, PHYS_PRESENCE); 353 354 /* Verifies that neither index0 nor index1 can be redefined */ 355 result = tpm1_nv_define_space(dev, INDEX0, perm, sizeof(uint32_t)); 356 assert(result == TPM_BAD_PRESENCE); 357 result = tpm1_nv_define_space(dev, INDEX1, perm, sizeof(uint32_t)); 358 assert(result == TPM_BAD_PRESENCE); 359 360 printf("done\n"); 361 return 0; 362} 363 364#define PERMPPGL (TPM_NV_PER_PPWRITE | TPM_NV_PER_GLOBALLOCK) 365#define PERMPP TPM_NV_PER_PPWRITE 366 367static int test_space_perm(struct udevice *dev) 368{ 369 uint32_t perm; 370 371 printf("Testing spaceperm ..."); 372 tpm_init(dev); 373 TPM_CHECK(TlclStartupIfNeeded(dev)); 374 TPM_CHECK(tpm_continue_self_test(dev)); 375 TPM_CHECK(tpm_tsc_physical_presence(dev, PRESENCE)); 376 TPM_CHECK(tpm_get_permissions(dev, INDEX0, &perm)); 377 assert((perm & PERMPPGL) == PERMPPGL); 378 TPM_CHECK(tpm_get_permissions(dev, INDEX1, &perm)); 379 assert((perm & PERMPP) == PERMPP); 380 printf("done\n"); 381 return 0; 382} 383 384static int test_startup(struct udevice *dev) 385{ 386 uint32_t result; 387 388 printf("Testing startup ...\n"); 389 390 tpm_init(dev); 391 result = tpm_startup(dev, TPM_ST_CLEAR); 392 if (result != 0 && result != TPM_INVALID_POSTINIT) 393 printf("\ttpm startup failed with 0x%x\n", result); 394 result = tpm_get_flags(dev, NULL, NULL, NULL); 395 if (result != 0) 396 printf("\ttpm getflags failed with 0x%x\n", result); 397 printf("\texecuting SelfTestFull\n"); 398 tpm_self_test_full(dev); 399 result = tpm_get_flags(dev, NULL, NULL, NULL); 400 if (result != 0) 401 printf("\ttpm getflags failed with 0x%x\n", result); 402 printf("\tdone\n"); 403 return 0; 404} 405 406/* 407 * Runs [op] and ensures it returns success and doesn't run longer than 408 * [time_limit] in milliseconds. 409 */ 410#define TTPM_CHECK(op, time_limit) do { \ 411 ulong start, time; \ 412 uint32_t __result; \ 413 \ 414 start = get_timer(0); \ 415 __result = op; \ 416 if (__result != TPM_SUCCESS) { \ 417 printf("\t" #op ": error 0x%x\n", __result); \ 418 return -1; \ 419 } \ 420 time = get_timer(start); \ 421 printf("\t" #op ": %lu ms\n", time); \ 422 if (time > (ulong)time_limit) { \ 423 printf("\t" #op " exceeded " #time_limit " ms\n"); \ 424 } \ 425} while (0) 426 427 428static int test_timing(struct udevice *dev) 429{ 430 uint8_t in[20], out[20]; 431 uint32_t x; 432 433 printf("Testing timing ..."); 434 tpm_init(dev); 435 TTPM_CHECK(TlclStartupIfNeeded(dev), 50); 436 TTPM_CHECK(tpm_continue_self_test(dev), 100); 437 TTPM_CHECK(tpm_self_test_full(dev), 1000); 438 TTPM_CHECK(tpm_tsc_physical_presence(dev, PRESENCE), 100); 439 TTPM_CHECK(tpm_nv_write_value(dev, INDEX0, (uint8_t *)&x, sizeof(x)), 440 100); 441 TTPM_CHECK(tpm_nv_read_value(dev, INDEX0, (uint8_t *)&x, sizeof(x)), 442 100); 443 TTPM_CHECK(tpm_pcr_extend(dev, 0, in, sizeof(in), out, "test"), 200); 444 TTPM_CHECK(tpm_set_global_lock(dev), 50); 445 TTPM_CHECK(tpm_tsc_physical_presence(dev, PHYS_PRESENCE), 100); 446 printf("done\n"); 447 return 0; 448} 449 450#define TPM_MAX_NV_WRITES_NOOWNER 64 451 452static int test_write_limit(struct udevice *dev) 453{ 454 uint32_t result; 455 int i; 456 457 printf("Testing writelimit ...\n"); 458 tpm_init(dev); 459 TPM_CHECK(TlclStartupIfNeeded(dev)); 460 TPM_CHECK(tpm_self_test_full(dev)); 461 TPM_CHECK(tpm_tsc_physical_presence(dev, PRESENCE)); 462 TPM_CHECK(tpm_force_clear(dev)); 463 TPM_CHECK(tpm_physical_enable(dev)); 464 TPM_CHECK(tpm_physical_set_deactivated(dev, 0)); 465 466 for (i = 0; i < TPM_MAX_NV_WRITES_NOOWNER + 2; i++) { 467 printf("\twriting %d\n", i); 468 result = tpm_nv_write_value(dev, INDEX0, (uint8_t *)&i, 469 sizeof(i)); 470 switch (result) { 471 case TPM_SUCCESS: 472 break; 473 case TPM_MAXNVWRITES: 474 assert(i >= TPM_MAX_NV_WRITES_NOOWNER); 475 break; 476 default: 477 pr_err("\tunexpected error code %d (0x%x)\n", 478 result, result); 479 } 480 } 481 482 /* Reset write count */ 483 TPM_CHECK(tpm_force_clear(dev)); 484 TPM_CHECK(tpm_physical_enable(dev)); 485 TPM_CHECK(tpm_physical_set_deactivated(dev, 0)); 486 487 /* Try writing again. */ 488 TPM_CHECK(tpm_nv_write_value(dev, INDEX0, (uint8_t *)&i, sizeof(i))); 489 printf("\tdone\n"); 490 return 0; 491} 492 493#define VOIDTEST(XFUNC) \ 494 int do_test_##XFUNC(struct cmd_tbl *cmd_tbl, int flag, int argc, \ 495 char *const argv[]) \ 496 { \ 497 struct udevice *dev; \ 498 int ret; \ 499\ 500 ret = get_tpm(&dev); \ 501 if (ret) \ 502 return ret; \ 503 return test_##XFUNC(dev); \ 504 } 505 506#define VOIDENT(XNAME) \ 507 U_BOOT_CMD_MKENT(XNAME, 0, 1, do_test_##XNAME, "", ""), 508 509VOIDTEST(early_extend) 510VOIDTEST(early_nvram) 511VOIDTEST(early_nvram2) 512VOIDTEST(enable) 513VOIDTEST(fast_enable) 514VOIDTEST(global_lock) 515VOIDTEST(lock) 516VOIDTEST(readonly) 517VOIDTEST(redefine_unowned) 518VOIDTEST(space_perm) 519VOIDTEST(startup) 520VOIDTEST(timing) 521VOIDTEST(write_limit) 522VOIDTEST(timer) 523 524static struct cmd_tbl cmd_cros_tpm_sub[] = { 525 VOIDENT(early_extend) 526 VOIDENT(early_nvram) 527 VOIDENT(early_nvram2) 528 VOIDENT(enable) 529 VOIDENT(fast_enable) 530 VOIDENT(global_lock) 531 VOIDENT(lock) 532 VOIDENT(readonly) 533 VOIDENT(redefine_unowned) 534 VOIDENT(space_perm) 535 VOIDENT(startup) 536 VOIDENT(timing) 537 VOIDENT(write_limit) 538 VOIDENT(timer) 539}; 540 541static int do_tpmtest(struct cmd_tbl *cmdtp, int flag, int argc, 542 char *const argv[]) 543{ 544 struct cmd_tbl *c; 545 int i; 546 547 printf("argc = %d, argv = ", argc); 548 549 for (i = 0; i < argc; i++) 550 printf(" %s", argv[i]); 551 552 printf("\n------\n"); 553 554 argc--; 555 argv++; 556 c = find_cmd_tbl(argv[0], cmd_cros_tpm_sub, 557 ARRAY_SIZE(cmd_cros_tpm_sub)); 558 return c ? c->cmd(cmdtp, flag, argc, argv) : cmd_usage(cmdtp); 559} 560 561U_BOOT_CMD(tpmtest, 2, 1, do_tpmtest, "TPM tests", 562 "\n\tearly_extend\n" 563 "\tearly_nvram\n" 564 "\tearly_nvram2\n" 565 "\tenable\n" 566 "\tfast_enable\n" 567 "\tglobal_lock\n" 568 "\tlock\n" 569 "\treadonly\n" 570 "\tredefine_unowned\n" 571 "\tspace_perm\n" 572 "\tstartup\n" 573 "\ttiming\n" 574 "\twrite_limit\n"); 575