]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/boot/efi/measure.c
Merge pull request #18007 from fw-strlen/ipv6_masq_and_dnat
[thirdparty/systemd.git] / src / boot / efi / measure.c
CommitLineData
db9ecf05 1/* SPDX-License-Identifier: LGPL-2.1-or-later */
92ed3bb4 2
349cc4a5 3#if ENABLE_TPM
92ed3bb4
HH
4
5#include <efi.h>
6#include <efilib.h>
7d2ebb6f 7
92ed3bb4
HH
8#include "measure.h"
9
7d2ebb6f
DDM
10#define EFI_TCG_GUID \
11 &(EFI_GUID) { 0xf541796d, 0xa62e, 0x4954, { 0xa7, 0x75, 0x95, 0x84, 0xf6, 0x1b, 0x9c, 0xdd } }
92ed3bb4
HH
12
13typedef struct _TCG_VERSION {
14 UINT8 Major;
15 UINT8 Minor;
16 UINT8 RevMajor;
17 UINT8 RevMinor;
18} TCG_VERSION;
19
bfdf8c3b
HH
20typedef struct tdEFI_TCG2_VERSION {
21 UINT8 Major;
22 UINT8 Minor;
23} EFI_TCG2_VERSION;
24
92ed3bb4
HH
25typedef struct _TCG_BOOT_SERVICE_CAPABILITY {
26 UINT8 Size;
27 struct _TCG_VERSION StructureVersion;
28 struct _TCG_VERSION ProtocolSpecVersion;
29 UINT8 HashAlgorithmBitmap;
30 BOOLEAN TPMPresentFlag;
31 BOOLEAN TPMDeactivatedFlag;
32} TCG_BOOT_SERVICE_CAPABILITY;
33
bfdf8c3b
HH
34typedef struct tdTREE_BOOT_SERVICE_CAPABILITY {
35 UINT8 Size;
36 EFI_TCG2_VERSION StructureVersion;
37 EFI_TCG2_VERSION ProtocolVersion;
38 UINT32 HashAlgorithmBitmap;
39 UINT32 SupportedEventLogs;
40 BOOLEAN TrEEPresentFlag;
41 UINT16 MaxCommandSize;
42 UINT16 MaxResponseSize;
43 UINT32 ManufacturerID;
44} TREE_BOOT_SERVICE_CAPABILITY;
45
92ed3bb4
HH
46typedef UINT32 TCG_ALGORITHM_ID;
47#define TCG_ALG_SHA 0x00000004 // The SHA1 algorithm
48
49#define SHA1_DIGEST_SIZE 20
50
51typedef struct _TCG_DIGEST {
52 UINT8 Digest[SHA1_DIGEST_SIZE];
53} TCG_DIGEST;
54
55#define EV_IPL 13
56
57typedef struct _TCG_PCR_EVENT {
58 UINT32 PCRIndex;
59 UINT32 EventType;
60 struct _TCG_DIGEST digest;
61 UINT32 EventSize;
62 UINT8 Event[1];
63} TCG_PCR_EVENT;
64
65INTERFACE_DECL(_EFI_TCG);
66
67typedef EFI_STATUS(EFIAPI * EFI_TCG_STATUS_CHECK) (IN struct _EFI_TCG * This,
68 OUT struct _TCG_BOOT_SERVICE_CAPABILITY * ProtocolCapability,
69 OUT UINT32 * TCGFeatureFlags,
70 OUT EFI_PHYSICAL_ADDRESS * EventLogLocation,
71 OUT EFI_PHYSICAL_ADDRESS * EventLogLastEntry);
72
73typedef EFI_STATUS(EFIAPI * EFI_TCG_HASH_ALL) (IN struct _EFI_TCG * This,
74 IN UINT8 * HashData,
75 IN UINT64 HashDataLen,
76 IN TCG_ALGORITHM_ID AlgorithmId,
77 IN OUT UINT64 * HashedDataLen, IN OUT UINT8 ** HashedDataResult);
78
79typedef EFI_STATUS(EFIAPI * EFI_TCG_LOG_EVENT) (IN struct _EFI_TCG * This,
80 IN struct _TCG_PCR_EVENT * TCGLogData,
81 IN OUT UINT32 * EventNumber, IN UINT32 Flags);
82
83typedef EFI_STATUS(EFIAPI * EFI_TCG_PASS_THROUGH_TO_TPM) (IN struct _EFI_TCG * This,
84 IN UINT32 TpmInputParameterBlockSize,
85 IN UINT8 * TpmInputParameterBlock,
86 IN UINT32 TpmOutputParameterBlockSize,
87 IN UINT8 * TpmOutputParameterBlock);
88
89typedef EFI_STATUS(EFIAPI * EFI_TCG_HASH_LOG_EXTEND_EVENT) (IN struct _EFI_TCG * This,
90 IN EFI_PHYSICAL_ADDRESS HashData,
91 IN UINT64 HashDataLen,
92 IN TCG_ALGORITHM_ID AlgorithmId,
93 IN struct _TCG_PCR_EVENT * TCGLogData,
94 IN OUT UINT32 * EventNumber,
95 OUT EFI_PHYSICAL_ADDRESS * EventLogLastEntry);
96
97typedef struct _EFI_TCG {
98 EFI_TCG_STATUS_CHECK StatusCheck;
99 EFI_TCG_HASH_ALL HashAll;
100 EFI_TCG_LOG_EVENT LogEvent;
101 EFI_TCG_PASS_THROUGH_TO_TPM PassThroughToTPM;
102 EFI_TCG_HASH_LOG_EXTEND_EVENT HashLogExtendEvent;
103} EFI_TCG;
104
7d2ebb6f
DDM
105#define EFI_TCG2_GUID \
106 &(EFI_GUID) { 0x607f766c, 0x7455, 0x42be, { 0x93, 0x0b, 0xe4, 0xd7, 0x6d, 0xb2, 0x72, 0x0f } }
92ed3bb4
HH
107
108typedef struct tdEFI_TCG2_PROTOCOL EFI_TCG2_PROTOCOL;
109
92ed3bb4
HH
110typedef UINT32 EFI_TCG2_EVENT_LOG_BITMAP;
111typedef UINT32 EFI_TCG2_EVENT_LOG_FORMAT;
112typedef UINT32 EFI_TCG2_EVENT_ALGORITHM_BITMAP;
113
92ed3bb4
HH
114typedef struct tdEFI_TCG2_BOOT_SERVICE_CAPABILITY {
115 UINT8 Size;
116 EFI_TCG2_VERSION StructureVersion;
117 EFI_TCG2_VERSION ProtocolVersion;
118 EFI_TCG2_EVENT_ALGORITHM_BITMAP HashAlgorithmBitmap;
119 EFI_TCG2_EVENT_LOG_BITMAP SupportedEventLogs;
120 BOOLEAN TPMPresentFlag;
121 UINT16 MaxCommandSize;
122 UINT16 MaxResponseSize;
123 UINT32 ManufacturerID;
124 UINT32 NumberOfPCRBanks;
125 EFI_TCG2_EVENT_ALGORITHM_BITMAP ActivePcrBanks;
126} EFI_TCG2_BOOT_SERVICE_CAPABILITY;
127
128#define EFI_TCG2_EVENT_HEADER_VERSION 1
129
130typedef struct {
131 UINT32 HeaderSize;
132 UINT16 HeaderVersion;
133 UINT32 PCRIndex;
134 UINT32 EventType;
2ee1c55d 135} __attribute__((packed)) EFI_TCG2_EVENT_HEADER;
92ed3bb4
HH
136
137typedef struct tdEFI_TCG2_EVENT {
138 UINT32 Size;
139 EFI_TCG2_EVENT_HEADER Header;
140 UINT8 Event[1];
2ee1c55d 141} __attribute__((packed)) EFI_TCG2_EVENT;
92ed3bb4
HH
142
143typedef EFI_STATUS(EFIAPI * EFI_TCG2_GET_CAPABILITY) (IN EFI_TCG2_PROTOCOL * This,
144 IN OUT EFI_TCG2_BOOT_SERVICE_CAPABILITY * ProtocolCapability);
145
146typedef EFI_STATUS(EFIAPI * EFI_TCG2_GET_EVENT_LOG) (IN EFI_TCG2_PROTOCOL * This,
147 IN EFI_TCG2_EVENT_LOG_FORMAT EventLogFormat,
148 OUT EFI_PHYSICAL_ADDRESS * EventLogLocation,
149 OUT EFI_PHYSICAL_ADDRESS * EventLogLastEntry,
150 OUT BOOLEAN * EventLogTruncated);
151
152typedef EFI_STATUS(EFIAPI * EFI_TCG2_HASH_LOG_EXTEND_EVENT) (IN EFI_TCG2_PROTOCOL * This,
153 IN UINT64 Flags,
154 IN EFI_PHYSICAL_ADDRESS DataToHash,
155 IN UINT64 DataToHashLen, IN EFI_TCG2_EVENT * EfiTcgEvent);
156
157typedef EFI_STATUS(EFIAPI * EFI_TCG2_SUBMIT_COMMAND) (IN EFI_TCG2_PROTOCOL * This,
158 IN UINT32 InputParameterBlockSize,
159 IN UINT8 * InputParameterBlock,
160 IN UINT32 OutputParameterBlockSize, IN UINT8 * OutputParameterBlock);
161
162typedef EFI_STATUS(EFIAPI * EFI_TCG2_GET_ACTIVE_PCR_BANKS) (IN EFI_TCG2_PROTOCOL * This, OUT UINT32 * ActivePcrBanks);
163
164typedef EFI_STATUS(EFIAPI * EFI_TCG2_SET_ACTIVE_PCR_BANKS) (IN EFI_TCG2_PROTOCOL * This, IN UINT32 ActivePcrBanks);
165
166typedef EFI_STATUS(EFIAPI * EFI_TCG2_GET_RESULT_OF_SET_ACTIVE_PCR_BANKS) (IN EFI_TCG2_PROTOCOL * This,
167 OUT UINT32 * OperationPresent, OUT UINT32 * Response);
168
169typedef struct tdEFI_TCG2_PROTOCOL {
170 EFI_TCG2_GET_CAPABILITY GetCapability;
171 EFI_TCG2_GET_EVENT_LOG GetEventLog;
172 EFI_TCG2_HASH_LOG_EXTEND_EVENT HashLogExtendEvent;
173 EFI_TCG2_SUBMIT_COMMAND SubmitCommand;
174 EFI_TCG2_GET_ACTIVE_PCR_BANKS GetActivePcrBanks;
175 EFI_TCG2_SET_ACTIVE_PCR_BANKS SetActivePcrBanks;
176 EFI_TCG2_GET_RESULT_OF_SET_ACTIVE_PCR_BANKS GetResultOfSetActivePcrBanks;
177} EFI_TCG2;
178
92ed3bb4
HH
179static EFI_STATUS tpm1_measure_to_pcr_and_event_log(const EFI_TCG *tcg, UINT32 pcrindex, const EFI_PHYSICAL_ADDRESS buffer,
180 UINTN buffer_size, const CHAR16 *description) {
181 EFI_STATUS status;
182 TCG_PCR_EVENT *tcg_event;
183 UINT32 event_number;
184 EFI_PHYSICAL_ADDRESS event_log_last;
185 UINTN desc_len;
186
187 desc_len = (StrLen(description) + 1) * sizeof(CHAR16);
188
189 tcg_event = AllocateZeroPool(desc_len + sizeof(TCG_PCR_EVENT));
190
234519ae 191 if (!tcg_event)
92ed3bb4
HH
192 return EFI_OUT_OF_RESOURCES;
193
194 tcg_event->EventSize = desc_len;
195 CopyMem((VOID *) & tcg_event->Event[0], (VOID *) description, desc_len);
196
197 tcg_event->PCRIndex = pcrindex;
198 tcg_event->EventType = EV_IPL;
199
200 event_number = 1;
201 status = uefi_call_wrapper(tcg->HashLogExtendEvent, 7,
a0693fc9 202 (EFI_TCG *) tcg, buffer, buffer_size, TCG_ALG_SHA, tcg_event, &event_number, &event_log_last);
92ed3bb4
HH
203
204 if (EFI_ERROR(status))
205 return status;
206
207 uefi_call_wrapper(BS->FreePool, 1, tcg_event);
208
209 return EFI_SUCCESS;
210}
211
92ed3bb4 212static EFI_STATUS tpm2_measure_to_pcr_and_event_log(const EFI_TCG2 *tcg, UINT32 pcrindex, const EFI_PHYSICAL_ADDRESS buffer,
f8e54bf3 213 UINT64 buffer_size, const CHAR16 *description) {
92ed3bb4
HH
214 EFI_STATUS status;
215 EFI_TCG2_EVENT *tcg_event;
216 UINTN desc_len;
217
218 desc_len = StrLen(description) * sizeof(CHAR16);
219
220 tcg_event = AllocateZeroPool(sizeof(*tcg_event) - sizeof(tcg_event->Event) + desc_len + 1);
221
234519ae 222 if (!tcg_event)
92ed3bb4
HH
223 return EFI_OUT_OF_RESOURCES;
224
bfdf8c3b 225 tcg_event->Size = sizeof(*tcg_event) - sizeof(tcg_event->Event) + desc_len + 1;
92ed3bb4
HH
226 tcg_event->Header.HeaderSize = sizeof(EFI_TCG2_EVENT_HEADER);
227 tcg_event->Header.HeaderVersion = EFI_TCG2_EVENT_HEADER_VERSION;
228 tcg_event->Header.PCRIndex = pcrindex;
229 tcg_event->Header.EventType = EV_IPL;
230
231 CopyMem((VOID *) tcg_event->Event, (VOID *) description, desc_len);
232
bfdf8c3b 233 status = uefi_call_wrapper(tcg->HashLogExtendEvent, 5, (EFI_TCG2 *) tcg, 0, buffer, (UINT64) buffer_size, tcg_event);
92ed3bb4
HH
234
235 uefi_call_wrapper(BS->FreePool, 1, tcg_event);
236
237 if (EFI_ERROR(status))
238 return status;
239
240 return EFI_SUCCESS;
241}
242
243static EFI_TCG * tcg1_interface_check(void) {
92ed3bb4
HH
244 EFI_STATUS status;
245 EFI_TCG *tcg;
246 TCG_BOOT_SERVICE_CAPABILITY capability;
247 UINT32 features;
248 EFI_PHYSICAL_ADDRESS event_log_location;
249 EFI_PHYSICAL_ADDRESS event_log_last_entry;
250
7d2ebb6f 251 status = LibLocateProtocol(EFI_TCG_GUID, (void **) &tcg);
92ed3bb4
HH
252
253 if (EFI_ERROR(status))
254 return NULL;
255
256 capability.Size = (UINT8) sizeof(capability);
257 status = uefi_call_wrapper(tcg->StatusCheck, 5, tcg, &capability, &features, &event_log_location, &event_log_last_entry);
258
259 if (EFI_ERROR(status))
260 return NULL;
261
262 if (capability.TPMDeactivatedFlag)
263 return NULL;
264
265 if (!capability.TPMPresentFlag)
266 return NULL;
267
268 return tcg;
269}
270
ee851229 271static EFI_TCG2 * tcg2_interface_check(void) {
92ed3bb4
HH
272 EFI_STATUS status;
273 EFI_TCG2 *tcg;
f8e54bf3 274 EFI_TCG2_BOOT_SERVICE_CAPABILITY capability;
92ed3bb4 275
7d2ebb6f 276 status = LibLocateProtocol(EFI_TCG2_GUID, (void **) &tcg);
92ed3bb4
HH
277
278 if (EFI_ERROR(status))
279 return NULL;
280
f8e54bf3
JR
281 capability.Size = (UINT8) sizeof(EFI_TCG2_BOOT_SERVICE_CAPABILITY);
282 status = uefi_call_wrapper(tcg->GetCapability, 2, tcg, &capability);
92ed3bb4
HH
283
284 if (EFI_ERROR(status))
285 return NULL;
286
f8e54bf3
JR
287 if (capability.StructureVersion.Major == 1 &&
288 capability.StructureVersion.Minor == 0) {
bfdf8c3b 289 TCG_BOOT_SERVICE_CAPABILITY *caps_1_0;
f8e54bf3 290 caps_1_0 = (TCG_BOOT_SERVICE_CAPABILITY *)&capability;
bfdf8c3b
HH
291 if (caps_1_0->TPMPresentFlag)
292 return tcg;
293 }
294
f8e54bf3 295 if (!capability.TPMPresentFlag)
92ed3bb4
HH
296 return NULL;
297
298 return tcg;
299}
300
301EFI_STATUS tpm_log_event(UINT32 pcrindex, const EFI_PHYSICAL_ADDRESS buffer, UINTN buffer_size, const CHAR16 *description) {
302 EFI_TCG *tpm1;
303 EFI_TCG2 *tpm2;
bfdf8c3b 304
f8e54bf3 305 tpm2 = tcg2_interface_check();
38cd55b0 306 if (tpm2)
f8e54bf3 307 return tpm2_measure_to_pcr_and_event_log(tpm2, pcrindex, buffer, buffer_size, description);
92ed3bb4
HH
308
309 tpm1 = tcg1_interface_check();
310 if (tpm1)
311 return tpm1_measure_to_pcr_and_event_log(tpm1, pcrindex, buffer, buffer_size, description);
312
313 /* No active TPM found, so don't return an error */
314 return EFI_SUCCESS;
315}
316
317#endif