tpm-sysfs.c (13364B)
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 340struct tpm_pcr_attr { 341 int alg_id; 342 int pcr; 343 struct device_attribute attr; 344}; 345 346#define to_tpm_pcr_attr(a) container_of(a, struct tpm_pcr_attr, attr) 347 348static ssize_t pcr_value_show(struct device *dev, 349 struct device_attribute *attr, 350 char *buf) 351{ 352 struct tpm_pcr_attr *ha = to_tpm_pcr_attr(attr); 353 struct tpm_chip *chip = to_tpm_chip(dev); 354 struct tpm_digest digest; 355 int i; 356 int digest_size = 0; 357 int rc; 358 char *str = buf; 359 360 for (i = 0; i < chip->nr_allocated_banks; i++) 361 if (ha->alg_id == chip->allocated_banks[i].alg_id) 362 digest_size = chip->allocated_banks[i].digest_size; 363 /* should never happen */ 364 if (!digest_size) 365 return -EINVAL; 366 367 digest.alg_id = ha->alg_id; 368 rc = tpm_pcr_read(chip, ha->pcr, &digest); 369 if (rc) 370 return rc; 371 for (i = 0; i < digest_size; i++) 372 str += sprintf(str, "%02X", digest.digest[i]); 373 str += sprintf(str, "\n"); 374 375 return str - buf; 376} 377 378/* 379 * The following set of defines represents all the magic to build 380 * the per hash attribute groups for displaying each bank of PCRs. 381 * The only slight problem with this approach is that every PCR is 382 * hard coded to be present, so you don't know if an PCR is missing 383 * until a cat of the file returns -EINVAL 384 * 385 * Also note you must ignore checkpatch warnings in this macro 386 * code. This is deep macro magic that checkpatch.pl doesn't 387 * understand. 388 */ 389 390/* Note, this must match TPM2_PLATFORM_PCR which is fixed at 24. */ 391#define _TPM_HELPER(_alg, _hash, F) \ 392 F(_alg, _hash, 0) \ 393 F(_alg, _hash, 1) \ 394 F(_alg, _hash, 2) \ 395 F(_alg, _hash, 3) \ 396 F(_alg, _hash, 4) \ 397 F(_alg, _hash, 5) \ 398 F(_alg, _hash, 6) \ 399 F(_alg, _hash, 7) \ 400 F(_alg, _hash, 8) \ 401 F(_alg, _hash, 9) \ 402 F(_alg, _hash, 10) \ 403 F(_alg, _hash, 11) \ 404 F(_alg, _hash, 12) \ 405 F(_alg, _hash, 13) \ 406 F(_alg, _hash, 14) \ 407 F(_alg, _hash, 15) \ 408 F(_alg, _hash, 16) \ 409 F(_alg, _hash, 17) \ 410 F(_alg, _hash, 18) \ 411 F(_alg, _hash, 19) \ 412 F(_alg, _hash, 20) \ 413 F(_alg, _hash, 21) \ 414 F(_alg, _hash, 22) \ 415 F(_alg, _hash, 23) 416 417/* ignore checkpatch warning about trailing ; in macro. */ 418#define PCR_ATTR(_alg, _hash, _pcr) \ 419 static struct tpm_pcr_attr dev_attr_pcr_##_hash##_##_pcr = { \ 420 .alg_id = _alg, \ 421 .pcr = _pcr, \ 422 .attr = { \ 423 .attr = { \ 424 .name = __stringify(_pcr), \ 425 .mode = 0444 \ 426 }, \ 427 .show = pcr_value_show \ 428 } \ 429 }; 430 431#define PCR_ATTRS(_alg, _hash) \ 432 _TPM_HELPER(_alg, _hash, PCR_ATTR) 433 434/* ignore checkpatch warning about trailing , in macro. */ 435#define PCR_ATTR_VAL(_alg, _hash, _pcr) \ 436 &dev_attr_pcr_##_hash##_##_pcr.attr.attr, 437 438#define PCR_ATTR_GROUP_ARRAY(_alg, _hash) \ 439 static struct attribute *pcr_group_attrs_##_hash[] = { \ 440 _TPM_HELPER(_alg, _hash, PCR_ATTR_VAL) \ 441 NULL \ 442 } 443 444#define PCR_ATTR_GROUP(_alg, _hash) \ 445 static struct attribute_group pcr_group_##_hash = { \ 446 .name = "pcr-" __stringify(_hash), \ 447 .attrs = pcr_group_attrs_##_hash \ 448 } 449 450#define PCR_ATTR_BUILD(_alg, _hash) \ 451 PCR_ATTRS(_alg, _hash) \ 452 PCR_ATTR_GROUP_ARRAY(_alg, _hash); \ 453 PCR_ATTR_GROUP(_alg, _hash) 454/* 455 * End of macro structure to build an attribute group containing 24 456 * PCR value files for each supported hash algorithm 457 */ 458 459/* 460 * The next set of macros implements the cleverness for each hash to 461 * build a static attribute group called pcr_group_<hash> which can be 462 * added to chip->groups[]. 463 * 464 * The first argument is the TPM algorithm id and the second is the 465 * hash used as both the suffix and the group name. Note: the group 466 * name is a directory in the top level tpm class with the name 467 * pcr-<hash>, so it must not clash with any other names already 468 * in the sysfs directory. 469 */ 470PCR_ATTR_BUILD(TPM_ALG_SHA1, sha1); 471PCR_ATTR_BUILD(TPM_ALG_SHA256, sha256); 472PCR_ATTR_BUILD(TPM_ALG_SHA384, sha384); 473PCR_ATTR_BUILD(TPM_ALG_SHA512, sha512); 474PCR_ATTR_BUILD(TPM_ALG_SM3_256, sm3); 475 476 477void tpm_sysfs_add_device(struct tpm_chip *chip) 478{ 479 int i; 480 481 WARN_ON(chip->groups_cnt != 0); 482 483 if (tpm_is_firmware_upgrade(chip)) 484 return; 485 486 if (chip->flags & TPM_CHIP_FLAG_TPM2) 487 chip->groups[chip->groups_cnt++] = &tpm2_dev_group; 488 else 489 chip->groups[chip->groups_cnt++] = &tpm1_dev_group; 490 491 /* add one group for each bank hash */ 492 for (i = 0; i < chip->nr_allocated_banks; i++) { 493 switch (chip->allocated_banks[i].alg_id) { 494 case TPM_ALG_SHA1: 495 chip->groups[chip->groups_cnt++] = &pcr_group_sha1; 496 break; 497 case TPM_ALG_SHA256: 498 chip->groups[chip->groups_cnt++] = &pcr_group_sha256; 499 break; 500 case TPM_ALG_SHA384: 501 chip->groups[chip->groups_cnt++] = &pcr_group_sha384; 502 break; 503 case TPM_ALG_SHA512: 504 chip->groups[chip->groups_cnt++] = &pcr_group_sha512; 505 break; 506 case TPM_ALG_SM3_256: 507 chip->groups[chip->groups_cnt++] = &pcr_group_sm3; 508 break; 509 default: 510 /* 511 * If triggers, send a patch to add both a 512 * PCR_ATTR_BUILD() macro above for the 513 * missing algorithm as well as an additional 514 * case in this switch statement. 515 */ 516 dev_err(&chip->dev, 517 "TPM with unsupported bank algorithm 0x%04x", 518 chip->allocated_banks[i].alg_id); 519 break; 520 } 521 } 522 523 /* 524 * This will only trigger if someone has added an additional 525 * hash to the tpm_algorithms enum without incrementing 526 * TPM_MAX_HASHES. 527 */ 528 WARN_ON(chip->groups_cnt > TPM_MAX_HASHES + 1); 529}