2 * Copyright (C) 2004 IBM Corporation
4 * Leendert van Doorn <leendert@watson.ibm.com>
5 * Dave Safford <safford@watson.ibm.com>
6 * Reiner Sailer <sailer@watson.ibm.com>
7 * Kylene Hall <kjhall@us.ibm.com>
9 * Copyright (C) 2013 Obsidian Research Corp
10 * Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
12 * sysfs filesystem inspection interface to the TPM
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation, version 2 of the
20 #include <linux/device.h>
23 #define READ_PUBEK_RESULT_SIZE 314
24 #define TPM_ORD_READPUBEK cpu_to_be32(124)
25 static struct tpm_input_header tpm_readpubek_header
= {
26 .tag
= TPM_TAG_RQU_COMMAND
,
27 .length
= cpu_to_be32(30),
28 .ordinal
= TPM_ORD_READPUBEK
30 static ssize_t
pubek_show(struct device
*dev
, struct device_attribute
*attr
,
34 struct tpm_cmd_t tpm_cmd
;
39 struct tpm_chip
*chip
= dev_get_drvdata(dev
);
41 tpm_cmd
.header
.in
= tpm_readpubek_header
;
42 err
= tpm_transmit_cmd(chip
, &tpm_cmd
, READ_PUBEK_RESULT_SIZE
,
43 "attempting to read the PUBEK");
48 ignore header 10 bytes
49 algorithm 32 bits (1 == RSA )
52 parameters (RSA 12->bytes: keybit, #primes, expbit)
55 ignore checksum 20 bytes
57 data
= tpm_cmd
.params
.readpubek_out_buffer
;
60 "Algorithm: %02X %02X %02X %02X\n"
61 "Encscheme: %02X %02X\n"
62 "Sigscheme: %02X %02X\n"
63 "Parameters: %02X %02X %02X %02X "
64 "%02X %02X %02X %02X "
65 "%02X %02X %02X %02X\n"
66 "Modulus length: %d\n"
68 data
[0], data
[1], data
[2], data
[3],
71 data
[12], data
[13], data
[14], data
[15],
72 data
[16], data
[17], data
[18], data
[19],
73 data
[20], data
[21], data
[22], data
[23],
74 be32_to_cpu(*((__be32
*) (data
+ 24))));
76 for (i
= 0; i
< 256; i
++) {
77 str
+= sprintf(str
, "%02X ", data
[i
+ 28]);
78 if ((i
+ 1) % 16 == 0)
79 str
+= sprintf(str
, "\n");
85 static DEVICE_ATTR_RO(pubek
);
87 static ssize_t
pcrs_show(struct device
*dev
, struct device_attribute
*attr
,
91 u8 digest
[TPM_DIGEST_SIZE
];
95 struct tpm_chip
*chip
= dev_get_drvdata(dev
);
97 rc
= tpm_getcap(dev
, TPM_CAP_PROP_PCR
, &cap
,
98 "attempting to determine the number of PCRS");
102 num_pcrs
= be32_to_cpu(cap
.num_pcrs
);
103 for (i
= 0; i
< num_pcrs
; i
++) {
104 rc
= tpm_pcr_read_dev(chip
, i
, digest
);
107 str
+= sprintf(str
, "PCR-%02d: ", i
);
108 for (j
= 0; j
< TPM_DIGEST_SIZE
; j
++)
109 str
+= sprintf(str
, "%02X ", digest
[j
]);
110 str
+= sprintf(str
, "\n");
114 static DEVICE_ATTR_RO(pcrs
);
116 static ssize_t
enabled_show(struct device
*dev
, struct device_attribute
*attr
,
122 rc
= tpm_getcap(dev
, TPM_CAP_FLAG_PERM
, &cap
,
123 "attempting to determine the permanent enabled state");
127 rc
= sprintf(buf
, "%d\n", !cap
.perm_flags
.disable
);
130 static DEVICE_ATTR_RO(enabled
);
132 static ssize_t
active_show(struct device
*dev
, struct device_attribute
*attr
,
138 rc
= tpm_getcap(dev
, TPM_CAP_FLAG_PERM
, &cap
,
139 "attempting to determine the permanent active state");
143 rc
= sprintf(buf
, "%d\n", !cap
.perm_flags
.deactivated
);
146 static DEVICE_ATTR_RO(active
);
148 static ssize_t
owned_show(struct device
*dev
, struct device_attribute
*attr
,
154 rc
= tpm_getcap(dev
, TPM_CAP_PROP_OWNER
, &cap
,
155 "attempting to determine the owner state");
159 rc
= sprintf(buf
, "%d\n", cap
.owned
);
162 static DEVICE_ATTR_RO(owned
);
164 static ssize_t
temp_deactivated_show(struct device
*dev
,
165 struct device_attribute
*attr
, char *buf
)
170 rc
= tpm_getcap(dev
, TPM_CAP_FLAG_VOL
, &cap
,
171 "attempting to determine the temporary state");
175 rc
= sprintf(buf
, "%d\n", cap
.stclear_flags
.deactivated
);
178 static DEVICE_ATTR_RO(temp_deactivated
);
180 static ssize_t
caps_show(struct device
*dev
, struct device_attribute
*attr
,
187 rc
= tpm_getcap(dev
, TPM_CAP_PROP_MANUFACTURER
, &cap
,
188 "attempting to determine the manufacturer");
191 str
+= sprintf(str
, "Manufacturer: 0x%x\n",
192 be32_to_cpu(cap
.manufacturer_id
));
194 /* Try to get a TPM version 1.2 TPM_CAP_VERSION_INFO */
195 rc
= tpm_getcap(dev
, CAP_VERSION_1_2
, &cap
,
196 "attempting to determine the 1.2 version");
199 "TCG version: %d.%d\nFirmware version: %d.%d\n",
200 cap
.tpm_version_1_2
.Major
,
201 cap
.tpm_version_1_2
.Minor
,
202 cap
.tpm_version_1_2
.revMajor
,
203 cap
.tpm_version_1_2
.revMinor
);
205 /* Otherwise just use TPM_STRUCT_VER */
206 rc
= tpm_getcap(dev
, CAP_VERSION_1_1
, &cap
,
207 "attempting to determine the 1.1 version");
211 "TCG version: %d.%d\nFirmware version: %d.%d\n",
212 cap
.tpm_version
.Major
,
213 cap
.tpm_version
.Minor
,
214 cap
.tpm_version
.revMajor
,
215 cap
.tpm_version
.revMinor
);
220 static DEVICE_ATTR_RO(caps
);
222 static ssize_t
cancel_store(struct device
*dev
, struct device_attribute
*attr
,
223 const char *buf
, size_t count
)
225 struct tpm_chip
*chip
= dev_get_drvdata(dev
);
229 chip
->ops
->cancel(chip
);
232 static DEVICE_ATTR_WO(cancel
);
234 static ssize_t
durations_show(struct device
*dev
, struct device_attribute
*attr
,
237 struct tpm_chip
*chip
= dev_get_drvdata(dev
);
239 if (chip
->vendor
.duration
[TPM_LONG
] == 0)
242 return sprintf(buf
, "%d %d %d [%s]\n",
243 jiffies_to_usecs(chip
->vendor
.duration
[TPM_SHORT
]),
244 jiffies_to_usecs(chip
->vendor
.duration
[TPM_MEDIUM
]),
245 jiffies_to_usecs(chip
->vendor
.duration
[TPM_LONG
]),
246 chip
->vendor
.duration_adjusted
247 ? "adjusted" : "original");
249 static DEVICE_ATTR_RO(durations
);
251 static ssize_t
timeouts_show(struct device
*dev
, struct device_attribute
*attr
,
254 struct tpm_chip
*chip
= dev_get_drvdata(dev
);
256 return sprintf(buf
, "%d %d %d %d [%s]\n",
257 jiffies_to_usecs(chip
->vendor
.timeout_a
),
258 jiffies_to_usecs(chip
->vendor
.timeout_b
),
259 jiffies_to_usecs(chip
->vendor
.timeout_c
),
260 jiffies_to_usecs(chip
->vendor
.timeout_d
),
261 chip
->vendor
.timeout_adjusted
262 ? "adjusted" : "original");
264 static DEVICE_ATTR_RO(timeouts
);
266 static struct attribute
*tpm_dev_attrs
[] = {
267 &dev_attr_pubek
.attr
,
269 &dev_attr_enabled
.attr
,
270 &dev_attr_active
.attr
,
271 &dev_attr_owned
.attr
,
272 &dev_attr_temp_deactivated
.attr
,
274 &dev_attr_cancel
.attr
,
275 &dev_attr_durations
.attr
,
276 &dev_attr_timeouts
.attr
,
280 static const struct attribute_group tpm_dev_group
= {
281 .attrs
= tpm_dev_attrs
,
284 int tpm_sysfs_add_device(struct tpm_chip
*chip
)
287 err
= sysfs_create_group(&chip
->pdev
->kobj
,
292 "failed to create sysfs attributes, %d\n", err
);
296 void tpm_sysfs_del_device(struct tpm_chip
*chip
)
298 sysfs_remove_group(&chip
->pdev
->kobj
, &tpm_dev_group
);