Skip to content

Commit 8c657a0

Browse files
committed
KEYS: trusted: Reserve TPM for seal and unseal operations
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: 2e19e10 ("KEYS: trusted: Move TPM2 trusted keys code") Reported-by: "James E.J. Bottomley" <[email protected]> Cc: [email protected] Cc: David Howells <[email protected]> Cc: Mimi Zohar <[email protected]> Cc: Sumit Garg <[email protected]> Acked-by Sumit Garg <[email protected]> Tested-by: Mimi Zohar <[email protected]> Signed-off-by: Jarkko Sakkinen <[email protected]>
1 parent 8da7520 commit 8c657a0

File tree

3 files changed

+22
-9
lines changed

3 files changed

+22
-9
lines changed

drivers/char/tpm/tpm.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -164,8 +164,6 @@ extern const struct file_operations tpmrm_fops;
164164
extern struct idr dev_nums_idr;
165165

166166
ssize_t tpm_transmit(struct tpm_chip *chip, u8 *buf, size_t bufsiz);
167-
ssize_t tpm_transmit_cmd(struct tpm_chip *chip, struct tpm_buf *buf,
168-
size_t min_rsp_body_length, const char *desc);
169167
int tpm_get_timeouts(struct tpm_chip *);
170168
int tpm_auto_startup(struct tpm_chip *chip);
171169

@@ -194,8 +192,6 @@ static inline void tpm_msleep(unsigned int delay_msec)
194192
int tpm_chip_start(struct tpm_chip *chip);
195193
void tpm_chip_stop(struct tpm_chip *chip);
196194
struct tpm_chip *tpm_find_get_ops(struct tpm_chip *chip);
197-
__must_check int tpm_try_get_ops(struct tpm_chip *chip);
198-
void tpm_put_ops(struct tpm_chip *chip);
199195

200196
struct tpm_chip *tpm_chip_alloc(struct device *dev,
201197
const struct tpm_class_ops *ops);

include/linux/tpm.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,10 @@ static inline u32 tpm2_rc_value(u32 rc)
404404
#if defined(CONFIG_TCG_TPM) || defined(CONFIG_TCG_TPM_MODULE)
405405

406406
extern int tpm_is_tpm2(struct tpm_chip *chip);
407+
extern __must_check int tpm_try_get_ops(struct tpm_chip *chip);
408+
extern void tpm_put_ops(struct tpm_chip *chip);
409+
extern ssize_t tpm_transmit_cmd(struct tpm_chip *chip, struct tpm_buf *buf,
410+
size_t min_rsp_body_length, const char *desc);
407411
extern int tpm_pcr_read(struct tpm_chip *chip, u32 pcr_idx,
408412
struct tpm_digest *digest);
409413
extern int tpm_pcr_extend(struct tpm_chip *chip, u32 pcr_idx,
@@ -417,7 +421,6 @@ static inline int tpm_is_tpm2(struct tpm_chip *chip)
417421
{
418422
return -ENODEV;
419423
}
420-
421424
static inline int tpm_pcr_read(struct tpm_chip *chip, int pcr_idx,
422425
struct tpm_digest *digest)
423426
{

security/keys/trusted-keys/trusted_tpm2.c

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,12 @@ int tpm2_seal_trusted(struct tpm_chip *chip,
8383
if (rc)
8484
return rc;
8585

86+
rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_CREATE);
87+
if (rc) {
88+
tpm_put_ops(chip);
89+
return rc;
90+
}
91+
8692
tpm_buf_append_u32(&buf, options->keyhandle);
8793
tpm2_buf_append_auth(&buf, TPM2_RS_PW,
8894
NULL /* nonce */, 0,
@@ -130,7 +136,7 @@ int tpm2_seal_trusted(struct tpm_chip *chip,
130136
goto out;
131137
}
132138

133-
rc = tpm_send(chip, buf.data, tpm_buf_length(&buf));
139+
rc = tpm_transmit_cmd(chip, &buf, 4, "sealing data");
134140
if (rc)
135141
goto out;
136142

@@ -157,6 +163,7 @@ int tpm2_seal_trusted(struct tpm_chip *chip,
157163
rc = -EPERM;
158164
}
159165

166+
tpm_put_ops(chip);
160167
return rc;
161168
}
162169

@@ -211,7 +218,7 @@ static int tpm2_load_cmd(struct tpm_chip *chip,
211218
goto out;
212219
}
213220

214-
rc = tpm_send(chip, buf.data, tpm_buf_length(&buf));
221+
rc = tpm_transmit_cmd(chip, &buf, 4, "loading blob");
215222
if (!rc)
216223
*blob_handle = be32_to_cpup(
217224
(__be32 *) &buf.data[TPM_HEADER_SIZE]);
@@ -260,7 +267,7 @@ static int tpm2_unseal_cmd(struct tpm_chip *chip,
260267
options->blobauth /* hmac */,
261268
TPM_DIGEST_SIZE);
262269

263-
rc = tpm_send(chip, buf.data, tpm_buf_length(&buf));
270+
rc = tpm_transmit_cmd(chip, &buf, 6, "unsealing");
264271
if (rc > 0)
265272
rc = -EPERM;
266273

@@ -304,12 +311,19 @@ int tpm2_unseal_trusted(struct tpm_chip *chip,
304311
u32 blob_handle;
305312
int rc;
306313

307-
rc = tpm2_load_cmd(chip, payload, options, &blob_handle);
314+
rc = tpm_try_get_ops(chip);
308315
if (rc)
309316
return rc;
310317

318+
rc = tpm2_load_cmd(chip, payload, options, &blob_handle);
319+
if (rc)
320+
goto out;
321+
311322
rc = tpm2_unseal_cmd(chip, payload, options, blob_handle);
312323
tpm2_flush_context(chip, blob_handle);
313324

325+
out:
326+
tpm_put_ops(chip);
327+
314328
return rc;
315329
}

0 commit comments

Comments
 (0)