]> git.proxmox.com Git - mirror_edk2.git/blob - SecurityPkg/Tcg/TrEEDxe/TrEEDxe.c
Move Smbios measurement from TCG driver to Smbios driver.
[mirror_edk2.git] / SecurityPkg / Tcg / TrEEDxe / TrEEDxe.c
1 /** @file
2 This module implements TrEE Protocol.
3
4 Copyright (c) 2013 - 2015, 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 EFI_TCG_LOG_AREA_SIZE 0x10000
59
60 #define TREE_DEFAULT_MAX_COMMAND_SIZE 0x1000
61 #define TREE_DEFAULT_MAX_RESPONSE_SIZE 0x1000
62
63 typedef struct {
64 EFI_GUID *EventGuid;
65 TREE_EVENT_LOG_FORMAT LogFormat;
66 } TREE_EVENT_INFO_STRUCT;
67
68 TREE_EVENT_INFO_STRUCT mTreeEventInfo[] = {
69 {&gTcgEventEntryHobGuid, TREE_EVENT_LOG_FORMAT_TCG_1_2},
70 };
71
72 #define TCG_EVENT_LOG_AREA_COUNT_MAX 2
73
74 typedef struct {
75 TREE_EVENT_LOG_FORMAT EventLogFormat;
76 EFI_PHYSICAL_ADDRESS Lasa;
77 UINT64 Laml;
78 UINTN EventLogSize;
79 UINT8 *LastEvent;
80 BOOLEAN EventLogStarted;
81 BOOLEAN EventLogTruncated;
82 } TCG_EVENT_LOG_AREA_STRUCT;
83
84 typedef struct _TCG_DXE_DATA {
85 TREE_BOOT_SERVICE_CAPABILITY BsCap;
86 EFI_TCG_CLIENT_ACPI_TABLE *TcgClientAcpiTable;
87 EFI_TCG_SERVER_ACPI_TABLE *TcgServerAcpiTable;
88 TCG_EVENT_LOG_AREA_STRUCT EventLogAreaStruct[TCG_EVENT_LOG_AREA_COUNT_MAX];
89 } TCG_DXE_DATA;
90
91 EFI_TCG_CLIENT_ACPI_TABLE mTcgClientAcpiTemplate = {
92 {
93 EFI_ACPI_3_0_TRUSTED_COMPUTING_PLATFORM_ALLIANCE_CAPABILITIES_TABLE_SIGNATURE,
94 sizeof (mTcgClientAcpiTemplate),
95 0x02 //Revision
96 //
97 // Compiler initializes the remaining bytes to 0
98 // These fields should be filled in in production
99 //
100 },
101 0, // 0 for PC Client Platform Class
102 0, // Log Area Max Length
103 (EFI_PHYSICAL_ADDRESS) (SIZE_4GB - 1) // Log Area Start Address
104 };
105
106 //
107 // The following EFI_TCG_SERVER_ACPI_TABLE default setting is just one example,
108 // the TPM device connectes to LPC, and also defined the ACPI _UID as 0xFF,
109 // this _UID can be changed and should match with the _UID setting of the TPM
110 // ACPI device object
111 //
112 EFI_TCG_SERVER_ACPI_TABLE mTcgServerAcpiTemplate = {
113 {
114 EFI_ACPI_3_0_TRUSTED_COMPUTING_PLATFORM_ALLIANCE_CAPABILITIES_TABLE_SIGNATURE,
115 sizeof (mTcgServerAcpiTemplate),
116 0x02 //Revision
117 //
118 // Compiler initializes the remaining bytes to 0
119 // These fields should be filled in in production
120 //
121 },
122 1, // 1 for Server Platform Class
123 0, // Reserved
124 0, // Log Area Max Length
125 (EFI_PHYSICAL_ADDRESS) (SIZE_4GB - 1), // Log Area Start Address
126 0x0100, // TCG Specification revision 1.0
127 2, // Device Flags
128 0, // Interrupt Flags
129 0, // GPE
130 {0}, // Reserved 3 bytes
131 0, // Global System Interrupt
132 {
133 EFI_ACPI_3_0_SYSTEM_MEMORY,
134 0,
135 0,
136 EFI_ACPI_3_0_BYTE,
137 0x0 // Base Address
138 },
139 0, // Reserved
140 {0}, // Configuration Address
141 0xFF, // 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 0, // ACPI _UID value of the device, can be changed for different platforms
144 0 // ACPI _UID value of the device, can be changed for different platforms
145 };
146
147 TCG_DXE_DATA mTcgDxeData = {
148 {
149 sizeof (TREE_BOOT_SERVICE_CAPABILITY_1_0), // Size
150 { 1, 0 }, // StructureVersion
151 { 1, 0 }, // ProtocolVersion
152 TREE_BOOT_HASH_ALG_SHA1, // HashAlgorithmBitmap
153 TREE_EVENT_LOG_FORMAT_TCG_1_2, // SupportedEventLogs
154 TRUE, // TrEEPresentFlag
155 TREE_DEFAULT_MAX_COMMAND_SIZE, // MaxCommandSize
156 TREE_DEFAULT_MAX_RESPONSE_SIZE, // MaxResponseSize
157 0 // ManufacturerID
158 },
159 &mTcgClientAcpiTemplate,
160 &mTcgServerAcpiTemplate,
161 };
162
163 UINTN mBootAttempts = 0;
164 CHAR16 mBootVarName[] = L"BootOrder";
165
166 VARIABLE_TYPE mVariableType[] = {
167 {EFI_SECURE_BOOT_MODE_NAME, &gEfiGlobalVariableGuid},
168 {EFI_PLATFORM_KEY_NAME, &gEfiGlobalVariableGuid},
169 {EFI_KEY_EXCHANGE_KEY_NAME, &gEfiGlobalVariableGuid},
170 {EFI_IMAGE_SECURITY_DATABASE, &gEfiImageSecurityDatabaseGuid},
171 {EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid},
172 };
173
174 EFI_HANDLE mImageHandle;
175
176 /**
177 Measure PE image into TPM log based on the authenticode image hashing in
178 PE/COFF Specification 8.0 Appendix A.
179
180 Caution: This function may receive untrusted input.
181 PE/COFF image is external input, so this function will validate its data structure
182 within this image buffer before use.
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 This function get digest from digest list.
629
630 @param HashAlg digest algorithm
631 @param DigestList digest list
632 @param Digest digest
633
634 @retval EFI_SUCCESS Sha1Digest is found and returned.
635 @retval EFI_NOT_FOUND Sha1Digest is not found.
636 **/
637 EFI_STATUS
638 Tpm2GetDigestFromDigestList (
639 IN TPMI_ALG_HASH HashAlg,
640 IN TPML_DIGEST_VALUES *DigestList,
641 IN VOID *Digest
642 )
643 {
644 UINTN Index;
645 UINT16 DigestSize;
646
647 DigestSize = GetHashSizeFromAlgo (HashAlg);
648 for (Index = 0; Index < DigestList->count; Index++) {
649 if (DigestList->digests[Index].hashAlg == HashAlg) {
650 CopyMem (
651 Digest,
652 &DigestList->digests[Index].digest,
653 DigestSize
654 );
655 return EFI_SUCCESS;
656 }
657 }
658
659 return EFI_NOT_FOUND;
660 }
661
662 /**
663 Add a new entry to the Event Log.
664
665 @param[in] DigestList A list of digest.
666 @param[in,out] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.
667 @param[in] NewEventData Pointer to the new event data.
668
669 @retval EFI_SUCCESS The new event log entry was added.
670 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
671 **/
672 EFI_STATUS
673 TcgDxeLogHashEvent (
674 IN TPML_DIGEST_VALUES *DigestList,
675 IN OUT TCG_PCR_EVENT_HDR *NewEventHdr,
676 IN UINT8 *NewEventData
677 )
678 {
679 EFI_STATUS Status;
680 EFI_TPL OldTpl;
681 UINTN Index;
682 EFI_STATUS RetStatus;
683
684 RetStatus = EFI_SUCCESS;
685 for (Index = 0; Index < sizeof(mTreeEventInfo)/sizeof(mTreeEventInfo[0]); Index++) {
686 DEBUG ((EFI_D_INFO, " LogFormat - 0x%08x\n", mTreeEventInfo[Index].LogFormat));
687 switch (mTreeEventInfo[Index].LogFormat) {
688 case TREE_EVENT_LOG_FORMAT_TCG_1_2:
689 Status = Tpm2GetDigestFromDigestList (TPM_ALG_SHA1, DigestList, &NewEventHdr->Digest);
690 if (!EFI_ERROR (Status)) {
691 //
692 // Enter critical region
693 //
694 OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);
695 Status = TcgDxeLogEvent (
696 mTreeEventInfo[Index].LogFormat,
697 NewEventHdr,
698 sizeof(TCG_PCR_EVENT_HDR),
699 NewEventData,
700 NewEventHdr->EventSize
701 );
702 if (Status != EFI_SUCCESS) {
703 RetStatus = Status;
704 }
705 gBS->RestoreTPL (OldTpl);
706 //
707 // Exit critical region
708 //
709 }
710 break;
711 }
712 }
713
714 return RetStatus;
715 }
716
717 /**
718 Do a hash operation on a data buffer, extend a specific TPM PCR with the hash result,
719 and add an entry to the Event Log.
720
721 @param[in] Flags Bitmap providing additional information.
722 @param[in] HashData Physical address of the start of the data buffer
723 to be hashed, extended, and logged.
724 @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData
725 @param[in, out] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.
726 @param[in] NewEventData Pointer to the new event data.
727
728 @retval EFI_SUCCESS Operation completed successfully.
729 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
730 @retval EFI_DEVICE_ERROR The command was unsuccessful.
731
732 **/
733 EFI_STATUS
734 TcgDxeHashLogExtendEvent (
735 IN UINT64 Flags,
736 IN UINT8 *HashData,
737 IN UINT64 HashDataLen,
738 IN OUT TCG_PCR_EVENT_HDR *NewEventHdr,
739 IN UINT8 *NewEventData
740 )
741 {
742 EFI_STATUS Status;
743 TPML_DIGEST_VALUES DigestList;
744
745 if (!mTcgDxeData.BsCap.TrEEPresentFlag) {
746 return EFI_DEVICE_ERROR;
747 }
748
749 Status = HashAndExtend (
750 NewEventHdr->PCRIndex,
751 HashData,
752 (UINTN)HashDataLen,
753 &DigestList
754 );
755 if (!EFI_ERROR (Status)) {
756 if ((Flags & TREE_EXTEND_ONLY) == 0) {
757 Status = TcgDxeLogHashEvent (&DigestList, NewEventHdr, NewEventData);
758 }
759 }
760
761 if (Status == EFI_DEVICE_ERROR) {
762 DEBUG ((EFI_D_ERROR, "TcgDxeHashLogExtendEvent - %r. Disable TPM.\n", Status));
763 mTcgDxeData.BsCap.TrEEPresentFlag = FALSE;
764 REPORT_STATUS_CODE (
765 EFI_ERROR_CODE | EFI_ERROR_MINOR,
766 (PcdGet32 (PcdStatusCodeSubClassTpmDevice) | EFI_P_EC_INTERFACE_ERROR)
767 );
768 }
769
770 return Status;
771 }
772
773 /**
774 The EFI_TREE_PROTOCOL HashLogExtendEvent function call provides callers with
775 an opportunity to extend and optionally log events without requiring
776 knowledge of actual TPM commands.
777 The extend operation will occur even if this function cannot create an event
778 log entry (e.g. due to the event log being full).
779
780 @param[in] This Indicates the calling context
781 @param[in] Flags Bitmap providing additional information.
782 @param[in] DataToHash Physical address of the start of the data buffer to be hashed.
783 @param[in] DataToHashLen The length in bytes of the buffer referenced by DataToHash.
784 @param[in] Event Pointer to data buffer containing information about the event.
785
786 @retval EFI_SUCCESS Operation completed successfully.
787 @retval EFI_DEVICE_ERROR The command was unsuccessful.
788 @retval EFI_VOLUME_FULL The extend operation occurred, but the event could not be written to one or more event logs.
789 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
790 @retval EFI_UNSUPPORTED The PE/COFF image type is not supported.
791 **/
792 EFI_STATUS
793 EFIAPI
794 TreeHashLogExtendEvent (
795 IN EFI_TREE_PROTOCOL *This,
796 IN UINT64 Flags,
797 IN EFI_PHYSICAL_ADDRESS DataToHash,
798 IN UINT64 DataToHashLen,
799 IN TrEE_EVENT *Event
800 )
801 {
802 EFI_STATUS Status;
803 TCG_PCR_EVENT_HDR NewEventHdr;
804 TPML_DIGEST_VALUES DigestList;
805
806 DEBUG ((EFI_D_INFO, "TreeHashLogExtendEvent ...\n"));
807
808 if ((This == NULL) || (DataToHash == 0) || (Event == NULL)) {
809 return EFI_INVALID_PARAMETER;
810 }
811
812 if (!mTcgDxeData.BsCap.TrEEPresentFlag) {
813 return EFI_UNSUPPORTED;
814 }
815
816 if (Event->Size < Event->Header.HeaderSize + sizeof(UINT32)) {
817 return EFI_INVALID_PARAMETER;
818 }
819
820 if (Event->Header.PCRIndex > MAX_PCR_INDEX) {
821 return EFI_INVALID_PARAMETER;
822 }
823
824 NewEventHdr.PCRIndex = Event->Header.PCRIndex;
825 NewEventHdr.EventType = Event->Header.EventType;
826 NewEventHdr.EventSize = Event->Size - sizeof(UINT32) - Event->Header.HeaderSize;
827 if ((Flags & PE_COFF_IMAGE) != 0) {
828 Status = MeasurePeImageAndExtend (
829 NewEventHdr.PCRIndex,
830 DataToHash,
831 (UINTN)DataToHashLen,
832 &DigestList
833 );
834 if (!EFI_ERROR (Status)) {
835 if ((Flags & TREE_EXTEND_ONLY) == 0) {
836 Status = TcgDxeLogHashEvent (&DigestList, &NewEventHdr, Event->Event);
837 }
838 }
839 if (Status == EFI_DEVICE_ERROR) {
840 DEBUG ((EFI_D_ERROR, "MeasurePeImageAndExtend - %r. Disable TPM.\n", Status));
841 mTcgDxeData.BsCap.TrEEPresentFlag = FALSE;
842 REPORT_STATUS_CODE (
843 EFI_ERROR_CODE | EFI_ERROR_MINOR,
844 (PcdGet32 (PcdStatusCodeSubClassTpmDevice) | EFI_P_EC_INTERFACE_ERROR)
845 );
846 }
847 } else {
848 Status = TcgDxeHashLogExtendEvent (
849 Flags,
850 (UINT8 *) (UINTN) DataToHash,
851 DataToHashLen,
852 &NewEventHdr,
853 Event->Event
854 );
855 }
856 DEBUG ((EFI_D_INFO, "TreeHashLogExtendEvent - %r\n", Status));
857 return Status;
858 }
859
860 /**
861 This service enables the sending of commands to the TrEE.
862
863 @param[in] This Indicates the calling context
864 @param[in] InputParameterBlockSize Size of the TrEE input parameter block.
865 @param[in] InputParameterBlock Pointer to the TrEE input parameter block.
866 @param[in] OutputParameterBlockSize Size of the TrEE output parameter block.
867 @param[in] OutputParameterBlock Pointer to the TrEE output parameter block.
868
869 @retval EFI_SUCCESS The command byte stream was successfully sent to the device and a response was successfully received.
870 @retval EFI_DEVICE_ERROR The command was not successfully sent to the device or a response was not successfully received from the device.
871 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
872 @retval EFI_BUFFER_TOO_SMALL The output parameter block is too small.
873 **/
874 EFI_STATUS
875 EFIAPI
876 TreeSubmitCommand (
877 IN EFI_TREE_PROTOCOL *This,
878 IN UINT32 InputParameterBlockSize,
879 IN UINT8 *InputParameterBlock,
880 IN UINT32 OutputParameterBlockSize,
881 IN UINT8 *OutputParameterBlock
882 )
883 {
884 EFI_STATUS Status;
885
886 DEBUG ((EFI_D_INFO, "TreeSubmitCommand ...\n"));
887
888 if ((This == NULL) ||
889 (InputParameterBlockSize == 0) || (InputParameterBlock == NULL) ||
890 (OutputParameterBlockSize == 0) || (OutputParameterBlock == NULL)) {
891 return EFI_INVALID_PARAMETER;
892 }
893
894 if (!mTcgDxeData.BsCap.TrEEPresentFlag) {
895 return EFI_UNSUPPORTED;
896 }
897
898 if (InputParameterBlockSize >= mTcgDxeData.BsCap.MaxCommandSize) {
899 return EFI_INVALID_PARAMETER;
900 }
901 if (OutputParameterBlockSize >= mTcgDxeData.BsCap.MaxResponseSize) {
902 return EFI_INVALID_PARAMETER;
903 }
904
905 Status = Tpm2SubmitCommand (
906 InputParameterBlockSize,
907 InputParameterBlock,
908 &OutputParameterBlockSize,
909 OutputParameterBlock
910 );
911 DEBUG ((EFI_D_INFO, "TreeSubmitCommand - %r\n", Status));
912 return Status;
913 }
914
915
916 EFI_TREE_PROTOCOL mTreeProtocol = {
917 TreeGetCapability,
918 TreeGetEventLog,
919 TreeHashLogExtendEvent,
920 TreeSubmitCommand
921 };
922
923 /**
924 Initialize the Event Log and log events passed from the PEI phase.
925
926 @retval EFI_SUCCESS Operation completed successfully.
927 @retval EFI_OUT_OF_RESOURCES Out of memory.
928
929 **/
930 EFI_STATUS
931 SetupEventLog (
932 VOID
933 )
934 {
935 EFI_STATUS Status;
936 VOID *TcgEvent;
937 EFI_PEI_HOB_POINTERS GuidHob;
938 EFI_PHYSICAL_ADDRESS Lasa;
939 UINTN Index;
940
941 DEBUG ((EFI_D_INFO, "SetupEventLog\n"));
942
943 //
944 // 1. Create Log Area
945 //
946 for (Index = 0; Index < sizeof(mTreeEventInfo)/sizeof(mTreeEventInfo[0]); Index++) {
947 mTcgDxeData.EventLogAreaStruct[Index].EventLogFormat = mTreeEventInfo[Index].LogFormat;
948 Lasa = (EFI_PHYSICAL_ADDRESS) (SIZE_4GB - 1);
949 Status = gBS->AllocatePages (
950 AllocateMaxAddress,
951 EfiACPIMemoryNVS,
952 EFI_SIZE_TO_PAGES (EFI_TCG_LOG_AREA_SIZE),
953 &Lasa
954 );
955 if (EFI_ERROR (Status)) {
956 return Status;
957 }
958 mTcgDxeData.EventLogAreaStruct[Index].Lasa = Lasa;
959 mTcgDxeData.EventLogAreaStruct[Index].Laml = EFI_TCG_LOG_AREA_SIZE;
960 //
961 // To initialize them as 0xFF is recommended
962 // because the OS can know the last entry for that.
963 //
964 SetMem ((VOID *)(UINTN)Lasa, EFI_TCG_LOG_AREA_SIZE, 0xFF);
965 }
966
967 //
968 // 2. Create ACPI table for TCG1.2 only
969 //
970 if (PcdGet8 (PcdTpmPlatformClass) == TCG_PLATFORM_TYPE_CLIENT) {
971 mTcgClientAcpiTemplate.Lasa = mTcgDxeData.EventLogAreaStruct[0].Lasa;
972 mTcgClientAcpiTemplate.Laml = EFI_TCG_LOG_AREA_SIZE;
973 } else {
974 mTcgServerAcpiTemplate.Lasa = mTcgDxeData.EventLogAreaStruct[0].Lasa;
975 mTcgServerAcpiTemplate.Laml = EFI_TCG_LOG_AREA_SIZE;
976 }
977
978 //
979 // 3. Sync data from PEI to DXE
980 //
981 Status = EFI_SUCCESS;
982 for (Index = 0; Index < sizeof(mTreeEventInfo)/sizeof(mTreeEventInfo[0]); Index++) {
983 GuidHob.Raw = GetHobList ();
984 Status = EFI_SUCCESS;
985 while (!EFI_ERROR (Status) &&
986 (GuidHob.Raw = GetNextGuidHob (mTreeEventInfo[Index].EventGuid, GuidHob.Raw)) != NULL) {
987 TcgEvent = GET_GUID_HOB_DATA (GuidHob.Guid);
988 GuidHob.Raw = GET_NEXT_HOB (GuidHob);
989 switch (mTreeEventInfo[Index].LogFormat) {
990 case TREE_EVENT_LOG_FORMAT_TCG_1_2:
991 Status = TcgDxeLogEvent (
992 mTreeEventInfo[Index].LogFormat,
993 TcgEvent,
994 sizeof(TCG_PCR_EVENT_HDR),
995 ((TCG_PCR_EVENT*)TcgEvent)->Event,
996 ((TCG_PCR_EVENT_HDR*)TcgEvent)->EventSize
997 );
998 break;
999 }
1000 }
1001 }
1002
1003 return Status;
1004 }
1005
1006 /**
1007 Measure and log an action string, and extend the measurement result into PCR[5].
1008
1009 @param[in] String A specific string that indicates an Action event.
1010
1011 @retval EFI_SUCCESS Operation completed successfully.
1012 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1013
1014 **/
1015 EFI_STATUS
1016 TcgMeasureAction (
1017 IN CHAR8 *String
1018 )
1019 {
1020 TCG_PCR_EVENT_HDR TcgEvent;
1021
1022 TcgEvent.PCRIndex = 5;
1023 TcgEvent.EventType = EV_EFI_ACTION;
1024 TcgEvent.EventSize = (UINT32)AsciiStrLen (String);
1025 return TcgDxeHashLogExtendEvent (
1026 0,
1027 (UINT8*)String,
1028 TcgEvent.EventSize,
1029 &TcgEvent,
1030 (UINT8 *) String
1031 );
1032 }
1033
1034 /**
1035 Measure and log EFI handoff tables, and extend the measurement result into PCR[1].
1036
1037 @retval EFI_SUCCESS Operation completed successfully.
1038 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1039
1040 **/
1041 EFI_STATUS
1042 MeasureHandoffTables (
1043 VOID
1044 )
1045 {
1046 EFI_STATUS Status;
1047 TCG_PCR_EVENT_HDR TcgEvent;
1048 EFI_HANDOFF_TABLE_POINTERS HandoffTables;
1049 UINTN ProcessorNum;
1050 EFI_CPU_PHYSICAL_LOCATION *ProcessorLocBuf;
1051
1052 ProcessorLocBuf = NULL;
1053 Status = EFI_SUCCESS;
1054
1055 if (PcdGet8 (PcdTpmPlatformClass) == TCG_PLATFORM_TYPE_SERVER) {
1056 //
1057 // Tcg Server spec.
1058 // Measure each processor EFI_CPU_PHYSICAL_LOCATION with EV_TABLE_OF_DEVICES to PCR[1]
1059 //
1060 Status = GetProcessorsCpuLocation(&ProcessorLocBuf, &ProcessorNum);
1061
1062 if (!EFI_ERROR(Status)){
1063 TcgEvent.PCRIndex = 1;
1064 TcgEvent.EventType = EV_TABLE_OF_DEVICES;
1065 TcgEvent.EventSize = sizeof (HandoffTables);
1066
1067 HandoffTables.NumberOfTables = 1;
1068 HandoffTables.TableEntry[0].VendorGuid = gEfiMpServiceProtocolGuid;
1069 HandoffTables.TableEntry[0].VendorTable = ProcessorLocBuf;
1070
1071 Status = TcgDxeHashLogExtendEvent (
1072 0,
1073 (UINT8*)(UINTN)ProcessorLocBuf,
1074 sizeof(EFI_CPU_PHYSICAL_LOCATION) * ProcessorNum,
1075 &TcgEvent,
1076 (UINT8*)&HandoffTables
1077 );
1078
1079 FreePool(ProcessorLocBuf);
1080 }
1081 }
1082
1083 return Status;
1084 }
1085
1086 /**
1087 Measure and log Separator event, and extend the measurement result into a specific PCR.
1088
1089 @param[in] PCRIndex PCR index.
1090
1091 @retval EFI_SUCCESS Operation completed successfully.
1092 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1093
1094 **/
1095 EFI_STATUS
1096 MeasureSeparatorEvent (
1097 IN TPM_PCRINDEX PCRIndex
1098 )
1099 {
1100 TCG_PCR_EVENT_HDR TcgEvent;
1101 UINT32 EventData;
1102
1103 DEBUG ((EFI_D_INFO, "MeasureSeparatorEvent Pcr - %x\n", PCRIndex));
1104
1105 EventData = 0;
1106 TcgEvent.PCRIndex = PCRIndex;
1107 TcgEvent.EventType = EV_SEPARATOR;
1108 TcgEvent.EventSize = (UINT32)sizeof (EventData);
1109 return TcgDxeHashLogExtendEvent (
1110 0,
1111 (UINT8 *)&EventData,
1112 sizeof (EventData),
1113 &TcgEvent,
1114 (UINT8 *)&EventData
1115 );
1116 }
1117
1118 /**
1119 Measure and log an EFI variable, and extend the measurement result into a specific PCR.
1120
1121 @param[in] PCRIndex PCR Index.
1122 @param[in] EventType Event type.
1123 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
1124 @param[in] VendorGuid A unique identifier for the vendor.
1125 @param[in] VarData The content of the variable data.
1126 @param[in] VarSize The size of the variable data.
1127
1128 @retval EFI_SUCCESS Operation completed successfully.
1129 @retval EFI_OUT_OF_RESOURCES Out of memory.
1130 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1131
1132 **/
1133 EFI_STATUS
1134 MeasureVariable (
1135 IN TPM_PCRINDEX PCRIndex,
1136 IN TCG_EVENTTYPE EventType,
1137 IN CHAR16 *VarName,
1138 IN EFI_GUID *VendorGuid,
1139 IN VOID *VarData,
1140 IN UINTN VarSize
1141 )
1142 {
1143 EFI_STATUS Status;
1144 TCG_PCR_EVENT_HDR TcgEvent;
1145 UINTN VarNameLength;
1146 EFI_VARIABLE_DATA_TREE *VarLog;
1147
1148 DEBUG ((EFI_D_INFO, "TrEEDxe: MeasureVariable (Pcr - %x, EventType - %x, ", (UINTN)PCRIndex, (UINTN)EventType));
1149 DEBUG ((EFI_D_INFO, "VariableName - %s, VendorGuid - %g)\n", VarName, VendorGuid));
1150
1151 VarNameLength = StrLen (VarName);
1152 TcgEvent.PCRIndex = PCRIndex;
1153 TcgEvent.EventType = EventType;
1154 TcgEvent.EventSize = (UINT32)(sizeof (*VarLog) + VarNameLength * sizeof (*VarName) + VarSize
1155 - sizeof (VarLog->UnicodeName) - sizeof (VarLog->VariableData));
1156
1157 VarLog = (EFI_VARIABLE_DATA_TREE*)AllocatePool (TcgEvent.EventSize);
1158 if (VarLog == NULL) {
1159 return EFI_OUT_OF_RESOURCES;
1160 }
1161
1162 VarLog->VariableName = *VendorGuid;
1163 VarLog->UnicodeNameLength = VarNameLength;
1164 VarLog->VariableDataLength = VarSize;
1165 CopyMem (
1166 VarLog->UnicodeName,
1167 VarName,
1168 VarNameLength * sizeof (*VarName)
1169 );
1170 if (VarSize != 0 && VarData != NULL) {
1171 CopyMem (
1172 (CHAR16 *)VarLog->UnicodeName + VarNameLength,
1173 VarData,
1174 VarSize
1175 );
1176 }
1177
1178 Status = TcgDxeHashLogExtendEvent (
1179 0,
1180 (UINT8*)VarLog,
1181 TcgEvent.EventSize,
1182 &TcgEvent,
1183 (UINT8*)VarLog
1184 );
1185
1186 FreePool (VarLog);
1187 return Status;
1188 }
1189
1190 /**
1191 Read then Measure and log an EFI variable, and extend the measurement result into a specific PCR.
1192
1193 @param[in] PCRIndex PCR Index.
1194 @param[in] EventType Event type.
1195 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
1196 @param[in] VendorGuid A unique identifier for the vendor.
1197 @param[out] VarSize The size of the variable data.
1198 @param[out] VarData Pointer to the content of the variable.
1199
1200 @retval EFI_SUCCESS Operation completed successfully.
1201 @retval EFI_OUT_OF_RESOURCES Out of memory.
1202 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1203
1204 **/
1205 EFI_STATUS
1206 ReadAndMeasureVariable (
1207 IN TPM_PCRINDEX PCRIndex,
1208 IN TCG_EVENTTYPE EventType,
1209 IN CHAR16 *VarName,
1210 IN EFI_GUID *VendorGuid,
1211 OUT UINTN *VarSize,
1212 OUT VOID **VarData
1213 )
1214 {
1215 EFI_STATUS Status;
1216
1217 Status = GetVariable2 (VarName, VendorGuid, VarData, VarSize);
1218 if (EventType == EV_EFI_VARIABLE_DRIVER_CONFIG) {
1219 if (EFI_ERROR (Status)) {
1220 //
1221 // It is valid case, so we need handle it.
1222 //
1223 *VarData = NULL;
1224 *VarSize = 0;
1225 }
1226 } else {
1227 //
1228 // if status error, VarData is freed and set NULL by GetVariable2
1229 //
1230 if (EFI_ERROR (Status)) {
1231 return EFI_NOT_FOUND;
1232 }
1233 }
1234
1235 Status = MeasureVariable (
1236 PCRIndex,
1237 EventType,
1238 VarName,
1239 VendorGuid,
1240 *VarData,
1241 *VarSize
1242 );
1243 return Status;
1244 }
1245
1246 /**
1247 Read then Measure and log an EFI boot variable, and extend the measurement result into PCR[5].
1248
1249 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
1250 @param[in] VendorGuid A unique identifier for the vendor.
1251 @param[out] VarSize The size of the variable data.
1252 @param[out] VarData Pointer to the content of the variable.
1253
1254 @retval EFI_SUCCESS Operation completed successfully.
1255 @retval EFI_OUT_OF_RESOURCES Out of memory.
1256 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1257
1258 **/
1259 EFI_STATUS
1260 ReadAndMeasureBootVariable (
1261 IN CHAR16 *VarName,
1262 IN EFI_GUID *VendorGuid,
1263 OUT UINTN *VarSize,
1264 OUT VOID **VarData
1265 )
1266 {
1267 return ReadAndMeasureVariable (
1268 5,
1269 EV_EFI_VARIABLE_BOOT,
1270 VarName,
1271 VendorGuid,
1272 VarSize,
1273 VarData
1274 );
1275 }
1276
1277 /**
1278 Read then Measure and log an EFI Secure variable, and extend the measurement result into PCR[7].
1279
1280 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.
1281 @param[in] VendorGuid A unique identifier for the vendor.
1282 @param[out] VarSize The size of the variable data.
1283 @param[out] VarData Pointer to the content of the variable.
1284
1285 @retval EFI_SUCCESS Operation completed successfully.
1286 @retval EFI_OUT_OF_RESOURCES Out of memory.
1287 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1288
1289 **/
1290 EFI_STATUS
1291 ReadAndMeasureSecureVariable (
1292 IN CHAR16 *VarName,
1293 IN EFI_GUID *VendorGuid,
1294 OUT UINTN *VarSize,
1295 OUT VOID **VarData
1296 )
1297 {
1298 return ReadAndMeasureVariable (
1299 7,
1300 EV_EFI_VARIABLE_DRIVER_CONFIG,
1301 VarName,
1302 VendorGuid,
1303 VarSize,
1304 VarData
1305 );
1306 }
1307
1308 /**
1309 Measure and log all EFI boot variables, and extend the measurement result into a specific PCR.
1310
1311 The EFI boot variables are BootOrder and Boot#### variables.
1312
1313 @retval EFI_SUCCESS Operation completed successfully.
1314 @retval EFI_OUT_OF_RESOURCES Out of memory.
1315 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1316
1317 **/
1318 EFI_STATUS
1319 MeasureAllBootVariables (
1320 VOID
1321 )
1322 {
1323 EFI_STATUS Status;
1324 UINT16 *BootOrder;
1325 UINTN BootCount;
1326 UINTN Index;
1327 VOID *BootVarData;
1328 UINTN Size;
1329
1330 Status = ReadAndMeasureBootVariable (
1331 mBootVarName,
1332 &gEfiGlobalVariableGuid,
1333 &BootCount,
1334 (VOID **) &BootOrder
1335 );
1336 if (Status == EFI_NOT_FOUND || BootOrder == NULL) {
1337 return EFI_SUCCESS;
1338 }
1339
1340 if (EFI_ERROR (Status)) {
1341 //
1342 // BootOrder can't be NULL if status is not EFI_NOT_FOUND
1343 //
1344 FreePool (BootOrder);
1345 return Status;
1346 }
1347
1348 BootCount /= sizeof (*BootOrder);
1349 for (Index = 0; Index < BootCount; Index++) {
1350 UnicodeSPrint (mBootVarName, sizeof (mBootVarName), L"Boot%04x", BootOrder[Index]);
1351 Status = ReadAndMeasureBootVariable (
1352 mBootVarName,
1353 &gEfiGlobalVariableGuid,
1354 &Size,
1355 &BootVarData
1356 );
1357 if (!EFI_ERROR (Status)) {
1358 FreePool (BootVarData);
1359 }
1360 }
1361
1362 FreePool (BootOrder);
1363 return EFI_SUCCESS;
1364 }
1365
1366 /**
1367 Measure and log all EFI Secure variables, and extend the measurement result into a specific PCR.
1368
1369 The EFI boot variables are BootOrder and Boot#### variables.
1370
1371 @retval EFI_SUCCESS Operation completed successfully.
1372 @retval EFI_OUT_OF_RESOURCES Out of memory.
1373 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1374
1375 **/
1376 EFI_STATUS
1377 MeasureAllSecureVariables (
1378 VOID
1379 )
1380 {
1381 EFI_STATUS Status;
1382 VOID *Data;
1383 UINTN DataSize;
1384 UINTN Index;
1385
1386 Status = EFI_NOT_FOUND;
1387 for (Index = 0; Index < sizeof(mVariableType)/sizeof(mVariableType[0]); Index++) {
1388 Status = ReadAndMeasureSecureVariable (
1389 mVariableType[Index].VariableName,
1390 mVariableType[Index].VendorGuid,
1391 &DataSize,
1392 &Data
1393 );
1394 if (!EFI_ERROR (Status)) {
1395 if (Data != NULL) {
1396 FreePool (Data);
1397 }
1398 }
1399 }
1400
1401 return EFI_SUCCESS;
1402 }
1403
1404 /**
1405 Measure and log launch of FirmwareDebugger, and extend the measurement result into a specific PCR.
1406
1407 @retval EFI_SUCCESS Operation completed successfully.
1408 @retval EFI_OUT_OF_RESOURCES Out of memory.
1409 @retval EFI_DEVICE_ERROR The operation was unsuccessful.
1410
1411 **/
1412 EFI_STATUS
1413 MeasureLaunchOfFirmwareDebugger (
1414 VOID
1415 )
1416 {
1417 TCG_PCR_EVENT_HDR TcgEvent;
1418
1419 TcgEvent.PCRIndex = 7;
1420 TcgEvent.EventType = EV_EFI_ACTION;
1421 TcgEvent.EventSize = sizeof(FIRMWARE_DEBUGGER_EVENT_STRING) - 1;
1422 return TcgDxeHashLogExtendEvent (
1423 0,
1424 (UINT8 *)FIRMWARE_DEBUGGER_EVENT_STRING,
1425 sizeof(FIRMWARE_DEBUGGER_EVENT_STRING) - 1,
1426 &TcgEvent,
1427 (UINT8 *)FIRMWARE_DEBUGGER_EVENT_STRING
1428 );
1429 }
1430
1431 /**
1432 Measure and log all Secure Boot Policy, and extend the measurement result into a specific PCR.
1433
1434 Platform firmware adhering to the policy must therefore measure the following values into PCR[7]: (in order listed)
1435 - The contents of the SecureBoot variable
1436 - The contents of the PK variable
1437 - The contents of the KEK variable
1438 - The contents of the EFI_IMAGE_SECURITY_DATABASE variable
1439 - The contents of the EFI_IMAGE_SECURITY_DATABASE1 variable
1440 - Separator
1441 - Entries in the EFI_IMAGE_SECURITY_DATABASE that are used to validate EFI Drivers or EFI Boot Applications in the boot path
1442
1443 NOTE: Because of the above, UEFI variables PK, KEK, EFI_IMAGE_SECURITY_DATABASE,
1444 EFI_IMAGE_SECURITY_DATABASE1 and SecureBoot SHALL NOT be measured into PCR[3].
1445
1446 @param[in] Event Event whose notification function is being invoked
1447 @param[in] Context Pointer to the notification function's context
1448 **/
1449 VOID
1450 EFIAPI
1451 MeasureSecureBootPolicy (
1452 IN EFI_EVENT Event,
1453 IN VOID *Context
1454 )
1455 {
1456 EFI_STATUS Status;
1457 VOID *Protocol;
1458
1459 Status = gBS->LocateProtocol (&gEfiVariableWriteArchProtocolGuid, NULL, (VOID **)&Protocol);
1460 if (EFI_ERROR (Status)) {
1461 return;
1462 }
1463
1464 if (PcdGetBool (PcdFirmwareDebuggerInitialized)) {
1465 Status = MeasureLaunchOfFirmwareDebugger ();
1466 DEBUG ((EFI_D_INFO, "MeasureLaunchOfFirmwareDebugger - %r\n", Status));
1467 }
1468
1469 Status = MeasureAllSecureVariables ();
1470 DEBUG ((EFI_D_INFO, "MeasureAllSecureVariables - %r\n", Status));
1471
1472 //
1473 // We need measure Separator(7) here, because this event must be between SecureBootPolicy (Configure)
1474 // and ImageVerification (Authority)
1475 // There might be a case that we need measure UEFI image from DriverOrder, besides BootOrder. So
1476 // the Authority measurement happen before ReadToBoot event.
1477 //
1478 Status = MeasureSeparatorEvent (7);
1479 DEBUG ((EFI_D_INFO, "MeasureSeparatorEvent - %r\n", Status));
1480 return ;
1481 }
1482
1483 /**
1484 Ready to Boot Event notification handler.
1485
1486 Sequence of OS boot events is measured in this event notification handler.
1487
1488 @param[in] Event Event whose notification function is being invoked
1489 @param[in] Context Pointer to the notification function's context
1490
1491 **/
1492 VOID
1493 EFIAPI
1494 OnReadyToBoot (
1495 IN EFI_EVENT Event,
1496 IN VOID *Context
1497 )
1498 {
1499 EFI_STATUS Status;
1500 TPM_PCRINDEX PcrIndex;
1501
1502 PERF_START_EX (mImageHandle, "EventRec", "TrEEDxe", 0, PERF_ID_TREE_DXE);
1503 if (mBootAttempts == 0) {
1504
1505 //
1506 // Measure handoff tables.
1507 //
1508 Status = MeasureHandoffTables ();
1509 if (EFI_ERROR (Status)) {
1510 DEBUG ((EFI_D_ERROR, "HOBs not Measured. Error!\n"));
1511 }
1512
1513 //
1514 // Measure BootOrder & Boot#### variables.
1515 //
1516 Status = MeasureAllBootVariables ();
1517 if (EFI_ERROR (Status)) {
1518 DEBUG ((EFI_D_ERROR, "Boot Variables not Measured. Error!\n"));
1519 }
1520
1521 //
1522 // 1. This is the first boot attempt.
1523 //
1524 Status = TcgMeasureAction (
1525 EFI_CALLING_EFI_APPLICATION
1526 );
1527 if (EFI_ERROR (Status)) {
1528 DEBUG ((EFI_D_ERROR, "%s not Measured. Error!\n", EFI_CALLING_EFI_APPLICATION));
1529 }
1530
1531 //
1532 // 2. Draw a line between pre-boot env and entering post-boot env.
1533 // PCR[7] is already done.
1534 //
1535 for (PcrIndex = 0; PcrIndex < 7; PcrIndex++) {
1536 Status = MeasureSeparatorEvent (PcrIndex);
1537 if (EFI_ERROR (Status)) {
1538 DEBUG ((EFI_D_ERROR, "Seperator Event not Measured. Error!\n"));
1539 }
1540 }
1541
1542 //
1543 // 3. Measure GPT. It would be done in SAP driver.
1544 //
1545
1546 //
1547 // 4. Measure PE/COFF OS loader. It would be done in SAP driver.
1548 //
1549
1550 //
1551 // 5. Read & Measure variable. BootOrder already measured.
1552 //
1553 } else {
1554 //
1555 // 6. Not first attempt, meaning a return from last attempt
1556 //
1557 Status = TcgMeasureAction (
1558 EFI_RETURNING_FROM_EFI_APPLICATOIN
1559 );
1560 if (EFI_ERROR (Status)) {
1561 DEBUG ((EFI_D_ERROR, "%s not Measured. Error!\n", EFI_RETURNING_FROM_EFI_APPLICATOIN));
1562 }
1563 }
1564
1565 DEBUG ((EFI_D_INFO, "TPM2 TrEEDxe Measure Data when ReadyToBoot\n"));
1566 //
1567 // Increase boot attempt counter.
1568 //
1569 mBootAttempts++;
1570 PERF_END_EX (mImageHandle, "EventRec", "TrEEDxe", 0, PERF_ID_TREE_DXE + 1);
1571 }
1572
1573 /**
1574 Install TCG ACPI Table when ACPI Table Protocol is available.
1575
1576 A system's firmware uses an ACPI table to identify the system's TCG capabilities
1577 to the Post-Boot environment. The information in this ACPI table is not guaranteed
1578 to be valid until the Host Platform transitions from pre-boot state to post-boot state.
1579
1580 @param[in] Event Event whose notification function is being invoked
1581 @param[in] Context Pointer to the notification function's context
1582 **/
1583 VOID
1584 EFIAPI
1585 InstallAcpiTable (
1586 IN EFI_EVENT Event,
1587 IN VOID *Context
1588 )
1589 {
1590 UINTN TableKey;
1591 EFI_STATUS Status;
1592 EFI_ACPI_TABLE_PROTOCOL *AcpiTable;
1593 UINT8 Checksum;
1594 UINT64 OemTableId;
1595
1596 Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **)&AcpiTable);
1597 if (EFI_ERROR (Status)) {
1598 return;
1599 }
1600
1601 if (PcdGet8 (PcdTpmPlatformClass) == TCG_PLATFORM_TYPE_CLIENT) {
1602 CopyMem (mTcgClientAcpiTemplate.Header.OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (mTcgClientAcpiTemplate.Header.OemId));
1603 OemTableId = PcdGet64 (PcdAcpiDefaultOemTableId);
1604 CopyMem (&mTcgClientAcpiTemplate.Header.OemTableId, &OemTableId, sizeof (UINT64));
1605 mTcgClientAcpiTemplate.Header.OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision);
1606 mTcgClientAcpiTemplate.Header.CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId);
1607 mTcgClientAcpiTemplate.Header.CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision);
1608 //
1609 // The ACPI table must be checksumed before calling the InstallAcpiTable()
1610 // service of the ACPI table protocol to install it.
1611 //
1612 Checksum = CalculateCheckSum8 ((UINT8 *)&mTcgClientAcpiTemplate, sizeof (mTcgClientAcpiTemplate));
1613 mTcgClientAcpiTemplate.Header.Checksum = Checksum;
1614
1615 Status = AcpiTable->InstallAcpiTable (
1616 AcpiTable,
1617 &mTcgClientAcpiTemplate,
1618 sizeof (mTcgClientAcpiTemplate),
1619 &TableKey
1620 );
1621 } else {
1622 CopyMem (mTcgServerAcpiTemplate.Header.OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (mTcgServerAcpiTemplate.Header.OemId));
1623 OemTableId = PcdGet64 (PcdAcpiDefaultOemTableId);
1624 CopyMem (&mTcgServerAcpiTemplate.Header.OemTableId, &OemTableId, sizeof (UINT64));
1625 mTcgServerAcpiTemplate.Header.OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision);
1626 mTcgServerAcpiTemplate.Header.CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId);
1627 mTcgServerAcpiTemplate.Header.CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision);
1628 //
1629 // The ACPI table must be checksumed before calling the InstallAcpiTable()
1630 // service of the ACPI table protocol to install it.
1631 //
1632 Checksum = CalculateCheckSum8 ((UINT8 *)&mTcgServerAcpiTemplate, sizeof (mTcgServerAcpiTemplate));
1633 mTcgServerAcpiTemplate.Header.Checksum = Checksum;
1634
1635 mTcgServerAcpiTemplate.BaseAddress.Address = PcdGet64 (PcdTpmBaseAddress);
1636 Status = AcpiTable->InstallAcpiTable (
1637 AcpiTable,
1638 &mTcgServerAcpiTemplate,
1639 sizeof (mTcgServerAcpiTemplate),
1640 &TableKey
1641 );
1642 }
1643
1644 if (EFI_ERROR (Status)) {
1645 DEBUG((EFI_D_ERROR, "Tcg Acpi Table installation failure"));
1646 }
1647 }
1648
1649 /**
1650 Exit Boot Services Event notification handler.
1651
1652 Measure invocation and success of ExitBootServices.
1653
1654 @param[in] Event Event whose notification function is being invoked
1655 @param[in] Context Pointer to the notification function's context
1656
1657 **/
1658 VOID
1659 EFIAPI
1660 OnExitBootServices (
1661 IN EFI_EVENT Event,
1662 IN VOID *Context
1663 )
1664 {
1665 EFI_STATUS Status;
1666
1667 //
1668 // Measure invocation of ExitBootServices,
1669 //
1670 Status = TcgMeasureAction (
1671 EFI_EXIT_BOOT_SERVICES_INVOCATION
1672 );
1673 if (EFI_ERROR (Status)) {
1674 DEBUG ((EFI_D_ERROR, "%s not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_INVOCATION));
1675 }
1676
1677 //
1678 // Measure success of ExitBootServices
1679 //
1680 Status = TcgMeasureAction (
1681 EFI_EXIT_BOOT_SERVICES_SUCCEEDED
1682 );
1683 if (EFI_ERROR (Status)) {
1684 DEBUG ((EFI_D_ERROR, "%s not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_SUCCEEDED));
1685 }
1686 }
1687
1688 /**
1689 Exit Boot Services Failed Event notification handler.
1690
1691 Measure Failure of ExitBootServices.
1692
1693 @param[in] Event Event whose notification function is being invoked
1694 @param[in] Context Pointer to the notification function's context
1695
1696 **/
1697 VOID
1698 EFIAPI
1699 OnExitBootServicesFailed (
1700 IN EFI_EVENT Event,
1701 IN VOID *Context
1702 )
1703 {
1704 EFI_STATUS Status;
1705
1706 //
1707 // Measure Failure of ExitBootServices,
1708 //
1709 Status = TcgMeasureAction (
1710 EFI_EXIT_BOOT_SERVICES_FAILED
1711 );
1712 if (EFI_ERROR (Status)) {
1713 DEBUG ((EFI_D_ERROR, "%s not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_FAILED));
1714 }
1715
1716 }
1717
1718 /**
1719 The function install TrEE protocol.
1720
1721 @retval EFI_SUCCESS TrEE protocol is installed.
1722 @retval other Some error occurs.
1723 **/
1724 EFI_STATUS
1725 InstallTrEE (
1726 VOID
1727 )
1728 {
1729 EFI_STATUS Status;
1730 EFI_HANDLE Handle;
1731
1732 Handle = NULL;
1733 Status = gBS->InstallMultipleProtocolInterfaces (
1734 &Handle,
1735 &gEfiTrEEProtocolGuid,
1736 &mTreeProtocol,
1737 NULL
1738 );
1739 return Status;
1740 }
1741
1742 /**
1743 The driver's entry point. It publishes EFI TrEE Protocol.
1744
1745 @param[in] ImageHandle The firmware allocated handle for the EFI image.
1746 @param[in] SystemTable A pointer to the EFI System Table.
1747
1748 @retval EFI_SUCCESS The entry point is executed successfully.
1749 @retval other Some error occurs when executing this entry point.
1750 **/
1751 EFI_STATUS
1752 EFIAPI
1753 DriverEntry (
1754 IN EFI_HANDLE ImageHandle,
1755 IN EFI_SYSTEM_TABLE *SystemTable
1756 )
1757 {
1758 EFI_STATUS Status;
1759 EFI_EVENT Event;
1760 VOID *Registration;
1761 UINT32 MaxCommandSize;
1762 UINT32 MaxResponseSize;
1763 TPML_PCR_SELECTION Pcrs;
1764 UINTN Index;
1765 UINT32 TpmHashAlgorithmBitmap;
1766
1767 mImageHandle = ImageHandle;
1768
1769 if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceNoneGuid) ||
1770 CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)){
1771 DEBUG ((EFI_D_ERROR, "No TPM2 instance required!\n"));
1772 return EFI_UNSUPPORTED;
1773 }
1774
1775 if (GetFirstGuidHob (&gTpmErrorHobGuid) != NULL) {
1776 DEBUG ((EFI_D_ERROR, "TPM2 error!\n"));
1777 return EFI_DEVICE_ERROR;
1778 }
1779
1780 Status = Tpm2RequestUseTpm ();
1781 if (EFI_ERROR (Status)) {
1782 DEBUG ((EFI_D_ERROR, "TPM2 not detected!\n"));
1783 return Status;
1784 }
1785
1786 //
1787 // Fill information
1788 //
1789 DEBUG ((EFI_D_INFO, "TrEE.ProtocolVersion - %02x.%02x\n", mTcgDxeData.BsCap.ProtocolVersion.Major, mTcgDxeData.BsCap.ProtocolVersion.Minor));
1790 DEBUG ((EFI_D_INFO, "TrEE.StructureVersion - %02x.%02x\n", mTcgDxeData.BsCap.StructureVersion.Major, mTcgDxeData.BsCap.StructureVersion.Minor));
1791
1792 Status = Tpm2GetCapabilityManufactureID (&mTcgDxeData.BsCap.ManufacturerID);
1793 if (EFI_ERROR (Status)) {
1794 DEBUG ((EFI_D_ERROR, "Tpm2GetCapabilityManufactureID fail!\n"));
1795 } else {
1796 DEBUG ((EFI_D_INFO, "Tpm2GetCapabilityManufactureID - %08x\n", mTcgDxeData.BsCap.ManufacturerID));
1797 }
1798
1799 DEBUG_CODE (
1800 UINT32 FirmwareVersion1;
1801 UINT32 FirmwareVersion2;
1802
1803 Status = Tpm2GetCapabilityFirmwareVersion (&FirmwareVersion1, &FirmwareVersion2);
1804 if (EFI_ERROR (Status)) {
1805 DEBUG ((EFI_D_ERROR, "Tpm2GetCapabilityFirmwareVersion fail!\n"));
1806 } else {
1807 DEBUG ((EFI_D_INFO, "Tpm2GetCapabilityFirmwareVersion - %08x %08x\n", FirmwareVersion1, FirmwareVersion2));
1808 }
1809 );
1810
1811 Status = Tpm2GetCapabilityMaxCommandResponseSize (&MaxCommandSize, &MaxResponseSize);
1812 if (EFI_ERROR (Status)) {
1813 DEBUG ((EFI_D_ERROR, "Tpm2GetCapabilityMaxCommandResponseSize fail!\n"));
1814 } else {
1815 mTcgDxeData.BsCap.MaxCommandSize = (UINT16)MaxCommandSize;
1816 mTcgDxeData.BsCap.MaxResponseSize = (UINT16)MaxResponseSize;
1817 DEBUG ((EFI_D_INFO, "Tpm2GetCapabilityMaxCommandResponseSize - %08x, %08x\n", MaxCommandSize, MaxResponseSize));
1818 }
1819
1820 Status = Tpm2GetCapabilityPcrs (&Pcrs);
1821 if (EFI_ERROR (Status)) {
1822 DEBUG ((EFI_D_ERROR, "Tpm2GetCapabilityPcrs fail!\n"));
1823 TpmHashAlgorithmBitmap = TREE_BOOT_HASH_ALG_SHA1;
1824 } else {
1825 DEBUG ((EFI_D_INFO, "Tpm2GetCapabilityPcrs Count - %08x\n", Pcrs.count));
1826 TpmHashAlgorithmBitmap = 0;
1827 for (Index = 0; Index < Pcrs.count; Index++) {
1828 DEBUG ((EFI_D_INFO, "hash - %x\n", Pcrs.pcrSelections[Index].hash));
1829 switch (Pcrs.pcrSelections[Index].hash) {
1830 case TPM_ALG_SHA1:
1831 TpmHashAlgorithmBitmap |= TREE_BOOT_HASH_ALG_SHA1;
1832 break;
1833 case TPM_ALG_SHA256:
1834 TpmHashAlgorithmBitmap |= TREE_BOOT_HASH_ALG_SHA256;
1835 break;
1836 case TPM_ALG_SHA384:
1837 TpmHashAlgorithmBitmap |= TREE_BOOT_HASH_ALG_SHA384;
1838 break;
1839 case TPM_ALG_SHA512:
1840 TpmHashAlgorithmBitmap |= TREE_BOOT_HASH_ALG_SHA512;
1841 break;
1842 case TPM_ALG_SM3_256:
1843 // TBD: Spec not define TREE_BOOT_HASH_ALG_SM3_256 yet
1844 break;
1845 }
1846 }
1847 }
1848 DEBUG ((EFI_D_INFO, "TPM.HashAlgorithmBitmap - 0x%08x\n", TpmHashAlgorithmBitmap));
1849
1850 DEBUG ((EFI_D_INFO, "TrEE.SupportedEventLogs - 0x%08x\n", mTcgDxeData.BsCap.SupportedEventLogs));
1851 mTcgDxeData.BsCap.HashAlgorithmBitmap = TpmHashAlgorithmBitmap;
1852 DEBUG ((EFI_D_INFO, "TrEE.HashAlgorithmBitmap - 0x%08x\n", mTcgDxeData.BsCap.HashAlgorithmBitmap));
1853
1854 if (mTcgDxeData.BsCap.TrEEPresentFlag) {
1855 //
1856 // Setup the log area and copy event log from hob list to it
1857 //
1858 Status = SetupEventLog ();
1859 ASSERT_EFI_ERROR (Status);
1860
1861 //
1862 // Measure handoff tables, Boot#### variables etc.
1863 //
1864 Status = EfiCreateEventReadyToBootEx (
1865 TPL_CALLBACK,
1866 OnReadyToBoot,
1867 NULL,
1868 &Event
1869 );
1870
1871 Status = gBS->CreateEventEx (
1872 EVT_NOTIFY_SIGNAL,
1873 TPL_NOTIFY,
1874 OnExitBootServices,
1875 NULL,
1876 &gEfiEventExitBootServicesGuid,
1877 &Event
1878 );
1879
1880 //
1881 // Measure Exit Boot Service failed
1882 //
1883 Status = gBS->CreateEventEx (
1884 EVT_NOTIFY_SIGNAL,
1885 TPL_NOTIFY,
1886 OnExitBootServicesFailed,
1887 NULL,
1888 &gEventExitBootServicesFailedGuid,
1889 &Event
1890 );
1891
1892 //
1893 // Create event callback, because we need access variable on SecureBootPolicyVariable
1894 // We should use VariableWriteArch instead of VariableArch, because Variable driver
1895 // may update SecureBoot value based on last setting.
1896 //
1897 EfiCreateProtocolNotifyEvent (&gEfiVariableWriteArchProtocolGuid, TPL_CALLBACK, MeasureSecureBootPolicy, NULL, &Registration);
1898 }
1899
1900 //
1901 // Install ACPI Table
1902 //
1903 EfiCreateProtocolNotifyEvent (&gEfiAcpiTableProtocolGuid, TPL_CALLBACK, InstallAcpiTable, NULL, &Registration);
1904
1905 //
1906 // Install TrEEProtocol
1907 //
1908 Status = InstallTrEE ();
1909 DEBUG ((EFI_D_INFO, "InstallTrEE - %r\n", Status));
1910
1911 return Status;
1912 }