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