/** @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;
  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);
    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;
}
