/** @file
  Miscellaneous routines specific to Https for HttpDxe driver.

Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "HttpDriver.h"

/**
  Returns the first occurrence of a Null-terminated ASCII sub-string in a Null-terminated
  ASCII string and ignore case during the search process.

  This function scans the contents of the ASCII string specified by String
  and returns the first occurrence of SearchString and ignore case during the search process.
  If SearchString is not found in String, then NULL is returned. If the length of SearchString
  is zero, then String is returned.

  If String is NULL, then ASSERT().
  If SearchString is NULL, then ASSERT().

  @param[in]  String          A pointer to a Null-terminated ASCII string.
  @param[in]  SearchString    A pointer to a Null-terminated ASCII string to search for.

  @retval NULL            If the SearchString does not appear in String.
  @retval others          If there is a match return the first occurrence of SearchingString.
                          If the length of SearchString is zero,return String.

**/
CHAR8 *
AsciiStrCaseStr (
  IN      CONST CHAR8  *String,
  IN      CONST CHAR8  *SearchString
  )
{
  CONST CHAR8  *FirstMatch;
  CONST CHAR8  *SearchStringTmp;

  CHAR8  Src;
  CHAR8  Dst;

  //
  // ASSERT both strings are less long than PcdMaximumAsciiStringLength
  //
  ASSERT (AsciiStrSize (String) != 0);
  ASSERT (AsciiStrSize (SearchString) != 0);

  if (*SearchString == '\0') {
    return (CHAR8 *)String;
  }

  while (*String != '\0') {
    SearchStringTmp = SearchString;
    FirstMatch      = String;

    while (  (*SearchStringTmp != '\0')
          && (*String != '\0'))
    {
      Src = *String;
      Dst = *SearchStringTmp;

      if ((Src >= 'A') && (Src <= 'Z')) {
        Src += ('a' - 'A');
      }

      if ((Dst >= 'A') && (Dst <= 'Z')) {
        Dst += ('a' - 'A');
      }

      if (Src != Dst) {
        break;
      }

      String++;
      SearchStringTmp++;
    }

    if (*SearchStringTmp == '\0') {
      return (CHAR8 *)FirstMatch;
    }

    String = FirstMatch + 1;
  }

  return NULL;
}

/**
  The callback function to free the net buffer list.

  @param[in]  Arg The opaque parameter.

**/
VOID
EFIAPI
FreeNbufList (
  IN VOID  *Arg
  )
{
  ASSERT (Arg != NULL);

  NetbufFreeList ((LIST_ENTRY *)Arg);
  FreePool (Arg);
}

/**
  Check whether the Url is from Https.

  @param[in]    Url             The pointer to a HTTP or HTTPS URL string.

  @retval TRUE                  The Url is from HTTPS.
  @retval FALSE                 The Url is from HTTP.

**/
BOOLEAN
IsHttpsUrl (
  IN CHAR8  *Url
  )
{
  CHAR8  *Tmp;

  Tmp = NULL;

  Tmp = AsciiStrCaseStr (Url, HTTPS_FLAG);
  if ((Tmp != NULL) && (Tmp == Url)) {
    return TRUE;
  }

  return FALSE;
}

/**
  Creates a Tls child handle, open EFI_TLS_PROTOCOL and EFI_TLS_CONFIGURATION_PROTOCOL.

  @param[in]  ImageHandle           The firmware allocated handle for the UEFI image.
  @param[out] TlsSb                 Pointer to the TLS SERVICE_BINDING_PROTOCOL.
  @param[out] TlsProto              Pointer to the EFI_TLS_PROTOCOL instance.
  @param[out] TlsConfiguration      Pointer to the EFI_TLS_CONFIGURATION_PROTOCOL instance.

  @return  The child handle with opened EFI_TLS_PROTOCOL and EFI_TLS_CONFIGURATION_PROTOCOL.

**/
EFI_HANDLE
EFIAPI
TlsCreateChild (
  IN  EFI_HANDLE                      ImageHandle,
  OUT EFI_SERVICE_BINDING_PROTOCOL    **TlsSb,
  OUT EFI_TLS_PROTOCOL                **TlsProto,
  OUT EFI_TLS_CONFIGURATION_PROTOCOL  **TlsConfiguration
  )
{
  EFI_STATUS  Status;
  EFI_HANDLE  TlsChildHandle;

  TlsChildHandle = 0;

  //
  // Locate TlsServiceBinding protocol.
  //
  gBS->LocateProtocol (
         &gEfiTlsServiceBindingProtocolGuid,
         NULL,
         (VOID **)TlsSb
         );
  if (*TlsSb == NULL) {
    return NULL;
  }

  Status = (*TlsSb)->CreateChild (*TlsSb, &TlsChildHandle);
  if (EFI_ERROR (Status)) {
    return NULL;
  }

  Status = gBS->OpenProtocol (
                  TlsChildHandle,
                  &gEfiTlsProtocolGuid,
                  (VOID **)TlsProto,
                  ImageHandle,
                  TlsChildHandle,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    (*TlsSb)->DestroyChild (*TlsSb, TlsChildHandle);
    return NULL;
  }

  Status = gBS->OpenProtocol (
                  TlsChildHandle,
                  &gEfiTlsConfigurationProtocolGuid,
                  (VOID **)TlsConfiguration,
                  ImageHandle,
                  TlsChildHandle,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    (*TlsSb)->DestroyChild (*TlsSb, TlsChildHandle);
    return NULL;
  }

  return TlsChildHandle;
}

