From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by mx.groups.io with SMTP id smtpd.web08.5676.1655519541534598350 for ; Fri, 17 Jun 2022 19:32:24 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="unable to parse pub key" header.i=@intel.com header.s=intel header.b=OWzIBaMh; spf=pass (domain: intel.com, ip: 134.134.136.24, mailfrom: min.m.xu@intel.com) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1655519542; x=1687055542; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Ma5nitTeCxzUbFn9JlzGGxyD0+UOIbbKoNywUZ1Re9s=; b=OWzIBaMh8nHBuvta/pTJxaEulaSebwosfX5/Mmrz2IEPCzE6wGNKkN5u 0OxGDyqigxqRJtunjlGMz8XbIyOjQWM2B3OtGH/j2KZFUqq+iJIThwHNr 7B+CmGGo2ymgsbcXz6oRU9JUiA+Um26HXCKRy5ub6vZpksnx8ZoZErXGb Z54/W5Rxn/8HSKwAAGq6+f66+YWCQ5rkQVikmR1tcVG1PGJI3iKnfmV6W uULQ4+xrTgFFHax/qCPAJksyZrAmXgXV6wnLw12tjJMvyZf/RKpKSX56v lTR63OzUjxSzRiS63VxOvm6iRcRAOQNO9ijIzge+PZ6Z+tOOcFtEoAEq9 w==; X-IronPort-AV: E=McAfee;i="6400,9594,10380"; a="280355741" X-IronPort-AV: E=Sophos;i="5.92,306,1650956400"; d="scan'208";a="280355741" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by orsmga102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Jun 2022 19:32:22 -0700 X-IronPort-AV: E=Sophos;i="5.92,306,1650956400"; d="scan'208";a="642270312" Received: from mxu9-mobl1.ccr.corp.intel.com ([10.249.173.231]) by fmsmga008-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Jun 2022 19:32:20 -0700 From: "Min Xu" To: devel@edk2.groups.io Cc: Min M Xu , Erdem Aktas , James Bottomley , Jiewen Yao , Gerd Hoffmann , Tom Lendacky Subject: [PATCH 1/3] OvmfPkg: Move TdxValidateCfv from PeilessStartupLib to PlatformInitLib Date: Sat, 18 Jun 2022 10:32:01 +0800 Message-Id: <3b3dce962500443d1281db91fd5e0ba2619aaf15.1655518585.git.min.m.xu@intel.com> X-Mailer: git-send-email 2.29.2.windows.2 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: Min M Xu TdxValidateCfv validates the integrity of Configuration FV (CFV). It was implemented in PeilessStartupLib which is included in IntelTdxX64. In OvmfPkgX64 we should validate CFV as well. So it is moved from PeilessStartupLib to PlatformInitLib so that it can be called in both OvmfPkgX64 and IntelTdxX64. Cc: Erdem Aktas Cc: James Bottomley Cc: Jiewen Yao Cc: Gerd Hoffmann Cc: Tom Lendacky Signed-off-by: Min Xu --- OvmfPkg/Include/Library/PlatformInitLib.h | 17 ++ OvmfPkg/Library/PeilessStartupLib/IntelTdx.c | 153 ------------------ .../PeilessStartupInternal.h | 17 -- OvmfPkg/Library/PlatformInitLib/IntelTdx.c | 153 ++++++++++++++++++ 4 files changed, 170 insertions(+), 170 deletions(-) diff --git a/OvmfPkg/Include/Library/PlatformInitLib.h b/OvmfPkg/Include/Library/PlatformInitLib.h index 2987a367cc9c..a3acfb1fb196 100644 --- a/OvmfPkg/Include/Library/PlatformInitLib.h +++ b/OvmfPkg/Include/Library/PlatformInitLib.h @@ -234,4 +234,21 @@ PlatformTdxPublishRamRegions ( VOID ); +/** + 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 // PLATFORM_INIT_LIB_H_ diff --git a/OvmfPkg/Library/PeilessStartupLib/IntelTdx.c b/OvmfPkg/Library/PeilessStartupLib/IntelTdx.c index 484fd21057c8..216c413caad5 100644 --- a/OvmfPkg/Library/PeilessStartupLib/IntelTdx.c +++ b/OvmfPkg/Library/PeilessStartupLib/IntelTdx.c @@ -7,8 +7,6 @@ #include #include #include -#include -#include #include #include #include @@ -37,157 +35,6 @@ typedef struct { #pragma pack() -/** - 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; -} - /** Measure the Hoblist passed from the VMM. diff --git a/OvmfPkg/Library/PeilessStartupLib/PeilessStartupInternal.h b/OvmfPkg/Library/PeilessStartupLib/PeilessStartupInternal.h index 74b5f46552c2..09cac3e26c67 100644 --- a/OvmfPkg/Library/PeilessStartupLib/PeilessStartupInternal.h +++ b/OvmfPkg/Library/PeilessStartupLib/PeilessStartupInternal.h @@ -52,23 +52,6 @@ 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 - ); - /** Measure the Hoblist passed from the VMM. diff --git a/OvmfPkg/Library/PlatformInitLib/IntelTdx.c b/OvmfPkg/Library/PlatformInitLib/IntelTdx.c index c6d7c8bb6e0e..626a670c9c64 100644 --- a/OvmfPkg/Library/PlatformInitLib/IntelTdx.c +++ b/OvmfPkg/Library/PlatformInitLib/IntelTdx.c @@ -20,6 +20,8 @@ #include #include #include +#include +#include #include #include @@ -561,3 +563,154 @@ PlatformTdxPublishRamRegions ( ); } } + +/** + 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; +} -- 2.29.2.windows.2