1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20#include <linux/device.h>
21#include "tpm.h"
22
23#define READ_PUBEK_RESULT_SIZE 314
24#define READ_PUBEK_RESULT_MIN_BODY_SIZE (28 + 256)
25#define TPM_ORD_READPUBEK 124
26static const struct tpm_input_header tpm_readpubek_header = {
27 .tag = cpu_to_be16(TPM_TAG_RQU_COMMAND),
28 .length = cpu_to_be32(30),
29 .ordinal = cpu_to_be32(TPM_ORD_READPUBEK)
30};
31static ssize_t pubek_show(struct device *dev, struct device_attribute *attr,
32 char *buf)
33{
34 u8 *data;
35 struct tpm_cmd_t tpm_cmd;
36 ssize_t err;
37 int i, rc;
38 char *str = buf;
39 struct tpm_chip *chip = to_tpm_chip(dev);
40
41 memset(&tpm_cmd, 0, sizeof(tpm_cmd));
42
43 tpm_cmd.header.in = tpm_readpubek_header;
44 err = tpm_transmit_cmd(chip, NULL, &tpm_cmd, READ_PUBEK_RESULT_SIZE,
45 READ_PUBEK_RESULT_MIN_BODY_SIZE, 0,
46 "attempting to read the PUBEK");
47 if (err)
48 goto out;
49
50
51
52
53
54
55
56
57
58
59
60 data = tpm_cmd.params.readpubek_out_buffer;
61 str +=
62 sprintf(str,
63 "Algorithm: %02X %02X %02X %02X\n"
64 "Encscheme: %02X %02X\n"
65 "Sigscheme: %02X %02X\n"
66 "Parameters: %02X %02X %02X %02X "
67 "%02X %02X %02X %02X "
68 "%02X %02X %02X %02X\n"
69 "Modulus length: %d\n"
70 "Modulus:\n",
71 data[0], data[1], data[2], data[3],
72 data[4], data[5],
73 data[6], data[7],
74 data[12], data[13], data[14], data[15],
75 data[16], data[17], data[18], data[19],
76 data[20], data[21], data[22], data[23],
77 be32_to_cpu(*((__be32 *) (data + 24))));
78
79 for (i = 0; i < 256; i++) {
80 str += sprintf(str, "%02X ", data[i + 28]);
81 if ((i + 1) % 16 == 0)
82 str += sprintf(str, "\n");
83 }
84out:
85 rc = str - buf;
86 return rc;
87}
88static DEVICE_ATTR_RO(pubek);
89
90static ssize_t pcrs_show(struct device *dev, struct device_attribute *attr,
91 char *buf)
92{
93 cap_t cap;
94 u8 digest[TPM_DIGEST_SIZE];
95 ssize_t rc;
96 int i, j, num_pcrs;
97 char *str = buf;
98 struct tpm_chip *chip = to_tpm_chip(dev);
99
100 rc = tpm_getcap(chip, TPM_CAP_PROP_PCR, &cap,
101 "attempting to determine the number of PCRS",
102 sizeof(cap.num_pcrs));
103 if (rc)
104 return 0;
105
106 num_pcrs = be32_to_cpu(cap.num_pcrs);
107 for (i = 0; i < num_pcrs; i++) {
108 rc = tpm_pcr_read_dev(chip, i, digest);
109 if (rc)
110 break;
111 str += sprintf(str, "PCR-%02d: ", i);
112 for (j = 0; j < TPM_DIGEST_SIZE; j++)
113 str += sprintf(str, "%02X ", digest[j]);
114 str += sprintf(str, "\n");
115 }
116 return str - buf;
117}
118static DEVICE_ATTR_RO(pcrs);
119
120static ssize_t enabled_show(struct device *dev, struct device_attribute *attr,
121 char *buf)
122{
123 cap_t cap;
124 ssize_t rc;
125
126 rc = tpm_getcap(to_tpm_chip(dev), TPM_CAP_FLAG_PERM, &cap,
127 "attempting to determine the permanent enabled state",
128 sizeof(cap.perm_flags));
129 if (rc)
130 return 0;
131
132 rc = sprintf(buf, "%d\n", !cap.perm_flags.disable);
133 return rc;
134}
135static DEVICE_ATTR_RO(enabled);
136
137static ssize_t active_show(struct device *dev, struct device_attribute *attr,
138 char *buf)
139{
140 cap_t cap;
141 ssize_t rc;
142
143 rc = tpm_getcap(to_tpm_chip(dev), TPM_CAP_FLAG_PERM, &cap,
144 "attempting to determine the permanent active state",
145 sizeof(cap.perm_flags));
146 if (rc)
147 return 0;
148
149 rc = sprintf(buf, "%d\n", !cap.perm_flags.deactivated);
150 return rc;
151}
152static DEVICE_ATTR_RO(active);
153
154static ssize_t owned_show(struct device *dev, struct device_attribute *attr,
155 char *buf)
156{
157 cap_t cap;
158 ssize_t rc;
159
160 rc = tpm_getcap(to_tpm_chip(dev), TPM_CAP_PROP_OWNER, &cap,
161 "attempting to determine the owner state",
162 sizeof(cap.owned));
163 if (rc)
164 return 0;
165
166 rc = sprintf(buf, "%d\n", cap.owned);
167 return rc;
168}
169static DEVICE_ATTR_RO(owned);
170
171static ssize_t temp_deactivated_show(struct device *dev,
172 struct device_attribute *attr, char *buf)
173{
174 cap_t cap;
175 ssize_t rc;
176
177 rc = tpm_getcap(to_tpm_chip(dev), TPM_CAP_FLAG_VOL, &cap,
178 "attempting to determine the temporary state",
179 sizeof(cap.stclear_flags));
180 if (rc)
181 return 0;
182
183 rc = sprintf(buf, "%d\n", cap.stclear_flags.deactivated);
184 return rc;
185}
186static DEVICE_ATTR_RO(temp_deactivated);
187
188static ssize_t caps_show(struct device *dev, struct device_attribute *attr,
189 char *buf)
190{
191 struct tpm_chip *chip = to_tpm_chip(dev);
192 cap_t cap;
193 ssize_t rc;
194 char *str = buf;
195
196 rc = tpm_getcap(chip, TPM_CAP_PROP_MANUFACTURER, &cap,
197 "attempting to determine the manufacturer",
198 sizeof(cap.manufacturer_id));
199 if (rc)
200 return 0;
201 str += sprintf(str, "Manufacturer: 0x%x\n",
202 be32_to_cpu(cap.manufacturer_id));
203
204
205 rc = tpm_getcap(chip, TPM_CAP_VERSION_1_2, &cap,
206 "attempting to determine the 1.2 version",
207 sizeof(cap.tpm_version_1_2));
208 if (!rc) {
209 str += sprintf(str,
210 "TCG version: %d.%d\nFirmware version: %d.%d\n",
211 cap.tpm_version_1_2.Major,
212 cap.tpm_version_1_2.Minor,
213 cap.tpm_version_1_2.revMajor,
214 cap.tpm_version_1_2.revMinor);
215 } else {
216
217 rc = tpm_getcap(chip, TPM_CAP_VERSION_1_1, &cap,
218 "attempting to determine the 1.1 version",
219 sizeof(cap.tpm_version));
220 if (rc)
221 return 0;
222 str += sprintf(str,
223 "TCG version: %d.%d\nFirmware version: %d.%d\n",
224 cap.tpm_version.Major,
225 cap.tpm_version.Minor,
226 cap.tpm_version.revMajor,
227 cap.tpm_version.revMinor);
228 }
229
230 return str - buf;
231}
232static DEVICE_ATTR_RO(caps);
233
234static ssize_t cancel_store(struct device *dev, struct device_attribute *attr,
235 const char *buf, size_t count)
236{
237 struct tpm_chip *chip = to_tpm_chip(dev);
238 if (chip == NULL)
239 return 0;
240
241 chip->ops->cancel(chip);
242 return count;
243}
244static DEVICE_ATTR_WO(cancel);
245
246static ssize_t durations_show(struct device *dev, struct device_attribute *attr,
247 char *buf)
248{
249 struct tpm_chip *chip = to_tpm_chip(dev);
250
251 if (chip->duration[TPM_LONG] == 0)
252 return 0;
253
254 return sprintf(buf, "%d %d %d [%s]\n",
255 jiffies_to_usecs(chip->duration[TPM_SHORT]),
256 jiffies_to_usecs(chip->duration[TPM_MEDIUM]),
257 jiffies_to_usecs(chip->duration[TPM_LONG]),
258 chip->duration_adjusted
259 ? "adjusted" : "original");
260}
261static DEVICE_ATTR_RO(durations);
262
263static ssize_t timeouts_show(struct device *dev, struct device_attribute *attr,
264 char *buf)
265{
266 struct tpm_chip *chip = to_tpm_chip(dev);
267
268 return sprintf(buf, "%d %d %d %d [%s]\n",
269 jiffies_to_usecs(chip->timeout_a),
270 jiffies_to_usecs(chip->timeout_b),
271 jiffies_to_usecs(chip->timeout_c),
272 jiffies_to_usecs(chip->timeout_d),
273 chip->timeout_adjusted
274 ? "adjusted" : "original");
275}
276static DEVICE_ATTR_RO(timeouts);
277
278static struct attribute *tpm_dev_attrs[] = {
279 &dev_attr_pubek.attr,
280 &dev_attr_pcrs.attr,
281 &dev_attr_enabled.attr,
282 &dev_attr_active.attr,
283 &dev_attr_owned.attr,
284 &dev_attr_temp_deactivated.attr,
285 &dev_attr_caps.attr,
286 &dev_attr_cancel.attr,
287 &dev_attr_durations.attr,
288 &dev_attr_timeouts.attr,
289 NULL,
290};
291
292static const struct attribute_group tpm_dev_group = {
293 .attrs = tpm_dev_attrs,
294};
295
296void tpm_sysfs_add_device(struct tpm_chip *chip)
297{
298
299
300
301 if (chip->flags & TPM_CHIP_FLAG_TPM2)
302 return;
303
304
305
306
307
308 WARN_ON(chip->groups_cnt != 0);
309 chip->groups[chip->groups_cnt++] = &tpm_dev_group;
310}
311