/**
  Create event for the TLS receive and transmit tokens which are used to receive and
  transmit TLS related messages.

  @param[in, out]  HttpInstance       Pointer to HTTP_PROTOCOL structure.

  @retval EFI_SUCCESS            The events are created successfully.
  @retval others                 Other error as indicated.

**/
EFI_STATUS
EFIAPI
TlsCreateTxRxEvent (
  IN OUT HTTP_PROTOCOL  *HttpInstance
  )
{
  EFI_STATUS  Status;

  if (!HttpInstance->LocalAddressIsIPv6) {
    //
    // For Tcp4TlsTxToken.
    //
    Status = gBS->CreateEvent (
                    EVT_NOTIFY_SIGNAL,
                    TPL_NOTIFY,
                    HttpCommonNotify,
                    &HttpInstance->TlsIsTxDone,
                    &HttpInstance->Tcp4TlsTxToken.CompletionToken.Event
                    );
    if (EFI_ERROR (Status)) {
      goto ERROR;
    }

    HttpInstance->Tcp4TlsTxData.Push                            = TRUE;
    HttpInstance->Tcp4TlsTxData.Urgent                          = FALSE;
    HttpInstance->Tcp4TlsTxData.DataLength                      = 0;
    HttpInstance->Tcp4TlsTxData.FragmentCount                   = 1;
    HttpInstance->Tcp4TlsTxData.FragmentTable[0].FragmentLength = HttpInstance->Tcp4TlsTxData.DataLength;
    HttpInstance->Tcp4TlsTxData.FragmentTable[0].FragmentBuffer = NULL;
    HttpInstance->Tcp4TlsTxToken.Packet.TxData                  = &HttpInstance->Tcp4TlsTxData;
    HttpInstance->Tcp4TlsTxToken.CompletionToken.Status         = EFI_NOT_READY;

    //
    // For Tcp4TlsRxToken.
    //
    Status = gBS->CreateEvent (
                    EVT_NOTIFY_SIGNAL,
                    TPL_NOTIFY,
                    HttpCommonNotify,
                    &HttpInstance->TlsIsRxDone,
                    &HttpInstance->Tcp4TlsRxToken.CompletionToken.Event
                    );
    if (EFI_ERROR (Status)) {
      goto ERROR;
    }

    HttpInstance->Tcp4TlsRxData.DataLength                      = 0;
    HttpInstance->Tcp4TlsRxData.FragmentCount                   = 1;
    HttpInstance->Tcp4TlsRxData.FragmentTable[0].FragmentLength = HttpInstance->Tcp4TlsRxData.DataLength;
    HttpInstance->Tcp4TlsRxData.FragmentTable[0].FragmentBuffer = NULL;
    HttpInstance->Tcp4TlsRxToken.Packet.RxData                  = &HttpInstance->Tcp4TlsRxData;
    HttpInstance->Tcp4TlsRxToken.CompletionToken.Status         = EFI_NOT_READY;
  } else {
    //
    // For Tcp6TlsTxToken.
    //
    Status = gBS->CreateEvent (
                    EVT_NOTIFY_SIGNAL,
                    TPL_NOTIFY,
                    HttpCommonNotify,
                    &HttpInstance->TlsIsTxDone,
                    &HttpInstance->Tcp6TlsTxToken.CompletionToken.Event
                    );
    if (EFI_ERROR (Status)) {
      goto ERROR;
    }

    HttpInstance->Tcp6TlsTxData.Push                            = TRUE;
    HttpInstance->Tcp6TlsTxData.Urgent                          = FALSE;
    HttpInstance->Tcp6TlsTxData.DataLength                      = 0;
    HttpInstance->Tcp6TlsTxData.FragmentCount                   = 1;
    HttpInstance->Tcp6TlsTxData.FragmentTable[0].FragmentLength = HttpInstance->Tcp6TlsTxData.DataLength;
    HttpInstance->Tcp6TlsTxData.FragmentTable[0].FragmentBuffer = NULL;
    HttpInstance->Tcp6TlsTxToken.Packet.TxData                  = &HttpInstance->Tcp6TlsTxData;
    HttpInstance->Tcp6TlsTxToken.CompletionToken.Status         = EFI_NOT_READY;

    //
    // For Tcp6TlsRxToken.
    //
    Status = gBS->CreateEvent (
                    EVT_NOTIFY_SIGNAL,
                    TPL_NOTIFY,
                    HttpCommonNotify,
                    &HttpInstance->TlsIsRxDone,
                    &HttpInstance->Tcp6TlsRxToken.CompletionToken.Event
                    );
    if (EFI_ERROR (Status)) {
      goto ERROR;
    }

    HttpInstance->Tcp6TlsRxData.DataLength                      = 0;
    HttpInstance->Tcp6TlsRxData.FragmentCount                   = 1;
    HttpInstance->Tcp6TlsRxData.FragmentTable[0].FragmentLength = HttpInstance->Tcp6TlsRxData.DataLength;
    HttpInstance->Tcp6TlsRxData.FragmentTable[0].FragmentBuffer = NULL;
    HttpInstance->Tcp6TlsRxToken.Packet.RxData                  = &HttpInstance->Tcp6TlsRxData;
    HttpInstance->Tcp6TlsRxToken.CompletionToken.Status         = EFI_NOT_READY;
  }

  return Status;

ERROR:
  //
  // Error handling
  //
  TlsCloseTxRxEvent (HttpInstance);

  return Status;
}

/**
  Close events in the TlsTxToken and TlsRxToken.

  @param[in]  HttpInstance   Pointer to HTTP_PROTOCOL structure.

**/
VOID
EFIAPI
TlsCloseTxRxEvent (
  IN  HTTP_PROTOCOL  *HttpInstance
  )
{
  ASSERT (HttpInstance != NULL);
  if (!HttpInstance->LocalAddressIsIPv6) {
    if (NULL != HttpInstance->Tcp4TlsTxToken.CompletionToken.Event) {
      gBS->CloseEvent (HttpInstance->Tcp4TlsTxToken.CompletionToken.Event);
      HttpInstance->Tcp4TlsTxToken.CompletionToken.Event = NULL;
    }

    if (NULL != HttpInstance->Tcp4TlsRxToken.CompletionToken.Event) {
      gBS->CloseEvent (HttpInstance->Tcp4TlsRxToken.CompletionToken.Event);
      HttpInstance->Tcp4TlsRxToken.CompletionToken.Event = NULL;
    }
  } else {
    if (NULL != HttpInstance->Tcp6TlsTxToken.CompletionToken.Event) {
      gBS->CloseEvent (HttpInstance->Tcp6TlsTxToken.CompletionToken.Event);
      HttpInstance->Tcp6TlsTxToken.CompletionToken.Event = NULL;
    }

    if (NULL != HttpInstance->Tcp6TlsRxToken.CompletionToken.Event) {
      gBS->CloseEvent (HttpInstance->Tcp6TlsRxToken.CompletionToken.Event);
      HttpInstance->Tcp6TlsRxToken.CompletionToken.Event = NULL;
    }
  }
}

