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