/** @file
  This driver verifies and reports OBB FVs.

Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "FvReportPei.h"

STATIC CONST HASH_ALG_INFO  mHashAlgInfo[] = {
  { TPM_ALG_SHA256, SHA256_DIGEST_SIZE, Sha256Init, Sha256Update, Sha256Final, Sha256HashAll }, // 000B
  { TPM_ALG_SHA384, SHA384_DIGEST_SIZE, Sha384Init, Sha384Update, Sha384Final, Sha384HashAll }, // 000C
  { TPM_ALG_SHA512, SHA512_DIGEST_SIZE, Sha512Init, Sha512Update, Sha512Final, Sha512HashAll }, // 000D
};

/**
  Find hash algorithm information from mHashAlgInfo according to given ID.

  @param[in]  HashAlgId          Hash algorithm type id.

  @retval Pointer to HASH_ALG_INFO if given hash algorithm is supported.
  @retval NULL if given algorithm is not supported.
**/
STATIC
CONST
HASH_ALG_INFO *
FindHashAlgInfo (
  IN UINT16  HashAlgId
  )
{
  UINTN  Index;

  for (Index = 0; Index < ARRAY_SIZE (mHashAlgInfo); ++Index) {
    if (mHashAlgInfo[Index].HashAlgId == HashAlgId) {
      return &mHashAlgInfo[Index];
    }
  }

  return NULL;
}

/**
  Install a EDKII_PEI_FIRMWARE_VOLUME_INFO_PREHASHED_FV_PPI instance so that
  TCG driver may use to extend PCRs.

  @param[in]  FvBuffer            Buffer containing the whole FV.
  @param[in]  FvLength            Length of the FV.
  @param[in]  HashAlgoId          Hash algorithm type id.
  @param[in]  HashSize            Hash size.
  @param[in]  HashValue           Hash value buffer.
**/
STATIC
VOID
InstallPreHashFvPpi (
  IN VOID    *FvBuffer,
  IN UINTN   FvLength,
  IN UINT16  HashAlgoId,
  IN UINT16  HashSize,
  IN UINT8   *HashValue
  )
{
  EFI_STATUS                                       Status;
  EFI_PEI_PPI_DESCRIPTOR                           *FvInfoPpiDescriptor;
  EDKII_PEI_FIRMWARE_VOLUME_INFO_PREHASHED_FV_PPI  *PreHashedFvPpi;
  UINTN                                            PpiSize;
  HASH_INFO                                        *HashInfo;

  PpiSize = sizeof (EDKII_PEI_FIRMWARE_VOLUME_INFO_PREHASHED_FV_PPI)
            + sizeof (HASH_INFO)
            + HashSize;

  PreHashedFvPpi = AllocatePool (PpiSize);
  ASSERT (PreHashedFvPpi != NULL);

  PreHashedFvPpi->FvBase   = (UINT32)(UINTN)FvBuffer;
  PreHashedFvPpi->FvLength = (UINT32)FvLength;
  PreHashedFvPpi->Count    = 1;

  HashInfo             = HASH_INFO_PTR (PreHashedFvPpi);
  HashInfo->HashAlgoId = HashAlgoId;
  HashInfo->HashSize   = HashSize;
  CopyMem (HASH_VALUE_PTR (HashInfo), HashValue, HashSize);

  FvInfoPpiDescriptor = AllocatePool (sizeof (EFI_PEI_PPI_DESCRIPTOR));
  ASSERT (FvInfoPpiDescriptor != NULL);

  FvInfoPpiDescriptor->Guid  = &gEdkiiPeiFirmwareVolumeInfoPrehashedFvPpiGuid;
  FvInfoPpiDescriptor->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
  FvInfoPpiDescriptor->Ppi   = (VOID *)PreHashedFvPpi;

  Status = PeiServicesInstallPpi (FvInfoPpiDescriptor);
  ASSERT_EFI_ERROR (Status);
}

