aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-03-10 17:37:29 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2019-03-10 17:37:29 -0700
commit5af7f115886f7ec193171e2e49b8000ddd1e7147 (patch)
tree117b9e99650b0772f683e6b8f734e2c94f6a6c3b /include/linux
parentMerge branch 'next-integrity' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security (diff)
parentMerge tag 'tpmdd-next-20190213' of git://git.infradead.org/users/jjs/linux-tpmdd into next-tpm (diff)
downloadlinux-dev-5af7f115886f7ec193171e2e49b8000ddd1e7147.tar.xz
linux-dev-5af7f115886f7ec193171e2e49b8000ddd1e7147.zip
Merge branch 'next-tpm' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security
Pull tpm updates from James Morris: - Clean up the transmission flow Cleaned up the whole transmission flow. Locking of the chip is now done in the level of tpm_try_get_ops() and tpm_put_ops() instead taking the chip lock inside tpm_transmit(). The nested calls inside tpm_transmit(), used with the resource manager, have been refactored out. Should make easier to perform more complex transactions with the TPM without making the subsystem a bigger mess (e.g. encrypted channel patches by James Bottomley). - PPI 1.3 support TPM PPI 1.3 introduces an additional optional command parameter that may be needed for some commands. Display the parameter if the command requires such a parameter. Only command 23 (SetPCRBanks) needs one. The PPI request file will show output like this then: # echo "23 16" > request # cat request 23 16 # echo "5" > request # cat request 5 - Extend all PCR banks in IMA Instead of static PCR banks array, the array of available PCR banks is now allocated dynamically. The digests sizes are determined dynamically using a probe PCR read without relying crypto's static list of hash algorithms. This should finally make sealing of measurements in IMA safe and secure. - TPM 2.0 selftests Added a test suite to tools/testing/selftests/tpm2 previously outside of the kernel tree: https://github.com/jsakkine-intel/tpm2-scripts * 'next-tpm' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security: (37 commits) tpm/ppi: Enable submission of optional command parameter for PPI 1.3 tpm/ppi: Possibly show command parameter if TPM PPI 1.3 is used tpm/ppi: Display up to 101 operations as define for version 1.3 tpm/ppi: rename TPM_PPI_REVISION_ID to TPM_PPI_REVISION_ID_1 tpm/ppi: pass function revision ID to tpm_eval_dsm() tpm: pass an array of tpm_extend_digest structures to tpm_pcr_extend() KEYS: trusted: explicitly use tpm_chip structure from tpm_default_chip() tpm: move tpm_chip definition to include/linux/tpm.h tpm: retrieve digest size of unknown algorithms with PCR read tpm: rename and export tpm2_digest and tpm2_algorithms tpm: dynamically allocate the allocated_banks array tpm: remove @flags from tpm_transmit() tpm: take TPM chip power gating out of tpm_transmit() tpm: introduce tpm_chip_start() and tpm_chip_stop() tpm: remove TPM_TRANSMIT_UNLOCKED flag tpm: use tpm_try_get_ops() in tpm-sysfs.c. tpm: remove @space from tpm_transmit() tpm: move TPM space code out of tpm_transmit() tpm: move tpm_validate_commmand() to tpm2-space.c tpm: clean up tpm_try_transmit() error handling flow ...
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/tpm.h129
-rw-r--r--include/linux/tpm_eventlog.h19
2 files changed, 129 insertions, 19 deletions
diff --git a/include/linux/tpm.h b/include/linux/tpm.h
index b49a55cf775f..1b5436b213a2 100644
--- a/include/linux/tpm.h
+++ b/include/linux/tpm.h
@@ -22,12 +22,41 @@
#ifndef __LINUX_TPM_H__
#define __LINUX_TPM_H__
+#include <linux/hw_random.h>
+#include <linux/acpi.h>
+#include <linux/cdev.h>
+#include <linux/fs.h>
+#include <crypto/hash_info.h>
+
#define TPM_DIGEST_SIZE 20 /* Max TPM v1.2 PCR size */
+#define TPM_MAX_DIGEST_SIZE SHA512_DIGEST_SIZE
struct tpm_chip;
struct trusted_key_payload;
struct trusted_key_options;
+enum tpm_algorithms {
+ TPM_ALG_ERROR = 0x0000,
+ TPM_ALG_SHA1 = 0x0004,
+ TPM_ALG_KEYEDHASH = 0x0008,
+ TPM_ALG_SHA256 = 0x000B,
+ TPM_ALG_SHA384 = 0x000C,
+ TPM_ALG_SHA512 = 0x000D,
+ TPM_ALG_NULL = 0x0010,
+ TPM_ALG_SM3_256 = 0x0012,
+};
+
+struct tpm_digest {
+ u16 alg_id;
+ u8 digest[TPM_MAX_DIGEST_SIZE];
+} __packed;
+
+struct tpm_bank_info {
+ u16 alg_id;
+ u16 digest_size;
+ u16 crypto_id;
+};
+
enum TPM_OPS_FLAGS {
TPM_OPS_AUTO_STARTUP = BIT(0),
};
@@ -41,7 +70,7 @@ struct tpm_class_ops {
int (*send) (struct tpm_chip *chip, u8 *buf, size_t len);
void (*cancel) (struct tpm_chip *chip);
u8 (*status) (struct tpm_chip *chip);
- bool (*update_timeouts)(struct tpm_chip *chip,
+ void (*update_timeouts)(struct tpm_chip *chip,
unsigned long *timeout_cap);
int (*go_idle)(struct tpm_chip *chip);
int (*cmd_ready)(struct tpm_chip *chip);
@@ -50,11 +79,100 @@ struct tpm_class_ops {
void (*clk_enable)(struct tpm_chip *chip, bool value);
};
+#define TPM_NUM_EVENT_LOG_FILES 3
+
+/* Indexes the duration array */
+enum tpm_duration {
+ TPM_SHORT = 0,
+ TPM_MEDIUM = 1,
+ TPM_LONG = 2,
+ TPM_LONG_LONG = 3,
+ TPM_UNDEFINED,
+ TPM_NUM_DURATIONS = TPM_UNDEFINED,
+};
+
+#define TPM_PPI_VERSION_LEN 3
+
+struct tpm_space {
+ u32 context_tbl[3];
+ u8 *context_buf;
+ u32 session_tbl[3];
+ u8 *session_buf;
+};
+
+struct tpm_bios_log {
+ void *bios_event_log;
+ void *bios_event_log_end;
+};
+
+struct tpm_chip_seqops {
+ struct tpm_chip *chip;
+ const struct seq_operations *seqops;
+};
+
+struct tpm_chip {
+ struct device dev;
+ struct device devs;
+ struct cdev cdev;
+ struct cdev cdevs;
+
+ /* A driver callback under ops cannot be run unless ops_sem is held
+ * (sometimes implicitly, eg for the sysfs code). ops becomes null
+ * when the driver is unregistered, see tpm_try_get_ops.
+ */
+ struct rw_semaphore ops_sem;
+ const struct tpm_class_ops *ops;
+
+ struct tpm_bios_log log;
+ struct tpm_chip_seqops bin_log_seqops;
+ struct tpm_chip_seqops ascii_log_seqops;
+
+ unsigned int flags;
+
+ int dev_num; /* /dev/tpm# */
+ unsigned long is_open; /* only one allowed */
+
+ char hwrng_name[64];
+ struct hwrng hwrng;
+
+ struct mutex tpm_mutex; /* tpm is processing */
+
+ unsigned long timeout_a; /* jiffies */
+ unsigned long timeout_b; /* jiffies */
+ unsigned long timeout_c; /* jiffies */
+ unsigned long timeout_d; /* jiffies */
+ bool timeout_adjusted;
+ unsigned long duration[TPM_NUM_DURATIONS]; /* jiffies */
+ bool duration_adjusted;
+
+ struct dentry *bios_dir[TPM_NUM_EVENT_LOG_FILES];
+
+ const struct attribute_group *groups[3];
+ unsigned int groups_cnt;
+
+ u32 nr_allocated_banks;
+ struct tpm_bank_info *allocated_banks;
+#ifdef CONFIG_ACPI
+ acpi_handle acpi_dev_handle;
+ char ppi_version[TPM_PPI_VERSION_LEN + 1];
+#endif /* CONFIG_ACPI */
+
+ struct tpm_space work_space;
+ u32 last_cc;
+ u32 nr_commands;
+ u32 *cc_attrs_tbl;
+
+ /* active locality */
+ int locality;
+};
+
#if defined(CONFIG_TCG_TPM) || defined(CONFIG_TCG_TPM_MODULE)
extern int tpm_is_tpm2(struct tpm_chip *chip);
-extern int tpm_pcr_read(struct tpm_chip *chip, u32 pcr_idx, u8 *res_buf);
-extern int tpm_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, const u8 *hash);
+extern int tpm_pcr_read(struct tpm_chip *chip, u32 pcr_idx,
+ struct tpm_digest *digest);
+extern int tpm_pcr_extend(struct tpm_chip *chip, u32 pcr_idx,
+ struct tpm_digest *digests);
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,
@@ -70,13 +188,14 @@ static inline int tpm_is_tpm2(struct tpm_chip *chip)
return -ENODEV;
}
-static inline int tpm_pcr_read(struct tpm_chip *chip, u32 pcr_idx, u8 *res_buf)
+static inline int tpm_pcr_read(struct tpm_chip *chip, int pcr_idx,
+ struct tpm_digest *digest)
{
return -ENODEV;
}
static inline int tpm_pcr_extend(struct tpm_chip *chip, u32 pcr_idx,
- const u8 *hash)
+ struct tpm_digest *digests)
{
return -ENODEV;
}
diff --git a/include/linux/tpm_eventlog.h b/include/linux/tpm_eventlog.h
index 20d9da77fc11..81519f163211 100644
--- a/include/linux/tpm_eventlog.h
+++ b/include/linux/tpm_eventlog.h
@@ -3,12 +3,11 @@
#ifndef __LINUX_TPM_EVENTLOG_H__
#define __LINUX_TPM_EVENTLOG_H__
-#include <crypto/hash_info.h>
+#include <linux/tpm.h>
#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
#define EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2 0x1
#define EFI_TCG2_EVENT_LOG_FORMAT_TCG_2 0x2
@@ -82,7 +81,7 @@ struct tcg_efi_specid_event_algs {
u16 digest_size;
} __packed;
-struct tcg_efi_specid_event {
+struct tcg_efi_specid_event_head {
u8 signature[16];
u32 platform_class;
u8 spec_version_minor;
@@ -90,9 +89,7 @@ struct tcg_efi_specid_event {
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];
+ struct tcg_efi_specid_event_algs digest_sizes[];
} __packed;
struct tcg_pcr_event {
@@ -108,17 +105,11 @@ struct tcg_event_field {
u8 event[0];
} __packed;
-struct tpm2_digest {
- u16 alg_id;
- u8 digest[SHA512_DIGEST_SIZE];
-} __packed;
-
-struct tcg_pcr_event2 {
+struct tcg_pcr_event2_head {
u32 pcr_idx;
u32 event_type;
u32 count;
- struct tpm2_digest digests[TPM2_ACTIVE_PCR_BANKS];
- struct tcg_event_field event;
+ struct tpm_digest digests[];
} __packed;
#endif