tpm.c revision 09e12f9f6bcd9af516d901223cebdbae58b32c9f
1/* 2 * Copyright (C) 2004 IBM Corporation 3 * 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 * Maintained by: <tpmdd_devel@lists.sourceforge.net> 11 * 12 * Device driver for TCG/TCPA TPM (trusted platform module). 13 * Specifications at www.trustedcomputinggroup.org 14 * 15 * This program is free software; you can redistribute it and/or 16 * modify it under the terms of the GNU General Public License as 17 * published by the Free Software Foundation, version 2 of the 18 * License. 19 * 20 * Note, the TPM chip is not interrupt driven (only polling) 21 * and can have very long timeouts (minutes!). Hence the unusual 22 * calls to msleep. 23 * 24 */ 25 26#include <linux/sched.h> 27#include <linux/poll.h> 28#include <linux/spinlock.h> 29#include "tpm.h" 30 31enum tpm_const { 32 TPM_MINOR = 224, /* officially assigned */ 33 TPM_BUFSIZE = 2048, 34 TPM_NUM_DEVICES = 256, 35 TPM_NUM_MASK_ENTRIES = TPM_NUM_DEVICES / (8 * sizeof(int)) 36}; 37 38static LIST_HEAD(tpm_chip_list); 39static DEFINE_SPINLOCK(driver_lock); 40static int dev_mask[TPM_NUM_MASK_ENTRIES]; 41 42static void user_reader_timeout(unsigned long ptr) 43{ 44 struct tpm_chip *chip = (struct tpm_chip *) ptr; 45 46 schedule_work(&chip->work); 47} 48 49static void timeout_work(void * ptr) 50{ 51 struct tpm_chip *chip = ptr; 52 53 down(&chip->buffer_mutex); 54 atomic_set(&chip->data_pending, 0); 55 memset(chip->data_buffer, 0, TPM_BUFSIZE); 56 up(&chip->buffer_mutex); 57} 58 59/* 60 * Internal kernel interface to transmit TPM commands 61 */ 62static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf, 63 size_t bufsiz) 64{ 65 ssize_t rc; 66 u32 count; 67 unsigned long stop; 68 69 count = be32_to_cpu(*((__be32 *) (buf + 2))); 70 71 if (count == 0) 72 return -ENODATA; 73 if (count > bufsiz) { 74 dev_err(chip->dev, 75 "invalid count value %x %zx \n", count, bufsiz); 76 return -E2BIG; 77 } 78 79 down(&chip->tpm_mutex); 80 81 if ((rc = chip->vendor->send(chip, (u8 *) buf, count)) < 0) { 82 dev_err(chip->dev, 83 "tpm_transmit: tpm_send: error %zd\n", rc); 84 goto out; 85 } 86 87 stop = jiffies + 2 * 60 * HZ; 88 do { 89 u8 status = chip->vendor->status(chip); 90 if ((status & chip->vendor->req_complete_mask) == 91 chip->vendor->req_complete_val) { 92 goto out_recv; 93 } 94 95 if ((status == chip->vendor->req_canceled)) { 96 dev_err(chip->dev, "Operation Canceled\n"); 97 rc = -ECANCELED; 98 goto out; 99 } 100 101 msleep(TPM_TIMEOUT); /* CHECK */ 102 rmb(); 103 } while (time_before(jiffies, stop)); 104 105 106 chip->vendor->cancel(chip); 107 dev_err(chip->dev, "Operation Timed out\n"); 108 rc = -ETIME; 109 goto out; 110 111out_recv: 112 rc = chip->vendor->recv(chip, (u8 *) buf, bufsiz); 113 if (rc < 0) 114 dev_err(chip->dev, 115 "tpm_transmit: tpm_recv: error %zd\n", rc); 116out: 117 up(&chip->tpm_mutex); 118 return rc; 119} 120 121#define TPM_DIGEST_SIZE 20 122#define CAP_PCR_RESULT_SIZE 18 123static const u8 cap_pcr[] = { 124 0, 193, /* TPM_TAG_RQU_COMMAND */ 125 0, 0, 0, 22, /* length */ 126 0, 0, 0, 101, /* TPM_ORD_GetCapability */ 127 0, 0, 0, 5, 128 0, 0, 0, 4, 129 0, 0, 1, 1 130}; 131 132#define READ_PCR_RESULT_SIZE 30 133static const u8 pcrread[] = { 134 0, 193, /* TPM_TAG_RQU_COMMAND */ 135 0, 0, 0, 14, /* length */ 136 0, 0, 0, 21, /* TPM_ORD_PcrRead */ 137 0, 0, 0, 0 /* PCR index */ 138}; 139 140ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr, 141 char *buf) 142{ 143 u8 data[READ_PCR_RESULT_SIZE]; 144 ssize_t len; 145 int i, j, num_pcrs; 146 __be32 index; 147 char *str = buf; 148 149 struct tpm_chip *chip = dev_get_drvdata(dev); 150 if (chip == NULL) 151 return -ENODEV; 152 153 memcpy(data, cap_pcr, sizeof(cap_pcr)); 154 if ((len = tpm_transmit(chip, data, sizeof(data))) 155 < CAP_PCR_RESULT_SIZE) { 156 dev_dbg(chip->dev, "A TPM error (%d) occurred " 157 "attempting to determine the number of PCRS\n", 158 be32_to_cpu(*((__be32 *) (data + 6)))); 159 return 0; 160 } 161 162 num_pcrs = be32_to_cpu(*((__be32 *) (data + 14))); 163 164 for (i = 0; i < num_pcrs; i++) { 165 memcpy(data, pcrread, sizeof(pcrread)); 166 index = cpu_to_be32(i); 167 memcpy(data + 10, &index, 4); 168 if ((len = tpm_transmit(chip, data, sizeof(data))) 169 < READ_PCR_RESULT_SIZE){ 170 dev_dbg(chip->dev, "A TPM error (%d) occurred" 171 " attempting to read PCR %d of %d\n", 172 be32_to_cpu(*((__be32 *) (data + 6))), 173 i, num_pcrs); 174 goto out; 175 } 176 str += sprintf(str, "PCR-%02d: ", i); 177 for (j = 0; j < TPM_DIGEST_SIZE; j++) 178 str += sprintf(str, "%02X ", *(data + 10 + j)); 179 str += sprintf(str, "\n"); 180 } 181out: 182 return str - buf; 183} 184EXPORT_SYMBOL_GPL(tpm_show_pcrs); 185 186#define READ_PUBEK_RESULT_SIZE 314 187static const u8 readpubek[] = { 188 0, 193, /* TPM_TAG_RQU_COMMAND */ 189 0, 0, 0, 30, /* length */ 190 0, 0, 0, 124, /* TPM_ORD_ReadPubek */ 191}; 192 193ssize_t tpm_show_pubek(struct device *dev, struct device_attribute *attr, 194 char *buf) 195{ 196 u8 *data; 197 ssize_t len; 198 int i, rc; 199 char *str = buf; 200 201 struct tpm_chip *chip = dev_get_drvdata(dev); 202 if (chip == NULL) 203 return -ENODEV; 204 205 data = kzalloc(READ_PUBEK_RESULT_SIZE, GFP_KERNEL); 206 if (!data) 207 return -ENOMEM; 208 209 memcpy(data, readpubek, sizeof(readpubek)); 210 211 if ((len = tpm_transmit(chip, data, READ_PUBEK_RESULT_SIZE)) < 212 READ_PUBEK_RESULT_SIZE) { 213 dev_dbg(chip->dev, "A TPM error (%d) occurred " 214 "attempting to read the PUBEK\n", 215 be32_to_cpu(*((__be32 *) (data + 6)))); 216 rc = 0; 217 goto out; 218 } 219 220 /* 221 ignore header 10 bytes 222 algorithm 32 bits (1 == RSA ) 223 encscheme 16 bits 224 sigscheme 16 bits 225 parameters (RSA 12->bytes: keybit, #primes, expbit) 226 keylenbytes 32 bits 227 256 byte modulus 228 ignore checksum 20 bytes 229 */ 230 231 str += 232 sprintf(str, 233 "Algorithm: %02X %02X %02X %02X\nEncscheme: %02X %02X\n" 234 "Sigscheme: %02X %02X\nParameters: %02X %02X %02X %02X" 235 " %02X %02X %02X %02X %02X %02X %02X %02X\n" 236 "Modulus length: %d\nModulus: \n", 237 data[10], data[11], data[12], data[13], data[14], 238 data[15], data[16], data[17], data[22], data[23], 239 data[24], data[25], data[26], data[27], data[28], 240 data[29], data[30], data[31], data[32], data[33], 241 be32_to_cpu(*((__be32 *) (data + 34)))); 242 243 for (i = 0; i < 256; i++) { 244 str += sprintf(str, "%02X ", data[i + 38]); 245 if ((i + 1) % 16 == 0) 246 str += sprintf(str, "\n"); 247 } 248 rc = str - buf; 249out: 250 kfree(data); 251 return rc; 252} 253EXPORT_SYMBOL_GPL(tpm_show_pubek); 254 255#define CAP_VER_RESULT_SIZE 18 256static const u8 cap_version[] = { 257 0, 193, /* TPM_TAG_RQU_COMMAND */ 258 0, 0, 0, 18, /* length */ 259 0, 0, 0, 101, /* TPM_ORD_GetCapability */ 260 0, 0, 0, 6, 261 0, 0, 0, 0 262}; 263 264#define CAP_MANUFACTURER_RESULT_SIZE 18 265static const u8 cap_manufacturer[] = { 266 0, 193, /* TPM_TAG_RQU_COMMAND */ 267 0, 0, 0, 22, /* length */ 268 0, 0, 0, 101, /* TPM_ORD_GetCapability */ 269 0, 0, 0, 5, 270 0, 0, 0, 4, 271 0, 0, 1, 3 272}; 273 274ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr, 275 char *buf) 276{ 277 u8 data[sizeof(cap_manufacturer)]; 278 ssize_t len; 279 char *str = buf; 280 281 struct tpm_chip *chip = dev_get_drvdata(dev); 282 if (chip == NULL) 283 return -ENODEV; 284 285 memcpy(data, cap_manufacturer, sizeof(cap_manufacturer)); 286 287 if ((len = tpm_transmit(chip, data, sizeof(data))) < 288 CAP_MANUFACTURER_RESULT_SIZE) 289 return len; 290 291 str += sprintf(str, "Manufacturer: 0x%x\n", 292 be32_to_cpu(*((__be32 *) (data + 14)))); 293 294 memcpy(data, cap_version, sizeof(cap_version)); 295 296 if ((len = tpm_transmit(chip, data, sizeof(data))) < 297 CAP_VER_RESULT_SIZE) 298 return len; 299 300 str += 301 sprintf(str, "TCG version: %d.%d\nFirmware version: %d.%d\n", 302 (int) data[14], (int) data[15], (int) data[16], 303 (int) data[17]); 304 305 return str - buf; 306} 307EXPORT_SYMBOL_GPL(tpm_show_caps); 308 309ssize_t tpm_store_cancel(struct device *dev, struct device_attribute *attr, 310 const char *buf, size_t count) 311{ 312 struct tpm_chip *chip = dev_get_drvdata(dev); 313 if (chip == NULL) 314 return 0; 315 316 chip->vendor->cancel(chip); 317 return count; 318} 319EXPORT_SYMBOL_GPL(tpm_store_cancel); 320 321/* 322 * Device file system interface to the TPM 323 */ 324int tpm_open(struct inode *inode, struct file *file) 325{ 326 int rc = 0, minor = iminor(inode); 327 struct tpm_chip *chip = NULL, *pos; 328 329 spin_lock(&driver_lock); 330 331 list_for_each_entry(pos, &tpm_chip_list, list) { 332 if (pos->vendor->miscdev.minor == minor) { 333 chip = pos; 334 break; 335 } 336 } 337 338 if (chip == NULL) { 339 rc = -ENODEV; 340 goto err_out; 341 } 342 343 if (chip->num_opens) { 344 dev_dbg(chip->dev, "Another process owns this TPM\n"); 345 rc = -EBUSY; 346 goto err_out; 347 } 348 349 chip->num_opens++; 350 get_device(chip->dev); 351 352 spin_unlock(&driver_lock); 353 354 chip->data_buffer = kmalloc(TPM_BUFSIZE * sizeof(u8), GFP_KERNEL); 355 if (chip->data_buffer == NULL) { 356 chip->num_opens--; 357 put_device(chip->dev); 358 return -ENOMEM; 359 } 360 361 atomic_set(&chip->data_pending, 0); 362 363 file->private_data = chip; 364 return 0; 365 366err_out: 367 spin_unlock(&driver_lock); 368 return rc; 369} 370EXPORT_SYMBOL_GPL(tpm_open); 371 372int tpm_release(struct inode *inode, struct file *file) 373{ 374 struct tpm_chip *chip = file->private_data; 375 376 spin_lock(&driver_lock); 377 file->private_data = NULL; 378 chip->num_opens--; 379 del_singleshot_timer_sync(&chip->user_read_timer); 380 atomic_set(&chip->data_pending, 0); 381 put_device(chip->dev); 382 kfree(chip->data_buffer); 383 spin_unlock(&driver_lock); 384 return 0; 385} 386EXPORT_SYMBOL_GPL(tpm_release); 387 388ssize_t tpm_write(struct file *file, const char __user *buf, 389 size_t size, loff_t * off) 390{ 391 struct tpm_chip *chip = file->private_data; 392 int in_size = size, out_size; 393 394 /* cannot perform a write until the read has cleared 395 either via tpm_read or a user_read_timer timeout */ 396 while (atomic_read(&chip->data_pending) != 0) 397 msleep(TPM_TIMEOUT); 398 399 down(&chip->buffer_mutex); 400 401 if (in_size > TPM_BUFSIZE) 402 in_size = TPM_BUFSIZE; 403 404 if (copy_from_user 405 (chip->data_buffer, (void __user *) buf, in_size)) { 406 up(&chip->buffer_mutex); 407 return -EFAULT; 408 } 409 410 /* atomic tpm command send and result receive */ 411 out_size = tpm_transmit(chip, chip->data_buffer, TPM_BUFSIZE); 412 413 atomic_set(&chip->data_pending, out_size); 414 up(&chip->buffer_mutex); 415 416 /* Set a timeout by which the reader must come claim the result */ 417 mod_timer(&chip->user_read_timer, jiffies + (60 * HZ)); 418 419 return in_size; 420} 421 422EXPORT_SYMBOL_GPL(tpm_write); 423 424ssize_t tpm_read(struct file * file, char __user *buf, 425 size_t size, loff_t * off) 426{ 427 struct tpm_chip *chip = file->private_data; 428 int ret_size; 429 430 del_singleshot_timer_sync(&chip->user_read_timer); 431 ret_size = atomic_read(&chip->data_pending); 432 atomic_set(&chip->data_pending, 0); 433 if (ret_size > 0) { /* relay data */ 434 if (size < ret_size) 435 ret_size = size; 436 437 down(&chip->buffer_mutex); 438 if (copy_to_user(buf, chip->data_buffer, ret_size)) 439 ret_size = -EFAULT; 440 up(&chip->buffer_mutex); 441 } 442 443 return ret_size; 444} 445EXPORT_SYMBOL_GPL(tpm_read); 446 447void tpm_remove_hardware(struct device *dev) 448{ 449 struct tpm_chip *chip = dev_get_drvdata(dev); 450 451 if (chip == NULL) { 452 dev_err(dev, "No device data found\n"); 453 return; 454 } 455 456 spin_lock(&driver_lock); 457 458 list_del(&chip->list); 459 460 spin_unlock(&driver_lock); 461 462 dev_set_drvdata(dev, NULL); 463 misc_deregister(&chip->vendor->miscdev); 464 kfree(chip->vendor->miscdev.name); 465 466 sysfs_remove_group(&dev->kobj, chip->vendor->attr_group); 467 468 dev_mask[chip->dev_num / TPM_NUM_MASK_ENTRIES ] &= 469 ~(1 << (chip->dev_num % TPM_NUM_MASK_ENTRIES)); 470 471 kfree(chip); 472 473 put_device(dev); 474} 475EXPORT_SYMBOL_GPL(tpm_remove_hardware); 476 477static u8 savestate[] = { 478 0, 193, /* TPM_TAG_RQU_COMMAND */ 479 0, 0, 0, 10, /* blob length (in bytes) */ 480 0, 0, 0, 152 /* TPM_ORD_SaveState */ 481}; 482 483/* 484 * We are about to suspend. Save the TPM state 485 * so that it can be restored. 486 */ 487int tpm_pm_suspend(struct device *dev, pm_message_t pm_state) 488{ 489 struct tpm_chip *chip = dev_get_drvdata(dev); 490 if (chip == NULL) 491 return -ENODEV; 492 493 tpm_transmit(chip, savestate, sizeof(savestate)); 494 return 0; 495} 496EXPORT_SYMBOL_GPL(tpm_pm_suspend); 497 498/* 499 * Resume from a power safe. The BIOS already restored 500 * the TPM state. 501 */ 502int tpm_pm_resume(struct device *dev) 503{ 504 struct tpm_chip *chip = dev_get_drvdata(dev); 505 506 if (chip == NULL) 507 return -ENODEV; 508 509 return 0; 510} 511EXPORT_SYMBOL_GPL(tpm_pm_resume); 512 513/* 514 * Called from tpm_<specific>.c probe function only for devices 515 * the driver has determined it should claim. Prior to calling 516 * this function the specific probe function has called pci_enable_device 517 * upon errant exit from this function specific probe function should call 518 * pci_disable_device 519 */ 520int tpm_register_hardware(struct device *dev, struct tpm_vendor_specific *entry) 521{ 522#define DEVNAME_SIZE 7 523 524 char *devname; 525 struct tpm_chip *chip; 526 int i, j; 527 528 /* Driver specific per-device data */ 529 chip = kzalloc(sizeof(*chip), GFP_KERNEL); 530 if (chip == NULL) 531 return -ENOMEM; 532 533 init_MUTEX(&chip->buffer_mutex); 534 init_MUTEX(&chip->tpm_mutex); 535 INIT_LIST_HEAD(&chip->list); 536 537 INIT_WORK(&chip->work, timeout_work, chip); 538 539 init_timer(&chip->user_read_timer); 540 chip->user_read_timer.function = user_reader_timeout; 541 chip->user_read_timer.data = (unsigned long) chip; 542 543 chip->vendor = entry; 544 545 chip->dev_num = -1; 546 547 for (i = 0; i < TPM_NUM_MASK_ENTRIES; i++) 548 for (j = 0; j < 8 * sizeof(int); j++) 549 if ((dev_mask[i] & (1 << j)) == 0) { 550 chip->dev_num = 551 i * TPM_NUM_MASK_ENTRIES + j; 552 dev_mask[i] |= 1 << j; 553 goto dev_num_search_complete; 554 } 555 556dev_num_search_complete: 557 if (chip->dev_num < 0) { 558 dev_err(dev, "No available tpm device numbers\n"); 559 kfree(chip); 560 return -ENODEV; 561 } else if (chip->dev_num == 0) 562 chip->vendor->miscdev.minor = TPM_MINOR; 563 else 564 chip->vendor->miscdev.minor = MISC_DYNAMIC_MINOR; 565 566 devname = kmalloc(DEVNAME_SIZE, GFP_KERNEL); 567 scnprintf(devname, DEVNAME_SIZE, "%s%d", "tpm", chip->dev_num); 568 chip->vendor->miscdev.name = devname; 569 570 chip->vendor->miscdev.dev = dev; 571 chip->dev = get_device(dev); 572 573 if (misc_register(&chip->vendor->miscdev)) { 574 dev_err(chip->dev, 575 "unable to misc_register %s, minor %d\n", 576 chip->vendor->miscdev.name, 577 chip->vendor->miscdev.minor); 578 put_device(dev); 579 kfree(chip); 580 dev_mask[i] &= !(1 << j); 581 return -ENODEV; 582 } 583 584 spin_lock(&driver_lock); 585 586 dev_set_drvdata(dev, chip); 587 588 list_add(&chip->list, &tpm_chip_list); 589 590 spin_unlock(&driver_lock); 591 592 sysfs_create_group(&dev->kobj, chip->vendor->attr_group); 593 594 return 0; 595} 596EXPORT_SYMBOL_GPL(tpm_register_hardware); 597 598MODULE_AUTHOR("Leendert van Doorn (leendert@watson.ibm.com)"); 599MODULE_DESCRIPTION("TPM Driver"); 600MODULE_VERSION("2.0"); 601MODULE_LICENSE("GPL"); 602