/** @file
  Implementation functions and structures for var check services.

Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
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 <Library/VarCheckLib.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>

#include <Guid/GlobalVariable.h>
#include <Guid/HardwareErrorVariable.h>

BOOLEAN mVarCheckLibEndOfDxe    = FALSE;

#define VAR_CHECK_TABLE_SIZE    0x8

UINTN                                   mVarCheckLibEndOfDxeCallbackCount = 0;
UINTN                                   mVarCheckLibEndOfDxeCallbackMaxCount = 0;
VAR_CHECK_END_OF_DXE_CALLBACK           *mVarCheckLibEndOfDxeCallback = NULL;

UINTN                                   mVarCheckLibAddressPointerCount = 0;
UINTN                                   mVarCheckLibAddressPointerMaxCount = 0;
VOID                                    ***mVarCheckLibAddressPointer = NULL;

UINTN                                   mNumberOfVarCheckHandler = 0;
UINTN                                   mMaxNumberOfVarCheckHandler = 0;
VAR_CHECK_SET_VARIABLE_CHECK_HANDLER    *mVarCheckHandlerTable = NULL;

typedef struct {
  EFI_GUID                      Guid;
  VAR_CHECK_VARIABLE_PROPERTY   VariableProperty;
  //CHAR16                        *Name;
} VAR_CHECK_VARIABLE_ENTRY;

UINTN                                   mNumberOfVarCheckVariable = 0;
UINTN                                   mMaxNumberOfVarCheckVariable = 0;
VARIABLE_ENTRY_PROPERTY                 **mVarCheckVariableTable = NULL;

//
// Handle variables with wildcard name specially.
//
VARIABLE_ENTRY_PROPERTY mVarCheckVariableWithWildcardName[] = {
  {
    &gEfiGlobalVariableGuid,
    L"Boot####",
    {
      0
    },
  },
  {
    &gEfiGlobalVariableGuid,
    L"Driver####",
    {
      0
    },
  },
  {
    &gEfiGlobalVariableGuid,
    L"SysPrep####",
    {
      0
    },
  },
  {
    &gEfiGlobalVariableGuid,
    L"Key####",
    {
      0
    },
  },
  {
    &gEfiHardwareErrorVariableGuid,
    L"HwErrRec####",
    {
      0
    },
  },
};

/**
  Check if a Unicode character is a hexadecimal character.

  This function checks if a Unicode character is a
  hexadecimal character.  The valid hexadecimal character is
  L'0' to L'9', L'a' to L'f', or L'A' to L'F'.


  @param[in] Char       The character to check against.

  @retval TRUE          If the Char is a hexadecmial character.
  @retval FALSE         If the Char is not a hexadecmial character.

**/
BOOLEAN
EFIAPI
VarCheckInternalIsHexaDecimalDigitCharacter (
  IN CHAR16             Char
  )
{
  return (BOOLEAN) ((Char >= L'0' && Char <= L'9') || (Char >= L'A' && Char <= L'F') || (Char >= L'a' && Char <= L'f'));
}

