From febf9b9f24f537b88ea5d4845a8d350d94d9e295 Mon Sep 17 00:00:00 2001 From: Sergii Dmytruk Date: Mon, 31 Oct 2022 15:30:15 +0200 Subject: security/tpm: make tis_probe() return tpm_family MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Via an out parameter. This is needed to be able to dynamically pick TSS implementation based on the information discovered on probing. Change-Id: I5006e0cdfef76ff79ce9e1cf280fcd5515ae01b0 Ticket: https://ticket.coreboot.org/issues/433 Signed-off-by: Sergii Dmytruk Reviewed-on: https://review.coreboot.org/c/coreboot/+/69159 Reviewed-by: Martin L Roth Reviewed-by: Jérémy Compostella Reviewed-by: Julius Werner Reviewed-by: Christian Walter Tested-by: build bot (Jenkins) --- src/drivers/i2c/tpm/cr50.c | 5 ++++- src/drivers/i2c/tpm/tis.c | 4 ++-- src/drivers/i2c/tpm/tis_atmel.c | 14 +++++++++++++- src/drivers/i2c/tpm/tpm.c | 18 +++++++++++++++++- src/drivers/i2c/tpm/tpm.h | 3 ++- 5 files changed, 38 insertions(+), 6 deletions(-) (limited to 'src/drivers/i2c') 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 #include #include @@ -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); -- cgit v1.2.3