Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/drivers/char/tpm/tpm-sysfs.c
26285 views
1
// SPDX-License-Identifier: GPL-2.0-only
2
/*
3
* Copyright (C) 2004 IBM Corporation
4
* Authors:
5
* Leendert van Doorn <[email protected]>
6
* Dave Safford <[email protected]>
7
* Reiner Sailer <[email protected]>
8
* Kylene Hall <[email protected]>
9
*
10
* Copyright (C) 2013 Obsidian Research Corp
11
* Jason Gunthorpe <[email protected]>
12
*
13
* sysfs filesystem inspection interface to the TPM
14
*/
15
#include <linux/device.h>
16
#include "tpm.h"
17
18
struct 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
32
static 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
74
out_buf:
75
tpm_buf_destroy(&tpm_buf);
76
out_ops:
77
tpm_put_ops(chip);
78
return str - buf;
79
}
80
static DEVICE_ATTR_RO(pubek);
81
82
static 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
}
115
static DEVICE_ATTR_RO(pcrs);
116
117
static 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);
133
out_ops:
134
tpm_put_ops(chip);
135
return rc;
136
}
137
static DEVICE_ATTR_RO(enabled);
138
139
static 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);
155
out_ops:
156
tpm_put_ops(chip);
157
return rc;
158
}
159
static DEVICE_ATTR_RO(active);
160
161
static 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);
177
out_ops:
178
tpm_put_ops(chip);
179
return rc;
180
}
181
static DEVICE_ATTR_RO(owned);
182
183
static 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);
199
out_ops:
200
tpm_put_ops(chip);
201
return rc;
202
}
203
static DEVICE_ATTR_RO(temp_deactivated);
204
205
static 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
242
out_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
250
out_ops:
251
tpm_put_ops(chip);
252
return rc;
253
}
254
static DEVICE_ATTR_RO(caps);
255
256
static 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
}
268
static DEVICE_ATTR_WO(cancel);
269
270
static 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
}
285
static DEVICE_ATTR_RO(durations);
286
287
static 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
}
300
static DEVICE_ATTR_RO(timeouts);
301
302
static 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
}
310
static DEVICE_ATTR_RO(tpm_version_major);
311
312
#ifdef CONFIG_TCG_TPM2_HMAC
313
static ssize_t null_name_show(struct device *dev, struct device_attribute *attr,
314
char *buf)
315
{
316
struct tpm_chip *chip = to_tpm_chip(dev);
317
int size = TPM2_NAME_SIZE;
318
319
bin2hex(buf, chip->null_key_name, size);
320
size *= 2;
321
buf[size++] = '\n';
322
return size;
323
}
324
static DEVICE_ATTR_RO(null_name);
325
#endif
326
327
static struct attribute *tpm1_dev_attrs[] = {
328
&dev_attr_pubek.attr,
329
&dev_attr_pcrs.attr,
330
&dev_attr_enabled.attr,
331
&dev_attr_active.attr,
332
&dev_attr_owned.attr,
333
&dev_attr_temp_deactivated.attr,
334
&dev_attr_caps.attr,
335
&dev_attr_cancel.attr,
336
&dev_attr_durations.attr,
337
&dev_attr_timeouts.attr,
338
&dev_attr_tpm_version_major.attr,
339
NULL,
340
};
341
342
static struct attribute *tpm2_dev_attrs[] = {
343
&dev_attr_tpm_version_major.attr,
344
#ifdef CONFIG_TCG_TPM2_HMAC
345
&dev_attr_null_name.attr,
346
#endif
347
NULL
348
};
349
350
static const struct attribute_group tpm1_dev_group = {
351
.attrs = tpm1_dev_attrs,
352
};
353
354
static const struct attribute_group tpm2_dev_group = {
355
.attrs = tpm2_dev_attrs,
356
};
357
358
struct tpm_pcr_attr {
359
int alg_id;
360
int pcr;
361
struct device_attribute attr;
362
};
363
364
#define to_tpm_pcr_attr(a) container_of(a, struct tpm_pcr_attr, attr)
365
366
static ssize_t pcr_value_show(struct device *dev,
367
struct device_attribute *attr,
368
char *buf)
369
{
370
struct tpm_pcr_attr *ha = to_tpm_pcr_attr(attr);
371
struct tpm_chip *chip = to_tpm_chip(dev);
372
struct tpm_digest digest;
373
int i;
374
int digest_size = 0;
375
int rc;
376
char *str = buf;
377
378
for (i = 0; i < chip->nr_allocated_banks; i++)
379
if (ha->alg_id == chip->allocated_banks[i].alg_id)
380
digest_size = chip->allocated_banks[i].digest_size;
381
/* should never happen */
382
if (!digest_size)
383
return -EINVAL;
384
385
digest.alg_id = ha->alg_id;
386
rc = tpm_pcr_read(chip, ha->pcr, &digest);
387
if (rc)
388
return rc;
389
for (i = 0; i < digest_size; i++)
390
str += sprintf(str, "%02X", digest.digest[i]);
391
str += sprintf(str, "\n");
392
393
return str - buf;
394
}
395
396
/*
397
* The following set of defines represents all the magic to build
398
* the per hash attribute groups for displaying each bank of PCRs.
399
* The only slight problem with this approach is that every PCR is
400
* hard coded to be present, so you don't know if an PCR is missing
401
* until a cat of the file returns -EINVAL
402
*
403
* Also note you must ignore checkpatch warnings in this macro
404
* code. This is deep macro magic that checkpatch.pl doesn't
405
* understand.
406
*/
407
408
/* Note, this must match TPM2_PLATFORM_PCR which is fixed at 24. */
409
#define _TPM_HELPER(_alg, _hash, F) \
410
F(_alg, _hash, 0) \
411
F(_alg, _hash, 1) \
412
F(_alg, _hash, 2) \
413
F(_alg, _hash, 3) \
414
F(_alg, _hash, 4) \
415
F(_alg, _hash, 5) \
416
F(_alg, _hash, 6) \
417
F(_alg, _hash, 7) \
418
F(_alg, _hash, 8) \
419
F(_alg, _hash, 9) \
420
F(_alg, _hash, 10) \
421
F(_alg, _hash, 11) \
422
F(_alg, _hash, 12) \
423
F(_alg, _hash, 13) \
424
F(_alg, _hash, 14) \
425
F(_alg, _hash, 15) \
426
F(_alg, _hash, 16) \
427
F(_alg, _hash, 17) \
428
F(_alg, _hash, 18) \
429
F(_alg, _hash, 19) \
430
F(_alg, _hash, 20) \
431
F(_alg, _hash, 21) \
432
F(_alg, _hash, 22) \
433
F(_alg, _hash, 23)
434
435
/* ignore checkpatch warning about trailing ; in macro. */
436
#define PCR_ATTR(_alg, _hash, _pcr) \
437
static struct tpm_pcr_attr dev_attr_pcr_##_hash##_##_pcr = { \
438
.alg_id = _alg, \
439
.pcr = _pcr, \
440
.attr = { \
441
.attr = { \
442
.name = __stringify(_pcr), \
443
.mode = 0444 \
444
}, \
445
.show = pcr_value_show \
446
} \
447
};
448
449
#define PCR_ATTRS(_alg, _hash) \
450
_TPM_HELPER(_alg, _hash, PCR_ATTR)
451
452
/* ignore checkpatch warning about trailing , in macro. */
453
#define PCR_ATTR_VAL(_alg, _hash, _pcr) \
454
&dev_attr_pcr_##_hash##_##_pcr.attr.attr,
455
456
#define PCR_ATTR_GROUP_ARRAY(_alg, _hash) \
457
static struct attribute *pcr_group_attrs_##_hash[] = { \
458
_TPM_HELPER(_alg, _hash, PCR_ATTR_VAL) \
459
NULL \
460
}
461
462
#define PCR_ATTR_GROUP(_alg, _hash) \
463
static struct attribute_group pcr_group_##_hash = { \
464
.name = "pcr-" __stringify(_hash), \
465
.attrs = pcr_group_attrs_##_hash \
466
}
467
468
#define PCR_ATTR_BUILD(_alg, _hash) \
469
PCR_ATTRS(_alg, _hash) \
470
PCR_ATTR_GROUP_ARRAY(_alg, _hash); \
471
PCR_ATTR_GROUP(_alg, _hash)
472
/*
473
* End of macro structure to build an attribute group containing 24
474
* PCR value files for each supported hash algorithm
475
*/
476
477
/*
478
* The next set of macros implements the cleverness for each hash to
479
* build a static attribute group called pcr_group_<hash> which can be
480
* added to chip->groups[].
481
*
482
* The first argument is the TPM algorithm id and the second is the
483
* hash used as both the suffix and the group name. Note: the group
484
* name is a directory in the top level tpm class with the name
485
* pcr-<hash>, so it must not clash with any other names already
486
* in the sysfs directory.
487
*/
488
PCR_ATTR_BUILD(TPM_ALG_SHA1, sha1);
489
PCR_ATTR_BUILD(TPM_ALG_SHA256, sha256);
490
PCR_ATTR_BUILD(TPM_ALG_SHA384, sha384);
491
PCR_ATTR_BUILD(TPM_ALG_SHA512, sha512);
492
PCR_ATTR_BUILD(TPM_ALG_SM3_256, sm3);
493
494
495
void tpm_sysfs_add_device(struct tpm_chip *chip)
496
{
497
int i;
498
499
WARN_ON(chip->groups_cnt != 0);
500
501
if (tpm_is_firmware_upgrade(chip))
502
return;
503
504
if (chip->flags & TPM_CHIP_FLAG_TPM2)
505
chip->groups[chip->groups_cnt++] = &tpm2_dev_group;
506
else
507
chip->groups[chip->groups_cnt++] = &tpm1_dev_group;
508
509
/* add one group for each bank hash */
510
for (i = 0; i < chip->nr_allocated_banks; i++) {
511
switch (chip->allocated_banks[i].alg_id) {
512
case TPM_ALG_SHA1:
513
chip->groups[chip->groups_cnt++] = &pcr_group_sha1;
514
break;
515
case TPM_ALG_SHA256:
516
chip->groups[chip->groups_cnt++] = &pcr_group_sha256;
517
break;
518
case TPM_ALG_SHA384:
519
chip->groups[chip->groups_cnt++] = &pcr_group_sha384;
520
break;
521
case TPM_ALG_SHA512:
522
chip->groups[chip->groups_cnt++] = &pcr_group_sha512;
523
break;
524
case TPM_ALG_SM3_256:
525
chip->groups[chip->groups_cnt++] = &pcr_group_sm3;
526
break;
527
default:
528
/*
529
* If triggers, send a patch to add both a
530
* PCR_ATTR_BUILD() macro above for the
531
* missing algorithm as well as an additional
532
* case in this switch statement.
533
*/
534
dev_err(&chip->dev,
535
"TPM with unsupported bank algorithm 0x%04x",
536
chip->allocated_banks[i].alg_id);
537
break;
538
}
539
}
540
541
/*
542
* This will only trigger if someone has added an additional
543
* hash to the tpm_algorithms enum without incrementing
544
* TPM_MAX_HASHES.
545
*/
546
WARN_ON(chip->groups_cnt > TPM_MAX_HASHES + 1);
547
}
548
549