Skip to content

Commit 4ba05b0

Browse files
committed
Merge tag 'tpmdd-next-6.12-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd
Pull tpm fixes from Jarkko Sakkinen: "Two bug fixes for TPM bus encryption (the remaining reported issues in the feature)" * tag 'tpmdd-next-6.12-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd: tpm: Disable TPM on tpm2_create_primary() failure tpm: Opt-in in disable PCR integrity protection
2 parents 9f8e716 + 423893f commit 4ba05b0

File tree

5 files changed

+87
-33
lines changed

5 files changed

+87
-33
lines changed

Documentation/admin-guide/kernel-parameters.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6727,6 +6727,15 @@
67276727
torture.verbose_sleep_duration= [KNL]
67286728
Duration of each verbose-printk() sleep in jiffies.
67296729

6730+
tpm.disable_pcr_integrity= [HW,TPM]
6731+
Do not protect PCR registers from unintended physical
6732+
access, or interposers in the bus by the means of
6733+
having an integrity protected session wrapped around
6734+
TPM2_PCR_Extend command. Consider this in a situation
6735+
where TPM is heavily utilized by IMA, thus protection
6736+
causing a major performance hit, and the space where
6737+
machines are deployed is by other means guarded.
6738+
67306739
tpm_suspend_pcr=[HW,TPM]
67316740
Format: integer pcr id
67326741
Specify that at suspend time, the tpm driver

drivers/char/tpm/tpm-buf.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,26 @@ void tpm_buf_append_u32(struct tpm_buf *buf, const u32 value)
146146
}
147147
EXPORT_SYMBOL_GPL(tpm_buf_append_u32);
148148

149+
/**
150+
* tpm_buf_append_handle() - Add a handle
151+
* @chip: &tpm_chip instance
152+
* @buf: &tpm_buf instance
153+
* @handle: a TPM object handle
154+
*
155+
* Add a handle to the buffer, and increase the count tracking the number of
156+
* handles in the command buffer. Works only for command buffers.
157+
*/
158+
void tpm_buf_append_handle(struct tpm_chip *chip, struct tpm_buf *buf, u32 handle)
159+
{
160+
if (buf->flags & TPM_BUF_TPM2B) {
161+
dev_err(&chip->dev, "Invalid buffer type (TPM2B)\n");
162+
return;
163+
}
164+
165+
tpm_buf_append_u32(buf, handle);
166+
buf->handles++;
167+
}
168+
149169
/**
150170
* tpm_buf_read() - Read from a TPM buffer
151171
* @buf: &tpm_buf instance

drivers/char/tpm/tpm2-cmd.c

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@
1414
#include "tpm.h"
1515
#include <crypto/hash_info.h>
1616

17+
static bool disable_pcr_integrity;
18+
module_param(disable_pcr_integrity, bool, 0444);
19+
MODULE_PARM_DESC(disable_pcr_integrity, "Disable integrity protection of TPM2_PCR_Extend");
20+
1721
static struct tpm2_hash tpm2_hash_map[] = {
1822
{HASH_ALGO_SHA1, TPM_ALG_SHA1},
1923
{HASH_ALGO_SHA256, TPM_ALG_SHA256},
@@ -232,18 +236,26 @@ int tpm2_pcr_extend(struct tpm_chip *chip, u32 pcr_idx,
232236
int rc;
233237
int i;
234238

235-
rc = tpm2_start_auth_session(chip);
236-
if (rc)
237-
return rc;
239+
if (!disable_pcr_integrity) {
240+
rc = tpm2_start_auth_session(chip);
241+
if (rc)
242+
return rc;
243+
}
238244

239245
rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_PCR_EXTEND);
240246
if (rc) {
241-
tpm2_end_auth_session(chip);
247+
if (!disable_pcr_integrity)
248+
tpm2_end_auth_session(chip);
242249
return rc;
243250
}
244251

245-
tpm_buf_append_name(chip, &buf, pcr_idx, NULL);
246-
tpm_buf_append_hmac_session(chip, &buf, 0, NULL, 0);
252+
if (!disable_pcr_integrity) {
253+
tpm_buf_append_name(chip, &buf, pcr_idx, NULL);
254+
tpm_buf_append_hmac_session(chip, &buf, 0, NULL, 0);
255+
} else {
256+
tpm_buf_append_handle(chip, &buf, pcr_idx);
257+
tpm_buf_append_auth(chip, &buf, 0, NULL, 0);
258+
}
247259

248260
tpm_buf_append_u32(&buf, chip->nr_allocated_banks);
249261

@@ -253,9 +265,11 @@ int tpm2_pcr_extend(struct tpm_chip *chip, u32 pcr_idx,
253265
chip->allocated_banks[i].digest_size);
254266
}
255267

256-
tpm_buf_fill_hmac_session(chip, &buf);
268+
if (!disable_pcr_integrity)
269+
tpm_buf_fill_hmac_session(chip, &buf);
257270
rc = tpm_transmit_cmd(chip, &buf, 0, "attempting extend a PCR value");
258-
rc = tpm_buf_check_hmac_response(chip, &buf, rc);
271+
if (!disable_pcr_integrity)
272+
rc = tpm_buf_check_hmac_response(chip, &buf, rc);
259273

260274
tpm_buf_destroy(&buf);
261275

drivers/char/tpm/tpm2-sessions.c

Lines changed: 33 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -237,9 +237,7 @@ void tpm_buf_append_name(struct tpm_chip *chip, struct tpm_buf *buf,
237237
#endif
238238

239239
if (!tpm2_chip_auth(chip)) {
240-
tpm_buf_append_u32(buf, handle);
241-
/* count the number of handles in the upper bits of flags */
242-
buf->handles++;
240+
tpm_buf_append_handle(chip, buf, handle);
243241
return;
244242
}
245243

