1 | /** @file
|
---|
2 | The library instance provides security service of TPM2 measure boot and
|
---|
3 | Confidential Computing (CC) measure boot.
|
---|
4 |
|
---|
5 | Caution: This file requires additional review when modified.
|
---|
6 | This library will have external input - PE/COFF image and GPT partition.
|
---|
7 | This external input must be validated carefully to avoid security issue like
|
---|
8 | buffer overflow, integer overflow.
|
---|
9 |
|
---|
10 | DxeTpm2MeasureBootLibImageRead() function will make sure the PE/COFF image content
|
---|
11 | read is within the image buffer.
|
---|
12 |
|
---|
13 | Tcg2MeasurePeImage() function will accept untrusted PE/COFF image and validate its
|
---|
14 | data structure within this image buffer before use.
|
---|
15 |
|
---|
16 | Tcg2MeasureGptTable() function will receive untrusted GPT partition table, and parse
|
---|
17 | partition data carefully.
|
---|
18 |
|
---|
19 | Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
|
---|
20 | (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
|
---|
21 | SPDX-License-Identifier: BSD-2-Clause-Patent
|
---|
22 |
|
---|
23 | Copyright (c) Microsoft Corporation.<BR>
|
---|
24 | SPDX-License-Identifier: BSD-2-Clause-Patent
|
---|
25 | **/
|
---|
26 |
|
---|
27 | #include <PiDxe.h>
|
---|
28 |
|
---|
29 | #include <Protocol/Tcg2Protocol.h>
|
---|
30 | #include <Protocol/BlockIo.h>
|
---|
31 | #include <Protocol/DiskIo.h>
|
---|
32 | #include <Protocol/DevicePathToText.h>
|
---|
33 | #include <Protocol/FirmwareVolumeBlock.h>
|
---|
34 |
|
---|
35 | #include <Guid/MeasuredFvHob.h>
|
---|
36 |
|
---|
37 | #include <Library/BaseLib.h>
|
---|
38 | #include <Library/DebugLib.h>
|
---|
39 | #include <Library/BaseMemoryLib.h>
|
---|
40 | #include <Library/MemoryAllocationLib.h>
|
---|
41 | #include <Library/DevicePathLib.h>
|
---|
42 | #include <Library/UefiBootServicesTableLib.h>
|
---|
43 | #include <Library/BaseCryptLib.h>
|
---|
44 | #include <Library/PeCoffLib.h>
|
---|
45 | #include <Library/SecurityManagementLib.h>
|
---|
46 | #include <Library/HobLib.h>
|
---|
47 | #include <Protocol/CcMeasurement.h>
|
---|
48 |
|
---|
49 | #include "DxeTpm2MeasureBootLibSanitization.h"
|
---|
50 |
|
---|
51 | typedef struct {
|
---|
52 | EFI_TCG2_PROTOCOL *Tcg2Protocol;
|
---|
53 | EFI_CC_MEASUREMENT_PROTOCOL *CcProtocol;
|
---|
54 | } MEASURE_BOOT_PROTOCOLS;
|
---|
55 |
|
---|
56 | //
|
---|
57 | // Flag to check GPT partition. It only need be measured once.
|
---|
58 | //
|
---|
59 | BOOLEAN mTcg2MeasureGptTableFlag = FALSE;
|
---|
60 | UINTN mTcg2MeasureGptCount = 0;
|
---|
61 | VOID *mTcg2FileBuffer;
|
---|
62 | UINTN mTcg2ImageSize;
|
---|
63 | //
|
---|
64 | // Measured FV handle cache
|
---|
65 | //
|
---|
66 | EFI_HANDLE mTcg2CacheMeasuredHandle = NULL;
|
---|
67 | MEASURED_HOB_DATA *mTcg2MeasuredHobData = NULL;
|
---|
68 |
|
---|
69 | /**
|
---|
70 | Reads contents of a PE/COFF image in memory buffer.
|
---|
71 |
|
---|
72 | Caution: This function may receive untrusted input.
|
---|
73 | PE/COFF image is external input, so this function will make sure the PE/COFF image content
|
---|
74 | read is within the image buffer.
|
---|
75 |
|
---|
76 | @param FileHandle Pointer to the file handle to read the PE/COFF image.
|
---|
77 | @param FileOffset Offset into the PE/COFF image to begin the read operation.
|
---|
78 | @param ReadSize On input, the size in bytes of the requested read operation.
|
---|
79 | On output, the number of bytes actually read.
|
---|
80 | @param Buffer Output buffer that contains the data read from the PE/COFF image.
|
---|
81 |
|
---|
82 | @retval EFI_SUCCESS The specified portion of the PE/COFF image was read and the size
|
---|
83 | **/
|
---|
84 | EFI_STATUS
|
---|
85 | EFIAPI
|
---|
86 | DxeTpm2MeasureBootLibImageRead (
|
---|
87 | IN VOID *FileHandle,
|
---|
88 | IN UINTN FileOffset,
|
---|
89 | IN OUT UINTN *ReadSize,
|
---|
90 | OUT VOID *Buffer
|
---|
91 | )
|
---|
92 | {
|
---|
93 | UINTN EndPosition;
|
---|
94 |
|
---|
95 | if ((FileHandle == NULL) || (ReadSize == NULL) || (Buffer == NULL)) {
|
---|
96 | return EFI_INVALID_PARAMETER;
|
---|
97 | }
|
---|
98 |
|
---|
99 | if (MAX_ADDRESS - FileOffset < *ReadSize) {
|
---|
100 | return EFI_INVALID_PARAMETER;
|
---|
101 | }
|
---|
102 |
|
---|
103 | EndPosition = FileOffset + *ReadSize;
|
---|
104 | if (EndPosition > mTcg2ImageSize) {
|
---|
105 | *ReadSize = (UINT32)(mTcg2ImageSize - FileOffset);
|
---|
106 | }
|
---|
107 |
|
---|
108 | if (FileOffset >= mTcg2ImageSize) {
|
---|
109 | *ReadSize = 0;
|
---|
110 | }
|
---|
111 |
|
---|
112 | CopyMem (Buffer, (UINT8 *)((UINTN)FileHandle + FileOffset), *ReadSize);
|
---|
113 |
|
---|
114 | return EFI_SUCCESS;
|
---|
115 | }
|
---|
116 |
|
---|
117 | /**
|
---|
118 | Measure GPT table data into TPM log.
|
---|
119 |
|
---|
120 | Caution: This function may receive untrusted input.
|
---|
121 | The GPT partition table is external input, so this function should parse partition data carefully.
|
---|
122 |
|
---|
123 | @param MeasureBootProtocols Pointer to the located MeasureBoot protocol instances (i.e. TCG2/CC protocol).
|
---|
124 | @param GptHandle Handle that GPT partition was installed.
|
---|
125 |
|
---|
126 | @retval EFI_SUCCESS Successfully measure GPT table.
|
---|
127 | @retval EFI_UNSUPPORTED Not support GPT table on the given handle.
|
---|
128 | @retval EFI_DEVICE_ERROR Can't get GPT table because device error.
|
---|
129 | @retval EFI_OUT_OF_RESOURCES No enough resource to measure GPT table.
|
---|
130 | @retval other error value
|
---|
131 | **/
|
---|
132 | EFI_STATUS
|
---|
133 | EFIAPI
|
---|
134 | Tcg2MeasureGptTable (
|
---|
135 | IN MEASURE_BOOT_PROTOCOLS *MeasureBootProtocols,
|
---|
136 | IN EFI_HANDLE GptHandle
|
---|
137 | )
|
---|
138 | {
|
---|
139 | EFI_STATUS Status;
|
---|
140 | EFI_BLOCK_IO_PROTOCOL *BlockIo;
|
---|
141 | EFI_DISK_IO_PROTOCOL *DiskIo;
|
---|
142 | EFI_PARTITION_TABLE_HEADER *PrimaryHeader;
|
---|
143 | EFI_PARTITION_ENTRY *PartitionEntry;
|
---|
144 | UINT8 *EntryPtr;
|
---|
145 | UINTN NumberOfPartition;
|
---|
146 | UINT32 Index;
|
---|
147 | UINT8 *EventPtr;
|
---|
148 | EFI_TCG2_EVENT *Tcg2Event;
|
---|
149 | EFI_CC_EVENT *CcEvent;
|
---|
150 | EFI_GPT_DATA *GptData;
|
---|
151 | UINT32 TcgEventSize;
|
---|
152 | EFI_TCG2_PROTOCOL *Tcg2Protocol;
|
---|
153 | EFI_CC_MEASUREMENT_PROTOCOL *CcProtocol;
|
---|
154 | EFI_CC_MR_INDEX MrIndex;
|
---|
155 | UINT32 AllocSize;
|
---|
156 |
|
---|
157 | if (mTcg2MeasureGptCount > 0) {
|
---|
158 | return EFI_SUCCESS;
|
---|
159 | }
|
---|
160 |
|
---|
161 | PrimaryHeader = NULL;
|
---|
162 | EntryPtr = NULL;
|
---|
163 | EventPtr = NULL;
|
---|
164 |
|
---|
165 | Tcg2Protocol = MeasureBootProtocols->Tcg2Protocol;
|
---|
166 | CcProtocol = MeasureBootProtocols->CcProtocol;
|
---|
167 |
|
---|
168 | if ((Tcg2Protocol == NULL) && (CcProtocol == NULL)) {
|
---|
169 | ASSERT (FALSE);
|
---|
170 | return EFI_UNSUPPORTED;
|
---|
171 | }
|
---|
172 |
|
---|
173 | if (sizeof (EFI_CC_EVENT) != sizeof (EFI_TCG2_EVENT)) {
|
---|
174 | ASSERT (FALSE);
|
---|
175 | return EFI_UNSUPPORTED;
|
---|
176 | }
|
---|
177 |
|
---|
178 | Status = gBS->HandleProtocol (GptHandle, &gEfiBlockIoProtocolGuid, (VOID **)&BlockIo);
|
---|
179 | if (EFI_ERROR (Status)) {
|
---|
180 | return EFI_UNSUPPORTED;
|
---|
181 | }
|
---|
182 |
|
---|
183 | Status = gBS->HandleProtocol (GptHandle, &gEfiDiskIoProtocolGuid, (VOID **)&DiskIo);
|
---|
184 | if (EFI_ERROR (Status)) {
|
---|
185 | return EFI_UNSUPPORTED;
|
---|
186 | }
|
---|
187 |
|
---|
188 | //
|
---|
189 | // Read the EFI Partition Table Header
|
---|
190 | //
|
---|
191 | PrimaryHeader = (EFI_PARTITION_TABLE_HEADER *)AllocatePool (BlockIo->Media->BlockSize);
|
---|
192 | if (PrimaryHeader == NULL) {
|
---|
193 | return EFI_OUT_OF_RESOURCES;
|
---|
194 | }
|
---|
195 |
|
---|
196 | Status = DiskIo->ReadDisk (
|
---|
197 | DiskIo,
|
---|
198 | BlockIo->Media->MediaId,
|
---|
199 | 1 * BlockIo->Media->BlockSize,
|
---|
200 | BlockIo->Media->BlockSize,
|
---|
201 | (UINT8 *)PrimaryHeader
|
---|
202 | );
|
---|
203 | if (EFI_ERROR (Status) || EFI_ERROR (Tpm2SanitizeEfiPartitionTableHeader (PrimaryHeader, BlockIo))) {
|
---|
204 | DEBUG ((DEBUG_ERROR, "Failed to read Partition Table Header or invalid Partition Table Header!\n"));
|
---|
205 | FreePool (PrimaryHeader);
|
---|
206 | return EFI_DEVICE_ERROR;
|
---|
207 | }
|
---|
208 |
|
---|
209 | //
|
---|
210 | // Read the partition entry.
|
---|
211 | //
|
---|
212 | Status = Tpm2SanitizePrimaryHeaderAllocationSize (PrimaryHeader, &AllocSize);
|
---|
213 | if (EFI_ERROR (Status)) {
|
---|
214 | FreePool (PrimaryHeader);
|
---|
215 | return EFI_BAD_BUFFER_SIZE;
|
---|
216 | }
|
---|
217 |
|
---|
218 | EntryPtr = (UINT8 *)AllocatePool (AllocSize);
|
---|
219 | if (EntryPtr == NULL) {
|
---|
220 | FreePool (PrimaryHeader);
|
---|
221 | return EFI_OUT_OF_RESOURCES;
|
---|
222 | }
|
---|
223 |
|
---|
224 | Status = DiskIo->ReadDisk (
|
---|
225 | DiskIo,
|
---|
226 | BlockIo->Media->MediaId,
|
---|
227 | MultU64x32 (PrimaryHeader->PartitionEntryLBA, BlockIo->Media->BlockSize),
|
---|
228 | AllocSize,
|
---|
229 | EntryPtr
|
---|
230 | );
|
---|
231 | if (EFI_ERROR (Status)) {
|
---|
232 | FreePool (PrimaryHeader);
|
---|
233 | FreePool (EntryPtr);
|
---|
234 | return EFI_DEVICE_ERROR;
|
---|
235 | }
|
---|
236 |
|
---|
237 | //
|
---|
238 | // Count the valid partition
|
---|
239 | //
|
---|
240 | PartitionEntry = (EFI_PARTITION_ENTRY *)EntryPtr;
|
---|
241 | NumberOfPartition = 0;
|
---|
242 | for (Index = 0; Index < PrimaryHeader->NumberOfPartitionEntries; Index++) {
|
---|
243 | if (!IsZeroGuid (&PartitionEntry->PartitionTypeGUID)) {
|
---|
244 | NumberOfPartition++;
|
---|
245 | }
|
---|
246 |
|
---|
247 | PartitionEntry = (EFI_PARTITION_ENTRY *)((UINT8 *)PartitionEntry + PrimaryHeader->SizeOfPartitionEntry);
|
---|
248 | }
|
---|
249 |
|
---|
250 | //
|
---|
251 | // Prepare Data for Measurement (CcProtocol and Tcg2Protocol)
|
---|
252 | //
|
---|
253 | Status = Tpm2SanitizePrimaryHeaderGptEventSize (PrimaryHeader, NumberOfPartition, &TcgEventSize);
|
---|
254 | if (EFI_ERROR (Status)) {
|
---|
255 | FreePool (PrimaryHeader);
|
---|
256 | FreePool (EntryPtr);
|
---|
257 | return EFI_DEVICE_ERROR;
|
---|
258 | }
|
---|
259 |
|
---|
260 | EventPtr = (UINT8 *)AllocateZeroPool (TcgEventSize);
|
---|
261 | if (EventPtr == NULL) {
|
---|
262 | Status = EFI_OUT_OF_RESOURCES;
|
---|
263 | goto Exit;
|
---|
264 | }
|
---|
265 |
|
---|
266 | Tcg2Event = (EFI_TCG2_EVENT *)EventPtr;
|
---|
267 | Tcg2Event->Size = TcgEventSize;
|
---|
268 | Tcg2Event->Header.HeaderSize = sizeof (EFI_TCG2_EVENT_HEADER);
|
---|
269 | Tcg2Event->Header.HeaderVersion = EFI_TCG2_EVENT_HEADER_VERSION;
|
---|
270 | Tcg2Event->Header.PCRIndex = 5;
|
---|
271 | Tcg2Event->Header.EventType = EV_EFI_GPT_EVENT;
|
---|
272 | GptData = (EFI_GPT_DATA *)Tcg2Event->Event;
|
---|
273 |
|
---|
274 | //
|
---|
275 | // Copy the EFI_PARTITION_TABLE_HEADER and NumberOfPartition
|
---|
276 | //
|
---|
277 | CopyMem ((UINT8 *)GptData, (UINT8 *)PrimaryHeader, sizeof (EFI_PARTITION_TABLE_HEADER));
|
---|
278 | GptData->NumberOfPartitions = NumberOfPartition;
|
---|
279 | //
|
---|
280 | // Copy the valid partition entry
|
---|
281 | //
|
---|
282 | PartitionEntry = (EFI_PARTITION_ENTRY *)EntryPtr;
|
---|
283 | NumberOfPartition = 0;
|
---|
284 | for (Index = 0; Index < PrimaryHeader->NumberOfPartitionEntries; Index++) {
|
---|
285 | if (!IsZeroGuid (&PartitionEntry->PartitionTypeGUID)) {
|
---|
286 | CopyMem (
|
---|
287 | (UINT8 *)&GptData->Partitions + NumberOfPartition * PrimaryHeader->SizeOfPartitionEntry,
|
---|
288 | (UINT8 *)PartitionEntry,
|
---|
289 | PrimaryHeader->SizeOfPartitionEntry
|
---|
290 | );
|
---|
291 | NumberOfPartition++;
|
---|
292 | }
|
---|
293 |
|
---|
294 | PartitionEntry = (EFI_PARTITION_ENTRY *)((UINT8 *)PartitionEntry + PrimaryHeader->SizeOfPartitionEntry);
|
---|
295 | }
|
---|
296 |
|
---|
297 | //
|
---|
298 | // Only one of TCG2_PROTOCOL or CC_MEASUREMENT_PROTOCOL is exposed.
|
---|
299 | // So Measure the GPT data with one of the protocol.
|
---|
300 | //
|
---|
301 | if (CcProtocol != NULL) {
|
---|
302 | //
|
---|
303 | // EFI_CC_EVENT share the same data structure with EFI_TCG2_EVENT
|
---|
304 | // except the MrIndex and PCRIndex in Header.
|
---|
305 | // Tcg2Event has been created and initialized before. So only the MrIndex need
|
---|
306 | // be adjusted.
|
---|
307 | //
|
---|
308 | Status = CcProtocol->MapPcrToMrIndex (CcProtocol, Tcg2Event->Header.PCRIndex, &MrIndex);
|
---|
309 | if (EFI_ERROR (Status)) {
|
---|
310 | DEBUG ((DEBUG_ERROR, "Cannot map PcrIndex(%d) to MrIndex\n", Tcg2Event->Header.PCRIndex));
|
---|
311 | goto Exit;
|
---|
312 | }
|
---|
313 |
|
---|
314 | CcEvent = (EFI_CC_EVENT *)EventPtr;
|
---|
315 | CcEvent->Header.MrIndex = MrIndex;
|
---|
316 | Status = CcProtocol->HashLogExtendEvent (
|
---|
317 | CcProtocol,
|
---|
318 | 0,
|
---|
319 | (EFI_PHYSICAL_ADDRESS)(UINTN)(VOID *)GptData,
|
---|
320 | (UINT64)TcgEventSize - OFFSET_OF (EFI_TCG2_EVENT, Event),
|
---|
321 | CcEvent
|
---|
322 | );
|
---|
323 | if (!EFI_ERROR (Status)) {
|
---|
324 | mTcg2MeasureGptCount++;
|
---|
325 | }
|
---|
326 |
|
---|
327 | DEBUG ((DEBUG_INFO, "DxeTpm2MeasureBootHandler - Cc MeasureGptTable - %r\n", Status));
|
---|
328 | } else if (Tcg2Protocol != NULL) {
|
---|
329 | //
|
---|
330 | // If Tcg2Protocol is installed, then Measure GPT data with this protocol.
|
---|
331 | //
|
---|
332 | Status = Tcg2Protocol->HashLogExtendEvent (
|
---|
333 | Tcg2Protocol,
|
---|
334 | 0,
|
---|
335 | (EFI_PHYSICAL_ADDRESS)(UINTN)(VOID *)GptData,
|
---|
336 | (UINT64)TcgEventSize - OFFSET_OF (EFI_TCG2_EVENT, Event),
|
---|
337 | Tcg2Event
|
---|
338 | );
|
---|
339 | if (!EFI_ERROR (Status)) {
|
---|
340 | mTcg2MeasureGptCount++;
|
---|
341 | }
|
---|
342 |
|
---|
343 | DEBUG ((DEBUG_INFO, "DxeTpm2MeasureBootHandler - Tcg2 MeasureGptTable - %r\n", Status));
|
---|
344 | }
|
---|
345 |
|
---|
346 | Exit:
|
---|
347 | if (PrimaryHeader != NULL) {
|
---|
348 | FreePool (PrimaryHeader);
|
---|
349 | }
|
---|
350 |
|
---|
351 | if (EntryPtr != NULL) {
|
---|
352 | FreePool (EntryPtr);
|
---|
353 | }
|
---|
354 |
|
---|
355 | if (EventPtr != NULL) {
|
---|
356 | FreePool (EventPtr);
|
---|
357 | }
|
---|
358 |
|
---|
359 | return Status;
|
---|
360 | }
|
---|
361 |
|
---|
362 | /**
|
---|
363 | Measure PE image into TPM log based on the authenticode image hashing in
|
---|
364 | PE/COFF Specification 8.0 Appendix A.
|
---|
365 |
|
---|
366 | Caution: This function may receive untrusted input.
|
---|
367 | PE/COFF image is external input, so this function will validate its data structure
|
---|
368 | within this image buffer before use.
|
---|
369 |
|
---|
370 | @param[in] MeasureBootProtocols Pointer to the located MeasureBoot protocol instances.
|
---|
371 | @param[in] ImageAddress Start address of image buffer.
|
---|
372 | @param[in] ImageSize Image size
|
---|
373 | @param[in] LinkTimeBase Address that the image is loaded into memory.
|
---|
374 | @param[in] ImageType Image subsystem type.
|
---|
375 | @param[in] FilePath File path is corresponding to the input image.
|
---|
376 |
|
---|
377 | @retval EFI_SUCCESS Successfully measure image.
|
---|
378 | @retval EFI_OUT_OF_RESOURCES No enough resource to measure image.
|
---|
379 | @retval EFI_UNSUPPORTED ImageType is unsupported or PE image is mal-format.
|
---|
380 | @retval other error value
|
---|
381 | **/
|
---|
382 | EFI_STATUS
|
---|
383 | EFIAPI
|
---|
384 | Tcg2MeasurePeImage (
|
---|
385 | IN MEASURE_BOOT_PROTOCOLS *MeasureBootProtocols,
|
---|
386 | IN EFI_PHYSICAL_ADDRESS ImageAddress,
|
---|
387 | IN UINTN ImageSize,
|
---|
388 | IN UINTN LinkTimeBase,
|
---|
389 | IN UINT16 ImageType,
|
---|
390 | IN EFI_DEVICE_PATH_PROTOCOL *FilePath
|
---|
391 | )
|
---|
392 | {
|
---|
393 | EFI_STATUS Status;
|
---|
394 | EFI_TCG2_EVENT *Tcg2Event;
|
---|
395 | EFI_IMAGE_LOAD_EVENT *ImageLoad;
|
---|
396 | UINT32 FilePathSize;
|
---|
397 | UINT32 EventSize;
|
---|
398 | EFI_CC_EVENT *CcEvent;
|
---|
399 | EFI_CC_MEASUREMENT_PROTOCOL *CcProtocol;
|
---|
400 | EFI_TCG2_PROTOCOL *Tcg2Protocol;
|
---|
401 | UINT8 *EventPtr;
|
---|
402 | EFI_CC_MR_INDEX MrIndex;
|
---|
403 |
|
---|
404 | Status = EFI_UNSUPPORTED;
|
---|
405 | ImageLoad = NULL;
|
---|
406 | EventPtr = NULL;
|
---|
407 | Tcg2Event = NULL;
|
---|
408 |
|
---|
409 | Tcg2Protocol = MeasureBootProtocols->Tcg2Protocol;
|
---|
410 | CcProtocol = MeasureBootProtocols->CcProtocol;
|
---|
411 |
|
---|
412 | if ((Tcg2Protocol == NULL) && (CcProtocol == NULL)) {
|
---|
413 | ASSERT (FALSE);
|
---|
414 | return EFI_UNSUPPORTED;
|
---|
415 | }
|
---|
416 |
|
---|
417 | if (sizeof (EFI_CC_EVENT) != sizeof (EFI_TCG2_EVENT)) {
|
---|
418 | ASSERT (FALSE);
|
---|
419 | return EFI_UNSUPPORTED;
|
---|
420 | }
|
---|
421 |
|
---|
422 | FilePathSize = (UINT32)GetDevicePathSize (FilePath);
|
---|
423 | Status = Tpm2SanitizePeImageEventSize (FilePathSize, &EventSize);
|
---|
424 | if (EFI_ERROR (Status)) {
|
---|
425 | return EFI_UNSUPPORTED;
|
---|
426 | }
|
---|
427 |
|
---|
428 | //
|
---|
429 | // Determine destination PCR by BootPolicy
|
---|
430 | //
|
---|
431 | // from a malicious GPT disk partition
|
---|
432 | EventPtr = AllocateZeroPool (EventSize);
|
---|
433 | if (EventPtr == NULL) {
|
---|
434 | return EFI_OUT_OF_RESOURCES;
|
---|
435 | }
|
---|
436 |
|
---|
437 | Tcg2Event = (EFI_TCG2_EVENT *)EventPtr;
|
---|
438 | Tcg2Event->Size = EventSize;
|
---|
439 | Tcg2Event->Header.HeaderSize = sizeof (EFI_TCG2_EVENT_HEADER);
|
---|
440 | Tcg2Event->Header.HeaderVersion = EFI_TCG2_EVENT_HEADER_VERSION;
|
---|
441 | ImageLoad = (EFI_IMAGE_LOAD_EVENT *)Tcg2Event->Event;
|
---|
442 |
|
---|
443 | switch (ImageType) {
|
---|
444 | case EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION:
|
---|
445 | Tcg2Event->Header.EventType = EV_EFI_BOOT_SERVICES_APPLICATION;
|
---|
446 | Tcg2Event->Header.PCRIndex = 4;
|
---|
447 | break;
|
---|
448 | case EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER:
|
---|
449 | Tcg2Event->Header.EventType = EV_EFI_BOOT_SERVICES_DRIVER;
|
---|
450 | Tcg2Event->Header.PCRIndex = 2;
|
---|
451 | break;
|
---|
452 | case EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER:
|
---|
453 | Tcg2Event->Header.EventType = EV_EFI_RUNTIME_SERVICES_DRIVER;
|
---|
454 | Tcg2Event->Header.PCRIndex = 2;
|
---|
455 | break;
|
---|
456 | default:
|
---|
457 | DEBUG (
|
---|
458 | (
|
---|
459 | DEBUG_ERROR,
|
---|
460 | "Tcg2MeasurePeImage: Unknown subsystem type %d",
|
---|
461 | ImageType
|
---|
462 | )
|
---|
463 | );
|
---|
464 | goto Finish;
|
---|
465 | }
|
---|
466 |
|
---|
467 | ImageLoad->ImageLocationInMemory = ImageAddress;
|
---|
468 | ImageLoad->ImageLengthInMemory = ImageSize;
|
---|
469 | ImageLoad->ImageLinkTimeAddress = LinkTimeBase;
|
---|
470 | ImageLoad->LengthOfDevicePath = FilePathSize;
|
---|
471 | if ((FilePath != NULL) && (FilePathSize != 0)) {
|
---|
472 | CopyMem (ImageLoad->DevicePath, FilePath, FilePathSize);
|
---|
473 | }
|
---|
474 |
|
---|
475 | //
|
---|
476 | // Log the PE data
|
---|
477 | //
|
---|
478 | if (CcProtocol != NULL) {
|
---|
479 | Status = CcProtocol->MapPcrToMrIndex (CcProtocol, Tcg2Event->Header.PCRIndex, &MrIndex);
|
---|
480 | if (EFI_ERROR (Status)) {
|
---|
481 | DEBUG ((DEBUG_ERROR, "Cannot map PcrIndex(%d) to MrIndex\n", Tcg2Event->Header.PCRIndex));
|
---|
482 | goto Finish;
|
---|
483 | }
|
---|
484 |
|
---|
485 | CcEvent = (EFI_CC_EVENT *)EventPtr;
|
---|
486 | CcEvent->Header.MrIndex = MrIndex;
|
---|
487 |
|
---|
488 | Status = CcProtocol->HashLogExtendEvent (
|
---|
489 | CcProtocol,
|
---|
490 | PE_COFF_IMAGE,
|
---|
491 | ImageAddress,
|
---|
492 | ImageSize,
|
---|
493 | CcEvent
|
---|
494 | );
|
---|
495 | DEBUG ((DEBUG_INFO, "DxeTpm2MeasureBootHandler - Cc MeasurePeImage - %r\n", Status));
|
---|
496 | } else if (Tcg2Protocol != NULL) {
|
---|
497 | Status = Tcg2Protocol->HashLogExtendEvent (
|
---|
498 | Tcg2Protocol,
|
---|
499 | PE_COFF_IMAGE,
|
---|
500 | ImageAddress,
|
---|
501 | ImageSize,
|
---|
502 | Tcg2Event
|
---|
503 | );
|
---|
504 | DEBUG ((DEBUG_INFO, "DxeTpm2MeasureBootHandler - Tcg2 MeasurePeImage - %r\n", Status));
|
---|
505 | }
|
---|
506 |
|
---|
507 | if (Status == EFI_VOLUME_FULL) {
|
---|
508 | //
|
---|
509 | // Volume full here means the image is hashed and its result is extended to PCR.
|
---|
510 | // But the event log can't be saved since log area is full.
|
---|
511 | // Just return EFI_SUCCESS in order not to block the image load.
|
---|
512 | //
|
---|
513 | Status = EFI_SUCCESS;
|
---|
514 | }
|
---|
515 |
|
---|
516 | Finish:
|
---|
517 | if (EventPtr != NULL) {
|
---|
518 | FreePool (EventPtr);
|
---|
519 | }
|
---|
520 |
|
---|
521 | return Status;
|
---|
522 | }
|
---|
523 |
|
---|
524 | /**
|
---|
525 | Get the measure boot protocols.
|
---|
526 |
|
---|
527 | There are 2 measure boot, TCG2 protocol based and Cc measurement protocol based.
|
---|
528 |
|
---|
529 | @param MeasureBootProtocols Pointer to the located measure boot protocol instances.
|
---|
530 |
|
---|
531 | @retval EFI_SUCCESS Successfully locate the measure boot protocol instances (at least one instance).
|
---|
532 | @retval EFI_UNSUPPORTED Measure boot is not supported.
|
---|
533 | **/
|
---|
534 | EFI_STATUS
|
---|
535 | EFIAPI
|
---|
536 | GetMeasureBootProtocols (
|
---|
537 | MEASURE_BOOT_PROTOCOLS *MeasureBootProtocols
|
---|
538 | )
|
---|
539 | {
|
---|
540 | EFI_STATUS Status;
|
---|
541 | EFI_TCG2_PROTOCOL *Tcg2Protocol;
|
---|
542 | EFI_CC_MEASUREMENT_PROTOCOL *CcProtocol;
|
---|
543 | EFI_TCG2_BOOT_SERVICE_CAPABILITY Tcg2ProtocolCapability;
|
---|
544 | EFI_CC_BOOT_SERVICE_CAPABILITY CcProtocolCapability;
|
---|
545 |
|
---|
546 | CcProtocol = NULL;
|
---|
547 | Status = gBS->LocateProtocol (&gEfiCcMeasurementProtocolGuid, NULL, (VOID **)&CcProtocol);
|
---|
548 | if (EFI_ERROR (Status)) {
|
---|
549 | //
|
---|
550 | // Cc Measurement protocol is not installed.
|
---|
551 | //
|
---|
552 | DEBUG ((DEBUG_VERBOSE, "CcMeasurementProtocol is not installed. - %r\n", Status));
|
---|
553 | } else {
|
---|
554 | ZeroMem (&CcProtocolCapability, sizeof (CcProtocolCapability));
|
---|
555 | CcProtocolCapability.Size = sizeof (CcProtocolCapability);
|
---|
556 | Status = CcProtocol->GetCapability (CcProtocol, &CcProtocolCapability);
|
---|
557 | if (EFI_ERROR (Status) || (CcProtocolCapability.CcType.Type == EFI_CC_TYPE_NONE)) {
|
---|
558 | DEBUG ((DEBUG_ERROR, " CcProtocol->GetCapability returns : %x, %r\n", CcProtocolCapability.CcType.Type, Status));
|
---|
559 | CcProtocol = NULL;
|
---|
560 | }
|
---|
561 | }
|
---|
562 |
|
---|
563 | Tcg2Protocol = NULL;
|
---|
564 | Status = gBS->LocateProtocol (&gEfiTcg2ProtocolGuid, NULL, (VOID **)&Tcg2Protocol);
|
---|
565 | if (EFI_ERROR (Status)) {
|
---|
566 | //
|
---|
567 | // Tcg2 protocol is not installed. So, TPM2 is not present.
|
---|
568 | //
|
---|
569 | DEBUG ((DEBUG_VERBOSE, "Tcg2Protocol is not installed. - %r\n", Status));
|
---|
570 | } else {
|
---|
571 | Tcg2ProtocolCapability.Size = (UINT8)sizeof (Tcg2ProtocolCapability);
|
---|
572 | Status = Tcg2Protocol->GetCapability (Tcg2Protocol, &Tcg2ProtocolCapability);
|
---|
573 | if (EFI_ERROR (Status) || (!Tcg2ProtocolCapability.TPMPresentFlag)) {
|
---|
574 | //
|
---|
575 | // TPM device doesn't work or activate.
|
---|
576 | //
|
---|
577 | DEBUG ((DEBUG_ERROR, "TPMPresentFlag=FALSE %r\n", Status));
|
---|
578 | Tcg2Protocol = NULL;
|
---|
579 | }
|
---|
580 | }
|
---|
581 |
|
---|
582 | MeasureBootProtocols->Tcg2Protocol = Tcg2Protocol;
|
---|
583 | MeasureBootProtocols->CcProtocol = CcProtocol;
|
---|
584 |
|
---|
585 | return (Tcg2Protocol == NULL && CcProtocol == NULL) ? EFI_UNSUPPORTED : EFI_SUCCESS;
|
---|
586 | }
|
---|
587 |
|
---|
588 | /**
|
---|
589 | The security handler is used to abstract platform-specific policy
|
---|
590 | from the DXE core response to an attempt to use a file that returns a
|
---|
591 | given status for the authentication check from the section extraction protocol.
|
---|
592 |
|
---|
593 | The possible responses in a given SAP implementation may include locking
|
---|
594 | flash upon failure to authenticate, attestation logging for all signed drivers,
|
---|
595 | and other exception operations. The File parameter allows for possible logging
|
---|
596 | within the SAP of the driver.
|
---|
597 |
|
---|
598 | If the file specified by File with an authentication status specified by
|
---|
599 | AuthenticationStatus is safe for the DXE Core to use, then EFI_SUCCESS is returned.
|
---|
600 |
|
---|
601 | If the file specified by File with an authentication status specified by
|
---|
602 | AuthenticationStatus is not safe for the DXE Core to use under any circumstances,
|
---|
603 | then EFI_ACCESS_DENIED is returned.
|
---|
604 |
|
---|
605 | If the file specified by File with an authentication status specified by
|
---|
606 | AuthenticationStatus is not safe for the DXE Core to use right now, but it
|
---|
607 | might be possible to use it at a future time, then EFI_SECURITY_VIOLATION is
|
---|
608 | returned.
|
---|
609 |
|
---|
610 | If check image specified by FileBuffer and File is NULL meanwhile, return EFI_ACCESS_DENIED.
|
---|
611 |
|
---|
612 | @param[in] AuthenticationStatus This is the authentication status returned
|
---|
613 | from the securitymeasurement services for the
|
---|
614 | input file.
|
---|
615 | @param[in] File This is a pointer to the device path of the file that is
|
---|
616 | being dispatched. This will optionally be used for logging.
|
---|
617 | @param[in] FileBuffer File buffer matches the input file device path.
|
---|
618 | @param[in] FileSize Size of File buffer matches the input file device path.
|
---|
619 | @param[in] BootPolicy A boot policy that was used to call LoadImage() UEFI service.
|
---|
620 |
|
---|
621 | @retval EFI_SUCCESS The file specified by DevicePath and non-NULL
|
---|
622 | FileBuffer did authenticate, and the platform policy dictates
|
---|
623 | that the DXE Foundation may use the file.
|
---|
624 | @retval other error value
|
---|
625 | **/
|
---|
626 | EFI_STATUS
|
---|
627 | EFIAPI
|
---|
628 | DxeTpm2MeasureBootHandler (
|
---|
629 | IN UINT32 AuthenticationStatus,
|
---|
630 | IN CONST EFI_DEVICE_PATH_PROTOCOL *File OPTIONAL,
|
---|
631 | IN VOID *FileBuffer,
|
---|
632 | IN UINTN FileSize,
|
---|
633 | IN BOOLEAN BootPolicy
|
---|
634 | )
|
---|
635 | {
|
---|
636 | MEASURE_BOOT_PROTOCOLS MeasureBootProtocols;
|
---|
637 | EFI_STATUS Status;
|
---|
638 | EFI_DEVICE_PATH_PROTOCOL *DevicePathNode;
|
---|
639 | EFI_DEVICE_PATH_PROTOCOL *OrigDevicePathNode;
|
---|
640 | EFI_HANDLE Handle;
|
---|
641 | EFI_HANDLE TempHandle;
|
---|
642 | BOOLEAN ApplicationRequired;
|
---|
643 | PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
|
---|
644 | EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvbProtocol;
|
---|
645 | EFI_PHYSICAL_ADDRESS FvAddress;
|
---|
646 | UINT32 Index;
|
---|
647 |
|
---|
648 | MeasureBootProtocols.Tcg2Protocol = NULL;
|
---|
649 | MeasureBootProtocols.CcProtocol = NULL;
|
---|
650 |
|
---|
651 | Status = GetMeasureBootProtocols (&MeasureBootProtocols);
|
---|
652 |
|
---|
653 | if (EFI_ERROR (Status)) {
|
---|
654 | //
|
---|
655 | // None of Measured boot protocols (Tcg2, Cc) is installed.
|
---|
656 | // Don't do any measurement, and directly return EFI_SUCCESS.
|
---|
657 | //
|
---|
658 | DEBUG ((DEBUG_INFO, "None of Tcg2Protocol/CcMeasurementProtocol is installed.\n"));
|
---|
659 | return EFI_SUCCESS;
|
---|
660 | }
|
---|
661 |
|
---|
662 | DEBUG (
|
---|
663 | (
|
---|
664 | DEBUG_INFO,
|
---|
665 | "Tcg2Protocol = %p, CcMeasurementProtocol = %p\n",
|
---|
666 | MeasureBootProtocols.Tcg2Protocol,
|
---|
667 | MeasureBootProtocols.CcProtocol
|
---|
668 | )
|
---|
669 | );
|
---|
670 |
|
---|
671 | //
|
---|
672 | // Copy File Device Path
|
---|
673 | //
|
---|
674 | OrigDevicePathNode = DuplicateDevicePath (File);
|
---|
675 |
|
---|
676 | //
|
---|
677 | // 1. Check whether this device path support BlockIo protocol.
|
---|
678 | // Is so, this device path may be a GPT device path.
|
---|
679 | //
|
---|
680 | DevicePathNode = OrigDevicePathNode;
|
---|
681 | Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &DevicePathNode, &Handle);
|
---|
682 | if (!EFI_ERROR (Status) && !mTcg2MeasureGptTableFlag) {
|
---|
683 | //
|
---|
684 | // Find the gpt partition on the given devicepath
|
---|
685 | //
|
---|
686 | DevicePathNode = OrigDevicePathNode;
|
---|
687 | ASSERT (DevicePathNode != NULL);
|
---|
688 | while (!IsDevicePathEnd (DevicePathNode)) {
|
---|
689 | //
|
---|
690 | // Find the Gpt partition
|
---|
691 | //
|
---|
692 | if ((DevicePathType (DevicePathNode) == MEDIA_DEVICE_PATH) &&
|
---|
693 | (DevicePathSubType (DevicePathNode) == MEDIA_HARDDRIVE_DP))
|
---|
694 | {
|
---|
695 | //
|
---|
696 | // Check whether it is a gpt partition or not
|
---|
697 | //
|
---|
698 | if ((((HARDDRIVE_DEVICE_PATH *)DevicePathNode)->MBRType == MBR_TYPE_EFI_PARTITION_TABLE_HEADER) &&
|
---|
699 | (((HARDDRIVE_DEVICE_PATH *)DevicePathNode)->SignatureType == SIGNATURE_TYPE_GUID))
|
---|
700 | {
|
---|
701 | //
|
---|
702 | // Change the partition device path to its parent device path (disk) and get the handle.
|
---|
703 | //
|
---|
704 | DevicePathNode->Type = END_DEVICE_PATH_TYPE;
|
---|
705 | DevicePathNode->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
|
---|
706 | DevicePathNode = OrigDevicePathNode;
|
---|
707 | Status = gBS->LocateDevicePath (
|
---|
708 | &gEfiDiskIoProtocolGuid,
|
---|
709 | &DevicePathNode,
|
---|
710 | &Handle
|
---|
711 | );
|
---|
712 | if (!EFI_ERROR (Status)) {
|
---|
713 | //
|
---|
714 | // Measure GPT disk.
|
---|
715 | //
|
---|
716 | Status = Tcg2MeasureGptTable (&MeasureBootProtocols, Handle);
|
---|
717 |
|
---|
718 | if (!EFI_ERROR (Status)) {
|
---|
719 | //
|
---|
720 | // GPT disk check done.
|
---|
721 | //
|
---|
722 | mTcg2MeasureGptTableFlag = TRUE;
|
---|
723 | }
|
---|
724 | }
|
---|
725 |
|
---|
726 | FreePool (OrigDevicePathNode);
|
---|
727 | OrigDevicePathNode = DuplicateDevicePath (File);
|
---|
728 | ASSERT (OrigDevicePathNode != NULL);
|
---|
729 | break;
|
---|
730 | }
|
---|
731 | }
|
---|
732 |
|
---|
733 | DevicePathNode = NextDevicePathNode (DevicePathNode);
|
---|
734 | }
|
---|
735 | }
|
---|
736 |
|
---|
737 | //
|
---|
738 | // 2. Measure PE image.
|
---|
739 | //
|
---|
740 | ApplicationRequired = FALSE;
|
---|
741 |
|
---|
742 | //
|
---|
743 | // Check whether this device path support FVB protocol.
|
---|
744 | //
|
---|
745 | DevicePathNode = OrigDevicePathNode;
|
---|
746 | Status = gBS->LocateDevicePath (&gEfiFirmwareVolumeBlockProtocolGuid, &DevicePathNode, &Handle);
|
---|
747 | if (!EFI_ERROR (Status)) {
|
---|
748 | //
|
---|
749 | // Don't check FV image, and directly return EFI_SUCCESS.
|
---|
750 | // It can be extended to the specific FV authentication according to the different requirement.
|
---|
751 | //
|
---|
752 | if (IsDevicePathEnd (DevicePathNode)) {
|
---|
753 | return EFI_SUCCESS;
|
---|
754 | }
|
---|
755 |
|
---|
756 | //
|
---|
757 | // The PE image from unmeasured Firmware volume need be measured
|
---|
758 | // The PE image from measured Firmware volume will be measured according to policy below.
|
---|
759 | // If it is driver, do not measure
|
---|
760 | // If it is application, still measure.
|
---|
761 | //
|
---|
762 | ApplicationRequired = TRUE;
|
---|
763 |
|
---|
764 | if ((mTcg2CacheMeasuredHandle != Handle) && (mTcg2MeasuredHobData != NULL)) {
|
---|
765 | //
|
---|
766 | // Search for Root FV of this PE image
|
---|
767 | //
|
---|
768 | TempHandle = Handle;
|
---|
769 | do {
|
---|
770 | Status = gBS->HandleProtocol (
|
---|
771 | TempHandle,
|
---|
772 | &gEfiFirmwareVolumeBlockProtocolGuid,
|
---|
773 | (VOID **)&FvbProtocol
|
---|
774 | );
|
---|
775 | TempHandle = FvbProtocol->ParentHandle;
|
---|
776 | } while (!EFI_ERROR (Status) && FvbProtocol->ParentHandle != NULL);
|
---|
777 |
|
---|
778 | //
|
---|
779 | // Search in measured FV Hob
|
---|
780 | //
|
---|
781 | Status = FvbProtocol->GetPhysicalAddress (FvbProtocol, &FvAddress);
|
---|
782 | if (EFI_ERROR (Status)) {
|
---|
783 | return Status;
|
---|
784 | }
|
---|
785 |
|
---|
786 | ApplicationRequired = FALSE;
|
---|
787 |
|
---|
788 | for (Index = 0; Index < mTcg2MeasuredHobData->Num; Index++) {
|
---|
789 | if (mTcg2MeasuredHobData->MeasuredFvBuf[Index].BlobBase == FvAddress) {
|
---|
790 | //
|
---|
791 | // Cache measured FV for next measurement
|
---|
792 | //
|
---|
793 | mTcg2CacheMeasuredHandle = Handle;
|
---|
794 | ApplicationRequired = TRUE;
|
---|
795 | break;
|
---|
796 | }
|
---|
797 | }
|
---|
798 | }
|
---|
799 | }
|
---|
800 |
|
---|
801 | //
|
---|
802 | // File is not found.
|
---|
803 | //
|
---|
804 | if (FileBuffer == NULL) {
|
---|
805 | Status = EFI_SECURITY_VIOLATION;
|
---|
806 | goto Finish;
|
---|
807 | }
|
---|
808 |
|
---|
809 | mTcg2ImageSize = FileSize;
|
---|
810 | mTcg2FileBuffer = FileBuffer;
|
---|
811 |
|
---|
812 | //
|
---|
813 | // Measure PE Image
|
---|
814 | //
|
---|
815 | DevicePathNode = OrigDevicePathNode;
|
---|
816 | ZeroMem (&ImageContext, sizeof (ImageContext));
|
---|
817 | ImageContext.Handle = (VOID *)FileBuffer;
|
---|
818 | ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE)DxeTpm2MeasureBootLibImageRead;
|
---|
819 |
|
---|
820 | //
|
---|
821 | // Get information about the image being loaded
|
---|
822 | //
|
---|
823 | Status = PeCoffLoaderGetImageInfo (&ImageContext);
|
---|
824 | if (EFI_ERROR (Status)) {
|
---|
825 | //
|
---|
826 | // Check for invalid parameters.
|
---|
827 | //
|
---|
828 | if (File == NULL) {
|
---|
829 | Status = EFI_ACCESS_DENIED;
|
---|
830 | }
|
---|
831 |
|
---|
832 | //
|
---|
833 | // The information can't be got from the invalid PeImage
|
---|
834 | //
|
---|
835 | goto Finish;
|
---|
836 | }
|
---|
837 |
|
---|
838 | //
|
---|
839 | // Measure only application if Application flag is set
|
---|
840 | // Measure drivers and applications if Application flag is not set
|
---|
841 | //
|
---|
842 | if ((!ApplicationRequired) ||
|
---|
843 | (ApplicationRequired && (ImageContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION)))
|
---|
844 | {
|
---|
845 | //
|
---|
846 | // Print the image path to be measured.
|
---|
847 | //
|
---|
848 | DEBUG_CODE_BEGIN ();
|
---|
849 | CHAR16 *ToText;
|
---|
850 | ToText = ConvertDevicePathToText (
|
---|
851 | DevicePathNode,
|
---|
852 | FALSE,
|
---|
853 | TRUE
|
---|
854 | );
|
---|
855 | if (ToText != NULL) {
|
---|
856 | DEBUG ((DEBUG_INFO, "The measured image path is %s.\n", ToText));
|
---|
857 | FreePool (ToText);
|
---|
858 | }
|
---|
859 |
|
---|
860 | DEBUG_CODE_END ();
|
---|
861 |
|
---|
862 | //
|
---|
863 | // Measure PE image into TPM log.
|
---|
864 | //
|
---|
865 | Status = Tcg2MeasurePeImage (
|
---|
866 | &MeasureBootProtocols,
|
---|
867 | (EFI_PHYSICAL_ADDRESS)(UINTN)FileBuffer,
|
---|
868 | FileSize,
|
---|
869 | (UINTN)ImageContext.ImageAddress,
|
---|
870 | ImageContext.ImageType,
|
---|
871 | DevicePathNode
|
---|
872 | );
|
---|
873 | }
|
---|
874 |
|
---|
875 | //
|
---|
876 | // Done, free the allocated resource.
|
---|
877 | //
|
---|
878 | Finish:
|
---|
879 | if (OrigDevicePathNode != NULL) {
|
---|
880 | FreePool (OrigDevicePathNode);
|
---|
881 | }
|
---|
882 |
|
---|
883 | DEBUG ((DEBUG_INFO, "DxeTpm2MeasureBootHandler - %r\n", Status));
|
---|
884 |
|
---|
885 | return Status;
|
---|
886 | }
|
---|
887 |
|
---|
888 | /**
|
---|
889 | Register the security handler to provide TPM measure boot service.
|
---|
890 |
|
---|
891 | @param ImageHandle ImageHandle of the loaded driver.
|
---|
892 | @param SystemTable Pointer to the EFI System Table.
|
---|
893 |
|
---|
894 | @retval EFI_SUCCESS Register successfully.
|
---|
895 | @retval EFI_OUT_OF_RESOURCES No enough memory to register this handler.
|
---|
896 | **/
|
---|
897 | EFI_STATUS
|
---|
898 | EFIAPI
|
---|
899 | DxeTpm2MeasureBootLibConstructor (
|
---|
900 | IN EFI_HANDLE ImageHandle,
|
---|
901 | IN EFI_SYSTEM_TABLE *SystemTable
|
---|
902 | )
|
---|
903 | {
|
---|
904 | EFI_HOB_GUID_TYPE *GuidHob;
|
---|
905 |
|
---|
906 | GuidHob = NULL;
|
---|
907 |
|
---|
908 | GuidHob = GetFirstGuidHob (&gMeasuredFvHobGuid);
|
---|
909 |
|
---|
910 | if (GuidHob != NULL) {
|
---|
911 | mTcg2MeasuredHobData = GET_GUID_HOB_DATA (GuidHob);
|
---|
912 | }
|
---|
913 |
|
---|
914 | return RegisterSecurity2Handler (
|
---|
915 | DxeTpm2MeasureBootHandler,
|
---|
916 | EFI_AUTH_OPERATION_MEASURE_IMAGE | EFI_AUTH_OPERATION_IMAGE_REQUIRED
|
---|
917 | );
|
---|
918 | }
|
---|