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 struct tpm_readpubek_out
{
34 #define READ_PUBEK_RESULT_MIN_BODY_SIZE (28 + 256)
35 #define TPM_ORD_READPUBEK 124
37 static ssize_t
pubek_show(struct device
*dev
, struct device_attribute
*attr
,
40 struct tpm_buf tpm_buf
;
41 struct tpm_readpubek_out
*out
;
45 struct tpm_chip
*chip
= to_tpm_chip(dev
);
48 memset(&anti_replay
, 0, sizeof(anti_replay
));
50 rc
= tpm_buf_init(&tpm_buf
, TPM_TAG_RQU_COMMAND
, TPM_ORD_READPUBEK
);
54 tpm_buf_append(&tpm_buf
, anti_replay
, sizeof(anti_replay
));
56 rc
= tpm_transmit_cmd(chip
, NULL
, tpm_buf
.data
, PAGE_SIZE
,
57 READ_PUBEK_RESULT_MIN_BODY_SIZE
, 0,
58 "attempting to read the PUBEK");
60 tpm_buf_destroy(&tpm_buf
);
64 out
= (struct tpm_readpubek_out
*)&tpm_buf
.data
[10];
67 "Algorithm: %02X %02X %02X %02X\n"
68 "Encscheme: %02X %02X\n"
69 "Sigscheme: %02X %02X\n"
70 "Parameters: %02X %02X %02X %02X "
71 "%02X %02X %02X %02X "
72 "%02X %02X %02X %02X\n"
73 "Modulus length: %d\n"
75 out
->algorithm
[0], out
->algorithm
[1], out
->algorithm
[2],
77 out
->encscheme
[0], out
->encscheme
[1],
78 out
->sigscheme
[0], out
->sigscheme
[1],
79 out
->parameters
[0], out
->parameters
[1],
80 out
->parameters
[2], out
->parameters
[3],
81 out
->parameters
[4], out
->parameters
[5],
82 out
->parameters
[6], out
->parameters
[7],
83 out
->parameters
[8], out
->parameters
[9],
84 out
->parameters
[10], out
->parameters
[11],
85 be32_to_cpu(out
->keysize
));
87 for (i
= 0; i
< 256; i
++) {
88 str
+= sprintf(str
, "%02X ", out
->modulus
[i
]);
89 if ((i
+ 1) % 16 == 0)
90 str
+= sprintf(str
, "\n");
94 tpm_buf_destroy(&tpm_buf
);
97 static DEVICE_ATTR_RO(pubek
);
99 static ssize_t
pcrs_show(struct device
*dev
, struct device_attribute
*attr
,
103 u8 digest
[TPM_DIGEST_SIZE
];
107 struct tpm_chip
*chip
= to_tpm_chip(dev
);
109 rc
= tpm_getcap(chip
, TPM_CAP_PROP_PCR
, &cap
,
110 "attempting to determine the number of PCRS",
111 sizeof(cap
.num_pcrs
));
115 num_pcrs
= be32_to_cpu(cap
.num_pcrs
);
116 for (i
= 0; i
< num_pcrs
; i
++) {
117 rc
= tpm_pcr_read_dev(chip
, i
, digest
);
120 str
+= sprintf(str
, "PCR-%02d: ", i
);
121 for (j
= 0; j
< TPM_DIGEST_SIZE
; j
++)
122 str
+= sprintf(str
, "%02X ", digest
[j
]);
123 str
+= sprintf(str
, "\n");
127 static DEVICE_ATTR_RO(pcrs
);
129 static ssize_t
enabled_show(struct device
*dev
, struct device_attribute
*attr
,
135 rc
= tpm_getcap(to_tpm_chip(dev
), TPM_CAP_FLAG_PERM
, &cap
,
136 "attempting to determine the permanent enabled state",
137 sizeof(cap
.perm_flags
));
141 rc
= sprintf(buf
, "%d\n", !cap
.perm_flags
.disable
);
144 static DEVICE_ATTR_RO(enabled
);
146 static ssize_t
active_show(struct device
*dev
, struct device_attribute
*attr
,
152 rc
= tpm_getcap(to_tpm_chip(dev
), TPM_CAP_FLAG_PERM
, &cap
,
153 "attempting to determine the permanent active state",
154 sizeof(cap
.perm_flags
));
158 rc
= sprintf(buf
, "%d\n", !cap
.perm_flags
.deactivated
);
161 static DEVICE_ATTR_RO(active
);
163 static ssize_t
owned_show(struct device
*dev
, struct device_attribute
*attr
,
169 rc
= tpm_getcap(to_tpm_chip(dev
), TPM_CAP_PROP_OWNER
, &cap
,
170 "attempting to determine the owner state",
175 rc
= sprintf(buf
, "%d\n", cap
.owned
);
178 static DEVICE_ATTR_RO(owned
);
180 static ssize_t
temp_deactivated_show(struct device
*dev
,
181 struct device_attribute
*attr
, char *buf
)
186 rc
= tpm_getcap(to_tpm_chip(dev
), TPM_CAP_FLAG_VOL
, &cap
,
187 "attempting to determine the temporary state",
188 sizeof(cap
.stclear_flags
));
192 rc
= sprintf(buf
, "%d\n", cap
.stclear_flags
.deactivated
);
195 static DEVICE_ATTR_RO(temp_deactivated
);
197 static ssize_t
caps_show(struct device
*dev
, struct device_attribute
*attr
,
200 struct tpm_chip
*chip
= to_tpm_chip(dev
);
205 rc
= tpm_getcap(chip
, TPM_CAP_PROP_MANUFACTURER
, &cap
,
206 "attempting to determine the manufacturer",
207 sizeof(cap
.manufacturer_id
));
210 str
+= sprintf(str
, "Manufacturer: 0x%x\n",
211 be32_to_cpu(cap
.manufacturer_id
));
213 /* Try to get a TPM version 1.2 TPM_CAP_VERSION_INFO */
214 rc
= tpm_getcap(chip
, TPM_CAP_VERSION_1_2
, &cap
,
215 "attempting to determine the 1.2 version",
216 sizeof(cap
.tpm_version_1_2
));
219 "TCG version: %d.%d\nFirmware version: %d.%d\n",
220 cap
.tpm_version_1_2
.Major
,
221 cap
.tpm_version_1_2
.Minor
,
222 cap
.tpm_version_1_2
.revMajor
,
223 cap
.tpm_version_1_2
.revMinor
);
225 /* Otherwise just use TPM_STRUCT_VER */
226 rc
= tpm_getcap(chip
, TPM_CAP_VERSION_1_1
, &cap
,
227 "attempting to determine the 1.1 version",
228 sizeof(cap
.tpm_version
));
232 "TCG version: %d.%d\nFirmware version: %d.%d\n",
233 cap
.tpm_version
.Major
,
234 cap
.tpm_version
.Minor
,
235 cap
.tpm_version
.revMajor
,
236 cap
.tpm_version
.revMinor
);
241 static DEVICE_ATTR_RO(caps
);
243 static ssize_t
cancel_store(struct device
*dev
, struct device_attribute
*attr
,
244 const char *buf
, size_t count
)
246 struct tpm_chip
*chip
= to_tpm_chip(dev
);
250 chip
->ops
->cancel(chip
);
253 static DEVICE_ATTR_WO(cancel
);
255 static ssize_t
durations_show(struct device
*dev
, struct device_attribute
*attr
,
258 struct tpm_chip
*chip
= to_tpm_chip(dev
);
260 if (chip
->duration
[TPM_LONG
] == 0)
263 return sprintf(buf
, "%d %d %d [%s]\n",
264 jiffies_to_usecs(chip
->duration
[TPM_SHORT
]),
265 jiffies_to_usecs(chip
->duration
[TPM_MEDIUM
]),
266 jiffies_to_usecs(chip
->duration
[TPM_LONG
]),
267 chip
->duration_adjusted
268 ? "adjusted" : "original");
270 static DEVICE_ATTR_RO(durations
);
272 static ssize_t
timeouts_show(struct device
*dev
, struct device_attribute
*attr
,
275 struct tpm_chip
*chip
= to_tpm_chip(dev
);
277 return sprintf(buf
, "%d %d %d %d [%s]\n",
278 jiffies_to_usecs(chip
->timeout_a
),
279 jiffies_to_usecs(chip
->timeout_b
),
280 jiffies_to_usecs(chip
->timeout_c
),
281 jiffies_to_usecs(chip
->timeout_d
),
282 chip
->timeout_adjusted
283 ? "adjusted" : "original");
285 static DEVICE_ATTR_RO(timeouts
);
287 static struct attribute
*tpm_dev_attrs
[] = {
288 &dev_attr_pubek
.attr
,
290 &dev_attr_enabled
.attr
,
291 &dev_attr_active
.attr
,
292 &dev_attr_owned
.attr
,
293 &dev_attr_temp_deactivated
.attr
,
295 &dev_attr_cancel
.attr
,
296 &dev_attr_durations
.attr
,
297 &dev_attr_timeouts
.attr
,
301 static const struct attribute_group tpm_dev_group
= {
302 .attrs
= tpm_dev_attrs
,
305 void tpm_sysfs_add_device(struct tpm_chip
*chip
)
307 /* XXX: If you wish to remove this restriction, you must first update
308 * tpm_sysfs to explicitly lock chip->ops.
310 if (chip
->flags
& TPM_CHIP_FLAG_TPM2
)
313 /* The sysfs routines rely on an implicit tpm_try_get_ops, device_del
314 * is called before ops is null'd and the sysfs core synchronizes this
315 * removal so that no callbacks are running or can run again
317 WARN_ON(chip
->groups_cnt
!= 0);
318 chip
->groups
[chip
->groups_cnt
++] = &tpm_dev_group
;