1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Copyright (C) 2004 IBM Corporation
4 * Authors:
5 * Leendert van Doorn <leendert@watson.ibm.com>
6 * Dave Safford <safford@watson.ibm.com>
7 * Reiner Sailer <sailer@watson.ibm.com>
8 * Kylene Hall <kjhall@us.ibm.com>
9 *
10 * Copyright (C) 2013 Obsidian Research Corp
11 * Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
12 *
13 * sysfs filesystem inspection interface to the TPM
14 */
15#include <linux/device.h>
16#include "tpm.h"
17
18struct tpm_readpubek_out {
19	u8 algorithm[4];
20	u8 encscheme[2];
21	u8 sigscheme[2];
22	__be32 paramsize;
23	u8 parameters[12];
24	__be32 keysize;
25	u8 modulus[256];
26	u8 checksum[20];
27} __packed;
28
29#define READ_PUBEK_RESULT_MIN_BODY_SIZE (28 + 256)
30#define TPM_ORD_READPUBEK 124
31
32static ssize_t pubek_show(struct device *dev, struct device_attribute *attr,
33			  char *buf)
34{
35	struct tpm_buf tpm_buf;
36	struct tpm_readpubek_out *out;
37	int i;
38	char *str = buf;
39	struct tpm_chip *chip = to_tpm_chip(dev);
40	char anti_replay[20];
41
42	memset(&anti_replay, 0, sizeof(anti_replay));
43
44	if (tpm_try_get_ops(chip))
45		return 0;
46
47	if (tpm_buf_init(&tpm_buf, TPM_TAG_RQU_COMMAND, TPM_ORD_READPUBEK))
48		goto out_ops;
49
50	tpm_buf_append(&tpm_buf, anti_replay, sizeof(anti_replay));
51
52	if (tpm_transmit_cmd(chip, &tpm_buf, READ_PUBEK_RESULT_MIN_BODY_SIZE,
53			     "attempting to read the PUBEK"))
54		goto out_buf;
55
56	out = (struct tpm_readpubek_out *)&tpm_buf.data[10];
57	str +=
58	    sprintf(str,
59		    "Algorithm: %4ph\n"
60		    "Encscheme: %2ph\n"
61		    "Sigscheme: %2ph\n"
62		    "Parameters: %12ph\n"
63		    "Modulus length: %d\n"
64		    "Modulus:\n",
65		    out->algorithm,
66		    out->encscheme,
67		    out->sigscheme,
68		    out->parameters,
69		    be32_to_cpu(out->keysize));
70
71	for (i = 0; i < 256; i += 16)
72		str += sprintf(str, "%16ph\n", &out->modulus[i]);
73
74out_buf:
75	tpm_buf_destroy(&tpm_buf);
76out_ops:
77	tpm_put_ops(chip);
78	return str - buf;
79}
80static DEVICE_ATTR_RO(pubek);
81
82static ssize_t pcrs_show(struct device *dev, struct device_attribute *attr,
83			 char *buf)
84{
85	cap_t cap;
86	u8 digest[TPM_DIGEST_SIZE];
87	u32 i, j, num_pcrs;
88	char *str = buf;
89	struct tpm_chip *chip = to_tpm_chip(dev);
90
91	if (tpm_try_get_ops(chip))
92		return 0;
93
94	if (tpm1_getcap(chip, TPM_CAP_PROP_PCR, &cap,
95			"attempting to determine the number of PCRS",
96			sizeof(cap.num_pcrs))) {
97		tpm_put_ops(chip);
98		return 0;
99	}
100
101	num_pcrs = be32_to_cpu(cap.num_pcrs);
102	for (i = 0; i < num_pcrs; i++) {
103		if (tpm1_pcr_read(chip, i, digest)) {
104			str = buf;
105			break;
106		}
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");
111	}
112	tpm_put_ops(chip);
113	return str - buf;
114}
115static DEVICE_ATTR_RO(pcrs);
116
117static ssize_t enabled_show(struct device *dev, struct device_attribute *attr,
118		     char *buf)
119{
120	struct tpm_chip *chip = to_tpm_chip(dev);
121	ssize_t rc = 0;
122	cap_t cap;
123
124	if (tpm_try_get_ops(chip))
125		return 0;
126
127	if (tpm1_getcap(chip, TPM_CAP_FLAG_PERM, &cap,
128			"attempting to determine the permanent enabled state",
129			sizeof(cap.perm_flags)))
130		goto out_ops;
131
132	rc = sprintf(buf, "%d\n", !cap.perm_flags.disable);
133out_ops:
134	tpm_put_ops(chip);
135	return rc;
136}
137static DEVICE_ATTR_RO(enabled);
138
139static ssize_t active_show(struct device *dev, struct device_attribute *attr,
140		    char *buf)
141{
142	struct tpm_chip *chip = to_tpm_chip(dev);
143	ssize_t rc = 0;
144	cap_t cap;
145
146	if (tpm_try_get_ops(chip))
147		return 0;
148
149	if (tpm1_getcap(chip, TPM_CAP_FLAG_PERM, &cap,
150			"attempting to determine the permanent active state",
151			sizeof(cap.perm_flags)))
152		goto out_ops;
153
154	rc = sprintf(buf, "%d\n", !cap.perm_flags.deactivated);
155out_ops:
156	tpm_put_ops(chip);
157	return rc;
158}
159static DEVICE_ATTR_RO(active);
160
161static ssize_t owned_show(struct device *dev, struct device_attribute *attr,
162			  char *buf)
163{
164	struct tpm_chip *chip = to_tpm_chip(dev);
165	ssize_t rc = 0;
166	cap_t cap;
167
168	if (tpm_try_get_ops(chip))
169		return 0;
170
171	if (tpm1_getcap(to_tpm_chip(dev), TPM_CAP_PROP_OWNER, &cap,
172			"attempting to determine the owner state",
173			sizeof(cap.owned)))
174		goto out_ops;
175
176	rc = sprintf(buf, "%d\n", cap.owned);
177out_ops:
178	tpm_put_ops(chip);
179	return rc;
180}
181static DEVICE_ATTR_RO(owned);
182
183static ssize_t temp_deactivated_show(struct device *dev,
184				     struct device_attribute *attr, char *buf)
185{
186	struct tpm_chip *chip = to_tpm_chip(dev);
187	ssize_t rc = 0;
188	cap_t cap;
189
190	if (tpm_try_get_ops(chip))
191		return 0;
192
193	if (tpm1_getcap(to_tpm_chip(dev), TPM_CAP_FLAG_VOL, &cap,
194			"attempting to determine the temporary state",
195			sizeof(cap.stclear_flags)))
196		goto out_ops;
197
198	rc = sprintf(buf, "%d\n", cap.stclear_flags.deactivated);
199out_ops:
200	tpm_put_ops(chip);
201	return rc;
202}
203static DEVICE_ATTR_RO(temp_deactivated);
204
205static ssize_t caps_show(struct device *dev, struct device_attribute *attr,
206			 char *buf)
207{
208	struct tpm_chip *chip = to_tpm_chip(dev);
209	struct tpm1_version *version;
210	ssize_t rc = 0;
211	char *str = buf;
212	cap_t cap;
213
214	if (tpm_try_get_ops(chip))
215		return 0;
216
217	if (tpm1_getcap(chip, TPM_CAP_PROP_MANUFACTURER, &cap,
218			"attempting to determine the manufacturer",
219			sizeof(cap.manufacturer_id)))
220		goto out_ops;
221
222	str += sprintf(str, "Manufacturer: 0x%x\n",
223		       be32_to_cpu(cap.manufacturer_id));
224
225	/* TPM 1.2 */
226	if (!tpm1_getcap(chip, TPM_CAP_VERSION_1_2, &cap,
227			 "attempting to determine the 1.2 version",
228			 sizeof(cap.version2))) {
229		version = &cap.version2.version;
230		goto out_print;
231	}
232
233	/* TPM 1.1 */
234	if (tpm1_getcap(chip, TPM_CAP_VERSION_1_1, &cap,
235			"attempting to determine the 1.1 version",
236			sizeof(cap.version1))) {
237		goto out_ops;
238	}
239
240	version = &cap.version1;
241
242out_print:
243	str += sprintf(str,
244		       "TCG version: %d.%d\nFirmware version: %d.%d\n",
245		       version->major, version->minor,
246		       version->rev_major, version->rev_minor);
247
248	rc = str - buf;
249
250out_ops:
251	tpm_put_ops(chip);
252	return rc;
253}
254static DEVICE_ATTR_RO(caps);
255
256static ssize_t cancel_store(struct device *dev, struct device_attribute *attr,
257			    const char *buf, size_t count)
258{
259	struct tpm_chip *chip = to_tpm_chip(dev);
260
261	if (tpm_try_get_ops(chip))
262		return 0;
263
264	chip->ops->cancel(chip);
265	tpm_put_ops(chip);
266	return count;
267}
268static DEVICE_ATTR_WO(cancel);
269
270static ssize_t durations_show(struct device *dev, struct device_attribute *attr,
271			      char *buf)
272{
273	struct tpm_chip *chip = to_tpm_chip(dev);
274
275	if (chip->duration[TPM_LONG] == 0)
276		return 0;
277
278	return sprintf(buf, "%d %d %d [%s]\n",
279		       jiffies_to_usecs(chip->duration[TPM_SHORT]),
280		       jiffies_to_usecs(chip->duration[TPM_MEDIUM]),
281		       jiffies_to_usecs(chip->duration[TPM_LONG]),
282		       chip->duration_adjusted
283		       ? "adjusted" : "original");
284}
285static DEVICE_ATTR_RO(durations);
286
287static ssize_t timeouts_show(struct device *dev, struct device_attribute *attr,
288			     char *buf)
289{
290	struct tpm_chip *chip = to_tpm_chip(dev);
291
292	return sprintf(buf, "%d %d %d %d [%s]\n",
293		       jiffies_to_usecs(chip->timeout_a),
294		       jiffies_to_usecs(chip->timeout_b),
295		       jiffies_to_usecs(chip->timeout_c),
296		       jiffies_to_usecs(chip->timeout_d),
297		       chip->timeout_adjusted
298		       ? "adjusted" : "original");
299}
300static DEVICE_ATTR_RO(timeouts);
301
302static ssize_t tpm_version_major_show(struct device *dev,
303				  struct device_attribute *attr, char *buf)
304{
305	struct tpm_chip *chip = to_tpm_chip(dev);
306
307	return sprintf(buf, "%s\n", chip->flags & TPM_CHIP_FLAG_TPM2
308		       ? "2" : "1");
309}
310static DEVICE_ATTR_RO(tpm_version_major);
311
312static struct attribute *tpm1_dev_attrs[] = {
313	&dev_attr_pubek.attr,
314	&dev_attr_pcrs.attr,
315	&dev_attr_enabled.attr,
316	&dev_attr_active.attr,
317	&dev_attr_owned.attr,
318	&dev_attr_temp_deactivated.attr,
319	&dev_attr_caps.attr,
320	&dev_attr_cancel.attr,
321	&dev_attr_durations.attr,
322	&dev_attr_timeouts.attr,
323	&dev_attr_tpm_version_major.attr,
324	NULL,
325};
326
327static struct attribute *tpm2_dev_attrs[] = {
328	&dev_attr_tpm_version_major.attr,
329	NULL
330};
331
332static const struct attribute_group tpm1_dev_group = {
333	.attrs = tpm1_dev_attrs,
334};
335
336static const struct attribute_group tpm2_dev_group = {
337	.attrs = tpm2_dev_attrs,
338};
339
340void tpm_sysfs_add_device(struct tpm_chip *chip)
341{
342	WARN_ON(chip->groups_cnt != 0);
343	if (chip->flags & TPM_CHIP_FLAG_TPM2)
344		chip->groups[chip->groups_cnt++] = &tpm2_dev_group;
345	else
346		chip->groups[chip->groups_cnt++] = &tpm1_dev_group;
347}
348