/** @file
  Common interfaces to call Security library.

  Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>

  This program and the accompanying materials
  are licensed and made available under the terms and conditions of the BSD License
  which accompanies this distribution.  The full text of the license may be found at
  http://opensource.org/licenses/bsd-license.php.

  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include "IpSecCryptIo.h"
//
// The informations for the supported Encrypt/Decrpt Alogrithm.
//
GLOBAL_REMOVE_IF_UNREFERENCED ENCRYPT_ALGORITHM mIpsecEncryptAlgorithmList[IPSEC_ENCRYPT_ALGORITHM_LIST_SIZE] = {
  {IKE_EALG_NULL, 0, 0, 1, NULL, NULL, NULL, NULL},
  {IKE_EALG_NONE, 0, 0, 1, NULL, NULL, NULL, NULL},
  {IKE_EALG_3DESCBC, 24, 8, 8, TdesGetContextSize, TdesInit, TdesCbcEncrypt, TdesCbcDecrypt},
  {IKE_EALG_AESCBC, 16, 16, 16, AesGetContextSize, AesInit, AesCbcEncrypt, AesCbcDecrypt}
};

//
// The informations for the supported Authentication algorithm
//
GLOBAL_REMOVE_IF_UNREFERENCED AUTH_ALGORITHM mIpsecAuthAlgorithmList[IPSEC_AUTH_ALGORITHM_LIST_SIZE] = {
  {IKE_AALG_NONE, 0, 0, 0, NULL, NULL, NULL, NULL},
  {IKE_AALG_NULL, 0, 0, 0, NULL, NULL, NULL, NULL},
  {IKE_AALG_SHA1HMAC, 20, 12, 64, HmacSha1GetContextSize, HmacSha1Init, HmacSha1Update, HmacSha1Final}
};

//
// The information for the supported Hash aglorithm
//
GLOBAL_REMOVE_IF_UNREFERENCED HASH_ALGORITHM mIpsecHashAlgorithmList[IPSEC_HASH_ALGORITHM_LIST_SIZE] = {
  {IKE_AALG_NONE, 0, 0, 0, NULL, NULL, NULL, NULL},
  {IKE_AALG_NULL, 0, 0, 0, NULL, NULL, NULL, NULL},
  {IKE_AALG_SHA1HMAC, 20, 12, 64, Sha1GetContextSize, Sha1Init, Sha1Update, Sha1Final}
};

BOOLEAN  mInitialRandomSeed = FALSE;

/**
  Get the block size of specified encryption algorithm.

  @param[in]  AlgorithmId          The encryption algorithm ID.

  @return The value of block size.

**/
UINTN
IpSecGetEncryptBlockSize (
  IN UINT8   AlgorithmId
  )
{
  UINT8 Index;

  for (Index = 0; Index < IPSEC_ENCRYPT_ALGORITHM_LIST_SIZE; Index++) {
    if (AlgorithmId == mIpsecEncryptAlgorithmList[Index].AlgorithmId) {
      return mIpsecEncryptAlgorithmList[Index].BlockSize;
    }
  }

  return (UINTN) -1;
}

/**
  Get the key length of the specified encryption algorithm.

  @param[in]  AlgorithmId          The encryption algorithm ID.

  @return The value of key length.

**/
UINTN
IpSecGetEncryptKeyLength (
  IN UINT8   AlgorithmId
  )
{
  UINT8 Index;

  for (Index = 0; Index < IPSEC_ENCRYPT_ALGORITHM_LIST_SIZE; Index++) {
    if (AlgorithmId == mIpsecEncryptAlgorithmList[Index].AlgorithmId) {
      return mIpsecEncryptAlgorithmList[Index].KeyLength;
    }
  }

  return (UINTN) -1;
}

/**
  Get the IV size of the specified encryption algorithm.

  @param[in]  AlgorithmId          The encryption algorithm ID.

  @return The value of IV size.

**/
UINTN
IpSecGetEncryptIvLength (
  IN UINT8 AlgorithmId
  )
{
  UINT8 Index;

  for (Index = 0; Index < IPSEC_ENCRYPT_ALGORITHM_LIST_SIZE; Index++) {
    if (AlgorithmId == mIpsecEncryptAlgorithmList[Index].AlgorithmId) {
      return mIpsecEncryptAlgorithmList[Index].IvLength;
    }
  }

  return (UINTN) -1;
}

