| 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 |
| |