/** @file
  Implement defer image load services for user identification in UEFI2.2.

Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/
#include "Defer3rdPartyImageLoad.h"

//
// The structure to save the deferred 3rd party image information.
//
typedef struct {
  EFI_DEVICE_PATH_PROTOCOL    *ImageDevicePath;
  BOOLEAN                     BootOption;
  BOOLEAN                     Loaded;
} DEFERRED_3RD_PARTY_IMAGE_INFO;

//
// The table to save the deferred 3rd party image item.
//
typedef struct {
  UINTN                            Count;          ///< deferred 3rd party image count
  DEFERRED_3RD_PARTY_IMAGE_INFO    *ImageInfo;     ///< deferred 3rd party image item
} DEFERRED_3RD_PARTY_IMAGE_TABLE;

BOOLEAN                         mImageLoadedAfterEndOfDxe = FALSE;
BOOLEAN                         mEndOfDxe                 = FALSE;
DEFERRED_3RD_PARTY_IMAGE_TABLE  mDeferred3rdPartyImage    = {
  0,       // Deferred image count
  NULL     // The deferred image info
};

EFI_DEFERRED_IMAGE_LOAD_PROTOCOL  mDeferredImageLoad = {
  GetDefferedImageInfo
};

/**
  Return whether the file comes from FV.

  @param[in]    File    This is a pointer to the device path of the file
                        that is being dispatched.

  @retval TRUE  File comes from FV.
  @retval FALSE File doesn't come from FV.
**/
BOOLEAN
FileFromFv (
  IN  CONST EFI_DEVICE_PATH_PROTOCOL  *File
  )
{
  EFI_STATUS                Status;
  EFI_HANDLE                DeviceHandle;
  EFI_DEVICE_PATH_PROTOCOL  *TempDevicePath;

  //
  // 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 TRUE;
    }
  }

  return FALSE;
}

/**
  Find the deferred image which matches the device path.

  @param[in]  ImageDevicePath  A pointer to the device path of a image.
  @param[in]  BootOption       Whether the image is a boot option.

  @return Pointer to the found deferred image or NULL if not found.
**/
DEFERRED_3RD_PARTY_IMAGE_INFO *
LookupImage (
  IN  CONST EFI_DEVICE_PATH_PROTOCOL  *ImageDevicePath,
  IN        BOOLEAN                   BootOption
  )
{
  UINTN  Index;
  UINTN  DevicePathSize;

  DevicePathSize = GetDevicePathSize (ImageDevicePath);

  for (Index = 0; Index < mDeferred3rdPartyImage.Count; Index++) {
    if (CompareMem (ImageDevicePath, mDeferred3rdPartyImage.ImageInfo[Index].ImageDevicePath, DevicePathSize) == 0) {
      ASSERT (mDeferred3rdPartyImage.ImageInfo[Index].BootOption == BootOption);
      return &mDeferred3rdPartyImage.ImageInfo[Index];
    }
  }

  return NULL;
}

/**
  Add the image info to a deferred image list.

  @param[in]  ImageDevicePath  A pointer to the device path of a image.
  @param[in]  BootOption       Whether the image is a boot option.

**/
VOID
QueueImage (
  IN  CONST EFI_DEVICE_PATH_PROTOCOL  *ImageDevicePath,
  IN        BOOLEAN                   BootOption
  )
{
  DEFERRED_3RD_PARTY_IMAGE_INFO  *ImageInfo;

  //
  // Expand memory for the new deferred image.
  //
  ImageInfo = ReallocatePool (
                mDeferred3rdPartyImage.Count * sizeof (DEFERRED_3RD_PARTY_IMAGE_INFO),
                (mDeferred3rdPartyImage.Count + 1) * sizeof (DEFERRED_3RD_PARTY_IMAGE_INFO),
                mDeferred3rdPartyImage.ImageInfo
                );
  if (ImageInfo == NULL) {
    return;
  }

  mDeferred3rdPartyImage.ImageInfo = ImageInfo;

  //
  // Save the deferred image information.
  //
  ImageInfo                  = &mDeferred3rdPartyImage.ImageInfo[mDeferred3rdPartyImage.Count];
  ImageInfo->ImageDevicePath = DuplicateDevicePath (ImageDevicePath);
  if (ImageInfo->ImageDevicePath == NULL) {
    return;
  }

  ImageInfo->BootOption = BootOption;
  ImageInfo->Loaded     = FALSE;
  mDeferred3rdPartyImage.Count++;
}

