tpm.c revision 3c2f606a098b07f053904ec8b8f4d0e101c28b35
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	flush_scheduled_work();
381	atomic_set(&chip->data_pending, 0);
382	put_device(chip->dev);
383	kfree(chip->data_buffer);
384	spin_unlock(&driver_lock);
385	return 0;
386}
387EXPORT_SYMBOL_GPL(tpm_release);
388
389ssize_t tpm_write(struct file *file, const char __user *buf,
390		  size_t size, loff_t *off)
391{
392	struct tpm_chip *chip = file->private_data;
393	int in_size = size, out_size;
394
395	/* cannot perform a write until the read has cleared
396	   either via tpm_read or a user_read_timer timeout */
397	while (atomic_read(&chip->data_pending) != 0)
398		msleep(TPM_TIMEOUT);
399
400	down(&chip->buffer_mutex);
401
402	if (in_size > TPM_BUFSIZE)
403		in_size = TPM_BUFSIZE;
404
405	if (copy_from_user
406	    (chip->data_buffer, (void __user *) buf, in_size)) {
407		up(&chip->buffer_mutex);
408		return -EFAULT;
409	}
410
411	/* atomic tpm command send and result receive */
412	out_size = tpm_transmit(chip, chip->data_buffer, TPM_BUFSIZE);
413
414	atomic_set(&chip->data_pending, out_size);
415	up(&chip->buffer_mutex);
416
417	/* Set a timeout by which the reader must come claim the result */
418	mod_timer(&chip->user_read_timer, jiffies + (60 * HZ));
419
420	return in_size;
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	flush_scheduled_work();
432	ret_size = atomic_read(&chip->data_pending);
433	atomic_set(&chip->data_pending, 0);
434	if (ret_size > 0) {	/* relay data */
435		if (size < ret_size)
436			ret_size = size;
437
438		down(&chip->buffer_mutex);
439		if (copy_to_user(buf, chip->data_buffer, ret_size))
440			ret_size = -EFAULT;
441		up(&chip->buffer_mutex);
442	}
443
444	return ret_size;
445}
446EXPORT_SYMBOL_GPL(tpm_read);
447
448void tpm_remove_hardware(struct device *dev)
449{
450	struct tpm_chip *chip = dev_get_drvdata(dev);
451
452	if (chip == NULL) {
453		dev_err(dev, "No device data found\n");
454		return;
455	}
456
457	spin_lock(&driver_lock);
458
459	list_del(&chip->list);
460
461	spin_unlock(&driver_lock);
462
463	dev_set_drvdata(dev, NULL);
464	misc_deregister(&chip->vendor->miscdev);
465	kfree(chip->vendor->miscdev.name);
466
467	sysfs_remove_group(&dev->kobj, chip->vendor->attr_group);
468	tpm_bios_log_teardown(chip->bios_dir);
469
470	dev_mask[chip->dev_num / TPM_NUM_MASK_ENTRIES ] &=
471		~(1 << (chip->dev_num % TPM_NUM_MASK_ENTRIES));
472
473	kfree(chip);
474
475	put_device(dev);
476}
477EXPORT_SYMBOL_GPL(tpm_remove_hardware);
478
479static u8 savestate[] = {
480	0, 193,			/* TPM_TAG_RQU_COMMAND */
481	0, 0, 0, 10,		/* blob length (in bytes) */
482	0, 0, 0, 152		/* TPM_ORD_SaveState */
483};
484
485/*
486 * We are about to suspend. Save the TPM state
487 * so that it can be restored.
488 */
489int tpm_pm_suspend(struct device *dev, pm_message_t pm_state)
490{
491	struct tpm_chip *chip = dev_get_drvdata(dev);
492	if (chip == NULL)
493		return -ENODEV;
494
495	tpm_transmit(chip, savestate, sizeof(savestate));
496	return 0;
497}
498EXPORT_SYMBOL_GPL(tpm_pm_suspend);
499
500/*
501 * Resume from a power safe. The BIOS already restored
502 * the TPM state.
503 */
504int tpm_pm_resume(struct device *dev)
505{
506	struct tpm_chip *chip = dev_get_drvdata(dev);
507
508	if (chip == NULL)
509		return -ENODEV;
510
511	return 0;
512}
513EXPORT_SYMBOL_GPL(tpm_pm_resume);
514
515/*
516 * Called from tpm_<specific>.c probe function only for devices
517 * the driver has determined it should claim.  Prior to calling
518 * this function the specific probe function has called pci_enable_device
519 * upon errant exit from this function specific probe function should call
520 * pci_disable_device
521 */
522int tpm_register_hardware(struct device *dev, struct tpm_vendor_specific *entry)
523{
524#define DEVNAME_SIZE 7
525
526	char *devname;
527	struct tpm_chip *chip;
528	int i, j;
529
530	/* Driver specific per-device data */
531	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
532	if (chip == NULL)
533		return -ENOMEM;
534
535	init_MUTEX(&chip->buffer_mutex);
536	init_MUTEX(&chip->tpm_mutex);
537	INIT_LIST_HEAD(&chip->list);
538
539	INIT_WORK(&chip->work, timeout_work, chip);
540
541	init_timer(&chip->user_read_timer);
542	chip->user_read_timer.function = user_reader_timeout;
543	chip->user_read_timer.data = (unsigned long) chip;
544
545	chip->vendor = entry;
546
547	chip->dev_num = -1;
548
549	for (i = 0; i < TPM_NUM_MASK_ENTRIES; i++)
550		for (j = 0; j < 8 * sizeof(int); j++)
551			if ((dev_mask[i] & (1 << j)) == 0) {
552				chip->dev_num =
553				    i * TPM_NUM_MASK_ENTRIES + j;
554				dev_mask[i] |= 1 << j;
555				goto dev_num_search_complete;
556			}
557
558dev_num_search_complete:
559	if (chip->dev_num < 0) {
560		dev_err(dev, "No available tpm device numbers\n");
561		kfree(chip);
562		return -ENODEV;
563	} else if (chip->dev_num == 0)
564		chip->vendor->miscdev.minor = TPM_MINOR;
565	else
566		chip->vendor->miscdev.minor = MISC_DYNAMIC_MINOR;
567
568	devname = kmalloc(DEVNAME_SIZE, GFP_KERNEL);
569	scnprintf(devname, DEVNAME_SIZE, "%s%d", "tpm", chip->dev_num);
570	chip->vendor->miscdev.name = devname;
571
572	chip->vendor->miscdev.dev = dev;
573	chip->dev = get_device(dev);
574
575	if (misc_register(&chip->vendor->miscdev)) {
576		dev_err(chip->dev,
577			"unable to misc_register %s, minor %d\n",
578			chip->vendor->miscdev.name,
579			chip->vendor->miscdev.minor);
580		put_device(dev);
581		kfree(chip);
582		dev_mask[i] &= !(1 << j);
583		return -ENODEV;
584	}
585
586	spin_lock(&driver_lock);
587
588	dev_set_drvdata(dev, chip);
589
590	list_add(&chip->list, &tpm_chip_list);
591
592	spin_unlock(&driver_lock);
593
594	sysfs_create_group(&dev->kobj, chip->vendor->attr_group);
595
596	chip->bios_dir = tpm_bios_log_setup(devname);
597
598	return 0;
599}
600EXPORT_SYMBOL_GPL(tpm_register_hardware);
601
602MODULE_AUTHOR("Leendert van Doorn (leendert@watson.ibm.com)");
603MODULE_DESCRIPTION("TPM Driver");
604MODULE_VERSION("2.0");
605MODULE_LICENSE("GPL");
606