Home | History | Annotate | Download | only in DxeHstiLib
      1 /** @file
      2 
      3   Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
      4   This program and the accompanying materials
      5   are licensed and made available under the terms and conditions of the BSD License
      6   which accompanies this distribution.  The full text of the license may be found at
      7   http://opensource.org/licenses/bsd-license.php
      8 
      9   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     10   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     11 
     12 **/
     13 
     14 #include "HstiDxe.h"
     15 
     16 /**
     17   Find HSTI table in AIP protocol, and return the data.
     18   This API will return the HSTI table with indicated Role and ImplementationID,
     19   NULL ImplementationID means to find the first HSTI table with indicated Role.
     20 
     21   @param Role             Role of HSTI data.
     22   @param ImplementationID ImplementationID of HSTI data.
     23                           NULL means find the first one match Role.
     24   @param HstiData         HSTI data. This buffer is allocated by callee, and it
     25                           is the responsibility of the caller to free it after
     26                           using it.
     27   @param HstiSize         HSTI size
     28 
     29   @return Aip             The AIP protocol having this HSTI.
     30   @return NULL            There is not HSTI table with the Role and ImplementationID published in system.
     31 **/
     32 VOID *
     33 InternalHstiFindAip (
     34   IN UINT32                   Role,
     35   IN CHAR16                   *ImplementationID OPTIONAL,
     36   OUT VOID                    **HstiData OPTIONAL,
     37   OUT UINTN                   *HstiSize OPTIONAL
     38   )
     39 {
     40   EFI_STATUS                        Status;
     41   EFI_ADAPTER_INFORMATION_PROTOCOL  *Aip;
     42   UINTN                             NoHandles;
     43   EFI_HANDLE                        *Handles;
     44   UINTN                             Index;
     45   EFI_GUID                          *InfoTypesBuffer;
     46   UINTN                             InfoTypesBufferCount;
     47   UINTN                             InfoTypesIndex;
     48   EFI_ADAPTER_INFORMATION_PROTOCOL  *AipCandidate;
     49   VOID                              *InformationBlock;
     50   UINTN                             InformationBlockSize;
     51   ADAPTER_INFO_PLATFORM_SECURITY    *Hsti;
     52 
     53   Status = gBS->LocateHandleBuffer (
     54                   ByProtocol,
     55                   &gEfiAdapterInformationProtocolGuid,
     56                   NULL,
     57                   &NoHandles,
     58                   &Handles
     59                   );
     60   if (EFI_ERROR (Status)) {
     61     return NULL;
     62   }
     63 
     64   Hsti = NULL;
     65   Aip = NULL;
     66   InformationBlock = NULL;
     67   InformationBlockSize = 0;
     68   for (Index = 0; Index < NoHandles; Index++) {
     69     Status = gBS->HandleProtocol (
     70                     Handles[Index],
     71                     &gEfiAdapterInformationProtocolGuid,
     72                     (VOID **)&Aip
     73                     );
     74     if (EFI_ERROR (Status)) {
     75       continue;
     76     }
     77 
     78     //
     79     // Check AIP
     80     //
     81     Status = Aip->GetSupportedTypes (
     82                     Aip,
     83                     &InfoTypesBuffer,
     84                     &InfoTypesBufferCount
     85                     );
     86     if (EFI_ERROR (Status)) {
     87       continue;
     88     }
     89 
     90     AipCandidate = NULL;
     91     for (InfoTypesIndex = 0; InfoTypesIndex < InfoTypesBufferCount; InfoTypesIndex++) {
     92       if (CompareGuid (&InfoTypesBuffer[InfoTypesIndex], &gAdapterInfoPlatformSecurityGuid)) {
     93         AipCandidate = Aip;
     94         break;
     95       }
     96     }
     97     FreePool (InfoTypesBuffer);
     98 
     99     if (AipCandidate == NULL) {
    100       continue;
    101     }
    102 
    103     //
    104     // Check HSTI Role
    105     //
    106     Aip = AipCandidate;
    107     Status = Aip->GetInformation (
    108                     Aip,
    109                     &gAdapterInfoPlatformSecurityGuid,
    110                     &InformationBlock,
    111                     &InformationBlockSize
    112                     );
    113     if (EFI_ERROR (Status)) {
    114       continue;
    115     }
    116 
    117     Hsti = InformationBlock;
    118     if ((Hsti->Role == Role) &&
    119         ((ImplementationID == NULL) || (StrCmp (ImplementationID, Hsti->ImplementationID) == 0))) {
    120       break;
    121     } else {
    122       Hsti = NULL;
    123       FreePool (InformationBlock);
    124       continue;
    125     }
    126   }
    127   FreePool (Handles);
    128 
    129   if (Hsti == NULL) {
    130     return NULL;
    131   }
    132 
    133   if (HstiData != NULL) {
    134     *HstiData = InformationBlock;
    135   }
    136   if (HstiSize != NULL) {
    137     *HstiSize = InformationBlockSize;
    138   }
    139   return Aip;
    140 }
    141 
    142 /**
    143   Return if input HSTI data follows HSTI specification.
    144 
    145   @param HstiData  HSTI data
    146   @param HstiSize  HSTI size
    147 
    148   @retval TRUE  HSTI data follows HSTI specification.
    149   @retval FALSE HSTI data does not follow HSTI specification.
    150 **/
    151 BOOLEAN
    152 InternalHstiIsValidTable (
    153   IN VOID                     *HstiData,
    154   IN UINTN                    HstiSize
    155   )
    156 {
    157   ADAPTER_INFO_PLATFORM_SECURITY  *Hsti;
    158   UINTN                           Index;
    159   CHAR16                          *ErrorString;
    160   CHAR16                          ErrorChar;
    161   UINTN                           ErrorStringSize;
    162   UINTN                           ErrorStringLength;
    163 
    164   Hsti = HstiData;
    165 
    166   //
    167   // basic check for header
    168   //
    169   if (HstiData == NULL) {
    170     DEBUG ((EFI_D_ERROR, "HstiData == NULL\n"));
    171     return FALSE;
    172   }
    173   if (HstiSize < sizeof(ADAPTER_INFO_PLATFORM_SECURITY)) {
    174     DEBUG ((EFI_D_ERROR, "HstiSize < sizeof(ADAPTER_INFO_PLATFORM_SECURITY)\n"));
    175     return FALSE;
    176   }
    177   if (((HstiSize - sizeof(ADAPTER_INFO_PLATFORM_SECURITY)) / 3) < Hsti->SecurityFeaturesSize) {
    178     DEBUG ((EFI_D_ERROR, "((HstiSize - sizeof(ADAPTER_INFO_PLATFORM_SECURITY)) / 3) < SecurityFeaturesSize\n"));
    179     return FALSE;
    180   }
    181 
    182   //
    183   // Check Version
    184   //
    185   if (Hsti->Version != PLATFORM_SECURITY_VERSION_VNEXTCS) {
    186     DEBUG ((EFI_D_ERROR, "Version != PLATFORM_SECURITY_VERSION_VNEXTCS\n"));
    187     return FALSE;
    188   }
    189 
    190   //
    191   // Check Role
    192   //
    193   if ((Hsti->Role < PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE) ||
    194       (Hsti->Role > PLATFORM_SECURITY_ROLE_IMPLEMENTOR_ODM)) {
    195     DEBUG ((EFI_D_ERROR, "Role < PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE ||\n"));
    196     DEBUG ((EFI_D_ERROR, "Role > PLATFORM_SECURITY_ROLE_IMPLEMENTOR_ODM\n"));
    197     return FALSE;
    198   }
    199 
    200   //
    201   // Check ImplementationID
    202   //
    203   for (Index = 0; Index < sizeof(Hsti->ImplementationID)/sizeof(Hsti->ImplementationID[0]); Index++) {
    204     if (Hsti->ImplementationID[Index] == 0) {
    205       break;
    206     }
    207   }
    208   if (Index == sizeof(Hsti->ImplementationID)/sizeof(Hsti->ImplementationID[0])) {
    209     DEBUG ((EFI_D_ERROR, "ImplementationID is no NUL CHAR\n"));
    210     return FALSE;
    211   }
    212 
    213   ErrorStringSize = HstiSize - sizeof(ADAPTER_INFO_PLATFORM_SECURITY) - Hsti->SecurityFeaturesSize * 3;
    214   ErrorString = (CHAR16 *)((UINTN)Hsti + sizeof(ADAPTER_INFO_PLATFORM_SECURITY) - Hsti->SecurityFeaturesSize * 3);
    215 
    216   //
    217   // basic check for ErrorString
    218   //
    219   if (ErrorStringSize == 0) {
    220     DEBUG ((EFI_D_ERROR, "ErrorStringSize == 0\n"));
    221     return FALSE;
    222   }
    223   if ((ErrorStringSize & BIT0) != 0) {
    224     DEBUG ((EFI_D_ERROR, "(ErrorStringSize & BIT0) != 0\n"));
    225     return FALSE;
    226   }
    227 
    228   //
    229   // ErrorString might not be CHAR16 aligned.
    230   //
    231   CopyMem (&ErrorChar, ErrorString, sizeof(ErrorChar));
    232   for (ErrorStringLength = 0; (ErrorChar != 0) && (ErrorStringLength < (ErrorStringSize/2)); ErrorStringLength++) {
    233     ErrorString++;
    234     CopyMem (&ErrorChar, ErrorString, sizeof(ErrorChar));
    235   }
    236 
    237   //
    238   // check the length of ErrorString
    239   //
    240   if (ErrorChar != 0) {
    241     DEBUG ((EFI_D_ERROR, "ErrorString has no NUL CHAR\n"));
    242     return FALSE;
    243   }
    244   if (ErrorStringLength == (ErrorStringSize/2)) {
    245     DEBUG ((EFI_D_ERROR, "ErrorString Length incorrect\n"));
    246     return FALSE;
    247   }
    248 
    249   return TRUE;
    250 }
    251 
    252 /**
    253   Publish HSTI table in AIP protocol.
    254 
    255   One system should have only one PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE.
    256 
    257   If the Role is NOT PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE,
    258   SecurityFeaturesRequired field will be ignored.
    259 
    260   @param Hsti      HSTI data
    261   @param HstiSize  HSTI size
    262 
    263   @retval EFI_SUCCESS          The HSTI data is published in AIP protocol.
    264   @retval EFI_ALREADY_STARTED  There is already HSTI table with Role and ImplementationID published in system.
    265   @retval EFI_VOLUME_CORRUPTED The input HSTI data does not follow HSTI specification.
    266   @retval EFI_OUT_OF_RESOURCES There is not enough system resource to publish HSTI data in AIP protocol.
    267 **/
    268 EFI_STATUS
    269 EFIAPI
    270 HstiLibSetTable (
    271   IN VOID                     *Hsti,
    272   IN UINTN                    HstiSize
    273   )
    274 {
    275   EFI_STATUS                       Status;
    276   EFI_HANDLE                       Handle;
    277   HSTI_AIP_PRIVATE_DATA            *HstiAip;
    278   EFI_ADAPTER_INFORMATION_PROTOCOL *Aip;
    279   UINT32                           Role;
    280   CHAR16                           *ImplementationID;
    281   UINT32                           SecurityFeaturesSize;
    282   UINT8                            *SecurityFeaturesRequired;
    283 
    284   if (!InternalHstiIsValidTable (Hsti, HstiSize)) {
    285     return EFI_VOLUME_CORRUPTED;
    286   }
    287 
    288   Role = ((ADAPTER_INFO_PLATFORM_SECURITY *)Hsti)->Role;
    289   ImplementationID = ((ADAPTER_INFO_PLATFORM_SECURITY *)Hsti)->ImplementationID;
    290   Aip = InternalHstiFindAip (Role, ImplementationID, NULL, NULL);
    291   if (Aip != NULL) {
    292     return EFI_ALREADY_STARTED;
    293   }
    294 
    295   HstiAip = AllocateZeroPool (sizeof(HSTI_AIP_PRIVATE_DATA));
    296   if (HstiAip == NULL) {
    297     return EFI_OUT_OF_RESOURCES;
    298   }
    299   HstiAip->Hsti = AllocateCopyPool (HstiSize, Hsti);
    300   if (HstiAip->Hsti == NULL) {
    301     FreePool (HstiAip);
    302     return EFI_OUT_OF_RESOURCES;
    303   }
    304   if (Role != PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE) {
    305     SecurityFeaturesRequired = (UINT8 *)HstiAip->Hsti + sizeof(ADAPTER_INFO_PLATFORM_SECURITY);
    306     SecurityFeaturesSize = ((ADAPTER_INFO_PLATFORM_SECURITY *)Hsti)->SecurityFeaturesSize;
    307     ZeroMem (SecurityFeaturesRequired, SecurityFeaturesSize);
    308   }
    309 
    310   HstiAip->Signature = HSTI_AIP_PRIVATE_SIGNATURE;
    311   CopyMem (&HstiAip->Aip, &mAdapterInformationProtocol, sizeof(EFI_ADAPTER_INFORMATION_PROTOCOL));
    312   HstiAip->HstiSize = HstiSize;
    313   HstiAip->HstiMaxSize = HstiSize;
    314 
    315   Handle = NULL;
    316   Status = gBS->InstallMultipleProtocolInterfaces (
    317                   &Handle,
    318                   &gEfiAdapterInformationProtocolGuid,
    319                   &HstiAip->Aip,
    320                   NULL
    321                   );
    322   if (EFI_ERROR (Status)) {
    323     FreePool (HstiAip->Hsti);
    324     FreePool (HstiAip);
    325   }
    326 
    327   return Status;
    328 }
    329 
    330 /**
    331   Search HSTI table in AIP protocol, and return the data.
    332   This API will return the HSTI table with indicated Role and ImplementationID,
    333   NULL ImplementationID means to find the first HSTI table with indicated Role.
    334 
    335   @param Role             Role of HSTI data.
    336   @param ImplementationID ImplementationID of HSTI data.
    337                           NULL means find the first one match Role.
    338   @param Hsti             HSTI data. This buffer is allocated by callee, and it
    339                           is the responsibility of the caller to free it after
    340                           using it.
    341   @param HstiSize         HSTI size
    342 
    343   @retval EFI_SUCCESS          The HSTI data in AIP protocol is returned.
    344   @retval EFI_NOT_FOUND        There is not HSTI table with the Role and ImplementationID published in system.
    345 **/
    346 EFI_STATUS
    347 EFIAPI
    348 HstiLibGetTable (
    349   IN UINT32                   Role,
    350   IN CHAR16                   *ImplementationID OPTIONAL,
    351   OUT VOID                    **Hsti,
    352   OUT UINTN                   *HstiSize
    353   )
    354 {
    355   EFI_ADAPTER_INFORMATION_PROTOCOL *Aip;
    356 
    357   Aip = InternalHstiFindAip (Role, ImplementationID, Hsti, HstiSize);
    358   if (Aip == NULL) {
    359     return EFI_NOT_FOUND;
    360   }
    361   return EFI_SUCCESS;
    362 }
    363 
    364 /**
    365   Record FeaturesVerified in published HSTI table.
    366   This API will update the HSTI table with indicated Role and ImplementationID,
    367   NULL ImplementationID means to find the first HSTI table with indicated Role.
    368 
    369   @param Role             Role of HSTI data.
    370   @param ImplementationID ImplementationID of HSTI data.
    371                           NULL means find the first one match Role.
    372   @param ByteIndex        Byte index of FeaturesVerified of HSTI data.
    373   @param BitMask          Bit mask of FeaturesVerified of HSTI data.
    374   @param Set              TRUE means to set the FeaturesVerified bit.
    375                           FALSE means to clear the FeaturesVerified bit.
    376 
    377   @retval EFI_SUCCESS          The FeaturesVerified of HSTI data updated in AIP protocol.
    378   @retval EFI_NOT_STARTED      There is not HSTI table with the Role and ImplementationID published in system.
    379   @retval EFI_UNSUPPORTED      The ByteIndex is invalid.
    380 **/
    381 EFI_STATUS
    382 InternalHstiRecordFeaturesVerified (
    383   IN UINT32                   Role,
    384   IN CHAR16                   *ImplementationID, OPTIONAL
    385   IN UINT32                   ByteIndex,
    386   IN UINT8                    Bit,
    387   IN BOOLEAN                  Set
    388   )
    389 {
    390   EFI_ADAPTER_INFORMATION_PROTOCOL *Aip;
    391   ADAPTER_INFO_PLATFORM_SECURITY   *Hsti;
    392   UINTN                            HstiSize;
    393   UINT8                            *SecurityFeaturesVerified;
    394   EFI_STATUS                       Status;
    395 
    396   Aip = InternalHstiFindAip (Role, ImplementationID, (VOID **)&Hsti, &HstiSize);
    397   if (Aip == NULL) {
    398     return EFI_NOT_STARTED;
    399   }
    400 
    401   if (ByteIndex >= Hsti->SecurityFeaturesSize) {
    402     return EFI_UNSUPPORTED;
    403   }
    404 
    405   SecurityFeaturesVerified = (UINT8 *)((UINTN)Hsti + sizeof(ADAPTER_INFO_PLATFORM_SECURITY) + Hsti->SecurityFeaturesSize * 2);
    406 
    407   if (Set) {
    408     SecurityFeaturesVerified[ByteIndex] = (UINT8)(SecurityFeaturesVerified[ByteIndex] | (Bit));
    409   } else {
    410     SecurityFeaturesVerified[ByteIndex] = (UINT8)(SecurityFeaturesVerified[ByteIndex] & (~Bit));
    411   }
    412 
    413   Status = Aip->SetInformation (
    414                   Aip,
    415                   &gAdapterInfoPlatformSecurityGuid,
    416                   Hsti,
    417                   HstiSize
    418                   );
    419   return Status;
    420 }
    421 
    422 /**
    423   Set FeaturesVerified in published HSTI table.
    424   This API will update the HSTI table with indicated Role and ImplementationID,
    425   NULL ImplementationID means to find the first HSTI table with indicated Role.
    426 
    427   @param Role             Role of HSTI data.
    428   @param ImplementationID ImplementationID of HSTI data.
    429                           NULL means find the first one match Role.
    430   @param ByteIndex        Byte index of FeaturesVerified of HSTI data.
    431   @param BitMask          Bit mask of FeaturesVerified of HSTI data.
    432 
    433   @retval EFI_SUCCESS          The FeaturesVerified of HSTI data updated in AIP protocol.
    434   @retval EFI_NOT_STARTED      There is not HSTI table with the Role and ImplementationID published in system.
    435   @retval EFI_UNSUPPORTED      The ByteIndex is invalid.
    436 **/
    437 EFI_STATUS
    438 EFIAPI
    439 HstiLibSetFeaturesVerified (
    440   IN UINT32                   Role,
    441   IN CHAR16                   *ImplementationID, OPTIONAL
    442   IN UINT32                   ByteIndex,
    443   IN UINT8                    BitMask
    444   )
    445 {
    446   return InternalHstiRecordFeaturesVerified (
    447            Role,
    448            ImplementationID,
    449            ByteIndex,
    450            BitMask,
    451            TRUE
    452            );
    453 }
    454 
    455 /**
    456   Clear FeaturesVerified in published HSTI table.
    457   This API will update the HSTI table with indicated Role and ImplementationID,
    458   NULL ImplementationID means to find the first HSTI table with indicated Role.
    459 
    460   @param Role             Role of HSTI data.
    461   @param ImplementationID ImplementationID of HSTI data.
    462                           NULL means find the first one match Role.
    463   @param ByteIndex        Byte index of FeaturesVerified of HSTI data.
    464   @param BitMask          Bit mask of FeaturesVerified of HSTI data.
    465 
    466   @retval EFI_SUCCESS          The FeaturesVerified of HSTI data updated in AIP protocol.
    467   @retval EFI_NOT_STARTED      There is not HSTI table with the Role and ImplementationID published in system.
    468   @retval EFI_UNSUPPORTED      The ByteIndex is invalid.
    469 **/
    470 EFI_STATUS
    471 EFIAPI
    472 HstiLibClearFeaturesVerified (
    473   IN UINT32                   Role,
    474   IN CHAR16                   *ImplementationID, OPTIONAL
    475   IN UINT32                   ByteIndex,
    476   IN UINT8                    BitMask
    477   )
    478 {
    479   return InternalHstiRecordFeaturesVerified (
    480            Role,
    481            ImplementationID,
    482            ByteIndex,
    483            BitMask,
    484            FALSE
    485            );
    486 }
    487 
    488 /**
    489   Record ErrorString in published HSTI table.
    490   This API will update the HSTI table with indicated Role and ImplementationID,
    491   NULL ImplementationID means to find the first HSTI table with indicated Role.
    492 
    493   @param Role             Role of HSTI data.
    494   @param ImplementationID ImplementationID of HSTI data.
    495                           NULL means find the first one match Role.
    496   @param ErrorString      ErrorString of HSTI data.
    497   @param Append           TRUE means to append the ErrorString to HSTI table.
    498                           FALSE means to set the ErrorString in HSTI table.
    499 
    500   @retval EFI_SUCCESS          The ErrorString of HSTI data is published in AIP protocol.
    501   @retval EFI_NOT_STARTED      There is not HSTI table with the Role and ImplementationID published in system.
    502   @retval EFI_OUT_OF_RESOURCES There is not enough system resource to update ErrorString.
    503 **/
    504 EFI_STATUS
    505 InternalHstiRecordErrorString (
    506   IN UINT32                   Role,
    507   IN CHAR16                   *ImplementationID, OPTIONAL
    508   IN CHAR16                   *ErrorString,
    509   IN BOOLEAN                  Append
    510   )
    511 {
    512   EFI_ADAPTER_INFORMATION_PROTOCOL *Aip;
    513   ADAPTER_INFO_PLATFORM_SECURITY   *Hsti;
    514   UINTN                            HstiSize;
    515   UINTN                            StringSize;
    516   VOID                             *NewHsti;
    517   UINTN                            NewHstiSize;
    518   UINTN                            Offset;
    519   EFI_STATUS                       Status;
    520 
    521   Aip = InternalHstiFindAip (Role, ImplementationID, (VOID **)&Hsti, &HstiSize);
    522   if (Aip == NULL) {
    523     return EFI_NOT_STARTED;
    524   }
    525 
    526   if (Append) {
    527     Offset = HstiSize - sizeof(CHAR16);
    528   } else {
    529     Offset = sizeof(ADAPTER_INFO_PLATFORM_SECURITY) + Hsti->SecurityFeaturesSize * 3;
    530   }
    531   StringSize = StrSize (ErrorString);
    532 
    533   NewHstiSize = Offset + StringSize;
    534   NewHsti = AllocatePool (NewHstiSize);
    535   if (NewHsti == NULL) {
    536     return EFI_OUT_OF_RESOURCES;
    537   }
    538 
    539   CopyMem (NewHsti, Hsti, Offset);
    540   CopyMem ((UINT8 *)NewHsti + Offset, ErrorString, StringSize);
    541 
    542   Status = Aip->SetInformation (
    543                   Aip,
    544                   &gAdapterInfoPlatformSecurityGuid,
    545                   NewHsti,
    546                   NewHstiSize
    547                   );
    548   return Status;
    549 }
    550 
    551 /**
    552   Append ErrorString in published HSTI table.
    553   This API will update the HSTI table with indicated Role and ImplementationID,
    554   NULL ImplementationID means to find the first HSTI table with indicated Role.
    555 
    556   @param Role             Role of HSTI data.
    557   @param ImplementationID ImplementationID of HSTI data.
    558                           NULL means find the first one match Role.
    559   @param ErrorString      ErrorString of HSTI data.
    560 
    561   @retval EFI_SUCCESS          The ErrorString of HSTI data is updated in AIP protocol.
    562   @retval EFI_NOT_STARTED      There is not HSTI table with the Role and ImplementationID published in system.
    563   @retval EFI_OUT_OF_RESOURCES There is not enough system resource to update ErrorString.
    564 **/
    565 EFI_STATUS
    566 EFIAPI
    567 HstiLibAppendErrorString (
    568   IN UINT32                   Role,
    569   IN CHAR16                   *ImplementationID, OPTIONAL
    570   IN CHAR16                   *ErrorString
    571   )
    572 {
    573   return InternalHstiRecordErrorString (
    574            Role,
    575            ImplementationID,
    576            ErrorString,
    577            TRUE
    578            );
    579 }
    580 
    581 /**
    582   Set a new ErrorString in published HSTI table.
    583   This API will update the HSTI table with indicated Role and ImplementationID,
    584   NULL ImplementationID means to find the first HSTI table with indicated Role.
    585 
    586   @param Role             Role of HSTI data.
    587   @param ImplementationID ImplementationID of HSTI data.
    588                           NULL means find the first one match Role.
    589   @param ErrorString      ErrorString of HSTI data.
    590 
    591   @retval EFI_SUCCESS          The ErrorString of HSTI data is updated in AIP protocol.
    592   @retval EFI_NOT_STARTED      There is not HSTI table with the Role and ImplementationID published in system.
    593   @retval EFI_OUT_OF_RESOURCES There is not enough system resource to update ErrorString.
    594 **/
    595 EFI_STATUS
    596 EFIAPI
    597 HstiLibSetErrorString (
    598   IN UINT32                   Role,
    599   IN CHAR16                   *ImplementationID, OPTIONAL
    600   IN CHAR16                   *ErrorString
    601   )
    602 {
    603   return InternalHstiRecordErrorString (
    604            Role,
    605            ImplementationID,
    606            ErrorString,
    607            FALSE
    608            );
    609 }
    610