/**
  Variable property get with wildcard name.

  @param[in] VariableName       Pointer to variable name.
  @param[in] VendorGuid         Pointer to variable vendor GUID.
  @param[in] WildcardMatch      Try wildcard match or not.

  @return Pointer to variable property.

**/
VAR_CHECK_VARIABLE_PROPERTY *
VariablePropertyGetWithWildcardName (
  IN CHAR16                         *VariableName,
  IN EFI_GUID                       *VendorGuid,
  IN BOOLEAN                        WildcardMatch
  )
{
  UINTN     Index;
  UINTN     NameLength;

  NameLength = StrLen (VariableName) - 4;
  for (Index = 0; Index < sizeof (mVarCheckVariableWithWildcardName)/sizeof (mVarCheckVariableWithWildcardName[0]); Index++) {
    if (CompareGuid (mVarCheckVariableWithWildcardName[Index].Guid, VendorGuid)){
      if (WildcardMatch) {
        if ((StrLen (VariableName) == StrLen (mVarCheckVariableWithWildcardName[Index].Name)) &&
            (StrnCmp (VariableName, mVarCheckVariableWithWildcardName[Index].Name, NameLength) == 0) &&
            VarCheckInternalIsHexaDecimalDigitCharacter (VariableName[NameLength]) &&
            VarCheckInternalIsHexaDecimalDigitCharacter (VariableName[NameLength + 1]) &&
            VarCheckInternalIsHexaDecimalDigitCharacter (VariableName[NameLength + 2]) &&
            VarCheckInternalIsHexaDecimalDigitCharacter (VariableName[NameLength + 3])) {
          return &mVarCheckVariableWithWildcardName[Index].VariableProperty;
        }
      }
      if (StrCmp (mVarCheckVariableWithWildcardName[Index].Name, VariableName) == 0) {
        return  &mVarCheckVariableWithWildcardName[Index].VariableProperty;
      }
    }
  }

  return NULL;
}

/**
  Variable property get function.

  @param[in] Name           Pointer to the variable name.
  @param[in] Guid           Pointer to the vendor GUID.
  @param[in] WildcardMatch  Try wildcard match or not.

  @return Pointer to the property of variable specified by the Name and Guid.

**/
VAR_CHECK_VARIABLE_PROPERTY *
VariablePropertyGetFunction (
  IN CHAR16                 *Name,
  IN EFI_GUID               *Guid,
  IN BOOLEAN                WildcardMatch
  )
{
  UINTN                     Index;
  VAR_CHECK_VARIABLE_ENTRY  *Entry;
  CHAR16                    *VariableName;

  for (Index = 0; Index < mNumberOfVarCheckVariable; Index++) {
    Entry = (VAR_CHECK_VARIABLE_ENTRY *) mVarCheckVariableTable[Index];
    VariableName = (CHAR16 *) ((UINTN) Entry + sizeof (*Entry));
    if (CompareGuid (&Entry->Guid, Guid) && (StrCmp (VariableName, Name) == 0)) {
      return &Entry->VariableProperty;
    }
  }

  return VariablePropertyGetWithWildcardName (Name, Guid, WildcardMatch);
}

