]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/char/tpm/tpm.c
187bcdaf7bf646b625809ab44819abc20bed9a57
[linux-2.6-omap-h63xx.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 static LIST_HEAD(tpm_chip_list);
39 static DEFINE_SPINLOCK(driver_lock);
40 static int dev_mask[TPM_NUM_MASK_ENTRIES];
41
42 static 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
49 static 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  */
62 static 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
111 out_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);
116 out:
117         up(&chip->tpm_mutex);
118         return rc;
119 }
120
121 #define TPM_DIGEST_SIZE 20
122 #define TPM_ERROR_SIZE 10
123 #define TPM_RET_CODE_IDX 6
124 #define TPM_GET_CAP_RET_SIZE_IDX 10
125 #define TPM_GET_CAP_RET_UINT32_1_IDX 14
126 #define TPM_GET_CAP_RET_UINT32_2_IDX 18
127 #define TPM_GET_CAP_RET_UINT32_3_IDX 22
128 #define TPM_GET_CAP_RET_UINT32_4_IDX 26
129
130 #define TPM_CAP_IDX 13
131 #define TPM_CAP_SUBCAP_IDX 21
132
133 enum tpm_capabilities {
134         TPM_CAP_PROP = 5,
135 };
136
137 enum tpm_sub_capabilities {
138         TPM_CAP_PROP_PCR = 0x1,
139         TPM_CAP_PROP_MANUFACTURER = 0x3,
140 };
141
142 /*
143  * This is a semi generic GetCapability command for use
144  * with the capability type TPM_CAP_PROP or TPM_CAP_FLAG
145  * and their associated sub_capabilities.
146  */
147
148 static const u8 tpm_cap[] = {
149         0, 193,                 /* TPM_TAG_RQU_COMMAND */
150         0, 0, 0, 22,            /* length */
151         0, 0, 0, 101,           /* TPM_ORD_GetCapability */
152         0, 0, 0, 0,             /* TPM_CAP_<TYPE> */
153         0, 0, 0, 4,             /* TPM_CAP_SUB_<TYPE> size */
154         0, 0, 1, 0              /* TPM_CAP_SUB_<TYPE> */
155 };
156
157 static ssize_t transmit_cmd(struct tpm_chip *chip, u8 *data, int len,
158                             char *desc)
159 {
160         int err;
161
162         len = tpm_transmit(chip, data, len);
163         if (len <  0)
164                 return len;
165         if (len == TPM_ERROR_SIZE) {
166                 err = be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX)));
167                 dev_dbg(chip->dev, "A TPM error (%d) occurred %s\n", err, desc);
168                 return err;
169         }
170         return 0;
171 }
172
173 static const u8 pcrread[] = {
174         0, 193,                 /* TPM_TAG_RQU_COMMAND */
175         0, 0, 0, 14,            /* length */
176         0, 0, 0, 21,            /* TPM_ORD_PcrRead */
177         0, 0, 0, 0              /* PCR index */
178 };
179
180 ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr,
181                       char *buf)
182 {
183         u8 data[30];
184         ssize_t rc;
185         int i, j, num_pcrs;
186         __be32 index;
187         char *str = buf;
188
189         struct tpm_chip *chip = dev_get_drvdata(dev);
190         if (chip == NULL)
191                 return -ENODEV;
192
193         memcpy(data, tpm_cap, sizeof(tpm_cap));
194         data[TPM_CAP_IDX] = TPM_CAP_PROP;
195         data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_PCR;
196
197         rc = transmit_cmd(chip, data, sizeof(data),
198                         "attempting to determine the number of PCRS");
199         if (rc)
200                 return 0;
201
202         num_pcrs = be32_to_cpu(*((__be32 *) (data + 14)));
203         for (i = 0; i < num_pcrs; i++) {
204                 memcpy(data, pcrread, sizeof(pcrread));
205                 index = cpu_to_be32(i);
206                 memcpy(data + 10, &index, 4);
207                 rc = transmit_cmd(chip, data, sizeof(data),
208                                 "attempting to read a PCR");
209                 if (rc)
210                         goto out;
211                 str += sprintf(str, "PCR-%02d: ", i);
212                 for (j = 0; j < TPM_DIGEST_SIZE; j++)
213                         str += sprintf(str, "%02X ", *(data + 10 + j));
214                 str += sprintf(str, "\n");
215         }
216 out:
217         return str - buf;
218 }
219 EXPORT_SYMBOL_GPL(tpm_show_pcrs);
220
221 #define  READ_PUBEK_RESULT_SIZE 314
222 static const u8 readpubek[] = {
223         0, 193,                 /* TPM_TAG_RQU_COMMAND */
224         0, 0, 0, 30,            /* length */
225         0, 0, 0, 124,           /* TPM_ORD_ReadPubek */
226 };
227
228 ssize_t tpm_show_pubek(struct device *dev, struct device_attribute *attr,
229                        char *buf)
230 {
231         u8 *data;
232         ssize_t err;
233         int i, rc;
234         char *str = buf;
235
236         struct tpm_chip *chip = dev_get_drvdata(dev);
237         if (chip == NULL)
238                 return -ENODEV;
239
240         data = kzalloc(READ_PUBEK_RESULT_SIZE, GFP_KERNEL);
241         if (!data)
242                 return -ENOMEM;
243
244         memcpy(data, readpubek, sizeof(readpubek));
245
246         err = transmit_cmd(chip, data, READ_PUBEK_RESULT_SIZE,
247                         "attempting to read the PUBEK");
248         if (err)
249                 goto out;
250
251         /* 
252            ignore header 10 bytes
253            algorithm 32 bits (1 == RSA )
254            encscheme 16 bits
255            sigscheme 16 bits
256            parameters (RSA 12->bytes: keybit, #primes, expbit)  
257            keylenbytes 32 bits
258            256 byte modulus
259            ignore checksum 20 bytes
260          */
261
262         str +=
263             sprintf(str,
264                     "Algorithm: %02X %02X %02X %02X\nEncscheme: %02X %02X\n"
265                     "Sigscheme: %02X %02X\nParameters: %02X %02X %02X %02X"
266                     " %02X %02X %02X %02X %02X %02X %02X %02X\n"
267                     "Modulus length: %d\nModulus: \n",
268                     data[10], data[11], data[12], data[13], data[14],
269                     data[15], data[16], data[17], data[22], data[23],
270                     data[24], data[25], data[26], data[27], data[28],
271                     data[29], data[30], data[31], data[32], data[33],
272                     be32_to_cpu(*((__be32 *) (data + 34))));
273
274         for (i = 0; i < 256; i++) {
275                 str += sprintf(str, "%02X ", data[i + 38]);
276                 if ((i + 1) % 16 == 0)
277                         str += sprintf(str, "\n");
278         }
279 out:
280         rc = str - buf;
281         kfree(data);
282         return rc;
283 }
284 EXPORT_SYMBOL_GPL(tpm_show_pubek);
285
286 #define CAP_VERSION_1_1 6
287 #define CAP_VERSION_IDX 13
288 static const u8 cap_version[] = {
289         0, 193,                 /* TPM_TAG_RQU_COMMAND */
290         0, 0, 0, 18,            /* length */
291         0, 0, 0, 101,           /* TPM_ORD_GetCapability */
292         0, 0, 0, 0,
293         0, 0, 0, 0
294 };
295
296 ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr,
297                       char *buf)
298 {
299         u8 data[30];
300         ssize_t rc;
301         char *str = buf;
302
303         struct tpm_chip *chip = dev_get_drvdata(dev);
304         if (chip == NULL)
305                 return -ENODEV;
306
307         memcpy(data, tpm_cap, sizeof(tpm_cap));
308         data[TPM_CAP_IDX] = TPM_CAP_PROP;
309         data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_MANUFACTURER;
310
311         rc = transmit_cmd(chip, data, sizeof(data),
312                         "attempting to determine the manufacturer");
313         if (rc)
314                 return 0;
315
316         str += sprintf(str, "Manufacturer: 0x%x\n",
317                        be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX))));
318
319         memcpy(data, cap_version, sizeof(cap_version));
320         data[CAP_VERSION_IDX] = CAP_VERSION_1_1;
321         rc = transmit_cmd(chip, data, sizeof(data),
322                         "attempting to determine the 1.1 version");
323         if (rc)
324                 goto out;
325
326         str += sprintf(str,
327                        "TCG version: %d.%d\nFirmware version: %d.%d\n",
328                        (int) data[14], (int) data[15], (int) data[16],
329                        (int) data[17]);
330
331 out:
332         return str - buf;
333 }
334 EXPORT_SYMBOL_GPL(tpm_show_caps);
335
336 ssize_t tpm_store_cancel(struct device *dev, struct device_attribute *attr,
337                         const char *buf, size_t count)
338 {
339         struct tpm_chip *chip = dev_get_drvdata(dev);
340         if (chip == NULL)
341                 return 0;
342
343         chip->vendor->cancel(chip);
344         return count;
345 }
346 EXPORT_SYMBOL_GPL(tpm_store_cancel);
347
348 /*
349  * Device file system interface to the TPM
350  */
351 int tpm_open(struct inode *inode, struct file *file)
352 {
353         int rc = 0, minor = iminor(inode);
354         struct tpm_chip *chip = NULL, *pos;
355
356         spin_lock(&driver_lock);
357
358         list_for_each_entry(pos, &tpm_chip_list, list) {
359                 if (pos->vendor->miscdev.minor == minor) {
360                         chip = pos;
361                         break;
362                 }
363         }
364
365         if (chip == NULL) {
366                 rc = -ENODEV;
367                 goto err_out;
368         }
369
370         if (chip->num_opens) {
371                 dev_dbg(chip->dev, "Another process owns this TPM\n");
372                 rc = -EBUSY;
373                 goto err_out;
374         }
375
376         chip->num_opens++;
377         get_device(chip->dev);
378
379         spin_unlock(&driver_lock);
380
381         chip->data_buffer = kmalloc(TPM_BUFSIZE * sizeof(u8), GFP_KERNEL);
382         if (chip->data_buffer == NULL) {
383                 chip->num_opens--;
384                 put_device(chip->dev);
385                 return -ENOMEM;
386         }
387
388         atomic_set(&chip->data_pending, 0);
389
390         file->private_data = chip;
391         return 0;
392
393 err_out:
394         spin_unlock(&driver_lock);
395         return rc;
396 }
397 EXPORT_SYMBOL_GPL(tpm_open);
398
399 int tpm_release(struct inode *inode, struct file *file)
400 {
401         struct tpm_chip *chip = file->private_data;
402
403         spin_lock(&driver_lock);
404         file->private_data = NULL;
405         chip->num_opens--;
406         del_singleshot_timer_sync(&chip->user_read_timer);
407         flush_scheduled_work();
408         atomic_set(&chip->data_pending, 0);
409         put_device(chip->dev);
410         kfree(chip->data_buffer);
411         spin_unlock(&driver_lock);
412         return 0;
413 }
414 EXPORT_SYMBOL_GPL(tpm_release);
415
416 ssize_t tpm_write(struct file *file, const char __user *buf,
417                   size_t size, loff_t *off)
418 {
419         struct tpm_chip *chip = file->private_data;
420         int in_size = size, out_size;
421
422         /* cannot perform a write until the read has cleared
423            either via tpm_read or a user_read_timer timeout */
424         while (atomic_read(&chip->data_pending) != 0)
425                 msleep(TPM_TIMEOUT);
426
427         down(&chip->buffer_mutex);
428
429         if (in_size > TPM_BUFSIZE)
430                 in_size = TPM_BUFSIZE;
431
432         if (copy_from_user
433             (chip->data_buffer, (void __user *) buf, in_size)) {
434                 up(&chip->buffer_mutex);
435                 return -EFAULT;
436         }
437
438         /* atomic tpm command send and result receive */
439         out_size = tpm_transmit(chip, chip->data_buffer, TPM_BUFSIZE);
440
441         atomic_set(&chip->data_pending, out_size);
442         up(&chip->buffer_mutex);
443
444         /* Set a timeout by which the reader must come claim the result */
445         mod_timer(&chip->user_read_timer, jiffies + (60 * HZ));
446
447         return in_size;
448 }
449 EXPORT_SYMBOL_GPL(tpm_write);
450
451 ssize_t tpm_read(struct file *file, char __user *buf,
452                  size_t size, loff_t *off)
453 {
454         struct tpm_chip *chip = file->private_data;
455         int ret_size;
456
457         del_singleshot_timer_sync(&chip->user_read_timer);
458         flush_scheduled_work();
459         ret_size = atomic_read(&chip->data_pending);
460         atomic_set(&chip->data_pending, 0);
461         if (ret_size > 0) {     /* relay data */
462                 if (size < ret_size)
463                         ret_size = size;
464
465                 down(&chip->buffer_mutex);
466                 if (copy_to_user(buf, chip->data_buffer, ret_size))
467                         ret_size = -EFAULT;
468                 up(&chip->buffer_mutex);
469         }
470
471         return ret_size;
472 }
473 EXPORT_SYMBOL_GPL(tpm_read);
474
475 void tpm_remove_hardware(struct device *dev)
476 {
477         struct tpm_chip *chip = dev_get_drvdata(dev);
478
479         if (chip == NULL) {
480                 dev_err(dev, "No device data found\n");
481                 return;
482         }
483
484         spin_lock(&driver_lock);
485
486         list_del(&chip->list);
487
488         spin_unlock(&driver_lock);
489
490         dev_set_drvdata(dev, NULL);
491         misc_deregister(&chip->vendor->miscdev);
492         kfree(chip->vendor->miscdev.name);
493
494         sysfs_remove_group(&dev->kobj, chip->vendor->attr_group);
495         tpm_bios_log_teardown(chip->bios_dir);
496
497         dev_mask[chip->dev_num / TPM_NUM_MASK_ENTRIES ] &=
498                 ~(1 << (chip->dev_num % TPM_NUM_MASK_ENTRIES));
499
500         kfree(chip);
501
502         put_device(dev);
503 }
504 EXPORT_SYMBOL_GPL(tpm_remove_hardware);
505
506 static u8 savestate[] = {
507         0, 193,                 /* TPM_TAG_RQU_COMMAND */
508         0, 0, 0, 10,            /* blob length (in bytes) */
509         0, 0, 0, 152            /* TPM_ORD_SaveState */
510 };
511
512 /*
513  * We are about to suspend. Save the TPM state
514  * so that it can be restored.
515  */
516 int tpm_pm_suspend(struct device *dev, pm_message_t pm_state)
517 {
518         struct tpm_chip *chip = dev_get_drvdata(dev);
519         if (chip == NULL)
520                 return -ENODEV;
521
522         tpm_transmit(chip, savestate, sizeof(savestate));
523         return 0;
524 }
525 EXPORT_SYMBOL_GPL(tpm_pm_suspend);
526
527 /*
528  * Resume from a power safe. The BIOS already restored
529  * the TPM state.
530  */
531 int tpm_pm_resume(struct device *dev)
532 {
533         struct tpm_chip *chip = dev_get_drvdata(dev);
534
535         if (chip == NULL)
536                 return -ENODEV;
537
538         return 0;
539 }
540 EXPORT_SYMBOL_GPL(tpm_pm_resume);
541
542 /*
543  * Called from tpm_<specific>.c probe function only for devices 
544  * the driver has determined it should claim.  Prior to calling
545  * this function the specific probe function has called pci_enable_device
546  * upon errant exit from this function specific probe function should call
547  * pci_disable_device
548  */
549 int tpm_register_hardware(struct device *dev, struct tpm_vendor_specific *entry)
550 {
551 #define DEVNAME_SIZE 7
552
553         char *devname;
554         struct tpm_chip *chip;
555         int i, j;
556
557         /* Driver specific per-device data */
558         chip = kzalloc(sizeof(*chip), GFP_KERNEL);
559         if (chip == NULL)
560                 return -ENOMEM;
561
562         init_MUTEX(&chip->buffer_mutex);
563         init_MUTEX(&chip->tpm_mutex);
564         INIT_LIST_HEAD(&chip->list);
565
566         INIT_WORK(&chip->work, timeout_work, chip);
567
568         init_timer(&chip->user_read_timer);
569         chip->user_read_timer.function = user_reader_timeout;
570         chip->user_read_timer.data = (unsigned long) chip;
571
572         chip->vendor = entry;
573
574         chip->dev_num = -1;
575
576         for (i = 0; i < TPM_NUM_MASK_ENTRIES; i++)
577                 for (j = 0; j < 8 * sizeof(int); j++)
578                         if ((dev_mask[i] & (1 << j)) == 0) {
579                                 chip->dev_num =
580                                     i * TPM_NUM_MASK_ENTRIES + j;
581                                 dev_mask[i] |= 1 << j;
582                                 goto dev_num_search_complete;
583                         }
584
585 dev_num_search_complete:
586         if (chip->dev_num < 0) {
587                 dev_err(dev, "No available tpm device numbers\n");
588                 kfree(chip);
589                 return -ENODEV;
590         } else if (chip->dev_num == 0)
591                 chip->vendor->miscdev.minor = TPM_MINOR;
592         else
593                 chip->vendor->miscdev.minor = MISC_DYNAMIC_MINOR;
594
595         devname = kmalloc(DEVNAME_SIZE, GFP_KERNEL);
596         scnprintf(devname, DEVNAME_SIZE, "%s%d", "tpm", chip->dev_num);
597         chip->vendor->miscdev.name = devname;
598
599         chip->vendor->miscdev.dev = dev;
600         chip->dev = get_device(dev);
601
602         if (misc_register(&chip->vendor->miscdev)) {
603                 dev_err(chip->dev,
604                         "unable to misc_register %s, minor %d\n",
605                         chip->vendor->miscdev.name,
606                         chip->vendor->miscdev.minor);
607                 put_device(dev);
608                 kfree(chip);
609                 dev_mask[i] &= !(1 << j);
610                 return -ENODEV;
611         }
612
613         spin_lock(&driver_lock);
614
615         dev_set_drvdata(dev, chip);
616
617         list_add(&chip->list, &tpm_chip_list);
618
619         spin_unlock(&driver_lock);
620
621         sysfs_create_group(&dev->kobj, chip->vendor->attr_group);
622
623         chip->bios_dir = tpm_bios_log_setup(devname);
624
625         return 0;
626 }
627 EXPORT_SYMBOL_GPL(tpm_register_hardware);
628
629 MODULE_AUTHOR("Leendert van Doorn (leendert@watson.ibm.com)");
630 MODULE_DESCRIPTION("TPM Driver");
631 MODULE_VERSION("2.0");
632 MODULE_LICENSE("GPL");