/** @file
  Implement image verification services for secure boot service

  Caution: This file requires additional review when modified.
  This library will have external input - PE/COFF image.
  This external input must be validated carefully to avoid security issue like
  buffer overflow, integer overflow.

  DxeImageVerificationLibImageRead() function will make sure the PE/COFF image content
  read is within the image buffer.

  DxeImageVerificationHandler(), HashPeImageByType(), HashPeImage() function will accept
  untrusted PE/COFF image and validate its data structure within this image buffer before use.

Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "DxeImageVerificationLib.h"

//
// Caution: This is used by a function which may receive untrusted input.
// These global variables hold PE/COFF image data, and they should be validated before use.
//
EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION  mNtHeader;
UINT32                               mPeCoffHeaderOffset;
EFI_GUID                             mCertType;

//
// Information on current PE/COFF image
//
UINTN  mImageSize;
UINT8  *mImageBase = NULL;
UINT8  mImageDigest[MAX_DIGEST_SIZE];
UINTN  mImageDigestSize;

//
// Notify string for authorization UI.
//
CHAR16  mNotifyString1[MAX_NOTIFY_STRING_LEN] = L"Image verification pass but not found in authorized database!";
CHAR16  mNotifyString2[MAX_NOTIFY_STRING_LEN] = L"Launch this image anyway? (Yes/Defer/No)";
//
// Public Exponent of RSA Key.
//
CONST UINT8  mRsaE[] = { 0x01, 0x00, 0x01 };

//
// OID ASN.1 Value for Hash Algorithms
//
UINT8  mHashOidValue[] = {
  0x2B, 0x0E, 0x03, 0x02, 0x1A,                         // OBJ_sha1
  0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, // OBJ_sha224
  0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, // OBJ_sha256
  0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, // OBJ_sha384
  0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, // OBJ_sha512
};

HASH_TABLE  mHash[] = {
 #ifndef DISABLE_SHA1_DEPRECATED_INTERFACES
  { L"SHA1",   20, &mHashOidValue[0],  5, Sha1GetContextSize,   Sha1Init,   Sha1Update,   Sha1Final   },
 #else
  { L"SHA1",   20, &mHashOidValue[0],  5, NULL,                 NULL,       NULL,         NULL        },
 #endif
  { L"SHA224", 28, &mHashOidValue[5],  9, NULL,                 NULL,       NULL,         NULL        },
  { L"SHA256", 32, &mHashOidValue[14], 9, Sha256GetContextSize, Sha256Init, Sha256Update, Sha256Final },
  { L"SHA384", 48, &mHashOidValue[23], 9, Sha384GetContextSize, Sha384Init, Sha384Update, Sha384Final },
  { L"SHA512", 64, &mHashOidValue[32], 9, Sha512GetContextSize, Sha512Init, Sha512Update, Sha512Final }
};

EFI_STRING  mHashTypeStr;

/**
  SecureBoot Hook for processing image verification.

  @param[in] VariableName                 Name of Variable to be found.
  @param[in] VendorGuid                   Variable vendor GUID.
  @param[in] DataSize                     Size of Data found. If size is less than the
                                          data, this value contains the required size.
  @param[in] Data                         Data pointer.

**/
VOID
EFIAPI
SecureBootHook (
  IN CHAR16    *VariableName,
  IN EFI_GUID  *VendorGuid,
  IN UINTN     DataSize,
  IN VOID      *Data
  );

/**
  Reads contents of a PE/COFF image in memory buffer.

  Caution: This function may receive untrusted input.
  PE/COFF image is external input, so this function will make sure the PE/COFF image content
  read is within the image buffer.

  @param  FileHandle      Pointer to the file handle to read the PE/COFF image.
  @param  FileOffset      Offset into the PE/COFF image to begin the read operation.
  @param  ReadSize        On input, the size in bytes of the requested read operation.
                          On output, the number of bytes actually read.
  @param  Buffer          Output buffer that contains the data read from the PE/COFF image.

  @retval EFI_SUCCESS     The specified portion of the PE/COFF image was read and the size
**/
EFI_STATUS
EFIAPI
DxeImageVerificationLibImageRead (
  IN     VOID   *FileHandle,
  IN     UINTN  FileOffset,
  IN OUT UINTN  *ReadSize,
  OUT    VOID   *Buffer
  )
{
  UINTN  EndPosition;

  if ((FileHandle == NULL) || (ReadSize == NULL) || (Buffer == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if (MAX_ADDRESS - FileOffset < *ReadSize) {
    return EFI_INVALID_PARAMETER;
  }

  EndPosition = FileOffset + *ReadSize;
  if (EndPosition > mImageSize) {
    *ReadSize = (UINT32)(mImageSize - FileOffset);
  }

  if (FileOffset >= mImageSize) {
    *ReadSize = 0;
  }

  CopyMem (Buffer, (UINT8 *)((UINTN)FileHandle + FileOffset), *ReadSize);

  return EFI_SUCCESS;
}

/**
  Get the image type.

  @param[in]    File       This is a pointer to the device path of the file that is
                           being dispatched.

  @return UINT32           Image Type

**/
UINT32
GetImageType (
  IN  CONST EFI_DEVICE_PATH_PROTOCOL  *File
  )
{
  EFI_STATUS                Status;
  EFI_HANDLE                DeviceHandle;
  EFI_DEVICE_PATH_PROTOCOL  *TempDevicePath;
  EFI_BLOCK_IO_PROTOCOL     *BlockIo;

  if (File == NULL) {
    return IMAGE_UNKNOWN;
  }

  //
  // First check to see if File is from a Firmware Volume
  //
  DeviceHandle   = NULL;
  TempDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)File;
  Status         = gBS->LocateDevicePath (
                          &gEfiFirmwareVolume2ProtocolGuid,
                          &TempDevicePath,
                          &DeviceHandle
                          );
  if (!EFI_ERROR (Status)) {
    Status = gBS->OpenProtocol (
                    DeviceHandle,
                    &gEfiFirmwareVolume2ProtocolGuid,
                    NULL,
                    NULL,
                    NULL,
                    EFI_OPEN_PROTOCOL_TEST_PROTOCOL
                    );
    if (!EFI_ERROR (Status)) {
      return IMAGE_FROM_FV;
    }
  }

  //
  // Next check to see if File is from a Block I/O device
  //
  DeviceHandle   = NULL;
  TempDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)File;
  Status         = gBS->LocateDevicePath (
                          &gEfiBlockIoProtocolGuid,
                          &TempDevicePath,
                          &DeviceHandle
                          );
  if (!EFI_ERROR (Status)) {
    BlockIo = NULL;
    Status  = gBS->OpenProtocol (
                     DeviceHandle,
                     &gEfiBlockIoProtocolGuid,
                     (VOID **)&BlockIo,
                     NULL,
                     NULL,
                     EFI_OPEN_PROTOCOL_GET_PROTOCOL
                     );
    if (!EFI_ERROR (Status) && (BlockIo != NULL)) {
      if (BlockIo->Media != NULL) {
        if (BlockIo->Media->RemovableMedia) {
          //
          // Block I/O is present and specifies the media is removable
          //
          return IMAGE_FROM_REMOVABLE_MEDIA;
        } else {
          //
          // Block I/O is present and specifies the media is not removable
          //
          return IMAGE_FROM_FIXED_MEDIA;
        }
      }
    }
  }

  //
  // File is not in a Firmware Volume or on a Block I/O device, so check to see if
  // the device path supports the Simple File System Protocol.
  //
  DeviceHandle   = NULL;
  TempDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)File;
  Status         = gBS->LocateDevicePath (
                          &gEfiSimpleFileSystemProtocolGuid,
                          &TempDevicePath,
                          &DeviceHandle
                          );
  if (!EFI_ERROR (Status)) {
    //
    // Simple File System is present without Block I/O, so assume media is fixed.
    //
    return IMAGE_FROM_FIXED_MEDIA;
  }

  //
  // File is not from an FV, Block I/O or Simple File System, so the only options
  // left are a PCI Option ROM and a Load File Protocol such as a PXE Boot from a NIC.
  //
  TempDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)File;
  while (!IsDevicePathEndType (TempDevicePath)) {
    switch (DevicePathType (TempDevicePath)) {
      case MEDIA_DEVICE_PATH:
        if (DevicePathSubType (TempDevicePath) == MEDIA_RELATIVE_OFFSET_RANGE_DP) {
          return IMAGE_FROM_OPTION_ROM;
        }

        break;

      case MESSAGING_DEVICE_PATH:
        if (DevicePathSubType (TempDevicePath) == MSG_MAC_ADDR_DP) {
          return IMAGE_FROM_REMOVABLE_MEDIA;
        }

        break;

      default:
        break;
    }

    TempDevicePath = NextDevicePathNode (TempDevicePath);
  }

  return IMAGE_UNKNOWN;
}