/**
  Read the TlsCaCertificate variable and configure it.

  @param[in, out]  HttpInstance       The HTTP instance private data.

  @retval EFI_SUCCESS            TlsCaCertificate is configured.
  @retval EFI_OUT_OF_RESOURCES   Can't allocate memory resources.
  @retval EFI_NOT_FOUND          Fail to get 'TlsCaCertificate' variable.
  @retval Others                 Other error as indicated.

**/
EFI_STATUS
TlsConfigCertificate (
  IN OUT HTTP_PROTOCOL  *HttpInstance
  )
{
  EFI_STATUS          Status;
  UINT8               *CACert;
  UINTN               CACertSize;
  UINT32              Index;
  EFI_SIGNATURE_LIST  *CertList;
  EFI_SIGNATURE_DATA  *Cert;
  UINTN               CertArraySizeInBytes;
  UINTN               CertCount;
  UINT32              ItemDataSize;

  CACert     = NULL;
  CACertSize = 0;

  //
  // Try to read the TlsCaCertificate variable.
  //
  Status = gRT->GetVariable (
                  EFI_TLS_CA_CERTIFICATE_VARIABLE,
                  &gEfiTlsCaCertificateGuid,
                  NULL,
                  &CACertSize,
                  NULL
                  );

  if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {
    return Status;
  }

  //
  // Allocate buffer and read the config variable.
  //
  CACert = AllocatePool (CACertSize);
  if (CACert == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Status = gRT->GetVariable (
                  EFI_TLS_CA_CERTIFICATE_VARIABLE,
                  &gEfiTlsCaCertificateGuid,
                  NULL,
                  &CACertSize,
                  CACert
                  );
  if (EFI_ERROR (Status)) {
    //
    // GetVariable still error or the variable is corrupted.
    //
    goto FreeCACert;
  }

  ASSERT (CACert != NULL);

  //
  // Sanity check
  //
  Status       = EFI_INVALID_PARAMETER;
  CertCount    = 0;
  ItemDataSize = (UINT32)CACertSize;
  while (ItemDataSize > 0) {
    if (ItemDataSize < sizeof (EFI_SIGNATURE_LIST)) {
      DEBUG ((
        DEBUG_ERROR,
        "%a: truncated EFI_SIGNATURE_LIST header\n",
        __FUNCTION__
        ));
      goto FreeCACert;
    }

    CertList = (EFI_SIGNATURE_LIST *)(CACert + (CACertSize - ItemDataSize));

    if (CertList->SignatureListSize < sizeof (EFI_SIGNATURE_LIST)) {
      DEBUG ((
        DEBUG_ERROR,
        "%a: SignatureListSize too small for EFI_SIGNATURE_LIST\n",
        __FUNCTION__
        ));
      goto FreeCACert;
    }

    if (CertList->SignatureListSize > ItemDataSize) {
      DEBUG ((
        DEBUG_ERROR,
        "%a: truncated EFI_SIGNATURE_LIST body\n",
        __FUNCTION__
        ));
      goto FreeCACert;
    }

    if (!CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid)) {
      DEBUG ((
        DEBUG_ERROR,
        "%a: only X509 certificates are supported\n",
        __FUNCTION__
        ));
      Status = EFI_UNSUPPORTED;
      goto FreeCACert;
    }

    if (CertList->SignatureHeaderSize != 0) {
      DEBUG ((
        DEBUG_ERROR,
        "%a: SignatureHeaderSize must be 0 for X509\n",
        __FUNCTION__
        ));
      goto FreeCACert;
    }

    if (CertList->SignatureSize < sizeof (EFI_SIGNATURE_DATA)) {
      DEBUG ((
        DEBUG_ERROR,
        "%a: SignatureSize too small for EFI_SIGNATURE_DATA\n",
        __FUNCTION__
        ));
      goto FreeCACert;
    }

    CertArraySizeInBytes = (CertList->SignatureListSize -
                            sizeof (EFI_SIGNATURE_LIST));
    if (CertArraySizeInBytes % CertList->SignatureSize != 0) {
      DEBUG ((
        DEBUG_ERROR,
        "%a: EFI_SIGNATURE_DATA array not a multiple of SignatureSize\n",
        __FUNCTION__
        ));
      goto FreeCACert;
    }

    CertCount    += CertArraySizeInBytes / CertList->SignatureSize;
    ItemDataSize -= CertList->SignatureListSize;
  }

  if (CertCount == 0) {
    DEBUG ((DEBUG_ERROR, "%a: no X509 certificates provided\n", __FUNCTION__));
    goto FreeCACert;
  }

  //
  // Enumerate all data and erasing the target item.
  //
  ItemDataSize = (UINT32)CACertSize;
  CertList     = (EFI_SIGNATURE_LIST *)CACert;
  while ((ItemDataSize > 0) && (ItemDataSize >= CertList->SignatureListSize)) {
    Cert      = (EFI_SIGNATURE_DATA *)((UINT8 *)CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
    CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;
    for (Index = 0; Index < CertCount; Index++) {
      //
      // EfiTlsConfigDataTypeCACertificate
      //
      Status = HttpInstance->TlsConfiguration->SetData (
                                                 HttpInstance->TlsConfiguration,
                                                 EfiTlsConfigDataTypeCACertificate,
                                                 Cert->SignatureData,
                                                 CertList->SignatureSize - sizeof (Cert->SignatureOwner)
                                                 );
      if (EFI_ERROR (Status)) {
        goto FreeCACert;
      }

      Cert = (EFI_SIGNATURE_DATA *)((UINT8 *)Cert + CertList->SignatureSize);
    }

    ItemDataSize -= CertList->SignatureListSize;
    CertList      = (EFI_SIGNATURE_LIST *)((UINT8 *)CertList + CertList->SignatureListSize);
  }

FreeCACert:
  FreePool (CACert);
  return Status;
}

/**
  Read the HttpTlsCipherList variable and configure it for HTTPS session.

  @param[in, out]  HttpInstance  The HTTP instance private data.

  @retval EFI_SUCCESS            The prefered HTTP TLS CipherList is configured.
  @retval EFI_NOT_FOUND          Fail to get 'HttpTlsCipherList' variable.
  @retval EFI_INVALID_PARAMETER  The contents of variable are invalid.
  @retval EFI_OUT_OF_RESOURCES   Can't allocate memory resources.

  @retval Others                 Other error as indicated.

**/
EFI_STATUS
TlsConfigCipherList (
  IN OUT HTTP_PROTOCOL  *HttpInstance
  )
{
  EFI_STATUS  Status;
  UINT8       *CipherList;
  UINTN       CipherListSize;

  CipherList     = NULL;
  CipherListSize = 0;

  //
  // Try to read the HttpTlsCipherList variable.
  //
  Status = gRT->GetVariable (
                  EDKII_HTTP_TLS_CIPHER_LIST_VARIABLE,
                  &gEdkiiHttpTlsCipherListGuid,
                  NULL,
                  &CipherListSize,
                  NULL
                  );
  ASSERT (EFI_ERROR (Status));
  if (Status != EFI_BUFFER_TOO_SMALL) {
    return Status;
  }

  if (CipherListSize % sizeof (EFI_TLS_CIPHER) != 0) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Allocate buffer and read the config variable.
  //
  CipherList = AllocatePool (CipherListSize);
  if (CipherList == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Status = gRT->GetVariable (
                  EDKII_HTTP_TLS_CIPHER_LIST_VARIABLE,
                  &gEdkiiHttpTlsCipherListGuid,
                  NULL,
                  &CipherListSize,
                  CipherList
                  );
  if (EFI_ERROR (Status)) {
    //
    // GetVariable still error or the variable is corrupted.
    //
    goto ON_EXIT;
  }

  ASSERT (CipherList != NULL);

  Status = HttpInstance->Tls->SetSessionData (
                                HttpInstance->Tls,
                                EfiTlsCipherList,
                                CipherList,
                                CipherListSize
                                );

ON_EXIT:
  FreePool (CipherList);

  return Status;
}

/**
  Configure TLS session data.

  @param[in, out]  HttpInstance       The HTTP instance private data.

  @retval EFI_SUCCESS            TLS session data is configured.
  @retval Others                 Other error as indicated.

**/
EFI_STATUS
EFIAPI
TlsConfigureSession (
  IN OUT HTTP_PROTOCOL  *HttpInstance
  )
{
  EFI_STATUS  Status;

  //
  // TlsConfigData initialization
  //
  HttpInstance->TlsConfigData.ConnectionEnd       = EfiTlsClient;
  HttpInstance->TlsConfigData.VerifyMethod        = EFI_TLS_VERIFY_PEER;
  HttpInstance->TlsConfigData.VerifyHost.Flags    = EFI_TLS_VERIFY_FLAG_NONE;
  HttpInstance->TlsConfigData.VerifyHost.HostName = HttpInstance->RemoteHost;
  HttpInstance->TlsConfigData.SessionState        = EfiTlsSessionNotStarted;

  //
  // EfiTlsConnectionEnd,
  // EfiTlsVerifyMethod,
  // EfiTlsVerifyHost,
  // EfiTlsSessionState
  //
  Status = HttpInstance->Tls->SetSessionData (
                                HttpInstance->Tls,
                                EfiTlsConnectionEnd,
                                &(HttpInstance->TlsConfigData.ConnectionEnd),
                                sizeof (EFI_TLS_CONNECTION_END)
                                );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = HttpInstance->Tls->SetSessionData (
                                HttpInstance->Tls,
                                EfiTlsVerifyMethod,
                                &HttpInstance->TlsConfigData.VerifyMethod,
                                sizeof (EFI_TLS_VERIFY)
                                );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = HttpInstance->Tls->SetSessionData (
                                HttpInstance->Tls,
                                EfiTlsVerifyHost,
                                &HttpInstance->TlsConfigData.VerifyHost,
                                sizeof (EFI_TLS_VERIFY_HOST)
                                );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = HttpInstance->Tls->SetSessionData (
                                HttpInstance->Tls,
                                EfiTlsSessionState,
                                &(HttpInstance->TlsConfigData.SessionState),
                                sizeof (EFI_TLS_SESSION_STATE)
                                );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Tls Cipher List
  //
  Status = TlsConfigCipherList (HttpInstance);
  if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
    DEBUG ((DEBUG_ERROR, "TlsConfigCipherList: return %r error.\n", Status));
    return Status;
  }

  //
  // Tls Config Certificate
  //
  Status = TlsConfigCertificate (HttpInstance);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "TLS Certificate Config Error!\n"));
    return Status;
  }

  //
  // TlsCreateTxRxEvent
  //
  Status = TlsCreateTxRxEvent (HttpInstance);
  if (EFI_ERROR (Status)) {
    goto ERROR;
  }

  return Status;

