mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Kylene Jo Hall <kjhall@us.ibm.com>
To: linux-kernel <linux-kernel@vger.kernel.org>
Cc: akpm@osdl.org,
	TPM Device Driver List <tpmdd-devel@lists.sourceforge.net>,
	Marcel Selhorst <selhorst@crypto.rub.de>
Subject: PATCH 6/7] tpm: new 1.2 sysfs files
Date: Mon, 03 Apr 2006 11:42:41 -0500	[thread overview]
Message-ID: <1144082562.29910.12.camel@localhost.localdomain> (raw)
In-Reply-To: <20060331202714.GC22987@sergelap.austin.ibm.com>

With the 1.2 TPM Specification there is more useful information
available.  This information is exported to the user through sysfs
functions that the 1.2 driver will use.

Signed-off-by: Kylene Hall <kjhall@us.ibm.com>
---
 drivers/char/tpm/tpm.c |  206 +++++++++++++++++++++++++++++++++++++++
 drivers/char/tpm/tpm.h |    7 +
 2 files changed, 213 insertions(+)

--- linux-2.6.16/drivers/char/tpm/tpm.c	2006-03-30 16:58:10.715155750 -0600
+++ linux-2.6.16-rc1-tpm/drivers/char/tpm/tpm.c	2006-03-30 16:51:48.567273000 -0600
@@ -431,17 +434,27 @@ out:
 #define TPM_GET_CAP_RET_UINT32_2_IDX 18
 #define TPM_GET_CAP_RET_UINT32_3_IDX 22
 #define TPM_GET_CAP_RET_UINT32_4_IDX 26
+#define TPM_GET_CAP_PERM_DISABLE_IDX 16
+#define TPM_GET_CAP_PERM_INACTIVE_IDX 18
+#define TPM_GET_CAP_RET_BOOL_1_IDX 14
+#define TPM_GET_CAP_TEMP_INACTIVE_IDX 16
 
 #define TPM_CAP_IDX 13
 #define TPM_CAP_SUBCAP_IDX 21
 
 enum tpm_capabilities {
+	TPM_CAP_FLAG = 4,
 	TPM_CAP_PROP = 5,
 };
 
 enum tpm_sub_capabilities {
 	TPM_CAP_PROP_PCR = 0x1,
 	TPM_CAP_PROP_MANUFACTURER = 0x3,
+	TPM_CAP_FLAG_PERM = 0x8,
+	TPM_CAP_FLAG_VOL = 0x9,
+	TPM_CAP_PROP_OWNER = 0x11,
+	TPM_CAP_PROP_TIS_TIMEOUT = 0x15,
+	TPM_CAP_PROP_TIS_DURATION = 0x20,
 };
 
 /*
@@ -459,6 +472,155 @@ static const u8 tpm_cap[] = {
 	0, 0, 1, 0		/* TPM_CAP_SUB_<TYPE> */
 };
 
