/** @file
  Var Check PCD handler.

Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include <Library/VarCheckLib.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/DxeServicesLib.h>

#include "VarCheckPcdStructure.h"

// #define DUMP_VAR_CHECK_PCD

GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8  mVarCheckPcdHex[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };

/**
  Dump some hexadecimal data.

  @param[in] Indent     How many spaces to indent the output.
  @param[in] Offset     The offset of the dump.
  @param[in] DataSize   The size in bytes of UserData.
  @param[in] UserData   The data to dump.

**/
VOID
VarCheckPcdInternalDumpHex (
  IN UINTN  Indent,
  IN UINTN  Offset,
  IN UINTN  DataSize,
  IN VOID   *UserData
  )
{
  UINT8  *Data;

  CHAR8  Val[50];

  CHAR8  Str[20];

  UINT8  TempByte;
  UINTN  Size;
  UINTN  Index;

  Data = UserData;
  while (DataSize != 0) {
    Size = 16;
    if (Size > DataSize) {
      Size = DataSize;
    }

    for (Index = 0; Index < Size; Index += 1) {
      TempByte           = Data[Index];
      Val[Index * 3 + 0] = mVarCheckPcdHex[TempByte >> 4];
      Val[Index * 3 + 1] = mVarCheckPcdHex[TempByte & 0xF];
      Val[Index * 3 + 2] = (CHAR8)((Index == 7) ? '-' : ' ');
      Str[Index]         = (CHAR8)((TempByte < ' ' || TempByte > 'z') ? '.' : TempByte);
    }

    Val[Index * 3] = 0;
    Str[Index]     = 0;
    DEBUG ((DEBUG_INFO, "%*a%08X: %-48a *%a*\r\n", Indent, "", Offset, Val, Str));

    Data     += Size;
    Offset   += Size;
    DataSize -= Size;
  }
}

/**
  Var Check Pcd ValidData.

  @param[in] PcdValidData   Pointer to Pcd ValidData
  @param[in] Data           Data pointer.
  @param[in] DataSize       Size of Data to set.

  @retval TRUE  Check pass
  @retval FALSE Check fail.

**/
BOOLEAN
VarCheckPcdValidData (
  IN VAR_CHECK_PCD_VALID_DATA_HEADER  *PcdValidData,
  IN VOID                             *Data,
  IN UINTN                            DataSize
  )
{
  UINT64  OneData;
  UINT64  Minimum;
  UINT64  Maximum;
  UINT64  OneValue;
  UINT8   *Ptr;

  OneData = 0;
  CopyMem (&OneData, (UINT8 *)Data + PcdValidData->VarOffset, PcdValidData->StorageWidth);

  switch (PcdValidData->Type) {
    case VarCheckPcdValidList:
      Ptr = (UINT8 *)((VAR_CHECK_PCD_VALID_LIST *)PcdValidData + 1);
      while ((UINTN)Ptr < (UINTN)PcdValidData + PcdValidData->Length) {
        OneValue = 0;
        CopyMem (&OneValue, Ptr, PcdValidData->StorageWidth);
        if (OneData == OneValue) {
          //
          // Match
          //
          break;
        }

        Ptr += PcdValidData->StorageWidth;
      }

      if ((UINTN)Ptr >= ((UINTN)PcdValidData + PcdValidData->Length)) {
        //
        // No match
        //
        DEBUG ((DEBUG_INFO, "VarCheckPcdValidData fail: ValidList mismatch (0x%lx)\n", OneData));
        DEBUG_CODE (
          VarCheckPcdInternalDumpHex (2, 0, PcdValidData->Length, (UINT8 *)PcdValidData);
          );
        return FALSE;
      }

      break;

    case VarCheckPcdValidRange:
      Minimum = 0;
      Maximum = 0;
      Ptr     = (UINT8 *)((VAR_CHECK_PCD_VALID_RANGE *)PcdValidData + 1);
      while ((UINTN)Ptr < (UINTN)PcdValidData + PcdValidData->Length) {
        CopyMem (&Minimum, Ptr, PcdValidData->StorageWidth);
        Ptr += PcdValidData->StorageWidth;
        CopyMem (&Maximum, Ptr, PcdValidData->StorageWidth);
        Ptr += PcdValidData->StorageWidth;

        if ((OneData >= Minimum) && (OneData <= Maximum)) {
          return TRUE;
        }
      }

      DEBUG ((DEBUG_INFO, "VarCheckPcdValidData fail: ValidRange mismatch (0x%lx)\n", OneData));
      DEBUG_CODE (
        VarCheckPcdInternalDumpHex (2, 0, PcdValidData->Length, (UINT8 *)PcdValidData);
        );
      return FALSE;
      break;

    default:
      ASSERT (FALSE);
      break;
  }

  return TRUE;
}

