]> git.proxmox.com Git - mirror_edk2.git/blob - SecurityPkg/Tcg/TrEEDxe/TrEEDxe.c
SecurityPkg: Tcg2Dxe: Report correct FinalEventLog size
[mirror_edk2.git] / SecurityPkg / Tcg / TrEEDxe / TrEEDxe.c
1 /** @file
2 This module implements TrEE Protocol.
3
4 Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #include <PiDxe.h>
16 #include <IndustryStandard/Acpi.h>
17 #include <IndustryStandard/PeImage.h>
18 #include <IndustryStandard/TcpaAcpi.h>
19
20 #include <Guid/GlobalVariable.h>
21 #include <Guid/HobList.h>
22 #include <Guid/TcgEventHob.h>
23 #include <Guid/EventGroup.h>
24 #include <Guid/EventExitBootServiceFailed.h>
25 #include <Guid/ImageAuthentication.h>
26 #include <Guid/TpmInstance.h>
27
28 #include <Protocol/DevicePath.h>
29 #include <Protocol/AcpiTable.h>
30 #include <Protocol/MpService.h>
31 #include <Protocol/VariableWrite.h>
32 #include <Protocol/TrEEProtocol.h>
33
34 #include <Library/DebugLib.h>
35 #include <Library/BaseMemoryLib.h>
36 #include <Library/UefiRuntimeServicesTableLib.h>
37 #include <Library/UefiDriverEntryPoint.h>
38 #include <Library/HobLib.h>
39 #include <Library/UefiBootServicesTableLib.h>
40 #include <Library/BaseLib.h>
41 #include <Library/MemoryAllocationLib.h>
42 #include <Library/PrintLib.h>
43 #include <Library/Tpm2CommandLib.h>
44 #include <Library/PcdLib.h>
45 #include <Library/UefiLib.h>
46 #include <Library/Tpm2DeviceLib.h>
47 #include <Library/HashLib.h>
48 #include <Library/PerformanceLib.h>
49 #include <Library/ReportStatusCodeLib.h>
50
51 #define PERF_ID_TREE_DXE 0x3120
52
53 typedef struct {
54 CHAR16 *VariableName;
55 EFI_GUID *VendorGuid;
56 } VARIABLE_TYPE;
57
58 #define TREE_DEFAULT_MAX_COMMAND_SIZE 0x1000
59 #define TREE_DEFAULT_MAX_RESPONSE_SIZE 0x1000
60
61 typedef struct {
62 EFI_GUID *EventGuid;
63 TREE_EVENT_LOG_FORMAT LogFormat;
64 } TREE_EVENT_INFO_STRUCT;
65
66 TREE_EVENT_INFO_STRUCT mTreeEventInfo[] = {
67 {&gTcgEventEntryHobGuid, TREE_EVENT_LOG_FORMAT_TCG_1_2},
68 };
69
70 #define TCG_EVENT_LOG_AREA_COUNT_MAX 2
71
72 typedef struct {
73 TREE_EVENT_LOG_FORMAT EventLogFormat;
74 EFI_PHYSICAL_ADDRESS Lasa;
75 UINT64 Laml;
76 UINTN EventLogSize;
77 UINT8 *LastEvent;
78 BOOLEAN EventLogStarted;
79 BOOLEAN EventLogTruncated;
80 } TCG_EVENT_LOG_AREA_STRUCT;
81
82 typedef struct _TCG_DXE_DATA {
83 TREE_BOOT_SERVICE_CAPABILITY BsCap;
84 EFI_TCG_CLIENT_ACPI_TABLE *TcgClientAcpiTable;
85 EFI_TCG_SERVER_ACPI_TABLE *TcgServerAcpiTable;
86 TCG_EVENT_LOG_AREA_STRUCT EventLogAreaStruct[TCG_EVENT_LOG_AREA_COUNT_MAX];
87 } TCG_DXE_DATA;
88
89 EFI_TCG_CLIENT_ACPI_TABLE mTcgClientAcpiTemplate = {
90 {
91 EFI_ACPI_3_0_TRUSTED_COMPUTING_PLATFORM_ALLIANCE_CAPABILITIES_TABLE_SIGNATURE,
92 sizeof (mTcgClientAcpiTemplate),
93 0x02 //Revision
94 //
95 // Compiler initializes the remaining bytes to 0
96 // These fields should be filled in in production
97 //
98 },
99 0, // 0 for PC Client Platform Class
100 0, // Log Area Max Length
101 (EFI_PHYSICAL_ADDRESS) (SIZE_4GB - 1) // Log Area Start Address
102 };
103
104 //
105 // The following EFI_TCG_SERVER_ACPI_TABLE default setting is just one example,
106 // the TPM device connectes to LPC, and also defined the ACPI _UID as 0xFF,
107 // this _UID can be changed and should match with the _UID setting of the TPM
108 // ACPI device object
109 //
110 EFI_TCG_SERVER_ACPI_TABLE mTcgServerAcpiTemplate = {
111 {
112 EFI_ACPI_3_0_TRUSTED_COMPUTING_PLATFORM_ALLIANCE_CAPABILITIES_TABLE_SIGNATURE,
113 sizeof (mTcgServerAcpiTemplate),
114 0x02 //Revision
115 //
116 // Compiler initializes the remaining bytes to 0
117 // These fields should be filled in in production
118 //
119 },
120 1, // 1 for Server Platform Class
121 0, // Reserved
122 0, // Log Area Max Length
123 (EFI_PHYSICAL_ADDRESS) (SIZE_4GB - 1), // Log Area Start Address
124 0x0100, // TCG Specification revision 1.0
125 2, // Device Flags
126 0, // Interrupt Flags
127 0, // GPE
128 {0}, // Reserved 3 bytes
129 0, // Global System Interrupt
130 {
131 EFI_ACPI_3_0_SYSTEM_MEMORY,
132 0,
133 0,
134 EFI_ACPI_3_0_BYTE,
135 0x0 // Base Address
136 },
137 0, // Reserved
138 {0}, // Configuration Address
139 0xFF, // ACPI _UID value of the device, can be changed for different platforms
140 0, // ACPI _UID value of the device, can be changed for different platforms
141 0, // ACPI _UID value of the device, can be changed for different platforms
142 0 // ACPI _UID value of the device, can be changed for different platforms
143 };
144
145 TCG_DXE_DATA mTcgDxeData = {
146 {
147 sizeof (TREE_BOOT_SERVICE_CAPABILITY_1_0), // Size
148 { 1, 0 }, // StructureVersion
149 { 1, 0 }, // ProtocolVersion
150 TREE_BOOT_HASH_ALG_SHA1, // HashAlgorithmBitmap
151 TREE_EVENT_LOG_FORMAT_TCG_1_2, // SupportedEventLogs
152 TRUE, // TrEEPresentFlag
153 TREE_DEFAULT_MAX_COMMAND_SIZE, // MaxCommandSize
154 TREE_DEFAULT_MAX_RESPONSE_SIZE, // MaxResponseSize
155 0 // ManufacturerID
156 },
157 &mTcgClientAcpiTemplate,
158 &mTcgServerAcpiTemplate,
159 };
160
161 UINTN mBootAttempts = 0;
162 CHAR16 mBootVarName[] = L"BootOrder";
163
164 VARIABLE_TYPE mVariableType[] = {
165 {EFI_SECURE_BOOT_MODE_NAME, &gEfiGlobalVariableGuid},
166 {EFI_PLATFORM_KEY_NAME, &gEfiGlobalVariableGuid},
167 {EFI_KEY_EXCHANGE_KEY_NAME, &gEfiGlobalVariableGuid},
168 {EFI_IMAGE_SECURITY_DATABASE, &gEfiImageSecurityDatabaseGuid},
169 {EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid},
170 };
171
172 EFI_HANDLE mImageHandle;
173
174 /**
175 Measure PE image into TPM log based on the authenticode image hashing in
176 PE/COFF Specification 8.0 Appendix A.
177
178 Caution: This function may receive untrusted input.
179 PE/COFF image is external input, so this function will validate its data structure
180 within this image buffer before use.
181
182 Notes: PE/COFF image is checked by BasePeCoffLib PeCoffLoaderGetImageInfo().
183
184 @param[in] PCRIndex TPM PCR index
185 @param[in] ImageAddress Start address of image buffer.
186 @param[in] ImageSize Image size
187 @param[out] DigestList Digeest list of this image.
188
189 @retval EFI_SUCCESS Successfully measure image.
190 @retval EFI_OUT_OF_RESOURCES No enough resource to measure image.
191 @retval other error value
192 **/
193 EFI_STATUS
194 MeasurePeImageAndExtend (
195 IN UINT32 PCRIndex,
196 IN EFI_PHYSICAL_ADDRESS ImageAddress,
197 IN UINTN ImageSize,
198 OUT TPML_DIGEST_VALUES *DigestList
199 );
200
201 /**
202
203 This function dump raw data.
204
205 @param Data raw data
206 @param Size raw data size
207
208 **/
209 VOID
210 InternalDumpData (
211 IN UINT8 *Data,
212 IN UINTN Size
213 )
214 {
215 UINTN Index;
216 for (Index = 0; Index < Size; Index++) {
217 DEBUG ((EFI_D_INFO, "%02x", (UINTN)Data[Index]));
218 }
219 }
220
221 /**
222
223 This function dump raw data with colume format.
224
225 @param Data raw data
226 @param Size raw data size
227
228 **/
229 VOID
230 InternalDumpHex (
231 IN UINT8 *Data,
232 IN UINTN Size
233 )
234 {
235 UINTN Index;
236 UINTN Count;
237 UINTN Left;
238
239 #define COLUME_SIZE (16 * 2)
240
241 Count = Size / COLUME_SIZE;
242 Left = Size % COLUME_SIZE;
243 for (Index = 0; Index < Count; Index++) {
244 DEBUG ((EFI_D_INFO, "%04x: ", Index * COLUME_SIZE));
245 InternalDumpData (Data + Index * COLUME_SIZE, COLUME_SIZE);
246 DEBUG ((EFI_D_INFO, "\n"));
247 }
248
249 if (Left != 0) {
250 DEBUG ((EFI_D_INFO, "%04x: ", Index * COLUME_SIZE));
251 InternalDumpData (Data + Index * COLUME_SIZE, Left);
252 DEBUG ((EFI_D_INFO, "\n"));
253 }
254 }
255
256 /**
257 Get All processors EFI_CPU_LOCATION in system. LocationBuf is allocated inside the function
258 Caller is responsible to free LocationBuf.
259
260 @param[out] LocationBuf Returns Processor Location Buffer.
261 @param[out] Num Returns processor number.
262
263 @retval EFI_SUCCESS Operation completed successfully.
264 @retval EFI_UNSUPPORTED MpService protocol not found.
265
266 **/
267 EFI_STATUS
268 GetProcessorsCpuLocation (
269 OUT EFI_CPU_PHYSICAL_LOCATION **LocationBuf,
270 OUT UINTN *Num
271 )
272 {
273 EFI_STATUS Status;
274 EFI_MP_SERVICES_PROTOCOL *MpProtocol;
275 UINTN ProcessorNum;
276 UINTN EnabledProcessorNum;
277 EFI_PROCESSOR_INFORMATION ProcessorInfo;
278 EFI_CPU_PHYSICAL_LOCATION *ProcessorLocBuf;
279 UINTN Index;
280
281 Status = gBS->LocateProtocol (&gEfiMpServiceProtocolGuid, NULL, (VOID **) &MpProtocol);
282 if (EFI_ERROR (Status)) {
283 //
284 // MP protocol is not installed
285 //
286 return EFI_UNSUPPORTED;
287 }
288
289 Status = MpProtocol->GetNumberOfProcessors(
290 MpProtocol,
291 &ProcessorNum,
292 &EnabledProcessorNum
293 );
294 if (EFI_ERROR(Status)){
295 return Status;
296 }
297
298 Status = gBS->AllocatePool(
299 EfiBootServicesData,
300 sizeof(EFI_CPU_PHYSICAL_LOCATION) * ProcessorNum,
301 (VOID **) &ProcessorLocBuf
302 );
303 if (EFI_ERROR(Status)){
304 return Status;
305 }
306
307 //
308 // Get each processor Location info
309 //
310 for (Index = 0; Index < ProcessorNum; Index++) {
311 Status = MpProtocol->GetProcessorInfo(
312 MpProtocol,
313 Index,
314 &ProcessorInfo
315 );
316 if (EFI_ERROR(Status)){
317 FreePool(ProcessorLocBuf);
318 return Status;
319 }
320
321 //
322 // Get all Processor Location info & measure
323 //
324 CopyMem(
325 &ProcessorLocBuf[Index],
326 &ProcessorInfo.Location,
327 sizeof(EFI_CPU_PHYSICAL_LOCATION)
328 );
329 }
330
331 *LocationBuf = ProcessorLocBuf;
332 *Num = ProcessorNum;
333
334 return Status;
335 }
336
337 /**
338 The EFI_TREE_PROTOCOL GetCapability function call provides protocol
339 capability information and state information about the TrEE.
340
341 @param[in] This Indicates the calling context
342 @param[in, out] ProtocolCapability The caller allocates memory for a TREE_BOOT_SERVICE_CAPABILITY
343 structure and sets the size field to the size of the structure allocated.
344 The callee fills in the fields with the EFI protocol capability information
345 and the current TrEE state information up to the number of fields which
346 fit within the size of the structure passed in.
347
348 @retval EFI_SUCCESS Operation completed successfully.
349 @retval EFI_DEVICE_ERROR The command was unsuccessful.
350 The ProtocolCapability variable will not be populated.
351 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
352 The ProtocolCapability variable will not be populated.
353 @retval EFI_BUFFER_TOO_SMALL The ProtocolCapability variable is too small to hold the full response.
354 It will be partially populated (required Size field will be set).
355 **/
356 EFI_STATUS
357 EFIAPI
358 TreeGetCapability (
359 IN EFI_TREE_PROTOCOL *This,
360 IN OUT TREE_BOOT_SERVICE_CAPABILITY *ProtocolCapability
361 )
362 {
363 DEBUG ((EFI_D_INFO, "TreeGetCapability ...\n"));
364
365 if ((This == NULL) || (ProtocolCapability == NULL)) {
366 return EFI_INVALID_PARAMETER;
367 }
368
369 if (ProtocolCapability->Size < mTcgDxeData.BsCap.Size) {
370 ProtocolCapability->Size = mTcgDxeData.BsCap.Size;
371 return EFI_BUFFER_TOO_SMALL;
372 }
373
374 CopyMem (ProtocolCapability, &mTcgDxeData.BsCap, mTcgDxeData.BsCap.Size);
375 DEBUG ((EFI_D_INFO, "TreeGetCapability - %r\n", EFI_SUCCESS));
376 return EFI_SUCCESS;
377 }
378
379 /**
380 This function dump event log.
381
382 @param[in] EventLogFormat The type of the event log for which the information is requested.
383 @param[in] EventLogLocation A pointer to the memory address of the event log.
384 @param[in] EventLogLastEntry If the Event Log contains more than one entry, this is a pointer to the
385 address of the start of the last entry in the event log in memory.
386 **/
387 VOID
388 DumpEventLog (
389 IN TREE_EVENT_LOG_FORMAT EventLogFormat,
390 IN EFI_PHYSICAL_ADDRESS EventLogLocation,
391 IN EFI_PHYSICAL_ADDRESS EventLogLastEntry
392 )
393 {
394 TCG_PCR_EVENT_HDR *EventHdr;
395 UINTN Index;
396
397 DEBUG ((EFI_D_INFO, "EventLogFormat: (0x%x)\n", EventLogFormat));
398
399 switch (EventLogFormat) {
400 case TREE_EVENT_LOG_FORMAT_TCG_1_2:
401 EventHdr = (TCG_PCR_EVENT_HDR *)(UINTN)EventLogLocation;
402 while ((UINTN)EventHdr <= EventLogLastEntry) {
403 DEBUG ((EFI_D_INFO, " Event:\n"));
404 DEBUG ((EFI_D_INFO, " PCRIndex - %d\n", EventHdr->PCRIndex));
405 DEBUG ((EFI_D_INFO, " EventType - 0x%08x\n", EventHdr->EventType));
406 DEBUG ((EFI_D_INFO, " Digest - "));
407 for (Index = 0; Index < sizeof(TCG_DIGEST); Index++) {
408 DEBUG ((EFI_D_INFO, "%02x ", EventHdr->Digest.digest[Index]));
409 }
410 DEBUG ((EFI_D_INFO, "\n"));
411 DEBUG ((EFI_D_INFO, " EventSize - 0x%08x\n", EventHdr->EventSize));
412 InternalDumpHex ((UINT8 *)(EventHdr + 1), EventHdr->EventSize);
413 EventHdr = (TCG_PCR_EVENT_HDR *)((UINTN)EventHdr + sizeof(TCG_PCR_EVENT_HDR) + EventHdr->EventSize);
414 }
415 break;
416 }
417
418 return ;
419 }
420
421 /**
422 The EFI_TREE_PROTOCOL Get Event Log function call allows a caller to
423 retrieve the address of a given event log and its last entry.
424
425 @param[in] This Indicates the calling context
426 @param[in] EventLogFormat The type of the event log for which the information is requested.
427 @param[out] EventLogLocation A pointer to the memory address of the event log.
428 @param[out] EventLogLastEntry If the Event Log contains more than one entry, this is a pointer to the
429 address of the start of the last entry in the event log in memory.
430 @param[out] EventLogTruncated If the Event Log is missing at least one entry because an event would
431 have exceeded the area allocated for events, this value is set to TRUE.
432 Otherwise, the value will be FALSE and the Event Log will be complete.
433
434 @retval EFI_SUCCESS Operation completed successfully.
435 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect
436 (e.g. asking for an event log whose format is not supported).
437 **/
438 EFI_STATUS
439 EFIAPI
440 TreeGetEventLog (
441 IN EFI_TREE_PROTOCOL *This,
442 IN TREE_EVENT_LOG_FORMAT EventLogFormat,
443 OUT EFI_PHYSICAL_ADDRESS *EventLogLocation,
444 OUT EFI_PHYSICAL_ADDRESS *EventLogLastEntry,
445 OUT BOOLEAN *EventLogTruncated
446 )
447 {
448 UINTN Index;
449
450 DEBUG ((EFI_D_INFO, "TreeGetEventLog ...\n"));
451
452 if (This == NULL) {
453 return EFI_INVALID_PARAMETER;
454 }
455
456 for (Index = 0; Index < sizeof(mTreeEventInfo)/sizeof(mTreeEventInfo[0]); Index++) {
457 if (EventLogFormat == mTreeEventInfo[Index].LogFormat) {
458 break;
459 }
460 }
461
462 if (Index == sizeof(mTreeEventInfo)/sizeof(mTreeEventInfo[0])) {
463 return EFI_INVALID_PARAMETER;
464 }
465
466 if (!mTcgDxeData.BsCap.TrEEPresentFlag) {
467 if (EventLogLocation != NULL) {
468 *EventLogLocation = 0;
469 }
470 if (EventLogLastEntry != NULL) {
471 *EventLogLastEntry = 0;
472 }
473 if (EventLogTruncated != NULL) {
474 *EventLogTruncated = FALSE;
475 }
476 return EFI_SUCCESS;
477 }
478
479 if (EventLogLocation != NULL) {
480 *EventLogLocation = mTcgDxeData.EventLogAreaStruct[Index].Lasa;
481 DEBUG ((EFI_D_INFO, "TreeGetEventLog (EventLogLocation - %x)\n", *EventLogLocation));
482 }
483
484 if (EventLogLastEntry != NULL) {
485 if (!mTcgDxeData.EventLogAreaStruct[Index].EventLogStarted) {
486 *EventLogLastEntry = (EFI_PHYSICAL_ADDRESS)(UINTN)0;
487 } else {
488 *EventLogLastEntry = (EFI_PHYSICAL_ADDRESS)(UINTN)mTcgDxeData.EventLogAreaStruct[Index].LastEvent;
489 }
490 DEBUG ((EFI_D_INFO, "TreeGetEventLog (EventLogLastEntry - %x)\n", *EventLogLastEntry));
491 }
492
493 if (EventLogTruncated != NULL) {
494 *EventLogTruncated = mTcgDxeData.EventLogAreaStruct[Index].EventLogTruncated;
495 DEBUG ((EFI_D_INFO, "TreeGetEventLog (EventLogTruncated - %x)\n", *EventLogTruncated));
496 }
497
498 DEBUG ((EFI_D_INFO, "TreeGetEventLog - %r\n", EFI_SUCCESS));
499
500 // Dump Event Log for debug purpose
501 if ((EventLogLocation != NULL) && (EventLogLastEntry != NULL)) {
502 DumpEventLog (EventLogFormat, *EventLogLocation, *EventLogLastEntry);
503 }
504
505 return EFI_SUCCESS;
506 }
507
508 /**
509 Add a new entry to the Event Log.
510
511 @param[in, out] EventLogPtr Pointer to the Event Log data.
512 @param[in, out] LogSize Size of the Event Log.
513 @param[in] MaxSize Maximum size of the Event Log.
514 @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR/TCG_PCR_EVENT_EX data structure.
515 @param[in] NewEventHdrSize New event header size.
516 @param[in] NewEventData Pointer to the new event data.
517 @param[in] NewEventSize New event data size.
518
519 @retval EFI_SUCCESS The new event log entry was added.
520 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
521
522 **/
523 EFI_STATUS
524 TcgCommLogEvent (
525 IN OUT UINT8 **EventLogPtr,
526 IN OUT UINTN *LogSize,
527 IN UINTN MaxSize,
528 IN VOID *NewEventHdr,
529 IN UINT32 NewEventHdrSize,
530 IN UINT8 *NewEventData,
531 IN UINT32 NewEventSize
532 )
533 {
534 UINTN NewLogSize;
535
536 if (NewEventSize > MAX_ADDRESS - NewEventHdrSize) {
537 return EFI_OUT_OF_RESOURCES;
538 }
539
540 NewLogSize = NewEventHdrSize + NewEventSize;
541
542 if (NewLogSize > MAX_ADDRESS - *LogSize) {
543 return EFI_OUT_OF_RESOURCES;
544 }
545
546 if (NewLogSize + *LogSize > MaxSize) {
547 DEBUG ((EFI_D_INFO, " MaxSize - 0x%x\n", MaxSize));
548 DEBUG ((EFI_D_INFO, " NewLogSize - 0x%x\n", NewLogSize));
549 DEBUG ((EFI_D_INFO, " LogSize - 0x%x\n", *LogSize));
550 DEBUG ((EFI_D_INFO, "TcgCommLogEvent - %r\n", EFI_OUT_OF_RESOURCES));
551 return EFI_OUT_OF_RESOURCES;
552 }
553
554 *EventLogPtr += *LogSize;
555 *LogSize += NewLogSize;
556 CopyMem (*EventLogPtr, NewEventHdr, NewEventHdrSize);
557 CopyMem (
558 *EventLogPtr + NewEventHdrSize,
559 NewEventData,
560 NewEventSize
561 );
562 return EFI_SUCCESS;
563 }
564
565 /**
566 Add a new entry to the Event Log.
567
568 @param[in] EventLogFormat The type of the event log for which the information is requested.
569 @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR/TCG_PCR_EVENT_EX data structure.
570 @param[in] NewEventHdrSize New event header size.
571 @param[in] NewEventData Pointer to the new event data.
572 @param[in] NewEventSize New event data size.
573
574 @retval EFI_SUCCESS The new event log entry was added.
575 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
576
577 **/
578 EFI_STATUS
579 TcgDxeLogEvent (
580 IN TREE_EVENT_LOG_FORMAT EventLogFormat,
581 IN VOID *NewEventHdr,
582 IN UINT32 NewEventHdrSize,
583 IN UINT8 *NewEventData,
584 IN UINT32 NewEventSize
585 )
586 {
587 EFI_STATUS Status;
588 UINTN Index;
589
590 for (Index = 0; Index < sizeof(mTreeEventInfo)/sizeof(mTreeEventInfo[0]); Index++) {
591 if (EventLogFormat == mTreeEventInfo[Index].LogFormat) {
592 break;
593 }
594 }
595
596 if (Index == sizeof(mTreeEventInfo)/sizeof(mTreeEventInfo[0])) {
597 return EFI_INVALID_PARAMETER;
598 }
599
600 if (mTcgDxeData.EventLogAreaStruct[Index].EventLogTruncated) {
601 return EFI_VOLUME_FULL;
602 }
603
604 mTcgDxeData.EventLogAreaStruct[Index].LastEvent = (UINT8*)(UINTN)mTcgDxeData.EventLogAreaStruct[Index].Lasa;
605 Status = TcgCommLogEvent (
606 &mTcgDxeData.EventLogAreaStruct[Index].LastEvent,
607 &mTcgDxeData.EventLogAreaStruct[Index].EventLogSize,
608 (UINTN)mTcgDxeData.EventLogAreaStruct[Index].Laml,
609 NewEventHdr,
610 NewEventHdrSize,
611 NewEventData,
612 NewEventSize
613 );
614
615 if (Status == EFI_DEVICE_ERROR) {
616 return EFI_DEVICE_ERROR;
617 } else if (Status == EFI_OUT_OF_RESOURCES) {
618 mTcgDxeData.EventLogAreaStruct[Index].EventLogTruncated = TRUE;
619 return EFI_VOLUME_FULL;
620 } else if (Status == EFI_SUCCESS) {
621 mTcgDxeData.EventLogAreaStruct[Index].EventLogStarted = TRUE;
622 }
623
624 return Status;
625 }
626
627 /**
628 Add a new entry to the Event Log.
629
630 @param[in] DigestList A list of digest.
631 @param[in,out] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.
632 @param[in] NewEventData Pointer to the new event data.
633
634 @retval EFI_SUCCESS The new event log entry was added.
635 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
636 **/
637 EFI_STATUS
638 TcgDxeLogHashEvent (
639 IN TPML_DIGEST_VALUES *DigestList,
640 IN OUT TCG_PCR_EVENT_HDR *NewEventHdr,
641 IN UINT8 *NewEventData
642 )
643 {
644 EFI_STATUS Status;
645 EFI_TPL OldTpl;
646 UINTN Index;
647 EFI_STATUS RetStatus;
648
649 RetStatus = EFI_SUCCESS;
650 for (Index = 0; Index < sizeof(mTreeEventInfo)/sizeof(mTreeEventInfo[0]); Index++) {
651 DEBUG ((EFI_D_INFO, " LogFormat - 0x%08x\n", mTreeEventInfo[Index].LogFormat));
652 switch (mTreeEventInfo[Index].LogFormat) {
653 case TREE_EVENT_LOG_FORMAT_TCG_1_2:
654 Status = GetDigestFromDigestList (TPM_ALG_SHA1, DigestList, &NewEventHdr->Digest);
655 if (!EFI_ERROR (Status)) {
656 //
657 // Enter critical region
658 //
659 OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);
660 Status = TcgDxeLogEvent (
661 mTreeEventInfo[Index].LogFormat,
662 NewEventHdr,
663 sizeof(TCG_PCR_EVENT_HDR),
664 NewEventData,
665 NewEventHdr->EventSize
666 );
667 if (Status != EFI_SUCCESS) {
668 RetStatus = Status;
669 }
670 gBS->RestoreTPL (OldTpl);
671 //
672 // Exit critical region
673 //
674 }
675 break;
676 }
677 }
678
679 return RetStatus;
680 }
681
682 /**
683 Do a hash operation on a data buffer, extend a specific TPM PCR with the hash result,
684 and add an entry to the Event Log.
685
686 @param[in] Flags Bitmap providing additional information.
687 @param[in] HashData Physical address of the start of the data buffer
688 to be hashed, extended, and logged.
689 @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData
690 @param[in, out] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.
691 @param[in] NewEventData Pointer to the new event data.
692
693 @retval EFI_SUCCESS Operation completed successfully.
694 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
695 @retval EFI_DEVICE_ERROR The command was unsuccessful.
696
697 **/
698 EFI_STATUS
699 TcgDxeHashLogExtendEvent (
700 IN UINT64 Flags,
701 IN UINT8 *HashData,
702 IN UINT64 HashDataLen,
703 IN OUT TCG_PCR_EVENT_HDR *NewEventHdr,
704 IN UINT8 *NewEventData
705 )
706 {
707 EFI_STATUS Status;
708 TPML_DIGEST_VALUES DigestList;
709
710 if (!mTcgDxeData.BsCap.TrEEPresentFlag) {
711 return EFI_DEVICE_ERROR;
712 }
713
714 Status = HashAndExtend (
715 NewEventHdr->PCRIndex,
716 HashData,
717 (UINTN)HashDataLen,
718 &DigestList
719 );
720 if (!EFI_ERROR (Status)) {
721 if ((Flags & TREE_EXTEND_ONLY) == 0) {
722 Status = TcgDxeLogHashEvent (&DigestList, NewEventHdr, NewEventData);
723 }
724 }
725
726 if (Status == EFI_DEVICE_ERROR) {
727 DEBUG ((EFI_D_ERROR, "TcgDxeHashLogExtendEvent - %r. Disable TPM.\n", Status));
728 mTcgDxeData.BsCap.TrEEPresentFlag = FALSE;
729 REPORT_STATUS_CODE (
730 EFI_ERROR_CODE | EFI_ERROR_MINOR,
731 (PcdGet32 (PcdStatusCodeSubClassTpmDevice) | EFI_P_EC_INTERFACE_ERROR)
732 );
733 }
734
735 return Status;
736 }
737
738 /**
739 The EFI_TREE_PROTOCOL HashLogExtendEvent function call provides callers with
740 an opportunity to extend and optionally log events without requiring
741 knowledge of actual TPM commands.
742 The extend operation will occur even if this function cannot create an event
743 log entry (e.g. due to the event log being full).
744
745 @param[in] This Indicates the calling context
746 @param[in] Flags Bitmap providing additional information.
747 @param[in] DataToHash Physical address of the start of the data buffer to be hashed.
748 @param[in] DataToHashLen The length in bytes of the buffer referenced by DataToHash.
749 @param[in] Event Pointer to data buffer containing information about the event.
750
751 @retval EFI_SUCCESS Operation completed successfully.
752 @retval EFI_DEVICE_ERROR The command was unsuccessful.
753 @retval EFI_VOLUME_FULL The extend operation occurred, but the event could not be written to one or more event logs.
754 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
755 @retval EFI_UNSUPPORTED The PE/COFF image type is not supported.
756 **/
757 EFI_STATUS
758 EFIAPI
759 TreeHashLogExtendEvent (
760 IN EFI_TREE_PROTOCOL *This,
761 IN UINT64 Flags,
762 IN EFI_PHYSICAL_ADDRESS DataToHash,
763 IN UINT64 DataToHashLen,
764 IN TrEE_EVENT *Event
765 )
766 {
767 EFI_STATUS Status;
768 TCG_PCR_EVENT_HDR NewEventHdr;
769 TPML_DIGEST_VALUES DigestList;
770
771 DEBUG ((EFI_D_INFO, "TreeHashLogExtendEvent ...\n"));
772
773 if ((This == NULL) || (DataToHash == 0) || (Event == NULL)) {
774 return EFI_INVALID_PARAMETER;
775 }
776
777 if (!mTcgDxeData.BsCap.TrEEPresentFlag) {
778 return EFI_UNSUPPORTED;
779 }
780
781 if (Event->Size < Event->Header.HeaderSize + sizeof(UINT32)) {
782 return EFI_INVALID_PARAMETER;
783 }
784
785 if (Event->Header.PCRIndex > MAX_PCR_INDEX) {
786 return EFI_INVALID_PARAMETER;
787 }
788
789 NewEventHdr.PCRIndex = Event->Header.PCRIndex;
790 NewEventHdr.EventType = Event->Header.EventType;
791 NewEventHdr.EventSize = Event->Size - sizeof(UINT32) - Event->Header.HeaderSize;
792 if ((Flags & PE_COFF_IMAGE) != 0) {
793 Status = MeasurePeImageAndExtend (
794 NewEventHdr.PCRIndex,
795 DataToHash,
796 (UINTN)DataToHashLen,
797 &DigestList
798 );
799 if (!EFI_ERROR (Status)) {
800 if ((Flags & TREE_EXTEND_ONLY) == 0) {
801 Status = TcgDxeLogHashEvent (&DigestList, &NewEventHdr, Event->Event);
802 }
803 }
804 if (Status == EFI_DEVICE_ERROR) {
805 DEBUG ((EFI_D_ERROR, "MeasurePeImageAndExtend - %r. Disable TPM.\n", Status));
806 mTcgDxeData.BsCap.TrEEPresentFlag = FALSE;
807 REPORT_STATUS_CODE (
808 EFI_ERROR_CODE | EFI_ERROR_MINOR,
809 (PcdGet32 (PcdStatusCodeSubClassTpmDevice) | EFI_P_EC_INTERFACE_ERROR)
810 );
811 }
812 } else {
813 Status = TcgDxeHashLogExtendEvent (
814 Flags,
815 (UINT8 *) (UINTN) DataToHash,
816 DataToHashLen,
817 &NewEventHdr,
818 Event->Event
819 );
820 }
821 DEBUG ((EFI_D_INFO, "TreeHashLogExtendEvent - %r\n", Status));
822 return Status;
823 }
824
825 /**
826 This service enables the sending of commands to the TrEE.
827
828 @param[in] This Indicates the calling context
829 @param[in] InputParameterBlockSize Size of the TrEE input parameter block.
830 @param[in] InputParameterBlock Pointer to the TrEE input parameter block.
831 @param[in] OutputParameterBlockSize Size of the TrEE output parameter block.
832 @param[in] OutputParameterBlock Pointer to the TrEE output parameter block.
833
834 @retval EFI_SUCCESS The command byte stream was successfully sent to the device and a response was successfully received.
835 @retval EFI_DEVICE_ERROR The command was not successfully sent to the device or a response was not successfully received from the device.
836 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
837 @retval EFI_BUFFER_TOO_SMALL The output parameter block is too small.
838 **/
839 EFI_STATUS
840 EFIAPI
841 TreeSubmitCommand (
842 IN EFI_TREE_PROTOCOL *This,
843 IN UINT32 InputParameterBlockSize,
844 IN UINT8 *InputParameterBlock,
845 IN UINT32 OutputParameterBlockSize,
846 IN UINT8 *OutputParameterBlock
847 )
848 {
849 EFI_STATUS Status;
850
851 DEBUG ((EFI_D_INFO, "TreeSubmitCommand ...\n"));
852
853 if ((This == NULL) ||
854 (InputParameterBlockSize == 0) || (InputParameterBlock == NULL) ||
855 (OutputParameterBlockSize == 0) || (OutputParameterBlock == NULL)) {
856 return EFI_INVALID_PARAMETER;
857 }
858
859 if (!mTcgDxeData.BsCap.TrEEPresentFlag) {
860 return EFI_UNSUPPORTED;
861 }
862
863 if (InputParameterBlockSize > mTcgDxeData.BsCap.MaxCommandSize) {
864 return EFI_INVALID_PARAMETER;
865 }
866 if (OutputParameterBlockSize > mTcgDxeData.BsCap.MaxResponseSize) {
867 return EFI_INVALID_PARAMETER;
868 }
869
870 Status = Tpm2SubmitCommand (
871 InputParameterBlockSize,
872 InputParameterBlock,
873 &OutputParameterBlockSize,
874 OutputParameterBlock
875 );
876 DEBUG ((EFI_D_INFO, "TreeSubmitCommand - %r\n", Status));
877 return Status;
878 }
879
880
881 EFI_TREE_PROTOCOL mTreeProtocol = {
882 TreeGetCapability,
883 TreeGetEventLog,
884 TreeHashLogExtendEvent,
885 TreeSubmitCommand
886 };
887
888 /**
889 Initialize the Event Log and log events passed from the PEI phase.
890
891 @retval EFI_SUCCESS Operation completed successfully.
892 @retval EFI_OUT_OF_RESOURCES Out of memory.
893
894 **/
895 EFI_STATUS
896 SetupEventLog (
897 VOID
898 )
899 {
900 EFI_STATUS Status;
901 VOID *TcgEvent;
902 EFI_PEI_HOB_POINTERS GuidHob;
903 EFI_PHYSICAL_ADDRESS Lasa;
904 UINTN Index;
905
906 DEBUG ((EFI_D_INFO, "SetupEventLog\n"));
907
908 //
909 // 1. Create Log Area
910 //
911 for (Index = 0; Index < sizeof(mTreeEventInfo)/sizeof(mTreeEventInfo[0]); Index++) {
912 mTcgDxeData.EventLogAreaStruct[Index].EventLogFormat = mTreeEventInfo[Index].LogFormat;
913 Lasa = (EFI_PHYSICAL_ADDRESS) (SIZE_4GB - 1);
914 Status = gBS->AllocatePages (
915 AllocateMaxAddress,
916 EfiACPIMemoryNVS,
917 EFI_SIZE_TO_PAGES (PcdGet32 (PcdTcgLogAreaMinLen)),
918 &Lasa
919 );
920 if (EFI_ERROR (Status)) {
921 return Status;
922 }
923 mTcgDxeData.EventLogAreaStruct[Index].Lasa = Lasa;
924 mTcgDxeData.EventLogAreaStruct[Index].Laml = PcdGet32 (PcdTcgLogAreaMinLen);
925 //
926 // To initialize them as 0xFF is recommended
927 // because the OS can know the last entry for that.
928 //
929 SetMem ((VOID *)(UINTN)Lasa, PcdGet32 (PcdTcgLogAreaMinLen), 0xFF);
930 }
931
932 //
933 // 2. Create ACPI table for TCG1.2 only
934 //
935 if (PcdGet8 (PcdTpmPlatformClass) == TCG_PLATFORM_TYPE_CLIENT) {
936 mTcgClientAcpiTemplate.Lasa = mTcgDxeData.EventLogAreaStruct[0].Lasa;
937 mTcgClientAcpiTemplate.Laml = PcdGet32 (PcdTcgLogAreaMinLen);
938 } else {
939 mTcgServerAcpiTemplate.Lasa = mTcgDxeData.EventLogAreaStruct[0].Lasa;
940 mTcgServerAcpiTemplate.Laml = PcdGet32 (PcdTcgLogAreaMinLen);
941 }
942
943 //
944 // 3. Sync data from PEI to DXE
945 //
946 Status = EFI_SUCCESS;
947 for (Index = 0; Index < sizeof(mTreeEventInfo)/sizeof(mTreeEventInfo[0]); Index++) {
948 GuidHob.Raw = GetHobList ();
949 Status = EFI_SUCCESS;
950 while (!EFI_ERROR (Status) &&
951 (GuidHob.Raw = GetNextGuidHob (mTreeEventInfo[Index].EventGuid, GuidHob.Raw)) != NULL) {
952 TcgEvent = GET_GUID_HOB_DATA (GuidHob.Guid);
953 GuidHob.Raw = GET_NEXT_HOB (GuidHob);
954 switch (mTreeEventInfo[Index].LogFormat) {
955 case TREE_EVENT_LOG_FORMAT_TCG_1_2:
956 Status = TcgDxeLogEvent (
957 mTreeEventInfo[Index].LogFormat,
958 TcgEvent,
959 sizeof(TCG_PCR_EVENT_HDR),
960 ((TCG_PCR_EVENT*)TcgEvent)->Event,
961 ((TCG_PCR_EVENT_HDR*)TcgEvent)->EventSize
962 );
963 break;
964 }
965 }
966 }
967
968 return Status;
969 }
970
971 /**
972 Measure and log an action string, and extend the measurement result into PCR[5].
973
974 @param[in] String A specific string that indicates an Action event.
975
976 @retval EFI_SUCCESS Operation completed successfully.
977 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
978
979 **/
980 EFI_STATUS
981 TcgMeasureAction (
982 IN CHAR8 *String
983 )
984 {
985 TCG_PCR_EVENT_HDR TcgEvent;
986
987 TcgEvent.PCRIndex = 5;
988 TcgEvent.EventType = EV_EFI_ACTION;
989 TcgEvent.EventSize = (UINT32)AsciiStrLen (String);
990 return TcgDxeHashLogExtendEvent (
991 0,
992 (UINT8*)String,
993 TcgEvent.EventSize,
994 &TcgEvent,
995 (UINT8 *) String
996 );
997 }
998
999 /**
1000 Measure and log EFI handoff tables, and extend the measurement result into PCR[1].
1001
1002 @retval EFI_SUCCESS Operation completed successfully.
1003 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1004
1005 **/
1006 EFI_STATUS
1007 MeasureHandoffTables (
1008 VOID
1009 )
1010 {
1011 EFI_STATUS Status;
1012 TCG_PCR_EVENT_HDR TcgEvent;
1013 EFI_HANDOFF_TABLE_POINTERS HandoffTables;
1014 UINTN ProcessorNum;
1015 EFI_CPU_PHYSICAL_LOCATION *ProcessorLocBuf;
1016
1017 ProcessorLocBuf = NULL;
1018 Status = EFI_SUCCESS;
1019
1020 if (PcdGet8 (PcdTpmPlatformClass) == TCG_PLATFORM_TYPE_SERVER) {
1021 //
1022 // Tcg Server spec.
1023 // Measure each processor EFI_CPU_PHYSICAL_LOCATION with EV_TABLE_OF_DEVICES to PCR[1]
1024 //
1025 Status = GetProcessorsCpuLocation(&ProcessorLocBuf, &ProcessorNum);
1026
1027 if (!EFI_ERROR(Status)){
1028 TcgEvent.PCRIndex = 1;
1029 TcgEvent.EventType = EV_TABLE_OF_DEVICES;
1030 TcgEvent.EventSize = sizeof (HandoffTables);
1031
1032 HandoffTables.NumberOfTables = 1;
1033 HandoffTables.TableEntry[0].VendorGuid = gEfiMpServiceProtocolGuid;
1034 HandoffTables.TableEntry[0].VendorTable = ProcessorLocBuf;
1035
1036 Status = TcgDxeHashLogExtendEvent (
1037 0,
1038 (UINT8*)(UINTN)ProcessorLocBuf,
1039 sizeof(EFI_CPU_PHYSICAL_LOCATION) * ProcessorNum,
1040 &TcgEvent,
1041 (UINT8*)&HandoffTables
1042 );
1043
1044 FreePool(ProcessorLocBuf);
1045 }
1046 }
1047
1048 return Status;
1049 }
1050
1051 /**
1052 Measure and log Separator event, and extend the measurement result into a specific PCR.
1053
1054 @param[in] PCRIndex PCR index.
1055
1056 @retval EFI_SUCCESS Operation completed successfully.
1057 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1058
1059 **/
1060 EFI_STATUS
1061 MeasureSeparatorEvent (
1062 IN TPM_PCRINDEX PCRIndex
1063 )
1064 {
1065 TCG_PCR_EVENT_HDR TcgEvent;
1066 UINT32 EventData;
1067
1068 DEBUG ((EFI_D_INFO, "MeasureSeparatorEvent Pcr - %x\n", PCRIndex));
1069
1070 EventData = 0;
1071 TcgEvent.PCRIndex = PCRIndex;
1072 TcgEvent.EventType = EV_SEPARATOR;
1073 TcgEvent.EventSize = (UINT32)sizeof (EventData);
1074 return TcgDxeHashLogExtendEvent (
1075 0,
1076 (UINT8 *)&EventData,
1077 sizeof (EventData),
1078 &TcgEvent,
1079 (UINT8 *)&EventData
1080 );
1081 }
1082
1083 /**
1084 Measure and log an EFI variable, and extend the measurement result into a specific PCR.
1085
1086 @param[in] PCRIndex PCR Index.
1087 @param[in] EventType Event type.
1088 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
1089 @param[in] VendorGuid A unique identifier for the vendor.
1090 @param[in] VarData The content of the variable data.
1091 @param[in] VarSize The size of the variable data.
1092
1093 @retval EFI_SUCCESS Operation completed successfully.
1094 @retval EFI_OUT_OF_RESOURCES Out of memory.
1095 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1096
1097 **/
1098 EFI_STATUS
1099 MeasureVariable (
1100 IN TPM_PCRINDEX PCRIndex,
1101 IN TCG_EVENTTYPE EventType,
1102 IN CHAR16 *VarName,
1103 IN EFI_GUID *VendorGuid,
1104 IN VOID *VarData,
1105 IN UINTN VarSize
1106 )
1107 {
1108 EFI_STATUS Status;
1109 TCG_PCR_EVENT_HDR TcgEvent;
1110 UINTN VarNameLength;
1111 EFI_VARIABLE_DATA_TREE *VarLog;
1112
1113 DEBUG ((EFI_D_INFO, "TrEEDxe: MeasureVariable (Pcr - %x, EventType - %x, ", (UINTN)PCRIndex, (UINTN)EventType));
1114 DEBUG ((EFI_D_INFO, "VariableName - %s, VendorGuid - %g)\n", VarName, VendorGuid));
1115
1116 VarNameLength = StrLen (VarName);
1117 TcgEvent.PCRIndex = PCRIndex;
1118 TcgEvent.EventType = EventType;
1119 TcgEvent.EventSize = (UINT32)(sizeof (*VarLog) + VarNameLength * sizeof (*VarName) + VarSize
1120 - sizeof (VarLog->UnicodeName) - sizeof (VarLog->VariableData));
1121
1122 VarLog = (EFI_VARIABLE_DATA_TREE*)AllocatePool (TcgEvent.EventSize);
1123 if (VarLog == NULL) {
1124 return EFI_OUT_OF_RESOURCES;
1125 }
1126
1127 VarLog->VariableName = *VendorGuid;
1128 VarLog->UnicodeNameLength = VarNameLength;
1129 VarLog->VariableDataLength = VarSize;
1130 CopyMem (
1131 VarLog->UnicodeName,
1132 VarName,
1133 VarNameLength * sizeof (*VarName)
1134 );
1135 if (VarSize != 0 && VarData != NULL) {
1136 CopyMem (
1137 (CHAR16 *)VarLog->UnicodeName + VarNameLength,
1138 VarData,
1139 VarSize
1140 );
1141 }
1142
1143 Status = TcgDxeHashLogExtendEvent (
1144 0,
1145 (UINT8*)VarLog,
1146 TcgEvent.EventSize,
1147 &TcgEvent,
1148 (UINT8*)VarLog
1149 );
1150
1151 FreePool (VarLog);
1152 return Status;
1153 }
1154
1155 /**
1156 Read then Measure and log an EFI variable, and extend the measurement result into a specific PCR.
1157
1158 @param[in] PCRIndex PCR Index.
1159 @param[in] EventType Event type.
1160 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
1161 @param[in] VendorGuid A unique identifier for the vendor.
1162 @param[out] VarSize The size of the variable data.
1163 @param[out] VarData Pointer to the content of the variable.
1164
1165 @retval EFI_SUCCESS Operation completed successfully.
1166 @retval EFI_OUT_OF_RESOURCES Out of memory.
1167 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1168
1169 **/
1170 EFI_STATUS
1171 ReadAndMeasureVariable (
1172 IN TPM_PCRINDEX PCRIndex,
1173 IN TCG_EVENTTYPE EventType,
1174 IN CHAR16 *VarName,
1175 IN EFI_GUID *VendorGuid,
1176 OUT UINTN *VarSize,
1177 OUT VOID **VarData
1178 )
1179 {
1180 EFI_STATUS Status;
1181
1182 Status = GetVariable2 (VarName, VendorGuid, VarData, VarSize);
1183 if (EventType == EV_EFI_VARIABLE_DRIVER_CONFIG) {
1184 if (EFI_ERROR (Status)) {
1185 //
1186 // It is valid case, so we need handle it.
1187 //
1188 *VarData = NULL;
1189 *VarSize = 0;
1190 }
1191 } else {
1192 //
1193 // if status error, VarData is freed and set NULL by GetVariable2
1194 //
1195 if (EFI_ERROR (Status)) {
1196 return EFI_NOT_FOUND;
1197 }
1198 }
1199
1200 Status = MeasureVariable (
1201 PCRIndex,
1202 EventType,
1203 VarName,
1204 VendorGuid,
1205 *VarData,
1206 *VarSize
1207 );
1208 return Status;
1209 }
1210
1211 /**
1212 Read then Measure and log an EFI boot variable, and extend the measurement result into PCR[5].
1213
1214 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
1215 @param[in] VendorGuid A unique identifier for the vendor.
1216 @param[out] VarSize The size of the variable data.
1217 @param[out] VarData Pointer to the content of the variable.
1218
1219 @retval EFI_SUCCESS Operation completed successfully.
1220 @retval EFI_OUT_OF_RESOURCES Out of memory.
1221 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1222
1223 **/
1224 EFI_STATUS
1225 ReadAndMeasureBootVariable (
1226 IN CHAR16 *VarName,
1227 IN EFI_GUID *VendorGuid,
1228 OUT UINTN *VarSize,
1229 OUT VOID **VarData
1230 )
1231 {
1232 return ReadAndMeasureVariable (
1233 5,
1234 EV_EFI_VARIABLE_BOOT,
1235 VarName,
1236 VendorGuid,
1237 VarSize,
1238 VarData
1239 );
1240 }
1241
1242 /**
1243 Read then Measure and log an EFI Secure variable, and extend the measurement result into PCR[7].
1244
1245 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
1246 @param[in] VendorGuid A unique identifier for the vendor.
1247 @param[out] VarSize The size of the variable data.
1248 @param[out] VarData Pointer to the content of the variable.
1249
1250 @retval EFI_SUCCESS Operation completed successfully.
1251 @retval EFI_OUT_OF_RESOURCES Out of memory.
1252 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1253
1254 **/
1255 EFI_STATUS
1256 ReadAndMeasureSecureVariable (
1257 IN CHAR16 *VarName,
1258 IN EFI_GUID *VendorGuid,
1259 OUT UINTN *VarSize,
1260 OUT VOID **VarData
1261 )
1262 {
1263 return ReadAndMeasureVariable (
1264 7,
1265 EV_EFI_VARIABLE_DRIVER_CONFIG,
1266 VarName,
1267 VendorGuid,
1268 VarSize,
1269 VarData
1270 );
1271 }
1272
1273 /**
1274 Measure and log all EFI boot variables, and extend the measurement result into a specific PCR.
1275
1276 The EFI boot variables are BootOrder and Boot#### variables.
1277
1278 @retval EFI_SUCCESS Operation completed successfully.
1279 @retval EFI_OUT_OF_RESOURCES Out of memory.
1280 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1281
1282 **/
1283 EFI_STATUS
1284 MeasureAllBootVariables (
1285 VOID
1286 )
1287 {
1288 EFI_STATUS Status;
1289 UINT16 *BootOrder;
1290 UINTN BootCount;
1291 UINTN Index;
1292 VOID *BootVarData;
1293 UINTN Size;
1294
1295 Status = ReadAndMeasureBootVariable (
1296 mBootVarName,
1297 &gEfiGlobalVariableGuid,
1298 &BootCount,
1299 (VOID **) &BootOrder
1300 );
1301 if (Status == EFI_NOT_FOUND || BootOrder == NULL) {
1302 return EFI_SUCCESS;
1303 }
1304
1305 if (EFI_ERROR (Status)) {
1306 //
1307 // BootOrder can't be NULL if status is not EFI_NOT_FOUND
1308 //
1309 FreePool (BootOrder);
1310 return Status;
1311 }
1312
1313 BootCount /= sizeof (*BootOrder);
1314 for (Index = 0; Index < BootCount; Index++) {
1315 UnicodeSPrint (mBootVarName, sizeof (mBootVarName), L"Boot%04x", BootOrder[Index]);
1316 Status = ReadAndMeasureBootVariable (
1317 mBootVarName,
1318 &gEfiGlobalVariableGuid,
1319 &Size,
1320 &BootVarData
1321 );
1322 if (!EFI_ERROR (Status)) {
1323 FreePool (BootVarData);
1324 }
1325 }
1326
1327 FreePool (BootOrder);
1328 return EFI_SUCCESS;
1329 }
1330
1331 /**
1332 Measure and log all EFI Secure variables, and extend the measurement result into a specific PCR.
1333
1334 The EFI boot variables are BootOrder and Boot#### variables.
1335
1336 @retval EFI_SUCCESS Operation completed successfully.
1337 @retval EFI_OUT_OF_RESOURCES Out of memory.
1338 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1339
1340 **/
1341 EFI_STATUS
1342 MeasureAllSecureVariables (
1343 VOID
1344 )
1345 {
1346 EFI_STATUS Status;
1347 VOID *Data;
1348 UINTN DataSize;
1349 UINTN Index;
1350
1351 Status = EFI_NOT_FOUND;
1352 for (Index = 0; Index < sizeof(mVariableType)/sizeof(mVariableType[0]); Index++) {
1353 Status = ReadAndMeasureSecureVariable (
1354 mVariableType[Index].VariableName,
1355 mVariableType[Index].VendorGuid,
1356 &DataSize,
1357 &Data
1358 );
1359 if (!EFI_ERROR (Status)) {
1360 if (Data != NULL) {
1361 FreePool (Data);
1362 }
1363 }
1364 }
1365
1366 return EFI_SUCCESS;
1367 }
1368
1369 /**
1370 Measure and log launch of FirmwareDebugger, and extend the measurement result into a specific PCR.
1371
1372 @retval EFI_SUCCESS Operation completed successfully.
1373 @retval EFI_OUT_OF_RESOURCES Out of memory.
1374 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1375
1376 **/
1377 EFI_STATUS
1378 MeasureLaunchOfFirmwareDebugger (
1379 VOID
1380 )
1381 {
1382 TCG_PCR_EVENT_HDR TcgEvent;
1383
1384 TcgEvent.PCRIndex = 7;
1385 TcgEvent.EventType = EV_EFI_ACTION;
1386 TcgEvent.EventSize = sizeof(FIRMWARE_DEBUGGER_EVENT_STRING) - 1;
1387 return TcgDxeHashLogExtendEvent (
1388 0,
1389 (UINT8 *)FIRMWARE_DEBUGGER_EVENT_STRING,
1390 sizeof(FIRMWARE_DEBUGGER_EVENT_STRING) - 1,
1391 &TcgEvent,
1392 (UINT8 *)FIRMWARE_DEBUGGER_EVENT_STRING
1393 );
1394 }
1395
1396 /**
1397 Measure and log all Secure Boot Policy, and extend the measurement result into a specific PCR.
1398
1399 Platform firmware adhering to the policy must therefore measure the following values into PCR[7]: (in order listed)
1400 - The contents of the SecureBoot variable
1401 - The contents of the PK variable
1402 - The contents of the KEK variable
1403 - The contents of the EFI_IMAGE_SECURITY_DATABASE variable
1404 - The contents of the EFI_IMAGE_SECURITY_DATABASE1 variable
1405 - Separator
1406 - Entries in the EFI_IMAGE_SECURITY_DATABASE that are used to validate EFI Drivers or EFI Boot Applications in the boot path
1407
1408 NOTE: Because of the above, UEFI variables PK, KEK, EFI_IMAGE_SECURITY_DATABASE,
1409 EFI_IMAGE_SECURITY_DATABASE1 and SecureBoot SHALL NOT be measured into PCR[3].
1410
1411 @param[in] Event Event whose notification function is being invoked
1412 @param[in] Context Pointer to the notification function's context
1413 **/
1414 VOID
1415 EFIAPI
1416 MeasureSecureBootPolicy (
1417 IN EFI_EVENT Event,
1418 IN VOID *Context
1419 )
1420 {
1421 EFI_STATUS Status;
1422 VOID *Protocol;
1423
1424 Status = gBS->LocateProtocol (&gEfiVariableWriteArchProtocolGuid, NULL, (VOID **)&Protocol);
1425 if (EFI_ERROR (Status)) {
1426 return;
1427 }
1428
1429 if (PcdGetBool (PcdFirmwareDebuggerInitialized)) {
1430 Status = MeasureLaunchOfFirmwareDebugger ();
1431 DEBUG ((EFI_D_INFO, "MeasureLaunchOfFirmwareDebugger - %r\n", Status));
1432 }
1433
1434 Status = MeasureAllSecureVariables ();
1435 DEBUG ((EFI_D_INFO, "MeasureAllSecureVariables - %r\n", Status));
1436
1437 //
1438 // We need measure Separator(7) here, because this event must be between SecureBootPolicy (Configure)
1439 // and ImageVerification (Authority)
1440 // There might be a case that we need measure UEFI image from DriverOrder, besides BootOrder. So
1441 // the Authority measurement happen before ReadToBoot event.
1442 //
1443 Status = MeasureSeparatorEvent (7);
1444 DEBUG ((EFI_D_INFO, "MeasureSeparatorEvent - %r\n", Status));
1445 return ;
1446 }
1447
1448 /**
1449 Ready to Boot Event notification handler.
1450
1451 Sequence of OS boot events is measured in this event notification handler.
1452
1453 @param[in] Event Event whose notification function is being invoked
1454 @param[in] Context Pointer to the notification function's context
1455
1456 **/
1457 VOID
1458 EFIAPI
1459 OnReadyToBoot (
1460 IN EFI_EVENT Event,
1461 IN VOID *Context
1462 )
1463 {
1464 EFI_STATUS Status;
1465 TPM_PCRINDEX PcrIndex;
1466
1467 PERF_START_EX (mImageHandle, "EventRec", "TrEEDxe", 0, PERF_ID_TREE_DXE);
1468 if (mBootAttempts == 0) {
1469
1470 //
1471 // Measure handoff tables.
1472 //
1473 Status = MeasureHandoffTables ();
1474 if (EFI_ERROR (Status)) {
1475 DEBUG ((EFI_D_ERROR, "HOBs not Measured. Error!\n"));
1476 }
1477
1478 //
1479 // Measure BootOrder & Boot#### variables.
1480 //
1481 Status = MeasureAllBootVariables ();
1482 if (EFI_ERROR (Status)) {
1483 DEBUG ((EFI_D_ERROR, "Boot Variables not Measured. Error!\n"));
1484 }
1485
1486 //
1487 // 1. This is the first boot attempt.
1488 //
1489 Status = TcgMeasureAction (
1490 EFI_CALLING_EFI_APPLICATION
1491 );
1492 if (EFI_ERROR (Status)) {
1493 DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_CALLING_EFI_APPLICATION));
1494 }
1495
1496 //
1497 // 2. Draw a line between pre-boot env and entering post-boot env.
1498 // PCR[7] is already done.
1499 //
1500 for (PcrIndex = 0; PcrIndex < 7; PcrIndex++) {
1501 Status = MeasureSeparatorEvent (PcrIndex);
1502 if (EFI_ERROR (Status)) {
1503 DEBUG ((EFI_D_ERROR, "Seperator Event not Measured. Error!\n"));
1504 }
1505 }
1506
1507 //
1508 // 3. Measure GPT. It would be done in SAP driver.
1509 //
1510
1511 //
1512 // 4. Measure PE/COFF OS loader. It would be done in SAP driver.
1513 //
1514
1515 //
1516 // 5. Read & Measure variable. BootOrder already measured.
1517 //
1518 } else {
1519 //
1520 // 6. Not first attempt, meaning a return from last attempt
1521 //
1522 Status = TcgMeasureAction (
1523 EFI_RETURNING_FROM_EFI_APPLICATOIN
1524 );
1525 if (EFI_ERROR (Status)) {
1526 DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_RETURNING_FROM_EFI_APPLICATOIN));
1527 }
1528 }
1529
1530 DEBUG ((EFI_D_INFO, "TPM2 TrEEDxe Measure Data when ReadyToBoot\n"));
1531 //
1532 // Increase boot attempt counter.
1533 //
1534 mBootAttempts++;
1535 PERF_END_EX (mImageHandle, "EventRec", "TrEEDxe", 0, PERF_ID_TREE_DXE + 1);
1536 }
1537
1538 /**
1539 Install TCG ACPI Table when ACPI Table Protocol is available.
1540
1541 A system's firmware uses an ACPI table to identify the system's TCG capabilities
1542 to the Post-Boot environment. The information in this ACPI table is not guaranteed
1543 to be valid until the Host Platform transitions from pre-boot state to post-boot state.
1544
1545 @param[in] Event Event whose notification function is being invoked
1546 @param[in] Context Pointer to the notification function's context
1547 **/
1548 VOID
1549 EFIAPI
1550 InstallAcpiTable (
1551 IN EFI_EVENT Event,
1552 IN VOID *Context
1553 )
1554 {
1555 UINTN TableKey;
1556 EFI_STATUS Status;
1557 EFI_ACPI_TABLE_PROTOCOL *AcpiTable;
1558 UINT8 Checksum;
1559 UINT64 OemTableId;
1560
1561 Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **)&AcpiTable);
1562 if (EFI_ERROR (Status)) {
1563 return;
1564 }
1565
1566 if (PcdGet8 (PcdTpmPlatformClass) == TCG_PLATFORM_TYPE_CLIENT) {
1567 CopyMem (mTcgClientAcpiTemplate.Header.OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (mTcgClientAcpiTemplate.Header.OemId));
1568 OemTableId = PcdGet64 (PcdAcpiDefaultOemTableId);
1569 CopyMem (&mTcgClientAcpiTemplate.Header.OemTableId, &OemTableId, sizeof (UINT64));
1570 mTcgClientAcpiTemplate.Header.OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision);
1571 mTcgClientAcpiTemplate.Header.CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId);
1572 mTcgClientAcpiTemplate.Header.CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision);
1573 //
1574 // The ACPI table must be checksumed before calling the InstallAcpiTable()
1575 // service of the ACPI table protocol to install it.
1576 //
1577 Checksum = CalculateCheckSum8 ((UINT8 *)&mTcgClientAcpiTemplate, sizeof (mTcgClientAcpiTemplate));
1578 mTcgClientAcpiTemplate.Header.Checksum = Checksum;
1579
1580 Status = AcpiTable->InstallAcpiTable (
1581 AcpiTable,
1582 &mTcgClientAcpiTemplate,
1583 sizeof (mTcgClientAcpiTemplate),
1584 &TableKey
1585 );
1586 } else {
1587 CopyMem (mTcgServerAcpiTemplate.Header.OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (mTcgServerAcpiTemplate.Header.OemId));
1588 OemTableId = PcdGet64 (PcdAcpiDefaultOemTableId);
1589 CopyMem (&mTcgServerAcpiTemplate.Header.OemTableId, &OemTableId, sizeof (UINT64));
1590 mTcgServerAcpiTemplate.Header.OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision);
1591 mTcgServerAcpiTemplate.Header.CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId);
1592 mTcgServerAcpiTemplate.Header.CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision);
1593 //
1594 // The ACPI table must be checksumed before calling the InstallAcpiTable()
1595 // service of the ACPI table protocol to install it.
1596 //
1597 Checksum = CalculateCheckSum8 ((UINT8 *)&mTcgServerAcpiTemplate, sizeof (mTcgServerAcpiTemplate));
1598 mTcgServerAcpiTemplate.Header.Checksum = Checksum;
1599
1600 mTcgServerAcpiTemplate.BaseAddress.Address = PcdGet64 (PcdTpmBaseAddress);
1601 Status = AcpiTable->InstallAcpiTable (
1602 AcpiTable,
1603 &mTcgServerAcpiTemplate,
1604 sizeof (mTcgServerAcpiTemplate),
1605 &TableKey
1606 );
1607 }
1608
1609 if (EFI_ERROR (Status)) {
1610 DEBUG((EFI_D_ERROR, "Tcg Acpi Table installation failure"));
1611 }
1612 }
1613
1614 /**
1615 Exit Boot Services Event notification handler.
1616
1617 Measure invocation and success of ExitBootServices.
1618
1619 @param[in] Event Event whose notification function is being invoked
1620 @param[in] Context Pointer to the notification function's context
1621
1622 **/
1623 VOID
1624 EFIAPI
1625 OnExitBootServices (
1626 IN EFI_EVENT Event,
1627 IN VOID *Context
1628 )
1629 {
1630 EFI_STATUS Status;
1631
1632 //
1633 // Measure invocation of ExitBootServices,
1634 //
1635 Status = TcgMeasureAction (
1636 EFI_EXIT_BOOT_SERVICES_INVOCATION
1637 );
1638 if (EFI_ERROR (Status)) {
1639 DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_INVOCATION));
1640 }
1641
1642 //
1643 // Measure success of ExitBootServices
1644 //
1645 Status = TcgMeasureAction (
1646 EFI_EXIT_BOOT_SERVICES_SUCCEEDED
1647 );
1648 if (EFI_ERROR (Status)) {
1649 DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_SUCCEEDED));
1650 }
1651 }
1652
1653 /**
1654 Exit Boot Services Failed Event notification handler.
1655
1656 Measure Failure of ExitBootServices.
1657
1658 @param[in] Event Event whose notification function is being invoked
1659 @param[in] Context Pointer to the notification function's context
1660
1661 **/
1662 VOID
1663 EFIAPI
1664 OnExitBootServicesFailed (
1665 IN EFI_EVENT Event,
1666 IN VOID *Context
1667 )
1668 {
1669 EFI_STATUS Status;
1670
1671 //
1672 // Measure Failure of ExitBootServices,
1673 //
1674 Status = TcgMeasureAction (
1675 EFI_EXIT_BOOT_SERVICES_FAILED
1676 );
1677 if (EFI_ERROR (Status)) {
1678 DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_FAILED));
1679 }
1680
1681 }
1682
1683 /**
1684 The function install TrEE protocol.
1685
1686 @retval EFI_SUCCESS TrEE protocol is installed.
1687 @retval other Some error occurs.
1688 **/
1689 EFI_STATUS
1690 InstallTrEE (
1691 VOID
1692 )
1693 {
1694 EFI_STATUS Status;
1695 EFI_HANDLE Handle;
1696
1697 Handle = NULL;
1698 Status = gBS->InstallMultipleProtocolInterfaces (
1699 &Handle,
1700 &gEfiTrEEProtocolGuid,
1701 &mTreeProtocol,
1702 NULL
1703 );
1704 return Status;
1705 }
1706
1707 /**
1708 The driver's entry point. It publishes EFI TrEE Protocol.
1709
1710 @param[in] ImageHandle The firmware allocated handle for the EFI image.
1711 @param[in] SystemTable A pointer to the EFI System Table.
1712
1713 @retval EFI_SUCCESS The entry point is executed successfully.
1714 @retval other Some error occurs when executing this entry point.
1715 **/
1716 EFI_STATUS
1717 EFIAPI
1718 DriverEntry (
1719 IN EFI_HANDLE ImageHandle,
1720 IN EFI_SYSTEM_TABLE *SystemTable
1721 )
1722 {
1723 EFI_STATUS Status;
1724 EFI_EVENT Event;
1725 VOID *Registration;
1726 UINT32 MaxCommandSize;
1727 UINT32 MaxResponseSize;
1728 TPML_PCR_SELECTION Pcrs;
1729 UINTN Index;
1730 UINT32 TpmHashAlgorithmBitmap;
1731
1732 mImageHandle = ImageHandle;
1733
1734 if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceNoneGuid) ||
1735 CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)){
1736 DEBUG ((EFI_D_ERROR, "No TPM2 instance required!\n"));
1737 return EFI_UNSUPPORTED;
1738 }
1739
1740 if (GetFirstGuidHob (&gTpmErrorHobGuid) != NULL) {
1741 DEBUG ((EFI_D_ERROR, "TPM2 error!\n"));
1742 return EFI_DEVICE_ERROR;
1743 }
1744
1745 Status = Tpm2RequestUseTpm ();
1746 if (EFI_ERROR (Status)) {
1747 DEBUG ((EFI_D_ERROR, "TPM2 not detected!\n"));
1748 return Status;
1749 }
1750
1751 //
1752 // Fill information
1753 //
1754 DEBUG ((EFI_D_INFO, "TrEE.ProtocolVersion - %02x.%02x\n", mTcgDxeData.BsCap.ProtocolVersion.Major, mTcgDxeData.BsCap.ProtocolVersion.Minor));
1755 DEBUG ((EFI_D_INFO, "TrEE.StructureVersion - %02x.%02x\n", mTcgDxeData.BsCap.StructureVersion.Major, mTcgDxeData.BsCap.StructureVersion.Minor));
1756
1757 Status = Tpm2GetCapabilityManufactureID (&mTcgDxeData.BsCap.ManufacturerID);
1758 if (EFI_ERROR (Status)) {
1759 DEBUG ((EFI_D_ERROR, "Tpm2GetCapabilityManufactureID fail!\n"));
1760 } else {
1761 DEBUG ((EFI_D_INFO, "Tpm2GetCapabilityManufactureID - %08x\n", mTcgDxeData.BsCap.ManufacturerID));
1762 }
1763
1764 DEBUG_CODE (
1765 UINT32 FirmwareVersion1;
1766 UINT32 FirmwareVersion2;
1767
1768 Status = Tpm2GetCapabilityFirmwareVersion (&FirmwareVersion1, &FirmwareVersion2);
1769 if (EFI_ERROR (Status)) {
1770 DEBUG ((EFI_D_ERROR, "Tpm2GetCapabilityFirmwareVersion fail!\n"));
1771 } else {
1772 DEBUG ((EFI_D_INFO, "Tpm2GetCapabilityFirmwareVersion - %08x %08x\n", FirmwareVersion1, FirmwareVersion2));
1773 }
1774 );
1775
1776 Status = Tpm2GetCapabilityMaxCommandResponseSize (&MaxCommandSize, &MaxResponseSize);
1777 if (EFI_ERROR (Status)) {
1778 DEBUG ((EFI_D_ERROR, "Tpm2GetCapabilityMaxCommandResponseSize fail!\n"));
1779 } else {
1780 mTcgDxeData.BsCap.MaxCommandSize = (UINT16)MaxCommandSize;
1781 mTcgDxeData.BsCap.MaxResponseSize = (UINT16)MaxResponseSize;
1782 DEBUG ((EFI_D_INFO, "Tpm2GetCapabilityMaxCommandResponseSize - %08x, %08x\n", MaxCommandSize, MaxResponseSize));
1783 }
1784
1785 Status = Tpm2GetCapabilityPcrs (&Pcrs);
1786 if (EFI_ERROR (Status)) {
1787 DEBUG ((EFI_D_ERROR, "Tpm2GetCapabilityPcrs fail!\n"));
1788 TpmHashAlgorithmBitmap = TREE_BOOT_HASH_ALG_SHA1;
1789 } else {
1790 DEBUG ((EFI_D_INFO, "Tpm2GetCapabilityPcrs Count - %08x\n", Pcrs.count));
1791 TpmHashAlgorithmBitmap = 0;
1792 for (Index = 0; Index < Pcrs.count; Index++) {
1793 DEBUG ((EFI_D_INFO, "hash - %x\n", Pcrs.pcrSelections[Index].hash));
1794 switch (Pcrs.pcrSelections[Index].hash) {
1795 case TPM_ALG_SHA1:
1796 TpmHashAlgorithmBitmap |= TREE_BOOT_HASH_ALG_SHA1;
1797 break;
1798 case TPM_ALG_SHA256:
1799 TpmHashAlgorithmBitmap |= TREE_BOOT_HASH_ALG_SHA256;
1800 break;
1801 case TPM_ALG_SHA384:
1802 TpmHashAlgorithmBitmap |= TREE_BOOT_HASH_ALG_SHA384;
1803 break;
1804 case TPM_ALG_SHA512:
1805 TpmHashAlgorithmBitmap |= TREE_BOOT_HASH_ALG_SHA512;
1806 break;
1807 case TPM_ALG_SM3_256:
1808 // TBD: Spec not define TREE_BOOT_HASH_ALG_SM3_256 yet
1809 break;
1810 }
1811 }
1812 }
1813 DEBUG ((EFI_D_INFO, "TPM.HashAlgorithmBitmap - 0x%08x\n", TpmHashAlgorithmBitmap));
1814
1815 DEBUG ((EFI_D_INFO, "TrEE.SupportedEventLogs - 0x%08x\n", mTcgDxeData.BsCap.SupportedEventLogs));
1816 mTcgDxeData.BsCap.HashAlgorithmBitmap = TpmHashAlgorithmBitmap;
1817 DEBUG ((EFI_D_INFO, "TrEE.HashAlgorithmBitmap - 0x%08x\n", mTcgDxeData.BsCap.HashAlgorithmBitmap));
1818
1819 if (mTcgDxeData.BsCap.TrEEPresentFlag) {
1820 //
1821 // Setup the log area and copy event log from hob list to it
1822 //
1823 Status = SetupEventLog ();
1824 ASSERT_EFI_ERROR (Status);
1825
1826 //
1827 // Measure handoff tables, Boot#### variables etc.
1828 //
1829 Status = EfiCreateEventReadyToBootEx (
1830 TPL_CALLBACK,
1831 OnReadyToBoot,
1832 NULL,
1833 &Event
1834 );
1835
1836 Status = gBS->CreateEventEx (
1837 EVT_NOTIFY_SIGNAL,
1838 TPL_NOTIFY,
1839 OnExitBootServices,
1840 NULL,
1841 &gEfiEventExitBootServicesGuid,
1842 &Event
1843 );
1844
1845 //
1846 // Measure Exit Boot Service failed
1847 //
1848 Status = gBS->CreateEventEx (
1849 EVT_NOTIFY_SIGNAL,
1850 TPL_NOTIFY,
1851 OnExitBootServicesFailed,
1852 NULL,
1853 &gEventExitBootServicesFailedGuid,
1854 &Event
1855 );
1856
1857 //
1858 // Create event callback, because we need access variable on SecureBootPolicyVariable
1859 // We should use VariableWriteArch instead of VariableArch, because Variable driver
1860 // may update SecureBoot value based on last setting.
1861 //
1862 EfiCreateProtocolNotifyEvent (&gEfiVariableWriteArchProtocolGuid, TPL_CALLBACK, MeasureSecureBootPolicy, NULL, &Registration);
1863 }
1864
1865 //
1866 // Install ACPI Table
1867 //
1868 EfiCreateProtocolNotifyEvent (&gEfiAcpiTableProtocolGuid, TPL_CALLBACK, InstallAcpiTable, NULL, &Registration);
1869
1870 //
1871 // Install TrEEProtocol
1872 //
1873 Status = InstallTrEE ();
1874 DEBUG ((EFI_D_INFO, "InstallTrEE - %r\n", Status));
1875
1876 return Status;
1877 }