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