v2:
To support the multiple certificate configuration,
EFI_SIGNATURE_LIST format is used for the variable
'TlsCaCertificate'.

This patch is used to enable HTTPS feature. HttpDxe driver
will consume TlsDxe driver. It can both support
http and https feature, it’s depended on the information in URL,
the HTTP instance can be able to determine whether to use http
or https.

Cc: Ye Ting <ting...@intel.com>
Cc: Fu Siyuan <siyuan...@intel.com>
Cc: Long Qin <qin.l...@intel.com>
Cc: El-Haj-Mahmoud Samer <samer.el-haj-mahm...@hpe.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jiaxin Wu <jiaxin...@intel.com>
---
 NetworkPkg/HttpDxe/HttpDriver.h   |    8 +-
 NetworkPkg/HttpDxe/HttpDxe.inf    |    8 +-
 NetworkPkg/HttpDxe/HttpImpl.c     |  188 +++-
 NetworkPkg/HttpDxe/HttpProto.c    |  395 ++++++---
 NetworkPkg/HttpDxe/HttpProto.h    |   65 +-
 NetworkPkg/HttpDxe/HttpsSupport.c | 1701 +++++++++++++++++++++++++++++++++++++
 NetworkPkg/HttpDxe/HttpsSupport.h |  314 +++++++
 7 files changed, 2542 insertions(+), 137 deletions(-)
 create mode 100644 NetworkPkg/HttpDxe/HttpsSupport.c
 create mode 100644 NetworkPkg/HttpDxe/HttpsSupport.h