VAR_CHECK_PCD_VARIABLE_HEADER  *mVarCheckPcdBin    = NULL;
UINTN                          mVarCheckPcdBinSize = 0;

/**
  SetVariable check handler PCD.

  @param[in] VariableName       Name of Variable to set.
  @param[in] VendorGuid         Variable vendor GUID.
  @param[in] Attributes         Attribute value of the variable.
  @param[in] DataSize           Size of Data to set.
  @param[in] Data               Data pointer.

  @retval EFI_SUCCESS               The SetVariable check result was success.
  @retval EFI_SECURITY_VIOLATION    Check fail.

**/
EFI_STATUS
EFIAPI
SetVariableCheckHandlerPcd (
  IN CHAR16    *VariableName,
  IN EFI_GUID  *VendorGuid,
  IN UINT32    Attributes,
  IN UINTN     DataSize,
  IN VOID      *Data
  )
{
  VAR_CHECK_PCD_VARIABLE_HEADER    *PcdVariable;
  VAR_CHECK_PCD_VALID_DATA_HEADER  *PcdValidData;

  if (mVarCheckPcdBin == NULL) {
    return EFI_SUCCESS;
  }

  if ((((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0) && (DataSize == 0)) || (Attributes == 0)) {
    //
    // Do not check delete variable.
    //
    return EFI_SUCCESS;
  }

  //
  // For Pcd Variable header align.
  //
  PcdVariable = (VAR_CHECK_PCD_VARIABLE_HEADER *)HEADER_ALIGN (mVarCheckPcdBin);
  while ((UINTN)PcdVariable < ((UINTN)mVarCheckPcdBin + mVarCheckPcdBinSize)) {
    if ((StrCmp ((CHAR16 *)(PcdVariable + 1), VariableName) == 0) &&
        (CompareGuid (&PcdVariable->Guid, VendorGuid)))
    {
      //
      // Found the Pcd Variable that could be used to do check.
      //
      DEBUG ((DEBUG_INFO, "VarCheckPcdVariable - %s:%g with Attributes = 0x%08x Size = 0x%x\n", VariableName, VendorGuid, Attributes, DataSize));
      if ((PcdVariable->Attributes != 0) && (PcdVariable->Attributes != Attributes)) {
        DEBUG ((DEBUG_INFO, "VarCheckPcdVariable fail for Attributes - 0x%08x\n", PcdVariable->Attributes));
        return EFI_SECURITY_VIOLATION;
      }

      if (DataSize == 0) {
        DEBUG ((DEBUG_INFO, "VarCheckPcdVariable - CHECK PASS with DataSize == 0 !\n"));
        return EFI_SUCCESS;
      }

      //
      // Do the check.
      // For Pcd ValidData header align.
      //
      PcdValidData = (VAR_CHECK_PCD_VALID_DATA_HEADER *)HEADER_ALIGN (((UINTN)PcdVariable + PcdVariable->HeaderLength));
      while ((UINTN)PcdValidData < ((UINTN)PcdVariable + PcdVariable->Length)) {
        if (((UINTN)PcdValidData->VarOffset + PcdValidData->StorageWidth) <= DataSize) {
          if (!VarCheckPcdValidData (PcdValidData, Data, DataSize)) {
            return EFI_SECURITY_VIOLATION;
          }
        }

        //
        // For Pcd ValidData header align.
        //
        PcdValidData = (VAR_CHECK_PCD_VALID_DATA_HEADER *)HEADER_ALIGN (((UINTN)PcdValidData + PcdValidData->Length));
      }

      DEBUG ((DEBUG_INFO, "VarCheckPcdVariable - ALL CHECK PASS!\n"));
      return EFI_SUCCESS;
    }

    //
    // For Pcd Variable header align.
    //
    PcdVariable = (VAR_CHECK_PCD_VARIABLE_HEADER *)HEADER_ALIGN (((UINTN)PcdVariable + PcdVariable->Length));
  }

  // Not found, so pass.
  return EFI_SUCCESS;
}

#ifdef DUMP_VAR_CHECK_PCD

/**
  Dump Pcd ValidData.

  @param[in] PcdValidData    Pointer to Pcd ValidData.

**/
VOID
DumpPcdValidData (
  IN VAR_CHECK_PCD_VALID_DATA_HEADER  *PcdValidData
  )
{
  UINT64  Minimum;
  UINT64  Maximum;
  UINT64  OneValue;
  UINT8   *Ptr;

  DEBUG ((DEBUG_INFO, "  VAR_CHECK_PCD_VALID_DATA_HEADER\n"));
  DEBUG ((DEBUG_INFO, "    Type          - 0x%02x\n", PcdValidData->Type));
  DEBUG ((DEBUG_INFO, "    Length        - 0x%02x\n", PcdValidData->Length));
  DEBUG ((DEBUG_INFO, "    VarOffset     - 0x%04x\n", PcdValidData->VarOffset));
  DEBUG ((DEBUG_INFO, "    StorageWidth  - 0x%02x\n", PcdValidData->StorageWidth));

  switch (PcdValidData->Type) {
    case VarCheckPcdValidList:
      Ptr = (UINT8 *)((VAR_CHECK_PCD_VALID_LIST *)PcdValidData + 1);
      while ((UINTN)Ptr < ((UINTN)PcdValidData + PcdValidData->Length)) {
        OneValue = 0;
        CopyMem (&OneValue, Ptr, PcdValidData->StorageWidth);
        switch (PcdValidData->StorageWidth) {
          case sizeof (UINT8):
            DEBUG ((DEBUG_INFO, "    ValidList   - 0x%02x\n", OneValue));
            break;
          case sizeof (UINT16):
            DEBUG ((DEBUG_INFO, "    ValidList   - 0x%04x\n", OneValue));
            break;
          case sizeof (UINT32):
            DEBUG ((DEBUG_INFO, "    ValidList   - 0x%08x\n", OneValue));
            break;
          case sizeof (UINT64):
            DEBUG ((DEBUG_INFO, "    ValidList   - 0x%016lx\n", OneValue));
            break;
          default:
            ASSERT (FALSE);
            break;
        }

        Ptr += PcdValidData->StorageWidth;
      }

      break;

    case VarCheckPcdValidRange:
      Minimum = 0;
      Maximum = 0;
      Ptr     = (UINT8 *)((VAR_CHECK_PCD_VALID_RANGE *)PcdValidData + 1);
      while ((UINTN)Ptr < (UINTN)PcdValidData + PcdValidData->Length) {
        CopyMem (&Minimum, Ptr, PcdValidData->StorageWidth);
        Ptr += PcdValidData->StorageWidth;
        CopyMem (&Maximum, Ptr, PcdValidData->StorageWidth);
        Ptr += PcdValidData->StorageWidth;

        switch (PcdValidData->StorageWidth) {
          case sizeof (UINT8):
            DEBUG ((DEBUG_INFO, "    Minimum       - 0x%02x\n", Minimum));
            DEBUG ((DEBUG_INFO, "    Maximum       - 0x%02x\n", Maximum));
            break;
          case sizeof (UINT16):
            DEBUG ((DEBUG_INFO, "    Minimum       - 0x%04x\n", Minimum));
            DEBUG ((DEBUG_INFO, "    Maximum       - 0x%04x\n", Maximum));
            break;
          case sizeof (UINT32):
            DEBUG ((DEBUG_INFO, "    Minimum       - 0x%08x\n", Minimum));
            DEBUG ((DEBUG_INFO, "    Maximum       - 0x%08x\n", Maximum));
            break;
          case sizeof (UINT64):
            DEBUG ((DEBUG_INFO, "    Minimum       - 0x%016lx\n", Minimum));
            DEBUG ((DEBUG_INFO, "    Maximum       - 0x%016lx\n", Maximum));
            break;
          default:
            ASSERT (FALSE);
            break;
        }
      }

      break;

    default:
      ASSERT (FALSE);
      break;
  }
}

/**
  Dump Pcd Variable.

  @param[in] PcdVariable    Pointer to Pcd Variable.

**/
VOID
DumpPcdVariable (
  IN VAR_CHECK_PCD_VARIABLE_HEADER  *PcdVariable
  )
{
  VAR_CHECK_PCD_VALID_DATA_HEADER  *PcdValidData;

  DEBUG ((DEBUG_INFO, "VAR_CHECK_PCD_VARIABLE_HEADER\n"));
  DEBUG ((DEBUG_INFO, "  Revision        - 0x%04x\n", PcdVariable->Revision));
  DEBUG ((DEBUG_INFO, "  HeaderLength    - 0x%04x\n", PcdVariable->HeaderLength));
  DEBUG ((DEBUG_INFO, "  Length          - 0x%08x\n", PcdVariable->Length));
  DEBUG ((DEBUG_INFO, "  Type            - 0x%02x\n", PcdVariable->Type));
  DEBUG ((DEBUG_INFO, "  Attributes      - 0x%08x\n", PcdVariable->Attributes));
  DEBUG ((DEBUG_INFO, "  Guid            - %g\n", &PcdVariable->Guid));
  DEBUG ((DEBUG_INFO, "  Name            - %s\n", PcdVariable + 1));

  //
  // For Pcd ValidData header align.
  //
  PcdValidData = (VAR_CHECK_PCD_VALID_DATA_HEADER *)HEADER_ALIGN (((UINTN)PcdVariable + PcdVariable->HeaderLength));
  while ((UINTN)PcdValidData < ((UINTN)PcdVariable + PcdVariable->Length)) {
    //
    // Dump Pcd ValidData related to the Pcd Variable.
    //
    DumpPcdValidData (PcdValidData);
    //
    // For Pcd ValidData header align.
    //
    PcdValidData = (VAR_CHECK_PCD_VALID_DATA_HEADER *)HEADER_ALIGN (((UINTN)PcdValidData + PcdValidData->Length));
  }
}

/**
  Dump Var Check PCD.

  @param[in] VarCheckPcdBin     Pointer to VarCheckPcdBin.
  @param[in] VarCheckPcdBinSize VarCheckPcdBin size.

**/
VOID
DumpVarCheckPcd (
  IN VOID   *VarCheckPcdBin,
  IN UINTN  VarCheckPcdBinSize
  )
{
  VAR_CHECK_PCD_VARIABLE_HEADER  *PcdVariable;

  DEBUG ((DEBUG_INFO, "DumpVarCheckPcd\n"));

  //
  // For Pcd Variable header align.
  //
  PcdVariable = (VAR_CHECK_PCD_VARIABLE_HEADER *)HEADER_ALIGN (VarCheckPcdBin);
  while ((UINTN)PcdVariable < ((UINTN)VarCheckPcdBin + VarCheckPcdBinSize)) {
    DumpPcdVariable (PcdVariable);
    //
    // For Pcd Variable header align.
    //
    PcdVariable = (VAR_CHECK_PCD_VARIABLE_HEADER *)HEADER_ALIGN (((UINTN)PcdVariable + PcdVariable->Length));
  }
}

#endif

/**
  Locate VarCheckPcdBin.

**/
VOID
EFIAPI
LocateVarCheckPcdBin (
  VOID
  )
{
  EFI_STATUS                     Status;
  VAR_CHECK_PCD_VARIABLE_HEADER  *VarCheckPcdBin;
  UINTN                          VarCheckPcdBinSize;

  //
  // Search the VarCheckPcdBin from the first RAW section of current FFS.
  //
  Status = GetSectionFromFfs (
             EFI_SECTION_RAW,
             0,
             (VOID **)&VarCheckPcdBin,
             &VarCheckPcdBinSize
             );
  if (!EFI_ERROR (Status)) {
    //
    // AllocateRuntimeZeroPool () from MemoryAllocateLib is used for runtime access
    // in SetVariable check handler.
    //
    mVarCheckPcdBin = AllocateRuntimeCopyPool (VarCheckPcdBinSize, VarCheckPcdBin);
    ASSERT (mVarCheckPcdBin != NULL);
    //
    // Make sure the allocated buffer for VarCheckPcdBin at required alignment.
    //
    ASSERT ((((UINTN)mVarCheckPcdBin) & (HEADER_ALIGNMENT - 1)) == 0);
    mVarCheckPcdBinSize = VarCheckPcdBinSize;
    FreePool (VarCheckPcdBin);

    DEBUG ((DEBUG_INFO, "VarCheckPcdBin - at 0x%x size = 0x%x\n", mVarCheckPcdBin, mVarCheckPcdBinSize));

 #ifdef DUMP_VAR_CHECK_PCD
    DEBUG_CODE (
      DumpVarCheckPcd (mVarCheckPcdBin, mVarCheckPcdBinSize);
      );
 #endif
  } else {
    DEBUG ((DEBUG_INFO, "[VarCheckPcd] No VarCheckPcdBin found at the first RAW section\n"));
  }
}

/**
  Constructor function of VarCheckPcdLib to register var check PCD handler.

  @param[in] ImageHandle    The firmware allocated handle for the EFI image.
  @param[in] SystemTable    A pointer to the EFI System Table.

  @retval EFI_SUCCESS       The constructor executed correctly.

**/
EFI_STATUS
EFIAPI
VarCheckPcdLibNullClassConstructor (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  LocateVarCheckPcdBin ();
  VarCheckLibRegisterAddressPointer ((VOID **)&mVarCheckPcdBin);
  VarCheckLibRegisterSetVariableCheckHandler (SetVariableCheckHandlerPcd);

  return EFI_SUCCESS;
}
