1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (c) 2023 Linaro Limited 4 * Copyright (c) 2018 Bootlin 5 * Author: Miquel Raynal <miquel.raynal@bootlin.com> 6 */ 7 8 #include <common.h> 9 #include <dm.h> 10 #include <dm/of_access.h> 11 #include <tpm_api.h> 12 #include <tpm-common.h> 13 #include <tpm-v2.h> 14 #include <u-boot/sha1.h> 15 #include <u-boot/sha256.h> 16 #include <u-boot/sha512.h> 17 #include <version_string.h> 18 #include <asm/io.h> 19 #include <linux/bitops.h> 20 #include <linux/unaligned/be_byteshift.h> 21 #include <linux/unaligned/generic.h> 22 #include <linux/unaligned/le_byteshift.h> 23 24 #include "tpm-utils.h" 25 26 const enum tpm2_algorithms tpm2_supported_algorithms[4] = { 27 TPM2_ALG_SHA1, 28 TPM2_ALG_SHA256, 29 TPM2_ALG_SHA384, 30 TPM2_ALG_SHA512, 31 }; 32 33 int tcg2_get_active_pcr_banks(struct udevice *dev, u32 *active_pcr_banks) 34 { 35 u32 supported = 0; 36 u32 pcr_banks = 0; 37 u32 active = 0; 38 int rc; 39 40 rc = tpm2_get_pcr_info(dev, &supported, &active, &pcr_banks); 41 if (rc) 42 return rc; 43 44 *active_pcr_banks = active; 45 46 return 0; 47 } 48 49 u32 tcg2_event_get_size(struct tpml_digest_values *digest_list) 50 { 51 u32 len; 52 size_t i; 53 54 len = offsetof(struct tcg_pcr_event2, digests); 55 len += offsetof(struct tpml_digest_values, digests); 56 for (i = 0; i < digest_list->count; ++i) { 57 u16 l = tpm2_algorithm_to_len(digest_list->digests[i].hash_alg); 58 59 if (!l) 60 continue; 61 62 len += l + offsetof(struct tpmt_ha, digest); 63 } 64 len += sizeof(u32); 65 66 return len; 67 } 68 69 int tcg2_create_digest(struct udevice *dev, const u8 *input, u32 length, 70 struct tpml_digest_values *digest_list) 71 { 72 u8 final[sizeof(union tpmu_ha)]; 73 sha256_context ctx_256; 74 sha512_context ctx_512; 75 sha1_context ctx; 76 u32 active; 77 size_t i; 78 u32 len; 79 int rc; 80 81 rc = tcg2_get_active_pcr_banks(dev, &active); 82 if (rc) 83 return rc; 84 85 digest_list->count = 0; 86 for (i = 0; i < ARRAY_SIZE(tpm2_supported_algorithms); ++i) { 87 u32 mask = 88 tpm2_algorithm_to_mask(tpm2_supported_algorithms[i]); 89 90 if (!(active & mask)) 91 continue; 92 93 switch (tpm2_supported_algorithms[i]) { 94 case TPM2_ALG_SHA1: 95 sha1_starts(&ctx); 96 sha1_update(&ctx, input, length); 97 sha1_finish(&ctx, final); 98 len = TPM2_SHA1_DIGEST_SIZE; 99 break; 100 case TPM2_ALG_SHA256: 101 sha256_starts(&ctx_256); 102 sha256_update(&ctx_256, input, length); 103 sha256_finish(&ctx_256, final); 104 len = TPM2_SHA256_DIGEST_SIZE; 105 break; 106 case TPM2_ALG_SHA384: 107 sha384_starts(&ctx_512); 108 sha384_update(&ctx_512, input, length); 109 sha384_finish(&ctx_512, final); 110 len = TPM2_SHA384_DIGEST_SIZE; 111 break; 112 case TPM2_ALG_SHA512: 113 sha512_starts(&ctx_512); 114 sha512_update(&ctx_512, input, length); 115 sha512_finish(&ctx_512, final); 116 len = TPM2_SHA512_DIGEST_SIZE; 117 break; 118 default: 119 printf("%s: unsupported algorithm %x\n", __func__, 120 tpm2_supported_algorithms[i]); 121 continue; 122 } 123 124 digest_list->digests[digest_list->count].hash_alg = 125 tpm2_supported_algorithms[i]; 126 memcpy(&digest_list->digests[digest_list->count].digest, final, 127 len); 128 digest_list->count++; 129 } 130 131 return 0; 132 } 133 134 void tcg2_log_append(u32 pcr_index, u32 event_type, 135 struct tpml_digest_values *digest_list, u32 size, 136 const u8 *event, u8 *log) 137 { 138 size_t len; 139 size_t pos; 140 u32 i; 141 142 pos = offsetof(struct tcg_pcr_event2, pcr_index); 143 put_unaligned_le32(pcr_index, log); 144 pos = offsetof(struct tcg_pcr_event2, event_type); 145 put_unaligned_le32(event_type, log + pos); 146 pos = offsetof(struct tcg_pcr_event2, digests) + 147 offsetof(struct tpml_digest_values, count); 148 put_unaligned_le32(digest_list->count, log + pos); 149 150 pos = offsetof(struct tcg_pcr_event2, digests) + 151 offsetof(struct tpml_digest_values, digests); 152 for (i = 0; i < digest_list->count; ++i) { 153 u16 hash_alg = digest_list->digests[i].hash_alg; 154 155 len = tpm2_algorithm_to_len(hash_alg); 156 if (!len) 157 continue; 158 159 pos += offsetof(struct tpmt_ha, hash_alg); 160 put_unaligned_le16(hash_alg, log + pos); 161 pos += offsetof(struct tpmt_ha, digest); 162 memcpy(log + pos, (u8 *)&digest_list->digests[i].digest, len); 163 pos += len; 164 } 165 166 put_unaligned_le32(size, log + pos); 167 pos += sizeof(u32); 168 memcpy(log + pos, event, size); 169 } 170 171 static int tcg2_log_append_check(struct tcg2_event_log *elog, u32 pcr_index, 172 u32 event_type, 173 struct tpml_digest_values *digest_list, 174 u32 size, const u8 *event) 175 { 176 u32 event_size; 177 u8 *log; 178 179 event_size = size + tcg2_event_get_size(digest_list); 180 if (elog->log_position + event_size > elog->log_size) { 181 printf("%s: log too large: %u + %u > %u\n", __func__, 182 elog->log_position, event_size, elog->log_size); 183 return -ENOBUFS; 184 } 185 186 log = elog->log + elog->log_position; 187 elog->log_position += event_size; 188 189 tcg2_log_append(pcr_index, event_type, digest_list, size, event, log); 190 191 return 0; 192 } 193 194 static int tcg2_log_init(struct udevice *dev, struct tcg2_event_log *elog) 195 { 196 struct tcg_efi_spec_id_event *ev; 197 struct tcg_pcr_event *log; 198 u32 event_size; 199 u32 count = 0; 200 u32 log_size; 201 u32 active; 202 u32 mask; 203 size_t i; 204 u16 len; 205 int rc; 206 207 rc = tcg2_get_active_pcr_banks(dev, &active); 208 if (rc) 209 return rc; 210 211 event_size = offsetof(struct tcg_efi_spec_id_event, digest_sizes); 212 for (i = 0; i < ARRAY_SIZE(tpm2_supported_algorithms); ++i) { 213 mask = tpm2_algorithm_to_mask(tpm2_supported_algorithms[i]); 214 215 if (!(active & mask)) 216 continue; 217 218 switch (tpm2_supported_algorithms[i]) { 219 case TPM2_ALG_SHA1: 220 case TPM2_ALG_SHA256: 221 case TPM2_ALG_SHA384: 222 case TPM2_ALG_SHA512: 223 count++; 224 break; 225 default: 226 continue; 227 } 228 } 229 230 event_size += 1 + 231 (sizeof(struct tcg_efi_spec_id_event_algorithm_size) * count); 232 log_size = offsetof(struct tcg_pcr_event, event) + event_size; 233 234 if (log_size > elog->log_size) { 235 printf("%s: log too large: %u > %u\n", __func__, log_size, 236 elog->log_size); 237 return -ENOBUFS; 238 } 239 240 log = (struct tcg_pcr_event *)elog->log; 241 put_unaligned_le32(0, &log->pcr_index); 242 put_unaligned_le32(EV_NO_ACTION, &log->event_type); 243 memset(&log->digest, 0, sizeof(log->digest)); 244 put_unaligned_le32(event_size, &log->event_size); 245 246 ev = (struct tcg_efi_spec_id_event *)log->event; 247 strlcpy((char *)ev->signature, TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03, 248 sizeof(ev->signature)); 249 put_unaligned_le32(0, &ev->platform_class); 250 ev->spec_version_minor = TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MINOR_TPM2; 251 ev->spec_version_major = TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MAJOR_TPM2; 252 ev->spec_errata = TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_ERRATA_TPM2; 253 ev->uintn_size = sizeof(size_t) / sizeof(u32); 254 put_unaligned_le32(count, &ev->number_of_algorithms); 255 256 count = 0; 257 for (i = 0; i < ARRAY_SIZE(tpm2_supported_algorithms); ++i) { 258 mask = tpm2_algorithm_to_mask(tpm2_supported_algorithms[i]); 259 260 if (!(active & mask)) 261 continue; 262 263 len = tpm2_algorithm_to_len(tpm2_supported_algorithms[i]); 264 if (!len) 265 continue; 266 267 put_unaligned_le16(tpm2_supported_algorithms[i], 268 &ev->digest_sizes[count].algorithm_id); 269 put_unaligned_le16(len, &ev->digest_sizes[count].digest_size); 270 count++; 271 } 272 273 *((u8 *)ev + (event_size - 1)) = 0; 274 elog->log_position = log_size; 275 276 return 0; 277 } 278 279 static int tcg2_replay_eventlog(struct tcg2_event_log *elog, 280 struct udevice *dev, 281 struct tpml_digest_values *digest_list, 282 u32 log_position) 283 { 284 const u32 offset = offsetof(struct tcg_pcr_event2, digests) + 285 offsetof(struct tpml_digest_values, digests); 286 u32 event_size; 287 u32 count; 288 u16 algo; 289 u32 pcr; 290 u32 pos; 291 u16 len; 292 u8 *log; 293 int rc; 294 u32 i; 295 296 while (log_position + offset < elog->log_size) { 297 log = elog->log + log_position; 298 299 pos = offsetof(struct tcg_pcr_event2, pcr_index); 300 pcr = get_unaligned_le32(log + pos); 301 pos = offsetof(struct tcg_pcr_event2, event_type); 302 if (!get_unaligned_le32(log + pos)) 303 return 0; 304 305 pos = offsetof(struct tcg_pcr_event2, digests) + 306 offsetof(struct tpml_digest_values, count); 307 count = get_unaligned_le32(log + pos); 308 if (count > ARRAY_SIZE(tpm2_supported_algorithms) || 309 (digest_list->count && digest_list->count != count)) 310 return 0; 311 312 pos = offsetof(struct tcg_pcr_event2, digests) + 313 offsetof(struct tpml_digest_values, digests); 314 for (i = 0; i < count; ++i) { 315 pos += offsetof(struct tpmt_ha, hash_alg); 316 if (log_position + pos + sizeof(u16) >= elog->log_size) 317 return 0; 318 319 algo = get_unaligned_le16(log + pos); 320 pos += offsetof(struct tpmt_ha, digest); 321 switch (algo) { 322 case TPM2_ALG_SHA1: 323 case TPM2_ALG_SHA256: 324 case TPM2_ALG_SHA384: 325 case TPM2_ALG_SHA512: 326 len = tpm2_algorithm_to_len(algo); 327 break; 328 default: 329 return 0; 330 } 331 332 if (digest_list->count) { 333 if (algo != digest_list->digests[i].hash_alg || 334 log_position + pos + len >= elog->log_size) 335 return 0; 336 337 memcpy(digest_list->digests[i].digest.sha512, 338 log + pos, len); 339 } 340 341 pos += len; 342 } 343 344 if (log_position + pos + sizeof(u32) >= elog->log_size) 345 return 0; 346 347 event_size = get_unaligned_le32(log + pos); 348 pos += event_size + sizeof(u32); 349 if (log_position + pos > elog->log_size) 350 return 0; 351 352 if (digest_list->count) { 353 rc = tcg2_pcr_extend(dev, pcr, digest_list); 354 if (rc) 355 return rc; 356 } 357 358 log_position += pos; 359 } 360 361 elog->log_position = log_position; 362 elog->found = true; 363 return 0; 364 } 365 366 static int tcg2_log_parse(struct udevice *dev, struct tcg2_event_log *elog) 367 { 368 struct tpml_digest_values digest_list; 369 struct tcg_efi_spec_id_event *event; 370 struct tcg_pcr_event *log; 371 u32 log_active; 372 u32 calc_size; 373 u32 active; 374 u32 count; 375 u32 evsz; 376 u32 mask; 377 u16 algo; 378 u16 len; 379 int rc; 380 u32 i; 381 u16 j; 382 383 if (elog->log_size <= offsetof(struct tcg_pcr_event, event)) 384 return 0; 385 386 log = (struct tcg_pcr_event *)elog->log; 387 if (get_unaligned_le32(&log->pcr_index) != 0 || 388 get_unaligned_le32(&log->event_type) != EV_NO_ACTION) 389 return 0; 390 391 for (i = 0; i < sizeof(log->digest); i++) { 392 if (log->digest[i]) 393 return 0; 394 } 395 396 evsz = get_unaligned_le32(&log->event_size); 397 if (evsz < offsetof(struct tcg_efi_spec_id_event, digest_sizes) || 398 evsz + offsetof(struct tcg_pcr_event, event) > elog->log_size) 399 return 0; 400 401 event = (struct tcg_efi_spec_id_event *)log->event; 402 if (memcmp(event->signature, TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03, 403 sizeof(TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03))) 404 return 0; 405 406 if (event->spec_version_minor != TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MINOR_TPM2 || 407 event->spec_version_major != TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MAJOR_TPM2) 408 return 0; 409 410 count = get_unaligned_le32(&event->number_of_algorithms); 411 if (count > ARRAY_SIZE(tpm2_supported_algorithms)) 412 return 0; 413 414 calc_size = offsetof(struct tcg_efi_spec_id_event, digest_sizes) + 415 (sizeof(struct tcg_efi_spec_id_event_algorithm_size) * count) + 416 1; 417 if (evsz != calc_size) 418 return 0; 419 420 rc = tcg2_get_active_pcr_banks(dev, &active); 421 if (rc) 422 return rc; 423 424 digest_list.count = 0; 425 log_active = 0; 426 427 for (i = 0; i < count; ++i) { 428 algo = get_unaligned_le16(&event->digest_sizes[i].algorithm_id); 429 mask = tpm2_algorithm_to_mask(algo); 430 431 if (!(active & mask)) 432 return 0; 433 434 switch (algo) { 435 case TPM2_ALG_SHA1: 436 case TPM2_ALG_SHA256: 437 case TPM2_ALG_SHA384: 438 case TPM2_ALG_SHA512: 439 len = get_unaligned_le16(&event->digest_sizes[i].digest_size); 440 if (tpm2_algorithm_to_len(algo) != len) 441 return 0; 442 digest_list.digests[digest_list.count++].hash_alg = algo; 443 break; 444 default: 445 return 0; 446 } 447 448 log_active |= mask; 449 } 450 451 /* Ensure the previous firmware extended all the PCRs. */ 452 if (log_active != active) 453 return 0; 454 455 /* Read PCR0 to check if previous firmware extended the PCRs or not. */ 456 rc = tcg2_pcr_read(dev, 0, &digest_list); 457 if (rc) 458 return rc; 459 460 for (i = 0; i < digest_list.count; ++i) { 461 len = tpm2_algorithm_to_len(digest_list.digests[i].hash_alg); 462 for (j = 0; j < len; ++j) { 463 if (digest_list.digests[i].digest.sha512[j]) 464 break; 465 } 466 467 /* PCR is non-zero; it has been extended, so skip extending. */ 468 if (j != len) { 469 digest_list.count = 0; 470 break; 471 } 472 } 473 474 return tcg2_replay_eventlog(elog, dev, &digest_list, 475 offsetof(struct tcg_pcr_event, event) + 476 evsz); 477 } 478 479 int tcg2_pcr_extend(struct udevice *dev, u32 pcr_index, 480 struct tpml_digest_values *digest_list) 481 { 482 u32 rc; 483 u32 i; 484 485 for (i = 0; i < digest_list->count; i++) { 486 u32 alg = digest_list->digests[i].hash_alg; 487 488 rc = tpm2_pcr_extend(dev, pcr_index, alg, 489 (u8 *)&digest_list->digests[i].digest, 490 tpm2_algorithm_to_len(alg)); 491 if (rc) { 492 printf("%s: error pcr:%u alg:%08x\n", __func__, 493 pcr_index, alg); 494 return rc; 495 } 496 } 497 498 return 0; 499 } 500 501 int tcg2_pcr_read(struct udevice *dev, u32 pcr_index, 502 struct tpml_digest_values *digest_list) 503 { 504 struct tpm_chip_priv *priv; 505 u32 rc; 506 u32 i; 507 508 priv = dev_get_uclass_priv(dev); 509 if (!priv) 510 return -ENODEV; 511 512 for (i = 0; i < digest_list->count; i++) { 513 u32 alg = digest_list->digests[i].hash_alg; 514 u8 *digest = (u8 *)&digest_list->digests[i].digest; 515 516 rc = tpm2_pcr_read(dev, pcr_index, priv->pcr_select_min, alg, 517 digest, tpm2_algorithm_to_len(alg), NULL); 518 if (rc) { 519 printf("%s: error pcr:%u alg:%08x\n", __func__, 520 pcr_index, alg); 521 return rc; 522 } 523 } 524 525 return 0; 526 } 527 528 int tcg2_measure_data(struct udevice *dev, struct tcg2_event_log *elog, 529 u32 pcr_index, u32 size, const u8 *data, u32 event_type, 530 u32 event_size, const u8 *event) 531 { 532 struct tpml_digest_values digest_list; 533 int rc; 534 535 if (data) 536 rc = tcg2_create_digest(dev, data, size, &digest_list); 537 else 538 rc = tcg2_create_digest(dev, event, event_size, &digest_list); 539 if (rc) 540 return rc; 541 542 rc = tcg2_pcr_extend(dev, pcr_index, &digest_list); 543 if (rc) 544 return rc; 545 546 return tcg2_log_append_check(elog, pcr_index, event_type, &digest_list, 547 event_size, event); 548 } 549 550 int tcg2_log_prepare_buffer(struct udevice *dev, struct tcg2_event_log *elog, 551 bool ignore_existing_log) 552 { 553 struct tcg2_event_log log; 554 int rc; 555 556 elog->log_position = 0; 557 elog->found = false; 558 559 rc = tcg2_platform_get_log(dev, (void **)&log.log, &log.log_size); 560 if (!rc) { 561 log.log_position = 0; 562 log.found = false; 563 564 if (!ignore_existing_log) { 565 rc = tcg2_log_parse(dev, &log); 566 if (rc) 567 return rc; 568 } 569 570 if (elog->log_size) { 571 if (log.found) { 572 if (elog->log_size < log.log_position) 573 return -ENOSPC; 574 575 /* 576 * Copy the discovered log into the user buffer 577 * if there's enough space. 578 */ 579 memcpy(elog->log, log.log, log.log_position); 580 } 581 582 unmap_physmem(log.log, MAP_NOCACHE); 583 } else { 584 elog->log = log.log; 585 elog->log_size = log.log_size; 586 } 587 588 elog->log_position = log.log_position; 589 elog->found = log.found; 590 } 591 592 /* 593 * Initialize the log buffer if no log was discovered and the buffer is 594 * valid. User's can pass in their own buffer as a fallback if no 595 * memory region is found. 596 */ 597 if (!elog->found && elog->log_size) 598 rc = tcg2_log_init(dev, elog); 599 600 return rc; 601 } 602 603 int tcg2_measurement_init(struct udevice **dev, struct tcg2_event_log *elog, 604 bool ignore_existing_log) 605 { 606 int rc; 607 608 rc = tcg2_platform_get_tpm2(dev); 609 if (rc) 610 return rc; 611 612 rc = tpm_auto_start(*dev); 613 if (rc) 614 return rc; 615 616 rc = tcg2_log_prepare_buffer(*dev, elog, ignore_existing_log); 617 if (rc) { 618 tcg2_measurement_term(*dev, elog, true); 619 return rc; 620 } 621 622 rc = tcg2_measure_event(*dev, elog, 0, EV_S_CRTM_VERSION, 623 strlen(version_string) + 1, 624 (u8 *)version_string); 625 if (rc) { 626 tcg2_measurement_term(*dev, elog, true); 627 return rc; 628 } 629 630 return 0; 631 } 632 633 void tcg2_measurement_term(struct udevice *dev, struct tcg2_event_log *elog, 634 bool error) 635 { 636 u32 event = error ? 0x1 : 0xffffffff; 637 int i; 638 639 for (i = 0; i < 8; ++i) 640 tcg2_measure_event(dev, elog, i, EV_SEPARATOR, sizeof(event), 641 (const u8 *)&event); 642 643 if (elog->log) 644 unmap_physmem(elog->log, MAP_NOCACHE); 645 } 646 647 __weak int tcg2_platform_get_log(struct udevice *dev, void **addr, u32 *size) 648 { 649 const __be32 *addr_prop; 650 const __be32 *size_prop; 651 int asize; 652 int ssize; 653 654 *addr = NULL; 655 *size = 0; 656 657 addr_prop = dev_read_prop(dev, "tpm_event_log_addr", &asize); 658 if (!addr_prop) 659 addr_prop = dev_read_prop(dev, "linux,sml-base", &asize); 660 661 size_prop = dev_read_prop(dev, "tpm_event_log_size", &ssize); 662 if (!size_prop) 663 size_prop = dev_read_prop(dev, "linux,sml-size", &ssize); 664 665 if (addr_prop && size_prop) { 666 u64 a = of_read_number(addr_prop, asize / sizeof(__be32)); 667 u64 s = of_read_number(size_prop, ssize / sizeof(__be32)); 668 669 *addr = map_physmem(a, s, MAP_NOCACHE); 670 *size = (u32)s; 671 } else { 672 struct ofnode_phandle_args args; 673 phys_addr_t a; 674 phys_size_t s; 675 676 if (dev_read_phandle_with_args(dev, "memory-region", NULL, 0, 677 0, &args)) 678 return -ENODEV; 679 680 a = ofnode_get_addr_size(args.node, "reg", &s); 681 if (a == FDT_ADDR_T_NONE) 682 return -ENOMEM; 683 684 *addr = map_physmem(a, s, MAP_NOCACHE); 685 *size = (u32)s; 686 } 687 688 return 0; 689 } 690 691 __weak int tcg2_platform_get_tpm2(struct udevice **dev) 692 { 693 for_each_tpm_device(*dev) { 694 if (tpm_get_version(*dev) == TPM_V2) 695 return 0; 696 } 697 698 return -ENODEV; 699 } 700 701 __weak void tcg2_platform_startup_error(struct udevice *dev, int rc) {} 702 703 u32 tpm2_startup(struct udevice *dev, enum tpm2_startup_types mode) 704 { 705 const u8 command_v2[12] = { 706 tpm_u16(TPM2_ST_NO_SESSIONS), 707 tpm_u32(12), 708 tpm_u32(TPM2_CC_STARTUP), 709 tpm_u16(mode), 710 }; 711 int ret; 712 713 /* 714 * Note TPM2_Startup command will return RC_SUCCESS the first time, 715 * but will return RC_INITIALIZE otherwise. 716 */ 717 ret = tpm_sendrecv_command(dev, command_v2, NULL, NULL); 718 if (ret && ret != TPM2_RC_INITIALIZE) 719 return ret; 720 721 return 0; 722 } 723 724 u32 tpm2_self_test(struct udevice *dev, enum tpm2_yes_no full_test) 725 { 726 const u8 command_v2[12] = { 727 tpm_u16(TPM2_ST_NO_SESSIONS), 728 tpm_u32(11), 729 tpm_u32(TPM2_CC_SELF_TEST), 730 full_test, 731 }; 732 733 return tpm_sendrecv_command(dev, command_v2, NULL, NULL); 734 } 735 736 u32 tpm2_auto_start(struct udevice *dev) 737 { 738 u32 rc; 739 740 /* 741 * the tpm_init() will return -EBUSY if the init has already happened 742 * The selftest and startup code can run multiple times with no side 743 * effects 744 */ 745 rc = tpm_init(dev); 746 if (rc && rc != -EBUSY) 747 return rc; 748 rc = tpm2_self_test(dev, TPMI_YES); 749 750 if (rc == TPM2_RC_INITIALIZE) { 751 rc = tpm2_startup(dev, TPM2_SU_CLEAR); 752 if (rc) 753 return rc; 754 755 rc = tpm2_self_test(dev, TPMI_YES); 756 } 757 758 return rc; 759 } 760 761 u32 tpm2_clear(struct udevice *dev, u32 handle, const char *pw, 762 const ssize_t pw_sz) 763 { 764 /* Length of the message header, up to start of password */ 765 uint offset = 27; 766 u8 command_v2[COMMAND_BUFFER_SIZE] = { 767 tpm_u16(TPM2_ST_SESSIONS), /* TAG */ 768 tpm_u32(offset + pw_sz), /* Length */ 769 tpm_u32(TPM2_CC_CLEAR), /* Command code */ 770 771 /* HANDLE */ 772 tpm_u32(handle), /* TPM resource handle */ 773 774 /* AUTH_SESSION */ 775 tpm_u32(9 + pw_sz), /* Authorization size */ 776 tpm_u32(TPM2_RS_PW), /* Session handle */ 777 tpm_u16(0), /* Size of <nonce> */ 778 /* <nonce> (if any) */ 779 0, /* Attributes: Cont/Excl/Rst */ 780 tpm_u16(pw_sz), /* Size of <hmac/password> */ 781 /* STRING(pw) <hmac/password> (if any) */ 782 }; 783 int ret; 784 785 /* 786 * Fill the command structure starting from the first buffer: 787 * - the password (if any) 788 */ 789 ret = pack_byte_string(command_v2, sizeof(command_v2), "s", 790 offset, pw, pw_sz); 791 offset += pw_sz; 792 if (ret) 793 return TPM_LIB_ERROR; 794 795 return tpm_sendrecv_command(dev, command_v2, NULL, NULL); 796 } 797 798 u32 tpm2_nv_define_space(struct udevice *dev, u32 space_index, 799 size_t space_size, u32 nv_attributes, 800 const u8 *nv_policy, size_t nv_policy_size) 801 { 802 /* 803 * Calculate the offset of the nv_policy piece by adding each of the 804 * chunks below. 805 */ 806 const int platform_len = sizeof(u32); 807 const int session_hdr_len = 13; 808 const int message_len = 14; 809 uint offset = TPM2_HDR_LEN + platform_len + session_hdr_len + 810 message_len; 811 u8 command_v2[COMMAND_BUFFER_SIZE] = { 812 /* header 10 bytes */ 813 tpm_u16(TPM2_ST_SESSIONS), /* TAG */ 814 tpm_u32(offset + nv_policy_size + 2),/* Length */ 815 tpm_u32(TPM2_CC_NV_DEFINE_SPACE),/* Command code */ 816 817 /* handles 4 bytes */ 818 tpm_u32(TPM2_RH_PLATFORM), /* Primary platform seed */ 819 820 /* session header 13 bytes */ 821 tpm_u32(9), /* Header size */ 822 tpm_u32(TPM2_RS_PW), /* Password authorisation */ 823 tpm_u16(0), /* nonce_size */ 824 0, /* session_attrs */ 825 tpm_u16(0), /* auth_size */ 826 827 /* message 14 bytes + policy */ 828 tpm_u16(message_len + nv_policy_size), /* size */ 829 tpm_u32(space_index), 830 tpm_u16(TPM2_ALG_SHA256), 831 tpm_u32(nv_attributes), 832 tpm_u16(nv_policy_size), 833 /* 834 * nv_policy 835 * space_size 836 */ 837 }; 838 int ret; 839 840 /* 841 * Fill the command structure starting from the first buffer: 842 * - the password (if any) 843 */ 844 ret = pack_byte_string(command_v2, sizeof(command_v2), "sw", 845 offset, nv_policy, nv_policy_size, 846 offset + nv_policy_size, space_size); 847 if (ret) 848 return TPM_LIB_ERROR; 849 850 return tpm_sendrecv_command(dev, command_v2, NULL, NULL); 851 } 852 853 u32 tpm2_pcr_extend(struct udevice *dev, u32 index, u32 algorithm, 854 const u8 *digest, u32 digest_len) 855 { 856 /* Length of the message header, up to start of digest */ 857 uint offset = 33; 858 u8 command_v2[COMMAND_BUFFER_SIZE] = { 859 tpm_u16(TPM2_ST_SESSIONS), /* TAG */ 860 tpm_u32(offset + digest_len), /* Length */ 861 tpm_u32(TPM2_CC_PCR_EXTEND), /* Command code */ 862 863 /* HANDLE */ 864 tpm_u32(index), /* Handle (PCR Index) */ 865 866 /* AUTH_SESSION */ 867 tpm_u32(9), /* Authorization size */ 868 tpm_u32(TPM2_RS_PW), /* Session handle */ 869 tpm_u16(0), /* Size of <nonce> */ 870 /* <nonce> (if any) */ 871 0, /* Attributes: Cont/Excl/Rst */ 872 tpm_u16(0), /* Size of <hmac/password> */ 873 /* <hmac/password> (if any) */ 874 875 /* hashes */ 876 tpm_u32(1), /* Count (number of hashes) */ 877 tpm_u16(algorithm), /* Algorithm of the hash */ 878 /* STRING(digest) Digest */ 879 }; 880 int ret; 881 882 if (!digest) 883 return -EINVAL; 884 /* 885 * Fill the command structure starting from the first buffer: 886 * - the digest 887 */ 888 ret = pack_byte_string(command_v2, sizeof(command_v2), "s", 889 offset, digest, digest_len); 890 if (ret) 891 return TPM_LIB_ERROR; 892 893 return tpm_sendrecv_command(dev, command_v2, NULL, NULL); 894 } 895 896 u32 tpm2_nv_read_value(struct udevice *dev, u32 index, void *data, u32 count) 897 { 898 u8 command_v2[COMMAND_BUFFER_SIZE] = { 899 /* header 10 bytes */ 900 tpm_u16(TPM2_ST_SESSIONS), /* TAG */ 901 tpm_u32(10 + 8 + 4 + 9 + 4), /* Length */ 902 tpm_u32(TPM2_CC_NV_READ), /* Command code */ 903 904 /* handles 8 bytes */ 905 tpm_u32(TPM2_RH_PLATFORM), /* Primary platform seed */ 906 tpm_u32(HR_NV_INDEX + index), /* Password authorisation */ 907 908 /* AUTH_SESSION */ 909 tpm_u32(9), /* Authorization size */ 910 tpm_u32(TPM2_RS_PW), /* Session handle */ 911 tpm_u16(0), /* Size of <nonce> */ 912 /* <nonce> (if any) */ 913 0, /* Attributes: Cont/Excl/Rst */ 914 tpm_u16(0), /* Size of <hmac/password> */ 915 /* <hmac/password> (if any) */ 916 917 tpm_u16(count), /* Number of bytes */ 918 tpm_u16(0), /* Offset */ 919 }; 920 size_t response_len = COMMAND_BUFFER_SIZE; 921 u8 response[COMMAND_BUFFER_SIZE]; 922 int ret; 923 u16 tag; 924 u32 size, code; 925 926 ret = tpm_sendrecv_command(dev, command_v2, response, &response_len); 927 if (ret) 928 return log_msg_ret("read", ret); 929 if (unpack_byte_string(response, response_len, "wdds", 930 0, &tag, 2, &size, 6, &code, 931 16, data, count)) 932 return TPM_LIB_ERROR; 933 934 return 0; 935 } 936 937 u32 tpm2_nv_write_value(struct udevice *dev, u32 index, const void *data, 938 u32 count) 939 { 940 struct tpm_chip_priv *priv = dev_get_uclass_priv(dev); 941 uint offset = 10 + 8 + 4 + 9 + 2; 942 uint len = offset + count + 2; 943 /* Use empty password auth if platform hierarchy is disabled */ 944 u32 auth = priv->plat_hier_disabled ? HR_NV_INDEX + index : 945 TPM2_RH_PLATFORM; 946 u8 command_v2[COMMAND_BUFFER_SIZE] = { 947 /* header 10 bytes */ 948 tpm_u16(TPM2_ST_SESSIONS), /* TAG */ 949 tpm_u32(len), /* Length */ 950 tpm_u32(TPM2_CC_NV_WRITE), /* Command code */ 951 952 /* handles 8 bytes */ 953 tpm_u32(auth), /* Primary platform seed */ 954 tpm_u32(HR_NV_INDEX + index), /* Password authorisation */ 955 956 /* AUTH_SESSION */ 957 tpm_u32(9), /* Authorization size */ 958 tpm_u32(TPM2_RS_PW), /* Session handle */ 959 tpm_u16(0), /* Size of <nonce> */ 960 /* <nonce> (if any) */ 961 0, /* Attributes: Cont/Excl/Rst */ 962 tpm_u16(0), /* Size of <hmac/password> */ 963 /* <hmac/password> (if any) */ 964 965 tpm_u16(count), 966 }; 967 size_t response_len = COMMAND_BUFFER_SIZE; 968 u8 response[COMMAND_BUFFER_SIZE]; 969 int ret; 970 971 ret = pack_byte_string(command_v2, sizeof(command_v2), "sw", 972 offset, data, count, 973 offset + count, 0); 974 if (ret) 975 return TPM_LIB_ERROR; 976 977 return tpm_sendrecv_command(dev, command_v2, response, &response_len); 978 } 979 980 u32 tpm2_pcr_read(struct udevice *dev, u32 idx, unsigned int idx_min_sz, 981 u16 algorithm, void *data, u32 digest_len, 982 unsigned int *updates) 983 { 984 u8 idx_array_sz = max(idx_min_sz, DIV_ROUND_UP(idx, 8)); 985 u8 command_v2[COMMAND_BUFFER_SIZE] = { 986 tpm_u16(TPM2_ST_NO_SESSIONS), /* TAG */ 987 tpm_u32(17 + idx_array_sz), /* Length */ 988 tpm_u32(TPM2_CC_PCR_READ), /* Command code */ 989 990 /* TPML_PCR_SELECTION */ 991 tpm_u32(1), /* Number of selections */ 992 tpm_u16(algorithm), /* Algorithm of the hash */ 993 idx_array_sz, /* Array size for selection */ 994 /* bitmap(idx) Selected PCR bitmap */ 995 }; 996 size_t response_len = COMMAND_BUFFER_SIZE; 997 u8 response[COMMAND_BUFFER_SIZE]; 998 unsigned int pcr_sel_idx = idx / 8; 999 u8 pcr_sel_bit = BIT(idx % 8); 1000 unsigned int counter = 0; 1001 int ret; 1002 1003 if (pack_byte_string(command_v2, COMMAND_BUFFER_SIZE, "b", 1004 17 + pcr_sel_idx, pcr_sel_bit)) 1005 return TPM_LIB_ERROR; 1006 1007 ret = tpm_sendrecv_command(dev, command_v2, response, &response_len); 1008 if (ret) 1009 return ret; 1010 1011 if (digest_len > response_len) 1012 return TPM_LIB_ERROR; 1013 1014 if (unpack_byte_string(response, response_len, "ds", 1015 10, &counter, 1016 response_len - digest_len, data, 1017 digest_len)) 1018 return TPM_LIB_ERROR; 1019 1020 if (updates) 1021 *updates = counter; 1022 1023 return 0; 1024 } 1025 1026 u32 tpm2_get_capability(struct udevice *dev, u32 capability, u32 property, 1027 void *buf, size_t prop_count) 1028 { 1029 u8 command_v2[COMMAND_BUFFER_SIZE] = { 1030 tpm_u16(TPM2_ST_NO_SESSIONS), /* TAG */ 1031 tpm_u32(22), /* Length */ 1032 tpm_u32(TPM2_CC_GET_CAPABILITY), /* Command code */ 1033 1034 tpm_u32(capability), /* Capability */ 1035 tpm_u32(property), /* Property */ 1036 tpm_u32(prop_count), /* Property count */ 1037 }; 1038 u8 response[COMMAND_BUFFER_SIZE]; 1039 size_t response_len = COMMAND_BUFFER_SIZE; 1040 unsigned int properties_off; 1041 int ret; 1042 1043 ret = tpm_sendrecv_command(dev, command_v2, response, &response_len); 1044 if (ret) 1045 return ret; 1046 1047 /* 1048 * In the response buffer, the properties are located after the: 1049 * tag (u16), response size (u32), response code (u32), 1050 * YES/NO flag (u8), TPM_CAP (u32). 1051 */ 1052 properties_off = sizeof(u16) + sizeof(u32) + sizeof(u32) + 1053 sizeof(u8) + sizeof(u32); 1054 memcpy(buf, &response[properties_off], response_len - properties_off); 1055 1056 return 0; 1057 } 1058 1059 static int tpm2_get_num_pcr(struct udevice *dev, u32 *num_pcr) 1060 { 1061 u8 response[(sizeof(struct tpms_capability_data) - 1062 offsetof(struct tpms_capability_data, data))]; 1063 u32 properties_offset = 1064 offsetof(struct tpml_tagged_tpm_property, tpm_property) + 1065 offsetof(struct tpms_tagged_property, value); 1066 u32 ret; 1067 1068 memset(response, 0, sizeof(response)); 1069 ret = tpm2_get_capability(dev, TPM2_CAP_TPM_PROPERTIES, 1070 TPM2_PT_PCR_COUNT, response, 1); 1071 if (ret) 1072 return ret; 1073 1074 *num_pcr = get_unaligned_be32(response + properties_offset); 1075 if (*num_pcr > TPM2_MAX_PCRS) { 1076 printf("%s: too many pcrs: %u\n", __func__, *num_pcr); 1077 return -E2BIG; 1078 } 1079 1080 return 0; 1081 } 1082 1083 static bool tpm2_is_active_pcr(struct tpms_pcr_selection *selection) 1084 { 1085 int i; 1086 1087 /* 1088 * check the pcr_select. If at least one of the PCRs supports the 1089 * algorithm add it on the active ones 1090 */ 1091 for (i = 0; i < selection->size_of_select; i++) { 1092 if (selection->pcr_select[i]) 1093 return true; 1094 } 1095 1096 return false; 1097 } 1098 1099 int tpm2_get_pcr_info(struct udevice *dev, u32 *supported_pcr, u32 *active_pcr, 1100 u32 *pcr_banks) 1101 { 1102 u8 response[(sizeof(struct tpms_capability_data) - 1103 offsetof(struct tpms_capability_data, data))]; 1104 struct tpml_pcr_selection pcrs; 1105 u32 num_pcr; 1106 size_t i; 1107 u32 ret; 1108 1109 *supported_pcr = 0; 1110 *active_pcr = 0; 1111 *pcr_banks = 0; 1112 memset(response, 0, sizeof(response)); 1113 ret = tpm2_get_capability(dev, TPM2_CAP_PCRS, 0, response, 1); 1114 if (ret) 1115 return ret; 1116 1117 pcrs.count = get_unaligned_be32(response); 1118 /* 1119 * We only support 5 algorithms for now so check against that 1120 * instead of TPM2_NUM_PCR_BANKS 1121 */ 1122 if (pcrs.count > ARRAY_SIZE(tpm2_supported_algorithms) || 1123 pcrs.count < 1) { 1124 printf("%s: too many pcrs: %u\n", __func__, pcrs.count); 1125 return -EMSGSIZE; 1126 } 1127 1128 ret = tpm2_get_num_pcr(dev, &num_pcr); 1129 if (ret) 1130 return ret; 1131 1132 for (i = 0; i < pcrs.count; i++) { 1133 /* 1134 * Definition of TPMS_PCR_SELECTION Structure 1135 * hash: u16 1136 * size_of_select: u8 1137 * pcr_select: u8 array 1138 * 1139 * The offsets depend on the number of the device PCRs 1140 * so we have to calculate them based on that 1141 */ 1142 u32 hash_offset = offsetof(struct tpml_pcr_selection, selection) + 1143 i * offsetof(struct tpms_pcr_selection, pcr_select) + 1144 i * ((num_pcr + 7) / 8); 1145 u32 size_select_offset = 1146 hash_offset + offsetof(struct tpms_pcr_selection, 1147 size_of_select); 1148 u32 pcr_select_offset = 1149 hash_offset + offsetof(struct tpms_pcr_selection, 1150 pcr_select); 1151 1152 pcrs.selection[i].hash = 1153 get_unaligned_be16(response + hash_offset); 1154 pcrs.selection[i].size_of_select = 1155 __get_unaligned_be(response + size_select_offset); 1156 if (pcrs.selection[i].size_of_select > TPM2_PCR_SELECT_MAX) { 1157 printf("%s: pcrs selection too large: %u\n", __func__, 1158 pcrs.selection[i].size_of_select); 1159 return -ENOBUFS; 1160 } 1161 /* copy the array of pcr_select */ 1162 memcpy(pcrs.selection[i].pcr_select, response + pcr_select_offset, 1163 pcrs.selection[i].size_of_select); 1164 } 1165 1166 for (i = 0; i < pcrs.count; i++) { 1167 u32 hash_mask = tpm2_algorithm_to_mask(pcrs.selection[i].hash); 1168 1169 if (hash_mask) { 1170 *supported_pcr |= hash_mask; 1171 if (tpm2_is_active_pcr(&pcrs.selection[i])) 1172 *active_pcr |= hash_mask; 1173 } else { 1174 printf("%s: unknown algorithm %x\n", __func__, 1175 pcrs.selection[i].hash); 1176 } 1177 } 1178 1179 *pcr_banks = pcrs.count; 1180 1181 return 0; 1182 } 1183 1184 u32 tpm2_dam_reset(struct udevice *dev, const char *pw, const ssize_t pw_sz) 1185 { 1186 u8 command_v2[COMMAND_BUFFER_SIZE] = { 1187 tpm_u16(TPM2_ST_SESSIONS), /* TAG */ 1188 tpm_u32(27 + pw_sz), /* Length */ 1189 tpm_u32(TPM2_CC_DAM_RESET), /* Command code */ 1190 1191 /* HANDLE */ 1192 tpm_u32(TPM2_RH_LOCKOUT), /* TPM resource handle */ 1193 1194 /* AUTH_SESSION */ 1195 tpm_u32(9 + pw_sz), /* Authorization size */ 1196 tpm_u32(TPM2_RS_PW), /* Session handle */ 1197 tpm_u16(0), /* Size of <nonce> */ 1198 /* <nonce> (if any) */ 1199 0, /* Attributes: Cont/Excl/Rst */ 1200 tpm_u16(pw_sz), /* Size of <hmac/password> */ 1201 /* STRING(pw) <hmac/password> (if any) */ 1202 }; 1203 unsigned int offset = 27; 1204 int ret; 1205 1206 /* 1207 * Fill the command structure starting from the first buffer: 1208 * - the password (if any) 1209 */ 1210 ret = pack_byte_string(command_v2, sizeof(command_v2), "s", 1211 offset, pw, pw_sz); 1212 offset += pw_sz; 1213 if (ret) 1214 return TPM_LIB_ERROR; 1215 1216 return tpm_sendrecv_command(dev, command_v2, NULL, NULL); 1217 } 1218 1219 u32 tpm2_dam_parameters(struct udevice *dev, const char *pw, 1220 const ssize_t pw_sz, unsigned int max_tries, 1221 unsigned int recovery_time, 1222 unsigned int lockout_recovery) 1223 { 1224 u8 command_v2[COMMAND_BUFFER_SIZE] = { 1225 tpm_u16(TPM2_ST_SESSIONS), /* TAG */ 1226 tpm_u32(27 + pw_sz + 12), /* Length */ 1227 tpm_u32(TPM2_CC_DAM_PARAMETERS), /* Command code */ 1228 1229 /* HANDLE */ 1230 tpm_u32(TPM2_RH_LOCKOUT), /* TPM resource handle */ 1231 1232 /* AUTH_SESSION */ 1233 tpm_u32(9 + pw_sz), /* Authorization size */ 1234 tpm_u32(TPM2_RS_PW), /* Session handle */ 1235 tpm_u16(0), /* Size of <nonce> */ 1236 /* <nonce> (if any) */ 1237 0, /* Attributes: Cont/Excl/Rst */ 1238 tpm_u16(pw_sz), /* Size of <hmac/password> */ 1239 /* STRING(pw) <hmac/password> (if any) */ 1240 1241 /* LOCKOUT PARAMETERS */ 1242 /* tpm_u32(max_tries) Max tries (0, always lock) */ 1243 /* tpm_u32(recovery_time) Recovery time (0, no lock) */ 1244 /* tpm_u32(lockout_recovery) Lockout recovery */ 1245 }; 1246 unsigned int offset = 27; 1247 int ret; 1248 1249 /* 1250 * Fill the command structure starting from the first buffer: 1251 * - the password (if any) 1252 * - max tries 1253 * - recovery time 1254 * - lockout recovery 1255 */ 1256 ret = pack_byte_string(command_v2, sizeof(command_v2), "sddd", 1257 offset, pw, pw_sz, 1258 offset + pw_sz, max_tries, 1259 offset + pw_sz + 4, recovery_time, 1260 offset + pw_sz + 8, lockout_recovery); 1261 offset += pw_sz + 12; 1262 if (ret) 1263 return TPM_LIB_ERROR; 1264 1265 return tpm_sendrecv_command(dev, command_v2, NULL, NULL); 1266 } 1267 1268 int tpm2_change_auth(struct udevice *dev, u32 handle, const char *newpw, 1269 const ssize_t newpw_sz, const char *oldpw, 1270 const ssize_t oldpw_sz) 1271 { 1272 unsigned int offset = 27; 1273 u8 command_v2[COMMAND_BUFFER_SIZE] = { 1274 tpm_u16(TPM2_ST_SESSIONS), /* TAG */ 1275 tpm_u32(offset + oldpw_sz + 2 + newpw_sz), /* Length */ 1276 tpm_u32(TPM2_CC_HIERCHANGEAUTH), /* Command code */ 1277 1278 /* HANDLE */ 1279 tpm_u32(handle), /* TPM resource handle */ 1280 1281 /* AUTH_SESSION */ 1282 tpm_u32(9 + oldpw_sz), /* Authorization size */ 1283 tpm_u32(TPM2_RS_PW), /* Session handle */ 1284 tpm_u16(0), /* Size of <nonce> */ 1285 /* <nonce> (if any) */ 1286 0, /* Attributes: Cont/Excl/Rst */ 1287 tpm_u16(oldpw_sz) /* Size of <hmac/password> */ 1288 /* STRING(oldpw) <hmac/password> (if any) */ 1289 1290 /* TPM2B_AUTH (TPM2B_DIGEST) */ 1291 /* tpm_u16(newpw_sz) Digest size, new pw length */ 1292 /* STRING(newpw) Digest buffer, new pw */ 1293 }; 1294 int ret; 1295 1296 /* 1297 * Fill the command structure starting from the first buffer: 1298 * - the old password (if any) 1299 * - size of the new password 1300 * - new password 1301 */ 1302 ret = pack_byte_string(command_v2, sizeof(command_v2), "sws", 1303 offset, oldpw, oldpw_sz, 1304 offset + oldpw_sz, newpw_sz, 1305 offset + oldpw_sz + 2, newpw, newpw_sz); 1306 offset += oldpw_sz + 2 + newpw_sz; 1307 if (ret) 1308 return TPM_LIB_ERROR; 1309 1310 return tpm_sendrecv_command(dev, command_v2, NULL, NULL); 1311 } 1312 1313 u32 tpm2_pcr_setauthpolicy(struct udevice *dev, const char *pw, 1314 const ssize_t pw_sz, u32 index, const char *key) 1315 { 1316 u8 command_v2[COMMAND_BUFFER_SIZE] = { 1317 tpm_u16(TPM2_ST_SESSIONS), /* TAG */ 1318 tpm_u32(35 + pw_sz + TPM2_DIGEST_LEN), /* Length */ 1319 tpm_u32(TPM2_CC_PCR_SETAUTHPOL), /* Command code */ 1320 1321 /* HANDLE */ 1322 tpm_u32(TPM2_RH_PLATFORM), /* TPM resource handle */ 1323 1324 /* AUTH_SESSION */ 1325 tpm_u32(9 + pw_sz), /* Authorization size */ 1326 tpm_u32(TPM2_RS_PW), /* session handle */ 1327 tpm_u16(0), /* Size of <nonce> */ 1328 /* <nonce> (if any) */ 1329 0, /* Attributes: Cont/Excl/Rst */ 1330 tpm_u16(pw_sz) /* Size of <hmac/password> */ 1331 /* STRING(pw) <hmac/password> (if any) */ 1332 1333 /* TPM2B_AUTH (TPM2B_DIGEST) */ 1334 /* tpm_u16(TPM2_DIGEST_LEN) Digest size length */ 1335 /* STRING(key) Digest buffer (PCR key) */ 1336 1337 /* TPMI_ALG_HASH */ 1338 /* tpm_u16(TPM2_ALG_SHA256) Algorithm of the hash */ 1339 1340 /* TPMI_DH_PCR */ 1341 /* tpm_u32(index), PCR Index */ 1342 }; 1343 unsigned int offset = 27; 1344 int ret; 1345 1346 /* 1347 * Fill the command structure starting from the first buffer: 1348 * - the password (if any) 1349 * - the PCR key length 1350 * - the PCR key 1351 * - the hash algorithm 1352 * - the PCR index 1353 */ 1354 ret = pack_byte_string(command_v2, sizeof(command_v2), "swswd", 1355 offset, pw, pw_sz, 1356 offset + pw_sz, TPM2_DIGEST_LEN, 1357 offset + pw_sz + 2, key, TPM2_DIGEST_LEN, 1358 offset + pw_sz + 2 + TPM2_DIGEST_LEN, 1359 TPM2_ALG_SHA256, 1360 offset + pw_sz + 4 + TPM2_DIGEST_LEN, index); 1361 offset += pw_sz + 2 + TPM2_DIGEST_LEN + 2 + 4; 1362 if (ret) 1363 return TPM_LIB_ERROR; 1364 1365 return tpm_sendrecv_command(dev, command_v2, NULL, NULL); 1366 } 1367 1368 u32 tpm2_pcr_setauthvalue(struct udevice *dev, const char *pw, 1369 const ssize_t pw_sz, u32 index, const char *key, 1370 const ssize_t key_sz) 1371 { 1372 u8 command_v2[COMMAND_BUFFER_SIZE] = { 1373 tpm_u16(TPM2_ST_SESSIONS), /* TAG */ 1374 tpm_u32(33 + pw_sz + TPM2_DIGEST_LEN), /* Length */ 1375 tpm_u32(TPM2_CC_PCR_SETAUTHVAL), /* Command code */ 1376 1377 /* HANDLE */ 1378 tpm_u32(index), /* Handle (PCR Index) */ 1379 1380 /* AUTH_SESSION */ 1381 tpm_u32(9 + pw_sz), /* Authorization size */ 1382 tpm_u32(TPM2_RS_PW), /* session handle */ 1383 tpm_u16(0), /* Size of <nonce> */ 1384 /* <nonce> (if any) */ 1385 0, /* Attributes: Cont/Excl/Rst */ 1386 tpm_u16(pw_sz), /* Size of <hmac/password> */ 1387 /* STRING(pw) <hmac/password> (if any) */ 1388 1389 /* TPM2B_DIGEST */ 1390 /* tpm_u16(key_sz) Key length */ 1391 /* STRING(key) Key */ 1392 }; 1393 unsigned int offset = 27; 1394 int ret; 1395 1396 /* 1397 * Fill the command structure starting from the first buffer: 1398 * - the password (if any) 1399 * - the number of digests, 1 in our case 1400 * - the algorithm, sha256 in our case 1401 * - the digest (64 bytes) 1402 */ 1403 ret = pack_byte_string(command_v2, sizeof(command_v2), "sws", 1404 offset, pw, pw_sz, 1405 offset + pw_sz, key_sz, 1406 offset + pw_sz + 2, key, key_sz); 1407 offset += pw_sz + 2 + key_sz; 1408 if (ret) 1409 return TPM_LIB_ERROR; 1410 1411 return tpm_sendrecv_command(dev, command_v2, NULL, NULL); 1412 } 1413 1414 u32 tpm2_get_random(struct udevice *dev, void *data, u32 count) 1415 { 1416 const u8 command_v2[10] = { 1417 tpm_u16(TPM2_ST_NO_SESSIONS), 1418 tpm_u32(12), 1419 tpm_u32(TPM2_CC_GET_RANDOM), 1420 }; 1421 u8 buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE]; 1422 1423 const size_t data_size_offset = 10; 1424 const size_t data_offset = 12; 1425 size_t response_length = sizeof(response); 1426 u32 data_size; 1427 u8 *out = data; 1428 1429 while (count > 0) { 1430 u32 this_bytes = min((size_t)count, 1431 sizeof(response) - data_offset); 1432 u32 err; 1433 1434 if (pack_byte_string(buf, sizeof(buf), "sw", 1435 0, command_v2, sizeof(command_v2), 1436 sizeof(command_v2), this_bytes)) 1437 return TPM_LIB_ERROR; 1438 err = tpm_sendrecv_command(dev, buf, response, 1439 &response_length); 1440 if (err) 1441 return err; 1442 if (unpack_byte_string(response, response_length, "w", 1443 data_size_offset, &data_size)) 1444 return TPM_LIB_ERROR; 1445 if (data_size > this_bytes) 1446 return TPM_LIB_ERROR; 1447 if (unpack_byte_string(response, response_length, "s", 1448 data_offset, out, data_size)) 1449 return TPM_LIB_ERROR; 1450 1451 count -= data_size; 1452 out += data_size; 1453 } 1454 1455 return 0; 1456 } 1457 1458 u32 tpm2_write_lock(struct udevice *dev, u32 index) 1459 { 1460 u8 command_v2[COMMAND_BUFFER_SIZE] = { 1461 /* header 10 bytes */ 1462 tpm_u16(TPM2_ST_SESSIONS), /* TAG */ 1463 tpm_u32(10 + 8 + 13), /* Length */ 1464 tpm_u32(TPM2_CC_NV_WRITELOCK), /* Command code */ 1465 1466 /* handles 8 bytes */ 1467 tpm_u32(TPM2_RH_PLATFORM), /* Primary platform seed */ 1468 tpm_u32(HR_NV_INDEX + index), /* Password authorisation */ 1469 1470 /* session header 9 bytes */ 1471 tpm_u32(9), /* Header size */ 1472 tpm_u32(TPM2_RS_PW), /* Password authorisation */ 1473 tpm_u16(0), /* nonce_size */ 1474 0, /* session_attrs */ 1475 tpm_u16(0), /* auth_size */ 1476 }; 1477 1478 return tpm_sendrecv_command(dev, command_v2, NULL, NULL); 1479 } 1480 1481 u32 tpm2_disable_platform_hierarchy(struct udevice *dev) 1482 { 1483 struct tpm_chip_priv *priv = dev_get_uclass_priv(dev); 1484 u8 command_v2[COMMAND_BUFFER_SIZE] = { 1485 /* header 10 bytes */ 1486 tpm_u16(TPM2_ST_SESSIONS), /* TAG */ 1487 tpm_u32(10 + 4 + 13 + 5), /* Length */ 1488 tpm_u32(TPM2_CC_HIER_CONTROL), /* Command code */ 1489 1490 /* 4 bytes */ 1491 tpm_u32(TPM2_RH_PLATFORM), /* Primary platform seed */ 1492 1493 /* session header 9 bytes */ 1494 tpm_u32(9), /* Header size */ 1495 tpm_u32(TPM2_RS_PW), /* Password authorisation */ 1496 tpm_u16(0), /* nonce_size */ 1497 0, /* session_attrs */ 1498 tpm_u16(0), /* auth_size */ 1499 1500 /* payload 5 bytes */ 1501 tpm_u32(TPM2_RH_PLATFORM), /* Hierarchy to disable */ 1502 0, /* 0=disable */ 1503 }; 1504 int ret; 1505 1506 ret = tpm_sendrecv_command(dev, command_v2, NULL, NULL); 1507 log_info("ret=%s, %x\n", dev->name, ret); 1508 if (ret) 1509 return ret; 1510 1511 priv->plat_hier_disabled = true; 1512 1513 return 0; 1514 } 1515 1516 u32 tpm2_submit_command(struct udevice *dev, const u8 *sendbuf, 1517 u8 *recvbuf, size_t *recv_size) 1518 { 1519 return tpm_sendrecv_command(dev, sendbuf, recvbuf, recv_size); 1520 } 1521 1522 u32 tpm2_report_state(struct udevice *dev, uint vendor_cmd, uint vendor_subcmd, 1523 u8 *recvbuf, size_t *recv_size) 1524 { 1525 u8 command_v2[COMMAND_BUFFER_SIZE] = { 1526 /* header 10 bytes */ 1527 tpm_u16(TPM2_ST_NO_SESSIONS), /* TAG */ 1528 tpm_u32(10 + 2), /* Length */ 1529 tpm_u32(vendor_cmd), /* Command code */ 1530 1531 tpm_u16(vendor_subcmd), 1532 }; 1533 int ret; 1534 1535 ret = tpm_sendrecv_command(dev, command_v2, recvbuf, recv_size); 1536 log_debug("ret=%s, %x\n", dev->name, ret); 1537 if (ret) 1538 return ret; 1539 if (*recv_size < 12) 1540 return -ENODATA; 1541 *recv_size -= 12; 1542 memcpy(recvbuf, recvbuf + 12, *recv_size); 1543 1544 return 0; 1545 } 1546 1547 u32 tpm2_enable_nvcommits(struct udevice *dev, uint vendor_cmd, 1548 uint vendor_subcmd) 1549 { 1550 u8 command_v2[COMMAND_BUFFER_SIZE] = { 1551 /* header 10 bytes */ 1552 tpm_u16(TPM2_ST_NO_SESSIONS), /* TAG */ 1553 tpm_u32(10 + 2), /* Length */ 1554 tpm_u32(vendor_cmd), /* Command code */ 1555 1556 tpm_u16(vendor_subcmd), 1557 }; 1558 int ret; 1559 1560 ret = tpm_sendrecv_command(dev, command_v2, NULL, NULL); 1561 log_debug("ret=%s, %x\n", dev->name, ret); 1562 if (ret) 1563 return ret; 1564 1565 return 0; 1566 } 1567