/**
  Calculate hash of Pe/Coff image based on the authenticode image hashing in
  PE/COFF Specification 8.0 Appendix A

  Caution: This function may receive untrusted input.
  PE/COFF image is external input, so this function will validate its data structure
  within this image buffer before use.

  Notes: PE/COFF image has been checked by BasePeCoffLib PeCoffLoaderGetImageInfo() in
  its caller function DxeImageVerificationHandler().

  @param[in]    HashAlg   Hash algorithm type.

  @retval TRUE            Successfully hash image.
  @retval FALSE           Fail in hash image.

**/
BOOLEAN
HashPeImage (
  IN  UINT32  HashAlg
  )
{
  BOOLEAN                   Status;
  EFI_IMAGE_SECTION_HEADER  *Section;
  VOID                      *HashCtx;
  UINTN                     CtxSize;
  UINT8                     *HashBase;
  UINTN                     HashSize;
  UINTN                     SumOfBytesHashed;
  EFI_IMAGE_SECTION_HEADER  *SectionHeader;
  UINTN                     Index;
  UINTN                     Pos;
  UINT32                    CertSize;
  UINT32                    NumberOfRvaAndSizes;

  HashCtx       = NULL;
  SectionHeader = NULL;
  Status        = FALSE;

  if ((HashAlg >= HASHALG_MAX)) {
    return FALSE;
  }

  //
  // Initialize context of hash.
  //
  ZeroMem (mImageDigest, MAX_DIGEST_SIZE);

  switch (HashAlg) {
 #ifndef DISABLE_SHA1_DEPRECATED_INTERFACES
    case HASHALG_SHA1:
      mImageDigestSize = SHA1_DIGEST_SIZE;
      mCertType        = gEfiCertSha1Guid;
      break;
 #endif

    case HASHALG_SHA256:
      mImageDigestSize = SHA256_DIGEST_SIZE;
      mCertType        = gEfiCertSha256Guid;
      break;

    case HASHALG_SHA384:
      mImageDigestSize = SHA384_DIGEST_SIZE;
      mCertType        = gEfiCertSha384Guid;
      break;

    case HASHALG_SHA512:
      mImageDigestSize = SHA512_DIGEST_SIZE;
      mCertType        = gEfiCertSha512Guid;
      break;

    default:
      return FALSE;
  }

  mHashTypeStr = mHash[HashAlg].Name;
  CtxSize      = mHash[HashAlg].GetContextSize ();

  HashCtx = AllocatePool (CtxSize);
  if (HashCtx == NULL) {
    return FALSE;
  }

  // 1.  Load the image header into memory.

  // 2.  Initialize a SHA hash context.
  Status = mHash[HashAlg].HashInit (HashCtx);

  if (!Status) {
    goto Done;
  }

  //
  // Measuring PE/COFF Image Header;
  // But CheckSum field and SECURITY data directory (certificate) are excluded
  //

  //
  // 3.  Calculate the distance from the base of the image header to the image checksum address.
  // 4.  Hash the image header from its base to beginning of the image checksum.
  //
  HashBase = mImageBase;
  if (mNtHeader.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
    //
    // Use PE32 offset.
    //
    HashSize            = (UINTN)(&mNtHeader.Pe32->OptionalHeader.CheckSum) - (UINTN)HashBase;
    NumberOfRvaAndSizes = mNtHeader.Pe32->OptionalHeader.NumberOfRvaAndSizes;
  } else if (mNtHeader.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
    //
    // Use PE32+ offset.
    //
    HashSize            = (UINTN)(&mNtHeader.Pe32Plus->OptionalHeader.CheckSum) - (UINTN)HashBase;
    NumberOfRvaAndSizes = mNtHeader.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes;
  } else {
    //
    // Invalid header magic number.
    //
    Status = FALSE;
    goto Done;
  }

  Status = mHash[HashAlg].HashUpdate (HashCtx, HashBase, HashSize);
  if (!Status) {
    goto Done;
  }

  //
  // 5.  Skip over the image checksum (it occupies a single ULONG).
  //
  if (NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_SECURITY) {
    //
    // 6.  Since there is no Cert Directory in optional header, hash everything
    //     from the end of the checksum to the end of image header.
    //
    if (mNtHeader.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
      //
      // Use PE32 offset.
      //
      HashBase = (UINT8 *)&mNtHeader.Pe32->OptionalHeader.CheckSum + sizeof (UINT32);
      HashSize = mNtHeader.Pe32->OptionalHeader.SizeOfHeaders - ((UINTN)HashBase - (UINTN)mImageBase);
    } else {
      //
      // Use PE32+ offset.
      //
      HashBase = (UINT8 *)&mNtHeader.Pe32Plus->OptionalHeader.CheckSum + sizeof (UINT32);
      HashSize = mNtHeader.Pe32Plus->OptionalHeader.SizeOfHeaders - ((UINTN)HashBase - (UINTN)mImageBase);
    }

    if (HashSize != 0) {
      Status = mHash[HashAlg].HashUpdate (HashCtx, HashBase, HashSize);
      if (!Status) {
        goto Done;
      }
    }
  } else {
    //
    // 7.  Hash everything from the end of the checksum to the start of the Cert Directory.
    //
    if (mNtHeader.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
      //
      // Use PE32 offset.
      //
      HashBase = (UINT8 *)&mNtHeader.Pe32->OptionalHeader.CheckSum + sizeof (UINT32);
      HashSize = (UINTN)(&mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - (UINTN)HashBase;
    } else {
      //
      // Use PE32+ offset.
      //
      HashBase = (UINT8 *)&mNtHeader.Pe32Plus->OptionalHeader.CheckSum + sizeof (UINT32);
      HashSize = (UINTN)(&mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - (UINTN)HashBase;
    }

    if (HashSize != 0) {
      Status = mHash[HashAlg].HashUpdate (HashCtx, HashBase, HashSize);
      if (!Status) {
        goto Done;
      }
    }

    //
    // 8.  Skip over the Cert Directory. (It is sizeof(IMAGE_DATA_DIRECTORY) bytes.)
    // 9.  Hash everything from the end of the Cert Directory to the end of image header.
    //
    if (mNtHeader.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
      //
      // Use PE32 offset
      //
      HashBase = (UINT8 *)&mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1];
      HashSize = mNtHeader.Pe32->OptionalHeader.SizeOfHeaders - ((UINTN)HashBase - (UINTN)mImageBase);
    } else {
      //
      // Use PE32+ offset.
      //
      HashBase = (UINT8 *)&mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1];
      HashSize = mNtHeader.Pe32Plus->OptionalHeader.SizeOfHeaders - ((UINTN)HashBase - (UINTN)mImageBase);
    }

    if (HashSize != 0) {
      Status = mHash[HashAlg].HashUpdate (HashCtx, HashBase, HashSize);
      if (!Status) {
        goto Done;
      }
    }
  }

  //
  // 10. Set the SUM_OF_BYTES_HASHED to the size of the header.
  //
  if (mNtHeader.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
    //
    // Use PE32 offset.
    //
    SumOfBytesHashed = mNtHeader.Pe32->OptionalHeader.SizeOfHeaders;
  } else {
    //
    // Use PE32+ offset
    //
    SumOfBytesHashed = mNtHeader.Pe32Plus->OptionalHeader.SizeOfHeaders;
  }

  Section = (EFI_IMAGE_SECTION_HEADER *)(
                                         mImageBase +
                                         mPeCoffHeaderOffset +
                                         sizeof (UINT32) +
                                         sizeof (EFI_IMAGE_FILE_HEADER) +
                                         mNtHeader.Pe32->FileHeader.SizeOfOptionalHeader
                                         );

  //
  // 11. Build a temporary table of pointers to all the IMAGE_SECTION_HEADER
  //     structures in the image. The 'NumberOfSections' field of the image
  //     header indicates how big the table should be. Do not include any
  //     IMAGE_SECTION_HEADERs in the table whose 'SizeOfRawData' field is zero.
  //
  SectionHeader = (EFI_IMAGE_SECTION_HEADER *)AllocateZeroPool (sizeof (EFI_IMAGE_SECTION_HEADER) * mNtHeader.Pe32->FileHeader.NumberOfSections);
  if (SectionHeader == NULL) {
    Status = FALSE;
    goto Done;
  }

  //
  // 12.  Using the 'PointerToRawData' in the referenced section headers as
  //      a key, arrange the elements in the table in ascending order. In other
  //      words, sort the section headers according to the disk-file offset of
  //      the section.
  //
  for (Index = 0; Index < mNtHeader.Pe32->FileHeader.NumberOfSections; Index++) {
    Pos = Index;
    while ((Pos > 0) && (Section->PointerToRawData < SectionHeader[Pos - 1].PointerToRawData)) {
      CopyMem (&SectionHeader[Pos], &SectionHeader[Pos - 1], sizeof (EFI_IMAGE_SECTION_HEADER));
      Pos--;
    }

    CopyMem (&SectionHeader[Pos], Section, sizeof (EFI_IMAGE_SECTION_HEADER));
    Section += 1;
  }

  //
  // 13.  Walk through the sorted table, bring the corresponding section
  //      into memory, and hash the entire section (using the 'SizeOfRawData'
  //      field in the section header to determine the amount of data to hash).
  // 14.  Add the section's 'SizeOfRawData' to SUM_OF_BYTES_HASHED .
  // 15.  Repeat steps 13 and 14 for all the sections in the sorted table.
  //
  for (Index = 0; Index < mNtHeader.Pe32->FileHeader.NumberOfSections; Index++) {
    Section = &SectionHeader[Index];
    if (Section->SizeOfRawData == 0) {
      continue;
    }

    HashBase = mImageBase + Section->PointerToRawData;
    HashSize = (UINTN)Section->SizeOfRawData;

    Status = mHash[HashAlg].HashUpdate (HashCtx, HashBase, HashSize);
    if (!Status) {
      goto Done;
    }

    SumOfBytesHashed += HashSize;
  }

  //
  // 16.  If the file size is greater than SUM_OF_BYTES_HASHED, there is extra
  //      data in the file that needs to be added to the hash. This data begins
  //      at file offset SUM_OF_BYTES_HASHED and its length is:
  //             FileSize  -  (CertDirectory->Size)
  //
  if (mImageSize > SumOfBytesHashed) {
    HashBase = mImageBase + SumOfBytesHashed;

    if (NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_SECURITY) {
      CertSize = 0;
    } else {
      if (mNtHeader.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
        //
        // Use PE32 offset.
        //
        CertSize = mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size;
      } else {
        //
        // Use PE32+ offset.
        //
        CertSize = mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size;
      }
    }

    if (mImageSize > CertSize + SumOfBytesHashed) {
      HashSize = (UINTN)(mImageSize - CertSize - SumOfBytesHashed);

      Status = mHash[HashAlg].HashUpdate (HashCtx, HashBase, HashSize);
      if (!Status) {
        goto Done;
      }
    } else if (mImageSize < CertSize + SumOfBytesHashed) {
      Status = FALSE;
      goto Done;
    }
  }

  Status = mHash[HashAlg].HashFinal (HashCtx, mImageDigest);

Done:
  if (HashCtx != NULL) {
    FreePool (HashCtx);
  }

  if (SectionHeader != NULL) {
    FreePool (SectionHeader);
  }

  return Status;
}

