summaryrefslogtreecommitdiff
path: root/src/drivers
diff options
context:
space:
mode:
authorSergii Dmytruk <sergii.dmytruk@3mdeb.com>2022-11-02 00:50:03 +0200
committerMartin L Roth <gaumless@gmail.com>2024-03-28 15:18:04 +0000
commit47e9e8cde1810ee9f249027b14ee9f82a7a52d84 (patch)
tree77771e49f8121bebb1b5904940ff7abf2714dccb /src/drivers
parent094a051732341d20e82c349ea10f85faea6e58d1 (diff)
security/tpm: replace CONFIG(TPMx) checks with runtime check
This prepares the code for enabling both CONFIG_TPM1 and CONFIG_TPM2 during compilation, in which case actual TPM family in use can be determined at runtime. In some places both compile-time and runtime checks are necessary. Yet in places like probe functions runtime state checks don't make sense as runtime state is defined by results of probing. Change-Id: Id9cc25aad8d1d7bfad12b7a92059b1b3641bbfa9 Ticket: https://ticket.coreboot.org/issues/433 Signed-off-by: Sergii Dmytruk <sergii.dmytruk@3mdeb.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/69161 Reviewed-by: Jérémy Compostella <jeremy.compostella@intel.com> Reviewed-by: Julius Werner <jwerner@chromium.org> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Diffstat (limited to 'src/drivers')
-rw-r--r--src/drivers/crb/tis.c3
-rw-r--r--src/drivers/crb/tpm.c26
-rw-r--r--src/drivers/crb/tpm.h1
-rw-r--r--src/drivers/pc80/tpm/tis.c2
-rw-r--r--src/drivers/tpm/ppi.c34
5 files changed, 57 insertions, 9 deletions
diff --git a/src/drivers/crb/tis.c b/src/drivers/crb/tis.c
index 21a7647108..04e255aa7f 100644
--- a/src/drivers/crb/tis.c
+++ b/src/drivers/crb/tis.c
@@ -142,6 +142,9 @@ static int smbios_write_type43_tpm(struct device *dev, int *handle, unsigned lon
uint32_t fw_ver1, fw_ver2;
uint8_t major_spec_ver, minor_spec_ver;
+ if (tlcl_get_family() == TPM_1)
+ return 0;
+
tpm2_get_info(&info);
/* If any of these have invalid values, assume TPM not present or disabled */
diff --git a/src/drivers/crb/tpm.c b/src/drivers/crb/tpm.c
index 4e9f6f2d2b..b568dcc7f4 100644
--- a/src/drivers/crb/tpm.c
+++ b/src/drivers/crb/tpm.c
@@ -320,3 +320,29 @@ void tpm2_get_info(struct tpm2_info *tpm2_info)
tpm2_info->device_id = (interfaceReg >> 32) & 0xFFFF;
tpm2_info->revision = (interfaceReg >> 24) & 0xFF;
}
+
+/*
+ * tpm2_has_crb_active
+ *
+ * Checks that CRB interface is available and active.
+ *
+ * The body was derived from crb_probe() which unlike this function can also
+ * write to registers.
+ */
+bool tpm2_has_crb_active(void)
+{
+ uint64_t tpmStatus = read64(CRB_REG(0, CRB_REG_INTF_ID));
+ printk(BIOS_SPEW, "Interface ID Reg. %llx\n", tpmStatus);
+
+ if ((tpmStatus & CRB_INTF_REG_CAP_CRB) == 0) {
+ printk(BIOS_DEBUG, "TPM: CRB Interface is not supported.\n");
+ return false;
+ }
+
+ if ((tpmStatus & (0xf)) != 1) {
+ printk(BIOS_DEBUG, "TPM: CRB Interface is not active.\n");
+ return false;
+ }
+
+ return true;
+}
diff --git a/src/drivers/crb/tpm.h b/src/drivers/crb/tpm.h
index 7b25e78b3b..60020c3ff9 100644
--- a/src/drivers/crb/tpm.h
+++ b/src/drivers/crb/tpm.h
@@ -64,3 +64,4 @@ tpm_result_t tpm2_init(void);
void tpm2_get_info(struct tpm2_info *tpm2_info);
size_t tpm2_process_command(const void *tpm2_command, size_t command_size,
void *tpm2_response, size_t max_response);
+bool tpm2_has_crb_active(void);
diff --git a/src/drivers/pc80/tpm/tis.c b/src/drivers/pc80/tpm/tis.c
index da443d3a09..568065c654 100644
--- a/src/drivers/pc80/tpm/tis.c
+++ b/src/drivers/pc80/tpm/tis.c
@@ -809,7 +809,7 @@ static void lpc_tpm_fill_ssdt(const struct device *dev)
acpigen_write_scope(path);
acpigen_write_device(acpi_device_name(dev));
- if (CONFIG(TPM2)) {
+ if (tlcl_get_family() == TPM_2) {
acpigen_write_name_string("_HID", "MSFT0101");
acpigen_write_name_string("_CID", "MSFT0101");
} else {
diff --git a/src/drivers/tpm/ppi.c b/src/drivers/tpm/ppi.c
index 6f12b411ba..d63b8f811b 100644
--- a/src/drivers/tpm/ppi.c
+++ b/src/drivers/tpm/ppi.c
@@ -5,6 +5,7 @@
#include <acpi/acpi_device.h>
#include <cbmem.h>
#include <console/console.h>
+#include <security/tpm/tss.h>
#include "tpm_ppi.h"
@@ -35,6 +36,8 @@ static void set_package_element_name(const char *package_name, unsigned int elem
/* PPI function is passed in src_op. Converted to Local2. Clobbers Local1 and Local2 */
static void verify_supported_ppi(uint8_t src_op)
{
+ enum tpm_family family = tlcl_get_family();
+
/*
* Old OSes incorrectly pass a Buffer instead of a Package.
* See TCG Physical Presence Interface Specification Chapter 8.1.2 for details.
@@ -62,7 +65,7 @@ static void verify_supported_ppi(uint8_t src_op)
acpigen_write_store();
acpigen_emit_namestring("^FSUP");
acpigen_emit_byte(LOCAL2_OP);
- acpigen_emit_byte(CONFIG(TPM1) ? ONE_OP : ZERO_OP);
+ acpigen_emit_byte(family == TPM_1 ? ONE_OP : ZERO_OP);
acpigen_emit_byte(LOCAL1_OP);
acpigen_write_if_lequal_op_int(LOCAL1_OP, 0);
@@ -84,7 +87,7 @@ static void verify_supported_ppi(uint8_t src_op)
acpigen_write_store();
acpigen_emit_namestring("^FSUP");
acpigen_emit_byte(LOCAL2_OP);
- acpigen_emit_byte(CONFIG(TPM1) ? ZERO_OP : ONE_OP);
+ acpigen_emit_byte(family == TPM_1 ? ZERO_OP : ONE_OP);
acpigen_emit_byte(LOCAL1_OP);
acpigen_write_if_lequal_op_int(LOCAL1_OP, 1);
@@ -114,7 +117,7 @@ static void tpm_ppi_func0_cb(void *arg)
*/
static void tpm_ppi_func1_cb(void *arg)
{
- if (CONFIG(TPM2))
+ if (tlcl_get_family() == TPM_2)
/* Interface version: 1.3 */
acpigen_write_return_string("1.3");
else
@@ -400,6 +403,8 @@ static void tpm_ppi_func7_cb(void *arg)
*/
static void tpm_ppi_func8_cb(void *arg)
{
+ enum tpm_family family = tlcl_get_family();
+
acpigen_write_to_integer(ARG1_OP, LOCAL0_OP);
/* Revision 1 */
@@ -410,7 +415,7 @@ static void tpm_ppi_func8_cb(void *arg)
acpigen_write_store();
acpigen_emit_namestring("^FSUP");
acpigen_emit_byte(LOCAL2_OP);
- acpigen_emit_byte(CONFIG(TPM1) ? ONE_OP : ZERO_OP);
+ acpigen_emit_byte(family == TPM_1 ? ONE_OP : ZERO_OP);
acpigen_emit_byte(LOCAL1_OP);
acpigen_write_if_lequal_op_int(LOCAL1_OP, 0);
acpigen_write_return_byte(0); /* Not implemented */
@@ -418,7 +423,7 @@ static void tpm_ppi_func8_cb(void *arg)
// FIXME: Only advertise supported functions
- if (CONFIG(TPM1)) {
+ if (family == TPM_1) {
/*
* Some functions do not require PP depending on configuration.
* Those aren't listed here, so the 'required PP' is always set for those.
@@ -434,7 +439,7 @@ static void tpm_ppi_func8_cb(void *arg)
acpigen_write_return_integer(PPI8_RET_ALLOWED);
acpigen_pop_len(); /* Pop : If */
}
- } else if (CONFIG(TPM2)) {
+ } else if (family == TPM_2) {
/*
* Some functions do not require PP depending on configuration.
* Those aren't listed here, so the 'required PP' is always set for those.
@@ -564,6 +569,12 @@ void tpm_ppi_acpi_fill_ssdt(const struct device *dev)
printk(BIOS_DEBUG, "PPI: Pending OS request: 0x%x (0x%x)\n", ppib->pprq, ppib->pprm);
printk(BIOS_DEBUG, "PPI: OS response: CMD 0x%x = 0x%x\n", ppib->lppr, ppib->pprp);
+ enum tpm_family family = tlcl_get_family();
+ if (family == TPM_UNKNOWN) {
+ printk(BIOS_WARN, "PPI: %s: aborting, because no TPM detected\n", __func__);
+ return;
+ }
+
/* Clear unsupported fields */
ppib->next_step = 0;
ppib->ppin = 1; // Not used by ACPI. Read by EDK-2, must be 1.
@@ -574,7 +585,7 @@ void tpm_ppi_acpi_fill_ssdt(const struct device *dev)
bool found = false;
/* Fill in defaults, the TPM command executor may overwrite this list */
memset(ppib->func, 0, sizeof(ppib->func));
- if (CONFIG(TPM1)) {
+ if (family == TPM_1) {
for (size_t i = 0; i < ARRAY_SIZE(tpm1_funcs); i++) {
ppib->func[tpm1_funcs[i]] = 1;
if (ppib->pprq == tpm1_funcs[i])
@@ -706,17 +717,24 @@ void tpm_ppi_acpi_fill_ssdt(const struct device *dev)
void lb_tpm_ppi(struct lb_header *header)
{
struct lb_tpm_physical_presence *tpm_ppi;
+ enum tpm_family family;
void *ppib;
ppib = cbmem_find(CBMEM_ID_TPM_PPI);
if (!ppib)
return;
+ family = tlcl_get_family();
+ if (family == TPM_UNKNOWN) {
+ printk(BIOS_WARN, "PPI: %s: aborting, because no TPM detected\n", __func__);
+ return;
+ }
+
tpm_ppi = (struct lb_tpm_physical_presence *)lb_new_record(header);
tpm_ppi->tag = LB_TAG_TPM_PPI_HANDOFF;
tpm_ppi->size = sizeof(*tpm_ppi);
tpm_ppi->ppi_address = (uintptr_t)ppib;
- tpm_ppi->tpm_version = CONFIG(TPM1) ? LB_TPM_VERSION_TPM_VERSION_1_2 :
+ tpm_ppi->tpm_version = family == TPM_1 ? LB_TPM_VERSION_TPM_VERSION_1_2 :
LB_TPM_VERSION_TPM_VERSION_2;
tpm_ppi->ppi_version = BCD(1, 3);