]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blame - drivers/char/tpm/eventlog/tpm1.c
Merge branch 'timers-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[mirror_ubuntu-jammy-kernel.git] / drivers / char / tpm / eventlog / tpm1.c
CommitLineData
2874c5fd 1// SPDX-License-Identifier: GPL-2.0-or-later
55a82ab3 2/*
e5dcd87f 3 * Copyright (C) 2005, 2012 IBM Corporation
55a82ab3
KJH
4 *
5 * Authors:
e5dcd87f 6 * Kent Yoder <key@linux.vnet.ibm.com>
55a82ab3
KJH
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>
2528a646 11 * Nayna Jain <nayna@linux.vnet.ibm.com>
55a82ab3 12 *
8e81cc13
KY
13 * Maintained by: <tpmdd-devel@lists.sourceforge.net>
14 *
748935ee 15 * Access to the event log created by a system's firmware / BIOS
55a82ab3
KJH
16 */
17
18#include <linux/seq_file.h>
58cc1e4f 19#include <linux/efi.h>
55a82ab3
KJH
20#include <linux/fs.h>
21#include <linux/security.h>
22#include <linux/module.h>
5a0e3ad6 23#include <linux/slab.h>
fd3ec366 24#include <linux/tpm_eventlog.h>
55a82ab3 25
0bfb2374 26#include "../tpm.h"
75d647f5 27#include "common.h"
55a82ab3 28
55a82ab3
KJH
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
55a82ab3 51static const char* tcpa_pc_event_id_strings[] = {
de66a695 52 "",
55a82ab3
KJH
53 "SMBIOS",
54 "BIS Certificate",
55 "POST BIOS ",
56 "ESCD ",
57 "CMOS",
58 "NVRAM",
59 "Option ROM",
60 "Option ROM config",
de66a695
SM
61 "",
62 "Option ROM microcode ",
55a82ab3 63 "S-CRTM Version",
de66a695
SM
64 "S-CRTM Contents ",
65 "POST Contents ",
66 "Table of Devices",
55a82ab3
KJH
67};
68
55a82ab3 69/* returns pointer to start of pos. entry of tcg log */
9b01b535 70static void *tpm1_bios_measurements_start(struct seq_file *m, loff_t *pos)
55a82ab3 71{
bb3b6b0f 72 loff_t i = 0;
748935ee
NJ
73 struct tpm_chip *chip = m->private;
74 struct tpm_bios_log *log = &chip->log;
d09cf7d7
KJH
75 void *addr = log->bios_event_log;
76 void *limit = log->bios_event_log_end;
55a82ab3 77 struct tcpa_event *event;
0cc698af
HCVL
78 u32 converted_event_size;
79 u32 converted_event_type;
80
55a82ab3 81 /* read over *pos measurements */
bb3b6b0f 82 do {
55a82ab3
KJH
83 event = addr;
84
bb3b6b0f 85 /* check if current entry is valid */
64494d39 86 if (addr + sizeof(struct tcpa_event) > limit)
bb3b6b0f
JZ
87 return NULL;
88
0cc698af
HCVL
89 converted_event_size =
90 do_endian_conversion(event->event_size);
91 converted_event_type =
92 do_endian_conversion(event->event_type);
93
bb3b6b0f
JZ
94 if (((converted_event_type == 0) && (converted_event_size == 0))
95 || ((addr + sizeof(struct tcpa_event) + converted_event_size)
64494d39 96 > limit))
bb3b6b0f 97 return NULL;
55a82ab3 98
bb3b6b0f
JZ
99 if (i++ == *pos)
100 break;
55a82ab3 101
bb3b6b0f
JZ
102 addr += (sizeof(struct tcpa_event) + converted_event_size);
103 } while (1);
55a82ab3
KJH
104
105 return addr;
106}
107
9b01b535 108static void *tpm1_bios_measurements_next(struct seq_file *m, void *v,
55a82ab3
KJH
109 loff_t *pos)
110{
111 struct tcpa_event *event = v;
748935ee
NJ
112 struct tpm_chip *chip = m->private;
113 struct tpm_bios_log *log = &chip->log;
d09cf7d7 114 void *limit = log->bios_event_log_end;
0cc698af
HCVL
115 u32 converted_event_size;
116 u32 converted_event_type;
55a82ab3 117
0cc698af
HCVL
118 converted_event_size = do_endian_conversion(event->event_size);
119
120 v += sizeof(struct tcpa_event) + converted_event_size;
55a82ab3
KJH
121
122 /* now check if current entry is valid */
64494d39 123 if ((v + sizeof(struct tcpa_event)) > limit)
55a82ab3
KJH
124 return NULL;
125
126 event = v;
127
0cc698af
HCVL
128 converted_event_size = do_endian_conversion(event->event_size);
129 converted_event_type = do_endian_conversion(event->event_type);
55a82ab3 130
0cc698af 131 if (((converted_event_type == 0) && (converted_event_size == 0)) ||
64494d39 132 ((v + sizeof(struct tcpa_event) + converted_event_size) > limit))
55a82ab3
KJH
133 return NULL;
134
135 (*pos)++;
136 return v;
137}
138
9b01b535 139static void tpm1_bios_measurements_stop(struct seq_file *m, void *v)
55a82ab3
KJH
140{
141}
142
143static int get_event_name(char *dest, struct tcpa_event *event,
144 unsigned char * event_entry)
145{
146 const char *name = "";
fbaa5869
EP
147 /* 41 so there is room for 40 data and 1 nul */
148 char data[41] = "";
55a82ab3 149 int i, n_len = 0, d_len = 0;
de66a695 150 struct tcpa_pc_event *pc_event;
55a82ab3 151
0cc698af 152 switch (do_endian_conversion(event->event_type)) {
55a82ab3
KJH
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:
0cc698af
HCVL
168 name = tcpa_event_type_strings[do_endian_conversion
169 (event->event_type)];
55a82ab3
KJH
170 n_len = strlen(name);
171 break;
172 case SEPARATOR:
173 case ACTION:
0cc698af
HCVL
174 if (MAX_TEXT_EVENT >
175 do_endian_conversion(event->event_size)) {
55a82ab3 176 name = event_entry;
0cc698af 177 n_len = do_endian_conversion(event->event_size);
55a82ab3
KJH
178 }
179 break;
180 case EVENT_TAG:
de66a695 181 pc_event = (struct tcpa_pc_event *)event_entry;
55a82ab3
KJH
182
183 /* ToDo Row data -> Base64 */
184
0cc698af 185 switch (do_endian_conversion(pc_event->event_id)) {
55a82ab3
KJH
186 case SMBIOS:
187 case BIS_CERT:
188 case CMOS:
189 case NVRAM:
190 case OPTION_ROM_EXEC:
191 case OPTION_ROM_CONFIG:
55a82ab3 192 case S_CRTM_VERSION:
0cc698af
HCVL
193 name = tcpa_pc_event_id_strings[do_endian_conversion
194 (pc_event->event_id)];
55a82ab3
KJH
195 n_len = strlen(name);
196 break;
de66a695 197 /* hash data */
55a82ab3
KJH
198 case POST_BIOS_ROM:
199 case ESCD:
de66a695
SM
200 case OPTION_ROM_MICROCODE:
201 case S_CRTM_CONTENTS:
202 case POST_CONTENTS:
0cc698af
HCVL
203 name = tcpa_pc_event_id_strings[do_endian_conversion
204 (pc_event->event_id)];
55a82ab3
KJH
205 n_len = strlen(name);
206 for (i = 0; i < 20; i++)
de66a695
SM
207 d_len += sprintf(&data[2*i], "%02x",
208 pc_event->event_data[i]);
55a82ab3
KJH
209 break;
210 default:
211 break;
212 }
213 default:
214 break;
215 }
216
217 return snprintf(dest, MAX_TEXT_EVENT, "[%.*s%.*s]",
218 n_len, name, d_len, data);
219
220}
221
9b01b535 222static int tpm1_binary_bios_measurements_show(struct seq_file *m, void *v)
55a82ab3 223{
44d7aff0 224 struct tcpa_event *event = v;
0cc698af 225 struct tcpa_event temp_event;
186d124f 226 char *temp_ptr;
44d7aff0 227 int i;
55a82ab3 228
0cc698af
HCVL
229 memcpy(&temp_event, event, sizeof(struct tcpa_event));
230
231 /* convert raw integers for endianness */
232 temp_event.pcr_index = do_endian_conversion(event->pcr_index);
233 temp_event.event_type = do_endian_conversion(event->event_type);
234 temp_event.event_size = do_endian_conversion(event->event_size);
235
186d124f 236 temp_ptr = (char *) &temp_event;
0cc698af 237
186d124f
HH
238 for (i = 0; i < (sizeof(struct tcpa_event) - 1) ; i++)
239 seq_putc(m, temp_ptr[i]);
240
241 temp_ptr = (char *) v;
242
243 for (i = (sizeof(struct tcpa_event) - 1);
244 i < (sizeof(struct tcpa_event) + temp_event.event_size); i++)
245 seq_putc(m, temp_ptr[i]);
55a82ab3 246
55a82ab3 247 return 0;
0cc698af 248
55a82ab3
KJH
249}
250
9b01b535 251static int tpm1_ascii_bios_measurements_show(struct seq_file *m, void *v)
55a82ab3
KJH
252{
253 int len = 0;
55a82ab3
KJH
254 char *eventname;
255 struct tcpa_event *event = v;
256 unsigned char *event_entry =
0cc698af 257 (unsigned char *)(v + sizeof(struct tcpa_event));
55a82ab3
KJH
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
0cc698af
HCVL
266 /* 1st: PCR */
267 seq_printf(m, "%2d ", do_endian_conversion(event->pcr_index));
55a82ab3
KJH
268
269 /* 2nd: SHA1 */
a3d64df8 270 seq_printf(m, "%20phN", event->pcr_value);
55a82ab3
KJH
271
272 /* 3rd: event type identifier */
0cc698af 273 seq_printf(m, " %02x", do_endian_conversion(event->event_type));
55a82ab3
KJH
274
275 len += get_event_name(eventname, event, event_entry);
276
277 /* 4th: eventname <= max + \'0' delimiter */
278 seq_printf(m, " %s\n", eventname);
279
59e89f3a 280 kfree(eventname);
55a82ab3
KJH
281 return 0;
282}
283
9b01b535
TW
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,
55a82ab3
KJH
289};
290
9b01b535
TW
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,
55a82ab3 296};