aboutsummaryrefslogtreecommitdiff
path: root/src/security
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/security
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/security')
-rw-r--r--src/security/tpm/tspi/crtm.h6
-rw-r--r--src/security/tpm/tspi/tspi.c25
-rw-r--r--src/security/tpm/tss.h31
-rw-r--r--src/security/vboot/secdata_tpm.c74
-rw-r--r--src/security/vboot/tpm_common.c4
5 files changed, 82 insertions, 58 deletions
diff --git a/src/security/tpm/tspi/crtm.h b/src/security/tpm/tspi/crtm.h
index 6f5eb2e716..69043e233a 100644
--- a/src/security/tpm/tspi/crtm.h
+++ b/src/security/tpm/tspi/crtm.h
@@ -9,10 +9,8 @@
#include <types.h>
#include <vb2_sha.h>
-#if CONFIG(TPM_LOG_CB) && CONFIG(TPM1)
-# define TPM_MEASURE_ALGO VB2_HASH_SHA1
-#elif CONFIG(TPM_LOG_CB) && CONFIG(TPM2)
-# define TPM_MEASURE_ALGO VB2_HASH_SHA256
+#if CONFIG(TPM_LOG_CB)
+# define TPM_MEASURE_ALGO (tlcl_get_family() == TPM_1 ? VB2_HASH_SHA1 : VB2_HASH_SHA256)
#elif CONFIG(TPM_LOG_TPM1)
# define TPM_MEASURE_ALGO VB2_HASH_SHA1
#elif CONFIG(TPM_LOG_TPM2)
diff --git a/src/security/tpm/tspi/tspi.c b/src/security/tpm/tspi/tspi.c
index 1a0f1d5c88..56b8fa8ede 100644
--- a/src/security/tpm/tspi/tspi.c
+++ b/src/security/tpm/tspi/tspi.c
@@ -17,6 +17,9 @@ static tpm_result_t tpm1_invoke_state_machine(void)
uint8_t deactivated;
tpm_result_t rc = TPM_SUCCESS;
+ if (tlcl_get_family() != TPM_1)
+ return rc;
+
/* Check that the TPM is enabled and activated. */
rc = tlcl1_get_flags(&disabled, &deactivated, NULL);
if (rc != TPM_SUCCESS) {
@@ -199,19 +202,19 @@ tpm_result_t tpm_clear_and_reenable(void)
return rc;
}
-#if CONFIG(TPM1)
- rc = tlcl1_set_enable();
- if (rc != TPM_SUCCESS) {
- printk(BIOS_ERR, "TPM Error (%#x): Can't set enabled state.\n", rc);
- return rc;
- }
+ if (tlcl_get_family() == TPM_1) {
+ rc = tlcl1_set_enable();
+ if (rc != TPM_SUCCESS) {
+ printk(BIOS_ERR, "TPM Error (%#x): Can't set enabled state.\n", rc);
+ return rc;
+ }
- rc = tlcl1_set_deactivated(0);
- if (rc != TPM_SUCCESS) {
- printk(BIOS_ERR, "TPM Error (%#x): Can't set deactivated state.\n", rc);
- return rc;
+ rc = tlcl1_set_deactivated(0);
+ if (rc != TPM_SUCCESS) {
+ printk(BIOS_ERR, "TPM Error (%#x): Can't set deactivated state.\n", rc);
+ return rc;
+ }
}
-#endif
return TPM_SUCCESS;
}
diff --git a/src/security/tpm/tss.h b/src/security/tpm/tss.h
index 3a019ead32..c9aec08262 100644
--- a/src/security/tpm/tss.h
+++ b/src/security/tpm/tss.h
@@ -33,16 +33,31 @@
*/
tpm_result_t tlcl_lib_init(void);
-/* Commands */
+/**
+ * Query active TPM family. Returns TPM_UNKNOWN if uninitialized and TPM_1 or TPM_2 otherwise.
+ */
+static inline enum tpm_family tlcl_get_family(void)
+{
+ /* Defined in tss/tss.c */
+ extern enum tpm_family tlcl_tpm_family;
+
+ if (CONFIG(TPM1) && CONFIG(TPM2))
+ return tlcl_tpm_family;
+ if (CONFIG(TPM1))
+ return TPM_1;
+ if (CONFIG(TPM2))
+ return TPM_2;
+ return TPM_UNKNOWN;
+}
-extern enum tpm_family tlcl_tpm_family;
+/* Commands */
-#define TLCL_CALL(name, ...) do { \
- if (CONFIG(TPM1) && (!CONFIG(TPM2) || tlcl_tpm_family == TPM_1)) \
- return tlcl1_##name(__VA_ARGS__); \
- if (CONFIG(TPM2) && (!CONFIG(TPM1) || tlcl_tpm_family == TPM_2)) \
- return tlcl2_##name(__VA_ARGS__); \
- return TPM_CB_INTERNAL_INCONSISTENCY; \
+#define TLCL_CALL(name, ...) do { \
+ if (tlcl_get_family() == TPM_1) \
+ return tlcl1_##name(__VA_ARGS__); \
+ if (tlcl_get_family() == TPM_2) \
+ return tlcl2_##name(__VA_ARGS__); \
+ return TPM_CB_INTERNAL_INCONSISTENCY; \
} while (0)
/**
diff --git a/src/security/vboot/secdata_tpm.c b/src/security/vboot/secdata_tpm.c
index 21901bb310..f60a5e2ee0 100644
--- a/src/security/vboot/secdata_tpm.c
+++ b/src/security/vboot/secdata_tpm.c
@@ -30,7 +30,7 @@ static tpm_result_t safe_write(uint32_t index, const void *data, uint32_t length
tpm_result_t antirollback_read_space_kernel(struct vb2_context *ctx)
{
- if (!CONFIG(TPM2)) {
+ if (tlcl_get_family() == TPM_1) {
/*
* Before reading the kernel space, verify its permissions. If
* the kernel space has the wrong permission, we give up. This
@@ -224,12 +224,6 @@ static uint32_t define_space(const char *name, uint32_t index, uint32_t length,
return rc;
}
-/* Nothing special in the TPM2 path yet. */
-static tpm_result_t safe_write(uint32_t index, const void *data, uint32_t length)
-{
- return tlcl_write(index, data, length);
-}
-
static tpm_result_t setup_space(const char *name, uint32_t index, const void *data,
uint32_t length, const TPMA_NV nv_attributes,
const uint8_t *nv_policy, size_t nv_policy_size)
@@ -376,7 +370,7 @@ static tpm_result_t setup_widevine_counter_spaces(void)
return rc;
}
-static tpm_result_t _factory_initialize_tpm(struct vb2_context *ctx)
+static tpm_result_t _factory_initialize_tpm2(struct vb2_context *ctx)
{
RETURN_ON_FAILURE(tlcl_force_clear());
@@ -426,11 +420,6 @@ static tpm_result_t _factory_initialize_tpm(struct vb2_context *ctx)
return TPM_SUCCESS;
}
-tpm_result_t antirollback_lock_space_firmware(void)
-{
- return tlcl2_lock_nv_write(FIRMWARE_NV_INDEX);
-}
-
tpm_result_t antirollback_read_space_mrc_hash(uint32_t index, uint8_t *data, uint32_t size)
{
if (size != HASH_NV_SIZE) {
@@ -521,25 +510,9 @@ tpm_result_t antirollback_write_space_vbios_hash(const uint8_t *data, uint32_t s
return safe_write(VBIOS_CACHE_NV_INDEX, data, size);
}
-#else
+#endif /* CONFIG(TPM2) */
-/**
- * Like tlcl_write(), but checks for write errors due to hitting the 64-write
- * limit and clears the TPM when that happens. This can only happen when the
- * TPM is unowned, so it is OK to clear it (and we really have no choice).
- * This is not expected to happen frequently, but it could happen.
- */
-
-static tpm_result_t safe_write(uint32_t index, const void *data, uint32_t length)
-{
- tpm_result_t rc = tlcl_write(index, data, length);
- if (rc == TPM_MAXNVWRITES) {
- RETURN_ON_FAILURE(tpm_clear_and_reenable());
- return tlcl_write(index, data, length);
- } else {
- return rc;
- }
-}
+#if CONFIG(TPM1)
/**
* Similarly to safe_write(), this ensures we don't fail a DefineSpace because
@@ -558,7 +531,7 @@ static tpm_result_t safe_define_space(uint32_t index, uint32_t perm, uint32_t si
}
}
-static tpm_result_t _factory_initialize_tpm(struct vb2_context *ctx)
+static tpm_result_t _factory_initialize_tpm1(struct vb2_context *ctx)
{
TPM_PERMANENT_FLAGS pflags;
tpm_result_t rc;
@@ -616,12 +589,45 @@ static tpm_result_t _factory_initialize_tpm(struct vb2_context *ctx)
return TPM_SUCCESS;
}
-tpm_result_t antirollback_lock_space_firmware(void)
+#endif /* CONFIG(TPM1) */
+
+static tpm_result_t safe_write(uint32_t index, const void *data, uint32_t length)
{
- return tlcl1_set_global_lock();
+ tpm_result_t rc = tlcl_write(index, data, length);
+ if (tlcl_get_family() == TPM_1 && rc == TPM_MAXNVWRITES) {
+ /**
+ * Clear the TPM on write error due to hitting the 64-write
+ * limit. This can only happen when the TPM is unowned, so it
+ * is OK to clear it (and we really have no choice). This is
+ * not expected to happen frequently, but it could happen.
+ */
+ RETURN_ON_FAILURE(tpm_clear_and_reenable());
+ rc = tlcl_write(index, data, length);
+ }
+ return rc;
}
+static uint32_t _factory_initialize_tpm(struct vb2_context *ctx)
+{
+#if CONFIG(TPM1)
+ if (tlcl_get_family() == TPM_1)
+ return _factory_initialize_tpm1(ctx);
+#endif
+#if CONFIG(TPM2)
+ if (tlcl_get_family() == TPM_2)
+ return _factory_initialize_tpm2(ctx);
#endif
+ return TPM_CB_CORRUPTED_STATE;
+}
+
+uint32_t antirollback_lock_space_firmware(void)
+{
+ if (tlcl_get_family() == TPM_1)
+ return tlcl1_set_global_lock();
+ if (tlcl_get_family() == TPM_2)
+ return tlcl2_lock_nv_write(FIRMWARE_NV_INDEX);
+ return TPM_CB_CORRUPTED_STATE;
+}
/**
* Perform one-time initializations.
diff --git a/src/security/vboot/tpm_common.c b/src/security/vboot/tpm_common.c
index 997c4e9cd9..dedf8dfebc 100644
--- a/src/security/vboot/tpm_common.c
+++ b/src/security/vboot/tpm_common.c
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <security/tpm/tspi.h>
+#include <security/tpm/tss.h>
#include <security/vboot/tpm_common.h>
#include <security/tpm/tss_errors.h>
#include <vb2_api.h>
@@ -43,7 +44,8 @@ tpm_result_t vboot_extend_pcr(struct vb2_context *ctx, int pcr,
*/
_Static_assert(sizeof(buffer) >= VB2_SHA256_DIGEST_SIZE,
"Buffer needs to be able to fit at least a SHA256");
- enum vb2_hash_algorithm algo = CONFIG(TPM1) ? VB2_HASH_SHA1 : VB2_HASH_SHA256;
+ enum vb2_hash_algorithm algo = tlcl_get_family() == TPM_1 ?
+ VB2_HASH_SHA1 : VB2_HASH_SHA256;
switch (which_digest) {
/* SHA1 of (devmode|recmode|keyblock) bits */