+++ /dev/null
-/** @file\r
- This module implements measuring PeCoff image for TrEE Protocol.\r
- \r
- Caution: This file requires additional review when modified.\r
- This driver will have external input - PE/COFF image.\r
- This external input must be validated carefully to avoid security issue like\r
- buffer overflow, integer overflow.\r
-\r
-Copyright (c) 2013 - 2017, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials \r
-are licensed and made available under the terms and conditions of the BSD License \r
-which accompanies this distribution. The full text of the license may be found at \r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-#include <PiDxe.h>\r
-\r
-#include <Library/BaseLib.h>\r
-#include <Library/DebugLib.h>\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/MemoryAllocationLib.h>\r
-#include <Library/DevicePathLib.h>\r
-#include <Library/UefiBootServicesTableLib.h>\r
-#include <Library/PeCoffLib.h>\r
-#include <Library/Tpm2CommandLib.h>\r
-#include <Library/HashLib.h>\r
-\r
-UINTN mTrEEDxeImageSize = 0;\r
-\r
-/**\r
- Reads contents of a PE/COFF image in memory buffer.\r
-\r
- Caution: This function may receive untrusted input.\r
- PE/COFF image is external input, so this function will make sure the PE/COFF image content\r
- read is within the image buffer.\r
-\r
- @param FileHandle Pointer to the file handle to read the PE/COFF image.\r
- @param FileOffset Offset into the PE/COFF image to begin the read operation.\r
- @param ReadSize On input, the size in bytes of the requested read operation.\r
- On output, the number of bytes actually read.\r
- @param Buffer Output buffer that contains the data read from the PE/COFF image.\r
-\r
- @retval EFI_SUCCESS The specified portion of the PE/COFF image was read and the size\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-TrEEDxeImageRead (\r
- IN VOID *FileHandle,\r
- IN UINTN FileOffset,\r
- IN OUT UINTN *ReadSize,\r
- OUT VOID *Buffer\r
- )\r
-{\r
- UINTN EndPosition;\r
-\r
- if (FileHandle == NULL || ReadSize == NULL || Buffer == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (MAX_ADDRESS - FileOffset < *ReadSize) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- EndPosition = FileOffset + *ReadSize;\r
- if (EndPosition > mTrEEDxeImageSize) {\r
- *ReadSize = (UINT32)(mTrEEDxeImageSize - FileOffset);\r
- }\r
-\r
- if (FileOffset >= mTrEEDxeImageSize) {\r
- *ReadSize = 0;\r
- }\r
-\r
- CopyMem (Buffer, (UINT8 *)((UINTN) FileHandle + FileOffset), *ReadSize);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Measure PE image into TPM log based on the authenticode image hashing in\r
- PE/COFF Specification 8.0 Appendix A.\r
-\r
- Caution: This function may receive untrusted input.\r
- PE/COFF image is external input, so this function will validate its data structure\r
- within this image buffer before use.\r
-\r
- Notes: PE/COFF image is checked by BasePeCoffLib PeCoffLoaderGetImageInfo().\r
-\r
- @param[in] PCRIndex TPM PCR index\r
- @param[in] ImageAddress Start address of image buffer.\r
- @param[in] ImageSize Image size\r
- @param[out] DigestList Digeest list of this image.\r
-\r
- @retval EFI_SUCCESS Successfully measure image.\r
- @retval EFI_OUT_OF_RESOURCES No enough resource to measure image.\r
- @retval other error value\r
-**/\r
-EFI_STATUS\r
-MeasurePeImageAndExtend (\r
- IN UINT32 PCRIndex,\r
- IN EFI_PHYSICAL_ADDRESS ImageAddress,\r
- IN UINTN ImageSize,\r
- OUT TPML_DIGEST_VALUES *DigestList\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_IMAGE_DOS_HEADER *DosHdr;\r
- UINT32 PeCoffHeaderOffset;\r
- EFI_IMAGE_SECTION_HEADER *Section;\r
- UINT8 *HashBase;\r
- UINTN HashSize;\r
- UINTN SumOfBytesHashed;\r
- EFI_IMAGE_SECTION_HEADER *SectionHeader;\r
- UINTN Index;\r
- UINTN Pos;\r
- UINT16 Magic;\r
- EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;\r
- UINT32 NumberOfRvaAndSizes;\r
- UINT32 CertSize;\r
- HASH_HANDLE HashHandle;\r
- PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;\r
-\r
- HashHandle = 0xFFFFFFFF; // Know bad value\r
-\r
- Status = EFI_UNSUPPORTED;\r
- SectionHeader = NULL;\r
-\r
- //\r
- // Check PE/COFF image\r
- //\r
- ZeroMem (&ImageContext, sizeof (ImageContext));\r
- ImageContext.Handle = (VOID *) (UINTN) ImageAddress;\r
- mTrEEDxeImageSize = ImageSize;\r
- ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) TrEEDxeImageRead;\r
-\r
- //\r
- // Get information about the image being loaded\r
- //\r
- Status = PeCoffLoaderGetImageInfo (&ImageContext);\r
- if (EFI_ERROR (Status)) {\r
- //\r
- // The information can't be got from the invalid PeImage\r
- //\r
- DEBUG ((DEBUG_INFO, "TreeDxe: PeImage invalid. Cannot retrieve image information.\n"));\r
- goto Finish;\r
- }\r
-\r
- DosHdr = (EFI_IMAGE_DOS_HEADER *) (UINTN) ImageAddress;\r
- PeCoffHeaderOffset = 0;\r
- if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {\r
- PeCoffHeaderOffset = DosHdr->e_lfanew;\r
- }\r
-\r
- Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINT8 *) (UINTN) ImageAddress + PeCoffHeaderOffset);\r
- if (Hdr.Pe32->Signature != EFI_IMAGE_NT_SIGNATURE) {\r
- Status = EFI_UNSUPPORTED;\r
- goto Finish;\r
- }\r
-\r
- //\r
- // PE/COFF Image Measurement\r
- //\r
- // NOTE: The following codes/steps are based upon the authenticode image hashing in\r
- // PE/COFF Specification 8.0 Appendix A.\r
- //\r
- //\r
-\r
- // 1. Load the image header into memory.\r
-\r
- // 2. Initialize a SHA hash context.\r
-\r
- Status = HashStart (&HashHandle);\r
- if (EFI_ERROR (Status)) {\r
- goto Finish;\r
- }\r
-\r
- //\r
- // Measuring PE/COFF Image Header;\r
- // But CheckSum field and SECURITY data directory (certificate) are excluded\r
- //\r
- if (Hdr.Pe32->FileHeader.Machine == IMAGE_FILE_MACHINE_IA64 && Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
- //\r
- // NOTE: Some versions of Linux ELILO for Itanium have an incorrect magic value \r
- // in the PE/COFF Header. If the MachineType is Itanium(IA64) and the \r
- // Magic value in the OptionalHeader is EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC\r
- // then override the magic value to EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC\r
- //\r
- Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;\r
- } else {\r
- //\r
- // Get the magic value from the PE/COFF Optional Header\r
- //\r
- Magic = Hdr.Pe32->OptionalHeader.Magic;\r
- }\r
- \r
- //\r
- // 3. Calculate the distance from the base of the image header to the image checksum address.\r
- // 4. Hash the image header from its base to beginning of the image checksum.\r
- //\r
- HashBase = (UINT8 *) (UINTN) ImageAddress;\r
- if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
- //\r
- // Use PE32 offset\r
- //\r
- NumberOfRvaAndSizes = Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes;\r
- HashSize = (UINTN) (&Hdr.Pe32->OptionalHeader.CheckSum) - (UINTN) HashBase;\r
- } else {\r
- //\r
- // Use PE32+ offset\r
- //\r
- NumberOfRvaAndSizes = Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes;\r
- HashSize = (UINTN) (&Hdr.Pe32Plus->OptionalHeader.CheckSum) - (UINTN) HashBase;\r
- }\r
-\r
- Status = HashUpdate (HashHandle, HashBase, HashSize);\r
- if (EFI_ERROR (Status)) {\r
- goto Finish;\r
- } \r
-\r
- //\r
- // 5. Skip over the image checksum (it occupies a single ULONG).\r
- //\r
- if (NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_SECURITY) {\r
- //\r
- // 6. Since there is no Cert Directory in optional header, hash everything\r
- // from the end of the checksum to the end of image header.\r
- //\r
- if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
- //\r
- // Use PE32 offset.\r
- //\r
- HashBase = (UINT8 *) &Hdr.Pe32->OptionalHeader.CheckSum + sizeof (UINT32);\r
- HashSize = Hdr.Pe32->OptionalHeader.SizeOfHeaders - (UINTN) (HashBase - ImageAddress);\r
- } else {\r
- //\r
- // Use PE32+ offset.\r
- //\r
- HashBase = (UINT8 *) &Hdr.Pe32Plus->OptionalHeader.CheckSum + sizeof (UINT32);\r
- HashSize = Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders - (UINTN) (HashBase - ImageAddress);\r
- }\r
-\r
- if (HashSize != 0) {\r
- Status = HashUpdate (HashHandle, HashBase, HashSize);\r
- if (EFI_ERROR (Status)) {\r
- goto Finish;\r
- }\r
- } \r
- } else {\r
- //\r
- // 7. Hash everything from the end of the checksum to the start of the Cert Directory.\r
- //\r
- if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
- //\r
- // Use PE32 offset\r
- //\r
- HashBase = (UINT8 *) &Hdr.Pe32->OptionalHeader.CheckSum + sizeof (UINT32);\r
- HashSize = (UINTN) (&Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - (UINTN) HashBase;\r
- } else {\r
- //\r
- // Use PE32+ offset\r
- // \r
- HashBase = (UINT8 *) &Hdr.Pe32Plus->OptionalHeader.CheckSum + sizeof (UINT32);\r
- HashSize = (UINTN) (&Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - (UINTN) HashBase;\r
- }\r
-\r
- if (HashSize != 0) {\r
- Status = HashUpdate (HashHandle, HashBase, HashSize);\r
- if (EFI_ERROR (Status)) {\r
- goto Finish;\r
- }\r
- }\r
-\r
- //\r
- // 8. Skip over the Cert Directory. (It is sizeof(IMAGE_DATA_DIRECTORY) bytes.)\r
- // 9. Hash everything from the end of the Cert Directory to the end of image header.\r
- //\r
- if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
- //\r
- // Use PE32 offset\r
- //\r
- HashBase = (UINT8 *) &Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1];\r
- HashSize = Hdr.Pe32->OptionalHeader.SizeOfHeaders - (UINTN) (HashBase - ImageAddress);\r
- } else {\r
- //\r
- // Use PE32+ offset\r
- //\r
- HashBase = (UINT8 *) &Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1];\r
- HashSize = Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders - (UINTN) (HashBase - ImageAddress);\r
- }\r
- \r
- if (HashSize != 0) {\r
- Status = HashUpdate (HashHandle, HashBase, HashSize);\r
- if (EFI_ERROR (Status)) {\r
- goto Finish;\r
- }\r
- }\r
- }\r
-\r
- //\r
- // 10. Set the SUM_OF_BYTES_HASHED to the size of the header\r
- //\r
- if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
- //\r
- // Use PE32 offset\r
- //\r
- SumOfBytesHashed = Hdr.Pe32->OptionalHeader.SizeOfHeaders;\r
- } else {\r
- //\r
- // Use PE32+ offset\r
- //\r
- SumOfBytesHashed = Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders;\r
- }\r
-\r
- //\r
- // 11. Build a temporary table of pointers to all the IMAGE_SECTION_HEADER\r
- // structures in the image. The 'NumberOfSections' field of the image\r
- // header indicates how big the table should be. Do not include any\r
- // IMAGE_SECTION_HEADERs in the table whose 'SizeOfRawData' field is zero.\r
- //\r
- SectionHeader = (EFI_IMAGE_SECTION_HEADER *) AllocateZeroPool (sizeof (EFI_IMAGE_SECTION_HEADER) * Hdr.Pe32->FileHeader.NumberOfSections);\r
- if (SectionHeader == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto Finish;\r
- }\r
-\r
- //\r
- // 12. Using the 'PointerToRawData' in the referenced section headers as\r
- // a key, arrange the elements in the table in ascending order. In other\r
- // words, sort the section headers according to the disk-file offset of\r
- // the section.\r
- //\r
- Section = (EFI_IMAGE_SECTION_HEADER *) (\r
- (UINT8 *) (UINTN) ImageAddress +\r
- PeCoffHeaderOffset +\r
- sizeof(UINT32) +\r
- sizeof(EFI_IMAGE_FILE_HEADER) +\r
- Hdr.Pe32->FileHeader.SizeOfOptionalHeader\r
- );\r
- for (Index = 0; Index < Hdr.Pe32->FileHeader.NumberOfSections; Index++) {\r
- Pos = Index;\r
- while ((Pos > 0) && (Section->PointerToRawData < SectionHeader[Pos - 1].PointerToRawData)) {\r
- CopyMem (&SectionHeader[Pos], &SectionHeader[Pos - 1], sizeof(EFI_IMAGE_SECTION_HEADER));\r
- Pos--;\r
- }\r
- CopyMem (&SectionHeader[Pos], Section, sizeof(EFI_IMAGE_SECTION_HEADER));\r
- Section += 1;\r
- }\r
-\r
- //\r
- // 13. Walk through the sorted table, bring the corresponding section\r
- // into memory, and hash the entire section (using the 'SizeOfRawData'\r
- // field in the section header to determine the amount of data to hash).\r
- // 14. Add the section's 'SizeOfRawData' to SUM_OF_BYTES_HASHED .\r
- // 15. Repeat steps 13 and 14 for all the sections in the sorted table.\r
- //\r
- for (Index = 0; Index < Hdr.Pe32->FileHeader.NumberOfSections; Index++) {\r
- Section = (EFI_IMAGE_SECTION_HEADER *) &SectionHeader[Index];\r
- if (Section->SizeOfRawData == 0) {\r
- continue;\r
- }\r
- HashBase = (UINT8 *) (UINTN) ImageAddress + Section->PointerToRawData;\r
- HashSize = (UINTN) Section->SizeOfRawData;\r
-\r
- Status = HashUpdate (HashHandle, HashBase, HashSize);\r
- if (EFI_ERROR (Status)) {\r
- goto Finish;\r
- }\r
-\r
- SumOfBytesHashed += HashSize;\r
- }\r
-\r
- //\r
- // 16. If the file size is greater than SUM_OF_BYTES_HASHED, there is extra\r
- // data in the file that needs to be added to the hash. This data begins\r
- // at file offset SUM_OF_BYTES_HASHED and its length is:\r
- // FileSize - (CertDirectory->Size)\r
- //\r
- if (ImageSize > SumOfBytesHashed) {\r
- HashBase = (UINT8 *) (UINTN) ImageAddress + SumOfBytesHashed;\r
-\r
- if (NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_SECURITY) {\r
- CertSize = 0;\r
- } else {\r
- if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
- //\r
- // Use PE32 offset.\r
- //\r
- CertSize = Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size;\r
- } else {\r
- //\r
- // Use PE32+ offset.\r
- //\r
- CertSize = Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size;\r
- }\r
- }\r
-\r
- if (ImageSize > CertSize + SumOfBytesHashed) {\r
- HashSize = (UINTN) (ImageSize - CertSize - SumOfBytesHashed);\r
-\r
- Status = HashUpdate (HashHandle, HashBase, HashSize);\r
- if (EFI_ERROR (Status)) {\r
- goto Finish;\r
- }\r
- } else if (ImageSize < CertSize + SumOfBytesHashed) {\r
- Status = EFI_UNSUPPORTED;\r
- goto Finish;\r
- }\r
- }\r
-\r
- //\r
- // 17. Finalize the SHA hash.\r
- //\r
- Status = HashCompleteAndExtend (HashHandle, PCRIndex, NULL, 0, DigestList);\r
- if (EFI_ERROR (Status)) {\r
- goto Finish;\r
- }\r
-\r
-Finish:\r
- if (SectionHeader != NULL) {\r
- FreePool (SectionHeader);\r
- }\r
-\r
- return Status;\r
-}\r
+++ /dev/null
-/** @file\r
- This module implements TrEE Protocol.\r
- \r
-Copyright (c) 2013 - 2017, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials \r
-are licensed and made available under the terms and conditions of the BSD License \r
-which accompanies this distribution. The full text of the license may be found at \r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-#include <PiDxe.h>\r
-#include <IndustryStandard/Acpi.h>\r
-#include <IndustryStandard/PeImage.h>\r
-#include <IndustryStandard/TcpaAcpi.h>\r
-\r
-#include <Guid/GlobalVariable.h>\r
-#include <Guid/HobList.h>\r
-#include <Guid/TcgEventHob.h>\r
-#include <Guid/EventGroup.h>\r
-#include <Guid/EventExitBootServiceFailed.h>\r
-#include <Guid/ImageAuthentication.h>\r
-#include <Guid/TpmInstance.h>\r
-\r
-#include <Protocol/DevicePath.h>\r
-#include <Protocol/AcpiTable.h>\r
-#include <Protocol/MpService.h>\r
-#include <Protocol/VariableWrite.h>\r
-#include <Protocol/TrEEProtocol.h>\r
-\r
-#include <Library/DebugLib.h>\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/UefiRuntimeServicesTableLib.h>\r
-#include <Library/UefiDriverEntryPoint.h>\r
-#include <Library/HobLib.h>\r
-#include <Library/UefiBootServicesTableLib.h>\r
-#include <Library/BaseLib.h>\r
-#include <Library/MemoryAllocationLib.h>\r
-#include <Library/PrintLib.h>\r
-#include <Library/Tpm2CommandLib.h>\r
-#include <Library/PcdLib.h>\r
-#include <Library/UefiLib.h>\r
-#include <Library/Tpm2DeviceLib.h>\r
-#include <Library/HashLib.h>\r
-#include <Library/PerformanceLib.h>\r
-#include <Library/ReportStatusCodeLib.h>\r
-\r
-#define PERF_ID_TREE_DXE 0x3120\r
-\r
-typedef struct {\r
- CHAR16 *VariableName;\r
- EFI_GUID *VendorGuid;\r
-} VARIABLE_TYPE;\r
-\r
-#define TREE_DEFAULT_MAX_COMMAND_SIZE 0x1000\r
-#define TREE_DEFAULT_MAX_RESPONSE_SIZE 0x1000\r
-\r
-typedef struct {\r
- EFI_GUID *EventGuid;\r
- TREE_EVENT_LOG_FORMAT LogFormat;\r
-} TREE_EVENT_INFO_STRUCT;\r
-\r
-TREE_EVENT_INFO_STRUCT mTreeEventInfo[] = {\r
- {&gTcgEventEntryHobGuid, TREE_EVENT_LOG_FORMAT_TCG_1_2},\r
-};\r
-\r
-#define TCG_EVENT_LOG_AREA_COUNT_MAX 2\r
-\r
-typedef struct {\r
- TREE_EVENT_LOG_FORMAT EventLogFormat;\r
- EFI_PHYSICAL_ADDRESS Lasa;\r
- UINT64 Laml;\r
- UINTN EventLogSize;\r
- UINT8 *LastEvent;\r
- BOOLEAN EventLogStarted;\r
- BOOLEAN EventLogTruncated;\r
-} TCG_EVENT_LOG_AREA_STRUCT;\r
-\r
-typedef struct _TCG_DXE_DATA {\r
- TREE_BOOT_SERVICE_CAPABILITY BsCap;\r
- EFI_TCG_CLIENT_ACPI_TABLE *TcgClientAcpiTable;\r
- EFI_TCG_SERVER_ACPI_TABLE *TcgServerAcpiTable;\r
- TCG_EVENT_LOG_AREA_STRUCT EventLogAreaStruct[TCG_EVENT_LOG_AREA_COUNT_MAX];\r
-} TCG_DXE_DATA;\r
-\r
-EFI_TCG_CLIENT_ACPI_TABLE mTcgClientAcpiTemplate = {\r
- {\r
- EFI_ACPI_3_0_TRUSTED_COMPUTING_PLATFORM_ALLIANCE_CAPABILITIES_TABLE_SIGNATURE,\r
- sizeof (mTcgClientAcpiTemplate),\r
- 0x02 //Revision\r
- //\r
- // Compiler initializes the remaining bytes to 0\r
- // These fields should be filled in in production\r
- //\r
- },\r
- 0, // 0 for PC Client Platform Class\r
- 0, // Log Area Max Length\r
- (EFI_PHYSICAL_ADDRESS) (SIZE_4GB - 1) // Log Area Start Address\r
-};\r
-\r
-//\r
-// The following EFI_TCG_SERVER_ACPI_TABLE default setting is just one example,\r
-// the TPM device connectes to LPC, and also defined the ACPI _UID as 0xFF,\r
-// this _UID can be changed and should match with the _UID setting of the TPM \r
-// ACPI device object \r
-//\r
-EFI_TCG_SERVER_ACPI_TABLE mTcgServerAcpiTemplate = {\r
- {\r
- EFI_ACPI_3_0_TRUSTED_COMPUTING_PLATFORM_ALLIANCE_CAPABILITIES_TABLE_SIGNATURE,\r
- sizeof (mTcgServerAcpiTemplate),\r
- 0x02 //Revision\r
- //\r
- // Compiler initializes the remaining bytes to 0\r
- // These fields should be filled in in production\r
- //\r
- },\r
- 1, // 1 for Server Platform Class\r
- 0, // Reserved\r
- 0, // Log Area Max Length\r
- (EFI_PHYSICAL_ADDRESS) (SIZE_4GB - 1), // Log Area Start Address\r
- 0x0100, // TCG Specification revision 1.0\r
- 2, // Device Flags\r
- 0, // Interrupt Flags\r
- 0, // GPE\r
- {0}, // Reserved 3 bytes\r
- 0, // Global System Interrupt\r
- {\r
- EFI_ACPI_3_0_SYSTEM_MEMORY,\r
- 0,\r
- 0,\r
- EFI_ACPI_3_0_BYTE,\r
- 0x0 // Base Address\r
- },\r
- 0, // Reserved\r
- {0}, // Configuration Address\r
- 0xFF, // ACPI _UID value of the device, can be changed for different platforms\r
- 0, // ACPI _UID value of the device, can be changed for different platforms\r
- 0, // ACPI _UID value of the device, can be changed for different platforms\r
- 0 // ACPI _UID value of the device, can be changed for different platforms\r
-};\r
-\r
-TCG_DXE_DATA mTcgDxeData = {\r
- {\r
- sizeof (TREE_BOOT_SERVICE_CAPABILITY_1_0), // Size\r
- { 1, 0 }, // StructureVersion\r
- { 1, 0 }, // ProtocolVersion\r
- TREE_BOOT_HASH_ALG_SHA1, // HashAlgorithmBitmap\r
- TREE_EVENT_LOG_FORMAT_TCG_1_2, // SupportedEventLogs\r
- TRUE, // TrEEPresentFlag\r
- TREE_DEFAULT_MAX_COMMAND_SIZE, // MaxCommandSize\r
- TREE_DEFAULT_MAX_RESPONSE_SIZE, // MaxResponseSize\r
- 0 // ManufacturerID\r
- },\r
- &mTcgClientAcpiTemplate,\r
- &mTcgServerAcpiTemplate,\r
-};\r
-\r
-UINTN mBootAttempts = 0;\r
-CHAR16 mBootVarName[] = L"BootOrder";\r
-\r
-VARIABLE_TYPE mVariableType[] = {\r
- {EFI_SECURE_BOOT_MODE_NAME, &gEfiGlobalVariableGuid},\r
- {EFI_PLATFORM_KEY_NAME, &gEfiGlobalVariableGuid},\r
- {EFI_KEY_EXCHANGE_KEY_NAME, &gEfiGlobalVariableGuid},\r
- {EFI_IMAGE_SECURITY_DATABASE, &gEfiImageSecurityDatabaseGuid},\r
- {EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid},\r
-};\r
-\r
-EFI_HANDLE mImageHandle;\r
-\r
-/**\r
- Measure PE image into TPM log based on the authenticode image hashing in\r
- PE/COFF Specification 8.0 Appendix A.\r
-\r
- Caution: This function may receive untrusted input.\r
- PE/COFF image is external input, so this function will validate its data structure\r
- within this image buffer before use.\r
-\r
- Notes: PE/COFF image is checked by BasePeCoffLib PeCoffLoaderGetImageInfo().\r
-\r
- @param[in] PCRIndex TPM PCR index\r
- @param[in] ImageAddress Start address of image buffer.\r
- @param[in] ImageSize Image size\r
- @param[out] DigestList Digeest list of this image.\r
-\r
- @retval EFI_SUCCESS Successfully measure image.\r
- @retval EFI_OUT_OF_RESOURCES No enough resource to measure image.\r
- @retval other error value\r
-**/\r
-EFI_STATUS\r
-MeasurePeImageAndExtend (\r
- IN UINT32 PCRIndex,\r
- IN EFI_PHYSICAL_ADDRESS ImageAddress,\r
- IN UINTN ImageSize,\r
- OUT TPML_DIGEST_VALUES *DigestList\r
- );\r
-\r
-/**\r
-\r
- This function dump raw data.\r
-\r
- @param Data raw data\r
- @param Size raw data size\r
-\r
-**/\r
-VOID\r
-InternalDumpData (\r
- IN UINT8 *Data,\r
- IN UINTN Size\r
- )\r
-{\r
- UINTN Index;\r
- for (Index = 0; Index < Size; Index++) {\r
- DEBUG ((EFI_D_INFO, "%02x", (UINTN)Data[Index]));\r
- }\r
-}\r
-\r
-/**\r
-\r
- This function dump raw data with colume format.\r
-\r
- @param Data raw data\r
- @param Size raw data size\r
-\r
-**/\r
-VOID\r
-InternalDumpHex (\r
- IN UINT8 *Data,\r
- IN UINTN Size\r
- )\r
-{\r
- UINTN Index;\r
- UINTN Count;\r
- UINTN Left;\r
-\r
-#define COLUME_SIZE (16 * 2)\r
-\r
- Count = Size / COLUME_SIZE;\r
- Left = Size % COLUME_SIZE;\r
- for (Index = 0; Index < Count; Index++) {\r
- DEBUG ((EFI_D_INFO, "%04x: ", Index * COLUME_SIZE));\r
- InternalDumpData (Data + Index * COLUME_SIZE, COLUME_SIZE);\r
- DEBUG ((EFI_D_INFO, "\n"));\r
- }\r
-\r
- if (Left != 0) {\r
- DEBUG ((EFI_D_INFO, "%04x: ", Index * COLUME_SIZE));\r
- InternalDumpData (Data + Index * COLUME_SIZE, Left);\r
- DEBUG ((EFI_D_INFO, "\n"));\r
- }\r
-}\r
-\r
-/**\r
- Get All processors EFI_CPU_LOCATION in system. LocationBuf is allocated inside the function\r
- Caller is responsible to free LocationBuf.\r
-\r
- @param[out] LocationBuf Returns Processor Location Buffer.\r
- @param[out] Num Returns processor number.\r
-\r
- @retval EFI_SUCCESS Operation completed successfully.\r
- @retval EFI_UNSUPPORTED MpService protocol not found.\r
-\r
-**/\r
-EFI_STATUS\r
-GetProcessorsCpuLocation (\r
- OUT EFI_CPU_PHYSICAL_LOCATION **LocationBuf,\r
- OUT UINTN *Num\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_MP_SERVICES_PROTOCOL *MpProtocol;\r
- UINTN ProcessorNum;\r
- UINTN EnabledProcessorNum;\r
- EFI_PROCESSOR_INFORMATION ProcessorInfo;\r
- EFI_CPU_PHYSICAL_LOCATION *ProcessorLocBuf;\r
- UINTN Index;\r
-\r
- Status = gBS->LocateProtocol (&gEfiMpServiceProtocolGuid, NULL, (VOID **) &MpProtocol);\r
- if (EFI_ERROR (Status)) {\r
- //\r
- // MP protocol is not installed\r
- //\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- Status = MpProtocol->GetNumberOfProcessors(\r
- MpProtocol,\r
- &ProcessorNum,\r
- &EnabledProcessorNum\r
- );\r
- if (EFI_ERROR(Status)){\r
- return Status;\r
- }\r
-\r
- Status = gBS->AllocatePool(\r
- EfiBootServicesData,\r
- sizeof(EFI_CPU_PHYSICAL_LOCATION) * ProcessorNum,\r
- (VOID **) &ProcessorLocBuf\r
- );\r
- if (EFI_ERROR(Status)){\r
- return Status;\r
- }\r
-\r
- //\r
- // Get each processor Location info\r
- //\r
- for (Index = 0; Index < ProcessorNum; Index++) {\r
- Status = MpProtocol->GetProcessorInfo(\r
- MpProtocol,\r
- Index,\r
- &ProcessorInfo\r
- );\r
- if (EFI_ERROR(Status)){\r
- FreePool(ProcessorLocBuf);\r
- return Status;\r
- }\r
-\r
- //\r
- // Get all Processor Location info & measure\r
- //\r
- CopyMem(\r
- &ProcessorLocBuf[Index],\r
- &ProcessorInfo.Location,\r
- sizeof(EFI_CPU_PHYSICAL_LOCATION)\r
- );\r
- }\r
-\r
- *LocationBuf = ProcessorLocBuf;\r
- *Num = ProcessorNum;\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- The EFI_TREE_PROTOCOL GetCapability function call provides protocol\r
- capability information and state information about the TrEE.\r
-\r
- @param[in] This Indicates the calling context\r
- @param[in, out] ProtocolCapability The caller allocates memory for a TREE_BOOT_SERVICE_CAPABILITY\r
- structure and sets the size field to the size of the structure allocated.\r
- The callee fills in the fields with the EFI protocol capability information\r
- and the current TrEE state information up to the number of fields which\r
- fit within the size of the structure passed in.\r
-\r
- @retval EFI_SUCCESS Operation completed successfully.\r
- @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
- The ProtocolCapability variable will not be populated. \r
- @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.\r
- The ProtocolCapability variable will not be populated.\r
- @retval EFI_BUFFER_TOO_SMALL The ProtocolCapability variable is too small to hold the full response.\r
- It will be partially populated (required Size field will be set). \r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-TreeGetCapability (\r
- IN EFI_TREE_PROTOCOL *This,\r
- IN OUT TREE_BOOT_SERVICE_CAPABILITY *ProtocolCapability\r
- )\r
-{\r
- DEBUG ((EFI_D_INFO, "TreeGetCapability ...\n"));\r
-\r
- if ((This == NULL) || (ProtocolCapability == NULL)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (ProtocolCapability->Size < mTcgDxeData.BsCap.Size) {\r
- ProtocolCapability->Size = mTcgDxeData.BsCap.Size;\r
- return EFI_BUFFER_TOO_SMALL;\r
- }\r
-\r
- CopyMem (ProtocolCapability, &mTcgDxeData.BsCap, mTcgDxeData.BsCap.Size);\r
- DEBUG ((EFI_D_INFO, "TreeGetCapability - %r\n", EFI_SUCCESS));\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- This function dump event log.\r
-\r
- @param[in] EventLogFormat The type of the event log for which the information is requested.\r
- @param[in] EventLogLocation A pointer to the memory address of the event log.\r
- @param[in] EventLogLastEntry If the Event Log contains more than one entry, this is a pointer to the\r
- address of the start of the last entry in the event log in memory.\r
-**/\r
-VOID\r
-DumpEventLog (\r
- IN TREE_EVENT_LOG_FORMAT EventLogFormat,\r
- IN EFI_PHYSICAL_ADDRESS EventLogLocation,\r
- IN EFI_PHYSICAL_ADDRESS EventLogLastEntry\r
- )\r
-{\r
- TCG_PCR_EVENT_HDR *EventHdr;\r
- UINTN Index;\r
-\r
- DEBUG ((EFI_D_INFO, "EventLogFormat: (0x%x)\n", EventLogFormat));\r
- \r
- switch (EventLogFormat) {\r
- case TREE_EVENT_LOG_FORMAT_TCG_1_2:\r
- EventHdr = (TCG_PCR_EVENT_HDR *)(UINTN)EventLogLocation;\r
- while ((UINTN)EventHdr <= EventLogLastEntry) {\r
- DEBUG ((EFI_D_INFO, " Event:\n"));\r
- DEBUG ((EFI_D_INFO, " PCRIndex - %d\n", EventHdr->PCRIndex));\r
- DEBUG ((EFI_D_INFO, " EventType - 0x%08x\n", EventHdr->EventType));\r
- DEBUG ((EFI_D_INFO, " Digest - "));\r
- for (Index = 0; Index < sizeof(TCG_DIGEST); Index++) {\r
- DEBUG ((EFI_D_INFO, "%02x ", EventHdr->Digest.digest[Index]));\r
- }\r
- DEBUG ((EFI_D_INFO, "\n"));\r
- DEBUG ((EFI_D_INFO, " EventSize - 0x%08x\n", EventHdr->EventSize));\r
- InternalDumpHex ((UINT8 *)(EventHdr + 1), EventHdr->EventSize);\r
- EventHdr = (TCG_PCR_EVENT_HDR *)((UINTN)EventHdr + sizeof(TCG_PCR_EVENT_HDR) + EventHdr->EventSize);\r
- }\r
- break;\r
- }\r
-\r
- return ;\r
-}\r
-\r
-/**\r
- The EFI_TREE_PROTOCOL Get Event Log function call allows a caller to\r
- retrieve the address of a given event log and its last entry. \r
-\r
- @param[in] This Indicates the calling context\r
- @param[in] EventLogFormat The type of the event log for which the information is requested.\r
- @param[out] EventLogLocation A pointer to the memory address of the event log.\r
- @param[out] EventLogLastEntry If the Event Log contains more than one entry, this is a pointer to the\r
- address of the start of the last entry in the event log in memory.\r
- @param[out] EventLogTruncated If the Event Log is missing at least one entry because an event would\r
- have exceeded the area allocated for events, this value is set to TRUE.\r
- Otherwise, the value will be FALSE and the Event Log will be complete.\r
-\r
- @retval EFI_SUCCESS Operation completed successfully.\r
- @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect\r
- (e.g. asking for an event log whose format is not supported).\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-TreeGetEventLog (\r
- IN EFI_TREE_PROTOCOL *This,\r
- IN TREE_EVENT_LOG_FORMAT EventLogFormat,\r
- OUT EFI_PHYSICAL_ADDRESS *EventLogLocation,\r
- OUT EFI_PHYSICAL_ADDRESS *EventLogLastEntry,\r
- OUT BOOLEAN *EventLogTruncated\r
- )\r
-{\r
- UINTN Index;\r
-\r
- DEBUG ((EFI_D_INFO, "TreeGetEventLog ...\n"));\r
-\r
- if (This == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- for (Index = 0; Index < sizeof(mTreeEventInfo)/sizeof(mTreeEventInfo[0]); Index++) {\r
- if (EventLogFormat == mTreeEventInfo[Index].LogFormat) {\r
- break;\r
- }\r
- }\r
-\r
- if (Index == sizeof(mTreeEventInfo)/sizeof(mTreeEventInfo[0])) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (!mTcgDxeData.BsCap.TrEEPresentFlag) {\r
- if (EventLogLocation != NULL) {\r
- *EventLogLocation = 0;\r
- }\r
- if (EventLogLastEntry != NULL) {\r
- *EventLogLastEntry = 0;\r
- }\r
- if (EventLogTruncated != NULL) {\r
- *EventLogTruncated = FALSE;\r
- }\r
- return EFI_SUCCESS;\r
- }\r
-\r
- if (EventLogLocation != NULL) {\r
- *EventLogLocation = mTcgDxeData.EventLogAreaStruct[Index].Lasa;\r
- DEBUG ((EFI_D_INFO, "TreeGetEventLog (EventLogLocation - %x)\n", *EventLogLocation));\r
- }\r
-\r
- if (EventLogLastEntry != NULL) {\r
- if (!mTcgDxeData.EventLogAreaStruct[Index].EventLogStarted) {\r
- *EventLogLastEntry = (EFI_PHYSICAL_ADDRESS)(UINTN)0;\r
- } else {\r
- *EventLogLastEntry = (EFI_PHYSICAL_ADDRESS)(UINTN)mTcgDxeData.EventLogAreaStruct[Index].LastEvent;\r
- }\r
- DEBUG ((EFI_D_INFO, "TreeGetEventLog (EventLogLastEntry - %x)\n", *EventLogLastEntry));\r
- }\r
-\r
- if (EventLogTruncated != NULL) {\r
- *EventLogTruncated = mTcgDxeData.EventLogAreaStruct[Index].EventLogTruncated;\r
- DEBUG ((EFI_D_INFO, "TreeGetEventLog (EventLogTruncated - %x)\n", *EventLogTruncated));\r
- }\r
-\r
- DEBUG ((EFI_D_INFO, "TreeGetEventLog - %r\n", EFI_SUCCESS));\r
-\r
- // Dump Event Log for debug purpose\r
- if ((EventLogLocation != NULL) && (EventLogLastEntry != NULL)) {\r
- DumpEventLog (EventLogFormat, *EventLogLocation, *EventLogLastEntry);\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Add a new entry to the Event Log.\r
-\r
- @param[in, out] EventLogPtr Pointer to the Event Log data. \r
- @param[in, out] LogSize Size of the Event Log. \r
- @param[in] MaxSize Maximum size of the Event Log.\r
- @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR/TCG_PCR_EVENT_EX data structure. \r
- @param[in] NewEventHdrSize New event header size.\r
- @param[in] NewEventData Pointer to the new event data. \r
- @param[in] NewEventSize New event data size.\r
- \r
- @retval EFI_SUCCESS The new event log entry was added.\r
- @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.\r
-\r
-**/\r
-EFI_STATUS\r
-TcgCommLogEvent (\r
- IN OUT UINT8 **EventLogPtr,\r
- IN OUT UINTN *LogSize,\r
- IN UINTN MaxSize,\r
- IN VOID *NewEventHdr,\r
- IN UINT32 NewEventHdrSize,\r
- IN UINT8 *NewEventData,\r
- IN UINT32 NewEventSize\r
- )\r
-{\r
- UINTN NewLogSize;\r
-\r
- if (NewEventSize > MAX_ADDRESS - NewEventHdrSize) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- NewLogSize = NewEventHdrSize + NewEventSize;\r
-\r
- if (NewLogSize > MAX_ADDRESS - *LogSize) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- if (NewLogSize + *LogSize > MaxSize) {\r
- DEBUG ((EFI_D_INFO, " MaxSize - 0x%x\n", MaxSize));\r
- DEBUG ((EFI_D_INFO, " NewLogSize - 0x%x\n", NewLogSize));\r
- DEBUG ((EFI_D_INFO, " LogSize - 0x%x\n", *LogSize));\r
- DEBUG ((EFI_D_INFO, "TcgCommLogEvent - %r\n", EFI_OUT_OF_RESOURCES));\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- *EventLogPtr += *LogSize;\r
- *LogSize += NewLogSize;\r
- CopyMem (*EventLogPtr, NewEventHdr, NewEventHdrSize);\r
- CopyMem (\r
- *EventLogPtr + NewEventHdrSize,\r
- NewEventData,\r
- NewEventSize\r
- );\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Add a new entry to the Event Log.\r
-\r
- @param[in] EventLogFormat The type of the event log for which the information is requested.\r
- @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR/TCG_PCR_EVENT_EX data structure. \r
- @param[in] NewEventHdrSize New event header size.\r
- @param[in] NewEventData Pointer to the new event data. \r
- @param[in] NewEventSize New event data size.\r
-\r
- @retval EFI_SUCCESS The new event log entry was added.\r
- @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.\r
-\r
-**/\r
-EFI_STATUS\r
-TcgDxeLogEvent (\r
- IN TREE_EVENT_LOG_FORMAT EventLogFormat,\r
- IN VOID *NewEventHdr,\r
- IN UINT32 NewEventHdrSize,\r
- IN UINT8 *NewEventData,\r
- IN UINT32 NewEventSize\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINTN Index;\r
-\r
- for (Index = 0; Index < sizeof(mTreeEventInfo)/sizeof(mTreeEventInfo[0]); Index++) {\r
- if (EventLogFormat == mTreeEventInfo[Index].LogFormat) {\r
- break;\r
- }\r
- }\r
-\r
- if (Index == sizeof(mTreeEventInfo)/sizeof(mTreeEventInfo[0])) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (mTcgDxeData.EventLogAreaStruct[Index].EventLogTruncated) {\r
- return EFI_VOLUME_FULL;\r
- }\r
-\r
- mTcgDxeData.EventLogAreaStruct[Index].LastEvent = (UINT8*)(UINTN)mTcgDxeData.EventLogAreaStruct[Index].Lasa;\r
- Status = TcgCommLogEvent (\r
- &mTcgDxeData.EventLogAreaStruct[Index].LastEvent,\r
- &mTcgDxeData.EventLogAreaStruct[Index].EventLogSize,\r
- (UINTN)mTcgDxeData.EventLogAreaStruct[Index].Laml,\r
- NewEventHdr,\r
- NewEventHdrSize,\r
- NewEventData,\r
- NewEventSize\r
- );\r
- \r
- if (Status == EFI_DEVICE_ERROR) {\r
- return EFI_DEVICE_ERROR;\r
- } else if (Status == EFI_OUT_OF_RESOURCES) {\r
- mTcgDxeData.EventLogAreaStruct[Index].EventLogTruncated = TRUE;\r
- return EFI_VOLUME_FULL;\r
- } else if (Status == EFI_SUCCESS) {\r
- mTcgDxeData.EventLogAreaStruct[Index].EventLogStarted = TRUE;\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Add a new entry to the Event Log.\r
-\r
- @param[in] DigestList A list of digest.\r
- @param[in,out] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.\r
- @param[in] NewEventData Pointer to the new event data.\r
-\r
- @retval EFI_SUCCESS The new event log entry was added.\r
- @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.\r
-**/\r
-EFI_STATUS\r
-TcgDxeLogHashEvent (\r
- IN TPML_DIGEST_VALUES *DigestList,\r
- IN OUT TCG_PCR_EVENT_HDR *NewEventHdr,\r
- IN UINT8 *NewEventData\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_TPL OldTpl;\r
- UINTN Index;\r
- EFI_STATUS RetStatus;\r
-\r
- RetStatus = EFI_SUCCESS;\r
- for (Index = 0; Index < sizeof(mTreeEventInfo)/sizeof(mTreeEventInfo[0]); Index++) {\r
- DEBUG ((EFI_D_INFO, " LogFormat - 0x%08x\n", mTreeEventInfo[Index].LogFormat));\r
- switch (mTreeEventInfo[Index].LogFormat) {\r
- case TREE_EVENT_LOG_FORMAT_TCG_1_2:\r
- Status = GetDigestFromDigestList (TPM_ALG_SHA1, DigestList, &NewEventHdr->Digest);\r
- if (!EFI_ERROR (Status)) {\r
- //\r
- // Enter critical region\r
- //\r
- OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);\r
- Status = TcgDxeLogEvent (\r
- mTreeEventInfo[Index].LogFormat,\r
- NewEventHdr,\r
- sizeof(TCG_PCR_EVENT_HDR),\r
- NewEventData,\r
- NewEventHdr->EventSize\r
- );\r
- if (Status != EFI_SUCCESS) {\r
- RetStatus = Status;\r
- }\r
- gBS->RestoreTPL (OldTpl);\r
- //\r
- // Exit critical region\r
- //\r
- }\r
- break;\r
- }\r
- }\r
-\r
- return RetStatus;\r
-}\r
-\r
-/**\r
- Do a hash operation on a data buffer, extend a specific TPM PCR with the hash result,\r
- and add an entry to the Event Log.\r
-\r
- @param[in] Flags Bitmap providing additional information.\r
- @param[in] HashData Physical address of the start of the data buffer \r
- to be hashed, extended, and logged.\r
- @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData\r
- @param[in, out] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure. \r
- @param[in] NewEventData Pointer to the new event data. \r
-\r
- @retval EFI_SUCCESS Operation completed successfully.\r
- @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.\r
- @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
-\r
-**/\r
-EFI_STATUS\r
-TcgDxeHashLogExtendEvent (\r
- IN UINT64 Flags,\r
- IN UINT8 *HashData,\r
- IN UINT64 HashDataLen,\r
- IN OUT TCG_PCR_EVENT_HDR *NewEventHdr,\r
- IN UINT8 *NewEventData\r
- )\r
-{\r
- EFI_STATUS Status;\r
- TPML_DIGEST_VALUES DigestList;\r
- \r
- if (!mTcgDxeData.BsCap.TrEEPresentFlag) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- Status = HashAndExtend (\r
- NewEventHdr->PCRIndex,\r
- HashData,\r
- (UINTN)HashDataLen,\r
- &DigestList\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- if ((Flags & TREE_EXTEND_ONLY) == 0) {\r
- Status = TcgDxeLogHashEvent (&DigestList, NewEventHdr, NewEventData);\r
- }\r
- }\r
-\r
- if (Status == EFI_DEVICE_ERROR) {\r
- DEBUG ((EFI_D_ERROR, "TcgDxeHashLogExtendEvent - %r. Disable TPM.\n", Status));\r
- mTcgDxeData.BsCap.TrEEPresentFlag = FALSE;\r
- REPORT_STATUS_CODE (\r
- EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
- (PcdGet32 (PcdStatusCodeSubClassTpmDevice) | EFI_P_EC_INTERFACE_ERROR)\r
- );\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- The EFI_TREE_PROTOCOL HashLogExtendEvent function call provides callers with\r
- an opportunity to extend and optionally log events without requiring\r
- knowledge of actual TPM commands. \r
- The extend operation will occur even if this function cannot create an event\r
- log entry (e.g. due to the event log being full). \r
-\r
- @param[in] This Indicates the calling context\r
- @param[in] Flags Bitmap providing additional information.\r
- @param[in] DataToHash Physical address of the start of the data buffer to be hashed. \r
- @param[in] DataToHashLen The length in bytes of the buffer referenced by DataToHash.\r
- @param[in] Event Pointer to data buffer containing information about the event.\r
-\r
- @retval EFI_SUCCESS Operation completed successfully.\r
- @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
- @retval EFI_VOLUME_FULL The extend operation occurred, but the event could not be written to one or more event logs.\r
- @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.\r
- @retval EFI_UNSUPPORTED The PE/COFF image type is not supported.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-TreeHashLogExtendEvent (\r
- IN EFI_TREE_PROTOCOL *This,\r
- IN UINT64 Flags,\r
- IN EFI_PHYSICAL_ADDRESS DataToHash,\r
- IN UINT64 DataToHashLen,\r
- IN TrEE_EVENT *Event\r
- )\r
-{\r
- EFI_STATUS Status;\r
- TCG_PCR_EVENT_HDR NewEventHdr;\r
- TPML_DIGEST_VALUES DigestList;\r
-\r
- DEBUG ((EFI_D_INFO, "TreeHashLogExtendEvent ...\n"));\r
-\r
- if ((This == NULL) || (DataToHash == 0) || (Event == NULL)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (!mTcgDxeData.BsCap.TrEEPresentFlag) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- if (Event->Size < Event->Header.HeaderSize + sizeof(UINT32)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (Event->Header.PCRIndex > MAX_PCR_INDEX) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- NewEventHdr.PCRIndex = Event->Header.PCRIndex;\r
- NewEventHdr.EventType = Event->Header.EventType;\r
- NewEventHdr.EventSize = Event->Size - sizeof(UINT32) - Event->Header.HeaderSize;\r
- if ((Flags & PE_COFF_IMAGE) != 0) {\r
- Status = MeasurePeImageAndExtend (\r
- NewEventHdr.PCRIndex,\r
- DataToHash,\r
- (UINTN)DataToHashLen,\r
- &DigestList\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- if ((Flags & TREE_EXTEND_ONLY) == 0) {\r
- Status = TcgDxeLogHashEvent (&DigestList, &NewEventHdr, Event->Event);\r
- }\r
- }\r
- if (Status == EFI_DEVICE_ERROR) {\r
- DEBUG ((EFI_D_ERROR, "MeasurePeImageAndExtend - %r. Disable TPM.\n", Status));\r
- mTcgDxeData.BsCap.TrEEPresentFlag = FALSE;\r
- REPORT_STATUS_CODE (\r
- EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
- (PcdGet32 (PcdStatusCodeSubClassTpmDevice) | EFI_P_EC_INTERFACE_ERROR)\r
- );\r
- }\r
- } else {\r
- Status = TcgDxeHashLogExtendEvent (\r
- Flags,\r
- (UINT8 *) (UINTN) DataToHash,\r
- DataToHashLen,\r
- &NewEventHdr,\r
- Event->Event\r
- );\r
- }\r
- DEBUG ((EFI_D_INFO, "TreeHashLogExtendEvent - %r\n", Status));\r
- return Status;\r
-}\r
-\r
-/**\r
- This service enables the sending of commands to the TrEE.\r
-\r
- @param[in] This Indicates the calling context\r
- @param[in] InputParameterBlockSize Size of the TrEE input parameter block.\r
- @param[in] InputParameterBlock Pointer to the TrEE input parameter block.\r
- @param[in] OutputParameterBlockSize Size of the TrEE output parameter block.\r
- @param[in] OutputParameterBlock Pointer to the TrEE output parameter block.\r
-\r
- @retval EFI_SUCCESS The command byte stream was successfully sent to the device and a response was successfully received.\r
- @retval EFI_DEVICE_ERROR The command was not successfully sent to the device or a response was not successfully received from the device.\r
- @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.\r
- @retval EFI_BUFFER_TOO_SMALL The output parameter block is too small. \r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-TreeSubmitCommand (\r
- IN EFI_TREE_PROTOCOL *This,\r
- IN UINT32 InputParameterBlockSize,\r
- IN UINT8 *InputParameterBlock,\r
- IN UINT32 OutputParameterBlockSize,\r
- IN UINT8 *OutputParameterBlock\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- DEBUG ((EFI_D_INFO, "TreeSubmitCommand ...\n"));\r
-\r
- if ((This == NULL) ||\r
- (InputParameterBlockSize == 0) || (InputParameterBlock == NULL) ||\r
- (OutputParameterBlockSize == 0) || (OutputParameterBlock == NULL)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (!mTcgDxeData.BsCap.TrEEPresentFlag) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- if (InputParameterBlockSize > mTcgDxeData.BsCap.MaxCommandSize) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- if (OutputParameterBlockSize > mTcgDxeData.BsCap.MaxResponseSize) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- Status = Tpm2SubmitCommand (\r
- InputParameterBlockSize,\r
- InputParameterBlock,\r
- &OutputParameterBlockSize,\r
- OutputParameterBlock\r
- );\r
- DEBUG ((EFI_D_INFO, "TreeSubmitCommand - %r\n", Status));\r
- return Status;\r
-}\r
-\r
-\r
-EFI_TREE_PROTOCOL mTreeProtocol = {\r
- TreeGetCapability,\r
- TreeGetEventLog,\r
- TreeHashLogExtendEvent,\r
- TreeSubmitCommand\r
-};\r
-\r
-/**\r
- Initialize the Event Log and log events passed from the PEI phase.\r
-\r
- @retval EFI_SUCCESS Operation completed successfully.\r
- @retval EFI_OUT_OF_RESOURCES Out of memory.\r
-\r
-**/\r
-EFI_STATUS\r
-SetupEventLog (\r
- VOID\r
- )\r
-{\r
- EFI_STATUS Status;\r
- VOID *TcgEvent;\r
- EFI_PEI_HOB_POINTERS GuidHob;\r
- EFI_PHYSICAL_ADDRESS Lasa;\r
- UINTN Index;\r
-\r
- DEBUG ((EFI_D_INFO, "SetupEventLog\n"));\r
-\r
- //\r
- // 1. Create Log Area\r
- //\r
- for (Index = 0; Index < sizeof(mTreeEventInfo)/sizeof(mTreeEventInfo[0]); Index++) {\r
- mTcgDxeData.EventLogAreaStruct[Index].EventLogFormat = mTreeEventInfo[Index].LogFormat;\r
- Lasa = (EFI_PHYSICAL_ADDRESS) (SIZE_4GB - 1);\r
- Status = gBS->AllocatePages (\r
- AllocateMaxAddress,\r
- EfiACPIMemoryNVS,\r
- EFI_SIZE_TO_PAGES (PcdGet32 (PcdTcgLogAreaMinLen)),\r
- &Lasa\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- mTcgDxeData.EventLogAreaStruct[Index].Lasa = Lasa;\r
- mTcgDxeData.EventLogAreaStruct[Index].Laml = PcdGet32 (PcdTcgLogAreaMinLen);\r
- //\r
- // To initialize them as 0xFF is recommended \r
- // because the OS can know the last entry for that.\r
- //\r
- SetMem ((VOID *)(UINTN)Lasa, PcdGet32 (PcdTcgLogAreaMinLen), 0xFF);\r
- }\r
-\r
- //\r
- // 2. Create ACPI table for TCG1.2 only\r
- //\r
- if (PcdGet8 (PcdTpmPlatformClass) == TCG_PLATFORM_TYPE_CLIENT) {\r
- mTcgClientAcpiTemplate.Lasa = mTcgDxeData.EventLogAreaStruct[0].Lasa;\r
- mTcgClientAcpiTemplate.Laml = PcdGet32 (PcdTcgLogAreaMinLen);\r
- } else {\r
- mTcgServerAcpiTemplate.Lasa = mTcgDxeData.EventLogAreaStruct[0].Lasa;\r
- mTcgServerAcpiTemplate.Laml = PcdGet32 (PcdTcgLogAreaMinLen);\r
- }\r
-\r
- //\r
- // 3. Sync data from PEI to DXE\r
- //\r
- Status = EFI_SUCCESS;\r
- for (Index = 0; Index < sizeof(mTreeEventInfo)/sizeof(mTreeEventInfo[0]); Index++) {\r
- GuidHob.Raw = GetHobList ();\r
- Status = EFI_SUCCESS;\r
- while (!EFI_ERROR (Status) && \r
- (GuidHob.Raw = GetNextGuidHob (mTreeEventInfo[Index].EventGuid, GuidHob.Raw)) != NULL) {\r
- TcgEvent = GET_GUID_HOB_DATA (GuidHob.Guid);\r
- GuidHob.Raw = GET_NEXT_HOB (GuidHob);\r
- switch (mTreeEventInfo[Index].LogFormat) {\r
- case TREE_EVENT_LOG_FORMAT_TCG_1_2:\r
- Status = TcgDxeLogEvent (\r
- mTreeEventInfo[Index].LogFormat,\r
- TcgEvent,\r
- sizeof(TCG_PCR_EVENT_HDR),\r
- ((TCG_PCR_EVENT*)TcgEvent)->Event,\r
- ((TCG_PCR_EVENT_HDR*)TcgEvent)->EventSize\r
- );\r
- break;\r
- }\r
- }\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Measure and log an action string, and extend the measurement result into PCR[5].\r
-\r
- @param[in] String A specific string that indicates an Action event. \r
- \r
- @retval EFI_SUCCESS Operation completed successfully.\r
- @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
-\r
-**/\r
-EFI_STATUS\r
-TcgMeasureAction (\r
- IN CHAR8 *String\r
- )\r
-{\r
- TCG_PCR_EVENT_HDR TcgEvent;\r
-\r
- TcgEvent.PCRIndex = 5;\r
- TcgEvent.EventType = EV_EFI_ACTION;\r
- TcgEvent.EventSize = (UINT32)AsciiStrLen (String);\r
- return TcgDxeHashLogExtendEvent (\r
- 0,\r
- (UINT8*)String,\r
- TcgEvent.EventSize,\r
- &TcgEvent,\r
- (UINT8 *) String\r
- );\r
-}\r
-\r
-/**\r
- Measure and log EFI handoff tables, and extend the measurement result into PCR[1].\r
-\r
- @retval EFI_SUCCESS Operation completed successfully.\r
- @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
-\r
-**/\r
-EFI_STATUS\r
-MeasureHandoffTables (\r
- VOID\r
- )\r
-{\r
- EFI_STATUS Status;\r
- TCG_PCR_EVENT_HDR TcgEvent;\r
- EFI_HANDOFF_TABLE_POINTERS HandoffTables;\r
- UINTN ProcessorNum;\r
- EFI_CPU_PHYSICAL_LOCATION *ProcessorLocBuf;\r
-\r
- ProcessorLocBuf = NULL;\r
- Status = EFI_SUCCESS;\r
-\r
- if (PcdGet8 (PcdTpmPlatformClass) == TCG_PLATFORM_TYPE_SERVER) {\r
- //\r
- // Tcg Server spec. \r
- // Measure each processor EFI_CPU_PHYSICAL_LOCATION with EV_TABLE_OF_DEVICES to PCR[1]\r
- //\r
- Status = GetProcessorsCpuLocation(&ProcessorLocBuf, &ProcessorNum);\r
-\r
- if (!EFI_ERROR(Status)){\r
- TcgEvent.PCRIndex = 1;\r
- TcgEvent.EventType = EV_TABLE_OF_DEVICES;\r
- TcgEvent.EventSize = sizeof (HandoffTables);\r
-\r
- HandoffTables.NumberOfTables = 1;\r
- HandoffTables.TableEntry[0].VendorGuid = gEfiMpServiceProtocolGuid;\r
- HandoffTables.TableEntry[0].VendorTable = ProcessorLocBuf;\r
-\r
- Status = TcgDxeHashLogExtendEvent (\r
- 0,\r
- (UINT8*)(UINTN)ProcessorLocBuf,\r
- sizeof(EFI_CPU_PHYSICAL_LOCATION) * ProcessorNum,\r
- &TcgEvent,\r
- (UINT8*)&HandoffTables\r
- );\r
-\r
- FreePool(ProcessorLocBuf);\r
- }\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Measure and log Separator event, and extend the measurement result into a specific PCR.\r
-\r
- @param[in] PCRIndex PCR index. \r
-\r
- @retval EFI_SUCCESS Operation completed successfully.\r
- @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
-\r
-**/\r
-EFI_STATUS\r
-MeasureSeparatorEvent (\r
- IN TPM_PCRINDEX PCRIndex\r
- )\r
-{\r
- TCG_PCR_EVENT_HDR TcgEvent;\r
- UINT32 EventData;\r
-\r
- DEBUG ((EFI_D_INFO, "MeasureSeparatorEvent Pcr - %x\n", PCRIndex));\r
-\r
- EventData = 0;\r
- TcgEvent.PCRIndex = PCRIndex;\r
- TcgEvent.EventType = EV_SEPARATOR;\r
- TcgEvent.EventSize = (UINT32)sizeof (EventData);\r
- return TcgDxeHashLogExtendEvent (\r
- 0,\r
- (UINT8 *)&EventData,\r
- sizeof (EventData),\r
- &TcgEvent,\r
- (UINT8 *)&EventData\r
- );\r
-}\r
-\r
-/**\r
- Measure and log an EFI variable, and extend the measurement result into a specific PCR.\r
-\r
- @param[in] PCRIndex PCR Index. \r
- @param[in] EventType Event type. \r
- @param[in] VarName A Null-terminated string that is the name of the vendor's variable.\r
- @param[in] VendorGuid A unique identifier for the vendor.\r
- @param[in] VarData The content of the variable data. \r
- @param[in] VarSize The size of the variable data. \r
- \r
- @retval EFI_SUCCESS Operation completed successfully.\r
- @retval EFI_OUT_OF_RESOURCES Out of memory.\r
- @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
-\r
-**/\r
-EFI_STATUS\r
-MeasureVariable (\r
- IN TPM_PCRINDEX PCRIndex,\r
- IN TCG_EVENTTYPE EventType,\r
- IN CHAR16 *VarName,\r
- IN EFI_GUID *VendorGuid,\r
- IN VOID *VarData,\r
- IN UINTN VarSize\r
- )\r
-{\r
- EFI_STATUS Status;\r
- TCG_PCR_EVENT_HDR TcgEvent;\r
- UINTN VarNameLength;\r
- EFI_VARIABLE_DATA_TREE *VarLog;\r
-\r
- DEBUG ((EFI_D_INFO, "TrEEDxe: MeasureVariable (Pcr - %x, EventType - %x, ", (UINTN)PCRIndex, (UINTN)EventType));\r
- DEBUG ((EFI_D_INFO, "VariableName - %s, VendorGuid - %g)\n", VarName, VendorGuid));\r
-\r
- VarNameLength = StrLen (VarName);\r
- TcgEvent.PCRIndex = PCRIndex;\r
- TcgEvent.EventType = EventType;\r
- TcgEvent.EventSize = (UINT32)(sizeof (*VarLog) + VarNameLength * sizeof (*VarName) + VarSize\r
- - sizeof (VarLog->UnicodeName) - sizeof (VarLog->VariableData));\r
-\r
- VarLog = (EFI_VARIABLE_DATA_TREE*)AllocatePool (TcgEvent.EventSize);\r
- if (VarLog == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- VarLog->VariableName = *VendorGuid;\r
- VarLog->UnicodeNameLength = VarNameLength;\r
- VarLog->VariableDataLength = VarSize;\r
- CopyMem (\r
- VarLog->UnicodeName,\r
- VarName,\r
- VarNameLength * sizeof (*VarName)\r
- );\r
- if (VarSize != 0 && VarData != NULL) {\r
- CopyMem (\r
- (CHAR16 *)VarLog->UnicodeName + VarNameLength,\r
- VarData,\r
- VarSize\r
- );\r
- }\r
-\r
- Status = TcgDxeHashLogExtendEvent (\r
- 0,\r
- (UINT8*)VarLog,\r
- TcgEvent.EventSize,\r
- &TcgEvent,\r
- (UINT8*)VarLog\r
- );\r
-\r
- FreePool (VarLog);\r
- return Status;\r
-}\r
-\r
-/**\r
- Read then Measure and log an EFI variable, and extend the measurement result into a specific PCR.\r
-\r
- @param[in] PCRIndex PCR Index. \r
- @param[in] EventType Event type. \r
- @param[in] VarName A Null-terminated string that is the name of the vendor's variable.\r
- @param[in] VendorGuid A unique identifier for the vendor.\r
- @param[out] VarSize The size of the variable data. \r
- @param[out] VarData Pointer to the content of the variable. \r
- \r
- @retval EFI_SUCCESS Operation completed successfully.\r
- @retval EFI_OUT_OF_RESOURCES Out of memory.\r
- @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
-\r
-**/\r
-EFI_STATUS\r
-ReadAndMeasureVariable (\r
- IN TPM_PCRINDEX PCRIndex,\r
- IN TCG_EVENTTYPE EventType,\r
- IN CHAR16 *VarName,\r
- IN EFI_GUID *VendorGuid,\r
- OUT UINTN *VarSize,\r
- OUT VOID **VarData\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- Status = GetVariable2 (VarName, VendorGuid, VarData, VarSize);\r
- if (EventType == EV_EFI_VARIABLE_DRIVER_CONFIG) {\r
- if (EFI_ERROR (Status)) {\r
- //\r
- // It is valid case, so we need handle it.\r
- //\r
- *VarData = NULL;\r
- *VarSize = 0;\r
- }\r
- } else {\r
- //\r
- // if status error, VarData is freed and set NULL by GetVariable2\r
- //\r
- if (EFI_ERROR (Status)) {\r
- return EFI_NOT_FOUND;\r
- }\r
- }\r
-\r
- Status = MeasureVariable (\r
- PCRIndex,\r
- EventType,\r
- VarName,\r
- VendorGuid,\r
- *VarData,\r
- *VarSize\r
- );\r
- return Status;\r
-}\r
-\r
-/**\r
- Read then Measure and log an EFI boot variable, and extend the measurement result into PCR[5].\r
-\r
- @param[in] VarName A Null-terminated string that is the name of the vendor's variable.\r
- @param[in] VendorGuid A unique identifier for the vendor.\r
- @param[out] VarSize The size of the variable data. \r
- @param[out] VarData Pointer to the content of the variable. \r
- \r
- @retval EFI_SUCCESS Operation completed successfully.\r
- @retval EFI_OUT_OF_RESOURCES Out of memory.\r
- @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
-\r
-**/\r
-EFI_STATUS\r
-ReadAndMeasureBootVariable (\r
- IN CHAR16 *VarName,\r
- IN EFI_GUID *VendorGuid,\r
- OUT UINTN *VarSize,\r
- OUT VOID **VarData\r
- )\r
-{\r
- return ReadAndMeasureVariable (\r
- 5,\r
- EV_EFI_VARIABLE_BOOT,\r
- VarName,\r
- VendorGuid,\r
- VarSize,\r
- VarData\r
- );\r
-}\r
-\r
-/**\r
- Read then Measure and log an EFI Secure variable, and extend the measurement result into PCR[7].\r
-\r
- @param[in] VarName A Null-terminated string that is the name of the vendor's variable.\r
- @param[in] VendorGuid A unique identifier for the vendor.\r
- @param[out] VarSize The size of the variable data. \r
- @param[out] VarData Pointer to the content of the variable. \r
- \r
- @retval EFI_SUCCESS Operation completed successfully.\r
- @retval EFI_OUT_OF_RESOURCES Out of memory.\r
- @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
-\r
-**/\r
-EFI_STATUS\r
-ReadAndMeasureSecureVariable (\r
- IN CHAR16 *VarName,\r
- IN EFI_GUID *VendorGuid,\r
- OUT UINTN *VarSize,\r
- OUT VOID **VarData\r
- )\r
-{\r
- return ReadAndMeasureVariable (\r
- 7,\r
- EV_EFI_VARIABLE_DRIVER_CONFIG,\r
- VarName,\r
- VendorGuid,\r
- VarSize,\r
- VarData\r
- );\r
-}\r
-\r
-/**\r
- Measure and log all EFI boot variables, and extend the measurement result into a specific PCR.\r
-\r
- The EFI boot variables are BootOrder and Boot#### variables.\r
-\r
- @retval EFI_SUCCESS Operation completed successfully.\r
- @retval EFI_OUT_OF_RESOURCES Out of memory.\r
- @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
-\r
-**/\r
-EFI_STATUS\r
-MeasureAllBootVariables (\r
- VOID\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT16 *BootOrder;\r
- UINTN BootCount;\r
- UINTN Index;\r
- VOID *BootVarData;\r
- UINTN Size;\r
-\r
- Status = ReadAndMeasureBootVariable (\r
- mBootVarName,\r
- &gEfiGlobalVariableGuid,\r
- &BootCount,\r
- (VOID **) &BootOrder\r
- );\r
- if (Status == EFI_NOT_FOUND || BootOrder == NULL) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- if (EFI_ERROR (Status)) {\r
- //\r
- // BootOrder can't be NULL if status is not EFI_NOT_FOUND\r
- //\r
- FreePool (BootOrder);\r
- return Status;\r
- }\r
-\r
- BootCount /= sizeof (*BootOrder);\r
- for (Index = 0; Index < BootCount; Index++) {\r
- UnicodeSPrint (mBootVarName, sizeof (mBootVarName), L"Boot%04x", BootOrder[Index]);\r
- Status = ReadAndMeasureBootVariable (\r
- mBootVarName,\r
- &gEfiGlobalVariableGuid,\r
- &Size,\r
- &BootVarData\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- FreePool (BootVarData);\r
- }\r
- }\r
-\r
- FreePool (BootOrder);\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Measure and log all EFI Secure variables, and extend the measurement result into a specific PCR.\r
-\r
- The EFI boot variables are BootOrder and Boot#### variables.\r
-\r
- @retval EFI_SUCCESS Operation completed successfully.\r
- @retval EFI_OUT_OF_RESOURCES Out of memory.\r
- @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
-\r
-**/\r
-EFI_STATUS\r
-MeasureAllSecureVariables (\r
- VOID\r
- )\r
-{\r
- EFI_STATUS Status;\r
- VOID *Data;\r
- UINTN DataSize;\r
- UINTN Index;\r
-\r
- Status = EFI_NOT_FOUND;\r
- for (Index = 0; Index < sizeof(mVariableType)/sizeof(mVariableType[0]); Index++) {\r
- Status = ReadAndMeasureSecureVariable (\r
- mVariableType[Index].VariableName,\r
- mVariableType[Index].VendorGuid,\r
- &DataSize,\r
- &Data\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- if (Data != NULL) {\r
- FreePool (Data);\r
- }\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Measure and log launch of FirmwareDebugger, and extend the measurement result into a specific PCR.\r
-\r
- @retval EFI_SUCCESS Operation completed successfully.\r
- @retval EFI_OUT_OF_RESOURCES Out of memory.\r
- @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
-\r
-**/\r
-EFI_STATUS\r
-MeasureLaunchOfFirmwareDebugger (\r
- VOID\r
- )\r
-{\r
- TCG_PCR_EVENT_HDR TcgEvent;\r
-\r
- TcgEvent.PCRIndex = 7;\r
- TcgEvent.EventType = EV_EFI_ACTION;\r
- TcgEvent.EventSize = sizeof(FIRMWARE_DEBUGGER_EVENT_STRING) - 1;\r
- return TcgDxeHashLogExtendEvent (\r
- 0,\r
- (UINT8 *)FIRMWARE_DEBUGGER_EVENT_STRING,\r
- sizeof(FIRMWARE_DEBUGGER_EVENT_STRING) - 1,\r
- &TcgEvent,\r
- (UINT8 *)FIRMWARE_DEBUGGER_EVENT_STRING\r
- );\r
-}\r
-\r
-/**\r
- Measure and log all Secure Boot Policy, and extend the measurement result into a specific PCR.\r
-\r
- Platform firmware adhering to the policy must therefore measure the following values into PCR[7]: (in order listed)\r
- - The contents of the SecureBoot variable\r
- - The contents of the PK variable\r
- - The contents of the KEK variable\r
- - The contents of the EFI_IMAGE_SECURITY_DATABASE variable\r
- - The contents of the EFI_IMAGE_SECURITY_DATABASE1 variable\r
- - Separator\r
- - Entries in the EFI_IMAGE_SECURITY_DATABASE that are used to validate EFI Drivers or EFI Boot Applications in the boot path\r
-\r
- NOTE: Because of the above, UEFI variables PK, KEK, EFI_IMAGE_SECURITY_DATABASE,\r
- EFI_IMAGE_SECURITY_DATABASE1 and SecureBoot SHALL NOT be measured into PCR[3].\r
-\r
- @param[in] Event Event whose notification function is being invoked\r
- @param[in] Context Pointer to the notification function's context\r
-**/\r
-VOID\r
-EFIAPI\r
-MeasureSecureBootPolicy (\r
- IN EFI_EVENT Event,\r
- IN VOID *Context\r
- )\r
-{\r
- EFI_STATUS Status;\r
- VOID *Protocol;\r
-\r
- Status = gBS->LocateProtocol (&gEfiVariableWriteArchProtocolGuid, NULL, (VOID **)&Protocol);\r
- if (EFI_ERROR (Status)) {\r
- return;\r
- }\r
-\r
- if (PcdGetBool (PcdFirmwareDebuggerInitialized)) {\r
- Status = MeasureLaunchOfFirmwareDebugger ();\r
- DEBUG ((EFI_D_INFO, "MeasureLaunchOfFirmwareDebugger - %r\n", Status));\r
- }\r
-\r
- Status = MeasureAllSecureVariables ();\r
- DEBUG ((EFI_D_INFO, "MeasureAllSecureVariables - %r\n", Status));\r
-\r
- //\r
- // We need measure Separator(7) here, because this event must be between SecureBootPolicy (Configure)\r
- // and ImageVerification (Authority)\r
- // There might be a case that we need measure UEFI image from DriverOrder, besides BootOrder. So\r
- // the Authority measurement happen before ReadToBoot event.\r
- //\r
- Status = MeasureSeparatorEvent (7);\r
- DEBUG ((EFI_D_INFO, "MeasureSeparatorEvent - %r\n", Status));\r
- return ;\r
-}\r
-\r
-/**\r
- Ready to Boot Event notification handler.\r
-\r
- Sequence of OS boot events is measured in this event notification handler.\r
-\r
- @param[in] Event Event whose notification function is being invoked\r
- @param[in] Context Pointer to the notification function's context\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-OnReadyToBoot (\r
- IN EFI_EVENT Event,\r
- IN VOID *Context\r
- )\r
-{\r
- EFI_STATUS Status;\r
- TPM_PCRINDEX PcrIndex;\r
-\r
- PERF_START_EX (mImageHandle, "EventRec", "TrEEDxe", 0, PERF_ID_TREE_DXE);\r
- if (mBootAttempts == 0) {\r
-\r
- //\r
- // Measure handoff tables.\r
- //\r
- Status = MeasureHandoffTables ();\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "HOBs not Measured. Error!\n"));\r
- }\r
-\r
- //\r
- // Measure BootOrder & Boot#### variables.\r
- //\r
- Status = MeasureAllBootVariables ();\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "Boot Variables not Measured. Error!\n"));\r
- }\r
-\r
- //\r
- // 1. This is the first boot attempt.\r
- //\r
- Status = TcgMeasureAction (\r
- EFI_CALLING_EFI_APPLICATION\r
- );\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_CALLING_EFI_APPLICATION));\r
- }\r
-\r
- //\r
- // 2. Draw a line between pre-boot env and entering post-boot env.\r
- // PCR[7] is already done.\r
- //\r
- for (PcrIndex = 0; PcrIndex < 7; PcrIndex++) {\r
- Status = MeasureSeparatorEvent (PcrIndex);\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "Seperator Event not Measured. Error!\n"));\r
- }\r
- }\r
-\r
- //\r
- // 3. Measure GPT. It would be done in SAP driver.\r
- //\r
-\r
- //\r
- // 4. Measure PE/COFF OS loader. It would be done in SAP driver.\r
- //\r
-\r
- //\r
- // 5. Read & Measure variable. BootOrder already measured.\r
- //\r
- } else {\r
- //\r
- // 6. Not first attempt, meaning a return from last attempt\r
- //\r
- Status = TcgMeasureAction (\r
- EFI_RETURNING_FROM_EFI_APPLICATOIN\r
- );\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_RETURNING_FROM_EFI_APPLICATOIN));\r
- }\r
- }\r
-\r
- DEBUG ((EFI_D_INFO, "TPM2 TrEEDxe Measure Data when ReadyToBoot\n"));\r
- //\r
- // Increase boot attempt counter.\r
- //\r
- mBootAttempts++;\r
- PERF_END_EX (mImageHandle, "EventRec", "TrEEDxe", 0, PERF_ID_TREE_DXE + 1);\r
-}\r
-\r
-/**\r
- Install TCG ACPI Table when ACPI Table Protocol is available.\r
-\r
- A system's firmware uses an ACPI table to identify the system's TCG capabilities \r
- to the Post-Boot environment. The information in this ACPI table is not guaranteed \r
- to be valid until the Host Platform transitions from pre-boot state to post-boot state. \r
-\r
- @param[in] Event Event whose notification function is being invoked\r
- @param[in] Context Pointer to the notification function's context\r
-**/\r
-VOID\r
-EFIAPI\r
-InstallAcpiTable (\r
- IN EFI_EVENT Event,\r
- IN VOID *Context\r
- )\r
-{\r
- UINTN TableKey;\r
- EFI_STATUS Status;\r
- EFI_ACPI_TABLE_PROTOCOL *AcpiTable;\r
- UINT8 Checksum;\r
- UINT64 OemTableId;\r
-\r
- Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **)&AcpiTable);\r
- if (EFI_ERROR (Status)) {\r
- return;\r
- }\r
-\r
- if (PcdGet8 (PcdTpmPlatformClass) == TCG_PLATFORM_TYPE_CLIENT) {\r
- CopyMem (mTcgClientAcpiTemplate.Header.OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (mTcgClientAcpiTemplate.Header.OemId));\r
- OemTableId = PcdGet64 (PcdAcpiDefaultOemTableId);\r
- CopyMem (&mTcgClientAcpiTemplate.Header.OemTableId, &OemTableId, sizeof (UINT64));\r
- mTcgClientAcpiTemplate.Header.OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision);\r
- mTcgClientAcpiTemplate.Header.CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId);\r
- mTcgClientAcpiTemplate.Header.CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision);\r
- //\r
- // The ACPI table must be checksumed before calling the InstallAcpiTable() \r
- // service of the ACPI table protocol to install it.\r
- //\r
- Checksum = CalculateCheckSum8 ((UINT8 *)&mTcgClientAcpiTemplate, sizeof (mTcgClientAcpiTemplate));\r
- mTcgClientAcpiTemplate.Header.Checksum = Checksum;\r
-\r
- Status = AcpiTable->InstallAcpiTable (\r
- AcpiTable,\r
- &mTcgClientAcpiTemplate,\r
- sizeof (mTcgClientAcpiTemplate),\r
- &TableKey\r
- );\r
- } else {\r
- CopyMem (mTcgServerAcpiTemplate.Header.OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (mTcgServerAcpiTemplate.Header.OemId));\r
- OemTableId = PcdGet64 (PcdAcpiDefaultOemTableId);\r
- CopyMem (&mTcgServerAcpiTemplate.Header.OemTableId, &OemTableId, sizeof (UINT64));\r
- mTcgServerAcpiTemplate.Header.OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision);\r
- mTcgServerAcpiTemplate.Header.CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId);\r
- mTcgServerAcpiTemplate.Header.CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision);\r
- //\r
- // The ACPI table must be checksumed before calling the InstallAcpiTable() \r
- // service of the ACPI table protocol to install it.\r
- //\r
- Checksum = CalculateCheckSum8 ((UINT8 *)&mTcgServerAcpiTemplate, sizeof (mTcgServerAcpiTemplate));\r
- mTcgServerAcpiTemplate.Header.Checksum = Checksum;\r
-\r
- mTcgServerAcpiTemplate.BaseAddress.Address = PcdGet64 (PcdTpmBaseAddress);\r
- Status = AcpiTable->InstallAcpiTable (\r
- AcpiTable,\r
- &mTcgServerAcpiTemplate,\r
- sizeof (mTcgServerAcpiTemplate),\r
- &TableKey\r
- );\r
- }\r
-\r
- if (EFI_ERROR (Status)) {\r
- DEBUG((EFI_D_ERROR, "Tcg Acpi Table installation failure"));\r
- }\r
-}\r
-\r
-/**\r
- Exit Boot Services Event notification handler.\r
-\r
- Measure invocation and success of ExitBootServices.\r
-\r
- @param[in] Event Event whose notification function is being invoked\r
- @param[in] Context Pointer to the notification function's context\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-OnExitBootServices (\r
- IN EFI_EVENT Event,\r
- IN VOID *Context\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Measure invocation of ExitBootServices,\r
- //\r
- Status = TcgMeasureAction (\r
- EFI_EXIT_BOOT_SERVICES_INVOCATION\r
- );\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_INVOCATION));\r
- }\r
-\r
- //\r
- // Measure success of ExitBootServices\r
- //\r
- Status = TcgMeasureAction (\r
- EFI_EXIT_BOOT_SERVICES_SUCCEEDED\r
- );\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_SUCCEEDED));\r
- }\r
-}\r
-\r
-/**\r
- Exit Boot Services Failed Event notification handler.\r
-\r
- Measure Failure of ExitBootServices.\r
-\r
- @param[in] Event Event whose notification function is being invoked\r
- @param[in] Context Pointer to the notification function's context\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-OnExitBootServicesFailed (\r
- IN EFI_EVENT Event,\r
- IN VOID *Context\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Measure Failure of ExitBootServices,\r
- //\r
- Status = TcgMeasureAction (\r
- EFI_EXIT_BOOT_SERVICES_FAILED\r
- );\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "%a not Measured. Error!\n", EFI_EXIT_BOOT_SERVICES_FAILED));\r
- }\r
-\r
-}\r
-\r
-/**\r
- The function install TrEE protocol.\r
- \r
- @retval EFI_SUCCESS TrEE protocol is installed.\r
- @retval other Some error occurs.\r
-**/\r
-EFI_STATUS\r
-InstallTrEE (\r
- VOID\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_HANDLE Handle;\r
-\r
- Handle = NULL;\r
- Status = gBS->InstallMultipleProtocolInterfaces (\r
- &Handle,\r
- &gEfiTrEEProtocolGuid,\r
- &mTreeProtocol,\r
- NULL\r
- );\r
- return Status;\r
-}\r
-\r
-/**\r
- The driver's entry point. It publishes EFI TrEE Protocol.\r
-\r
- @param[in] ImageHandle The firmware allocated handle for the EFI image. \r
- @param[in] SystemTable A pointer to the EFI System Table.\r
- \r
- @retval EFI_SUCCESS The entry point is executed successfully.\r
- @retval other Some error occurs when executing this entry point.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-DriverEntry (\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE *SystemTable\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_EVENT Event;\r
- VOID *Registration;\r
- UINT32 MaxCommandSize;\r
- UINT32 MaxResponseSize;\r
- TPML_PCR_SELECTION Pcrs;\r
- UINTN Index;\r
- UINT32 TpmHashAlgorithmBitmap;\r
-\r
- mImageHandle = ImageHandle;\r
-\r
- if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceNoneGuid) ||\r
- CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)){\r
- DEBUG ((DEBUG_INFO, "No TPM2 instance required!\n"));\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- if (GetFirstGuidHob (&gTpmErrorHobGuid) != NULL) {\r
- DEBUG ((EFI_D_ERROR, "TPM2 error!\n"));\r
- return EFI_DEVICE_ERROR;\r
- }\r
- \r
- Status = Tpm2RequestUseTpm ();\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "TPM2 not detected!\n"));\r
- return Status;\r
- }\r
- \r
- //\r
- // Fill information\r
- //\r
- DEBUG ((EFI_D_INFO, "TrEE.ProtocolVersion - %02x.%02x\n", mTcgDxeData.BsCap.ProtocolVersion.Major, mTcgDxeData.BsCap.ProtocolVersion.Minor));\r
- DEBUG ((EFI_D_INFO, "TrEE.StructureVersion - %02x.%02x\n", mTcgDxeData.BsCap.StructureVersion.Major, mTcgDxeData.BsCap.StructureVersion.Minor));\r
-\r
- Status = Tpm2GetCapabilityManufactureID (&mTcgDxeData.BsCap.ManufacturerID);\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "Tpm2GetCapabilityManufactureID fail!\n"));\r
- } else {\r
- DEBUG ((EFI_D_INFO, "Tpm2GetCapabilityManufactureID - %08x\n", mTcgDxeData.BsCap.ManufacturerID));\r
- }\r
-\r
- DEBUG_CODE (\r
- UINT32 FirmwareVersion1;\r
- UINT32 FirmwareVersion2;\r
-\r
- Status = Tpm2GetCapabilityFirmwareVersion (&FirmwareVersion1, &FirmwareVersion2);\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "Tpm2GetCapabilityFirmwareVersion fail!\n"));\r
- } else {\r
- DEBUG ((EFI_D_INFO, "Tpm2GetCapabilityFirmwareVersion - %08x %08x\n", FirmwareVersion1, FirmwareVersion2));\r
- }\r
- );\r
-\r
- Status = Tpm2GetCapabilityMaxCommandResponseSize (&MaxCommandSize, &MaxResponseSize);\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "Tpm2GetCapabilityMaxCommandResponseSize fail!\n"));\r
- } else {\r
- mTcgDxeData.BsCap.MaxCommandSize = (UINT16)MaxCommandSize;\r
- mTcgDxeData.BsCap.MaxResponseSize = (UINT16)MaxResponseSize;\r
- DEBUG ((EFI_D_INFO, "Tpm2GetCapabilityMaxCommandResponseSize - %08x, %08x\n", MaxCommandSize, MaxResponseSize));\r
- }\r
-\r
- Status = Tpm2GetCapabilityPcrs (&Pcrs);\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "Tpm2GetCapabilityPcrs fail!\n"));\r
- TpmHashAlgorithmBitmap = TREE_BOOT_HASH_ALG_SHA1;\r
- } else {\r
- DEBUG ((EFI_D_INFO, "Tpm2GetCapabilityPcrs Count - %08x\n", Pcrs.count));\r
- TpmHashAlgorithmBitmap = 0;\r
- for (Index = 0; Index < Pcrs.count; Index++) {\r
- DEBUG ((EFI_D_INFO, "hash - %x\n", Pcrs.pcrSelections[Index].hash));\r
- switch (Pcrs.pcrSelections[Index].hash) {\r
- case TPM_ALG_SHA1:\r
- TpmHashAlgorithmBitmap |= TREE_BOOT_HASH_ALG_SHA1;\r
- break;\r
- case TPM_ALG_SHA256:\r
- TpmHashAlgorithmBitmap |= TREE_BOOT_HASH_ALG_SHA256;\r
- break;\r
- case TPM_ALG_SHA384:\r
- TpmHashAlgorithmBitmap |= TREE_BOOT_HASH_ALG_SHA384;\r
- break;\r
- case TPM_ALG_SHA512:\r
- TpmHashAlgorithmBitmap |= TREE_BOOT_HASH_ALG_SHA512;\r
- break;\r
- case TPM_ALG_SM3_256:\r
- // TBD: Spec not define TREE_BOOT_HASH_ALG_SM3_256 yet\r
- break;\r
- }\r
- }\r
- }\r
- DEBUG ((EFI_D_INFO, "TPM.HashAlgorithmBitmap - 0x%08x\n", TpmHashAlgorithmBitmap));\r
-\r
- DEBUG ((EFI_D_INFO, "TrEE.SupportedEventLogs - 0x%08x\n", mTcgDxeData.BsCap.SupportedEventLogs));\r
- mTcgDxeData.BsCap.HashAlgorithmBitmap = TpmHashAlgorithmBitmap;\r
- DEBUG ((EFI_D_INFO, "TrEE.HashAlgorithmBitmap - 0x%08x\n", mTcgDxeData.BsCap.HashAlgorithmBitmap));\r
-\r
- if (mTcgDxeData.BsCap.TrEEPresentFlag) {\r
- //\r
- // Setup the log area and copy event log from hob list to it\r
- //\r
- Status = SetupEventLog ();\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // Measure handoff tables, Boot#### variables etc.\r
- //\r
- Status = EfiCreateEventReadyToBootEx (\r
- TPL_CALLBACK,\r
- OnReadyToBoot,\r
- NULL,\r
- &Event\r
- );\r
-\r
- Status = gBS->CreateEventEx (\r
- EVT_NOTIFY_SIGNAL,\r
- TPL_NOTIFY,\r
- OnExitBootServices,\r
- NULL,\r
- &gEfiEventExitBootServicesGuid,\r
- &Event\r
- );\r
-\r
- //\r
- // Measure Exit Boot Service failed \r
- //\r
- Status = gBS->CreateEventEx (\r
- EVT_NOTIFY_SIGNAL,\r
- TPL_NOTIFY,\r
- OnExitBootServicesFailed,\r
- NULL,\r
- &gEventExitBootServicesFailedGuid,\r
- &Event\r
- );\r
-\r
- //\r
- // Create event callback, because we need access variable on SecureBootPolicyVariable\r
- // We should use VariableWriteArch instead of VariableArch, because Variable driver\r
- // may update SecureBoot value based on last setting.\r
- //\r
- EfiCreateProtocolNotifyEvent (&gEfiVariableWriteArchProtocolGuid, TPL_CALLBACK, MeasureSecureBootPolicy, NULL, &Registration);\r
- }\r
-\r
- //\r
- // Install ACPI Table\r
- //\r
- EfiCreateProtocolNotifyEvent (&gEfiAcpiTableProtocolGuid, TPL_CALLBACK, InstallAcpiTable, NULL, &Registration);\r
-\r
- //\r
- // Install TrEEProtocol\r
- //\r
- Status = InstallTrEE ();\r
- DEBUG ((EFI_D_INFO, "InstallTrEE - %r\n", Status));\r
-\r
- return Status;\r
-}\r