diff options
author | Sergii Dmytruk <sergii.dmytruk@3mdeb.com> | 2022-10-31 18:41:52 +0200 |
---|---|---|
committer | Martin L Roth <gaumless@gmail.com> | 2024-03-28 15:16:19 +0000 |
commit | 094a051732341d20e82c349ea10f85faea6e58d1 (patch) | |
tree | a6da34deaf0607885577218e0fb950f1bec18034 | |
parent | febf9b9f24f537b88ea5d4845a8d350d94d9e295 (diff) |
security/tpm: resolve conflicts in TSS implementations
No functional changes. Refactor code such that there won't be any
compiler or linker errors if TSS 1.2 and TSS 2.0 were both compiled
in.
One might want to support both TPM families for example if TPM is
pluggable, while currently one has to reflash firmware along with
switching TPM device.
Change-Id: Ia0ea5a917c46ada9fc3274f17240e12bca98db6a
Ticket: https://ticket.coreboot.org/issues/433
Signed-off-by: Sergii Dmytruk <sergii.dmytruk@3mdeb.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/69160
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Julius Werner <jwerner@chromium.org>
-rw-r--r-- | src/drivers/crb/tis.c | 2 | ||||
-rw-r--r-- | src/security/tpm/Makefile.mk | 7 | ||||
-rw-r--r-- | src/security/tpm/tspi/tspi.c | 10 | ||||
-rw-r--r-- | src/security/tpm/tss.h | 182 | ||||
-rw-r--r-- | src/security/tpm/tss/tcg-1.2/tss.c | 110 | ||||
-rw-r--r-- | src/security/tpm/tss/tcg-2.0/tss.c | 120 | ||||
-rw-r--r-- | src/security/tpm/tss/tcg-2.0/tss_marshaling.c | 10 | ||||
-rw-r--r-- | src/security/tpm/tss/tss.c | 39 | ||||
-rw-r--r-- | src/security/tpm/tss/vendor/cr50/cr50.c | 17 | ||||
-rw-r--r-- | src/security/tpm/tss1.h | 94 | ||||
-rw-r--r-- | src/security/tpm/tss2.h | 83 | ||||
-rw-r--r-- | src/security/vboot/secdata_tpm.c | 23 | ||||
-rw-r--r-- | src/soc/amd/common/psp_verstage/psp_verstage.c | 4 | ||||
-rw-r--r-- | src/vendorcode/eltan/security/mboot/mboot.c | 4 | ||||
-rw-r--r-- | src/vendorcode/google/chromeos/tpm2.c | 2 |
15 files changed, 412 insertions, 295 deletions
diff --git a/src/drivers/crb/tis.c b/src/drivers/crb/tis.c index 766ee25d95..21a7647108 100644 --- a/src/drivers/crb/tis.c +++ b/src/drivers/crb/tis.c @@ -120,7 +120,7 @@ static tpm_result_t tpm_get_cap(uint32_t property, uint32_t *value) if (!value) return TPM_CB_INVALID_ARG; - rc = tlcl_get_capability(TPM_CAP_TPM_PROPERTIES, property, 1, &cap_data); + rc = tlcl2_get_capability(TPM_CAP_TPM_PROPERTIES, property, 1, &cap_data); if (rc) return rc; diff --git a/src/security/tpm/Makefile.mk b/src/security/tpm/Makefile.mk index ade9656940..fe16192ff6 100644 --- a/src/security/tpm/Makefile.mk +++ b/src/security/tpm/Makefile.mk @@ -12,6 +12,8 @@ bootblock-y += tss/tcg-1.2/tss.c verstage-y += tss/tcg-1.2/tss.c postcar-y += tss/tcg-1.2/tss.c +all-y += tss/tss.c + ## TSPI ramstage-y += tspi/tspi.c @@ -26,18 +28,23 @@ ifeq ($(CONFIG_TPM2),y) ramstage-y += tss/tcg-2.0/tss_marshaling.c ramstage-y += tss/tcg-2.0/tss.c +ramstage-y += tss/tss.c romstage-y += tss/tcg-2.0/tss_marshaling.c romstage-y += tss/tcg-2.0/tss.c +romstage-y += tss/tss.c verstage-$(CONFIG_VBOOT) += tss/tcg-2.0/tss_marshaling.c verstage-$(CONFIG_VBOOT) += tss/tcg-2.0/tss.c +verstage-$(CONFIG_VBOOT) += tss/tss.c postcar-y += tss/tcg-2.0/tss_marshaling.c postcar-y += tss/tcg-2.0/tss.c +postcar-y += tss/tss.c bootblock-y += tss/tcg-2.0/tss_marshaling.c bootblock-y += tss/tcg-2.0/tss.c +bootblock-y += tss/tss.c ## TSPI diff --git a/src/security/tpm/tspi/tspi.c b/src/security/tpm/tspi/tspi.c index 80f33d59c6..1a0f1d5c88 100644 --- a/src/security/tpm/tspi/tspi.c +++ b/src/security/tpm/tspi/tspi.c @@ -18,7 +18,7 @@ static tpm_result_t tpm1_invoke_state_machine(void) tpm_result_t rc = TPM_SUCCESS; /* Check that the TPM is enabled and activated. */ - rc = tlcl_get_flags(&disabled, &deactivated, NULL); + rc = tlcl1_get_flags(&disabled, &deactivated, NULL); if (rc != TPM_SUCCESS) { printk(BIOS_ERR, "TPM Error (%#x): Can't read capabilities.\n", rc); return rc; @@ -27,7 +27,7 @@ static tpm_result_t tpm1_invoke_state_machine(void) if (disabled) { printk(BIOS_INFO, "TPM: is disabled. Enabling...\n"); - rc = tlcl_set_enable(); + rc = tlcl1_set_enable(); if (rc != TPM_SUCCESS) { printk(BIOS_ERR, "TPM Error (%#x): Can't set enabled state.\n", rc); return rc; @@ -37,7 +37,7 @@ static tpm_result_t tpm1_invoke_state_machine(void) if (!!deactivated != CONFIG(TPM_DEACTIVATE)) { printk(BIOS_INFO, "TPM: Unexpected TPM deactivated state. Toggling...\n"); - rc = tlcl_set_deactivated(!deactivated); + rc = tlcl1_set_deactivated(!deactivated); if (rc != TPM_SUCCESS) { printk(BIOS_ERR, "TPM Error (%#x): Can't toggle deactivated state.\n", rc); @@ -200,13 +200,13 @@ tpm_result_t tpm_clear_and_reenable(void) } #if CONFIG(TPM1) - rc = tlcl_set_enable(); + rc = tlcl1_set_enable(); if (rc != TPM_SUCCESS) { printk(BIOS_ERR, "TPM Error (%#x): Can't set enabled state.\n", rc); return rc; } - rc = tlcl_set_deactivated(0); + rc = tlcl1_set_deactivated(0); if (rc != TPM_SUCCESS) { printk(BIOS_ERR, "TPM Error (%#x): Can't set deactivated state.\n", rc); return rc; diff --git a/src/security/tpm/tss.h b/src/security/tpm/tss.h index 9a5521f086..3a019ead32 100644 --- a/src/security/tpm/tss.h +++ b/src/security/tpm/tss.h @@ -12,110 +12,66 @@ #include <types.h> #include <vb2_sha.h> +#include <security/tpm/tis.h> #include <security/tpm/tss_errors.h> #include <security/tpm/tss/vendor/cr50/cr50.h> - -#if CONFIG(TPM1) - #include <security/tpm/tss/tcg-1.2/tss_structures.h> - -/** - * Define a space with permission [perm]. [index] is the index for the space, - * [size] the usable data size. The TPM error code is returned. - */ -tpm_result_t tlcl_define_space(uint32_t index, uint32_t perm, uint32_t size); - -/** - * Issue a PhysicalEnable. The TPM error code is returned. - */ -tpm_result_t tlcl_set_enable(void); - -/** - * Issue a SetDeactivated. Pass 0 to activate. Returns result code. - */ -tpm_result_t tlcl_set_deactivated(uint8_t flag); - -/** - * Get flags of interest. Pointers for flags you aren't interested in may - * be NULL. The TPM error code is returned. - */ -tpm_result_t tlcl_get_flags(uint8_t *disable, uint8_t *deactivated, - uint8_t *nvlocked); - -/** - * Get the entire set of permanent flags. - */ -tpm_result_t tlcl_get_permanent_flags(TPM_PERMANENT_FLAGS *pflags); - -#endif - -#if CONFIG(TPM2) - #include <security/tpm/tss/tcg-2.0/tss_structures.h> +#include <security/tpm/tss1.h> +#include <security/tpm/tss2.h> /* - * Define a TPM2 space. The define space command TPM command used by the tlcl - * layer offers the ability to use custom nv attributes and policies. - */ -tpm_result_t tlcl_define_space(uint32_t space_index, size_t space_size, - const TPMA_NV nv_attributes, - const uint8_t *nv_policy, size_t nv_policy_size); - -/* - * Issue TPM2_GetCapability command - */ -tpm_result_t tlcl_get_capability(TPM_CAP capability, uint32_t property, - uint32_t property_count, - TPMS_CAPABILITY_DATA *capability_data); - -/* Issue TPM2_NV_SetBits command */ -tpm_result_t tlcl_set_bits(uint32_t index, uint64_t bits); - -/* - * Makes tpm_process_command available for on top implementations of - * custom tpm standards like cr50 + * Operations that are applicable to both TPM versions have wrappers which + * pick the implementation based on version determined during initialization via + * tlcl_lib_init(). + * + * Other operations are defined in tss1.h and tss2.h. */ -void *tpm_process_command(TPM_CC command, void *command_body); - -/* Return digest size of hash algorithm */ -uint16_t tlcl_get_hash_size_from_algo(TPMI_ALG_HASH hash_algo); - -#endif - -/*****************************************************************************/ -/* Generic Functions implemented in tlcl.c */ /** * Call this first. Returns 0 if success, nonzero if error. */ tpm_result_t tlcl_lib_init(void); -/** - * Perform a raw TPM request/response transaction. - */ -tpm_result_t tlcl_send_receive(const uint8_t *request, uint8_t *response, - int max_length); - /* Commands */ +extern enum tpm_family tlcl_tpm_family; + +#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; \ + } while (0) + /** * Send a TPM_Startup(ST_CLEAR). The TPM error code is returned (0 for * success). */ -tpm_result_t tlcl_startup(void); +static inline tpm_result_t tlcl_startup(void) +{ + TLCL_CALL(startup); +} /** * Resume by sending a TPM_Startup(ST_STATE). The TPM error code is returned * (0 for success). */ -tpm_result_t tlcl_resume(void); +static inline tpm_result_t tlcl_resume(void) +{ + TLCL_CALL(resume); +} /** * Save TPM state by sending either TPM_SaveState() (TPM1.2) or * TPM_Shutdown(ST_STATE) (TPM2.0). The TPM error code is returned (0 for * success). */ -tpm_result_t tlcl_save_state(void); +static inline tpm_result_t tlcl_save_state(void) +{ + TLCL_CALL(save_state); +} /** * Run the self test. @@ -123,81 +79,71 @@ tpm_result_t tlcl_save_state(void); * Note---this is synchronous. To run this in parallel with other firmware, * use ContinueSelfTest(). The TPM error code is returned. */ -tpm_result_t tlcl_self_test_full(void); - -/** - * Run the self test in the background. - */ -tpm_result_t tlcl_continue_self_test(void); +static inline tpm_result_t tlcl_self_test_full(void) +{ + TLCL_CALL(self_test_full); +} /** * Write [length] bytes of [data] to space at [index]. The TPM error code is * returned. */ -tpm_result_t tlcl_write(uint32_t index, const void *data, uint32_t length); +static inline tpm_result_t tlcl_write(uint32_t index, const void *data, uint32_t length) +{ + TLCL_CALL(write, index, data, length); +} /** * Read [length] bytes from space at [index] into [data]. The TPM error code * is returned. */ -tpm_result_t tlcl_read(uint32_t index, void *data, uint32_t length); +static inline tpm_result_t tlcl_read(uint32_t index, void *data, uint32_t length) +{ + TLCL_CALL(read, index, data, length); +} /** * Assert physical presence in software. The TPM error code is returned. */ -tpm_result_t tlcl_assert_physical_presence(void); +static inline tpm_result_t tlcl_assert_physical_presence(void) +{ + TLCL_CALL(assert_physical_presence); +} /** * Enable the physical presence command. The TPM error code is returned. */ -tpm_result_t tlcl_physical_presence_cmd_enable(void); +static inline tpm_result_t tlcl_physical_presence_cmd_enable(void) +{ + TLCL_CALL(physical_presence_cmd_enable); +} /** * Finalize the physical presence settings: software PP is enabled, hardware PP * is disabled, and the lifetime lock is set. The TPM error code is returned. */ -tpm_result_t tlcl_finalize_physical_presence(void); - -/** - * Set the nvLocked bit. The TPM error code is returned. - */ -tpm_result_t tlcl_set_nv_locked(void); +static inline tpm_result_t tlcl_finalize_physical_presence(void) +{ + TLCL_CALL(finalize_physical_presence); +} /** * Issue a ForceClear. The TPM error code is returned. */ -tpm_result_t tlcl_force_clear(void); - -/** - * Set Clear Control. The TPM error code is returned. - */ -tpm_result_t tlcl_clear_control(bool disable); - -/** - * Set the bGlobalLock flag, which only a reboot can clear. The TPM error - * code is returned. - */ -tpm_result_t tlcl_set_global_lock(void); - -/** - * Make an NV Ram location read_only. The TPM error code is returned. - */ -tpm_result_t tlcl_lock_nv_write(uint32_t index); +static inline tpm_result_t tlcl_force_clear(void) +{ + TLCL_CALL(force_clear); +} /** * Perform a TPM_Extend. */ -tpm_result_t tlcl_extend(int pcr_num, const uint8_t *digest_data, - enum vb2_hash_algorithm digest_algo); +static inline tpm_result_t tlcl_extend(int pcr_num, const uint8_t *digest_data, + enum vb2_hash_algorithm digest_algo) +{ + TLCL_CALL(extend, pcr_num, digest_data, digest_algo); +} -/** - * Disable platform hierarchy. Specific to TPM2. The TPM error code is returned. - */ -tpm_result_t tlcl_disable_platform_hierarchy(void); - -/** - * Get the permission bits for the NVRAM space with |index|. - */ -tpm_result_t tlcl_get_permissions(uint32_t index, uint32_t *permissions); +extern tis_sendrecv_fn tlcl_tis_sendrecv; #endif /* TSS_H_ */ diff --git a/src/security/tpm/tss/tcg-1.2/tss.c b/src/security/tpm/tss/tcg-1.2/tss.c index 913f79b106..04a02682a9 100644 --- a/src/security/tpm/tss/tcg-1.2/tss.c +++ b/src/security/tpm/tss/tcg-1.2/tss.c @@ -24,8 +24,6 @@ #include <console/console.h> #define VBDEBUG(format, args...) printk(BIOS_DEBUG, format, ## args) -static tis_sendrecv_fn tis_sendrecv; - static tpm_result_t tpm_send_receive(const uint8_t *request, uint32_t request_length, uint8_t *response, @@ -34,12 +32,12 @@ static tpm_result_t tpm_send_receive(const uint8_t *request, size_t len = *response_length; tpm_result_t rc; - if (tis_sendrecv == NULL) { + if (tlcl_tis_sendrecv == NULL) { printk(BIOS_ERR, "Attempted use of uninitialized TSS 1.2 stack\n"); return TPM_FAIL; } - rc = tis_sendrecv(request, request_length, response, &len); + rc = tlcl_tis_sendrecv(request, request_length, response, &len); if (rc) return rc; /* check 64->32bit overflow and (re)check response buffer overflow */ @@ -83,8 +81,8 @@ static inline tpm_result_t tpm_return_code(const uint8_t *buffer) * Like TlclSendReceive below, but do not retry if NEEDS_SELFTEST or * DOING_SELFTEST errors are returned. */ -static tpm_result_t tlcl_send_receive_no_retry(const uint8_t *request, - uint8_t *response, int max_length) +static tpm_result_t tlcl1_send_receive_no_retry(const uint8_t *request, + uint8_t *response, int max_length) { uint32_t response_length = max_length; tpm_result_t rc; @@ -112,21 +110,18 @@ static tpm_result_t tlcl_send_receive_no_retry(const uint8_t *request, /* Sends a TPM command and gets a response. Returns 0 if success or the TPM * error code if error. Waits for the self test to complete if needed. */ -tpm_result_t tlcl_send_receive(const uint8_t *request, uint8_t *response, - int max_length) +tpm_result_t tlcl1_send_receive(const uint8_t *request, uint8_t *response, int max_length) { - tpm_result_t rc = tlcl_send_receive_no_retry(request, response, - max_length); + tpm_result_t rc = tlcl1_send_receive_no_retry(request, response, max_length); /* If the command fails because the self test has not completed, try it * again after attempting to ensure that the self test has completed. */ if (rc == TPM_NEEDS_SELFTEST || rc == TPM_DOING_SELFTEST) { - rc = tlcl_continue_self_test(); + rc = tlcl1_continue_self_test(); if (rc != TPM_SUCCESS) return rc; #if defined(TPM_BLOCKING_CONTINUESELFTEST) || defined(VB_RECOVERY_MODE) /* Retry only once */ - rc = tlcl_send_receive_no_retry(request, response, - max_length); + rc = tlcl1_send_receive_no_retry(request, response, max_length); #else /* This needs serious testing. The TPM specification says: "iii. * The caller MUST wait for the actions of TPM_ContinueSelfTest @@ -134,8 +129,7 @@ tpm_result_t tlcl_send_receive(const uint8_t *request, uint8_t *response, * ContinueSelfTest is non-blocking, how do we know that the * actions have completed other than trying again? */ do { - rc = tlcl_send_receive_no_retry(request, response, - max_length); + rc = tlcl1_send_receive_no_retry(request, response, max_length); } while (rc == TPM_DOING_SELFTEST); #endif } @@ -146,64 +140,45 @@ tpm_result_t tlcl_send_receive(const uint8_t *request, uint8_t *response, static tpm_result_t send(const uint8_t *command) { uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; - return tlcl_send_receive(command, response, sizeof(response)); + return tlcl1_send_receive(command, response, sizeof(response)); } /* Exported functions. */ -tpm_result_t tlcl_lib_init(void) -{ - enum tpm_family family; - - if (tis_sendrecv != NULL) - return TPM_SUCCESS; - - 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; -} - -tpm_result_t tlcl_startup(void) +tpm_result_t tlcl1_startup(void) { VBDEBUG("TPM: Startup\n"); return send(tpm_startup_cmd.buffer); } -tpm_result_t tlcl_resume(void) +tpm_result_t tlcl1_resume(void) { VBDEBUG("TPM: Resume\n"); return send(tpm_resume_cmd.buffer); } -tpm_result_t tlcl_save_state(void) +tpm_result_t tlcl1_save_state(void) { VBDEBUG("TPM: Save state\n"); return send(tpm_savestate_cmd.buffer); } -tpm_result_t tlcl_self_test_full(void) +tpm_result_t tlcl1_self_test_full(void) { VBDEBUG("TPM: Self test full\n"); return send(tpm_selftestfull_cmd.buffer); } -tpm_result_t tlcl_continue_self_test(void) +tpm_result_t tlcl1_continue_self_test(void) { uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; VBDEBUG("TPM: Continue self test\n"); /* Call the No Retry version of SendReceive to avoid recursion. */ - return tlcl_send_receive_no_retry(tpm_continueselftest_cmd.buffer, - response, sizeof(response)); + return tlcl1_send_receive_no_retry(tpm_continueselftest_cmd.buffer, + response, sizeof(response)); } -tpm_result_t tlcl_define_space(uint32_t index, uint32_t perm, uint32_t size) +tpm_result_t tlcl1_define_space(uint32_t index, uint32_t perm, uint32_t size) { struct s_tpm_nv_definespace_cmd cmd; VBDEBUG("TPM: TlclDefineSpace(%#x, %#x, %d)\n", index, perm, size); @@ -214,7 +189,7 @@ tpm_result_t tlcl_define_space(uint32_t index, uint32_t perm, uint32_t size) return send(cmd.buffer); } -tpm_result_t tlcl_write(uint32_t index, const void *data, uint32_t length) +tpm_result_t tlcl1_write(uint32_t index, const void *data, uint32_t length) { struct s_tpm_nv_write_cmd cmd; uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; @@ -231,10 +206,10 @@ tpm_result_t tlcl_write(uint32_t index, const void *data, uint32_t length) if (length > 0) memcpy(cmd.buffer + tpm_nv_write_cmd.data, data, length); - return tlcl_send_receive(cmd.buffer, response, sizeof(response)); + return tlcl1_send_receive(cmd.buffer, response, sizeof(response)); } -tpm_result_t tlcl_read(uint32_t index, void *data, uint32_t length) +tpm_result_t tlcl1_read(uint32_t index, void *data, uint32_t length) { struct s_tpm_nv_read_cmd cmd; uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; @@ -246,7 +221,7 @@ tpm_result_t tlcl_read(uint32_t index, void *data, uint32_t length) to_tpm_uint32(cmd.buffer + tpm_nv_read_cmd.index, index); to_tpm_uint32(cmd.buffer + tpm_nv_read_cmd.length, length); - rc = tlcl_send_receive(cmd.buffer, response, sizeof(response)); + rc = tlcl1_send_receive(cmd.buffer, response, sizeof(response)); if (rc == TPM_SUCCESS && length > 0) { uint8_t *nv_read_cursor = response + kTpmResponseHeaderLength; from_tpm_uint32(nv_read_cursor, &result_length); @@ -259,43 +234,43 @@ tpm_result_t tlcl_read(uint32_t index, void *data, uint32_t length) return rc; } -tpm_result_t tlcl_assert_physical_presence(void) +tpm_result_t tlcl1_assert_physical_presence(void) { VBDEBUG("TPM: Asserting physical presence\n"); return send(tpm_ppassert_cmd.buffer); } -tpm_result_t tlcl_physical_presence_cmd_enable(void) +tpm_result_t tlcl1_physical_presence_cmd_enable(void) { VBDEBUG("TPM: Enable the physical presence command\n"); return send(tpm_ppenable_cmd.buffer); } -tpm_result_t tlcl_finalize_physical_presence(void) +tpm_result_t tlcl1_finalize_physical_presence(void) { VBDEBUG("TPM: Enable PP cmd, disable HW pp, and set lifetime lock\n"); return send(tpm_finalizepp_cmd.buffer); } -tpm_result_t tlcl_set_nv_locked(void) +tpm_result_t tlcl1_set_nv_locked(void) { VBDEBUG("TPM: Set NV locked\n"); - return tlcl_define_space(TPM_NV_INDEX_LOCK, 0, 0); + return tlcl1_define_space(TPM_NV_INDEX_LOCK, 0, 0); } -tpm_result_t tlcl_force_clear(void) +tpm_result_t tlcl1_force_clear(void) { VBDEBUG("TPM: Force clear\n"); return send(tpm_forceclear_cmd.buffer); } -tpm_result_t tlcl_set_enable(void) +tpm_result_t tlcl1_set_enable(void) { VBDEBUG("TPM: Enabling TPM\n"); return send(tpm_physicalenable_cmd.buffer); } -tpm_result_t tlcl_set_deactivated(uint8_t flag) +tpm_result_t tlcl1_set_deactivated(uint8_t flag) { struct s_tpm_physicalsetdeactivated_cmd cmd; VBDEBUG("TPM: SetDeactivated(%d)\n", flag); @@ -304,12 +279,12 @@ tpm_result_t tlcl_set_deactivated(uint8_t flag) return send(cmd.buffer); } -tpm_result_t tlcl_get_permanent_flags(TPM_PERMANENT_FLAGS *pflags) +tpm_result_t tlcl1_get_permanent_flags(TPM_PERMANENT_FLAGS *pflags) { uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; uint32_t size; - tpm_result_t rc = tlcl_send_receive(tpm_getflags_cmd.buffer, response, - sizeof(response)); + tpm_result_t rc = + tlcl1_send_receive(tpm_getflags_cmd.buffer, response, sizeof(response)); if (rc != TPM_SUCCESS) return rc; from_tpm_uint32(response + kTpmResponseHeaderLength, &size); @@ -320,11 +295,10 @@ tpm_result_t tlcl_get_permanent_flags(TPM_PERMANENT_FLAGS *pflags) return rc; } -tpm_result_t tlcl_get_flags(uint8_t *disable, uint8_t *deactivated, - uint8_t *nvlocked) +tpm_result_t tlcl1_get_flags(uint8_t *disable, uint8_t *deactivated, uint8_t *nvlocked) { TPM_PERMANENT_FLAGS pflags; - tpm_result_t rc = tlcl_get_permanent_flags(&pflags); + tpm_result_t rc = tlcl1_get_permanent_flags(&pflags); if (rc == TPM_SUCCESS) { if (disable) *disable = pflags.disable; @@ -338,14 +312,14 @@ tpm_result_t tlcl_get_flags(uint8_t *disable, uint8_t *deactivated, return rc; } -tpm_result_t tlcl_set_global_lock(void) +tpm_result_t tlcl1_set_global_lock(void) { VBDEBUG("TPM: Set global lock\n"); - return tlcl_write(TPM_NV_INDEX0, NULL, 0); + return tlcl1_write(TPM_NV_INDEX0, NULL, 0); } -tpm_result_t tlcl_extend(int pcr_num, const uint8_t *digest_data, - enum vb2_hash_algorithm digest_algo) +tpm_result_t tlcl1_extend(int pcr_num, const uint8_t *digest_data, + enum vb2_hash_algorithm digest_algo) { struct s_tpm_extend_cmd cmd; uint8_t response[kTpmResponseHeaderLength + kPcrDigestLength]; @@ -357,10 +331,10 @@ tpm_result_t tlcl_extend(int pcr_num, const uint8_t *digest_data, to_tpm_uint32(cmd.buffer + tpm_extend_cmd.pcrNum, pcr_num); memcpy(cmd.buffer + cmd.inDigest, digest_data, kPcrDigestLength); - return tlcl_send_receive(cmd.buffer, response, sizeof(response)); + return tlcl1_send_receive(cmd.buffer, response, sizeof(response)); } -tpm_result_t tlcl_get_permissions(uint32_t index, uint32_t *permissions) +tpm_result_t tlcl1_get_permissions(uint32_t index, uint32_t *permissions) { struct s_tpm_getpermissions_cmd cmd; uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; @@ -370,7 +344,7 @@ tpm_result_t tlcl_get_permissions(uint32_t index, uint32_t *permissions) memcpy(&cmd, &tpm_getpermissions_cmd, sizeof(cmd)); to_tpm_uint32(cmd.buffer + tpm_getpermissions_cmd.index, index); - rc = tlcl_send_receive(cmd.buffer, response, sizeof(response)); + rc = tlcl1_send_receive(cmd.buffer, response, sizeof(response)); if (rc != TPM_SUCCESS) return rc; diff --git a/src/security/tpm/tss/tcg-2.0/tss.c b/src/security/tpm/tss/tcg-2.0/tss.c index 27390a78ab..282845e44c 100644 --- a/src/security/tpm/tss/tcg-2.0/tss.c +++ b/src/security/tpm/tss/tcg-2.0/tss.c @@ -16,9 +16,7 @@ * TPM2 specification. */ -static tis_sendrecv_fn tis_sendrecv; - -void *tpm_process_command(TPM_CC command, void *command_body) +void *tlcl2_process_command(TPM_CC command, void *command_body) { struct obuf ob; struct ibuf ib; @@ -28,7 +26,7 @@ void *tpm_process_command(TPM_CC command, void *command_body) /* Command/response buffer. */ static uint8_t cr_buffer[TPM_BUFFER_SIZE]; - if (tis_sendrecv == NULL) { + if (tlcl_tis_sendrecv == NULL) { printk(BIOS_ERR, "Attempted use of uninitialized TSS 2.0 stack\n"); return NULL; } @@ -43,7 +41,7 @@ void *tpm_process_command(TPM_CC command, void *command_body) sendb = obuf_contents(&ob, &out_size); in_size = sizeof(cr_buffer); - if (tis_sendrecv(sendb, out_size, cr_buffer, &in_size)) { + if (tlcl_tis_sendrecv(sendb, out_size, cr_buffer, &in_size)) { printk(BIOS_ERR, "tpm transaction failed\n"); return NULL; } @@ -53,13 +51,13 @@ void *tpm_process_command(TPM_CC command, void *command_body) return tpm_unmarshal_response(command, &ib); } -static tpm_result_t tlcl_send_startup(TPM_SU type) +static tpm_result_t tlcl2_send_startup(TPM_SU type) { struct tpm2_startup startup; struct tpm2_response *response; startup.startup_type = type; - response = tpm_process_command(TPM2_Startup, &startup); + response = tlcl2_process_command(TPM2_Startup, &startup); /* IO error, tpm2_response pointer is empty. */ if (!response) { @@ -82,18 +80,18 @@ static tpm_result_t tlcl_send_startup(TPM_SU type) return TPM_IOERROR; } -tpm_result_t tlcl_resume(void) +tpm_result_t tlcl2_resume(void) { - return tlcl_send_startup(TPM_SU_STATE); + return tlcl2_send_startup(TPM_SU_STATE); } -static tpm_result_t tlcl_send_shutdown(TPM_SU type) +static tpm_result_t tlcl2_send_shutdown(TPM_SU type) { struct tpm2_shutdown shutdown; struct tpm2_response *response; shutdown.shutdown_type = type; - response = tpm_process_command(TPM2_Shutdown, &shutdown); + response = tlcl2_process_command(TPM2_Shutdown, &shutdown); /* IO error, tpm2_response pointer is empty. */ if (!response) { @@ -111,12 +109,12 @@ static tpm_result_t tlcl_send_shutdown(TPM_SU type) return TPM_IOERROR; } -tpm_result_t tlcl_save_state(void) +tpm_result_t tlcl2_save_state(void) { - return tlcl_send_shutdown(TPM_SU_STATE); + return tlcl2_send_shutdown(TPM_SU_STATE); } -tpm_result_t tlcl_assert_physical_presence(void) +tpm_result_t tlcl2_assert_physical_presence(void) { /* * Nothing to do on TPM2 for this, use platform hierarchy availability @@ -142,8 +140,12 @@ static TPM_ALG_ID tpmalg_from_vb2_hash(enum vb2_hash_algorithm hash_type) } } -tpm_result_t tlcl_extend(int pcr_num, const uint8_t *digest_data, - enum vb2_hash_algorithm digest_type) +/* + * The caller will provide the digest in a 32 byte buffer, let's consider it a + * sha256 digest. + */ +tpm_result_t tlcl2_extend(int pcr_num, const uint8_t *digest_data, + enum vb2_hash_algorithm digest_type) { struct tpm2_pcr_extend_cmd pcr_ext_cmd; struct tpm2_response *response; @@ -160,7 +162,7 @@ tpm_result_t tlcl_extend(int pcr_num, const uint8_t *digest_data, memcpy(pcr_ext_cmd.digests.digests[0].digest.sha512, digest_data, vb2_digest_size(digest_type)); - response = tpm_process_command(TPM2_PCR_Extend, &pcr_ext_cmd); + response = tlcl2_process_command(TPM2_PCR_Extend, &pcr_ext_cmd); printk(BIOS_INFO, "%s: response is %#x\n", __func__, response ? response->hdr.tpm_code : -1); @@ -170,18 +172,18 @@ tpm_result_t tlcl_extend(int pcr_num, const uint8_t *digest_data, return TPM_SUCCESS; } -tpm_result_t tlcl_finalize_physical_presence(void) +tpm_result_t tlcl2_finalize_physical_presence(void) { /* Nothing needs to be done with tpm2. */ printk(BIOS_INFO, "%s:%s:%d\n", __FILE__, __func__, __LINE__); return TPM_SUCCESS; } -tpm_result_t tlcl_force_clear(void) +tpm_result_t tlcl2_force_clear(void) { struct tpm2_response *response; - response = tpm_process_command(TPM2_Clear, NULL); + response = tlcl2_process_command(TPM2_Clear, NULL); printk(BIOS_INFO, "%s: response is %#x\n", __func__, response ? response->hdr.tpm_code : -1); @@ -191,16 +193,16 @@ tpm_result_t tlcl_force_clear(void) return TPM_SUCCESS; } -tpm_result_t tlcl_clear_control(bool disable) +tpm_result_t tlcl2_clear_control(bool disable) { struct tpm2_response *response; struct tpm2_clear_control_cmd cc = { .disable = 0, }; - response = tpm_process_command(TPM2_ClearControl, &cc); + response = tlcl2_process_command(TPM2_ClearControl, &cc); printk(BIOS_INFO, "%s: response is %#x\n", - __func__, response ? response->hdr.tpm_code : -1); + __func__, response ? response->hdr.tpm_code : -1); if (!response || response->hdr.tpm_code) return TPM_IOERROR; @@ -208,37 +210,13 @@ tpm_result_t tlcl_clear_control(bool disable) return TPM_SUCCESS; } -/* 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(&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; -} - -tpm_result_t tlcl_physical_presence_cmd_enable(void) +tpm_result_t tlcl2_physical_presence_cmd_enable(void) { printk(BIOS_INFO, "%s:%s:%d\n", __FILE__, __func__, __LINE__); return TPM_SUCCESS; } -tpm_result_t tlcl_read(uint32_t index, void *data, uint32_t length) +tpm_result_t tlcl2_read(uint32_t index, void *data, uint32_t length) { struct tpm2_nv_read_cmd nv_readc; struct tpm2_response *response; @@ -248,7 +226,7 @@ tpm_result_t tlcl_read(uint32_t index, void *data, uint32_t length) nv_readc.nvIndex = HR_NV_INDEX + index; nv_readc.size = length; - response = tpm_process_command(TPM2_NV_Read, &nv_readc); + response = tlcl2_process_command(TPM2_NV_Read, &nv_readc); /* Need to map tpm error codes into internal values. */ if (!response) @@ -287,20 +265,20 @@ tpm_result_t tlcl_read(uint32_t index, void *data, uint32_t length) return TPM_SUCCESS; } -tpm_result_t tlcl_self_test_full(void) +tpm_result_t tlcl2_self_test_full(void) { struct tpm2_self_test st; struct tpm2_response *response; st.yes_no = 1; - response = tpm_process_command(TPM2_SelfTest, &st); + response = tlcl2_process_command(TPM2_SelfTest, &st); printk(BIOS_INFO, "%s: response is %#x\n", __func__, response ? response->hdr.tpm_code : -1); return TPM_SUCCESS; } -tpm_result_t tlcl_lock_nv_write(uint32_t index) +tpm_result_t tlcl2_lock_nv_write(uint32_t index) { struct tpm2_response *response; /* TPM Will reject attempts to write at non-defined index. */ @@ -308,7 +286,7 @@ tpm_result_t tlcl_lock_nv_write(uint32_t index) .nvIndex = HR_NV_INDEX + index, }; - response = tpm_process_command(TPM2_NV_WriteLock, &nv_wl); + response = tlcl2_process_command(TPM2_NV_WriteLock, &nv_wl); printk(BIOS_INFO, "%s: response is %#x\n", __func__, response ? response->hdr.tpm_code : -1); @@ -319,12 +297,12 @@ tpm_result_t tlcl_lock_nv_write(uint32_t index) return TPM_SUCCESS; } -tpm_result_t tlcl_startup(void) +tpm_result_t tlcl2_startup(void) { - return tlcl_send_startup(TPM_SU_CLEAR); + return tlcl2_send_startup(TPM_SU_CLEAR); } -tpm_result_t tlcl_write(uint32_t index, const void *data, uint32_t length) +tpm_result_t tlcl2_write(uint32_t index, const void *data, uint32_t length) { struct tpm2_nv_write_cmd nv_writec; struct tpm2_response *response; @@ -335,7 +313,7 @@ tpm_result_t tlcl_write(uint32_t index, const void *data, uint32_t length) nv_writec.data.t.size = length; nv_writec.data.t.buffer = data; - response = tpm_process_command(TPM2_NV_Write, &nv_writec); + response = tlcl2_process_command(TPM2_NV_Write, &nv_writec); printk(BIOS_INFO, "%s: response is %#x\n", __func__, response ? response->hdr.tpm_code : -1); @@ -347,7 +325,7 @@ tpm_result_t tlcl_write(uint32_t index, const void *data, uint32_t length) return TPM_SUCCESS; } -tpm_result_t tlcl_set_bits(uint32_t index, uint64_t bits) +tpm_result_t tlcl2_set_bits(uint32_t index, uint64_t bits) { struct tpm2_nv_setbits_cmd nvsb_cmd; struct tpm2_response *response; @@ -358,7 +336,7 @@ tpm_result_t tlcl_set_bits(uint32_t index, uint64_t bits) nvsb_cmd.nvIndex = HR_NV_INDEX + index; nvsb_cmd.bits = bits; - response = tpm_process_command(TPM2_NV_SetBits, &nvsb_cmd); + response = tlcl2_process_command(TPM2_NV_SetBits, &nvsb_cmd); printk(BIOS_INFO, "%s: response is %#x\n", __func__, response ? response->hdr.tpm_code : -1); @@ -370,9 +348,9 @@ tpm_result_t tlcl_set_bits(uint32_t index, uint64_t bits) return TPM_SUCCESS; } -tpm_result_t tlcl_define_space(uint32_t space_index, size_t space_size, - const TPMA_NV nv_attributes, - const uint8_t *nv_policy, size_t nv_policy_size) +tpm_result_t tlcl2_define_space(uint32_t space_index, size_t space_size, + const TPMA_NV nv_attributes, + const uint8_t *nv_policy, size_t nv_policy_size) { struct tpm2_nv_define_space_cmd nvds_cmd; struct tpm2_response *response; @@ -395,7 +373,7 @@ tpm_result_t tlcl_define_space(uint32_t space_index, size_t space_size, nvds_cmd.publicInfo.authPolicy.t.size = nv_policy_size; } - response = tpm_process_command(TPM2_NV_DefineSpace, &nvds_cmd); + response = tlcl2_process_command(TPM2_NV_DefineSpace, &nvds_cmd); printk(BIOS_INFO, "%s: response is %#x\n", __func__, response ? response->hdr.tpm_code : -1); @@ -413,7 +391,7 @@ tpm_result_t tlcl_define_space(uint32_t space_index, size_t space_size, } } -uint16_t tlcl_get_hash_size_from_algo(TPMI_ALG_HASH hash_algo) +uint16_t tlcl2_get_hash_size_from_algo(TPMI_ALG_HASH hash_algo) { uint16_t value; @@ -445,7 +423,7 @@ uint16_t tlcl_get_hash_size_from_algo(TPMI_ALG_HASH hash_algo) return value; } -tpm_result_t tlcl_disable_platform_hierarchy(void) +tpm_result_t tlcl2_disable_platform_hierarchy(void) { struct tpm2_response *response; struct tpm2_hierarchy_control_cmd hc = { @@ -453,7 +431,7 @@ tpm_result_t tlcl_disable_platform_hierarchy(void) .state = 0, }; - response = tpm_process_command(TPM2_Hierarchy_Control, &hc); + response = tlcl2_process_command(TPM2_Hierarchy_Control, &hc); if (!response || response->hdr.tpm_code) return TPM_CB_INTERNAL_INCONSISTENCY; @@ -461,9 +439,9 @@ tpm_result_t tlcl_disable_platform_hierarchy(void) return TPM_SUCCESS; } -tpm_result_t tlcl_get_capability(TPM_CAP capability, uint32_t property, - uint32_t property_count, - TPMS_CAPABILITY_DATA *capability_data) +tpm_result_t tlcl2_get_capability(TPM_CAP capability, uint32_t property, + uint32_t property_count, + TPMS_CAPABILITY_DATA *capability_data) { struct tpm2_get_capability cmd; struct tpm2_response *response; @@ -478,7 +456,7 @@ tpm_result_t tlcl_get_capability(TPM_CAP capability, uint32_t property, return TPM_IOERROR; } - response = tpm_process_command(TPM2_GetCapability, &cmd); + response = tlcl2_process_command(TPM2_GetCapability, &cmd); if (!response) { printk(BIOS_ERR, "%s: Command Failed\n", __func__); diff --git a/src/security/tpm/tss/tcg-2.0/tss_marshaling.c b/src/security/tpm/tss/tcg-2.0/tss_marshaling.c index 5ade6395bb..3039a8b8ba 100644 --- a/src/security/tpm/tss/tcg-2.0/tss_marshaling.c +++ b/src/security/tpm/tss/tcg-2.0/tss_marshaling.c @@ -79,23 +79,23 @@ static int marshal_TPMT_HA(struct obuf *ob, const TPMT_HA *tpmtha) switch (tpmtha->hashAlg) { case TPM_ALG_SHA1: rc |= obuf_write(ob, tpmtha->digest.sha1, - tlcl_get_hash_size_from_algo(tpmtha->hashAlg)); + tlcl2_get_hash_size_from_algo(tpmtha->hashAlg)); break; case TPM_ALG_SHA256: rc |= obuf_write(ob, tpmtha->digest.sha256, - tlcl_get_hash_size_from_algo(tpmtha->hashAlg)); + tlcl2_get_hash_size_from_algo(tpmtha->hashAlg)); break; case TPM_ALG_SM3_256: rc |= obuf_write(ob, tpmtha->digest.sm3_256, - tlcl_get_hash_size_from_algo(tpmtha->hashAlg)); + tlcl2_get_hash_size_from_algo(tpmtha->hashAlg)); break; case TPM_ALG_SHA384: rc |= obuf_write(ob, tpmtha->digest.sha384, - tlcl_get_hash_size_from_algo(tpmtha->hashAlg)); + tlcl2_get_hash_size_from_algo(tpmtha->hashAlg)); break; case TPM_ALG_SHA512: rc |= obuf_write(ob, tpmtha->digest.sha512, - tlcl_get_hash_size_from_algo(tpmtha->hashAlg)); + tlcl2_get_hash_size_from_algo(tpmtha->hashAlg)); break; default: rc = -1; diff --git a/src/security/tpm/tss/tss.c b/src/security/tpm/tss/tss.c new file mode 100644 index 0000000000..bd0e98582b --- /dev/null +++ b/src/security/tpm/tss/tss.c @@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ + +#include <console/console.h> +#include <security/tpm/tis.h> +#include <security/tpm/tss.h> + +/* + * This unit is meant to dispatch to either TPM1.2 or TPM2.0 TSS implementation + * based on TPM family determined on probing during initialization. + */ + +enum tpm_family tlcl_tpm_family = TPM_UNKNOWN; + +tis_sendrecv_fn tlcl_tis_sendrecv; + +/* Probe for TPM device and choose implementation based on the returned TPM family. */ +tpm_result_t tlcl_lib_init(void) +{ + /* Don't probe for TPM more than once per stage. */ + static bool init_done; + if (init_done) + return tlcl_tpm_family == TPM_UNKNOWN ? TPM_CB_NO_DEVICE : TPM_SUCCESS; + + /* Set right away to make recursion impossible. */ + init_done = true; + + tlcl_tis_sendrecv = tis_probe(&tlcl_tpm_family); + + if (tlcl_tis_sendrecv == NULL) { + printk(BIOS_ERR, "%s: tis_probe failed\n", __func__); + tlcl_tpm_family = TPM_UNKNOWN; + } else if (tlcl_tpm_family != TPM_1 && tlcl_tpm_family != TPM_2) { + printk(BIOS_ERR, "%s: tis_probe returned incorrect TPM family: %d\n", __func__, + tlcl_tpm_family); + tlcl_tpm_family = TPM_UNKNOWN; + } + + return tlcl_tpm_family == TPM_UNKNOWN ? TPM_CB_NO_DEVICE : TPM_SUCCESS; +} diff --git a/src/security/tpm/tss/vendor/cr50/cr50.c b/src/security/tpm/tss/vendor/cr50/cr50.c index 31eab2d5d4..b843afa369 100644 --- a/src/security/tpm/tss/vendor/cr50/cr50.c +++ b/src/security/tpm/tss/vendor/cr50/cr50.c @@ -16,7 +16,7 @@ tpm_result_t tlcl_cr50_enable_nvcommits(void) printk(BIOS_INFO, "Enabling cr50 nvmem commits\n"); - response = tpm_process_command(TPM2_CR50_VENDOR_COMMAND, &sub_command); + response = tlcl2_process_command(TPM2_CR50_VENDOR_COMMAND, &sub_command); if (!response || (response && response->hdr.tpm_code)) { if (response) @@ -39,7 +39,7 @@ tpm_result_t tlcl_cr50_enable_update(uint16_t timeout_ms, printk(BIOS_INFO, "Checking cr50 for pending updates\n"); - response = tpm_process_command(TPM2_CR50_VENDOR_COMMAND, command_body); + response = tlcl2_process_command(TPM2_CR50_VENDOR_COMMAND, command_body); if (!response || response->hdr.tpm_code) return TPM_IOERROR; @@ -55,7 +55,7 @@ tpm_result_t tlcl_cr50_get_recovery_button(uint8_t *recovery_button_state) printk(BIOS_INFO, "Checking cr50 for recovery request\n"); - response = tpm_process_command(TPM2_CR50_VENDOR_COMMAND, &sub_command); + response = tlcl2_process_command(TPM2_CR50_VENDOR_COMMAND, &sub_command); if (!response || response->hdr.tpm_code) return TPM_IOERROR; @@ -72,7 +72,7 @@ tpm_result_t tlcl_cr50_get_tpm_mode(uint8_t *tpm_mode) printk(BIOS_INFO, "Reading cr50 TPM mode\n"); - response = tpm_process_command(TPM2_CR50_VENDOR_COMMAND, &mode_command); + response = tlcl2_process_command(TPM2_CR50_VENDOR_COMMAND, &mode_command); if (!response) return TPM_IOERROR; @@ -112,7 +112,7 @@ tpm_result_t tlcl_cr50_get_boot_mode(uint8_t *boot_mode) printk(BIOS_DEBUG, "Reading cr50 boot mode\n"); - response = tpm_process_command(TPM2_CR50_VENDOR_COMMAND, &mode_command); + response = tlcl2_process_command(TPM2_CR50_VENDOR_COMMAND, &mode_command); if (!response) return TPM_IOERROR; @@ -141,8 +141,7 @@ tpm_result_t tlcl_cr50_immediate_reset(uint16_t timeout_ms) * Issue an immediate reset to the Cr50. */ printk(BIOS_INFO, "Issuing cr50 reset\n"); - response = tpm_process_command(TPM2_CR50_VENDOR_COMMAND, - &reset_command_body); + response = tlcl2_process_command(TPM2_CR50_VENDOR_COMMAND, &reset_command_body); if (!response) return TPM_IOERROR; @@ -157,7 +156,7 @@ tpm_result_t tlcl_cr50_reset_ec(void) printk(BIOS_DEBUG, "Issuing EC reset\n"); - response = tpm_process_command(TPM2_CR50_VENDOR_COMMAND, &reset_cmd); + response = tlcl2_process_command(TPM2_CR50_VENDOR_COMMAND, &reset_cmd); if (!response) return TPM_IOERROR; @@ -183,7 +182,7 @@ tpm_result_t tlcl_cr50_get_factory_config(uint64_t *factory_config) uint16_t factory_config_command = TPM2_CR50_SUB_CMD_GET_FACTORY_CONFIG; *factory_config = 0; - response = tpm_process_command(TPM2_CR50_VENDOR_COMMAND, &factory_config_command); + response = tlcl2_process_command(TPM2_CR50_VENDOR_COMMAND, &factory_config_command); if (!response) return TPM_IOERROR; diff --git a/src/security/tpm/tss1.h b/src/security/tpm/tss1.h new file mode 100644 index 0000000000..9894e80b20 --- /dev/null +++ b/src/security/tpm/tss1.h @@ -0,0 +1,94 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ + +#ifndef TSS1_H_ +#define TSS1_H_ + +#include <types.h> +#include <vb2_sha.h> + +#include <security/tpm/tss/tcg-1.2/tss_structures.h> +#include <security/tpm/tss_errors.h> + +/* + * TPM1.2-specific + * + * Some operations don't have counterparts in standard and are directly exposed + * here. + * + * Other operations are applicable to both TPM versions and have wrappers which + * pick the implementation based on version determined during initialization via + * tlcl_lib_init(). + */ + +/** + * Define a space with permission [perm]. [index] is the index for the space, + * [size] the usable data size. The TPM error code is returned. + */ +tpm_result_t tlcl1_define_space(uint32_t index, uint32_t perm, uint32_t size); + +/** + * Issue a PhysicalEnable. The TPM error code is returned. + */ +tpm_result_t tlcl1_set_enable(void); + +/** + * Issue a SetDeactivated. Pass 0 to activate. Returns result code. + */ +tpm_result_t tlcl1_set_deactivated(uint8_t flag); + +/** + * Get flags of interest. Pointers for flags you aren't interested in may + * be NULL. The TPM error code is returned. + */ +tpm_result_t tlcl1_get_flags(uint8_t *disable, uint8_t *deactivated, uint8_t *nvlocked); + +/** + * Perform a raw TPM request/response transaction. + */ +tpm_result_t tlcl1_send_receive(const uint8_t *request, uint8_t *response, int max_length); + +/** + * Run the self test in the background. + */ +tpm_result_t tlcl1_continue_self_test(void); + +/** + * Set the nvLocked bit. The TPM error code is returned. + */ +tpm_result_t tlcl1_set_nv_locked(void); + +/** + * Get the entire set of permanent flags. + */ +tpm_result_t tlcl1_get_permanent_flags(TPM_PERMANENT_FLAGS *pflags); + +/** + * Set the bGlobalLock flag, which only a reboot can clear. The TPM error + * code is returned. + */ +tpm_result_t tlcl1_set_global_lock(void); + +/** + * Get the permission bits for the NVRAM space with |index|. + */ +tpm_result_t tlcl1_get_permissions(uint32_t index, uint32_t *permissions); + +/* + * Declarations for "private" functions which are dispatched to by tss/tss.c + * based on TPM family. + */ + +tpm_result_t tlcl1_save_state(void); +tpm_result_t tlcl1_resume(void); +tpm_result_t tlcl1_startup(void); +tpm_result_t tlcl1_self_test_full(void); +tpm_result_t tlcl1_read(uint32_t index, void *data, uint32_t length); +tpm_result_t tlcl1_write(uint32_t index, const void *data, uint32_t length); +tpm_result_t tlcl1_assert_physical_presence(void); +tpm_result_t tlcl1_physical_presence_cmd_enable(void); +tpm_result_t tlcl1_finalize_physical_presence(void); +tpm_result_t tlcl1_force_clear(void); +tpm_result_t tlcl1_extend(int pcr_num, const uint8_t *digest_data, + enum vb2_hash_algorithm digest_algo); + +#endif /* TSS1_H_ */ diff --git a/src/security/tpm/tss2.h b/src/security/tpm/tss2.h new file mode 100644 index 0000000000..16ccf5db6f --- /dev/null +++ b/src/security/tpm/tss2.h @@ -0,0 +1,83 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ + +#ifndef TSS2_H_ +#define TSS2_H_ + +#include <types.h> +#include <vb2_sha.h> + +#include <security/tpm/tss/tcg-2.0/tss_structures.h> +#include <security/tpm/tss_errors.h> + +/* + * TPM2-specific + * + * Some operations don't have counterparts in standard and are directly exposed + * here. + * + * Other operations are applicable to both TPM versions and have wrappers which + * pick the implementation based on version determined during initialization via + * tlcl_lib_init(). + */ + +/* + * Define a TPM2 space. The define space command TPM command used by the tlcl + * layer offers the ability to use custom nv attributes and policies. + */ +tpm_result_t tlcl2_define_space(uint32_t space_index, size_t space_size, + const TPMA_NV nv_attributes, + const uint8_t *nv_policy, size_t nv_policy_size); + +/* + * Issue TPM2_GetCapability command + */ +tpm_result_t tlcl2_get_capability(TPM_CAP capability, uint32_t property, + uint32_t property_count, + TPMS_CAPABILITY_DATA *capability_data); + +/* Issue TPM2_NV_SetBits command */ +tpm_result_t tlcl2_set_bits(uint32_t index, uint64_t bits); + +/* + * Makes tlcl2_process_command available for on top implementations of + * custom tpm standards like cr50 + */ +void *tlcl2_process_command(TPM_CC command, void *command_body); + +/* Return digest size of hash algorithm */ +uint16_t tlcl2_get_hash_size_from_algo(TPMI_ALG_HASH hash_algo); + +/** + * Set Clear Control. The TPM error code is returned. + */ +tpm_result_t tlcl2_clear_control(bool disable); + +/** + * Make an NV Ram location read_only. The TPM error code is returned. + */ +tpm_result_t tlcl2_lock_nv_write(uint32_t index); + +/** + * Disable platform hierarchy. Specific to TPM2. The TPM error code is returned. + */ +tpm_result_t tlcl2_disable_platform_hierarchy(void); + +/* + * Declarations for "private" functions which are dispatched to by tss/tss.c + * based on TPM family. + */ + +tpm_result_t tlcl2_save_state(void); +tpm_result_t tlcl2_resume(void); +tpm_result_t tlcl2_startup(void); +tpm_result_t tlcl2_self_test_full(void); +tpm_result_t tlcl2_read(uint32_t index, void *data, uint32_t length); +tpm_result_t tlcl2_write(uint32_t index, const void *data, uint32_t length); +tpm_result_t tlcl2_assert_physical_presence(void); +tpm_result_t tlcl2_physical_presence_cmd_enable(void); +tpm_result_t tlcl2_finalize_physical_presence(void); +tpm_result_t tlcl2_force_clear(void); +tpm_result_t tlcl2_extend(int pcr_num, const uint8_t *digest_data, + enum vb2_hash_algorithm digest_algo); + +#endif /* TSS2_H_ */ diff --git a/src/security/vboot/secdata_tpm.c b/src/security/vboot/secdata_tpm.c index 1204be8787..21901bb310 100644 --- a/src/security/vboot/secdata_tpm.c +++ b/src/security/vboot/secdata_tpm.c @@ -41,8 +41,7 @@ tpm_result_t antirollback_read_space_kernel(struct vb2_context *ctx) */ uint32_t perms; - RETURN_ON_FAILURE(tlcl_get_permissions(KERNEL_NV_INDEX, - &perms)); + RETURN_ON_FAILURE(tlcl1_get_permissions(KERNEL_NV_INDEX, &perms)); if (perms != TPM_NV_PER_PPWRITE) { printk(BIOS_ERR, "TPM: invalid secdata_kernel permissions\n"); @@ -208,8 +207,7 @@ static uint32_t define_space(const char *name, uint32_t index, uint32_t length, { tpm_result_t rc; - rc = tlcl_define_space(index, length, nv_attributes, nv_policy, - nv_policy_size); + rc = tlcl2_define_space(index, length, nv_attributes, nv_policy, nv_policy_size); if (rc == TPM_CB_NV_DEFINED) { /* * Continue with writing: it may be defined, but not written @@ -334,8 +332,7 @@ static tpm_result_t setup_zte_spaces(void) * Since the RMA counter has the BITS attribute, we need to call * TPM2_NV_SetBits() in order to initialize it. */ - rc = tlcl_set_bits(ZTE_RMA_BYTES_COUNTER_INDEX, - rma_bytes_counter_default); + rc = tlcl2_set_bits(ZTE_RMA_BYTES_COUNTER_INDEX, rma_bytes_counter_default); if (rc != TPM_SUCCESS) { VBDEBUG("%s: Failed to init RMA Bytes counter space wit error %#x\n", __func__, rc); @@ -431,7 +428,7 @@ static tpm_result_t _factory_initialize_tpm(struct vb2_context *ctx) tpm_result_t antirollback_lock_space_firmware(void) { - return tlcl_lock_nv_write(FIRMWARE_NV_INDEX); + 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) @@ -475,7 +472,7 @@ tpm_result_t antirollback_write_space_mrc_hash(uint32_t index, const uint8_t *da tpm_result_t antirollback_lock_space_mrc_hash(uint32_t index) { - return tlcl_lock_nv_write(index); + return tlcl2_lock_nv_write(index); } static tpm_result_t read_space_vbios_hash(uint8_t *data) @@ -552,10 +549,10 @@ static tpm_result_t safe_write(uint32_t index, const void *data, uint32_t length */ static tpm_result_t safe_define_space(uint32_t index, uint32_t perm, uint32_t size) { - tpm_result_t rc = tlcl_define_space(index, perm, size); + tpm_result_t rc = tlcl1_define_space(index, perm, size); if (rc == TPM_MAXNVWRITES) { RETURN_ON_FAILURE(tpm_clear_and_reenable()); - return tlcl_define_space(index, perm, size); + return tlcl1_define_space(index, perm, size); } else { return rc; } @@ -569,7 +566,7 @@ static tpm_result_t _factory_initialize_tpm(struct vb2_context *ctx) vb2api_secdata_firmware_create(ctx); vb2api_secdata_kernel_create_v0(ctx); - rc = tlcl_get_permanent_flags(&pflags); + rc = tlcl1_get_permanent_flags(&pflags); if (rc != TPM_SUCCESS) return rc; @@ -592,7 +589,7 @@ static tpm_result_t _factory_initialize_tpm(struct vb2_context *ctx) VBDEBUG("TPM: nvLocked=%d\n", pflags.nvLocked); if (!pflags.nvLocked) { VBDEBUG("TPM: Enabling NV locking\n"); - RETURN_ON_FAILURE(tlcl_set_nv_locked()); + RETURN_ON_FAILURE(tlcl1_set_nv_locked()); } /* Clear TPM owner, in case the TPM is already owned for some reason. */ @@ -621,7 +618,7 @@ static tpm_result_t _factory_initialize_tpm(struct vb2_context *ctx) tpm_result_t antirollback_lock_space_firmware(void) { - return tlcl_set_global_lock(); + return tlcl1_set_global_lock(); } #endif diff --git a/src/soc/amd/common/psp_verstage/psp_verstage.c b/src/soc/amd/common/psp_verstage/psp_verstage.c index b49acae843..0b09c5fae9 100644 --- a/src/soc/amd/common/psp_verstage/psp_verstage.c +++ b/src/soc/amd/common/psp_verstage/psp_verstage.c @@ -227,9 +227,9 @@ static void psp_verstage_s0i3_resume(void) reboot_into_recovery(vboot_get_context(), POSTCODE_INIT_TPM_FAILED); } - rc = tlcl_disable_platform_hierarchy(); + rc = tlcl2_disable_platform_hierarchy(); if (rc != TPM_SUCCESS) { - printk(BIOS_ERR, "tlcl_disable_platform_hierarchy failed rc:%d\n", rc); + printk(BIOS_ERR, "tlcl2_disable_platform_hierarchy failed rc:%d\n", rc); reboot_into_recovery(vboot_get_context(), POSTCODE_INIT_TPM_FAILED); } } diff --git a/src/vendorcode/eltan/security/mboot/mboot.c b/src/vendorcode/eltan/security/mboot/mboot.c index b456d2633b..9cdd0de2fe 100644 --- a/src/vendorcode/eltan/security/mboot/mboot.c +++ b/src/vendorcode/eltan/security/mboot/mboot.c @@ -67,7 +67,7 @@ EFI_TCG2_EVENT_ALGORITHM_BITMAP tpm2_get_active_pcrs(void) * * Return the TPM PCR information. * - * This function parses the data got from tlcl_get_capability and returns the + * This function parses the data got from tlcl2_get_capability and returns the * PcrSelection. * * @param[out] Pcrs The Pcr Selection @@ -81,7 +81,7 @@ tpm_result_t tpm2_get_capability_pcrs(TPML_PCR_SELECTION *Pcrs) tpm_result_t rc; int index; - rc = tlcl_get_capability(TPM_CAP_PCRS, 0, 1, &TpmCap); + rc = tlcl2_get_capability(TPM_CAP_PCRS, 0, 1, &TpmCap); if (rc == TPM_SUCCESS) { Pcrs->count = TpmCap.data.assignedPCR.count; printk(BIOS_DEBUG, "Pcrs->count = %d\n", Pcrs->count); diff --git a/src/vendorcode/google/chromeos/tpm2.c b/src/vendorcode/google/chromeos/tpm2.c index 9a99f7d285..31c28c9d2a 100644 --- a/src/vendorcode/google/chromeos/tpm2.c +++ b/src/vendorcode/google/chromeos/tpm2.c @@ -22,7 +22,7 @@ static void disable_platform_hierarchy(void *unused) return; } - rc = tlcl_disable_platform_hierarchy(); + rc = tlcl2_disable_platform_hierarchy(); if (rc != TPM_SUCCESS) printk(BIOS_ERR, "Platform hierarchy disablement failed: %#x\n", rc); |