1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) 2016 IBM Corporation
6 * Nayna Jain <nayna@linux.vnet.ibm.com>
8 * Access to TPM 2.0 event log as written by Firmware.
9 * It assumes that writer of event log has followed TCG Specification
10 * for Family "2.0" and written the event data in little endian.
11 * With that, it doesn't need any endian conversion for structure
15 #include <linux/seq_file.h>
17 #include <linux/security.h>
18 #include <linux/module.h>
19 #include <linux/slab.h>
20 #include <linux/tpm_eventlog.h>
26 * calc_tpm2_event_size() - calculate the event size, where event
27 * is an entry in the TPM 2.0 event log. The event is of type Crypto
28 * Agile Log Entry Format as defined in TCG EFI Protocol Specification
31 * @event: event whose size is to be calculated.
32 * @event_header: the first event in the event log.
34 * Returns size of the event. If it is an invalid event, returns 0.
36 static size_t calc_tpm2_event_size(struct tcg_pcr_event2_head
*event
,
37 struct tcg_pcr_event
*event_header
)
39 return __calc_tpm2_event_size(event
, event_header
, false);
42 static void *tpm2_bios_measurements_start(struct seq_file
*m
, loff_t
*pos
)
44 struct tpm_chip
*chip
= m
->private;
45 struct tpm_bios_log
*log
= &chip
->log
;
46 void *addr
= log
->bios_event_log
;
47 void *limit
= log
->bios_event_log_end
;
48 struct tcg_pcr_event
*event_header
;
49 struct tcg_pcr_event2_head
*event
;
54 size
= struct_size(event_header
, event
, event_header
->event_size
);
57 if (addr
+ size
< limit
) {
58 if ((event_header
->event_type
== 0) &&
59 (event_header
->event_size
== 0))
61 return SEQ_START_TOKEN
;
68 size
= calc_tpm2_event_size(event
, event_header
);
69 if ((addr
+ size
>= limit
) || (size
== 0))
73 for (i
= 0; i
< (*pos
- 1); i
++) {
75 size
= calc_tpm2_event_size(event
, event_header
);
77 if ((addr
+ size
>= limit
) || (size
== 0))
85 static void *tpm2_bios_measurements_next(struct seq_file
*m
, void *v
,
88 struct tcg_pcr_event
*event_header
;
89 struct tcg_pcr_event2_head
*event
;
90 struct tpm_chip
*chip
= m
->private;
91 struct tpm_bios_log
*log
= &chip
->log
;
92 void *limit
= log
->bios_event_log_end
;
97 event_header
= log
->bios_event_log
;
99 if (v
== SEQ_START_TOKEN
) {
100 event_size
= struct_size(event_header
, event
,
101 event_header
->event_size
);
102 marker
= event_header
;
105 event_size
= calc_tpm2_event_size(event
, event_header
);
111 marker
= marker
+ event_size
;
117 event_size
= calc_tpm2_event_size(event
, event_header
);
118 if (((v
+ event_size
) >= limit
) || (event_size
== 0))
124 static void tpm2_bios_measurements_stop(struct seq_file
*m
, void *v
)
128 static int tpm2_binary_bios_measurements_show(struct seq_file
*m
, void *v
)
130 struct tpm_chip
*chip
= m
->private;
131 struct tpm_bios_log
*log
= &chip
->log
;
132 struct tcg_pcr_event
*event_header
= log
->bios_event_log
;
133 struct tcg_pcr_event2_head
*event
= v
;
137 if (v
== SEQ_START_TOKEN
) {
138 size
= struct_size(event_header
, event
,
139 event_header
->event_size
);
140 temp_ptr
= event_header
;
143 seq_write(m
, temp_ptr
, size
);
145 size
= calc_tpm2_event_size(event
, event_header
);
148 seq_write(m
, temp_ptr
, size
);
154 const struct seq_operations tpm2_binary_b_measurements_seqops
= {
155 .start
= tpm2_bios_measurements_start
,
156 .next
= tpm2_bios_measurements_next
,
157 .stop
= tpm2_bios_measurements_stop
,
158 .show
= tpm2_binary_bios_measurements_show
,