diff options
| -rw-r--r-- | drivers/char/tpm/Makefile | 1 | ||||
| -rw-r--r-- | drivers/char/tpm/tpm.c | 1 | ||||
| -rw-r--r-- | drivers/char/tpm/tpm_acpi.c | 104 | ||||
| -rw-r--r-- | drivers/char/tpm/tpm_eventlog.c (renamed from drivers/char/tpm/tpm_bios.c) | 147 | ||||
| -rw-r--r-- | drivers/char/tpm/tpm_eventlog.h | 71 |
5 files changed, 182 insertions, 142 deletions
diff --git a/drivers/char/tpm/Makefile b/drivers/char/tpm/Makefile index a9c3afc92dbc..beac52f61a82 100644 --- a/drivers/char/tpm/Makefile +++ b/drivers/char/tpm/Makefile | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | obj-$(CONFIG_TCG_TPM) += tpm.o | 4 | obj-$(CONFIG_TCG_TPM) += tpm.o |
| 5 | ifdef CONFIG_ACPI | 5 | ifdef CONFIG_ACPI |
| 6 | obj-$(CONFIG_TCG_TPM) += tpm_bios.o | 6 | obj-$(CONFIG_TCG_TPM) += tpm_bios.o |
| 7 | tpm_bios-objs += tpm_eventlog.o tpm_acpi.o | ||
| 7 | endif | 8 | endif |
| 8 | obj-$(CONFIG_TCG_TIS) += tpm_tis.o | 9 | obj-$(CONFIG_TCG_TIS) += tpm_tis.o |
| 9 | obj-$(CONFIG_TCG_TIS_I2C_INFINEON) += tpm_i2c_infineon.o | 10 | obj-$(CONFIG_TCG_TIS_I2C_INFINEON) += tpm_i2c_infineon.o |
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index 817f0ee202b6..677c6e26593f 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c | |||
| @@ -30,6 +30,7 @@ | |||
| 30 | #include <linux/freezer.h> | 30 | #include <linux/freezer.h> |
| 31 | 31 | ||
| 32 | #include "tpm.h" | 32 | #include "tpm.h" |
| 33 | #include "tpm_eventlog.h" | ||
| 33 | 34 | ||
| 34 | enum tpm_const { | 35 | enum tpm_const { |
| 35 | TPM_MINOR = 224, /* officially assigned */ | 36 | TPM_MINOR = 224, /* officially assigned */ |
diff --git a/drivers/char/tpm/tpm_acpi.c b/drivers/char/tpm/tpm_acpi.c new file mode 100644 index 000000000000..a1bb5a182df9 --- /dev/null +++ b/drivers/char/tpm/tpm_acpi.c | |||
| @@ -0,0 +1,104 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2005 IBM Corporation | ||
| 3 | * | ||
| 4 | * Authors: | ||
| 5 | * Seiji Munetoh <munetoh@jp.ibm.com> | ||
| 6 | * Stefan Berger <stefanb@us.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 | * Access to the eventlog extended by the TCG BIOS of PC platform | ||
| 13 | * | ||
| 14 | * This program is free software; you can redistribute it and/or | ||
| 15 | * modify it under the terms of the GNU General Public License | ||
| 16 | * as published by the Free Software Foundation; either version | ||
| 17 | * 2 of the License, or (at your option) any later version. | ||
| 18 | * | ||
| 19 | */ | ||
| 20 | |||
| 21 | #include <linux/seq_file.h> | ||
| 22 | #include <linux/fs.h> | ||
| 23 | #include <linux/security.h> | ||
| 24 | #include <linux/module.h> | ||
| 25 | #include <linux/slab.h> | ||
| 26 | #include <acpi/acpi.h> | ||
| 27 | |||
| 28 | #include "tpm.h" | ||
| 29 | #include "tpm_eventlog.h" | ||
| 30 | |||
| 31 | struct acpi_tcpa { | ||
| 32 | struct acpi_table_header hdr; | ||
| 33 | u16 platform_class; | ||
| 34 | union { | ||
| 35 | struct client_hdr { | ||
| 36 | u32 log_max_len __attribute__ ((packed)); | ||
| 37 | u64 log_start_addr __attribute__ ((packed)); | ||
| 38 | } client; | ||
| 39 | struct server_hdr { | ||
| 40 | u16 reserved; | ||
| 41 | u64 log_max_len __attribute__ ((packed)); | ||
| 42 | u64 log_start_addr __attribute__ ((packed)); | ||
| 43 | } server; | ||
| 44 | }; | ||
| 45 | }; | ||
| 46 | |||
| 47 | /* read binary bios log */ | ||
| 48 | int read_log(struct tpm_bios_log *log) | ||
| 49 | { | ||
| 50 | struct acpi_tcpa *buff; | ||
| 51 | acpi_status status; | ||
| 52 | struct acpi_table_header *virt; | ||
| 53 | u64 len, start; | ||
| 54 | |||
| 55 | if (log->bios_event_log != NULL) { | ||
| 56 | printk(KERN_ERR | ||
| 57 | "%s: ERROR - Eventlog already initialized\n", | ||
| 58 | __func__); | ||
| 59 | return -EFAULT; | ||
| 60 | } | ||
| 61 | |||
| 62 | /* Find TCPA entry in RSDT (ACPI_LOGICAL_ADDRESSING) */ | ||
| 63 | status = acpi_get_table(ACPI_SIG_TCPA, 1, | ||
| 64 | (struct acpi_table_header **)&buff); | ||
| 65 | |||
| 66 | if (ACPI_FAILURE(status)) { | ||
| 67 | printk(KERN_ERR "%s: ERROR - Could not get TCPA table\n", | ||
| 68 | __func__); | ||
| 69 | return -EIO; | ||
| 70 | } | ||
| 71 | |||
| 72 | switch(buff->platform_class) { | ||
| 73 | case BIOS_SERVER: | ||
| 74 | len = buff->server.log_max_len; | ||
| 75 | start = buff->server.log_start_addr; | ||
| 76 | break; | ||
| 77 | case BIOS_CLIENT: | ||
| 78 | default: | ||
| 79 | len = buff->client.log_max_len; | ||
| 80 | start = buff->client.log_start_addr; | ||
| 81 | break; | ||
| 82 | } | ||
| 83 | if (!len) { | ||
| 84 | printk(KERN_ERR "%s: ERROR - TCPA log area empty\n", __func__); | ||
| 85 | return -EIO; | ||
| 86 | } | ||
| 87 | |||
| 88 | /* malloc EventLog space */ | ||
| 89 | log->bios_event_log = kmalloc(len, GFP_KERNEL); | ||
| 90 | if (!log->bios_event_log) { | ||
| 91 | printk("%s: ERROR - Not enough Memory for BIOS measurements\n", | ||
| 92 | __func__); | ||
| 93 | return -ENOMEM; | ||
| 94 | } | ||
| 95 | |||
| 96 | log->bios_event_log_end = log->bios_event_log + len; | ||
| 97 | |||
| 98 | virt = acpi_os_map_memory(start, len); | ||
| 99 | |||
| 100 | memcpy(log->bios_event_log, virt, len); | ||
| 101 | |||
| 102 | acpi_os_unmap_memory(virt, len); | ||
| 103 | return 0; | ||
| 104 | } | ||
diff --git a/drivers/char/tpm/tpm_bios.c b/drivers/char/tpm/tpm_eventlog.c index 0636520fa9bf..84ddc557b8f8 100644 --- a/drivers/char/tpm/tpm_bios.c +++ b/drivers/char/tpm/tpm_eventlog.c | |||
| @@ -1,7 +1,8 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (C) 2005 IBM Corporation | 2 | * Copyright (C) 2005, 2012 IBM Corporation |
| 3 | * | 3 | * |
| 4 | * Authors: | 4 | * Authors: |
| 5 | * Kent Yoder <key@linux.vnet.ibm.com> | ||
| 5 | * Seiji Munetoh <munetoh@jp.ibm.com> | 6 | * Seiji Munetoh <munetoh@jp.ibm.com> |
| 6 | * Stefan Berger <stefanb@us.ibm.com> | 7 | * Stefan Berger <stefanb@us.ibm.com> |
| 7 | * Reiner Sailer <sailer@watson.ibm.com> | 8 | * Reiner Sailer <sailer@watson.ibm.com> |
| @@ -9,7 +10,7 @@ | |||
| 9 | * | 10 | * |
| 10 | * Maintained by: <tpmdd-devel@lists.sourceforge.net> | 11 | * Maintained by: <tpmdd-devel@lists.sourceforge.net> |
| 11 | * | 12 | * |
| 12 | * Access to the eventlog extended by the TCG BIOS of PC platform | 13 | * Access to the eventlog created by a system's firmware / BIOS |
| 13 | * | 14 | * |
| 14 | * This program is free software; you can redistribute it and/or | 15 | * This program is free software; you can redistribute it and/or |
| 15 | * modify it under the terms of the GNU General Public License | 16 | * modify it under the terms of the GNU General Public License |
| @@ -23,67 +24,10 @@ | |||
| 23 | #include <linux/security.h> | 24 | #include <linux/security.h> |
| 24 | #include <linux/module.h> | 25 | #include <linux/module.h> |
| 25 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
| 26 | #include <acpi/acpi.h> | ||
| 27 | #include "tpm.h" | ||
| 28 | |||
| 29 | #define TCG_EVENT_NAME_LEN_MAX 255 | ||
| 30 | #define MAX_TEXT_EVENT 1000 /* Max event string length */ | ||
| 31 | #define ACPI_TCPA_SIG "TCPA" /* 0x41504354 /'TCPA' */ | ||
| 32 | |||
| 33 | enum bios_platform_class { | ||
| 34 | BIOS_CLIENT = 0x00, | ||
| 35 | BIOS_SERVER = 0x01, | ||
| 36 | }; | ||
| 37 | |||
| 38 | struct tpm_bios_log { | ||
| 39 | void *bios_event_log; | ||
| 40 | void *bios_event_log_end; | ||
| 41 | }; | ||
| 42 | |||
| 43 | struct acpi_tcpa { | ||
| 44 | struct acpi_table_header hdr; | ||
| 45 | u16 platform_class; | ||
| 46 | union { | ||
| 47 | struct client_hdr { | ||
| 48 | u32 log_max_len __attribute__ ((packed)); | ||
| 49 | u64 log_start_addr __attribute__ ((packed)); | ||
| 50 | } client; | ||
| 51 | struct server_hdr { | ||
| 52 | u16 reserved; | ||
| 53 | u64 log_max_len __attribute__ ((packed)); | ||
| 54 | u64 log_start_addr __attribute__ ((packed)); | ||
| 55 | } server; | ||
| 56 | }; | ||
| 57 | }; | ||
| 58 | 27 | ||
| 59 | struct tcpa_event { | 28 | #include "tpm.h" |
| 60 | u32 pcr_index; | 29 | #include "tpm_eventlog.h" |
| 61 | u32 event_type; | ||
| 62 | u8 pcr_value[20]; /* SHA1 */ | ||
| 63 | u32 event_size; | ||
| 64 | u8 event_data[0]; | ||
| 65 | }; | ||
| 66 | 30 | ||
| 67 | enum tcpa_event_types { | ||
| 68 | PREBOOT = 0, | ||
| 69 | POST_CODE, | ||
| 70 | UNUSED, | ||
| 71 | NO_ACTION, | ||
| 72 | SEPARATOR, | ||
| 73 | ACTION, | ||
| 74 | EVENT_TAG, | ||
| 75 | SCRTM_CONTENTS, | ||
| 76 | SCRTM_VERSION, | ||
| 77 | CPU_MICROCODE, | ||
| 78 | PLATFORM_CONFIG_FLAGS, | ||
| 79 | TABLE_OF_DEVICES, | ||
| 80 | COMPACT_HASH, | ||
| 81 | IPL, | ||
| 82 | IPL_PARTITION_DATA, | ||
| 83 | NONHOST_CODE, | ||
| 84 | NONHOST_CONFIG, | ||
| 85 | NONHOST_INFO, | ||
| 86 | }; | ||
| 87 | 31 | ||
| 88 | static const char* tcpa_event_type_strings[] = { | 32 | static const char* tcpa_event_type_strings[] = { |
| 89 | "PREBOOT", | 33 | "PREBOOT", |
| @@ -106,28 +50,6 @@ static const char* tcpa_event_type_strings[] = { | |||
| 106 | "Non-Host Info" | 50 | "Non-Host Info" |
| 107 | }; | 51 | }; |
| 108 | 52 | ||
| 109 | struct tcpa_pc_event { | ||
| 110 | u32 event_id; | ||
| 111 | u32 event_size; | ||
| 112 | u8 event_data[0]; | ||
| 113 | }; | ||
| 114 | |||
| 115 | enum tcpa_pc_event_ids { | ||
| 116 | SMBIOS = 1, | ||
| 117 | BIS_CERT, | ||
| 118 | POST_BIOS_ROM, | ||
| 119 | ESCD, | ||
| 120 | CMOS, | ||
| 121 | NVRAM, | ||
| 122 | OPTION_ROM_EXEC, | ||
| 123 | OPTION_ROM_CONFIG, | ||
| 124 | OPTION_ROM_MICROCODE = 10, | ||
| 125 | S_CRTM_VERSION, | ||
| 126 | S_CRTM_CONTENTS, | ||
| 127 | POST_CONTENTS, | ||
| 128 | HOST_TABLE_OF_DEVICES, | ||
| 129 | }; | ||
| 130 | |||
| 131 | static const char* tcpa_pc_event_id_strings[] = { | 53 | static const char* tcpa_pc_event_id_strings[] = { |
| 132 | "", | 54 | "", |
| 133 | "SMBIOS", | 55 | "SMBIOS", |
| @@ -358,65 +280,6 @@ static const struct seq_operations tpm_binary_b_measurments_seqops = { | |||
| 358 | .show = tpm_binary_bios_measurements_show, | 280 | .show = tpm_binary_bios_measurements_show, |
| 359 | }; | 281 | }; |
| 360 | 282 | ||
| 361 | /* read binary bios log */ | ||
| 362 | static int read_log(struct tpm_bios_log *log) | ||
| 363 | { | ||
| 364 | struct acpi_tcpa *buff; | ||
| 365 | acpi_status status; | ||
| 366 | struct acpi_table_header *virt; | ||
| 367 | u64 len, start; | ||
| 368 | |||
| 369 | if (log->bios_event_log != NULL) { | ||
| 370 | printk(KERN_ERR | ||
| 371 | "%s: ERROR - Eventlog already initialized\n", | ||
| 372 | __func__); | ||
| 373 | return -EFAULT; | ||
| 374 | } | ||
| 375 | |||
| 376 | /* Find TCPA entry in RSDT (ACPI_LOGICAL_ADDRESSING) */ | ||
| 377 | status = acpi_get_table(ACPI_SIG_TCPA, 1, | ||
| 378 | (struct acpi_table_header **)&buff); | ||
| 379 | |||
| 380 | if (ACPI_FAILURE(status)) { | ||
| 381 | printk(KERN_ERR "%s: ERROR - Could not get TCPA table\n", | ||
| 382 | __func__); | ||
| 383 | return -EIO; | ||
| 384 | } | ||
| 385 | |||
| 386 | switch(buff->platform_class) { | ||
| 387 | case BIOS_SERVER: | ||
| 388 | len = buff->server.log_max_len; | ||
| 389 | start = buff->server.log_start_addr; | ||
| 390 | break; | ||
| 391 | case BIOS_CLIENT: | ||
| 392 | default: | ||
| 393 | len = buff->client.log_max_len; | ||
| 394 | start = buff->client.log_start_addr; | ||
| 395 | break; | ||
| 396 | } | ||
| 397 | if (!len) { | ||
| 398 | printk(KERN_ERR "%s: ERROR - TCPA log area empty\n", __func__); | ||
| 399 | return -EIO; | ||
| 400 | } | ||
| 401 | |||
| 402 | /* malloc EventLog space */ | ||
| 403 | log->bios_event_log = kmalloc(len, GFP_KERNEL); | ||
| 404 | if (!log->bios_event_log) { | ||
| 405 | printk("%s: ERROR - Not enough Memory for BIOS measurements\n", | ||
| 406 | __func__); | ||
| 407 | return -ENOMEM; | ||
| 408 | } | ||
| 409 | |||
| 410 | log->bios_event_log_end = log->bios_event_log + len; | ||
| 411 | |||
| 412 | virt = acpi_os_map_memory(start, len); | ||
| 413 | |||
| 414 | memcpy(log->bios_event_log, virt, len); | ||
| 415 | |||
| 416 | acpi_os_unmap_memory(virt, len); | ||
| 417 | return 0; | ||
| 418 | } | ||
| 419 | |||
| 420 | static int tpm_ascii_bios_measurements_open(struct inode *inode, | 283 | static int tpm_ascii_bios_measurements_open(struct inode *inode, |
| 421 | struct file *file) | 284 | struct file *file) |
| 422 | { | 285 | { |
diff --git a/drivers/char/tpm/tpm_eventlog.h b/drivers/char/tpm/tpm_eventlog.h new file mode 100644 index 000000000000..8e23ccdf8a83 --- /dev/null +++ b/drivers/char/tpm/tpm_eventlog.h | |||
| @@ -0,0 +1,71 @@ | |||
| 1 | |||
| 2 | #ifndef __TPM_EVENTLOG_H__ | ||
| 3 | #define __TPM_EVENTLOG_H__ | ||
| 4 | |||
| 5 | #define TCG_EVENT_NAME_LEN_MAX 255 | ||
| 6 | #define MAX_TEXT_EVENT 1000 /* Max event string length */ | ||
| 7 | #define ACPI_TCPA_SIG "TCPA" /* 0x41504354 /'TCPA' */ | ||
| 8 | |||
| 9 | enum bios_platform_class { | ||
| 10 | BIOS_CLIENT = 0x00, | ||
| 11 | BIOS_SERVER = 0x01, | ||
| 12 | }; | ||
| 13 | |||
| 14 | struct tpm_bios_log { | ||
| 15 | void *bios_event_log; | ||
| 16 | void *bios_event_log_end; | ||
| 17 | }; | ||
| 18 | |||
| 19 | struct tcpa_event { | ||
| 20 | u32 pcr_index; | ||
| 21 | u32 event_type; | ||
| 22 | u8 pcr_value[20]; /* SHA1 */ | ||
| 23 | u32 event_size; | ||
| 24 | u8 event_data[0]; | ||
| 25 | }; | ||
| 26 | |||
| 27 | enum tcpa_event_types { | ||
| 28 | PREBOOT = 0, | ||
| 29 | POST_CODE, | ||
| 30 | UNUSED, | ||
| 31 | NO_ACTION, | ||
| 32 | SEPARATOR, | ||
| 33 | ACTION, | ||
| 34 | EVENT_TAG, | ||
| 35 | SCRTM_CONTENTS, | ||
| 36 | SCRTM_VERSION, | ||
| 37 | CPU_MICROCODE, | ||
| 38 | PLATFORM_CONFIG_FLAGS, | ||
| 39 | TABLE_OF_DEVICES, | ||
| 40 | COMPACT_HASH, | ||
| 41 | IPL, | ||
| 42 | IPL_PARTITION_DATA, | ||
| 43 | NONHOST_CODE, | ||
| 44 | NONHOST_CONFIG, | ||
| 45 | NONHOST_INFO, | ||
| 46 | }; | ||
| 47 | |||
| 48 | struct tcpa_pc_event { | ||
| 49 | u32 event_id; | ||
| 50 | u32 event_size; | ||
| 51 | u8 event_data[0]; | ||
| 52 | }; | ||
| 53 | |||
| 54 | enum tcpa_pc_event_ids { | ||
| 55 | SMBIOS = 1, | ||
| 56 | BIS_CERT, | ||
| 57 | POST_BIOS_ROM, | ||
| 58 | ESCD, | ||
| 59 | CMOS, | ||
| 60 | NVRAM, | ||
| 61 | OPTION_ROM_EXEC, | ||
| 62 | OPTION_ROM_CONFIG, | ||
| 63 | OPTION_ROM_MICROCODE = 10, | ||
| 64 | S_CRTM_VERSION, | ||
| 65 | S_CRTM_CONTENTS, | ||
| 66 | POST_CONTENTS, | ||
| 67 | HOST_TABLE_OF_DEVICES, | ||
| 68 | }; | ||
| 69 | |||
| 70 | int read_log(struct tpm_bios_log *log); | ||
| 71 | #endif | ||
