brintos

brintos / linux-shallow public Read only

0
0
Text · 6.9 KiB · 12ee42a Raw
297 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Copyright (C) 2005, 2012 IBM Corporation4 *5 * Authors:6 *	Kent Yoder <key@linux.vnet.ibm.com>7 *	Seiji Munetoh <munetoh@jp.ibm.com>8 *	Stefan Berger <stefanb@us.ibm.com>9 *	Reiner Sailer <sailer@watson.ibm.com>10 *	Kylene Hall <kjhall@us.ibm.com>11 *	Nayna Jain <nayna@linux.vnet.ibm.com>12 *13 * Maintained by: <tpmdd-devel@lists.sourceforge.net>14 *15 * Access to the event log created by a system's firmware / BIOS16 */17 18#include <linux/seq_file.h>19#include <linux/efi.h>20#include <linux/fs.h>21#include <linux/security.h>22#include <linux/module.h>23#include <linux/slab.h>24#include <linux/tpm_eventlog.h>25 26#include "../tpm.h"27#include "common.h"28 29 30static const char* tcpa_event_type_strings[] = {31	"PREBOOT",32	"POST CODE",33	"",34	"NO ACTION",35	"SEPARATOR",36	"ACTION",37	"EVENT TAG",38	"S-CRTM Contents",39	"S-CRTM Version",40	"CPU Microcode",41	"Platform Config Flags",42	"Table of Devices",43	"Compact Hash",44	"IPL",45	"IPL Partition Data",46	"Non-Host Code",47	"Non-Host Config",48	"Non-Host Info"49};50 51static const char* tcpa_pc_event_id_strings[] = {52	"",53	"SMBIOS",54	"BIS Certificate",55	"POST BIOS ",56	"ESCD ",57	"CMOS",58	"NVRAM",59	"Option ROM",60	"Option ROM config",61	"",62	"Option ROM microcode ",63	"S-CRTM Version",64	"S-CRTM Contents ",65	"POST Contents ",66	"Table of Devices",67};68 69/* returns pointer to start of pos. entry of tcg log */70static void *tpm1_bios_measurements_start(struct seq_file *m, loff_t *pos)71{72	loff_t i = 0;73	struct tpm_chip *chip = m->private;74	struct tpm_bios_log *log = &chip->log;75	void *addr = log->bios_event_log;76	void *limit = log->bios_event_log_end;77	struct tcpa_event *event;78	u32 converted_event_size;79	u32 converted_event_type;80 81	/* read over *pos measurements */82	do {83		event = addr;84 85		/* check if current entry is valid */86		if (addr + sizeof(struct tcpa_event) > limit)87			return NULL;88 89		converted_event_size =90		    do_endian_conversion(event->event_size);91		converted_event_type =92		    do_endian_conversion(event->event_type);93 94		if (((converted_event_type == 0) && (converted_event_size == 0))95		    || ((addr + sizeof(struct tcpa_event) + converted_event_size)96			> limit))97			return NULL;98 99		if (i++ == *pos)100			break;101 102		addr += (sizeof(struct tcpa_event) + converted_event_size);103	} while (1);104 105	return addr;106}107 108static void *tpm1_bios_measurements_next(struct seq_file *m, void *v,109					loff_t *pos)110{111	struct tcpa_event *event = v;112	struct tpm_chip *chip = m->private;113	struct tpm_bios_log *log = &chip->log;114	void *limit = log->bios_event_log_end;115	u32 converted_event_size;116	u32 converted_event_type;117 118	(*pos)++;119	converted_event_size = do_endian_conversion(event->event_size);120 121	v += sizeof(struct tcpa_event) + converted_event_size;122 123	/* now check if current entry is valid */124	if ((v + sizeof(struct tcpa_event)) > limit)125		return NULL;126 127	event = v;128 129	converted_event_size = do_endian_conversion(event->event_size);130	converted_event_type = do_endian_conversion(event->event_type);131 132	if (((converted_event_type == 0) && (converted_event_size == 0)) ||133	    ((v + sizeof(struct tcpa_event) + converted_event_size) > limit))134		return NULL;135 136	return v;137}138 139static void tpm1_bios_measurements_stop(struct seq_file *m, void *v)140{141}142 143static int get_event_name(char *dest, struct tcpa_event *event,144			unsigned char * event_entry)145{146	const char *name = "";147	/* 41 so there is room for 40 data and 1 nul */148	char data[41] = "";149	int i, n_len = 0, d_len = 0;150	struct tcpa_pc_event *pc_event;151 152	switch (do_endian_conversion(event->event_type)) {153	case PREBOOT:154	case POST_CODE:155	case UNUSED:156	case NO_ACTION:157	case SCRTM_CONTENTS:158	case SCRTM_VERSION:159	case CPU_MICROCODE:160	case PLATFORM_CONFIG_FLAGS:161	case TABLE_OF_DEVICES:162	case COMPACT_HASH:163	case IPL:164	case IPL_PARTITION_DATA:165	case NONHOST_CODE:166	case NONHOST_CONFIG:167	case NONHOST_INFO:168		name = tcpa_event_type_strings[do_endian_conversion169						(event->event_type)];170		n_len = strlen(name);171		break;172	case SEPARATOR:173	case ACTION:174		if (MAX_TEXT_EVENT >175		    do_endian_conversion(event->event_size)) {176			name = event_entry;177			n_len = do_endian_conversion(event->event_size);178		}179		break;180	case EVENT_TAG:181		pc_event = (struct tcpa_pc_event *)event_entry;182 183		/* ToDo Row data -> Base64 */184 185		switch (do_endian_conversion(pc_event->event_id)) {186		case SMBIOS:187		case BIS_CERT:188		case CMOS:189		case NVRAM:190		case OPTION_ROM_EXEC:191		case OPTION_ROM_CONFIG:192		case S_CRTM_VERSION:193			name = tcpa_pc_event_id_strings[do_endian_conversion194							(pc_event->event_id)];195			n_len = strlen(name);196			break;197		/* hash data */198		case POST_BIOS_ROM:199		case ESCD:200		case OPTION_ROM_MICROCODE:201		case S_CRTM_CONTENTS:202		case POST_CONTENTS:203			name = tcpa_pc_event_id_strings[do_endian_conversion204							(pc_event->event_id)];205			n_len = strlen(name);206			for (i = 0; i < 20; i++)207				d_len += sprintf(&data[2*i], "%02x",208						pc_event->event_data[i]);209			break;210		default:211			break;212		}213		break;214	default:215		break;216	}217 218	return snprintf(dest, MAX_TEXT_EVENT, "[%.*s%.*s]",219			n_len, name, d_len, data);220 221}222 223static int tpm1_binary_bios_measurements_show(struct seq_file *m, void *v)224{225	struct tcpa_event *event = v;226	struct tcpa_event temp_event;227	char *temp_ptr;228	int i;229 230	memcpy(&temp_event, event, sizeof(struct tcpa_event));231 232	/* convert raw integers for endianness */233	temp_event.pcr_index = do_endian_conversion(event->pcr_index);234	temp_event.event_type = do_endian_conversion(event->event_type);235	temp_event.event_size = do_endian_conversion(event->event_size);236 237	temp_ptr = (char *) &temp_event;238 239	for (i = 0; i < (sizeof(struct tcpa_event) - 1) ; i++)240		seq_putc(m, temp_ptr[i]);241 242	temp_ptr = (char *) v;243 244	for (i = (sizeof(struct tcpa_event) - 1);245	     i < (sizeof(struct tcpa_event) + temp_event.event_size); i++)246		seq_putc(m, temp_ptr[i]);247 248	return 0;249 250}251 252static int tpm1_ascii_bios_measurements_show(struct seq_file *m, void *v)253{254	char *eventname;255	struct tcpa_event *event = v;256	unsigned char *event_entry =257	    (unsigned char *)(v + sizeof(struct tcpa_event));258 259	eventname = kmalloc(MAX_TEXT_EVENT, GFP_KERNEL);260	if (!eventname) {261		printk(KERN_ERR "%s: ERROR - No Memory for event name\n ",262		       __func__);263		return -EFAULT;264	}265 266	/* 1st: PCR */267	seq_printf(m, "%2d ", do_endian_conversion(event->pcr_index));268 269	/* 2nd: SHA1 */270	seq_printf(m, "%20phN", event->pcr_value);271 272	/* 3rd: event type identifier */273	seq_printf(m, " %02x", do_endian_conversion(event->event_type));274 275	get_event_name(eventname, event, event_entry);276 277	/* 4th: eventname <= max + \'0' delimiter */278	seq_printf(m, " %s\n", eventname);279 280	kfree(eventname);281	return 0;282}283 284const struct seq_operations tpm1_ascii_b_measurements_seqops = {285	.start = tpm1_bios_measurements_start,286	.next = tpm1_bios_measurements_next,287	.stop = tpm1_bios_measurements_stop,288	.show = tpm1_ascii_bios_measurements_show,289};290 291const struct seq_operations tpm1_binary_b_measurements_seqops = {292	.start = tpm1_bios_measurements_start,293	.next = tpm1_bios_measurements_next,294	.stop = tpm1_bios_measurements_stop,295	.show = tpm1_binary_bios_measurements_show,296};297