Keyrings Archive on lore.kernel.org
 help / color / Atom feed
* [PATCH v4 1/3] KEYS: trusted: Fix incorrect handling of tpm_get_random()
       [not found] <20201013025156.111305-1-jarkko.sakkinen@linux.intel.com>
@ 2020-10-13  2:51 ` Jarkko Sakkinen
  2020-10-13  2:51 ` [PATCH v4 2/3] KEYS: trusted: Fix migratable=1 failing Jarkko Sakkinen
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Jarkko Sakkinen @ 2020-10-13  2:51 UTC (permalink / raw)
  To: linux-integrity
  Cc: David Howells, Mimi Zohar, James Bottomley, Jarkko Sakkinen,
	stable, James E.J. Bottomley, Kent Yoder, James Morris,
	Serge E. Hallyn, H. Peter Anvin, David Safford,
	open list:KEYS-TRUSTED, open list:SECURITY SUBSYSTEM, open list

When tpm_get_random() was introduced, it defined the following API for the
return value:

1. A positive value tells how many bytes of random data was generated.
2. A negative value on error.

However, in the call sites the API was used incorrectly, i.e. as it would
only return negative values and otherwise zero. Returning he positive read
counts to the user space does not make any possible sense.

Fix this by returning -EIO when tpm_get_random() returns a positive value.

Fixes: 41ab999c80f1 ("tpm: Move tpm_get_random api into the TPM device driver")
Cc: stable@vger.kernel.org
Cc: Mimi Zohar <zohar@linux.ibm.com>
Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
Cc: David Howells <dhowells@redhat.com>
Cc: Kent Yoder <key@linux.vnet.ibm.com>
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
---
 security/keys/trusted-keys/trusted_tpm1.c | 20 +++++++++++++++++---
 1 file changed, 17 insertions(+), 3 deletions(-)

