hc
2023-12-08 01573e231f18eb2d99162747186f59511f56b64d
kernel/include/linux/tpm_eventlog.h
....@@ -3,12 +3,11 @@
33 #ifndef __LINUX_TPM_EVENTLOG_H__
44 #define __LINUX_TPM_EVENTLOG_H__
55
6
-#include <crypto/hash_info.h>
6
+#include <linux/tpm.h>
77
88 #define TCG_EVENT_NAME_LEN_MAX 255
99 #define MAX_TEXT_EVENT 1000 /* Max event string length */
1010 #define ACPI_TCPA_SIG "TCPA" /* 0x41504354 /'TCPA' */
11
-#define TPM2_ACTIVE_PCR_BANKS 3
1211
1312 #define EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2 0x1
1413 #define EFI_TCG2_EVENT_LOG_FORMAT_TCG_2 0x2
....@@ -29,7 +28,7 @@
2928 u32 event_type;
3029 u8 pcr_value[20]; /* SHA1 */
3130 u32 event_size;
32
- u8 event_data[0];
31
+ u8 event_data[];
3332 };
3433
3534 enum tcpa_event_types {
....@@ -56,7 +55,7 @@
5655 struct tcpa_pc_event {
5756 u32 event_id;
5857 u32 event_size;
59
- u8 event_data[0];
58
+ u8 event_data[];
6059 };
6160
6261 enum tcpa_pc_event_ids {
....@@ -82,7 +81,9 @@
8281 u16 digest_size;
8382 } __packed;
8483
85
-struct tcg_efi_specid_event {
84
+#define TCG_SPECID_SIG "Spec ID Event03"
85
+
86
+struct tcg_efi_specid_event_head {
8687 u8 signature[16];
8788 u32 platform_class;
8889 u8 spec_version_minor;
....@@ -90,9 +91,7 @@
9091 u8 spec_errata;
9192 u8 uintnsize;
9293 u32 num_algs;
93
- struct tcg_efi_specid_event_algs digest_sizes[TPM2_ACTIVE_PCR_BANKS];
94
- u8 vendor_info_size;
95
- u8 vendor_info[0];
94
+ struct tcg_efi_specid_event_algs digest_sizes[];
9695 } __packed;
9796
9897 struct tcg_pcr_event {
....@@ -100,25 +99,196 @@
10099 u32 event_type;
101100 u8 digest[20];
102101 u32 event_size;
103
- u8 event[0];
102
+ u8 event[];
104103 } __packed;
105104
106105 struct tcg_event_field {
107106 u32 event_size;
108
- u8 event[0];
107
+ u8 event[];
109108 } __packed;
110109
111
-struct tpm2_digest {
112
- u16 alg_id;
113
- u8 digest[SHA512_DIGEST_SIZE];
114
-} __packed;
115
-
116
-struct tcg_pcr_event2 {
110
+struct tcg_pcr_event2_head {
117111 u32 pcr_idx;
118112 u32 event_type;
119113 u32 count;
120
- struct tpm2_digest digests[TPM2_ACTIVE_PCR_BANKS];
121
- struct tcg_event_field event;
114
+ struct tpm_digest digests[];
122115 } __packed;
123116
117
+struct tcg_algorithm_size {
118
+ u16 algorithm_id;
119
+ u16 algorithm_size;
120
+};
121
+
122
+struct tcg_algorithm_info {
123
+ u8 signature[16];
124
+ u32 platform_class;
125
+ u8 spec_version_minor;
126
+ u8 spec_version_major;
127
+ u8 spec_errata;
128
+ u8 uintn_size;
129
+ u32 number_of_algorithms;
130
+ struct tcg_algorithm_size digest_sizes[];
131
+};
132
+
133
+#ifndef TPM_MEMREMAP
134
+#define TPM_MEMREMAP(start, size) NULL
135
+#endif
136
+
137
+#ifndef TPM_MEMUNMAP
138
+#define TPM_MEMUNMAP(start, size) do{} while(0)
139
+#endif
140
+
141
+/**
142
+ * __calc_tpm2_event_size - calculate the size of a TPM2 event log entry
143
+ * @event: Pointer to the event whose size should be calculated
144
+ * @event_header: Pointer to the initial event containing the digest lengths
145
+ * @do_mapping: Whether or not the event needs to be mapped
146
+ *
147
+ * The TPM2 event log format can contain multiple digests corresponding to
148
+ * separate PCR banks, and also contains a variable length of the data that
149
+ * was measured. This requires knowledge of how long each digest type is,
150
+ * and this information is contained within the first event in the log.
151
+ *
152
+ * We calculate the length by examining the number of events, and then looking
153
+ * at each event in turn to determine how much space is used for events in
154
+ * total. Once we've done this we know the offset of the data length field,
155
+ * and can calculate the total size of the event.
156
+ *
157
+ * Return: size of the event on success, 0 on failure
158
+ */
159
+
160
+static __always_inline int __calc_tpm2_event_size(struct tcg_pcr_event2_head *event,
161
+ struct tcg_pcr_event *event_header,
162
+ bool do_mapping)
163
+{
164
+ struct tcg_efi_specid_event_head *efispecid;
165
+ struct tcg_event_field *event_field;
166
+ void *mapping = NULL;
167
+ int mapping_size;
168
+ void *marker;
169
+ void *marker_start;
170
+ u32 halg_size;
171
+ size_t size;
172
+ u16 halg;
173
+ int i;
174
+ int j;
175
+ u32 count, event_type;
176
+ const u8 zero_digest[sizeof(event_header->digest)] = {0};
177
+
178
+ marker = event;
179
+ marker_start = marker;
180
+ marker = marker + sizeof(event->pcr_idx) + sizeof(event->event_type)
181
+ + sizeof(event->count);
182
+
183
+ /* Map the event header */
184
+ if (do_mapping) {
185
+ mapping_size = marker - marker_start;
186
+ mapping = TPM_MEMREMAP((unsigned long)marker_start,
187
+ mapping_size);
188
+ if (!mapping) {
189
+ size = 0;
190
+ goto out;
191
+ }
192
+ } else {
193
+ mapping = marker_start;
194
+ }
195
+
196
+ event = (struct tcg_pcr_event2_head *)mapping;
197
+ /*
198
+ * The loop below will unmap these fields if the log is larger than
199
+ * one page, so save them here for reference:
200
+ */
201
+ count = READ_ONCE(event->count);
202
+ event_type = READ_ONCE(event->event_type);
203
+
204
+ /* Verify that it's the log header */
205
+ if (event_header->pcr_idx != 0 ||
206
+ event_header->event_type != NO_ACTION ||
207
+ memcmp(event_header->digest, zero_digest, sizeof(zero_digest))) {
208
+ size = 0;
209
+ goto out;
210
+ }
211
+
212
+ efispecid = (struct tcg_efi_specid_event_head *)event_header->event;
213
+
214
+ /*
215
+ * Perform validation of the event in order to identify malformed
216
+ * events. This function may be asked to parse arbitrary byte sequences
217
+ * immediately following a valid event log. The caller expects this
218
+ * function to recognize that the byte sequence is not a valid event
219
+ * and to return an event size of 0.
220
+ */
221
+ if (memcmp(efispecid->signature, TCG_SPECID_SIG,
222
+ sizeof(TCG_SPECID_SIG)) ||
223
+ !efispecid->num_algs || count != efispecid->num_algs) {
224
+ size = 0;
225
+ goto out;
226
+ }
227
+
228
+ for (i = 0; i < count; i++) {
229
+ halg_size = sizeof(event->digests[i].alg_id);
230
+
231
+ /* Map the digest's algorithm identifier */
232
+ if (do_mapping) {
233
+ TPM_MEMUNMAP(mapping, mapping_size);
234
+ mapping_size = halg_size;
235
+ mapping = TPM_MEMREMAP((unsigned long)marker,
236
+ mapping_size);
237
+ if (!mapping) {
238
+ size = 0;
239
+ goto out;
240
+ }
241
+ } else {
242
+ mapping = marker;
243
+ }
244
+
245
+ memcpy(&halg, mapping, halg_size);
246
+ marker = marker + halg_size;
247
+
248
+ for (j = 0; j < efispecid->num_algs; j++) {
249
+ if (halg == efispecid->digest_sizes[j].alg_id) {
250
+ marker +=
251
+ efispecid->digest_sizes[j].digest_size;
252
+ break;
253
+ }
254
+ }
255
+ /* Algorithm without known length. Such event is unparseable. */
256
+ if (j == efispecid->num_algs) {
257
+ size = 0;
258
+ goto out;
259
+ }
260
+ }
261
+
262
+ /*
263
+ * Map the event size - we don't read from the event itself, so
264
+ * we don't need to map it
265
+ */
266
+ if (do_mapping) {
267
+ TPM_MEMUNMAP(mapping, mapping_size);
268
+ mapping_size += sizeof(event_field->event_size);
269
+ mapping = TPM_MEMREMAP((unsigned long)marker,
270
+ mapping_size);
271
+ if (!mapping) {
272
+ size = 0;
273
+ goto out;
274
+ }
275
+ } else {
276
+ mapping = marker;
277
+ }
278
+
279
+ event_field = (struct tcg_event_field *)mapping;
280
+
281
+ marker = marker + sizeof(event_field->event_size)
282
+ + event_field->event_size;
283
+ size = marker - marker_start;
284
+
285
+ if (event_type == 0 && event_field->event_size == 0)
286
+ size = 0;
287
+
288
+out:
289
+ if (do_mapping)
290
+ TPM_MEMUNMAP(mapping, mapping_size);
291
+ return size;
292
+}
293
+
124294 #endif