/**
  Get the HMAC digest length by the specified Algorithm ID.

  @param[in]  AlgorithmId  The specified Alogrithm ID.

  @return The digest length of the specified Authentication Algorithm ID.

**/
UINTN
IpSecGetHmacDigestLength (
  IN UINT8  AlgorithmId
  )
{
  UINT8 Index;

  for (Index = 0; Index < IPSEC_AUTH_ALGORITHM_LIST_SIZE; Index++) {
    if (mIpsecAuthAlgorithmList[Index].AlgorithmId == AlgorithmId) {
      //
      // Return the Digest Length of the Algorithm.
      //
      return mIpsecAuthAlgorithmList[Index].DigestLength;
    }
  }

  return 0;
}

/**
  Get the ICV size of the specified Authenticaion algorithm.

  @param[in]  AlgorithmId          The Authentication algorithm ID.

  @return The value of ICV size.

**/
UINTN
IpSecGetIcvLength (
  IN UINT8  AlgorithmId
  )
{
  UINT8 Index;

  for (Index = 0; Index < IPSEC_AUTH_ALGORITHM_LIST_SIZE; Index++) {
    if (AlgorithmId == mIpsecAuthAlgorithmList[Index].AlgorithmId) {
      return mIpsecAuthAlgorithmList[Index].IcvLength;
    }
  }

  return (UINTN) -1;
}

/**
  Generate a random data for IV. If the IvSize is zero, not needed to create
  IV and return EFI_SUCCESS.

  @param[in]  IvBuffer  The pointer of the IV buffer.
  @param[in]  IvSize    The IV size in bytes.

  @retval     EFI_SUCCESS  Create a random data for IV.

**/
EFI_STATUS
IpSecGenerateIv (
  IN UINT8                           *IvBuffer,
  IN UINTN                           IvSize
  )
{
  if (IvSize != 0) {
    return IpSecCryptoIoGenerateRandomBytes (IvBuffer, IvSize);
  }

  return EFI_SUCCESS;
}

/**
  Get index of the specified encryption algorithm from the mIpsecEncryptAlgorithmList.

  @param[in]  AlgorithmId          The encryption algorithm ID.

  @return the index.

**/
UINTN
IpSecGetIndexFromEncList (
  IN UINT8   AlgorithmId
  )
{
  UINT8 Index;

  for (Index = 0; Index < IPSEC_ENCRYPT_ALGORITHM_LIST_SIZE; Index++) {
    if (AlgorithmId == mIpsecEncryptAlgorithmList[Index].AlgorithmId) {
      return Index;
    }
  }

  return (UINTN) -1;
}

/**
  Get index of the specified encryption algorithm from the mIpsecAuthAlgorithmList.

  @param[in]  AlgorithmId          The encryption algorithm ID.

  @return the index.

**/
UINTN
IpSecGetIndexFromAuthList (
  IN UINT8   AlgorithmId
  )
{
  UINT8 Index;

  for (Index = 0; Index < IPSEC_AUTH_ALGORITHM_LIST_SIZE; Index++) {
    if (AlgorithmId == mIpsecAuthAlgorithmList[Index].AlgorithmId) {
      //
      // The BlockSize is same with IvSize.
      //
      return Index;
    }
  }

  return (UINTN) -1;
}

