/** @file
  Common interfaces to call Security library.

  Copyright (c) 2009 - 2016, 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;
}