diff --git a/NetworkPkg/HttpDxe/HttpDriver.h b/NetworkPkg/HttpDxe/HttpDriver.h
index 9c0002a..3c30c12 100644
--- a/NetworkPkg/HttpDxe/HttpDriver.h
+++ b/NetworkPkg/HttpDxe/HttpDriver.h
@@ -1,9 +1,9 @@
 /** @file
   The header files of the driver binding and service binding protocol for 
HttpDxe driver.
 
-  Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2015 - 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
@@ -22,10 +22,11 @@
 
 //
 // Libraries
 //
 #include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
 #include <Library/MemoryAllocationLib.h>
 #include <Library/BaseLib.h>
 #include <Library/UefiLib.h>
 #include <Library/DebugLib.h>
 #include <Library/NetLib.h>
@@ -48,12 +49,14 @@
 #include <Protocol/Tcp6.h>
 #include <Protocol/Dns4.h>
 #include <Protocol/Dns6.h>
 #include <Protocol/Ip4Config2.h>
 #include <Protocol/Ip6Config.h>
+#include <Protocol/Tls.h>
+#include <Protocol/TlsConfig.h>
 
-
+#include <Guid/ImageAuthentication.h>
 //
 // Produced Protocols
 //
 #include <Protocol/Http.h>
 
@@ -77,10 +80,11 @@ extern EFI_HTTP_UTILITIES_PROTOCOL  *mHttpUtilities;
 // Include files with function prototypes
 //
 #include "ComponentName.h"
 #include "HttpImpl.h"
 #include "HttpProto.h"
+#include "HttpsSupport.h"
 #include "HttpDns.h"
 
 typedef struct {
   EFI_SERVICE_BINDING_PROTOCOL  *ServiceBinding;
   UINTN                         NumberOfChildren;
diff --git a/NetworkPkg/HttpDxe/HttpDxe.inf b/NetworkPkg/HttpDxe/HttpDxe.inf
index bf2cbee..a228c3d 100644
--- a/NetworkPkg/HttpDxe/HttpDxe.inf
+++ b/NetworkPkg/HttpDxe/HttpDxe.inf
@@ -1,9 +1,9 @@
 ## @file
 #  Implementation of EFI HTTP protocol interfaces.
 #
-#  Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
 #
 #  This program and the accompanying materials
 #  are licensed and made available under the terms and conditions of the BSD 
License
 #  which accompanies this distribution. The full text of the license may be 
found at
 #  http://opensource.org/licenses/bsd-license.php.
@@ -36,14 +36,17 @@
   HttpDriver.c
   HttpImpl.h
   HttpImpl.c
   HttpProto.h
   HttpProto.c
+  HttpsSupport.h
+  HttpsSupport.c
 
 [LibraryClasses]
   UefiDriverEntryPoint
   UefiBootServicesTableLib
+  UefiRuntimeServicesTableLib
   MemoryAllocationLib
   BaseLib
   UefiLib
   DebugLib
   NetLib
@@ -62,8 +65,11 @@
   gEfiDns4ProtocolGuid                             ## SOMETIMES_CONSUMES
   gEfiDns6ServiceBindingProtocolGuid               ## SOMETIMES_CONSUMES
   gEfiDns6ProtocolGuid                             ## SOMETIMES_CONSUMES
   gEfiIp4Config2ProtocolGuid                       ## SOMETIMES_CONSUMES
   gEfiIp6ConfigProtocolGuid                        ## SOMETIMES_CONSUMES
+  gEfiTlsServiceBindingProtocolGuid                ## SOMETIMES_CONSUMES
+  gEfiTlsProtocolGuid                              ## SOMETIMES_CONSUMES
+  gEfiTlsConfigurationProtocolGuid                 ## SOMETIMES_CONSUMES
 
 [UserExtensions.TianoCore."ExtraFiles"]
   HttpDxeExtra.uni
\ No newline at end of file
diff --git a/NetworkPkg/HttpDxe/HttpImpl.c b/NetworkPkg/HttpDxe/HttpImpl.c
index 63b683e..8d81a90 100644
--- a/NetworkPkg/HttpDxe/HttpImpl.c
+++ b/NetworkPkg/HttpDxe/HttpImpl.c
@@ -238,10 +238,11 @@ EfiHttpRequest (
   CHAR8                         *HostName;
   UINT16                        RemotePort;
   HTTP_PROTOCOL                 *HttpInstance;
   BOOLEAN                       Configure;
   BOOLEAN                       ReConfigure;
+  BOOLEAN                       TlsConfigure;
   CHAR8                         *RequestStr;
   CHAR8                         *Url;
   UINTN                         UrlLen;
   CHAR16                        *HostNameStr;
   HTTP_TOKEN_WRAP               *Wrap;
@@ -306,10 +307,38 @@ EfiHttpRequest (
     HttpInstance->Url = Url;    
   } 
 
 
   UnicodeStrToAsciiStr (Request->Url, Url);
+
+  //
+  // From the information in Url, the HTTP instance will 
+  // be able to determine whether to use http or https.
+  //
+  HttpInstance->UseHttps = IsHttpsUrl (Url);
+
+  TlsConfigure = FALSE;
+
+  //
+  // Check whether we need to create Tls child and open the TLS protocol.
+  //
+  if (HttpInstance->UseHttps && HttpInstance->TlsChildHandle == NULL) {
+    //
+    // Use TlsSb to create Tls child and open the TLS protocol.
+    //
+    HttpInstance->TlsChildHandle = TlsCreateChild (
+                                     HttpInstance->Service->ImageHandle,
+                                     &(HttpInstance->Tls),
+                                     &(HttpInstance->TlsConfiguration)
+                                     );
+    if (HttpInstance->TlsChildHandle == NULL) {
+      return EFI_DEVICE_ERROR;
+    }
+
+    TlsConfigure = TRUE;
+  }
+
   UrlParser = NULL;
   Status = HttpParseUrl (Url, (UINT32) AsciiStrLen (Url), FALSE, &UrlParser);
   if (EFI_ERROR (Status)) {
     goto Error1;
   }
@@ -321,30 +350,38 @@ EfiHttpRequest (
     goto Error1;
   }
 
   Status = HttpUrlGetPort (Url, UrlParser, &RemotePort);
   if (EFI_ERROR (Status)) {
-    RemotePort = HTTP_DEFAULT_PORT;
+    if (HttpInstance->UseHttps) {
+      RemotePort = HTTPS_DEFAULT_PORT;
+    } else {
+      RemotePort = HTTP_DEFAULT_PORT;
+    }
   }
   //
   // If Configure is TRUE, it indicates the first time to call Request();
   // If ReConfigure is TRUE, it indicates the request URL is not same
   // with the previous call to Request();
   //
   Configure   = TRUE;
-  ReConfigure = TRUE;  
+  ReConfigure = TRUE;
 
   if (HttpInstance->RemoteHost == NULL) {
     //
     // Request() is called the first time. 
     //
     ReConfigure = FALSE;
   } else {
     if ((HttpInstance->RemotePort == RemotePort) &&
-        (AsciiStrCmp (HttpInstance->RemoteHost, HostName) == 0)) {
+        (AsciiStrCmp (HttpInstance->RemoteHost, HostName) == 0) && 
+        (!HttpInstance->UseHttps || (HttpInstance->UseHttps && 
+                                     !TlsConfigure && 
+                                     HttpInstance->TlsSessionState == 
EfiTlsSessionDataTransferring))) {
       //
       // Host Name and port number of the request URL are the same with 
previous call to Request().
+      // If Https protocol used, the corresponding SessionState is 
EfiTlsSessionDataTransferring.
       // Check whether previous TCP packet sent out.
       //
       if (EFI_ERROR (NetMapIterate (&HttpInstance->TxTokens, HttpTcpNotReady, 
NULL))) {
         //
         // Wrap the HTTP token in HTTP_TOKEN_WRAP
@@ -423,11 +460,10 @@ EfiHttpRequest (
       if (EFI_ERROR (Status)) {
         goto Error1;
       }
     }
 
-
     //
     // Save the RemotePort and RemoteHost.
     //
     ASSERT (HttpInstance->RemoteHost == NULL);
     HttpInstance->RemotePort = RemotePort;
@@ -442,10 +478,20 @@ EfiHttpRequest (
     if (!HttpInstance->LocalAddressIsIPv6) {
       ASSERT (HttpInstance->Tcp4 != NULL);
     } else {
       ASSERT (HttpInstance->Tcp6 != NULL);
     }
+
+    if (HttpInstance->UseHttps && !TlsConfigure) {
+      Status = TlsCloseSession (HttpInstance);
+      if (EFI_ERROR (Status)) {
+        goto Error1;
+      }
+      
+      TlsCloseTxRxEvent (HttpInstance);
+    }
+    
     HttpCloseConnection (HttpInstance);
     EfiHttpCancel (This, NULL);
   }
 
   //
@@ -459,16 +505,21 @@ EfiHttpRequest (
 
   Wrap->HttpToken      = Token;
   Wrap->HttpInstance   = HttpInstance;
   Wrap->TcpWrap.Method = Request->Method;
 
-  Status = HttpInitTcp (HttpInstance, Wrap, Configure);
+  Status = HttpInitSession (
+             HttpInstance, 
+             Wrap, 
+             Configure || ReConfigure, 
+             TlsConfigure
+             );
   if (EFI_ERROR (Status)) {
     goto Error2;
-  }  
+  }
 
-  if (!Configure) {
+  if (!Configure && !ReConfigure && !TlsConfigure) {
     //
     // For the new HTTP token, create TX TCP token events.    
     //
     Status = HttpCreateTcpTxEvent (Wrap);
     if (EFI_ERROR (Status)) {
@@ -537,10 +588,15 @@ Error4:
   if (RequestStr != NULL) {
     FreePool (RequestStr);
   }  
 
 Error3:
+  if (HttpInstance->UseHttps) {
+    TlsCloseSession (HttpInstance);
+    TlsCloseTxRxEvent (HttpInstance);
+  }  
+  
   HttpCloseConnection (HttpInstance);
 
 Error2:
   HttpCloseTcpConnCloseEvent (HttpInstance);
   if (NULL != Wrap->TcpWrap.Tx4Token.CompletionToken.Event) {
@@ -837,10 +893,11 @@ HttpResponseWorker (
   HTTP_PROTOCOL                 *HttpInstance;
   EFI_HTTP_TOKEN                *Token;
   NET_MAP_ITEM                  *Item;
   HTTP_TOKEN_WRAP               *ValueInItem;
   UINTN                         HdrLen;
+  NET_FRAGMENT                  Fragment;
 
   if (Wrap == NULL || Wrap->HttpInstance == NULL) {
     return EFI_INVALID_PARAMETER;
   }
   
@@ -853,21 +910,15 @@ HttpResponseWorker (
   HttpMsg->Headers          = NULL;
   HttpHeaders               = NULL;
   SizeofHeaders             = 0;
   BufferSize                = 0;
   EndofHeader               = NULL;
+  Fragment.Len              = 0;
+  Fragment.Bulk             = NULL;
  
   if (HttpMsg->Data.Response != NULL) {
     //
-    // Need receive the HTTP headers, prepare buffer.
-    //
-    Status = HttpCreateTcpRxEventForHeader (HttpInstance);
-    if (EFI_ERROR (Status)) {
-      goto Error;
-    }
-
-    //
     // Check whether we have cached header from previous call.
     //
     if ((HttpInstance->CacheBody != NULL) && (HttpInstance->NextMsg != NULL)) {
       //
       // The data is stored at [NextMsg, CacheBody + CacheLen].
@@ -925,27 +976,30 @@ HttpResponseWorker (
     //
     // Search for Status Code.
     //
     StatusCodeStr = HttpHeaders + AsciiStrLen (HTTP_VERSION_STR) + 1;
     if (StatusCodeStr == NULL) {
+      Status = EFI_NOT_READY;
       goto Error;
     }
 
     StatusCode = AsciiStrDecimalToUintn (StatusCodeStr);
 
     //
     // Remove the first line of HTTP message, e.g. "HTTP/1.1 200 OK\r\n".
     //
     Tmp = AsciiStrStr (HttpHeaders, HTTP_CRLF_STR);
     if (Tmp == NULL) {
+      Status = EFI_NOT_READY;
       goto Error;
     }
 
     Tmp = Tmp + AsciiStrLen (HTTP_CRLF_STR);
     SizeofHeaders = SizeofHeaders - (Tmp - HttpHeaders);
     HeaderTmp = AllocateZeroPool (SizeofHeaders);
     if (HeaderTmp == NULL) {
+      Status = EFI_OUT_OF_RESOURCES;
       goto Error;
     }
 
     CopyMem (HeaderTmp, Tmp, SizeofHeaders);
     FreePool (HttpHeaders);
@@ -1098,13 +1152,91 @@ HttpResponseWorker (
   ASSERT (HttpInstance->MsgParser != NULL);
 
   //
   // We still need receive more data when there is no cache data and MsgParser 
is not NULL;
   //
-  Status = HttpTcpReceiveBody (Wrap, HttpMsg);
-  if (EFI_ERROR (Status)) {
-    goto Error;
+  if (!HttpInstance->UseHttps) {
+    Status = HttpTcpReceiveBody (Wrap, HttpMsg);
+    if (EFI_ERROR (Status)) {
+      goto Error;
+    }
+  } else {
+    Status = HttpsReceive (HttpInstance, &Fragment, NULL);
+    if (EFI_ERROR (Status)) {
+      goto Error;
+    }
+
+    //
+    // Check whether we receive a complete HTTP message.
+    //
+    Status = HttpParseMessageBody (
+               HttpInstance->MsgParser,
+               (UINTN) Fragment.Len,
+               (CHAR8 *) Fragment.Bulk
+               );
+    if (EFI_ERROR (Status)) {
+      goto Error;
+    }
+
+    if (HttpIsMessageComplete (HttpInstance->MsgParser)) {
+      //
+      // Free the MsgParse since we already have a full HTTP message.
+      //
+      HttpFreeMsgParser (HttpInstance->MsgParser);
+      HttpInstance->MsgParser = NULL;
+    }
+
+    //
+    // We receive part of header of next HTTP msg.
+    //
+    if (HttpInstance->NextMsg != NULL) {
+      HttpMsg->BodyLength = MIN ((UINTN) (HttpInstance->NextMsg - (CHAR8 *) 
Fragment.Bulk), HttpMsg->BodyLength);
+      CopyMem (HttpMsg->Body, Fragment.Bulk, HttpMsg->BodyLength);
+      
+      HttpInstance->CacheLen = Fragment.Len - HttpMsg->BodyLength;
+      if (HttpInstance->CacheLen != 0) {
+        if (HttpInstance->CacheBody != NULL) {
+          FreePool (HttpInstance->CacheBody);
+        }
+        
+        HttpInstance->CacheBody = AllocateZeroPool (HttpInstance->CacheLen);
+        if (HttpInstance->CacheBody == NULL) {
+          Status = EFI_OUT_OF_RESOURCES;
+          goto Error;
+        }
+        
+        CopyMem (HttpInstance->CacheBody, Fragment.Bulk + HttpMsg->BodyLength, 
HttpInstance->CacheLen);
+        HttpInstance->CacheOffset = 0;
+
+        HttpInstance->NextMsg = HttpInstance->CacheBody + (UINTN) 
(HttpInstance->NextMsg - (CHAR8 *) (Fragment.Bulk + HttpMsg->BodyLength));
+      }
+    } else {
+      HttpMsg->BodyLength = MIN (Fragment.Len, (UINT32) HttpMsg->BodyLength);
+      CopyMem (HttpMsg->Body, Fragment.Bulk, HttpMsg->BodyLength);
+      HttpInstance->CacheLen = Fragment.Len - HttpMsg->BodyLength;
+      if (HttpInstance->CacheLen != 0) {
+        if (HttpInstance->CacheBody != NULL) {
+          FreePool (HttpInstance->CacheBody);
+        }
+        
+        HttpInstance->CacheBody = AllocateZeroPool (HttpInstance->CacheLen);
+        if (HttpInstance->CacheBody == NULL) {
+          Status = EFI_OUT_OF_RESOURCES;
+          goto Error;
+        }
+
+        CopyMem (HttpInstance->CacheBody, Fragment.Bulk + HttpMsg->BodyLength, 
HttpInstance->CacheLen);
+        HttpInstance->CacheOffset = 0;
+      }
+    }
+
+    if (Fragment.Bulk != NULL) {
+      FreePool (Fragment.Bulk);
+      Fragment.Bulk = NULL;
+    }
+
+    goto Exit;
   }
 
   return Status;
 
 Exit:
@@ -1130,14 +1262,21 @@ Error2:
 Error:
   HttpTcpTokenCleanup (Wrap);
   
   if (HttpHeaders != NULL) {
     FreePool (HttpHeaders);
+    HttpHeaders = NULL;
+  }
+
+  if (Fragment.Bulk != NULL) {
+    FreePool (Fragment.Bulk);
+    Fragment.Bulk = NULL;
   }
 
   if (HttpMsg->Headers != NULL) {
     FreePool (HttpMsg->Headers);
+    HttpMsg->Headers = NULL;
   }
 
   if (HttpInstance->CacheBody != NULL) {
     FreePool (HttpInstance->CacheBody);
     HttpInstance->CacheBody = NULL;
@@ -1244,13 +1383,20 @@ EfiHttpResponse (
   }
 
   Wrap->HttpInstance = HttpInstance;
   Wrap->HttpToken    = Token;
 
-  Status = HttpCreateTcpRxEvent (Wrap);
-  if (EFI_ERROR (Status)) {
-    goto Error;
+  //
+  // Notes: For Https, receive token wrapped in HTTP_TOKEN_WRAP is not used to 
+  // receive the https response. A special TlsRxToken is used for receiving 
TLS 
+  // related messages. It should be a blocking response.
+  //
+  if (!HttpInstance->UseHttps) {
+    Status = HttpCreateTcpRxEvent (Wrap);
+    if (EFI_ERROR (Status)) {
+      goto Error;
+    }
   }
 
   Status = NetMapInsertTail (&HttpInstance->RxTokens, Token, Wrap);
   if (EFI_ERROR (Status)) {
     goto Error;
diff --git a/NetworkPkg/HttpDxe/HttpProto.c b/NetworkPkg/HttpDxe/HttpProto.c
index 156f138..26fc3fd 100644
--- a/NetworkPkg/HttpDxe/HttpProto.c
+++ b/NetworkPkg/HttpDxe/HttpProto.c
@@ -1,9 +1,9 @@
 /** @file
   Miscellaneous routines for HttpDxe driver.
 
-Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2015 - 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
@@ -410,19 +410,19 @@ HttpCreateTcpTxEvent (
                     TPL_NOTIFY,
                     HttpTcpTransmitNotify,
                     Wrap,
                     &TcpWrap->Tx4Token.CompletionToken.Event
                     );
-      if (EFI_ERROR (Status)) {
-        return Status;
-      }
-    
-      TcpWrap->Tx4Data.Push = TRUE;
-      TcpWrap->Tx4Data.Urgent = FALSE;
-      TcpWrap->Tx4Data.FragmentCount = 1;
-      TcpWrap->Tx4Token.Packet.TxData = &Wrap->TcpWrap.Tx4Data;
-      TcpWrap->Tx4Token.CompletionToken.Status = EFI_NOT_READY;
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+  
+    TcpWrap->Tx4Data.Push = TRUE;
+    TcpWrap->Tx4Data.Urgent = FALSE;
+    TcpWrap->Tx4Data.FragmentCount = 1;
+    TcpWrap->Tx4Token.Packet.TxData = &Wrap->TcpWrap.Tx4Data;
+    TcpWrap->Tx4Token.CompletionToken.Status = EFI_NOT_READY;
 
   } else {
     Status = gBS->CreateEvent (
                     EVT_NOTIFY_SIGNAL,
                     TPL_NOTIFY,
@@ -438,11 +438,10 @@ HttpCreateTcpTxEvent (
     TcpWrap->Tx6Data.Urgent = FALSE;
     TcpWrap->Tx6Data.FragmentCount  = 1;
     TcpWrap->Tx6Token.Packet.TxData = &Wrap->TcpWrap.Tx6Data;
     TcpWrap->Tx6Token.CompletionToken.Status =EFI_NOT_READY;
     
-    
   }
   
   return EFI_SUCCESS;
 }
 
@@ -901,10 +900,26 @@ HttpCleanProtocol (
            HttpInstance->Service->ImageHandle,
            HttpInstance->Handle
            );
   }
   
+  if (HttpInstance->TlsConfigData.CACert != NULL) {
+    FreePool (HttpInstance->TlsConfigData.CACert);
+    HttpInstance->TlsConfigData.CACert = NULL;
+  }
+
+  if (HttpInstance->TlsConfigData.ClientCert != NULL) {
+    FreePool (HttpInstance->TlsConfigData.ClientCert);
+    HttpInstance->TlsConfigData.ClientCert = NULL;
+  }
+
+  if (HttpInstance->TlsConfigData.ClientPrivateKey != NULL) {
+    FreePool (HttpInstance->TlsConfigData.ClientPrivateKey);
+    HttpInstance->TlsConfigData.ClientPrivateKey = NULL;
+  }
+
+  TlsCloseTxRxEvent (HttpInstance); 
 }
 
 /**
   Establish TCP connection with HTTP server.
 
@@ -1158,11 +1173,12 @@ HttpConfigureTcp6 (
   return EFI_SUCCESS;
  
 }
 
 /**
-  Check existing TCP connection, if in error state, recover TCP4 connection.
+  Check existing TCP connection, if in error state, recover TCP4 connection. 
Then, 
+  connect one TLS session if required.
 
   @param[in]  HttpInstance       The HTTP instance private data.
 
   @retval EFI_SUCCESS            The TCP connection is established.
   @retval EFI_NOT_READY          TCP4 protocol child is not created or 
configured.
@@ -1199,15 +1215,33 @@ HttpConnectTcp4 (
     return EFI_SUCCESS;
   } else if (Tcp4State > Tcp4StateEstablished ) {
     HttpCloseConnection(HttpInstance);
   }
 
-  return HttpCreateConnection (HttpInstance);
+  Status = HttpCreateConnection (HttpInstance);
+  if (EFI_ERROR(Status)){
+    DEBUG ((EFI_D_ERROR, "Tcp4 Connection fail - %x\n", Status));
+    return Status;
+  }
+  
+  //
+  // Tls session connection.
+  //
+  if (HttpInstance->UseHttps) {
+    Status = TlsConnectSession (HttpInstance, NULL); 
+    if (EFI_ERROR (Status)) {
+      TlsCloseTxRxEvent (HttpInstance);
+      return Status;
+    }
+  }
+
+  return Status;
 }
 
 /**
-  Check existing TCP connection, if in error state, recover TCP6 connection.
+  Check existing TCP connection, if in error state, recover TCP6 connection. 
Then, 
+  connect one TLS session if required.
 
   @param[in]  HttpInstance       The HTTP instance private data.
 
   @retval EFI_SUCCESS            The TCP connection is established.
   @retval EFI_NOT_READY          TCP6 protocol child is not created or 
configured.
@@ -1244,34 +1278,63 @@ HttpConnectTcp6 (
     return EFI_SUCCESS;
   } else if (Tcp6State > Tcp6StateEstablished ) {
     HttpCloseConnection(HttpInstance);
   }
 
-  return HttpCreateConnection (HttpInstance);
+  Status = HttpCreateConnection (HttpInstance);
+  if (EFI_ERROR(Status)){
+    DEBUG ((EFI_D_ERROR, "Tcp6 Connection fail - %x\n", Status));
+    return Status;
+  }
+  
+  //
+  // Tls session connection.
+  //
+  if (HttpInstance->UseHttps) {
+    Status = TlsConnectSession (HttpInstance, NULL); 
+    if (EFI_ERROR (Status)) {
+      TlsCloseTxRxEvent (HttpInstance);
+      return Status;
+    }
+  }
+
+  return Status;
 }
 
 /**
-  Initialize TCP related data.
+  Initialize Http session.
 
   @param[in]  HttpInstance       The HTTP instance private data.
   @param[in]  Wrap               The HTTP token's wrap data.
-  @param[in]  Configure          The Flag indicates whether the first time to 
initialize Tcp.
+  @param[in]  Configure          The Flag indicates whether need to initialize 
session.
+  @param[in]  TlsConfigure       The Flag indicates whether it's the new Tls 
session.
 
-  @retval EFI_SUCCESS            The initialization of TCP instance is done. 
+  @retval EFI_SUCCESS            The initialization of session is done. 
   @retval Others                 Other error as indicated.
 
 **/
 EFI_STATUS
