/** @file ;****************************************************************************** ;* Copyright 2021 Insyde Software Corp. All Rights Reserved. ;* ;* You may not reproduce, distribute, publish, display, perform, modify, adapt, ;* transmit, broadcast, present, recite, release, license or otherwise exploit ;* any part of this publication in any form, by any means, without the prior ;* written permission of Insyde Software Corp. ;* ;****************************************************************************** */ /** @file This file contains DXE driver for testing and publishing HSTI @copyright INTEL CONFIDENTIAL Copyright 2015 - 2021 Intel Corporation. The source code contained or described herein and all documents related to the source code ("Material") are owned by Intel Corporation or its suppliers or licensors. Title to the Material remains with Intel Corporation or its suppliers and licensors. The Material may contain trade secrets and proprietary and confidential information of Intel Corporation and its suppliers and licensors, and is protected by worldwide copyright and trade secret laws and treaty provisions. No part of the Material may be used, copied, reproduced, modified, published, uploaded, posted, transmitted, distributed, or disclosed in any way without Intel's prior express written permission. No license under any patent, copyright, trade secret or other intellectual property right is granted to or conferred upon you by disclosure or delivery of the Materials, either expressly, by implication, inducement, estoppel or otherwise. Any license under such intellectual property rights must be express and approved by Intel in writing. Unless otherwise agreed by Intel in writing, you may not remove or alter this notice or any other notice embedded in Materials by Intel or Intel's suppliers or licensors in any way. This file contains an 'Intel Peripheral Driver' and is uniquely identified as "Intel Reference Module" and is licensed for Intel CPUs and chipsets under the terms of your license agreement with Intel or your vendor. This file may be modified by the user, subject to additional terms of the license agreement. @par Specification **/ #include "HstiIhvDxe.h" ADAPTER_INFO_PLATFORM_SECURITY_STRUCT mHstiStruct = { PLATFORM_SECURITY_VERSION_VNEXTCS, PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE, {HSTI_PLATFORM_NAME}, HSTI_SECURITY_FEATURE_SIZE, {0}, // SecurityFeaturesRequired {0}, // SecurityFeaturesImplemented {0}, // SecurityFeaturesVerified 0, }; //[-start-211104-BAOTAN0003-modify]// #ifdef LCFC_SUPPORT UINT8 mFeatureRequired[HSTI_SECURITY_FEATURE_SIZE] = { // // Byte 0 // // HSTI_BYTE0_HARDWARE_ROOTED_BOOT_INTEGRITY | // HSTI_BYTE0_BOOT_FIRMWARE_MEDIA_PROTECTION | // HSTI_BYTE0_SIGNED_FIRMWARE_UPDATE | // HSTI_BYTE0_MEASURED_BOOT_ENFORCEMENT | HSTI_BYTE0_INTEGRATED_DEVICE_DMA_PROTECTION | HSTI_BYTE0_DEBUG_INTERFACE_SECURITY_CONFIGURATION, // HSTI_BYTE0_SECURE_CPU_CONFIGURATION, // // Byte 1 // HSTI_BYTE1_SECURE_MEMORY_MAP_CONFIGURATION | HSTI_BYTE1_SECURE_INTEGRATED_GRAPHICS_CONFIGURATION | // HSTI_BYTE1_SECURE_PCH_CONFIGURATION, // // Byte 2 // 0, }; //[-start-210730-IB17800134-modify]// UINT8 mFeatureImplemented[HSTI_SECURITY_FEATURE_SIZE] = { // // Byte 0 // //#if (FixedPcdGetBool (PcdBootGuardEnable) == 1) // HSTI_BYTE0_HARDWARE_ROOTED_BOOT_INTEGRITY | //#endif // HSTI_BYTE0_BOOT_FIRMWARE_MEDIA_PROTECTION | //#if (FixedPcdGetBool (PcdBiosGuardEnable) == 1) // HSTI_BYTE0_SIGNED_FIRMWARE_UPDATE | //#endif // HSTI_BYTE0_MEASURED_BOOT_ENFORCEMENT | HSTI_BYTE0_INTEGRATED_DEVICE_DMA_PROTECTION | HSTI_BYTE0_DEBUG_INTERFACE_SECURITY_CONFIGURATION, // HSTI_BYTE0_SECURE_CPU_CONFIGURATION, // // Byte 1 // HSTI_BYTE1_SECURE_MEMORY_MAP_CONFIGURATION | HSTI_BYTE1_SECURE_INTEGRATED_GRAPHICS_CONFIGURATION | // HSTI_BYTE1_SECURE_PCH_CONFIGURATION, // // Byte 2 // 0, }; //[-end-210730-IB17800134-modify]// #else UINT8 mFeatureRequired[HSTI_SECURITY_FEATURE_SIZE] = { // // Byte 0 // HSTI_BYTE0_HARDWARE_ROOTED_BOOT_INTEGRITY | HSTI_BYTE0_BOOT_FIRMWARE_MEDIA_PROTECTION | HSTI_BYTE0_SIGNED_FIRMWARE_UPDATE | HSTI_BYTE0_MEASURED_BOOT_ENFORCEMENT | HSTI_BYTE0_INTEGRATED_DEVICE_DMA_PROTECTION | HSTI_BYTE0_DEBUG_INTERFACE_SECURITY_CONFIGURATION | HSTI_BYTE0_SECURE_CPU_CONFIGURATION, // // Byte 1 // HSTI_BYTE1_SECURE_MEMORY_MAP_CONFIGURATION | HSTI_BYTE1_SECURE_INTEGRATED_GRAPHICS_CONFIGURATION | HSTI_BYTE1_SECURE_PCH_CONFIGURATION, // // Byte 2 // 0, }; //[-start-210730-IB17800134-modify]// UINT8 mFeatureImplemented[HSTI_SECURITY_FEATURE_SIZE] = { // // Byte 0 // #if (FixedPcdGetBool (PcdBootGuardEnable) == 1) HSTI_BYTE0_HARDWARE_ROOTED_BOOT_INTEGRITY | #endif HSTI_BYTE0_BOOT_FIRMWARE_MEDIA_PROTECTION | #if (FixedPcdGetBool (PcdBiosGuardEnable) == 1) HSTI_BYTE0_SIGNED_FIRMWARE_UPDATE | #endif HSTI_BYTE0_MEASURED_BOOT_ENFORCEMENT | HSTI_BYTE0_INTEGRATED_DEVICE_DMA_PROTECTION | HSTI_BYTE0_DEBUG_INTERFACE_SECURITY_CONFIGURATION | HSTI_BYTE0_SECURE_CPU_CONFIGURATION, // // Byte 1 // HSTI_BYTE1_SECURE_MEMORY_MAP_CONFIGURATION | HSTI_BYTE1_SECURE_INTEGRATED_GRAPHICS_CONFIGURATION | HSTI_BYTE1_SECURE_PCH_CONFIGURATION, // // Byte 2 // 0, }; //[-end-210730-IB17800134-modify]// #endif //[-end-211104-BAOTAN0003-modify]// DXE_SI_POLICY_PROTOCOL *mSiPolicyData; /** Initialize HSTI feature data **/ VOID InitData ( VOID ) { EFI_STATUS Status; ADAPTER_INFO_PLATFORM_SECURITY *Hsti; UINT8 *SecurityFeatures; UINTN Index; if ((mSiPolicyData != NULL) && (mSiPolicyData->Hsti != NULL)) { /// /// Take cached HSTI feature bitmap data pointed to by policy and publish to OS /// Hsti = mSiPolicyData->Hsti; SecurityFeatures = (UINT8 *) (Hsti + 1); DEBUG ((DEBUG_INFO, " SecurityFeaturesRequired - ")); for (Index = 0; Index < Hsti->SecurityFeaturesSize; Index++) { DEBUG ((DEBUG_INFO, "%02x ", SecurityFeatures[Index])); } DEBUG ((DEBUG_INFO, "\n")); CopyMem ( mHstiStruct.SecurityFeaturesRequired, SecurityFeatures, sizeof (mFeatureRequired) ); SecurityFeatures = (UINT8 *) (SecurityFeatures + Hsti->SecurityFeaturesSize); DEBUG ((DEBUG_INFO, " SecurityFeaturesImplemented - ")); for (Index = 0; Index < Hsti->SecurityFeaturesSize; Index++) { DEBUG ((DEBUG_INFO, "%02x ", SecurityFeatures[Index])); } DEBUG ((DEBUG_INFO, "\n")); CopyMem ( mHstiStruct.SecurityFeaturesImplemented, SecurityFeatures, sizeof (mFeatureImplemented) ); SecurityFeatures = (UINT8 *) (SecurityFeatures + Hsti->SecurityFeaturesSize); DEBUG ((DEBUG_INFO, " SecurityFeaturesVerified - ")); for (Index = 0; Index < Hsti->SecurityFeaturesSize; Index++) { DEBUG ((DEBUG_INFO, "%02x ", SecurityFeatures[Index])); } DEBUG ((DEBUG_INFO, "\n")); CopyMem ( mHstiStruct.SecurityFeaturesVerified, SecurityFeatures, sizeof (mFeatureImplemented) ); } else { /// /// Set only the bitmaps not related to verified, those will get updated during test process /// CopyMem ( mHstiStruct.SecurityFeaturesRequired, mFeatureRequired, sizeof (mFeatureRequired) ); CopyMem ( mHstiStruct.SecurityFeaturesImplemented, mFeatureImplemented, sizeof (mFeatureImplemented) ); } Status = HstiLibSetTable ( &mHstiStruct, sizeof (mHstiStruct) ); if (EFI_ERROR (Status)) { if (Status != EFI_ALREADY_STARTED) { DEBUG ((DEBUG_INFO, " There is already HSTI table with Role and ImplementationID published in system\n")); ASSERT_EFI_ERROR (Status); } } } /** Check HSTI Library Set was Successful **/ VOID CheckStatusForHstiLibSet ( IN EFI_STATUS Status ) { if (Status != EFI_SUCCESS) { DEBUG ((DEBUG_INFO, " There is no HSTI Table Published or ByteIndex is Invalid\n")); ASSERT_EFI_ERROR (Status); } } /** Check HSTI Library Set was Successful **/ VOID CheckStatusForHstiLibAppend ( IN EFI_STATUS Status ) { if (Status != EFI_SUCCESS) { DEBUG ((DEBUG_INFO, " There is no HSTI Table Published or not enough system \ resources to update Status String\n")); ASSERT_EFI_ERROR (Status); } } /** Concatenate Status string. @param[in] StatusCodeString - Status Code @param[in] StatusString - Status Text @param[out] StringSizeOut - Return String size for memory deallocation @retval CHAR16 - Concatenated string. Note: This function will always return a string. In case of error while trying to create the Concatenated String, it will as well return a string for Invalid output Parameter or out of resources error. **/ CHAR16 * EFIAPI BuildHstiStatusStringAndSize ( IN CHAR16 *StatusCodeString, IN CHAR16 *StatusString, OUT UINTN StringSizeOut ) { UINTN Offset; UINTN TotalStringSize; UINTN StatusCodeStringSize; UINTN StatusStringSize; CHAR16 *StatusStringOut; StatusStringOut = NULL; Offset = 0; TotalStringSize = 0; StatusCodeStringSize = 0; StatusStringSize = 0; if ((StatusCodeString == NULL) || (StatusString == NULL)) { DEBUG ((DEBUG_INFO, " %s", HSTI_BUILD_STRING_ERROR)); return HSTI_BUILD_STRING_ERROR; } StatusCodeStringSize = StrSize (StatusCodeString); StatusStringSize = StrSize (StatusString); TotalStringSize = StatusCodeStringSize + StatusStringSize; StatusStringOut = AllocateZeroPool (TotalStringSize); if (StatusStringOut == NULL) { DEBUG ((DEBUG_INFO, " %s", HSTI_OUT_OF_RESOURCES_ERROR)); return HSTI_OUT_OF_RESOURCES_ERROR; } CopyMem ( StatusStringOut + Offset, StatusCodeString, (StatusCodeStringSize - 1) ); Offset += StrLen (StatusCodeString); CopyMem ( StatusStringOut + Offset, StatusString, StatusStringSize ); Offset += StrLen (StatusString); StringSizeOut = TotalStringSize; return StatusStringOut; } /** Concatenate Status string and Append HSTI Status String if it hasn't been reported yet. The codes are tracked by externally provided bitmap. If CodeReportedBitmap[CodeIndexBit] is not set, append the string Otherwise do nothing @param[in] StatusCodeString - Status Code @param[in] CodeReportedBitmap - Flags for which codes have been used @param[in] CodeIndexBit - Flag index for reported code @retval EFI_SUCCESS The Status String was successfully build and saved in HSTI Status Structure. **/ EFI_STATUS EFIAPI BuildAndAppendHstiUniqueStatusString ( IN CHAR16 *StatusCodeString, IN CHAR16 *StatusString, IN OUT UINT32 *CodeReportedBitmap, IN UINT32 CodeIndexBit ) { EFI_STATUS Status = EFI_SUCCESS; if (!(*CodeReportedBitmap & CodeIndexBit)) { Status = BuildAndAppendHstiStatusString (StatusCodeString, StatusString); if (!EFI_ERROR (Status)){ *CodeReportedBitmap |= CodeIndexBit; } } return Status; } /** Concatenate Status string and Append HSTI Status String. @param[in] StatusCodeString - Status Code @param[in] StatusString - Status Text @retval EFI_SUCCESS The Status String was successfully build and saved in HSTI Status Structure. **/ EFI_STATUS EFIAPI BuildAndAppendHstiStatusString ( IN CHAR16 *StatusCodeString, IN CHAR16 *StatusString ) { EFI_STATUS Status; UINTN TotalStringSize; CHAR16 *StatusStringOut; StatusStringOut = NULL; TotalStringSize = 0; StatusStringOut = BuildHstiStatusStringAndSize (StatusCodeString, StatusString, TotalStringSize ); Status = HstiLibAppendErrorString ( PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE, NULL, StatusStringOut ); CheckStatusForHstiLibAppend (Status); if (StatusStringOut != NULL) { ZeroMem (StatusStringOut, sizeof (TotalStringSize)); FreePool (StatusStringOut); } return Status; } /** Update HSTI feature data from cached results or rerun tests **/ VOID UpdateData ( VOID ) { ADAPTER_INFO_PLATFORM_SECURITY *Hsti; UINT8 *SecurityFeatures; CHAR16 *StatusString; if ((mSiPolicyData != NULL) && (mSiPolicyData->Hsti != NULL)) { Hsti = mSiPolicyData->Hsti; SecurityFeatures = (UINT8 *) (Hsti + 1); SecurityFeatures = (UINT8 *) (SecurityFeatures + Hsti->SecurityFeaturesSize); SecurityFeatures = (UINT8 *) (SecurityFeatures + Hsti->SecurityFeaturesSize); StatusString = (CHAR16 *) (SecurityFeatures + Hsti->SecurityFeaturesSize); HstiLibSetErrorString (PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE,NULL,StatusString); } else { DEBUG ((DEBUG_INFO, "HSTI - Intel Independent Hardware Vendor (Ihv) Tests\n")); DEBUG ((DEBUG_INFO, "Hardware Rooted Boot Integrity Configuration\n")); CheckHardwareRootedBootIntegrity (); DEBUG ((DEBUG_INFO, "Signed Firmware Update Configuration\n")); CheckSignedFirmwareUpdate (); DEBUG ((DEBUG_INFO, "Measured Boot Enforcement Configuration\n")); CheckMeasuredBootEnforcement (); DEBUG ((DEBUG_INFO, "Integrated Device DMA Protection Configuration\n")); CheckIntegratedDeviceDmaProtection (); DEBUG ((DEBUG_INFO, "Secure Debug Interface Configuration\n")); CheckSecureDebugInterfaceConfiguration (); DEBUG ((DEBUG_INFO, "Secure CPU Configuration\n")); CheckSecureCpuConfiguration (); DEBUG ((DEBUG_INFO, "Secure Memory Map Configuration\n")); CheckSecureMemoryMapConfiguration (); DEBUG ((DEBUG_INFO, "Secure Integrated Graphics Configuration\n")); CheckSecureIntegratedGraphicsConfiguration (); DEBUG ((DEBUG_INFO, "Boot Firmware Media Protection (SPI) Configuration\n")); CheckBootFirmwareMediaProtection (); DEBUG ((DEBUG_INFO, "Secure PCH Configuration\n")); CheckSecurePchConfiguration (); } } /** Dump HSTI info to serial @param[in] HstiData - Pointer to HSTI data **/ VOID DumpHsti ( IN VOID *HstiData ) { ADAPTER_INFO_PLATFORM_SECURITY *Hsti; UINT8 *SecurityFeatures; CHAR16 *StatusString; UINTN Index; CHAR16 StatusChar; UINTN DebugIndex; CHAR16 StatusDebugString [MAX_DEBUG_HSTI_MESSAGE_LENGTH]; Hsti = HstiData; DebugIndex = 0; DEBUG ((DEBUG_INFO, "\nHSTI\n")); DEBUG ((DEBUG_INFO, " Version - 0x%08x\n", Hsti->Version)); DEBUG ((DEBUG_INFO, " Role - 0x%08x\n", Hsti->Role)); DEBUG ((DEBUG_INFO, " ImplementationID - %S\n", Hsti->ImplementationID)); DEBUG ((DEBUG_INFO, " SecurityFeaturesSize - 0x%08x\n", Hsti->SecurityFeaturesSize)); SecurityFeatures = (UINT8 *) (Hsti + 1); if (Hsti->Role == PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE) { DEBUG ((DEBUG_INFO, " SecurityFeaturesRequired - ")); for (Index = 0; Index < Hsti->SecurityFeaturesSize; Index++) { DEBUG ((DEBUG_INFO, "%02x ", SecurityFeatures[Index])); } DEBUG ((DEBUG_INFO, "\n")); SecurityFeatures = (UINT8 *) (SecurityFeatures + Hsti->SecurityFeaturesSize); } DEBUG ((DEBUG_INFO, " SecurityFeaturesImplemented - ")); for (Index = 0; Index < Hsti->SecurityFeaturesSize; Index++) { DEBUG ((DEBUG_INFO, "%02x ", SecurityFeatures[Index])); } DEBUG ((DEBUG_INFO, "\n")); SecurityFeatures = (UINT8 *) (SecurityFeatures + Hsti->SecurityFeaturesSize); DEBUG ((DEBUG_INFO, " SecurityFeaturesVerified - ")); for (Index = 0; Index < Hsti->SecurityFeaturesSize; Index++) { DEBUG ((DEBUG_INFO, "%02x ", SecurityFeatures[Index])); } DEBUG ((DEBUG_INFO, "\n")); StatusString = (CHAR16 *) (SecurityFeatures + Hsti->SecurityFeaturesSize); DEBUG ((DEBUG_INFO, " UnexpectedStatusString - \"")); CopyMem (&StatusChar, StatusString, sizeof (StatusChar)); ZeroMem (StatusDebugString, sizeof (StatusDebugString)); // HSTI UEFI Structure is not 16-bit aligned for this reason // Status String may not be always 16-bit aligned (difficulting // Status String manipulation using string functions) // Due to this limitation, previously, code was printing to Serial Comm port // character by character, now with this workaround implementation, code // will print 128 characters to Serial Comm port instead of one by one // For this reason below code is implemented to working around // this string handling (require 16-bit alignment) limitation while (StatusChar != 0) { // Allocate two characters: one for last character and one for Null terminator if (DebugIndex < MAX_DEBUG_HSTI_MESSAGE_LENGTH - 2) { if (StatusChar == '\n') { StatusDebugString[DebugIndex] = StatusChar; StatusDebugString[DebugIndex + 1] = '\0'; DEBUG((DEBUG_INFO, "%s", StatusDebugString)); ZeroMem (StatusDebugString, sizeof (StatusDebugString)); DebugIndex = 0; } else { StatusDebugString[DebugIndex] = StatusChar; DebugIndex++; } } else { StatusDebugString[DebugIndex] = StatusChar; StatusDebugString[DebugIndex + 1] = L'\0'; DEBUG((DEBUG_INFO, "%s", StatusDebugString)); ZeroMem (StatusDebugString, sizeof (StatusDebugString)); DebugIndex = 0; } StatusString++; CopyMem (&StatusChar, StatusString, sizeof (StatusChar)); // Make sure last message is completely sent prior leaving the loop if ((StatusChar == 0) && (DebugIndex < MAX_DEBUG_HSTI_MESSAGE_LENGTH - 1)) { StatusDebugString[DebugIndex] = StatusChar; DEBUG((DEBUG_INFO, "%s", StatusDebugString)); } } DEBUG ((DEBUG_INFO, "\"\n")); ZeroMem (StatusDebugString, sizeof (StatusDebugString)); } /** Retrieve HSTI Table from AIP **/ VOID DumpData ( VOID ) { VOID *Hsti; UINTN HstiSize; EFI_STATUS Status; Status = HstiLibGetTable ( PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE, NULL, &Hsti, &HstiSize ); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "HSTI (Role - 0x%08x) not found!\n", PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE)); return; } if (mSiPolicyData != NULL) { mSiPolicyData->Hsti = (ADAPTER_INFO_PLATFORM_SECURITY *) Hsti; mSiPolicyData->HstiSize = HstiSize; } DumpHsti (Hsti); } /** Handler to gather and publish HSTI results on ReadyToBootEvent @param[in] Event Event whose notification function is being invoked @param[in] Context Pointer to the notification function's context **/ VOID EFIAPI OnReadyToBoot ( EFI_EVENT Event, VOID *Context ) { EFI_HANDLE Handle; EFI_STATUS Status; InitMp (); InitData (); UpdateData (); DumpData (); Handle = NULL; Status = gBS->InstallProtocolInterface ( &Handle, &gHstiPublishCompleteProtocolGuid, EFI_NATIVE_INTERFACE, NULL ); ASSERT_EFI_ERROR (Status); if (Event != NULL) { gBS->CloseEvent (Event); } } /** The driver's entry point. @param[in] ImageHandle The firmware allocated handle for the EFI image. @param[in] SystemTable A pointer to the EFI System Table. @retval EFI_SUCCESS The entry point is executed successfully. @retval other Some error occurs when executing this entry point. **/ EFI_STATUS EFIAPI HstiIhvDxeEntrypoint ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; EFI_EVENT Event; // // Locate DxeSiPolicyProtocolGuid protocol instance and assign it to a global variable // Status = gBS->LocateProtocol ( &gDxeSiPolicyProtocolGuid, NULL, (VOID **) &mSiPolicyData ); if (EFI_ERROR (Status)) { mSiPolicyData = NULL; DEBUG ((DEBUG_ERROR,"Failed to locate DxeSiPolicyProtocolGuid Protocol\n")); return Status; } Status = gBS->InstallProtocolInterface ( &gImageHandle, &gHstiProtocolGuid, EFI_NATIVE_INTERFACE, NULL ); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "HSTI Protocol Installation Failed\n")); ASSERT_EFI_ERROR (Status); return Status; } EfiCreateEventReadyToBootEx ( TPL_NOTIFY, OnReadyToBoot, NULL, &Event ); return EFI_SUCCESS; }