From aaedfe3c126c434badb608284ad72d8a07ce162b Mon Sep 17 00:00:00 2001 From: "Yao, Jiewen" Date: Mon, 19 Jan 2015 06:08:23 +0000 Subject: [PATCH] Add HSTI support. Add HSTI header file and a library to assist HSTI table creation. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: "Yao, Jiewen" Reviewed-by: "Gao, Liming" git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16621 6f19259b-4bc3-4df7-8a09-765794883524 --- MdePkg/Include/IndustryStandard/Hsti.h | 82 +++ MdePkg/Include/Library/HstiLib.h | 158 ++++++ MdePkg/Library/DxeHstiLib/DxeHstiLib.inf | 48 ++ MdePkg/Library/DxeHstiLib/DxeHstiLib.uni | Bin 0 -> 1612 bytes MdePkg/Library/DxeHstiLib/HstiAip.c | 175 +++++++ MdePkg/Library/DxeHstiLib/HstiDxe.c | 609 +++++++++++++++++++++++ MdePkg/Library/DxeHstiLib/HstiDxe.h | 65 +++ MdePkg/MdePkg.dec | 5 +- MdePkg/MdePkg.dsc | 3 +- 9 files changed, 1143 insertions(+), 2 deletions(-) create mode 100644 MdePkg/Include/IndustryStandard/Hsti.h create mode 100644 MdePkg/Include/Library/HstiLib.h create mode 100644 MdePkg/Library/DxeHstiLib/DxeHstiLib.inf create mode 100644 MdePkg/Library/DxeHstiLib/DxeHstiLib.uni create mode 100644 MdePkg/Library/DxeHstiLib/HstiAip.c create mode 100644 MdePkg/Library/DxeHstiLib/HstiDxe.c create mode 100644 MdePkg/Library/DxeHstiLib/HstiDxe.h diff --git a/MdePkg/Include/IndustryStandard/Hsti.h b/MdePkg/Include/IndustryStandard/Hsti.h new file mode 100644 index 0000000000..1f118551a0 --- /dev/null +++ b/MdePkg/Include/IndustryStandard/Hsti.h @@ -0,0 +1,82 @@ +/** @file + Support for HSTI 1.0 specification, defined at + Microsoft Hardware Security Testability Specification. + + Copyright (c) 2015, Intel Corporation. All rights reserved.
+ 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 __HSTI_H__ +#define __HSTI_H__ + +#pragma pack(1) + +#define ADAPTER_INFO_PLATFORM_SECURITY_GUID \ + {0x6be272c7, 0x1320, 0x4ccd, { 0x90, 0x17, 0xd4, 0x61, 0x2c, 0x01, 0x2b, 0x25 }} + +#define PLATFORM_SECURITY_VERSION_VNEXTCS 0x00000003 + +#define PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE 0x00000001 // IHV +#define PLATFORM_SECURITY_ROLE_PLATFORM_IBV 0x00000002 +#define PLATFORM_SECURITY_ROLE_IMPLEMENTOR_OEM 0x00000003 +#define PLATFORM_SECURITY_ROLE_IMPLEMENTOR_ODM 0x00000004 + +typedef struct { + // + // Return PLATFORM_SECURITY_VERSION_VNEXTCS + // + UINT32 Version; + // + // The role of the publisher of this interface. Reference platform designers + // such as IHVs and IBVs are expected to return PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE + // and PLATFORM_SECURITY_ROLE_PLATFORM_IBV respectively. + // If the test modules from the designers are unable to fully verify all + // security features, then the platform implementers, OEMs and ODMs, will + // need to publish this interface with a role of Implementer. + // + UINT32 Role; + // + // Human readable vendor, model, & version of this implementation. + // + CHAR16 ImplementationID[256]; + // + // The size in bytes of the SecurityFeaturesRequired and SecurityFeaturesEnabled arrays. + // The arrays must be the same size. + // + UINT32 SecurityFeaturesSize; + // + // IHV-defined bitfield corresponding to all security features which must be + // implemented to meet the security requirements defined by PLATFORM_SECURITY_VERSION Version. + // +//UINT8 SecurityFeaturesRequired[]; //Ignored for non-IHV + // + // Publisher-defined bitfield corresponding to all security features which + // have implemented programmatic tests in this module. + // +//UINT8 SecurityFeaturesImplemented[]; + // + // Publisher-defined bitfield corresponding to all security features which + // have been verified implemented by this implementation. + // +//UINT8 SecurityFeaturesVerified[]; + // + // A Null-terminated string, one failure per line (CR/LF terminated), with a + // unique identifier that the OEM/ODM can use to locate the documentation + // which will describe the steps to remediate the failure - a URL to the + // documentation is recommended. + // +//CHAR16 ErrorString[]; +} ADAPTER_INFO_PLATFORM_SECURITY; + +#pragma pack() + +extern EFI_GUID gAdapterInfoPlatformSecurityGuid; + +#endif diff --git a/MdePkg/Include/Library/HstiLib.h b/MdePkg/Include/Library/HstiLib.h new file mode 100644 index 0000000000..9af8817b75 --- /dev/null +++ b/MdePkg/Include/Library/HstiLib.h @@ -0,0 +1,158 @@ +/** @file + Provides services to create, get and update HSTI table in AIP protocol. + + Copyright (c) 2015, Intel Corporation. All rights reserved.
+ 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 __HSTI_LIB_H__ +#define __HSTI_LIB_H__ + +/** + Publish HSTI table in AIP protocol. + + One system should have only one PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE. + + If the Role is NOT PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE, + SecurityFeaturesRequired field will be ignored. + + @param Hsti HSTI data + @param HstiSize HSTI size + + @retval EFI_SUCCESS The HSTI data is published in AIP protocol. + @retval EFI_ALREADY_STARTED There is already HSTI table with Role and ImplementationID published in system. + @retval EFI_VOLUME_CORRUPTED The input HSTI data does not follow HSTI specification. + @retval EFI_OUT_OF_RESOURCES There is not enough system resource to publish HSTI data in AIP protocol. +**/ +EFI_STATUS +EFIAPI +HstiLibSetTable ( + IN VOID *Hsti, + IN UINTN HstiSize + ); + +/** + Search HSTI table in AIP protocol, and return the data. + This API will return the HSTI table with indicated Role and ImplementationID, + NULL ImplementationID means to find the first HSTI table with indicated Role. + + @param Role Role of HSTI data. + @param ImplementationID ImplementationID of HSTI data. + NULL means find the first one match Role. + @param Hsti HSTI data. This buffer is allocated by callee, and it + is the responsibility of the caller to free it after + using it. + @param HstiSize HSTI size + + @retval EFI_SUCCESS The HSTI data in AIP protocol is returned. + @retval EFI_NOT_FOUND There is not HSTI table with the Role and ImplementationID published in system. +**/ +EFI_STATUS +EFIAPI +HstiLibGetTable ( + IN UINT32 Role, + IN CHAR16 *ImplementationID OPTIONAL, + OUT VOID **Hsti, + OUT UINTN *HstiSize + ); + +/** + Set FeaturesVerified in published HSTI table. + This API will update the HSTI table with indicated Role and ImplementationID, + NULL ImplementationID means to find the first HSTI table with indicated Role. + + @param Role Role of HSTI data. + @param ImplementationID ImplementationID of HSTI data. + NULL means find the first one match Role. + @param ByteIndex Byte index of FeaturesVerified of HSTI data. + @param BitMask Bit mask of FeaturesVerified of HSTI data. + + @retval EFI_SUCCESS The FeaturesVerified of HSTI data updated in AIP protocol. + @retval EFI_NOT_STARTED There is not HSTI table with the Role and ImplementationID published in system. + @retval EFI_UNSUPPORTED The ByteIndex is invalid. +**/ +EFI_STATUS +EFIAPI +HstiLibSetFeaturesVerified ( + IN UINT32 Role, + IN CHAR16 *ImplementationID, OPTIONAL + IN UINT32 ByteIndex, + IN UINT8 BitMask + ); + +/** + Clear FeaturesVerified in published HSTI table. + This API will update the HSTI table with indicated Role and ImplementationID, + NULL ImplementationID means to find the first HSTI table with indicated Role. + + @param Role Role of HSTI data. + @param ImplementationID ImplementationID of HSTI data. + NULL means find the first one match Role. + @param ByteIndex Byte index of FeaturesVerified of HSTI data. + @param BitMask Bit mask of FeaturesVerified of HSTI data. + + @retval EFI_SUCCESS The FeaturesVerified of HSTI data updated in AIP protocol. + @retval EFI_NOT_STARTED There is not HSTI table with the Role and ImplementationID published in system. + @retval EFI_UNSUPPORTED The ByteIndex is invalid. +**/ +EFI_STATUS +EFIAPI +HstiLibClearFeaturesVerified ( + IN UINT32 Role, + IN CHAR16 *ImplementationID, OPTIONAL + IN UINT32 ByteIndex, + IN UINT8 BitMask + ); + +/** + Append ErrorString in published HSTI table. + This API will update the HSTI table with indicated Role and ImplementationID, + NULL ImplementationID means to find the first HSTI table with indicated Role. + + @param Role Role of HSTI data. + @param ImplementationID ImplementationID of HSTI data. + NULL means find the first one match Role. + @param ErrorString ErrorString of HSTI data. + + @retval EFI_SUCCESS The ErrorString of HSTI data is updated in AIP protocol. + @retval EFI_NOT_STARTED There is not HSTI table with the Role and ImplementationID published in system. + @retval EFI_OUT_OF_RESOURCES There is not enough system resource to update ErrorString. +**/ +EFI_STATUS +EFIAPI +HstiLibAppendErrorString ( + IN UINT32 Role, + IN CHAR16 *ImplementationID, OPTIONAL + IN CHAR16 *ErrorString + ); + +/** + Set a new ErrorString in published HSTI table. + This API will update the HSTI table with indicated Role and ImplementationID, + NULL ImplementationID means to find the first HSTI table with indicated Role. + + @param Role Role of HSTI data. + @param ImplementationID ImplementationID of HSTI data. + NULL means find the first one match Role. + @param ErrorString ErrorString of HSTI data. + + @retval EFI_SUCCESS The ErrorString of HSTI data is updated in AIP protocol. + @retval EFI_NOT_STARTED There is not HSTI table with the Role and ImplementationID published in system. + @retval EFI_OUT_OF_RESOURCES There is not enough system resource to update ErrorString. +**/ +EFI_STATUS +EFIAPI +HstiLibSetErrorString ( + IN UINT32 Role, + IN CHAR16 *ImplementationID, OPTIONAL + IN CHAR16 *ErrorString + ); + +#endif diff --git a/MdePkg/Library/DxeHstiLib/DxeHstiLib.inf b/MdePkg/Library/DxeHstiLib/DxeHstiLib.inf new file mode 100644 index 0000000000..a694c2c8ae --- /dev/null +++ b/MdePkg/Library/DxeHstiLib/DxeHstiLib.inf @@ -0,0 +1,48 @@ +## @file +# DXE instance of Hsti Library. +# +# Copyright (c) 2015, Intel Corporation. All rights reserved.
+# +# 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. +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = DxeHstiLib + MODULE_UNI_FILE = DxeHstiLib.uni + FILE_GUID = 7DE1C620-F587-4116-A36D-40F3467B9A0C + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = HstiLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER + +[Sources] + HstiAip.c + HstiDxe.c + HstiDxe.h + +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + MemoryAllocationLib + DebugLib + UefiBootServicesTableLib + +[Guids] +## SOMETIMES_PRODUCES ## GUID +## SOMETIMES_CONSUMES ## GUID + gAdapterInfoPlatformSecurityGuid + +[Protocols] +## SOMETIMES_PRODUCES +## SOMETIMES_CONSUMES + gEfiAdapterInformationProtocolGuid + diff --git a/MdePkg/Library/DxeHstiLib/DxeHstiLib.uni b/MdePkg/Library/DxeHstiLib/DxeHstiLib.uni new file mode 100644 index 0000000000000000000000000000000000000000..d5b7a782490f11501db945e605eaf6e93a471338 GIT binary patch literal 1612 zcmbW2TW`}q5QXO%iT|)lUjVfURN@68L_!Um6rq*ekJ|*%fHco`Ck0{@9+|3wvpYj8lA6_?R=+nUYg# zb5;vROVFLQ*_TB`Tlv`(MpIV5(@wB_Z5`{`n+Ny|;80-gz%Rj_c^?bry5)qv!a{e= zVL8TPfu;7=oLge=SP?7vD;Ui|i}#fhIz4Aknn^)%iugJ`@isYpbL{4{BU+vN=2-|k zG6}vGo^{Pq%*40Y>Z3b__|!M(Sf5yiC`B%j>#f&fO#Az73)l!zSV1rOQa0$;BY5t{ zMXHMZCF>zV;`{@feNOjv30khP8g0&BZxj%tYDZUPPDLbM`5aYF1#M+tdZnA(z9c@a zJ?&Slj9@;oqrIIbC|7(jZ=DUu?gTzv@+Y$ov~By$JVi^r4D|z6Q!;GGDDesp?TkKQ zJt9Q)Q!+ZiqVJJ2M#^Nh4SL}UwL#zUbIlHS?tad`cxB$BvvaI^p4l1eDX7B8y!Re6 zao3uB4zQJtyaucH*vk7?`j700xn5wh@e*#4Py=e5h@PTFmsc;JCp)^uoKjV3dG1=% zcd*Tx@OpxN7a(O|3_(lm0!GqH%C=E!0G~ho4v3;&!Hme~w8}f>!Vy?v+5q)`>sMpT z{NGqB=6(1oAG%weA7cJ@*7X}Y^*W^7 + 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. + +**/ + +#include "HstiDxe.h" + +/** + Returns the current state information for the adapter. + + This function returns information of type InformationType from the adapter. + If an adapter does not support the requested informational type, then + EFI_UNSUPPORTED is returned. + + @param[in] This A pointer to the EFI_ADAPTER_INFORMATION_PROTOCOL instance. + @param[in] InformationType A pointer to an EFI_GUID that defines the contents of InformationBlock. + @param[out] InformationBlock The service returns a pointer to the buffer with the InformationBlock + structure which contains details about the data specific to InformationType. + @param[out] InformationBlockSize The driver returns the size of the InformationBlock in bytes. + + @retval EFI_SUCCESS The InformationType information was retrieved. + @retval EFI_UNSUPPORTED The InformationType is not known. + @retval EFI_DEVICE_ERROR The device reported an error. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. + @retval EFI_INVALID_PARAMETER This is NULL. + @retval EFI_INVALID_PARAMETER InformationBlock is NULL. + @retval EFI_INVALID_PARAMETER InformationBlockSize is NULL. + +**/ +EFI_STATUS +EFIAPI +HstiAipGetInfo ( + IN EFI_ADAPTER_INFORMATION_PROTOCOL *This, + IN EFI_GUID *InformationType, + OUT VOID **InformationBlock, + OUT UINTN *InformationBlockSize + ) +{ + HSTI_AIP_PRIVATE_DATA *HstiAip; + + if ((This == NULL) || (InformationBlock == NULL) || (InformationBlockSize == NULL)) { + return EFI_INVALID_PARAMETER; + } + if (!CompareGuid (InformationType, &gAdapterInfoPlatformSecurityGuid)) { + return EFI_UNSUPPORTED; + } + + HstiAip = HSTI_AIP_PRIVATE_DATA_FROM_THIS(This); + + *InformationBlock = AllocateCopyPool (HstiAip->HstiSize, HstiAip->Hsti); + if (*InformationBlock == NULL) { + return EFI_OUT_OF_RESOURCES; + } + *InformationBlockSize = HstiAip->HstiSize; + return EFI_SUCCESS; +} + +/** + Sets state information for an adapter. + + This function sends information of type InformationType for an adapter. + If an adapter does not support the requested information type, then EFI_UNSUPPORTED + is returned. + + @param[in] This A pointer to the EFI_ADAPTER_INFORMATION_PROTOCOL instance. + @param[in] InformationType A pointer to an EFI_GUID that defines the contents of InformationBlock. + @param[in] InformationBlock A pointer to the InformationBlock structure which contains details + about the data specific to InformationType. + @param[in] InformationBlockSize The size of the InformationBlock in bytes. + + @retval EFI_SUCCESS The information was received and interpreted successfully. + @retval EFI_UNSUPPORTED The InformationType is not known. + @retval EFI_DEVICE_ERROR The device reported an error. + @retval EFI_INVALID_PARAMETER This is NULL. + @retval EFI_INVALID_PARAMETER InformationBlock is NULL. + @retval EFI_WRITE_PROTECTED The InformationType cannot be modified using EFI_ADAPTER_INFO_SET_INFO(). + +**/ +EFI_STATUS +EFIAPI +HstiAipSetInfo ( + IN EFI_ADAPTER_INFORMATION_PROTOCOL *This, + IN EFI_GUID *InformationType, + IN VOID *InformationBlock, + IN UINTN InformationBlockSize + ) +{ + HSTI_AIP_PRIVATE_DATA *HstiAip; + VOID *NewHsti; + + if ((This == NULL) || (InformationBlock == NULL)) { + return EFI_INVALID_PARAMETER; + } + if (!CompareGuid (InformationType, &gAdapterInfoPlatformSecurityGuid)) { + return EFI_UNSUPPORTED; + } + + if (!InternalHstiIsValidTable (InformationBlock, InformationBlockSize)) { + return EFI_VOLUME_CORRUPTED; + } + + HstiAip = HSTI_AIP_PRIVATE_DATA_FROM_THIS(This); + + if (InformationBlockSize > HstiAip->HstiMaxSize) { + NewHsti = AllocateZeroPool (InformationBlockSize); + if (NewHsti == NULL) { + return EFI_OUT_OF_RESOURCES; + } + FreePool (HstiAip->Hsti); + HstiAip->Hsti = NewHsti; + HstiAip->HstiSize = 0; + HstiAip->HstiMaxSize = InformationBlockSize; + } + + CopyMem (HstiAip->Hsti, InformationBlock, InformationBlockSize); + HstiAip->HstiSize = InformationBlockSize; + return EFI_SUCCESS; +} + +/** + Get a list of supported information types for this instance of the protocol. + + This function returns a list of InformationType GUIDs that are supported on an + adapter with this instance of EFI_ADAPTER_INFORMATION_PROTOCOL. The list is returned + in InfoTypesBuffer, and the number of GUID pointers in InfoTypesBuffer is returned in + InfoTypesBufferCount. + + @param[in] This A pointer to the EFI_ADAPTER_INFORMATION_PROTOCOL instance. + @param[out] InfoTypesBuffer A pointer to the array of InformationType GUIDs that are supported + by This. + @param[out] InfoTypesBufferCount A pointer to the number of GUIDs present in InfoTypesBuffer. + + @retval EFI_SUCCESS The list of information type GUIDs that are supported on this adapter was + returned in InfoTypesBuffer. The number of information type GUIDs was + returned in InfoTypesBufferCount. + @retval EFI_INVALID_PARAMETER This is NULL. + @retval EFI_INVALID_PARAMETER InfoTypesBuffer is NULL. + @retval EFI_INVALID_PARAMETER InfoTypesBufferCount is NULL. + @retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the results. + +**/ +EFI_STATUS +EFIAPI +HstiAipGetSupportedTypes ( + IN EFI_ADAPTER_INFORMATION_PROTOCOL *This, + OUT EFI_GUID **InfoTypesBuffer, + OUT UINTN *InfoTypesBufferCount + ) +{ + if ((This == NULL) || (InfoTypesBuffer == NULL) || (InfoTypesBufferCount == NULL)) { + return EFI_INVALID_PARAMETER; + } + + *InfoTypesBuffer = AllocateCopyPool (sizeof(gAdapterInfoPlatformSecurityGuid), &gAdapterInfoPlatformSecurityGuid); + if (*InfoTypesBuffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + *InfoTypesBufferCount = 1; + + return EFI_SUCCESS; +} + +EFI_ADAPTER_INFORMATION_PROTOCOL mAdapterInformationProtocol = { + HstiAipGetInfo, + HstiAipSetInfo, + HstiAipGetSupportedTypes, +}; diff --git a/MdePkg/Library/DxeHstiLib/HstiDxe.c b/MdePkg/Library/DxeHstiLib/HstiDxe.c new file mode 100644 index 0000000000..c7a5769bf5 --- /dev/null +++ b/MdePkg/Library/DxeHstiLib/HstiDxe.c @@ -0,0 +1,609 @@ +/** @file + + Copyright (c) 2015, Intel Corporation. All rights reserved.
+ 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. + +**/ + +#include "HstiDxe.h" + +/** + Find HSTI table in AIP protocol, and return the data. + This API will return the HSTI table with indicated Role and ImplementationID, + NULL ImplementationID means to find the first HSTI table with indicated Role. + + @param Role Role of HSTI data. + @param ImplementationID ImplementationID of HSTI data. + NULL means find the first one match Role. + @param HstiData HSTI data. This buffer is allocated by callee, and it + is the responsibility of the caller to free it after + using it. + @param HstiSize HSTI size + + @return Aip The AIP protocol having this HSTI. + @return NULL There is not HSTI table with the Role and ImplementationID published in system. +**/ +VOID * +InternalHstiFindAip ( + IN UINT32 Role, + IN CHAR16 *ImplementationID OPTIONAL, + OUT VOID **HstiData OPTIONAL, + OUT UINTN *HstiSize OPTIONAL + ) +{ + EFI_STATUS Status; + EFI_ADAPTER_INFORMATION_PROTOCOL *Aip; + UINTN NoHandles; + EFI_HANDLE *Handles; + UINTN Index; + EFI_GUID *InfoTypesBuffer; + UINTN InfoTypesBufferCount; + UINTN InfoTypesIndex; + EFI_ADAPTER_INFORMATION_PROTOCOL *AipCandidate; + VOID *InformationBlock; + UINTN InformationBlockSize; + ADAPTER_INFO_PLATFORM_SECURITY *Hsti; + + Status = gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiAdapterInformationProtocolGuid, + NULL, + &NoHandles, + &Handles + ); + if (EFI_ERROR (Status)) { + return NULL; + } + + Hsti = NULL; + Aip = NULL; + InformationBlock = NULL; + InformationBlockSize = 0; + for (Index = 0; Index < NoHandles; Index++) { + Status = gBS->HandleProtocol ( + Handles[Index], + &gEfiAdapterInformationProtocolGuid, + (VOID **)&Aip + ); + if (EFI_ERROR (Status)) { + continue; + } + + // + // Check AIP + // + Status = Aip->GetSupportedTypes ( + Aip, + &InfoTypesBuffer, + &InfoTypesBufferCount + ); + if (EFI_ERROR (Status)) { + continue; + } + + AipCandidate = NULL; + for (InfoTypesIndex = 0; InfoTypesIndex < InfoTypesBufferCount; InfoTypesIndex++) { + if (CompareGuid (&InfoTypesBuffer[InfoTypesIndex], &gAdapterInfoPlatformSecurityGuid)) { + AipCandidate = Aip; + break; + } + } + FreePool (InfoTypesBuffer); + + if (AipCandidate == NULL) { + continue; + } + + // + // Check HSTI Role + // + Aip = AipCandidate; + Status = Aip->GetInformation ( + Aip, + &gAdapterInfoPlatformSecurityGuid, + &InformationBlock, + &InformationBlockSize + ); + if (EFI_ERROR (Status)) { + continue; + } + + Hsti = InformationBlock; + if ((Hsti->Role == Role) && + ((ImplementationID == NULL) || (StrCmp (ImplementationID, Hsti->ImplementationID) == 0))) { + break; + } else { + Hsti = NULL; + FreePool (InformationBlock); + continue; + } + } + FreePool (Handles); + + if (Hsti == NULL) { + return NULL; + } + + if (HstiData != NULL) { + *HstiData = InformationBlock; + } + if (HstiSize != NULL) { + *HstiSize = InformationBlockSize; + } + return Aip; +} + +/** + Return if input HSTI data follows HSTI specification. + + @param HstiData HSTI data + @param HstiSize HSTI size + + @retval TRUE HSTI data follows HSTI specification. + @retval FALSE HSTI data does not follow HSTI specification. +**/ +BOOLEAN +InternalHstiIsValidTable ( + IN VOID *HstiData, + IN UINTN HstiSize + ) +{ + ADAPTER_INFO_PLATFORM_SECURITY *Hsti; + UINTN Index; + CHAR16 *ErrorString; + CHAR16 ErrorChar; + UINTN ErrorStringSize; + UINTN ErrorStringLength; + + Hsti = HstiData; + + // + // basic check for header + // + if (HstiData == NULL) { + DEBUG ((EFI_D_ERROR, "HstiData == NULL\n")); + return FALSE; + } + if (HstiSize < sizeof(ADAPTER_INFO_PLATFORM_SECURITY)) { + DEBUG ((EFI_D_ERROR, "HstiSize < sizeof(ADAPTER_INFO_PLATFORM_SECURITY)\n")); + return FALSE; + } + if (((HstiSize - sizeof(ADAPTER_INFO_PLATFORM_SECURITY)) / 3) < Hsti->SecurityFeaturesSize) { + DEBUG ((EFI_D_ERROR, "((HstiSize - sizeof(ADAPTER_INFO_PLATFORM_SECURITY)) / 3) < SecurityFeaturesSize\n")); + return FALSE; + } + + // + // Check Version + // + if (Hsti->Version != PLATFORM_SECURITY_VERSION_VNEXTCS) { + DEBUG ((EFI_D_ERROR, "Version != PLATFORM_SECURITY_VERSION_VNEXTCS\n")); + return FALSE; + } + + // + // Check Role + // + if ((Hsti->Role < PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE) || + (Hsti->Role > PLATFORM_SECURITY_ROLE_IMPLEMENTOR_ODM)) { + DEBUG ((EFI_D_ERROR, "Role < PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE ||\n")); + DEBUG ((EFI_D_ERROR, "Role > PLATFORM_SECURITY_ROLE_IMPLEMENTOR_ODM\n")); + return FALSE; + } + + // + // Check ImplementationID + // + for (Index = 0; Index < sizeof(Hsti->ImplementationID); Index++) { + if (Hsti->ImplementationID[Index] == 0) { + break; + } + } + if (Index == sizeof(Hsti->ImplementationID)) { + DEBUG ((EFI_D_ERROR, "ImplementationID is no NUL CHAR\n")); + return FALSE; + } + + ErrorStringSize = HstiSize - sizeof(ADAPTER_INFO_PLATFORM_SECURITY) - Hsti->SecurityFeaturesSize * 3; + ErrorString = (CHAR16 *)((UINTN)Hsti + sizeof(ADAPTER_INFO_PLATFORM_SECURITY) - Hsti->SecurityFeaturesSize * 3); + + // + // basic check for ErrorString + // + if (ErrorStringSize == 0) { + DEBUG ((EFI_D_ERROR, "ErrorStringSize == 0\n")); + return FALSE; + } + if ((ErrorStringSize & BIT0) != 0) { + DEBUG ((EFI_D_ERROR, "(ErrorStringSize & BIT0) != 0\n")); + return FALSE; + } + + // + // ErrorString might not be CHAR16 aligned. + // + CopyMem (&ErrorChar, ErrorString, sizeof(ErrorChar)); + for (ErrorStringLength = 0; (ErrorChar != 0) && (ErrorStringLength < (ErrorStringSize/2)); ErrorStringLength++) { + ErrorString++; + CopyMem (&ErrorChar, ErrorString, sizeof(ErrorChar)); + } + + // + // check the length of ErrorString + // + if (ErrorChar != 0) { + DEBUG ((EFI_D_ERROR, "ErrorString has no NUL CHAR\n")); + return FALSE; + } + if (ErrorStringLength == (ErrorStringSize/2)) { + DEBUG ((EFI_D_ERROR, "ErrorString Length incorrect\n")); + return FALSE; + } + + return TRUE; +} + +/** + Publish HSTI table in AIP protocol. + + One system should have only one PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE. + + If the Role is NOT PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE, + SecurityFeaturesRequired field will be ignored. + + @param Hsti HSTI data + @param HstiSize HSTI size + + @retval EFI_SUCCESS The HSTI data is published in AIP protocol. + @retval EFI_ALREADY_STARTED There is already HSTI table with Role and ImplementationID published in system. + @retval EFI_VOLUME_CORRUPTED The input HSTI data does not follow HSTI specification. + @retval EFI_OUT_OF_RESOURCES There is not enough system resource to publish HSTI data in AIP protocol. +**/ +EFI_STATUS +EFIAPI +HstiLibSetTable ( + IN VOID *Hsti, + IN UINTN HstiSize + ) +{ + EFI_STATUS Status; + EFI_HANDLE Handle; + HSTI_AIP_PRIVATE_DATA *HstiAip; + EFI_ADAPTER_INFORMATION_PROTOCOL *Aip; + UINT32 Role; + CHAR16 *ImplementationID; + UINT32 SecurityFeaturesSize; + UINT8 *SecurityFeaturesRequired; + + if (!InternalHstiIsValidTable (Hsti, HstiSize)) { + return EFI_VOLUME_CORRUPTED; + } + + Role = ((ADAPTER_INFO_PLATFORM_SECURITY *)Hsti)->Role; + ImplementationID = ((ADAPTER_INFO_PLATFORM_SECURITY *)Hsti)->ImplementationID; + Aip = InternalHstiFindAip (Role, ImplementationID, NULL, NULL); + if (Aip != NULL) { + return EFI_ALREADY_STARTED; + } + + HstiAip = AllocateZeroPool (sizeof(HSTI_AIP_PRIVATE_DATA)); + if (HstiAip == NULL) { + return EFI_OUT_OF_RESOURCES; + } + HstiAip->Hsti = AllocateCopyPool (HstiSize, Hsti); + if (HstiAip == NULL) { + FreePool (HstiAip); + return EFI_OUT_OF_RESOURCES; + } + if (Role != PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE) { + SecurityFeaturesRequired = (UINT8 *)HstiAip->Hsti + sizeof(ADAPTER_INFO_PLATFORM_SECURITY); + SecurityFeaturesSize = ((ADAPTER_INFO_PLATFORM_SECURITY *)Hsti)->SecurityFeaturesSize; + ZeroMem (SecurityFeaturesRequired, SecurityFeaturesSize); + } + + HstiAip->Signature = HSTI_AIP_PRIVATE_SIGNATURE; + CopyMem (&HstiAip->Aip, &mAdapterInformationProtocol, sizeof(EFI_ADAPTER_INFORMATION_PROTOCOL)); + HstiAip->HstiSize = HstiSize; + HstiAip->HstiMaxSize = HstiSize; + + Handle = NULL; + Status = gBS->InstallMultipleProtocolInterfaces ( + &Handle, + &gEfiAdapterInformationProtocolGuid, + &HstiAip->Aip, + NULL + ); + if (EFI_ERROR (Status)) { + FreePool (HstiAip->Hsti); + FreePool (HstiAip); + } + + return Status; +} + +/** + Search HSTI table in AIP protocol, and return the data. + This API will return the HSTI table with indicated Role and ImplementationID, + NULL ImplementationID means to find the first HSTI table with indicated Role. + + @param Role Role of HSTI data. + @param ImplementationID ImplementationID of HSTI data. + NULL means find the first one match Role. + @param Hsti HSTI data. This buffer is allocated by callee, and it + is the responsibility of the caller to free it after + using it. + @param HstiSize HSTI size + + @retval EFI_SUCCESS The HSTI data in AIP protocol is returned. + @retval EFI_NOT_FOUND There is not HSTI table with the Role and ImplementationID published in system. +**/ +EFI_STATUS +EFIAPI +HstiLibGetTable ( + IN UINT32 Role, + IN CHAR16 *ImplementationID OPTIONAL, + OUT VOID **Hsti, + OUT UINTN *HstiSize + ) +{ + EFI_ADAPTER_INFORMATION_PROTOCOL *Aip; + + Aip = InternalHstiFindAip (Role, ImplementationID, Hsti, HstiSize); + if (Aip == NULL) { + return EFI_NOT_FOUND; + } + return EFI_SUCCESS; +} + +/** + Record FeaturesVerified in published HSTI table. + This API will update the HSTI table with indicated Role and ImplementationID, + NULL ImplementationID means to find the first HSTI table with indicated Role. + + @param Role Role of HSTI data. + @param ImplementationID ImplementationID of HSTI data. + NULL means find the first one match Role. + @param ByteIndex Byte index of FeaturesVerified of HSTI data. + @param BitMask Bit mask of FeaturesVerified of HSTI data. + @param Set TRUE means to set the FeaturesVerified bit. + FALSE means to clear the FeaturesVerified bit. + + @retval EFI_SUCCESS The FeaturesVerified of HSTI data updated in AIP protocol. + @retval EFI_NOT_STARTED There is not HSTI table with the Role and ImplementationID published in system. + @retval EFI_UNSUPPORTED The ByteIndex is invalid. +**/ +EFI_STATUS +InternalHstiRecordFeaturesVerified ( + IN UINT32 Role, + IN CHAR16 *ImplementationID, OPTIONAL + IN UINT32 ByteIndex, + IN UINT8 Bit, + IN BOOLEAN Set + ) +{ + EFI_ADAPTER_INFORMATION_PROTOCOL *Aip; + ADAPTER_INFO_PLATFORM_SECURITY *Hsti; + UINTN HstiSize; + UINT8 *SecurityFeaturesVerified; + EFI_STATUS Status; + + Aip = InternalHstiFindAip (Role, ImplementationID, &Hsti, &HstiSize); + if (Aip == NULL) { + return EFI_NOT_STARTED; + } + + if (ByteIndex >= Hsti->SecurityFeaturesSize) { + return EFI_UNSUPPORTED; + } + + SecurityFeaturesVerified = (UINT8 *)((UINTN)Hsti + sizeof(ADAPTER_INFO_PLATFORM_SECURITY) + Hsti->SecurityFeaturesSize * 2); + + if (Set) { + SecurityFeaturesVerified[ByteIndex] = (UINT8)(SecurityFeaturesVerified[ByteIndex] | (Bit)); + } else { + SecurityFeaturesVerified[ByteIndex] = (UINT8)(SecurityFeaturesVerified[ByteIndex] & (~Bit)); + } + + Status = Aip->SetInformation ( + Aip, + &gAdapterInfoPlatformSecurityGuid, + Hsti, + HstiSize + ); + return Status; +} + +/** + Set FeaturesVerified in published HSTI table. + This API will update the HSTI table with indicated Role and ImplementationID, + NULL ImplementationID means to find the first HSTI table with indicated Role. + + @param Role Role of HSTI data. + @param ImplementationID ImplementationID of HSTI data. + NULL means find the first one match Role. + @param ByteIndex Byte index of FeaturesVerified of HSTI data. + @param BitMask Bit mask of FeaturesVerified of HSTI data. + + @retval EFI_SUCCESS The FeaturesVerified of HSTI data updated in AIP protocol. + @retval EFI_NOT_STARTED There is not HSTI table with the Role and ImplementationID published in system. + @retval EFI_UNSUPPORTED The ByteIndex is invalid. +**/ +EFI_STATUS +EFIAPI +HstiLibSetFeaturesVerified ( + IN UINT32 Role, + IN CHAR16 *ImplementationID, OPTIONAL + IN UINT32 ByteIndex, + IN UINT8 BitMask + ) +{ + return InternalHstiRecordFeaturesVerified ( + Role, + ImplementationID, + ByteIndex, + BitMask, + TRUE + ); +} + +/** + Clear FeaturesVerified in published HSTI table. + This API will update the HSTI table with indicated Role and ImplementationID, + NULL ImplementationID means to find the first HSTI table with indicated Role. + + @param Role Role of HSTI data. + @param ImplementationID ImplementationID of HSTI data. + NULL means find the first one match Role. + @param ByteIndex Byte index of FeaturesVerified of HSTI data. + @param BitMask Bit mask of FeaturesVerified of HSTI data. + + @retval EFI_SUCCESS The FeaturesVerified of HSTI data updated in AIP protocol. + @retval EFI_NOT_STARTED There is not HSTI table with the Role and ImplementationID published in system. + @retval EFI_UNSUPPORTED The ByteIndex is invalid. +**/ +EFI_STATUS +EFIAPI +HstiLibClearFeaturesVerified ( + IN UINT32 Role, + IN CHAR16 *ImplementationID, OPTIONAL + IN UINT32 ByteIndex, + IN UINT8 BitMask + ) +{ + return InternalHstiRecordFeaturesVerified ( + Role, + ImplementationID, + ByteIndex, + BitMask, + FALSE + ); +} + +/** + Record ErrorString in published HSTI table. + This API will update the HSTI table with indicated Role and ImplementationID, + NULL ImplementationID means to find the first HSTI table with indicated Role. + + @param Role Role of HSTI data. + @param ImplementationID ImplementationID of HSTI data. + NULL means find the first one match Role. + @param ErrorString ErrorString of HSTI data. + @param Append TRUE means to append the ErrorString to HSTI table. + FALSE means to set the ErrorString in HSTI table. + + @retval EFI_SUCCESS The ErrorString of HSTI data is published in AIP protocol. + @retval EFI_NOT_STARTED There is not HSTI table with the Role and ImplementationID published in system. + @retval EFI_OUT_OF_RESOURCES There is not enough system resource to update ErrorString. +**/ +EFI_STATUS +InternalHstiRecordErrorString ( + IN UINT32 Role, + IN CHAR16 *ImplementationID, OPTIONAL + IN CHAR16 *ErrorString, + IN BOOLEAN Append + ) +{ + EFI_ADAPTER_INFORMATION_PROTOCOL *Aip; + ADAPTER_INFO_PLATFORM_SECURITY *Hsti; + UINTN HstiSize; + UINTN StringSize; + VOID *NewHsti; + UINTN NewHstiSize; + UINTN Offset; + EFI_STATUS Status; + + Aip = InternalHstiFindAip (Role, ImplementationID, &Hsti, &HstiSize); + if (Aip == NULL) { + return EFI_NOT_STARTED; + } + + if (Append) { + Offset = HstiSize - sizeof(CHAR16); + } else { + Offset = sizeof(ADAPTER_INFO_PLATFORM_SECURITY) + Hsti->SecurityFeaturesSize * 3; + } + StringSize = StrSize (ErrorString); + + NewHstiSize = Offset + StringSize; + NewHsti = AllocatePool (NewHstiSize); + if (NewHsti == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + CopyMem (NewHsti, Hsti, Offset); + CopyMem ((UINT8 *)NewHsti + Offset, ErrorString, StringSize); + + Status = Aip->SetInformation ( + Aip, + &gAdapterInfoPlatformSecurityGuid, + NewHsti, + NewHstiSize + ); + return Status; +} + +/** + Append ErrorString in published HSTI table. + This API will update the HSTI table with indicated Role and ImplementationID, + NULL ImplementationID means to find the first HSTI table with indicated Role. + + @param Role Role of HSTI data. + @param ImplementationID ImplementationID of HSTI data. + NULL means find the first one match Role. + @param ErrorString ErrorString of HSTI data. + + @retval EFI_SUCCESS The ErrorString of HSTI data is updated in AIP protocol. + @retval EFI_NOT_STARTED There is not HSTI table with the Role and ImplementationID published in system. + @retval EFI_OUT_OF_RESOURCES There is not enough system resource to update ErrorString. +**/ +EFI_STATUS +EFIAPI +HstiLibAppendErrorString ( + IN UINT32 Role, + IN CHAR16 *ImplementationID, OPTIONAL + IN CHAR16 *ErrorString + ) +{ + return InternalHstiRecordErrorString ( + Role, + ImplementationID, + ErrorString, + TRUE + ); +} + +/** + Set a new ErrorString in published HSTI table. + This API will update the HSTI table with indicated Role and ImplementationID, + NULL ImplementationID means to find the first HSTI table with indicated Role. + + @param Role Role of HSTI data. + @param ImplementationID ImplementationID of HSTI data. + NULL means find the first one match Role. + @param ErrorString ErrorString of HSTI data. + + @retval EFI_SUCCESS The ErrorString of HSTI data is updated in AIP protocol. + @retval EFI_NOT_STARTED There is not HSTI table with the Role and ImplementationID published in system. + @retval EFI_OUT_OF_RESOURCES There is not enough system resource to update ErrorString. +**/ +EFI_STATUS +EFIAPI +HstiLibSetErrorString ( + IN UINT32 Role, + IN CHAR16 *ImplementationID, OPTIONAL + IN CHAR16 *ErrorString + ) +{ + return InternalHstiRecordErrorString ( + Role, + ImplementationID, + ErrorString, + FALSE + ); +} diff --git a/MdePkg/Library/DxeHstiLib/HstiDxe.h b/MdePkg/Library/DxeHstiLib/HstiDxe.h new file mode 100644 index 0000000000..aaa4a0c4a1 --- /dev/null +++ b/MdePkg/Library/DxeHstiLib/HstiDxe.h @@ -0,0 +1,65 @@ +/** @file + + Copyright (c) 2015, Intel Corporation. All rights reserved.
+ 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 _HSTI_DXE_H_ +#define _HSTI_DXE_H_ + +#include +#include +#include +#include +#include +#include + +#include + +#include + +#define HSTI_AIP_PRIVATE_SIGNATURE SIGNATURE_32('H', 'S', 'T', 'I') + +typedef struct { + UINT32 Signature; + LIST_ENTRY Link; + EFI_ADAPTER_INFORMATION_PROTOCOL Aip; + VOID *Hsti; + UINTN HstiSize; + UINTN HstiMaxSize; +} HSTI_AIP_PRIVATE_DATA; + +#define HSTI_AIP_PRIVATE_DATA_FROM_THIS(a) \ + CR (a, \ + HSTI_AIP_PRIVATE_DATA, \ + Aip, \ + HSTI_AIP_PRIVATE_SIGNATURE \ + ) + +#define HSTI_DEFAULT_ERROR_STRING_LEN 255 + +extern EFI_ADAPTER_INFORMATION_PROTOCOL mAdapterInformationProtocol; + +/** + Return if input HSTI data follows HSTI specification. + + @param HstiData HSTI data + @param HstiSize HSTI size + + @retval TRUE HSTI data follows HSTI specification. + @retval FALSE HSTI data does not follow HSTI specification. +**/ +BOOLEAN +InternalHstiIsValidTable ( + IN VOID *HstiData, + IN UINTN HstiSize + ); + +#endif \ No newline at end of file diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec index 1eb4346e18..573277d51f 100644 --- a/MdePkg/MdePkg.dec +++ b/MdePkg/MdePkg.dec @@ -4,7 +4,7 @@ # It also provides the definitions(including PPIs/PROTOCOLs/GUIDs) of # EFI1.10/UEFI2.4/PI1.3 and some Industry Standards. # -# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.
+# Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.
# Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
# # This program and the accompanying materials are licensed and made available under @@ -626,6 +626,9 @@ ## Include/Guid/VectorHandoffTable.h gEfiVectorHandoffTableGuid = { 0x996ec11c, 0x5397, 0x4e73, { 0xb5, 0x8f, 0x82, 0x7e, 0x52, 0x90, 0x6d, 0xef }} + ## Include/IndustryStandard/Hsti.h + gAdapterInfoPlatformSecurityGuid = {0x6be272c7, 0x1320, 0x4ccd, { 0x90, 0x17, 0xd4, 0x61, 0x2c, 0x01, 0x2b, 0x25 }} + [Guids.IA32, Guids.X64] ## Include/Guid/Cper.h gEfiIa32X64ErrorTypeCacheCheckGuid = { 0xA55701F5, 0xE3EF, 0x43de, { 0xAC, 0x72, 0x24, 0x9B, 0x57, 0x3F, 0xAD, 0x2C }} diff --git a/MdePkg/MdePkg.dsc b/MdePkg/MdePkg.dsc index 14a339cd49..6e527f4e0d 100644 --- a/MdePkg/MdePkg.dsc +++ b/MdePkg/MdePkg.dsc @@ -1,7 +1,7 @@ ## @file # EFI/PI MdePkg Package # -# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.
+# Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.
# Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
# # This program and the accompanying materials @@ -91,6 +91,7 @@ MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf MdePkg/Library/DxeSmbusLib/DxeSmbusLib.inf MdePkg/Library/DxeIoLibCpuIo2/DxeIoLibCpuIo2.inf + MdePkg/Library/DxeHstiLib/DxeHstiLib.inf MdePkg/Library/DxeRuntimePciExpressLib/DxeRuntimePciExpressLib.inf -- 2.39.2