/**
  Recognize the Hash algorithm in PE/COFF Authenticode and calculate hash of
  Pe/Coff image based on the authenticode image hashing in PE/COFF Specification
  8.0 Appendix A

  Caution: This function may receive untrusted input.
  PE/COFF image is external input, so this function will validate its data structure
  within this image buffer before use.

  @param[in]  AuthData            Pointer to the Authenticode Signature retrieved from signed image.
  @param[in]  AuthDataSize        Size of the Authenticode Signature in bytes.

  @retval EFI_UNSUPPORTED             Hash algorithm is not supported.
  @retval EFI_BAD_BUFFER_SIZE         AuthData provided is invalid size.
  @retval EFI_SUCCESS                 Hash successfully.

**/
EFI_STATUS
HashPeImageByType (
  IN UINT8  *AuthData,
  IN UINTN  AuthDataSize
  )
{
  UINT8  Index;

  //
  // Check the Hash algorithm in PE/COFF Authenticode.
  //    According to PKCS#7 Definition:
  //        SignedData ::= SEQUENCE {
  //            version Version,
  //            digestAlgorithms DigestAlgorithmIdentifiers,
  //            contentInfo ContentInfo,
  //            .... }
  //    The DigestAlgorithmIdentifiers can be used to determine the hash algorithm in PE/COFF hashing
  //    This field has the fixed offset (+32) in final Authenticode ASN.1 data.
  //    Fixed offset (+32) is calculated based on two bytes of length encoding.
  //
  if ((AuthDataSize > 1) && ((*(AuthData + 1) & TWO_BYTE_ENCODE) != TWO_BYTE_ENCODE)) {
    //
    // Only support two bytes of Long Form of Length Encoding.
    //
    return EFI_BAD_BUFFER_SIZE;
  }

  for (Index = 0; Index < HASHALG_MAX; Index++) {
    if (AuthDataSize < 32 + mHash[Index].OidLength) {
      continue;
    }

    if (CompareMem (AuthData + 32, mHash[Index].OidValue, mHash[Index].OidLength) == 0) {
      break;
    }
  }

  if (Index == HASHALG_MAX) {
    return EFI_UNSUPPORTED;
  }

  //
  // HASH PE Image based on Hash algorithm in PE/COFF Authenticode.
  //
  if (!HashPeImage (Index)) {
    return EFI_UNSUPPORTED;
  }

  return EFI_SUCCESS;
}

/**
  Returns the size of a given image execution info table in bytes.

  This function returns the size, in bytes, of the image execution info table specified by
  ImageExeInfoTable. If ImageExeInfoTable is NULL, then 0 is returned.

  @param  ImageExeInfoTable          A pointer to a image execution info table structure.

  @retval 0       If ImageExeInfoTable is NULL.
  @retval Others  The size of a image execution info table in bytes.

**/
UINTN
GetImageExeInfoTableSize (
  EFI_IMAGE_EXECUTION_INFO_TABLE  *ImageExeInfoTable
  )
{
  UINTN                     Index;
  EFI_IMAGE_EXECUTION_INFO  *ImageExeInfoItem;
  UINTN                     TotalSize;

  if (ImageExeInfoTable == NULL) {
    return 0;
  }

  ImageExeInfoItem = (EFI_IMAGE_EXECUTION_INFO *)((UINT8 *)ImageExeInfoTable + sizeof (EFI_IMAGE_EXECUTION_INFO_TABLE));
  TotalSize        = sizeof (EFI_IMAGE_EXECUTION_INFO_TABLE);
  for (Index = 0; Index < ImageExeInfoTable->NumberOfImages; Index++) {
    TotalSize       += ReadUnaligned32 ((UINT32 *)&ImageExeInfoItem->InfoSize);
    ImageExeInfoItem = (EFI_IMAGE_EXECUTION_INFO *)((UINT8 *)ImageExeInfoItem + ReadUnaligned32 ((UINT32 *)&ImageExeInfoItem->InfoSize));
  }

  return TotalSize;
}

/**
  Create an Image Execution Information Table entry and add it to system configuration table.

  @param[in]  Action          Describes the action taken by the firmware regarding this image.
  @param[in]  Name            Input a null-terminated, user-friendly name.
  @param[in]  DevicePath      Input device path pointer.
  @param[in]  Signature       Input signature info in EFI_SIGNATURE_LIST data structure.
  @param[in]  SignatureSize   Size of signature. Must be zero if Signature is NULL.

**/
VOID
AddImageExeInfo (
  IN       EFI_IMAGE_EXECUTION_ACTION  Action,
  IN       CHAR16                      *Name OPTIONAL,
  IN CONST EFI_DEVICE_PATH_PROTOCOL    *DevicePath,
  IN       EFI_SIGNATURE_LIST          *Signature OPTIONAL,
  IN       UINTN                       SignatureSize
  )
{
  EFI_IMAGE_EXECUTION_INFO_TABLE  *ImageExeInfoTable;
  EFI_IMAGE_EXECUTION_INFO_TABLE  *NewImageExeInfoTable;
  EFI_IMAGE_EXECUTION_INFO        *ImageExeInfoEntry;
  UINTN                           ImageExeInfoTableSize;
  UINTN                           NewImageExeInfoEntrySize;
  UINTN                           NameStringLen;
  UINTN                           DevicePathSize;
  CHAR16                          *NameStr;

  ImageExeInfoTable    = NULL;
  NewImageExeInfoTable = NULL;
  ImageExeInfoEntry    = NULL;
  NameStringLen        = 0;
  NameStr              = NULL;

  if (DevicePath == NULL) {
    return;
  }

  if (Name != NULL) {
    NameStringLen = StrSize (Name);
  } else {
    NameStringLen = sizeof (CHAR16);
  }

  EfiGetSystemConfigurationTable (&gEfiImageSecurityDatabaseGuid, (VOID **)&ImageExeInfoTable);
  if (ImageExeInfoTable != NULL) {
    //
    // The table has been found!
    // We must enlarge the table to accommodate the new exe info entry.
    //
    ImageExeInfoTableSize = GetImageExeInfoTableSize (ImageExeInfoTable);
  } else {
    //
    // Not Found!
    // We should create a new table to append to the configuration table.
    //
    ImageExeInfoTableSize = sizeof (EFI_IMAGE_EXECUTION_INFO_TABLE);
  }

  DevicePathSize = GetDevicePathSize (DevicePath);

  //
  // Signature size can be odd. Pad after signature to ensure next EXECUTION_INFO entry align
  //
  ASSERT (Signature != NULL || SignatureSize == 0);
  NewImageExeInfoEntrySize = sizeof (EFI_IMAGE_EXECUTION_INFO) + NameStringLen + DevicePathSize + SignatureSize;

  NewImageExeInfoTable = (EFI_IMAGE_EXECUTION_INFO_TABLE *)AllocateRuntimePool (ImageExeInfoTableSize + NewImageExeInfoEntrySize);
  if (NewImageExeInfoTable == NULL) {
    return;
  }

  if (ImageExeInfoTable != NULL) {
    CopyMem (NewImageExeInfoTable, ImageExeInfoTable, ImageExeInfoTableSize);
  } else {
    NewImageExeInfoTable->NumberOfImages = 0;
  }

  NewImageExeInfoTable->NumberOfImages++;
  ImageExeInfoEntry = (EFI_IMAGE_EXECUTION_INFO *)((UINT8 *)NewImageExeInfoTable + ImageExeInfoTableSize);
  //
  // Update new item's information.
  //
  WriteUnaligned32 ((UINT32 *)ImageExeInfoEntry, Action);
  WriteUnaligned32 ((UINT32 *)((UINT8 *)ImageExeInfoEntry + sizeof (EFI_IMAGE_EXECUTION_ACTION)), (UINT32)NewImageExeInfoEntrySize);

  NameStr = (CHAR16 *)(ImageExeInfoEntry + 1);
  if (Name != NULL) {
    CopyMem ((UINT8 *)NameStr, Name, NameStringLen);
  } else {
    ZeroMem ((UINT8 *)NameStr, sizeof (CHAR16));
  }

  CopyMem (
    (UINT8 *)NameStr + NameStringLen,
    DevicePath,
    DevicePathSize
    );
  if (Signature != NULL) {
    CopyMem (
      (UINT8 *)NameStr + NameStringLen + DevicePathSize,
      Signature,
      SignatureSize
      );
  }

  //
  // Update/replace the image execution table.
  //
  gBS->InstallConfigurationTable (&gEfiImageSecurityDatabaseGuid, (VOID *)NewImageExeInfoTable);

  //
  // Free Old table data!
  //
  if (ImageExeInfoTable != NULL) {
    FreePool (ImageExeInfoTable);
  }
}

