mirror of https://github.com/acidanthera/audk.git
OvmfPkg/IntelTdx: Measure Td HobList and Configuration FV
RFC: https://bugzilla.tianocore.org/show_bug.cgi?id=3853 TdHobList and Configuration FV are external data provided by Host VMM. These are not trusted in Td guest. So they should be validated , measured and extended to Td RTMR registers. In the meantime 2 EFI_CC_EVENT_HOB are created. These 2 GUIDed HOBs carry the hash value of TdHobList and Configuration FV. In DXE phase EFI_CC_EVENT can be created based on these 2 GUIDed HOBs. Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Jordan Justen <jordan.l.justen@intel.com> Cc: Brijesh Singh <brijesh.singh@amd.com> Cc: Erdem Aktas <erdemaktas@google.com> Cc: James Bottomley <jejb@linux.ibm.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Tom Lendacky <thomas.lendacky@amd.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Reviewed-by: Jiewen Yao <jiewen.yao@intel.com> Signed-off-by: Min Xu <min.m.xu@intel.com>
This commit is contained in:
parent
a708536dce
commit
4b0a622635
|
@ -527,6 +527,10 @@
|
|||
OvmfPkg/IntelTdx/Sec/SecMain.inf {
|
||||
<LibraryClasses>
|
||||
NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
|
||||
SecMeasurementLib|OvmfPkg/Library/SecMeasurementLib/SecMeasurementLibTdx.inf
|
||||
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SecCryptLib.inf
|
||||
HashLib|SecurityPkg/Library/HashLibTdx/HashLibTdx.inf
|
||||
NULL|SecurityPkg/Library/HashInstanceLibSha384/HashInstanceLibSha384.inf
|
||||
}
|
||||
|
||||
#
|
||||
|
|
|
@ -0,0 +1,163 @@
|
|||
/** @file
|
||||
Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
**/
|
||||
|
||||
#include <PiPei.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Guid/VariableFormat.h>
|
||||
#include <Guid/SystemNvDataGuid.h>
|
||||
#include "PeilessStartupInternal.h"
|
||||
|
||||
/**
|
||||
Check padding data all bit should be 1.
|
||||
|
||||
@param[in] Buffer - A pointer to buffer header
|
||||
@param[in] BufferSize - Buffer size
|
||||
|
||||
@retval TRUE - The padding data is valid.
|
||||
@retval TRUE - The padding data is invalid.
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
CheckPaddingData (
|
||||
IN UINT8 *Buffer,
|
||||
IN UINT32 BufferSize
|
||||
)
|
||||
{
|
||||
UINT32 index;
|
||||
|
||||
for (index = 0; index < BufferSize; index++) {
|
||||
if (Buffer[index] != 0xFF) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
Check the integrity of CFV data.
|
||||
|
||||
@param[in] TdxCfvBase - A pointer to CFV header
|
||||
@param[in] TdxCfvSize - CFV data size
|
||||
|
||||
@retval TRUE - The CFV data is valid.
|
||||
@retval FALSE - The CFV data is invalid.
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
EFIAPI
|
||||
TdxValidateCfv (
|
||||
IN UINT8 *TdxCfvBase,
|
||||
IN UINT32 TdxCfvSize
|
||||
)
|
||||
{
|
||||
UINT16 Checksum;
|
||||
UINTN VariableBase;
|
||||
UINT32 VariableOffset;
|
||||
UINT32 VariableOffsetBeforeAlign;
|
||||
EFI_FIRMWARE_VOLUME_HEADER *CfvFvHeader;
|
||||
VARIABLE_STORE_HEADER *CfvVariableStoreHeader;
|
||||
AUTHENTICATED_VARIABLE_HEADER *VariableHeader;
|
||||
|
||||
static EFI_GUID FvHdrGUID = EFI_SYSTEM_NV_DATA_FV_GUID;
|
||||
static EFI_GUID VarStoreHdrGUID = EFI_AUTHENTICATED_VARIABLE_GUID;
|
||||
|
||||
VariableOffset = 0;
|
||||
|
||||
if (TdxCfvBase == NULL) {
|
||||
DEBUG ((DEBUG_ERROR, "TDX CFV: CFV pointer is NULL\n"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//
|
||||
// Verify the header zerovetor, filesystemguid,
|
||||
// revision, signature, attributes, fvlength, checksum
|
||||
// HeaderLength cannot be an odd number
|
||||
//
|
||||
CfvFvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)TdxCfvBase;
|
||||
|
||||
if ((!IsZeroBuffer (CfvFvHeader->ZeroVector, 16)) ||
|
||||
(!CompareGuid (&FvHdrGUID, &CfvFvHeader->FileSystemGuid)) ||
|
||||
(CfvFvHeader->Signature != EFI_FVH_SIGNATURE) ||
|
||||
(CfvFvHeader->Attributes != 0x4feff) ||
|
||||
(CfvFvHeader->Revision != EFI_FVH_REVISION) ||
|
||||
(CfvFvHeader->FvLength != TdxCfvSize)
|
||||
)
|
||||
{
|
||||
DEBUG ((DEBUG_ERROR, "TDX CFV: Basic FV headers were invalid\n"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//
|
||||
// Verify the header checksum
|
||||
//
|
||||
Checksum = CalculateSum16 ((VOID *)CfvFvHeader, CfvFvHeader->HeaderLength);
|
||||
|
||||
if (Checksum != 0) {
|
||||
DEBUG ((DEBUG_ERROR, "TDX CFV: FV checksum was invalid\n"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//
|
||||
// Verify the header signature, size, format, state
|
||||
//
|
||||
CfvVariableStoreHeader = (VARIABLE_STORE_HEADER *)(TdxCfvBase + CfvFvHeader->HeaderLength);
|
||||
if ((!CompareGuid (&VarStoreHdrGUID, &CfvVariableStoreHeader->Signature)) ||
|
||||
(CfvVariableStoreHeader->Format != VARIABLE_STORE_FORMATTED) ||
|
||||
(CfvVariableStoreHeader->State != VARIABLE_STORE_HEALTHY) ||
|
||||
(CfvVariableStoreHeader->Size > (CfvFvHeader->FvLength - CfvFvHeader->HeaderLength)) ||
|
||||
(CfvVariableStoreHeader->Size < sizeof (VARIABLE_STORE_HEADER))
|
||||
)
|
||||
{
|
||||
DEBUG ((DEBUG_ERROR, "TDX CFV: Variable Store header was invalid\n"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//
|
||||
// Verify the header startId, state
|
||||
// Verify data to the end
|
||||
//
|
||||
VariableBase = (UINTN)TdxCfvBase + CfvFvHeader->HeaderLength + sizeof (VARIABLE_STORE_HEADER);
|
||||
while (VariableOffset < (CfvVariableStoreHeader->Size - sizeof (VARIABLE_STORE_HEADER))) {
|
||||
VariableHeader = (AUTHENTICATED_VARIABLE_HEADER *)(VariableBase + VariableOffset);
|
||||
if (VariableHeader->StartId != VARIABLE_DATA) {
|
||||
if (!CheckPaddingData ((UINT8 *)VariableHeader, CfvVariableStoreHeader->Size - sizeof (VARIABLE_STORE_HEADER) - VariableOffset)) {
|
||||
DEBUG ((DEBUG_ERROR, "TDX CFV: Variable header was invalid\n"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
VariableOffset = CfvVariableStoreHeader->Size - sizeof (VARIABLE_STORE_HEADER);
|
||||
} else {
|
||||
if (!((VariableHeader->State == VAR_IN_DELETED_TRANSITION) ||
|
||||
(VariableHeader->State == VAR_DELETED) ||
|
||||
(VariableHeader->State == VAR_HEADER_VALID_ONLY) ||
|
||||
(VariableHeader->State == VAR_ADDED)))
|
||||
{
|
||||
DEBUG ((DEBUG_ERROR, "TDX CFV: Variable header was invalid\n"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
VariableOffset += sizeof (AUTHENTICATED_VARIABLE_HEADER) + VariableHeader->NameSize + VariableHeader->DataSize;
|
||||
// Verify VariableOffset should be less than or equal CfvVariableStoreHeader->Size - sizeof(VARIABLE_STORE_HEADER)
|
||||
if (VariableOffset > (CfvVariableStoreHeader->Size - sizeof (VARIABLE_STORE_HEADER))) {
|
||||
DEBUG ((DEBUG_ERROR, "TDX CFV: Variable header was invalid\n"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
VariableOffsetBeforeAlign = VariableOffset;
|
||||
// 4 byte align
|
||||
VariableOffset = (VariableOffset + 3) & (UINTN)(~3);
|
||||
|
||||
if (!CheckPaddingData ((UINT8 *)(VariableBase + VariableOffsetBeforeAlign), VariableOffset - VariableOffsetBeforeAlign)) {
|
||||
DEBUG ((DEBUG_ERROR, "TDX CFV: Variable header was invalid\n"));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
|
@ -20,6 +20,7 @@
|
|||
#include <ConfidentialComputingGuestAttr.h>
|
||||
#include <Guid/MemoryTypeInformation.h>
|
||||
#include <OvmfPlatforms.h>
|
||||
#include <Library/SecMeasurementLib.h>
|
||||
#include "PeilessStartupInternal.h"
|
||||
|
||||
#define GET_GPAW_INIT_STATE(INFO) ((UINT8) ((INFO) & 0x3f))
|
||||
|
@ -133,11 +134,13 @@ PeilessStartup (
|
|||
UINT32 DxeCodeSize;
|
||||
TD_RETURN_DATA TdReturnData;
|
||||
VOID *VmmHobList;
|
||||
UINT8 *CfvBase;
|
||||
|
||||
Status = EFI_SUCCESS;
|
||||
BootFv = NULL;
|
||||
VmmHobList = NULL;
|
||||
SecCoreData = (EFI_SEC_PEI_HAND_OFF *)Context;
|
||||
CfvBase = (UINT8 *)(UINTN)FixedPcdGet32 (PcdCfvBase);
|
||||
|
||||
ZeroMem (&PlatformInfoHob, sizeof (PlatformInfoHob));
|
||||
|
||||
|
@ -167,6 +170,34 @@ PeilessStartup (
|
|||
|
||||
DEBUG ((DEBUG_INFO, "HobList: %p\n", GetHobList ()));
|
||||
|
||||
if (TdIsEnabled ()) {
|
||||
//
|
||||
// Measure HobList
|
||||
//
|
||||
Status = MeasureHobList (VmmHobList);
|
||||
if (EFI_ERROR (Status)) {
|
||||
ASSERT (FALSE);
|
||||
CpuDeadLoop ();
|
||||
}
|
||||
|
||||
//
|
||||
// Validate Tdx CFV
|
||||
//
|
||||
if (!TdxValidateCfv (CfvBase, FixedPcdGet32 (PcdCfvRawDataSize))) {
|
||||
ASSERT (FALSE);
|
||||
CpuDeadLoop ();
|
||||
}
|
||||
|
||||
//
|
||||
// Measure Tdx CFV
|
||||
//
|
||||
Status = MeasureFvImage ((EFI_PHYSICAL_ADDRESS)(UINTN)CfvBase, FixedPcdGet32 (PcdCfvRawDataSize), 1);
|
||||
if (EFI_ERROR (Status)) {
|
||||
ASSERT (FALSE);
|
||||
CpuDeadLoop ();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Initialize the Platform
|
||||
//
|
||||
|
|
|
@ -52,4 +52,21 @@ EFIAPI
|
|||
ConstructSecHobList (
|
||||
);
|
||||
|
||||
/**
|
||||
Check the integrity of CFV data.
|
||||
|
||||
@param[in] TdxCfvBase - A pointer to CFV header
|
||||
@param[in] TdxCfvSize - CFV data size
|
||||
|
||||
@retval TRUE - The CFV data is valid.
|
||||
@retval FALSE - The CFV data is invalid.
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
EFIAPI
|
||||
TdxValidateCfv (
|
||||
IN UINT8 *TdxCfvBase,
|
||||
IN UINT32 TdxCfvSize
|
||||
);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -29,8 +29,7 @@
|
|||
PeilessStartup.c
|
||||
Hob.c
|
||||
DxeLoad.c
|
||||
|
||||
[Sources.X64]
|
||||
IntelTdx.c
|
||||
X64/VirtualMemory.c
|
||||
|
||||
[Packages]
|
||||
|
@ -39,6 +38,8 @@
|
|||
UefiCpuPkg/UefiCpuPkg.dec
|
||||
OvmfPkg/OvmfPkg.dec
|
||||
EmbeddedPkg/EmbeddedPkg.dec
|
||||
CryptoPkg/CryptoPkg.dec
|
||||
SecurityPkg/SecurityPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
|
@ -56,6 +57,8 @@
|
|||
PrePiLib
|
||||
QemuFwCfgLib
|
||||
PlatformInitLib
|
||||
HashLib
|
||||
SecMeasurementLib
|
||||
|
||||
[Guids]
|
||||
gEfiHobMemoryAllocModuleGuid
|
||||
|
@ -63,6 +66,7 @@
|
|||
gUefiOvmfPkgPlatformInfoGuid
|
||||
gEfiMemoryTypeInformationGuid
|
||||
gPcdDataBaseHobGuid
|
||||
gCcEventEntryHobGuid
|
||||
|
||||
[Pcd]
|
||||
gUefiOvmfPkgTokenSpaceGuid.PcdCfvBase
|
||||
|
|
Loading…
Reference in New Issue