diff --git a/security/keys/trusted-keys/trusted_tpm1.c b/security/keys/trusted-keys/trusted_tpm1.c
index b9fe02e5f84f..c7b1701cdac5 100644
--- a/security/keys/trusted-keys/trusted_tpm1.c
+++ b/security/keys/trusted-keys/trusted_tpm1.c
@@ -403,9 +403,12 @@ static int osap(struct tpm_buf *tb, struct osapsess *s,
 	int ret;
 
 	ret = tpm_get_random(chip, ononce, TPM_NONCE_SIZE);
-	if (ret != TPM_NONCE_SIZE)
+	if (ret < 0)
 		return ret;
 
+	if (ret != TPM_NONCE_SIZE)
+		return -EIO;
+
 	tpm_buf_reset(tb, TPM_TAG_RQU_COMMAND, TPM_ORD_OSAP);
 	tpm_buf_append_u16(tb, type);
 	tpm_buf_append_u32(tb, handle);
@@ -496,8 +499,12 @@ static int tpm_seal(struct tpm_buf *tb, uint16_t keytype,
 		goto out;
 
 	ret = tpm_get_random(chip, td->nonceodd, TPM_NONCE_SIZE);
+	if (ret < 0)
+		return ret;
+
 	if (ret != TPM_NONCE_SIZE)
-		goto out;
+		return -EIO;
+
 	ordinal = htonl(TPM_ORD_SEAL);
 	datsize = htonl(datalen);
 	pcrsize = htonl(pcrinfosize);
@@ -601,9 +608,12 @@ static int tpm_unseal(struct tpm_buf *tb,
 
 	ordinal = htonl(TPM_ORD_UNSEAL);
 	ret = tpm_get_random(chip, nonceodd, TPM_NONCE_SIZE);
+	if (ret < 0)
+		return ret;
+
 	if (ret != TPM_NONCE_SIZE) {
 		pr_info("trusted_key: tpm_get_random failed (%d)\n", ret);
-		return ret;
+		return -EIO;
 	}
 	ret = TSS_authhmac(authdata1, keyauth, TPM_NONCE_SIZE,
 			   enonce1, nonceodd, cont, sizeof(uint32_t),
@@ -1013,8 +1023,12 @@ static int trusted_instantiate(struct key *key,
 	case Opt_new:
 		key_len = payload->key_len;
 		ret = tpm_get_random(chip, payload->key, key_len);
+		if (ret < 0)
+			goto out;
+
 		if (ret != key_len) {
 			pr_info("trusted_key: key_create failed (%d)\n", ret);
+			ret = -EIO;
 			goto out;
 		}
 		if (tpm2)
-- 
2.25.1

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v4 2/3] KEYS: trusted: Fix migratable=1 failing
       [not found] <20201013025156.111305-1-jarkko.sakkinen@linux.intel.com>
  2020-10-13  2:51 ` [PATCH v4 1/3] KEYS: trusted: Fix incorrect handling of tpm_get_random() Jarkko Sakkinen
@ 2020-10-13  2:51 ` Jarkko Sakkinen
  2020-10-13  2:51 ` [PATCH v4 3/3] KEYS: trusted: Reserve TPM for seal and unseal operations Jarkko Sakkinen
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Jarkko Sakkinen @ 2020-10-13  2:51 UTC (permalink / raw)
  To: linux-integrity
  Cc: David Howells, Mimi Zohar, James Bottomley, Jarkko Sakkinen,
	stable, James Morris, Serge E. Hallyn, David Safford,
	open list:KEYS-TRUSTED, open list:SECURITY SUBSYSTEM, open list

Consider the following transcript:

$ keyctl add trusted kmk "new 32 blobauth=helloworld keyhandle€000000 migratable=1" @u
add_key: Invalid argument

The documentation has the following description:

  migratable=   0|1 indicating permission to reseal to new PCR values,
                default 1 (resealing allowed)

The consequence is that "migratable=1" should succeed. Fix this by
allowing this condition to pass instead of return -EINVAL.

[*] Documentation/security/keys/trusted-encrypted.rst

Cc: stable@vger.kernel.org
Cc: "James E.J. Bottomley" <jejb@linux.ibm.com>
Cc: Mimi Zohar <zohar@linux.ibm.com>
Cc: David Howells <dhowells@redhat.com>
Fixes: d00a1c72f7f4 ("keys: add new trusted key-type")
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
---
 security/keys/trusted-keys/trusted_tpm1.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/security/keys/trusted-keys/trusted_tpm1.c b/security/keys/trusted-keys/trusted_tpm1.c
index c7b1701cdac5..7a937c3c5283 100644
--- a/security/keys/trusted-keys/trusted_tpm1.c
+++ b/security/keys/trusted-keys/trusted_tpm1.c
@@ -801,7 +801,7 @@ static int getoptions(char *c, struct trusted_key_payload *pay,
 		case Opt_migratable:
 			if (*args[0].from = '0')
 				pay->migratable = 0;
-			else
+			else if (*args[0].from != '1')
 				return -EINVAL;
 			break;
 		case Opt_pcrlock:
-- 
2.25.1

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v4 3/3] KEYS: trusted: Reserve TPM for seal and unseal operations
       [not found] <20201013025156.111305-1-jarkko.sakkinen@linux.intel.com>
  2020-10-13  2:51 ` [PATCH v4 1/3] KEYS: trusted: Fix incorrect handling of tpm_get_random() Jarkko Sakkinen
  2020-10-13  2:51 ` [PATCH v4 2/3] KEYS: trusted: Fix migratable=1 failing Jarkko Sakkinen
@ 2020-10-13  2:51 ` Jarkko Sakkinen
  2020-10-30  8:52 ` [PATCH v4 1/3,RESEND] KEYS: trusted: Fix incorrect handling of tpm_get_random() Jarkko Sakkinen
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Jarkko Sakkinen @ 2020-10-13  2:51 UTC (permalink / raw)
  To: linux-integrity
  Cc: David Howells, Mimi Zohar, James Bottomley, Jarkko Sakkinen,
	James E.J. Bottomley, stable, Sumit Garg, kernel test robot,
	Peter Huewe, Jason Gunthorpe, Arnd Bergmann, Greg Kroah-Hartman,
	James Morris, Serge E. Hallyn, Jerry Snitselaar, Alexey Klimov,
	open list, open list:KEYS-TRUSTED, open list:SECURITY SUBSYSTEM

When TPM 2.0 trusted keys code was moved to the trusted keys subsystem,
the operations were unwrapped from tpm_try_get_ops() and tpm_put_ops(),
which are used to take temporarily the ownership of the TPM chip. The
ownership is only taken inside tpm_send(), but this is not sufficient,
as in the key load TPM2_CC_LOAD, TPM2_CC_UNSEAL and TPM2_FLUSH_CONTEXT
need to be done as a one single atom.

Fix this issue by introducting trusted_tpm_load() and trusted_tpm_new(),
which wrap these operations, and take the TPM chip ownership before
sending anything. Use tpm_transmit_cmd() to send TPM commands instead
of tpm_send(), reverting back to the old behaviour.

Fixes: 2e19e10131a0 ("KEYS: trusted: Move TPM2 trusted keys code")
Reported-by: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
Cc: stable@vger.kernel.org
Cc: David Howells <dhowells@redhat.com>
Cc: Mimi Zohar <zohar@linux.ibm.com>
Cc: Sumit Garg <sumit.garg@linaro.org>
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Reported-by: kernel test robot <lkp@intel.com>
---
 drivers/char/tpm/tpm.h                    |  4 --
 include/linux/tpm.h                       |  5 +-
 security/keys/trusted-keys/trusted_tpm1.c | 78 +++++++++++++++--------
 security/keys/trusted-keys/trusted_tpm2.c |  6 +-
 4 files changed, 60 insertions(+), 33 deletions(-)

diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 947d1db0a5cc..283f78211c3a 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -164,8 +164,6 @@ extern const struct file_operations tpmrm_fops;
 extern struct idr dev_nums_idr;
 
 ssize_t tpm_transmit(struct tpm_chip *chip, u8 *buf, size_t bufsiz);
-ssize_t tpm_transmit_cmd(struct tpm_chip *chip, struct tpm_buf *buf,
-			 size_t min_rsp_body_length, const char *desc);
 int tpm_get_timeouts(struct tpm_chip *);
 int tpm_auto_startup(struct tpm_chip *chip);
 
@@ -194,8 +192,6 @@ static inline void tpm_msleep(unsigned int delay_msec)
 int tpm_chip_start(struct tpm_chip *chip);
 void tpm_chip_stop(struct tpm_chip *chip);
 struct tpm_chip *tpm_find_get_ops(struct tpm_chip *chip);
-__must_check int tpm_try_get_ops(struct tpm_chip *chip);
-void tpm_put_ops(struct tpm_chip *chip);
 
 struct tpm_chip *tpm_chip_alloc(struct device *dev,
 				const struct tpm_class_ops *ops);
diff --git a/include/linux/tpm.h b/include/linux/tpm.h
index 8f4ff39f51e7..804a3f69bbd9 100644
--- a/include/linux/tpm.h
+++ b/include/linux/tpm.h
@@ -397,6 +397,10 @@ static inline u32 tpm2_rc_value(u32 rc)
 #if defined(CONFIG_TCG_TPM) || defined(CONFIG_TCG_TPM_MODULE)
 
 extern int tpm_is_tpm2(struct tpm_chip *chip);
+extern __must_check int tpm_try_get_ops(struct tpm_chip *chip);
+extern void tpm_put_ops(struct tpm_chip *chip);
+extern ssize_t tpm_transmit_cmd(struct tpm_chip *chip, struct tpm_buf *buf,
+				size_t min_rsp_body_length, const char *desc);
 extern int tpm_pcr_read(struct tpm_chip *chip, u32 pcr_idx,
 			struct tpm_digest *digest);
 extern int tpm_pcr_extend(struct tpm_chip *chip, u32 pcr_idx,
@@ -410,7 +414,6 @@ static inline int tpm_is_tpm2(struct tpm_chip *chip)
 {
 	return -ENODEV;
 }
-
 static inline int tpm_pcr_read(struct tpm_chip *chip, int pcr_idx,
 			       struct tpm_digest *digest)
 {
diff --git a/security/keys/trusted-keys/trusted_tpm1.c b/security/keys/trusted-keys/trusted_tpm1.c
index 7a937c3c5283..20ca18e17437 100644
--- a/security/keys/trusted-keys/trusted_tpm1.c
+++ b/security/keys/trusted-keys/trusted_tpm1.c
@@ -950,6 +950,51 @@ static struct trusted_key_payload *trusted_payload_alloc(struct key *key)
 	return p;
 }
 
+static int trusted_tpm_load(struct tpm_chip *chip,
+			    struct trusted_key_payload *payload,
+			    struct trusted_key_options *options)
+{
+	int ret;
+
+	if (tpm_is_tpm2(chip)) {
+		ret = tpm_try_get_ops(chip);
+		if (!ret) {
+			ret = tpm2_unseal_trusted(chip, payload, options);
+			tpm_put_ops(chip);
+		}
+	} else {
+		ret = key_unseal(payload, options);
+	}
+
+	return ret;
+}
+
+static int trusted_tpm_new(struct tpm_chip *chip,
+			   struct trusted_key_payload *payload,
+			   struct trusted_key_options *options)
+{
+	int ret;
+
+	ret = tpm_get_random(chip, payload->key, payload->key_len);
+	if (ret < 0)
+		return ret;
+
+	if (ret != payload->key_len)
+		return -EIO;
+
+	if (tpm_is_tpm2(chip)) {
+		ret = tpm_try_get_ops(chip);
+		if (!ret) {
+			ret = tpm2_seal_trusted(chip, payload, options);
+			tpm_put_ops(chip);
+		}
+	} else {
+		ret = key_seal(payload, options);
+	}
+
+	return ret;
+}
+
 /*
  * trusted_instantiate - create a new trusted key
  *
@@ -968,12 +1013,6 @@ static int trusted_instantiate(struct key *key,
 	char *datablob;
 	int ret = 0;
 	int key_cmd;
-	size_t key_len;
-	int tpm2;
-
-	tpm2 = tpm_is_tpm2(chip);
-	if (tpm2 < 0)
-		return tpm2;
 
 	if (datalen <= 0 || datalen > 32767 || !prep->data)
 		return -EINVAL;
@@ -1011,32 +1050,21 @@ static int trusted_instantiate(struct key *key,
 
 	switch (key_cmd) {
 	case Opt_load:
-		if (tpm2)
-			ret = tpm2_unseal_trusted(chip, payload, options);
-		else
-			ret = key_unseal(payload, options);
+		ret = trusted_tpm_load(chip, payload, options);
+
 		dump_payload(payload);
 		dump_options(options);
+
 		if (ret < 0)
-			pr_info("trusted_key: key_unseal failed (%d)\n", ret);
+			pr_info("%s: load failed (%d)\n", __func__, ret);
+
 		break;
 	case Opt_new:
-		key_len = payload->key_len;
-		ret = tpm_get_random(chip, payload->key, key_len);
-		if (ret < 0)
-			goto out;
+		ret = trusted_tpm_new(chip, payload, options);
 
-		if (ret != key_len) {
-			pr_info("trusted_key: key_create failed (%d)\n", ret);
-			ret = -EIO;
-			goto out;
-		}
-		if (tpm2)
-			ret = tpm2_seal_trusted(chip, payload, options);
-		else
-			ret = key_seal(payload, options);
 		if (ret < 0)
-			pr_info("trusted_key: key_seal failed (%d)\n", ret);
+			pr_info("%s: new failed (%d)\n", __func__, ret);
+
 		break;
 	default:
 		ret = -EINVAL;
diff --git a/security/keys/trusted-keys/trusted_tpm2.c b/security/keys/trusted-keys/trusted_tpm2.c
index 08ec7f48f01d..effdb67fac6d 100644
--- a/security/keys/trusted-keys/trusted_tpm2.c
+++ b/security/keys/trusted-keys/trusted_tpm2.c
@@ -130,7 +130,7 @@ int tpm2_seal_trusted(struct tpm_chip *chip,
 		goto out;
 	}
 
-	rc = tpm_send(chip, buf.data, tpm_buf_length(&buf));
+	rc = tpm_transmit_cmd(chip, &buf, 4, "sealing data");
 	if (rc)
 		goto out;
 
@@ -211,7 +211,7 @@ static int tpm2_load_cmd(struct tpm_chip *chip,
 		goto out;
 	}
 
-	rc = tpm_send(chip, buf.data, tpm_buf_length(&buf));
+	rc = tpm_transmit_cmd(chip, &buf, 4, "loading blob");
 	if (!rc)
 		*blob_handle = be32_to_cpup(
 			(__be32 *) &buf.data[TPM_HEADER_SIZE]);
@@ -260,7 +260,7 @@ static int tpm2_unseal_cmd(struct tpm_chip *chip,
 			     options->blobauth /* hmac */,
 			     TPM_DIGEST_SIZE);
 
-	rc = tpm_send(chip, buf.data, tpm_buf_length(&buf));
+	rc = tpm_transmit_cmd(chip, &buf, 6, "unsealing");
 	if (rc > 0)
 		rc = -EPERM;
 
-- 
2.25.1

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v4 1/3,RESEND] KEYS: trusted: Fix incorrect handling of tpm_get_random()
       [not found] <20201013025156.111305-1-jarkko.sakkinen@linux.intel.com>
                   ` (2 preceding siblings ...)
  2020-10-13  2:51 ` [PATCH v4 3/3] KEYS: trusted: Reserve TPM for seal and unseal operations Jarkko Sakkinen
@ 2020-10-30  8:52 ` Jarkko Sakkinen
  2020-10-30  8:52 ` [PATCH v4 2/3,RESEND] KEYS: trusted: Fix migratable=1 failing Jarkko Sakkinen
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Jarkko Sakkinen @ 2020-10-30  8:52 UTC (permalink / raw)
  To: linux-integrity
  Cc: David Howells, Mimi Zohar, James Bottomley, Jarkko Sakkinen,
	stable, James E.J. Bottomley, Kent Yoder, James Morris,
	Serge E. Hallyn, H. Peter Anvin, David Safford,
	open list:KEYS-TRUSTED, open list:SECURITY SUBSYSTEM, open list

When tpm_get_random() was introduced, it defined the following API for the
return value:

1. A positive value tells how many bytes of random data was generated.
2. A negative value on error.

However, in the call sites the API was used incorrectly, i.e. as it would
only return negative values and otherwise zero. Returning he positive read
counts to the user space does not make any possible sense.

Fix this by returning -EIO when tpm_get_random() returns a positive value.

Fixes: 41ab999c80f1 ("tpm: Move tpm_get_random api into the TPM device driver")
Cc: stable@vger.kernel.org
Cc: Mimi Zohar <zohar@linux.ibm.com>
Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
Cc: David Howells <dhowells@redhat.com>
Cc: Kent Yoder <key@linux.vnet.ibm.com>
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
---
 security/keys/trusted-keys/trusted_tpm1.c | 20 +++++++++++++++++---
 1 file changed, 17 insertions(+), 3 deletions(-)

diff --git a/security/keys/trusted-keys/trusted_tpm1.c b/security/keys/trusted-keys/trusted_tpm1.c
index b9fe02e5f84f..c7b1701cdac5 100644
--- a/security/keys/trusted-keys/trusted_tpm1.c
+++ b/security/keys/trusted-keys/trusted_tpm1.c
@@ -403,9 +403,12 @@ static int osap(struct tpm_buf *tb, struct osapsess *s,
 	int ret;
 
 	ret = tpm_get_random(chip, ononce, TPM_NONCE_SIZE);
-	if (ret != TPM_NONCE_SIZE)
+	if (ret < 0)
 		return ret;
 
+	if (ret != TPM_NONCE_SIZE)
+		return -EIO;
+
 	tpm_buf_reset(tb, TPM_TAG_RQU_COMMAND, TPM_ORD_OSAP);
 	tpm_buf_append_u16(tb, type);
 	tpm_buf_append_u32(tb, handle);
@@ -496,8 +499,12 @@ static int tpm_seal(struct tpm_buf *tb, uint16_t keytype,
 		goto out;
 
 	ret = tpm_get_random(chip, td->nonceodd, TPM_NONCE_SIZE);
+	if (ret < 0)
+		return ret;
+
 	if (ret != TPM_NONCE_SIZE)
-		goto out;
+		return -EIO;
+
 	ordinal = htonl(TPM_ORD_SEAL);
 	datsize = htonl(datalen);
 	pcrsize = htonl(pcrinfosize);
@@ -601,9 +608,12 @@ static int tpm_unseal(struct tpm_buf *tb,
 
 	ordinal = htonl(TPM_ORD_UNSEAL);
 	ret = tpm_get_random(chip, nonceodd, TPM_NONCE_SIZE);
+	if (ret < 0)
+		return ret;
+
 	if (ret != TPM_NONCE_SIZE) {
 		pr_info("trusted_key: tpm_get_random failed (%d)\n", ret);
-		return ret;
+		return -EIO;
 	}
 	ret = TSS_authhmac(authdata1, keyauth, TPM_NONCE_SIZE,
 			   enonce1, nonceodd, cont, sizeof(uint32_t),
@@ -1013,8 +1023,12 @@ static int trusted_instantiate(struct key *key,
 	case Opt_new:
 		key_len = payload->key_len;
 		ret = tpm_get_random(chip, payload->key, key_len);
+		if (ret < 0)
+			goto out;
+
 		if (ret != key_len) {
 			pr_info("trusted_key: key_create failed (%d)\n", ret);
+			ret = -EIO;
 			goto out;
 		}
 		if (tpm2)
-- 
2.25.1


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v4 2/3,RESEND] KEYS: trusted: Fix migratable=1 failing
       [not found] <20201013025156.111305-1-jarkko.sakkinen@linux.intel.com>
                   ` (3 preceding siblings ...)
  2020-10-30  8:52 ` [PATCH v4 1/3,RESEND] KEYS: trusted: Fix incorrect handling of tpm_get_random() Jarkko Sakkinen
@ 2020-10-30  8:52 ` Jarkko Sakkinen
  2020-10-30  8:52 ` [PATCH v4 3/3,RESEND] KEYS: trusted: Reserve TPM for seal and unseal operations Jarkko Sakkinen
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Jarkko Sakkinen @ 2020-10-30  8:52 UTC (permalink / raw)
  To: linux-integrity
  Cc: David Howells, Mimi Zohar, James Bottomley, Jarkko Sakkinen,
	stable, James Morris, Serge E. Hallyn, David Safford,
	open list:KEYS-TRUSTED, open list:SECURITY SUBSYSTEM, open list

Consider the following transcript:

$ keyctl add trusted kmk "new 32 blobauth=helloworld keyhandle=80000000 migratable=1" @u
add_key: Invalid argument

The documentation has the following description:

  migratable=   0|1 indicating permission to reseal to new PCR values,
                default 1 (resealing allowed)

The consequence is that "migratable=1" should succeed. Fix this by
allowing this condition to pass instead of return -EINVAL.

[*] Documentation/security/keys/trusted-encrypted.rst

Cc: stable@vger.kernel.org
Cc: "James E.J. Bottomley" <jejb@linux.ibm.com>
Cc: Mimi Zohar <zohar@linux.ibm.com>
Cc: David Howells <dhowells@redhat.com>
Fixes: d00a1c72f7f4 ("keys: add new trusted key-type")
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
---
 security/keys/trusted-keys/trusted_tpm1.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/security/keys/trusted-keys/trusted_tpm1.c b/security/keys/trusted-keys/trusted_tpm1.c
index c7b1701cdac5..7a937c3c5283 100644
--- a/security/keys/trusted-keys/trusted_tpm1.c
+++ b/security/keys/trusted-keys/trusted_tpm1.c
@@ -801,7 +801,7 @@ static int getoptions(char *c, struct trusted_key_payload *pay,
 		case Opt_migratable:
 			if (*args[0].from == '0')
 				pay->migratable = 0;
-			else
+			else if (*args[0].from != '1')
 				return -EINVAL;
 			break;
 		case Opt_pcrlock:
-- 
2.25.1


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v4 3/3,RESEND] KEYS: trusted: Reserve TPM for seal and unseal operations
       [not found] <20201013025156.111305-1-jarkko.sakkinen@linux.intel.com>
                   ` (4 preceding siblings ...)
  2020-10-30  8:52 ` [PATCH v4 2/3,RESEND] KEYS: trusted: Fix migratable=1 failing Jarkko Sakkinen
@ 2020-10-30  8:52 ` Jarkko Sakkinen
  2020-11-04  1:18 ` [PATCH v4 1/3,RESEND 2] KEYS: trusted: Fix incorrect handling of tpm_get_random() Jarkko Sakkinen
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Jarkko Sakkinen @ 2020-10-30  8:52 UTC (permalink / raw)
  To: linux-integrity
  Cc: David Howells, Mimi Zohar, James Bottomley, Jarkko Sakkinen,
	James E.J. Bottomley, stable, Sumit Garg, kernel test robot,
	Peter Huewe, Jason Gunthorpe, Arnd Bergmann, Greg Kroah-Hartman,
	James Morris, Serge E. Hallyn, Jerry Snitselaar, Alexey Klimov,
	open list, open list:KEYS-TRUSTED, open list:SECURITY SUBSYSTEM

When TPM 2.0 trusted keys code was moved to the trusted keys subsystem,
the operations were unwrapped from tpm_try_get_ops() and tpm_put_ops(),
which are used to take temporarily the ownership of the TPM chip. The
ownership is only taken inside tpm_send(), but this is not sufficient,
as in the key load TPM2_CC_LOAD, TPM2_CC_UNSEAL and TPM2_FLUSH_CONTEXT
need to be done as a one single atom.

Fix this issue by introducting trusted_tpm_load() and trusted_tpm_new(),
which wrap these operations, and take the TPM chip ownership before
sending anything. Use tpm_transmit_cmd() to send TPM commands instead
of tpm_send(), reverting back to the old behaviour.

Fixes: 2e19e10131a0 ("KEYS: trusted: Move TPM2 trusted keys code")
Reported-by: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
Cc: stable@vger.kernel.org
Cc: David Howells <dhowells@redhat.com>
Cc: Mimi Zohar <zohar@linux.ibm.com>
Cc: Sumit Garg <sumit.garg@linaro.org>
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Reported-by: kernel test robot <lkp@intel.com>
---
 drivers/char/tpm/tpm.h                    |  4 --
 include/linux/tpm.h                       |  5 +-
 security/keys/trusted-keys/trusted_tpm1.c | 78 +++++++++++++++--------
 security/keys/trusted-keys/trusted_tpm2.c |  6 +-
 4 files changed, 60 insertions(+), 33 deletions(-)

diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 947d1db0a5cc..283f78211c3a 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -164,8 +164,6 @@ extern const struct file_operations tpmrm_fops;
 extern struct idr dev_nums_idr;
 
 ssize_t tpm_transmit(struct tpm_chip *chip, u8 *buf, size_t bufsiz);
-ssize_t tpm_transmit_cmd(struct tpm_chip *chip, struct tpm_buf *buf,
-			 size_t min_rsp_body_length, const char *desc);
 int tpm_get_timeouts(struct tpm_chip *);
 int tpm_auto_startup(struct tpm_chip *chip);
 
@@ -194,8 +192,6 @@ static inline void tpm_msleep(unsigned int delay_msec)
 int tpm_chip_start(struct tpm_chip *chip);
 void tpm_chip_stop(struct tpm_chip *chip);
 struct tpm_chip *tpm_find_get_ops(struct tpm_chip *chip);
-__must_check int tpm_try_get_ops(struct tpm_chip *chip);
-void tpm_put_ops(struct tpm_chip *chip);
 
 struct tpm_chip *tpm_chip_alloc(struct device *dev,
 				const struct tpm_class_ops *ops);
diff --git a/include/linux/tpm.h b/include/linux/tpm.h
index 8f4ff39f51e7..804a3f69bbd9 100644
--- a/include/linux/tpm.h
+++ b/include/linux/tpm.h
@@ -397,6 +397,10 @@ static inline u32 tpm2_rc_value(u32 rc)
 #if defined(CONFIG_TCG_TPM) || defined(CONFIG_TCG_TPM_MODULE)
 
 extern int tpm_is_tpm2(struct tpm_chip *chip);
+extern __must_check int tpm_try_get_ops(struct tpm_chip *chip);
+extern void tpm_put_ops(struct tpm_chip *chip);
+extern ssize_t tpm_transmit_cmd(struct tpm_chip *chip, struct tpm_buf *buf,
+				size_t min_rsp_body_length, const char *desc);
 extern int tpm_pcr_read(struct tpm_chip *chip, u32 pcr_idx,
 			struct tpm_digest *digest);
 extern int tpm_pcr_extend(struct tpm_chip *chip, u32 pcr_idx,
@@ -410,7 +414,6 @@ static inline int tpm_is_tpm2(struct tpm_chip *chip)
 {
 	return -ENODEV;
 }
-
 static inline int tpm_pcr_read(struct tpm_chip *chip, int pcr_idx,
 			       struct tpm_digest *digest)
 {
diff --git a/security/keys/trusted-keys/trusted_tpm1.c b/security/keys/trusted-keys/trusted_tpm1.c
index 7a937c3c5283..20ca18e17437 100644
--- a/security/keys/trusted-keys/trusted_tpm1.c
+++ b/security/keys/trusted-keys/trusted_tpm1.c
@@ -950,6 +950,51 @@ static struct trusted_key_payload *trusted_payload_alloc(struct key *key)
 	return p;
 }
 
+static int trusted_tpm_load(struct tpm_chip *chip,
+			    struct trusted_key_payload *payload,
+			    struct trusted_key_options *options)
+{
+	int ret;
+
+	if (tpm_is_tpm2(chip)) {
+		ret = tpm_try_get_ops(chip);
+		if (!ret) {
+			ret = tpm2_unseal_trusted(chip, payload, options);
+			tpm_put_ops(chip);
+		}
+	} else {
+		ret = key_unseal(payload, options);
+	}
+
+	return ret;
+}
+
+static int trusted_tpm_new(struct tpm_chip *chip,
+			   struct trusted_key_payload *payload,
+			   struct trusted_key_options *options)
+{
+	int ret;
+
+	ret = tpm_get_random(chip, payload->key, payload->key_len);
+	if (ret < 0)
+		return ret;
+
+	if (ret != payload->key_len)
+		return -EIO;
+
+	if (tpm_is_tpm2(chip)) {
+		ret = tpm_try_get_ops(chip);
+		if (!ret) {
+			ret = tpm2_seal_trusted(chip, payload, options);
+			tpm_put_ops(chip);
+		}
+	} else {
+		ret = key_seal(payload, options);
+	}
+
+	return ret;
+}
+
 /*
  * trusted_instantiate - create a new trusted key
  *
@@ -968,12 +1013,6 @@ static int trusted_instantiate(struct key *key,
 	char *datablob;
 	int ret = 0;
 	int key_cmd;
-	size_t key_len;
-	int tpm2;
-
-	tpm2 = tpm_is_tpm2(chip);
-	if (tpm2 < 0)
-		return tpm2;
 
 	if (datalen <= 0 || datalen > 32767 || !prep->data)
 		return -EINVAL;
@@ -1011,32 +1050,21 @@ static int trusted_instantiate(struct key *key,
 
 	switch (key_cmd) {
 	case Opt_load:
-		if (tpm2)
-			ret = tpm2_unseal_trusted(chip, payload, options);
-		else
-			ret = key_unseal(payload, options);
+		ret = trusted_tpm_load(chip, payload, options);
+
 		dump_payload(payload);
 		dump_options(options);
+
 		if (ret < 0)
-			pr_info("trusted_key: key_unseal failed (%d)\n", ret);
+			pr_info("%s: load failed (%d)\n", __func__, ret);
+
 		break;
 	case Opt_new:
-		key_len = payload->key_len;
-		ret = tpm_get_random(chip, payload->key, key_len);
-		if (ret < 0)
-			goto out;
+		ret = trusted_tpm_new(chip, payload, options);
 
-		if (ret != key_len) {
-			pr_info("trusted_key: key_create failed (%d)\n", ret);
-			ret = -EIO;
-			goto out;
-		}
-		if (tpm2)
-			ret = tpm2_seal_trusted(chip, payload, options);
-		else
-			ret = key_seal(payload, options);
 		if (ret < 0)
-			pr_info("trusted_key: key_seal failed (%d)\n", ret);
+			pr_info("%s: new failed (%d)\n", __func__, ret);
+
 		break;
 	default:
 		ret = -EINVAL;
diff --git a/security/keys/trusted-keys/trusted_tpm2.c b/security/keys/trusted-keys/trusted_tpm2.c
index 08ec7f48f01d..effdb67fac6d 100644
--- a/security/keys/trusted-keys/trusted_tpm2.c
+++ b/security/keys/trusted-keys/trusted_tpm2.c
@@ -130,7 +130,7 @@ int tpm2_seal_trusted(struct tpm_chip *chip,
 		goto out;
 	}
 
-	rc = tpm_send(chip, buf.data, tpm_buf_length(&buf));
+	rc = tpm_transmit_cmd(chip, &buf, 4, "sealing data");
 	if (rc)
 		goto out;
 
@@ -211,7 +211,7 @@ static int tpm2_load_cmd(struct tpm_chip *chip,
 		goto out;
 	}
 
-	rc = tpm_send(chip, buf.data, tpm_buf_length(&buf));
+	rc = tpm_transmit_cmd(chip, &buf, 4, "loading blob");
 	if (!rc)
 		*blob_handle = be32_to_cpup(
 			(__be32 *) &buf.data[TPM_HEADER_SIZE]);
@@ -260,7 +260,7 @@ static int tpm2_unseal_cmd(struct tpm_chip *chip,
 			     options->blobauth /* hmac */,
 			     TPM_DIGEST_SIZE);
 
-	rc = tpm_send(chip, buf.data, tpm_buf_length(&buf));
+	rc = tpm_transmit_cmd(chip, &buf, 6, "unsealing");
 	if (rc > 0)
 		rc = -EPERM;
 
-- 
2.25.1


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v4 1/3,RESEND 2] KEYS: trusted: Fix incorrect handling of tpm_get_random()
       [not found] <20201013025156.111305-1-jarkko.sakkinen@linux.intel.com>
                   ` (5 preceding siblings ...)
  2020-10-30  8:52 ` [PATCH v4 3/3,RESEND] KEYS: trusted: Reserve TPM for seal and unseal operations Jarkko Sakkinen
@ 2020-11-04  1:18 ` Jarkko Sakkinen
  2020-11-04  1:18 ` [PATCH v4 2/3,RESEND 2] KEYS: trusted: Fix migratable=1 failing Jarkko Sakkinen
  2020-11-04  1:19 ` [PATCH v4 3/3,RESEND 2] KEYS: trusted: Reserve TPM for seal and unseal operations Jarkko Sakkinen
  8 siblings, 0 replies; 11+ messages in thread
From: Jarkko Sakkinen @ 2020-11-04  1:18 UTC (permalink / raw)
  To: linux-integrity
  Cc: David Howells, Mimi Zohar, James Bottomley, Jarkko Sakkinen,
	stable, James E.J. Bottomley, Kent Yoder, James Morris,
	Serge E. Hallyn, H. Peter Anvin, David Safford,
	open list:KEYS-TRUSTED, open list:SECURITY SUBSYSTEM, open list

When tpm_get_random() was introduced, it defined the following API for the
return value:

1. A positive value tells how many bytes of random data was generated.
2. A negative value on error.

However, in the call sites the API was used incorrectly, i.e. as it would
only return negative values and otherwise zero. Returning he positive read
counts to the user space does not make any possible sense.

Fix this by returning -EIO when tpm_get_random() returns a positive value.

Fixes: 41ab999c80f1 ("tpm: Move tpm_get_random api into the TPM device driver")
Cc: stable@vger.kernel.org
Cc: Mimi Zohar <zohar@linux.ibm.com>
Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
Cc: David Howells <dhowells@redhat.com>
Cc: Kent Yoder <key@linux.vnet.ibm.com>
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
---
 security/keys/trusted-keys/trusted_tpm1.c | 20 +++++++++++++++++---
 1 file changed, 17 insertions(+), 3 deletions(-)

diff --git a/security/keys/trusted-keys/trusted_tpm1.c b/security/keys/trusted-keys/trusted_tpm1.c
index b9fe02e5f84f..c7b1701cdac5 100644
--- a/security/keys/trusted-keys/trusted_tpm1.c
+++ b/security/keys/trusted-keys/trusted_tpm1.c
@@ -403,9 +403,12 @@ static int osap(struct tpm_buf *tb, struct osapsess *s,
 	int ret;
 
 	ret = tpm_get_random(chip, ononce, TPM_NONCE_SIZE);
-	if (ret != TPM_NONCE_SIZE)
+	if (ret < 0)
 		return ret;
 
+	if (ret != TPM_NONCE_SIZE)
+		return -EIO;
+
 	tpm_buf_reset(tb, TPM_TAG_RQU_COMMAND, TPM_ORD_OSAP);
 	tpm_buf_append_u16(tb, type);
 	tpm_buf_append_u32(tb, handle);
@@ -496,8 +499,12 @@ static int tpm_seal(struct tpm_buf *tb, uint16_t keytype,
 		goto out;
 
 	ret = tpm_get_random(chip, td->nonceodd, TPM_NONCE_SIZE);
+	if (ret < 0)
+		return ret;
+
 	if (ret != TPM_NONCE_SIZE)
-		goto out;
+		return -EIO;
+
 	ordinal = htonl(TPM_ORD_SEAL);
 	datsize = htonl(datalen);
 	pcrsize = htonl(pcrinfosize);
@@ -601,9 +608,12 @@ static int tpm_unseal(struct tpm_buf *tb,
 
 	ordinal = htonl(TPM_ORD_UNSEAL);
 	ret = tpm_get_random(chip, nonceodd, TPM_NONCE_SIZE);
+	if (ret < 0)
+		return ret;
+
 	if (ret != TPM_NONCE_SIZE) {
 		pr_info("trusted_key: tpm_get_random failed (%d)\n", ret);
-		return ret;
+		return -EIO;
 	}
 	ret = TSS_authhmac(authdata1, keyauth, TPM_NONCE_SIZE,
 			   enonce1, nonceodd, cont, sizeof(uint32_t),
@@ -1013,8 +1023,12 @@ static int trusted_instantiate(struct key *key,
 	case Opt_new:
 		key_len = payload->key_len;
 		ret = tpm_get_random(chip, payload->key, key_len);
+		if (ret < 0)
+			goto out;
+
 		if (ret != key_len) {
 			pr_info("trusted_key: key_create failed (%d)\n", ret);
+			ret = -EIO;
 			goto out;
 		}
 		if (tpm2)
-- 
2.25.1


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v4 2/3,RESEND 2] KEYS: trusted: Fix migratable=1 failing
       [not found] <20201013025156.111305-1-jarkko.sakkinen@linux.intel.com>
                   ` (6 preceding siblings ...)
  2020-11-04  1:18 ` [PATCH v4 1/3,RESEND 2] KEYS: trusted: Fix incorrect handling of tpm_get_random() Jarkko Sakkinen
@ 2020-11-04  1:18 ` Jarkko Sakkinen
  2020-11-04  1:19 ` [PATCH v4 3/3,RESEND 2] KEYS: trusted: Reserve TPM for seal and unseal operations Jarkko Sakkinen
  8 siblings, 0 replies; 11+ messages in thread
From: Jarkko Sakkinen @ 2020-11-04  1:18 UTC (permalink / raw)
  To: linux-integrity
  Cc: David Howells, Mimi Zohar, James Bottomley, Jarkko Sakkinen,
	stable, James Morris, Serge E. Hallyn, David Safford,
	open list:KEYS-TRUSTED, open list:SECURITY SUBSYSTEM, open list

Consider the following transcript:

$ keyctl add trusted kmk "new 32 blobauth=helloworld keyhandle=80000000 migratable=1" @u
add_key: Invalid argument

The documentation has the following description:

  migratable=   0|1 indicating permission to reseal to new PCR values,
                default 1 (resealing allowed)

The consequence is that "migratable=1" should succeed. Fix this by
allowing this condition to pass instead of return -EINVAL.

[*] Documentation/security/keys/trusted-encrypted.rst

Cc: stable@vger.kernel.org
Cc: "James E.J. Bottomley" <jejb@linux.ibm.com>
Cc: Mimi Zohar <zohar@linux.ibm.com>
Cc: David Howells <dhowells@redhat.com>
Fixes: d00a1c72f7f4 ("keys: add new trusted key-type")
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
---
 security/keys/trusted-keys/trusted_tpm1.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/security/keys/trusted-keys/trusted_tpm1.c b/security/keys/trusted-keys/trusted_tpm1.c
index c7b1701cdac5..7a937c3c5283 100644
--- a/security/keys/trusted-keys/trusted_tpm1.c
+++ b/security/keys/trusted-keys/trusted_tpm1.c
@@ -801,7 +801,7 @@ static int getoptions(char *c, struct trusted_key_payload *pay,
 		case Opt_migratable:
 			if (*args[0].from == '0')
 				pay->migratable = 0;
-			else
+			else if (*args[0].from != '1')
 				return -EINVAL;
 			break;
 		case Opt_pcrlock:
-- 
2.25.1


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v4 3/3,RESEND 2] KEYS: trusted: Reserve TPM for seal and unseal operations
       [not found] <20201013025156.111305-1-jarkko.sakkinen@linux.intel.com>
                   ` (7 preceding siblings ...)
  2020-11-04  1:18 ` [PATCH v4 2/3,RESEND 2] KEYS: trusted: Fix migratable=1 failing Jarkko Sakkinen
@ 2020-11-04  1:19 ` Jarkko Sakkinen
  2020-11-04  7:30   ` Sumit Garg
  8 siblings, 1 reply; 11+ messages in thread
From: Jarkko Sakkinen @ 2020-11-04  1:19 UTC (permalink / raw)
  To: linux-integrity
  Cc: David Howells, Mimi Zohar, James Bottomley, Jarkko Sakkinen,
	James E.J. Bottomley, stable, Sumit Garg, kernel test robot,
	Peter Huewe, Jason Gunthorpe, Arnd Bergmann, Greg Kroah-Hartman,
	James Morris, Serge E. Hallyn, Jerry Snitselaar, Alexey Klimov,
	open list, open list:KEYS-TRUSTED, open list:SECURITY SUBSYSTEM

When TPM 2.0 trusted keys code was moved to the trusted keys subsystem,
the operations were unwrapped from tpm_try_get_ops() and tpm_put_ops(),
which are used to take temporarily the ownership of the TPM chip. The
ownership is only taken inside tpm_send(), but this is not sufficient,
as in the key load TPM2_CC_LOAD, TPM2_CC_UNSEAL and TPM2_FLUSH_CONTEXT
need to be done as a one single atom.

Fix this issue by introducting trusted_tpm_load() and trusted_tpm_new(),
which wrap these operations, and take the TPM chip ownership before
sending anything. Use tpm_transmit_cmd() to send TPM commands instead
of tpm_send(), reverting back to the old behaviour.

Fixes: 2e19e10131a0 ("KEYS: trusted: Move TPM2 trusted keys code")
Reported-by: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
Cc: stable@vger.kernel.org
Cc: David Howells <dhowells@redhat.com>
Cc: Mimi Zohar <zohar@linux.ibm.com>
Cc: Sumit Garg <sumit.garg@linaro.org>
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Reported-by: kernel test robot <lkp@intel.com>
---
 drivers/char/tpm/tpm.h                    |  4 --
 include/linux/tpm.h                       |  5 +-
 security/keys/trusted-keys/trusted_tpm1.c | 78 +++++++++++++++--------
 security/keys/trusted-keys/trusted_tpm2.c |  6 +-
 4 files changed, 60 insertions(+), 33 deletions(-)

diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 947d1db0a5cc..283f78211c3a 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -164,8 +164,6 @@ extern const struct file_operations tpmrm_fops;
 extern struct idr dev_nums_idr;
 
 ssize_t tpm_transmit(struct tpm_chip *chip, u8 *buf, size_t bufsiz);
-ssize_t tpm_transmit_cmd(struct tpm_chip *chip, struct tpm_buf *buf,
-			 size_t min_rsp_body_length, const char *desc);
 int tpm_get_timeouts(struct tpm_chip *);
 int tpm_auto_startup(struct tpm_chip *chip);
 
@@ -194,8 +192,6 @@ static inline void tpm_msleep(unsigned int delay_msec)
 int tpm_chip_start(struct tpm_chip *chip);
 void tpm_chip_stop(struct tpm_chip *chip);
 struct tpm_chip *tpm_find_get_ops(struct tpm_chip *chip);
-__must_check int tpm_try_get_ops(struct tpm_chip *chip);
-void tpm_put_ops(struct tpm_chip *chip);
 
 struct tpm_chip *tpm_chip_alloc(struct device *dev,
 				const struct tpm_class_ops *ops);
diff --git a/include/linux/tpm.h b/include/linux/tpm.h
index 8f4ff39f51e7..804a3f69bbd9 100644
--- a/include/linux/tpm.h
+++ b/include/linux/tpm.h
@@ -397,6 +397,10 @@ static inline u32 tpm2_rc_value(u32 rc)
 #if defined(CONFIG_TCG_TPM) || defined(CONFIG_TCG_TPM_MODULE)
 
 extern int tpm_is_tpm2(struct tpm_chip *chip);
+extern __must_check int tpm_try_get_ops(struct tpm_chip *chip);
+extern void tpm_put_ops(struct tpm_chip *chip);
+extern ssize_t tpm_transmit_cmd(struct tpm_chip *chip, struct tpm_buf *buf,
+				size_t min_rsp_body_length, const char *desc);
 extern int tpm_pcr_read(struct tpm_chip *chip, u32 pcr_idx,
 			struct tpm_digest *digest);
 extern int tpm_pcr_extend(struct tpm_chip *chip, u32 pcr_idx,
@@ -410,7 +414,6 @@ static inline int tpm_is_tpm2(struct tpm_chip *chip)
 {
 	return -ENODEV;
 }
-
 static inline int tpm_pcr_read(struct tpm_chip *chip, int pcr_idx,
 			       struct tpm_digest *digest)
 {
diff --git a/security/keys/trusted-keys/trusted_tpm1.c b/security/keys/trusted-keys/trusted_tpm1.c
index 7a937c3c5283..20ca18e17437 100644
--- a/security/keys/trusted-keys/trusted_tpm1.c
+++ b/security/keys/trusted-keys/trusted_tpm1.c
@@ -950,6 +950,51 @@ static struct trusted_key_payload *trusted_payload_alloc(struct key *key)
 	return p;
 }
 
+static int trusted_tpm_load(struct tpm_chip *chip,
+			    struct trusted_key_payload *payload,
+			    struct trusted_key_options *options)
+{
+	int ret;
+
+	if (tpm_is_tpm2(chip)) {
+		ret = tpm_try_get_ops(chip);
+		if (!ret) {
+			ret = tpm2_unseal_trusted(chip, payload, options);
+			tpm_put_ops(chip);
+		}
+	} else {
+		ret = key_unseal(payload, options);
+	}
+
+	return ret;
+}
+
+static int trusted_tpm_new(struct tpm_chip *chip,
+			   struct trusted_key_payload *payload,
+			   struct trusted_key_options *options)
+{
+	int ret;
+
+	ret = tpm_get_random(chip, payload->key, payload->key_len);
+	if (ret < 0)
+		return ret;
+
+	if (ret != payload->key_len)
+		return -EIO;
+
+	if (tpm_is_tpm2(chip)) {
+		ret = tpm_try_get_ops(chip);
+		if (!ret) {
+			ret = tpm2_seal_trusted(chip, payload, options);
+			tpm_put_ops(chip);
+		}
+	} else {
+		ret = key_seal(payload, options);
+	}
+
+	return ret;
+}
+
 /*
  * trusted_instantiate - create a new trusted key
  *
@@ -968,12 +1013,6 @@ static int trusted_instantiate(struct key *key,
 	char *datablob;
 	int ret = 0;
 	int key_cmd;
-	size_t key_len;
-	int tpm2;
-
-	tpm2 = tpm_is_tpm2(chip);
-	if (tpm2 < 0)
-		return tpm2;
 
 	if (datalen <= 0 || datalen > 32767 || !prep->data)
 		return -EINVAL;
@@ -1011,32 +1050,21 @@ static int trusted_instantiate(struct key *key,
 
 	switch (key_cmd) {
 	case Opt_load:
-		if (tpm2)
-			ret = tpm2_unseal_trusted(chip, payload, options);
-		else
-			ret = key_unseal(payload, options);
+		ret = trusted_tpm_load(chip, payload, options);
+
 		dump_payload(payload);
 		dump_options(options);
+
 		if (ret < 0)
-			pr_info("trusted_key: key_unseal failed (%d)\n", ret);
+			pr_info("%s: load failed (%d)\n", __func__, ret);
+
 		break;
 	case Opt_new:
-		key_len = payload->key_len;
-		ret = tpm_get_random(chip, payload->key, key_len);
-		if (ret < 0)
-			goto out;
+		ret = trusted_tpm_new(chip, payload, options);
 
-		if (ret != key_len) {
-			pr_info("trusted_key: key_create failed (%d)\n", ret);
-			ret = -EIO;
-			goto out;
-		}
-		if (tpm2)
-			ret = tpm2_seal_trusted(chip, payload, options);
-		else
-			ret = key_seal(payload, options);
 		if (ret < 0)
-			pr_info("trusted_key: key_seal failed (%d)\n", ret);
+			pr_info("%s: new failed (%d)\n", __func__, ret);
+
 		break;
 	default:
 		ret = -EINVAL;
diff --git a/security/keys/trusted-keys/trusted_tpm2.c b/security/keys/trusted-keys/trusted_tpm2.c
index 08ec7f48f01d..effdb67fac6d 100644
--- a/security/keys/trusted-keys/trusted_tpm2.c
+++ b/security/keys/trusted-keys/trusted_tpm2.c
@@ -130,7 +130,7 @@ int tpm2_seal_trusted(struct tpm_chip *chip,
 		goto out;
 	}
 
-	rc = tpm_send(chip, buf.data, tpm_buf_length(&buf));
+	rc = tpm_transmit_cmd(chip, &buf, 4, "sealing data");
 	if (rc)
 		goto out;
 
@@ -211,7 +211,7 @@ static int tpm2_load_cmd(struct tpm_chip *chip,
 		goto out;
 	}
 
-	rc = tpm_send(chip, buf.data, tpm_buf_length(&buf));
+	rc = tpm_transmit_cmd(chip, &buf, 4, "loading blob");
 	if (!rc)
 		*blob_handle = be32_to_cpup(
 			(__be32 *) &buf.data[TPM_HEADER_SIZE]);
@@ -260,7 +260,7 @@ static int tpm2_unseal_cmd(struct tpm_chip *chip,
 			     options->blobauth /* hmac */,
 			     TPM_DIGEST_SIZE);
 
-	rc = tpm_send(chip, buf.data, tpm_buf_length(&buf));
+	rc = tpm_transmit_cmd(chip, &buf, 6, "unsealing");
 	if (rc > 0)
 		rc = -EPERM;
 
-- 
2.25.1


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v4 3/3,RESEND 2] KEYS: trusted: Reserve TPM for seal and unseal operations
  2020-11-04  1:19 ` [PATCH v4 3/3,RESEND 2] KEYS: trusted: Reserve TPM for seal and unseal operations Jarkko Sakkinen
@ 2020-11-04  7:30   ` Sumit Garg
  2020-11-04 10:32     ` Jarkko Sakkinen
  0 siblings, 1 reply; 11+ messages in thread
From: Sumit Garg @ 2020-11-04  7:30 UTC (permalink / raw)
  To: Jarkko Sakkinen
  Cc: linux-integrity, David Howells, Mimi Zohar, James Bottomley,
	James E.J. Bottomley, stable, kernel test robot, Peter Huewe,
	Jason Gunthorpe, Arnd Bergmann, Greg Kroah-Hartman, James Morris,
	Serge E. Hallyn, Jerry Snitselaar, Alexey Klimov, open list,
	open list:KEYS-TRUSTED, open list:SECURITY SUBSYSTEM

Hi Jarkko,

On Wed, 4 Nov 2020 at 06:49, Jarkko Sakkinen
<jarkko.sakkinen@linux.intel.com> wrote:
>
> When TPM 2.0 trusted keys code was moved to the trusted keys subsystem,
> the operations were unwrapped from tpm_try_get_ops() and tpm_put_ops(),
> which are used to take temporarily the ownership of the TPM chip. The
> ownership is only taken inside tpm_send(), but this is not sufficient,
> as in the key load TPM2_CC_LOAD, TPM2_CC_UNSEAL and TPM2_FLUSH_CONTEXT
> need to be done as a one single atom.
>
> Fix this issue by introducting trusted_tpm_load() and trusted_tpm_new(),
> which wrap these operations, and take the TPM chip ownership before
> sending anything.

I am not sure if we really need these new APIs in order to fix this
issue, see below.

> Use tpm_transmit_cmd() to send TPM commands instead
> of tpm_send(), reverting back to the old behaviour.
>
> Fixes: 2e19e10131a0 ("KEYS: trusted: Move TPM2 trusted keys code")
> Reported-by: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
> Cc: stable@vger.kernel.org
> Cc: David Howells <dhowells@redhat.com>
> Cc: Mimi Zohar <zohar@linux.ibm.com>
> Cc: Sumit Garg <sumit.garg@linaro.org>
> Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
> Reported-by: kernel test robot <lkp@intel.com>
> ---
>  drivers/char/tpm/tpm.h                    |  4 --
>  include/linux/tpm.h                       |  5 +-
>  security/keys/trusted-keys/trusted_tpm1.c | 78 +++++++++++++++--------
>  security/keys/trusted-keys/trusted_tpm2.c |  6 +-
>  4 files changed, 60 insertions(+), 33 deletions(-)
>
> diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
> index 947d1db0a5cc..283f78211c3a 100644
> --- a/drivers/char/tpm/tpm.h
> +++ b/drivers/char/tpm/tpm.h
> @@ -164,8 +164,6 @@ extern const struct file_operations tpmrm_fops;
>  extern struct idr dev_nums_idr;
>
>  ssize_t tpm_transmit(struct tpm_chip *chip, u8 *buf, size_t bufsiz);
> -ssize_t tpm_transmit_cmd(struct tpm_chip *chip, struct tpm_buf *buf,
> -                        size_t min_rsp_body_length, const char *desc);
>  int tpm_get_timeouts(struct tpm_chip *);
>  int tpm_auto_startup(struct tpm_chip *chip);
>
> @@ -194,8 +192,6 @@ static inline void tpm_msleep(unsigned int delay_msec)
>  int tpm_chip_start(struct tpm_chip *chip);
>  void tpm_chip_stop(struct tpm_chip *chip);
>  struct tpm_chip *tpm_find_get_ops(struct tpm_chip *chip);
> -__must_check int tpm_try_get_ops(struct tpm_chip *chip);
> -void tpm_put_ops(struct tpm_chip *chip);
>
>  struct tpm_chip *tpm_chip_alloc(struct device *dev,
>                                 const struct tpm_class_ops *ops);
> diff --git a/include/linux/tpm.h b/include/linux/tpm.h
> index 8f4ff39f51e7..804a3f69bbd9 100644
> --- a/include/linux/tpm.h
> +++ b/include/linux/tpm.h
> @@ -397,6 +397,10 @@ static inline u32 tpm2_rc_value(u32 rc)
>  #if defined(CONFIG_TCG_TPM) || defined(CONFIG_TCG_TPM_MODULE)
>
>  extern int tpm_is_tpm2(struct tpm_chip *chip);
> +extern __must_check int tpm_try_get_ops(struct tpm_chip *chip);
> +extern void tpm_put_ops(struct tpm_chip *chip);
> +extern ssize_t tpm_transmit_cmd(struct tpm_chip *chip, struct tpm_buf *buf,
> +                               size_t min_rsp_body_length, const char *desc);
>  extern int tpm_pcr_read(struct tpm_chip *chip, u32 pcr_idx,
>                         struct tpm_digest *digest);
>  extern int tpm_pcr_extend(struct tpm_chip *chip, u32 pcr_idx,
> @@ -410,7 +414,6 @@ static inline int tpm_is_tpm2(struct tpm_chip *chip)
>  {
>         return -ENODEV;
>  }
> -
>  static inline int tpm_pcr_read(struct tpm_chip *chip, int pcr_idx,
>                                struct tpm_digest *digest)
>  {
> diff --git a/security/keys/trusted-keys/trusted_tpm1.c b/security/keys/trusted-keys/trusted_tpm1.c
> index 7a937c3c5283..20ca18e17437 100644
> --- a/security/keys/trusted-keys/trusted_tpm1.c
> +++ b/security/keys/trusted-keys/trusted_tpm1.c
> @@ -950,6 +950,51 @@ static struct trusted_key_payload *trusted_payload_alloc(struct key *key)
>         return p;
>  }
>
> +static int trusted_tpm_load(struct tpm_chip *chip,
> +                           struct trusted_key_payload *payload,
> +                           struct trusted_key_options *options)
> +{
> +       int ret;
> +
> +       if (tpm_is_tpm2(chip)) {
> +               ret = tpm_try_get_ops(chip);

Can't we move this TPM 2.0 specific operation within
tpm2_unseal_trusted() instead?

> +               if (!ret) {
> +                       ret = tpm2_unseal_trusted(chip, payload, options);
> +                       tpm_put_ops(chip);

Ditto.

> +               }
> +       } else {
> +               ret = key_unseal(payload, options);
> +       }
> +
> +       return ret;
> +}
> +
> +static int trusted_tpm_new(struct tpm_chip *chip,
> +                          struct trusted_key_payload *payload,
> +                          struct trusted_key_options *options)
> +{
> +       int ret;
> +
> +       ret = tpm_get_random(chip, payload->key, payload->key_len);
> +       if (ret < 0)
> +               return ret;
> +
> +       if (ret != payload->key_len)
> +               return -EIO;
> +
> +       if (tpm_is_tpm2(chip)) {
> +               ret = tpm_try_get_ops(chip);

Same here, to move this within tpm2_seal_trusted() instead?

> +               if (!ret) {
> +                       ret = tpm2_seal_trusted(chip, payload, options);
> +                       tpm_put_ops(chip);

Ditto.

-Sumit

> +               }
> +       } else {
> +               ret = key_seal(payload, options);
> +       }
> +
> +       return ret;
> +}
> +
>  /*
>   * trusted_instantiate - create a new trusted key
>   *
> @@ -968,12 +1013,6 @@ static int trusted_instantiate(struct key *key,
>         char *datablob;
>         int ret = 0;
>         int key_cmd;
> -       size_t key_len;
> -       int tpm2;
> -
> -       tpm2 = tpm_is_tpm2(chip);
> -       if (tpm2 < 0)
> -               return tpm2;
>
>         if (datalen <= 0 || datalen > 32767 || !prep->data)
>                 return -EINVAL;
> @@ -1011,32 +1050,21 @@ static int trusted_instantiate(struct key *key,
>
>         switch (key_cmd) {
>         case Opt_load:
> -               if (tpm2)
> -                       ret = tpm2_unseal_trusted(chip, payload, options);
> -               else
> -                       ret = key_unseal(payload, options);
> +               ret = trusted_tpm_load(chip, payload, options);
> +
>                 dump_payload(payload);
>                 dump_options(options);
> +
>                 if (ret < 0)
> -                       pr_info("trusted_key: key_unseal failed (%d)\n", ret);
> +                       pr_info("%s: load failed (%d)\n", __func__, ret);
> +
>                 break;
>         case Opt_new:
> -               key_len = payload->key_len;
> -               ret = tpm_get_random(chip, payload->key, key_len);
> -               if (ret < 0)
> -                       goto out;
> +               ret = trusted_tpm_new(chip, payload, options);
>
> -               if (ret != key_len) {
> -                       pr_info("trusted_key: key_create failed (%d)\n", ret);
> -                       ret = -EIO;
> -                       goto out;
> -               }
> -               if (tpm2)
> -                       ret = tpm2_seal_trusted(chip, payload, options);
> -               else
> -                       ret = key_seal(payload, options);
>                 if (ret < 0)
> -                       pr_info("trusted_key: key_seal failed (%d)\n", ret);
> +                       pr_info("%s: new failed (%d)\n", __func__, ret);
> +
>                 break;
>         default:
>                 ret = -EINVAL;
> diff --git a/security/keys/trusted-keys/trusted_tpm2.c b/security/keys/trusted-keys/trusted_tpm2.c
> index 08ec7f48f01d..effdb67fac6d 100644
> --- a/security/keys/trusted-keys/trusted_tpm2.c
> +++ b/security/keys/trusted-keys/trusted_tpm2.c
> @@ -130,7 +130,7 @@ int tpm2_seal_trusted(struct tpm_chip *chip,
>                 goto out;
>         }
>
> -       rc = tpm_send(chip, buf.data, tpm_buf_length(&buf));
> +       rc = tpm_transmit_cmd(chip, &buf, 4, "sealing data");
>         if (rc)
>                 goto out;
>
> @@ -211,7 +211,7 @@ static int tpm2_load_cmd(struct tpm_chip *chip,
>                 goto out;
>         }
>
> -       rc = tpm_send(chip, buf.data, tpm_buf_length(&buf));
> +       rc = tpm_transmit_cmd(chip, &buf, 4, "loading blob");
>         if (!rc)
>                 *blob_handle = be32_to_cpup(
>                         (__be32 *) &buf.data[TPM_HEADER_SIZE]);
> @@ -260,7 +260,7 @@ static int tpm2_unseal_cmd(struct tpm_chip *chip,
>                              options->blobauth /* hmac */,
>                              TPM_DIGEST_SIZE);
>
> -       rc = tpm_send(chip, buf.data, tpm_buf_length(&buf));
> +       rc = tpm_transmit_cmd(chip, &buf, 6, "unsealing");
>         if (rc > 0)
>                 rc = -EPERM;
>
> --
> 2.25.1
>

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v4 3/3,RESEND 2] KEYS: trusted: Reserve TPM for seal and unseal operations
  2020-11-04  7:30   ` Sumit Garg
@ 2020-11-04 10:32     ` Jarkko Sakkinen
  0 siblings, 0 replies; 11+ messages in thread
From: Jarkko Sakkinen @ 2020-11-04 10:32 UTC (permalink / raw)
  To: Sumit Garg
  Cc: Jarkko Sakkinen, linux-integrity, David Howells, Mimi Zohar,
	James Bottomley, James E.J. Bottomley, stable, kernel test robot,
	Peter Huewe, Jason Gunthorpe, Arnd Bergmann, Greg Kroah-Hartman,
	James Morris, Serge E. Hallyn, Jerry Snitselaar, Alexey Klimov,
	open list, open list:KEYS-TRUSTED, open list:SECURITY SUBSYSTEM

On Wed, Nov 04, 2020 at 01:00:09PM +0530, Sumit Garg wrote:
> Hi Jarkko,
> 
> On Wed, 4 Nov 2020 at 06:49, Jarkko Sakkinen
> <jarkko.sakkinen@linux.intel.com> wrote:
> >
> > When TPM 2.0 trusted keys code was moved to the trusted keys subsystem,
> > the operations were unwrapped from tpm_try_get_ops() and tpm_put_ops(),
> > which are used to take temporarily the ownership of the TPM chip. The
> > ownership is only taken inside tpm_send(), but this is not sufficient,
> > as in the key load TPM2_CC_LOAD, TPM2_CC_UNSEAL and TPM2_FLUSH_CONTEXT
> > need to be done as a one single atom.
> >
> > Fix this issue by introducting trusted_tpm_load() and trusted_tpm_new(),
> > which wrap these operations, and take the TPM chip ownership before
> > sending anything.
> 
> I am not sure if we really need these new APIs in order to fix this
> issue, see below.

They are not API, as they are static functions. Not necessarily
disregarding the argument, just remarking a technical detail.

> > Use tpm_transmit_cmd() to send TPM commands instead
> > of tpm_send(), reverting back to the old behaviour.
> >
> > Fixes: 2e19e10131a0 ("KEYS: trusted: Move TPM2 trusted keys code")
> > Reported-by: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
> > Cc: stable@vger.kernel.org
> > Cc: David Howells <dhowells@redhat.com>
> > Cc: Mimi Zohar <zohar@linux.ibm.com>
> > Cc: Sumit Garg <sumit.garg@linaro.org>
> > Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
> > Reported-by: kernel test robot <lkp@intel.com>
> > ---
> >  drivers/char/tpm/tpm.h                    |  4 --
> >  include/linux/tpm.h                       |  5 +-
> >  security/keys/trusted-keys/trusted_tpm1.c | 78 +++++++++++++++--------
> >  security/keys/trusted-keys/trusted_tpm2.c |  6 +-
> >  4 files changed, 60 insertions(+), 33 deletions(-)
> >
> > diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
> > index 947d1db0a5cc..283f78211c3a 100644
> > --- a/drivers/char/tpm/tpm.h
> > +++ b/drivers/char/tpm/tpm.h
> > @@ -164,8 +164,6 @@ extern const struct file_operations tpmrm_fops;
> >  extern struct idr dev_nums_idr;
> >
> >  ssize_t tpm_transmit(struct tpm_chip *chip, u8 *buf, size_t bufsiz);
> > -ssize_t tpm_transmit_cmd(struct tpm_chip *chip, struct tpm_buf *buf,
> > -                        size_t min_rsp_body_length, const char *desc);
> >  int tpm_get_timeouts(struct tpm_chip *);
> >  int tpm_auto_startup(struct tpm_chip *chip);
> >
> > @@ -194,8 +192,6 @@ static inline void tpm_msleep(unsigned int delay_msec)
> >  int tpm_chip_start(struct tpm_chip *chip);
> >  void tpm_chip_stop(struct tpm_chip *chip);
> >  struct tpm_chip *tpm_find_get_ops(struct tpm_chip *chip);
> > -__must_check int tpm_try_get_ops(struct tpm_chip *chip);
> > -void tpm_put_ops(struct tpm_chip *chip);
> >
> >  struct tpm_chip *tpm_chip_alloc(struct device *dev,
> >                                 const struct tpm_class_ops *ops);
> > diff --git a/include/linux/tpm.h b/include/linux/tpm.h
> > index 8f4ff39f51e7..804a3f69bbd9 100644
> > --- a/include/linux/tpm.h
> > +++ b/include/linux/tpm.h
> > @@ -397,6 +397,10 @@ static inline u32 tpm2_rc_value(u32 rc)
> >  #if defined(CONFIG_TCG_TPM) || defined(CONFIG_TCG_TPM_MODULE)
> >
> >  extern int tpm_is_tpm2(struct tpm_chip *chip);
> > +extern __must_check int tpm_try_get_ops(struct tpm_chip *chip);
> > +extern void tpm_put_ops(struct tpm_chip *chip);
> > +extern ssize_t tpm_transmit_cmd(struct tpm_chip *chip, struct tpm_buf *buf,
> > +                               size_t min_rsp_body_length, const char *desc);
> >  extern int tpm_pcr_read(struct tpm_chip *chip, u32 pcr_idx,
> >                         struct tpm_digest *digest);
> >  extern int tpm_pcr_extend(struct tpm_chip *chip, u32 pcr_idx,
> > @@ -410,7 +414,6 @@ static inline int tpm_is_tpm2(struct tpm_chip *chip)
> >  {
> >         return -ENODEV;
> >  }
> > -
> >  static inline int tpm_pcr_read(struct tpm_chip *chip, int pcr_idx,
> >                                struct tpm_digest *digest)
> >  {
> > diff --git a/security/keys/trusted-keys/trusted_tpm1.c b/security/keys/trusted-keys/trusted_tpm1.c
> > index 7a937c3c5283..20ca18e17437 100644
> > --- a/security/keys/trusted-keys/trusted_tpm1.c
> > +++ b/security/keys/trusted-keys/trusted_tpm1.c
> > @@ -950,6 +950,51 @@ static struct trusted_key_payload *trusted_payload_alloc(struct key *key)
> >         return p;
> >  }
> >
> > +static int trusted_tpm_load(struct tpm_chip *chip,
> > +                           struct trusted_key_payload *payload,
> > +                           struct trusted_key_options *options)
> > +{
> > +       int ret;
> > +
> > +       if (tpm_is_tpm2(chip)) {
> > +               ret = tpm_try_get_ops(chip);
> 
> Can't we move this TPM 2.0 specific operation within
> tpm2_unseal_trusted() instead?
> 
> > +               if (!ret) {
> > +                       ret = tpm2_unseal_trusted(chip, payload, options);
> > +                       tpm_put_ops(chip);
> 
> Ditto.
> 
> > +               }
> > +       } else {
> > +               ret = key_unseal(payload, options);
> > +       }
> > +
> > +       return ret;
> > +}
> > +
> > +static int trusted_tpm_new(struct tpm_chip *chip,
> > +                          struct trusted_key_payload *payload,
> > +                          struct trusted_key_options *options)
> > +{
> > +       int ret;
> > +
> > +       ret = tpm_get_random(chip, payload->key, payload->key_len);
> > +       if (ret < 0)
> > +               return ret;
> > +
> > +       if (ret != payload->key_len)
> > +               return -EIO;
> > +
> > +       if (tpm_is_tpm2(chip)) {
> > +               ret = tpm_try_get_ops(chip);
> 
> Same here, to move this within tpm2_seal_trusted() instead?
> 
> > +               if (!ret) {
> > +                       ret = tpm2_seal_trusted(chip, payload, options);
> > +                       tpm_put_ops(chip);
> 
> Ditto.

I think that would make sense anyhow, as not introducing new static
functions means less potential merge conflicts when backporting. And
yeah, also probably makes your life easier with the feature patch set
under review.

I can refine this.

> -Sumit

/Jarkko

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, back to index

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <20201013025156.111305-1-jarkko.sakkinen@linux.intel.com>
2020-10-13  2:51 ` [PATCH v4 1/3] KEYS: trusted: Fix incorrect handling of tpm_get_random() Jarkko Sakkinen
2020-10-13  2:51 ` [PATCH v4 2/3] KEYS: trusted: Fix migratable=1 failing Jarkko Sakkinen
2020-10-13  2:51 ` [PATCH v4 3/3] KEYS: trusted: Reserve TPM for seal and unseal operations Jarkko Sakkinen
2020-10-30  8:52 ` [PATCH v4 1/3,RESEND] KEYS: trusted: Fix incorrect handling of tpm_get_random() Jarkko Sakkinen
2020-10-30  8:52 ` [PATCH v4 2/3,RESEND] KEYS: trusted: Fix migratable=1 failing Jarkko Sakkinen
2020-10-30  8:52 ` [PATCH v4 3/3,RESEND] KEYS: trusted: Reserve TPM for seal and unseal operations Jarkko Sakkinen
2020-11-04  1:18 ` [PATCH v4 1/3,RESEND 2] KEYS: trusted: Fix incorrect handling of tpm_get_random() Jarkko Sakkinen
2020-11-04  1:18 ` [PATCH v4 2/3,RESEND 2] KEYS: trusted: Fix migratable=1 failing Jarkko Sakkinen
2020-11-04  1:19 ` [PATCH v4 3/3,RESEND 2] KEYS: trusted: Reserve TPM for seal and unseal operations Jarkko Sakkinen
2020-11-04  7:30   ` Sumit Garg
2020-11-04 10:32     ` Jarkko Sakkinen

Keyrings Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/keyrings/0 keyrings/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 keyrings keyrings/ https://lore.kernel.org/keyrings \
		keyrings@vger.kernel.org
	public-inbox-index keyrings

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.keyrings


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git