/**
  Check whether the hash of an given X.509 certificate is in forbidden database (DBX).

  @param[in]  Certificate       Pointer to X.509 Certificate that is searched for.
  @param[in]  CertSize          Size of X.509 Certificate.
  @param[in]  SignatureList     Pointer to the Signature List in forbidden database.
  @param[in]  SignatureListSize Size of Signature List.
  @param[out] RevocationTime    Return the time that the certificate was revoked.
  @param[out] IsFound           Search result. Only valid if EFI_SUCCESS returned.

  @retval EFI_SUCCESS           Finished the search without any error.
  @retval Others                Error occurred in the search of database.

**/
EFI_STATUS
IsCertHashFoundInDbx (
  IN  UINT8               *Certificate,
  IN  UINTN               CertSize,
  IN  EFI_SIGNATURE_LIST  *SignatureList,
  IN  UINTN               SignatureListSize,
  OUT EFI_TIME            *RevocationTime,
  OUT BOOLEAN             *IsFound
  )
{
  EFI_STATUS          Status;
  EFI_SIGNATURE_LIST  *DbxList;
  UINTN               DbxSize;
  EFI_SIGNATURE_DATA  *CertHash;
  UINTN               CertHashCount;
  UINTN               Index;
  UINT32              HashAlg;
  VOID                *HashCtx;
  UINT8               CertDigest[MAX_DIGEST_SIZE];
  UINT8               *DbxCertHash;
  UINTN               SiglistHeaderSize;
  UINT8               *TBSCert;
  UINTN               TBSCertSize;

  Status   = EFI_ABORTED;
  *IsFound = FALSE;
  DbxList  = SignatureList;
  DbxSize  = SignatureListSize;
  HashCtx  = NULL;
  HashAlg  = HASHALG_MAX;

  if ((RevocationTime == NULL) || (DbxList == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Retrieve the TBSCertificate from the X.509 Certificate.
  //
  if (!X509GetTBSCert (Certificate, CertSize, &TBSCert, &TBSCertSize)) {
    return Status;
  }

  while ((DbxSize > 0) && (SignatureListSize >= DbxList->SignatureListSize)) {
    //
    // Determine Hash Algorithm of Certificate in the forbidden database.
    //
    if (CompareGuid (&DbxList->SignatureType, &gEfiCertX509Sha256Guid)) {
      HashAlg = HASHALG_SHA256;
    } else if (CompareGuid (&DbxList->SignatureType, &gEfiCertX509Sha384Guid)) {
      HashAlg = HASHALG_SHA384;
    } else if (CompareGuid (&DbxList->SignatureType, &gEfiCertX509Sha512Guid)) {
      HashAlg = HASHALG_SHA512;
    } else {
      DbxSize -= DbxList->SignatureListSize;
      DbxList  = (EFI_SIGNATURE_LIST *)((UINT8 *)DbxList + DbxList->SignatureListSize);
      continue;
    }

    //
    // Calculate the hash value of current TBSCertificate for comparision.
    //
    if (mHash[HashAlg].GetContextSize == NULL) {
      goto Done;
    }

    ZeroMem (CertDigest, MAX_DIGEST_SIZE);
    HashCtx = AllocatePool (mHash[HashAlg].GetContextSize ());
    if (HashCtx == NULL) {
      goto Done;
    }

    if (!mHash[HashAlg].HashInit (HashCtx)) {
      goto Done;
    }

    if (!mHash[HashAlg].HashUpdate (HashCtx, TBSCert, TBSCertSize)) {
      goto Done;
    }

    if (!mHash[HashAlg].HashFinal (HashCtx, CertDigest)) {
      goto Done;
    }

    FreePool (HashCtx);
    HashCtx = NULL;

    SiglistHeaderSize = sizeof (EFI_SIGNATURE_LIST) + DbxList->SignatureHeaderSize;
    CertHash          = (EFI_SIGNATURE_DATA *)((UINT8 *)DbxList + SiglistHeaderSize);
    CertHashCount     = (DbxList->SignatureListSize - SiglistHeaderSize) / DbxList->SignatureSize;
    for (Index = 0; Index < CertHashCount; Index++) {
      //
      // Iterate each Signature Data Node within this CertList for verify.
      //
      DbxCertHash = CertHash->SignatureData;
      if (CompareMem (DbxCertHash, CertDigest, mHash[HashAlg].DigestLength) == 0) {
        //
        // Hash of Certificate is found in forbidden database.
        //
        Status   = EFI_SUCCESS;
        *IsFound = TRUE;

        //
        // Return the revocation time.
        //
        CopyMem (RevocationTime, (EFI_TIME *)(DbxCertHash + mHash[HashAlg].DigestLength), sizeof (EFI_TIME));
        goto Done;
      }

      CertHash = (EFI_SIGNATURE_DATA *)((UINT8 *)CertHash + DbxList->SignatureSize);
    }

    DbxSize -= DbxList->SignatureListSize;
    DbxList  = (EFI_SIGNATURE_LIST *)((UINT8 *)DbxList + DbxList->SignatureListSize);
  }

  Status = EFI_SUCCESS;

Done:
  if (HashCtx != NULL) {
    FreePool (HashCtx);
  }

  return Status;
}

/**
  Check whether signature is in specified database.

  @param[in]  VariableName        Name of database variable that is searched in.
  @param[in]  Signature           Pointer to signature that is searched for.
  @param[in]  CertType            Pointer to hash algorithm.
  @param[in]  SignatureSize       Size of Signature.
  @param[out] IsFound             Search result. Only valid if EFI_SUCCESS returned

  @retval EFI_SUCCESS             Finished the search without any error.
  @retval Others                  Error occurred in the search of database.

**/
EFI_STATUS
IsSignatureFoundInDatabase (
  IN  CHAR16    *VariableName,
  IN  UINT8     *Signature,
  IN  EFI_GUID  *CertType,
  IN  UINTN     SignatureSize,
  OUT BOOLEAN   *IsFound
  )
{
  EFI_STATUS          Status;
  EFI_SIGNATURE_LIST  *CertList;
  EFI_SIGNATURE_DATA  *Cert;
  UINTN               DataSize;
  UINT8               *Data;
  UINTN               Index;
  UINTN               CertCount;

  //
  // Read signature database variable.
  //
  *IsFound = FALSE;
  Data     = NULL;
  DataSize = 0;
  Status   = gRT->GetVariable (VariableName, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, NULL);
  if (Status != EFI_BUFFER_TOO_SMALL) {
    if (Status == EFI_NOT_FOUND) {
      //
      // No database, no need to search.
      //
      Status = EFI_SUCCESS;
    }

    return Status;
  }

  Data = (UINT8 *)AllocateZeroPool (DataSize);
  if (Data == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Status = gRT->GetVariable (VariableName, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, Data);
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  //
  // Enumerate all signature data in SigDB to check if signature exists for executable.
  //
  CertList = (EFI_SIGNATURE_LIST *)Data;
  while ((DataSize > 0) && (DataSize >= CertList->SignatureListSize)) {
    CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;
    Cert      = (EFI_SIGNATURE_DATA *)((UINT8 *)CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
    if ((CertList->SignatureSize == sizeof (EFI_SIGNATURE_DATA) - 1 + SignatureSize) && (CompareGuid (&CertList->SignatureType, CertType))) {
      for (Index = 0; Index < CertCount; Index++) {
        if (CompareMem (Cert->SignatureData, Signature, SignatureSize) == 0) {
          //
          // Find the signature in database.
          //
          *IsFound = TRUE;
          //
          // Entries in UEFI_IMAGE_SECURITY_DATABASE that are used to validate image should be measured
          //
          if (StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE) == 0) {
            SecureBootHook (VariableName, &gEfiImageSecurityDatabaseGuid, CertList->SignatureSize, Cert);
          }

          break;
        }

        Cert = (EFI_SIGNATURE_DATA *)((UINT8 *)Cert + CertList->SignatureSize);
      }

      if (*IsFound) {
        break;
      }
    }

    DataSize -= CertList->SignatureListSize;
    CertList  = (EFI_SIGNATURE_LIST *)((UINT8 *)CertList + CertList->SignatureListSize);
  }

Done:
  if (Data != NULL) {
    FreePool (Data);
  }

  return Status;
}

/**
  Check whether the timestamp is valid by comparing the signing time and the revocation time.

  @param SigningTime         A pointer to the signing time.
  @param RevocationTime      A pointer to the revocation time.

  @retval  TRUE              The SigningTime is not later than the RevocationTime.
  @retval  FALSE             The SigningTime is later than the RevocationTime.

**/
BOOLEAN
IsValidSignatureByTimestamp (
  IN EFI_TIME  *SigningTime,
  IN EFI_TIME  *RevocationTime
  )
{
  if (SigningTime->Year != RevocationTime->Year) {
    return (BOOLEAN)(SigningTime->Year < RevocationTime->Year);
  } else if (SigningTime->Month != RevocationTime->Month) {
    return (BOOLEAN)(SigningTime->Month < RevocationTime->Month);
  } else if (SigningTime->Day != RevocationTime->Day) {
    return (BOOLEAN)(SigningTime->Day < RevocationTime->Day);
  } else if (SigningTime->Hour != RevocationTime->Hour) {
    return (BOOLEAN)(SigningTime->Hour < RevocationTime->Hour);
  } else if (SigningTime->Minute != RevocationTime->Minute) {
    return (BOOLEAN)(SigningTime->Minute < RevocationTime->Minute);
  }

  return (BOOLEAN)(SigningTime->Second <= RevocationTime->Second);
}

/**
  Check if the given time value is zero.

  @param[in]  Time      Pointer of a time value.

  @retval     TRUE      The Time is Zero.
  @retval     FALSE     The Time is not Zero.

**/
BOOLEAN
IsTimeZero (
  IN EFI_TIME  *Time
  )
{
  if ((Time->Year == 0) && (Time->Month == 0) &&  (Time->Day == 0) &&
      (Time->Hour == 0) && (Time->Minute == 0) && (Time->Second == 0))
  {
    return TRUE;
  }

  return FALSE;
}

/**
  Check whether the timestamp signature is valid and the signing time is also earlier than
  the revocation time.

  @param[in]  AuthData        Pointer to the Authenticode signature retrieved from signed image.
  @param[in]  AuthDataSize    Size of the Authenticode signature in bytes.
  @param[in]  RevocationTime  The time that the certificate was revoked.

  @retval TRUE      Timestamp signature is valid and signing time is no later than the
                    revocation time.
  @retval FALSE     Timestamp signature is not valid or the signing time is later than the
                    revocation time.

**/
BOOLEAN
PassTimestampCheck (
  IN UINT8     *AuthData,
  IN UINTN     AuthDataSize,
  IN EFI_TIME  *RevocationTime
  )
{
  EFI_STATUS          Status;
  BOOLEAN             VerifyStatus;
  EFI_SIGNATURE_LIST  *CertList;
  EFI_SIGNATURE_DATA  *Cert;
  UINT8               *DbtData;
  UINTN               DbtDataSize;
  UINT8               *RootCert;
  UINTN               RootCertSize;
  UINTN               Index;
  UINTN               CertCount;
  EFI_TIME            SigningTime;

  //
  // Variable Initialization
  //
  VerifyStatus = FALSE;
  DbtData      = NULL;
  CertList     = NULL;
  Cert         = NULL;
  RootCert     = NULL;
  RootCertSize = 0;

  //
  // If RevocationTime is zero, the certificate shall be considered to always be revoked.
  //
  if (IsTimeZero (RevocationTime)) {
    return FALSE;
  }

  //
  // RevocationTime is non-zero, the certificate should be considered to be revoked from that time and onwards.
  // Using the dbt to get the trusted TSA certificates.
  //
  DbtDataSize = 0;
  Status      = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE2, &gEfiImageSecurityDatabaseGuid, NULL, &DbtDataSize, NULL);
  if (Status != EFI_BUFFER_TOO_SMALL) {
    goto Done;
  }

  DbtData = (UINT8 *)AllocateZeroPool (DbtDataSize);
  if (DbtData == NULL) {
    goto Done;
  }

  Status = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE2, &gEfiImageSecurityDatabaseGuid, NULL, &DbtDataSize, (VOID *)DbtData);
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  CertList = (EFI_SIGNATURE_LIST *)DbtData;
  while ((DbtDataSize > 0) && (DbtDataSize >= CertList->SignatureListSize)) {
    if (CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid)) {
      Cert      = (EFI_SIGNATURE_DATA *)((UINT8 *)CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
      CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;
      for (Index = 0; Index < CertCount; Index++) {
        //
        // Iterate each Signature Data Node within this CertList for verify.
        //
        RootCert     = Cert->SignatureData;
        RootCertSize = CertList->SignatureSize - sizeof (EFI_GUID);
        //
        // Get the signing time if the timestamp signature is valid.
        //
        if (ImageTimestampVerify (AuthData, AuthDataSize, RootCert, RootCertSize, &SigningTime)) {
          //
          // The signer signature is valid only when the signing time is earlier than revocation time.
          //
          if (IsValidSignatureByTimestamp (&SigningTime, RevocationTime)) {
            VerifyStatus = TRUE;
            goto Done;
          }
        }

        Cert = (EFI_SIGNATURE_DATA *)((UINT8 *)Cert + CertList->SignatureSize);
      }
    }

    DbtDataSize -= CertList->SignatureListSize;
    CertList     = (EFI_SIGNATURE_LIST *)((UINT8 *)CertList + CertList->SignatureListSize);
  }

Done:
  if (DbtData != NULL) {
    FreePool (DbtData);
  }

  return VerifyStatus;
}

/**
  Check whether the image signature is forbidden by the forbidden database (dbx).
  The image is forbidden to load if any certificates for signing are revoked before signing time.

  @param[in]  AuthData      Pointer to the Authenticode signature retrieved from the signed image.
  @param[in]  AuthDataSize  Size of the Authenticode signature in bytes.

  @retval TRUE              Image is forbidden by dbx.
  @retval FALSE             Image is not forbidden by dbx.

**/
BOOLEAN
IsForbiddenByDbx (
  IN UINT8  *AuthData,
  IN UINTN  AuthDataSize
  )
{
  EFI_STATUS          Status;
  BOOLEAN             IsForbidden;
  BOOLEAN             IsFound;
  UINT8               *Data;
  UINTN               DataSize;
  EFI_SIGNATURE_LIST  *CertList;
  UINTN               CertListSize;
  EFI_SIGNATURE_DATA  *CertData;
  UINT8               *RootCert;
  UINTN               RootCertSize;
  UINTN               CertCount;
  UINTN               Index;
  UINT8               *CertBuffer;
  UINTN               BufferLength;
  UINT8               *TrustedCert;
  UINTN               TrustedCertLength;
  UINT8               CertNumber;
  UINT8               *CertPtr;
  UINT8               *Cert;
  UINTN               CertSize;
  EFI_TIME            RevocationTime;

  //
  // Variable Initialization
  //
  IsForbidden       = TRUE;
  Data              = NULL;
  CertList          = NULL;
  CertData          = NULL;
  RootCert          = NULL;
  RootCertSize      = 0;
  Cert              = NULL;
  CertBuffer        = NULL;
  BufferLength      = 0;
  TrustedCert       = NULL;
  TrustedCertLength = 0;

  //
  // The image will not be forbidden if dbx can't be got.
  //
  DataSize = 0;
  Status   = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, NULL);
  ASSERT (EFI_ERROR (Status));
  if (Status != EFI_BUFFER_TOO_SMALL) {
    if (Status == EFI_NOT_FOUND) {
      //
      // Evidently not in dbx if the database doesn't exist.
      //
      IsForbidden = FALSE;
    }

    return IsForbidden;
  }

  Data = (UINT8 *)AllocateZeroPool (DataSize);
  if (Data == NULL) {
    return IsForbidden;
  }

  Status = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, (VOID *)Data);
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  //
  // Verify image signature with RAW X509 certificates in DBX database.
  // If passed, the image will be forbidden.
  //
  CertList     = (EFI_SIGNATURE_LIST *)Data;
  CertListSize = DataSize;
  while ((CertListSize > 0) && (CertListSize >= CertList->SignatureListSize)) {
    if (CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid)) {
      CertData  = (EFI_SIGNATURE_DATA *)((UINT8 *)CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
      CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;

      for (Index = 0; Index < CertCount; Index++) {
        //
        // Iterate each Signature Data Node within this CertList for verify.
        //
        RootCert     = CertData->SignatureData;
        RootCertSize = CertList->SignatureSize - sizeof (EFI_GUID);

        //
        // Call AuthenticodeVerify library to Verify Authenticode struct.
        //
        IsForbidden = AuthenticodeVerify (
                        AuthData,
                        AuthDataSize,
                        RootCert,
                        RootCertSize,
                        mImageDigest,
                        mImageDigestSize
                        );
        if (IsForbidden) {
          DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Image is signed but signature is forbidden by DBX.\n"));
          goto Done;
        }

        CertData = (EFI_SIGNATURE_DATA *)((UINT8 *)CertData + CertList->SignatureSize);
      }
    }

    CertListSize -= CertList->SignatureListSize;
    CertList      = (EFI_SIGNATURE_LIST *)((UINT8 *)CertList + CertList->SignatureListSize);
  }

  //
  // Check X.509 Certificate Hash & Possible Timestamp.
  //

  //
  // Retrieve the certificate stack from AuthData
  // The output CertStack format will be:
  //       UINT8  CertNumber;
  //       UINT32 Cert1Length;
  //       UINT8  Cert1[];
  //       UINT32 Cert2Length;
  //       UINT8  Cert2[];
  //       ...
  //       UINT32 CertnLength;
  //       UINT8  Certn[];
  //
  Pkcs7GetSigners (AuthData, AuthDataSize, &CertBuffer, &BufferLength, &TrustedCert, &TrustedCertLength);
  if ((BufferLength == 0) || (CertBuffer == NULL) || ((*CertBuffer) == 0)) {
    IsForbidden = TRUE;
    goto Done;
  }

  //
  // Check if any hash of certificates embedded in AuthData is in the forbidden database.
  //
  CertNumber = (UINT8)(*CertBuffer);
  CertPtr    = CertBuffer + 1;
  for (Index = 0; Index < CertNumber; Index++) {
    CertSize = (UINTN)ReadUnaligned32 ((UINT32 *)CertPtr);
    Cert     = (UINT8 *)CertPtr + sizeof (UINT32);
    //
    // Advance CertPtr to the next cert in image signer's cert list
    //
    CertPtr = CertPtr + sizeof (UINT32) + CertSize;

    Status = IsCertHashFoundInDbx (Cert, CertSize, (EFI_SIGNATURE_LIST *)Data, DataSize, &RevocationTime, &IsFound);
    if (EFI_ERROR (Status)) {
      //
      // Error in searching dbx. Consider it as 'found'. RevocationTime might
      // not be valid in such situation.
      //
      IsForbidden = TRUE;
    } else if (IsFound) {
      //
      // Found Cert in dbx successfully. Check the timestamp signature and
      // signing time to determine if the image can be trusted.
      //
      if (PassTimestampCheck (AuthData, AuthDataSize, &RevocationTime)) {
        IsForbidden = FALSE;
        //
        // Pass DBT check. Continue to check other certs in image signer's cert list against DBX, DBT
        //
        continue;
      } else {
        IsForbidden = TRUE;
        DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Image is signed but signature failed the timestamp check.\n"));
        goto Done;
      }
    }
  }

  IsForbidden = FALSE;

