aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/tpm/tpm_bios.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/tpm/tpm_bios.c')
-rw-r--r--drivers/char/tpm/tpm_bios.c137
1 files changed, 67 insertions, 70 deletions
diff --git a/drivers/char/tpm/tpm_bios.c b/drivers/char/tpm/tpm_bios.c
index 537aa45d8c67..a611972024e6 100644
--- a/drivers/char/tpm/tpm_bios.c
+++ b/drivers/char/tpm/tpm_bios.c
@@ -29,6 +29,11 @@
29#define MAX_TEXT_EVENT 1000 /* Max event string length */ 29#define MAX_TEXT_EVENT 1000 /* Max event string length */
30#define ACPI_TCPA_SIG "TCPA" /* 0x41504354 /'TCPA' */ 30#define ACPI_TCPA_SIG "TCPA" /* 0x41504354 /'TCPA' */
31 31
32enum bios_platform_class {
33 BIOS_CLIENT = 0x00,
34 BIOS_SERVER = 0x01,
35};
36
32struct tpm_bios_log { 37struct tpm_bios_log {
33 void *bios_event_log; 38 void *bios_event_log;
34 void *bios_event_log_end; 39 void *bios_event_log_end;
@@ -36,9 +41,18 @@ struct tpm_bios_log {
36 41
37struct acpi_tcpa { 42struct acpi_tcpa {
38 struct acpi_table_header hdr; 43 struct acpi_table_header hdr;
39 u16 reserved; 44 u16 platform_class;
40 u32 log_max_len __attribute__ ((packed)); 45 union {
41 u32 log_start_addr __attribute__ ((packed)); 46 struct client_hdr {
47 u32 log_max_len __attribute__ ((packed));
48 u64 log_start_addr __attribute__ ((packed));
49 } client;
50 struct server_hdr {
51 u16 reserved;
52 u64 log_max_len __attribute__ ((packed));
53 u64 log_start_addr __attribute__ ((packed));
54 } server;
55 };
42}; 56};
43 57
44struct tcpa_event { 58struct tcpa_event {
@@ -91,6 +105,12 @@ static const char* tcpa_event_type_strings[] = {
91 "Non-Host Info" 105 "Non-Host Info"
92}; 106};
93 107
108struct tcpa_pc_event {
109 u32 event_id;
110 u32 event_size;
111 u8 event_data[0];
112};
113
94enum tcpa_pc_event_ids { 114enum tcpa_pc_event_ids {
95 SMBIOS = 1, 115 SMBIOS = 1,
96 BIS_CERT, 116 BIS_CERT,
@@ -100,14 +120,15 @@ enum tcpa_pc_event_ids {
100 NVRAM, 120 NVRAM,
101 OPTION_ROM_EXEC, 121 OPTION_ROM_EXEC,
102 OPTION_ROM_CONFIG, 122 OPTION_ROM_CONFIG,
103 OPTION_ROM_MICROCODE, 123 OPTION_ROM_MICROCODE = 10,
104 S_CRTM_VERSION, 124 S_CRTM_VERSION,
105 S_CRTM_CONTENTS, 125 S_CRTM_CONTENTS,
106 POST_CONTENTS, 126 POST_CONTENTS,
127 HOST_TABLE_OF_DEVICES,
107}; 128};
108 129
109static const char* tcpa_pc_event_id_strings[] = { 130static const char* tcpa_pc_event_id_strings[] = {
110 "" 131 "",
111 "SMBIOS", 132 "SMBIOS",
112 "BIS Certificate", 133 "BIS Certificate",
113 "POST BIOS ", 134 "POST BIOS ",
@@ -116,10 +137,12 @@ static const char* tcpa_pc_event_id_strings[] = {
116 "NVRAM", 137 "NVRAM",
117 "Option ROM", 138 "Option ROM",
118 "Option ROM config", 139 "Option ROM config",
119 "Option ROM microcode", 140 "",
141 "Option ROM microcode ",
120 "S-CRTM Version", 142 "S-CRTM Version",
121 "S-CRTM Contents", 143 "S-CRTM Contents ",
122 "S-CRTM POST Contents", 144 "POST Contents ",
145 "Table of Devices",
123}; 146};
124 147
125/* returns pointer to start of pos. entry of tcg log */ 148/* returns pointer to start of pos. entry of tcg log */
@@ -191,7 +214,7 @@ static int get_event_name(char *dest, struct tcpa_event *event,
191 const char *name = ""; 214 const char *name = "";
192 char data[40] = ""; 215 char data[40] = "";
193 int i, n_len = 0, d_len = 0; 216 int i, n_len = 0, d_len = 0;
194 u32 event_id; 217 struct tcpa_pc_event *pc_event;
195 218
196 switch(event->event_type) { 219 switch(event->event_type) {
197 case PREBOOT: 220 case PREBOOT:
@@ -220,31 +243,32 @@ static int get_event_name(char *dest, struct tcpa_event *event,
220 } 243 }
221 break; 244 break;
222 case EVENT_TAG: 245 case EVENT_TAG:
223 event_id = be32_to_cpu(*((u32 *)event_entry)); 246 pc_event = (struct tcpa_pc_event *)event_entry;
224 247
225 /* ToDo Row data -> Base64 */ 248 /* ToDo Row data -> Base64 */
226 249
227 switch (event_id) { 250 switch (pc_event->event_id) {
228 case SMBIOS: 251 case SMBIOS:
229 case BIS_CERT: 252 case BIS_CERT:
230 case CMOS: 253 case CMOS:
231 case NVRAM: 254 case NVRAM:
232 case OPTION_ROM_EXEC: 255 case OPTION_ROM_EXEC:
233 case OPTION_ROM_CONFIG: 256 case OPTION_ROM_CONFIG:
234 case OPTION_ROM_MICROCODE:
235 case S_CRTM_VERSION: 257 case S_CRTM_VERSION:
236 case S_CRTM_CONTENTS: 258 name = tcpa_pc_event_id_strings[pc_event->event_id];
237 case POST_CONTENTS:
238 name = tcpa_pc_event_id_strings[event_id];
239 n_len = strlen(name); 259 n_len = strlen(name);
240 break; 260 break;
261 /* hash data */
241 case POST_BIOS_ROM: 262 case POST_BIOS_ROM:
242 case ESCD: 263 case ESCD:
243 name = tcpa_pc_event_id_strings[event_id]; 264 case OPTION_ROM_MICROCODE:
265 case S_CRTM_CONTENTS:
266 case POST_CONTENTS:
267 name = tcpa_pc_event_id_strings[pc_event->event_id];
244 n_len = strlen(name); 268 n_len = strlen(name);
245 for (i = 0; i < 20; i++) 269 for (i = 0; i < 20; i++)
246 d_len += sprintf(data, "%02x", 270 d_len += sprintf(&data[2*i], "%02x",
247 event_entry[8 + i]); 271 pc_event->event_data[i]);
248 break; 272 break;
249 default: 273 default:
250 break; 274 break;
@@ -260,52 +284,13 @@ static int get_event_name(char *dest, struct tcpa_event *event,
260 284
261static int tpm_binary_bios_measurements_show(struct seq_file *m, void *v) 285static int tpm_binary_bios_measurements_show(struct seq_file *m, void *v)
262{ 286{
287 struct tcpa_event *event = v;
288 char *data = v;
289 int i;
263 290
264 char *eventname; 291 for (i = 0; i < sizeof(struct tcpa_event) + event->event_size; i++)
265 char data[4];
266 u32 help;
267 int i, len;
268 struct tcpa_event *event = (struct tcpa_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) {
274 printk(KERN_ERR "%s: ERROR - No Memory for event name\n ",
275 __func__);
276 return -ENOMEM;
277 }
278
279 /* 1st: PCR used is in little-endian format (4 bytes) */
280 help = le32_to_cpu(event->pcr_index);
281 memcpy(data, &help, 4);
282 for (i = 0; i < 4; i++)
283 seq_putc(m, data[i]);
284
285 /* 2nd: SHA1 (20 bytes) */
286 for (i = 0; i < 20; i++)
287 seq_putc(m, event->pcr_value[i]);
288
289 /* 3rd: event type identifier (4 bytes) */
290 help = le32_to_cpu(event->event_type);
291 memcpy(data, &help, 4);
292 for (i = 0; i < 4; i++)
293 seq_putc(m, data[i]); 292 seq_putc(m, data[i]);
294 293
295 len = 0;
296
297 len += get_event_name(eventname, event, event_entry);
298
299 /* 4th: filename <= 255 + \'0' delimiter */
300 if (len > TCG_EVENT_NAME_LEN_MAX)
301 len = TCG_EVENT_NAME_LEN_MAX;
302
303 for (i = 0; i < len; i++)
304 seq_putc(m, eventname[i]);
305
306 /* 5th: delimiter */
307 seq_putc(m, '\0');
308
309 return 0; 294 return 0;
310} 295}
311 296
@@ -353,6 +338,7 @@ static int tpm_ascii_bios_measurements_show(struct seq_file *m, void *v)
353 /* 4th: eventname <= max + \'0' delimiter */ 338 /* 4th: eventname <= max + \'0' delimiter */
354 seq_printf(m, " %s\n", eventname); 339 seq_printf(m, " %s\n", eventname);
355 340
341 kfree(eventname);
356 return 0; 342 return 0;
357} 343}
358 344
@@ -376,6 +362,7 @@ static int read_log(struct tpm_bios_log *log)
376 struct acpi_tcpa *buff; 362 struct acpi_tcpa *buff;
377 acpi_status status; 363 acpi_status status;
378 struct acpi_table_header *virt; 364 struct acpi_table_header *virt;
365 u64 len, start;
379 366
380 if (log->bios_event_log != NULL) { 367 if (log->bios_event_log != NULL) {
381 printk(KERN_ERR 368 printk(KERN_ERR
@@ -396,27 +383,37 @@ static int read_log(struct tpm_bios_log *log)
396 return -EIO; 383 return -EIO;
397 } 384 }
398 385
399 if (buff->log_max_len == 0) { 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) {
400 printk(KERN_ERR "%s: ERROR - TCPA log area empty\n", __func__); 398 printk(KERN_ERR "%s: ERROR - TCPA log area empty\n", __func__);
401 return -EIO; 399 return -EIO;
402 } 400 }
403 401
404 /* malloc EventLog space */ 402 /* malloc EventLog space */
405 log->bios_event_log = kmalloc(buff->log_max_len, GFP_KERNEL); 403 log->bios_event_log = kmalloc(len, GFP_KERNEL);
406 if (!log->bios_event_log) { 404 if (!log->bios_event_log) {
407 printk 405 printk("%s: ERROR - Not enough Memory for BIOS measurements\n",
408 ("%s: ERROR - Not enough Memory for BIOS measurements\n", 406 __func__);
409 __func__);
410 return -ENOMEM; 407 return -ENOMEM;
411 } 408 }
412 409
413 log->bios_event_log_end = log->bios_event_log + buff->log_max_len; 410 log->bios_event_log_end = log->bios_event_log + len;
414 411
415 acpi_os_map_memory(buff->log_start_addr, buff->log_max_len, (void *) &virt); 412 acpi_os_map_memory(start, len, (void *) &virt);
416 413
417 memcpy(log->bios_event_log, virt, buff->log_max_len); 414 memcpy(log->bios_event_log, virt, len);
418 415
419 acpi_os_unmap_memory(virt, buff->log_max_len); 416 acpi_os_unmap_memory(virt, len);
420 return 0; 417 return 0;
421} 418}
422 419