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