/**
  Calculate and verify hash value for given FV.

  @param[in]  HashInfo            Hash information of the FV.
  @param[in]  FvInfo              Information of FV used for verification.
  @param[in]  FvNumber            Length of the FV.
  @param[in]  BootMode            Length of the FV.

  @retval EFI_SUCCESS           The given FV is integrate.
  @retval EFI_VOLUME_CORRUPTED  The given FV is corrupted (hash mismatch).
  @retval EFI_UNSUPPORTED       The hash algorithm is not supported.
**/
STATIC
EFI_STATUS
VerifyHashedFv (
  IN FV_HASH_INFO    *HashInfo,
  IN HASHED_FV_INFO  *FvInfo,
  IN UINTN           FvNumber,
  IN EFI_BOOT_MODE   BootMode
  )
{
  UINTN                                 FvIndex;
  CONST HASH_ALG_INFO                   *AlgInfo;
  UINT8                                 *HashValue;
  UINT8                                 *FvHashValue;
  VOID                                  *FvBuffer;
  EDKII_PEI_FIRMWARE_VOLUME_SHADOW_PPI  *FvShadowPpi;
  EFI_STATUS                            Status;

  if ((HashInfo == NULL) ||
      (HashInfo->HashSize == 0) ||
      (HashInfo->HashAlgoId == TPM_ALG_NULL))
  {
    DEBUG ((DEBUG_INFO, "Bypass FV hash verification\r\n"));
    return EFI_SUCCESS;
  }

  AlgInfo = FindHashAlgInfo (HashInfo->HashAlgoId);
  if ((AlgInfo == NULL) || (AlgInfo->HashSize != HashInfo->HashSize)) {
    DEBUG ((
      DEBUG_ERROR,
      "Unsupported or wrong hash algorithm: %04X (size=%d)\r\n",
      HashInfo->HashAlgoId,
      HashInfo->HashSize
      ));
    return EFI_UNSUPPORTED;
  }

  ASSERT (FvInfo != NULL);
  ASSERT (FvNumber > 0);

  //
  // We need a hash value for each FV as well as one for all FVs.
  //
  HashValue = AllocateZeroPool (AlgInfo->HashSize * (FvNumber + 1));
  ASSERT (HashValue != NULL);

  //
  // Calculate hash value for each FV first.
  //
  FvHashValue = HashValue;
  for (FvIndex = 0; FvIndex < FvNumber; ++FvIndex) {
    //
    // Not meant for verified boot and/or measured boot?
    //
    if (((FvInfo[FvIndex].Flag & HASHED_FV_FLAG_VERIFIED_BOOT) == 0) &&
        ((FvInfo[FvIndex].Flag & HASHED_FV_FLAG_MEASURED_BOOT) == 0))
    {
      continue;
    }

    //
    // Skip any FV not meant for current boot mode.
    //
    if ((FvInfo[FvIndex].Flag & HASHED_FV_FLAG_SKIP_BOOT_MODE (BootMode)) != 0) {
      DEBUG ((
        DEBUG_INFO,
        "Skip FV[%016lX] for boot mode[%d]\r\n",
        FvInfo[FvIndex].Base,
        BootMode
        ));
      continue;
    }

    DEBUG ((
      DEBUG_INFO,
      "Pre-hashed[alg=%04X,size=%d,flag=%016lX] FV: 0x%016lX (%08lX) (Flag=%016lX)\r\n",
      HashInfo->HashAlgoId,
      HashInfo->HashSize,
      HashInfo->HashFlag,
      FvInfo[FvIndex].Base,
      FvInfo[FvIndex].Length,
      FvInfo[FvIndex].Flag
      ));

    //
    // Copy FV to permanent memory to avoid potential TOC/TOU.
    //
    FvBuffer = AllocatePages (EFI_SIZE_TO_PAGES ((UINTN)FvInfo[FvIndex].Length));

    ASSERT (FvBuffer != NULL);
    Status = PeiServicesLocatePpi (
               &gEdkiiPeiFirmwareVolumeShadowPpiGuid,
               0,
               NULL,
               (VOID **)&FvShadowPpi
               );

    if (!EFI_ERROR (Status)) {
      Status = FvShadowPpi->FirmwareVolumeShadow (
                              (EFI_PHYSICAL_ADDRESS)FvInfo[FvIndex].Base,
                              FvBuffer,
                              (UINTN)FvInfo[FvIndex].Length
                              );
    }

    if (EFI_ERROR (Status)) {
      CopyMem (
        FvBuffer,
        (CONST VOID *)(UINTN)FvInfo[FvIndex].Base,
        (UINTN)FvInfo[FvIndex].Length
        );
    }

    if (!AlgInfo->HashAll (FvBuffer, (UINTN)FvInfo[FvIndex].Length, FvHashValue)) {
      Status = EFI_ABORTED;
      goto Done;
    }

    //
    // Report the FV measurement.
    //
    if ((FvInfo[FvIndex].Flag & HASHED_FV_FLAG_MEASURED_BOOT) != 0) {
      InstallPreHashFvPpi (
        FvBuffer,
        (UINTN)FvInfo[FvIndex].Length,
        HashInfo->HashAlgoId,
        HashInfo->HashSize,
        FvHashValue
        );
    }

    //
    // Don't keep the hash value of current FV if we don't need to verify it.
    //
    if ((FvInfo[FvIndex].Flag & HASHED_FV_FLAG_VERIFIED_BOOT) != 0) {
      FvHashValue += AlgInfo->HashSize;
    }

    //
    // Use memory copy of the FV from now on.
    //
    FvInfo[FvIndex].Base = (UINT64)(UINTN)FvBuffer;
  }

  //
  // Check final hash for all FVs.
  //
  if ((FvHashValue == HashValue) ||
      (AlgInfo->HashAll (HashValue, FvHashValue - HashValue, FvHashValue) &&
       (CompareMem (HashInfo->Hash, FvHashValue, AlgInfo->HashSize) == 0)))
  {
    Status = EFI_SUCCESS;
  } else {
    Status = EFI_VOLUME_CORRUPTED;
  }

Done:
  FreePool (HashValue);
  return Status;
}

