mirror of https://github.com/torvalds/linux.git
Hi,
This pull request for TPM driver contains changes to unify TPM return
code translation between trusted_tpm2 and TPM driver itself. Other than
that the changes are either bug fixes or minor imrovements.
Change log that should explain the previous iterations:
1. "Documentation: tpm-security.rst: change title to section"
https://lore.kernel.org/all/86514a6ab364e01f163470a91cacef120e1b8b47.camel@HansenPartnership.com/
2. "drivers/char/tpm: use min() instead of min_t()"
https://lore.kernel.org/all/20251201161228.3c09d88a@pumpkin/
3. Removed spurious kfree(): https://lore.kernel.org/linux-integrity/aS+K5nO2MP7N+kxQ@ly-workstation/
BR, Jarkko
-----BEGIN PGP SIGNATURE-----
iHUEABYKAB0WIQRE6pSOnaBC00OEHEIaerohdGur0gUCaTComgAKCRAaerohdGur
0t38AQDThfcJhDmgfR3zYo0C8rtNQwM06fnooqsiDjTRHYXu6QEArRKJfR9B/vpN
vIAloxIgIUxQbewBJ1DfxJ7OVO2kGwA=
=hMwZ
-----END PGP SIGNATURE-----
Merge tag 'tpmdd-next-6.19-rc1-v4' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd
Pull tpm updates from Jarkko Sakkinen:
"This contains changes to unify TPM return code translation between
trusted_tpm2 and TPM driver itself. Other than that the changes are
either bug fixes or minor imrovements"
* tag 'tpmdd-next-6.19-rc1-v4' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd:
KEYS: trusted: Use tpm_ret_to_err() in trusted_tpm2
tpm: Use -EPERM as fallback error code in tpm_ret_to_err
tpm: Cap the number of PCR banks
tpm: Remove tpm_find_get_ops
tpm: add WQ_PERCPU to alloc_workqueue users
tpm_crb: add missing loc parameter to kerneldoc
tpm_crb: Fix a spelling mistake
selftests: tpm2: Fix ill defined assertions
This commit is contained in:
commit
028bd4a146
|
|
@ -230,42 +230,6 @@ struct tpm_chip *tpm_default_chip(void)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(tpm_default_chip);
|
||||
|
||||
/**
|
||||
* tpm_find_get_ops() - find and reserve a TPM chip
|
||||
* @chip: a &struct tpm_chip instance, %NULL for the default chip
|
||||
*
|
||||
* Finds a TPM chip and reserves its class device and operations. The chip must
|
||||
* be released with tpm_put_ops() after use.
|
||||
* This function is for internal use only. It supports existing TPM callers
|
||||
* by accepting NULL, but those callers should be converted to pass in a chip
|
||||
* directly.
|
||||
*
|
||||
* Return:
|
||||
* A reserved &struct tpm_chip instance.
|
||||
* %NULL if a chip is not found.
|
||||
* %NULL if the chip is not available.
|
||||
*/
|
||||
struct tpm_chip *tpm_find_get_ops(struct tpm_chip *chip)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (chip) {
|
||||
if (!tpm_try_get_ops(chip))
|
||||
return chip;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
chip = tpm_default_chip();
|
||||
if (!chip)
|
||||
return NULL;
|
||||
rc = tpm_try_get_ops(chip);
|
||||
/* release additional reference we got from tpm_default_chip() */
|
||||
put_device(&chip->dev);
|
||||
if (rc)
|
||||
return NULL;
|
||||
return chip;
|
||||
}
|
||||
|
||||
/**
|
||||
* tpm_dev_release() - free chip memory and the device number
|
||||
* @dev: the character device for the TPM chip
|
||||
|
|
@ -282,7 +246,6 @@ static void tpm_dev_release(struct device *dev)
|
|||
|
||||
kfree(chip->work_space.context_buf);
|
||||
kfree(chip->work_space.session_buf);
|
||||
kfree(chip->allocated_banks);
|
||||
#ifdef CONFIG_TCG_TPM2_HMAC
|
||||
kfree(chip->auth);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -275,7 +275,8 @@ void tpm_common_release(struct file *file, struct file_priv *priv)
|
|||
|
||||
int __init tpm_dev_common_init(void)
|
||||
{
|
||||
tpm_dev_wq = alloc_workqueue("tpm_dev_wq", WQ_MEM_RECLAIM, 0);
|
||||
tpm_dev_wq = alloc_workqueue("tpm_dev_wq", WQ_MEM_RECLAIM | WQ_PERCPU,
|
||||
0);
|
||||
|
||||
return !tpm_dev_wq ? -ENOMEM : 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -313,10 +313,13 @@ int tpm_is_tpm2(struct tpm_chip *chip)
|
|||
{
|
||||
int rc;
|
||||
|
||||
chip = tpm_find_get_ops(chip);
|
||||
if (!chip)
|
||||
return -ENODEV;
|
||||
|
||||
rc = tpm_try_get_ops(chip);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = (chip->flags & TPM_CHIP_FLAG_TPM2) != 0;
|
||||
|
||||
tpm_put_ops(chip);
|
||||
|
|
@ -338,10 +341,13 @@ int tpm_pcr_read(struct tpm_chip *chip, u32 pcr_idx,
|
|||
{
|
||||
int rc;
|
||||
|
||||
chip = tpm_find_get_ops(chip);
|
||||
if (!chip)
|
||||
return -ENODEV;
|
||||
|
||||
rc = tpm_try_get_ops(chip);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
if (chip->flags & TPM_CHIP_FLAG_TPM2)
|
||||
rc = tpm2_pcr_read(chip, pcr_idx, digest, NULL);
|
||||
else
|
||||
|
|
@ -369,10 +375,13 @@ int tpm_pcr_extend(struct tpm_chip *chip, u32 pcr_idx,
|
|||
int rc;
|
||||
int i;
|
||||
|
||||
chip = tpm_find_get_ops(chip);
|
||||
if (!chip)
|
||||
return -ENODEV;
|
||||
|
||||
rc = tpm_try_get_ops(chip);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
for (i = 0; i < chip->nr_allocated_banks; i++) {
|
||||
if (digests[i].alg_id != chip->allocated_banks[i].alg_id) {
|
||||
rc = -EINVAL;
|
||||
|
|
@ -492,10 +501,13 @@ int tpm_get_random(struct tpm_chip *chip, u8 *out, size_t max)
|
|||
if (!out || max > TPM_MAX_RNG_DATA)
|
||||
return -EINVAL;
|
||||
|
||||
chip = tpm_find_get_ops(chip);
|
||||
if (!chip)
|
||||
return -ENODEV;
|
||||
|
||||
rc = tpm_try_get_ops(chip);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
if (chip->flags & TPM_CHIP_FLAG_TPM2)
|
||||
rc = tpm2_get_random(chip, out, max);
|
||||
else
|
||||
|
|
|
|||
|
|
@ -267,7 +267,6 @@ static inline void tpm_msleep(unsigned int delay_msec)
|
|||
int tpm_chip_bootstrap(struct tpm_chip *chip);
|
||||
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);
|
||||
|
||||
struct tpm_chip *tpm_chip_alloc(struct device *dev,
|
||||
const struct tpm_class_ops *ops);
|
||||
|
|
|
|||
|
|
@ -799,11 +799,6 @@ int tpm1_pm_suspend(struct tpm_chip *chip, u32 tpm_suspend_pcr)
|
|||
*/
|
||||
int tpm1_get_pcr_allocation(struct tpm_chip *chip)
|
||||
{
|
||||
chip->allocated_banks = kcalloc(1, sizeof(*chip->allocated_banks),
|
||||
GFP_KERNEL);
|
||||
if (!chip->allocated_banks)
|
||||
return -ENOMEM;
|
||||
|
||||
chip->allocated_banks[0].alg_id = TPM_ALG_SHA1;
|
||||
chip->allocated_banks[0].digest_size = hash_digest_size[HASH_ALGO_SHA1];
|
||||
chip->allocated_banks[0].crypto_id = HASH_ALGO_SHA1;
|
||||
|
|
|
|||
|
|
@ -550,11 +550,9 @@ ssize_t tpm2_get_pcr_allocation(struct tpm_chip *chip)
|
|||
|
||||
nr_possible_banks = be32_to_cpup(
|
||||
(__be32 *)&buf.data[TPM_HEADER_SIZE + 5]);
|
||||
|
||||
chip->allocated_banks = kcalloc(nr_possible_banks,
|
||||
sizeof(*chip->allocated_banks),
|
||||
GFP_KERNEL);
|
||||
if (!chip->allocated_banks) {
|
||||
if (nr_possible_banks > TPM2_MAX_PCR_BANKS) {
|
||||
pr_err("tpm: out of bank capacity: %u > %u\n",
|
||||
nr_possible_banks, TPM2_MAX_PCR_BANKS);
|
||||
rc = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -179,6 +179,7 @@ static int crb_try_pluton_doorbell(struct crb_priv *priv, bool wait_for_complete
|
|||
*
|
||||
* @dev: crb device
|
||||
* @priv: crb private data
|
||||
* @loc: locality
|
||||
*
|
||||
* Write CRB_CTRL_REQ_GO_IDLE to TPM_CRB_CTRL_REQ
|
||||
* The device should respond within TIMEOUT_C by clearing the bit.
|
||||
|
|
@ -233,6 +234,7 @@ static int crb_go_idle(struct tpm_chip *chip)
|
|||
*
|
||||
* @dev: crb device
|
||||
* @priv: crb private data
|
||||
* @loc: locality
|
||||
*
|
||||
* Write CRB_CTRL_REQ_CMD_READY to TPM_CRB_CTRL_REQ
|
||||
* and poll till the device acknowledge it by clearing the bit.
|
||||
|
|
@ -412,7 +414,7 @@ static int crb_do_acpi_start(struct tpm_chip *chip)
|
|||
#ifdef CONFIG_ARM64
|
||||
/*
|
||||
* This is a TPM Command Response Buffer start method that invokes a
|
||||
* Secure Monitor Call to requrest the firmware to execute or cancel
|
||||
* Secure Monitor Call to request the firmware to execute or cancel
|
||||
* a TPM 2.0 command.
|
||||
*/
|
||||
static int tpm_crb_smc_start(struct device *dev, unsigned long func_id)
|
||||
|
|
|
|||
|
|
@ -265,8 +265,7 @@ static u8 tpm_tis_status(struct tpm_chip *chip)
|
|||
|
||||
/*
|
||||
* Dump stack for forensics, as invalid TPM_STS.x could be
|
||||
* potentially triggered by impaired tpm_try_get_ops() or
|
||||
* tpm_find_get_ops().
|
||||
* potentially triggered by impaired tpm_try_get_ops().
|
||||
*/
|
||||
dump_stack();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,9 @@
|
|||
#include <crypto/aes.h>
|
||||
|
||||
#define TPM_DIGEST_SIZE 20 /* Max TPM v1.2 PCR size */
|
||||
#define TPM_MAX_DIGEST_SIZE SHA512_DIGEST_SIZE
|
||||
|
||||
#define TPM2_MAX_DIGEST_SIZE SHA512_DIGEST_SIZE
|
||||
#define TPM2_MAX_PCR_BANKS 8
|
||||
|
||||
struct tpm_chip;
|
||||
struct trusted_key_payload;
|
||||
|
|
@ -68,7 +70,7 @@ enum tpm2_curves {
|
|||
|
||||
struct tpm_digest {
|
||||
u16 alg_id;
|
||||
u8 digest[TPM_MAX_DIGEST_SIZE];
|
||||
u8 digest[TPM2_MAX_DIGEST_SIZE];
|
||||
} __packed;
|
||||
|
||||
struct tpm_bank_info {
|
||||
|
|
@ -189,7 +191,7 @@ struct tpm_chip {
|
|||
unsigned int groups_cnt;
|
||||
|
||||
u32 nr_allocated_banks;
|
||||
struct tpm_bank_info *allocated_banks;
|
||||
struct tpm_bank_info allocated_banks[TPM2_MAX_PCR_BANKS];
|
||||
#ifdef CONFIG_ACPI
|
||||
acpi_handle acpi_dev_handle;
|
||||
char ppi_version[TPM_PPI_VERSION_LEN + 1];
|
||||
|
|
@ -454,8 +456,10 @@ static inline ssize_t tpm_ret_to_err(ssize_t ret)
|
|||
return 0;
|
||||
case TPM2_RC_SESSION_MEMORY:
|
||||
return -ENOMEM;
|
||||
case TPM2_RC_HASH:
|
||||
return -EINVAL;
|
||||
default:
|
||||
return -EFAULT;
|
||||
return -EPERM;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -333,25 +333,19 @@ int tpm2_seal_trusted(struct tpm_chip *chip,
|
|||
}
|
||||
|
||||
blob_len = tpm2_key_encode(payload, options, &buf.data[offset], blob_len);
|
||||
if (blob_len < 0)
|
||||
rc = blob_len;
|
||||
|
||||
out:
|
||||
tpm_buf_destroy(&sized);
|
||||
tpm_buf_destroy(&buf);
|
||||
|
||||
if (rc > 0) {
|
||||
if (tpm2_rc_value(rc) == TPM2_RC_HASH)
|
||||
rc = -EINVAL;
|
||||
else
|
||||
rc = -EPERM;
|
||||
}
|
||||
if (blob_len < 0)
|
||||
rc = blob_len;
|
||||
else
|
||||
if (!rc)
|
||||
payload->blob_len = blob_len;
|
||||
|
||||
out_put:
|
||||
tpm_put_ops(chip);
|
||||
return rc;
|
||||
return tpm_ret_to_err(rc);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -455,10 +449,7 @@ static int tpm2_load_cmd(struct tpm_chip *chip,
|
|||
out:
|
||||
tpm_buf_destroy(&buf);
|
||||
|
||||
if (rc > 0)
|
||||
rc = -EPERM;
|
||||
|
||||
return rc;
|
||||
return tpm_ret_to_err(rc);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -521,8 +512,6 @@ static int tpm2_unseal_cmd(struct tpm_chip *chip,
|
|||
tpm_buf_fill_hmac_session(chip, &buf);
|
||||
rc = tpm_transmit_cmd(chip, &buf, 6, "unsealing");
|
||||
rc = tpm_buf_check_hmac_response(chip, &buf, rc);
|
||||
if (rc > 0)
|
||||
rc = -EPERM;
|
||||
|
||||
if (!rc) {
|
||||
data_len = be16_to_cpup(
|
||||
|
|
@ -555,7 +544,7 @@ static int tpm2_unseal_cmd(struct tpm_chip *chip,
|
|||
|
||||
out:
|
||||
tpm_buf_destroy(&buf);
|
||||
return rc;
|
||||
return tpm_ret_to_err(rc);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -587,6 +576,5 @@ int tpm2_unseal_trusted(struct tpm_chip *chip,
|
|||
|
||||
out:
|
||||
tpm_put_ops(chip);
|
||||
|
||||
return rc;
|
||||
return tpm_ret_to_err(rc);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -437,7 +437,7 @@ class Client:
|
|||
|
||||
def extend_pcr(self, i, dig, bank_alg = TPM2_ALG_SHA1):
|
||||
ds = get_digest_size(bank_alg)
|
||||
assert(ds == len(dig))
|
||||
assert ds == len(dig)
|
||||
|
||||
auth_cmd = AuthCommand()
|
||||
|
||||
|
|
@ -589,7 +589,7 @@ class Client:
|
|||
def seal(self, parent_key, data, auth_value, policy_dig,
|
||||
name_alg = TPM2_ALG_SHA1):
|
||||
ds = get_digest_size(name_alg)
|
||||
assert(not policy_dig or ds == len(policy_dig))
|
||||
assert not policy_dig or ds == len(policy_dig)
|
||||
|
||||
attributes = 0
|
||||
if not policy_dig:
|
||||
|
|
|
|||
Loading…
Reference in New Issue