/** @file
  This library is BaseCrypto SHA384 hash instance.
  It can be registered to BaseCrypto router, to serve as hash engine.

Copyright (c) 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 SHA384 to digest list.

  @param DigestList   digest list
  @param Sha384Digest SHA384 digest
**/
VOID
Tpm2SetSha384ToDigestList (
  IN TPML_DIGEST_VALUES *DigestList,
  IN UINT8              *Sha384Digest
  )
{
  DigestList->count = 1;
  DigestList->digests[0].hashAlg = TPM_ALG_SHA384;
  CopyMem (
    DigestList->digests[0].digest.sha384,
    Sha384Digest,
    SHA384_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
Sha384HashInit (
  OUT HASH_HANDLE    *HashHandle
  )
{
  VOID     *Sha384Ctx;
  UINTN    CtxSize;

  CtxSize = Sha384GetContextSize ();
  Sha384Ctx = AllocatePool (CtxSize);
  ASSERT (Sha384Ctx != NULL);

  Sha384Init (Sha384Ctx);

  *HashHandle = (HASH_HANDLE)Sha384Ctx;

  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
Sha384HashUpdate (
  IN HASH_HANDLE    HashHandle,
  IN VOID           *DataToHash,
  IN UINTN          DataToHashLen
  )
{
  VOID     *Sha384Ctx;

  Sha384Ctx = (VOID *)HashHandle;
  Sha384Update (Sha384Ctx, 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
Sha384HashFinal (
  IN HASH_HANDLE         HashHandle,
  OUT TPML_DIGEST_VALUES *DigestList
  )
{
  UINT8         Digest[SHA384_DIGEST_SIZE];
  VOID          *Sha384Ctx;

  Sha384Ctx = (VOID *)HashHandle;
  Sha384Final (Sha384Ctx, Digest);

  FreePool (Sha384Ctx);

  Tpm2SetSha384ToDigestList (DigestList, Digest);

  return EFI_SUCCESS;
}

HASH_INTERFACE  mSha384InternalHashInstance = {
  HASH_ALGORITHM_SHA384_GUID,
  Sha384HashInit,
  Sha384HashUpdate,
  Sha384HashFinal,
};

/**
  The function register SHA384 instance.

  @retval EFI_SUCCESS   SHA384 instance is registered, or system does not support register SHA384 instance
**/
EFI_STATUS
EFIAPI
HashInstanceLibSha384Constructor (
  VOID
  )
{
  EFI_STATUS  Status;

  Status = RegisterHashInterfaceLib (&mSha384InternalHashInstance);
  if ((Status == EFI_SUCCESS) || (Status == EFI_UNSUPPORTED)) {
    //
    // Unsupported means platform policy does not need this instance enabled.
    //
    return EFI_SUCCESS;
  }
  return Status;
}
