mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-23 07:27:30 -04:00
Merge tag 'for-next-tpm-7.2-rc1-fixed' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd
Pull tpm updates from Jarkko Sakkinen: "Only bug fixes" * tag 'for-next-tpm-7.2-rc1-fixed' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd: tpm: fix event_size output in tpm1_binary_bios_measurements_show tpm: tpm_crb_ffa: revert defered_probed when tpm_crb_ffa is built-in tpm: tpm2-sessions: wait for async KPP completion in tpm_buf_append_salt tpm: tpm_tis: Add settle time for some TPMs tpm: tpm_tis: store entire did_vid tpm_crb: Check ACPI_COMPANION() against NULL during probe tpm: tpm_tis_spi: Use wait_woken() in wait_for_tmp_stat() tpm: Initialize name_size_alg for non-NULL name in tpm_buf_append_name() tpm: restore timeout for key creation commands tpm: svsm: constify tpm_chip_ops
This commit is contained in:
@@ -236,12 +236,12 @@ static int tpm1_binary_bios_measurements_show(struct seq_file *m, void *v)
|
||||
|
||||
temp_ptr = (char *) &temp_event;
|
||||
|
||||
for (i = 0; i < (sizeof(struct tcpa_event) - 1) ; i++)
|
||||
for (i = 0; i < sizeof(struct tcpa_event); i++)
|
||||
seq_putc(m, temp_ptr[i]);
|
||||
|
||||
temp_ptr = (char *) v;
|
||||
|
||||
for (i = (sizeof(struct tcpa_event) - 1);
|
||||
for (i = sizeof(struct tcpa_event);
|
||||
i < (sizeof(struct tcpa_event) + temp_event.event_size); i++)
|
||||
seq_putc(m, temp_ptr[i]);
|
||||
|
||||
|
||||
@@ -71,9 +71,9 @@ static const struct {
|
||||
{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_CC_CREATE_PRIMARY, 300000},
|
||||
{TPM2_CC_CREATE, 300000},
|
||||
{TPM2_CC_CREATE_LOADED, 300000},
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -285,11 +285,14 @@ int tpm_buf_append_name(struct tpm_chip *chip, struct tpm_buf *buf,
|
||||
mso == TPM2_MSO_NVRAM) {
|
||||
if (!name) {
|
||||
ret = tpm2_read_public(chip, handle, auth->name[slot]);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
name_size_alg = ret;
|
||||
} else {
|
||||
ret = name_size(name);
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
name_size_alg = ret;
|
||||
} else {
|
||||
if (name) {
|
||||
dev_err(&chip->dev, "handle 0x%08x does not use a name\n",
|
||||
@@ -489,15 +492,17 @@ static void tpm2_KDFe(u8 z[EC_PT_SZ], const char *str, u8 *pt_u, u8 *pt_v,
|
||||
sha256_final(&sctx, out);
|
||||
}
|
||||
|
||||
static void tpm_buf_append_salt(struct tpm_buf *buf, struct tpm_chip *chip,
|
||||
struct tpm2_auth *auth)
|
||||
static int tpm_buf_append_salt(struct tpm_buf *buf, struct tpm_chip *chip,
|
||||
struct tpm2_auth *auth)
|
||||
{
|
||||
struct crypto_kpp *kpp;
|
||||
struct kpp_request *req;
|
||||
DECLARE_CRYPTO_WAIT(wait);
|
||||
struct scatterlist s[2], d[1];
|
||||
struct ecdh p = {0};
|
||||
u8 encoded_key[EC_PT_SZ], *x, *y;
|
||||
unsigned int buf_len;
|
||||
int rc;
|
||||
|
||||
/* secret is two sized points */
|
||||
tpm_buf_append_u16(buf, (EC_PT_SZ + 2)*2);
|
||||
@@ -520,14 +525,15 @@ static void tpm_buf_append_salt(struct tpm_buf *buf, struct tpm_chip *chip,
|
||||
kpp = crypto_alloc_kpp("ecdh-nist-p256", CRYPTO_ALG_INTERNAL, 0);
|
||||
if (IS_ERR(kpp)) {
|
||||
dev_err(&chip->dev, "crypto ecdh allocation failed\n");
|
||||
return;
|
||||
return PTR_ERR(kpp);
|
||||
}
|
||||
|
||||
buf_len = crypto_ecdh_key_len(&p);
|
||||
if (sizeof(encoded_key) < buf_len) {
|
||||
dev_err(&chip->dev, "salt buffer too small needs %d\n",
|
||||
buf_len);
|
||||
goto out;
|
||||
rc = -EINVAL;
|
||||
goto err_free_kpp;
|
||||
}
|
||||
crypto_ecdh_encode_key(encoded_key, buf_len, &p);
|
||||
/* this generates a random private key */
|
||||
@@ -535,11 +541,17 @@ static void tpm_buf_append_salt(struct tpm_buf *buf, struct tpm_chip *chip,
|
||||
|
||||
/* salt is now the public point of this private key */
|
||||
req = kpp_request_alloc(kpp, GFP_KERNEL);
|
||||
if (!req)
|
||||
goto out;
|
||||
if (!req) {
|
||||
rc = -ENOMEM;
|
||||
goto err_free_kpp;
|
||||
}
|
||||
kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
|
||||
crypto_req_done, &wait);
|
||||
kpp_request_set_input(req, NULL, 0);
|
||||
kpp_request_set_output(req, s, EC_PT_SZ*2);
|
||||
crypto_kpp_generate_public_key(req);
|
||||
rc = crypto_wait_req(crypto_kpp_generate_public_key(req), &wait);
|
||||
if (rc)
|
||||
goto err_free_req;
|
||||
/*
|
||||
* we're not done: now we have to compute the shared secret
|
||||
* which is our private key multiplied by the tpm_key public
|
||||
@@ -551,8 +563,9 @@ static void tpm_buf_append_salt(struct tpm_buf *buf, struct tpm_chip *chip,
|
||||
kpp_request_set_input(req, s, EC_PT_SZ*2);
|
||||
sg_init_one(d, auth->salt, EC_PT_SZ);
|
||||
kpp_request_set_output(req, d, EC_PT_SZ);
|
||||
crypto_kpp_compute_shared_secret(req);
|
||||
kpp_request_free(req);
|
||||
rc = crypto_wait_req(crypto_kpp_compute_shared_secret(req), &wait);
|
||||
if (rc)
|
||||
goto err_free_req;
|
||||
|
||||
/*
|
||||
* pass the shared secret through KDFe for salt. Note salt
|
||||
@@ -562,8 +575,16 @@ static void tpm_buf_append_salt(struct tpm_buf *buf, struct tpm_chip *chip,
|
||||
*/
|
||||
tpm2_KDFe(auth->salt, "SECRET", x, chip->null_ec_key_x, auth->salt);
|
||||
|
||||
out:
|
||||
kpp_request_free(req);
|
||||
crypto_free_kpp(kpp);
|
||||
return 0;
|
||||
|
||||
err_free_req:
|
||||
kpp_request_free(req);
|
||||
|
||||
err_free_kpp:
|
||||
crypto_free_kpp(kpp);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1018,7 +1039,12 @@ int tpm2_start_auth_session(struct tpm_chip *chip)
|
||||
tpm_buf_append(&buf, auth->our_nonce, sizeof(auth->our_nonce));
|
||||
|
||||
/* append encrypted salt and squirrel away unencrypted in auth */
|
||||
tpm_buf_append_salt(&buf, chip, auth);
|
||||
rc = tpm_buf_append_salt(&buf, chip, auth);
|
||||
if (rc) {
|
||||
tpm2_flush_context(chip, null_key);
|
||||
tpm_buf_destroy(&buf);
|
||||
goto out;
|
||||
}
|
||||
/* session type (HMAC, audit or policy) */
|
||||
tpm_buf_append_u8(&buf, TPM2_SE_HMAC);
|
||||
|
||||
|
||||
@@ -786,8 +786,8 @@ static int crb_map_pluton(struct device *dev, struct crb_priv *priv,
|
||||
static int crb_acpi_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct acpi_device *device = ACPI_COMPANION(dev);
|
||||
struct acpi_table_tpm2 *buf;
|
||||
struct acpi_device *device;
|
||||
struct crb_priv *priv;
|
||||
struct tpm_chip *chip;
|
||||
struct tpm2_crb_smc *crb_smc;
|
||||
@@ -797,6 +797,10 @@ static int crb_acpi_probe(struct platform_device *pdev)
|
||||
u32 sm;
|
||||
int rc;
|
||||
|
||||
device = ACPI_COMPANION(dev);
|
||||
if (!device)
|
||||
return -ENODEV;
|
||||
|
||||
status = acpi_get_table(ACPI_SIG_TPM2, 1,
|
||||
(struct acpi_table_header **) &buf);
|
||||
if (ACPI_FAILURE(status) || buf->header.length < sizeof(*buf)) {
|
||||
|
||||
@@ -177,23 +177,13 @@ static int tpm_crb_ffa_to_linux_errno(int errno)
|
||||
*/
|
||||
int tpm_crb_ffa_init(void)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (!IS_MODULE(CONFIG_TCG_ARM_CRB_FFA)) {
|
||||
ret = ffa_register(&tpm_crb_ffa_driver);
|
||||
if (ret) {
|
||||
tpm_crb_ffa = ERR_PTR(-ENODEV);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (!tpm_crb_ffa)
|
||||
ret = -ENOENT;
|
||||
return -ENOENT;
|
||||
|
||||
if (IS_ERR_VALUE(tpm_crb_ffa))
|
||||
ret = -ENODEV;
|
||||
return -ENODEV;
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(tpm_crb_ffa_init);
|
||||
|
||||
@@ -405,9 +395,7 @@ static struct ffa_driver tpm_crb_ffa_driver = {
|
||||
.id_table = tpm_crb_ffa_device_id,
|
||||
};
|
||||
|
||||
#ifdef MODULE
|
||||
module_ffa_driver(tpm_crb_ffa_driver);
|
||||
#endif
|
||||
|
||||
MODULE_AUTHOR("Arm");
|
||||
MODULE_DESCRIPTION("TPM CRB FFA driver");
|
||||
|
||||
@@ -49,7 +49,7 @@ static int tpm_svsm_send(struct tpm_chip *chip, u8 *buf, size_t bufsiz,
|
||||
return svsm_vtpm_cmd_response_parse(priv->buffer, buf, bufsiz);
|
||||
}
|
||||
|
||||
static struct tpm_class_ops tpm_chip_ops = {
|
||||
static const struct tpm_class_ops tpm_chip_ops = {
|
||||
.flags = TPM_OPS_AUTO_STARTUP,
|
||||
.send = tpm_svsm_send,
|
||||
};
|
||||
|
||||
@@ -66,8 +66,8 @@ static int wait_for_tpm_stat(struct tpm_chip *chip, u8 mask,
|
||||
bool check_cancel)
|
||||
{
|
||||
struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
|
||||
DEFINE_WAIT_FUNC(wait, woken_wake_function);
|
||||
unsigned long stop;
|
||||
long rc;
|
||||
u8 status;
|
||||
bool canceled = false;
|
||||
u8 sts_mask;
|
||||
@@ -87,23 +87,30 @@ static int wait_for_tpm_stat(struct tpm_chip *chip, u8 mask,
|
||||
/* process status changes with irq support */
|
||||
if (sts_mask) {
|
||||
ret = -ETIME;
|
||||
add_wait_queue(queue, &wait);
|
||||
again:
|
||||
if (wait_for_tpm_stat_cond(chip, sts_mask, check_cancel,
|
||||
&canceled)) {
|
||||
ret = canceled ? -ECANCELED : 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
timeout = stop - jiffies;
|
||||
if ((long)timeout <= 0)
|
||||
return -ETIME;
|
||||
rc = wait_event_interruptible_timeout(*queue,
|
||||
wait_for_tpm_stat_cond(chip, sts_mask, check_cancel,
|
||||
&canceled),
|
||||
timeout);
|
||||
if (rc > 0) {
|
||||
if (canceled)
|
||||
return -ECANCELED;
|
||||
ret = 0;
|
||||
}
|
||||
if (rc == -ERESTARTSYS && freezing(current)) {
|
||||
clear_thread_flag(TIF_SIGPENDING);
|
||||
goto again;
|
||||
goto out;
|
||||
|
||||
if (signal_pending(current)) {
|
||||
if (freezing(current)) {
|
||||
clear_thread_flag(TIF_SIGPENDING);
|
||||
goto again;
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
|
||||
wait_woken(&wait, TASK_INTERRUPTIBLE, timeout);
|
||||
goto again;
|
||||
out:
|
||||
remove_wait_queue(queue, &wait);
|
||||
}
|
||||
|
||||
if (ret)
|
||||
@@ -171,6 +178,9 @@ static int __tpm_tis_relinquish_locality(struct tpm_tis_data *priv, int l)
|
||||
{
|
||||
tpm_tis_write8(priv, TPM_ACCESS(l), TPM_ACCESS_ACTIVE_LOCALITY);
|
||||
|
||||
if (test_bit(TPM_TIS_SETTLE_AFTER_RELINQUISH, &priv->flags))
|
||||
tpm_msleep(TPM_TIMEOUT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -792,9 +802,10 @@ static int probe_itpm(struct tpm_chip *chip)
|
||||
static bool tpm_tis_req_canceled(struct tpm_chip *chip, u8 status)
|
||||
{
|
||||
struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
|
||||
u16 vendor_id = priv->did_vid;
|
||||
|
||||
if (!test_bit(TPM_TIS_DEFAULT_CANCELLATION, &priv->flags)) {
|
||||
switch (priv->manufacturer_id) {
|
||||
switch (vendor_id) {
|
||||
case TPM_VID_WINBOND:
|
||||
return ((status == TPM_STS_VALID) ||
|
||||
(status == (TPM_STS_VALID | TPM_STS_COMMAND_READY)));
|
||||
@@ -1115,7 +1126,8 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
|
||||
const struct tpm_tis_phy_ops *phy_ops,
|
||||
acpi_handle acpi_dev_handle)
|
||||
{
|
||||
u32 vendor;
|
||||
u16 vendor_id;
|
||||
u16 device_id;
|
||||
u32 intfcaps;
|
||||
u32 intmask;
|
||||
u32 clkrun_val;
|
||||
@@ -1148,21 +1160,25 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
|
||||
|
||||
dev_set_drvdata(&chip->dev, priv);
|
||||
|
||||
rc = tpm_tis_read32(priv, TPM_DID_VID(0), &vendor);
|
||||
rc = tpm_tis_read32(priv, TPM_DID_VID(0), &priv->did_vid);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
priv->manufacturer_id = vendor;
|
||||
vendor_id = priv->did_vid;
|
||||
device_id = priv->did_vid >> 16;
|
||||
|
||||
if (priv->manufacturer_id == TPM_VID_ATML &&
|
||||
if (vendor_id == TPM_VID_ATML &&
|
||||
!(chip->flags & TPM_CHIP_FLAG_TPM2)) {
|
||||
priv->timeout_min = TIS_TIMEOUT_MIN_ATML;
|
||||
priv->timeout_max = TIS_TIMEOUT_MAX_ATML;
|
||||
}
|
||||
|
||||
if (priv->manufacturer_id == TPM_VID_IFX)
|
||||
if (vendor_id == TPM_VID_IFX)
|
||||
set_bit(TPM_TIS_STATUS_VALID_RETRY, &priv->flags);
|
||||
|
||||
if (vendor_id == TPM_VID_WINBOND && device_id == 0x00FE)
|
||||
set_bit(TPM_TIS_SETTLE_AFTER_RELINQUISH, &priv->flags);
|
||||
|
||||
if (is_bsw()) {
|
||||
priv->ilb_base_addr = ioremap(INTEL_LEGACY_BLK_BASE_ADDR,
|
||||
ILB_REMAP_SIZE);
|
||||
@@ -1247,9 +1263,9 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
|
||||
if (rc < 0)
|
||||
goto out_err;
|
||||
|
||||
dev_info(dev, "%s TPM (device-id 0x%X, rev-id %d)\n",
|
||||
dev_info(dev, "%s TPM (vendor-id 0x%X, device-id 0x%X, rev-id %d)\n",
|
||||
(chip->flags & TPM_CHIP_FLAG_TPM2) ? "2.0" : "1.2",
|
||||
vendor >> 16, rid);
|
||||
vendor_id, device_id, rid);
|
||||
|
||||
probe = probe_itpm(chip);
|
||||
if (probe < 0) {
|
||||
@@ -1315,6 +1331,9 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
|
||||
|
||||
return 0;
|
||||
out_err:
|
||||
dev_err(dev, "TPM vid 0x%X, did 0x%X init failed with error %d\n",
|
||||
vendor_id, device_id, rc);
|
||||
|
||||
if (chip->ops->clk_enable != NULL)
|
||||
chip->ops->clk_enable(chip, false);
|
||||
|
||||
|
||||
@@ -90,11 +90,12 @@ enum tpm_tis_flags {
|
||||
TPM_TIS_DEFAULT_CANCELLATION = 2,
|
||||
TPM_TIS_IRQ_TESTED = 3,
|
||||
TPM_TIS_STATUS_VALID_RETRY = 4,
|
||||
TPM_TIS_SETTLE_AFTER_RELINQUISH = 5,
|
||||
};
|
||||
|
||||
struct tpm_tis_data {
|
||||
struct tpm_chip *chip;
|
||||
u16 manufacturer_id;
|
||||
u32 did_vid;
|
||||
struct mutex locality_count_mutex;
|
||||
unsigned int locality_count;
|
||||
int locality;
|
||||
|
||||
Reference in New Issue
Block a user