From fd3ec3663718e5f89fbcbc18a67885203fd914a1 Mon Sep 17 00:00:00 2001 From: Thiebaud Weksteen Date: Wed, 20 Sep 2017 10:13:36 +0200 Subject: tpm: move tpm_eventlog.h outside of drivers folder The generic definitions of data structures in tpm_eventlog.h are required by other part of the kernel (namely, the EFI stub). Signed-off-by: Thiebaud Weksteen Reviewed-by: Javier Martinez Canillas Tested-by: Javier Martinez Canillas Tested-by: Jarkko Sakkinen Reviewed-by: Jarkko Sakkinen Signed-off-by: Jarkko Sakkinen --- include/linux/tpm_eventlog.h | 121 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 include/linux/tpm_eventlog.h (limited to 'include/linux') diff --git a/include/linux/tpm_eventlog.h b/include/linux/tpm_eventlog.h new file mode 100644 index 000000000000..a2a86783f974 --- /dev/null +++ b/include/linux/tpm_eventlog.h @@ -0,0 +1,121 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __LINUX_TPM_EVENTLOG_H__ +#define __LINUX_TPM_EVENTLOG_H__ + +#include + +#define TCG_EVENT_NAME_LEN_MAX 255 +#define MAX_TEXT_EVENT 1000 /* Max event string length */ +#define ACPI_TCPA_SIG "TCPA" /* 0x41504354 /'TCPA' */ +#define TPM2_ACTIVE_PCR_BANKS 3 + +#ifdef CONFIG_PPC64 +#define do_endian_conversion(x) be32_to_cpu(x) +#else +#define do_endian_conversion(x) x +#endif + +enum bios_platform_class { + BIOS_CLIENT = 0x00, + BIOS_SERVER = 0x01, +}; + +struct tcpa_event { + u32 pcr_index; + u32 event_type; + u8 pcr_value[20]; /* SHA1 */ + u32 event_size; + u8 event_data[0]; +}; + +enum tcpa_event_types { + PREBOOT = 0, + POST_CODE, + UNUSED, + NO_ACTION, + SEPARATOR, + ACTION, + EVENT_TAG, + SCRTM_CONTENTS, + SCRTM_VERSION, + CPU_MICROCODE, + PLATFORM_CONFIG_FLAGS, + TABLE_OF_DEVICES, + COMPACT_HASH, + IPL, + IPL_PARTITION_DATA, + NONHOST_CODE, + NONHOST_CONFIG, + NONHOST_INFO, +}; + +struct tcpa_pc_event { + u32 event_id; + u32 event_size; + u8 event_data[0]; +}; + +enum tcpa_pc_event_ids { + SMBIOS = 1, + BIS_CERT, + POST_BIOS_ROM, + ESCD, + CMOS, + NVRAM, + OPTION_ROM_EXEC, + OPTION_ROM_CONFIG, + OPTION_ROM_MICROCODE = 10, + S_CRTM_VERSION, + S_CRTM_CONTENTS, + POST_CONTENTS, + HOST_TABLE_OF_DEVICES, +}; + +/* http://www.trustedcomputinggroup.org/tcg-efi-protocol-specification/ */ + +struct tcg_efi_specid_event_algs { + u16 alg_id; + u16 digest_size; +} __packed; + +struct tcg_efi_specid_event { + u8 signature[16]; + u32 platform_class; + u8 spec_version_minor; + u8 spec_version_major; + u8 spec_errata; + u8 uintnsize; + u32 num_algs; + struct tcg_efi_specid_event_algs digest_sizes[TPM2_ACTIVE_PCR_BANKS]; + u8 vendor_info_size; + u8 vendor_info[0]; +} __packed; + +struct tcg_pcr_event { + u32 pcr_idx; + u32 event_type; + u8 digest[20]; + u32 event_size; + u8 event[0]; +} __packed; + +struct tcg_event_field { + u32 event_size; + u8 event[0]; +} __packed; + +struct tpm2_digest { + u16 alg_id; + u8 digest[SHA512_DIGEST_SIZE]; +} __packed; + +struct tcg_pcr_event2 { + u32 pcr_idx; + u32 event_type; + u32 count; + struct tpm2_digest digests[TPM2_ACTIVE_PCR_BANKS]; + struct tcg_event_field event; +} __packed; + +#endif -- cgit v1.2.3 From 4d01d29d9307d321149ff5ad66d47bee8e56c012 Mon Sep 17 00:00:00 2001 From: Thiebaud Weksteen Date: Wed, 20 Sep 2017 10:13:38 +0200 Subject: tpm: add event log format version Although defined as part of the TCG EFI specification, we add these definitions here so that any event log provider may reference them. Signed-off-by: Thiebaud Weksteen Reviewed-by: Javier Martinez Canillas Tested-by: Javier Martinez Canillas Tested-by: Jarkko Sakkinen Reviewed-by: Jarkko Sakkinen Signed-off-by: Jarkko Sakkinen --- include/linux/tpm_eventlog.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/tpm_eventlog.h b/include/linux/tpm_eventlog.h index a2a86783f974..20d9da77fc11 100644 --- a/include/linux/tpm_eventlog.h +++ b/include/linux/tpm_eventlog.h @@ -10,6 +10,9 @@ #define ACPI_TCPA_SIG "TCPA" /* 0x41504354 /'TCPA' */ #define TPM2_ACTIVE_PCR_BANKS 3 +#define EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2 0x1 +#define EFI_TCG2_EVENT_LOG_FORMAT_TCG_2 0x2 + #ifdef CONFIG_PPC64 #define do_endian_conversion(x) be32_to_cpu(x) #else -- cgit v1.2.3 From 33b6d03469b2206fb51ecc37f40411a857ad8fff Mon Sep 17 00:00:00 2001 From: Thiebaud Weksteen Date: Wed, 20 Sep 2017 10:13:39 +0200 Subject: efi: call get_event_log before ExitBootServices With TPM 2.0 specification, the event logs may only be accessible by calling an EFI Boot Service. Modify the EFI stub to copy the log area to a new Linux-specific EFI configuration table so it remains accessible once booted. When calling this service, it is possible to specify the expected format of the logs: TPM 1.2 (SHA1) or TPM 2.0 ("Crypto Agile"). For now, only the first format is retrieved. Signed-off-by: Thiebaud Weksteen Reviewed-by: Javier Martinez Canillas Tested-by: Javier Martinez Canillas Tested-by: Jarkko Sakkinen Reviewed-by: Jarkko Sakkinen Signed-off-by: Jarkko Sakkinen --- include/linux/efi.h | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) (limited to 'include/linux') diff --git a/include/linux/efi.h b/include/linux/efi.h index d813f7b04da7..dcea82dc4b89 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -473,6 +473,39 @@ typedef struct { u64 get_all; } apple_properties_protocol_64_t; +typedef struct { + u32 get_capability; + u32 get_event_log; + u32 hash_log_extend_event; + u32 submit_command; + u32 get_active_pcr_banks; + u32 set_active_pcr_banks; + u32 get_result_of_set_active_pcr_banks; +} efi_tcg2_protocol_32_t; + +typedef struct { + u64 get_capability; + u64 get_event_log; + u64 hash_log_extend_event; + u64 submit_command; + u64 get_active_pcr_banks; + u64 set_active_pcr_banks; + u64 get_result_of_set_active_pcr_banks; +} efi_tcg2_protocol_64_t; + +typedef u32 efi_tcg2_event_log_format; + +typedef struct { + void *get_capability; + efi_status_t (*get_event_log)(efi_handle_t, efi_tcg2_event_log_format, + efi_physical_addr_t *, efi_physical_addr_t *, efi_bool_t *); + void *hash_log_extend_event; + void *submit_command; + void *get_active_pcr_banks; + void *set_active_pcr_banks; + void *get_result_of_set_active_pcr_banks; +} efi_tcg2_protocol_t; + /* * Types and defines for EFI ResetSystem */ @@ -623,6 +656,7 @@ void efi_native_runtime_setup(void); #define EFI_MEMORY_ATTRIBUTES_TABLE_GUID EFI_GUID(0xdcfa911d, 0x26eb, 0x469f, 0xa2, 0x20, 0x38, 0xb7, 0xdc, 0x46, 0x12, 0x20) #define EFI_CONSOLE_OUT_DEVICE_GUID EFI_GUID(0xd3b36f2c, 0xd551, 0x11d4, 0x9a, 0x46, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d) #define APPLE_PROPERTIES_PROTOCOL_GUID EFI_GUID(0x91bd12fe, 0xf6c3, 0x44fb, 0xa5, 0xb7, 0x51, 0x22, 0xab, 0x30, 0x3a, 0xe0) +#define EFI_TCG2_PROTOCOL_GUID EFI_GUID(0x607f766c, 0x7455, 0x42be, 0x93, 0x0b, 0xe4, 0xd7, 0x6d, 0xb2, 0x72, 0x0f) #define EFI_IMAGE_SECURITY_DATABASE_GUID EFI_GUID(0xd719b2cb, 0x3d3a, 0x4596, 0xa3, 0xbc, 0xda, 0xd0, 0x0e, 0x67, 0x65, 0x6f) #define EFI_SHIM_LOCK_GUID EFI_GUID(0x605dab50, 0xe046, 0x4300, 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23) @@ -635,6 +669,7 @@ void efi_native_runtime_setup(void); #define LINUX_EFI_ARM_SCREEN_INFO_TABLE_GUID EFI_GUID(0xe03fc20a, 0x85dc, 0x406e, 0xb9, 0x0e, 0x4a, 0xb5, 0x02, 0x37, 0x1d, 0x95) #define LINUX_EFI_LOADER_ENTRY_GUID EFI_GUID(0x4a67b082, 0x0a4c, 0x41cf, 0xb6, 0xc7, 0x44, 0x0b, 0x29, 0xbb, 0x8c, 0x4f) #define LINUX_EFI_RANDOM_SEED_TABLE_GUID EFI_GUID(0x1ce1e5bc, 0x7ceb, 0x42f2, 0x81, 0xe5, 0x8a, 0xad, 0xf1, 0x80, 0xf5, 0x7b) +#define LINUX_EFI_TPM_EVENT_LOG_GUID EFI_GUID(0xb7799cb0, 0xeca2, 0x4943, 0x96, 0x67, 0x1f, 0xae, 0x07, 0xb7, 0x47, 0xfa) typedef struct { efi_guid_t guid; @@ -909,6 +944,7 @@ extern struct efi { unsigned long properties_table; /* properties table */ unsigned long mem_attr_table; /* memory attributes table */ unsigned long rng_seed; /* UEFI firmware random seed */ + unsigned long tpm_log; /* TPM2 Event Log table */ efi_get_time_t *get_time; efi_set_time_t *set_time; efi_get_wakeup_time_t *get_wakeup_time; @@ -1534,6 +1570,8 @@ static inline void efi_enable_reset_attack_mitigation(efi_system_table_t *sys_table_arg) { } #endif +void efi_retrieve_tpm2_eventlog(efi_system_table_t *sys_table); + /* * Arch code can implement the following three template macros, avoiding * reptition for the void/non-void return cases of {__,}efi_call_virt(): @@ -1601,4 +1639,12 @@ struct linux_efi_random_seed { u8 bits[]; }; +struct linux_efi_tpm_eventlog { + u32 size; + u8 version; + u8 log[]; +}; + +extern int efi_tpm_eventlog_init(void); + #endif /* _LINUX_EFI_H */ -- cgit v1.2.3 From aad887f6641145fec2a801da2ce4ed36cf99c6a5 Mon Sep 17 00:00:00 2001 From: Jarkko Sakkinen Date: Sun, 5 Nov 2017 13:16:26 +0200 Subject: tpm: use struct tpm_chip for tpm_chip_find_get() Device number (the character device index) is not a stable identifier for a TPM chip. That is the reason why every call site passes TPM_ANY_NUM to tpm_chip_find_get(). This commit changes the API in a way that instead a struct tpm_chip instance is given and NULL means the default chip. In addition, this commit refines the documentation to be up to date with the implementation. Suggested-by: Jason Gunthorpe (@chip_num -> @chip part) Signed-off-by: Jarkko Sakkinen Reviewed-by: Jason Gunthorpe Tested-by: PrasannaKumar Muralidharan --- include/linux/tpm.h | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) (limited to 'include/linux') diff --git a/include/linux/tpm.h b/include/linux/tpm.h index 5a090f5ab335..ddc9b88ff6d3 100644 --- a/include/linux/tpm.h +++ b/include/linux/tpm.h @@ -24,11 +24,6 @@ #define TPM_DIGEST_SIZE 20 /* Max TPM v1.2 PCR size */ -/* - * Chip num is this value or a valid tpm idx - */ -#define TPM_ANY_NUM 0xFFFF - struct tpm_chip; struct trusted_key_payload; struct trusted_key_options; @@ -54,42 +49,47 @@ struct tpm_class_ops { #if defined(CONFIG_TCG_TPM) || defined(CONFIG_TCG_TPM_MODULE) -extern int tpm_is_tpm2(u32 chip_num); -extern int tpm_pcr_read(u32 chip_num, int pcr_idx, u8 *res_buf); -extern int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash); -extern int tpm_send(u32 chip_num, void *cmd, size_t buflen); -extern int tpm_get_random(u32 chip_num, u8 *data, size_t max); -extern int tpm_seal_trusted(u32 chip_num, +extern int tpm_is_tpm2(struct tpm_chip *chip); +extern int tpm_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf); +extern int tpm_pcr_extend(struct tpm_chip *chip, int pcr_idx, const u8 *hash); +extern int tpm_send(struct tpm_chip *chip, void *cmd, size_t buflen); +extern int tpm_get_random(struct tpm_chip *chip, u8 *data, size_t max); +extern int tpm_seal_trusted(struct tpm_chip *chip, struct trusted_key_payload *payload, struct trusted_key_options *options); -extern int tpm_unseal_trusted(u32 chip_num, +extern int tpm_unseal_trusted(struct tpm_chip *chip, struct trusted_key_payload *payload, struct trusted_key_options *options); #else -static inline int tpm_is_tpm2(u32 chip_num) +static inline int tpm_is_tpm2(struct tpm_chip *chip) { return -ENODEV; } -static inline int tpm_pcr_read(u32 chip_num, int pcr_idx, u8 *res_buf) { +static inline int tpm_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf) +{ return -ENODEV; } -static inline int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash) { +static inline int tpm_pcr_extend(struct tpm_chip *chip, int pcr_idx, + const u8 *hash) +{ return -ENODEV; } -static inline int tpm_send(u32 chip_num, void *cmd, size_t buflen) { +static inline int tpm_send(struct tpm_chip *chip, void *cmd, size_t buflen) +{ return -ENODEV; } -static inline int tpm_get_random(u32 chip_num, u8 *data, size_t max) { +static inline int tpm_get_random(struct tpm_chip *chip, u8 *data, size_t max) +{ return -ENODEV; } -static inline int tpm_seal_trusted(u32 chip_num, +static inline int tpm_seal_trusted(struct tpm_chip *chip, struct trusted_key_payload *payload, struct trusted_key_options *options) { return -ENODEV; } -static inline int tpm_unseal_trusted(u32 chip_num, +static inline int tpm_unseal_trusted(struct tpm_chip *chip, struct trusted_key_payload *payload, struct trusted_key_options *options) { -- cgit v1.2.3 From b3e958ce4c585bf666de249dc794971ebc62d2d3 Mon Sep 17 00:00:00 2001 From: Azhar Shaikh Date: Fri, 22 Dec 2017 12:13:44 -0800 Subject: tpm: Keep CLKRUN enabled throughout the duration of transmit_cmd() Commit 5e572cab92f0bb5 ("tpm: Enable CLKRUN protocol for Braswell systems") disabled CLKRUN protocol during TPM transactions and re-enabled once the transaction is completed. But there were still some corner cases observed where, reading of TPM header failed for savestate command while going to suspend, which resulted in suspend failure. To fix this issue keep the CLKRUN protocol disabled for the entire duration of a single TPM command and not disabling and re-enabling again for every TPM transaction. For the other TPM accesses outside TPM command flow, add a higher level of disabling and re-enabling the CLKRUN protocol, instead of doing for every TPM transaction. Fixes: 5e572cab92f0bb5 ("tpm: Enable CLKRUN protocol for Braswell systems") Signed-off-by: Azhar Shaikh Reviewed-by: Jarkko Sakkinen Tested-by: Jarkko Sakkinen Signed-off-by: Jarkko Sakkinen --- include/linux/tpm.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/tpm.h b/include/linux/tpm.h index ddc9b88ff6d3..bcdd3790e94d 100644 --- a/include/linux/tpm.h +++ b/include/linux/tpm.h @@ -45,6 +45,7 @@ struct tpm_class_ops { unsigned long *timeout_cap); int (*request_locality)(struct tpm_chip *chip, int loc); void (*relinquish_locality)(struct tpm_chip *chip, int loc); + void (*clk_enable)(struct tpm_chip *chip, bool value); }; #if defined(CONFIG_TCG_TPM) || defined(CONFIG_TCG_TPM_MODULE) -- cgit v1.2.3