blob: 20f3fe607e65c3f302c129b9474f6e08e130033c [file] [log] [blame]
From 9382586e9b9dd7b8da911dff2778b191a600e25d Mon Sep 17 00:00:00 2001
From: Andrey Pronin <apronin@chromium.org>
Date: Thu, 14 Jul 2016 12:02:53 -0700
Subject: [PATCH] FROMLIST: tpm: add sysfs attributes for tpm2
Add sysfs attributes in TPM2.0 case for:
- TPM_PT_PERMANENT flags
- TPM_PT_STARTUP_CLEAR flags
- lockout-related properties
BUG=chrome-os-partner:55219
TEST=Boot on kevin, verify that sysfs attributes are present
(am from https://patchwork.kernel.org/patch/9250659/)
Change-Id: I47cb1793736781fbea93e5bf80b783e0ac9e8628
Signed-off-by: Andrey Pronin <apronin@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/362179
Reviewed-by: Dmitry Torokhov <dtor@chromium.org>
Conflicts: drivers/char/tpm/tpm-chip.c
drivers/char/tpm/tpm.h
[rebase412(groeck):
Fix conflicts (context changes);
overloaded enum tpm2_properties;
new method for shutdown handling in core]
Signed-off-by: Guenter Roeck <groeck@chromium.org>
[rebase54(groeck): Context conflicts;
squash:
CHROMIUM: tpm: Protect tpm2 sysfs accesses against shutdown
]
Signed-off-by: Guenter Roeck <groeck@chromium.org>
[rebase510(groeck):
Conflicts:
drivers/char/tpm/tpm-sysfs.c (upstream now supports one tpm2 sysfs attribute)
drivers/char/tpm/tpm.h (changes moved to include/linux/tpm.h)
]
Signed-off-by: Guenter Roeck <groeck@chromium.org>
---
drivers/char/tpm/tpm-sysfs.c | 123 +++++++++++++++++++++++++++++++++++
include/linux/tpm.h | 29 ++++++++-
2 files changed, 151 insertions(+), 1 deletion(-)
diff --git a/drivers/char/tpm/tpm-sysfs.c b/drivers/char/tpm/tpm-sysfs.c
index 63f03cfb8e6a..8ba8cee38adc 100644
--- a/drivers/char/tpm/tpm-sysfs.c
+++ b/drivers/char/tpm/tpm-sysfs.c
@@ -324,7 +324,129 @@ static struct attribute *tpm1_dev_attrs[] = {
NULL,
};
+struct tpm2_prop_flag_dev_attribute {
+ struct device_attribute attr;
+ u32 property_id;
+ u32 flag_mask;
+};
+
+struct tpm2_prop_u32_dev_attribute {
+ struct device_attribute attr;
+ u32 property_id;
+};
+
+static ssize_t tpm2_prop_flag_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct tpm2_prop_flag_dev_attribute *pa =
+ container_of(attr, struct tpm2_prop_flag_dev_attribute, attr);
+ struct tpm_chip *chip = to_tpm_chip(dev);
+ u32 flags;
+ ssize_t rc;
+
+ rc = tpm_try_get_ops(chip);
+ if (rc)
+ return rc;
+
+ rc = tpm2_get_tpm_pt(chip, pa->property_id, &flags, "reading property");
+ if (rc) {
+ rc = 0;
+ goto error;
+ }
+
+ rc = sprintf(buf, "%d\n", !!(flags & pa->flag_mask));
+error:
+ tpm_put_ops(chip);
+ return rc;
+}
+
+static ssize_t tpm2_prop_u32_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct tpm2_prop_u32_dev_attribute *pa =
+ container_of(attr, struct tpm2_prop_u32_dev_attribute, attr);
+ struct tpm_chip *chip = to_tpm_chip(dev);
+ u32 value;
+ ssize_t rc;
+
+ rc = tpm_try_get_ops(chip);
+ if (rc)
+ return rc;
+
+ rc = tpm2_get_tpm_pt(chip, pa->property_id, &value, "reading property");
+ if (rc) {
+ rc = 0;
+ goto error;
+ }
+
+ rc = sprintf(buf, "%u\n", value);
+error:
+ tpm_put_ops(chip);
+ return rc;
+}
+
+#define TPM2_PROP_FLAG_ATTR(_name, _property_id, _flag_mask) \
+ struct tpm2_prop_flag_dev_attribute attr_tpm2_prop_##_name = { \
+ __ATTR(_name, S_IRUGO, tpm2_prop_flag_show, NULL), \
+ _property_id, _flag_mask \
+ }
+
+#define TPM2_PROP_U32_ATTR(_name, _property_id) \
+ struct tpm2_prop_u32_dev_attribute attr_tpm2_prop_##_name = { \
+ __ATTR(_name, S_IRUGO, tpm2_prop_u32_show, NULL), \
+ _property_id \
+ }
+
+TPM2_PROP_FLAG_ATTR(owner_auth_set,
+ TPM2_PT_PERMANENT, TPM2_ATTR_OWNER_AUTH_SET);
+TPM2_PROP_FLAG_ATTR(endorsement_auth_set,
+ TPM2_PT_PERMANENT, TPM2_ATTR_ENDORSEMENT_AUTH_SET);
+TPM2_PROP_FLAG_ATTR(lockout_auth_set,
+ TPM2_PT_PERMANENT, TPM2_ATTR_LOCKOUT_AUTH_SET);
+TPM2_PROP_FLAG_ATTR(disable_clear,
+ TPM2_PT_PERMANENT, TPM2_ATTR_DISABLE_CLEAR);
+TPM2_PROP_FLAG_ATTR(in_lockout,
+ TPM2_PT_PERMANENT, TPM2_ATTR_IN_LOCKOUT);
+TPM2_PROP_FLAG_ATTR(tpm_generated_eps,
+ TPM2_PT_PERMANENT, TPM2_ATTR_TPM_GENERATED_EPS);
+
+TPM2_PROP_FLAG_ATTR(ph_enable,
+ TPM2_PT_STARTUP_CLEAR, TPM2_ATTR_PH_ENABLE);
+TPM2_PROP_FLAG_ATTR(sh_enable,
+ TPM2_PT_STARTUP_CLEAR, TPM2_ATTR_SH_ENABLE);
+TPM2_PROP_FLAG_ATTR(eh_enable,
+ TPM2_PT_STARTUP_CLEAR, TPM2_ATTR_EH_ENABLE);
+TPM2_PROP_FLAG_ATTR(ph_enable_nv,
+ TPM2_PT_STARTUP_CLEAR, TPM2_ATTR_PH_ENABLE_NV);
+TPM2_PROP_FLAG_ATTR(orderly,
+ TPM2_PT_STARTUP_CLEAR, TPM2_ATTR_ORDERLY);
+
+TPM2_PROP_U32_ATTR(lockout_counter, TPM2_PT_LOCKOUT_COUNTER);
+TPM2_PROP_U32_ATTR(max_auth_fail, TPM2_PT_MAX_AUTH_FAIL);
+TPM2_PROP_U32_ATTR(lockout_interval, TPM2_PT_LOCKOUT_INTERVAL);
+TPM2_PROP_U32_ATTR(lockout_recovery, TPM2_PT_LOCKOUT_RECOVERY);
+
+#define ATTR_FOR_TPM2_PROP(_name) (&attr_tpm2_prop_##_name.attr.attr)
static struct attribute *tpm2_dev_attrs[] = {
+ ATTR_FOR_TPM2_PROP(owner_auth_set),
+ ATTR_FOR_TPM2_PROP(endorsement_auth_set),
+ ATTR_FOR_TPM2_PROP(lockout_auth_set),
+ ATTR_FOR_TPM2_PROP(disable_clear),
+ ATTR_FOR_TPM2_PROP(in_lockout),
+ ATTR_FOR_TPM2_PROP(tpm_generated_eps),
+ ATTR_FOR_TPM2_PROP(ph_enable),
+ ATTR_FOR_TPM2_PROP(sh_enable),
+ ATTR_FOR_TPM2_PROP(eh_enable),
+ ATTR_FOR_TPM2_PROP(ph_enable_nv),
+ ATTR_FOR_TPM2_PROP(orderly),
+ ATTR_FOR_TPM2_PROP(lockout_counter),
+ ATTR_FOR_TPM2_PROP(max_auth_fail),
+ ATTR_FOR_TPM2_PROP(lockout_interval),
+ ATTR_FOR_TPM2_PROP(lockout_recovery),
+ &dev_attr_durations.attr,
+ &dev_attr_timeouts.attr,
&dev_attr_tpm_version_major.attr,
NULL
};
@@ -476,6 +598,7 @@ PCR_ATTR_BUILD(TPM_ALG_SM3_256, sm3);
void tpm_sysfs_add_device(struct tpm_chip *chip)
{
+ /* FIXME: update tpm_sysfs to explicitly lock chip->ops for TPM 2.0 */
int i;
WARN_ON(chip->groups_cnt != 0);
diff --git a/include/linux/tpm.h b/include/linux/tpm.h
index 543aa3b1dedc..d5b21f0213ee 100644
--- a/include/linux/tpm.h
+++ b/include/linux/tpm.h
@@ -253,7 +253,34 @@ enum tpm2_capabilities {
};
enum tpm2_properties {
- TPM_PT_TOTAL_COMMANDS = 0x0129,
+ TPM_PT_TOTAL_COMMANDS = 0x0129,
+ TPM2_PT_NONE = 0,
+ TPM2_PT_GROUP = 0x100,
+ TPM2_PT_FIXED = TPM2_PT_GROUP,
+ TPM2_PT_VAR = TPM2_PT_GROUP * 2,
+ TPM2_PT_PERMANENT = TPM2_PT_VAR + 0,
+ TPM2_PT_STARTUP_CLEAR = TPM2_PT_VAR + 1,
+ TPM2_PT_LOCKOUT_COUNTER = TPM2_PT_VAR + 14,
+ TPM2_PT_MAX_AUTH_FAIL = TPM2_PT_VAR + 15,
+ TPM2_PT_LOCKOUT_INTERVAL = TPM2_PT_VAR + 16,
+ TPM2_PT_LOCKOUT_RECOVERY = TPM2_PT_VAR + 17,
+};
+
+enum tpm2_attr_permanent {
+ TPM2_ATTR_OWNER_AUTH_SET = BIT(0),
+ TPM2_ATTR_ENDORSEMENT_AUTH_SET = BIT(1),
+ TPM2_ATTR_LOCKOUT_AUTH_SET = BIT(2),
+ TPM2_ATTR_DISABLE_CLEAR = BIT(8),
+ TPM2_ATTR_IN_LOCKOUT = BIT(9),
+ TPM2_ATTR_TPM_GENERATED_EPS = BIT(10),
+};
+
+enum tpm2_attr_startup_clear {
+ TPM2_ATTR_PH_ENABLE = BIT(0),
+ TPM2_ATTR_SH_ENABLE = BIT(1),
+ TPM2_ATTR_EH_ENABLE = BIT(2),
+ TPM2_ATTR_PH_ENABLE_NV = BIT(3),
+ TPM2_ATTR_ORDERLY = BIT(31),
};
enum tpm2_startup_types {
--
2.17.1