Done:
  if (Data != NULL) {
    FreePool (Data);
  }

  Pkcs7FreeSigners (CertBuffer);
  Pkcs7FreeSigners (TrustedCert);

  return IsForbidden;
}

/**
  Check whether the image signature can be verified by the trusted certificates in DB database.

  @param[in]  AuthData      Pointer to the Authenticode signature retrieved from signed image.
  @param[in]  AuthDataSize  Size of the Authenticode signature in bytes.

  @retval TRUE         Image passed verification using certificate in db.
  @retval FALSE        Image didn't pass verification using certificate in db.

**/
BOOLEAN
IsAllowedByDb (
  IN UINT8  *AuthData,
  IN UINTN  AuthDataSize
  )
{
  EFI_STATUS          Status;
  BOOLEAN             VerifyStatus;
  BOOLEAN             IsFound;
  EFI_SIGNATURE_LIST  *CertList;
  EFI_SIGNATURE_DATA  *CertData;
  UINTN               DataSize;
  UINT8               *Data;
  UINT8               *RootCert;
  UINTN               RootCertSize;
  UINTN               Index;
  UINTN               CertCount;
  UINTN               DbxDataSize;
  UINT8               *DbxData;
  EFI_TIME            RevocationTime;

  Data         = NULL;
  CertList     = NULL;
  CertData     = NULL;
  RootCert     = NULL;
  DbxData      = NULL;
  RootCertSize = 0;
  VerifyStatus = FALSE;

  //
  // Fetch 'db' content. If 'db' doesn't exist or encounters problem to get the
  // data, return not-allowed-by-db (FALSE).
  //
  DataSize = 0;
  Status   = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, NULL);
  ASSERT (EFI_ERROR (Status));
  if (Status != EFI_BUFFER_TOO_SMALL) {
    return VerifyStatus;
  }

  Data = (UINT8 *)AllocateZeroPool (DataSize);
  if (Data == NULL) {
    return VerifyStatus;
  }

  Status = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE, &gEfiImageSecurityDatabaseGuid, NULL, &DataSize, (VOID *)Data);
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  //
  // Fetch 'dbx' content. If 'dbx' doesn't exist, continue to check 'db'.
  // If any other errors occurred, no need to check 'db' but just return
  // not-allowed-by-db (FALSE) to avoid bypass.
  //
  DbxDataSize = 0;
  Status      = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid, NULL, &DbxDataSize, NULL);
  ASSERT (EFI_ERROR (Status));
  if (Status != EFI_BUFFER_TOO_SMALL) {
    if (Status != EFI_NOT_FOUND) {
      goto Done;
    }

    //
    // 'dbx' does not exist. Continue to check 'db'.
    //
  } else {
    //
    // 'dbx' exists. Get its content.
    //
    DbxData = (UINT8 *)AllocateZeroPool (DbxDataSize);
    if (DbxData == NULL) {
      goto Done;
    }

    Status = gRT->GetVariable (EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid, NULL, &DbxDataSize, (VOID *)DbxData);
    if (EFI_ERROR (Status)) {
      goto Done;
    }
  }

  //
  // Find X509 certificate in Signature List to verify the signature in pkcs7 signed data.
  //
  CertList = (EFI_SIGNATURE_LIST *)Data;
  while ((DataSize > 0) && (DataSize >= CertList->SignatureListSize)) {
    if (CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid)) {
      CertData  = (EFI_SIGNATURE_DATA *)((UINT8 *)CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
      CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;

      for (Index = 0; Index < CertCount; Index++) {
        //
        // Iterate each Signature Data Node within this CertList for verify.
        //
        RootCert     = CertData->SignatureData;
        RootCertSize = CertList->SignatureSize - sizeof (EFI_GUID);

        //
        // Call AuthenticodeVerify library to Verify Authenticode struct.
        //
        VerifyStatus = AuthenticodeVerify (
                         AuthData,
                         AuthDataSize,
                         RootCert,
                         RootCertSize,
                         mImageDigest,
                         mImageDigestSize
                         );
        if (VerifyStatus) {
          //
          // The image is signed and its signature is found in 'db'.
          //
          if (DbxData != NULL) {
            //
            // Here We still need to check if this RootCert's Hash is revoked
            //
            Status = IsCertHashFoundInDbx (RootCert, RootCertSize, (EFI_SIGNATURE_LIST *)DbxData, DbxDataSize, &RevocationTime, &IsFound);
            if (EFI_ERROR (Status)) {
              //
              // Error in searching dbx. Consider it as 'found'. RevocationTime might
              // not be valid in such situation.
              //
              VerifyStatus = FALSE;
            } else if (IsFound) {
              //
              // Check the timestamp signature and signing time to determine if the RootCert can be trusted.
              //
              VerifyStatus = PassTimestampCheck (AuthData, AuthDataSize, &RevocationTime);
              if (!VerifyStatus) {
                DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Image is signed and signature is accepted by DB, but its root cert failed the timestamp check.\n"));
              }
            }
          }

          //
          // There's no 'dbx' to check revocation time against (must-be pass),
          // or, there's revocation time found in 'dbx' and checked againt 'dbt'
          // (maybe pass or fail, depending on timestamp compare result). Either
          // way the verification job has been completed at this point.
          //
          goto Done;
        }

        CertData = (EFI_SIGNATURE_DATA *)((UINT8 *)CertData + CertList->SignatureSize);
      }
    }

    DataSize -= CertList->SignatureListSize;
    CertList  = (EFI_SIGNATURE_LIST *)((UINT8 *)CertList + CertList->SignatureListSize);
  }

