Merge tag 'tpmdd-next-v6.18-2' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd

Pull tpm updates from Jarkko Sakkinen:

 - Disable TCG_TPM2_HMAC from defconfig

   It causes performance issues, and breaks some atypical
   configurations.

 - simplify code using the new crypto library

 - misc fixes and cleanups

* tag 'tpmdd-next-v6.18-2' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd:
  tpm: Prevent local DOS via tpm/tpm0/ppi/*operations
  tpm: use a map for tpm2_calc_ordinal_duration()
  tpm_tis: Fix incorrect arguments in tpm_tis_probe_irq_single
  tpm: Use HMAC-SHA256 library instead of open-coded HMAC
  tpm: Compare HMAC values in constant time
  tpm: Disable TPM2_TCG_HMAC by default
This commit is contained in:
Linus Torvalds
2025-10-10 08:34:11 -07:00
8 changed files with 137 additions and 199 deletions

View File

@@ -29,10 +29,11 @@ if TCG_TPM
config TCG_TPM2_HMAC
bool "Use HMAC and encrypted transactions on the TPM bus"
default X86_64
default n
select CRYPTO_ECDH
select CRYPTO_LIB_AESCFB
select CRYPTO_LIB_SHA256
select CRYPTO_LIB_UTILS
help
Setting this causes us to deploy a scheme which uses request
and response HMACs in addition to encryption for

View File

@@ -52,7 +52,7 @@ MODULE_PARM_DESC(suspend_pcr,
unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal)
{
if (chip->flags & TPM_CHIP_FLAG_TPM2)
return tpm2_calc_ordinal_duration(chip, ordinal);
return tpm2_calc_ordinal_duration(ordinal);
else
return tpm1_calc_ordinal_duration(chip, ordinal);
}

View File

@@ -299,7 +299,7 @@ ssize_t tpm2_get_tpm_pt(struct tpm_chip *chip, u32 property_id,
ssize_t tpm2_get_pcr_allocation(struct tpm_chip *chip);
int tpm2_auto_startup(struct tpm_chip *chip);
void tpm2_shutdown(struct tpm_chip *chip, u16 shutdown_type);
unsigned long tpm2_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal);
unsigned long tpm2_calc_ordinal_duration(u32 ordinal);
int tpm2_probe(struct tpm_chip *chip);
int tpm2_get_cc_attrs_tbl(struct tpm_chip *chip);
int tpm2_find_cc(struct tpm_chip *chip, u32 cc);

View File

@@ -28,120 +28,57 @@ static struct tpm2_hash tpm2_hash_map[] = {
int tpm2_get_timeouts(struct tpm_chip *chip)
{
/* Fixed timeouts for TPM2 */
chip->timeout_a = msecs_to_jiffies(TPM2_TIMEOUT_A);
chip->timeout_b = msecs_to_jiffies(TPM2_TIMEOUT_B);
chip->timeout_c = msecs_to_jiffies(TPM2_TIMEOUT_C);
chip->timeout_d = msecs_to_jiffies(TPM2_TIMEOUT_D);
/* PTP spec timeouts */
chip->duration[TPM_SHORT] = msecs_to_jiffies(TPM2_DURATION_SHORT);
chip->duration[TPM_MEDIUM] = msecs_to_jiffies(TPM2_DURATION_MEDIUM);
chip->duration[TPM_LONG] = msecs_to_jiffies(TPM2_DURATION_LONG);
/* Key creation commands long timeouts */
chip->duration[TPM_LONG_LONG] =
msecs_to_jiffies(TPM2_DURATION_LONG_LONG);
chip->flags |= TPM_CHIP_FLAG_HAVE_TIMEOUTS;
return 0;
}
/**
* tpm2_ordinal_duration_index() - returns an index to the chip duration table
* @ordinal: TPM command ordinal.
*
* The function returns an index to the chip duration table
* (enum tpm_duration), that describes the maximum amount of
* time the chip could take to return the result for a particular ordinal.
*
* The values of the MEDIUM, and LONG durations are taken
* from the PC Client Profile (PTP) specification (750, 2000 msec)
*
* LONG_LONG is for commands that generates keys which empirically takes
* a longer time on some systems.
*
* Return:
* * TPM_MEDIUM
* * TPM_LONG
* * TPM_LONG_LONG
* * TPM_UNDEFINED
/*
* Contains the maximum durations in milliseconds for TPM2 commands.
*/
static u8 tpm2_ordinal_duration_index(u32 ordinal)
{
switch (ordinal) {
/* Startup */
case TPM2_CC_STARTUP: /* 144 */
return TPM_MEDIUM;
case TPM2_CC_SELF_TEST: /* 143 */
return TPM_LONG;
case TPM2_CC_GET_RANDOM: /* 17B */
return TPM_LONG;
case TPM2_CC_SEQUENCE_UPDATE: /* 15C */
return TPM_MEDIUM;
case TPM2_CC_SEQUENCE_COMPLETE: /* 13E */
return TPM_MEDIUM;
case TPM2_CC_EVENT_SEQUENCE_COMPLETE: /* 185 */
return TPM_MEDIUM;
case TPM2_CC_HASH_SEQUENCE_START: /* 186 */
return TPM_MEDIUM;
case TPM2_CC_VERIFY_SIGNATURE: /* 177 */
return TPM_LONG_LONG;
case TPM2_CC_PCR_EXTEND: /* 182 */
return TPM_MEDIUM;
case TPM2_CC_HIERARCHY_CONTROL: /* 121 */
return TPM_LONG;
case TPM2_CC_HIERARCHY_CHANGE_AUTH: /* 129 */
return TPM_LONG;
case TPM2_CC_GET_CAPABILITY: /* 17A */
return TPM_MEDIUM;
case TPM2_CC_NV_READ: /* 14E */
return TPM_LONG;
case TPM2_CC_CREATE_PRIMARY: /* 131 */
return TPM_LONG_LONG;
case TPM2_CC_CREATE: /* 153 */
return TPM_LONG_LONG;
case TPM2_CC_CREATE_LOADED: /* 191 */
return TPM_LONG_LONG;
default:
return TPM_UNDEFINED;
}
}
static const struct {
unsigned long ordinal;
unsigned long duration;
} tpm2_ordinal_duration_map[] = {
{TPM2_CC_STARTUP, 750},
{TPM2_CC_SELF_TEST, 3000},
{TPM2_CC_GET_RANDOM, 2000},
{TPM2_CC_SEQUENCE_UPDATE, 750},
{TPM2_CC_SEQUENCE_COMPLETE, 750},
{TPM2_CC_EVENT_SEQUENCE_COMPLETE, 750},
{TPM2_CC_HASH_SEQUENCE_START, 750},
{TPM2_CC_VERIFY_SIGNATURE, 30000},
{TPM2_CC_PCR_EXTEND, 750},
{TPM2_CC_HIERARCHY_CONTROL, 2000},
{TPM2_CC_HIERARCHY_CHANGE_AUTH, 2000},
{TPM2_CC_GET_CAPABILITY, 750},
{TPM2_CC_NV_READ, 2000},
{TPM2_CC_CREATE_PRIMARY, 30000},
{TPM2_CC_CREATE, 30000},
{TPM2_CC_CREATE_LOADED, 30000},
};
/**
* tpm2_calc_ordinal_duration() - calculate the maximum command duration
* @chip: TPM chip to use.
* tpm2_calc_ordinal_duration() - Calculate the maximum command duration
* @ordinal: TPM command ordinal.
*
* The function returns the maximum amount of time the chip could take
* to return the result for a particular ordinal in jiffies.
*
* Return: A maximal duration time for an ordinal in jiffies.
* Returns the maximum amount of time the chip is expected by kernel to
* take in jiffies.
*/
unsigned long tpm2_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal)
unsigned long tpm2_calc_ordinal_duration(u32 ordinal)
{
unsigned int index;
int i;
index = tpm2_ordinal_duration_index(ordinal);
for (i = 0; i < ARRAY_SIZE(tpm2_ordinal_duration_map); i++)
if (ordinal == tpm2_ordinal_duration_map[i].ordinal)
return msecs_to_jiffies(tpm2_ordinal_duration_map[i].duration);
if (index != TPM_UNDEFINED)
return chip->duration[index];
else
return msecs_to_jiffies(TPM2_DURATION_DEFAULT);
return msecs_to_jiffies(TPM2_DURATION_DEFAULT);
}
struct tpm2_pcr_read_out {
__be32 update_cnt;
__be32 pcr_selects_cnt;

View File

@@ -69,8 +69,8 @@
#include <linux/unaligned.h>
#include <crypto/kpp.h>
#include <crypto/ecdh.h>
#include <crypto/hash.h>
#include <crypto/hmac.h>
#include <crypto/sha2.h>
#include <crypto/utils.h>
/* maximum number of names the TPM must remember for authorization */
#define AUTH_MAX_NAMES 3
@@ -384,51 +384,6 @@ EXPORT_SYMBOL_GPL(tpm_buf_append_hmac_session);
static int tpm2_create_primary(struct tpm_chip *chip, u32 hierarchy,
u32 *handle, u8 *name);
/*
* It turns out the crypto hmac(sha256) is hard for us to consume
* because it assumes a fixed key and the TPM seems to change the key
* on every operation, so we weld the hmac init and final functions in
* here to give it the same usage characteristics as a regular hash
*/
static void tpm2_hmac_init(struct sha256_ctx *sctx, u8 *key, u32 key_len)
{
u8 pad[SHA256_BLOCK_SIZE];
int i;
sha256_init(sctx);
for (i = 0; i < sizeof(pad); i++) {
if (i < key_len)
pad[i] = key[i];
else
pad[i] = 0;
pad[i] ^= HMAC_IPAD_VALUE;
}
sha256_update(sctx, pad, sizeof(pad));
}
static void tpm2_hmac_final(struct sha256_ctx *sctx, u8 *key, u32 key_len,
u8 *out)
{
u8 pad[SHA256_BLOCK_SIZE];
int i;
for (i = 0; i < sizeof(pad); i++) {
if (i < key_len)
pad[i] = key[i];
else
pad[i] = 0;
pad[i] ^= HMAC_OPAD_VALUE;
}
/* collect the final hash; use out as temporary storage */
sha256_final(sctx, out);
sha256_init(sctx);
sha256_update(sctx, pad, sizeof(pad));
sha256_update(sctx, out, SHA256_DIGEST_SIZE);
sha256_final(sctx, out);
}
/*
* assume hash sha256 and nonces u, v of size SHA256_DIGEST_SIZE but
* otherwise standard tpm2_KDFa. Note output is in bytes not bits.
@@ -440,16 +395,16 @@ static void tpm2_KDFa(u8 *key, u32 key_len, const char *label, u8 *u,
const __be32 bits = cpu_to_be32(bytes * 8);
while (bytes > 0) {
struct sha256_ctx sctx;
struct hmac_sha256_ctx hctx;
__be32 c = cpu_to_be32(counter);
tpm2_hmac_init(&sctx, key, key_len);
sha256_update(&sctx, (u8 *)&c, sizeof(c));
sha256_update(&sctx, label, strlen(label)+1);
sha256_update(&sctx, u, SHA256_DIGEST_SIZE);
sha256_update(&sctx, v, SHA256_DIGEST_SIZE);
sha256_update(&sctx, (u8 *)&bits, sizeof(bits));
tpm2_hmac_final(&sctx, key, key_len, out);
hmac_sha256_init_usingrawkey(&hctx, key, key_len);
hmac_sha256_update(&hctx, (u8 *)&c, sizeof(c));
hmac_sha256_update(&hctx, label, strlen(label) + 1);
hmac_sha256_update(&hctx, u, SHA256_DIGEST_SIZE);
hmac_sha256_update(&hctx, v, SHA256_DIGEST_SIZE);
hmac_sha256_update(&hctx, (u8 *)&bits, sizeof(bits));
hmac_sha256_final(&hctx, out);
bytes -= SHA256_DIGEST_SIZE;
counter++;
@@ -593,6 +548,7 @@ void tpm_buf_fill_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf)
u32 attrs;
u8 cphash[SHA256_DIGEST_SIZE];
struct sha256_ctx sctx;
struct hmac_sha256_ctx hctx;
if (!auth)
return;
@@ -704,14 +660,14 @@ void tpm_buf_fill_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf)
sha256_final(&sctx, cphash);
/* now calculate the hmac */
tpm2_hmac_init(&sctx, auth->session_key, sizeof(auth->session_key)
+ auth->passphrase_len);
sha256_update(&sctx, cphash, sizeof(cphash));
sha256_update(&sctx, auth->our_nonce, sizeof(auth->our_nonce));
sha256_update(&sctx, auth->tpm_nonce, sizeof(auth->tpm_nonce));
sha256_update(&sctx, &auth->attrs, 1);
tpm2_hmac_final(&sctx, auth->session_key, sizeof(auth->session_key)
+ auth->passphrase_len, hmac);
hmac_sha256_init_usingrawkey(&hctx, auth->session_key,
sizeof(auth->session_key) +
auth->passphrase_len);
hmac_sha256_update(&hctx, cphash, sizeof(cphash));
hmac_sha256_update(&hctx, auth->our_nonce, sizeof(auth->our_nonce));
hmac_sha256_update(&hctx, auth->tpm_nonce, sizeof(auth->tpm_nonce));
hmac_sha256_update(&hctx, &auth->attrs, 1);
hmac_sha256_final(&hctx, hmac);
}
EXPORT_SYMBOL(tpm_buf_fill_hmac_session);
@@ -751,6 +707,7 @@ int tpm_buf_check_hmac_response(struct tpm_chip *chip, struct tpm_buf *buf,
u8 rphash[SHA256_DIGEST_SIZE];
u32 attrs, cc;
struct sha256_ctx sctx;
struct hmac_sha256_ctx hctx;
u16 tag = be16_to_cpu(head->tag);
int parm_len, len, i, handles;
@@ -820,21 +777,20 @@ int tpm_buf_check_hmac_response(struct tpm_chip *chip, struct tpm_buf *buf,
sha256_final(&sctx, rphash);
/* now calculate the hmac */
tpm2_hmac_init(&sctx, auth->session_key, sizeof(auth->session_key)
+ auth->passphrase_len);
sha256_update(&sctx, rphash, sizeof(rphash));
sha256_update(&sctx, auth->tpm_nonce, sizeof(auth->tpm_nonce));
sha256_update(&sctx, auth->our_nonce, sizeof(auth->our_nonce));
sha256_update(&sctx, &auth->attrs, 1);
hmac_sha256_init_usingrawkey(&hctx, auth->session_key,
sizeof(auth->session_key) +
auth->passphrase_len);
hmac_sha256_update(&hctx, rphash, sizeof(rphash));
hmac_sha256_update(&hctx, auth->tpm_nonce, sizeof(auth->tpm_nonce));
hmac_sha256_update(&hctx, auth->our_nonce, sizeof(auth->our_nonce));
hmac_sha256_update(&hctx, &auth->attrs, 1);
/* we're done with the rphash, so put our idea of the hmac there */
tpm2_hmac_final(&sctx, auth->session_key, sizeof(auth->session_key)
+ auth->passphrase_len, rphash);
if (memcmp(rphash, &buf->data[offset_s], SHA256_DIGEST_SIZE) == 0) {
rc = 0;
} else {
hmac_sha256_final(&hctx, rphash);
if (crypto_memneq(rphash, &buf->data[offset_s], SHA256_DIGEST_SIZE)) {
dev_err(&chip->dev, "TPM: HMAC check failed\n");
goto out;
}
rc = 0;
/* now do response decryption */
if (auth->attrs & TPM2_SA_ENCRYPT) {

View File

@@ -33,6 +33,20 @@ static const guid_t tpm_ppi_guid =
GUID_INIT(0x3DDDFAA6, 0x361B, 0x4EB4,
0xA4, 0x24, 0x8D, 0x10, 0x08, 0x9D, 0x16, 0x53);
static const char * const tpm_ppi_info[] = {
"Not implemented",
"BIOS only",
"Blocked for OS by system firmware",
"User required",
"User not required",
};
/* A spinlock to protect access to the cache from concurrent reads */
static DEFINE_MUTEX(tpm_ppi_lock);
static u32 ppi_operations_cache[PPI_VS_REQ_END + 1];
static bool ppi_cache_populated;
static bool tpm_ppi_req_has_parameter(u64 req)
{
return req == 23;
@@ -277,8 +291,7 @@ cleanup:
return status;
}
static ssize_t show_ppi_operations(acpi_handle dev_handle, char *buf, u32 start,
u32 end)
static ssize_t cache_ppi_operations(acpi_handle dev_handle, char *buf)
{
int i;
u32 ret;
@@ -286,34 +299,22 @@ static ssize_t show_ppi_operations(acpi_handle dev_handle, char *buf, u32 start,
union acpi_object *obj, tmp;
union acpi_object argv = ACPI_INIT_DSM_ARGV4(1, &tmp);
static char *info[] = {
"Not implemented",
"BIOS only",
"Blocked for OS by BIOS",
"User required",
"User not required",
};
if (!acpi_check_dsm(dev_handle, &tpm_ppi_guid, TPM_PPI_REVISION_ID_1,
1 << TPM_PPI_FN_GETOPR))
return -EPERM;
tmp.integer.type = ACPI_TYPE_INTEGER;
for (i = start; i <= end; i++) {
for (i = 0; i <= PPI_VS_REQ_END; i++) {
tmp.integer.value = i;
obj = tpm_eval_dsm(dev_handle, TPM_PPI_FN_GETOPR,
ACPI_TYPE_INTEGER, &argv,
TPM_PPI_REVISION_ID_1);
if (!obj) {
if (!obj)
return -ENOMEM;
} else {
ret = obj->integer.value;
ACPI_FREE(obj);
}
if (ret > 0 && ret < ARRAY_SIZE(info))
len += sysfs_emit_at(buf, len, "%d %d: %s\n",
i, ret, info[ret]);
ret = obj->integer.value;
ppi_operations_cache[i] = ret;
ACPI_FREE(obj);
}
return len;
@@ -324,9 +325,30 @@ static ssize_t tpm_show_ppi_tcg_operations(struct device *dev,
char *buf)
{
struct tpm_chip *chip = to_tpm_chip(dev);
ssize_t len = 0;
u32 ret;
int i;
return show_ppi_operations(chip->acpi_dev_handle, buf, 0,
PPI_TPM_REQ_MAX);
mutex_lock(&tpm_ppi_lock);
if (!ppi_cache_populated) {
len = cache_ppi_operations(chip->acpi_dev_handle, buf);
if (len < 0) {
mutex_unlock(&tpm_ppi_lock);
return len;
}
ppi_cache_populated = true;
}
for (i = 0; i <= PPI_TPM_REQ_MAX; i++) {
ret = ppi_operations_cache[i];
if (ret >= 0 && ret < ARRAY_SIZE(tpm_ppi_info))
len += sysfs_emit_at(buf, len, "%d %d: %s\n",
i, ret, tpm_ppi_info[ret]);
}
mutex_unlock(&tpm_ppi_lock);
return len;
}
static ssize_t tpm_show_ppi_vs_operations(struct device *dev,
@@ -334,9 +356,30 @@ static ssize_t tpm_show_ppi_vs_operations(struct device *dev,
char *buf)
{
struct tpm_chip *chip = to_tpm_chip(dev);
ssize_t len = 0;
u32 ret;
int i;
return show_ppi_operations(chip->acpi_dev_handle, buf, PPI_VS_REQ_START,
PPI_VS_REQ_END);
mutex_lock(&tpm_ppi_lock);
if (!ppi_cache_populated) {
len = cache_ppi_operations(chip->acpi_dev_handle, buf);
if (len < 0) {
mutex_unlock(&tpm_ppi_lock);
return len;
}
ppi_cache_populated = true;
}
for (i = PPI_VS_REQ_START; i <= PPI_VS_REQ_END; i++) {
ret = ppi_operations_cache[i];
if (ret >= 0 && ret < ARRAY_SIZE(tpm_ppi_info))
len += sysfs_emit_at(buf, len, "%d %d: %s\n",
i, ret, tpm_ppi_info[ret]);
}
mutex_unlock(&tpm_ppi_lock);
return len;
}
static DEVICE_ATTR(version, S_IRUGO, tpm_show_ppi_version, NULL);

View File

@@ -978,8 +978,8 @@ restore_irqs:
* will call disable_irq which undoes all of the above.
*/
if (!(chip->flags & TPM_CHIP_FLAG_IRQ)) {
tpm_tis_write8(priv, original_int_vec,
TPM_INT_VECTOR(priv->locality));
tpm_tis_write8(priv, TPM_INT_VECTOR(priv->locality),
original_int_vec);
rc = -1;
}

View File

@@ -228,10 +228,11 @@ enum tpm2_timeouts {
TPM2_TIMEOUT_B = 4000,
TPM2_TIMEOUT_C = 200,
TPM2_TIMEOUT_D = 30,
};
enum tpm2_durations {
TPM2_DURATION_SHORT = 20,
TPM2_DURATION_MEDIUM = 750,
TPM2_DURATION_LONG = 2000,
TPM2_DURATION_LONG_LONG = 300000,
TPM2_DURATION_DEFAULT = 120000,
};