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