/** @file
  Miscellaneous routines specific to Https for HttpDxe driver.

Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
(C) Copyright 2016 Hewlett Packard Enterprise Development LP<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 "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] 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_TLS_PROTOCOL               **TlsProto,
  OUT EFI_TLS_CONFIGURATION_PROTOCOL **TlsConfiguration
  )
{
  EFI_STATUS                    Status;
  EFI_SERVICE_BINDING_PROTOCOL  *TlsSb;
  EFI_HANDLE                    TlsChildHandle;

  TlsSb          = NULL;
  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               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.
    // Fall back to the default value.
    //
    FreePool (CACert);

    return EFI_NOT_FOUND;
  }

  ASSERT (CACert != NULL);

  //
  // 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)) {
        FreePool (CACert);
        return Status;
      }

      Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) Cert + CertList->SignatureSize);
    }

    ItemDataSize -= CertList->SignatureListSize;
    CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize);
  }

  FreePool (CACert);
  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.SessionState = EfiTlsSessionNotStarted;

  //
  // EfiTlsConnectionEnd,
  // EfiTlsVerifyMethod
  // 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,
                                EfiTlsSessionState,
                                &(HttpInstance->TlsConfigData.SessionState),
                                sizeof (EFI_TLS_SESSION_STATE)
                                );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Tls Config Certificate
  //
  Status = TlsConfigCertificate (HttpInstance);
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_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 it's
  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     = sizeof (TLS_RECORD_HEADER);
  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 == TLS_CONTENT_TYPE_HANDSHAKE ||
    RecordHeader.ContentType == TLS_CONTENT_TYPE_ALERT ||
    RecordHeader.ContentType == TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC ||
    RecordHeader.ContentType == TLS_CONTENT_TYPE_APPLICATION_DATA) &&
    (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);

  if (EFI_ERROR (Status)) {
    return Status;
  }

  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.
  @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.

  @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) {
    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 == TLS_CONTENT_TYPE_APPLICATION_DATA) &&
    (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 == TLS_CONTENT_TYPE_APPLICATION_DATA);

    BufferInSize = ((TLS_RECORD_HEADER *) (TempFragment.Bulk))->Length;
    BufferIn = AllocateZeroPool (BufferInSize);
    if (BufferIn == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      return Status;
    }

    CopyMem (BufferIn, TempFragment.Bulk + sizeof (TLS_RECORD_HEADER), BufferInSize);

    //
    // Free the buffer in TempFragment.
    //
    FreePool (TempFragment.Bulk);

  } else if ((RecordHeader.ContentType == TLS_CONTENT_TYPE_ALERT) &&
    (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 ((EFI_D_ERROR, "TLS Session State Error!\n"));
      return EFI_ABORTED;
    }

    BufferIn = NULL;
    BufferInSize = 0;
  }

  Fragment->Bulk = BufferIn;
  Fragment->Len = (UINT32) BufferInSize;

  return Status;
}
