aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJarkko Sakkinen2016-08-16 14:00:38 -0500
committerGreg Kroah-Hartman2016-10-16 10:36:15 -0500
commitc0201ae6796a830fa7eb0cb537239102bedcbcc5 (patch)
tree6fa9c6ca61906a98a7e42d5e8eabeac1f7ce7c6f
parent0040b7466cbd6d7a7f84d0eed86e328da21c0e27 (diff)
downloadgraphics-kernel-feature-tree-c0201ae6796a830fa7eb0cb537239102bedcbcc5.tar.gz
graphics-kernel-feature-tree-c0201ae6796a830fa7eb0cb537239102bedcbcc5.tar.xz
graphics-kernel-feature-tree-c0201ae6796a830fa7eb0cb537239102bedcbcc5.zip
tpm: fix a race condition in tpm2_unseal_trusted()
commit d4816edfe706497a8525480c1685ceb9871bc118 upstream. Unseal and load operations should be done as an atomic operation. This commit introduces unlocked tpm_transmit() so that tpm2_unseal_trusted() can do the locking by itself. Fixes: 0fe5480303a1 ("keys, trusted: seal/unseal with TPM 2.0 chips") Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Reviewed-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/char/tpm/tpm-dev.c2
-rw-r--r--drivers/char/tpm/tpm-interface.c51
-rw-r--r--drivers/char/tpm/tpm-sysfs.c2
-rw-r--r--drivers/char/tpm/tpm.h12
-rw-r--r--drivers/char/tpm/tpm2-cmd.c101
5 files changed, 103 insertions, 65 deletions
diff --git a/drivers/char/tpm/tpm-dev.c b/drivers/char/tpm/tpm-dev.c
index de0337ebd658..4f3137d9a35e 100644
--- a/drivers/char/tpm/tpm-dev.c
+++ b/drivers/char/tpm/tpm-dev.c
@@ -139,7 +139,7 @@ static ssize_t tpm_write(struct file *file, const char __user *buf,
139 139
140 /* atomic tpm command send and result receive */ 140 /* atomic tpm command send and result receive */
141 out_size = tpm_transmit(priv->chip, priv->data_buffer, 141 out_size = tpm_transmit(priv->chip, priv->data_buffer,
142 sizeof(priv->data_buffer)); 142 sizeof(priv->data_buffer), 0);
143 if (out_size < 0) { 143 if (out_size < 0) {
144 mutex_unlock(&priv->buffer_mutex); 144 mutex_unlock(&priv->buffer_mutex);
145 return out_size; 145 return out_size;
diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
index c50637db3a8a..17abe52e6365 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -328,8 +328,8 @@ EXPORT_SYMBOL_GPL(tpm_calc_ordinal_duration);
328/* 328/*
329 * Internal kernel interface to transmit TPM commands 329 * Internal kernel interface to transmit TPM commands
330 */ 330 */
331ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf, 331ssize_t tpm_transmit(struct tpm_chip *chip, const u8 *buf, size_t bufsiz,
332 size_t bufsiz) 332 unsigned int flags)
333{ 333{
334 ssize_t rc; 334 ssize_t rc;
335 u32 count, ordinal; 335 u32 count, ordinal;
@@ -348,7 +348,8 @@ ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
348 return -E2BIG; 348 return -E2BIG;
349 } 349 }
350 350
351 mutex_lock(&chip->tpm_mutex); 351 if (!(flags & TPM_TRANSMIT_UNLOCKED))
352 mutex_lock(&chip->tpm_mutex);
352 353
353 rc = chip->ops->send(chip, (u8 *) buf, count); 354 rc = chip->ops->send(chip, (u8 *) buf, count);
354 if (rc < 0) { 355 if (rc < 0) {
@@ -391,20 +392,21 @@ out_recv:
391 dev_err(chip->pdev, 392 dev_err(chip->pdev,
392 "tpm_transmit: tpm_recv: error %zd\n", rc); 393 "tpm_transmit: tpm_recv: error %zd\n", rc);
393out: 394out:
394 mutex_unlock(&chip->tpm_mutex); 395 if (!(flags & TPM_TRANSMIT_UNLOCKED))
396 mutex_unlock(&chip->tpm_mutex);
395 return rc; 397 return rc;
396} 398}
397 399
398#define TPM_DIGEST_SIZE 20 400#define TPM_DIGEST_SIZE 20
399#define TPM_RET_CODE_IDX 6 401#define TPM_RET_CODE_IDX 6
400 402
401ssize_t tpm_transmit_cmd(struct tpm_chip *chip, void *cmd, 403ssize_t tpm_transmit_cmd(struct tpm_chip *chip, const void *cmd,
402 int len, const char *desc) 404 int len, unsigned int flags, const char *desc)
403{ 405{
404 struct tpm_output_header *header; 406 const struct tpm_output_header *header;
405 int err; 407 int err;
406 408
407 len = tpm_transmit(chip, (u8 *) cmd, len); 409 len = tpm_transmit(chip, (const u8 *)cmd, len, flags);
408 if (len < 0) 410 if (len < 0)
409 return len; 411 return len;
410 else if (len < TPM_HEADER_SIZE) 412 else if (len < TPM_HEADER_SIZE)
@@ -452,7 +454,8 @@ ssize_t tpm_getcap(struct device *dev, __be32 subcap_id, cap_t *cap,
452 tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4); 454 tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4);
453 tpm_cmd.params.getcap_in.subcap = subcap_id; 455 tpm_cmd.params.getcap_in.subcap = subcap_id;
454 } 456 }
455 rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE, desc); 457 rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE, 0,
458 desc);
456 if (!rc) 459 if (!rc)
457 *cap = tpm_cmd.params.getcap_out.cap; 460 *cap = tpm_cmd.params.getcap_out.cap;
458 return rc; 461 return rc;
@@ -468,7 +471,7 @@ void tpm_gen_interrupt(struct tpm_chip *chip)
468 tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4); 471 tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4);
469 tpm_cmd.params.getcap_in.subcap = TPM_CAP_PROP_TIS_TIMEOUT; 472 tpm_cmd.params.getcap_in.subcap = TPM_CAP_PROP_TIS_TIMEOUT;
470 473
471 rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE, 474 rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE, 0,
472 "attempting to determine the timeouts"); 475 "attempting to determine the timeouts");
473} 476}
474EXPORT_SYMBOL_GPL(tpm_gen_interrupt); 477EXPORT_SYMBOL_GPL(tpm_gen_interrupt);
@@ -489,7 +492,7 @@ static int tpm_startup(struct tpm_chip *chip, __be16 startup_type)
489 start_cmd.header.in = tpm_startup_header; 492 start_cmd.header.in = tpm_startup_header;
490 493
491 start_cmd.params.startup_in.startup_type = startup_type; 494 start_cmd.params.startup_in.startup_type = startup_type;
492 return tpm_transmit_cmd(chip, &start_cmd, TPM_INTERNAL_RESULT_SIZE, 495 return tpm_transmit_cmd(chip, &start_cmd, TPM_INTERNAL_RESULT_SIZE, 0,
493 "attempting to start the TPM"); 496 "attempting to start the TPM");
494} 497}
495 498
@@ -505,7 +508,8 @@ int tpm_get_timeouts(struct tpm_chip *chip)
505 tpm_cmd.params.getcap_in.cap = TPM_CAP_PROP; 508 tpm_cmd.params.getcap_in.cap = TPM_CAP_PROP;
506 tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4); 509 tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4);
507 tpm_cmd.params.getcap_in.subcap = TPM_CAP_PROP_TIS_TIMEOUT; 510 tpm_cmd.params.getcap_in.subcap = TPM_CAP_PROP_TIS_TIMEOUT;
508 rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE, NULL); 511 rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE, 0,
512 NULL);
509 513
510 if (rc == TPM_ERR_INVALID_POSTINIT) { 514 if (rc == TPM_ERR_INVALID_POSTINIT) {
511 /* The TPM is not started, we are the first to talk to it. 515 /* The TPM is not started, we are the first to talk to it.
@@ -519,7 +523,7 @@ int tpm_get_timeouts(struct tpm_chip *chip)
519 tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4); 523 tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4);
520 tpm_cmd.params.getcap_in.subcap = TPM_CAP_PROP_TIS_TIMEOUT; 524 tpm_cmd.params.getcap_in.subcap = TPM_CAP_PROP_TIS_TIMEOUT;
521 rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE, 525 rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE,
522 NULL); 526 0, NULL);
523 } 527 }
524 if (rc) { 528 if (rc) {
525 dev_err(chip->pdev, 529 dev_err(chip->pdev,
@@ -580,7 +584,7 @@ duration:
580 tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4); 584 tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4);
581 tpm_cmd.params.getcap_in.subcap = TPM_CAP_PROP_TIS_DURATION; 585 tpm_cmd.params.getcap_in.subcap = TPM_CAP_PROP_TIS_DURATION;
582 586
583 rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE, 587 rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE, 0,
584 "attempting to determine the durations"); 588 "attempting to determine the durations");
585 if (rc) 589 if (rc)
586 return rc; 590 return rc;
@@ -636,7 +640,7 @@ static int tpm_continue_selftest(struct tpm_chip *chip)
636 struct tpm_cmd_t cmd; 640 struct tpm_cmd_t cmd;
637 641
638 cmd.header.in = continue_selftest_header; 642 cmd.header.in = continue_selftest_header;
639 rc = tpm_transmit_cmd(chip, &cmd, CONTINUE_SELFTEST_RESULT_SIZE, 643 rc = tpm_transmit_cmd(chip, &cmd, CONTINUE_SELFTEST_RESULT_SIZE, 0,
640 "continue selftest"); 644 "continue selftest");
641 return rc; 645 return rc;
642} 646}
@@ -656,7 +660,7 @@ int tpm_pcr_read_dev(struct tpm_chip *chip, int pcr_idx, u8 *res_buf)
656 660
657 cmd.header.in = pcrread_header; 661 cmd.header.in = pcrread_header;
658 cmd.params.pcrread_in.pcr_idx = cpu_to_be32(pcr_idx); 662 cmd.params.pcrread_in.pcr_idx = cpu_to_be32(pcr_idx);
659 rc = tpm_transmit_cmd(chip, &cmd, READ_PCR_RESULT_SIZE, 663 rc = tpm_transmit_cmd(chip, &cmd, READ_PCR_RESULT_SIZE, 0,
660 "attempting to read a pcr value"); 664 "attempting to read a pcr value");
661 665
662 if (rc == 0) 666 if (rc == 0)
@@ -754,7 +758,7 @@ int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash)
754 cmd.header.in = pcrextend_header; 758 cmd.header.in = pcrextend_header;
755 cmd.params.pcrextend_in.pcr_idx = cpu_to_be32(pcr_idx); 759 cmd.params.pcrextend_in.pcr_idx = cpu_to_be32(pcr_idx);
756 memcpy(cmd.params.pcrextend_in.hash, hash, TPM_DIGEST_SIZE); 760 memcpy(cmd.params.pcrextend_in.hash, hash, TPM_DIGEST_SIZE);
757 rc = tpm_transmit_cmd(chip, &cmd, EXTEND_PCR_RESULT_SIZE, 761 rc = tpm_transmit_cmd(chip, &cmd, EXTEND_PCR_RESULT_SIZE, 0,
758 "attempting extend a PCR value"); 762 "attempting extend a PCR value");
759 763
760 tpm_chip_put(chip); 764 tpm_chip_put(chip);
@@ -793,7 +797,7 @@ int tpm_do_selftest(struct tpm_chip *chip)
793 /* Attempt to read a PCR value */ 797 /* Attempt to read a PCR value */
794 cmd.header.in = pcrread_header; 798 cmd.header.in = pcrread_header;
795 cmd.params.pcrread_in.pcr_idx = cpu_to_be32(0); 799 cmd.params.pcrread_in.pcr_idx = cpu_to_be32(0);
796 rc = tpm_transmit(chip, (u8 *) &cmd, READ_PCR_RESULT_SIZE); 800 rc = tpm_transmit(chip, (u8 *) &cmd, READ_PCR_RESULT_SIZE, 0);
797 /* Some buggy TPMs will not respond to tpm_tis_ready() for 801 /* Some buggy TPMs will not respond to tpm_tis_ready() for
798 * around 300ms while the self test is ongoing, keep trying 802 * around 300ms while the self test is ongoing, keep trying
799 * until the self test duration expires. */ 803 * until the self test duration expires. */
@@ -834,7 +838,7 @@ int tpm_send(u32 chip_num, void *cmd, size_t buflen)
834 if (chip == NULL) 838 if (chip == NULL)
835 return -ENODEV; 839 return -ENODEV;
836 840
837 rc = tpm_transmit_cmd(chip, cmd, buflen, "attempting tpm_cmd"); 841 rc = tpm_transmit_cmd(chip, cmd, buflen, 0, "attempting tpm_cmd");
838 842
839 tpm_chip_put(chip); 843 tpm_chip_put(chip);
840 return rc; 844 return rc;
@@ -936,14 +940,15 @@ int tpm_pm_suspend(struct device *dev)
936 cmd.params.pcrextend_in.pcr_idx = cpu_to_be32(tpm_suspend_pcr); 940 cmd.params.pcrextend_in.pcr_idx = cpu_to_be32(tpm_suspend_pcr);
937 memcpy(cmd.params.pcrextend_in.hash, dummy_hash, 941 memcpy(cmd.params.pcrextend_in.hash, dummy_hash,
938 TPM_DIGEST_SIZE); 942 TPM_DIGEST_SIZE);
939 rc = tpm_transmit_cmd(chip, &cmd, EXTEND_PCR_RESULT_SIZE, 943 rc = tpm_transmit_cmd(chip, &cmd, EXTEND_PCR_RESULT_SIZE, 0,
940 "extending dummy pcr before suspend"); 944 "extending dummy pcr before suspend");
941 } 945 }
942 946
943 /* now do the actual savestate */ 947 /* now do the actual savestate */
944 for (try = 0; try < TPM_RETRY; try++) { 948 for (try = 0; try < TPM_RETRY; try++) {
945 cmd.header.in = savestate_header; 949 cmd.header.in = savestate_header;
946 rc = tpm_transmit_cmd(chip, &cmd, SAVESTATE_RESULT_SIZE, NULL); 950 rc = tpm_transmit_cmd(chip, &cmd, SAVESTATE_RESULT_SIZE, 0,
951 NULL);
947 952
948 /* 953 /*
949 * If the TPM indicates that it is too busy to respond to 954 * If the TPM indicates that it is too busy to respond to
@@ -1027,8 +1032,8 @@ int tpm_get_random(u32 chip_num, u8 *out, size_t max)
1027 tpm_cmd.params.getrandom_in.num_bytes = cpu_to_be32(num_bytes); 1032 tpm_cmd.params.getrandom_in.num_bytes = cpu_to_be32(num_bytes);
1028 1033
1029 err = tpm_transmit_cmd(chip, &tpm_cmd, 1034 err = tpm_transmit_cmd(chip, &tpm_cmd,
1030 TPM_GETRANDOM_RESULT_SIZE + num_bytes, 1035 TPM_GETRANDOM_RESULT_SIZE + num_bytes,
1031 "attempting get random"); 1036 0, "attempting get random");
1032 if (err) 1037 if (err)
1033 break; 1038 break;
1034 1039
diff --git a/drivers/char/tpm/tpm-sysfs.c b/drivers/char/tpm/tpm-sysfs.c
index ee66fd4673f3..f880856aa75e 100644
--- a/drivers/char/tpm/tpm-sysfs.c
+++ b/drivers/char/tpm/tpm-sysfs.c
@@ -39,7 +39,7 @@ static ssize_t pubek_show(struct device *dev, struct device_attribute *attr,
39 struct tpm_chip *chip = dev_get_drvdata(dev); 39 struct tpm_chip *chip = dev_get_drvdata(dev);
40 40
41 tpm_cmd.header.in = tpm_readpubek_header; 41 tpm_cmd.header.in = tpm_readpubek_header;
42 err = tpm_transmit_cmd(chip, &tpm_cmd, READ_PUBEK_RESULT_SIZE, 42 err = tpm_transmit_cmd(chip, &tpm_cmd, READ_PUBEK_RESULT_SIZE, 0,
43 "attempting to read the PUBEK"); 43 "attempting to read the PUBEK");
44 if (err) 44 if (err)
45 goto out; 45 goto out;
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index a4257a32964f..2216861f89f1 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -498,11 +498,15 @@ extern struct class *tpm_class;
498extern dev_t tpm_devt; 498extern dev_t tpm_devt;
499extern const struct file_operations tpm_fops; 499extern const struct file_operations tpm_fops;
500 500
501enum tpm_transmit_flags {
502 TPM_TRANSMIT_UNLOCKED = BIT(0),
503};
504
505ssize_t tpm_transmit(struct tpm_chip *chip, const u8 *buf, size_t bufsiz,
506 unsigned int flags);
507ssize_t tpm_transmit_cmd(struct tpm_chip *chip, const void *cmd, int len,
508 unsigned int flags, const char *desc);
501ssize_t tpm_getcap(struct device *, __be32, cap_t *, const char *); 509ssize_t tpm_getcap(struct device *, __be32, cap_t *, const char *);
502ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
503 size_t bufsiz);
504ssize_t tpm_transmit_cmd(struct tpm_chip *chip, void *cmd, int len,
505 const char *desc);
506extern int tpm_get_timeouts(struct tpm_chip *); 510extern int tpm_get_timeouts(struct tpm_chip *);
507extern void tpm_gen_interrupt(struct tpm_chip *); 511extern void tpm_gen_interrupt(struct tpm_chip *);
508extern int tpm_do_selftest(struct tpm_chip *); 512extern int tpm_do_selftest(struct tpm_chip *);
diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
index 678af51fb29e..cb7e4f6b70ba 100644
--- a/drivers/char/tpm/tpm2-cmd.c
+++ b/drivers/char/tpm/tpm2-cmd.c
@@ -264,7 +264,7 @@ int tpm2_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf)
264 sizeof(cmd.params.pcrread_in.pcr_select)); 264 sizeof(cmd.params.pcrread_in.pcr_select));
265 cmd.params.pcrread_in.pcr_select[pcr_idx >> 3] = 1 << (pcr_idx & 0x7); 265 cmd.params.pcrread_in.pcr_select[pcr_idx >> 3] = 1 << (pcr_idx & 0x7);
266 266
267 rc = tpm_transmit_cmd(chip, &cmd, sizeof(cmd), 267 rc = tpm_transmit_cmd(chip, &cmd, sizeof(cmd), 0,
268 "attempting to read a pcr value"); 268 "attempting to read a pcr value");
269 if (rc == 0) { 269 if (rc == 0) {
270 buf = cmd.params.pcrread_out.digest; 270 buf = cmd.params.pcrread_out.digest;
@@ -312,7 +312,7 @@ int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx, const u8 *hash)
312 cmd.params.pcrextend_in.hash_alg = cpu_to_be16(TPM2_ALG_SHA1); 312 cmd.params.pcrextend_in.hash_alg = cpu_to_be16(TPM2_ALG_SHA1);
313 memcpy(cmd.params.pcrextend_in.digest, hash, TPM_DIGEST_SIZE); 313 memcpy(cmd.params.pcrextend_in.digest, hash, TPM_DIGEST_SIZE);
314 314
315 rc = tpm_transmit_cmd(chip, &cmd, sizeof(cmd), 315 rc = tpm_transmit_cmd(chip, &cmd, sizeof(cmd), 0,
316 "attempting extend a PCR value"); 316 "attempting extend a PCR value");
317 317
318 return rc; 318 return rc;
@@ -358,7 +358,7 @@ int tpm2_get_random(struct tpm_chip *chip, u8 *out, size_t max)
358 cmd.header.in = tpm2_getrandom_header; 358 cmd.header.in = tpm2_getrandom_header;
359 cmd.params.getrandom_in.size = cpu_to_be16(num_bytes); 359 cmd.params.getrandom_in.size = cpu_to_be16(num_bytes);
360 360
361 err = tpm_transmit_cmd(chip, &cmd, sizeof(cmd), 361 err = tpm_transmit_cmd(chip, &cmd, sizeof(cmd), 0,
362 "attempting get random"); 362 "attempting get random");
363 if (err) 363 if (err)
364 break; 364 break;
@@ -416,12 +416,12 @@ static void tpm2_buf_append_auth(struct tpm_buf *buf, u32 session_handle,
416} 416}
417 417
418/** 418/**
419 * tpm2_seal_trusted() - seal a trusted key 419 * tpm2_seal_trusted() - seal the payload of a trusted key
420 * @chip_num: A specific chip number for the request or TPM_ANY_NUM 420 * @chip_num: TPM chip to use
421 * @options: authentication values and other options
422 * @payload: the key data in clear and encrypted form 421 * @payload: the key data in clear and encrypted form
422 * @options: authentication values and other options
423 * 423 *
424 * Returns < 0 on error and 0 on success. 424 * Return: < 0 on error and 0 on success.
425 */ 425 */
426int tpm2_seal_trusted(struct tpm_chip *chip, 426int tpm2_seal_trusted(struct tpm_chip *chip,
427 struct trusted_key_payload *payload, 427 struct trusted_key_payload *payload,
@@ -472,7 +472,7 @@ int tpm2_seal_trusted(struct tpm_chip *chip,
472 goto out; 472 goto out;
473 } 473 }
474 474
475 rc = tpm_transmit_cmd(chip, buf.data, PAGE_SIZE, "sealing data"); 475 rc = tpm_transmit_cmd(chip, buf.data, PAGE_SIZE, 0, "sealing data");
476 if (rc) 476 if (rc)
477 goto out; 477 goto out;
478 478
@@ -494,10 +494,18 @@ out:
494 return rc; 494 return rc;
495} 495}
496 496
497static int tpm2_load(struct tpm_chip *chip, 497/**
498 struct trusted_key_payload *payload, 498 * tpm2_load_cmd() - execute a TPM2_Load command
499 struct trusted_key_options *options, 499 * @chip_num: TPM chip to use
500 u32 *blob_handle) 500 * @payload: the key data in clear and encrypted form
501 * @options: authentication values and other options
502 *
503 * Return: same as with tpm_transmit_cmd
504 */
505static int tpm2_load_cmd(struct tpm_chip *chip,
506 struct trusted_key_payload *payload,
507 struct trusted_key_options *options,
508 u32 *blob_handle, unsigned int flags)
501{ 509{
502 struct tpm_buf buf; 510 struct tpm_buf buf;
503 unsigned int private_len; 511 unsigned int private_len;
@@ -532,7 +540,7 @@ static int tpm2_load(struct tpm_chip *chip,
532 goto out; 540 goto out;
533 } 541 }
534 542
535 rc = tpm_transmit_cmd(chip, buf.data, PAGE_SIZE, "loading blob"); 543 rc = tpm_transmit_cmd(chip, buf.data, PAGE_SIZE, flags, "loading blob");
536 if (!rc) 544 if (!rc)
537 *blob_handle = be32_to_cpup( 545 *blob_handle = be32_to_cpup(
538 (__be32 *) &buf.data[TPM_HEADER_SIZE]); 546 (__be32 *) &buf.data[TPM_HEADER_SIZE]);
@@ -546,7 +554,16 @@ out:
546 return rc; 554 return rc;
547} 555}
548 556
549static void tpm2_flush_context(struct tpm_chip *chip, u32 handle) 557/**
558 * tpm2_flush_context_cmd() - execute a TPM2_FlushContext command
559 * @chip_num: TPM chip to use
560 * @payload: the key data in clear and encrypted form
561 * @options: authentication values and other options
562 *
563 * Return: same as with tpm_transmit_cmd
564 */
565static void tpm2_flush_context_cmd(struct tpm_chip *chip, u32 handle,
566 unsigned int flags)
550{ 567{
551 struct tpm_buf buf; 568 struct tpm_buf buf;
552 int rc; 569 int rc;
@@ -560,7 +577,8 @@ static void tpm2_flush_context(struct tpm_chip *chip, u32 handle)
560 577
561 tpm_buf_append_u32(&buf, handle); 578 tpm_buf_append_u32(&buf, handle);
562 579
563 rc = tpm_transmit_cmd(chip, buf.data, PAGE_SIZE, "flushing context"); 580 rc = tpm_transmit_cmd(chip, buf.data, PAGE_SIZE, flags,
581 "flushing context");
564 if (rc) 582 if (rc)
565 dev_warn(chip->pdev, "0x%08x was not flushed, rc=%d\n", handle, 583 dev_warn(chip->pdev, "0x%08x was not flushed, rc=%d\n", handle,
566 rc); 584 rc);
@@ -568,10 +586,18 @@ static void tpm2_flush_context(struct tpm_chip *chip, u32 handle)
568 tpm_buf_destroy(&buf); 586 tpm_buf_destroy(&buf);
569} 587}
570 588
571static int tpm2_unseal(struct tpm_chip *chip, 589/**
572 struct trusted_key_payload *payload, 590 * tpm2_unseal_cmd() - execute a TPM2_Unload command
573 struct trusted_key_options *options, 591 * @chip_num: TPM chip to use
574 u32 blob_handle) 592 * @payload: the key data in clear and encrypted form
593 * @options: authentication values and other options
594 *
595 * Return: same as with tpm_transmit_cmd
596 */
597static int tpm2_unseal_cmd(struct tpm_chip *chip,
598 struct trusted_key_payload *payload,
599 struct trusted_key_options *options,
600 u32 blob_handle, unsigned int flags)
575{ 601{
576 struct tpm_buf buf; 602 struct tpm_buf buf;
577 u16 data_len; 603 u16 data_len;
@@ -589,7 +615,7 @@ static int tpm2_unseal(struct tpm_chip *chip,
589 options->blobauth /* hmac */, 615 options->blobauth /* hmac */,
590 TPM_DIGEST_SIZE); 616 TPM_DIGEST_SIZE);
591 617
592 rc = tpm_transmit_cmd(chip, buf.data, PAGE_SIZE, "unsealing"); 618 rc = tpm_transmit_cmd(chip, buf.data, PAGE_SIZE, flags, "unsealing");
593 if (rc > 0) 619 if (rc > 0)
594 rc = -EPERM; 620 rc = -EPERM;
595 621
@@ -608,12 +634,12 @@ static int tpm2_unseal(struct tpm_chip *chip,
608} 634}
609 635
610/** 636/**
611 * tpm_unseal_trusted() - unseal a trusted key 637 * tpm_unseal_trusted() - unseal the payload of a trusted key
612 * @chip_num: A specific chip number for the request or TPM_ANY_NUM 638 * @chip_num: TPM chip to use
613 * @options: authentication values and other options
614 * @payload: the key data in clear and encrypted form 639 * @payload: the key data in clear and encrypted form
640 * @options: authentication values and other options
615 * 641 *
616 * Returns < 0 on error and 0 on success. 642 * Return: < 0 on error and 0 on success.
617 */ 643 */
618int tpm2_unseal_trusted(struct tpm_chip *chip, 644int tpm2_unseal_trusted(struct tpm_chip *chip,
619 struct trusted_key_payload *payload, 645 struct trusted_key_payload *payload,
@@ -622,14 +648,17 @@ int tpm2_unseal_trusted(struct tpm_chip *chip,
622 u32 blob_handle; 648 u32 blob_handle;
623 int rc; 649 int rc;
624 650
625 rc = tpm2_load(chip, payload, options, &blob_handle); 651 mutex_lock(&chip->tpm_mutex);
652 rc = tpm2_load_cmd(chip, payload, options, &blob_handle,
653 TPM_TRANSMIT_UNLOCKED);
626 if (rc) 654 if (rc)
627 return rc; 655 goto out;
628
629 rc = tpm2_unseal(chip, payload, options, blob_handle);
630
631 tpm2_flush_context(chip, blob_handle);
632 656
657 rc = tpm2_unseal_cmd(chip, payload, options, blob_handle,
658 TPM_TRANSMIT_UNLOCKED);
659 tpm2_flush_context_cmd(chip, blob_handle, TPM_TRANSMIT_UNLOCKED);
660out:
661 mutex_unlock(&chip->tpm_mutex);
633 return rc; 662 return rc;
634} 663}
635 664
@@ -655,7 +684,7 @@ ssize_t tpm2_get_tpm_pt(struct tpm_chip *chip, u32 property_id, u32 *value,
655 cmd.params.get_tpm_pt_in.property_id = cpu_to_be32(property_id); 684 cmd.params.get_tpm_pt_in.property_id = cpu_to_be32(property_id);
656 cmd.params.get_tpm_pt_in.property_cnt = cpu_to_be32(1); 685 cmd.params.get_tpm_pt_in.property_cnt = cpu_to_be32(1);
657 686
658 rc = tpm_transmit_cmd(chip, &cmd, sizeof(cmd), desc); 687 rc = tpm_transmit_cmd(chip, &cmd, sizeof(cmd), 0, desc);
659 if (!rc) 688 if (!rc)
660 *value = be32_to_cpu(cmd.params.get_tpm_pt_out.value); 689 *value = be32_to_cpu(cmd.params.get_tpm_pt_out.value);
661 690
@@ -689,7 +718,7 @@ int tpm2_startup(struct tpm_chip *chip, u16 startup_type)
689 cmd.header.in = tpm2_startup_header; 718 cmd.header.in = tpm2_startup_header;
690 719
691 cmd.params.startup_in.startup_type = cpu_to_be16(startup_type); 720 cmd.params.startup_in.startup_type = cpu_to_be16(startup_type);
692 return tpm_transmit_cmd(chip, &cmd, sizeof(cmd), 721 return tpm_transmit_cmd(chip, &cmd, sizeof(cmd), 0,
693 "attempting to start the TPM"); 722 "attempting to start the TPM");
694} 723}
695EXPORT_SYMBOL_GPL(tpm2_startup); 724EXPORT_SYMBOL_GPL(tpm2_startup);
@@ -718,7 +747,7 @@ void tpm2_shutdown(struct tpm_chip *chip, u16 shutdown_type)
718 cmd.header.in = tpm2_shutdown_header; 747 cmd.header.in = tpm2_shutdown_header;
719 cmd.params.startup_in.startup_type = cpu_to_be16(shutdown_type); 748 cmd.params.startup_in.startup_type = cpu_to_be16(shutdown_type);
720 749
721 rc = tpm_transmit_cmd(chip, &cmd, sizeof(cmd), "stopping the TPM"); 750 rc = tpm_transmit_cmd(chip, &cmd, sizeof(cmd), 0, "stopping the TPM");
722 751
723 /* In places where shutdown command is sent there's no much we can do 752 /* In places where shutdown command is sent there's no much we can do
724 * except print the error code on a system failure. 753 * except print the error code on a system failure.
@@ -784,7 +813,7 @@ static int tpm2_start_selftest(struct tpm_chip *chip, bool full)
784 cmd.header.in = tpm2_selftest_header; 813 cmd.header.in = tpm2_selftest_header;
785 cmd.params.selftest_in.full_test = full; 814 cmd.params.selftest_in.full_test = full;
786 815
787 rc = tpm_transmit_cmd(chip, &cmd, TPM2_SELF_TEST_IN_SIZE, 816 rc = tpm_transmit_cmd(chip, &cmd, TPM2_SELF_TEST_IN_SIZE, 0,
788 "continue selftest"); 817 "continue selftest");
789 818
790 /* At least some prototype chips seem to give RC_TESTING error 819 /* At least some prototype chips seem to give RC_TESTING error
@@ -836,7 +865,7 @@ int tpm2_do_selftest(struct tpm_chip *chip)
836 cmd.params.pcrread_in.pcr_select[1] = 0x00; 865 cmd.params.pcrread_in.pcr_select[1] = 0x00;
837 cmd.params.pcrread_in.pcr_select[2] = 0x00; 866 cmd.params.pcrread_in.pcr_select[2] = 0x00;
838 867
839 rc = tpm_transmit_cmd(chip, (u8 *) &cmd, sizeof(cmd), NULL); 868 rc = tpm_transmit_cmd(chip, &cmd, sizeof(cmd), 0, NULL);
840 if (rc < 0) 869 if (rc < 0)
841 break; 870 break;
842 871
@@ -885,7 +914,7 @@ int tpm2_probe(struct tpm_chip *chip)
885 cmd.params.get_tpm_pt_in.property_id = cpu_to_be32(0x100); 914 cmd.params.get_tpm_pt_in.property_id = cpu_to_be32(0x100);
886 cmd.params.get_tpm_pt_in.property_cnt = cpu_to_be32(1); 915 cmd.params.get_tpm_pt_in.property_cnt = cpu_to_be32(1);
887 916
888 rc = tpm_transmit(chip, (const char *) &cmd, sizeof(cmd)); 917 rc = tpm_transmit(chip, (const u8 *)&cmd, sizeof(cmd), 0);
889 if (rc < 0) 918 if (rc < 0)
890 return rc; 919 return rc;
891 else if (rc < TPM_HEADER_SIZE) 920 else if (rc < TPM_HEADER_SIZE)