@@ -272,6 +270,31 @@ void tpm_buf_append_name(struct tpm_chip *chip, struct tpm_buf *buf,
272270
}
273271
EXPORT_SYMBOL_GPL(tpm_buf_append_name);
274272

273+
void tpm_buf_append_auth(struct tpm_chip *chip, struct tpm_buf *buf,
274+
u8 attributes, u8 *passphrase, int passphrase_len)
275+
{
276+
/* offset tells us where the sessions area begins */
277+
int offset = buf->handles * 4 + TPM_HEADER_SIZE;
278+
u32 len = 9 + passphrase_len;
279+
280+
if (tpm_buf_length(buf) != offset) {
281+
/* not the first session so update the existing length */
282+
len += get_unaligned_be32(&buf->data[offset]);
283+
put_unaligned_be32(len, &buf->data[offset]);
284+
} else {
285+
tpm_buf_append_u32(buf, len);
286+
}
287+
/* auth handle */
288+
tpm_buf_append_u32(buf, TPM2_RS_PW);
289+
/* nonce */
290+
tpm_buf_append_u16(buf, 0);
291+
/* attributes */
292+
tpm_buf_append_u8(buf, 0);
293+
/* passphrase */
294+
tpm_buf_append_u16(buf, passphrase_len);
295+
tpm_buf_append(buf, passphrase, passphrase_len);
296+
}
297+
275298
/**
276299
* tpm_buf_append_hmac_session() - Append a TPM session element
277300
* @chip: the TPM chip structure
@@ -309,26 +332,8 @@ void tpm_buf_append_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf,
309332
#endif
310333

311334
if (!tpm2_chip_auth(chip)) {
312-
/* offset tells us where the sessions area begins */
313-
int offset = buf->handles * 4 + TPM_HEADER_SIZE;
314-
u32 len = 9 + passphrase_len;
315-
316-
if (tpm_buf_length(buf) != offset) {
317-
/* not the first session so update the existing length */
318-
len += get_unaligned_be32(&buf->data[offset]);
319-
put_unaligned_be32(len, &buf->data[offset]);
320-
} else {
321-
tpm_buf_append_u32(buf, len);
322-
}
323-
/* auth handle */
324-
tpm_buf_append_u32(buf, TPM2_RS_PW);
325-
/* nonce */
326-
tpm_buf_append_u16(buf, 0);
327-
/* attributes */
328-
tpm_buf_append_u8(buf, 0);
329-
/* passphrase */
330-
tpm_buf_append_u16(buf, passphrase_len);
331-
tpm_buf_append(buf, passphrase, passphrase_len);
335+
tpm_buf_append_auth(chip, buf, attributes, passphrase,
336+
passphrase_len);
332337
return;
333338
}
334339

@@ -948,10 +953,13 @@ static int tpm2_load_null(struct tpm_chip *chip, u32 *null_key)
948953
/* Deduce from the name change TPM interference: */
949954
dev_err(&chip->dev, "null key integrity check failed\n");
950955
tpm2_flush_context(chip, tmp_null_key);
951-
chip->flags |= TPM_CHIP_FLAG_DISABLE;
952956

953957
err:
954-
return rc ? -ENODEV : 0;
958+
if (rc) {
959+
chip->flags |= TPM_CHIP_FLAG_DISABLE;
960+
rc = -ENODEV;
961+
}
962+
return rc;
955963
}
956964

957965
/**

include/linux/tpm.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,7 @@ void tpm_buf_append_u32(struct tpm_buf *buf, const u32 value);
421421
u8 tpm_buf_read_u8(struct tpm_buf *buf, off_t *offset);
422422
u16 tpm_buf_read_u16(struct tpm_buf *buf, off_t *offset);
423423
u32 tpm_buf_read_u32(struct tpm_buf *buf, off_t *offset);
424+
void tpm_buf_append_handle(struct tpm_chip *chip, struct tpm_buf *buf, u32 handle);
424425

425426
/*
426427
* Check if TPM device is in the firmware upgrade mode.
@@ -505,6 +506,8 @@ void tpm_buf_append_name(struct tpm_chip *chip, struct tpm_buf *buf,
505506
void tpm_buf_append_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf,
506507
u8 attributes, u8 *passphrase,
507508
int passphraselen);
509+
void tpm_buf_append_auth(struct tpm_chip *chip, struct tpm_buf *buf,
510+
u8 attributes, u8 *passphrase, int passphraselen);
508511
static inline void tpm_buf_append_hmac_session_opt(struct tpm_chip *chip,
509512
struct tpm_buf *buf,
510513
u8 attributes,

0 commit comments

Comments
 (0)