Branch data Line data Source code
1 : : /* SPDX-License-Identifier: GPL-2.0 */
2 : :
3 : : #ifndef __LINUX_TPM_EVENTLOG_H__
4 : : #define __LINUX_TPM_EVENTLOG_H__
5 : :
6 : : #include <linux/tpm.h>
7 : :
8 : : #define TCG_EVENT_NAME_LEN_MAX 255
9 : : #define MAX_TEXT_EVENT 1000 /* Max event string length */
10 : : #define ACPI_TCPA_SIG "TCPA" /* 0x41504354 /'TCPA' */
11 : :
12 : : #define EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2 0x1
13 : : #define EFI_TCG2_EVENT_LOG_FORMAT_TCG_2 0x2
14 : :
15 : : #ifdef CONFIG_PPC64
16 : : #define do_endian_conversion(x) be32_to_cpu(x)
17 : : #else
18 : : #define do_endian_conversion(x) x
19 : : #endif
20 : :
21 : : enum bios_platform_class {
22 : : BIOS_CLIENT = 0x00,
23 : : BIOS_SERVER = 0x01,
24 : : };
25 : :
26 : : struct tcpa_event {
27 : : u32 pcr_index;
28 : : u32 event_type;
29 : : u8 pcr_value[20]; /* SHA1 */
30 : : u32 event_size;
31 : : u8 event_data[0];
32 : : };
33 : :
34 : : enum tcpa_event_types {
35 : : PREBOOT = 0,
36 : : POST_CODE,
37 : : UNUSED,
38 : : NO_ACTION,
39 : : SEPARATOR,
40 : : ACTION,
41 : : EVENT_TAG,
42 : : SCRTM_CONTENTS,
43 : : SCRTM_VERSION,
44 : : CPU_MICROCODE,
45 : : PLATFORM_CONFIG_FLAGS,
46 : : TABLE_OF_DEVICES,
47 : : COMPACT_HASH,
48 : : IPL,
49 : : IPL_PARTITION_DATA,
50 : : NONHOST_CODE,
51 : : NONHOST_CONFIG,
52 : : NONHOST_INFO,
53 : : };
54 : :
55 : : struct tcpa_pc_event {
56 : : u32 event_id;
57 : : u32 event_size;
58 : : u8 event_data[0];
59 : : };
60 : :
61 : : enum tcpa_pc_event_ids {
62 : : SMBIOS = 1,
63 : : BIS_CERT,
64 : : POST_BIOS_ROM,
65 : : ESCD,
66 : : CMOS,
67 : : NVRAM,
68 : : OPTION_ROM_EXEC,
69 : : OPTION_ROM_CONFIG,
70 : : OPTION_ROM_MICROCODE = 10,
71 : : S_CRTM_VERSION,
72 : : S_CRTM_CONTENTS,
73 : : POST_CONTENTS,
74 : : HOST_TABLE_OF_DEVICES,
75 : : };
76 : :
77 : : /* http://www.trustedcomputinggroup.org/tcg-efi-protocol-specification/ */
78 : :
79 : : struct tcg_efi_specid_event_algs {
80 : : u16 alg_id;
81 : : u16 digest_size;
82 : : } __packed;
83 : :
84 : : struct tcg_efi_specid_event_head {
85 : : u8 signature[16];
86 : : u32 platform_class;
87 : : u8 spec_version_minor;
88 : : u8 spec_version_major;
89 : : u8 spec_errata;
90 : : u8 uintnsize;
91 : : u32 num_algs;
92 : : struct tcg_efi_specid_event_algs digest_sizes[];
93 : : } __packed;
94 : :
95 : : struct tcg_pcr_event {
96 : : u32 pcr_idx;
97 : : u32 event_type;
98 : : u8 digest[20];
99 : : u32 event_size;
100 : : u8 event[0];
101 : : } __packed;
102 : :
103 : : struct tcg_event_field {
104 : : u32 event_size;
105 : : u8 event[0];
106 : : } __packed;
107 : :
108 : : struct tcg_pcr_event2_head {
109 : : u32 pcr_idx;
110 : : u32 event_type;
111 : : u32 count;
112 : : struct tpm_digest digests[];
113 : : } __packed;
114 : :
115 : : struct tcg_algorithm_size {
116 : : u16 algorithm_id;
117 : : u16 algorithm_size;
118 : : };
119 : :
120 : : struct tcg_algorithm_info {
121 : : u8 signature[16];
122 : : u32 platform_class;
123 : : u8 spec_version_minor;
124 : : u8 spec_version_major;
125 : : u8 spec_errata;
126 : : u8 uintn_size;
127 : : u32 number_of_algorithms;
128 : : struct tcg_algorithm_size digest_sizes[];
129 : : };
130 : :
131 : : #ifndef TPM_MEMREMAP
132 : : #define TPM_MEMREMAP(start, size) NULL
133 : : #endif
134 : :
135 : : #ifndef TPM_MEMUNMAP
136 : : #define TPM_MEMUNMAP(start, size) do{} while(0)
137 : : #endif
138 : :
139 : : /**
140 : : * __calc_tpm2_event_size - calculate the size of a TPM2 event log entry
141 : : * @event: Pointer to the event whose size should be calculated
142 : : * @event_header: Pointer to the initial event containing the digest lengths
143 : : * @do_mapping: Whether or not the event needs to be mapped
144 : : *
145 : : * The TPM2 event log format can contain multiple digests corresponding to
146 : : * separate PCR banks, and also contains a variable length of the data that
147 : : * was measured. This requires knowledge of how long each digest type is,
148 : : * and this information is contained within the first event in the log.
149 : : *
150 : : * We calculate the length by examining the number of events, and then looking
151 : : * at each event in turn to determine how much space is used for events in
152 : : * total. Once we've done this we know the offset of the data length field,
153 : : * and can calculate the total size of the event.
154 : : *
155 : : * Return: size of the event on success, 0 on failure
156 : : */
157 : :
158 : 0 : static inline int __calc_tpm2_event_size(struct tcg_pcr_event2_head *event,
159 : : struct tcg_pcr_event *event_header,
160 : : bool do_mapping)
161 : : {
162 : 0 : struct tcg_efi_specid_event_head *efispecid;
163 : 0 : struct tcg_event_field *event_field;
164 : 0 : void *mapping = NULL;
165 : 0 : int mapping_size;
166 : 0 : void *marker;
167 : 0 : void *marker_start;
168 : 0 : u32 halg_size;
169 : 0 : size_t size;
170 : 0 : u16 halg;
171 : 0 : int i;
172 : 0 : int j;
173 : 0 : u32 count, event_type;
174 : :
175 : 0 : marker = event;
176 : 0 : marker_start = marker;
177 : 0 : marker = marker + sizeof(event->pcr_idx) + sizeof(event->event_type)
178 : : + sizeof(event->count);
179 : :
180 : : /* Map the event header */
181 [ # # ]: 0 : if (do_mapping) {
182 : 0 : mapping_size = marker - marker_start;
183 : 0 : mapping = TPM_MEMREMAP((unsigned long)marker_start,
184 : : mapping_size);
185 [ # # ]: 0 : if (!mapping) {
186 : 0 : size = 0;
187 : 0 : goto out;
188 : : }
189 : : } else {
190 : : mapping = marker_start;
191 : : }
192 : :
193 : 0 : event = (struct tcg_pcr_event2_head *)mapping;
194 : : /*
195 : : * The loop below will unmap these fields if the log is larger than
196 : : * one page, so save them here for reference:
197 : : */
198 [ # # ]: 0 : count = READ_ONCE(event->count);
199 : : event_type = READ_ONCE(event->event_type);
200 : :
201 : 0 : efispecid = (struct tcg_efi_specid_event_head *)event_header->event;
202 : :
203 : : /* Check if event is malformed. */
204 [ # # ]: 0 : if (count > efispecid->num_algs) {
205 : 0 : size = 0;
206 : 0 : goto out;
207 : : }
208 : :
209 [ # # ]: 0 : for (i = 0; i < count; i++) {
210 : 0 : halg_size = sizeof(event->digests[i].alg_id);
211 : :
212 : : /* Map the digest's algorithm identifier */
213 [ # # ]: 0 : if (do_mapping) {
214 : 0 : TPM_MEMUNMAP(mapping, mapping_size);
215 : 0 : mapping_size = halg_size;
216 : 0 : mapping = TPM_MEMREMAP((unsigned long)marker,
217 : : mapping_size);
218 [ # # ]: 0 : if (!mapping) {
219 : 0 : size = 0;
220 : 0 : goto out;
221 : : }
222 : : } else {
223 : : mapping = marker;
224 : : }
225 : :
226 : 0 : memcpy(&halg, mapping, halg_size);
227 : 0 : marker = marker + halg_size;
228 : :
229 [ # # ]: 0 : for (j = 0; j < efispecid->num_algs; j++) {
230 [ # # ]: 0 : if (halg == efispecid->digest_sizes[j].alg_id) {
231 : 0 : marker +=
232 : 0 : efispecid->digest_sizes[j].digest_size;
233 : 0 : break;
234 : : }
235 : : }
236 : : /* Algorithm without known length. Such event is unparseable. */
237 [ # # ]: 0 : if (j == efispecid->num_algs) {
238 : 0 : size = 0;
239 : 0 : goto out;
240 : : }
241 : : }
242 : :
243 : : /*
244 : : * Map the event size - we don't read from the event itself, so
245 : : * we don't need to map it
246 : : */
247 [ # # ]: 0 : if (do_mapping) {
248 : 0 : TPM_MEMUNMAP(mapping, mapping_size);
249 : 0 : mapping_size += sizeof(event_field->event_size);
250 : 0 : mapping = TPM_MEMREMAP((unsigned long)marker,
251 : : mapping_size);
252 [ # # ]: 0 : if (!mapping) {
253 : 0 : size = 0;
254 : 0 : goto out;
255 : : }
256 : : } else {
257 : : mapping = marker;
258 : : }
259 : :
260 : 0 : event_field = (struct tcg_event_field *)mapping;
261 : :
262 : 0 : marker = marker + sizeof(event_field->event_size)
263 : 0 : + event_field->event_size;
264 : 0 : size = marker - marker_start;
265 : :
266 [ # # # # ]: 0 : if (event_type == 0 && event_field->event_size == 0)
267 : 0 : size = 0;
268 : :
269 : 0 : out:
270 [ # # ]: 0 : if (do_mapping)
271 : 0 : TPM_MEMUNMAP(mapping, mapping_size);
272 : 0 : return size;
273 : : }
274 : :
275 : : #endif
|