diff options
author | Sergii Dmytruk <sergii.dmytruk@3mdeb.com> | 2022-11-02 00:50:03 +0200 |
---|---|---|
committer | Martin L Roth <gaumless@gmail.com> | 2024-03-28 15:18:04 +0000 |
commit | 47e9e8cde1810ee9f249027b14ee9f82a7a52d84 (patch) | |
tree | 77771e49f8121bebb1b5904940ff7abf2714dccb /src/security/vboot | |
parent | 094a051732341d20e82c349ea10f85faea6e58d1 (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/vboot')
-rw-r--r-- | src/security/vboot/secdata_tpm.c | 74 | ||||
-rw-r--r-- | src/security/vboot/tpm_common.c | 4 |
2 files changed, 43 insertions, 35 deletions
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 */ |