/**
  Report FV to PEI and/or DXE core for dispatch.

  @param[in] FvInfo     Information of a FV.

**/
STATIC
VOID
ReportHashedFv (
  IN HASHED_FV_INFO  *FvInfo
  )
{
  CONST EFI_GUID  *FvFormat;

  if ((FvInfo->Flag & HASHED_FV_FLAG_REPORT_FV_HOB) != 0) {
    //
    // Require DXE core to process this FV.
    //
    BuildFvHob (
      (EFI_PHYSICAL_ADDRESS)FvInfo->Base,
      FvInfo->Length
      );
    DEBUG ((DEBUG_INFO, "Reported FV HOB: %016lX (%08lX)\r\n", FvInfo->Base, FvInfo->Length));
  }

  if ((FvInfo->Flag & HASHED_FV_FLAG_REPORT_FV_INFO_PPI) != 0) {
    //
    // Require PEI core to process this FV.
    //
    FvFormat = &((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)FvInfo->Base)->FileSystemGuid;
    PeiServicesInstallFvInfoPpi (
      FvFormat,
      (VOID *)(UINTN)FvInfo->Base,
      (UINT32)FvInfo->Length,
      NULL,
      NULL
      );
    DEBUG ((DEBUG_INFO, "Reported FV PPI: %016lX (%08lX)\r\n", FvInfo->Base, FvInfo->Length));
  }
}

/**
  Verify and report pre-hashed FVs.

  Doing this must be at post-memory to make sure there's enough memory to hold
  all FVs to be verified. This is necessary for mitigating TOCTOU issue.

  This function will never return if the verification is failed.

  @param[in] StoredHashFvPpi  Pointer to PPI containing hash information.
  @param[in] BootMode         Current boot mode.

  @retval Pointer to structure containing valid hash information for current boot mode.
  @retval NULL if there's no hash associated with current boot mode.
**/
STATIC
FV_HASH_INFO *
GetHashInfo (
  IN EDKII_PEI_FIRMWARE_VOLUME_INFO_STORED_HASH_FV_PPI  *StoredHashFvPpi,
  IN EFI_BOOT_MODE                                      BootMode
  )
{
  FV_HASH_INFO  *HashInfo;

  if ((StoredHashFvPpi->HashInfo.HashFlag & FV_HASH_FLAG_BOOT_MODE (BootMode)) != 0) {
    HashInfo = &StoredHashFvPpi->HashInfo;
  } else {
    HashInfo = NULL;
  }

  return HashInfo;
}