Done:

  if (VerifyStatus) {
    SecureBootHook (EFI_IMAGE_SECURITY_DATABASE, &gEfiImageSecurityDatabaseGuid, CertList->SignatureSize, CertData);
  }

  if (Data != NULL) {
    FreePool (Data);
  }

  if (DbxData != NULL) {
    FreePool (DbxData);
  }

  return VerifyStatus;
}

/**
  Provide verification service for signed images, which include both signature validation
  and platform policy control. For signature types, both UEFI WIN_CERTIFICATE_UEFI_GUID and
  MSFT Authenticode type signatures are supported.

  In this implementation, only verify external executables when in USER MODE.
  Executables from FV is bypass, so pass in AuthenticationStatus is ignored.

  The image verification policy is:
    If the image is signed,
      At least one valid signature or at least one hash value of the image must match a record
      in the security database "db", and no valid signature nor any hash value of the image may
      be reflected in the security database "dbx".
    Otherwise, the image is not signed,
      The hash value of the image must match a record in the security database "db", and
      not be reflected in the security data base "dbx".

  Caution: This function may receive untrusted input.
  PE/COFF image is external input, so this function will validate its data structure
  within this image buffer before use.

  @param[in]    AuthenticationStatus
                           This is the authentication status returned from the security
                           measurement services for the input file.
  @param[in]    File       This is a pointer to the device path of the file that is
                           being dispatched. This will optionally be used for logging.
  @param[in]    FileBuffer File buffer matches the input file device path.
  @param[in]    FileSize   Size of File buffer matches the input file device path.
  @param[in]    BootPolicy A boot policy that was used to call LoadImage() UEFI service.

  @retval EFI_SUCCESS            The file specified by DevicePath and non-NULL
                                 FileBuffer did authenticate, and the platform policy dictates
                                 that the DXE Foundation may use the file.
  @retval EFI_SUCCESS            The device path specified by NULL device path DevicePath
                                 and non-NULL FileBuffer did authenticate, and the platform
                                 policy dictates that the DXE Foundation may execute the image in
                                 FileBuffer.
  @retval EFI_SECURITY_VIOLATION The file specified by File did not authenticate, and
                                 the platform policy dictates that File should be placed
                                 in the untrusted state. The image has been added to the file
                                 execution table.
  @retval EFI_ACCESS_DENIED      The file specified by File and FileBuffer did not
                                 authenticate, and the platform policy dictates that the DXE
                                 Foundation may not use File. The image has
                                 been added to the file execution table.

**/
EFI_STATUS
EFIAPI
DxeImageVerificationHandler (
  IN  UINT32                          AuthenticationStatus,
  IN  CONST EFI_DEVICE_PATH_PROTOCOL  *File  OPTIONAL,
  IN  VOID                            *FileBuffer,
  IN  UINTN                           FileSize,
  IN  BOOLEAN                         BootPolicy
  )
{
  EFI_IMAGE_DOS_HEADER          *DosHdr;
  BOOLEAN                       IsVerified;
  EFI_SIGNATURE_LIST            *SignatureList;
  UINTN                         SignatureListSize;
  EFI_SIGNATURE_DATA            *Signature;
  EFI_IMAGE_EXECUTION_ACTION    Action;
  WIN_CERTIFICATE               *WinCertificate;
  UINT32                        Policy;
  UINT8                         SecureBoot;
  UINTN                         SecureBootSize;
  PE_COFF_LOADER_IMAGE_CONTEXT  ImageContext;
  UINT32                        NumberOfRvaAndSizes;
  WIN_CERTIFICATE_EFI_PKCS      *PkcsCertData;
  WIN_CERTIFICATE_UEFI_GUID     *WinCertUefiGuid;
  UINT8                         *AuthData;
  UINTN                         AuthDataSize;
  EFI_IMAGE_DATA_DIRECTORY      *SecDataDir;
  UINT32                        SecDataDirEnd;
  UINT32                        SecDataDirLeft;
  UINT32                        OffSet;
  CHAR16                        *NameStr;
  RETURN_STATUS                 PeCoffStatus;
  EFI_STATUS                    HashStatus;
  EFI_STATUS                    DbStatus;
  EFI_STATUS                    VarStatus;
  UINT32                        VarAttr;
  BOOLEAN                       IsFound;
  UINT8                         HashAlg;
  BOOLEAN                       IsFoundInDatabase;

  SignatureList     = NULL;
  SignatureListSize = 0;
  WinCertificate    = NULL;
  SecDataDir        = NULL;
  PkcsCertData      = NULL;
  Action            = EFI_IMAGE_EXECUTION_AUTH_UNTESTED;
  IsVerified        = FALSE;
  IsFound           = FALSE;
  IsFoundInDatabase = FALSE;

  //
  // Sanity check:
  // Ensure that either File or FileBuffer is provided.
  // Return EFI_INVALID_PARAMETER if both are NULL.
  // This prevents security verification from proceeding
  // when no valid input buffer is available.
  //
  if ((File == NULL) && (FileBuffer == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Check the image type and get policy setting.
  //
  switch (GetImageType (File)) {
    case IMAGE_FROM_FV:
      Policy = ALWAYS_EXECUTE;
      break;

    case IMAGE_FROM_OPTION_ROM:
      Policy = PcdGet32 (PcdOptionRomImageVerificationPolicy);
      break;

    case IMAGE_FROM_REMOVABLE_MEDIA:
      Policy = PcdGet32 (PcdRemovableMediaImageVerificationPolicy);
      break;

    case IMAGE_FROM_FIXED_MEDIA:
      Policy = PcdGet32 (PcdFixedMediaImageVerificationPolicy);
      break;

    default:
      Policy = DENY_EXECUTE_ON_SECURITY_VIOLATION;
      break;
  }

  //
  // If policy is always/never execute, return directly.
  //
  if (Policy == ALWAYS_EXECUTE) {
    return EFI_SUCCESS;
  }

  if (Policy == NEVER_EXECUTE) {
    return EFI_ACCESS_DENIED;
  }

  //
  // The policy QUERY_USER_ON_SECURITY_VIOLATION and ALLOW_EXECUTE_ON_SECURITY_VIOLATION
  // violates the UEFI spec and has been removed.
  //
  ASSERT (Policy != QUERY_USER_ON_SECURITY_VIOLATION && Policy != ALLOW_EXECUTE_ON_SECURITY_VIOLATION);
  if ((Policy == QUERY_USER_ON_SECURITY_VIOLATION) || (Policy == ALLOW_EXECUTE_ON_SECURITY_VIOLATION)) {
    CpuDeadLoop ();
  }

  SecureBootSize = sizeof (SecureBoot);
  VarStatus      = gRT->GetVariable (EFI_SECURE_BOOT_MODE_NAME, &gEfiGlobalVariableGuid, &VarAttr, &SecureBootSize, &SecureBoot);
  //
  // Skip verification if SecureBoot variable doesn't exist.
  //
  if (VarStatus == EFI_NOT_FOUND) {
    return EFI_SUCCESS;
  }

  //
  // Skip verification if SecureBoot is disabled but not AuditMode
  //
  if ((VarStatus == EFI_SUCCESS) &&
      (VarAttr == (EFI_VARIABLE_BOOTSERVICE_ACCESS |
                   EFI_VARIABLE_RUNTIME_ACCESS)) &&
      (SecureBoot == SECURE_BOOT_MODE_DISABLE))
  {
    return EFI_SUCCESS;
  }

  //
  // Read the Dos header.
  //
  if (FileBuffer == NULL) {
    return EFI_ACCESS_DENIED;
  }

  mImageBase = (UINT8 *)FileBuffer;
  mImageSize = FileSize;

  ZeroMem (&ImageContext, sizeof (ImageContext));
  ImageContext.Handle    = (VOID *)FileBuffer;
  ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE)DxeImageVerificationLibImageRead;

  //
  // Get information about the image being loaded
  //
  PeCoffStatus = PeCoffLoaderGetImageInfo (&ImageContext);
  if (RETURN_ERROR (PeCoffStatus)) {
    //
    // The information can't be got from the invalid PeImage
    //
    DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: PeImage invalid. Cannot retrieve image information.\n"));
    goto Failed;
  }

  DosHdr = (EFI_IMAGE_DOS_HEADER *)mImageBase;
  if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {
    //
    // DOS image header is present,
    // so read the PE header after the DOS image header.
    //
    mPeCoffHeaderOffset = DosHdr->e_lfanew;
  } else {
    mPeCoffHeaderOffset = 0;
  }

  //
  // Check PE/COFF image.
  //
  mNtHeader.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)(mImageBase + mPeCoffHeaderOffset);
  if (mNtHeader.Pe32->Signature != EFI_IMAGE_NT_SIGNATURE) {
    //
    // It is not a valid Pe/Coff file.
    //
    DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Not a valid PE/COFF image.\n"));
    goto Failed;
  }

  if (mNtHeader.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
    //
    // Use PE32 offset.
    //
    NumberOfRvaAndSizes = mNtHeader.Pe32->OptionalHeader.NumberOfRvaAndSizes;
    if (NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_SECURITY) {
      SecDataDir = (EFI_IMAGE_DATA_DIRECTORY *)&mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY];
    }
  } else {
    //
    // Use PE32+ offset.
    //
    NumberOfRvaAndSizes = mNtHeader.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes;
    if (NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_SECURITY) {
      SecDataDir = (EFI_IMAGE_DATA_DIRECTORY *)&mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY];
    }
  }

  //
  // Start Image Validation.
  //
  if ((SecDataDir == NULL) || (SecDataDir->Size == 0)) {
    //
    // This image is not signed. The hash value of the image must match a record in the security database "db",
    // and not be reflected in the security data base "dbx".
    //
    HashAlg = sizeof (mHash) / sizeof (HASH_TABLE);
    while (HashAlg > 0) {
      HashAlg--;
      if ((mHash[HashAlg].GetContextSize == NULL) || (mHash[HashAlg].HashInit == NULL) || (mHash[HashAlg].HashUpdate == NULL) || (mHash[HashAlg].HashFinal == NULL)) {
        continue;
      }

      if (!HashPeImage (HashAlg)) {
        continue;
      }

      DbStatus = IsSignatureFoundInDatabase (
                   EFI_IMAGE_SECURITY_DATABASE1,
                   mImageDigest,
                   &mCertType,
                   mImageDigestSize,
                   &IsFound
                   );
      if (EFI_ERROR (DbStatus) || IsFound) {
        //
        // Image Hash is in forbidden database (DBX).
        //
        DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Image is not signed and %s hash of image is forbidden by DBX.\n", mHashTypeStr));
        goto Failed;
      }

      DbStatus = IsSignatureFoundInDatabase (
                   EFI_IMAGE_SECURITY_DATABASE,
                   mImageDigest,
                   &mCertType,
                   mImageDigestSize,
                   &IsFound
                   );
      if (!EFI_ERROR (DbStatus) && IsFound) {
        //
        // Image Hash is in allowed database (DB).
        //
        IsFoundInDatabase = TRUE;
      }
    }

    if (IsFoundInDatabase) {
      return EFI_SUCCESS;
    }

    //
    // Image Hash is not found in both forbidden and allowed database.
    //
    DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Image is not signed and %s hash of image is not found in DB/DBX.\n", mHashTypeStr));
    goto Failed;
  }

  //
  // Verify the signature of the image, multiple signatures are allowed as per PE/COFF Section 4.7
  // "Attribute Certificate Table".
  // The first certificate starts at offset (SecDataDir->VirtualAddress) from the start of the file.
  //
  SecDataDirEnd = SecDataDir->VirtualAddress + SecDataDir->Size;
  for (OffSet = SecDataDir->VirtualAddress;
       OffSet < SecDataDirEnd;
       OffSet += (WinCertificate->dwLength + ALIGN_SIZE (WinCertificate->dwLength)))
  {
    SecDataDirLeft = SecDataDirEnd - OffSet;
    if (SecDataDirLeft <= sizeof (WIN_CERTIFICATE)) {
      break;
    }

    WinCertificate = (WIN_CERTIFICATE *)(mImageBase + OffSet);
    if ((SecDataDirLeft < WinCertificate->dwLength) ||
        (SecDataDirLeft - WinCertificate->dwLength <
         ALIGN_SIZE (WinCertificate->dwLength)))
    {
      break;
    }

    //
    // Verify the image's Authenticode signature, only DER-encoded PKCS#7 signed data is supported.
    //
    if (WinCertificate->wCertificateType == WIN_CERT_TYPE_PKCS_SIGNED_DATA) {
      //
      // The certificate is formatted as WIN_CERTIFICATE_EFI_PKCS which is described in the
      // Authenticode specification.
      //
      PkcsCertData = (WIN_CERTIFICATE_EFI_PKCS *)WinCertificate;
      if (PkcsCertData->Hdr.dwLength <= sizeof (PkcsCertData->Hdr)) {
        break;
      }

      AuthData     = PkcsCertData->CertData;
      AuthDataSize = PkcsCertData->Hdr.dwLength - sizeof (PkcsCertData->Hdr);
    } else if (WinCertificate->wCertificateType == WIN_CERT_TYPE_EFI_GUID) {
      //
      // The certificate is formatted as WIN_CERTIFICATE_UEFI_GUID which is described in UEFI Spec.
      //
      WinCertUefiGuid = (WIN_CERTIFICATE_UEFI_GUID *)WinCertificate;
      if (WinCertUefiGuid->Hdr.dwLength <= OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData)) {
        break;
      }

      if (!CompareGuid (&WinCertUefiGuid->CertType, &gEfiCertPkcs7Guid)) {
        continue;
      }

      AuthData     = WinCertUefiGuid->CertData;
      AuthDataSize = WinCertUefiGuid->Hdr.dwLength - OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData);
    } else {
      if (WinCertificate->dwLength < sizeof (WIN_CERTIFICATE)) {
        break;
      }

      continue;
    }

    HashStatus = HashPeImageByType (AuthData, AuthDataSize);
    if (EFI_ERROR (HashStatus)) {
      continue;
    }

    //
    // Check the digital signature against the revoked certificate in forbidden database (dbx).
    //
    if (IsForbiddenByDbx (AuthData, AuthDataSize)) {
      Action     = EFI_IMAGE_EXECUTION_AUTH_SIG_FAILED;
      IsVerified = FALSE;
      break;
    }

    //
    // Check the digital signature against the valid certificate in allowed database (db).
    //
    if (!IsVerified) {
      if (IsAllowedByDb (AuthData, AuthDataSize)) {
        IsVerified = TRUE;
      }
    }

    //
    // Check the image's hash value.
    //
    DbStatus = IsSignatureFoundInDatabase (
                 EFI_IMAGE_SECURITY_DATABASE1,
                 mImageDigest,
                 &mCertType,
                 mImageDigestSize,
                 &IsFound
                 );
    if (EFI_ERROR (DbStatus) || IsFound) {
      Action = EFI_IMAGE_EXECUTION_AUTH_SIG_FOUND;
      DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Image is signed but %s hash of image is found in DBX.\n", mHashTypeStr));
      IsVerified = FALSE;
      break;
    }

    if (!IsVerified) {
      DbStatus = IsSignatureFoundInDatabase (
                   EFI_IMAGE_SECURITY_DATABASE,
                   mImageDigest,
                   &mCertType,
                   mImageDigestSize,
                   &IsFound
                   );
      if (!EFI_ERROR (DbStatus) && IsFound) {
        IsVerified = TRUE;
      } else {
        Action = EFI_IMAGE_EXECUTION_AUTH_SIG_NOT_FOUND;
        DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Image is signed but signature is not allowed by DB and %s hash of image is not found in DB/DBX.\n", mHashTypeStr));
      }
    }
  }

  if (OffSet != SecDataDirEnd) {
    //
    // The Size in Certificate Table or the attribute certificate table is corrupted.
    //
    IsVerified = FALSE;
  }

  if (IsVerified) {
    return EFI_SUCCESS;
  }

  if ((Action == EFI_IMAGE_EXECUTION_AUTH_SIG_FAILED) || (Action == EFI_IMAGE_EXECUTION_AUTH_SIG_FOUND)) {
    //
    // Get image hash value as signature of executable.
    //
    SignatureListSize = sizeof (EFI_SIGNATURE_LIST) + sizeof (EFI_SIGNATURE_DATA) - 1 + mImageDigestSize;
    SignatureList     = (EFI_SIGNATURE_LIST *)AllocateZeroPool (SignatureListSize);
    if (SignatureList == NULL) {
      SignatureListSize = 0;
      goto Failed;
    }

    SignatureList->SignatureHeaderSize = 0;
    SignatureList->SignatureListSize   = (UINT32)SignatureListSize;
    SignatureList->SignatureSize       = (UINT32)(sizeof (EFI_SIGNATURE_DATA) - 1 + mImageDigestSize);
    CopyMem (&SignatureList->SignatureType, &mCertType, sizeof (EFI_GUID));
    Signature = (EFI_SIGNATURE_DATA *)((UINT8 *)SignatureList + sizeof (EFI_SIGNATURE_LIST));
    CopyMem (Signature->SignatureData, mImageDigest, mImageDigestSize);
  }

