summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/drivers/crb/tis.c6
-rw-r--r--src/drivers/i2c/tpm/cr50.c5
-rw-r--r--src/drivers/i2c/tpm/tis.c4
-rw-r--r--src/drivers/i2c/tpm/tis_atmel.c14
-rw-r--r--src/drivers/i2c/tpm/tpm.c18
-rw-r--r--src/drivers/i2c/tpm/tpm.h3
-rw-r--r--src/drivers/pc80/tpm/tis.c39
-rw-r--r--src/drivers/spi/tpm/tis.c6
-rw-r--r--src/security/tpm/tis.h15
-rw-r--r--src/security/tpm/tss/tcg-1.2/tss.c9
-rw-r--r--src/security/tpm/tss/tcg-2.0/tss.c11
11 files changed, 99 insertions, 31 deletions
diff --git a/src/drivers/crb/tis.c b/src/drivers/crb/tis.c
index a5d7dcc7ed..766ee25d95 100644
--- a/src/drivers/crb/tis.c
+++ b/src/drivers/crb/tis.c
@@ -46,7 +46,7 @@ static tpm_result_t crb_tpm_sendrecv(const uint8_t *sendbuf, size_t sbuf_size, u
return TPM_SUCCESS;
}
-tis_sendrecv_fn tis_probe(void)
+tis_sendrecv_fn tis_probe(enum tpm_family *family)
{
struct tpm2_info info;
@@ -54,6 +54,10 @@ tis_sendrecv_fn tis_probe(void)
if (tpm2_init())
return NULL;
+ /* CRB interface exists only in TPM2 */
+ if (family != NULL)
+ *family = TPM_2;
+
tpm2_get_info(&info);
printk(BIOS_INFO, "Initialized TPM device %s revision %d\n", tis_get_dev_name(&info),
diff --git a/src/drivers/i2c/tpm/cr50.c b/src/drivers/i2c/tpm/cr50.c
index 8462198410..b58fbc8a67 100644
--- a/src/drivers/i2c/tpm/cr50.c
+++ b/src/drivers/i2c/tpm/cr50.c
@@ -424,8 +424,11 @@ static void cr50_vendor_init(struct tpm_chip *chip)
chip->cancel = &cr50_i2c_tis_ready;
}
-tpm_result_t tpm_vendor_probe(unsigned int bus, uint32_t addr)
+tpm_result_t tpm_vendor_probe(unsigned int bus, uint32_t addr, enum tpm_family *family)
{
+ /* cr50 is TPM2 */
+ if (family != NULL)
+ *family = TPM_2;
return TPM_SUCCESS;
}
diff --git a/src/drivers/i2c/tpm/tis.c b/src/drivers/i2c/tpm/tis.c
index 6cb05f0dd7..fd09240494 100644
--- a/src/drivers/i2c/tpm/tis.c
+++ b/src/drivers/i2c/tpm/tis.c
@@ -118,9 +118,9 @@ static tpm_result_t i2c_tpm_sendrecv(const uint8_t *sendbuf, size_t sbuf_size,
return TPM_SUCCESS;
}
-tis_sendrecv_fn tis_probe(void)
+tis_sendrecv_fn tis_probe(enum tpm_family *family)
{
- if (tpm_vendor_probe(CONFIG_DRIVER_TPM_I2C_BUS, CONFIG_DRIVER_TPM_I2C_ADDR))
+ if (tpm_vendor_probe(CONFIG_DRIVER_TPM_I2C_BUS, CONFIG_DRIVER_TPM_I2C_ADDR, family))
return NULL;
if (tpm_vendor_init(&chip, CONFIG_DRIVER_TPM_I2C_BUS, CONFIG_DRIVER_TPM_I2C_ADDR))
diff --git a/src/drivers/i2c/tpm/tis_atmel.c b/src/drivers/i2c/tpm/tis_atmel.c
index 0a29049d95..a0bbf33fc4 100644
--- a/src/drivers/i2c/tpm/tis_atmel.c
+++ b/src/drivers/i2c/tpm/tis_atmel.c
@@ -107,7 +107,19 @@ static tpm_result_t i2c_tis_sendrecv(const uint8_t *sendbuf, size_t sbuf_size,
return TPM_SUCCESS;
}
-tis_sendrecv_fn tis_probe(void)
+tis_sendrecv_fn tis_probe(enum tpm_family *family)
{
+ /*
+ * Can't query version or really anything as the device doesn't support
+ * much through this interface (can't specify address on accesses).
+ *
+ * Hence the assumption is that whatever TPM version is enabled at
+ * compile-time defines what the device supports. The check is written
+ * in a way to give TPM 1 preference even if support for both versions
+ * is compiled in.
+ */
+ if (family != NULL)
+ *family = CONFIG(TPM1) ? TPM_1 : TPM_2;
+
return &i2c_tis_sendrecv;
}
diff --git a/src/drivers/i2c/tpm/tpm.c b/src/drivers/i2c/tpm/tpm.c
index 541eb3aaa0..eb279844e8 100644
--- a/src/drivers/i2c/tpm/tpm.c
+++ b/src/drivers/i2c/tpm/tpm.c
@@ -451,13 +451,29 @@ out_err:
/* Initialization of I2C TPM */
-tpm_result_t tpm_vendor_probe(unsigned int bus, uint32_t addr)
+tpm_result_t tpm_vendor_probe(unsigned int bus, uint32_t addr, enum tpm_family *family)
{
struct stopwatch sw;
uint8_t buf = 0;
int ret;
long sw_run_duration = SLEEP_DURATION_PROBE_MS;
+ /*
+ * Infineon "I2C Protocol Stack Specification v0.20" is supposedly a
+ * simple adoption of the LPC TIS Protocol to the I2C Bus, but looking
+ * at "TCG PC Client Specific TIS" doesn't confirm that and Infineon's
+ * specification isn't publicly available.
+ *
+ * Because it's unknown how to access information about TPM version of
+ * the device in this case, the assumption is that whatever TPM version
+ * is enabled at compile-time defines what the device supports. And
+ * since this driver doesn't appear to be used with TPM 2 devices, the
+ * check is written in a way to give TPM 1 preference even if support
+ * for both versions is compiled in.
+ */
+ if (family != NULL)
+ *family = CONFIG(TPM1) ? TPM_1 : TPM_2;
+
tpm_dev.chip_type = UNKNOWN;
tpm_dev.bus = bus;
tpm_dev.addr = addr;
diff --git a/src/drivers/i2c/tpm/tpm.h b/src/drivers/i2c/tpm/tpm.h
index 628ad4dc69..46935e2495 100644
--- a/src/drivers/i2c/tpm/tpm.h
+++ b/src/drivers/i2c/tpm/tpm.h
@@ -12,6 +12,7 @@
#ifndef __DRIVERS_TPM_SLB9635_I2C_TPM_H__
#define __DRIVERS_TPM_SLB9635_I2C_TPM_H__
+#include <security/tpm/tis.h>
#include <security/tpm/tss_errors.h>
#include <stdint.h>
@@ -51,7 +52,7 @@ struct tpm_chip {
/* ---------- Interface for TPM vendor ------------ */
-tpm_result_t tpm_vendor_probe(unsigned int bus, uint32_t addr);
+tpm_result_t tpm_vendor_probe(unsigned int bus, uint32_t addr, enum tpm_family *family);
tpm_result_t tpm_vendor_init(struct tpm_chip *chip, unsigned int bus, uint32_t dev_addr);
diff --git a/src/drivers/pc80/tpm/tis.c b/src/drivers/pc80/tpm/tis.c
index 90fa32e318..da443d3a09 100644
--- a/src/drivers/pc80/tpm/tis.c
+++ b/src/drivers/pc80/tpm/tis.c
@@ -78,12 +78,6 @@
/* 1 second is plenty for anything TPM does.*/
#define MAX_DELAY_US USECS_PER_SEC
-enum tpm_family {
- TPM_UNKNOWN = 0,
- TPM_1 = 1,
- TPM_2 = 2,
-};
-
/*
* Structures defined below allow creating descriptions of TPM vendor/device
* ID information for run time discovery.
@@ -380,8 +374,10 @@ static tpm_result_t tis_command_ready(u8 locality)
* Returns TPM_SUCCESS on success (the device is found or was found during
* an earlier invocation) or TPM_CB_FAIL if the device is not found.
*/
-static tpm_result_t pc80_tis_probe(void)
+static tpm_result_t pc80_tis_probe(enum tpm_family *family)
{
+ static enum tpm_family tpm_family;
+
const char *device_name = NULL;
const char *vendor_name = NULL;
const struct device_name *dev;
@@ -389,11 +385,13 @@ static tpm_result_t pc80_tis_probe(void)
u16 vid, did;
u8 locality = 0, intf_type;
int i;
- enum tpm_family family;
const char *family_str;
- if (vendor_dev_id)
+ if (vendor_dev_id) {
+ if (family != NULL)
+ *family = tpm_family;
return TPM_SUCCESS; /* Already probed. */
+ }
didvid = tpm_read_did_vid(0);
if (!didvid || (didvid == 0xffffffff)) {
@@ -409,10 +407,10 @@ static tpm_result_t pc80_tis_probe(void)
switch (intf_version) {
case 0:
case 2:
- family = TPM_1;
+ tpm_family = TPM_1;
break;
case 3:
- family = TPM_2;
+ tpm_family = TPM_2;
break;
default:
printf("%s: Unexpected TPM interface version: %d\n", __func__,
@@ -420,7 +418,7 @@ static tpm_result_t pc80_tis_probe(void)
return TPM_CB_PROBE_FAILURE;
}
} else if (intf_type == 0) {
- family = TPM_2;
+ tpm_family = TPM_2;
} else {
printf("%s: Unexpected TPM interface type: %d\n", __func__, intf_type);
return TPM_CB_PROBE_FAILURE;
@@ -439,7 +437,7 @@ static tpm_result_t pc80_tis_probe(void)
}
dev = &vendor_names[i].dev_names[j];
while (dev->dev_id != 0xffff) {
- if (dev->dev_id == did && dev->family == family) {
+ if (dev->dev_id == did && dev->family == tpm_family) {
device_name = dev->dev_name;
break;
}
@@ -449,7 +447,7 @@ static tpm_result_t pc80_tis_probe(void)
break;
}
- family_str = (family == TPM_1 ? "TPM 1.2" : "TPM 2.0");
+ family_str = (tpm_family == TPM_1 ? "TPM 1.2" : "TPM 2.0");
if (vendor_name == NULL) {
printk(BIOS_INFO, "Found %s 0x%04x by 0x%04x\n", family_str, did, vid);
} else if (device_name == NULL) {
@@ -460,6 +458,8 @@ static tpm_result_t pc80_tis_probe(void)
device_name, did, vendor_name, vid);
}
+ if (family != NULL)
+ *family = tpm_family;
return TPM_SUCCESS;
}
@@ -720,12 +720,15 @@ static tpm_result_t pc80_tpm_sendrecv(const uint8_t *sendbuf, size_t send_size,
/*
* tis_probe()
*
- * Probe for the TPM device and set it up for use within locality 0. Returns
- * pointer to send-receive function on success or NULL on failure.
+ * Probe for the TPM device and set it up for use within locality 0.
+ *
+ * @tpm_family - pointer to tpm_family which is set to TPM family of the device.
+ *
+ * Returns pointer to send-receive function on success or NULL on failure.
*/
-tis_sendrecv_fn tis_probe(void)
+tis_sendrecv_fn tis_probe(enum tpm_family *family)
{
- if (pc80_tis_probe())
+ if (pc80_tis_probe(family))
return NULL;
if (pc80_tis_open())
diff --git a/src/drivers/spi/tpm/tis.c b/src/drivers/spi/tpm/tis.c
index 90d7f59ba9..89ea985da8 100644
--- a/src/drivers/spi/tpm/tis.c
+++ b/src/drivers/spi/tpm/tis.c
@@ -40,7 +40,7 @@ static tpm_result_t tpm_sendrecv(const uint8_t *sendbuf, size_t sbuf_size,
return TPM_SUCCESS;
}
-tis_sendrecv_fn tis_probe(void)
+tis_sendrecv_fn tis_probe(enum tpm_family *family)
{
struct spi_slave spi;
struct tpm2_info info;
@@ -56,6 +56,10 @@ tis_sendrecv_fn tis_probe(void)
return NULL;
}
+ /* tpm2_process_command() is used unconditionally in tpm_sendrecv() */
+ if (family != NULL)
+ *family = TPM_2;
+
tpm2_get_info(&info);
printk(BIOS_INFO, "Initialized TPM device %s revision %d\n",
diff --git a/src/security/tpm/tis.h b/src/security/tpm/tis.h
index ac07bfb5c6..4a8dc14c31 100644
--- a/src/security/tpm/tis.h
+++ b/src/security/tpm/tis.h
@@ -32,6 +32,12 @@ enum tis_status {
TPM_STS_RESPONSE_RETRY = (1 << 1),
};
+enum tpm_family {
+ TPM_UNKNOWN = 0,
+ TPM_1 = 1,
+ TPM_2 = 2,
+};
+
/*
* tis_sendrecv()
*
@@ -50,13 +56,16 @@ typedef tpm_result_t (*tis_sendrecv_fn)(const u8 *sendbuf, size_t send_size, u8
/*
* tis_probe()
*
- * Probe for the TPM device and set it up for use within locality 0. Returns
- * pointer to send-receive function on success or NULL on failure.
+ * Probe for the TPM device and set it up for use within locality 0.
+ *
+ * @family - pointer which is set to TPM family of the device
+ *
+ * Returns pointer to send-receive function on success or NULL on failure.
*
* Do not call this explicitly, it's meant to be used exclusively by TSS
* implementation (tlcl_lib_init() function to be specific).
*/
-tis_sendrecv_fn tis_probe(void);
+tis_sendrecv_fn tis_probe(enum tpm_family *family);
/*
* tis_vendor_write()
diff --git a/src/security/tpm/tss/tcg-1.2/tss.c b/src/security/tpm/tss/tcg-1.2/tss.c
index f0d28dfe3f..913f79b106 100644
--- a/src/security/tpm/tss/tcg-1.2/tss.c
+++ b/src/security/tpm/tss/tcg-1.2/tss.c
@@ -153,13 +153,20 @@ static tpm_result_t send(const uint8_t *command)
tpm_result_t tlcl_lib_init(void)
{
+ enum tpm_family family;
+
if (tis_sendrecv != NULL)
return TPM_SUCCESS;
- tis_sendrecv = tis_probe();
+ tis_sendrecv = tis_probe(&family);
if (tis_sendrecv == NULL)
return TPM_CB_NO_DEVICE;
+ if (family != TPM_1) {
+ tis_sendrecv = NULL;
+ return TPM_CB_INTERNAL_INCONSISTENCY;
+ }
+
return TPM_SUCCESS;
}
diff --git a/src/security/tpm/tss/tcg-2.0/tss.c b/src/security/tpm/tss/tcg-2.0/tss.c
index 135d2964e6..27390a78ab 100644
--- a/src/security/tpm/tss/tcg-2.0/tss.c
+++ b/src/security/tpm/tss/tcg-2.0/tss.c
@@ -211,15 +211,24 @@ tpm_result_t tlcl_clear_control(bool disable)
/* This function is called directly by vboot, uses vboot return types. */
tpm_result_t tlcl_lib_init(void)
{
+ enum tpm_family family;
+
if (tis_sendrecv != NULL)
return TPM_SUCCESS;
- tis_sendrecv = tis_probe();
+ tis_sendrecv = tis_probe(&family);
if (tis_sendrecv == NULL) {
printk(BIOS_ERR, "%s: tis_probe returned error\n", __func__);
return TPM_CB_NO_DEVICE;
}
+ if (family != TPM_2) {
+ tis_sendrecv = NULL;
+ printk(BIOS_ERR, "%s: tis_probe returned unsupported TPM family: %d\n",
+ __func__, family);
+ return TPM_CB_INTERNAL_INCONSISTENCY;
+ }
+
return TPM_SUCCESS;
}