/**
  Var check add table entry.

  @param[in, out] Table         Pointer to table buffer.
  @param[in, out] MaxNumber     Pointer to maximum number of entry in the table.
  @param[in, out] CurrentNumber Pointer to current number of entry in the table.
  @param[in]      Entry         Entry will be added to the table.

  @retval EFI_SUCCESS           Reallocate memory successfully.
  @retval EFI_OUT_OF_RESOURCES  No enough memory to allocate.

**/
EFI_STATUS
VarCheckAddTableEntry (
  IN OUT UINTN      **Table,
  IN OUT UINTN      *MaxNumber,
  IN OUT UINTN      *CurrentNumber,
  IN UINTN          Entry
  )
{
  UINTN     *TempTable;

  //
  // Check whether the table is enough to store new entry.
  //
  if (*CurrentNumber == *MaxNumber) {
    //
    // Reallocate memory for the table.
    //
    TempTable = ReallocateRuntimePool (
                  *MaxNumber * sizeof (UINTN),
                  (*MaxNumber + VAR_CHECK_TABLE_SIZE) * sizeof (UINTN),
                  *Table
                  );

    //
    // No enough resource to allocate.
    //
    if (TempTable == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    *Table = TempTable;
    //
    // Increase max number.
    //
    *MaxNumber += VAR_CHECK_TABLE_SIZE;
  }

  //
  // Add entry to the table.
  //
  (*Table)[*CurrentNumber] = Entry;
  (*CurrentNumber)++;

  return EFI_SUCCESS;
}

/**
  Register END_OF_DXE callback.
  The callback will be invoked by VarCheckLibInitializeAtEndOfDxe().

  @param[in] Callback           END_OF_DXE callback.

  @retval EFI_SUCCESS           The callback was registered successfully.
  @retval EFI_INVALID_PARAMETER Callback is NULL.
  @retval EFI_ACCESS_DENIED     EFI_END_OF_DXE_EVENT_GROUP_GUID or EFI_EVENT_GROUP_READY_TO_BOOT has
                                already been signaled.
  @retval EFI_OUT_OF_RESOURCES  There is not enough resource for the callback register request.

**/
EFI_STATUS
EFIAPI
VarCheckLibRegisterEndOfDxeCallback (
  IN VAR_CHECK_END_OF_DXE_CALLBACK  Callback
  )
{
  EFI_STATUS    Status;

  if (Callback == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (mVarCheckLibEndOfDxe) {
    return EFI_ACCESS_DENIED;
  }

  Status = VarCheckAddTableEntry (
           (UINTN **) &mVarCheckLibEndOfDxeCallback,
           &mVarCheckLibEndOfDxeCallbackMaxCount,
           &mVarCheckLibEndOfDxeCallbackCount,
           (UINTN) Callback
           );

  DEBUG ((EFI_D_INFO, "VarCheckLibRegisterEndOfDxeCallback - 0x%x %r\n", Callback, Status));

  return Status;
}

/**
  Var check initialize at END_OF_DXE.

  This function needs to be called at END_OF_DXE.
  Address pointers may be returned,
  and caller needs to ConvertPointer() for the pointers.

  @param[in, out] AddressPointerCount   Output pointer to address pointer count.

  @return Address pointer buffer, NULL if input AddressPointerCount is NULL.

**/
VOID ***
EFIAPI
VarCheckLibInitializeAtEndOfDxe (
  IN OUT UINTN                  *AddressPointerCount OPTIONAL
  )
{
  VOID                          *TempTable;
  UINTN                         TotalCount;
  UINTN                         Index;

  for (Index = 0; Index < mVarCheckLibEndOfDxeCallbackCount; Index++) {
    //
    // Invoke the callback registered by VarCheckLibRegisterEndOfDxeCallback().
    //
    mVarCheckLibEndOfDxeCallback[Index] ();
  }
  if (mVarCheckLibEndOfDxeCallback != NULL) {
    //
    // Free the callback buffer.
    //
    mVarCheckLibEndOfDxeCallbackCount = 0;
    mVarCheckLibEndOfDxeCallbackMaxCount = 0;
    FreePool ((VOID *) mVarCheckLibEndOfDxeCallback);
    mVarCheckLibEndOfDxeCallback = NULL;
  }

  mVarCheckLibEndOfDxe = TRUE;

  if (AddressPointerCount == NULL) {
    if (mVarCheckLibAddressPointer != NULL) {
      //
      // Free the address pointer buffer.
      //
      mVarCheckLibAddressPointerCount = 0;
      mVarCheckLibAddressPointerMaxCount = 0;
      FreePool ((VOID *) mVarCheckLibAddressPointer);
      mVarCheckLibAddressPointer = NULL;
    }
    return NULL;
  }

  //
  // Get the total count needed.
  // Also cover VarCheckHandler and the entries, and VarCheckVariable and the entries.
  //
  TotalCount = mVarCheckLibAddressPointerCount + (mNumberOfVarCheckHandler + 1) + (mNumberOfVarCheckVariable + 1);
  TempTable = ReallocateRuntimePool (
                mVarCheckLibAddressPointerMaxCount * sizeof (VOID **),
                TotalCount * sizeof (VOID **),
                (VOID *) mVarCheckLibAddressPointer
                );

  if (TempTable != NULL) {
    mVarCheckLibAddressPointer = (VOID ***) TempTable;

    //
    // Cover VarCheckHandler and the entries.
    //
    mVarCheckLibAddressPointer[mVarCheckLibAddressPointerCount++] = (VOID **) &mVarCheckHandlerTable;
    for (Index = 0; Index < mNumberOfVarCheckHandler; Index++) {
      mVarCheckLibAddressPointer[mVarCheckLibAddressPointerCount++] = (VOID **) &mVarCheckHandlerTable[Index];
    }

    //
    // Cover VarCheckVariable and the entries.
    //
    mVarCheckLibAddressPointer[mVarCheckLibAddressPointerCount++] = (VOID **) &mVarCheckVariableTable;
    for (Index = 0; Index < mNumberOfVarCheckVariable; Index++) {
      mVarCheckLibAddressPointer[mVarCheckLibAddressPointerCount++] = (VOID **) &mVarCheckVariableTable[Index];
    }

    ASSERT (mVarCheckLibAddressPointerCount == TotalCount);
    mVarCheckLibAddressPointerMaxCount = mVarCheckLibAddressPointerCount;
  }

  *AddressPointerCount = mVarCheckLibAddressPointerCount;
  return mVarCheckLibAddressPointer;
}

/**
  Register address pointer.
  The AddressPointer may be returned by VarCheckLibInitializeAtEndOfDxe().

  @param[in] AddressPointer     Address pointer.

  @retval EFI_SUCCESS           The address pointer was registered successfully.
  @retval EFI_INVALID_PARAMETER AddressPointer is NULL.
  @retval EFI_ACCESS_DENIED     EFI_END_OF_DXE_EVENT_GROUP_GUID or EFI_EVENT_GROUP_READY_TO_BOOT has
                                already been signaled.
  @retval EFI_OUT_OF_RESOURCES  There is not enough resource for the address pointer register request.

**/
EFI_STATUS
EFIAPI
VarCheckLibRegisterAddressPointer (
  IN VOID                       **AddressPointer
  )
{
  EFI_STATUS    Status;

  if (AddressPointer == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (mVarCheckLibEndOfDxe) {
    return EFI_ACCESS_DENIED;
  }

  Status = VarCheckAddTableEntry(
           (UINTN **) &mVarCheckLibAddressPointer,
           &mVarCheckLibAddressPointerMaxCount,
           &mVarCheckLibAddressPointerCount,
           (UINTN) AddressPointer
           );

  DEBUG ((EFI_D_INFO, "VarCheckLibRegisterAddressPointer - 0x%x %r\n", AddressPointer, Status));

  return Status;
}

/**
  Register SetVariable check handler.

  @param[in] Handler            Pointer to check handler.

  @retval EFI_SUCCESS           The SetVariable check handler was registered successfully.
  @retval EFI_INVALID_PARAMETER Handler is NULL.
  @retval EFI_ACCESS_DENIED     EFI_END_OF_DXE_EVENT_GROUP_GUID or EFI_EVENT_GROUP_READY_TO_BOOT has
                                already been signaled.
  @retval EFI_OUT_OF_RESOURCES  There is not enough resource for the SetVariable check handler register request.
  @retval EFI_UNSUPPORTED       This interface is not implemented.
                                For example, it is unsupported in VarCheck protocol if both VarCheck and SmmVarCheck protocols are present.

**/
EFI_STATUS
EFIAPI
VarCheckLibRegisterSetVariableCheckHandler (
  IN VAR_CHECK_SET_VARIABLE_CHECK_HANDLER   Handler
  )
{
  EFI_STATUS    Status;

  if (Handler == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (mVarCheckLibEndOfDxe) {
    return EFI_ACCESS_DENIED;
  }

  Status =  VarCheckAddTableEntry(
             (UINTN **) &mVarCheckHandlerTable,
             &mMaxNumberOfVarCheckHandler,
             &mNumberOfVarCheckHandler,
             (UINTN) Handler
             );

  DEBUG ((EFI_D_INFO, "VarCheckLibRegisterSetVariableCheckHandler - 0x%x %r\n", Handler, Status));

  return Status;
}

/**
  Variable property set.

  @param[in] Name               Pointer to the variable name.
  @param[in] Guid               Pointer to the vendor GUID.
  @param[in] VariableProperty   Pointer to the input variable property.

  @retval EFI_SUCCESS           The property of variable specified by the Name and Guid was set successfully.
  @retval EFI_INVALID_PARAMETER Name, Guid or VariableProperty is NULL, or Name is an empty string,
                                or the fields of VariableProperty are not valid.
  @retval EFI_ACCESS_DENIED     EFI_END_OF_DXE_EVENT_GROUP_GUID or EFI_EVENT_GROUP_READY_TO_BOOT has
                                already been signaled.
  @retval EFI_OUT_OF_RESOURCES  There is not enough resource for the variable property set request.

**/
EFI_STATUS
EFIAPI
VarCheckLibVariablePropertySet (
  IN CHAR16                         *Name,
  IN EFI_GUID                       *Guid,
  IN VAR_CHECK_VARIABLE_PROPERTY    *VariableProperty
  )
{
  EFI_STATUS                    Status;
  VAR_CHECK_VARIABLE_ENTRY      *Entry;
  CHAR16                        *VariableName;
  VAR_CHECK_VARIABLE_PROPERTY   *Property;

  if (Name == NULL || Name[0] == 0 || Guid == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (VariableProperty == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (VariableProperty->Revision != VAR_CHECK_VARIABLE_PROPERTY_REVISION) {
    return EFI_INVALID_PARAMETER;
  }

  if (mVarCheckLibEndOfDxe) {
    return EFI_ACCESS_DENIED;
  }

  Status = EFI_SUCCESS;

  //
  // Get the pointer of property data for set.
  //
  Property = VariablePropertyGetFunction (Name, Guid, FALSE);
  if (Property != NULL) {
    CopyMem (Property, VariableProperty, sizeof (*VariableProperty));
  } else {
    Entry = AllocateRuntimeZeroPool (sizeof (*Entry) + StrSize (Name));
    if (Entry == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }
    VariableName = (CHAR16 *) ((UINTN) Entry + sizeof (*Entry));
    StrCpyS (VariableName, StrSize (Name)/sizeof (CHAR16), Name);
    CopyGuid (&Entry->Guid, Guid);
    CopyMem (&Entry->VariableProperty, VariableProperty, sizeof (*VariableProperty));

    Status = VarCheckAddTableEntry(
               (UINTN **) &mVarCheckVariableTable,
               &mMaxNumberOfVarCheckVariable,
               &mNumberOfVarCheckVariable,
               (UINTN) Entry
               );

    if (EFI_ERROR (Status)) {
      FreePool (Entry);
    }
  }

  return Status;
}

/**
  Variable property get.

  @param[in]  Name              Pointer to the variable name.
  @param[in]  Guid              Pointer to the vendor GUID.
  @param[out] VariableProperty  Pointer to the output variable property.

  @retval EFI_SUCCESS           The property of variable specified by the Name and Guid was got successfully.
  @retval EFI_INVALID_PARAMETER Name, Guid or VariableProperty is NULL, or Name is an empty string.
  @retval EFI_NOT_FOUND         The property of variable specified by the Name and Guid was not found.

**/
EFI_STATUS
EFIAPI
VarCheckLibVariablePropertyGet (
  IN CHAR16                         *Name,
  IN EFI_GUID                       *Guid,
  OUT VAR_CHECK_VARIABLE_PROPERTY   *VariableProperty
  )
{
  VAR_CHECK_VARIABLE_PROPERTY   *Property;

  if (Name == NULL || Name[0] == 0 || Guid == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (VariableProperty == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Property = VariablePropertyGetFunction (Name, Guid, TRUE);
  //
  // Also check the property revision before using the property data.
  // There is no property set to this variable(wildcard name)
  // if the revision is not VAR_CHECK_VARIABLE_PROPERTY_REVISION.
  //
  if ((Property != NULL) && (Property->Revision == VAR_CHECK_VARIABLE_PROPERTY_REVISION)) {
    CopyMem (VariableProperty, Property, sizeof (*VariableProperty));
    return EFI_SUCCESS;
  }

  return EFI_NOT_FOUND;
}

/**
  SetVariable check.

  @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.
  @param[in] RequestSource      Request source.

  @retval EFI_SUCCESS           The SetVariable check result was success.
  @retval EFI_INVALID_PARAMETER An invalid combination of attribute bits, name, GUID,
                                DataSize and Data value was supplied.
  @retval EFI_WRITE_PROTECTED   The variable in question is read-only.
  @retval Others                The other return status from check handler.

**/
EFI_STATUS
EFIAPI
VarCheckLibSetVariableCheck (
  IN CHAR16                     *VariableName,
  IN EFI_GUID                   *VendorGuid,
  IN UINT32                     Attributes,
  IN UINTN                      DataSize,
  IN VOID                       *Data,
  IN VAR_CHECK_REQUEST_SOURCE   RequestSource
  )
{
  EFI_STATUS                    Status;
  UINTN                         Index;
  VAR_CHECK_VARIABLE_PROPERTY   *Property;

  if (!mVarCheckLibEndOfDxe) {
    //
    // Only do check after End Of Dxe.
    //
    return EFI_SUCCESS;
  }

  Property = VariablePropertyGetFunction (VariableName, VendorGuid, TRUE);
  //
  // Also check the property revision before using the property data.
  // There is no property set to this variable(wildcard name)
  // if the revision is not VAR_CHECK_VARIABLE_PROPERTY_REVISION.
  //
  if ((Property != NULL) && (Property->Revision == VAR_CHECK_VARIABLE_PROPERTY_REVISION)) {
    if ((RequestSource != VarCheckFromTrusted) && ((Property->Property & VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY) != 0)) {
      DEBUG ((EFI_D_INFO, "Variable Check ReadOnly variable fail %r - %g:%s\n", EFI_WRITE_PROTECTED, VendorGuid, VariableName));
      return EFI_WRITE_PROTECTED;
    }
    if (!((((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0) && (DataSize == 0)) || (Attributes == 0))) {
      //
      // Not to delete variable.
      //
      if ((Property->Attributes != 0) && ((Attributes & (~EFI_VARIABLE_APPEND_WRITE)) != Property->Attributes)) {
        DEBUG ((EFI_D_INFO, "Variable Check Attributes(0x%08x to 0x%08x) fail %r - %g:%s\n", Property->Attributes, Attributes, EFI_INVALID_PARAMETER, VendorGuid, VariableName));
        return EFI_INVALID_PARAMETER;
      }
      if (DataSize != 0) {
        if ((DataSize < Property->MinSize) || (DataSize > Property->MaxSize)) {
          DEBUG ((EFI_D_INFO, "Variable Check DataSize fail(0x%x not in 0x%x - 0x%x) %r - %g:%s\n", DataSize, Property->MinSize, Property->MaxSize, EFI_INVALID_PARAMETER, VendorGuid, VariableName));
          return EFI_INVALID_PARAMETER;
        }
      }
    }
  }

  for (Index = 0; Index < mNumberOfVarCheckHandler; Index++) {
    Status = mVarCheckHandlerTable[Index] (
               VariableName,
               VendorGuid,
               Attributes,
               DataSize,
               Data
               );
    if (EFI_ERROR (Status)) {
      DEBUG ((EFI_D_INFO, "Variable Check handler fail %r - %g:%s\n", Status, VendorGuid, VariableName));
      return Status;
    }
  }
  return EFI_SUCCESS;
}
