/** @file
  Miscellaneous routines specific to Https for HttpDxe driver.

Copyright (c) 2016 - 2017, 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 == 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.
  @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 == 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 + sizeof (TLS_RECORD_HEADER), 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 ((EFI_D_ERROR, "TLS Session State Error!\n"));
      return EFI_ABORTED;
    }

    BufferIn = NULL;
    BufferInSize = 0;
  }

  Fragment->Bulk = BufferIn;
  Fragment->Len = (UINT32) BufferInSize;

  return Status;
}