/**
  Returns information about a deferred image.

  This function returns information about a single deferred image. The deferred images are
  numbered consecutively, starting with 0.  If there is no image which corresponds to
  ImageIndex, then EFI_NOT_FOUND is returned. All deferred images may be returned by
  iteratively calling this function until EFI_NOT_FOUND is returned.
  Image may be NULL and ImageSize set to 0 if the decision to defer execution was made
  because of the location of the executable image, rather than its actual contents.

  @param[in]  This             Points to this instance of the EFI_DEFERRED_IMAGE_LOAD_PROTOCOL.
  @param[in]  ImageIndex       Zero-based index of the deferred index.
  @param[out] ImageDevicePath  On return, points to a pointer to the device path of the image.
                               The device path should not be freed by the caller.
  @param[out] Image            On return, points to the first byte of the image or NULL if the
                               image is not available. The image should not be freed by the caller
                               unless LoadImage() has been successfully called.
  @param[out] ImageSize        On return, the size of the image, or 0 if the image is not available.
  @param[out] BootOption       On return, points to TRUE if the image was intended as a boot option
                               or FALSE if it was not intended as a boot option.

  @retval EFI_SUCCESS           Image information returned successfully.
  @retval EFI_NOT_FOUND         ImageIndex does not refer to a valid image.
  @retval EFI_INVALID_PARAMETER ImageDevicePath is NULL or Image is NULL or ImageSize is NULL or
                                BootOption is NULL.

**/
EFI_STATUS
EFIAPI
GetDefferedImageInfo (
  IN     EFI_DEFERRED_IMAGE_LOAD_PROTOCOL  *This,
  IN     UINTN                             ImageIndex,
  OUT EFI_DEVICE_PATH_PROTOCOL             **ImageDevicePath,
  OUT VOID                                 **Image,
  OUT UINTN                                *ImageSize,
  OUT BOOLEAN                              *BootOption
  )
{
  UINTN  Index;
  UINTN  NewCount;

  if ((This == NULL) || (ImageSize == NULL) || (Image == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if ((ImageDevicePath == NULL) || (BootOption == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Remove the loaded images from the defer list in the first call.
  //
  if (ImageIndex == 0) {
    NewCount = 0;
    for (Index = 0; Index < mDeferred3rdPartyImage.Count; Index++) {
      if (!mDeferred3rdPartyImage.ImageInfo[Index].Loaded) {
        CopyMem (
          &mDeferred3rdPartyImage.ImageInfo[NewCount],
          &mDeferred3rdPartyImage.ImageInfo[Index],
          sizeof (DEFERRED_3RD_PARTY_IMAGE_INFO)
          );
        NewCount++;
      }
    }

    mDeferred3rdPartyImage.Count = NewCount;
  }

  if (ImageIndex >= mDeferred3rdPartyImage.Count) {
    return EFI_NOT_FOUND;
  }

  //
  // Get the request deferred image.
  //
  *ImageDevicePath = mDeferred3rdPartyImage.ImageInfo[ImageIndex].ImageDevicePath;
  *BootOption      = mDeferred3rdPartyImage.ImageInfo[ImageIndex].BootOption;
  *Image           = NULL;
  *ImageSize       = 0;

  return EFI_SUCCESS;
}

/**
  Callback function executed when the EndOfDxe event group is signaled.

  @param[in] Event      Event whose notification function is being invoked.
  @param[in] Context    The pointer to the notification function's context, which
                        is implementation-dependent.
**/
VOID
EFIAPI
EndOfDxe (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  )
{
  mEndOfDxe = TRUE;
}

/**
  Event notification for gEfiDxeSmmReadyToLockProtocolGuid event.

  This function reports failure if any deferred image is loaded before
  this callback.
  Platform should publish ReadyToLock protocol immediately after signaling
  of the End of DXE Event.

  @param  Event                 The Event that is being processed, not used.
  @param  Context               Event Context, not used.

**/
VOID
EFIAPI
DxeSmmReadyToLock (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  )
{
  EFI_STATUS  Status;
  VOID        *Interface;

  Status = gBS->LocateProtocol (&gEfiDxeSmmReadyToLockProtocolGuid, NULL, &Interface);
  if (EFI_ERROR (Status)) {
    return;
  }

  gBS->CloseEvent (Event);

  if (mImageLoadedAfterEndOfDxe) {
    //
    // Platform should not dispatch the 3rd party images after signaling EndOfDxe event
    // but before publishing DxeSmmReadyToLock protocol.
    //
    DEBUG ((
      DEBUG_ERROR,
      "[Security] 3rd party images must be dispatched after DxeSmmReadyToLock Protocol installation!\n"
      ));
    REPORT_STATUS_CODE (
      EFI_ERROR_CODE | EFI_ERROR_UNRECOVERED,
      (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_EC_ILLEGAL_SOFTWARE_STATE)
      );
    ASSERT (FALSE);
    CpuDeadLoop ();
  }
}

/**
  Defer the 3rd party image load and installs Deferred Image Load Protocol.

  @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]  BootPolicy            A boot policy that was used to call LoadImage() UEFI service.

  @retval EFI_SUCCESS               The file is not 3rd party image and can be loaded immediately.
  @retval EFI_ACCESS_DENIED         The file is 3rd party image and needs deferred.
**/
EFI_STATUS
Defer3rdPartyImageLoad (
  IN  CONST EFI_DEVICE_PATH_PROTOCOL  *File,
  IN  BOOLEAN                         BootPolicy
  )
{
  DEFERRED_3RD_PARTY_IMAGE_INFO  *ImageInfo;

  //
  // Ignore if File is NULL.
  //
  if (File == NULL) {
    return EFI_SUCCESS;
  }

  if (FileFromFv (File)) {
    return EFI_SUCCESS;
  }

  ImageInfo = LookupImage (File, BootPolicy);

  DEBUG_CODE_BEGIN ();
  CHAR16  *DevicePathStr;

  DevicePathStr = ConvertDevicePathToText (File, FALSE, FALSE);
  DEBUG ((
    DEBUG_INFO,
    "[Security] 3rd party image[%p] %s EndOfDxe: %s.\n",
    ImageInfo,
    mEndOfDxe ? L"can be loaded after" : L"is deferred to load before",
    DevicePathStr
    ));
  if (DevicePathStr != NULL) {
    FreePool (DevicePathStr);
  }

  DEBUG_CODE_END ();

  if (mEndOfDxe) {
    mImageLoadedAfterEndOfDxe = TRUE;
    //
    // The image might be first time loaded after EndOfDxe,
    // So ImageInfo can be NULL.
    //
    if (ImageInfo != NULL) {
      ImageInfo->Loaded = TRUE;
    }

    return EFI_SUCCESS;
  } else {
    //
    // The image might be second time loaded before EndOfDxe,
    // So ImageInfo can be non-NULL.
    //
    if (ImageInfo == NULL) {
      QueueImage (File, BootPolicy);
    }

    return EFI_ACCESS_DENIED;
  }
}

/**
  Installs DeferredImageLoad Protocol and listens EndOfDxe event.
**/
VOID
Defer3rdPartyImageLoadInitialize (
  VOID
  )
{
  EFI_STATUS  Status;
  EFI_HANDLE  Handle;
  EFI_EVENT   Event;
  VOID        *Registration;

  Handle = NULL;
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &Handle,
                  &gEfiDeferredImageLoadProtocolGuid,
                  &mDeferredImageLoad,
                  NULL
                  );
  ASSERT_EFI_ERROR (Status);

  Status = gBS->CreateEventEx (
                  EVT_NOTIFY_SIGNAL,
                  TPL_CALLBACK,
                  EndOfDxe,
                  NULL,
                  &gEfiEndOfDxeEventGroupGuid,
                  &Event
                  );
  ASSERT_EFI_ERROR (Status);

  EfiCreateProtocolNotifyEvent (
    &gEfiDxeSmmReadyToLockProtocolGuid,
    TPL_CALLBACK,
    DxeSmmReadyToLock,
    NULL,
    &Registration
    );
}
