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