[PATCH] tpm: sysfs owernship changes
[powerpc.git] / drivers / char / tpm / tpm.c
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
31 enum 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
38   /* PCI configuration addresses */
39 enum tpm_pci_config_addr {
40         PCI_GEN_PMCON_1 = 0xA0,
41         PCI_GEN1_DEC = 0xE4,
42         PCI_LPC_EN = 0xE6,
43         PCI_GEN2_DEC = 0xEC
44 };
45
46 enum tpm_config {
47         TPM_LOCK_REG = 0x0D,
48         TPM_INTERUPT_REG = 0x0A,
49         TPM_BASE_ADDR_LO = 0x08,
50         TPM_BASE_ADDR_HI = 0x09,
51         TPM_UNLOCK_VALUE = 0x55,
52         TPM_LOCK_VALUE = 0xAA,
53         TPM_DISABLE_INTERUPT_VALUE = 0x00
54 };
55
56
57 static LIST_HEAD(tpm_chip_list);
58 static DEFINE_SPINLOCK(driver_lock);
59 static int dev_mask[TPM_NUM_MASK_ENTRIES];
60
61 static void user_reader_timeout(unsigned long ptr)
62 {
63         struct tpm_chip *chip = (struct tpm_chip *) ptr;
64
65         down(&chip->buffer_mutex);
66         atomic_set(&chip->data_pending, 0);
67         memset(chip->data_buffer, 0, TPM_BUFSIZE);
68         up(&chip->buffer_mutex);
69 }
70
71 /*
72  * Initialize the LPC bus and enable the TPM ports
73  */
74 int tpm_lpc_bus_init(struct pci_dev *pci_dev, u16 base)
75 {
76         u32 lpcenable, tmp;
77         int is_lpcm = 0;
78
79         switch (pci_dev->vendor) {
80         case PCI_VENDOR_ID_INTEL:
81                 switch (pci_dev->device) {
82                 case PCI_DEVICE_ID_INTEL_82801CA_12:
83                 case PCI_DEVICE_ID_INTEL_82801DB_12:
84                         is_lpcm = 1;
85                         break;
86                 }
87                 /* init ICH (enable LPC) */
88                 pci_read_config_dword(pci_dev, PCI_GEN1_DEC, &lpcenable);
89                 lpcenable |= 0x20000000;
90                 pci_write_config_dword(pci_dev, PCI_GEN1_DEC, lpcenable);
91
92                 if (is_lpcm) {
93                         pci_read_config_dword(pci_dev, PCI_GEN1_DEC,
94                                               &lpcenable);
95                         if ((lpcenable & 0x20000000) == 0) {
96                                 dev_err(&pci_dev->dev,
97                                         "cannot enable LPC\n");
98                                 return -ENODEV;
99                         }
100                 }
101
102                 /* initialize TPM registers */
103                 pci_read_config_dword(pci_dev, PCI_GEN2_DEC, &tmp);
104
105                 if (!is_lpcm)
106                         tmp = (tmp & 0xFFFF0000) | (base & 0xFFF0);
107                 else
108                         tmp =
109                             (tmp & 0xFFFF0000) | (base & 0xFFF0) |
110                             0x00000001;
111
112                 pci_write_config_dword(pci_dev, PCI_GEN2_DEC, tmp);
113
114                 if (is_lpcm) {
115                         pci_read_config_dword(pci_dev, PCI_GEN_PMCON_1,
116                                               &tmp);
117                         tmp |= 0x00000004;      /* enable CLKRUN */
118                         pci_write_config_dword(pci_dev, PCI_GEN_PMCON_1,
119                                                tmp);
120                 }
121                 break;
122         case PCI_VENDOR_ID_AMD:
123                 /* nothing yet */
124                 break;
125         }
126
127         tpm_write_index(TPM_LOCK_REG, TPM_UNLOCK_VALUE);
128         tpm_write_index(TPM_INTERUPT_REG, TPM_DISABLE_INTERUPT_VALUE);
129         tpm_write_index(TPM_BASE_ADDR_LO, base);
130         tpm_write_index(TPM_BASE_ADDR_HI, (base & 0xFF00) >> 8);
131         tpm_write_index(TPM_LOCK_REG, TPM_LOCK_VALUE);
132
133         return 0;
134 }
135
136 EXPORT_SYMBOL_GPL(tpm_lpc_bus_init);
137
138 /*
139  * Internal kernel interface to transmit TPM commands
140  */
141 static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
142                             size_t bufsiz)
143 {
144         ssize_t len;
145         u32 count;
146         unsigned long stop;
147
148         count = be32_to_cpu(*((__be32 *) (buf + 2)));
149
150         if (count == 0)
151                 return -ENODATA;
152         if (count > bufsiz) {
153                 dev_err(&chip->pci_dev->dev,
154                         "invalid count value %x %zx \n", count, bufsiz);
155                 return -E2BIG;
156         }
157
158         down(&chip->tpm_mutex);
159
160         if ((len = chip->vendor->send(chip, (u8 *) buf, count)) < 0) {
161                 dev_err(&chip->pci_dev->dev,
162                         "tpm_transmit: tpm_send: error %zd\n", len);
163                 return len;
164         }
165
166         stop = jiffies + 2 * 60 * HZ;
167         do {
168                 u8 status = inb(chip->vendor->base + 1);
169                 if ((status & chip->vendor->req_complete_mask) ==
170                     chip->vendor->req_complete_val) {
171                         goto out_recv;
172                 }
173                 msleep(TPM_TIMEOUT); /* CHECK */
174                 rmb();
175         } while (time_before(jiffies, stop));
176
177
178         chip->vendor->cancel(chip);
179         dev_err(&chip->pci_dev->dev, "Time expired\n");
180         up(&chip->tpm_mutex);
181         return -EIO;
182
183 out_recv:
184         len = chip->vendor->recv(chip, (u8 *) buf, bufsiz);
185         if (len < 0)
186                 dev_err(&chip->pci_dev->dev,
187                         "tpm_transmit: tpm_recv: error %zd\n", len);
188         up(&chip->tpm_mutex);
189         return len;
190 }
191
192 #define TPM_DIGEST_SIZE 20
193 #define CAP_PCR_RESULT_SIZE 18
194 static const u8 cap_pcr[] = {
195         0, 193,                 /* TPM_TAG_RQU_COMMAND */
196         0, 0, 0, 22,            /* length */
197         0, 0, 0, 101,           /* TPM_ORD_GetCapability */
198         0, 0, 0, 5,
199         0, 0, 0, 4,
200         0, 0, 1, 1
201 };
202
203 #define READ_PCR_RESULT_SIZE 30
204 static const u8 pcrread[] = {
205         0, 193,                 /* TPM_TAG_RQU_COMMAND */
206         0, 0, 0, 14,            /* length */
207         0, 0, 0, 21,            /* TPM_ORD_PcrRead */
208         0, 0, 0, 0              /* PCR index */
209 };
210
211 ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr,
212                       char *buf)
213 {
214         u8 data[READ_PCR_RESULT_SIZE];
215         ssize_t len;
216         int i, j, num_pcrs;
217         __be32 index;
218         char *str = buf;
219
220         struct tpm_chip *chip =
221             pci_get_drvdata(to_pci_dev(dev));
222         if (chip == NULL)
223                 return -ENODEV;
224
225         memcpy(data, cap_pcr, sizeof(cap_pcr));
226         if ((len = tpm_transmit(chip, data, sizeof(data)))
227             < CAP_PCR_RESULT_SIZE)
228                 return len;
229
230         num_pcrs = be32_to_cpu(*((__be32 *) (data + 14)));
231
232         for (i = 0; i < num_pcrs; i++) {
233                 memcpy(data, pcrread, sizeof(pcrread));
234                 index = cpu_to_be32(i);
235                 memcpy(data + 10, &index, 4);
236                 if ((len = tpm_transmit(chip, data, sizeof(data)))
237                     < READ_PCR_RESULT_SIZE)
238                         return len;
239                 str += sprintf(str, "PCR-%02d: ", i);
240                 for (j = 0; j < TPM_DIGEST_SIZE; j++)
241                         str += sprintf(str, "%02X ", *(data + 10 + j));
242                 str += sprintf(str, "\n");
243         }
244         return str - buf;
245 }
246
247 EXPORT_SYMBOL_GPL(tpm_show_pcrs);
248
249 #define  READ_PUBEK_RESULT_SIZE 314
250 static const u8 readpubek[] = {
251         0, 193,                 /* TPM_TAG_RQU_COMMAND */
252         0, 0, 0, 30,            /* length */
253         0, 0, 0, 124,           /* TPM_ORD_ReadPubek */
254 };
255
256 ssize_t tpm_show_pubek(struct device *dev, struct device_attribute *attr,
257                        char *buf)
258 {
259         u8 *data;
260         ssize_t len;
261         int i, rc;
262         char *str = buf;
263
264         struct tpm_chip *chip =
265             pci_get_drvdata(to_pci_dev(dev));
266         if (chip == NULL)
267                 return -ENODEV;
268
269         data = kmalloc(READ_PUBEK_RESULT_SIZE, GFP_KERNEL);
270         if (!data)
271                 return -ENOMEM;
272
273         memcpy(data, readpubek, sizeof(readpubek));
274         memset(data + sizeof(readpubek), 0, 20);        /* zero nonce */
275
276         if ((len = tpm_transmit(chip, data, READ_PUBEK_RESULT_SIZE)) <
277             READ_PUBEK_RESULT_SIZE) {
278                 rc = len;
279                 goto out;
280         }
281
282         /* 
283            ignore header 10 bytes
284            algorithm 32 bits (1 == RSA )
285            encscheme 16 bits
286            sigscheme 16 bits
287            parameters (RSA 12->bytes: keybit, #primes, expbit)  
288            keylenbytes 32 bits
289            256 byte modulus
290            ignore checksum 20 bytes
291          */
292
293         str +=
294             sprintf(str,
295                     "Algorithm: %02X %02X %02X %02X\nEncscheme: %02X %02X\n"
296                     "Sigscheme: %02X %02X\nParameters: %02X %02X %02X %02X"
297                     " %02X %02X %02X %02X %02X %02X %02X %02X\n"
298                     "Modulus length: %d\nModulus: \n",
299                     data[10], data[11], data[12], data[13], data[14],
300                     data[15], data[16], data[17], data[22], data[23],
301                     data[24], data[25], data[26], data[27], data[28],
302                     data[29], data[30], data[31], data[32], data[33],
303                     be32_to_cpu(*((__be32 *) (data + 32))));
304
305         for (i = 0; i < 256; i++) {
306                 str += sprintf(str, "%02X ", data[i + 39]);
307                 if ((i + 1) % 16 == 0)
308                         str += sprintf(str, "\n");
309         }
310         rc = str - buf;
311 out:
312         kfree(data);
313         return rc;
314 }
315
316 EXPORT_SYMBOL_GPL(tpm_show_pubek);
317
318 #define CAP_VER_RESULT_SIZE 18
319 static const u8 cap_version[] = {
320         0, 193,                 /* TPM_TAG_RQU_COMMAND */
321         0, 0, 0, 18,            /* length */
322         0, 0, 0, 101,           /* TPM_ORD_GetCapability */
323         0, 0, 0, 6,
324         0, 0, 0, 0
325 };
326
327 #define CAP_MANUFACTURER_RESULT_SIZE 18
328 static const u8 cap_manufacturer[] = {
329         0, 193,                 /* TPM_TAG_RQU_COMMAND */
330         0, 0, 0, 22,            /* length */
331         0, 0, 0, 101,           /* TPM_ORD_GetCapability */
332         0, 0, 0, 5,
333         0, 0, 0, 4,
334         0, 0, 1, 3
335 };
336
337 ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr,
338                       char *buf)
339 {
340         u8 data[sizeof(cap_manufacturer)];
341         ssize_t len;
342         char *str = buf;
343
344         struct tpm_chip *chip =
345             pci_get_drvdata(to_pci_dev(dev));
346         if (chip == NULL)
347                 return -ENODEV;
348
349         memcpy(data, cap_manufacturer, sizeof(cap_manufacturer));
350
351         if ((len = tpm_transmit(chip, data, sizeof(data))) <
352             CAP_MANUFACTURER_RESULT_SIZE)
353                 return len;
354
355         str += sprintf(str, "Manufacturer: 0x%x\n",
356                        be32_to_cpu(*((__be32 *) (data + 14))));
357
358         memcpy(data, cap_version, sizeof(cap_version));
359
360         if ((len = tpm_transmit(chip, data, sizeof(data))) <
361             CAP_VER_RESULT_SIZE)
362                 return len;
363
364         str +=
365             sprintf(str, "TCG version: %d.%d\nFirmware version: %d.%d\n",
366                     (int) data[14], (int) data[15], (int) data[16],
367                     (int) data[17]);
368
369         return str - buf;
370 }
371 EXPORT_SYMBOL_GPL(tpm_show_caps);
372
373 ssize_t tpm_store_cancel(struct device *dev, struct device_attribute *attr,
374                         const char *buf, size_t count)
375 {
376         struct tpm_chip *chip = dev_get_drvdata(dev);
377         if (chip == NULL)
378                 return 0;
379
380         chip->vendor->cancel(chip);
381         return count;
382 }
383 EXPORT_SYMBOL_GPL(tpm_store_cancel);
384
385
386 /*
387  * Device file system interface to the TPM
388  */
389 int tpm_open(struct inode *inode, struct file *file)
390 {
391         int rc = 0, minor = iminor(inode);
392         struct tpm_chip *chip = NULL, *pos;
393
394         spin_lock(&driver_lock);
395
396         list_for_each_entry(pos, &tpm_chip_list, list) {
397                 if (pos->vendor->miscdev.minor == minor) {
398                         chip = pos;
399                         break;
400                 }
401         }
402
403         if (chip == NULL) {
404                 rc = -ENODEV;
405                 goto err_out;
406         }
407
408         if (chip->num_opens) {
409                 dev_dbg(&chip->pci_dev->dev,
410                         "Another process owns this TPM\n");
411                 rc = -EBUSY;
412                 goto err_out;
413         }
414
415         chip->num_opens++;
416         pci_dev_get(chip->pci_dev);
417
418         spin_unlock(&driver_lock);
419
420         chip->data_buffer = kmalloc(TPM_BUFSIZE * sizeof(u8), GFP_KERNEL);
421         if (chip->data_buffer == NULL) {
422                 chip->num_opens--;
423                 pci_dev_put(chip->pci_dev);
424                 return -ENOMEM;
425         }
426
427         atomic_set(&chip->data_pending, 0);
428
429         file->private_data = chip;
430         return 0;
431
432 err_out:
433         spin_unlock(&driver_lock);
434         return rc;
435 }
436
437 EXPORT_SYMBOL_GPL(tpm_open);
438
439 int tpm_release(struct inode *inode, struct file *file)
440 {
441         struct tpm_chip *chip = file->private_data;
442         
443         file->private_data = NULL;
444
445         spin_lock(&driver_lock);
446         chip->num_opens--;
447         del_singleshot_timer_sync(&chip->user_read_timer);
448         atomic_set(&chip->data_pending, 0);
449
450         pci_dev_put(chip->pci_dev);
451         return 0;
452 }
453
454 EXPORT_SYMBOL_GPL(tpm_release);
455
456 ssize_t tpm_write(struct file * file, const char __user * buf,
457                   size_t size, loff_t * off)
458 {
459         struct tpm_chip *chip = file->private_data;
460         int in_size = size, out_size;
461
462         /* cannot perform a write until the read has cleared
463            either via tpm_read or a user_read_timer timeout */
464         while (atomic_read(&chip->data_pending) != 0)
465                 msleep(TPM_TIMEOUT);
466
467         down(&chip->buffer_mutex);
468
469         if (in_size > TPM_BUFSIZE)
470                 in_size = TPM_BUFSIZE;
471
472         if (copy_from_user
473             (chip->data_buffer, (void __user *) buf, in_size)) {
474                 up(&chip->buffer_mutex);
475                 return -EFAULT;
476         }
477
478         /* atomic tpm command send and result receive */
479         out_size = tpm_transmit(chip, chip->data_buffer, TPM_BUFSIZE);
480
481         atomic_set(&chip->data_pending, out_size);
482         up(&chip->buffer_mutex);
483
484         /* Set a timeout by which the reader must come claim the result */
485         mod_timer(&chip->user_read_timer, jiffies + (60 * HZ));
486
487         return in_size;
488 }
489
490 EXPORT_SYMBOL_GPL(tpm_write);
491
492 ssize_t tpm_read(struct file * file, char __user * buf,
493                  size_t size, loff_t * off)
494 {
495         struct tpm_chip *chip = file->private_data;
496         int ret_size;
497
498         del_singleshot_timer_sync(&chip->user_read_timer);
499         ret_size = atomic_read(&chip->data_pending);
500         atomic_set(&chip->data_pending, 0);
501         if (ret_size > 0) {     /* relay data */
502                 if (size < ret_size)
503                         ret_size = size;
504
505                 down(&chip->buffer_mutex);
506                 if (copy_to_user
507                     ((void __user *) buf, chip->data_buffer, ret_size))
508                         ret_size = -EFAULT;
509                 up(&chip->buffer_mutex);
510         }
511
512         return ret_size;
513 }
514
515 EXPORT_SYMBOL_GPL(tpm_read);
516
517 void __devexit tpm_remove(struct pci_dev *pci_dev)
518 {
519         struct tpm_chip *chip = pci_get_drvdata(pci_dev);
520
521         if (chip == NULL) {
522                 dev_err(&pci_dev->dev, "No device data found\n");
523                 return;
524         }
525
526         spin_lock(&driver_lock);
527
528         list_del(&chip->list);
529
530         spin_unlock(&driver_lock);
531
532         pci_set_drvdata(pci_dev, NULL);
533         misc_deregister(&chip->vendor->miscdev);
534
535         sysfs_remove_group(&pci_dev->dev.kobj, chip->vendor->attr_group);
536
537         pci_disable_device(pci_dev);
538
539         dev_mask[chip->dev_num / TPM_NUM_MASK_ENTRIES ] &= !(1 << (chip->dev_num % TPM_NUM_MASK_ENTRIES));
540
541         kfree(chip);
542
543         pci_dev_put(pci_dev);
544 }
545
546 EXPORT_SYMBOL_GPL(tpm_remove);
547
548 static u8 savestate[] = {
549         0, 193,                 /* TPM_TAG_RQU_COMMAND */
550         0, 0, 0, 10,            /* blob length (in bytes) */
551         0, 0, 0, 152            /* TPM_ORD_SaveState */
552 };
553
554 /*
555  * We are about to suspend. Save the TPM state
556  * so that it can be restored.
557  */
558 int tpm_pm_suspend(struct pci_dev *pci_dev, pm_message_t pm_state)
559 {
560         struct tpm_chip *chip = pci_get_drvdata(pci_dev);
561         if (chip == NULL)
562                 return -ENODEV;
563
564         tpm_transmit(chip, savestate, sizeof(savestate));
565         return 0;
566 }
567
568 EXPORT_SYMBOL_GPL(tpm_pm_suspend);
569
570 /*
571  * Resume from a power safe. The BIOS already restored
572  * the TPM state.
573  */
574 int tpm_pm_resume(struct pci_dev *pci_dev)
575 {
576         struct tpm_chip *chip = pci_get_drvdata(pci_dev);
577
578         if (chip == NULL)
579                 return -ENODEV;
580
581         spin_lock(&driver_lock);
582         tpm_lpc_bus_init(pci_dev, chip->vendor->base);
583         spin_unlock(&driver_lock);
584
585         return 0;
586 }
587
588 EXPORT_SYMBOL_GPL(tpm_pm_resume);
589
590 /*
591  * Called from tpm_<specific>.c probe function only for devices 
592  * the driver has determined it should claim.  Prior to calling
593  * this function the specific probe function has called pci_enable_device
594  * upon errant exit from this function specific probe function should call
595  * pci_disable_device
596  */
597 int tpm_register_hardware(struct pci_dev *pci_dev,
598                           struct tpm_vendor_specific *entry)
599 {
600         char devname[7];
601         struct tpm_chip *chip;
602         int i, j;
603
604         /* Driver specific per-device data */
605         chip = kmalloc(sizeof(*chip), GFP_KERNEL);
606         if (chip == NULL)
607                 return -ENOMEM;
608
609         memset(chip, 0, sizeof(struct tpm_chip));
610
611         init_MUTEX(&chip->buffer_mutex);
612         init_MUTEX(&chip->tpm_mutex);
613         INIT_LIST_HEAD(&chip->list);
614
615         init_timer(&chip->user_read_timer);
616         chip->user_read_timer.function = user_reader_timeout;
617         chip->user_read_timer.data = (unsigned long) chip;
618
619         chip->vendor = entry;
620
621         chip->dev_num = -1;
622
623         for (i = 0; i < TPM_NUM_MASK_ENTRIES; i++)
624                 for (j = 0; j < 8 * sizeof(int); j++)
625                         if ((dev_mask[i] & (1 << j)) == 0) {
626                                 chip->dev_num =
627                                     i * TPM_NUM_MASK_ENTRIES + j;
628                                 dev_mask[i] |= 1 << j;
629                                 goto dev_num_search_complete;
630                         }
631
632 dev_num_search_complete:
633         if (chip->dev_num < 0) {
634                 dev_err(&pci_dev->dev,
635                         "No available tpm device numbers\n");
636                 kfree(chip);
637                 return -ENODEV;
638         } else if (chip->dev_num == 0)
639                 chip->vendor->miscdev.minor = TPM_MINOR;
640         else
641                 chip->vendor->miscdev.minor = MISC_DYNAMIC_MINOR;
642
643         snprintf(devname, sizeof(devname), "%s%d", "tpm", chip->dev_num);
644         chip->vendor->miscdev.name = devname;
645
646         chip->vendor->miscdev.dev = &(pci_dev->dev);
647         chip->pci_dev = pci_dev_get(pci_dev);
648
649         if (misc_register(&chip->vendor->miscdev)) {
650                 dev_err(&chip->pci_dev->dev,
651                         "unable to misc_register %s, minor %d\n",
652                         chip->vendor->miscdev.name,
653                         chip->vendor->miscdev.minor);
654                 pci_dev_put(pci_dev);
655                 kfree(chip);
656                 dev_mask[i] &= !(1 << j);
657                 return -ENODEV;
658         }
659
660         pci_set_drvdata(pci_dev, chip);
661
662         list_add(&chip->list, &tpm_chip_list);
663
664         sysfs_create_group(&pci_dev->dev.kobj, chip->vendor->attr_group);
665
666         return 0;
667 }
668
669 EXPORT_SYMBOL_GPL(tpm_register_hardware);
670
671 MODULE_AUTHOR("Leendert van Doorn (leendert@watson.ibm.com)");
672 MODULE_DESCRIPTION("TPM Driver");
673 MODULE_VERSION("2.0");
674 MODULE_LICENSE("GPL");