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