-HttpInitTcp (
+HttpInitSession (
   IN  HTTP_PROTOCOL    *HttpInstance,
   IN  HTTP_TOKEN_WRAP  *Wrap,
-  IN  BOOLEAN          Configure
+  IN  BOOLEAN          Configure,
+  IN  BOOLEAN          TlsConfigure
   )
 {
   EFI_STATUS           Status;
   ASSERT (HttpInstance != NULL);
 
+  //
+  // Configure Tls session.
+  //
+  if (TlsConfigure) {
+    Status = TlsConfigureSession (HttpInstance);
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+  }
+
   if (!HttpInstance->LocalAddressIsIPv6) {
     //
     // Configure TCP instance.
     //
     if (Configure) {
@@ -1311,11 +1374,11 @@ HttpInitTcp (
   return EFI_SUCCESS;
   
 }
 
 /**
-  Send the HTTP message through TCP4 or TCP6.
+  Send the HTTP or HTTPS message through TCP4 or TCP6.
 
   @param[in]  HttpInstance       The HTTP instance private data.
   @param[in]  Wrap               The HTTP token's wrap data.
   @param[in]  TxString           Buffer containing the HTTP message string.
   @param[in]  TxStringLen        Length of the HTTP message string in bytes.
@@ -1335,18 +1398,68 @@ HttpTransmitTcp (
   EFI_STATUS                    Status;
   EFI_TCP4_IO_TOKEN             *Tx4Token;
   EFI_TCP4_PROTOCOL             *Tcp4;
   EFI_TCP6_IO_TOKEN             *Tx6Token;
   EFI_TCP6_PROTOCOL             *Tcp6;
+  UINT8                         *Buffer;  
+  UINTN                         BufferSize;
+  NET_FRAGMENT                  TempFragment;
+
+  Status                = EFI_SUCCESS;
+  Buffer                = NULL;
+
+  //
+  // Need to encrypt data.
+  //
+  if (HttpInstance->UseHttps) {
+    //
+    // Build BufferOut data
+    //
+    BufferSize = sizeof (TLSRecordHeader) + TxStringLen;
+    Buffer     = AllocateZeroPool (BufferSize);
+    if (Buffer == NULL) {
+      Status = EFI_OUT_OF_RESOURCES;
+      return Status;
+    }
+    ((TLSRecordHeader *) Buffer)->ContentType = 
TLS_CONTENT_TYPE_APPLICATION_DATA;
+    ((TLSRecordHeader *) Buffer)->Version.Major = 
HttpInstance->TlsConfigData.Version.Major;
+    ((TLSRecordHeader *) Buffer)->Version.Minor = 
HttpInstance->TlsConfigData.Version.Minor;
+    ((TLSRecordHeader *) Buffer)->Length = (UINT16) (TxStringLen);
+    CopyMem (Buffer + sizeof (TLSRecordHeader), TxString, TxStringLen);
+    
+    //
+    // Encrypt Packet.
+    //
+    Status = TlsProcessMessage (
+               HttpInstance, 
+               Buffer, 
+               BufferSize, 
+               EfiTlsEncrypt, 
+               &TempFragment
+               );
+    
+    FreePool (Buffer);
+
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+  }
   
-  if (!HttpInstance->LocalAddressIsIPv6) {     
+  if (!HttpInstance->LocalAddressIsIPv6) {
     Tcp4 = HttpInstance->Tcp4;
     Tx4Token = &Wrap->TcpWrap.Tx4Token;
+
+    if (HttpInstance->UseHttps) {
+      Tx4Token->Packet.TxData->DataLength = TempFragment.Len;
+      Tx4Token->Packet.TxData->FragmentTable[0].FragmentLength = 
TempFragment.Len;
+      Tx4Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) 
TempFragment.Bulk;
+    } else {
+      Tx4Token->Packet.TxData->DataLength = (UINT32) TxStringLen;
+      Tx4Token->Packet.TxData->FragmentTable[0].FragmentLength = (UINT32) 
TxStringLen;
+      Tx4Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) 
TxString;
+    }
     
-    Tx4Token->Packet.TxData->DataLength = (UINT32) TxStringLen;
-    Tx4Token->Packet.TxData->FragmentTable[0].FragmentLength = (UINT32) 
TxStringLen;
-    Tx4Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) 
TxString;
     Tx4Token->CompletionToken.Status = EFI_NOT_READY;  
     
     Wrap->TcpWrap.IsTxDone = FALSE;
     Status  = Tcp4->Transmit (Tcp4, Tx4Token);
     if (EFI_ERROR (Status)) {
@@ -1355,25 +1468,31 @@ HttpTransmitTcp (
     }
 
   } else {
     Tcp6 = HttpInstance->Tcp6;
     Tx6Token = &Wrap->TcpWrap.Tx6Token;
-
-    Tx6Token->Packet.TxData->DataLength = (UINT32) TxStringLen;
-    Tx6Token->Packet.TxData->FragmentTable[0].FragmentLength = (UINT32) 
TxStringLen;
-    Tx6Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) 
TxString;
+    
+    if (HttpInstance->UseHttps) {
+      Tx6Token->Packet.TxData->DataLength = TempFragment.Len;
+      Tx6Token->Packet.TxData->FragmentTable[0].FragmentLength = 
TempFragment.Len;
+      Tx6Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) 
TempFragment.Bulk;
+    } else {
+      Tx6Token->Packet.TxData->DataLength = (UINT32) TxStringLen;
+      Tx6Token->Packet.TxData->FragmentTable[0].FragmentLength = (UINT32) 
TxStringLen;
+      Tx6Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) 
TxString;
+    }
+    
     Tx6Token->CompletionToken.Status = EFI_NOT_READY;
 
     Wrap->TcpWrap.IsTxDone = FALSE;
     Status = Tcp6->Transmit (Tcp6, Tx6Token);
     if (EFI_ERROR (Status)) {
       DEBUG ((EFI_D_ERROR, "Transmit failed: %r\n", Status));
       return Status;
     }
   }
   
-
   return Status;
 }
 
 /**
   Check whether the user's token or event has already
@@ -1439,11 +1558,11 @@ HttpTcpNotReady (
   
   return EFI_SUCCESS;
 }
 
 /**
-  Transmit the HTTP mssage by processing the associated HTTP token.
+  Transmit the HTTP or HTTPS mssage by processing the associated HTTP token.
 
   @param[in]  Map                The container of Tx4Token or Tx6Token.
   @param[in]  Item               Current item to check against.
   @param[in]  Context            The Token to check againist.
 
@@ -1557,149 +1676,217 @@ HttpTcpReceiveHeader (
   EFI_TCP6_IO_TOKEN             *Rx6Token;
   EFI_TCP6_PROTOCOL             *Tcp6;
   CHAR8                         **EndofHeader;
   CHAR8                         **HttpHeaders;
   CHAR8                         *Buffer;
+  NET_FRAGMENT                  Fragment;
 
   ASSERT (HttpInstance != NULL);
 
   EndofHeader = HttpInstance->EndofHeader;
   HttpHeaders = HttpInstance->HttpHeaders;
   Tcp4 = HttpInstance->Tcp4;
   Tcp6 = HttpInstance->Tcp6;
   Buffer      = NULL;
   Rx4Token    = NULL;
   Rx6Token    = NULL;
+  Fragment.Len  = 0;
+  Fragment.Bulk = NULL;
   
   if (HttpInstance->LocalAddressIsIPv6) {
     ASSERT (Tcp6 != NULL);
   } else {
     ASSERT (Tcp4 != NULL);
   }
 
-  if (!HttpInstance->LocalAddressIsIPv6) {
-    Rx4Token = &HttpInstance->Rx4Token;
-    Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer = 
AllocateZeroPool (DEF_BUF_LEN);
-    if (Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer == NULL) {
-      Status = EFI_OUT_OF_RESOURCES;
+  if (!HttpInstance->UseHttps) {
+    Status = HttpCreateTcpRxEventForHeader (HttpInstance);
+    if (EFI_ERROR (Status)) {
       return Status;
     }
+  }
+
+  if (!HttpInstance->LocalAddressIsIPv6) {
+    if (!HttpInstance->UseHttps) {
+      Rx4Token = &HttpInstance->Rx4Token;
+      Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer = 
AllocateZeroPool (DEF_BUF_LEN);
+      if (Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer == NULL) {
+        Status = EFI_OUT_OF_RESOURCES;
+        return Status;
+      }
+    }
   
     //
     // Receive the HTTP headers only when EFI_HTTP_RESPONSE_DATA is not NULL.
     //
-    while (*EndofHeader == NULL) {   
-      HttpInstance->IsRxDone = FALSE;
-      Rx4Token->Packet.RxData->DataLength = DEF_BUF_LEN;
-      Rx4Token->Packet.RxData->FragmentTable[0].FragmentLength = DEF_BUF_LEN;
-      Status = Tcp4->Receive (Tcp4, Rx4Token);
-      if (EFI_ERROR (Status)) {
-        DEBUG ((EFI_D_ERROR, "Tcp4 receive failed: %r\n", Status));
-        return Status;
+    while (*EndofHeader == NULL) {
+      if (!HttpInstance->UseHttps) {
+        HttpInstance->IsRxDone = FALSE;
+        Rx4Token->Packet.RxData->DataLength = DEF_BUF_LEN;
+        Rx4Token->Packet.RxData->FragmentTable[0].FragmentLength = DEF_BUF_LEN;
+        Status = Tcp4->Receive (Tcp4, Rx4Token);
+        if (EFI_ERROR (Status)) {
+          DEBUG ((EFI_D_ERROR, "Tcp4 receive failed: %r\n", Status));
+          return Status;
+        }
+        
+        while (!HttpInstance->IsRxDone) {
+          Tcp4->Poll (Tcp4);
+        }    
+
+        Status = Rx4Token->CompletionToken.Status;
+        if (EFI_ERROR (Status)) {
+          return Status;
+        }
+        
+        Fragment.Len  = 
Rx4Token->Packet.RxData->FragmentTable[0].FragmentLength;
+        Fragment.Bulk = (UINT8 *) 
Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer;
+      } else {
+        if (Fragment.Bulk != NULL) {
+          FreePool (Fragment.Bulk);
+          Fragment.Bulk = NULL;
+        }
+        
+        Status = HttpsReceive (HttpInstance, &Fragment, NULL);
+        if (EFI_ERROR (Status)) {
+          DEBUG ((EFI_D_ERROR, "Tcp4 receive failed: %r\n", Status));
+          return Status;
+        }
       }
-      
-      while (!HttpInstance->IsRxDone) {
-       Tcp4->Poll (Tcp4);
-      }    
-  
-      Status = Rx4Token->CompletionToken.Status;
-      if (EFI_ERROR (Status)) {
-        return Status;
-      }
-  
+
       //
       // Append the response string.
       //
-      *BufferSize = (*SizeofHeaders) + 
Rx4Token->Packet.RxData->FragmentTable[0].FragmentLength;
+      *BufferSize = *SizeofHeaders + Fragment.Len;
       Buffer      = AllocateZeroPool (*BufferSize);
       if (Buffer == NULL) {
         Status = EFI_OUT_OF_RESOURCES;
         return Status;
       }
-  
+
       if (*HttpHeaders != NULL) {
-        CopyMem (Buffer, *HttpHeaders, (*SizeofHeaders));
+        CopyMem (Buffer, *HttpHeaders, *SizeofHeaders);
         FreePool (*HttpHeaders);
       }
-  
+
       CopyMem (
-        Buffer + (*SizeofHeaders),
-        Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer,
-        Rx4Token->Packet.RxData->FragmentTable[0].FragmentLength
+        Buffer + *SizeofHeaders,
+        Fragment.Bulk,
+        Fragment.Len
         );
-      *HttpHeaders    = Buffer;
-      *SizeofHeaders  = *BufferSize;
-  
+      *HttpHeaders   = Buffer;
+      *SizeofHeaders = *BufferSize;
+
       //
       // Check whether we received end of HTTP headers.
       //
       *EndofHeader = AsciiStrStr (*HttpHeaders, HTTP_END_OF_HDR_STR); 
-    }
-    FreePool (Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer);
-    Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer = NULL;
+    };
     
+    //
+    // Free the buffer.
+    //
+    if (Rx4Token != NULL && Rx4Token->Packet.RxData != NULL && 
Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer != NULL) {
+      FreePool (Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer);
+      Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer = NULL;
+      Fragment.Bulk = NULL;
+    }
+
+    if (Fragment.Bulk != NULL) {
+      FreePool (Fragment.Bulk);
+      Fragment.Bulk = NULL;
+    } 
   } else {
-    Rx6Token = &HttpInstance->Rx6Token;
-    Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer = 
AllocateZeroPool (DEF_BUF_LEN);
-    if (Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer == NULL) {
-      Status = EFI_OUT_OF_RESOURCES;
-      return Status;
+    if (!HttpInstance->UseHttps) {
+      Rx6Token = &HttpInstance->Rx6Token;
+      Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer = 
AllocateZeroPool (DEF_BUF_LEN);
+      if (Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer == NULL) {
+        Status = EFI_OUT_OF_RESOURCES;
+        return Status;
+      }
     }
   
     //
     // Receive the HTTP headers only when EFI_HTTP_RESPONSE_DATA is not NULL.
     //
-    while (*EndofHeader == NULL) {   
-      HttpInstance->IsRxDone = FALSE;
-      Rx6Token->Packet.RxData->DataLength = DEF_BUF_LEN;
-      Rx6Token->Packet.RxData->FragmentTable[0].FragmentLength = DEF_BUF_LEN;
-      Status = Tcp6->Receive (Tcp6, Rx6Token);
-      if (EFI_ERROR (Status)) {
-        DEBUG ((EFI_D_ERROR, "Tcp6 receive failed: %r\n", Status));
-        return Status;
-      }
-      
-      while (!HttpInstance->IsRxDone) {
-       Tcp6->Poll (Tcp6);
-      }    
-  
-      Status = Rx6Token->CompletionToken.Status;
-      if (EFI_ERROR (Status)) {
-        return Status;
+    while (*EndofHeader == NULL) {
+      if (!HttpInstance->UseHttps) {
+        HttpInstance->IsRxDone = FALSE;
+        Rx6Token->Packet.RxData->DataLength = DEF_BUF_LEN;
+        Rx6Token->Packet.RxData->FragmentTable[0].FragmentLength = DEF_BUF_LEN;
+        Status = Tcp6->Receive (Tcp6, Rx6Token);
+        if (EFI_ERROR (Status)) {
+          DEBUG ((EFI_D_ERROR, "Tcp6 receive failed: %r\n", Status));
+          return Status;
+        }
+        
+        while (!HttpInstance->IsRxDone) {
+          Tcp6->Poll (Tcp6);
+        }    
+
+        Status = Rx6Token->CompletionToken.Status;
+        if (EFI_ERROR (Status)) {
+          return Status;
+        }
+        
+        Fragment.Len  = 
Rx6Token->Packet.RxData->FragmentTable[0].FragmentLength;
+        Fragment.Bulk = (UINT8 *) 
Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer;
+      } else {
+        if (Fragment.Bulk != NULL) {
+          FreePool (Fragment.Bulk);
+          Fragment.Bulk = NULL;
+        }
+        
+        Status = HttpsReceive (HttpInstance, &Fragment, NULL);
+        if (EFI_ERROR (Status)) {
+          DEBUG ((EFI_D_ERROR, "Tcp6 receive failed: %r\n", Status));
+          return Status;
+        }
       }
-  
+
       //
       // Append the response string.
       //
-      *BufferSize = (*SizeofHeaders) + 
Rx6Token->Packet.RxData->FragmentTable[0].FragmentLength;
+      *BufferSize = *SizeofHeaders + Fragment.Len;
       Buffer      = AllocateZeroPool (*BufferSize);
       if (Buffer == NULL) {
         Status = EFI_OUT_OF_RESOURCES;
         return Status;
       }
-  
+
       if (*HttpHeaders != NULL) {
-        CopyMem (Buffer, *HttpHeaders, (*SizeofHeaders));
+        CopyMem (Buffer, *HttpHeaders, *SizeofHeaders);
         FreePool (*HttpHeaders);
       }
-  
+
       CopyMem (
-        Buffer + (*SizeofHeaders),
-        Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer,
-        Rx6Token->Packet.RxData->FragmentTable[0].FragmentLength
+        Buffer + *SizeofHeaders,
+        Fragment.Bulk,
+        Fragment.Len
         );
-      *HttpHeaders     = Buffer;
-      *SizeofHeaders  = *BufferSize;
-  
+      *HttpHeaders   = Buffer;
+      *SizeofHeaders = *BufferSize;
+
       //
       // Check whether we received end of HTTP headers.
       //
-      *EndofHeader = AsciiStrStr (*HttpHeaders, HTTP_END_OF_HDR_STR);
-  
+      *EndofHeader = AsciiStrStr (*HttpHeaders, HTTP_END_OF_HDR_STR); 
+    };
+
+    //
+    // Free the buffer.
+    //
+    if (Rx6Token != NULL && Rx6Token->Packet.RxData != NULL && 
Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer != NULL) {
+      FreePool (Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer);
+      Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer = NULL;
+      Fragment.Bulk = NULL;
+    }
+
+    if (Fragment.Bulk != NULL) {
+      FreePool (Fragment.Bulk);
+      Fragment.Bulk = NULL;
     }
-    FreePool (Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer);
-    Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer = NULL;    
   }     
 
   //
   // Skip the CRLF after the HTTP headers.
   //
diff --git a/NetworkPkg/HttpDxe/HttpProto.h b/NetworkPkg/HttpDxe/HttpProto.h
index 7b4b343..b54ae70 100644
--- a/NetworkPkg/HttpDxe/HttpProto.h
+++ b/NetworkPkg/HttpDxe/HttpProto.h
@@ -80,10 +80,24 @@ typedef struct {
   BOOLEAN                       IsRxDone;
   UINTN                         BodyLen;
   EFI_HTTP_METHOD               Method;
 } HTTP_TCP_TOKEN_WRAP;
 
+typedef struct {
+  EFI_TLS_VERSION               Version;
+  EFI_TLS_CONNECTION_END        ConnectionEnd;
+  EFI_TLS_VERIFY                VerifyMethod;
+  EFI_TLS_SESSION_STATE         SessionState;
+  
+  VOID                          *CACert;
+  UINTN                         CACertSize;
+  VOID                          *ClientCert;
+  UINTN                         ClientCertSize;
+  VOID                          *ClientPrivateKey;
+  UINTN                         ClientPrivateKeySize;
+} TLS_CONFIG_DATA;
+
 typedef struct _HTTP_PROTOCOL {
   UINT32                        Signature;
   EFI_HTTP_PROTOCOL             Http;
   EFI_HANDLE                    Handle;
   HTTP_SERVICE                  *Service;
@@ -149,10 +163,39 @@ typedef struct _HTTP_PROTOCOL {
 
   NET_MAP                       TxTokens;
   NET_MAP                       RxTokens;
 
   CHAR8                         *Url;
+
+  //
+  // Https Support
+  //
+  BOOLEAN                          UseHttps;
+  
+  EFI_HANDLE                       TlsChildHandle; /// Tls ChildHandle
+  TLS_CONFIG_DATA                  TlsConfigData;
+  EFI_TLS_PROTOCOL                 *Tls;
+  EFI_TLS_CONFIGURATION_PROTOCOL   *TlsConfiguration;
+  EFI_TLS_SESSION_STATE            TlsSessionState;
+
+  //
+  // TlsTxData used for transmitting TLS related messages.
+  //
+  EFI_TCP4_IO_TOKEN                Tcp4TlsTxToken;
+  EFI_TCP4_TRANSMIT_DATA           Tcp4TlsTxData;
+  EFI_TCP6_IO_TOKEN                Tcp6TlsTxToken;
+  EFI_TCP6_TRANSMIT_DATA           Tcp6TlsTxData;
+  BOOLEAN                          TlsIsTxDone;
+
+  //
+  // TlsRxData used for receiving TLS related messages.
+  //
+  EFI_TCP4_IO_TOKEN                Tcp4TlsRxToken;
+  EFI_TCP4_RECEIVE_DATA            Tcp4TlsRxData;
+  EFI_TCP6_IO_TOKEN                Tcp6TlsRxToken;
+  EFI_TCP6_RECEIVE_DATA            Tcp6TlsRxData;
+  BOOLEAN                          TlsIsRxDone;
 } HTTP_PROTOCOL;
 
 typedef struct {
   EFI_HTTP_TOKEN                *HttpToken;
   HTTP_PROTOCOL                 *HttpInstance;
@@ -348,11 +391,12 @@ HttpConfigureTcp6 (
   IN  HTTP_PROTOCOL        *HttpInstance,
   IN  HTTP_TOKEN_WRAP      *Wrap
   );
 
 /**
-  Check existing TCP connection, if in error state, receover TCP4 connection.
+  Check existing TCP connection, if in error state, recover TCP4 connection. 
Then, 
+  connect one TLS session if required.
 
   @param[in]  HttpInstance       The HTTP instance private data.
 
   @retval EFI_SUCCESS            The TCP connection is established.
   @retval EFI_NOT_READY          TCP4 protocol child is not created or 
configured.
@@ -363,11 +407,12 @@ EFI_STATUS
 HttpConnectTcp4 (
   IN  HTTP_PROTOCOL        *HttpInstance
   );
 
 /**
-  Check existing TCP connection, if in error state, recover TCP6 connection.
+  Check existing TCP connection, if in error state, recover TCP6 connection. 
Then, 
+  connect one TLS session if required.
 
   @param[in]  HttpInstance       The HTTP instance private data.
 
   @retval EFI_SUCCESS            The TCP connection is established.
   @retval EFI_NOT_READY          TCP6 protocol child is not created or 
configured.
@@ -378,11 +423,11 @@ EFI_STATUS
 HttpConnectTcp6 (
   IN  HTTP_PROTOCOL        *HttpInstance
   );
 
 /**
-  Send the HTTP message through TCP4 or TCP6.
+  Send the HTTP or HTTPS message through TCP4 or TCP6.
 
   @param[in]  HttpInstance       The HTTP instance private data.
   @param[in]  Wrap               The HTTP token's wrap data.
   @param[in]  TxString           Buffer containing the HTTP message string.
   @param[in]  TxStringLen        Length of the HTTP message string in bytes.
@@ -439,29 +484,31 @@ HttpTcpNotReady (
   IN NET_MAP_ITEM           *Item,
   IN VOID                   *Context
   );
 
 /**
-  Initialize TCP related data.
+  Initialize Http session.
 
   @param[in]  HttpInstance       The HTTP instance private data.
   @param[in]  Wrap               The HTTP token's wrap data.
-  @param[in]  Configure          The Flag indicates whether the first time to 
initialize Tcp.
+  @param[in]  Configure          The Flag indicates whether need to initialize 
session.
+  @param[in]  TlsConfigure       The Flag indicates whether it's the new Tls 
session.
 
-  @retval EFI_SUCCESS            The initialization of TCP instance is done. 
+  @retval EFI_SUCCESS            The initialization of session is done. 
   @retval Others                 Other error as indicated.
 
 **/
 EFI_STATUS
-HttpInitTcp (
+HttpInitSession (
   IN  HTTP_PROTOCOL    *HttpInstance,
   IN  HTTP_TOKEN_WRAP  *Wrap,
-  IN  BOOLEAN          Configure
+  IN  BOOLEAN          Configure,
+  IN  BOOLEAN          TlsConfigure
   );
 
 /**
-  Transmit the HTTP mssage by processing the associated HTTP token.
+  Transmit the HTTP or HTTPS mssage by processing the associated HTTP token.
 
   @param[in]  Map                The container of TxToken or Tx6Token.
   @param[in]  Item               Current item to check against.
   @param[in]  Context            The Token to check againist.
 
diff --git a/NetworkPkg/HttpDxe/HttpsSupport.c 
b/NetworkPkg/HttpDxe/HttpsSupport.c
new file mode 100644
index 0000000..09aaa46
--- /dev/null
+++ b/NetworkPkg/HttpDxe/HttpsSupport.c
@@ -0,0 +1,1701 @@
+/** @file
+  Miscellaneous routines specific to Https for HttpDxe driver.
+
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD 
License
+which accompanies this distribution.  The full text of the license may be 
found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "HttpDriver.h"
+
+EFI_GUID mEfiTlsCaCertificateGuid = EFI_TLS_CA_CERTIFICATE_GUID;
+
+/**
+  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 = (UINT8 *) HttpInstance->TlsConfigData.CACert;
+  CACertSize = HttpInstance->TlsConfigData.CACertSize; 
+  
+  //
+  // Try to read the TlsCaCertificate variable.
+  //
+  CACertSize = 0;
+  Status  = gRT->GetVariable (
+                   EFI_TLS_CA_CERTIFICATE_VARIABLE,
+                   &mEfiTlsCaCertificateGuid,
+                   NULL,
+                   &CACertSize,
+                   NULL
+                   );
+
+  if (Status == EFI_BUFFER_TOO_SMALL) {
+    //
+    // 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,
+                    &mEfiTlsCaCertificateGuid,
+                    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;
+    }
+  }
+
+  //
+  // 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)) {
+        return Status;
+      }
+      
+      Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) Cert + CertList->SignatureSize);
+    }
+
+
+    ItemDataSize -= CertList->SignatureListSize;
+    CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + 
CertList->SignatureListSize);
+  }
+  
+  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.Version.Major = TLS10_PROTOCOL_VERSION_MAJOR;
+  HttpInstance->TlsConfigData.Version.Minor = TLS10_PROTOCOL_VERSION_MINOR;
+  HttpInstance->TlsConfigData.ConnectionEnd = EfiTlsClient;
+  HttpInstance->TlsConfigData.VerifyMethod = EFI_TLS_VERIFY_PEER;
+  HttpInstance->TlsConfigData.SessionState = EfiTlsSessionNotStarted;
+
+  //
+  // EfiTlsVersion
+  // EfiTlsConnectionEnd,
+  // EfiTlsVerifyMethod
+  // EfiTlsSessionState
+  //
+  Status = HttpInstance->Tls->SetSessionData (
+                                HttpInstance->Tls,
+                                EfiTlsVersion,
+                                &(HttpInstance->TlsConfigData.Version),
+                                sizeof (EFI_TLS_VERSION)
+                                );
+  if (EFI_ERROR (Status)) {
+    goto ERROR;
+  }
+  
+  Status = HttpInstance->Tls->SetSessionData (
+                                HttpInstance->Tls,
+                                EfiTlsConnectionEnd,
+                                &(HttpInstance->TlsConfigData.ConnectionEnd),
+                                sizeof (EFI_TLS_CONNECTION_END)
+                                );
+  if (EFI_ERROR (Status)) {
+    goto ERROR;
+  }
+
+  Status = HttpInstance->Tls->SetSessionData (
+                                HttpInstance->Tls,
+                                EfiTlsVerifyMethod,
+                                &HttpInstance->TlsConfigData.VerifyMethod,
+                                sizeof (EFI_TLS_VERIFY)
+                                );
+  if (EFI_ERROR (Status)) {
+    goto ERROR;
+  }
+  
+  Status = HttpInstance->Tls->SetSessionData (
+                                HttpInstance->Tls,
+                                EfiTlsSessionState,
+                                &(HttpInstance->TlsConfigData.SessionState),
+                                sizeof (EFI_TLS_SESSION_STATE)
+                                );
+  if (EFI_ERROR (Status)) {
+    goto ERROR;
+  }
+  
+  //
+  // Tls Config Certificate
+  //
+  Status = TlsConfigCertificate (HttpInstance);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "TLS Certificate Config Error!\n"));
+    goto ERROR;
+  }
+  
+  //
+  // 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 trasmitted.
+  @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;
+    
+    //
+    // Trasnmit 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;
+    
+    //
+    // Trasnmit 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. This 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;
+  TLSRecordHeader 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 (TLSRecordHeader);
+  PduHdr  = NetbufAlloc (Len);
+  if (PduHdr == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto ON_EXIT;
+  }
+
+  Header = NetbufAllocSpace (PduHdr, Len, NET_BUF_TAIL);
+  ASSERT (Header != NULL);
+
+  //
+  // First step, receive one TLS header.
+  //
+  Status = TlsCommonReceive (HttpInstance, PduHdr, Timeout);
+  if (EFI_ERROR (Status)) {
+    goto ON_EXIT;
+  }
+
+  RecordHeader = *(TLSRecordHeader *) 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;
+  }
+
+  ASSERT(Header != NULL);
+    
+  Len = SwapBytes16(RecordHeader.Length);
+  if (Len == 0) {
+    //
+    // No TLS playload.
+    //
+    goto FORM_PDU;
+  }
+
+  //
+  // Allocate buffer to receive one TLS playload.
+  //
+  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 playload.
+  //
+  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);  
+  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)) {
+      return Status;
+    }
+    
+    if (BufferOutSize != 0) {
+      //
+      // Transmit the response packet.
+      //
+      PacketOut = NetbufAlloc ((UINT32) BufferOutSize);      
+      DataOut = NetbufAllocSpace (PacketOut, (UINT32) BufferOutSize, 
NET_BUF_TAIL);      
+      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 contiue 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;    
+    }
+  }
+
+  ASSERT(HttpInstance->TlsSessionState == EfiTlsSessionDataTransferring);
+
+  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);      
+  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 sucessfully.
+
+  @retval EFI_SUCCESS          Message is processed sucessfully.
+  @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 accroding 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;
+  TLSRecordHeader                 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 = *(TLSRecordHeader *) 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);
+          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 (((TLSRecordHeader *) (TempFragment.Bulk))->ContentType == 
TLS_CONTENT_TYPE_APPLICATION_DATA);
+    
+    BufferInSize = ((TLSRecordHeader *) (TempFragment.Bulk))->Length;
+    BufferIn = AllocateZeroPool (BufferInSize);
+    ASSERT (BufferIn != NULL);
+
+    CopyMem (BufferIn, TempFragment.Bulk + sizeof (TLSRecordHeader), 
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);
+      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;
+}
diff --git a/NetworkPkg/HttpDxe/HttpsSupport.h 
b/NetworkPkg/HttpDxe/HttpsSupport.h
new file mode 100644
index 0000000..682a6b6
--- /dev/null
+++ b/NetworkPkg/HttpDxe/HttpsSupport.h
@@ -0,0 +1,314 @@
+/** @file
+  The header files of miscellaneous routines specific to Https for HttpDxe 
driver.
+
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD 
License
+which accompanies this distribution.  The full text of the license may be 
found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __EFI_HTTPS_SUPPORT_H__
+#define __EFI_HTTPS_SUPPORT_H__
+
+#pragma pack (push, 1)
+
+#define HTTPS_DEFAULT_PORT       443
+
+#define HTTPS_FLAG               "https"
+
+//
+// Private variable for CA Certificate configuration
+//
+#define EFI_TLS_CA_CERTIFICATE_GUID \
+  { \
+    0xfd2340D0, 0x3dab, 0x4349, { 0xa6, 0xc7, 0x3b, 0x4f, 0x12, 0xb4, 0x8e, 
0xae } \
+  }
+
+#define EFI_TLS_CA_CERTIFICATE_VARIABLE          L"TlsCaCertificate"
+
+//
+// TLS Version
+//
+#define TLS10_PROTOCOL_VERSION_MAJOR  0x03
+#define TLS10_PROTOCOL_VERSION_MINOR  0x01
+#define TLS11_PROTOCOL_VERSION_MAJOR  0x03
+#define TLS11_PROTOCOL_VERSION_MINOR  0x02
+#define TLS12_PROTOCOL_VERSION_MAJOR  0x03
+#define TLS12_PROTOCOL_VERSION_MINOR  0x03
+
+//
+// Cipher Suite
+//
+#define TLS_RSA_WITH_RC4_128_SHA                 {0x00, 0x05}
+#define TLS_RSA_WITH_3DES_EDE_CBC_SHA            {0x00, 0x0A}
+#define TLS_RSA_WITH_AES_128_CBC_SHA             {0x00, 0x2F}
+#define TLS_RSA_WITH_AES_256_CBC_SHA             {0x00, 0x35}
+#define TLS_RSA_WITH_AES_128_CBC_SHA256          {0x00, 0x3C}
+#define TLS_RSA_WITH_AES_256_CBC_SHA256          {0x00, 0x3D}
+
+//
+// Content Type
+//
+typedef enum {
+  TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC = 20,
+  TLS_CONTENT_TYPE_ALERT              = 21,
+  TLS_CONTENT_TYPE_HANDSHAKE          = 22,
+  TLS_CONTENT_TYPE_APPLICATION_DATA   = 23,
+} TLS_CONTENT_TYPE;
+
+//
+// Tls RecordHeader
+// 
+typedef struct {   
+  UINT8                   ContentType;
+  EFI_TLS_VERSION         Version;
+  UINT16                  Length;
+} TLSRecordHeader;
+
+#pragma pack (pop)
+
+
+/**
+  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
+  );
+
+/**
+  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
+  );
+
+/**
+  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
+  );
+
+/**
+  Close events in the TlsTxToken and TlsRxToken.
+
+  @param[in]  HttpInstance   Pointer to HTTP_PROTOCOL structure.
+  
+**/
+VOID
+EFIAPI
+TlsCloseTxRxEvent (
+  IN  HTTP_PROTOCOL        *HttpInstance
+  );
+
+/**
+  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
+  );
+
+/**
+  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
+  );
+
+/**
+  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 trasmitted.
+  @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
+  );
+
+/**
+  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
+  );
+
+/**
+  Receive one TLS PDU. An TLS PDU contains an TLS record header and it's
+  corresponding record data. The 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
+  );
+
+/**
+  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
+  );
+
+/**
+  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 or Packet 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
+  );
+
+/**
+  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 sucessfully.
+
+  @retval EFI_SUCCESS          Message is processed sucessfully.
+  @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
+  );
+
+/**
+  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
+  );
+
+#endif
-- 
1.9.5.msysgit.1

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to