Enable TPM measurement lib to measure all PE image from a FV unmeasured by TcgPei

Signed-off-by: Chao Zhang <chao.b.zhang@intel.com>
Reviewed-by  : Dong, Guo  <guo.dong@intel.com>

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13714 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
czhang46 2012-09-11 02:26:50 +00:00
parent 884ed92356
commit 2aadc9205b
6 changed files with 224 additions and 29 deletions

View File

@ -0,0 +1,29 @@
/** @file
Defines the HOB GUID used to pass all PEI trusted FV info to
DXE Driver.
Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _TRUSTED_FV_HOB_H_
#define _TRUSTED_FV_HOB_H_
///
/// The Global ID of a GUIDed HOB used to pass all PEI trusted FV info to DXE Driver.
///
#define EFI_TRUSTED_FV_HOB_GUID \
{ \
0xb2360b42, 0x7173, 0x420a, { 0x86, 0x96, 0x46, 0xca, 0x6b, 0xab, 0x10, 0x60 } \
}
extern EFI_GUID gTrustedFvHobGuid;
#endif

View File

@ -29,10 +29,12 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <PiDxe.h>
#include <Protocol/TcgService.h>
#include <Protocol/FirmwareVolume2.h>
#include <Protocol/BlockIo.h>
#include <Protocol/DiskIo.h>
#include <Protocol/DevicePathToText.h>
#include <Protocol/FirmwareVolumeBlock.h>
#include <Guid/TrustedFvHob.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
@ -43,6 +45,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Library/BaseCryptLib.h>
#include <Library/PeCoffLib.h>
#include <Library/SecurityManagementLib.h>
#include <Library/HobLib.h>
//
// Flag to check GPT partition. It only need be measured once.
@ -52,6 +55,11 @@ EFI_GUID mZeroGuid = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}
UINTN mMeasureGptCount = 0;
VOID *mFileBuffer;
UINTN mImageSize;
//
// Measured FV handle cache
//
EFI_HANDLE mCacheMeasuredHandle = NULL;
UINT32 *mGuidHobData = NULL;
/**
Reads contents of a PE/COFF image in memory buffer.
@ -718,17 +726,22 @@ DxeTpmMeasureBootHandler (
IN BOOLEAN BootPolicy
)
{
EFI_TCG_PROTOCOL *TcgProtocol;
EFI_STATUS Status;
TCG_EFI_BOOT_SERVICE_CAPABILITY ProtocolCapability;
UINT32 TCGFeatureFlags;
EFI_PHYSICAL_ADDRESS EventLogLocation;
EFI_PHYSICAL_ADDRESS EventLogLastEntry;
EFI_DEVICE_PATH_PROTOCOL *DevicePathNode;
EFI_DEVICE_PATH_PROTOCOL *OrigDevicePathNode;
EFI_HANDLE Handle;
BOOLEAN ApplicationRequired;
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
EFI_TCG_PROTOCOL *TcgProtocol;
EFI_STATUS Status;
TCG_EFI_BOOT_SERVICE_CAPABILITY ProtocolCapability;
UINT32 TCGFeatureFlags;
EFI_PHYSICAL_ADDRESS EventLogLocation;
EFI_PHYSICAL_ADDRESS EventLogLastEntry;
EFI_DEVICE_PATH_PROTOCOL *DevicePathNode;
EFI_DEVICE_PATH_PROTOCOL *OrigDevicePathNode;
EFI_HANDLE Handle;
EFI_HANDLE TempHandle;
BOOLEAN ApplicationRequired;
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvbProtocol;
EFI_PHYSICAL_ADDRESS FvAddress;
EFI_PLATFORM_FIRMWARE_BLOB *TrustedFvBuf;
UINT32 Index;
Status = gBS->LocateProtocol (&gEfiTcgProtocolGuid, NULL, (VOID **) &TcgProtocol);
if (EFI_ERROR (Status)) {
@ -822,10 +835,10 @@ DxeTpmMeasureBootHandler (
ApplicationRequired = FALSE;
//
// Check whether this device path support FV2 protocol.
// Check whether this device path support FVB protocol.
//
DevicePathNode = OrigDevicePathNode;
Status = gBS->LocateDevicePath (&gEfiFirmwareVolume2ProtocolGuid, &DevicePathNode, &Handle);
Status = gBS->LocateDevicePath (&gEfiFirmwareVolumeBlockProtocolGuid, &DevicePathNode, &Handle);
if (!EFI_ERROR (Status)) {
//
// Don't check FV image, and directly return EFI_SUCCESS.
@ -835,13 +848,51 @@ DxeTpmMeasureBootHandler (
return EFI_SUCCESS;
}
//
// The image from Firmware image will not be mearsured.
// Current policy doesn't measure PeImage from Firmware if it is driver
// If the got PeImage is application, it will be still be measured.
// The PE image from untrusted Firmware volume need be measured
// The PE image from trusted Firmware volume will be mearsured according to policy below.
// if it is driver, do not measure
// If it is application, still measure.
//
ApplicationRequired = TRUE;
if (mCacheMeasuredHandle != Handle && mGuidHobData != NULL) {
//
// Search for Root FV of this PE image
//
TempHandle = Handle;
do {
Status = gBS->HandleProtocol(
TempHandle,
&gEfiFirmwareVolumeBlockProtocolGuid,
&FvbProtocol
);
TempHandle = FvbProtocol->ParentHandle;
} while (!EFI_ERROR(Status) && FvbProtocol->ParentHandle != NULL);
//
// Search in measured FV Hob
//
Status = FvbProtocol->GetPhysicalAddress(FvbProtocol, &FvAddress);
if (EFI_ERROR(Status)){
return Status;
}
TrustedFvBuf = (EFI_PLATFORM_FIRMWARE_BLOB *)(mGuidHobData + 1);
ApplicationRequired = FALSE;
for (Index = 0; Index < *mGuidHobData; Index++) {
if(TrustedFvBuf[Index].BlobBase == FvAddress) {
//
// Cache measured FV for next measurement
//
mCacheMeasuredHandle = Handle;
ApplicationRequired = TRUE;
break;
}
}
}
}
//
// File is not found.
//
@ -941,6 +992,16 @@ DxeTpmMeasureBootLibConstructor (
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_HOB_GUID_TYPE *GuidHob;
GuidHob = NULL;
GuidHob = GetFirstGuidHob (&gTrustedFvHobGuid);
if (GuidHob != NULL) {
mGuidHobData = GET_GUID_HOB_DATA (GuidHob);
}
return RegisterSecurity2Handler (
DxeTpmMeasureBootHandler,
EFI_AUTH_OPERATION_MEASURE_IMAGE | EFI_AUTH_OPERATION_IMAGE_REQUIRED

View File

@ -50,10 +50,14 @@
PeCoffLib
BaseLib
SecurityManagementLib
HobLib
[Guids]
gTrustedFvHobGuid
[Protocols]
gEfiTcgProtocolGuid ## CONSUMES
gEfiFirmwareVolume2ProtocolGuid ## CONSUMES
gEfiFirmwareVolumeBlockProtocolGuid ## CONSUMES
gEfiBlockIoProtocolGuid ## CONSUMES
gEfiDiskIoProtocolGuid ## CONSUMES
gEfiDevicePathToTextProtocolGuid ## SOMETIMES_CONSUMES (Only used in debug mode)

View File

@ -47,6 +47,9 @@
## Include/Guid/TcgEventHob.h
gTcgEventEntryHobGuid = { 0x2e3044ac, 0x879f, 0x490f, {0x97, 0x60, 0xbb, 0xdf, 0xaf, 0x69, 0x5f, 0x50 }}
## Include/Guid/TrustedFvHob.h
gTrustedFvHobGuid = { 0xb2360b42, 0x7173, 0x420a, { 0x86, 0x96, 0x46, 0xca, 0x6b, 0xab, 0x10, 0x60 }}
## Include/Guid/PhysicalPresenceData.h
gEfiPhysicalPresenceGuid = { 0xf6499b1, 0xe9ad, 0x493d, { 0xb9, 0xc2, 0x2f, 0x90, 0x81, 0x5c, 0x6c, 0xbc }}

View File

@ -20,7 +20,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Ppi/LockPhysicalPresence.h>
#include <Ppi/TpmInitialized.h>
#include <Ppi/FirmwareVolume.h>
#include <Ppi/EndOfPeiPhase.h>
#include <Guid/TcgEventHob.h>
#include <Guid/TrustedFvHob.h>
#include <Library/DebugLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/PeiServicesLib.h>
@ -41,6 +45,12 @@ EFI_PEI_PPI_DESCRIPTOR mTpmInitializedPpiList = {
NULL
};
EFI_PLATFORM_FIRMWARE_BLOB mMeasuredBaseFvInfo[FixedPcdGet32 (PcdPeiCoreMaxFvSupported)];
UINT32 mMeasuredBaseFvIndex = 0;
EFI_PLATFORM_FIRMWARE_BLOB mMeasuredChildFvInfo[FixedPcdGet32 (PcdPeiCoreMaxFvSupported)];
UINT32 mMeasuredChildFvIndex = 0;
/**
Lock physical presence if needed.
@ -78,6 +88,25 @@ FirmwareVolmeInfoPpiNotifyCallback (
IN VOID *Ppi
);
/**
Record all measured Firmware Volum Information into a Guid Hob
@param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
@param[in] NotifyDescriptor Address of the notification descriptor data structure.
@param[in] Ppi Address of the PPI that was installed.
@retval EFI_SUCCESS The FV Info is measured and recorded to TPM.
@return Others Fail to measure FV.
**/
EFI_STATUS
EFIAPI
EndofPeiSignalNotifyCallBack (
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
IN VOID *Ppi
);
EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList[] = {
{
EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,
@ -85,14 +114,73 @@ EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList[] = {
PhysicalPresencePpiNotifyCallback
},
{
(EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,
&gEfiPeiFirmwareVolumeInfoPpiGuid,
FirmwareVolmeInfoPpiNotifyCallback
},
{
(EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
&gEfiEndOfPeiSignalPpiGuid,
EndofPeiSignalNotifyCallBack
}
};
EFI_PLATFORM_FIRMWARE_BLOB mMeasuredFvInfo[FixedPcdGet32 (PcdPeiCoreMaxFvSupported)];
UINT32 mMeasuredFvIndex = 0;
/**
Record all measured Firmware Volum Information into a Guid Hob
Guid Hob payload layout is
UINT32 *************************** FIRMWARE_BLOB number
EFI_PLATFORM_FIRMWARE_BLOB******** BLOB Array
@param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
@param[in] NotifyDescriptor Address of the notification descriptor data structure.
@param[in] Ppi Address of the PPI that was installed.
@retval EFI_SUCCESS The FV Info is measured and recorded to TPM.
@return Others Fail to measure FV.
**/
EFI_STATUS
EFIAPI
EndofPeiSignalNotifyCallBack (
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
IN VOID *Ppi
)
{
UINT8 *HobData;
HobData = NULL;
//
// Create a Guid hob to save all trusted Fv
//
HobData = BuildGuidHob(
&gTrustedFvHobGuid,
sizeof(UINTN) + sizeof(EFI_PLATFORM_FIRMWARE_BLOB) * (mMeasuredBaseFvIndex + mMeasuredChildFvIndex)
);
if (HobData != NULL){
//
// Save measured FV info enty number
//
*(UINT32 *)HobData = mMeasuredBaseFvIndex + mMeasuredChildFvIndex;
HobData += sizeof(UINT32);
//
// Save measured base Fv info
//
CopyMem (HobData, mMeasuredBaseFvInfo, sizeof(EFI_PLATFORM_FIRMWARE_BLOB) * (mMeasuredBaseFvIndex));
HobData += sizeof(EFI_PLATFORM_FIRMWARE_BLOB) * (mMeasuredBaseFvIndex);
//
// Save measured child Fv info
//
CopyMem (HobData, mMeasuredChildFvInfo, sizeof(EFI_PLATFORM_FIRMWARE_BLOB) * (mMeasuredChildFvIndex));
}
return EFI_SUCCESS;
}
/**
Do a hash operation on a data buffer, extend a specific TPM PCR with the hash result,
@ -228,8 +316,8 @@ MeasureFvImage (
//
// Check whether FV is in the measured FV list.
//
for (Index = 0; Index < mMeasuredFvIndex; Index ++) {
if (mMeasuredFvInfo[Index].BlobBase == FvBase) {
for (Index = 0; Index < mMeasuredBaseFvIndex; Index ++) {
if (mMeasuredBaseFvInfo[Index].BlobBase == FvBase) {
return EFI_SUCCESS;
}
}
@ -260,10 +348,11 @@ MeasureFvImage (
//
// Add new FV into the measured FV list.
//
ASSERT (mMeasuredFvIndex < FixedPcdGet32 (PcdPeiCoreMaxFvSupported));
if (mMeasuredFvIndex < FixedPcdGet32 (PcdPeiCoreMaxFvSupported)) {
mMeasuredFvInfo[mMeasuredFvIndex].BlobBase = FvBase;
mMeasuredFvInfo[mMeasuredFvIndex++].BlobLength = FvLength;
ASSERT (mMeasuredBaseFvIndex < FixedPcdGet32 (PcdPeiCoreMaxFvSupported));
if (mMeasuredBaseFvIndex < FixedPcdGet32 (PcdPeiCoreMaxFvSupported)) {
mMeasuredBaseFvInfo[mMeasuredBaseFvIndex].BlobBase = FvBase;
mMeasuredBaseFvInfo[mMeasuredBaseFvIndex].BlobLength = FvLength;
mMeasuredBaseFvIndex++;
}
return Status;
@ -369,9 +458,16 @@ FirmwareVolmeInfoPpiNotifyCallback (
//
// This is an FV from an FFS file, and the parent FV must have already been measured,
// No need to measure twice, so just returns
// No need to measure twice, so just record the FV and return
//
if (Fv->ParentFvName != NULL || Fv->ParentFileName != NULL ) {
ASSERT (mMeasuredChildFvIndex < FixedPcdGet32 (PcdPeiCoreMaxFvSupported));
if (mMeasuredChildFvIndex < FixedPcdGet32 (PcdPeiCoreMaxFvSupported)) {
mMeasuredChildFvInfo[mMeasuredChildFvIndex].BlobBase = (EFI_PHYSICAL_ADDRESS) (UINTN) Fv->FvInfo;
mMeasuredChildFvInfo[mMeasuredChildFvIndex].BlobLength = Fv->FvInfoSize;
mMeasuredChildFvIndex++;
}
return EFI_SUCCESS;
}

View File

@ -51,11 +51,13 @@
[Guids]
gTcgEventEntryHobGuid
gTrustedFvHobGuid
[Ppis]
gPeiLockPhysicalPresencePpiGuid
gEfiPeiFirmwareVolumeInfoPpiGuid
gPeiTpmInitializedPpiGuid
gEfiEndOfPeiSignalPpiGuid
[Pcd]
gEfiSecurityPkgTokenSpaceGuid.PcdHideTpm