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 memset(&tpm_cmd
, 0, sizeof(tpm_cmd
));
43 tpm_cmd
.header
.in
= tpm_readpubek_header
;
44 err
= tpm_transmit_cmd(chip
, &tpm_cmd
, READ_PUBEK_RESULT_SIZE
, 0,
45 "attempting to read the PUBEK");
50 ignore header 10 bytes
51 algorithm 32 bits (1 == RSA )
54 parameters (RSA 12->bytes: keybit, #primes, expbit)
57 ignore checksum 20 bytes
59 data
= tpm_cmd
.params
.readpubek_out_buffer
;
62 "Algorithm: %02X %02X %02X %02X\n"
63 "Encscheme: %02X %02X\n"
64 "Sigscheme: %02X %02X\n"
65 "Parameters: %02X %02X %02X %02X "
66 "%02X %02X %02X %02X "
67 "%02X %02X %02X %02X\n"
68 "Modulus length: %d\n"
70 data
[0], data
[1], data
[2], data
[3],
73 data
[12], data
[13], data
[14], data
[15],
74 data
[16], data
[17], data
[18], data
[19],
75 data
[20], data
[21], data
[22], data
[23],
76 be32_to_cpu(*((__be32
*) (data
+ 24))));
78 for (i
= 0; i
< 256; i
++) {
79 str
+= sprintf(str
, "%02X ", data
[i
+ 28]);
80 if ((i
+ 1) % 16 == 0)
81 str
+= sprintf(str
, "\n");
87 static DEVICE_ATTR_RO(pubek
);
89 static ssize_t
pcrs_show(struct device
*dev
, struct device_attribute
*attr
,
93 u8 digest
[TPM_DIGEST_SIZE
];
97 struct tpm_chip
*chip
= dev_get_drvdata(dev
);
99 rc
= tpm_getcap(dev
, TPM_CAP_PROP_PCR
, &cap
,
100 "attempting to determine the number of PCRS");
104 num_pcrs
= be32_to_cpu(cap
.num_pcrs
);
105 for (i
= 0; i
< num_pcrs
; i
++) {
106 rc
= tpm_pcr_read_dev(chip
, i
, digest
);
109 str
+= sprintf(str
, "PCR-%02d: ", i
);
110 for (j
= 0; j
< TPM_DIGEST_SIZE
; j
++)
111 str
+= sprintf(str
, "%02X ", digest
[j
]);
112 str
+= sprintf(str
, "\n");
116 static DEVICE_ATTR_RO(pcrs
);
118 static ssize_t
enabled_show(struct device
*dev
, struct device_attribute
*attr
,
124 rc
= tpm_getcap(dev
, TPM_CAP_FLAG_PERM
, &cap
,
125 "attempting to determine the permanent enabled state");
129 rc
= sprintf(buf
, "%d\n", !cap
.perm_flags
.disable
);
132 static DEVICE_ATTR_RO(enabled
);
134 static ssize_t
active_show(struct device
*dev
, struct device_attribute
*attr
,
140 rc
= tpm_getcap(dev
, TPM_CAP_FLAG_PERM
, &cap
,
141 "attempting to determine the permanent active state");
145 rc
= sprintf(buf
, "%d\n", !cap
.perm_flags
.deactivated
);
148 static DEVICE_ATTR_RO(active
);
150 static ssize_t
owned_show(struct device
*dev
, struct device_attribute
*attr
,
156 rc
= tpm_getcap(dev
, TPM_CAP_PROP_OWNER
, &cap
,
157 "attempting to determine the owner state");
161 rc
= sprintf(buf
, "%d\n", cap
.owned
);
164 static DEVICE_ATTR_RO(owned
);
166 static ssize_t
temp_deactivated_show(struct device
*dev
,
167 struct device_attribute
*attr
, char *buf
)
172 rc
= tpm_getcap(dev
, TPM_CAP_FLAG_VOL
, &cap
,
173 "attempting to determine the temporary state");
177 rc
= sprintf(buf
, "%d\n", cap
.stclear_flags
.deactivated
);
180 static DEVICE_ATTR_RO(temp_deactivated
);
182 static ssize_t
caps_show(struct device
*dev
, struct device_attribute
*attr
,
189 rc
= tpm_getcap(dev
, TPM_CAP_PROP_MANUFACTURER
, &cap
,
190 "attempting to determine the manufacturer");
193 str
+= sprintf(str
, "Manufacturer: 0x%x\n",
194 be32_to_cpu(cap
.manufacturer_id
));
196 /* Try to get a TPM version 1.2 TPM_CAP_VERSION_INFO */
197 rc
= tpm_getcap(dev
, CAP_VERSION_1_2
, &cap
,
198 "attempting to determine the 1.2 version");
201 "TCG version: %d.%d\nFirmware version: %d.%d\n",
202 cap
.tpm_version_1_2
.Major
,
203 cap
.tpm_version_1_2
.Minor
,
204 cap
.tpm_version_1_2
.revMajor
,
205 cap
.tpm_version_1_2
.revMinor
);
207 /* Otherwise just use TPM_STRUCT_VER */
208 rc
= tpm_getcap(dev
, CAP_VERSION_1_1
, &cap
,
209 "attempting to determine the 1.1 version");
213 "TCG version: %d.%d\nFirmware version: %d.%d\n",
214 cap
.tpm_version
.Major
,
215 cap
.tpm_version
.Minor
,
216 cap
.tpm_version
.revMajor
,
217 cap
.tpm_version
.revMinor
);
222 static DEVICE_ATTR_RO(caps
);
224 static ssize_t
cancel_store(struct device
*dev
, struct device_attribute
*attr
,
225 const char *buf
, size_t count
)
227 struct tpm_chip
*chip
= dev_get_drvdata(dev
);
231 chip
->ops
->cancel(chip
);
234 static DEVICE_ATTR_WO(cancel
);
236 static ssize_t
durations_show(struct device
*dev
, struct device_attribute
*attr
,
239 struct tpm_chip
*chip
= dev_get_drvdata(dev
);
241 if (chip
->vendor
.duration
[TPM_LONG
] == 0)
244 return sprintf(buf
, "%d %d %d [%s]\n",
245 jiffies_to_usecs(chip
->vendor
.duration
[TPM_SHORT
]),
246 jiffies_to_usecs(chip
->vendor
.duration
[TPM_MEDIUM
]),
247 jiffies_to_usecs(chip
->vendor
.duration
[TPM_LONG
]),
248 chip
->vendor
.duration_adjusted
249 ? "adjusted" : "original");
251 static DEVICE_ATTR_RO(durations
);
253 static ssize_t
timeouts_show(struct device
*dev
, struct device_attribute
*attr
,
256 struct tpm_chip
*chip
= dev_get_drvdata(dev
);
258 return sprintf(buf
, "%d %d %d %d [%s]\n",
259 jiffies_to_usecs(chip
->vendor
.timeout_a
),
260 jiffies_to_usecs(chip
->vendor
.timeout_b
),
261 jiffies_to_usecs(chip
->vendor
.timeout_c
),
262 jiffies_to_usecs(chip
->vendor
.timeout_d
),
263 chip
->vendor
.timeout_adjusted
264 ? "adjusted" : "original");
266 static DEVICE_ATTR_RO(timeouts
);
268 static struct attribute
*tpm_dev_attrs
[] = {
269 &dev_attr_pubek
.attr
,
271 &dev_attr_enabled
.attr
,
272 &dev_attr_active
.attr
,
273 &dev_attr_owned
.attr
,
274 &dev_attr_temp_deactivated
.attr
,
276 &dev_attr_cancel
.attr
,
277 &dev_attr_durations
.attr
,
278 &dev_attr_timeouts
.attr
,
282 static const struct attribute_group tpm_dev_group
= {
283 .attrs
= tpm_dev_attrs
,
286 int tpm_sysfs_add_device(struct tpm_chip
*chip
)
290 /* XXX: If you wish to remove this restriction, you must first update
291 * tpm_sysfs to explicitly lock chip->ops.
293 if (chip
->flags
& TPM_CHIP_FLAG_TPM2
)
296 err
= sysfs_create_group(&chip
->dev
.parent
->kobj
,
301 "failed to create sysfs attributes, %d\n", err
);
305 void tpm_sysfs_del_device(struct tpm_chip
*chip
)
307 /* The sysfs routines rely on an implicit tpm_try_get_ops, this
308 * function is called before ops is null'd and the sysfs core
309 * synchronizes this removal so that no callbacks are running or can
312 sysfs_remove_group(&chip
->dev
.parent
->kobj
, &tpm_dev_group
);