xref: /linux/drivers/char/tpm/eventlog/tpm1.c (revision 0bfb23746052168620c5b52f49d8a47c3bb022fa)
1 /*
2  * Copyright (C) 2005, 2012 IBM Corporation
3  *
4  * Authors:
5  *	Kent Yoder <key@linux.vnet.ibm.com>
6  *	Seiji Munetoh <munetoh@jp.ibm.com>
7  *	Stefan Berger <stefanb@us.ibm.com>
8  *	Reiner Sailer <sailer@watson.ibm.com>
9  *	Kylene Hall <kjhall@us.ibm.com>
10  *	Nayna Jain <nayna@linux.vnet.ibm.com>
11  *
12  * Maintained by: <tpmdd-devel@lists.sourceforge.net>
13  *
14  * Access to the event log created by a system's firmware / BIOS
15  *
16  * This program is free software; you can redistribute it and/or
17  * modify it under the terms of the GNU General Public License
18  * as published by the Free Software Foundation; either version
19  * 2 of the License, or (at your option) any later version.
20  *
21  */
22 
23 #include <linux/seq_file.h>
24 #include <linux/efi.h>
25 #include <linux/fs.h>
26 #include <linux/security.h>
27 #include <linux/module.h>
28 #include <linux/slab.h>
29 #include <linux/tpm_eventlog.h>
30 
31 #include "../tpm.h"
32 
33 
34 static const char* tcpa_event_type_strings[] = {
35 	"PREBOOT",
36 	"POST CODE",
37 	"",
38 	"NO ACTION",
39 	"SEPARATOR",
40 	"ACTION",
41 	"EVENT TAG",
42 	"S-CRTM Contents",
43 	"S-CRTM Version",
44 	"CPU Microcode",
45 	"Platform Config Flags",
46 	"Table of Devices",
47 	"Compact Hash",
48 	"IPL",
49 	"IPL Partition Data",
50 	"Non-Host Code",
51 	"Non-Host Config",
52 	"Non-Host Info"
53 };
54 
55 static const char* tcpa_pc_event_id_strings[] = {
56 	"",
57 	"SMBIOS",
58 	"BIS Certificate",
59 	"POST BIOS ",
60 	"ESCD ",
61 	"CMOS",
62 	"NVRAM",
63 	"Option ROM",
64 	"Option ROM config",
65 	"",
66 	"Option ROM microcode ",
67 	"S-CRTM Version",
68 	"S-CRTM Contents ",
69 	"POST Contents ",
70 	"Table of Devices",
71 };
72 
73 /* returns pointer to start of pos. entry of tcg log */
74 static void *tpm_bios_measurements_start(struct seq_file *m, loff_t *pos)
75 {
76 	loff_t i;
77 	struct tpm_chip *chip = m->private;
78 	struct tpm_bios_log *log = &chip->log;
79 	void *addr = log->bios_event_log;
80 	void *limit = log->bios_event_log_end;
81 	struct tcpa_event *event;
82 	u32 converted_event_size;
83 	u32 converted_event_type;
84 
85 
86 	/* read over *pos measurements */
87 	for (i = 0; i < *pos; i++) {
88 		event = addr;
89 
90 		converted_event_size =
91 		    do_endian_conversion(event->event_size);
92 		converted_event_type =
93 		    do_endian_conversion(event->event_type);
94 
95 		if ((addr + sizeof(struct tcpa_event)) < limit) {
96 			if ((converted_event_type == 0) &&
97 			    (converted_event_size == 0))
98 				return NULL;
99 			addr += (sizeof(struct tcpa_event) +
100 				 converted_event_size);
101 		}
102 	}
103 
104 	/* now check if current entry is valid */
105 	if ((addr + sizeof(struct tcpa_event)) >= limit)
106 		return NULL;
107 
108 	event = addr;
109 
110 	converted_event_size = do_endian_conversion(event->event_size);
111 	converted_event_type = do_endian_conversion(event->event_type);
112 
113 	if (((converted_event_type == 0) && (converted_event_size == 0))
114 	    || ((addr + sizeof(struct tcpa_event) + converted_event_size)
115 		>= limit))
116 		return NULL;
117 
118 	return addr;
119 }
120 
121 static void *tpm_bios_measurements_next(struct seq_file *m, void *v,
122 					loff_t *pos)
123 {
124 	struct tcpa_event *event = v;
125 	struct tpm_chip *chip = m->private;
126 	struct tpm_bios_log *log = &chip->log;
127 	void *limit = log->bios_event_log_end;
128 	u32 converted_event_size;
129 	u32 converted_event_type;
130 
131 	converted_event_size = do_endian_conversion(event->event_size);
132 
133 	v += sizeof(struct tcpa_event) + converted_event_size;
134 
135 	/* now check if current entry is valid */
136 	if ((v + sizeof(struct tcpa_event)) >= limit)
137 		return NULL;
138 
139 	event = v;
140 
141 	converted_event_size = do_endian_conversion(event->event_size);
142 	converted_event_type = do_endian_conversion(event->event_type);
143 
144 	if (((converted_event_type == 0) && (converted_event_size == 0)) ||
145 	    ((v + sizeof(struct tcpa_event) + converted_event_size) >= limit))
146 		return NULL;
147 
148 	(*pos)++;
149 	return v;
150 }
151 
152 static void tpm_bios_measurements_stop(struct seq_file *m, void *v)
153 {
154 }
155 
156 static int get_event_name(char *dest, struct tcpa_event *event,
157 			unsigned char * event_entry)
158 {
159 	const char *name = "";
160 	/* 41 so there is room for 40 data and 1 nul */
161 	char data[41] = "";
162 	int i, n_len = 0, d_len = 0;
163 	struct tcpa_pc_event *pc_event;
164 
165 	switch (do_endian_conversion(event->event_type)) {
166 	case PREBOOT:
167 	case POST_CODE:
168 	case UNUSED:
169 	case NO_ACTION:
170 	case SCRTM_CONTENTS:
171 	case SCRTM_VERSION:
172 	case CPU_MICROCODE:
173 	case PLATFORM_CONFIG_FLAGS:
174 	case TABLE_OF_DEVICES:
175 	case COMPACT_HASH:
176 	case IPL:
177 	case IPL_PARTITION_DATA:
178 	case NONHOST_CODE:
179 	case NONHOST_CONFIG:
180 	case NONHOST_INFO:
181 		name = tcpa_event_type_strings[do_endian_conversion
182 						(event->event_type)];
183 		n_len = strlen(name);
184 		break;
185 	case SEPARATOR:
186 	case ACTION:
187 		if (MAX_TEXT_EVENT >
188 		    do_endian_conversion(event->event_size)) {
189 			name = event_entry;
190 			n_len = do_endian_conversion(event->event_size);
191 		}
192 		break;
193 	case EVENT_TAG:
194 		pc_event = (struct tcpa_pc_event *)event_entry;
195 
196 		/* ToDo Row data -> Base64 */
197 
198 		switch (do_endian_conversion(pc_event->event_id)) {
199 		case SMBIOS:
200 		case BIS_CERT:
201 		case CMOS:
202 		case NVRAM:
203 		case OPTION_ROM_EXEC:
204 		case OPTION_ROM_CONFIG:
205 		case S_CRTM_VERSION:
206 			name = tcpa_pc_event_id_strings[do_endian_conversion
207 							(pc_event->event_id)];
208 			n_len = strlen(name);
209 			break;
210 		/* hash data */
211 		case POST_BIOS_ROM:
212 		case ESCD:
213 		case OPTION_ROM_MICROCODE:
214 		case S_CRTM_CONTENTS:
215 		case POST_CONTENTS:
216 			name = tcpa_pc_event_id_strings[do_endian_conversion
217 							(pc_event->event_id)];
218 			n_len = strlen(name);
219 			for (i = 0; i < 20; i++)
220 				d_len += sprintf(&data[2*i], "%02x",
221 						pc_event->event_data[i]);
222 			break;
223 		default:
224 			break;
225 		}
226 	default:
227 		break;
228 	}
229 
230 	return snprintf(dest, MAX_TEXT_EVENT, "[%.*s%.*s]",
231 			n_len, name, d_len, data);
232 
233 }
234 
235 static int tpm_binary_bios_measurements_show(struct seq_file *m, void *v)
236 {
237 	struct tcpa_event *event = v;
238 	struct tcpa_event temp_event;
239 	char *temp_ptr;
240 	int i;
241 
242 	memcpy(&temp_event, event, sizeof(struct tcpa_event));
243 
244 	/* convert raw integers for endianness */
245 	temp_event.pcr_index = do_endian_conversion(event->pcr_index);
246 	temp_event.event_type = do_endian_conversion(event->event_type);
247 	temp_event.event_size = do_endian_conversion(event->event_size);
248 
249 	temp_ptr = (char *) &temp_event;
250 
251 	for (i = 0; i < (sizeof(struct tcpa_event) - 1) ; i++)
252 		seq_putc(m, temp_ptr[i]);
253 
254 	temp_ptr = (char *) v;
255 
256 	for (i = (sizeof(struct tcpa_event) - 1);
257 	     i < (sizeof(struct tcpa_event) + temp_event.event_size); i++)
258 		seq_putc(m, temp_ptr[i]);
259 
260 	return 0;
261 
262 }
263 
264 static int tpm_bios_measurements_release(struct inode *inode,
265 					 struct file *file)
266 {
267 	struct seq_file *seq = (struct seq_file *)file->private_data;
268 	struct tpm_chip *chip = (struct tpm_chip *)seq->private;
269 
270 	put_device(&chip->dev);
271 
272 	return seq_release(inode, file);
273 }
274 
275 static int tpm_ascii_bios_measurements_show(struct seq_file *m, void *v)
276 {
277 	int len = 0;
278 	char *eventname;
279 	struct tcpa_event *event = v;
280 	unsigned char *event_entry =
281 	    (unsigned char *)(v + sizeof(struct tcpa_event));
282 
283 	eventname = kmalloc(MAX_TEXT_EVENT, GFP_KERNEL);
284 	if (!eventname) {
285 		printk(KERN_ERR "%s: ERROR - No Memory for event name\n ",
286 		       __func__);
287 		return -EFAULT;
288 	}
289 
290 	/* 1st: PCR */
291 	seq_printf(m, "%2d ", do_endian_conversion(event->pcr_index));
292 
293 	/* 2nd: SHA1 */
294 	seq_printf(m, "%20phN", event->pcr_value);
295 
296 	/* 3rd: event type identifier */
297 	seq_printf(m, " %02x", do_endian_conversion(event->event_type));
298 
299 	len += get_event_name(eventname, event, event_entry);
300 
301 	/* 4th: eventname <= max + \'0' delimiter */
302 	seq_printf(m, " %s\n", eventname);
303 
304 	kfree(eventname);
305 	return 0;
306 }
307 
308 static const struct seq_operations tpm_ascii_b_measurements_seqops = {
309 	.start = tpm_bios_measurements_start,
310 	.next = tpm_bios_measurements_next,
311 	.stop = tpm_bios_measurements_stop,
312 	.show = tpm_ascii_bios_measurements_show,
313 };
314 
315 static const struct seq_operations tpm_binary_b_measurements_seqops = {
316 	.start = tpm_bios_measurements_start,
317 	.next = tpm_bios_measurements_next,
318 	.stop = tpm_bios_measurements_stop,
319 	.show = tpm_binary_bios_measurements_show,
320 };
321 
322 static int tpm_bios_measurements_open(struct inode *inode,
323 					    struct file *file)
324 {
325 	int err;
326 	struct seq_file *seq;
327 	struct tpm_chip_seqops *chip_seqops;
328 	const struct seq_operations *seqops;
329 	struct tpm_chip *chip;
330 
331 	inode_lock(inode);
332 	if (!inode->i_private) {
333 		inode_unlock(inode);
334 		return -ENODEV;
335 	}
336 	chip_seqops = (struct tpm_chip_seqops *)inode->i_private;
337 	seqops = chip_seqops->seqops;
338 	chip = chip_seqops->chip;
339 	get_device(&chip->dev);
340 	inode_unlock(inode);
341 
342 	/* now register seq file */
343 	err = seq_open(file, seqops);
344 	if (!err) {
345 		seq = file->private_data;
346 		seq->private = chip;
347 	}
348 
349 	return err;
350 }
351 
352 static const struct file_operations tpm_bios_measurements_ops = {
353 	.owner = THIS_MODULE,
354 	.open = tpm_bios_measurements_open,
355 	.read = seq_read,
356 	.llseek = seq_lseek,
357 	.release = tpm_bios_measurements_release,
358 };
359 
360 static int tpm_read_log(struct tpm_chip *chip)
361 {
362 	int rc;
363 
364 	if (chip->log.bios_event_log != NULL) {
365 		dev_dbg(&chip->dev,
366 			"%s: ERROR - event log already initialized\n",
367 			__func__);
368 		return -EFAULT;
369 	}
370 
371 	rc = tpm_read_log_acpi(chip);
372 	if (rc != -ENODEV)
373 		return rc;
374 
375 	rc = tpm_read_log_efi(chip);
376 	if (rc != -ENODEV)
377 		return rc;
378 
379 	return tpm_read_log_of(chip);
380 }
381 
382 /*
383  * tpm_bios_log_setup() - Read the event log from the firmware
384  * @chip: TPM chip to use.
385  *
386  * If an event log is found then the securityfs files are setup to
387  * export it to userspace, otherwise nothing is done.
388  *
389  * Returns -ENODEV if the firmware has no event log or securityfs is not
390  * supported.
391  */
392 int tpm_bios_log_setup(struct tpm_chip *chip)
393 {
394 	const char *name = dev_name(&chip->dev);
395 	unsigned int cnt;
396 	int log_version;
397 	int rc = 0;
398 
399 	rc = tpm_read_log(chip);
400 	if (rc < 0)
401 		return rc;
402 	log_version = rc;
403 
404 	cnt = 0;
405 	chip->bios_dir[cnt] = securityfs_create_dir(name, NULL);
406 	/* NOTE: securityfs_create_dir can return ENODEV if securityfs is
407 	 * compiled out. The caller should ignore the ENODEV return code.
408 	 */
409 	if (IS_ERR(chip->bios_dir[cnt]))
410 		goto err;
411 	cnt++;
412 
413 	chip->bin_log_seqops.chip = chip;
414 	if (log_version == EFI_TCG2_EVENT_LOG_FORMAT_TCG_2)
415 		chip->bin_log_seqops.seqops =
416 			&tpm2_binary_b_measurements_seqops;
417 	else
418 		chip->bin_log_seqops.seqops =
419 			&tpm_binary_b_measurements_seqops;
420 
421 
422 	chip->bios_dir[cnt] =
423 	    securityfs_create_file("binary_bios_measurements",
424 				   0440, chip->bios_dir[0],
425 				   (void *)&chip->bin_log_seqops,
426 				   &tpm_bios_measurements_ops);
427 	if (IS_ERR(chip->bios_dir[cnt]))
428 		goto err;
429 	cnt++;
430 
431 	if (!(chip->flags & TPM_CHIP_FLAG_TPM2)) {
432 
433 		chip->ascii_log_seqops.chip = chip;
434 		chip->ascii_log_seqops.seqops =
435 			&tpm_ascii_b_measurements_seqops;
436 
437 		chip->bios_dir[cnt] =
438 			securityfs_create_file("ascii_bios_measurements",
439 					       0440, chip->bios_dir[0],
440 					       (void *)&chip->ascii_log_seqops,
441 					       &tpm_bios_measurements_ops);
442 		if (IS_ERR(chip->bios_dir[cnt]))
443 			goto err;
444 		cnt++;
445 	}
446 
447 	return 0;
448 
449 err:
450 	rc = PTR_ERR(chip->bios_dir[cnt]);
451 	chip->bios_dir[cnt] = NULL;
452 	tpm_bios_log_teardown(chip);
453 	return rc;
454 }
455 
456 void tpm_bios_log_teardown(struct tpm_chip *chip)
457 {
458 	int i;
459 	struct inode *inode;
460 
461 	/* securityfs_remove currently doesn't take care of handling sync
462 	 * between removal and opening of pseudo files. To handle this, a
463 	 * workaround is added by making i_private = NULL here during removal
464 	 * and to check it during open(), both within inode_lock()/unlock().
465 	 * This design ensures that open() either safely gets kref or fails.
466 	 */
467 	for (i = (TPM_NUM_EVENT_LOG_FILES - 1); i >= 0; i--) {
468 		if (chip->bios_dir[i]) {
469 			inode = d_inode(chip->bios_dir[i]);
470 			inode_lock(inode);
471 			inode->i_private = NULL;
472 			inode_unlock(inode);
473 			securityfs_remove(chip->bios_dir[i]);
474 		}
475 	}
476 }
477