/**
  Encrypt the buffer.

  This function calls relevant encryption interface from CryptoLib according to
  the input algorithm ID. The InData should be multiple of block size. This function
  doesn't perform the padding. If it has the Ivec data, the length of it should be
  same with the block size. The block size is different from the different algorithm.

  @param[in]       AlgorithmId    The Algorithm identification defined in RFC.
  @param[in]       Key            Pointer to the buffer containing encrypting key.
  @param[in]       KeyBits        The length of the key in bits.
  @param[in]       Ivec           Point to the buffer containing the Initialization
                                  Vector (IV) data.
  @param[in]       InData         Point to the buffer containing the data to be
                                  encrypted.
  @param[in]       InDataLength   The length of InData in Bytes.
  @param[out]      OutData        Point to the buffer that receives the encryption
                                  output.

  @retval EFI_UNSUPPORTED       The input Algorithm is not supported.
  @retval EFI_OUT_OF_RESOURCE   The required resource can't be allocated.
  @retval EFI_SUCCESS           The operation completed successfully.

**/
EFI_STATUS
IpSecCryptoIoEncrypt (
  IN CONST UINT8      AlgorithmId,
  IN CONST UINT8      *Key,
  IN CONST UINTN      KeyBits,
  IN CONST UINT8      *Ivec, OPTIONAL
  IN       UINT8      *InData,
  IN       UINTN      InDataLength,
     OUT   UINT8      *OutData
  )
{
  UINTN         Index;
  UINTN         ContextSize;
  UINT8         *Context;
  EFI_STATUS    Status;

  Status = EFI_UNSUPPORTED;

  switch (AlgorithmId) {

  case IKE_EALG_NULL:
  case IKE_EALG_NONE:
    CopyMem (OutData, InData, InDataLength);
    return EFI_SUCCESS;

  case IKE_EALG_3DESCBC:
  case IKE_EALG_AESCBC:
    Index = IpSecGetIndexFromEncList (AlgorithmId);
    if (Index == -1) {
      return Status;
    }
    //
    // Get Context Size
    //
    ContextSize = mIpsecEncryptAlgorithmList[Index].CipherGetContextSize ();
    Context     = AllocateZeroPool (ContextSize);

    if (Context == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }
    //
    // Initiate Context
    //
    if (mIpsecEncryptAlgorithmList[Index].CipherInitiate (Context, Key, KeyBits)) {
      if (mIpsecEncryptAlgorithmList[Index].CipherEncrypt (Context, InData, InDataLength, Ivec, OutData)) {
        Status = EFI_SUCCESS;
      }
    }
    break;

  default:
    return Status;

  }

  if (Context != NULL) {
    FreePool (Context);
  }

  return Status;
}

