diff options
author | Jarkko Sakkinen <jarkko@kernel.org> | 2021-01-29 02:56:21 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2021-03-04 13:38:29 +0300 |
commit | 67118bb78d72aab5b831f054a74ae856339a1974 (patch) | |
tree | 22b88615e2075a57b77b39dc69309c05682ff605 /security/keys | |
parent | 54c527c18e7fc4c00ee2c97d10c24ccdb07393aa (diff) | |
download | linux-67118bb78d72aab5b831f054a74ae856339a1974.tar.xz |
KEYS: trusted: Reserve TPM for seal and unseal operations
commit 8c657a0590de585b1115847c17b34a58025f2f4b upstream.
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.
Take the TPM chip ownership before sending anything with
tpm_try_get_ops() and tpm_put_ops(), and 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>
Acked-by Sumit Garg <sumit.garg@linaro.org>
Tested-by: Mimi Zohar <zohar@linux.ibm.com>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'security/keys')
-rw-r--r-- | security/keys/trusted-keys/trusted_tpm2.c | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/security/keys/trusted-keys/trusted_tpm2.c b/security/keys/trusted-keys/trusted_tpm2.c index 08ec7f48f01d..e2a0ed5d02f0 100644 --- a/security/keys/trusted-keys/trusted_tpm2.c +++ b/security/keys/trusted-keys/trusted_tpm2.c @@ -83,6 +83,12 @@ int tpm2_seal_trusted(struct tpm_chip *chip, if (rc) return rc; + rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_CREATE); + if (rc) { + tpm_put_ops(chip); + return rc; + } + tpm_buf_append_u32(&buf, options->keyhandle); tpm2_buf_append_auth(&buf, TPM2_RS_PW, NULL /* nonce */, 0, @@ -130,7 +136,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; @@ -157,6 +163,7 @@ out: rc = -EPERM; } + tpm_put_ops(chip); return rc; } @@ -211,7 +218,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 +267,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; @@ -304,12 +311,19 @@ int tpm2_unseal_trusted(struct tpm_chip *chip, u32 blob_handle; int rc; - rc = tpm2_load_cmd(chip, payload, options, &blob_handle); + rc = tpm_try_get_ops(chip); if (rc) return rc; + rc = tpm2_load_cmd(chip, payload, options, &blob_handle); + if (rc) + goto out; + rc = tpm2_unseal_cmd(chip, payload, options, blob_handle); tpm2_flush_context(chip, blob_handle); +out: + tpm_put_ops(chip); + return rc; } |