+void tpm_gen_interrupt(struct tpm_chip *chip)
+{
+	u8 data[30];
+	ssize_t len;
+
+	memcpy(data, tpm_cap, sizeof(tpm_cap));
+	data[TPM_CAP_IDX] = TPM_CAP_PROP;
+	data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_TIS_TIMEOUT;
+
+	if ((len = tpm_transmit(chip, data, sizeof(data)))
+	    <= TPM_ERROR_SIZE)
+		dev_dbg(chip->dev, "A TPM error (%d) occurred "
+			"attempting to determine the timeouts\n",
+			be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX))));
+}
+EXPORT_SYMBOL_GPL(tpm_gen_interrupt);
+
+void tpm_get_timeouts(struct tpm_chip *chip)
+{
+	u8 data[30];
+	ssize_t len;
+	u32 timeout;
+
+	memcpy(data, tpm_cap, sizeof(tpm_cap));
+	data[TPM_CAP_IDX] = TPM_CAP_PROP;
+	data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_TIS_TIMEOUT;
+
+	if ((len = tpm_transmit(chip, data, sizeof(data)))
+	    <= TPM_ERROR_SIZE) {
+		dev_dbg(chip->dev, "A TPM error (%d) occurred "
+			"attempting to determine the timeouts\n",
+			be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX))));
+		goto duration;
+	}
+
+	if ((len =
+	     be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_SIZE_IDX))))
+	    != 4 * sizeof(u32))
+		goto duration;
+
+	/* Don't overwrite default if value is 0 */
+	timeout = 
+	    be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX)));
+	if (timeout)
+		chip->vendor.timeout_a = timeout;
+	timeout =
+	    be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_2_IDX)));
+	if (timeout)
+		chip->vendor.timeout_b = timeout;
+	timeout =
+	    be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_3_IDX)));
+	if (timeout)
+		chip->vendor.timeout_c = timeout;
+	timeout =
+	    be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_4_IDX)));
+	if (timeout)
+		chip->vendor.timeout_d = timeout;
+
+duration:
+	memcpy(data, tpm_cap, sizeof(tpm_cap));
+	data[TPM_CAP_IDX] = TPM_CAP_PROP;
+	data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_TIS_DURATION;
+
+	if ((len = tpm_transmit(chip, data, sizeof(data)))
+	    <= TPM_ERROR_SIZE) {
+		dev_dbg(chip->dev, "A TPM error (%d) occurred "
+			"attempting to determine the durations\n",
+			be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX))));
+		return;
+	}
+
+	if ((len =
+	     be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_SIZE_IDX))))
+	    != 3 * sizeof(u32))
+		return;
+
+	chip->vendor.duration[TPM_SHORT] =
+	    be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX)));
+	chip->vendor.duration[TPM_MEDIUM] =
+	    be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_2_IDX)));
+	chip->vendor.duration[TPM_LONG] =
+	    be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_3_IDX)));
+}
+EXPORT_SYMBOL_GPL(tpm_get_timeouts);
+
+ssize_t tpm_show_state(struct device * dev, struct device_attribute * attr,
+		       char *buf)
+{
+	u8 data[35];
+	ssize_t len;
+	char *str = buf;
+
+	struct tpm_chip *chip = dev_get_drvdata(dev);
+	if (chip == NULL)
+		return -ENODEV;
+
+	memcpy(data, tpm_cap, sizeof(tpm_cap));
+	data[TPM_CAP_IDX] = TPM_CAP_FLAG;
+	data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_PERM;
+
+	if ((len = tpm_transmit(chip, data, sizeof(data)))
+	    <= TPM_ERROR_SIZE)
+		dev_dbg(chip->dev, "A TPM error (%d) occurred "
+			"attempting to determine the permanent state\n",
+			be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX))));
+	else {
+		str +=
+		    sprintf(str, "%s\n",
+			    (data[TPM_GET_CAP_PERM_DISABLE_IDX] ==
+			     1) ? "Disabled" : "Enabled");
+		str +=
+		    sprintf(str, "%s\n",
+			    (data[TPM_GET_CAP_PERM_INACTIVE_IDX] ==
+			     1) ? "Inactive" : "Active");
+	}
+	memcpy(data, tpm_cap, sizeof(tpm_cap));
+	data[TPM_CAP_IDX] = TPM_CAP_PROP;
+	data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_OWNER;
+
+	if ((len = tpm_transmit(chip, data, sizeof(data)))
+	    <= TPM_ERROR_SIZE)
+		dev_dbg(chip->dev, "A TPM error (%d) occurred "
+			"attempting to determine the owner state\n",
+			be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX))));
+	else
+		str +=
+		    sprintf(str, "%s\n",
+			    (data[TPM_GET_CAP_RET_BOOL_1_IDX] ==
+			     1) ? "Owned" : "Unowned");
+
+	memcpy(data, tpm_cap, sizeof(tpm_cap));
+	data[TPM_CAP_IDX] = TPM_CAP_FLAG;
+	data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_VOL;
+
+	if ((len = tpm_transmit(chip, data, sizeof(data)))
+	    <= TPM_ERROR_SIZE) {
+		dev_dbg(chip->dev, "A TPM error (%d) occurred "
+			"attempting to determine the temporary state\n",
+			be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX))));
+		goto out;
+	}
+
+	if (data[TPM_GET_CAP_TEMP_INACTIVE_IDX] != 0)
+		str += sprintf(str, "Deactivated for this boot\n");
+out:
+	return str - buf;
+}
+EXPORT_SYMBOL_GPL(tpm_show_state);
+
 static const u8 pcrread[] = {
 	0, 193,			/* TPM_TAG_RQU_COMMAND */
 	0, 0, 0, 14,		/* length */
@@ -590,6 +768,7 @@ out:
 EXPORT_SYMBOL_GPL(tpm_show_pubek);
 
 #define CAP_VERSION_1_1 6
+#define CAP_VERSION_1_2 0x1A
 #define CAP_VERSION_IDX 13
 static const u8 cap_version[] = {
 	0, 193,			/* TPM_TAG_RQU_COMMAND */
@@ -651,6 +830,52 @@ out:
 }
 EXPORT_SYMBOL_GPL(tpm_show_caps);
 
+ssize_t tpm_show_caps_1_2(struct device * dev,
+			  struct device_attribute * attr, char *buf)
+{
+	u8 data[30];
+	ssize_t len;
+	char *str = buf;
+
+	struct tpm_chip *chip = dev_get_drvdata(dev);
+	if (chip == NULL)
+		return -ENODEV;
+
+	memcpy(data, tpm_cap, sizeof(tpm_cap));
+	data[TPM_CAP_IDX] = TPM_CAP_PROP;
+	data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_MANUFACTURER;
+
+	if ((len = tpm_transmit(chip, data, sizeof(data))) <=
+	    TPM_ERROR_SIZE) {
+		dev_dbg(chip->dev, "A TPM error (%d) occurred "
+			"attempting to determine the manufacturer\n",
+			be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX))));
+		return 0;
+	}
+
+	str += sprintf(str, "Manufacturer: 0x%x\n",
+		       be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX))));
+
+	memcpy(data, cap_version, sizeof(cap_version));
+	data[CAP_VERSION_IDX] = CAP_VERSION_1_2;
+
+	if ((len = tpm_transmit(chip, data, sizeof(data))) <=
+	    TPM_ERROR_SIZE) {
+		dev_err(chip->dev, "A TPM error (%d) occurred "
+			"attempting to determine the 1.2 version\n",
+			be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX))));
+		goto out;
+	}
+	str += sprintf(str,
+		       "TCG version: %d.%d\nFirmware version: %d.%d\n",
+		       (int) data[16], (int) data[17], (int) data[18],
+		       (int) data[19]);
+
+out:
+	return str - buf;
+}
+EXPORT_SYMBOL_GPL(tpm_show_caps_1_2);
+
 ssize_t tpm_store_cancel(struct device *dev, struct device_attribute *attr,
 			const char *buf, size_t count)
 {
--- linux-2.6.16/drivers/char/tpm/tpm.h	2006-03-30 16:58:10.715155750 -0600
+++ linux-2.6.16-rc1-tpm/drivers/char/tpm/tpm.h	2006-03-29 14:16:30.119053500 -0600
@@ -41,8 +41,12 @@ extern ssize_t tpm_show_pcrs(struct devi
 				char *);
 extern ssize_t tpm_show_caps(struct device *, struct device_attribute *attr,
 				char *);
+extern ssize_t tpm_show_caps_1_2(struct device *, struct device_attribute *attr,
+				char *);
 extern ssize_t tpm_store_cancel(struct device *, struct device_attribute *attr,
 				const char *, size_t);
+extern ssize_t tpm_show_state(struct device *, struct device_attribute *attr,
+				char *);
 
 struct tpm_chip;
 
@@ -62,6 +68,7 @@ struct tpm_vendor_specific {
 	u8 (*status) (struct tpm_chip *);
 	struct miscdevice miscdev;
 	struct attribute_group *attr_group;
+	u32 timeout_a, timeout_b, timeout_c, timeout_d;
 	u32 duration[3];
 };
 
@@ -100,6 +114,8 @@ static inline void tpm_write_index(int b
 	outb(value & 0xFF, base+1);
 }
 
+extern void tpm_get_timeouts(struct tpm_chip *);
+extern void tpm_gen_interrupt(struct tpm_chip *);
 extern unsigned long tpm_calc_ordinal_duration(struct tpm_chip *, u32);
 extern struct tpm_chip* tpm_register_hardware(struct device *,
 				 const struct tpm_vendor_specific *);



       reply	other threads:[~2006-04-03 16:42 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <1143823501.2992.170.camel@localhost.localdomain>
     [not found] ` <20060331202714.GC22987@sergelap.austin.ibm.com>
2006-04-03 16:42   ` Kylene Jo Hall [this message]
2006-04-03 21:47     ` Greg KH

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1144082562.29910.12.camel@localhost.localdomain \
    --to=kjhall@us.ibm.com \
    --cc=akpm@osdl.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=selhorst@crypto.rub.de \
    --cc=tpmdd-devel@lists.sourceforge.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

Powered by JetHome