/**
  Decrypts the buffer.

  This function calls relevant Decryption interface from CryptoLib according to
  the input algorithm ID. The InData should be multiple of block size. This function
  doesn't perform the padding. If it has the Ivec data, the length of it should be
  same with the block size. The block size is different from the different algorithm.

  @param[in]       AlgorithmId    The Algorithm identification defined in RFC.
  @param[in]       Key            Pointer to the buffer containing encrypting key.
  @param[in]       KeyBits        The length of the key in bits.
  @param[in]       Ivec           Point to the buffer containing the Initialization
                                  Vector (IV) data.
  @param[in]       InData         Point to the buffer containing the data to be
                                  decrypted.
  @param[in]       InDataLength   The length of InData in Bytes.
  @param[out]      OutData        Pointer to the buffer that receives the decryption
                                  output.

  @retval EFI_UNSUPPORTED       The input Algorithm is not supported.
  @retval EFI_OUT_OF_RESOURCE   The required resource can't be allocated.
  @retval EFI_SUCCESS           The operation completed successfully.

**/
EFI_STATUS
IpSecCryptoIoDecrypt (
  IN CONST UINT8      AlgorithmId,
  IN CONST UINT8      *Key,
  IN CONST UINTN      KeyBits,
  IN CONST UINT8      *Ivec, OPTIONAL
  IN       UINT8      *InData,
  IN       UINTN      InDataLength,
     OUT   UINT8      *OutData
  )
{
  UINTN         Index;
  UINTN         ContextSize;
  UINT8         *Context;
  EFI_STATUS    Status;

  Status = EFI_UNSUPPORTED;

  switch (AlgorithmId) {

  case IKE_EALG_NULL:
  case IKE_EALG_NONE:
    CopyMem (OutData, InData, InDataLength);
    return EFI_SUCCESS;

  case IKE_EALG_3DESCBC:
  case IKE_EALG_AESCBC:
    Index = IpSecGetIndexFromEncList(AlgorithmId);
    if (Index == -1) {
      return Status;
    }

    //
    // Get Context Size
    //
    ContextSize = mIpsecEncryptAlgorithmList[Index].CipherGetContextSize();
    Context     = AllocateZeroPool (ContextSize);
    if (Context == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    //
    // Initiate Context
    //
    if (mIpsecEncryptAlgorithmList[Index].CipherInitiate (Context, Key, KeyBits)) {
      if (mIpsecEncryptAlgorithmList[Index].CipherDecrypt (Context, InData, InDataLength, Ivec, OutData)) {
        Status = EFI_SUCCESS;
      }
    }
    break;

  default:
    return Status;
  }

  if (Context != NULL) {
    FreePool (Context);
  }

  return Status;
}

/**
  Digests the Payload with key and store the result into the OutData.

  This function calls relevant Hmac interface from CryptoLib according to
  the input algorithm ID. It computes all datas from InDataFragment and output
  the result into the OutData buffer. If the OutDataSize is larger than the related
  HMAC algorithm output size, return EFI_INVALID_PARAMETER.

  @param[in]      AlgorithmId     The authentication Identification.
  @param[in]      Key             Pointer of the authentication key.
  @param[in]      KeyLength       The length of the Key in bytes.
  @param[in]      InDataFragment  The list contains all data to be authenticated.
  @param[in]      FragmentCount   The size of the InDataFragment.
  @param[out]     OutData         For in, the buffer to receive the output data.
                                  For out, the buffer contains the authenticated data.
  @param[in]      OutDataSize     The size of the buffer of OutData.

  @retval EFI_UNSUPPORTED       If the AuthAlg is not in the support list.
  @retval EFI_INVALID_PARAMETER The OutData buffer size is larger than algorithm digest size.
  @retval EFI_SUCCESS           Authenticate the payload successfully.
  @retval otherwise             Authentication of the payload fails.

**/
EFI_STATUS
IpSecCryptoIoHmac (
  IN     CONST UINT8              AlgorithmId,
  IN     CONST UINT8              *Key,
  IN           UINTN              KeyLength,
  IN           HASH_DATA_FRAGMENT *InDataFragment,
  IN           UINTN              FragmentCount,
     OUT       UINT8              *OutData,
  IN           UINTN              OutDataSize
  )
{
  UINTN        ContextSize;
  UINTN        Index;
  UINT8        FragmentIndex;
  UINT8        *HashContext;
  EFI_STATUS   Status;
  UINT8        *OutHashData;
  UINTN        OutHashSize;

  Status      = EFI_UNSUPPORTED;
  OutHashData = NULL;

  OutHashSize = IpSecGetHmacDigestLength (AlgorithmId);
  //
  // If the expected hash data size is larger than the related Hash algorithm
  // output length, return EFI_INVALID_PARAMETER.
  //
  if (OutDataSize > OutHashSize) {
    return EFI_INVALID_PARAMETER;
  }
  OutHashData = AllocatePool (OutHashSize);

  if (OutHashData == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  switch (AlgorithmId) {

  case IKE_AALG_NONE :
  case IKE_AALG_NULL :
    return EFI_SUCCESS;

  case IKE_AALG_SHA1HMAC:
    Index = IpSecGetIndexFromAuthList (AlgorithmId);
    if (Index == -1) {
      return Status;
    }

    //
    // Get Context Size
    //
    ContextSize = mIpsecAuthAlgorithmList[Index].HmacGetContextSize();
    HashContext = AllocateZeroPool (ContextSize);

    if (HashContext == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto Exit;
    }

    //
    // Initiate HMAC context and hash the input data.
    //
    if (mIpsecAuthAlgorithmList[Index].HmacInitiate(HashContext, Key, KeyLength)) {
      for (FragmentIndex = 0; FragmentIndex < FragmentCount; FragmentIndex++) {
        if (!mIpsecAuthAlgorithmList[Index].HmacUpdate (
                HashContext,
                InDataFragment[FragmentIndex].Data,
                InDataFragment[FragmentIndex].DataSize
                )
          ) {
          goto Exit;
        }
      }
      if (mIpsecAuthAlgorithmList[Index].HmacFinal (HashContext, OutHashData)) {
        //
        // In some cases, like the Icv computing, the Icv size might be less than
        // the key length size, so copy the part of hash data to the OutData.
        //
        CopyMem (OutData, OutHashData, OutDataSize);
        Status = EFI_SUCCESS;
      }

      goto Exit;
    }

  default:
    return Status;
  }

Exit:
  if (HashContext != NULL) {
    FreePool (HashContext);
  }
  if (OutHashData != NULL) {
    FreePool (OutHashData);
  }

  return Status;
}

/**
  Digests the Payload and store the result into the OutData.

  This function calls relevant Hash interface from CryptoLib according to
  the input algorithm ID. It computes all datas from InDataFragment and output
  the result into the OutData buffer. If the OutDataSize is larger than the related
  Hash algorithm output size, return EFI_INVALID_PARAMETER.

  @param[in]      AlgorithmId     The authentication Identification.
  @param[in]      InDataFragment  A list contains all data to be authenticated.
  @param[in]      FragmentCount   The size of the InDataFragment.
  @param[out]     OutData         For in, the buffer to receive the output data.
                                  For out, the buffer contains the authenticated data.
  @param[in]      OutDataSize     The size of the buffer of OutData.

  @retval EFI_UNSUPPORTED       If the AuthAlg is not in the support list.
  @retval EFI_SUCCESS           Authenticated the payload successfully.
  @retval EFI_INVALID_PARAMETER If the OutDataSize is larger than the related Hash
                                algorithm could handle.
  @retval otherwise             Authentication of the payload failed.

**/
EFI_STATUS
IpSecCryptoIoHash (
  IN     CONST UINT8              AlgorithmId,
  IN           HASH_DATA_FRAGMENT *InDataFragment,
  IN           UINTN              FragmentCount,
     OUT       UINT8              *OutData,
  IN           UINTN              OutDataSize
  )
{
  UINTN        ContextSize;
  UINTN        Index;
  UINT8        FragmentIndex;
  UINT8        *HashContext;
  EFI_STATUS   Status;
  UINT8        *OutHashData;
  UINTN        OutHashSize;

  Status      = EFI_UNSUPPORTED;
  OutHashData = NULL;

  OutHashSize = IpSecGetHmacDigestLength (AlgorithmId);
  //
  // If the expected hash data size is larger than the related Hash algorithm
  // output length, return EFI_INVALID_PARAMETER.
  //
  if (OutDataSize > OutHashSize) {
    return EFI_INVALID_PARAMETER;
  }
  OutHashData = AllocatePool (OutHashSize);
  if (OutHashData == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  switch (AlgorithmId) {

  case IKE_AALG_NONE:
  case IKE_AALG_NULL:
    return EFI_SUCCESS;

  case IKE_AALG_SHA1HMAC:
    Index = IpSecGetIndexFromAuthList (AlgorithmId);
    if (Index == -1) {
      return Status;
    }
    //
    // Get Context Size
    //
    ContextSize = mIpsecHashAlgorithmList[Index].HashGetContextSize();
    HashContext = AllocateZeroPool (ContextSize);
    if (HashContext == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto Exit;
    }

    //
    // Initiate Hash context and hash the input data.
    //
    if (mIpsecHashAlgorithmList[Index].HashInitiate(HashContext)) {
      for (FragmentIndex = 0; FragmentIndex < FragmentCount; FragmentIndex++) {
        if (!mIpsecHashAlgorithmList[Index].HashUpdate (
                HashContext,
                InDataFragment[FragmentIndex].Data,
                InDataFragment[FragmentIndex].DataSize
                )
          ) {
          goto Exit;
        }
      }
      if (mIpsecHashAlgorithmList[Index].HashFinal (HashContext, OutHashData)) {
        //
        // In some cases, like the Icv computing, the Icv size might be less than
        // the key length size, so copy the part of hash data to the OutData.
        //
        CopyMem (OutData, OutHashData, OutDataSize);
        Status = EFI_SUCCESS;
      }

      goto Exit;
    }

  default:
    return Status;
  }

Exit:
  if (HashContext != NULL) {
    FreePool (HashContext);
  }
  if (OutHashData != NULL) {
    FreePool (OutHashData);
  }

  return Status;
}

/**
  Generates the Diffie-Hellman public key.

  This function first initiate a DHContext, then call the DhSetParameter() to set
  the prime and primelength, at end call the DhGenerateKey() to generates random
  secret exponent, and computes the public key. The output returned via parameter
  PublicKey and PublicKeySize. DH context is updated accordingly. If the PublicKey
  buffer is too small to hold the public key, EFI_INVALID_PARAMETER is returned
  and PublicKeySize is set to the required buffer size to obtain the public key.

  @param[in, out] DhContext       Pointer to the DH context.
  @param[in]      Generator       Value of generator.
  @param[in]      PrimeLength     Length in bits of prime to be generated.
  @param[in]      Prime           Pointer to the buffer to receive the generated
                                  prime number.
  @param[out]     PublicKey       Pointer to the buffer to receive generated public key.
  @param[in, out] PublicKeySize   For in, the size of PublicKey buffer in bytes.
                                  For out, the size of data returned in PublicKey
                                  buffer in bytes.

  @retval EFI_SUCCESS             The operation performs successfully.
  @retval Otherwise               The operation is failed.

**/
EFI_STATUS
IpSecCryptoIoDhGetPublicKey (
  IN OUT   UINT8  **DhContext,
  IN       UINTN  Generator,
  IN       UINTN  PrimeLength,
  IN CONST UINT8  *Prime,
     OUT   UINT8  *PublicKey,
  IN OUT   UINTN  *PublicKeySize
  )
{
  EFI_STATUS   Status;

  *DhContext = DhNew ();
  ASSERT (*DhContext != NULL);
  if (!DhSetParameter (*DhContext, Generator, PrimeLength, Prime)) {
    Status = EFI_INVALID_PARAMETER;
    goto Exit;
  }

  if (!DhGenerateKey (*DhContext, PublicKey, PublicKeySize)) {
    Status = EFI_INVALID_PARAMETER;
    goto Exit;
  }
  return EFI_SUCCESS;

Exit:
  if (*DhContext != NULL) {
    DhFree (*DhContext);
    DhContext = NULL;
  }

  return Status;
}

/**
  Generates exchanged common key.

  Given peer's public key, this function computes the exchanged common key, based
  on its own context including value of prime modulus and random secret exponent.

  @param[in, out] DhContext         Pointer to the DH context.
  @param[in]      PeerPublicKey     Pointer to the peer's Public Key.
  @param[in]      PeerPublicKeySize Size of peer's public key in bytes.
  @param[out]     Key               Pointer to the buffer to receive generated key.
  @param[in, out] KeySize           For in, the size of Key buffer in bytes.
                                    For out, the size of data returned in Key
                                    buffer in bytes.

  @retval EFI_SUCCESS              The operation performs successfully.
  @retval Otherwise                The operation is failed.

**/
EFI_STATUS
IpSecCryptoIoDhComputeKey (
  IN   OUT   UINT8  *DhContext,
  IN   CONST UINT8  *PeerPublicKey,
  IN         UINTN  PeerPublicKeySize,
       OUT   UINT8  *Key,
  IN   OUT   UINTN  *KeySize
  )
{
  if (!DhComputeKey (DhContext, PeerPublicKey, PeerPublicKeySize, Key, KeySize)) {
    return EFI_INVALID_PARAMETER;
  }

  return EFI_SUCCESS;
}

/**
  Releases the DH context. If DhContext is NULL, return EFI_INVALID_PARAMETER.

  @param[in, out]     DhContext         Pointer to the DH context to be freed.

  @retval EFI_SUCCESS              The operation performs successfully.
  @retval EFI_INVALID_PARAMETER    The DhContext is NULL.

**/
EFI_STATUS
IpSecCryptoIoFreeDh (
  IN   OUT   UINT8  **DhContext
  )
{
  if (*DhContext == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  DhFree (*DhContext);
  return EFI_SUCCESS;
}

/**
  Generates random numbers of specified size.

  If the Random Generator wasn't initiated, initiate it first, then call RandomBytes.

  @param[out]  OutBuffer        Pointer to buffer to receive random value.
  @param[in]   Bytes            Size of random bytes to generate.

  @retval EFI_SUCCESS              The operation performs successfully.
  @retval Otherwise                The operation is failed.

**/
EFI_STATUS
IpSecCryptoIoGenerateRandomBytes (
  OUT UINT8*    OutBuffer,
  IN  UINTN     Bytes
  )
{
  if (!mInitialRandomSeed) {
    RandomSeed (NULL, 0);
    mInitialRandomSeed = TRUE;
  }
  if (RandomBytes (OutBuffer, Bytes)) {
    return EFI_SUCCESS;
  } else {
    return EFI_INVALID_PARAMETER;
  }
}

/**
  Authenticate data with the certificate.

  @param[in]      InData          Pointer to the Data to be signed.
  @param[in]      InDataSize      InData size in bytes.
  @param[in]      PrivateKey      Pointer to the  private key.
  @param[in]      PrivateKeySize  The size of Private Key in bytes.
  @param[in]      KeyPassWord     Pointer to the password for retrieving private key.
  @param[in]      KeyPwdSize      The size of Key Password in bytes.
  @param[out]     OutData         The pointer to the signed data.
  @param[in, out] OutDataSize     Pointer to contain the size of out data.

**/
VOID
IpSecCryptoIoAuthDataWithCertificate (
  IN     UINT8   *InData,
  IN     UINTN   InDataSize,
  IN     UINT8   *PrivateKey,
  IN     UINTN   PrivateKeySize,
  IN     UINT8   *KeyPassWord,
  IN     UINTN   KeyPwdSize,
     OUT UINT8   **OutData,
  IN OUT UINTN   *OutDataSize
  )
{
  UINT8         *RsaContext;
  UINT8         *Signature;
  UINTN         SigSize;

  SigSize   = 0;
  RsaContext = NULL;

  //
  // Retrieve RSA Private Key from password-protected PEM data
  //
  RsaGetPrivateKeyFromPem (
    (CONST UINT8 *)PrivateKey,
    PrivateKeySize,
    (CONST CHAR8 *)KeyPassWord,
    (VOID **) &RsaContext
    );
  if (RsaContext == NULL) {
    return;
  }

  //
  // Sign data
  //
  Signature = NULL;
  if (!RsaPkcs1Sign (RsaContext, InData, InDataSize, Signature, &SigSize)) {
    Signature = AllocateZeroPool (SigSize);
  } else {
    return;
  }

  RsaPkcs1Sign (RsaContext, InData, InDataSize, Signature, &SigSize);

  *OutData     = Signature;
  *OutDataSize = SigSize;

  if (RsaContext != NULL) {
    RsaFree (RsaContext);
  }
}

/**
  Verify the singed data with the public key which is contained in a certificate.

  @param[in]     InCert          Pointer to the Certificate which contains the
                                 public key.
  @param[in]     CertLen         The size of Certificate in bytes.
  @param[in]     InCa            Pointer to the CA certificate
  @param[in]     CaLen           The size of CA certificate in bytes.
  @param[in]     InData          Pointer to octet message hash to be checked.
  @param[in]     InDataSize      Size of the message hash in bytes.
  @param[in]     Singnature      The pointer to the RSA PKCS1-V1_5 signature to be verified.
  @param[in]     SigSize         Size of signature in bytes.

  @retval  TRUE   Valid signature encoded in PKCS1-v1_5.
  @retval  FALSE  Invalid signature or invalid RSA context.

**/
BOOLEAN
IpSecCryptoIoVerifySignDataByCertificate (
  IN     UINT8   *InCert,
  IN     UINTN   CertLen,
  IN     UINT8   *InCa,
  IN     UINTN   CaLen,
  IN     UINT8   *InData,
  IN     UINTN   InDataSize,
  IN     UINT8   *Singnature,
  IN     UINTN   SigSize
  )
{
  UINT8         *RsaContext;
  BOOLEAN       Status;

  //
  // Create the RSA Context
  //
  RsaContext = RsaNew ();
  if (RsaContext == NULL) {
    return FALSE;
  }

  //
  // Verify the validity of X509 Certificate
  //
  if (!X509VerifyCert (InCert, CertLen, InCa, CaLen)) {
    return FALSE;
  }

  //
  // Retrieve the RSA public Key from Certificate
  //
  RsaGetPublicKeyFromX509 ((CONST UINT8 *)InCert, CertLen, (VOID **)&RsaContext);

  //
  // Verify data
  //
  Status = RsaPkcs1Verify (RsaContext, InData, InDataSize, Singnature, SigSize);

  if (RsaContext != NULL) {
    RsaFree (RsaContext);
  }

  return Status;
}

/**
  Retrieves the RSA Public Key from one X509 certificate (DER format only).

  @param[in]     InCert            Pointer to the certificate.
  @param[in]     CertLen           The size of the certificate in bytes.
  @param[out]    PublicKey         Pointer to the retrieved public key.
  @param[out]    PublicKeyLen      Size of Public Key in bytes.

  @retval  EFI_SUCCESS            Successfully get the public Key.
  @retval  EFI_INVALID_PARAMETER  The certificate is malformed.

**/
EFI_STATUS
IpSecCryptoIoGetPublicKeyFromCert (
  IN     UINT8   *InCert,
  IN     UINTN   CertLen,
  OUT    UINT8   **PublicKey,
  OUT    UINTN   *PublicKeyLen
  )
{
  UINT8         *RsaContext;
  EFI_STATUS    Status;

  Status = EFI_SUCCESS;

  //
  // Create the RSA Context
  //
  RsaContext = RsaNew ();

  //
  // Retrieve the RSA public key from CA Certificate
  //
  if (!RsaGetPublicKeyFromX509 ((CONST UINT8 *)InCert, CertLen, (VOID **) &RsaContext)) {
    Status = EFI_INVALID_PARAMETER;
    goto EXIT;
  }

  *PublicKeyLen = 0;

  RsaGetKey (RsaContext, RsaKeyN, NULL, PublicKeyLen);

  *PublicKey = AllocateZeroPool (*PublicKeyLen);
  if (*PublicKey == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto EXIT;
  }

  if (!RsaGetKey (RsaContext, RsaKeyN, *PublicKey, PublicKeyLen)) {
    Status = EFI_INVALID_PARAMETER;
  }

EXIT:
  if (RsaContext != NULL) {
    RsaFree (RsaContext);
  }

  return Status;
}

/**
  Retrieves the subject name from one X509 certificate (DER format only).

  @param[in]     InCert            Pointer to the X509 certificate.
  @param[in]     CertSize          The size of the X509 certificate in bytes.
  @param[out]    CertSubject       Pointer to the retrieved certificate subject.
  @param[out]    SubjectSize       The size of Certificate Subject in bytes.

  @retval  EFI_SUCCESS            Retrieved the certificate subject successfully.
  @retval  EFI_INVALID_PARAMETER  The certificate is malformed.

**/
EFI_STATUS
IpSecCryptoIoGetSubjectFromCert (
  IN     UINT8   *InCert,
  IN     UINTN   CertSize,
  OUT    UINT8   **CertSubject,
  OUT    UINTN   *SubjectSize
  )
{
  EFI_STATUS    Status;

  Status = EFI_SUCCESS;

  *SubjectSize = 0;
  X509GetSubjectName (InCert, CertSize, *CertSubject, SubjectSize);

  *CertSubject = AllocateZeroPool (*SubjectSize);
  if (!X509GetSubjectName (InCert, CertSize, *CertSubject, SubjectSize)) {
    Status = EFI_INVALID_PARAMETER;
  }

  return Status;
}
