/** @file
  This library is BaseCrypto SHA256 hash instance.
  It can be registered to BaseCrypto router, to serve as hash engine.

Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved. <BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include <PiPei.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/BaseCryptLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/HashLib.h>

/**
  The function set SHA256 to digest list.

  @param DigestList   digest list
  @param Sha256Digest SHA256 digest
**/
VOID
Tpm2SetSha256ToDigestList (
  IN TPML_DIGEST_VALUES  *DigestList,
  IN UINT8               *Sha256Digest
  )
{
  DigestList->count              = 1;
  DigestList->digests[0].hashAlg = TPM_ALG_SHA256;
  CopyMem (
    DigestList->digests[0].digest.sha256,
    Sha256Digest,
    SHA256_DIGEST_SIZE
    );
}

/**
  Start hash sequence.

  @param HashHandle Hash handle.

  @retval EFI_SUCCESS          Hash sequence start and HandleHandle returned.
  @retval EFI_OUT_OF_RESOURCES No enough resource to start hash.
**/
EFI_STATUS
EFIAPI
Sha256HashInit (
  OUT HASH_HANDLE  *HashHandle
  )
{
  VOID   *Sha256Ctx;
  UINTN  CtxSize;

  CtxSize   = Sha256GetContextSize ();
  Sha256Ctx = AllocatePool (CtxSize);
  ASSERT (Sha256Ctx != NULL);

  Sha256Init (Sha256Ctx);

  *HashHandle = (HASH_HANDLE)Sha256Ctx;

  return EFI_SUCCESS;
}

/**
  Update hash sequence data.

  @param HashHandle    Hash handle.
  @param DataToHash    Data to be hashed.
  @param DataToHashLen Data size.

  @retval EFI_SUCCESS     Hash sequence updated.
**/
EFI_STATUS
EFIAPI
Sha256HashUpdate (
  IN HASH_HANDLE  HashHandle,
  IN VOID         *DataToHash,
  IN UINTN        DataToHashLen
  )
{
  VOID  *Sha256Ctx;

  Sha256Ctx = (VOID *)HashHandle;
  Sha256Update (Sha256Ctx, DataToHash, DataToHashLen);

  return EFI_SUCCESS;
}

/**
  Complete hash sequence complete.

  @param HashHandle    Hash handle.
  @param DigestList    Digest list.

  @retval EFI_SUCCESS     Hash sequence complete and DigestList is returned.
**/
EFI_STATUS
EFIAPI
Sha256HashFinal (
  IN HASH_HANDLE          HashHandle,
  OUT TPML_DIGEST_VALUES  *DigestList
  )
{
  UINT8  Digest[SHA256_DIGEST_SIZE];
  VOID   *Sha256Ctx;

  Sha256Ctx = (VOID *)HashHandle;
  Sha256Final (Sha256Ctx, Digest);

  FreePool (Sha256Ctx);

  Tpm2SetSha256ToDigestList (DigestList, Digest);

  return EFI_SUCCESS;
}

HASH_INTERFACE  mSha256InternalHashInstance = {
  HASH_ALGORITHM_SHA256_GUID,
  Sha256HashInit,
  Sha256HashUpdate,
  Sha256HashFinal,
};

/**
  The function register SHA256 instance.

  @retval EFI_SUCCESS   SHA256 instance is registered, or system does not support register SHA256 instance
**/
EFI_STATUS
EFIAPI
HashInstanceLibSha256Constructor (
  VOID
  )
{
  EFI_STATUS  Status;

  Status = RegisterHashInterfaceLib (&mSha256InternalHashInstance);
  if ((Status == EFI_SUCCESS) || (Status == EFI_UNSUPPORTED)) {
    //
    // Unsupported means platform policy does not need this instance enabled.
    //
    return EFI_SUCCESS;
  }

  return Status;
}
