tpm1.c (0bfb23746052168620c5b52f49d8a47c3bb022fa) tpm1.c (9b01b53566298812cb38a2e72d034ac8131c20d6)
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>

--- 57 unchanged lines hidden (view full) ---

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 */
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>

--- 57 unchanged lines hidden (view full) ---

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 */
74static void *tpm_bios_measurements_start(struct seq_file *m, loff_t *pos)
74static void *tpm1_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;

--- 30 unchanged lines hidden (view full) ---

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
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;

--- 30 unchanged lines hidden (view full) ---

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
121static void *tpm_bios_measurements_next(struct seq_file *m, void *v,
121static void *tpm1_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;

--- 14 unchanged lines hidden (view full) ---

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
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;

--- 14 unchanged lines hidden (view full) ---

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
152static void tpm_bios_measurements_stop(struct seq_file *m, void *v)
152static void tpm1_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 = "";
160 /* 41 so there is room for 40 data and 1 nul */

--- 66 unchanged lines hidden (view full) ---

227 break;
228 }
229
230 return snprintf(dest, MAX_TEXT_EVENT, "[%.*s%.*s]",
231 n_len, name, d_len, data);
232
233}
234
153{
154}
155
156static 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 */

--- 66 unchanged lines hidden (view full) ---

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)
235static int tpm1_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

--- 12 unchanged lines hidden (view full) ---

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
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

--- 12 unchanged lines hidden (view full) ---

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
264static int tpm_bios_measurements_release(struct inode *inode,
265 struct file *file)
264static int tpm1_ascii_bios_measurements_show(struct seq_file *m, void *v)
266{
265{
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
275static 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) {

--- 15 unchanged lines hidden (view full) ---

300
301 /* 4th: eventname <= max + \'0' delimiter */
302 seq_printf(m, " %s\n", eventname);
303
304 kfree(eventname);
305 return 0;
306}
307
266 int len = 0;
267 char *eventname;
268 struct tcpa_event *event = v;
269 unsigned char *event_entry =
270 (unsigned char *)(v + sizeof(struct tcpa_event));
271
272 eventname = kmalloc(MAX_TEXT_EVENT, GFP_KERNEL);
273 if (!eventname) {

--- 15 unchanged lines hidden (view full) ---

289
290 /* 4th: eventname <= max + \'0' delimiter */
291 seq_printf(m, " %s\n", eventname);
292
293 kfree(eventname);
294 return 0;
295}
296
308static 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,
297const struct seq_operations tpm1_ascii_b_measurements_seqops = {
298 .start = tpm1_bios_measurements_start,
299 .next = tpm1_bios_measurements_next,
300 .stop = tpm1_bios_measurements_stop,
301 .show = tpm1_ascii_bios_measurements_show,
313};
314
302};
303
315static 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,
304const struct seq_operations tpm1_binary_b_measurements_seqops = {
305 .start = tpm1_bios_measurements_start,
306 .next = tpm1_bios_measurements_next,
307 .stop = tpm1_bios_measurements_stop,
308 .show = tpm1_binary_bios_measurements_show,
320};
309};
321
322static 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
352static 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
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);
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 */
392int 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
449err:
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
456void 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}