+/** @file\r
+\r
+ Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
+ This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "HstiDxe.h"\r
+\r
+/**\r
+ Find HSTI table in AIP protocol, and return the data.\r
+ This API will return the HSTI table with indicated Role and ImplementationID,\r
+ NULL ImplementationID means to find the first HSTI table with indicated Role.\r
+\r
+ @param Role Role of HSTI data.\r
+ @param ImplementationID ImplementationID of HSTI data.\r
+ NULL means find the first one match Role.\r
+ @param HstiData HSTI data. This buffer is allocated by callee, and it\r
+ is the responsibility of the caller to free it after\r
+ using it.\r
+ @param HstiSize HSTI size\r
+\r
+ @return Aip The AIP protocol having this HSTI.\r
+ @return NULL There is not HSTI table with the Role and ImplementationID published in system.\r
+**/\r
+VOID *\r
+InternalHstiFindAip (\r
+ IN UINT32 Role,\r
+ IN CHAR16 *ImplementationID OPTIONAL,\r
+ OUT VOID **HstiData OPTIONAL,\r
+ OUT UINTN *HstiSize OPTIONAL\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_ADAPTER_INFORMATION_PROTOCOL *Aip;\r
+ UINTN NoHandles;\r
+ EFI_HANDLE *Handles;\r
+ UINTN Index;\r
+ EFI_GUID *InfoTypesBuffer;\r
+ UINTN InfoTypesBufferCount;\r
+ UINTN InfoTypesIndex;\r
+ EFI_ADAPTER_INFORMATION_PROTOCOL *AipCandidate;\r
+ VOID *InformationBlock;\r
+ UINTN InformationBlockSize;\r
+ ADAPTER_INFO_PLATFORM_SECURITY *Hsti;\r
+\r
+ Status = gBS->LocateHandleBuffer (\r
+ ByProtocol,\r
+ &gEfiAdapterInformationProtocolGuid,\r
+ NULL,\r
+ &NoHandles,\r
+ &Handles\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return NULL;\r
+ }\r
+\r
+ Hsti = NULL;\r
+ Aip = NULL;\r
+ InformationBlock = NULL;\r
+ InformationBlockSize = 0;\r
+ for (Index = 0; Index < NoHandles; Index++) {\r
+ Status = gBS->HandleProtocol (\r
+ Handles[Index],\r
+ &gEfiAdapterInformationProtocolGuid,\r
+ (VOID **)&Aip\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // Check AIP\r
+ //\r
+ Status = Aip->GetSupportedTypes (\r
+ Aip,\r
+ &InfoTypesBuffer,\r
+ &InfoTypesBufferCount\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ continue;\r
+ }\r
+\r
+ AipCandidate = NULL;\r
+ for (InfoTypesIndex = 0; InfoTypesIndex < InfoTypesBufferCount; InfoTypesIndex++) {\r
+ if (CompareGuid (&InfoTypesBuffer[InfoTypesIndex], &gAdapterInfoPlatformSecurityGuid)) {\r
+ AipCandidate = Aip;\r
+ break;\r
+ }\r
+ }\r
+ FreePool (InfoTypesBuffer);\r
+\r
+ if (AipCandidate == NULL) {\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // Check HSTI Role\r
+ //\r
+ Aip = AipCandidate;\r
+ Status = Aip->GetInformation (\r
+ Aip,\r
+ &gAdapterInfoPlatformSecurityGuid,\r
+ &InformationBlock,\r
+ &InformationBlockSize\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ continue;\r
+ }\r
+\r
+ Hsti = InformationBlock;\r
+ if ((Hsti->Role == Role) && \r
+ ((ImplementationID == NULL) || (StrCmp (ImplementationID, Hsti->ImplementationID) == 0))) {\r
+ break;\r
+ } else {\r
+ Hsti = NULL;\r
+ FreePool (InformationBlock);\r
+ continue;\r
+ }\r
+ }\r
+ FreePool (Handles);\r
+\r
+ if (Hsti == NULL) {\r
+ return NULL;\r
+ }\r
+\r
+ if (HstiData != NULL) {\r
+ *HstiData = InformationBlock;\r
+ }\r
+ if (HstiSize != NULL) {\r
+ *HstiSize = InformationBlockSize;\r
+ }\r
+ return Aip;\r
+}\r
+\r
+/**\r
+ Return if input HSTI data follows HSTI specification.\r
+\r
+ @param HstiData HSTI data\r
+ @param HstiSize HSTI size\r
+\r
+ @retval TRUE HSTI data follows HSTI specification.\r
+ @retval FALSE HSTI data does not follow HSTI specification.\r
+**/\r
+BOOLEAN\r
+InternalHstiIsValidTable (\r
+ IN VOID *HstiData,\r
+ IN UINTN HstiSize\r
+ )\r
+{\r
+ ADAPTER_INFO_PLATFORM_SECURITY *Hsti;\r
+ UINTN Index;\r
+ CHAR16 *ErrorString;\r
+ CHAR16 ErrorChar;\r
+ UINTN ErrorStringSize;\r
+ UINTN ErrorStringLength;\r
+\r
+ Hsti = HstiData;\r
+\r
+ //\r
+ // basic check for header\r
+ //\r
+ if (HstiData == NULL) {\r
+ DEBUG ((EFI_D_ERROR, "HstiData == NULL\n"));\r
+ return FALSE;\r
+ }\r
+ if (HstiSize < sizeof(ADAPTER_INFO_PLATFORM_SECURITY)) {\r
+ DEBUG ((EFI_D_ERROR, "HstiSize < sizeof(ADAPTER_INFO_PLATFORM_SECURITY)\n"));\r
+ return FALSE;\r
+ }\r
+ if (((HstiSize - sizeof(ADAPTER_INFO_PLATFORM_SECURITY)) / 3) < Hsti->SecurityFeaturesSize) {\r
+ DEBUG ((EFI_D_ERROR, "((HstiSize - sizeof(ADAPTER_INFO_PLATFORM_SECURITY)) / 3) < SecurityFeaturesSize\n"));\r
+ return FALSE;\r
+ }\r
+\r
+ //\r
+ // Check Version\r
+ //\r
+ if (Hsti->Version != PLATFORM_SECURITY_VERSION_VNEXTCS) {\r
+ DEBUG ((EFI_D_ERROR, "Version != PLATFORM_SECURITY_VERSION_VNEXTCS\n"));\r
+ return FALSE;\r
+ }\r
+\r
+ //\r
+ // Check Role\r
+ //\r
+ if ((Hsti->Role < PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE) ||\r
+ (Hsti->Role > PLATFORM_SECURITY_ROLE_IMPLEMENTOR_ODM)) {\r
+ DEBUG ((EFI_D_ERROR, "Role < PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE ||\n"));\r
+ DEBUG ((EFI_D_ERROR, "Role > PLATFORM_SECURITY_ROLE_IMPLEMENTOR_ODM\n"));\r
+ return FALSE;\r
+ }\r
+\r
+ //\r
+ // Check ImplementationID\r
+ //\r
+ for (Index = 0; Index < sizeof(Hsti->ImplementationID); Index++) {\r
+ if (Hsti->ImplementationID[Index] == 0) {\r
+ break;\r
+ }\r
+ }\r
+ if (Index == sizeof(Hsti->ImplementationID)) {\r
+ DEBUG ((EFI_D_ERROR, "ImplementationID is no NUL CHAR\n"));\r
+ return FALSE;\r
+ }\r
+\r
+ ErrorStringSize = HstiSize - sizeof(ADAPTER_INFO_PLATFORM_SECURITY) - Hsti->SecurityFeaturesSize * 3;\r
+ ErrorString = (CHAR16 *)((UINTN)Hsti + sizeof(ADAPTER_INFO_PLATFORM_SECURITY) - Hsti->SecurityFeaturesSize * 3);\r
+\r
+ //\r
+ // basic check for ErrorString\r
+ //\r
+ if (ErrorStringSize == 0) {\r
+ DEBUG ((EFI_D_ERROR, "ErrorStringSize == 0\n"));\r
+ return FALSE;\r
+ }\r
+ if ((ErrorStringSize & BIT0) != 0) {\r
+ DEBUG ((EFI_D_ERROR, "(ErrorStringSize & BIT0) != 0\n"));\r
+ return FALSE;\r
+ }\r
+\r
+ //\r
+ // ErrorString might not be CHAR16 aligned.\r
+ //\r
+ CopyMem (&ErrorChar, ErrorString, sizeof(ErrorChar));\r
+ for (ErrorStringLength = 0; (ErrorChar != 0) && (ErrorStringLength < (ErrorStringSize/2)); ErrorStringLength++) {\r
+ ErrorString++;\r
+ CopyMem (&ErrorChar, ErrorString, sizeof(ErrorChar));\r
+ }\r
+\r
+ //\r
+ // check the length of ErrorString\r
+ //\r
+ if (ErrorChar != 0) {\r
+ DEBUG ((EFI_D_ERROR, "ErrorString has no NUL CHAR\n"));\r
+ return FALSE;\r
+ }\r
+ if (ErrorStringLength == (ErrorStringSize/2)) {\r
+ DEBUG ((EFI_D_ERROR, "ErrorString Length incorrect\n"));\r
+ return FALSE;\r
+ }\r
+\r
+ return TRUE;\r
+}\r
+\r
+/**\r
+ Publish HSTI table in AIP protocol.\r
+\r
+ One system should have only one PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE.\r
+\r
+ If the Role is NOT PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE,\r
+ SecurityFeaturesRequired field will be ignored.\r
+\r
+ @param Hsti HSTI data\r
+ @param HstiSize HSTI size\r
+\r
+ @retval EFI_SUCCESS The HSTI data is published in AIP protocol.\r
+ @retval EFI_ALREADY_STARTED There is already HSTI table with Role and ImplementationID published in system.\r
+ @retval EFI_VOLUME_CORRUPTED The input HSTI data does not follow HSTI specification.\r
+ @retval EFI_OUT_OF_RESOURCES There is not enough system resource to publish HSTI data in AIP protocol.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+HstiLibSetTable (\r
+ IN VOID *Hsti,\r
+ IN UINTN HstiSize\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_HANDLE Handle;\r
+ HSTI_AIP_PRIVATE_DATA *HstiAip;\r
+ EFI_ADAPTER_INFORMATION_PROTOCOL *Aip;\r
+ UINT32 Role;\r
+ CHAR16 *ImplementationID;\r
+ UINT32 SecurityFeaturesSize;\r
+ UINT8 *SecurityFeaturesRequired;\r
+\r
+ if (!InternalHstiIsValidTable (Hsti, HstiSize)) {\r
+ return EFI_VOLUME_CORRUPTED;\r
+ }\r
+\r
+ Role = ((ADAPTER_INFO_PLATFORM_SECURITY *)Hsti)->Role;\r
+ ImplementationID = ((ADAPTER_INFO_PLATFORM_SECURITY *)Hsti)->ImplementationID;\r
+ Aip = InternalHstiFindAip (Role, ImplementationID, NULL, NULL);\r
+ if (Aip != NULL) {\r
+ return EFI_ALREADY_STARTED;\r
+ }\r
+\r
+ HstiAip = AllocateZeroPool (sizeof(HSTI_AIP_PRIVATE_DATA));\r
+ if (HstiAip == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ HstiAip->Hsti = AllocateCopyPool (HstiSize, Hsti);\r
+ if (HstiAip == NULL) {\r
+ FreePool (HstiAip);\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ if (Role != PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE) {\r
+ SecurityFeaturesRequired = (UINT8 *)HstiAip->Hsti + sizeof(ADAPTER_INFO_PLATFORM_SECURITY);\r
+ SecurityFeaturesSize = ((ADAPTER_INFO_PLATFORM_SECURITY *)Hsti)->SecurityFeaturesSize;\r
+ ZeroMem (SecurityFeaturesRequired, SecurityFeaturesSize);\r
+ }\r
+\r
+ HstiAip->Signature = HSTI_AIP_PRIVATE_SIGNATURE;\r
+ CopyMem (&HstiAip->Aip, &mAdapterInformationProtocol, sizeof(EFI_ADAPTER_INFORMATION_PROTOCOL));\r
+ HstiAip->HstiSize = HstiSize;\r
+ HstiAip->HstiMaxSize = HstiSize;\r
+ \r
+ Handle = NULL;\r
+ Status = gBS->InstallMultipleProtocolInterfaces (\r
+ &Handle,\r
+ &gEfiAdapterInformationProtocolGuid,\r
+ &HstiAip->Aip,\r
+ NULL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ FreePool (HstiAip->Hsti);\r
+ FreePool (HstiAip);\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Search HSTI table in AIP protocol, and return the data.\r
+ This API will return the HSTI table with indicated Role and ImplementationID,\r
+ NULL ImplementationID means to find the first HSTI table with indicated Role.\r
+\r
+ @param Role Role of HSTI data.\r
+ @param ImplementationID ImplementationID of HSTI data.\r
+ NULL means find the first one match Role.\r
+ @param Hsti HSTI data. This buffer is allocated by callee, and it\r
+ is the responsibility of the caller to free it after\r
+ using it.\r
+ @param HstiSize HSTI size\r
+\r
+ @retval EFI_SUCCESS The HSTI data in AIP protocol is returned.\r
+ @retval EFI_NOT_FOUND There is not HSTI table with the Role and ImplementationID published in system.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+HstiLibGetTable (\r
+ IN UINT32 Role,\r
+ IN CHAR16 *ImplementationID OPTIONAL,\r
+ OUT VOID **Hsti,\r
+ OUT UINTN *HstiSize\r
+ )\r
+{\r
+ EFI_ADAPTER_INFORMATION_PROTOCOL *Aip;\r
+\r
+ Aip = InternalHstiFindAip (Role, ImplementationID, Hsti, HstiSize);\r
+ if (Aip == NULL) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Record FeaturesVerified in published HSTI table.\r
+ This API will update the HSTI table with indicated Role and ImplementationID,\r
+ NULL ImplementationID means to find the first HSTI table with indicated Role.\r
+\r
+ @param Role Role of HSTI data.\r
+ @param ImplementationID ImplementationID of HSTI data.\r
+ NULL means find the first one match Role.\r
+ @param ByteIndex Byte index of FeaturesVerified of HSTI data.\r
+ @param BitMask Bit mask of FeaturesVerified of HSTI data.\r
+ @param Set TRUE means to set the FeaturesVerified bit.\r
+ FALSE means to clear the FeaturesVerified bit.\r
+\r
+ @retval EFI_SUCCESS The FeaturesVerified of HSTI data updated in AIP protocol.\r
+ @retval EFI_NOT_STARTED There is not HSTI table with the Role and ImplementationID published in system.\r
+ @retval EFI_UNSUPPORTED The ByteIndex is invalid.\r
+**/\r
+EFI_STATUS\r
+InternalHstiRecordFeaturesVerified (\r
+ IN UINT32 Role,\r
+ IN CHAR16 *ImplementationID, OPTIONAL\r
+ IN UINT32 ByteIndex,\r
+ IN UINT8 Bit,\r
+ IN BOOLEAN Set\r
+ )\r
+{\r
+ EFI_ADAPTER_INFORMATION_PROTOCOL *Aip;\r
+ ADAPTER_INFO_PLATFORM_SECURITY *Hsti;\r
+ UINTN HstiSize;\r
+ UINT8 *SecurityFeaturesVerified;\r
+ EFI_STATUS Status;\r
+\r
+ Aip = InternalHstiFindAip (Role, ImplementationID, &Hsti, &HstiSize);\r
+ if (Aip == NULL) {\r
+ return EFI_NOT_STARTED;\r
+ }\r
+\r
+ if (ByteIndex >= Hsti->SecurityFeaturesSize) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ SecurityFeaturesVerified = (UINT8 *)((UINTN)Hsti + sizeof(ADAPTER_INFO_PLATFORM_SECURITY) + Hsti->SecurityFeaturesSize * 2);\r
+\r
+ if (Set) {\r
+ SecurityFeaturesVerified[ByteIndex] = (UINT8)(SecurityFeaturesVerified[ByteIndex] | (Bit));\r
+ } else {\r
+ SecurityFeaturesVerified[ByteIndex] = (UINT8)(SecurityFeaturesVerified[ByteIndex] & (~Bit));\r
+ }\r
+\r
+ Status = Aip->SetInformation (\r
+ Aip,\r
+ &gAdapterInfoPlatformSecurityGuid,\r
+ Hsti,\r
+ HstiSize\r
+ );\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Set FeaturesVerified in published HSTI table.\r
+ This API will update the HSTI table with indicated Role and ImplementationID,\r
+ NULL ImplementationID means to find the first HSTI table with indicated Role.\r
+\r
+ @param Role Role of HSTI data.\r
+ @param ImplementationID ImplementationID of HSTI data.\r
+ NULL means find the first one match Role.\r
+ @param ByteIndex Byte index of FeaturesVerified of HSTI data.\r
+ @param BitMask Bit mask of FeaturesVerified of HSTI data.\r
+\r
+ @retval EFI_SUCCESS The FeaturesVerified of HSTI data updated in AIP protocol.\r
+ @retval EFI_NOT_STARTED There is not HSTI table with the Role and ImplementationID published in system.\r
+ @retval EFI_UNSUPPORTED The ByteIndex is invalid.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+HstiLibSetFeaturesVerified (\r
+ IN UINT32 Role,\r
+ IN CHAR16 *ImplementationID, OPTIONAL\r
+ IN UINT32 ByteIndex,\r
+ IN UINT8 BitMask\r
+ )\r
+{\r
+ return InternalHstiRecordFeaturesVerified (\r
+ Role,\r
+ ImplementationID,\r
+ ByteIndex,\r
+ BitMask,\r
+ TRUE\r
+ );\r
+}\r
+\r
+/**\r
+ Clear FeaturesVerified in published HSTI table.\r
+ This API will update the HSTI table with indicated Role and ImplementationID,\r
+ NULL ImplementationID means to find the first HSTI table with indicated Role.\r
+\r
+ @param Role Role of HSTI data.\r
+ @param ImplementationID ImplementationID of HSTI data.\r
+ NULL means find the first one match Role.\r
+ @param ByteIndex Byte index of FeaturesVerified of HSTI data.\r
+ @param BitMask Bit mask of FeaturesVerified of HSTI data.\r
+\r
+ @retval EFI_SUCCESS The FeaturesVerified of HSTI data updated in AIP protocol.\r
+ @retval EFI_NOT_STARTED There is not HSTI table with the Role and ImplementationID published in system.\r
+ @retval EFI_UNSUPPORTED The ByteIndex is invalid.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+HstiLibClearFeaturesVerified (\r
+ IN UINT32 Role,\r
+ IN CHAR16 *ImplementationID, OPTIONAL\r
+ IN UINT32 ByteIndex,\r
+ IN UINT8 BitMask\r
+ )\r
+{\r
+ return InternalHstiRecordFeaturesVerified (\r
+ Role,\r
+ ImplementationID,\r
+ ByteIndex,\r
+ BitMask,\r
+ FALSE\r
+ );\r
+}\r
+\r
+/**\r
+ Record ErrorString in published HSTI table.\r
+ This API will update the HSTI table with indicated Role and ImplementationID,\r
+ NULL ImplementationID means to find the first HSTI table with indicated Role.\r
+\r
+ @param Role Role of HSTI data.\r
+ @param ImplementationID ImplementationID of HSTI data.\r
+ NULL means find the first one match Role.\r
+ @param ErrorString ErrorString of HSTI data.\r
+ @param Append TRUE means to append the ErrorString to HSTI table.\r
+ FALSE means to set the ErrorString in HSTI table.\r
+\r
+ @retval EFI_SUCCESS The ErrorString of HSTI data is published in AIP protocol.\r
+ @retval EFI_NOT_STARTED There is not HSTI table with the Role and ImplementationID published in system.\r
+ @retval EFI_OUT_OF_RESOURCES There is not enough system resource to update ErrorString.\r
+**/\r
+EFI_STATUS\r
+InternalHstiRecordErrorString (\r
+ IN UINT32 Role,\r
+ IN CHAR16 *ImplementationID, OPTIONAL\r
+ IN CHAR16 *ErrorString,\r
+ IN BOOLEAN Append\r
+ )\r
+{\r
+ EFI_ADAPTER_INFORMATION_PROTOCOL *Aip;\r
+ ADAPTER_INFO_PLATFORM_SECURITY *Hsti;\r
+ UINTN HstiSize;\r
+ UINTN StringSize;\r
+ VOID *NewHsti;\r
+ UINTN NewHstiSize;\r
+ UINTN Offset;\r
+ EFI_STATUS Status;\r
+\r
+ Aip = InternalHstiFindAip (Role, ImplementationID, &Hsti, &HstiSize);\r
+ if (Aip == NULL) {\r
+ return EFI_NOT_STARTED;\r
+ }\r
+\r
+ if (Append) {\r
+ Offset = HstiSize - sizeof(CHAR16);\r
+ } else {\r
+ Offset = sizeof(ADAPTER_INFO_PLATFORM_SECURITY) + Hsti->SecurityFeaturesSize * 3;\r
+ }\r
+ StringSize = StrSize (ErrorString);\r
+\r
+ NewHstiSize = Offset + StringSize;\r
+ NewHsti = AllocatePool (NewHstiSize);\r
+ if (NewHsti == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ CopyMem (NewHsti, Hsti, Offset);\r
+ CopyMem ((UINT8 *)NewHsti + Offset, ErrorString, StringSize);\r
+\r
+ Status = Aip->SetInformation (\r
+ Aip,\r
+ &gAdapterInfoPlatformSecurityGuid,\r
+ NewHsti,\r
+ NewHstiSize\r
+ );\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Append ErrorString in published HSTI table.\r
+ This API will update the HSTI table with indicated Role and ImplementationID,\r
+ NULL ImplementationID means to find the first HSTI table with indicated Role.\r
+\r
+ @param Role Role of HSTI data.\r
+ @param ImplementationID ImplementationID of HSTI data.\r
+ NULL means find the first one match Role.\r
+ @param ErrorString ErrorString of HSTI data.\r
+\r
+ @retval EFI_SUCCESS The ErrorString of HSTI data is updated in AIP protocol.\r
+ @retval EFI_NOT_STARTED There is not HSTI table with the Role and ImplementationID published in system.\r
+ @retval EFI_OUT_OF_RESOURCES There is not enough system resource to update ErrorString.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+HstiLibAppendErrorString (\r
+ IN UINT32 Role,\r
+ IN CHAR16 *ImplementationID, OPTIONAL\r
+ IN CHAR16 *ErrorString\r
+ )\r
+{\r
+ return InternalHstiRecordErrorString (\r
+ Role,\r
+ ImplementationID,\r
+ ErrorString,\r
+ TRUE\r
+ );\r
+}\r
+\r
+/**\r
+ Set a new ErrorString in published HSTI table.\r
+ This API will update the HSTI table with indicated Role and ImplementationID,\r
+ NULL ImplementationID means to find the first HSTI table with indicated Role.\r
+\r
+ @param Role Role of HSTI data.\r
+ @param ImplementationID ImplementationID of HSTI data.\r
+ NULL means find the first one match Role.\r
+ @param ErrorString ErrorString of HSTI data.\r
+\r
+ @retval EFI_SUCCESS The ErrorString of HSTI data is updated in AIP protocol.\r
+ @retval EFI_NOT_STARTED There is not HSTI table with the Role and ImplementationID published in system.\r
+ @retval EFI_OUT_OF_RESOURCES There is not enough system resource to update ErrorString.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+HstiLibSetErrorString (\r
+ IN UINT32 Role,\r
+ IN CHAR16 *ImplementationID, OPTIONAL\r
+ IN CHAR16 *ErrorString\r
+ )\r
+{\r
+ return InternalHstiRecordErrorString (\r
+ Role,\r
+ ImplementationID,\r
+ ErrorString,\r
+ FALSE\r
+ );\r
+}\r