--- /dev/null
+/** @file\r
+ Defines the HOB GUID used to pass all PEI trusted FV info to \r
+ DXE Driver.\r
+ \r
+Copyright (c) 2012, 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
+#ifndef _TRUSTED_FV_HOB_H_\r
+#define _TRUSTED_FV_HOB_H_\r
+\r
+///\r
+/// The Global ID of a GUIDed HOB used to pass all PEI trusted FV info to DXE Driver.\r
+///\r
+#define EFI_TRUSTED_FV_HOB_GUID \\r
+ { \\r
+ 0xb2360b42, 0x7173, 0x420a, { 0x86, 0x96, 0x46, 0xca, 0x6b, 0xab, 0x10, 0x60 } \\r
+ }\r
+\r
+extern EFI_GUID gTrustedFvHobGuid;\r
+\r
+#endif\r
#include <PiDxe.h>\r
\r
#include <Protocol/TcgService.h>\r
-#include <Protocol/FirmwareVolume2.h>\r
#include <Protocol/BlockIo.h>\r
#include <Protocol/DiskIo.h>\r
#include <Protocol/DevicePathToText.h>\r
+#include <Protocol/FirmwareVolumeBlock.h>\r
+\r
+#include <Guid/TrustedFvHob.h>\r
\r
#include <Library/BaseLib.h>\r
#include <Library/DebugLib.h>\r
#include <Library/BaseCryptLib.h>\r
#include <Library/PeCoffLib.h>\r
#include <Library/SecurityManagementLib.h>\r
+#include <Library/HobLib.h>\r
\r
//\r
// Flag to check GPT partition. It only need be measured once.\r
UINTN mMeasureGptCount = 0;\r
VOID *mFileBuffer;\r
UINTN mImageSize;\r
+//\r
+// Measured FV handle cache\r
+//\r
+EFI_HANDLE mCacheMeasuredHandle = NULL;\r
+UINT32 *mGuidHobData = NULL;\r
\r
/**\r
Reads contents of a PE/COFF image in memory buffer.\r
IN BOOLEAN BootPolicy\r
)\r
{\r
- EFI_TCG_PROTOCOL *TcgProtocol;\r
- EFI_STATUS Status;\r
- TCG_EFI_BOOT_SERVICE_CAPABILITY ProtocolCapability;\r
- UINT32 TCGFeatureFlags;\r
- EFI_PHYSICAL_ADDRESS EventLogLocation;\r
- EFI_PHYSICAL_ADDRESS EventLogLastEntry;\r
- EFI_DEVICE_PATH_PROTOCOL *DevicePathNode;\r
- EFI_DEVICE_PATH_PROTOCOL *OrigDevicePathNode;\r
- EFI_HANDLE Handle;\r
- BOOLEAN ApplicationRequired;\r
- PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;\r
+ EFI_TCG_PROTOCOL *TcgProtocol;\r
+ EFI_STATUS Status;\r
+ TCG_EFI_BOOT_SERVICE_CAPABILITY ProtocolCapability;\r
+ UINT32 TCGFeatureFlags;\r
+ EFI_PHYSICAL_ADDRESS EventLogLocation;\r
+ EFI_PHYSICAL_ADDRESS EventLogLastEntry;\r
+ EFI_DEVICE_PATH_PROTOCOL *DevicePathNode;\r
+ EFI_DEVICE_PATH_PROTOCOL *OrigDevicePathNode;\r
+ EFI_HANDLE Handle;\r
+ EFI_HANDLE TempHandle;\r
+ BOOLEAN ApplicationRequired;\r
+ PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;\r
+ EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvbProtocol;\r
+ EFI_PHYSICAL_ADDRESS FvAddress;\r
+ EFI_PLATFORM_FIRMWARE_BLOB *TrustedFvBuf;\r
+ UINT32 Index;\r
\r
Status = gBS->LocateProtocol (&gEfiTcgProtocolGuid, NULL, (VOID **) &TcgProtocol);\r
if (EFI_ERROR (Status)) {\r
ApplicationRequired = FALSE;\r
\r
//\r
- // Check whether this device path support FV2 protocol.\r
+ // Check whether this device path support FVB protocol.\r
//\r
DevicePathNode = OrigDevicePathNode;\r
- Status = gBS->LocateDevicePath (&gEfiFirmwareVolume2ProtocolGuid, &DevicePathNode, &Handle);\r
+ Status = gBS->LocateDevicePath (&gEfiFirmwareVolumeBlockProtocolGuid, &DevicePathNode, &Handle);\r
if (!EFI_ERROR (Status)) {\r
//\r
// Don't check FV image, and directly return EFI_SUCCESS.\r
return EFI_SUCCESS;\r
}\r
//\r
- // The image from Firmware image will not be mearsured.\r
- // Current policy doesn't measure PeImage from Firmware if it is driver\r
- // If the got PeImage is application, it will be still be measured.\r
+ // The PE image from untrusted Firmware volume need be measured\r
+ // The PE image from trusted Firmware volume will be mearsured according to policy below.\r
+ // if it is driver, do not measure\r
+ // If it is application, still measure.\r
//\r
ApplicationRequired = TRUE;\r
+\r
+ if (mCacheMeasuredHandle != Handle && mGuidHobData != NULL) {\r
+ //\r
+ // Search for Root FV of this PE image\r
+ //\r
+ TempHandle = Handle;\r
+ do {\r
+ Status = gBS->HandleProtocol(\r
+ TempHandle, \r
+ &gEfiFirmwareVolumeBlockProtocolGuid,\r
+ &FvbProtocol\r
+ );\r
+ TempHandle = FvbProtocol->ParentHandle;\r
+ } while (!EFI_ERROR(Status) && FvbProtocol->ParentHandle != NULL);\r
+\r
+ //\r
+ // Search in measured FV Hob\r
+ //\r
+ Status = FvbProtocol->GetPhysicalAddress(FvbProtocol, &FvAddress);\r
+ if (EFI_ERROR(Status)){\r
+ return Status;\r
+ }\r
+\r
+ TrustedFvBuf = (EFI_PLATFORM_FIRMWARE_BLOB *)(mGuidHobData + 1);\r
+ ApplicationRequired = FALSE;\r
+\r
+ for (Index = 0; Index < *mGuidHobData; Index++) {\r
+ if(TrustedFvBuf[Index].BlobBase == FvAddress) {\r
+ //\r
+ // Cache measured FV for next measurement\r
+ //\r
+ mCacheMeasuredHandle = Handle;\r
+ ApplicationRequired = TRUE;\r
+ break;\r
+ }\r
+ }\r
+ }\r
}\r
- \r
+\r
//\r
// File is not found.\r
//\r
IN EFI_SYSTEM_TABLE *SystemTable\r
)\r
{\r
+ EFI_HOB_GUID_TYPE *GuidHob;\r
+\r
+ GuidHob = NULL;\r
+\r
+ GuidHob = GetFirstGuidHob (&gTrustedFvHobGuid);\r
+\r
+ if (GuidHob != NULL) {\r
+ mGuidHobData = GET_GUID_HOB_DATA (GuidHob);\r
+ }\r
+\r
return RegisterSecurity2Handler (\r
DxeTpmMeasureBootHandler,\r
EFI_AUTH_OPERATION_MEASURE_IMAGE | EFI_AUTH_OPERATION_IMAGE_REQUIRED\r
PeCoffLib\r
BaseLib\r
SecurityManagementLib\r
+ HobLib\r
+\r
+[Guids]\r
+ gTrustedFvHobGuid\r
\r
[Protocols]\r
gEfiTcgProtocolGuid ## CONSUMES\r
- gEfiFirmwareVolume2ProtocolGuid ## CONSUMES\r
+ gEfiFirmwareVolumeBlockProtocolGuid ## CONSUMES\r
gEfiBlockIoProtocolGuid ## CONSUMES\r
gEfiDiskIoProtocolGuid ## CONSUMES\r
gEfiDevicePathToTextProtocolGuid ## SOMETIMES_CONSUMES (Only used in debug mode)\r
## Include/Guid/TcgEventHob.h\r
gTcgEventEntryHobGuid = { 0x2e3044ac, 0x879f, 0x490f, {0x97, 0x60, 0xbb, 0xdf, 0xaf, 0x69, 0x5f, 0x50 }}\r
\r
+ ## Include/Guid/TrustedFvHob.h\r
+ gTrustedFvHobGuid = { 0xb2360b42, 0x7173, 0x420a, { 0x86, 0x96, 0x46, 0xca, 0x6b, 0xab, 0x10, 0x60 }}\r
+\r
## Include/Guid/PhysicalPresenceData.h\r
gEfiPhysicalPresenceGuid = { 0xf6499b1, 0xe9ad, 0x493d, { 0xb9, 0xc2, 0x2f, 0x90, 0x81, 0x5c, 0x6c, 0xbc }}\r
\r
#include <Ppi/LockPhysicalPresence.h>\r
#include <Ppi/TpmInitialized.h>\r
#include <Ppi/FirmwareVolume.h>\r
+#include <Ppi/EndOfPeiPhase.h>\r
+\r
#include <Guid/TcgEventHob.h>\r
+#include <Guid/TrustedFvHob.h>\r
+\r
#include <Library/DebugLib.h>\r
#include <Library/BaseMemoryLib.h>\r
#include <Library/PeiServicesLib.h>\r
NULL\r
};\r
\r
+EFI_PLATFORM_FIRMWARE_BLOB mMeasuredBaseFvInfo[FixedPcdGet32 (PcdPeiCoreMaxFvSupported)];\r
+UINT32 mMeasuredBaseFvIndex = 0;\r
+\r
+EFI_PLATFORM_FIRMWARE_BLOB mMeasuredChildFvInfo[FixedPcdGet32 (PcdPeiCoreMaxFvSupported)];\r
+UINT32 mMeasuredChildFvIndex = 0;\r
+\r
/**\r
Lock physical presence if needed.\r
\r
IN VOID *Ppi\r
);\r
\r
+/**\r
+ Record all measured Firmware Volum Information into a Guid Hob\r
+\r
+ @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.\r
+ @param[in] NotifyDescriptor Address of the notification descriptor data structure.\r
+ @param[in] Ppi Address of the PPI that was installed.\r
+\r
+ @retval EFI_SUCCESS The FV Info is measured and recorded to TPM.\r
+ @return Others Fail to measure FV.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EndofPeiSignalNotifyCallBack (\r
+ IN EFI_PEI_SERVICES **PeiServices,\r
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,\r
+ IN VOID *Ppi\r
+ );\r
+\r
EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList[] = {\r
{\r
EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,\r
PhysicalPresencePpiNotifyCallback\r
},\r
{\r
- (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
+ EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,\r
&gEfiPeiFirmwareVolumeInfoPpiGuid,\r
FirmwareVolmeInfoPpiNotifyCallback \r
+ },\r
+ {\r
+ (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
+ &gEfiEndOfPeiSignalPpiGuid,\r
+ EndofPeiSignalNotifyCallBack\r
}\r
};\r
\r
-EFI_PLATFORM_FIRMWARE_BLOB mMeasuredFvInfo[FixedPcdGet32 (PcdPeiCoreMaxFvSupported)];\r
-UINT32 mMeasuredFvIndex = 0;\r
+/**\r
+ Record all measured Firmware Volum Information into a Guid Hob\r
+ Guid Hob payload layout is \r
+\r
+ UINT32 *************************** FIRMWARE_BLOB number\r
+ EFI_PLATFORM_FIRMWARE_BLOB******** BLOB Array\r
+\r
+ @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.\r
+ @param[in] NotifyDescriptor Address of the notification descriptor data structure.\r
+ @param[in] Ppi Address of the PPI that was installed.\r
+\r
+ @retval EFI_SUCCESS The FV Info is measured and recorded to TPM.\r
+ @return Others Fail to measure FV.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EndofPeiSignalNotifyCallBack (\r
+ IN EFI_PEI_SERVICES **PeiServices,\r
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,\r
+ IN VOID *Ppi\r
+ )\r
+{ \r
+ UINT8 *HobData;\r
+\r
+ HobData = NULL;\r
+\r
+ //\r
+ // Create a Guid hob to save all trusted Fv \r
+ //\r
+ HobData = BuildGuidHob(\r
+ &gTrustedFvHobGuid,\r
+ sizeof(UINTN) + sizeof(EFI_PLATFORM_FIRMWARE_BLOB) * (mMeasuredBaseFvIndex + mMeasuredChildFvIndex)\r
+ );\r
+\r
+ if (HobData != NULL){\r
+ //\r
+ // Save measured FV info enty number\r
+ //\r
+ *(UINT32 *)HobData = mMeasuredBaseFvIndex + mMeasuredChildFvIndex;\r
+\r
+ HobData += sizeof(UINT32);\r
+ //\r
+ // Save measured base Fv info\r
+ //\r
+ CopyMem (HobData, mMeasuredBaseFvInfo, sizeof(EFI_PLATFORM_FIRMWARE_BLOB) * (mMeasuredBaseFvIndex));\r
+\r
+ HobData += sizeof(EFI_PLATFORM_FIRMWARE_BLOB) * (mMeasuredBaseFvIndex);\r
+ //\r
+ // Save measured child Fv info\r
+ //\r
+ CopyMem (HobData, mMeasuredChildFvInfo, sizeof(EFI_PLATFORM_FIRMWARE_BLOB) * (mMeasuredChildFvIndex));\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
\r
/**\r
Do a hash operation on a data buffer, extend a specific TPM PCR with the hash result,\r
//\r
// Check whether FV is in the measured FV list.\r
//\r
- for (Index = 0; Index < mMeasuredFvIndex; Index ++) {\r
- if (mMeasuredFvInfo[Index].BlobBase == FvBase) {\r
+ for (Index = 0; Index < mMeasuredBaseFvIndex; Index ++) {\r
+ if (mMeasuredBaseFvInfo[Index].BlobBase == FvBase) {\r
return EFI_SUCCESS;\r
}\r
}\r
//\r
// Add new FV into the measured FV list.\r
//\r
- ASSERT (mMeasuredFvIndex < FixedPcdGet32 (PcdPeiCoreMaxFvSupported));\r
- if (mMeasuredFvIndex < FixedPcdGet32 (PcdPeiCoreMaxFvSupported)) {\r
- mMeasuredFvInfo[mMeasuredFvIndex].BlobBase = FvBase;\r
- mMeasuredFvInfo[mMeasuredFvIndex++].BlobLength = FvLength;\r
+ ASSERT (mMeasuredBaseFvIndex < FixedPcdGet32 (PcdPeiCoreMaxFvSupported));\r
+ if (mMeasuredBaseFvIndex < FixedPcdGet32 (PcdPeiCoreMaxFvSupported)) {\r
+ mMeasuredBaseFvInfo[mMeasuredBaseFvIndex].BlobBase = FvBase;\r
+ mMeasuredBaseFvInfo[mMeasuredBaseFvIndex].BlobLength = FvLength;\r
+ mMeasuredBaseFvIndex++;\r
}\r
\r
return Status;\r
\r
//\r
// This is an FV from an FFS file, and the parent FV must have already been measured,\r
- // No need to measure twice, so just returns\r
+ // No need to measure twice, so just record the FV and return\r
//\r
if (Fv->ParentFvName != NULL || Fv->ParentFileName != NULL ) {\r
+ \r
+ ASSERT (mMeasuredChildFvIndex < FixedPcdGet32 (PcdPeiCoreMaxFvSupported));\r
+ if (mMeasuredChildFvIndex < FixedPcdGet32 (PcdPeiCoreMaxFvSupported)) {\r
+ mMeasuredChildFvInfo[mMeasuredChildFvIndex].BlobBase = (EFI_PHYSICAL_ADDRESS) (UINTN) Fv->FvInfo;\r
+ mMeasuredChildFvInfo[mMeasuredChildFvIndex].BlobLength = Fv->FvInfoSize;\r
+ mMeasuredChildFvIndex++;\r
+ }\r
return EFI_SUCCESS;\r
}\r
\r
\r
[Guids]\r
gTcgEventEntryHobGuid\r
+ gTrustedFvHobGuid\r
\r
[Ppis]\r
gPeiLockPhysicalPresencePpiGuid\r
gEfiPeiFirmwareVolumeInfoPpiGuid\r
gPeiTpmInitializedPpiGuid\r
+ gEfiEndOfPeiSignalPpiGuid\r
\r
[Pcd]\r
gEfiSecurityPkgTokenSpaceGuid.PcdHideTpm\r