/**
  Verify and report pre-hashed FVs.

  Doing this must be at post-memory to make sure there's enough memory to hold
  all FVs to be verified. This is necessary for mitigating TOCTOU issue.

  This function will never return if the verification is failed.

  @param[in] PeiServices      General purpose services available to every PEIM.
  @param[in] BootMode         Current boot mode.

  @retval EFI_SUCCESS         The function completed successfully.
**/
STATIC
EFI_STATUS
CheckStoredHashFv (
  IN CONST EFI_PEI_SERVICES  **PeiServices,
  IN EFI_BOOT_MODE           BootMode
  )
{
  EFI_STATUS                                         Status;
  EDKII_PEI_FIRMWARE_VOLUME_INFO_STORED_HASH_FV_PPI  *StoredHashFvPpi;
  FV_HASH_INFO                                       *HashInfo;
  UINTN                                              FvIndex;

  //
  // Check pre-hashed FV list
  //
  StoredHashFvPpi = NULL;
  Status          = PeiServicesLocatePpi (
                      &gEdkiiPeiFirmwareVolumeInfoStoredHashFvPpiGuid,
                      0,
                      NULL,
                      (VOID **)&StoredHashFvPpi
                      );
  if (!EFI_ERROR (Status) && (StoredHashFvPpi != NULL) && (StoredHashFvPpi->FvNumber > 0)) {
    HashInfo = GetHashInfo (StoredHashFvPpi, BootMode);
    Status   = VerifyHashedFv (
                 HashInfo,
                 StoredHashFvPpi->FvInfo,
                 StoredHashFvPpi->FvNumber,
                 BootMode
                 );
    if (!EFI_ERROR (Status)) {
      DEBUG ((DEBUG_INFO, "OBB verification passed (%r)\r\n", Status));

      //
      // Report the FVs to PEI core and/or DXE core.
      //
      for (FvIndex = 0; FvIndex < StoredHashFvPpi->FvNumber; ++FvIndex) {
        if ((StoredHashFvPpi->FvInfo[FvIndex].Flag
             & HASHED_FV_FLAG_SKIP_BOOT_MODE (BootMode)) == 0)
        {
          ReportHashedFv (&StoredHashFvPpi->FvInfo[FvIndex]);
        }
      }

      REPORT_STATUS_CODE (
        EFI_PROGRESS_CODE,
        PcdGet32 (PcdStatusCodeFvVerificationPass)
        );
    } else {
      DEBUG ((DEBUG_ERROR, "ERROR: Failed to verify OBB FVs (%r)\r\n", Status));

      REPORT_STATUS_CODE_EX (
        EFI_PROGRESS_CODE,
        PcdGet32 (PcdStatusCodeFvVerificationFail),
        0,
        NULL,
        &gEdkiiPeiFirmwareVolumeInfoStoredHashFvPpiGuid,
        StoredHashFvPpi,
        sizeof (*StoredHashFvPpi)
        );

      ASSERT_EFI_ERROR (Status);
    }
  } else {
    DEBUG ((DEBUG_ERROR, "ERROR: No/invalid StoredHashFvPpi located\r\n"));

    ASSERT_EFI_ERROR (Status);
    ASSERT (StoredHashFvPpi != NULL && StoredHashFvPpi->FvNumber > 0);

    Status = EFI_NOT_FOUND;
  }

  return Status;
}

/**
  Main entry for FvReport PEIM.

  @param[in]  FileHandle              Handle of the file being invoked.
  @param[in]  PeiServices             Pointer to PEI Services table.

  @retval EFI_SUCCESS  If all FVs reported by StoredHashFvPpi are verified.

**/
EFI_STATUS
EFIAPI
FvReportEntryPoint (
  IN       EFI_PEI_FILE_HANDLE  FileHandle,
  IN CONST EFI_PEI_SERVICES     **PeiServices
  )
{
  EFI_STATUS     Status;
  EFI_BOOT_MODE  BootMode;

  Status = PeiServicesGetBootMode (&BootMode);
  ASSERT_EFI_ERROR (Status);

  Status = CheckStoredHashFv (PeiServices, BootMode);
  if (EFI_ERROR (Status)) {
    //
    // Never pass control to left part of BIOS if any error.
    //
    CpuDeadLoop ();
  }

  return Status;
}