Failed:
  //
  // Policy decides to defer or reject the image; add its information in image
  // executable information table in either case.
  //
  NameStr = ConvertDevicePathToText (File, FALSE, TRUE);
  AddImageExeInfo (Action, NameStr, File, SignatureList, SignatureListSize);
  if (NameStr != NULL) {
    DEBUG ((DEBUG_INFO, "The image doesn't pass verification: %s\n", NameStr));
    FreePool (NameStr);
  }

  if (SignatureList != NULL) {
    FreePool (SignatureList);
  }

  if (Policy == DEFER_EXECUTE_ON_SECURITY_VIOLATION) {
    return EFI_SECURITY_VIOLATION;
  }

  return EFI_ACCESS_DENIED;
}

/**
  On Ready To Boot Services Event notification handler.

  Add the image execution information table if it is not in system configuration table.

  @param[in]  Event     Event whose notification function is being invoked
  @param[in]  Context   Pointer to the notification function's context

**/
VOID
EFIAPI
OnReadyToBoot (
  IN      EFI_EVENT  Event,
  IN      VOID       *Context
  )
{
  EFI_IMAGE_EXECUTION_INFO_TABLE  *ImageExeInfoTable;
  UINTN                           ImageExeInfoTableSize;

  EfiGetSystemConfigurationTable (&gEfiImageSecurityDatabaseGuid, (VOID **)&ImageExeInfoTable);
  if (ImageExeInfoTable != NULL) {
    return;
  }

  ImageExeInfoTableSize = sizeof (EFI_IMAGE_EXECUTION_INFO_TABLE);
  ImageExeInfoTable     = (EFI_IMAGE_EXECUTION_INFO_TABLE *)AllocateRuntimePool (ImageExeInfoTableSize);
  if (ImageExeInfoTable == NULL) {
    return;
  }

  ImageExeInfoTable->NumberOfImages = 0;
  gBS->InstallConfigurationTable (&gEfiImageSecurityDatabaseGuid, (VOID *)ImageExeInfoTable);
}

/**
  Register security measurement handler.

  @param  ImageHandle   ImageHandle of the loaded driver.
  @param  SystemTable   Pointer to the EFI System Table.

  @retval EFI_SUCCESS   The handlers were registered successfully.
**/
EFI_STATUS
EFIAPI
DxeImageVerificationLibConstructor (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_EVENT  Event;

  //
  // Register the event to publish the image execution table.
  //
  EfiCreateEventReadyToBootEx (
    TPL_CALLBACK,
    OnReadyToBoot,
    NULL,
    &Event
    );

  return RegisterSecurity2Handler (
           DxeImageVerificationHandler,
           EFI_AUTH_OPERATION_VERIFY_IMAGE | EFI_AUTH_OPERATION_IMAGE_REQUIRED
           );
}
