/** @file

  Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#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) || (InfoTypesBuffer == NULL) || (InfoTypesBufferCount == 0)) {
      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 ((DEBUG_ERROR, "HstiData == NULL\n"));
    return FALSE;
  }

  if (HstiSize < sizeof (ADAPTER_INFO_PLATFORM_SECURITY)) {
    DEBUG ((DEBUG_ERROR, "HstiSize < sizeof(ADAPTER_INFO_PLATFORM_SECURITY)\n"));
    return FALSE;
  }

  if (((HstiSize - sizeof (ADAPTER_INFO_PLATFORM_SECURITY)) / 3) < Hsti->SecurityFeaturesSize) {
    DEBUG ((DEBUG_ERROR, "((HstiSize - sizeof(ADAPTER_INFO_PLATFORM_SECURITY)) / 3) < SecurityFeaturesSize\n"));
    return FALSE;
  }

  //
  // Check Version
  //
  if (Hsti->Version != PLATFORM_SECURITY_VERSION_VNEXTCS) {
    DEBUG ((DEBUG_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 ((DEBUG_ERROR, "Role < PLATFORM_SECURITY_ROLE_PLATFORM_REFERENCE ||\n"));
    DEBUG ((DEBUG_ERROR, "Role > PLATFORM_SECURITY_ROLE_IMPLEMENTOR_ODM\n"));
    return FALSE;
  }

  //
  // Check ImplementationID
  //
  for (Index = 0; Index < sizeof (Hsti->ImplementationID)/sizeof (Hsti->ImplementationID[0]); Index++) {
    if (Hsti->ImplementationID[Index] == 0) {
      break;
    }
  }

  if (Index == sizeof (Hsti->ImplementationID)/sizeof (Hsti->ImplementationID[0])) {
    DEBUG ((DEBUG_ERROR, "ImplementationID has 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 ((DEBUG_ERROR, "ErrorStringSize == 0\n"));
    return FALSE;
  }

  if ((ErrorStringSize & BIT0) != 0) {
    DEBUG ((DEBUG_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 ((DEBUG_ERROR, "ErrorString has no NUL CHAR\n"));
    return FALSE;
  }

  if (ErrorStringLength == (ErrorStringSize/2)) {
    DEBUG ((DEBUG_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->Hsti == 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, (VOID **)&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
                  );
  FreePool (Hsti);
  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, (VOID **)&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
                  );
  FreePool (Hsti);
  FreePool (NewHsti);
  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
           );
}
