tpm-interface.c (58472f5cd4f6ff02488c8da3cdbf719e9dd21e48) | tpm-interface.c (745b361e989af21ad40811c2586b60229f870a68) |
---|---|
1/* 2 * Copyright (C) 2004 IBM Corporation 3 * Copyright (C) 2014 Intel Corporation 4 * 5 * Authors: 6 * Leendert van Doorn <leendert@watson.ibm.com> 7 * Dave Safford <safford@watson.ibm.com> 8 * Reiner Sailer <sailer@watson.ibm.com> --- 314 unchanged lines hidden (view full) --- 323 duration = chip->duration[duration_idx]; 324 if (duration <= 0) 325 return 2 * 60 * HZ; 326 else 327 return duration; 328} 329EXPORT_SYMBOL_GPL(tpm_calc_ordinal_duration); 330 | 1/* 2 * Copyright (C) 2004 IBM Corporation 3 * Copyright (C) 2014 Intel Corporation 4 * 5 * Authors: 6 * Leendert van Doorn <leendert@watson.ibm.com> 7 * Dave Safford <safford@watson.ibm.com> 8 * Reiner Sailer <sailer@watson.ibm.com> --- 314 unchanged lines hidden (view full) --- 323 duration = chip->duration[duration_idx]; 324 if (duration <= 0) 325 return 2 * 60 * HZ; 326 else 327 return duration; 328} 329EXPORT_SYMBOL_GPL(tpm_calc_ordinal_duration); 330 |
331static bool tpm_validate_command(struct tpm_chip *chip, const u8 *cmd, | 331static bool tpm_validate_command(struct tpm_chip *chip, 332 struct tpm_space *space, 333 const u8 *cmd, |
332 size_t len) 333{ 334 const struct tpm_input_header *header = (const void *)cmd; 335 int i; 336 u32 cc; 337 u32 attrs; 338 unsigned int nr_handles; 339 340 if (len < TPM_HEADER_SIZE) 341 return false; 342 | 334 size_t len) 335{ 336 const struct tpm_input_header *header = (const void *)cmd; 337 int i; 338 u32 cc; 339 u32 attrs; 340 unsigned int nr_handles; 341 342 if (len < TPM_HEADER_SIZE) 343 return false; 344 |
345 if (!space) 346 return true; 347 |
|
343 if (chip->flags & TPM_CHIP_FLAG_TPM2 && chip->nr_commands) { 344 cc = be32_to_cpu(header->ordinal); 345 346 i = tpm2_find_cc(chip, cc); 347 if (i < 0) { 348 dev_dbg(&chip->dev, "0x%04X is an invalid command\n", 349 cc); 350 return false; --- 20 unchanged lines hidden (view full) --- 371 * @buf: TPM command buffer 372 * @bufsiz: length of the TPM command buffer 373 * @flags: tpm transmit flags - bitmap 374 * 375 * Return: 376 * 0 when the operation is successful. 377 * A negative number for system errors (errno). 378 */ | 348 if (chip->flags & TPM_CHIP_FLAG_TPM2 && chip->nr_commands) { 349 cc = be32_to_cpu(header->ordinal); 350 351 i = tpm2_find_cc(chip, cc); 352 if (i < 0) { 353 dev_dbg(&chip->dev, "0x%04X is an invalid command\n", 354 cc); 355 return false; --- 20 unchanged lines hidden (view full) --- 376 * @buf: TPM command buffer 377 * @bufsiz: length of the TPM command buffer 378 * @flags: tpm transmit flags - bitmap 379 * 380 * Return: 381 * 0 when the operation is successful. 382 * A negative number for system errors (errno). 383 */ |
379ssize_t tpm_transmit(struct tpm_chip *chip, const u8 *buf, size_t bufsiz, 380 unsigned int flags) | 384ssize_t tpm_transmit(struct tpm_chip *chip, struct tpm_space *space, 385 u8 *buf, size_t bufsiz, unsigned int flags) |
381{ | 386{ |
382 const struct tpm_output_header *header = (void *)buf; 383 ssize_t rc; | 387 struct tpm_output_header *header = (void *)buf; 388 int rc; 389 ssize_t len = 0; |
384 u32 count, ordinal; 385 unsigned long stop; 386 | 390 u32 count, ordinal; 391 unsigned long stop; 392 |
387 if (!tpm_validate_command(chip, buf, bufsiz)) | 393 if (!tpm_validate_command(chip, space, buf, bufsiz)) |
388 return -EINVAL; 389 390 if (bufsiz > TPM_BUFSIZE) 391 bufsiz = TPM_BUFSIZE; 392 393 count = be32_to_cpu(*((__be32 *) (buf + 2))); 394 ordinal = be32_to_cpu(*((__be32 *) (buf + 6))); 395 if (count == 0) --- 5 unchanged lines hidden (view full) --- 401 } 402 403 if (!(flags & TPM_TRANSMIT_UNLOCKED)) 404 mutex_lock(&chip->tpm_mutex); 405 406 if (chip->dev.parent) 407 pm_runtime_get_sync(chip->dev.parent); 408 | 394 return -EINVAL; 395 396 if (bufsiz > TPM_BUFSIZE) 397 bufsiz = TPM_BUFSIZE; 398 399 count = be32_to_cpu(*((__be32 *) (buf + 2))); 400 ordinal = be32_to_cpu(*((__be32 *) (buf + 6))); 401 if (count == 0) --- 5 unchanged lines hidden (view full) --- 407 } 408 409 if (!(flags & TPM_TRANSMIT_UNLOCKED)) 410 mutex_lock(&chip->tpm_mutex); 411 412 if (chip->dev.parent) 413 pm_runtime_get_sync(chip->dev.parent); 414 |
415 rc = tpm2_prepare_space(chip, space, ordinal, buf); 416 if (rc) 417 goto out; 418 |
|
409 rc = chip->ops->send(chip, (u8 *) buf, count); 410 if (rc < 0) { 411 dev_err(&chip->dev, | 419 rc = chip->ops->send(chip, (u8 *) buf, count); 420 if (rc < 0) { 421 dev_err(&chip->dev, |
412 "tpm_transmit: tpm_send: error %zd\n", rc); | 422 "tpm_transmit: tpm_send: error %d\n", rc); |
413 goto out; 414 } 415 416 if (chip->flags & TPM_CHIP_FLAG_IRQ) 417 goto out_recv; 418 419 if (chip->flags & TPM_CHIP_FLAG_TPM2) 420 stop = jiffies + tpm2_calc_ordinal_duration(chip, ordinal); --- 16 unchanged lines hidden (view full) --- 437 } while (time_before(jiffies, stop)); 438 439 chip->ops->cancel(chip); 440 dev_err(&chip->dev, "Operation Timed out\n"); 441 rc = -ETIME; 442 goto out; 443 444out_recv: | 423 goto out; 424 } 425 426 if (chip->flags & TPM_CHIP_FLAG_IRQ) 427 goto out_recv; 428 429 if (chip->flags & TPM_CHIP_FLAG_TPM2) 430 stop = jiffies + tpm2_calc_ordinal_duration(chip, ordinal); --- 16 unchanged lines hidden (view full) --- 447 } while (time_before(jiffies, stop)); 448 449 chip->ops->cancel(chip); 450 dev_err(&chip->dev, "Operation Timed out\n"); 451 rc = -ETIME; 452 goto out; 453 454out_recv: |
445 rc = chip->ops->recv(chip, (u8 *) buf, bufsiz); 446 if (rc < 0) { | 455 len = chip->ops->recv(chip, (u8 *) buf, bufsiz); 456 if (len < 0) { 457 rc = len; |
447 dev_err(&chip->dev, | 458 dev_err(&chip->dev, |
448 "tpm_transmit: tpm_recv: error %zd\n", rc); | 459 "tpm_transmit: tpm_recv: error %d\n", rc); |
449 goto out; | 460 goto out; |
450 } else if (rc < TPM_HEADER_SIZE) { | 461 } else if (len < TPM_HEADER_SIZE) { |
451 rc = -EFAULT; 452 goto out; 453 } 454 | 462 rc = -EFAULT; 463 goto out; 464 } 465 |
455 if (rc != be32_to_cpu(header->length)) | 466 if (len != be32_to_cpu(header->length)) { 467 rc = -EFAULT; |
456 goto out; | 468 goto out; |
469 } |
|
457 | 470 |
471 rc = tpm2_commit_space(chip, space, ordinal, buf, &len); 472 |
|
458out: 459 if (chip->dev.parent) 460 pm_runtime_put_sync(chip->dev.parent); 461 462 if (!(flags & TPM_TRANSMIT_UNLOCKED)) 463 mutex_unlock(&chip->tpm_mutex); | 473out: 474 if (chip->dev.parent) 475 pm_runtime_put_sync(chip->dev.parent); 476 477 if (!(flags & TPM_TRANSMIT_UNLOCKED)) 478 mutex_unlock(&chip->tpm_mutex); |
464 return rc; | 479 return rc ? rc : len; |
465} 466 467/** 468 * tmp_transmit_cmd - send a tpm command to the device 469 * The function extracts tpm out header return code 470 * 471 * @chip: TPM chip to use 472 * @buf: TPM command buffer 473 * @bufsiz: length of the buffer 474 * @min_rsp_body_length: minimum expected length of response body 475 * @flags: tpm transmit flags - bitmap 476 * @desc: command description used in the error message 477 * 478 * Return: 479 * 0 when the operation is successful. 480 * A negative number for system errors (errno). 481 * A positive number for a TPM error. 482 */ | 480} 481 482/** 483 * tmp_transmit_cmd - send a tpm command to the device 484 * The function extracts tpm out header return code 485 * 486 * @chip: TPM chip to use 487 * @buf: TPM command buffer 488 * @bufsiz: length of the buffer 489 * @min_rsp_body_length: minimum expected length of response body 490 * @flags: tpm transmit flags - bitmap 491 * @desc: command description used in the error message 492 * 493 * Return: 494 * 0 when the operation is successful. 495 * A negative number for system errors (errno). 496 * A positive number for a TPM error. 497 */ |
483ssize_t tpm_transmit_cmd(struct tpm_chip *chip, const void *buf, 484 size_t bufsiz, size_t min_rsp_body_length, 485 unsigned int flags, const char *desc) | 498ssize_t tpm_transmit_cmd(struct tpm_chip *chip, struct tpm_space *space, 499 const void *buf, size_t bufsiz, 500 size_t min_rsp_body_length, unsigned int flags, 501 const char *desc) |
486{ 487 const struct tpm_output_header *header = buf; 488 int err; 489 ssize_t len; 490 | 502{ 503 const struct tpm_output_header *header = buf; 504 int err; 505 ssize_t len; 506 |
491 len = tpm_transmit(chip, (const u8 *)buf, bufsiz, flags); | 507 len = tpm_transmit(chip, space, (u8 *)buf, bufsiz, flags); |
492 if (len < 0) 493 return len; 494 495 err = be32_to_cpu(header->return_code); 496 if (err != 0 && desc) 497 dev_err(&chip->dev, "A TPM error (%d) occurred %s\n", err, 498 desc); 499 if (err) --- 36 unchanged lines hidden (view full) --- 536 tpm_cmd.params.getcap_in.cap = 537 cpu_to_be32(TPM_CAP_FLAG); 538 else 539 tpm_cmd.params.getcap_in.cap = 540 cpu_to_be32(TPM_CAP_PROP); 541 tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4); 542 tpm_cmd.params.getcap_in.subcap = cpu_to_be32(subcap_id); 543 } | 508 if (len < 0) 509 return len; 510 511 err = be32_to_cpu(header->return_code); 512 if (err != 0 && desc) 513 dev_err(&chip->dev, "A TPM error (%d) occurred %s\n", err, 514 desc); 515 if (err) --- 36 unchanged lines hidden (view full) --- 552 tpm_cmd.params.getcap_in.cap = 553 cpu_to_be32(TPM_CAP_FLAG); 554 else 555 tpm_cmd.params.getcap_in.cap = 556 cpu_to_be32(TPM_CAP_PROP); 557 tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4); 558 tpm_cmd.params.getcap_in.subcap = cpu_to_be32(subcap_id); 559 } |
544 rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE, | 560 rc = tpm_transmit_cmd(chip, NULL, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE, |
545 min_cap_length, 0, desc); 546 if (!rc) 547 *cap = tpm_cmd.params.getcap_out.cap; 548 return rc; 549} 550EXPORT_SYMBOL_GPL(tpm_getcap); 551 552#define TPM_ORD_STARTUP cpu_to_be32(153) --- 7 unchanged lines hidden (view full) --- 560}; 561 562static int tpm_startup(struct tpm_chip *chip, __be16 startup_type) 563{ 564 struct tpm_cmd_t start_cmd; 565 start_cmd.header.in = tpm_startup_header; 566 567 start_cmd.params.startup_in.startup_type = startup_type; | 561 min_cap_length, 0, desc); 562 if (!rc) 563 *cap = tpm_cmd.params.getcap_out.cap; 564 return rc; 565} 566EXPORT_SYMBOL_GPL(tpm_getcap); 567 568#define TPM_ORD_STARTUP cpu_to_be32(153) --- 7 unchanged lines hidden (view full) --- 576}; 577 578static int tpm_startup(struct tpm_chip *chip, __be16 startup_type) 579{ 580 struct tpm_cmd_t start_cmd; 581 start_cmd.header.in = tpm_startup_header; 582 583 start_cmd.params.startup_in.startup_type = startup_type; |
568 return tpm_transmit_cmd(chip, &start_cmd, TPM_INTERNAL_RESULT_SIZE, 0, | 584 return tpm_transmit_cmd(chip, NULL, &start_cmd, 585 TPM_INTERNAL_RESULT_SIZE, 0, |
569 0, "attempting to start the TPM"); 570} 571 572int tpm_get_timeouts(struct tpm_chip *chip) 573{ 574 cap_t cap; 575 unsigned long timeout_old[4], timeout_chip[4], timeout_eff[4]; 576 ssize_t rc; --- 140 unchanged lines hidden (view full) --- 717 * a TPM error code. 718 */ 719static int tpm_continue_selftest(struct tpm_chip *chip) 720{ 721 int rc; 722 struct tpm_cmd_t cmd; 723 724 cmd.header.in = continue_selftest_header; | 586 0, "attempting to start the TPM"); 587} 588 589int tpm_get_timeouts(struct tpm_chip *chip) 590{ 591 cap_t cap; 592 unsigned long timeout_old[4], timeout_chip[4], timeout_eff[4]; 593 ssize_t rc; --- 140 unchanged lines hidden (view full) --- 734 * a TPM error code. 735 */ 736static int tpm_continue_selftest(struct tpm_chip *chip) 737{ 738 int rc; 739 struct tpm_cmd_t cmd; 740 741 cmd.header.in = continue_selftest_header; |
725 rc = tpm_transmit_cmd(chip, &cmd, CONTINUE_SELFTEST_RESULT_SIZE, 0, 0, 726 "continue selftest"); | 742 rc = tpm_transmit_cmd(chip, NULL, &cmd, CONTINUE_SELFTEST_RESULT_SIZE, 743 0, 0, "continue selftest"); |
727 return rc; 728} 729 730#define TPM_ORDINAL_PCRREAD cpu_to_be32(21) 731#define READ_PCR_RESULT_SIZE 30 732#define READ_PCR_RESULT_BODY_SIZE 20 733static const struct tpm_input_header pcrread_header = { 734 .tag = TPM_TAG_RQU_COMMAND, 735 .length = cpu_to_be32(14), 736 .ordinal = TPM_ORDINAL_PCRREAD 737}; 738 739int tpm_pcr_read_dev(struct tpm_chip *chip, int pcr_idx, u8 *res_buf) 740{ 741 int rc; 742 struct tpm_cmd_t cmd; 743 744 cmd.header.in = pcrread_header; 745 cmd.params.pcrread_in.pcr_idx = cpu_to_be32(pcr_idx); | 744 return rc; 745} 746 747#define TPM_ORDINAL_PCRREAD cpu_to_be32(21) 748#define READ_PCR_RESULT_SIZE 30 749#define READ_PCR_RESULT_BODY_SIZE 20 750static const struct tpm_input_header pcrread_header = { 751 .tag = TPM_TAG_RQU_COMMAND, 752 .length = cpu_to_be32(14), 753 .ordinal = TPM_ORDINAL_PCRREAD 754}; 755 756int tpm_pcr_read_dev(struct tpm_chip *chip, int pcr_idx, u8 *res_buf) 757{ 758 int rc; 759 struct tpm_cmd_t cmd; 760 761 cmd.header.in = pcrread_header; 762 cmd.params.pcrread_in.pcr_idx = cpu_to_be32(pcr_idx); |
746 rc = tpm_transmit_cmd(chip, &cmd, READ_PCR_RESULT_SIZE, | 763 rc = tpm_transmit_cmd(chip, NULL, &cmd, READ_PCR_RESULT_SIZE, |
747 READ_PCR_RESULT_BODY_SIZE, 0, 748 "attempting to read a pcr value"); 749 750 if (rc == 0) 751 memcpy(res_buf, cmd.params.pcrread_out.pcr_result, 752 TPM_DIGEST_SIZE); 753 return rc; 754} --- 95 unchanged lines hidden (view full) --- 850 rc = tpm2_pcr_extend(chip, pcr_idx, count, digest_list); 851 tpm_put_ops(chip); 852 return rc; 853 } 854 855 cmd.header.in = pcrextend_header; 856 cmd.params.pcrextend_in.pcr_idx = cpu_to_be32(pcr_idx); 857 memcpy(cmd.params.pcrextend_in.hash, hash, TPM_DIGEST_SIZE); | 764 READ_PCR_RESULT_BODY_SIZE, 0, 765 "attempting to read a pcr value"); 766 767 if (rc == 0) 768 memcpy(res_buf, cmd.params.pcrread_out.pcr_result, 769 TPM_DIGEST_SIZE); 770 return rc; 771} --- 95 unchanged lines hidden (view full) --- 867 rc = tpm2_pcr_extend(chip, pcr_idx, count, digest_list); 868 tpm_put_ops(chip); 869 return rc; 870 } 871 872 cmd.header.in = pcrextend_header; 873 cmd.params.pcrextend_in.pcr_idx = cpu_to_be32(pcr_idx); 874 memcpy(cmd.params.pcrextend_in.hash, hash, TPM_DIGEST_SIZE); |
858 rc = tpm_transmit_cmd(chip, &cmd, EXTEND_PCR_RESULT_SIZE, | 875 rc = tpm_transmit_cmd(chip, NULL, &cmd, EXTEND_PCR_RESULT_SIZE, |
859 EXTEND_PCR_RESULT_BODY_SIZE, 0, 860 "attempting extend a PCR value"); 861 862 tpm_put_ops(chip); 863 return rc; 864} 865EXPORT_SYMBOL_GPL(tpm_pcr_extend); 866 --- 88 unchanged lines hidden (view full) --- 955{ 956 struct tpm_chip *chip; 957 int rc; 958 959 chip = tpm_chip_find_get(chip_num); 960 if (chip == NULL) 961 return -ENODEV; 962 | 876 EXTEND_PCR_RESULT_BODY_SIZE, 0, 877 "attempting extend a PCR value"); 878 879 tpm_put_ops(chip); 880 return rc; 881} 882EXPORT_SYMBOL_GPL(tpm_pcr_extend); 883 --- 88 unchanged lines hidden (view full) --- 972{ 973 struct tpm_chip *chip; 974 int rc; 975 976 chip = tpm_chip_find_get(chip_num); 977 if (chip == NULL) 978 return -ENODEV; 979 |
963 rc = tpm_transmit_cmd(chip, cmd, buflen, 0, 0, "attempting tpm_cmd"); 964 | 980 rc = tpm_transmit_cmd(chip, NULL, cmd, buflen, 0, 0, 981 "attempting tpm_cmd"); |
965 tpm_put_ops(chip); 966 return rc; 967} 968EXPORT_SYMBOL_GPL(tpm_send); 969 970static bool wait_for_tpm_stat_cond(struct tpm_chip *chip, u8 mask, 971 bool check_cancel, bool *canceled) 972{ --- 84 unchanged lines hidden (view full) --- 1057 } 1058 1059 /* for buggy tpm, flush pcrs with extend to selected dummy */ 1060 if (tpm_suspend_pcr) { 1061 cmd.header.in = pcrextend_header; 1062 cmd.params.pcrextend_in.pcr_idx = cpu_to_be32(tpm_suspend_pcr); 1063 memcpy(cmd.params.pcrextend_in.hash, dummy_hash, 1064 TPM_DIGEST_SIZE); | 982 tpm_put_ops(chip); 983 return rc; 984} 985EXPORT_SYMBOL_GPL(tpm_send); 986 987static bool wait_for_tpm_stat_cond(struct tpm_chip *chip, u8 mask, 988 bool check_cancel, bool *canceled) 989{ --- 84 unchanged lines hidden (view full) --- 1074 } 1075 1076 /* for buggy tpm, flush pcrs with extend to selected dummy */ 1077 if (tpm_suspend_pcr) { 1078 cmd.header.in = pcrextend_header; 1079 cmd.params.pcrextend_in.pcr_idx = cpu_to_be32(tpm_suspend_pcr); 1080 memcpy(cmd.params.pcrextend_in.hash, dummy_hash, 1081 TPM_DIGEST_SIZE); |
1065 rc = tpm_transmit_cmd(chip, &cmd, EXTEND_PCR_RESULT_SIZE, 1066 EXTEND_PCR_RESULT_BODY_SIZE, 0, | 1082 rc = tpm_transmit_cmd(chip, NULL, &cmd, EXTEND_PCR_RESULT_SIZE, 1083 EXTEND_PCR_RESULT_BODY_SIZE, 0, |
1067 "extending dummy pcr before suspend"); 1068 } 1069 1070 /* now do the actual savestate */ 1071 for (try = 0; try < TPM_RETRY; try++) { 1072 cmd.header.in = savestate_header; | 1084 "extending dummy pcr before suspend"); 1085 } 1086 1087 /* now do the actual savestate */ 1088 for (try = 0; try < TPM_RETRY; try++) { 1089 cmd.header.in = savestate_header; |
1073 rc = tpm_transmit_cmd(chip, &cmd, SAVESTATE_RESULT_SIZE, 0, 1074 0, NULL); | 1090 rc = tpm_transmit_cmd(chip, NULL, &cmd, SAVESTATE_RESULT_SIZE, 1091 0, 0, NULL); |
1075 1076 /* 1077 * If the TPM indicates that it is too busy to respond to 1078 * this command then retry before giving up. It can take 1079 * several seconds for this TPM to be ready. 1080 * 1081 * This can happen if the TPM has already been sent the 1082 * SaveState command before the driver has loaded. TCG 1.2 --- 66 unchanged lines hidden (view full) --- 1149 tpm_put_ops(chip); 1150 return err; 1151 } 1152 1153 do { 1154 tpm_cmd.header.in = tpm_getrandom_header; 1155 tpm_cmd.params.getrandom_in.num_bytes = cpu_to_be32(num_bytes); 1156 | 1092 1093 /* 1094 * If the TPM indicates that it is too busy to respond to 1095 * this command then retry before giving up. It can take 1096 * several seconds for this TPM to be ready. 1097 * 1098 * This can happen if the TPM has already been sent the 1099 * SaveState command before the driver has loaded. TCG 1.2 --- 66 unchanged lines hidden (view full) --- 1166 tpm_put_ops(chip); 1167 return err; 1168 } 1169 1170 do { 1171 tpm_cmd.header.in = tpm_getrandom_header; 1172 tpm_cmd.params.getrandom_in.num_bytes = cpu_to_be32(num_bytes); 1173 |
1157 err = tpm_transmit_cmd(chip, &tpm_cmd, | 1174 err = tpm_transmit_cmd(chip, NULL, &tpm_cmd, |
1158 TPM_GETRANDOM_RESULT_SIZE + num_bytes, 1159 offsetof(struct tpm_getrandom_out, 1160 rng_data), 1161 0, "attempting get random"); 1162 if (err) 1163 break; 1164 1165 recd = be32_to_cpu(tpm_cmd.params.getrandom_out.rng_data_len); --- 106 unchanged lines hidden --- | 1175 TPM_GETRANDOM_RESULT_SIZE + num_bytes, 1176 offsetof(struct tpm_getrandom_out, 1177 rng_data), 1178 0, "attempting get random"); 1179 if (err) 1180 break; 1181 1182 recd = be32_to_cpu(tpm_cmd.params.getrandom_out.rng_data_len); --- 106 unchanged lines hidden --- |