ERROR:
  TlsCloseTxRxEvent (HttpInstance);

  return Status;
}

/**
  Transmit the Packet by processing the associated HTTPS token.

  @param[in, out]   HttpInstance    Pointer to HTTP_PROTOCOL structure.
  @param[in]        Packet          The packet to transmit.

  @retval EFI_SUCCESS            The packet is transmitted.
  @retval EFI_INVALID_PARAMETER  HttpInstance is NULL or Packet is NULL.
  @retval EFI_OUT_OF_RESOURCES   Can't allocate memory resources.
  @retval EFI_DEVICE_ERROR       An unexpected system or network error occurred.
  @retval Others                 Other errors as indicated.

**/
EFI_STATUS
EFIAPI
TlsCommonTransmit (
  IN OUT HTTP_PROTOCOL  *HttpInstance,
  IN     NET_BUF        *Packet
  )
{
  EFI_STATUS  Status;
  VOID        *Data;
  UINTN       Size;

  if ((HttpInstance == NULL) || (Packet == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if (!HttpInstance->LocalAddressIsIPv6) {
    Size = sizeof (EFI_TCP4_TRANSMIT_DATA) +
           (Packet->BlockOpNum - 1) * sizeof (EFI_TCP4_FRAGMENT_DATA);
  } else {
    Size = sizeof (EFI_TCP6_TRANSMIT_DATA) +
           (Packet->BlockOpNum - 1) * sizeof (EFI_TCP6_FRAGMENT_DATA);
  }

  Data = AllocatePool (Size);
  if (Data == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  if (!HttpInstance->LocalAddressIsIPv6) {
    ((EFI_TCP4_TRANSMIT_DATA *)Data)->Push       = TRUE;
    ((EFI_TCP4_TRANSMIT_DATA *)Data)->Urgent     = FALSE;
    ((EFI_TCP4_TRANSMIT_DATA *)Data)->DataLength = Packet->TotalSize;

    //
    // Build the fragment table.
    //
    ((EFI_TCP4_TRANSMIT_DATA *)Data)->FragmentCount = Packet->BlockOpNum;

    NetbufBuildExt (
      Packet,
      (NET_FRAGMENT *)&((EFI_TCP4_TRANSMIT_DATA *)Data)->FragmentTable[0],
      &((EFI_TCP4_TRANSMIT_DATA *)Data)->FragmentCount
      );

    HttpInstance->Tcp4TlsTxToken.Packet.TxData = (EFI_TCP4_TRANSMIT_DATA *)Data;

    Status = EFI_DEVICE_ERROR;

    //
    // Transmit the packet.
    //
    Status = HttpInstance->Tcp4->Transmit (HttpInstance->Tcp4, &HttpInstance->Tcp4TlsTxToken);
    if (EFI_ERROR (Status)) {
      goto ON_EXIT;
    }

    while (!HttpInstance->TlsIsTxDone) {
      HttpInstance->Tcp4->Poll (HttpInstance->Tcp4);
    }

    HttpInstance->TlsIsTxDone = FALSE;
    Status                    = HttpInstance->Tcp4TlsTxToken.CompletionToken.Status;
  } else {
    ((EFI_TCP6_TRANSMIT_DATA *)Data)->Push       = TRUE;
    ((EFI_TCP6_TRANSMIT_DATA *)Data)->Urgent     = FALSE;
    ((EFI_TCP6_TRANSMIT_DATA *)Data)->DataLength = Packet->TotalSize;

    //
    // Build the fragment table.
    //
    ((EFI_TCP6_TRANSMIT_DATA *)Data)->FragmentCount = Packet->BlockOpNum;

    NetbufBuildExt (
      Packet,
      (NET_FRAGMENT *)&((EFI_TCP6_TRANSMIT_DATA *)Data)->FragmentTable[0],
      &((EFI_TCP6_TRANSMIT_DATA *)Data)->FragmentCount
      );

    HttpInstance->Tcp6TlsTxToken.Packet.TxData = (EFI_TCP6_TRANSMIT_DATA *)Data;

    Status = EFI_DEVICE_ERROR;

    //
    // Transmit the packet.
    //
    Status = HttpInstance->Tcp6->Transmit (HttpInstance->Tcp6, &HttpInstance->Tcp6TlsTxToken);
    if (EFI_ERROR (Status)) {
      goto ON_EXIT;
    }

    while (!HttpInstance->TlsIsTxDone) {
      HttpInstance->Tcp6->Poll (HttpInstance->Tcp6);
    }

    HttpInstance->TlsIsTxDone = FALSE;
    Status                    = HttpInstance->Tcp6TlsTxToken.CompletionToken.Status;
  }

ON_EXIT:
  FreePool (Data);

  return Status;
}

/**
  Receive the Packet by processing the associated HTTPS token.

  @param[in, out]   HttpInstance    Pointer to HTTP_PROTOCOL structure.
  @param[in]        Packet          The packet to transmit.
  @param[in]        Timeout         The time to wait for connection done.

  @retval EFI_SUCCESS            The Packet is received.
  @retval EFI_INVALID_PARAMETER  HttpInstance is NULL or Packet is NULL.
  @retval EFI_OUT_OF_RESOURCES   Can't allocate memory resources.
  @retval EFI_TIMEOUT            The operation is time out.
  @retval Others                 Other error as indicated.

**/
EFI_STATUS
EFIAPI
TlsCommonReceive (
  IN OUT HTTP_PROTOCOL  *HttpInstance,
  IN     NET_BUF        *Packet,
  IN     EFI_EVENT      Timeout
  )
{
  EFI_TCP4_RECEIVE_DATA  *Tcp4RxData;
  EFI_TCP6_RECEIVE_DATA  *Tcp6RxData;
  EFI_STATUS             Status;
  NET_FRAGMENT           *Fragment;
  UINT32                 FragmentCount;
  UINT32                 CurrentFragment;

  Tcp4RxData = NULL;
  Tcp6RxData = NULL;

  if ((HttpInstance == NULL) || (Packet == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  FragmentCount = Packet->BlockOpNum;
  Fragment      = AllocatePool (FragmentCount * sizeof (NET_FRAGMENT));
  if (Fragment == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_EXIT;
  }

  //
  // Build the fragment table.
  //
  NetbufBuildExt (Packet, Fragment, &FragmentCount);

  if (!HttpInstance->LocalAddressIsIPv6) {
    Tcp4RxData = HttpInstance->Tcp4TlsRxToken.Packet.RxData;
    if (Tcp4RxData == NULL) {
      return EFI_INVALID_PARAMETER;
    }

    Tcp4RxData->FragmentCount = 1;
  } else {
    Tcp6RxData = HttpInstance->Tcp6TlsRxToken.Packet.RxData;
    if (Tcp6RxData == NULL) {
      return EFI_INVALID_PARAMETER;
    }

    Tcp6RxData->FragmentCount = 1;
  }

  CurrentFragment = 0;
  Status          = EFI_SUCCESS;

  while (CurrentFragment < FragmentCount) {
    if (!HttpInstance->LocalAddressIsIPv6) {
      Tcp4RxData->DataLength                      = Fragment[CurrentFragment].Len;
      Tcp4RxData->FragmentTable[0].FragmentLength = Fragment[CurrentFragment].Len;
      Tcp4RxData->FragmentTable[0].FragmentBuffer = Fragment[CurrentFragment].Bulk;
      Status                                      = HttpInstance->Tcp4->Receive (HttpInstance->Tcp4, &HttpInstance->Tcp4TlsRxToken);
    } else {
      Tcp6RxData->DataLength                      = Fragment[CurrentFragment].Len;
      Tcp6RxData->FragmentTable[0].FragmentLength = Fragment[CurrentFragment].Len;
      Tcp6RxData->FragmentTable[0].FragmentBuffer = Fragment[CurrentFragment].Bulk;
      Status                                      = HttpInstance->Tcp6->Receive (HttpInstance->Tcp6, &HttpInstance->Tcp6TlsRxToken);
    }

    if (EFI_ERROR (Status)) {
      goto ON_EXIT;
    }

    while (!HttpInstance->TlsIsRxDone && ((Timeout == NULL) || EFI_ERROR (gBS->CheckEvent (Timeout)))) {
      //
      // Poll until some data is received or an error occurs.
      //
      if (!HttpInstance->LocalAddressIsIPv6) {
        HttpInstance->Tcp4->Poll (HttpInstance->Tcp4);
      } else {
        HttpInstance->Tcp6->Poll (HttpInstance->Tcp6);
      }
    }

    if (!HttpInstance->TlsIsRxDone) {
      //
      // Timeout occurs, cancel the receive request.
      //
      if (!HttpInstance->LocalAddressIsIPv6) {
        HttpInstance->Tcp4->Cancel (HttpInstance->Tcp4, &HttpInstance->Tcp4TlsRxToken.CompletionToken);
      } else {
        HttpInstance->Tcp6->Cancel (HttpInstance->Tcp6, &HttpInstance->Tcp6TlsRxToken.CompletionToken);
      }

      Status = EFI_TIMEOUT;
      goto ON_EXIT;
    } else {
      HttpInstance->TlsIsRxDone = FALSE;
    }

    if (!HttpInstance->LocalAddressIsIPv6) {
      Status = HttpInstance->Tcp4TlsRxToken.CompletionToken.Status;
      if (EFI_ERROR (Status)) {
        goto ON_EXIT;
      }

      Fragment[CurrentFragment].Len -= Tcp4RxData->FragmentTable[0].FragmentLength;
      if (Fragment[CurrentFragment].Len == 0) {
        CurrentFragment++;
      } else {
        Fragment[CurrentFragment].Bulk += Tcp4RxData->FragmentTable[0].FragmentLength;
      }
    } else {
      Status = HttpInstance->Tcp6TlsRxToken.CompletionToken.Status;
      if (EFI_ERROR (Status)) {
        goto ON_EXIT;
      }

      Fragment[CurrentFragment].Len -= Tcp6RxData->FragmentTable[0].FragmentLength;
      if (Fragment[CurrentFragment].Len == 0) {
        CurrentFragment++;
      } else {
        Fragment[CurrentFragment].Bulk += Tcp6RxData->FragmentTable[0].FragmentLength;
      }
    }
  }

ON_EXIT:

  if (Fragment != NULL) {
    FreePool (Fragment);
  }

  return Status;
}

/**
  Receive one TLS PDU. An TLS PDU contains an TLS record header and its
  corresponding record data. These two parts will be put into two blocks of buffers in the
  net buffer.

  @param[in, out]      HttpInstance    Pointer to HTTP_PROTOCOL structure.
  @param[out]          Pdu             The received TLS PDU.
  @param[in]           Timeout         The time to wait for connection done.

  @retval EFI_SUCCESS          An TLS PDU is received.
  @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
  @retval EFI_PROTOCOL_ERROR   An unexpected TLS packet was received.
  @retval Others               Other errors as indicated.

**/
EFI_STATUS
EFIAPI
TlsReceiveOnePdu (
  IN OUT HTTP_PROTOCOL  *HttpInstance,
  OUT NET_BUF           **Pdu,
  IN     EFI_EVENT      Timeout
  )
{
  EFI_STATUS  Status;

  LIST_ENTRY  *NbufList;

  UINT32  Len;

  NET_BUF            *PduHdr;
  UINT8              *Header;
  TLS_RECORD_HEADER  RecordHeader;

  NET_BUF  *DataSeg;

  NbufList = NULL;
  PduHdr   = NULL;
  Header   = NULL;
  DataSeg  = NULL;

  NbufList = AllocatePool (sizeof (LIST_ENTRY));
  if (NbufList == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  InitializeListHead (NbufList);

  //
  // Allocate buffer to receive one TLS header.
  //
  Len    = TLS_RECORD_HEADER_LENGTH;
  PduHdr = NetbufAlloc (Len);
  if (PduHdr == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_EXIT;
  }

  Header = NetbufAllocSpace (PduHdr, Len, NET_BUF_TAIL);
  if (Header == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_EXIT;
  }

  //
  // First step, receive one TLS header.
  //
  Status = TlsCommonReceive (HttpInstance, PduHdr, Timeout);
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  RecordHeader = *(TLS_RECORD_HEADER *)Header;
  if (((RecordHeader.ContentType == TlsContentTypeHandshake) ||
       (RecordHeader.ContentType == TlsContentTypeAlert) ||
       (RecordHeader.ContentType == TlsContentTypeChangeCipherSpec) ||
       (RecordHeader.ContentType == TlsContentTypeApplicationData)) &&
      (RecordHeader.Version.Major == 0x03) && /// Major versions are same.
      ((RecordHeader.Version.Minor == TLS10_PROTOCOL_VERSION_MINOR) ||
       (RecordHeader.Version.Minor == TLS11_PROTOCOL_VERSION_MINOR) ||
       (RecordHeader.Version.Minor == TLS12_PROTOCOL_VERSION_MINOR))
      )
  {
    InsertTailList (NbufList, &PduHdr->List);
  } else {
    Status = EFI_PROTOCOL_ERROR;
    goto ON_EXIT;
  }

  Len = SwapBytes16 (RecordHeader.Length);
  if (Len == 0) {
    //
    // No TLS payload.
    //
    goto FORM_PDU;
  }

  //
  // Allocate buffer to receive one TLS payload.
  //
  DataSeg = NetbufAlloc (Len);
  if (DataSeg == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_EXIT;
  }

  NetbufAllocSpace (DataSeg, Len, NET_BUF_TAIL);

  //
  // Second step, receive one TLS payload.
  //
  Status = TlsCommonReceive (HttpInstance, DataSeg, Timeout);
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  InsertTailList (NbufList, &DataSeg->List);

FORM_PDU:
  //
  // Form the PDU from a list of PDU.
  //
  *Pdu = NetbufFromBufList (NbufList, 0, 0, FreeNbufList, NbufList);
  if (*Pdu == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
  }

ON_EXIT:

  if (EFI_ERROR (Status)) {
    //
    // Free the Nbufs in this NbufList and the NbufList itself.
    //
    FreeNbufList (NbufList);
  }

  return Status;
}

/**
  Connect one TLS session by finishing the TLS handshake process.

  @param[in]  HttpInstance       The HTTP instance private data.
  @param[in]  Timeout            The time to wait for connection done.

  @retval EFI_SUCCESS            The TLS session is established.
  @retval EFI_OUT_OF_RESOURCES   Can't allocate memory resources.
  @retval EFI_ABORTED            TLS session state is incorrect.
  @retval Others                 Other error as indicated.

**/
EFI_STATUS
EFIAPI
TlsConnectSession (
  IN  HTTP_PROTOCOL  *HttpInstance,
  IN  EFI_EVENT      Timeout
  )
{
  EFI_STATUS  Status;
  UINT8       *BufferOut;
  UINTN       BufferOutSize;
  NET_BUF     *PacketOut;
  UINT8       *DataOut;
  NET_BUF     *Pdu;
  UINT8       *BufferIn;
  UINTN       BufferInSize;
  UINT8       *GetSessionDataBuffer;
  UINTN       GetSessionDataBufferSize;

  BufferOut = NULL;
  PacketOut = NULL;
  DataOut   = NULL;
  Pdu       = NULL;
  BufferIn  = NULL;

  //
  // Initialize TLS state.
  //
  HttpInstance->TlsSessionState = EfiTlsSessionNotStarted;
  Status                        = HttpInstance->Tls->SetSessionData (
                                                       HttpInstance->Tls,
                                                       EfiTlsSessionState,
                                                       &(HttpInstance->TlsSessionState),
                                                       sizeof (EFI_TLS_SESSION_STATE)
                                                       );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Create ClientHello
  //
  BufferOutSize = DEF_BUF_LEN;
  BufferOut     = AllocateZeroPool (BufferOutSize);
  if (BufferOut == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    return Status;
  }

  Status = HttpInstance->Tls->BuildResponsePacket (
                                HttpInstance->Tls,
                                NULL,
                                0,
                                BufferOut,
                                &BufferOutSize
                                );
  if (Status == EFI_BUFFER_TOO_SMALL) {
    FreePool (BufferOut);
    BufferOut = AllocateZeroPool (BufferOutSize);
    if (BufferOut == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      return Status;
    }

    Status = HttpInstance->Tls->BuildResponsePacket (
                                  HttpInstance->Tls,
                                  NULL,
                                  0,
                                  BufferOut,
                                  &BufferOutSize
                                  );
  }

  if (EFI_ERROR (Status)) {
    FreePool (BufferOut);
    return Status;
  }

  //
  // Transmit ClientHello
  //
  PacketOut = NetbufAlloc ((UINT32)BufferOutSize);
  DataOut   = NetbufAllocSpace (PacketOut, (UINT32)BufferOutSize, NET_BUF_TAIL);
  if (DataOut == NULL) {
    FreePool (BufferOut);
    return EFI_OUT_OF_RESOURCES;
  }

  CopyMem (DataOut, BufferOut, BufferOutSize);
  Status = TlsCommonTransmit (HttpInstance, PacketOut);

  FreePool (BufferOut);
  NetbufFree (PacketOut);

  if (EFI_ERROR (Status)) {
    return Status;
  }

  while (HttpInstance->TlsSessionState != EfiTlsSessionDataTransferring && \
         ((Timeout == NULL) || EFI_ERROR (gBS->CheckEvent (Timeout))))
  {
    //
    // Receive one TLS record.
    //
    Status = TlsReceiveOnePdu (HttpInstance, &Pdu, Timeout);
    if (EFI_ERROR (Status)) {
      return Status;
    }

    BufferInSize = Pdu->TotalSize;
    BufferIn     = AllocateZeroPool (BufferInSize);
    if (BufferIn == NULL) {
      NetbufFree (Pdu);
      Status = EFI_OUT_OF_RESOURCES;
      return Status;
    }

    NetbufCopy (Pdu, 0, (UINT32)BufferInSize, BufferIn);

    NetbufFree (Pdu);

    //
    // Handle Receive data.
    //
    BufferOutSize = DEF_BUF_LEN;
    BufferOut     = AllocateZeroPool (BufferOutSize);
    if (BufferOut == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      return Status;
    }

    Status = HttpInstance->Tls->BuildResponsePacket (
                                  HttpInstance->Tls,
                                  BufferIn,
                                  BufferInSize,
                                  BufferOut,
                                  &BufferOutSize
                                  );
    if (Status == EFI_BUFFER_TOO_SMALL) {
      FreePool (BufferOut);
      BufferOut = AllocateZeroPool (BufferOutSize);
      if (BufferOut == NULL) {
        FreePool (BufferIn);
        Status = EFI_OUT_OF_RESOURCES;
        return Status;
      }

      Status = HttpInstance->Tls->BuildResponsePacket (
                                    HttpInstance->Tls,
                                    BufferIn,
                                    BufferInSize,
                                    BufferOut,
                                    &BufferOutSize
                                    );
    }

    FreePool (BufferIn);

    if (EFI_ERROR (Status)) {
      FreePool (BufferOut);
      return Status;
    }

    if (BufferOutSize != 0) {
      //
      // Transmit the response packet.
      //
      PacketOut = NetbufAlloc ((UINT32)BufferOutSize);
      DataOut   = NetbufAllocSpace (PacketOut, (UINT32)BufferOutSize, NET_BUF_TAIL);
      if (DataOut == NULL) {
        FreePool (BufferOut);
        return EFI_OUT_OF_RESOURCES;
      }

      CopyMem (DataOut, BufferOut, BufferOutSize);

      Status = TlsCommonTransmit (HttpInstance, PacketOut);

      NetbufFree (PacketOut);

      if (EFI_ERROR (Status)) {
        FreePool (BufferOut);
        return Status;
      }
    }

    FreePool (BufferOut);

    //
    // Get the session state, then decide whether need to continue handle received packet.
    //
    GetSessionDataBufferSize = DEF_BUF_LEN;
    GetSessionDataBuffer     = AllocateZeroPool (GetSessionDataBufferSize);
    if (GetSessionDataBuffer == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      return Status;
    }

    Status = HttpInstance->Tls->GetSessionData (
                                  HttpInstance->Tls,
                                  EfiTlsSessionState,
                                  GetSessionDataBuffer,
                                  &GetSessionDataBufferSize
                                  );
    if (Status == EFI_BUFFER_TOO_SMALL) {
      FreePool (GetSessionDataBuffer);
      GetSessionDataBuffer = AllocateZeroPool (GetSessionDataBufferSize);
      if (GetSessionDataBuffer == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        return Status;
      }

      Status = HttpInstance->Tls->GetSessionData (
                                    HttpInstance->Tls,
                                    EfiTlsSessionState,
                                    GetSessionDataBuffer,
                                    &GetSessionDataBufferSize
                                    );
    }

    if (EFI_ERROR (Status)) {
      FreePool (GetSessionDataBuffer);
      return Status;
    }

    ASSERT (GetSessionDataBufferSize == sizeof (EFI_TLS_SESSION_STATE));
    HttpInstance->TlsSessionState = *(EFI_TLS_SESSION_STATE *)GetSessionDataBuffer;

    FreePool (GetSessionDataBuffer);

    if (HttpInstance->TlsSessionState == EfiTlsSessionError) {
      return EFI_ABORTED;
    }
  }

  if (HttpInstance->TlsSessionState != EfiTlsSessionDataTransferring) {
    Status = EFI_ABORTED;
  }

  return Status;
}

/**
  Close the TLS session and send out the close notification message.

  @param[in]  HttpInstance       The HTTP instance private data.

  @retval EFI_SUCCESS            The TLS session is closed.
  @retval EFI_INVALID_PARAMETER  HttpInstance is NULL.
  @retval EFI_OUT_OF_RESOURCES   Can't allocate memory resources.
  @retval Others                 Other error as indicated.

**/
EFI_STATUS
EFIAPI
TlsCloseSession (
  IN  HTTP_PROTOCOL  *HttpInstance
  )
{
  EFI_STATUS  Status;

  UINT8  *BufferOut;
  UINTN  BufferOutSize;

  NET_BUF  *PacketOut;
  UINT8    *DataOut;

  Status    = EFI_SUCCESS;
  BufferOut = NULL;
  PacketOut = NULL;
  DataOut   = NULL;

  if (HttpInstance == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  HttpInstance->TlsSessionState = EfiTlsSessionClosing;

  Status = HttpInstance->Tls->SetSessionData (
                                HttpInstance->Tls,
                                EfiTlsSessionState,
                                &(HttpInstance->TlsSessionState),
                                sizeof (EFI_TLS_SESSION_STATE)
                                );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  BufferOutSize = DEF_BUF_LEN;
  BufferOut     = AllocateZeroPool (BufferOutSize);
  if (BufferOut == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    return Status;
  }

  Status = HttpInstance->Tls->BuildResponsePacket (
                                HttpInstance->Tls,
                                NULL,
                                0,
                                BufferOut,
                                &BufferOutSize
                                );
  if (Status == EFI_BUFFER_TOO_SMALL) {
    FreePool (BufferOut);
    BufferOut = AllocateZeroPool (BufferOutSize);
    if (BufferOut == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      return Status;
    }

    Status = HttpInstance->Tls->BuildResponsePacket (
                                  HttpInstance->Tls,
                                  NULL,
                                  0,
                                  BufferOut,
                                  &BufferOutSize
                                  );
  }

  if (EFI_ERROR (Status)) {
    FreePool (BufferOut);
    return Status;
  }

  PacketOut = NetbufAlloc ((UINT32)BufferOutSize);
  DataOut   = NetbufAllocSpace (PacketOut, (UINT32)BufferOutSize, NET_BUF_TAIL);
  if (DataOut == NULL) {
    FreePool (BufferOut);
    return EFI_OUT_OF_RESOURCES;
  }

  CopyMem (DataOut, BufferOut, BufferOutSize);

  Status = TlsCommonTransmit (HttpInstance, PacketOut);

  FreePool (BufferOut);
  NetbufFree (PacketOut);

  return Status;
}

/**
  Process one message according to the CryptMode.

  @param[in]           HttpInstance    Pointer to HTTP_PROTOCOL structure.
  @param[in]           Message         Pointer to the message buffer needed to processed.
                                       If ProcessMode is EfiTlsEncrypt, the message contain the TLS
                                       header and plain text TLS APP payload.
                                       If ProcessMode is EfiTlsDecrypt, the message contain the TLS
                                       header and cipher text TLS APP payload.
  @param[in]           MessageSize     Pointer to the message buffer size.
  @param[in]           ProcessMode     Process mode.
  @param[in, out]      Fragment        Only one Fragment returned after the Message is
                                       processed successfully.
                                       If ProcessMode is EfiTlsEncrypt, the fragment contain the TLS
                                       header and cipher text TLS APP payload.
                                       If ProcessMode is EfiTlsDecrypt, the fragment contain the TLS
                                       header and plain text TLS APP payload.

  @retval EFI_SUCCESS          Message is processed successfully.
  @retval EFI_OUT_OF_RESOURCES   Can't allocate memory resources.
  @retval Others               Other errors as indicated.

**/
EFI_STATUS
EFIAPI
TlsProcessMessage (
  IN     HTTP_PROTOCOL       *HttpInstance,
  IN     UINT8               *Message,
  IN     UINTN               MessageSize,
  IN     EFI_TLS_CRYPT_MODE  ProcessMode,
  IN OUT NET_FRAGMENT        *Fragment
  )
{
  EFI_STATUS             Status;
  UINT8                  *Buffer;
  UINT32                 BufferSize;
  UINT32                 BytesCopied;
  EFI_TLS_FRAGMENT_DATA  *FragmentTable;
  UINT32                 FragmentCount;
  EFI_TLS_FRAGMENT_DATA  *OriginalFragmentTable;
  UINTN                  Index;

  Status                = EFI_SUCCESS;
  Buffer                = NULL;
  BufferSize            = 0;
  BytesCopied           = 0;
  FragmentTable         = NULL;
  OriginalFragmentTable = NULL;

  //
  // Rebuild fragment table from BufferIn.
  //
  FragmentCount = 1;
  FragmentTable = AllocateZeroPool (FragmentCount * sizeof (EFI_TLS_FRAGMENT_DATA));
  if (FragmentTable == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_EXIT;
  }

  FragmentTable->FragmentLength = (UINT32)MessageSize;
  FragmentTable->FragmentBuffer = Message;

  //
  // Record the original FragmentTable.
  //
  OriginalFragmentTable = FragmentTable;

  //
  // Process the Message.
  //
  Status = HttpInstance->Tls->ProcessPacket (
                                HttpInstance->Tls,
                                &FragmentTable,
                                &FragmentCount,
                                ProcessMode
                                );
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  //
  // Calculate the size according to FragmentTable.
  //
  for (Index = 0; Index < FragmentCount; Index++) {
    BufferSize += FragmentTable[Index].FragmentLength;
  }

  //
  // Allocate buffer for processed data.
  //
  Buffer = AllocateZeroPool (BufferSize);
  if (Buffer == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_EXIT;
  }

  //
  // Copy the new FragmentTable buffer into Buffer.
  //
  for (Index = 0; Index < FragmentCount; Index++) {
    CopyMem (
      (Buffer + BytesCopied),
      FragmentTable[Index].FragmentBuffer,
      FragmentTable[Index].FragmentLength
      );
    BytesCopied += FragmentTable[Index].FragmentLength;

    //
    // Free the FragmentBuffer since it has been copied.
    //
    FreePool (FragmentTable[Index].FragmentBuffer);
  }

  Fragment->Len  = BufferSize;
  Fragment->Bulk = Buffer;

ON_EXIT:

  if (OriginalFragmentTable != NULL) {
    if ( FragmentTable == OriginalFragmentTable) {
      FragmentTable = NULL;
    }

    FreePool (OriginalFragmentTable);
    OriginalFragmentTable = NULL;
  }

  //
  // Caller has the responsibility to free the FragmentTable.
  //
  if (FragmentTable != NULL) {
    FreePool (FragmentTable);
    FragmentTable = NULL;
  }

  return Status;
}

/**
  Receive one fragment decrypted from one TLS record.

  @param[in]           HttpInstance    Pointer to HTTP_PROTOCOL structure.
  @param[in, out]      Fragment        The received Fragment.
  @param[in]           Timeout         The time to wait for connection done.

  @retval EFI_SUCCESS          One fragment is received.
  @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
  @retval EFI_ABORTED          Something wrong decryption the message.
  @retval Others               Other errors as indicated.

**/
EFI_STATUS
EFIAPI
HttpsReceive (
  IN     HTTP_PROTOCOL  *HttpInstance,
  IN OUT NET_FRAGMENT   *Fragment,
  IN     EFI_EVENT      Timeout
  )
{
  EFI_STATUS         Status;
  NET_BUF            *Pdu;
  TLS_RECORD_HEADER  RecordHeader;
  UINT8              *BufferIn;
  UINTN              BufferInSize;
  NET_FRAGMENT       TempFragment;
  UINT8              *BufferOut;
  UINTN              BufferOutSize;
  NET_BUF            *PacketOut;
  UINT8              *DataOut;
  UINT8              *GetSessionDataBuffer;
  UINTN              GetSessionDataBufferSize;

  Status                   = EFI_SUCCESS;
  Pdu                      = NULL;
  BufferIn                 = NULL;
  BufferInSize             = 0;
  BufferOut                = NULL;
  BufferOutSize            = 0;
  PacketOut                = NULL;
  DataOut                  = NULL;
  GetSessionDataBuffer     = NULL;
  GetSessionDataBufferSize = 0;

  //
  // Receive only one TLS record
  //
  Status = TlsReceiveOnePdu (HttpInstance, &Pdu, Timeout);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  BufferInSize = Pdu->TotalSize;
  BufferIn     = AllocateZeroPool (BufferInSize);
  if (BufferIn == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    NetbufFree (Pdu);
    return Status;
  }

  NetbufCopy (Pdu, 0, (UINT32)BufferInSize, BufferIn);

  NetbufFree (Pdu);

  //
  // Handle Receive data.
  //
  RecordHeader = *(TLS_RECORD_HEADER *)BufferIn;

  if ((RecordHeader.ContentType == TlsContentTypeApplicationData) &&
      (RecordHeader.Version.Major == 0x03) &&
      ((RecordHeader.Version.Minor == TLS10_PROTOCOL_VERSION_MINOR) ||
       (RecordHeader.Version.Minor == TLS11_PROTOCOL_VERSION_MINOR) ||
       (RecordHeader.Version.Minor == TLS12_PROTOCOL_VERSION_MINOR))
      )
  {
    //
    // Decrypt Packet.
    //
    Status = TlsProcessMessage (
               HttpInstance,
               BufferIn,
               BufferInSize,
               EfiTlsDecrypt,
               &TempFragment
               );

    FreePool (BufferIn);

    if (EFI_ERROR (Status)) {
      if (Status == EFI_ABORTED) {
        //
        // Something wrong decryption the message.
        // BuildResponsePacket() will be called to generate Error Alert message and send it out.
        //
        BufferOutSize = DEF_BUF_LEN;
        BufferOut     = AllocateZeroPool (BufferOutSize);
        if (BufferOut == NULL) {
          Status = EFI_OUT_OF_RESOURCES;
          return Status;
        }

        Status = HttpInstance->Tls->BuildResponsePacket (
                                      HttpInstance->Tls,
                                      NULL,
                                      0,
                                      BufferOut,
                                      &BufferOutSize
                                      );
        if (Status == EFI_BUFFER_TOO_SMALL) {
          FreePool (BufferOut);
          BufferOut = AllocateZeroPool (BufferOutSize);
          if (BufferOut == NULL) {
            Status = EFI_OUT_OF_RESOURCES;
            return Status;
          }

          Status = HttpInstance->Tls->BuildResponsePacket (
                                        HttpInstance->Tls,
                                        NULL,
                                        0,
                                        BufferOut,
                                        &BufferOutSize
                                        );
        }

        if (EFI_ERROR (Status)) {
          FreePool (BufferOut);
          return Status;
        }

        if (BufferOutSize != 0) {
          PacketOut = NetbufAlloc ((UINT32)BufferOutSize);
          DataOut   = NetbufAllocSpace (PacketOut, (UINT32)BufferOutSize, NET_BUF_TAIL);
          if (DataOut == NULL) {
            FreePool (BufferOut);
            return EFI_OUT_OF_RESOURCES;
          }

          CopyMem (DataOut, BufferOut, BufferOutSize);

          Status = TlsCommonTransmit (HttpInstance, PacketOut);

          NetbufFree (PacketOut);
        }

        FreePool (BufferOut);

        if (EFI_ERROR (Status)) {
          return Status;
        }

        return EFI_ABORTED;
      }

      return Status;
    }

    //
    // Parsing buffer.
    //
    ASSERT (((TLS_RECORD_HEADER *)(TempFragment.Bulk))->ContentType == TlsContentTypeApplicationData);

    BufferInSize = ((TLS_RECORD_HEADER *)(TempFragment.Bulk))->Length;
    BufferIn     = AllocateZeroPool (BufferInSize);
    if (BufferIn == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      return Status;
    }

    CopyMem (BufferIn, TempFragment.Bulk + TLS_RECORD_HEADER_LENGTH, BufferInSize);

    //
    // Free the buffer in TempFragment.
    //
    FreePool (TempFragment.Bulk);
  } else if ((RecordHeader.ContentType == TlsContentTypeAlert) &&
             (RecordHeader.Version.Major == 0x03) &&
             ((RecordHeader.Version.Minor == TLS10_PROTOCOL_VERSION_MINOR) ||
              (RecordHeader.Version.Minor == TLS11_PROTOCOL_VERSION_MINOR) ||
              (RecordHeader.Version.Minor == TLS12_PROTOCOL_VERSION_MINOR))
             )
  {
    BufferOutSize = DEF_BUF_LEN;
    BufferOut     = AllocateZeroPool (BufferOutSize);
    if (BufferOut == NULL) {
      FreePool (BufferIn);
      Status = EFI_OUT_OF_RESOURCES;
      return Status;
    }

    Status = HttpInstance->Tls->BuildResponsePacket (
                                  HttpInstance->Tls,
                                  BufferIn,
                                  BufferInSize,
                                  BufferOut,
                                  &BufferOutSize
                                  );
    if (Status == EFI_BUFFER_TOO_SMALL) {
      FreePool (BufferOut);
      BufferOut = AllocateZeroPool (BufferOutSize);
      if (BufferOut == NULL) {
        FreePool (BufferIn);
        Status = EFI_OUT_OF_RESOURCES;
        return Status;
      }

      Status = HttpInstance->Tls->BuildResponsePacket (
                                    HttpInstance->Tls,
                                    BufferIn,
                                    BufferInSize,
                                    BufferOut,
                                    &BufferOutSize
                                    );
    }

    FreePool (BufferIn);

    if (EFI_ERROR (Status)) {
      FreePool (BufferOut);
      return Status;
    }

    if (BufferOutSize != 0) {
      PacketOut = NetbufAlloc ((UINT32)BufferOutSize);
      DataOut   = NetbufAllocSpace (PacketOut, (UINT32)BufferOutSize, NET_BUF_TAIL);
      if (DataOut == NULL) {
        FreePool (BufferOut);
        return EFI_OUT_OF_RESOURCES;
      }

      CopyMem (DataOut, BufferOut, BufferOutSize);

      Status = TlsCommonTransmit (HttpInstance, PacketOut);

      NetbufFree (PacketOut);
    }

    FreePool (BufferOut);

    //
    // Get the session state.
    //
    GetSessionDataBufferSize = DEF_BUF_LEN;
    GetSessionDataBuffer     = AllocateZeroPool (GetSessionDataBufferSize);
    if (GetSessionDataBuffer == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      return Status;
    }

    Status = HttpInstance->Tls->GetSessionData (
                                  HttpInstance->Tls,
                                  EfiTlsSessionState,
                                  GetSessionDataBuffer,
                                  &GetSessionDataBufferSize
                                  );
    if (Status == EFI_BUFFER_TOO_SMALL) {
      FreePool (GetSessionDataBuffer);
      GetSessionDataBuffer = AllocateZeroPool (GetSessionDataBufferSize);
      if (GetSessionDataBuffer == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        return Status;
      }

      Status = HttpInstance->Tls->GetSessionData (
                                    HttpInstance->Tls,
                                    EfiTlsSessionState,
                                    GetSessionDataBuffer,
                                    &GetSessionDataBufferSize
                                    );
    }

    if (EFI_ERROR (Status)) {
      FreePool (GetSessionDataBuffer);
      return Status;
    }

    ASSERT (GetSessionDataBufferSize == sizeof (EFI_TLS_SESSION_STATE));
    HttpInstance->TlsSessionState = *(EFI_TLS_SESSION_STATE *)GetSessionDataBuffer;

    FreePool (GetSessionDataBuffer);

    if (HttpInstance->TlsSessionState == EfiTlsSessionError) {
      DEBUG ((DEBUG_ERROR, "TLS Session State Error!\n"));
      return EFI_ABORTED;
    }

    BufferIn     = NULL;
    BufferInSize = 0;
  }

  Fragment->Bulk = BufferIn;
  Fragment->Len  = (UINT32)BufferInSize;

  return Status;
}
