diff options
Diffstat (limited to 'src')
-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); |