Merge branch 'next-tpm' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris...
[linux-2.6-block.git] / drivers / char / tpm / tpm1_eventlog.c
CommitLineData
55a82ab3 1/*
e5dcd87f 2 * Copyright (C) 2005, 2012 IBM Corporation
55a82ab3
KJH
3 *
4 * Authors:
e5dcd87f 5 * Kent Yoder <key@linux.vnet.ibm.com>
55a82ab3
KJH
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>
2528a646 10 * Nayna Jain <nayna@linux.vnet.ibm.com>
55a82ab3 11 *
8e81cc13
KY
12 * Maintained by: <tpmdd-devel@lists.sourceforge.net>
13 *
748935ee 14 * Access to the event log created by a system's firmware / BIOS
55a82ab3
KJH
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>
58cc1e4f 24#include <linux/efi.h>
55a82ab3
KJH
25#include <linux/fs.h>
26#include <linux/security.h>
27#include <linux/module.h>
5a0e3ad6 28#include <linux/slab.h>
fd3ec366 29#include <linux/tpm_eventlog.h>
55a82ab3 30
e5dcd87f 31#include "tpm.h"
55a82ab3 32
55a82ab3
KJH
33
34static 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
55a82ab3 55static const char* tcpa_pc_event_id_strings[] = {
de66a695 56 "",
55a82ab3
KJH
57 "SMBIOS",
58 "BIS Certificate",
59 "POST BIOS ",
60 "ESCD ",
61 "CMOS",
62 "NVRAM",
63 "Option ROM",
64 "Option ROM config",
de66a695
SM
65 "",
66 "Option ROM microcode ",
55a82ab3 67 "S-CRTM Version",
de66a695
SM
68 "S-CRTM Contents ",
69 "POST Contents ",
70 "Table of Devices",
55a82ab3
KJH
71};
72
55a82ab3
KJH
73/* returns pointer to start of pos. entry of tcg log */
74static void *tpm_bios_measurements_start(struct seq_file *m, loff_t *pos)
75{
76 loff_t i;
748935ee
NJ
77 struct tpm_chip *chip = m->private;
78 struct tpm_bios_log *log = &chip->log;
d09cf7d7
KJH
79 void *addr = log->bios_event_log;
80 void *limit = log->bios_event_log_end;
55a82ab3 81 struct tcpa_event *event;
0cc698af
HCVL
82 u32 converted_event_size;
83 u32 converted_event_type;
84
55a82ab3
KJH
85
86 /* read over *pos measurements */
87 for (i = 0; i < *pos; i++) {
88 event = addr;
89
0cc698af
HCVL
90 converted_event_size =
91 do_endian_conversion(event->event_size);
92 converted_event_type =
93 do_endian_conversion(event->event_type);
94
d09cf7d7 95 if ((addr + sizeof(struct tcpa_event)) < limit) {
0cc698af
HCVL
96 if ((converted_event_type == 0) &&
97 (converted_event_size == 0))
55a82ab3 98 return NULL;
0cc698af
HCVL
99 addr += (sizeof(struct tcpa_event) +
100 converted_event_size);
55a82ab3
KJH
101 }
102 }
103
104 /* now check if current entry is valid */
d09cf7d7 105 if ((addr + sizeof(struct tcpa_event)) >= limit)
55a82ab3
KJH
106 return NULL;
107
108 event = addr;
109
0cc698af
HCVL
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))
55a82ab3
KJH
116 return NULL;
117
118 return addr;
119}
120
121static void *tpm_bios_measurements_next(struct seq_file *m, void *v,
122 loff_t *pos)
123{
124 struct tcpa_event *event = v;
748935ee
NJ
125 struct tpm_chip *chip = m->private;
126 struct tpm_bios_log *log = &chip->log;
d09cf7d7 127 void *limit = log->bios_event_log_end;
0cc698af
HCVL
128 u32 converted_event_size;
129 u32 converted_event_type;
55a82ab3 130
0cc698af
HCVL
131 converted_event_size = do_endian_conversion(event->event_size);
132
133 v += sizeof(struct tcpa_event) + converted_event_size;
55a82ab3
KJH
134
135 /* now check if current entry is valid */
d09cf7d7 136 if ((v + sizeof(struct tcpa_event)) >= limit)
55a82ab3
KJH
137 return NULL;
138
139 event = v;
140
0cc698af
HCVL
141 converted_event_size = do_endian_conversion(event->event_size);
142 converted_event_type = do_endian_conversion(event->event_type);
55a82ab3 143
0cc698af
HCVL
144 if (((converted_event_type == 0) && (converted_event_size == 0)) ||
145 ((v + sizeof(struct tcpa_event) + converted_event_size) >= limit))
55a82ab3
KJH
146 return NULL;
147
148 (*pos)++;
149 return v;
150}
151
152static void tpm_bios_measurements_stop(struct seq_file *m, void *v)
153{
154}
155
156static int get_event_name(char *dest, struct tcpa_event *event,
157 unsigned char * event_entry)
158{
159 const char *name = "";
fbaa5869
EP
160 /* 41 so there is room for 40 data and 1 nul */
161 char data[41] = "";
55a82ab3 162 int i, n_len = 0, d_len = 0;
de66a695 163 struct tcpa_pc_event *pc_event;
55a82ab3 164
0cc698af 165 switch (do_endian_conversion(event->event_type)) {
55a82ab3
KJH
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:
0cc698af
HCVL
181 name = tcpa_event_type_strings[do_endian_conversion
182 (event->event_type)];
55a82ab3
KJH
183 n_len = strlen(name);
184 break;
185 case SEPARATOR:
186 case ACTION:
0cc698af
HCVL
187 if (MAX_TEXT_EVENT >
188 do_endian_conversion(event->event_size)) {
55a82ab3 189 name = event_entry;
0cc698af 190 n_len = do_endian_conversion(event->event_size);
55a82ab3
KJH
191 }
192 break;
193 case EVENT_TAG:
de66a695 194 pc_event = (struct tcpa_pc_event *)event_entry;
55a82ab3
KJH
195
196 /* ToDo Row data -> Base64 */
197
0cc698af 198 switch (do_endian_conversion(pc_event->event_id)) {
55a82ab3
KJH
199 case SMBIOS:
200 case BIS_CERT:
201 case CMOS:
202 case NVRAM:
203 case OPTION_ROM_EXEC:
204 case OPTION_ROM_CONFIG:
55a82ab3 205 case S_CRTM_VERSION:
0cc698af
HCVL
206 name = tcpa_pc_event_id_strings[do_endian_conversion
207 (pc_event->event_id)];
55a82ab3
KJH
208 n_len = strlen(name);
209 break;
de66a695 210 /* hash data */
55a82ab3
KJH
211 case POST_BIOS_ROM:
212 case ESCD:
de66a695
SM
213 case OPTION_ROM_MICROCODE:
214 case S_CRTM_CONTENTS:
215 case POST_CONTENTS:
0cc698af
HCVL
216 name = tcpa_pc_event_id_strings[do_endian_conversion
217 (pc_event->event_id)];
55a82ab3
KJH
218 n_len = strlen(name);
219 for (i = 0; i < 20; i++)
de66a695
SM
220 d_len += sprintf(&data[2*i], "%02x",
221 pc_event->event_data[i]);
55a82ab3
KJH
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
235static int tpm_binary_bios_measurements_show(struct seq_file *m, void *v)
236{
44d7aff0 237 struct tcpa_event *event = v;
0cc698af 238 struct tcpa_event temp_event;
186d124f 239 char *temp_ptr;
44d7aff0 240 int i;
55a82ab3 241
0cc698af
HCVL
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
186d124f 249 temp_ptr = (char *) &temp_event;
0cc698af 250
186d124f
HH
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]);
55a82ab3 259
55a82ab3 260 return 0;
0cc698af 261
55a82ab3
KJH
262}
263
264static int tpm_bios_measurements_release(struct inode *inode,
265 struct file *file)
266{
748935ee
NJ
267 struct seq_file *seq = (struct seq_file *)file->private_data;
268 struct tpm_chip *chip = (struct tpm_chip *)seq->private;
d09cf7d7 269
748935ee 270 put_device(&chip->dev);
d09cf7d7 271
55a82ab3
KJH
272 return seq_release(inode, file);
273}
274
275static int tpm_ascii_bios_measurements_show(struct seq_file *m, void *v)
276{
277 int len = 0;
55a82ab3
KJH
278 char *eventname;
279 struct tcpa_event *event = v;
280 unsigned char *event_entry =
0cc698af 281 (unsigned char *)(v + sizeof(struct tcpa_event));
55a82ab3
KJH
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
0cc698af
HCVL
290 /* 1st: PCR */
291 seq_printf(m, "%2d ", do_endian_conversion(event->pcr_index));
55a82ab3
KJH
292
293 /* 2nd: SHA1 */
a3d64df8 294 seq_printf(m, "%20phN", event->pcr_value);
55a82ab3
KJH
295
296 /* 3rd: event type identifier */
0cc698af 297 seq_printf(m, " %02x", do_endian_conversion(event->event_type));
55a82ab3
KJH
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
59e89f3a 304 kfree(eventname);
55a82ab3
KJH
305 return 0;
306}
307
2528a646 308static const struct seq_operations tpm_ascii_b_measurements_seqops = {
55a82ab3
KJH
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
2528a646 315static const struct seq_operations tpm_binary_b_measurements_seqops = {
55a82ab3
KJH
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
2528a646 322static int tpm_bios_measurements_open(struct inode *inode,
55a82ab3
KJH
323 struct file *file)
324{
325 int err;
d09cf7d7 326 struct seq_file *seq;
748935ee
NJ
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);
55a82ab3
KJH
341
342 /* now register seq file */
2528a646 343 err = seq_open(file, seqops);
d09cf7d7
KJH
344 if (!err) {
345 seq = file->private_data;
748935ee 346 seq->private = chip;
d09cf7d7 347 }
178554ae 348
d09cf7d7 349 return err;
55a82ab3
KJH
350}
351
2528a646 352static const struct file_operations tpm_bios_measurements_ops = {
f40e68ef 353 .owner = THIS_MODULE,
2528a646 354 .open = tpm_bios_measurements_open,
55a82ab3
KJH
355 .read = seq_read,
356 .llseek = seq_lseek,
357 .release = tpm_bios_measurements_release,
358};
359
02ae1382
NJ
360static 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);
0cf577a0 372 if (rc != -ENODEV)
02ae1382
NJ
373 return rc;
374
58cc1e4f
TW
375 rc = tpm_read_log_efi(chip);
376 if (rc != -ENODEV)
377 return rc;
378
0cf577a0 379 return tpm_read_log_of(chip);
02ae1382
NJ
380}
381
0cf577a0
JG
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 *
9430066a
JG
389 * Returns -ENODEV if the firmware has no event log or securityfs is not
390 * supported.
0cf577a0 391 */
cd9b7631 392int tpm_bios_log_setup(struct tpm_chip *chip)
ca4a031f 393{
cd9b7631
JS
394 const char *name = dev_name(&chip->dev);
395 unsigned int cnt;
58cc1e4f 396 int log_version;
748935ee 397 int rc = 0;
cd9b7631 398
02ae1382 399 rc = tpm_read_log(chip);
58cc1e4f 400 if (rc < 0)
0cf577a0 401 return rc;
58cc1e4f 402 log_version = rc;
748935ee 403
cd9b7631
JS
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
748935ee 413 chip->bin_log_seqops.chip = chip;
58cc1e4f 414 if (log_version == EFI_TCG2_EVENT_LOG_FORMAT_TCG_2)
4d23cc32
NJ
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
748935ee 421
cd9b7631 422 chip->bios_dir[cnt] =
55a82ab3 423 securityfs_create_file("binary_bios_measurements",
cd9b7631 424 0440, chip->bios_dir[0],
748935ee 425 (void *)&chip->bin_log_seqops,
2528a646 426 &tpm_bios_measurements_ops);
cd9b7631
JS
427 if (IS_ERR(chip->bios_dir[cnt]))
428 goto err;
429 cnt++;
55a82ab3 430
4d23cc32 431 if (!(chip->flags & TPM_CHIP_FLAG_TPM2)) {
748935ee 432
4d23cc32
NJ
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 }
55a82ab3 446
cd9b7631 447 return 0;
55a82ab3 448
cd9b7631 449err:
9430066a 450 rc = PTR_ERR(chip->bios_dir[cnt]);
cd9b7631
JS
451 chip->bios_dir[cnt] = NULL;
452 tpm_bios_log_teardown(chip);
9430066a 453 return rc;
55a82ab3 454}
55a82ab3 455
cd9b7631 456void tpm_bios_log_teardown(struct tpm_chip *chip)
55a82ab3
KJH
457{
458 int i;
748935ee 459 struct inode *inode;
55a82ab3 460
748935ee
NJ
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--) {
005451d4
SB
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 }
748935ee 475 }
55a82ab3 476}