public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH v2 05/10] NetworkPkg/TlsDxe: TlsDxe driver implementation over OpenSSL
@ 2016-12-15  7:22 Jiaxin Wu
  2016-12-16  6:16 ` Ye, Ting
  0 siblings, 1 reply; 3+ messages in thread
From: Jiaxin Wu @ 2016-12-15  7:22 UTC (permalink / raw)
  To: edk2-devel
  Cc: Ye Ting, Fu Siyuan, Zhang Lubo, Long Qin, Thomas Palmer,
	Wu Jiaxin

v2:
* Refine the TlsEcryptPacket/TlsDecryptPacket function
according the community feedback.

This patch is the implementation of EFI TLS Service Binding
Protocol, EFI TLS Protocol and EFI TLS Configuration Protocol
Interfaces.

Cc: Ye Ting <ting.ye@intel.com>
Cc: Fu Siyuan <siyuan.fu@intel.com>
Cc: Zhang Lubo <lubo.zhang@intel.com>
Cc: Long Qin <qin.long@intel.com>
Cc: Thomas Palmer <thomas.palmer@hpe.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Wu Jiaxin <jiaxin.wu@intel.com>
---
 NetworkPkg/TlsDxe/TlsConfigProtocol.c | 152 ++++++++
 NetworkPkg/TlsDxe/TlsDriver.c         | 498 +++++++++++++++++++++++++++
 NetworkPkg/TlsDxe/TlsDriver.h         | 237 +++++++++++++
 NetworkPkg/TlsDxe/TlsDxe.inf          |  65 ++++
 NetworkPkg/TlsDxe/TlsDxe.uni          |  25 ++
 NetworkPkg/TlsDxe/TlsDxeExtra.uni     |  18 +
 NetworkPkg/TlsDxe/TlsImpl.c           | 326 ++++++++++++++++++
 NetworkPkg/TlsDxe/TlsImpl.h           | 315 +++++++++++++++++
 NetworkPkg/TlsDxe/TlsProtocol.c       | 632 ++++++++++++++++++++++++++++++++++
 9 files changed, 2268 insertions(+)
 create mode 100644 NetworkPkg/TlsDxe/TlsConfigProtocol.c
 create mode 100644 NetworkPkg/TlsDxe/TlsDriver.c
 create mode 100644 NetworkPkg/TlsDxe/TlsDriver.h
 create mode 100644 NetworkPkg/TlsDxe/TlsDxe.inf
 create mode 100644 NetworkPkg/TlsDxe/TlsDxe.uni
 create mode 100644 NetworkPkg/TlsDxe/TlsDxeExtra.uni
 create mode 100644 NetworkPkg/TlsDxe/TlsImpl.c
 create mode 100644 NetworkPkg/TlsDxe/TlsImpl.h
 create mode 100644 NetworkPkg/TlsDxe/TlsProtocol.c

diff --git a/NetworkPkg/TlsDxe/TlsConfigProtocol.c b/NetworkPkg/TlsDxe/TlsConfigProtocol.c
new file mode 100644
index 0000000..2ec79c9
--- /dev/null
+++ b/NetworkPkg/TlsDxe/TlsConfigProtocol.c
@@ -0,0 +1,152 @@
+/** @file
+  Implementation of EFI TLS Configuration Protocol Interfaces.
+
+  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 "TlsImpl.h"
+
+EFI_TLS_CONFIGURATION_PROTOCOL  mTlsConfigurationProtocol = {
+  TlsConfigurationSetData,
+  TlsConfigurationGetData
+};
+
+/**
+  Set TLS configuration data.
+
+  The SetData() function sets TLS configuration to non-volatile storage or volatile
+  storage.
+
+  @param[in]  This                Pointer to the EFI_TLS_CONFIGURATION_PROTOCOL instance.
+  @param[in]  DataType            Configuration data type.
+  @param[in]  Data                Pointer to configuration data.
+  @param[in]  DataSize            Total size of configuration data.
+
+  @retval EFI_SUCCESS             The TLS configuration data is set successfully.
+  @retval EFI_INVALID_PARAMETER   One or more of the following conditions is TRUE:
+                                  This is NULL.
+                                  Data is NULL.
+                                  DataSize is 0.
+  @retval EFI_UNSUPPORTED         The DataType is unsupported.
+  @retval EFI_OUT_OF_RESOURCES    Required system resources could not be allocated.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsConfigurationSetData (
+  IN     EFI_TLS_CONFIGURATION_PROTOCOL  *This,
+  IN     EFI_TLS_CONFIG_DATA_TYPE        DataType,
+  IN     VOID                            *Data,
+  IN     UINTN                           DataSize
+  )
+{
+  EFI_STATUS                Status;
+  TLS_INSTANCE              *Instance;
+  EFI_TPL                   OldTpl;
+
+  Status = EFI_SUCCESS;
+
+  if (This == NULL ||  Data == NULL || DataSize == 0) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+  Instance = TLS_INSTANCE_FROM_CONFIGURATION_THIS (This);
+
+  switch (DataType) {
+  case EfiTlsConfigDataTypeCACertificate:
+    Status = TlsSetCaCertificate (Instance->TlsConn, Data, DataSize);
+    break;
+  case EfiTlsConfigDataTypeHostPublicCert:
+    Status = TlsSetHostPublicCert (Instance->TlsConn, Data, DataSize);
+    break;
+  case EfiTlsConfigDataTypeHostPrivateKey:
+    Status = TlsSetHostPrivateKey (Instance->TlsConn, Data, DataSize);
+    break;
+  case EfiTlsConfigDataTypeCertRevocationList:
+    Status = TlsSetCertRevocationList (Data, DataSize);
+    break;
+  default:
+     Status = EFI_UNSUPPORTED;
+  }
+
+  gBS->RestoreTPL (OldTpl);
+  return Status;
+}
+
+/**
+  Get TLS configuration data.
+
+  The GetData() function gets TLS configuration.
+
+  @param[in]       This           Pointer to the EFI_TLS_CONFIGURATION_PROTOCOL instance.
+  @param[in]       DataType       Configuration data type.
+  @param[in, out]  Data           Pointer to configuration data.
+  @param[in, out]  DataSize       Total size of configuration data. On input, it means
+                                  the size of Data buffer. On output, it means the size
+                                  of copied Data buffer if EFI_SUCCESS, and means the
+                                  size of desired Data buffer if EFI_BUFFER_TOO_SMALL.
+
+  @retval EFI_SUCCESS             The TLS configuration data is got successfully.
+  @retval EFI_INVALID_PARAMETER   One or more of the following conditions is TRUE:
+                                  This is NULL.
+                                  DataSize is NULL.
+                                  Data is NULL if *DataSize is not zero.
+  @retval EFI_UNSUPPORTED         The DataType is unsupported.
+  @retval EFI_NOT_FOUND           The TLS configuration data is not found.
+  @retval EFI_BUFFER_TOO_SMALL    The buffer is too small to hold the data.
+**/
+EFI_STATUS
+EFIAPI
+TlsConfigurationGetData (
+  IN     EFI_TLS_CONFIGURATION_PROTOCOL  *This,
+  IN     EFI_TLS_CONFIG_DATA_TYPE        DataType,
+  IN OUT VOID                            *Data, OPTIONAL
+  IN OUT UINTN                           *DataSize
+  )
+{
+  EFI_STATUS                Status;
+  TLS_INSTANCE              *Instance;
+
+  EFI_TPL                   OldTpl;
+
+  Status = EFI_SUCCESS;
+
+  if (This == NULL || DataSize == NULL || (Data == NULL && *DataSize != 0)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+  Instance = TLS_INSTANCE_FROM_CONFIGURATION_THIS (This);
+
+  switch (DataType) {
+  case EfiTlsConfigDataTypeCACertificate:
+    Status = TlsGetCaCertificate (Instance->TlsConn, Data, DataSize);
+    break;
+  case EfiTlsConfigDataTypeHostPublicCert:
+    Status = TlsGetHostPublicCert (Instance->TlsConn, Data, DataSize);
+    break;
+  case EfiTlsConfigDataTypeHostPrivateKey:
+    Status = TlsGetHostPrivateKey (Instance->TlsConn, Data, DataSize);
+    break;
+  case EfiTlsConfigDataTypeCertRevocationList:
+    Status = TlsGetCertRevocationList (Data, DataSize);
+    break;
+  default:
+    Status = EFI_UNSUPPORTED;
+  }
+
+  gBS->RestoreTPL (OldTpl);
+  return Status;
+}
diff --git a/NetworkPkg/TlsDxe/TlsDriver.c b/NetworkPkg/TlsDxe/TlsDriver.c
new file mode 100644
index 0000000..0a75c39
--- /dev/null
+++ b/NetworkPkg/TlsDxe/TlsDriver.c
@@ -0,0 +1,498 @@
+/** @file
+  The Driver Binding and Service Binding Protocol for TlsDxe 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 "TlsImpl.h"
+
+EFI_SERVICE_BINDING_PROTOCOL mTlsServiceBinding = {
+  TlsServiceBindingCreateChild,
+  TlsServiceBindingDestroyChild
+};
+
+/**
+  Release all the resources used by the TLS instance.
+
+  @param[in]  Instance        The TLS instance data.
+
+**/
+VOID
+TlsCleanInstance (
+  IN TLS_INSTANCE           *Instance
+  )
+{
+  if (Instance != NULL) {
+    if (Instance->TlsConn != NULL) {
+      TlsFree (Instance->TlsConn);
+    }
+
+    FreePool (Instance);
+  }
+}
+
+/**
+  Create the TLS instance and initialize it.
+
+  @param[in]  Service              The pointer to the TLS service.
+  @param[out] Instance             The pointer to the TLS instance.
+
+  @retval EFI_OUT_OF_RESOURCES   Failed to allocate resources.
+  @retval EFI_SUCCESS            The TLS instance is created.
+
+**/
+EFI_STATUS
+TlsCreateInstance (
+  IN  TLS_SERVICE         *Service,
+  OUT TLS_INSTANCE        **Instance
+  )
+{
+  TLS_INSTANCE            *TlsInstance;
+
+  *Instance = NULL;
+
+  TlsInstance = AllocateZeroPool (sizeof (TLS_INSTANCE));
+  if (TlsInstance == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  TlsInstance->Signature = TLS_INSTANCE_SIGNATURE;
+  InitializeListHead (&TlsInstance->Link);
+  TlsInstance->InDestroy = FALSE;
+  TlsInstance->Service   = Service;
+
+  CopyMem (&TlsInstance->Tls, &mTlsProtocol, sizeof (TlsInstance->Tls));
+  CopyMem (&TlsInstance->TlsConfig, &mTlsConfigurationProtocol, sizeof (TlsInstance->TlsConfig));
+
+  TlsInstance->TlsSessionState = EfiTlsSessionNotStarted;
+
+  *Instance = TlsInstance;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Release all the resources used by the TLS service binding instance.
+
+  @param[in]  Service        The TLS service data.
+
+**/
+VOID
+TlsCleanService (
+  IN TLS_SERVICE     *Service
+  )
+{
+  if (Service != NULL) {
+    if (Service->TlsCtx != NULL) {
+      TlsCtxFree (Service->TlsCtx);
+    }
+
+    FreePool (Service);
+  }
+}
+
+/**
+  Create then initialize a TLS service.
+
+  @param[in]  Image                  ImageHandle of the TLS driver
+  @param[out] Service                The service for TLS driver
+
+  @retval EFI_OUT_OF_RESOURCES   Failed to allocate resource to create the service.
+  @retval EFI_SUCCESS            The service is created for the driver.
+
+**/
+EFI_STATUS
+TlsCreateService (
+  IN  EFI_HANDLE            Image,
+  OUT TLS_SERVICE           **Service
+  )
+{
+  EFI_STATUS             Status;
+  TLS_SERVICE            *TlsService;
+
+  Status = EFI_SUCCESS;
+  *Service = NULL;
+
+  ASSERT (Service != NULL);
+
+  //
+  // Allocate a TLS Service Data
+  //
+  TlsService = AllocateZeroPool (sizeof (TLS_SERVICE));
+  if (TlsService == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  //
+  // Initialize TLS Service Data
+  //
+  TlsService->Signature        = TLS_SERVICE_SIGNATURE;
+  CopyMem (&TlsService->ServiceBinding, &mTlsServiceBinding, sizeof (TlsService->ServiceBinding));
+  TlsService->TlsChildrenNum   = 0;
+  InitializeListHead (&TlsService->TlsChildrenList);
+  TlsService->ImageHandle      = Image;
+
+  *Service = TlsService;
+
+  return Status;
+}
+
+/**
+  Unloads an image.
+
+  @param[in]  ImageHandle           Handle that identifies the image to be unloaded.
+
+  @retval EFI_SUCCESS           The image has been unloaded.
+  @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsUnload (
+  IN EFI_HANDLE  ImageHandle
+  )
+{
+  EFI_STATUS                      Status;
+  UINTN                           HandleNum;
+  EFI_HANDLE                      *HandleBuffer;
+  UINT32                          Index;
+  EFI_SERVICE_BINDING_PROTOCOL    *ServiceBinding;
+  TLS_SERVICE                     *TlsService;
+
+  HandleBuffer   = NULL;
+  ServiceBinding = NULL;
+  TlsService     = NULL;
+
+  //
+  // Locate all the handles with Tls service binding protocol.
+  //
+  Status = gBS->LocateHandleBuffer (
+                  ByProtocol,
+                  &gEfiTlsServiceBindingProtocolGuid,
+                  NULL,
+                  &HandleNum,
+                  &HandleBuffer
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  for (Index = 0; Index < HandleNum; Index++) {
+    //
+    // Firstly, find ServiceBinding interface
+    //
+    Status = gBS->OpenProtocol (
+                    HandleBuffer[Index],
+                    &gEfiTlsServiceBindingProtocolGuid,
+                    (VOID **) &ServiceBinding,
+                    ImageHandle,
+                    NULL,
+                    EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
+                    );
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+
+    TlsService = TLS_SERVICE_FROM_THIS (ServiceBinding);
+
+    //
+    // Then, uninstall ServiceBinding interface
+    //
+    Status = gBS->UninstallMultipleProtocolInterfaces (
+                    HandleBuffer[Index],
+                    &gEfiTlsServiceBindingProtocolGuid, ServiceBinding,
+                    NULL
+                    );
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+
+    TlsCleanService (TlsService);
+  }
+
+  if (HandleBuffer != NULL) {
+    FreePool (HandleBuffer);
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This is the declaration of an EFI image entry point. This entry point is
+  the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
+  both device drivers and bus drivers.
+
+  @param  ImageHandle           The firmware allocated handle for the UEFI image.
+  @param  SystemTable           A pointer to the EFI System Table.
+
+  @retval EFI_SUCCESS           The operation completed successfully.
+  @retval Others                An unexpected error occurred.
+**/
+EFI_STATUS
+EFIAPI
+TlsDriverEntryPoint (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  EFI_STATUS             Status;
+
+  TLS_SERVICE            *TlsService;
+
+  //
+  // Create TLS Service
+  //
+  Status = TlsCreateService (ImageHandle, &TlsService);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  ASSERT (TlsService != NULL);
+
+  //
+  // Initializes the OpenSSL library.
+  //
+  TlsInitialize ();
+
+  //
+  // Create a new SSL_CTX object as framework to establish TLS/SSL enabled
+  // connections. TLS 1.0 is used as the default version.
+  //
+  TlsService->TlsCtx = TlsCtxNew (TLS10_PROTOCOL_VERSION_MAJOR, TLS10_PROTOCOL_VERSION_MINOR);
+  if (TlsService->TlsCtx == NULL) {
+    FreePool (TlsService);
+    return EFI_ABORTED;
+  }
+
+  //
+  // Install the TlsServiceBinding Protocol onto Handle
+  //
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &TlsService->Handle,
+                  &gEfiTlsServiceBindingProtocolGuid,
+                  &TlsService->ServiceBinding,
+                  NULL
+                  );
+  if (EFI_ERROR (Status)) {
+    goto ON_CLEAN_SERVICE;
+  }
+
+  return Status;
+
+ON_CLEAN_SERVICE:
+  TlsCleanService (TlsService);
+
+  return Status;
+}
+
+/**
+  Creates a child handle and installs a protocol.
+
+  The CreateChild() function installs a protocol on ChildHandle.
+  If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle.
+  If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle.
+
+  @param[in] This        Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
+  @param[in] ChildHandle Pointer to the handle of the child to create. If it is NULL,
+                         then a new handle is created. If it is a pointer to an existing UEFI handle,
+                         then the protocol is added to the existing UEFI handle.
+
+  @retval EFI_SUCCES            The protocol was added to ChildHandle.
+  @retval EFI_INVALID_PARAMETER ChildHandle is NULL.
+  @retval EFI_OUT_OF_RESOURCES  There are not enough resources available to create
+                                the child.
+  @retval other                 The child handle was not created.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsServiceBindingCreateChild (
+  IN EFI_SERVICE_BINDING_PROTOCOL  *This,
+  IN EFI_HANDLE                    *ChildHandle
+  )
+{
+  TLS_SERVICE         *TlsService;
+  TLS_INSTANCE        *TlsInstance;
+  EFI_STATUS           Status;
+  EFI_TPL              OldTpl;
+
+  if ((This == NULL) || (ChildHandle == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  TlsService = TLS_SERVICE_FROM_THIS (This);
+
+  Status = TlsCreateInstance (TlsService, &TlsInstance);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  ASSERT (TlsInstance != NULL);
+
+  //
+  // Create a new TLS connection object.
+  //
+  TlsInstance->TlsConn = TlsNew (TlsService->TlsCtx);
+  if (TlsInstance->TlsConn == NULL) {
+    Status = EFI_ABORTED;
+    goto ON_ERROR;
+  }
+
+  //
+  // Set default ConnectionEnd to EfiTlsClient
+  //
+  Status = TlsSetConnectionEnd (TlsInstance->TlsConn, EfiTlsClient);
+  if (EFI_ERROR (Status)) {
+    goto ON_ERROR;
+  }
+
+  //
+  // Install TLS protocol and configuration protocol onto ChildHandle
+  //
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  ChildHandle,
+                  &gEfiTlsProtocolGuid,
+                  &TlsInstance->Tls,
+                  &gEfiTlsConfigurationProtocolGuid,
+                  &TlsInstance->TlsConfig,
+                  NULL
+                  );
+  if (EFI_ERROR (Status)) {
+    goto ON_ERROR;
+  }
+
+  TlsInstance->ChildHandle = *ChildHandle;
+
+  //
+  // Add it to the TLS service's child list.
+  //
+  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+  InsertTailList (&TlsService->TlsChildrenList, &TlsInstance->Link);
+  TlsService->TlsChildrenNum++;
+
+  gBS->RestoreTPL (OldTpl);
+
+  return EFI_SUCCESS;
+
+ON_ERROR:
+  TlsCleanInstance (TlsInstance);
+  return Status;
+}
+
+/**
+  Destroys a child handle with a protocol installed on it.
+
+  The DestroyChild() function does the opposite of CreateChild(). It removes a protocol
+  that was installed by CreateChild() from ChildHandle. If the removed protocol is the
+  last protocol on ChildHandle, then ChildHandle is destroyed.
+
+  @param  This        Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
+  @param  ChildHandle Handle of the child to destroy.
+
+  @retval EFI_SUCCES            The protocol was removed from ChildHandle.
+  @retval EFI_UNSUPPORTED       ChildHandle does not support the protocol that is being removed.
+  @retval EFI_INVALID_PARAMETER Child handle is NULL.
+  @retval EFI_ACCESS_DENIED     The protocol could not be removed from the ChildHandle
+                                because its services are being used.
+  @retval other                 The child handle was not destroyed.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsServiceBindingDestroyChild (
+  IN EFI_SERVICE_BINDING_PROTOCOL  *This,
+  IN EFI_HANDLE                    ChildHandle
+  )
+{
+  TLS_SERVICE                    *TlsService;
+  TLS_INSTANCE                   *TlsInstance;
+
+  EFI_TLS_PROTOCOL               *Tls;
+  EFI_TLS_CONFIGURATION_PROTOCOL *TlsConfig;
+  EFI_STATUS                     Status;
+  EFI_TPL                        OldTpl;
+
+  if ((This == NULL) || (ChildHandle == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  TlsService = TLS_SERVICE_FROM_THIS (This);
+
+  //
+  // Find TLS protocol interface installed in ChildHandle
+  //
+  Status = gBS->OpenProtocol (
+                  ChildHandle,
+                  &gEfiTlsProtocolGuid,
+                  (VOID **) &Tls,
+                  TlsService->ImageHandle,
+                  NULL,
+                  EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Find TLS configuration protocol interface installed in ChildHandle
+  //
+  Status = gBS->OpenProtocol (
+                  ChildHandle,
+                  &gEfiTlsConfigurationProtocolGuid,
+                  (VOID **) &TlsConfig,
+                  TlsService->ImageHandle,
+                  NULL,
+                  EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  TlsInstance  = TLS_INSTANCE_FROM_PROTOCOL_THIS (Tls);
+
+  if (TlsInstance->Service != TlsService) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (TlsInstance->InDestroy) {
+    return EFI_SUCCESS;
+  }
+
+  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+  TlsInstance->InDestroy = TRUE;
+
+  //
+  // Uninstall the TLS protocol and TLS Configuration Protocol interface installed in ChildHandle.
+  //
+  Status = gBS->UninstallMultipleProtocolInterfaces (
+                  ChildHandle,
+                  &gEfiTlsProtocolGuid,
+                  Tls,
+                  &gEfiTlsConfigurationProtocolGuid,
+                  TlsConfig,
+                  NULL
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  RemoveEntryList (&TlsInstance->Link);
+  TlsService->TlsChildrenNum--;
+
+  gBS->RestoreTPL (OldTpl);
+
+  TlsCleanInstance (TlsInstance);
+
+  return EFI_SUCCESS;
+}
diff --git a/NetworkPkg/TlsDxe/TlsDriver.h b/NetworkPkg/TlsDxe/TlsDriver.h
new file mode 100644
index 0000000..c3c30a8
--- /dev/null
+++ b/NetworkPkg/TlsDxe/TlsDriver.h
@@ -0,0 +1,237 @@
+/** @file
+  Header file of the Driver Binding and Service Binding Protocol for TlsDxe 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_TLS_DRIVER_H__
+#define __EFI_TLS_DRIVER_H__
+
+#include <Uefi.h>
+
+//
+// Driver Protocols
+//
+#include <Protocol/ServiceBinding.h>
+
+//
+// Driver Version
+//
+#define TLS_VERSION  0x00000000
+
+#define TLS_SERVICE_SIGNATURE    SIGNATURE_32 ('T', 'L', 'S', 'S')
+
+#define TLS_INSTANCE_SIGNATURE   SIGNATURE_32 ('T', 'L', 'S', 'I')
+
+///
+/// TLS Service Data
+///
+typedef struct _TLS_SERVICE  TLS_SERVICE;
+
+///
+/// TLS Instance Data
+///
+typedef struct _TLS_INSTANCE TLS_INSTANCE;
+
+
+struct _TLS_SERVICE {
+  UINT32                          Signature;
+  EFI_SERVICE_BINDING_PROTOCOL    ServiceBinding;
+
+  UINT16                          TlsChildrenNum;
+  LIST_ENTRY                      TlsChildrenList;
+
+  //
+  // Handle to install TlsServiceBinding protocol.
+  //
+  EFI_HANDLE                      Handle;
+  EFI_HANDLE                      ImageHandle;
+
+  //
+  // Main SSL Context object which is created by a server or client once per program
+  // life-time and which holds mainly default values for the SSL object which are later
+  // created for the connections.
+  //
+  VOID                            *TlsCtx;
+};
+
+struct _TLS_INSTANCE {
+  UINT32                          Signature;
+  LIST_ENTRY                      Link;
+
+  BOOLEAN                         InDestroy;
+
+  TLS_SERVICE                     *Service;
+  EFI_HANDLE                      ChildHandle;
+
+  EFI_TLS_PROTOCOL                Tls;
+  EFI_TLS_CONFIGURATION_PROTOCOL  TlsConfig;
+
+  EFI_TLS_SESSION_STATE           TlsSessionState;
+
+  //
+  // Main SSL Connection which is created by a server or a client
+  // per established connection.
+  //
+  VOID                            *TlsConn;
+};
+
+
+#define TLS_SERVICE_FROM_THIS(a)   \
+  CR (a, TLS_SERVICE, ServiceBinding, TLS_SERVICE_SIGNATURE)
+
+#define TLS_INSTANCE_FROM_PROTOCOL_THIS(a)  \
+  CR (a, TLS_INSTANCE, Tls, TLS_INSTANCE_SIGNATURE)
+
+#define TLS_INSTANCE_FROM_CONFIGURATION_THIS(a)  \
+  CR (a, TLS_INSTANCE, TlsConfig, TLS_INSTANCE_SIGNATURE)
+
+
+/**
+  Release all the resources used by the TLS instance.
+
+  @param[in]  Instance        The TLS instance data.
+
+**/
+VOID
+TlsCleanInstance (
+  IN TLS_INSTANCE           *Instance
+  );
+
+/**
+  Create the TLS instance and initialize it.
+
+  @param[in]  Service              The pointer to the TLS service.
+  @param[out] Instance             The pointer to the TLS instance.
+
+  @retval EFI_OUT_OF_RESOURCES   Failed to allocate resources.
+  @retval EFI_SUCCESS            The TLS instance is created.
+
+**/
+EFI_STATUS
+TlsCreateInstance (
+  IN  TLS_SERVICE         *Service,
+  OUT TLS_INSTANCE        **Instance
+  );
+
+/**
+  Release all the resources used by the TLS service binding instance.
+
+  @param[in]  Service        The TLS service data.
+
+**/
+VOID
+TlsCleanService (
+  IN TLS_SERVICE     *Service
+  );
+
+/**
+  Create then initialize a TLS service.
+
+  @param[in]  Image                  ImageHandle of the TLS driver
+  @param[out] Service                The service for TLS driver
+
+  @retval EFI_OUT_OF_RESOURCES   Failed to allocate resource to create the service.
+  @retval EFI_SUCCESS            The service is created for the driver.
+
+**/
+EFI_STATUS
+TlsCreateService (
+  IN  EFI_HANDLE            Image,
+  OUT TLS_SERVICE           **Service
+  );
+
+/**
+  Unloads an image.
+
+  @param[in]  ImageHandle       Handle that identifies the image to be unloaded.
+
+  @retval EFI_SUCCESS           The image has been unloaded.
+  @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsUnload (
+  IN EFI_HANDLE  ImageHandle
+  );
+
+/**
+  This is the declaration of an EFI image entry point. This entry point is
+  the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
+  both device drivers and bus drivers.
+
+  @param  ImageHandle           The firmware allocated handle for the UEFI image.
+  @param  SystemTable           A pointer to the EFI System Table.
+
+  @retval EFI_SUCCESS           The operation completed successfully.
+  @retval Others                An unexpected error occurred.
+**/
+EFI_STATUS
+EFIAPI
+TlsDriverEntryPoint (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  );
+
+/**
+  Creates a child handle and installs a protocol.
+
+  The CreateChild() function installs a protocol on ChildHandle.
+  If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle.
+  If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle.
+
+  @param[in] This        Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
+  @param[in] ChildHandle Pointer to the handle of the child to create. If it is NULL,
+                         then a new handle is created. If it is a pointer to an existing UEFI handle,
+                         then the protocol is added to the existing UEFI handle.
+
+  @retval EFI_SUCCES            The protocol was added to ChildHandle.
+  @retval EFI_INVALID_PARAMETER ChildHandle is NULL.
+  @retval EFI_OUT_OF_RESOURCES  There are not enough resources available to create
+                                the child.
+  @retval other                 The child handle was not created.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsServiceBindingCreateChild (
+  IN EFI_SERVICE_BINDING_PROTOCOL  *This,
+  IN EFI_HANDLE                    *ChildHandle
+  );
+
+/**
+  Destroys a child handle with a protocol installed on it.
+
+  The DestroyChild() function does the opposite of CreateChild(). It removes a protocol
+  that was installed by CreateChild() from ChildHandle. If the removed protocol is the
+  last protocol on ChildHandle, then ChildHandle is destroyed.
+
+  @param  This        Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
+  @param  ChildHandle Handle of the child to destroy.
+
+  @retval EFI_SUCCES            The protocol was removed from ChildHandle.
+  @retval EFI_UNSUPPORTED       ChildHandle does not support the protocol that is being removed.
+  @retval EFI_INVALID_PARAMETER Child handle is NULL.
+  @retval EFI_ACCESS_DENIED     The protocol could not be removed from the ChildHandle
+                                because its services are being used.
+  @retval other                 The child handle was not destroyed.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsServiceBindingDestroyChild (
+  IN EFI_SERVICE_BINDING_PROTOCOL  *This,
+  IN EFI_HANDLE                    ChildHandle
+  );
+
+#endif
diff --git a/NetworkPkg/TlsDxe/TlsDxe.inf b/NetworkPkg/TlsDxe/TlsDxe.inf
new file mode 100644
index 0000000..dba3257
--- /dev/null
+++ b/NetworkPkg/TlsDxe/TlsDxe.inf
@@ -0,0 +1,65 @@
+## @file
+#  This module produces EFI TLS Protocol, EFI TLS Service Binding Protocol and
+#  EFI TLS Configuration Protocol.
+#
+#  This module produces EFI TLS (Transport Layer Security) Protocol and EFI TLS
+#  Service Binding Protocol, to provide TLS services.
+#
+#  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.
+#
+#
+##
+
+[Defines]
+  INF_VERSION               = 0x00010005
+  BASE_NAME                 = TlsDxe
+  FILE_GUID                 = 3aceb0c0-3c72-11e4-9a56-74d435052646
+  MODULE_TYPE               = UEFI_DRIVER
+  VERSION_STRING            = 1.0
+  ENTRY_POINT               = TlsDriverEntryPoint
+  UNLOAD_IMAGE              = TlsUnload
+  MODULE_UNI_FILE           = TlsDxe.uni
+
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  CryptoPkg/CryptoPkg.dec
+
+[Sources]
+  TlsDriver.h
+  TlsDriver.c
+  TlsProtocol.c
+  TlsConfigProtocol.c
+  TlsImpl.h
+  TlsImpl.c
+
+[LibraryClasses]
+  UefiDriverEntryPoint
+  UefiBootServicesTableLib
+  MemoryAllocationLib
+  BaseMemoryLib
+  BaseLib
+  UefiLib
+  DebugLib
+  NetLib
+  BaseCryptLib
+  TlsLib
+
+[Protocols]
+  gEfiTlsServiceBindingProtocolGuid          ## PRODUCES
+  gEfiTlsProtocolGuid                        ## PRODUCES
+  gEfiTlsConfigurationProtocolGuid           ## PRODUCES
+
+[UserExtensions.TianoCore."ExtraFiles"]
+  TlsDxeExtra.uni
diff --git a/NetworkPkg/TlsDxe/TlsDxe.uni b/NetworkPkg/TlsDxe/TlsDxe.uni
new file mode 100644
index 0000000..98c41ca
--- /dev/null
+++ b/NetworkPkg/TlsDxe/TlsDxe.uni
@@ -0,0 +1,25 @@
+// /** @file
+// This module produces EFI TLS Protocol, EFI TLS Service Binding Protocol and
+// EFI TLS Configuration Protocol.
+//
+// This module produces EFI TLS (Transport Layer Security) Protocol, EFI TLS
+// Service Binding Protocol, and EFI TLS Configuration Protocol to provide TLS
+// services.
+//
+// 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.
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT             #language en-US "UEFI TLS service"
+
+#string STR_MODULE_DESCRIPTION          #language en-US "This module produces EFI TLS Protocol, EFI TLS Service Binding Protocol and EFI TLS Configuration Protocol to provide EFI TLS services."
+
diff --git a/NetworkPkg/TlsDxe/TlsDxeExtra.uni b/NetworkPkg/TlsDxe/TlsDxeExtra.uni
new file mode 100644
index 0000000..a38582a
--- /dev/null
+++ b/NetworkPkg/TlsDxe/TlsDxeExtra.uni
@@ -0,0 +1,18 @@
+// /** @file
+// TlsDxe Localized Strings and Content
+//
+// 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.
+//
+// **/
+
+#string STR_PROPERTIES_MODULE_NAME
+#language en-US
+"EFI TLS DXE Driver"
diff --git a/NetworkPkg/TlsDxe/TlsImpl.c b/NetworkPkg/TlsDxe/TlsImpl.c
new file mode 100644
index 0000000..9b7bf7d
--- /dev/null
+++ b/NetworkPkg/TlsDxe/TlsImpl.c
@@ -0,0 +1,326 @@
+/** @file
+  The Miscellaneous Routines for TlsDxe 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 "TlsImpl.h"
+
+/**
+  Encrypt the message listed in fragment.
+
+  @param[in]       TlsInstance    The pointer to the TLS instance.
+  @param[in, out]  FragmentTable  Pointer to a list of fragment.
+                                  On input these fragments contain the TLS header and
+                                  plain text TLS payload;
+                                  On output these fragments contain the TLS header and
+                                  cipher text TLS payload.
+  @param[in]       FragmentCount  Number of fragment.
+
+  @retval EFI_SUCCESS             The operation completed successfully.
+  @retval EFI_OUT_OF_RESOURCES    Can't allocate memory resources.
+  @retval EFI_ABORTED             TLS session state is incorrect.
+  @retval Others                  Other errors as indicated.
+**/
+EFI_STATUS
+TlsEcryptPacket (
+  IN     TLS_INSTANCE                  *TlsInstance,
+  IN OUT EFI_TLS_FRAGMENT_DATA         **FragmentTable,
+  IN     UINT32                        *FragmentCount
+  )
+{
+  EFI_STATUS          Status;
+  UINTN               Index;
+  UINT32              BytesCopied;
+  UINT32              BufferInSize;
+  UINT8               *BufferIn;
+  UINT8               *BufferInPtr;
+  TLS_RECORD_HEADER   *RecordHeaderIn;
+  UINT16              ThisPlainMessageSize;
+  TLS_RECORD_HEADER   *TempRecordHeader;
+  UINT16              ThisMessageSize;
+  UINT32              BufferOutSize;
+  UINT8               *BufferOut;
+  INTN                Ret;
+  
+  Status           = EFI_SUCCESS;
+  BytesCopied      = 0;
+  BufferInSize     = 0;
+  BufferIn         = NULL;
+  BufferInPtr      = NULL;
+  RecordHeaderIn   = NULL;
+  TempRecordHeader = NULL;
+  BufferOutSize    = 0;
+  BufferOut        = NULL;
+  Ret              = 0;
+
+  //
+  // Calculate the size according to the fragment table.
+  //
+  for (Index = 0; Index < *FragmentCount; Index++) {
+    BufferInSize += (*FragmentTable)[Index].FragmentLength;
+  }
+
+  //
+  // Allocate buffer for processing data.
+  //
+  BufferIn = AllocateZeroPool (BufferInSize);
+  if (BufferIn == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto ERROR;
+  }
+
+  //
+  // Copy all TLS plain record header and payload into ProcessBuffer.
+  //
+  for (Index = 0; Index < *FragmentCount; Index++) {
+    CopyMem (
+      (BufferIn + BytesCopied),
+      (*FragmentTable)[Index].FragmentBuffer,
+      (*FragmentTable)[Index].FragmentLength
+      );
+    BytesCopied += (*FragmentTable)[Index].FragmentLength;
+  }
+
+  BufferOut = AllocateZeroPool (MAX_BUFFER_SIZE);
+  if (BufferOut == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto ERROR;
+  }
+
+  //
+  // Parsing buffer.
+  //
+  BufferInPtr = BufferIn;
+  TempRecordHeader = (TLS_RECORD_HEADER *) BufferOut;
+  while ((UINTN) BufferInPtr < (UINTN) BufferIn + BufferInSize) {
+    RecordHeaderIn = (TLS_RECORD_HEADER *) BufferInPtr;
+    
+    if (RecordHeaderIn->ContentType != TLS_CONTENT_TYPE_APPLICATION_DATA) {
+      Status = EFI_INVALID_PARAMETER;
+      goto ERROR;
+    }
+    
+    ThisPlainMessageSize = RecordHeaderIn->Length;
+
+    TlsWrite (TlsInstance->TlsConn, (UINT8 *) (RecordHeaderIn + 1), ThisPlainMessageSize);
+    
+    Ret = TlsCtrlTrafficOut (TlsInstance->TlsConn, (UINT8 *)(TempRecordHeader), MAX_BUFFER_SIZE - BufferOutSize);
+
+    if (Ret > 0) {
+      ThisMessageSize = (UINT16) Ret;
+    } else {
+      //
+      // No data was successfully encrypted, continue the other messages encryption.
+      //
+      DEBUG ((EFI_D_WARN, "TlsEcryptPacket: No data read from TLS object.\n"));
+    
+      ThisMessageSize = 0;
+    }
+
+    BufferOutSize += ThisMessageSize;
+
+    BufferInPtr += RECORD_HEADER_LEN + ThisPlainMessageSize;
+    TempRecordHeader += ThisMessageSize;
+  }
+
+  FreePool (BufferIn);
+  BufferIn = NULL;
+
+  //
+  // The caller will take responsible to handle the original fragment table.
+  //
+  *FragmentTable = AllocateZeroPool (sizeof (EFI_TLS_FRAGMENT_DATA));
+  if (*FragmentTable == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto ERROR;
+  }
+
+  (*FragmentTable)[0].FragmentBuffer  = BufferOut;
+  (*FragmentTable)[0].FragmentLength  = BufferOutSize;
+  *FragmentCount                      = 1;
+
+  return Status;
+
+ERROR:
+  
+  if (BufferIn != NULL) {
+    FreePool (BufferIn);
+    BufferIn = NULL;
+  }
+
+  if (BufferOut != NULL) {
+    FreePool (BufferOut);
+    BufferOut = NULL;
+  }
+  
+  return Status;
+}
+
+/**
+  Decrypt the message listed in fragment.
+
+  @param[in]       TlsInstance    The pointer to the TLS instance.
+  @param[in, out]  FragmentTable  Pointer to a list of fragment.
+                                  On input these fragments contain the TLS header and
+                                  cipher text TLS payload;
+                                  On output these fragments contain the TLS header and
+                                  plain text TLS payload.
+  @param[in]       FragmentCount  Number of fragment.
+
+  @retval EFI_SUCCESS             The operation completed successfully.
+  @retval EFI_OUT_OF_RESOURCES    Can't allocate memory resources.
+  @retval EFI_ABORTED             TLS session state is incorrect.
+  @retval Others                  Other errors as indicated.
+**/
+EFI_STATUS
+TlsDecryptPacket (
+  IN     TLS_INSTANCE                  *TlsInstance,
+  IN OUT EFI_TLS_FRAGMENT_DATA         **FragmentTable,
+  IN     UINT32                        *FragmentCount
+  )
+{
+  EFI_STATUS          Status;
+  UINTN               Index;
+  UINT32              BytesCopied;
+  UINT8               *BufferIn;
+  UINT32              BufferInSize;
+  UINT8               *BufferInPtr;
+  TLS_RECORD_HEADER   *RecordHeaderIn;
+  UINT16              ThisCipherMessageSize;
+  TLS_RECORD_HEADER   *TempRecordHeader;
+  UINT16              ThisPlainMessageSize;
+  UINT8               *BufferOut;
+  UINT32              BufferOutSize;
+  INTN                Ret;
+
+  Status           = EFI_SUCCESS;
+  BytesCopied      = 0;
+  BufferIn         = NULL;
+  BufferInSize     = 0;
+  BufferInPtr      = NULL;
+  RecordHeaderIn   = NULL;
+  TempRecordHeader = NULL;
+  BufferOut        = NULL;
+  BufferOutSize    = 0;
+  Ret              = 0;
+
+  //
+  // Calculate the size according to the fragment table.
+  //
+  for (Index = 0; Index < *FragmentCount; Index++) {
+    BufferInSize += (*FragmentTable)[Index].FragmentLength;
+  }
+
+  //
+  // Allocate buffer for processing data
+  //
+  BufferIn = AllocateZeroPool (BufferInSize);
+  if (BufferIn == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto ERROR;
+  }
+
+  //
+  // Copy all TLS plain record header and payload to ProcessBuffer
+  //
+  for (Index = 0; Index < *FragmentCount; Index++) {
+    CopyMem (
+      (BufferIn + BytesCopied),
+      (*FragmentTable)[Index].FragmentBuffer,
+      (*FragmentTable)[Index].FragmentLength
+      );
+    BytesCopied += (*FragmentTable)[Index].FragmentLength;
+  }
+
+  BufferOut = AllocateZeroPool (MAX_BUFFER_SIZE);
+  if (BufferOut == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto ERROR;
+  }
+
+  //
+  // Parsing buffer. Received packet may have multiply TLS record message.
+  //
+  BufferInPtr = BufferIn;
+  TempRecordHeader = (TLS_RECORD_HEADER *) BufferOut;
+  while ((UINTN) BufferInPtr < (UINTN) BufferIn + BufferInSize) {
+    RecordHeaderIn = (TLS_RECORD_HEADER *) BufferInPtr;
+
+    if (RecordHeaderIn->ContentType != TLS_CONTENT_TYPE_APPLICATION_DATA) {
+      Status = EFI_INVALID_PARAMETER;
+      goto ERROR;
+    }
+    
+    ThisCipherMessageSize = NTOHS (RecordHeaderIn->Length);
+
+    Ret = TlsCtrlTrafficIn (TlsInstance->TlsConn, (UINT8 *) (RecordHeaderIn), RECORD_HEADER_LEN + ThisCipherMessageSize);
+    if (Ret != RECORD_HEADER_LEN + ThisCipherMessageSize) {
+      TlsInstance->TlsSessionState = EfiTlsSessionError;
+      Status = EFI_ABORTED;
+      goto ERROR;
+    }
+
+    Ret = 0;
+    Ret = TlsRead (TlsInstance->TlsConn, (UINT8 *) (TempRecordHeader + 1), MAX_BUFFER_SIZE - BufferOutSize);
+
+    if (Ret > 0) {
+      ThisPlainMessageSize = (UINT16) Ret;
+    } else {
+      //
+      // No data was successfully decrypted, continue the other messages decryption.
+      //
+      DEBUG ((EFI_D_WARN, "TlsDecryptPacket: No data read from TLS object.\n"));
+    
+      ThisPlainMessageSize = 0;
+    }
+
+    CopyMem (TempRecordHeader, RecordHeaderIn, RECORD_HEADER_LEN);
+    TempRecordHeader->Length = ThisPlainMessageSize;
+    BufferOutSize += RECORD_HEADER_LEN + ThisPlainMessageSize;
+
+    BufferInPtr += RECORD_HEADER_LEN + ThisCipherMessageSize;
+    TempRecordHeader += RECORD_HEADER_LEN + ThisPlainMessageSize;
+  }
+
+  FreePool (BufferIn);
+  BufferIn = NULL;
+
+  //
+  // The caller will take responsible to handle the original fragment table
+  //
+  *FragmentTable = AllocateZeroPool (sizeof (EFI_TLS_FRAGMENT_DATA));
+  if (*FragmentTable == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto ERROR;
+  }
+
+  (*FragmentTable)[0].FragmentBuffer  = BufferOut;
+  (*FragmentTable)[0].FragmentLength  = BufferOutSize;
+  *FragmentCount                      = 1;
+
+  return Status;
+
+ERROR:
+  
+  if (BufferIn != NULL) {
+    FreePool (BufferIn);
+    BufferIn = NULL;
+  }
+
+  if (BufferOut != NULL) {
+    FreePool (BufferOut);
+    BufferOut = NULL;
+  }
+  
+  return Status;  
+}
diff --git a/NetworkPkg/TlsDxe/TlsImpl.h b/NetworkPkg/TlsDxe/TlsImpl.h
new file mode 100644
index 0000000..b0615cb
--- /dev/null
+++ b/NetworkPkg/TlsDxe/TlsImpl.h
@@ -0,0 +1,315 @@
+/** @file
+  Header file of Miscellaneous Routines for TlsDxe 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_TLS_IMPL_H__
+#define __EFI_TLS_IMPL_H__
+
+//
+// Libraries
+//
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/BaseLib.h>
+#include <Library/UefiLib.h>
+#include <Library/DebugLib.h>
+#include <Library/NetLib.h>
+#include <Library/BaseCryptLib.h>
+#include <Library/TlsLib.h>
+
+//
+// Consumed Protocols
+//
+#include <Protocol/Tls.h>
+#include <Protocol/TlsConfig.h>
+
+#include <IndustryStandard/Tls1.h>
+
+#include "TlsDriver.h"
+
+//
+// Protocol instances
+//
+extern EFI_SERVICE_BINDING_PROTOCOL    mTlsServiceBinding;
+extern EFI_TLS_PROTOCOL                mTlsProtocol;
+extern EFI_TLS_CONFIGURATION_PROTOCOL  mTlsConfigurationProtocol;
+
+#define RECORD_HEADER_LEN 5 /// ContentType(1) + Version(2) + Length(2)
+
+#define MAX_BUFFER_SIZE   32768
+
+/**
+  Encrypt the message listed in fragment.
+
+  @param[in]       TlsInstance    The pointer to the TLS instance.
+  @param[in, out]  FragmentTable  Pointer to a list of fragment.
+                                  On input these fragments contain the TLS header and
+                                  plain text TLS payload;
+                                  On output these fragments contain the TLS header and
+                                  cipher text TLS payload.
+  @param[in]       FragmentCount  Number of fragment.
+
+  @retval EFI_SUCCESS             The operation completed successfully.
+  @retval EFI_OUT_OF_RESOURCES    Can't allocate memory resources.
+  @retval EFI_ABORTED             TLS session state is incorrect.
+  @retval Others                  Other errors as indicated.
+**/
+EFI_STATUS
+TlsEcryptPacket (
+  IN     TLS_INSTANCE                  *TlsInstance,
+  IN OUT EFI_TLS_FRAGMENT_DATA         **FragmentTable,
+  IN     UINT32                        *FragmentCount
+  );
+
+/**
+  Decrypt the message listed in fragment.
+
+  @param[in]       TlsInstance    The pointer to the TLS instance.
+  @param[in, out]  FragmentTable  Pointer to a list of fragment.
+                                  On input these fragments contain the TLS header and
+                                  cipher text TLS payload;
+                                  On output these fragments contain the TLS header and
+                                  plain text TLS payload.
+  @param[in]       FragmentCount  Number of fragment.
+
+  @retval EFI_SUCCESS             The operation completed successfully.
+  @retval EFI_OUT_OF_RESOURCES    Can't allocate memory resources.
+  @retval EFI_ABORTED             TLS session state is incorrect.
+  @retval Others                  Other errors as indicated.
+**/
+EFI_STATUS
+TlsDecryptPacket (
+  IN     TLS_INSTANCE                  *TlsInstance,
+  IN OUT EFI_TLS_FRAGMENT_DATA         **FragmentTable,
+  IN     UINT32                        *FragmentCount
+  );
+
+/**
+  Set TLS session data.
+
+  The SetSessionData() function set data for a new TLS session. All session data should
+  be set before BuildResponsePacket() invoked.
+
+  @param[in]  This                Pointer to the EFI_TLS_PROTOCOL instance.
+  @param[in]  DataType            TLS session data type.
+  @param[in]  Data                Pointer to session data.
+  @param[in]  DataSize            Total size of session data.
+
+  @retval EFI_SUCCESS             The TLS session data is set successfully.
+  @retval EFI_INVALID_PARAMETER   One or more of the following conditions is TRUE:
+                                  This is NULL.
+                                  Data is NULL.
+                                  DataSize is 0.
+  @retval EFI_UNSUPPORTED         The DataType is unsupported.
+  @retval EFI_ACCESS_DENIED       If the DataType is one of below:
+                                  EfiTlsClientRandom
+                                  EfiTlsServerRandom
+                                  EfiTlsKeyMaterial
+  @retval EFI_NOT_READY           Current TLS session state is NOT
+                                  EfiTlsSessionStateNotStarted.
+  @retval EFI_OUT_OF_RESOURCES    Required system resources could not be allocated.
+**/
+EFI_STATUS
+EFIAPI
+TlsSetSessionData (
+  IN     EFI_TLS_PROTOCOL              *This,
+  IN     EFI_TLS_SESSION_DATA_TYPE     DataType,
+  IN     VOID                          *Data,
+  IN     UINTN                         DataSize
+  );
+
+/**
+  Get TLS session data.
+
+  The GetSessionData() function return the TLS session information.
+
+  @param[in]       This           Pointer to the EFI_TLS_PROTOCOL instance.
+  @param[in]       DataType       TLS session data type.
+  @param[in, out]  Data           Pointer to session data.
+  @param[in, out]  DataSize       Total size of session data. On input, it means
+                                  the size of Data buffer. On output, it means the size
+                                  of copied Data buffer if EFI_SUCCESS, and means the
+                                  size of desired Data buffer if EFI_BUFFER_TOO_SMALL.
+
+  @retval EFI_SUCCESS             The TLS session data is got successfully.
+  @retval EFI_INVALID_PARAMETER   One or more of the following conditions is TRUE:
+                                  This is NULL.
+                                  DataSize is NULL.
+                                  Data is NULL if *DataSize is not zero.
+  @retval EFI_UNSUPPORTED         The DataType is unsupported.
+  @retval EFI_NOT_FOUND           The TLS session data is not found.
+  @retval EFI_NOT_READY           The DataType is not ready in current session state.
+  @retval EFI_BUFFER_TOO_SMALL    The buffer is too small to hold the data.
+**/
+EFI_STATUS
+EFIAPI
+TlsGetSessionData (
+  IN     EFI_TLS_PROTOCOL              *This,
+  IN     EFI_TLS_SESSION_DATA_TYPE     DataType,
+  IN OUT VOID                          *Data,  OPTIONAL
+  IN OUT UINTN                         *DataSize
+  );
+
+/**
+  Build response packet according to TLS state machine. This function is only valid for
+  alert, handshake and change_cipher_spec content type.
+
+  The BuildResponsePacket() function builds TLS response packet in response to the TLS
+  request packet specified by RequestBuffer and RequestSize. If RequestBuffer is NULL and
+  RequestSize is 0, and TLS session status is EfiTlsSessionNotStarted, the TLS session
+  will be initiated and the response packet needs to be ClientHello. If RequestBuffer is
+  NULL and RequestSize is 0, and TLS session status is EfiTlsSessionClosing, the TLS
+  session will be closed and response packet needs to be CloseNotify. If RequestBuffer is
+  NULL and RequestSize is 0, and TLS session status is EfiTlsSessionError, the TLS
+  session has errors and the response packet needs to be Alert message based on error
+  type.
+
+  @param[in]       This           Pointer to the EFI_TLS_PROTOCOL instance.
+  @param[in]       RequestBuffer  Pointer to the most recently received TLS packet. NULL
+                                  means TLS need initiate the TLS session and response
+                                  packet need to be ClientHello.
+  @param[in]       RequestSize    Packet size in bytes for the most recently received TLS
+                                  packet. 0 is only valid when RequestBuffer is NULL.
+  @param[out]      Buffer         Pointer to the buffer to hold the built packet.
+  @param[in, out]  BufferSize     Pointer to the buffer size in bytes. On input, it is
+                                  the buffer size provided by the caller. On output, it
+                                  is the buffer size in fact needed to contain the
+                                  packet.
+
+  @retval EFI_SUCCESS             The required TLS packet is built successfully.
+  @retval EFI_INVALID_PARAMETER   One or more of the following conditions is TRUE:
+                                  This is NULL.
+                                  RequestBuffer is NULL but RequestSize is NOT 0.
+                                  RequestSize is 0 but RequestBuffer is NOT NULL.
+                                  BufferSize is NULL.
+                                  Buffer is NULL if *BufferSize is not zero.
+  @retval EFI_BUFFER_TOO_SMALL    BufferSize is too small to hold the response packet.
+  @retval EFI_NOT_READY           Current TLS session state is NOT ready to build
+                                  ResponsePacket.
+  @retval EFI_ABORTED             Something wrong build response packet.
+**/
+EFI_STATUS
+EFIAPI
+TlsBuildResponsePacket (
+  IN     EFI_TLS_PROTOCOL              *This,
+  IN     UINT8                         *RequestBuffer, OPTIONAL
+  IN     UINTN                         RequestSize, OPTIONAL
+     OUT UINT8                         *Buffer, OPTIONAL
+  IN OUT UINTN                         *BufferSize
+  );
+
+/**
+  Decrypt or encrypt TLS packet during session. This function is only valid after
+  session connected and for application_data content type.
+
+  The ProcessPacket () function process each inbound or outbound TLS APP packet.
+
+  @param[in]       This           Pointer to the EFI_TLS_PROTOCOL instance.
+  @param[in, out]  FragmentTable  Pointer to a list of fragment. The caller will take
+                                  responsible to handle the original FragmentTable while
+                                  it may be reallocated in TLS driver. If CryptMode is
+                                  EfiTlsEncrypt, on input these fragments contain the TLS
+                                  header and plain text TLS APP payload; on output these
+                                  fragments contain the TLS header and cipher text TLS
+                                  APP payload. If CryptMode is EfiTlsDecrypt, on input
+                                  these fragments contain the TLS header and cipher text
+                                  TLS APP payload; on output these fragments contain the
+                                  TLS header and plain text TLS APP payload.
+  @param[in]       FragmentCount  Number of fragment.
+  @param[in]       CryptMode      Crypt mode.
+
+  @retval EFI_SUCCESS             The operation completed successfully.
+  @retval EFI_INVALID_PARAMETER   One or more of the following conditions is TRUE:
+                                  This is NULL.
+                                  FragmentTable is NULL.
+                                  FragmentCount is NULL.
+                                  CryptoMode is invalid.
+  @retval EFI_NOT_READY           Current TLS session state is NOT
+                                  EfiTlsSessionDataTransferring.
+  @retval EFI_ABORTED             Something wrong decryption the message. TLS session
+                                  status will become EfiTlsSessionError. The caller need
+                                  call BuildResponsePacket() to generate Error Alert
+                                  message and send it out.
+  @retval EFI_OUT_OF_RESOURCES    No enough resource to finish the operation.
+**/
+EFI_STATUS
+EFIAPI
+TlsProcessPacket (
+  IN     EFI_TLS_PROTOCOL              *This,
+  IN OUT EFI_TLS_FRAGMENT_DATA         **FragmentTable,
+  IN     UINT32                        *FragmentCount,
+  IN     EFI_TLS_CRYPT_MODE            CryptMode
+  );
+
+/**
+  Set TLS configuration data.
+
+  The SetData() function sets TLS configuration to non-volatile storage or volatile
+  storage.
+
+  @param[in]  This                Pointer to the EFI_TLS_CONFIGURATION_PROTOCOL instance.
+  @param[in]  DataType            Configuration data type.
+  @param[in]  Data                Pointer to configuration data.
+  @param[in]  DataSize            Total size of configuration data.
+
+  @retval EFI_SUCCESS             The TLS configuration data is set successfully.
+  @retval EFI_INVALID_PARAMETER   One or more of the following conditions is TRUE:
+                                  This is NULL.
+                                  Data is NULL.
+                                  DataSize is 0.
+  @retval EFI_UNSUPPORTED         The DataType is unsupported.
+  @retval EFI_OUT_OF_RESOURCES    Required system resources could not be allocated.
+**/
+EFI_STATUS
+EFIAPI
+TlsConfigurationSetData (
+  IN     EFI_TLS_CONFIGURATION_PROTOCOL  *This,
+  IN     EFI_TLS_CONFIG_DATA_TYPE        DataType,
+  IN     VOID                            *Data,
+  IN     UINTN                           DataSize
+  );
+
+/**
+  Get TLS configuration data.
+
+  The GetData() function gets TLS configuration.
+
+  @param[in]       This           Pointer to the EFI_TLS_CONFIGURATION_PROTOCOL instance.
+  @param[in]       DataType       Configuration data type.
+  @param[in, out]  Data           Pointer to configuration data.
+  @param[in, out]  DataSize       Total size of configuration data. On input, it means
+                                  the size of Data buffer. On output, it means the size
+                                  of copied Data buffer if EFI_SUCCESS, and means the
+                                  size of desired Data buffer if EFI_BUFFER_TOO_SMALL.
+
+  @retval EFI_SUCCESS             The TLS configuration data is got successfully.
+  @retval EFI_INVALID_PARAMETER   One or more of the following conditions is TRUE:
+                                  This is NULL.
+                                  DataSize is NULL.
+                                  Data is NULL if *DataSize is not zero.
+  @retval EFI_UNSUPPORTED         The DataType is unsupported.
+  @retval EFI_NOT_FOUND           The TLS configuration data is not found.
+  @retval EFI_BUFFER_TOO_SMALL    The buffer is too small to hold the data.
+**/
+EFI_STATUS
+EFIAPI
+TlsConfigurationGetData (
+  IN     EFI_TLS_CONFIGURATION_PROTOCOL  *This,
+  IN     EFI_TLS_CONFIG_DATA_TYPE        DataType,
+  IN OUT VOID                            *Data, OPTIONAL
+  IN OUT UINTN                           *DataSize
+  );
+
+#endif
diff --git a/NetworkPkg/TlsDxe/TlsProtocol.c b/NetworkPkg/TlsDxe/TlsProtocol.c
new file mode 100644
index 0000000..bc617e1
--- /dev/null
+++ b/NetworkPkg/TlsDxe/TlsProtocol.c
@@ -0,0 +1,632 @@
+/** @file
+  Implementation of EFI TLS Protocol Interfaces.
+
+  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 "TlsImpl.h"
+
+EFI_TLS_PROTOCOL  mTlsProtocol = {
+  TlsSetSessionData,
+  TlsGetSessionData,
+  TlsBuildResponsePacket,
+  TlsProcessPacket
+};
+
+/**
+  Set TLS session data.
+
+  The SetSessionData() function set data for a new TLS session. All session data should
+  be set before BuildResponsePacket() invoked.
+
+  @param[in]  This                Pointer to the EFI_TLS_PROTOCOL instance.
+  @param[in]  DataType            TLS session data type.
+  @param[in]  Data                Pointer to session data.
+  @param[in]  DataSize            Total size of session data.
+
+  @retval EFI_SUCCESS             The TLS session data is set successfully.
+  @retval EFI_INVALID_PARAMETER   One or more of the following conditions is TRUE:
+                                  This is NULL.
+                                  Data is NULL.
+                                  DataSize is 0.
+  @retval EFI_UNSUPPORTED         The DataType is unsupported.
+  @retval EFI_ACCESS_DENIED       If the DataType is one of below:
+                                  EfiTlsClientRandom
+                                  EfiTlsServerRandom
+                                  EfiTlsKeyMaterial
+  @retval EFI_NOT_READY           Current TLS session state is NOT
+                                  EfiTlsSessionStateNotStarted.
+  @retval EFI_OUT_OF_RESOURCES    Required system resources could not be allocated.
+**/
+EFI_STATUS
+EFIAPI
+TlsSetSessionData (
+  IN     EFI_TLS_PROTOCOL              *This,
+  IN     EFI_TLS_SESSION_DATA_TYPE     DataType,
+  IN     VOID                          *Data,
+  IN     UINTN                         DataSize
+  )
+{
+  EFI_STATUS                Status;
+  TLS_INSTANCE              *Instance;
+  UINT16                    *CipherId;
+  UINTN                     Index;
+
+  EFI_TPL                   OldTpl;
+
+  Status = EFI_SUCCESS;
+  CipherId = NULL;
+
+  if (This == NULL || Data == NULL || DataSize == 0) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+  Instance = TLS_INSTANCE_FROM_PROTOCOL_THIS (This);
+
+  if (DataType != EfiTlsSessionState  && Instance->TlsSessionState != EfiTlsSessionNotStarted){
+    Status = EFI_NOT_READY;
+    goto ON_EXIT;
+  }
+
+  switch (DataType) {
+  //
+  // Session Configuration
+  //
+  case EfiTlsVersion:
+    if (DataSize != sizeof (EFI_TLS_VERSION)) {
+      Status = EFI_INVALID_PARAMETER;
+      goto ON_EXIT;
+    }
+
+    Status = TlsSetVersion (Instance->TlsConn, ((EFI_TLS_VERSION *) Data)->Major, ((EFI_TLS_VERSION *) Data)->Minor);
+    break;
+  case EfiTlsConnectionEnd:
+    if (DataSize != sizeof (EFI_TLS_CONNECTION_END)) {
+      Status = EFI_INVALID_PARAMETER;
+      goto ON_EXIT;
+    }
+
+    Status = TlsSetConnectionEnd (Instance->TlsConn, *((EFI_TLS_CONNECTION_END *) Data));
+    break;
+  case EfiTlsCipherList:
+    CipherId = AllocatePool (DataSize);
+    if (CipherId == NULL) {
+      Status = EFI_OUT_OF_RESOURCES;
+      goto ON_EXIT;
+    }
+
+    for (Index = 0; Index < DataSize / sizeof (EFI_TLS_CIPHER); Index++) {
+      *(CipherId +Index) = HTONS (*(((UINT16 *) Data) + Index));
+    }
+
+    Status = TlsSetCipherList (Instance->TlsConn, CipherId, DataSize / sizeof (EFI_TLS_CIPHER));
+
+    FreePool (CipherId);
+    break;
+  case EfiTlsCompressionMethod:
+    //
+    // TLS seems only define one CompressionMethod.null, which specifies that data exchanged via the
+    // record protocol will not be compressed.
+    // More information from OpenSSL: http://www.openssl.org/docs/manmaster/ssl/SSL_COMP_add_compression_method.html
+    // The TLS RFC does however not specify compression methods or their corresponding identifiers,
+    // so there is currently no compatible way to integrate compression with unknown peers.
+    // It is therefore currently not recommended to integrate compression into applications.
+    // Applications for non-public use may agree on certain compression methods.
+    // Using different compression methods with the same identifier will lead to connection failure.
+    //
+    for (Index = 0; Index < DataSize / sizeof (EFI_TLS_COMPRESSION); Index++) {
+      Status = TlsSetCompressionMethod (*((UINT8 *) Data + Index));
+      if (EFI_ERROR (Status)) {
+        break;
+      }
+    }
+
+    break;
+  case EfiTlsExtensionData:
+    Status = EFI_UNSUPPORTED;
+    goto ON_EXIT;
+  case EfiTlsVerifyMethod:
+    if (DataSize != sizeof (EFI_TLS_VERIFY)) {
+      Status = EFI_INVALID_PARAMETER;
+      goto ON_EXIT;
+    }
+
+    TlsSetVerify (Instance->TlsConn, *((UINT32 *) Data));
+    break;
+  case EfiTlsSessionID:
+    if (DataSize != sizeof (EFI_TLS_SESSION_ID)) {
+      Status = EFI_INVALID_PARAMETER;
+      goto ON_EXIT;
+    }
+
+    Status = TlsSetSessionId (
+               Instance->TlsConn,
+               ((EFI_TLS_SESSION_ID *) Data)->Data,
+               ((EFI_TLS_SESSION_ID *) Data)->Length
+               );
+    break;
+  case EfiTlsSessionState:
+    if (DataSize != sizeof (EFI_TLS_SESSION_STATE)) {
+      Status = EFI_INVALID_PARAMETER;
+      goto ON_EXIT;
+    }
+
+    Instance->TlsSessionState = *(EFI_TLS_SESSION_STATE *) Data;
+    break;
+  //
+  // Session information
+  //
+  case EfiTlsClientRandom:
+    Status = EFI_ACCESS_DENIED;
+    break;
+  case EfiTlsServerRandom:
+    Status = EFI_ACCESS_DENIED;
+    break;
+  case EfiTlsKeyMaterial:
+    Status = EFI_ACCESS_DENIED;
+    break;
+  //
+  // Unsupported type.
+  //
+  default:
+    Status = EFI_UNSUPPORTED;
+  }
+
+ON_EXIT:
+  gBS->RestoreTPL (OldTpl);
+  return Status;
+}
+
+/**
+  Get TLS session data.
+
+  The GetSessionData() function return the TLS session information.
+
+  @param[in]       This           Pointer to the EFI_TLS_PROTOCOL instance.
+  @param[in]       DataType       TLS session data type.
+  @param[in, out]  Data           Pointer to session data.
+  @param[in, out]  DataSize       Total size of session data. On input, it means
+                                  the size of Data buffer. On output, it means the size
+                                  of copied Data buffer if EFI_SUCCESS, and means the
+                                  size of desired Data buffer if EFI_BUFFER_TOO_SMALL.
+
+  @retval EFI_SUCCESS             The TLS session data is got successfully.
+  @retval EFI_INVALID_PARAMETER   One or more of the following conditions is TRUE:
+                                  This is NULL.
+                                  DataSize is NULL.
+                                  Data is NULL if *DataSize is not zero.
+  @retval EFI_UNSUPPORTED         The DataType is unsupported.
+  @retval EFI_NOT_FOUND           The TLS session data is not found.
+  @retval EFI_NOT_READY           The DataType is not ready in current session state.
+  @retval EFI_BUFFER_TOO_SMALL    The buffer is too small to hold the data.
+**/
+EFI_STATUS
+EFIAPI
+TlsGetSessionData (
+  IN     EFI_TLS_PROTOCOL              *This,
+  IN     EFI_TLS_SESSION_DATA_TYPE     DataType,
+  IN OUT VOID                          *Data,  OPTIONAL
+  IN OUT UINTN                         *DataSize
+  )
+{
+  EFI_STATUS                Status;
+  TLS_INSTANCE              *Instance;
+
+  EFI_TPL                   OldTpl;
+
+  Status = EFI_SUCCESS;
+
+  if (This == NULL || DataSize == NULL || (Data == NULL && *DataSize != 0)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+  Instance = TLS_INSTANCE_FROM_PROTOCOL_THIS (This);
+
+  if (Instance->TlsSessionState == EfiTlsSessionNotStarted &&
+    (DataType == EfiTlsSessionID || DataType == EfiTlsClientRandom ||
+    DataType == EfiTlsServerRandom || DataType == EfiTlsKeyMaterial)) {
+    Status = EFI_NOT_READY;
+    goto ON_EXIT;
+  }
+
+  switch (DataType) {
+  case EfiTlsVersion:
+    if (*DataSize < sizeof (EFI_TLS_VERSION)) {
+      *DataSize = sizeof (EFI_TLS_VERSION);
+      Status = EFI_BUFFER_TOO_SMALL;
+      goto ON_EXIT;
+    }
+    *DataSize = sizeof (EFI_TLS_VERSION);
+    *((UINT16 *) Data) = HTONS (TlsGetVersion (Instance->TlsConn));
+    break;
+  case EfiTlsConnectionEnd:
+    if (*DataSize < sizeof (EFI_TLS_CONNECTION_END)) {
+      *DataSize = sizeof (EFI_TLS_CONNECTION_END);
+      Status = EFI_BUFFER_TOO_SMALL;
+      goto ON_EXIT;
+    }
+    *DataSize = sizeof (EFI_TLS_CONNECTION_END);
+    *((UINT8 *) Data) = TlsGetConnectionEnd (Instance->TlsConn);
+    break;
+  case EfiTlsCipherList:
+    //
+    // Get the current session cipher suite.
+    //
+    if (*DataSize < sizeof (EFI_TLS_CIPHER)) {
+      *DataSize = sizeof (EFI_TLS_CIPHER);
+      Status = EFI_BUFFER_TOO_SMALL;
+      goto ON_EXIT;
+    }
+    *DataSize = sizeof(EFI_TLS_CIPHER);
+    Status = TlsGetCurrentCipher (Instance->TlsConn, (UINT16 *) Data);
+    *((UINT16 *) Data) = HTONS (*((UINT16 *) Data));
+    break;
+  case EfiTlsCompressionMethod:
+    //
+    // Get the current session compression method.
+    //
+    if (*DataSize < sizeof (EFI_TLS_COMPRESSION)) {
+      *DataSize = sizeof (EFI_TLS_COMPRESSION);
+      Status = EFI_BUFFER_TOO_SMALL;
+      goto ON_EXIT;
+    }
+    *DataSize = sizeof (EFI_TLS_COMPRESSION);
+    Status = TlsGetCurrentCompressionId (Instance->TlsConn, (UINT8 *) Data);
+    break;
+  case EfiTlsExtensionData:
+    Status = EFI_UNSUPPORTED;
+    goto ON_EXIT;
+  case EfiTlsVerifyMethod:
+    if (*DataSize < sizeof (EFI_TLS_VERIFY)) {
+      *DataSize = sizeof (EFI_TLS_VERIFY);
+      Status = EFI_BUFFER_TOO_SMALL;
+      goto ON_EXIT;
+    }
+    *DataSize = sizeof (EFI_TLS_VERIFY);
+    *((UINT32 *) Data) = TlsGetVerify (Instance->TlsConn);
+    break;
+  case EfiTlsSessionID:
+    if (*DataSize < sizeof (EFI_TLS_SESSION_ID)) {
+      *DataSize = sizeof (EFI_TLS_SESSION_ID);
+      Status = EFI_BUFFER_TOO_SMALL;
+      goto ON_EXIT;
+    }
+    *DataSize = sizeof (EFI_TLS_SESSION_ID);
+    Status = TlsGetSessionId (
+               Instance->TlsConn,
+               ((EFI_TLS_SESSION_ID *) Data)->Data,
+               &(((EFI_TLS_SESSION_ID *) Data)->Length)
+               );
+    break;
+  case EfiTlsSessionState:
+    if (*DataSize < sizeof (EFI_TLS_SESSION_STATE)) {
+      *DataSize = sizeof (EFI_TLS_SESSION_STATE);
+      Status = EFI_BUFFER_TOO_SMALL;
+      goto ON_EXIT;
+    }
+    *DataSize = sizeof (EFI_TLS_SESSION_STATE);
+    CopyMem (Data, &Instance->TlsSessionState, *DataSize);
+    break;
+  case EfiTlsClientRandom:
+    if (*DataSize < sizeof (EFI_TLS_RANDOM)) {
+      *DataSize = sizeof (EFI_TLS_RANDOM);
+      Status = EFI_BUFFER_TOO_SMALL;
+      goto ON_EXIT;
+    }
+    *DataSize = sizeof (EFI_TLS_RANDOM);
+    TlsGetClientRandom (Instance->TlsConn, (UINT8 *) Data);
+    break;
+  case EfiTlsServerRandom:
+    if (*DataSize < sizeof (EFI_TLS_RANDOM)) {
+      *DataSize = sizeof (EFI_TLS_RANDOM);
+      Status = EFI_BUFFER_TOO_SMALL;
+      goto ON_EXIT;
+    }
+    *DataSize = sizeof (EFI_TLS_RANDOM);
+    TlsGetServerRandom (Instance->TlsConn, (UINT8 *) Data);
+    break;
+  case EfiTlsKeyMaterial:
+    if (*DataSize < sizeof (EFI_TLS_MASTER_SECRET)) {
+      *DataSize = sizeof (EFI_TLS_MASTER_SECRET);
+      Status = EFI_BUFFER_TOO_SMALL;
+      goto ON_EXIT;
+    }
+    *DataSize = sizeof (EFI_TLS_MASTER_SECRET);
+    Status = TlsGetKeyMaterial (Instance->TlsConn, (UINT8 *) Data);
+    break;
+  //
+  // Unsupported type.
+  //
+  default:
+    Status = EFI_UNSUPPORTED;
+  }
+
+ON_EXIT:
+  gBS->RestoreTPL (OldTpl);
+  return Status;
+}
+
+/**
+  Build response packet according to TLS state machine. This function is only valid for
+  alert, handshake and change_cipher_spec content type.
+
+  The BuildResponsePacket() function builds TLS response packet in response to the TLS
+  request packet specified by RequestBuffer and RequestSize. If RequestBuffer is NULL and
+  RequestSize is 0, and TLS session status is EfiTlsSessionNotStarted, the TLS session
+  will be initiated and the response packet needs to be ClientHello. If RequestBuffer is
+  NULL and RequestSize is 0, and TLS session status is EfiTlsSessionClosing, the TLS
+  session will be closed and response packet needs to be CloseNotify. If RequestBuffer is
+  NULL and RequestSize is 0, and TLS session status is EfiTlsSessionError, the TLS
+  session has errors and the response packet needs to be Alert message based on error
+  type.
+
+  @param[in]       This           Pointer to the EFI_TLS_PROTOCOL instance.
+  @param[in]       RequestBuffer  Pointer to the most recently received TLS packet. NULL
+                                  means TLS need initiate the TLS session and response
+                                  packet need to be ClientHello.
+  @param[in]       RequestSize    Packet size in bytes for the most recently received TLS
+                                  packet. 0 is only valid when RequestBuffer is NULL.
+  @param[out]      Buffer         Pointer to the buffer to hold the built packet.
+  @param[in, out]  BufferSize     Pointer to the buffer size in bytes. On input, it is
+                                  the buffer size provided by the caller. On output, it
+                                  is the buffer size in fact needed to contain the
+                                  packet.
+
+  @retval EFI_SUCCESS             The required TLS packet is built successfully.
+  @retval EFI_INVALID_PARAMETER   One or more of the following conditions is TRUE:
+                                  This is NULL.
+                                  RequestBuffer is NULL but RequestSize is NOT 0.
+                                  RequestSize is 0 but RequestBuffer is NOT NULL.
+                                  BufferSize is NULL.
+                                  Buffer is NULL if *BufferSize is not zero.
+  @retval EFI_BUFFER_TOO_SMALL    BufferSize is too small to hold the response packet.
+  @retval EFI_NOT_READY           Current TLS session state is NOT ready to build
+                                  ResponsePacket.
+  @retval EFI_ABORTED             Something wrong build response packet.
+**/
+EFI_STATUS
+EFIAPI
+TlsBuildResponsePacket (
+  IN     EFI_TLS_PROTOCOL              *This,
+  IN     UINT8                         *RequestBuffer, OPTIONAL
+  IN     UINTN                         RequestSize, OPTIONAL
+     OUT UINT8                         *Buffer, OPTIONAL
+  IN OUT UINTN                         *BufferSize
+  )
+{
+  EFI_STATUS                Status;
+  TLS_INSTANCE              *Instance;
+  EFI_TPL                   OldTpl;
+
+  Status = EFI_SUCCESS;
+
+  if ((This == NULL) || (BufferSize == NULL) ||
+      (RequestBuffer == NULL && RequestSize != 0) ||
+      (RequestBuffer != NULL && RequestSize == 0) ||
+      (Buffer == NULL && *BufferSize !=0)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+  Instance = TLS_INSTANCE_FROM_PROTOCOL_THIS (This);
+
+  if(RequestBuffer == NULL && RequestSize == 0) {
+    switch (Instance->TlsSessionState) {
+    case EfiTlsSessionNotStarted:
+      //
+      // ClientHello.
+      //
+      Status = TlsDoHandshake (
+                 Instance->TlsConn,
+                 NULL,
+                 0,
+                 Buffer,
+                 BufferSize
+                 );
+      if (EFI_ERROR (Status)) {
+        goto ON_EXIT;
+      }
+
+      //
+      // *BufferSize should not be zero when ClientHello.
+      //
+      if (*BufferSize == 0) {
+        Status = EFI_ABORTED;
+        goto ON_EXIT;
+      }
+
+      Instance->TlsSessionState = EfiTlsSessionHandShaking;
+
+      break;
+    case EfiTlsSessionClosing:
+      //
+      // TLS session will be closed and response packet needs to be CloseNotify.
+      //
+      Status = TlsCloseNotify (
+                 Instance->TlsConn,
+                 Buffer,
+                 BufferSize
+                 );
+      if (EFI_ERROR (Status)) {
+        goto ON_EXIT;
+      }
+
+      //
+      // *BufferSize should not be zero when build CloseNotify message.
+      //
+      if (*BufferSize == 0) {
+        Status = EFI_ABORTED;
+        goto ON_EXIT;
+      }
+
+      break;
+    case EfiTlsSessionError:
+      //
+      // TLS session has errors and the response packet needs to be Alert
+      // message based on error type.
+      //
+      Status = TlsHandeAlert (
+                 Instance->TlsConn,
+                 NULL,
+                 0,
+                 Buffer,
+                 BufferSize
+                 );
+      if (EFI_ERROR (Status)) {
+        goto ON_EXIT;
+      }
+
+      break;
+    default:
+      //
+      // Current TLS session state is NOT ready to build ResponsePacket.
+      //
+      Status = EFI_NOT_READY;
+    }
+  } else {
+    //
+    // 1. Received packet may have multiply TLS record messages.
+    // 2. One TLS record message may have multiply handshake protocol.
+    // 3. Some errors may be happened in handshake.
+    // TlsDoHandshake() can handle all of those cases.
+    //
+    if (TlsInHandshake (Instance->TlsConn)) {
+      Status = TlsDoHandshake (
+                 Instance->TlsConn,
+                 RequestBuffer,
+                 RequestSize,
+                 Buffer,
+                 BufferSize
+                 );
+      if (EFI_ERROR (Status)) {
+        goto ON_EXIT;
+      }
+
+      if (!TlsInHandshake (Instance->TlsConn)) {
+        Instance->TlsSessionState = EfiTlsSessionDataTransferring;
+      }
+    } else {
+      //
+      // Must be alert message, Decrypt it and build the ResponsePacket.
+      //
+      ASSERT (((TLS_RECORD_HEADER *) RequestBuffer)->ContentType == TLS_CONTENT_TYPE_ALERT);
+
+      Status = TlsHandeAlert (
+                 Instance->TlsConn,
+                 RequestBuffer,
+                 RequestSize,
+                 Buffer,
+                 BufferSize
+                 );
+      if (EFI_ERROR (Status)) {
+        if (Status != EFI_BUFFER_TOO_SMALL) {
+          Instance->TlsSessionState = EfiTlsSessionError;
+        }
+
+        goto ON_EXIT;
+      }
+    }
+  }
+
+ON_EXIT:
+  gBS->RestoreTPL (OldTpl);
+  return Status;
+}
+
+/**
+  Decrypt or encrypt TLS packet during session. This function is only valid after
+  session connected and for application_data content type.
+
+  The ProcessPacket () function process each inbound or outbound TLS APP packet.
+
+  @param[in]       This           Pointer to the EFI_TLS_PROTOCOL instance.
+  @param[in, out]  FragmentTable  Pointer to a list of fragment. The caller will take
+                                  responsible to handle the original FragmentTable while
+                                  it may be reallocated in TLS driver. If CryptMode is
+                                  EfiTlsEncrypt, on input these fragments contain the TLS
+                                  header and plain text TLS APP payload; on output these
+                                  fragments contain the TLS header and cipher text TLS
+                                  APP payload. If CryptMode is EfiTlsDecrypt, on input
+                                  these fragments contain the TLS header and cipher text
+                                  TLS APP payload; on output these fragments contain the
+                                  TLS header and plain text TLS APP payload.
+  @param[in]       FragmentCount  Number of fragment.
+  @param[in]       CryptMode      Crypt mode.
+
+  @retval EFI_SUCCESS             The operation completed successfully.
+  @retval EFI_INVALID_PARAMETER   One or more of the following conditions is TRUE:
+                                  This is NULL.
+                                  FragmentTable is NULL.
+                                  FragmentCount is NULL.
+                                  CryptoMode is invalid.
+  @retval EFI_NOT_READY           Current TLS session state is NOT
+                                  EfiTlsSessionDataTransferring.
+  @retval EFI_ABORTED             Something wrong decryption the message. TLS session
+                                  status will become EfiTlsSessionError. The caller need
+                                  call BuildResponsePacket() to generate Error Alert
+                                  message and send it out.
+  @retval EFI_OUT_OF_RESOURCES    No enough resource to finish the operation.
+**/
+EFI_STATUS
+EFIAPI
+TlsProcessPacket (
+  IN     EFI_TLS_PROTOCOL              *This,
+  IN OUT EFI_TLS_FRAGMENT_DATA         **FragmentTable,
+  IN     UINT32                        *FragmentCount,
+  IN     EFI_TLS_CRYPT_MODE            CryptMode
+  )
+{
+  EFI_STATUS                Status;
+  TLS_INSTANCE              *Instance;
+
+  EFI_TPL                   OldTpl;
+
+  Status = EFI_SUCCESS;
+
+  if (This == NULL || FragmentTable == NULL || FragmentCount == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+  Instance = TLS_INSTANCE_FROM_PROTOCOL_THIS (This);
+
+  if (Instance->TlsSessionState != EfiTlsSessionDataTransferring) {
+    Status = EFI_NOT_READY;
+    goto ON_EXIT;
+  }
+
+  //
+  // Packet sent or received may have multiply TLS record message(Application data type).
+  // So,on input these fragments contain the TLS header and TLS APP payload;
+  // on output these fragments also contain the TLS header and TLS APP payload.
+  //
+  switch (CryptMode) {
+  case EfiTlsEncrypt:
+    Status = TlsEcryptPacket (Instance, FragmentTable, FragmentCount);
+    break;
+  case EfiTlsDecrypt:
+    Status = TlsDecryptPacket (Instance, FragmentTable, FragmentCount);
+    break;
+  default:
+    return EFI_INVALID_PARAMETER;
+  }
+
+ON_EXIT:
+  gBS->RestoreTPL (OldTpl);
+  return Status;
+}
-- 
1.9.5.msysgit.1



^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH v2 05/10] NetworkPkg/TlsDxe: TlsDxe driver implementation over OpenSSL
  2016-12-15  7:22 [PATCH v2 05/10] NetworkPkg/TlsDxe: TlsDxe driver implementation over OpenSSL Jiaxin Wu
@ 2016-12-16  6:16 ` Ye, Ting
  2016-12-16  7:30   ` Wu, Jiaxin
  0 siblings, 1 reply; 3+ messages in thread
From: Ye, Ting @ 2016-12-16  6:16 UTC (permalink / raw)
  To: Wu, Jiaxin, edk2-devel@lists.01.org
  Cc: Fu, Siyuan, Zhang, Lubo, Long, Qin, Thomas Palmer

Hi Jiaxin,

Some comments included as below.

1. In TlsCreateService
     Line 325: ASSERT checks after assignment in line 323.  Should put ASSERT earlier. 
     'Status' looks useless.

2. TlsDriver.h
     I think the macros ' TLS_INSTANCE_FROM_PROTOCOL_THIS' and ' TLS_INSTANCE_FROM_CONFIGURATION_THIS' are hard to read. Maybe we could remove the '_THIS' postfix? 
     Please define appropriate names.

3. TlsImpl.c
    I think it's better to update TlsEcryptPacket to TlsEncryptPacket
    And also update "continue the other messages encryption\decryption." To "continue to encrypt/decrypt other messages."
	" The caller will take responsible to..." to " The caller will be responsible to... "
	"Received packet may have multiply TLS record message." To " Received packet may have multiple TLS record messages."
	Also update Multiply to multiple in other places.

   "Copy all TLS plain record header and payload to ProcessBuffer".  ProcessBuffer looks a local variable but not exist. May update to BufferIn? Please double check.

Others are good to me.

Reviewed-by: Ye Ting <ting.ye@intel.com> 

Thanks,
Ting

-----Original Message-----
From: Wu, Jiaxin 
Sent: Thursday, December 15, 2016 3:22 PM
To: edk2-devel@lists.01.org
Cc: Ye, Ting <ting.ye@intel.com>; Fu, Siyuan <siyuan.fu@intel.com>; Zhang, Lubo <lubo.zhang@intel.com>; Long, Qin <qin.long@intel.com>; Thomas Palmer <thomas.palmer@hpe.com>; Wu, Jiaxin <jiaxin.wu@intel.com>
Subject: [PATCH v2 05/10] NetworkPkg/TlsDxe: TlsDxe driver implementation over OpenSSL

v2:
* Refine the TlsEcryptPacket/TlsDecryptPacket function
according the community feedback.

This patch is the implementation of EFI TLS Service Binding
Protocol, EFI TLS Protocol and EFI TLS Configuration Protocol
Interfaces.

Cc: Ye Ting <ting.ye@intel.com>
Cc: Fu Siyuan <siyuan.fu@intel.com>
Cc: Zhang Lubo <lubo.zhang@intel.com>
Cc: Long Qin <qin.long@intel.com>
Cc: Thomas Palmer <thomas.palmer@hpe.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Wu Jiaxin <jiaxin.wu@intel.com>
---
 NetworkPkg/TlsDxe/TlsConfigProtocol.c | 152 ++++++++
 NetworkPkg/TlsDxe/TlsDriver.c         | 498 +++++++++++++++++++++++++++
 NetworkPkg/TlsDxe/TlsDriver.h         | 237 +++++++++++++
 NetworkPkg/TlsDxe/TlsDxe.inf          |  65 ++++
 NetworkPkg/TlsDxe/TlsDxe.uni          |  25 ++
 NetworkPkg/TlsDxe/TlsDxeExtra.uni     |  18 +
 NetworkPkg/TlsDxe/TlsImpl.c           | 326 ++++++++++++++++++
 NetworkPkg/TlsDxe/TlsImpl.h           | 315 +++++++++++++++++
 NetworkPkg/TlsDxe/TlsProtocol.c       | 632 ++++++++++++++++++++++++++++++++++
 9 files changed, 2268 insertions(+)
 create mode 100644 NetworkPkg/TlsDxe/TlsConfigProtocol.c
 create mode 100644 NetworkPkg/TlsDxe/TlsDriver.c
 create mode 100644 NetworkPkg/TlsDxe/TlsDriver.h
 create mode 100644 NetworkPkg/TlsDxe/TlsDxe.inf
 create mode 100644 NetworkPkg/TlsDxe/TlsDxe.uni
 create mode 100644 NetworkPkg/TlsDxe/TlsDxeExtra.uni
 create mode 100644 NetworkPkg/TlsDxe/TlsImpl.c
 create mode 100644 NetworkPkg/TlsDxe/TlsImpl.h
 create mode 100644 NetworkPkg/TlsDxe/TlsProtocol.c

diff --git a/NetworkPkg/TlsDxe/TlsConfigProtocol.c b/NetworkPkg/TlsDxe/TlsConfigProtocol.c
new file mode 100644
index 0000000..2ec79c9
--- /dev/null
+++ b/NetworkPkg/TlsDxe/TlsConfigProtocol.c
@@ -0,0 +1,152 @@
+/** @file
+  Implementation of EFI TLS Configuration Protocol Interfaces.
+
+  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 "TlsImpl.h"
+
+EFI_TLS_CONFIGURATION_PROTOCOL  mTlsConfigurationProtocol = {
+  TlsConfigurationSetData,
+  TlsConfigurationGetData
+};
+
+/**
+  Set TLS configuration data.
+
+  The SetData() function sets TLS configuration to non-volatile storage or volatile
+  storage.
+
+  @param[in]  This                Pointer to the EFI_TLS_CONFIGURATION_PROTOCOL instance.
+  @param[in]  DataType            Configuration data type.
+  @param[in]  Data                Pointer to configuration data.
+  @param[in]  DataSize            Total size of configuration data.
+
+  @retval EFI_SUCCESS             The TLS configuration data is set successfully.
+  @retval EFI_INVALID_PARAMETER   One or more of the following conditions is TRUE:
+                                  This is NULL.
+                                  Data is NULL.
+                                  DataSize is 0.
+  @retval EFI_UNSUPPORTED         The DataType is unsupported.
+  @retval EFI_OUT_OF_RESOURCES    Required system resources could not be allocated.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsConfigurationSetData (
+  IN     EFI_TLS_CONFIGURATION_PROTOCOL  *This,
+  IN     EFI_TLS_CONFIG_DATA_TYPE        DataType,
+  IN     VOID                            *Data,
+  IN     UINTN                           DataSize
+  )
+{
+  EFI_STATUS                Status;
+  TLS_INSTANCE              *Instance;
+  EFI_TPL                   OldTpl;
+
+  Status = EFI_SUCCESS;
+
+  if (This == NULL ||  Data == NULL || DataSize == 0) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+  Instance = TLS_INSTANCE_FROM_CONFIGURATION_THIS (This);
+
+  switch (DataType) {
+  case EfiTlsConfigDataTypeCACertificate:
+    Status = TlsSetCaCertificate (Instance->TlsConn, Data, DataSize);
+    break;
+  case EfiTlsConfigDataTypeHostPublicCert:
+    Status = TlsSetHostPublicCert (Instance->TlsConn, Data, DataSize);
+    break;
+  case EfiTlsConfigDataTypeHostPrivateKey:
+    Status = TlsSetHostPrivateKey (Instance->TlsConn, Data, DataSize);
+    break;
+  case EfiTlsConfigDataTypeCertRevocationList:
+    Status = TlsSetCertRevocationList (Data, DataSize);
+    break;
+  default:
+     Status = EFI_UNSUPPORTED;
+  }
+
+  gBS->RestoreTPL (OldTpl);
+  return Status;
+}
+
+/**
+  Get TLS configuration data.
+
+  The GetData() function gets TLS configuration.
+
+  @param[in]       This           Pointer to the EFI_TLS_CONFIGURATION_PROTOCOL instance.
+  @param[in]       DataType       Configuration data type.
+  @param[in, out]  Data           Pointer to configuration data.
+  @param[in, out]  DataSize       Total size of configuration data. On input, it means
+                                  the size of Data buffer. On output, it means the size
+                                  of copied Data buffer if EFI_SUCCESS, and means the
+                                  size of desired Data buffer if EFI_BUFFER_TOO_SMALL.
+
+  @retval EFI_SUCCESS             The TLS configuration data is got successfully.
+  @retval EFI_INVALID_PARAMETER   One or more of the following conditions is TRUE:
+                                  This is NULL.
+                                  DataSize is NULL.
+                                  Data is NULL if *DataSize is not zero.
+  @retval EFI_UNSUPPORTED         The DataType is unsupported.
+  @retval EFI_NOT_FOUND           The TLS configuration data is not found.
+  @retval EFI_BUFFER_TOO_SMALL    The buffer is too small to hold the data.
+**/
+EFI_STATUS
+EFIAPI
+TlsConfigurationGetData (
+  IN     EFI_TLS_CONFIGURATION_PROTOCOL  *This,
+  IN     EFI_TLS_CONFIG_DATA_TYPE        DataType,
+  IN OUT VOID                            *Data, OPTIONAL
+  IN OUT UINTN                           *DataSize
+  )
+{
+  EFI_STATUS                Status;
+  TLS_INSTANCE              *Instance;
+
+  EFI_TPL                   OldTpl;
+
+  Status = EFI_SUCCESS;
+
+  if (This == NULL || DataSize == NULL || (Data == NULL && *DataSize != 0)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+  Instance = TLS_INSTANCE_FROM_CONFIGURATION_THIS (This);
+
+  switch (DataType) {
+  case EfiTlsConfigDataTypeCACertificate:
+    Status = TlsGetCaCertificate (Instance->TlsConn, Data, DataSize);
+    break;
+  case EfiTlsConfigDataTypeHostPublicCert:
+    Status = TlsGetHostPublicCert (Instance->TlsConn, Data, DataSize);
+    break;
+  case EfiTlsConfigDataTypeHostPrivateKey:
+    Status = TlsGetHostPrivateKey (Instance->TlsConn, Data, DataSize);
+    break;
+  case EfiTlsConfigDataTypeCertRevocationList:
+    Status = TlsGetCertRevocationList (Data, DataSize);
+    break;
+  default:
+    Status = EFI_UNSUPPORTED;
+  }
+
+  gBS->RestoreTPL (OldTpl);
+  return Status;
+}
diff --git a/NetworkPkg/TlsDxe/TlsDriver.c b/NetworkPkg/TlsDxe/TlsDriver.c
new file mode 100644
index 0000000..0a75c39
--- /dev/null
+++ b/NetworkPkg/TlsDxe/TlsDriver.c
@@ -0,0 +1,498 @@
+/** @file
+  The Driver Binding and Service Binding Protocol for TlsDxe 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 "TlsImpl.h"
+
+EFI_SERVICE_BINDING_PROTOCOL mTlsServiceBinding = {
+  TlsServiceBindingCreateChild,
+  TlsServiceBindingDestroyChild
+};
+
+/**
+  Release all the resources used by the TLS instance.
+
+  @param[in]  Instance        The TLS instance data.
+
+**/
+VOID
+TlsCleanInstance (
+  IN TLS_INSTANCE           *Instance
+  )
+{
+  if (Instance != NULL) {
+    if (Instance->TlsConn != NULL) {
+      TlsFree (Instance->TlsConn);
+    }
+
+    FreePool (Instance);
+  }
+}
+
+/**
+  Create the TLS instance and initialize it.
+
+  @param[in]  Service              The pointer to the TLS service.
+  @param[out] Instance             The pointer to the TLS instance.
+
+  @retval EFI_OUT_OF_RESOURCES   Failed to allocate resources.
+  @retval EFI_SUCCESS            The TLS instance is created.
+
+**/
+EFI_STATUS
+TlsCreateInstance (
+  IN  TLS_SERVICE         *Service,
+  OUT TLS_INSTANCE        **Instance
+  )
+{
+  TLS_INSTANCE            *TlsInstance;
+
+  *Instance = NULL;
+
+  TlsInstance = AllocateZeroPool (sizeof (TLS_INSTANCE));
+  if (TlsInstance == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  TlsInstance->Signature = TLS_INSTANCE_SIGNATURE;
+  InitializeListHead (&TlsInstance->Link);
+  TlsInstance->InDestroy = FALSE;
+  TlsInstance->Service   = Service;
+
+  CopyMem (&TlsInstance->Tls, &mTlsProtocol, sizeof (TlsInstance->Tls));
+  CopyMem (&TlsInstance->TlsConfig, &mTlsConfigurationProtocol, sizeof (TlsInstance->TlsConfig));
+
+  TlsInstance->TlsSessionState = EfiTlsSessionNotStarted;
+
+  *Instance = TlsInstance;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Release all the resources used by the TLS service binding instance.
+
+  @param[in]  Service        The TLS service data.
+
+**/
+VOID
+TlsCleanService (
+  IN TLS_SERVICE     *Service
+  )
+{
+  if (Service != NULL) {
+    if (Service->TlsCtx != NULL) {
+      TlsCtxFree (Service->TlsCtx);
+    }
+
+    FreePool (Service);
+  }
+}
+
+/**
+  Create then initialize a TLS service.
+
+  @param[in]  Image                  ImageHandle of the TLS driver
+  @param[out] Service                The service for TLS driver
+
+  @retval EFI_OUT_OF_RESOURCES   Failed to allocate resource to create the service.
+  @retval EFI_SUCCESS            The service is created for the driver.
+
+**/
+EFI_STATUS
+TlsCreateService (
+  IN  EFI_HANDLE            Image,
+  OUT TLS_SERVICE           **Service
+  )
+{
+  EFI_STATUS             Status;
+  TLS_SERVICE            *TlsService;
+
+  Status = EFI_SUCCESS;
+  *Service = NULL;
+
+  ASSERT (Service != NULL);
+
+  //
+  // Allocate a TLS Service Data
+  //
+  TlsService = AllocateZeroPool (sizeof (TLS_SERVICE));
+  if (TlsService == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  //
+  // Initialize TLS Service Data
+  //
+  TlsService->Signature        = TLS_SERVICE_SIGNATURE;
+  CopyMem (&TlsService->ServiceBinding, &mTlsServiceBinding, sizeof (TlsService->ServiceBinding));
+  TlsService->TlsChildrenNum   = 0;
+  InitializeListHead (&TlsService->TlsChildrenList);
+  TlsService->ImageHandle      = Image;
+
+  *Service = TlsService;
+
+  return Status;
+}
+
+/**
+  Unloads an image.
+
+  @param[in]  ImageHandle           Handle that identifies the image to be unloaded.
+
+  @retval EFI_SUCCESS           The image has been unloaded.
+  @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsUnload (
+  IN EFI_HANDLE  ImageHandle
+  )
+{
+  EFI_STATUS                      Status;
+  UINTN                           HandleNum;
+  EFI_HANDLE                      *HandleBuffer;
+  UINT32                          Index;
+  EFI_SERVICE_BINDING_PROTOCOL    *ServiceBinding;
+  TLS_SERVICE                     *TlsService;
+
+  HandleBuffer   = NULL;
+  ServiceBinding = NULL;
+  TlsService     = NULL;
+
+  //
+  // Locate all the handles with Tls service binding protocol.
+  //
+  Status = gBS->LocateHandleBuffer (
+                  ByProtocol,
+                  &gEfiTlsServiceBindingProtocolGuid,
+                  NULL,
+                  &HandleNum,
+                  &HandleBuffer
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  for (Index = 0; Index < HandleNum; Index++) {
+    //
+    // Firstly, find ServiceBinding interface
+    //
+    Status = gBS->OpenProtocol (
+                    HandleBuffer[Index],
+                    &gEfiTlsServiceBindingProtocolGuid,
+                    (VOID **) &ServiceBinding,
+                    ImageHandle,
+                    NULL,
+                    EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
+                    );
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+
+    TlsService = TLS_SERVICE_FROM_THIS (ServiceBinding);
+
+    //
+    // Then, uninstall ServiceBinding interface
+    //
+    Status = gBS->UninstallMultipleProtocolInterfaces (
+                    HandleBuffer[Index],
+                    &gEfiTlsServiceBindingProtocolGuid, ServiceBinding,
+                    NULL
+                    );
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+
+    TlsCleanService (TlsService);
+  }
+
+  if (HandleBuffer != NULL) {
+    FreePool (HandleBuffer);
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This is the declaration of an EFI image entry point. This entry point is
+  the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
+  both device drivers and bus drivers.
+
+  @param  ImageHandle           The firmware allocated handle for the UEFI image.
+  @param  SystemTable           A pointer to the EFI System Table.
+
+  @retval EFI_SUCCESS           The operation completed successfully.
+  @retval Others                An unexpected error occurred.
+**/
+EFI_STATUS
+EFIAPI
+TlsDriverEntryPoint (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  EFI_STATUS             Status;
+
+  TLS_SERVICE            *TlsService;
+
+  //
+  // Create TLS Service
+  //
+  Status = TlsCreateService (ImageHandle, &TlsService);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  ASSERT (TlsService != NULL);
+
+  //
+  // Initializes the OpenSSL library.
+  //
+  TlsInitialize ();
+
+  //
+  // Create a new SSL_CTX object as framework to establish TLS/SSL enabled
+  // connections. TLS 1.0 is used as the default version.
+  //
+  TlsService->TlsCtx = TlsCtxNew (TLS10_PROTOCOL_VERSION_MAJOR, TLS10_PROTOCOL_VERSION_MINOR);
+  if (TlsService->TlsCtx == NULL) {
+    FreePool (TlsService);
+    return EFI_ABORTED;
+  }
+
+  //
+  // Install the TlsServiceBinding Protocol onto Handle
+  //
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &TlsService->Handle,
+                  &gEfiTlsServiceBindingProtocolGuid,
+                  &TlsService->ServiceBinding,
+                  NULL
+                  );
+  if (EFI_ERROR (Status)) {
+    goto ON_CLEAN_SERVICE;
+  }
+
+  return Status;
+
+ON_CLEAN_SERVICE:
+  TlsCleanService (TlsService);
+
+  return Status;
+}
+
+/**
+  Creates a child handle and installs a protocol.
+
+  The CreateChild() function installs a protocol on ChildHandle.
+  If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle.
+  If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle.
+
+  @param[in] This        Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
+  @param[in] ChildHandle Pointer to the handle of the child to create. If it is NULL,
+                         then a new handle is created. If it is a pointer to an existing UEFI handle,
+                         then the protocol is added to the existing UEFI handle.
+
+  @retval EFI_SUCCES            The protocol was added to ChildHandle.
+  @retval EFI_INVALID_PARAMETER ChildHandle is NULL.
+  @retval EFI_OUT_OF_RESOURCES  There are not enough resources available to create
+                                the child.
+  @retval other                 The child handle was not created.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsServiceBindingCreateChild (
+  IN EFI_SERVICE_BINDING_PROTOCOL  *This,
+  IN EFI_HANDLE                    *ChildHandle
+  )
+{
+  TLS_SERVICE         *TlsService;
+  TLS_INSTANCE        *TlsInstance;
+  EFI_STATUS           Status;
+  EFI_TPL              OldTpl;
+
+  if ((This == NULL) || (ChildHandle == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  TlsService = TLS_SERVICE_FROM_THIS (This);
+
+  Status = TlsCreateInstance (TlsService, &TlsInstance);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  ASSERT (TlsInstance != NULL);
+
+  //
+  // Create a new TLS connection object.
+  //
+  TlsInstance->TlsConn = TlsNew (TlsService->TlsCtx);
+  if (TlsInstance->TlsConn == NULL) {
+    Status = EFI_ABORTED;
+    goto ON_ERROR;
+  }
+
+  //
+  // Set default ConnectionEnd to EfiTlsClient
+  //
+  Status = TlsSetConnectionEnd (TlsInstance->TlsConn, EfiTlsClient);
+  if (EFI_ERROR (Status)) {
+    goto ON_ERROR;
+  }
+
+  //
+  // Install TLS protocol and configuration protocol onto ChildHandle
+  //
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  ChildHandle,
+                  &gEfiTlsProtocolGuid,
+                  &TlsInstance->Tls,
+                  &gEfiTlsConfigurationProtocolGuid,
+                  &TlsInstance->TlsConfig,
+                  NULL
+                  );
+  if (EFI_ERROR (Status)) {
+    goto ON_ERROR;
+  }
+
+  TlsInstance->ChildHandle = *ChildHandle;
+
+  //
+  // Add it to the TLS service's child list.
+  //
+  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+  InsertTailList (&TlsService->TlsChildrenList, &TlsInstance->Link);
+  TlsService->TlsChildrenNum++;
+
+  gBS->RestoreTPL (OldTpl);
+
+  return EFI_SUCCESS;
+
+ON_ERROR:
+  TlsCleanInstance (TlsInstance);
+  return Status;
+}
+
+/**
+  Destroys a child handle with a protocol installed on it.
+
+  The DestroyChild() function does the opposite of CreateChild(). It removes a protocol
+  that was installed by CreateChild() from ChildHandle. If the removed protocol is the
+  last protocol on ChildHandle, then ChildHandle is destroyed.
+
+  @param  This        Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
+  @param  ChildHandle Handle of the child to destroy.
+
+  @retval EFI_SUCCES            The protocol was removed from ChildHandle.
+  @retval EFI_UNSUPPORTED       ChildHandle does not support the protocol that is being removed.
+  @retval EFI_INVALID_PARAMETER Child handle is NULL.
+  @retval EFI_ACCESS_DENIED     The protocol could not be removed from the ChildHandle
+                                because its services are being used.
+  @retval other                 The child handle was not destroyed.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsServiceBindingDestroyChild (
+  IN EFI_SERVICE_BINDING_PROTOCOL  *This,
+  IN EFI_HANDLE                    ChildHandle
+  )
+{
+  TLS_SERVICE                    *TlsService;
+  TLS_INSTANCE                   *TlsInstance;
+
+  EFI_TLS_PROTOCOL               *Tls;
+  EFI_TLS_CONFIGURATION_PROTOCOL *TlsConfig;
+  EFI_STATUS                     Status;
+  EFI_TPL                        OldTpl;
+
+  if ((This == NULL) || (ChildHandle == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  TlsService = TLS_SERVICE_FROM_THIS (This);
+
+  //
+  // Find TLS protocol interface installed in ChildHandle
+  //
+  Status = gBS->OpenProtocol (
+                  ChildHandle,
+                  &gEfiTlsProtocolGuid,
+                  (VOID **) &Tls,
+                  TlsService->ImageHandle,
+                  NULL,
+                  EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Find TLS configuration protocol interface installed in ChildHandle
+  //
+  Status = gBS->OpenProtocol (
+                  ChildHandle,
+                  &gEfiTlsConfigurationProtocolGuid,
+                  (VOID **) &TlsConfig,
+                  TlsService->ImageHandle,
+                  NULL,
+                  EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  TlsInstance  = TLS_INSTANCE_FROM_PROTOCOL_THIS (Tls);
+
+  if (TlsInstance->Service != TlsService) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (TlsInstance->InDestroy) {
+    return EFI_SUCCESS;
+  }
+
+  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+  TlsInstance->InDestroy = TRUE;
+
+  //
+  // Uninstall the TLS protocol and TLS Configuration Protocol interface installed in ChildHandle.
+  //
+  Status = gBS->UninstallMultipleProtocolInterfaces (
+                  ChildHandle,
+                  &gEfiTlsProtocolGuid,
+                  Tls,
+                  &gEfiTlsConfigurationProtocolGuid,
+                  TlsConfig,
+                  NULL
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  RemoveEntryList (&TlsInstance->Link);
+  TlsService->TlsChildrenNum--;
+
+  gBS->RestoreTPL (OldTpl);
+
+  TlsCleanInstance (TlsInstance);
+
+  return EFI_SUCCESS;
+}
diff --git a/NetworkPkg/TlsDxe/TlsDriver.h b/NetworkPkg/TlsDxe/TlsDriver.h
new file mode 100644
index 0000000..c3c30a8
--- /dev/null
+++ b/NetworkPkg/TlsDxe/TlsDriver.h
@@ -0,0 +1,237 @@
+/** @file
+  Header file of the Driver Binding and Service Binding Protocol for TlsDxe 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_TLS_DRIVER_H__
+#define __EFI_TLS_DRIVER_H__
+
+#include <Uefi.h>
+
+//
+// Driver Protocols
+//
+#include <Protocol/ServiceBinding.h>
+
+//
+// Driver Version
+//
+#define TLS_VERSION  0x00000000
+
+#define TLS_SERVICE_SIGNATURE    SIGNATURE_32 ('T', 'L', 'S', 'S')
+
+#define TLS_INSTANCE_SIGNATURE   SIGNATURE_32 ('T', 'L', 'S', 'I')
+
+///
+/// TLS Service Data
+///
+typedef struct _TLS_SERVICE  TLS_SERVICE;
+
+///
+/// TLS Instance Data
+///
+typedef struct _TLS_INSTANCE TLS_INSTANCE;
+
+
+struct _TLS_SERVICE {
+  UINT32                          Signature;
+  EFI_SERVICE_BINDING_PROTOCOL    ServiceBinding;
+
+  UINT16                          TlsChildrenNum;
+  LIST_ENTRY                      TlsChildrenList;
+
+  //
+  // Handle to install TlsServiceBinding protocol.
+  //
+  EFI_HANDLE                      Handle;
+  EFI_HANDLE                      ImageHandle;
+
+  //
+  // Main SSL Context object which is created by a server or client once per program
+  // life-time and which holds mainly default values for the SSL object which are later
+  // created for the connections.
+  //
+  VOID                            *TlsCtx;
+};
+
+struct _TLS_INSTANCE {
+  UINT32                          Signature;
+  LIST_ENTRY                      Link;
+
+  BOOLEAN                         InDestroy;
+
+  TLS_SERVICE                     *Service;
+  EFI_HANDLE                      ChildHandle;
+
+  EFI_TLS_PROTOCOL                Tls;
+  EFI_TLS_CONFIGURATION_PROTOCOL  TlsConfig;
+
+  EFI_TLS_SESSION_STATE           TlsSessionState;
+
+  //
+  // Main SSL Connection which is created by a server or a client
+  // per established connection.
+  //
+  VOID                            *TlsConn;
+};
+
+
+#define TLS_SERVICE_FROM_THIS(a)   \
+  CR (a, TLS_SERVICE, ServiceBinding, TLS_SERVICE_SIGNATURE)
+
+#define TLS_INSTANCE_FROM_PROTOCOL_THIS(a)  \
+  CR (a, TLS_INSTANCE, Tls, TLS_INSTANCE_SIGNATURE)
+
+#define TLS_INSTANCE_FROM_CONFIGURATION_THIS(a)  \
+  CR (a, TLS_INSTANCE, TlsConfig, TLS_INSTANCE_SIGNATURE)
+
+
+/**
+  Release all the resources used by the TLS instance.
+
+  @param[in]  Instance        The TLS instance data.
+
+**/
+VOID
+TlsCleanInstance (
+  IN TLS_INSTANCE           *Instance
+  );
+
+/**
+  Create the TLS instance and initialize it.
+
+  @param[in]  Service              The pointer to the TLS service.
+  @param[out] Instance             The pointer to the TLS instance.
+
+  @retval EFI_OUT_OF_RESOURCES   Failed to allocate resources.
+  @retval EFI_SUCCESS            The TLS instance is created.
+
+**/
+EFI_STATUS
+TlsCreateInstance (
+  IN  TLS_SERVICE         *Service,
+  OUT TLS_INSTANCE        **Instance
+  );
+
+/**
+  Release all the resources used by the TLS service binding instance.
+
+  @param[in]  Service        The TLS service data.
+
+**/
+VOID
+TlsCleanService (
+  IN TLS_SERVICE     *Service
+  );
+
+/**
+  Create then initialize a TLS service.
+
+  @param[in]  Image                  ImageHandle of the TLS driver
+  @param[out] Service                The service for TLS driver
+
+  @retval EFI_OUT_OF_RESOURCES   Failed to allocate resource to create the service.
+  @retval EFI_SUCCESS            The service is created for the driver.
+
+**/
+EFI_STATUS
+TlsCreateService (
+  IN  EFI_HANDLE            Image,
+  OUT TLS_SERVICE           **Service
+  );
+
+/**
+  Unloads an image.
+
+  @param[in]  ImageHandle       Handle that identifies the image to be unloaded.
+
+  @retval EFI_SUCCESS           The image has been unloaded.
+  @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsUnload (
+  IN EFI_HANDLE  ImageHandle
+  );
+
+/**
+  This is the declaration of an EFI image entry point. This entry point is
+  the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
+  both device drivers and bus drivers.
+
+  @param  ImageHandle           The firmware allocated handle for the UEFI image.
+  @param  SystemTable           A pointer to the EFI System Table.
+
+  @retval EFI_SUCCESS           The operation completed successfully.
+  @retval Others                An unexpected error occurred.
+**/
+EFI_STATUS
+EFIAPI
+TlsDriverEntryPoint (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  );
+
+/**
+  Creates a child handle and installs a protocol.
+
+  The CreateChild() function installs a protocol on ChildHandle.
+  If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle.
+  If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle.
+
+  @param[in] This        Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
+  @param[in] ChildHandle Pointer to the handle of the child to create. If it is NULL,
+                         then a new handle is created. If it is a pointer to an existing UEFI handle,
+                         then the protocol is added to the existing UEFI handle.
+
+  @retval EFI_SUCCES            The protocol was added to ChildHandle.
+  @retval EFI_INVALID_PARAMETER ChildHandle is NULL.
+  @retval EFI_OUT_OF_RESOURCES  There are not enough resources available to create
+                                the child.
+  @retval other                 The child handle was not created.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsServiceBindingCreateChild (
+  IN EFI_SERVICE_BINDING_PROTOCOL  *This,
+  IN EFI_HANDLE                    *ChildHandle
+  );
+
+/**
+  Destroys a child handle with a protocol installed on it.
+
+  The DestroyChild() function does the opposite of CreateChild(). It removes a protocol
+  that was installed by CreateChild() from ChildHandle. If the removed protocol is the
+  last protocol on ChildHandle, then ChildHandle is destroyed.
+
+  @param  This        Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
+  @param  ChildHandle Handle of the child to destroy.
+
+  @retval EFI_SUCCES            The protocol was removed from ChildHandle.
+  @retval EFI_UNSUPPORTED       ChildHandle does not support the protocol that is being removed.
+  @retval EFI_INVALID_PARAMETER Child handle is NULL.
+  @retval EFI_ACCESS_DENIED     The protocol could not be removed from the ChildHandle
+                                because its services are being used.
+  @retval other                 The child handle was not destroyed.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsServiceBindingDestroyChild (
+  IN EFI_SERVICE_BINDING_PROTOCOL  *This,
+  IN EFI_HANDLE                    ChildHandle
+  );
+
+#endif
diff --git a/NetworkPkg/TlsDxe/TlsDxe.inf b/NetworkPkg/TlsDxe/TlsDxe.inf
new file mode 100644
index 0000000..dba3257
--- /dev/null
+++ b/NetworkPkg/TlsDxe/TlsDxe.inf
@@ -0,0 +1,65 @@
+## @file
+#  This module produces EFI TLS Protocol, EFI TLS Service Binding Protocol and
+#  EFI TLS Configuration Protocol.
+#
+#  This module produces EFI TLS (Transport Layer Security) Protocol and EFI TLS
+#  Service Binding Protocol, to provide TLS services.
+#
+#  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.
+#
+#
+##
+
+[Defines]
+  INF_VERSION               = 0x00010005
+  BASE_NAME                 = TlsDxe
+  FILE_GUID                 = 3aceb0c0-3c72-11e4-9a56-74d435052646
+  MODULE_TYPE               = UEFI_DRIVER
+  VERSION_STRING            = 1.0
+  ENTRY_POINT               = TlsDriverEntryPoint
+  UNLOAD_IMAGE              = TlsUnload
+  MODULE_UNI_FILE           = TlsDxe.uni
+
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  CryptoPkg/CryptoPkg.dec
+
+[Sources]
+  TlsDriver.h
+  TlsDriver.c
+  TlsProtocol.c
+  TlsConfigProtocol.c
+  TlsImpl.h
+  TlsImpl.c
+
+[LibraryClasses]
+  UefiDriverEntryPoint
+  UefiBootServicesTableLib
+  MemoryAllocationLib
+  BaseMemoryLib
+  BaseLib
+  UefiLib
+  DebugLib
+  NetLib
+  BaseCryptLib
+  TlsLib
+
+[Protocols]
+  gEfiTlsServiceBindingProtocolGuid          ## PRODUCES
+  gEfiTlsProtocolGuid                        ## PRODUCES
+  gEfiTlsConfigurationProtocolGuid           ## PRODUCES
+
+[UserExtensions.TianoCore."ExtraFiles"]
+  TlsDxeExtra.uni
diff --git a/NetworkPkg/TlsDxe/TlsDxe.uni b/NetworkPkg/TlsDxe/TlsDxe.uni
new file mode 100644
index 0000000..98c41ca
--- /dev/null
+++ b/NetworkPkg/TlsDxe/TlsDxe.uni
@@ -0,0 +1,25 @@
+// /** @file
+// This module produces EFI TLS Protocol, EFI TLS Service Binding Protocol and
+// EFI TLS Configuration Protocol.
+//
+// This module produces EFI TLS (Transport Layer Security) Protocol, EFI TLS
+// Service Binding Protocol, and EFI TLS Configuration Protocol to provide TLS
+// services.
+//
+// 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.
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT             #language en-US "UEFI TLS service"
+
+#string STR_MODULE_DESCRIPTION          #language en-US "This module produces EFI TLS Protocol, EFI TLS Service Binding Protocol and EFI TLS Configuration Protocol to provide EFI TLS services."
+
diff --git a/NetworkPkg/TlsDxe/TlsDxeExtra.uni b/NetworkPkg/TlsDxe/TlsDxeExtra.uni
new file mode 100644
index 0000000..a38582a
--- /dev/null
+++ b/NetworkPkg/TlsDxe/TlsDxeExtra.uni
@@ -0,0 +1,18 @@
+// /** @file
+// TlsDxe Localized Strings and Content
+//
+// 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.
+//
+// **/
+
+#string STR_PROPERTIES_MODULE_NAME
+#language en-US
+"EFI TLS DXE Driver"
diff --git a/NetworkPkg/TlsDxe/TlsImpl.c b/NetworkPkg/TlsDxe/TlsImpl.c
new file mode 100644
index 0000000..9b7bf7d
--- /dev/null
+++ b/NetworkPkg/TlsDxe/TlsImpl.c
@@ -0,0 +1,326 @@
+/** @file
+  The Miscellaneous Routines for TlsDxe 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 "TlsImpl.h"
+
+/**
+  Encrypt the message listed in fragment.
+
+  @param[in]       TlsInstance    The pointer to the TLS instance.
+  @param[in, out]  FragmentTable  Pointer to a list of fragment.
+                                  On input these fragments contain the TLS header and
+                                  plain text TLS payload;
+                                  On output these fragments contain the TLS header and
+                                  cipher text TLS payload.
+  @param[in]       FragmentCount  Number of fragment.
+
+  @retval EFI_SUCCESS             The operation completed successfully.
+  @retval EFI_OUT_OF_RESOURCES    Can't allocate memory resources.
+  @retval EFI_ABORTED             TLS session state is incorrect.
+  @retval Others                  Other errors as indicated.
+**/
+EFI_STATUS
+TlsEcryptPacket (
+  IN     TLS_INSTANCE                  *TlsInstance,
+  IN OUT EFI_TLS_FRAGMENT_DATA         **FragmentTable,
+  IN     UINT32                        *FragmentCount
+  )
+{
+  EFI_STATUS          Status;
+  UINTN               Index;
+  UINT32              BytesCopied;
+  UINT32              BufferInSize;
+  UINT8               *BufferIn;
+  UINT8               *BufferInPtr;
+  TLS_RECORD_HEADER   *RecordHeaderIn;
+  UINT16              ThisPlainMessageSize;
+  TLS_RECORD_HEADER   *TempRecordHeader;
+  UINT16              ThisMessageSize;
+  UINT32              BufferOutSize;
+  UINT8               *BufferOut;
+  INTN                Ret;
+  
+  Status           = EFI_SUCCESS;
+  BytesCopied      = 0;
+  BufferInSize     = 0;
+  BufferIn         = NULL;
+  BufferInPtr      = NULL;
+  RecordHeaderIn   = NULL;
+  TempRecordHeader = NULL;
+  BufferOutSize    = 0;
+  BufferOut        = NULL;
+  Ret              = 0;
+
+  //
+  // Calculate the size according to the fragment table.
+  //
+  for (Index = 0; Index < *FragmentCount; Index++) {
+    BufferInSize += (*FragmentTable)[Index].FragmentLength;
+  }
+
+  //
+  // Allocate buffer for processing data.
+  //
+  BufferIn = AllocateZeroPool (BufferInSize);
+  if (BufferIn == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto ERROR;
+  }
+
+  //
+  // Copy all TLS plain record header and payload into ProcessBuffer.
+  //
+  for (Index = 0; Index < *FragmentCount; Index++) {
+    CopyMem (
+      (BufferIn + BytesCopied),
+      (*FragmentTable)[Index].FragmentBuffer,
+      (*FragmentTable)[Index].FragmentLength
+      );
+    BytesCopied += (*FragmentTable)[Index].FragmentLength;
+  }
+
+  BufferOut = AllocateZeroPool (MAX_BUFFER_SIZE);
+  if (BufferOut == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto ERROR;
+  }
+
+  //
+  // Parsing buffer.
+  //
+  BufferInPtr = BufferIn;
+  TempRecordHeader = (TLS_RECORD_HEADER *) BufferOut;
+  while ((UINTN) BufferInPtr < (UINTN) BufferIn + BufferInSize) {
+    RecordHeaderIn = (TLS_RECORD_HEADER *) BufferInPtr;
+    
+    if (RecordHeaderIn->ContentType != TLS_CONTENT_TYPE_APPLICATION_DATA) {
+      Status = EFI_INVALID_PARAMETER;
+      goto ERROR;
+    }
+    
+    ThisPlainMessageSize = RecordHeaderIn->Length;
+
+    TlsWrite (TlsInstance->TlsConn, (UINT8 *) (RecordHeaderIn + 1), ThisPlainMessageSize);
+    
+    Ret = TlsCtrlTrafficOut (TlsInstance->TlsConn, (UINT8 *)(TempRecordHeader), MAX_BUFFER_SIZE - BufferOutSize);
+
+    if (Ret > 0) {
+      ThisMessageSize = (UINT16) Ret;
+    } else {
+      //
+      // No data was successfully encrypted, continue the other messages encryption.
+      //
+      DEBUG ((EFI_D_WARN, "TlsEcryptPacket: No data read from TLS object.\n"));
+    
+      ThisMessageSize = 0;
+    }
+
+    BufferOutSize += ThisMessageSize;
+
+    BufferInPtr += RECORD_HEADER_LEN + ThisPlainMessageSize;
+    TempRecordHeader += ThisMessageSize;
+  }
+
+  FreePool (BufferIn);
+  BufferIn = NULL;
+
+  //
+  // The caller will take responsible to handle the original fragment table.
+  //
+  *FragmentTable = AllocateZeroPool (sizeof (EFI_TLS_FRAGMENT_DATA));
+  if (*FragmentTable == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto ERROR;
+  }
+
+  (*FragmentTable)[0].FragmentBuffer  = BufferOut;
+  (*FragmentTable)[0].FragmentLength  = BufferOutSize;
+  *FragmentCount                      = 1;
+
+  return Status;
+
+ERROR:
+  
+  if (BufferIn != NULL) {
+    FreePool (BufferIn);
+    BufferIn = NULL;
+  }
+
+  if (BufferOut != NULL) {
+    FreePool (BufferOut);
+    BufferOut = NULL;
+  }
+  
+  return Status;
+}
+
+/**
+  Decrypt the message listed in fragment.
+
+  @param[in]       TlsInstance    The pointer to the TLS instance.
+  @param[in, out]  FragmentTable  Pointer to a list of fragment.
+                                  On input these fragments contain the TLS header and
+                                  cipher text TLS payload;
+                                  On output these fragments contain the TLS header and
+                                  plain text TLS payload.
+  @param[in]       FragmentCount  Number of fragment.
+
+  @retval EFI_SUCCESS             The operation completed successfully.
+  @retval EFI_OUT_OF_RESOURCES    Can't allocate memory resources.
+  @retval EFI_ABORTED             TLS session state is incorrect.
+  @retval Others                  Other errors as indicated.
+**/
+EFI_STATUS
+TlsDecryptPacket (
+  IN     TLS_INSTANCE                  *TlsInstance,
+  IN OUT EFI_TLS_FRAGMENT_DATA         **FragmentTable,
+  IN     UINT32                        *FragmentCount
+  )
+{
+  EFI_STATUS          Status;
+  UINTN               Index;
+  UINT32              BytesCopied;
+  UINT8               *BufferIn;
+  UINT32              BufferInSize;
+  UINT8               *BufferInPtr;
+  TLS_RECORD_HEADER   *RecordHeaderIn;
+  UINT16              ThisCipherMessageSize;
+  TLS_RECORD_HEADER   *TempRecordHeader;
+  UINT16              ThisPlainMessageSize;
+  UINT8               *BufferOut;
+  UINT32              BufferOutSize;
+  INTN                Ret;
+
+  Status           = EFI_SUCCESS;
+  BytesCopied      = 0;
+  BufferIn         = NULL;
+  BufferInSize     = 0;
+  BufferInPtr      = NULL;
+  RecordHeaderIn   = NULL;
+  TempRecordHeader = NULL;
+  BufferOut        = NULL;
+  BufferOutSize    = 0;
+  Ret              = 0;
+
+  //
+  // Calculate the size according to the fragment table.
+  //
+  for (Index = 0; Index < *FragmentCount; Index++) {
+    BufferInSize += (*FragmentTable)[Index].FragmentLength;
+  }
+
+  //
+  // Allocate buffer for processing data
+  //
+  BufferIn = AllocateZeroPool (BufferInSize);
+  if (BufferIn == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto ERROR;
+  }
+
+  //
+  // Copy all TLS plain record header and payload to ProcessBuffer
+  //
+  for (Index = 0; Index < *FragmentCount; Index++) {
+    CopyMem (
+      (BufferIn + BytesCopied),
+      (*FragmentTable)[Index].FragmentBuffer,
+      (*FragmentTable)[Index].FragmentLength
+      );
+    BytesCopied += (*FragmentTable)[Index].FragmentLength;
+  }
+
+  BufferOut = AllocateZeroPool (MAX_BUFFER_SIZE);
+  if (BufferOut == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto ERROR;
+  }
+
+  //
+  // Parsing buffer. Received packet may have multiply TLS record message.
+  //
+  BufferInPtr = BufferIn;
+  TempRecordHeader = (TLS_RECORD_HEADER *) BufferOut;
+  while ((UINTN) BufferInPtr < (UINTN) BufferIn + BufferInSize) {
+    RecordHeaderIn = (TLS_RECORD_HEADER *) BufferInPtr;
+
+    if (RecordHeaderIn->ContentType != TLS_CONTENT_TYPE_APPLICATION_DATA) {
+      Status = EFI_INVALID_PARAMETER;
+      goto ERROR;
+    }
+    
+    ThisCipherMessageSize = NTOHS (RecordHeaderIn->Length);
+
+    Ret = TlsCtrlTrafficIn (TlsInstance->TlsConn, (UINT8 *) (RecordHeaderIn), RECORD_HEADER_LEN + ThisCipherMessageSize);
+    if (Ret != RECORD_HEADER_LEN + ThisCipherMessageSize) {
+      TlsInstance->TlsSessionState = EfiTlsSessionError;
+      Status = EFI_ABORTED;
+      goto ERROR;
+    }
+
+    Ret = 0;
+    Ret = TlsRead (TlsInstance->TlsConn, (UINT8 *) (TempRecordHeader + 1), MAX_BUFFER_SIZE - BufferOutSize);
+
+    if (Ret > 0) {
+      ThisPlainMessageSize = (UINT16) Ret;
+    } else {
+      //
+      // No data was successfully decrypted, continue the other messages decryption.
+      //
+      DEBUG ((EFI_D_WARN, "TlsDecryptPacket: No data read from TLS object.\n"));
+    
+      ThisPlainMessageSize = 0;
+    }
+
+    CopyMem (TempRecordHeader, RecordHeaderIn, RECORD_HEADER_LEN);
+    TempRecordHeader->Length = ThisPlainMessageSize;
+    BufferOutSize += RECORD_HEADER_LEN + ThisPlainMessageSize;
+
+    BufferInPtr += RECORD_HEADER_LEN + ThisCipherMessageSize;
+    TempRecordHeader += RECORD_HEADER_LEN + ThisPlainMessageSize;
+  }
+
+  FreePool (BufferIn);
+  BufferIn = NULL;
+
+  //
+  // The caller will take responsible to handle the original fragment table
+  //
+  *FragmentTable = AllocateZeroPool (sizeof (EFI_TLS_FRAGMENT_DATA));
+  if (*FragmentTable == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto ERROR;
+  }
+
+  (*FragmentTable)[0].FragmentBuffer  = BufferOut;
+  (*FragmentTable)[0].FragmentLength  = BufferOutSize;
+  *FragmentCount                      = 1;
+
+  return Status;
+
+ERROR:
+  
+  if (BufferIn != NULL) {
+    FreePool (BufferIn);
+    BufferIn = NULL;
+  }
+
+  if (BufferOut != NULL) {
+    FreePool (BufferOut);
+    BufferOut = NULL;
+  }
+  
+  return Status;  
+}
diff --git a/NetworkPkg/TlsDxe/TlsImpl.h b/NetworkPkg/TlsDxe/TlsImpl.h
new file mode 100644
index 0000000..b0615cb
--- /dev/null
+++ b/NetworkPkg/TlsDxe/TlsImpl.h
@@ -0,0 +1,315 @@
+/** @file
+  Header file of Miscellaneous Routines for TlsDxe 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_TLS_IMPL_H__
+#define __EFI_TLS_IMPL_H__
+
+//
+// Libraries
+//
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/BaseLib.h>
+#include <Library/UefiLib.h>
+#include <Library/DebugLib.h>
+#include <Library/NetLib.h>
+#include <Library/BaseCryptLib.h>
+#include <Library/TlsLib.h>
+
+//
+// Consumed Protocols
+//
+#include <Protocol/Tls.h>
+#include <Protocol/TlsConfig.h>
+
+#include <IndustryStandard/Tls1.h>
+
+#include "TlsDriver.h"
+
+//
+// Protocol instances
+//
+extern EFI_SERVICE_BINDING_PROTOCOL    mTlsServiceBinding;
+extern EFI_TLS_PROTOCOL                mTlsProtocol;
+extern EFI_TLS_CONFIGURATION_PROTOCOL  mTlsConfigurationProtocol;
+
+#define RECORD_HEADER_LEN 5 /// ContentType(1) + Version(2) + Length(2)
+
+#define MAX_BUFFER_SIZE   32768
+
+/**
+  Encrypt the message listed in fragment.
+
+  @param[in]       TlsInstance    The pointer to the TLS instance.
+  @param[in, out]  FragmentTable  Pointer to a list of fragment.
+                                  On input these fragments contain the TLS header and
+                                  plain text TLS payload;
+                                  On output these fragments contain the TLS header and
+                                  cipher text TLS payload.
+  @param[in]       FragmentCount  Number of fragment.
+
+  @retval EFI_SUCCESS             The operation completed successfully.
+  @retval EFI_OUT_OF_RESOURCES    Can't allocate memory resources.
+  @retval EFI_ABORTED             TLS session state is incorrect.
+  @retval Others                  Other errors as indicated.
+**/
+EFI_STATUS
+TlsEcryptPacket (
+  IN     TLS_INSTANCE                  *TlsInstance,
+  IN OUT EFI_TLS_FRAGMENT_DATA         **FragmentTable,
+  IN     UINT32                        *FragmentCount
+  );
+
+/**
+  Decrypt the message listed in fragment.
+
+  @param[in]       TlsInstance    The pointer to the TLS instance.
+  @param[in, out]  FragmentTable  Pointer to a list of fragment.
+                                  On input these fragments contain the TLS header and
+                                  cipher text TLS payload;
+                                  On output these fragments contain the TLS header and
+                                  plain text TLS payload.
+  @param[in]       FragmentCount  Number of fragment.
+
+  @retval EFI_SUCCESS             The operation completed successfully.
+  @retval EFI_OUT_OF_RESOURCES    Can't allocate memory resources.
+  @retval EFI_ABORTED             TLS session state is incorrect.
+  @retval Others                  Other errors as indicated.
+**/
+EFI_STATUS
+TlsDecryptPacket (
+  IN     TLS_INSTANCE                  *TlsInstance,
+  IN OUT EFI_TLS_FRAGMENT_DATA         **FragmentTable,
+  IN     UINT32                        *FragmentCount
+  );
+
+/**
+  Set TLS session data.
+
+  The SetSessionData() function set data for a new TLS session. All session data should
+  be set before BuildResponsePacket() invoked.
+
+  @param[in]  This                Pointer to the EFI_TLS_PROTOCOL instance.
+  @param[in]  DataType            TLS session data type.
+  @param[in]  Data                Pointer to session data.
+  @param[in]  DataSize            Total size of session data.
+
+  @retval EFI_SUCCESS             The TLS session data is set successfully.
+  @retval EFI_INVALID_PARAMETER   One or more of the following conditions is TRUE:
+                                  This is NULL.
+                                  Data is NULL.
+                                  DataSize is 0.
+  @retval EFI_UNSUPPORTED         The DataType is unsupported.
+  @retval EFI_ACCESS_DENIED       If the DataType is one of below:
+                                  EfiTlsClientRandom
+                                  EfiTlsServerRandom
+                                  EfiTlsKeyMaterial
+  @retval EFI_NOT_READY           Current TLS session state is NOT
+                                  EfiTlsSessionStateNotStarted.
+  @retval EFI_OUT_OF_RESOURCES    Required system resources could not be allocated.
+**/
+EFI_STATUS
+EFIAPI
+TlsSetSessionData (
+  IN     EFI_TLS_PROTOCOL              *This,
+  IN     EFI_TLS_SESSION_DATA_TYPE     DataType,
+  IN     VOID                          *Data,
+  IN     UINTN                         DataSize
+  );
+
+/**
+  Get TLS session data.
+
+  The GetSessionData() function return the TLS session information.
+
+  @param[in]       This           Pointer to the EFI_TLS_PROTOCOL instance.
+  @param[in]       DataType       TLS session data type.
+  @param[in, out]  Data           Pointer to session data.
+  @param[in, out]  DataSize       Total size of session data. On input, it means
+                                  the size of Data buffer. On output, it means the size
+                                  of copied Data buffer if EFI_SUCCESS, and means the
+                                  size of desired Data buffer if EFI_BUFFER_TOO_SMALL.
+
+  @retval EFI_SUCCESS             The TLS session data is got successfully.
+  @retval EFI_INVALID_PARAMETER   One or more of the following conditions is TRUE:
+                                  This is NULL.
+                                  DataSize is NULL.
+                                  Data is NULL if *DataSize is not zero.
+  @retval EFI_UNSUPPORTED         The DataType is unsupported.
+  @retval EFI_NOT_FOUND           The TLS session data is not found.
+  @retval EFI_NOT_READY           The DataType is not ready in current session state.
+  @retval EFI_BUFFER_TOO_SMALL    The buffer is too small to hold the data.
+**/
+EFI_STATUS
+EFIAPI
+TlsGetSessionData (
+  IN     EFI_TLS_PROTOCOL              *This,
+  IN     EFI_TLS_SESSION_DATA_TYPE     DataType,
+  IN OUT VOID                          *Data,  OPTIONAL
+  IN OUT UINTN                         *DataSize
+  );
+
+/**
+  Build response packet according to TLS state machine. This function is only valid for
+  alert, handshake and change_cipher_spec content type.
+
+  The BuildResponsePacket() function builds TLS response packet in response to the TLS
+  request packet specified by RequestBuffer and RequestSize. If RequestBuffer is NULL and
+  RequestSize is 0, and TLS session status is EfiTlsSessionNotStarted, the TLS session
+  will be initiated and the response packet needs to be ClientHello. If RequestBuffer is
+  NULL and RequestSize is 0, and TLS session status is EfiTlsSessionClosing, the TLS
+  session will be closed and response packet needs to be CloseNotify. If RequestBuffer is
+  NULL and RequestSize is 0, and TLS session status is EfiTlsSessionError, the TLS
+  session has errors and the response packet needs to be Alert message based on error
+  type.
+
+  @param[in]       This           Pointer to the EFI_TLS_PROTOCOL instance.
+  @param[in]       RequestBuffer  Pointer to the most recently received TLS packet. NULL
+                                  means TLS need initiate the TLS session and response
+                                  packet need to be ClientHello.
+  @param[in]       RequestSize    Packet size in bytes for the most recently received TLS
+                                  packet. 0 is only valid when RequestBuffer is NULL.
+  @param[out]      Buffer         Pointer to the buffer to hold the built packet.
+  @param[in, out]  BufferSize     Pointer to the buffer size in bytes. On input, it is
+                                  the buffer size provided by the caller. On output, it
+                                  is the buffer size in fact needed to contain the
+                                  packet.
+
+  @retval EFI_SUCCESS             The required TLS packet is built successfully.
+  @retval EFI_INVALID_PARAMETER   One or more of the following conditions is TRUE:
+                                  This is NULL.
+                                  RequestBuffer is NULL but RequestSize is NOT 0.
+                                  RequestSize is 0 but RequestBuffer is NOT NULL.
+                                  BufferSize is NULL.
+                                  Buffer is NULL if *BufferSize is not zero.
+  @retval EFI_BUFFER_TOO_SMALL    BufferSize is too small to hold the response packet.
+  @retval EFI_NOT_READY           Current TLS session state is NOT ready to build
+                                  ResponsePacket.
+  @retval EFI_ABORTED             Something wrong build response packet.
+**/
+EFI_STATUS
+EFIAPI
+TlsBuildResponsePacket (
+  IN     EFI_TLS_PROTOCOL              *This,
+  IN     UINT8                         *RequestBuffer, OPTIONAL
+  IN     UINTN                         RequestSize, OPTIONAL
+     OUT UINT8                         *Buffer, OPTIONAL
+  IN OUT UINTN                         *BufferSize
+  );
+
+/**
+  Decrypt or encrypt TLS packet during session. This function is only valid after
+  session connected and for application_data content type.
+
+  The ProcessPacket () function process each inbound or outbound TLS APP packet.
+
+  @param[in]       This           Pointer to the EFI_TLS_PROTOCOL instance.
+  @param[in, out]  FragmentTable  Pointer to a list of fragment. The caller will take
+                                  responsible to handle the original FragmentTable while
+                                  it may be reallocated in TLS driver. If CryptMode is
+                                  EfiTlsEncrypt, on input these fragments contain the TLS
+                                  header and plain text TLS APP payload; on output these
+                                  fragments contain the TLS header and cipher text TLS
+                                  APP payload. If CryptMode is EfiTlsDecrypt, on input
+                                  these fragments contain the TLS header and cipher text
+                                  TLS APP payload; on output these fragments contain the
+                                  TLS header and plain text TLS APP payload.
+  @param[in]       FragmentCount  Number of fragment.
+  @param[in]       CryptMode      Crypt mode.
+
+  @retval EFI_SUCCESS             The operation completed successfully.
+  @retval EFI_INVALID_PARAMETER   One or more of the following conditions is TRUE:
+                                  This is NULL.
+                                  FragmentTable is NULL.
+                                  FragmentCount is NULL.
+                                  CryptoMode is invalid.
+  @retval EFI_NOT_READY           Current TLS session state is NOT
+                                  EfiTlsSessionDataTransferring.
+  @retval EFI_ABORTED             Something wrong decryption the message. TLS session
+                                  status will become EfiTlsSessionError. The caller need
+                                  call BuildResponsePacket() to generate Error Alert
+                                  message and send it out.
+  @retval EFI_OUT_OF_RESOURCES    No enough resource to finish the operation.
+**/
+EFI_STATUS
+EFIAPI
+TlsProcessPacket (
+  IN     EFI_TLS_PROTOCOL              *This,
+  IN OUT EFI_TLS_FRAGMENT_DATA         **FragmentTable,
+  IN     UINT32                        *FragmentCount,
+  IN     EFI_TLS_CRYPT_MODE            CryptMode
+  );
+
+/**
+  Set TLS configuration data.
+
+  The SetData() function sets TLS configuration to non-volatile storage or volatile
+  storage.
+
+  @param[in]  This                Pointer to the EFI_TLS_CONFIGURATION_PROTOCOL instance.
+  @param[in]  DataType            Configuration data type.
+  @param[in]  Data                Pointer to configuration data.
+  @param[in]  DataSize            Total size of configuration data.
+
+  @retval EFI_SUCCESS             The TLS configuration data is set successfully.
+  @retval EFI_INVALID_PARAMETER   One or more of the following conditions is TRUE:
+                                  This is NULL.
+                                  Data is NULL.
+                                  DataSize is 0.
+  @retval EFI_UNSUPPORTED         The DataType is unsupported.
+  @retval EFI_OUT_OF_RESOURCES    Required system resources could not be allocated.
+**/
+EFI_STATUS
+EFIAPI
+TlsConfigurationSetData (
+  IN     EFI_TLS_CONFIGURATION_PROTOCOL  *This,
+  IN     EFI_TLS_CONFIG_DATA_TYPE        DataType,
+  IN     VOID                            *Data,
+  IN     UINTN                           DataSize
+  );
+
+/**
+  Get TLS configuration data.
+
+  The GetData() function gets TLS configuration.
+
+  @param[in]       This           Pointer to the EFI_TLS_CONFIGURATION_PROTOCOL instance.
+  @param[in]       DataType       Configuration data type.
+  @param[in, out]  Data           Pointer to configuration data.
+  @param[in, out]  DataSize       Total size of configuration data. On input, it means
+                                  the size of Data buffer. On output, it means the size
+                                  of copied Data buffer if EFI_SUCCESS, and means the
+                                  size of desired Data buffer if EFI_BUFFER_TOO_SMALL.
+
+  @retval EFI_SUCCESS             The TLS configuration data is got successfully.
+  @retval EFI_INVALID_PARAMETER   One or more of the following conditions is TRUE:
+                                  This is NULL.
+                                  DataSize is NULL.
+                                  Data is NULL if *DataSize is not zero.
+  @retval EFI_UNSUPPORTED         The DataType is unsupported.
+  @retval EFI_NOT_FOUND           The TLS configuration data is not found.
+  @retval EFI_BUFFER_TOO_SMALL    The buffer is too small to hold the data.
+**/
+EFI_STATUS
+EFIAPI
+TlsConfigurationGetData (
+  IN     EFI_TLS_CONFIGURATION_PROTOCOL  *This,
+  IN     EFI_TLS_CONFIG_DATA_TYPE        DataType,
+  IN OUT VOID                            *Data, OPTIONAL
+  IN OUT UINTN                           *DataSize
+  );
+
+#endif
diff --git a/NetworkPkg/TlsDxe/TlsProtocol.c b/NetworkPkg/TlsDxe/TlsProtocol.c
new file mode 100644
index 0000000..bc617e1
--- /dev/null
+++ b/NetworkPkg/TlsDxe/TlsProtocol.c
@@ -0,0 +1,632 @@
+/** @file
+  Implementation of EFI TLS Protocol Interfaces.
+
+  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 "TlsImpl.h"
+
+EFI_TLS_PROTOCOL  mTlsProtocol = {
+  TlsSetSessionData,
+  TlsGetSessionData,
+  TlsBuildResponsePacket,
+  TlsProcessPacket
+};
+
+/**
+  Set TLS session data.
+
+  The SetSessionData() function set data for a new TLS session. All session data should
+  be set before BuildResponsePacket() invoked.
+
+  @param[in]  This                Pointer to the EFI_TLS_PROTOCOL instance.
+  @param[in]  DataType            TLS session data type.
+  @param[in]  Data                Pointer to session data.
+  @param[in]  DataSize            Total size of session data.
+
+  @retval EFI_SUCCESS             The TLS session data is set successfully.
+  @retval EFI_INVALID_PARAMETER   One or more of the following conditions is TRUE:
+                                  This is NULL.
+                                  Data is NULL.
+                                  DataSize is 0.
+  @retval EFI_UNSUPPORTED         The DataType is unsupported.
+  @retval EFI_ACCESS_DENIED       If the DataType is one of below:
+                                  EfiTlsClientRandom
+                                  EfiTlsServerRandom
+                                  EfiTlsKeyMaterial
+  @retval EFI_NOT_READY           Current TLS session state is NOT
+                                  EfiTlsSessionStateNotStarted.
+  @retval EFI_OUT_OF_RESOURCES    Required system resources could not be allocated.
+**/
+EFI_STATUS
+EFIAPI
+TlsSetSessionData (
+  IN     EFI_TLS_PROTOCOL              *This,
+  IN     EFI_TLS_SESSION_DATA_TYPE     DataType,
+  IN     VOID                          *Data,
+  IN     UINTN                         DataSize
+  )
+{
+  EFI_STATUS                Status;
+  TLS_INSTANCE              *Instance;
+  UINT16                    *CipherId;
+  UINTN                     Index;
+
+  EFI_TPL                   OldTpl;
+
+  Status = EFI_SUCCESS;
+  CipherId = NULL;
+
+  if (This == NULL || Data == NULL || DataSize == 0) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+  Instance = TLS_INSTANCE_FROM_PROTOCOL_THIS (This);
+
+  if (DataType != EfiTlsSessionState  && Instance->TlsSessionState != EfiTlsSessionNotStarted){
+    Status = EFI_NOT_READY;
+    goto ON_EXIT;
+  }
+
+  switch (DataType) {
+  //
+  // Session Configuration
+  //
+  case EfiTlsVersion:
+    if (DataSize != sizeof (EFI_TLS_VERSION)) {
+      Status = EFI_INVALID_PARAMETER;
+      goto ON_EXIT;
+    }
+
+    Status = TlsSetVersion (Instance->TlsConn, ((EFI_TLS_VERSION *) Data)->Major, ((EFI_TLS_VERSION *) Data)->Minor);
+    break;
+  case EfiTlsConnectionEnd:
+    if (DataSize != sizeof (EFI_TLS_CONNECTION_END)) {
+      Status = EFI_INVALID_PARAMETER;
+      goto ON_EXIT;
+    }
+
+    Status = TlsSetConnectionEnd (Instance->TlsConn, *((EFI_TLS_CONNECTION_END *) Data));
+    break;
+  case EfiTlsCipherList:
+    CipherId = AllocatePool (DataSize);
+    if (CipherId == NULL) {
+      Status = EFI_OUT_OF_RESOURCES;
+      goto ON_EXIT;
+    }
+
+    for (Index = 0; Index < DataSize / sizeof (EFI_TLS_CIPHER); Index++) {
+      *(CipherId +Index) = HTONS (*(((UINT16 *) Data) + Index));
+    }
+
+    Status = TlsSetCipherList (Instance->TlsConn, CipherId, DataSize / sizeof (EFI_TLS_CIPHER));
+
+    FreePool (CipherId);
+    break;
+  case EfiTlsCompressionMethod:
+    //
+    // TLS seems only define one CompressionMethod.null, which specifies that data exchanged via the
+    // record protocol will not be compressed.
+    // More information from OpenSSL: http://www.openssl.org/docs/manmaster/ssl/SSL_COMP_add_compression_method.html
+    // The TLS RFC does however not specify compression methods or their corresponding identifiers,
+    // so there is currently no compatible way to integrate compression with unknown peers.
+    // It is therefore currently not recommended to integrate compression into applications.
+    // Applications for non-public use may agree on certain compression methods.
+    // Using different compression methods with the same identifier will lead to connection failure.
+    //
+    for (Index = 0; Index < DataSize / sizeof (EFI_TLS_COMPRESSION); Index++) {
+      Status = TlsSetCompressionMethod (*((UINT8 *) Data + Index));
+      if (EFI_ERROR (Status)) {
+        break;
+      }
+    }
+
+    break;
+  case EfiTlsExtensionData:
+    Status = EFI_UNSUPPORTED;
+    goto ON_EXIT;
+  case EfiTlsVerifyMethod:
+    if (DataSize != sizeof (EFI_TLS_VERIFY)) {
+      Status = EFI_INVALID_PARAMETER;
+      goto ON_EXIT;
+    }
+
+    TlsSetVerify (Instance->TlsConn, *((UINT32 *) Data));
+    break;
+  case EfiTlsSessionID:
+    if (DataSize != sizeof (EFI_TLS_SESSION_ID)) {
+      Status = EFI_INVALID_PARAMETER;
+      goto ON_EXIT;
+    }
+
+    Status = TlsSetSessionId (
+               Instance->TlsConn,
+               ((EFI_TLS_SESSION_ID *) Data)->Data,
+               ((EFI_TLS_SESSION_ID *) Data)->Length
+               );
+    break;
+  case EfiTlsSessionState:
+    if (DataSize != sizeof (EFI_TLS_SESSION_STATE)) {
+      Status = EFI_INVALID_PARAMETER;
+      goto ON_EXIT;
+    }
+
+    Instance->TlsSessionState = *(EFI_TLS_SESSION_STATE *) Data;
+    break;
+  //
+  // Session information
+  //
+  case EfiTlsClientRandom:
+    Status = EFI_ACCESS_DENIED;
+    break;
+  case EfiTlsServerRandom:
+    Status = EFI_ACCESS_DENIED;
+    break;
+  case EfiTlsKeyMaterial:
+    Status = EFI_ACCESS_DENIED;
+    break;
+  //
+  // Unsupported type.
+  //
+  default:
+    Status = EFI_UNSUPPORTED;
+  }
+
+ON_EXIT:
+  gBS->RestoreTPL (OldTpl);
+  return Status;
+}
+
+/**
+  Get TLS session data.
+
+  The GetSessionData() function return the TLS session information.
+
+  @param[in]       This           Pointer to the EFI_TLS_PROTOCOL instance.
+  @param[in]       DataType       TLS session data type.
+  @param[in, out]  Data           Pointer to session data.
+  @param[in, out]  DataSize       Total size of session data. On input, it means
+                                  the size of Data buffer. On output, it means the size
+                                  of copied Data buffer if EFI_SUCCESS, and means the
+                                  size of desired Data buffer if EFI_BUFFER_TOO_SMALL.
+
+  @retval EFI_SUCCESS             The TLS session data is got successfully.
+  @retval EFI_INVALID_PARAMETER   One or more of the following conditions is TRUE:
+                                  This is NULL.
+                                  DataSize is NULL.
+                                  Data is NULL if *DataSize is not zero.
+  @retval EFI_UNSUPPORTED         The DataType is unsupported.
+  @retval EFI_NOT_FOUND           The TLS session data is not found.
+  @retval EFI_NOT_READY           The DataType is not ready in current session state.
+  @retval EFI_BUFFER_TOO_SMALL    The buffer is too small to hold the data.
+**/
+EFI_STATUS
+EFIAPI
+TlsGetSessionData (
+  IN     EFI_TLS_PROTOCOL              *This,
+  IN     EFI_TLS_SESSION_DATA_TYPE     DataType,
+  IN OUT VOID                          *Data,  OPTIONAL
+  IN OUT UINTN                         *DataSize
+  )
+{
+  EFI_STATUS                Status;
+  TLS_INSTANCE              *Instance;
+
+  EFI_TPL                   OldTpl;
+
+  Status = EFI_SUCCESS;
+
+  if (This == NULL || DataSize == NULL || (Data == NULL && *DataSize != 0)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+  Instance = TLS_INSTANCE_FROM_PROTOCOL_THIS (This);
+
+  if (Instance->TlsSessionState == EfiTlsSessionNotStarted &&
+    (DataType == EfiTlsSessionID || DataType == EfiTlsClientRandom ||
+    DataType == EfiTlsServerRandom || DataType == EfiTlsKeyMaterial)) {
+    Status = EFI_NOT_READY;
+    goto ON_EXIT;
+  }
+
+  switch (DataType) {
+  case EfiTlsVersion:
+    if (*DataSize < sizeof (EFI_TLS_VERSION)) {
+      *DataSize = sizeof (EFI_TLS_VERSION);
+      Status = EFI_BUFFER_TOO_SMALL;
+      goto ON_EXIT;
+    }
+    *DataSize = sizeof (EFI_TLS_VERSION);
+    *((UINT16 *) Data) = HTONS (TlsGetVersion (Instance->TlsConn));
+    break;
+  case EfiTlsConnectionEnd:
+    if (*DataSize < sizeof (EFI_TLS_CONNECTION_END)) {
+      *DataSize = sizeof (EFI_TLS_CONNECTION_END);
+      Status = EFI_BUFFER_TOO_SMALL;
+      goto ON_EXIT;
+    }
+    *DataSize = sizeof (EFI_TLS_CONNECTION_END);
+    *((UINT8 *) Data) = TlsGetConnectionEnd (Instance->TlsConn);
+    break;
+  case EfiTlsCipherList:
+    //
+    // Get the current session cipher suite.
+    //
+    if (*DataSize < sizeof (EFI_TLS_CIPHER)) {
+      *DataSize = sizeof (EFI_TLS_CIPHER);
+      Status = EFI_BUFFER_TOO_SMALL;
+      goto ON_EXIT;
+    }
+    *DataSize = sizeof(EFI_TLS_CIPHER);
+    Status = TlsGetCurrentCipher (Instance->TlsConn, (UINT16 *) Data);
+    *((UINT16 *) Data) = HTONS (*((UINT16 *) Data));
+    break;
+  case EfiTlsCompressionMethod:
+    //
+    // Get the current session compression method.
+    //
+    if (*DataSize < sizeof (EFI_TLS_COMPRESSION)) {
+      *DataSize = sizeof (EFI_TLS_COMPRESSION);
+      Status = EFI_BUFFER_TOO_SMALL;
+      goto ON_EXIT;
+    }
+    *DataSize = sizeof (EFI_TLS_COMPRESSION);
+    Status = TlsGetCurrentCompressionId (Instance->TlsConn, (UINT8 *) Data);
+    break;
+  case EfiTlsExtensionData:
+    Status = EFI_UNSUPPORTED;
+    goto ON_EXIT;
+  case EfiTlsVerifyMethod:
+    if (*DataSize < sizeof (EFI_TLS_VERIFY)) {
+      *DataSize = sizeof (EFI_TLS_VERIFY);
+      Status = EFI_BUFFER_TOO_SMALL;
+      goto ON_EXIT;
+    }
+    *DataSize = sizeof (EFI_TLS_VERIFY);
+    *((UINT32 *) Data) = TlsGetVerify (Instance->TlsConn);
+    break;
+  case EfiTlsSessionID:
+    if (*DataSize < sizeof (EFI_TLS_SESSION_ID)) {
+      *DataSize = sizeof (EFI_TLS_SESSION_ID);
+      Status = EFI_BUFFER_TOO_SMALL;
+      goto ON_EXIT;
+    }
+    *DataSize = sizeof (EFI_TLS_SESSION_ID);
+    Status = TlsGetSessionId (
+               Instance->TlsConn,
+               ((EFI_TLS_SESSION_ID *) Data)->Data,
+               &(((EFI_TLS_SESSION_ID *) Data)->Length)
+               );
+    break;
+  case EfiTlsSessionState:
+    if (*DataSize < sizeof (EFI_TLS_SESSION_STATE)) {
+      *DataSize = sizeof (EFI_TLS_SESSION_STATE);
+      Status = EFI_BUFFER_TOO_SMALL;
+      goto ON_EXIT;
+    }
+    *DataSize = sizeof (EFI_TLS_SESSION_STATE);
+    CopyMem (Data, &Instance->TlsSessionState, *DataSize);
+    break;
+  case EfiTlsClientRandom:
+    if (*DataSize < sizeof (EFI_TLS_RANDOM)) {
+      *DataSize = sizeof (EFI_TLS_RANDOM);
+      Status = EFI_BUFFER_TOO_SMALL;
+      goto ON_EXIT;
+    }
+    *DataSize = sizeof (EFI_TLS_RANDOM);
+    TlsGetClientRandom (Instance->TlsConn, (UINT8 *) Data);
+    break;
+  case EfiTlsServerRandom:
+    if (*DataSize < sizeof (EFI_TLS_RANDOM)) {
+      *DataSize = sizeof (EFI_TLS_RANDOM);
+      Status = EFI_BUFFER_TOO_SMALL;
+      goto ON_EXIT;
+    }
+    *DataSize = sizeof (EFI_TLS_RANDOM);
+    TlsGetServerRandom (Instance->TlsConn, (UINT8 *) Data);
+    break;
+  case EfiTlsKeyMaterial:
+    if (*DataSize < sizeof (EFI_TLS_MASTER_SECRET)) {
+      *DataSize = sizeof (EFI_TLS_MASTER_SECRET);
+      Status = EFI_BUFFER_TOO_SMALL;
+      goto ON_EXIT;
+    }
+    *DataSize = sizeof (EFI_TLS_MASTER_SECRET);
+    Status = TlsGetKeyMaterial (Instance->TlsConn, (UINT8 *) Data);
+    break;
+  //
+  // Unsupported type.
+  //
+  default:
+    Status = EFI_UNSUPPORTED;
+  }
+
+ON_EXIT:
+  gBS->RestoreTPL (OldTpl);
+  return Status;
+}
+
+/**
+  Build response packet according to TLS state machine. This function is only valid for
+  alert, handshake and change_cipher_spec content type.
+
+  The BuildResponsePacket() function builds TLS response packet in response to the TLS
+  request packet specified by RequestBuffer and RequestSize. If RequestBuffer is NULL and
+  RequestSize is 0, and TLS session status is EfiTlsSessionNotStarted, the TLS session
+  will be initiated and the response packet needs to be ClientHello. If RequestBuffer is
+  NULL and RequestSize is 0, and TLS session status is EfiTlsSessionClosing, the TLS
+  session will be closed and response packet needs to be CloseNotify. If RequestBuffer is
+  NULL and RequestSize is 0, and TLS session status is EfiTlsSessionError, the TLS
+  session has errors and the response packet needs to be Alert message based on error
+  type.
+
+  @param[in]       This           Pointer to the EFI_TLS_PROTOCOL instance.
+  @param[in]       RequestBuffer  Pointer to the most recently received TLS packet. NULL
+                                  means TLS need initiate the TLS session and response
+                                  packet need to be ClientHello.
+  @param[in]       RequestSize    Packet size in bytes for the most recently received TLS
+                                  packet. 0 is only valid when RequestBuffer is NULL.
+  @param[out]      Buffer         Pointer to the buffer to hold the built packet.
+  @param[in, out]  BufferSize     Pointer to the buffer size in bytes. On input, it is
+                                  the buffer size provided by the caller. On output, it
+                                  is the buffer size in fact needed to contain the
+                                  packet.
+
+  @retval EFI_SUCCESS             The required TLS packet is built successfully.
+  @retval EFI_INVALID_PARAMETER   One or more of the following conditions is TRUE:
+                                  This is NULL.
+                                  RequestBuffer is NULL but RequestSize is NOT 0.
+                                  RequestSize is 0 but RequestBuffer is NOT NULL.
+                                  BufferSize is NULL.
+                                  Buffer is NULL if *BufferSize is not zero.
+  @retval EFI_BUFFER_TOO_SMALL    BufferSize is too small to hold the response packet.
+  @retval EFI_NOT_READY           Current TLS session state is NOT ready to build
+                                  ResponsePacket.
+  @retval EFI_ABORTED             Something wrong build response packet.
+**/
+EFI_STATUS
+EFIAPI
+TlsBuildResponsePacket (
+  IN     EFI_TLS_PROTOCOL              *This,
+  IN     UINT8                         *RequestBuffer, OPTIONAL
+  IN     UINTN                         RequestSize, OPTIONAL
+     OUT UINT8                         *Buffer, OPTIONAL
+  IN OUT UINTN                         *BufferSize
+  )
+{
+  EFI_STATUS                Status;
+  TLS_INSTANCE              *Instance;
+  EFI_TPL                   OldTpl;
+
+  Status = EFI_SUCCESS;
+
+  if ((This == NULL) || (BufferSize == NULL) ||
+      (RequestBuffer == NULL && RequestSize != 0) ||
+      (RequestBuffer != NULL && RequestSize == 0) ||
+      (Buffer == NULL && *BufferSize !=0)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+  Instance = TLS_INSTANCE_FROM_PROTOCOL_THIS (This);
+
+  if(RequestBuffer == NULL && RequestSize == 0) {
+    switch (Instance->TlsSessionState) {
+    case EfiTlsSessionNotStarted:
+      //
+      // ClientHello.
+      //
+      Status = TlsDoHandshake (
+                 Instance->TlsConn,
+                 NULL,
+                 0,
+                 Buffer,
+                 BufferSize
+                 );
+      if (EFI_ERROR (Status)) {
+        goto ON_EXIT;
+      }
+
+      //
+      // *BufferSize should not be zero when ClientHello.
+      //
+      if (*BufferSize == 0) {
+        Status = EFI_ABORTED;
+        goto ON_EXIT;
+      }
+
+      Instance->TlsSessionState = EfiTlsSessionHandShaking;
+
+      break;
+    case EfiTlsSessionClosing:
+      //
+      // TLS session will be closed and response packet needs to be CloseNotify.
+      //
+      Status = TlsCloseNotify (
+                 Instance->TlsConn,
+                 Buffer,
+                 BufferSize
+                 );
+      if (EFI_ERROR (Status)) {
+        goto ON_EXIT;
+      }
+
+      //
+      // *BufferSize should not be zero when build CloseNotify message.
+      //
+      if (*BufferSize == 0) {
+        Status = EFI_ABORTED;
+        goto ON_EXIT;
+      }
+
+      break;
+    case EfiTlsSessionError:
+      //
+      // TLS session has errors and the response packet needs to be Alert
+      // message based on error type.
+      //
+      Status = TlsHandeAlert (
+                 Instance->TlsConn,
+                 NULL,
+                 0,
+                 Buffer,
+                 BufferSize
+                 );
+      if (EFI_ERROR (Status)) {
+        goto ON_EXIT;
+      }
+
+      break;
+    default:
+      //
+      // Current TLS session state is NOT ready to build ResponsePacket.
+      //
+      Status = EFI_NOT_READY;
+    }
+  } else {
+    //
+    // 1. Received packet may have multiply TLS record messages.
+    // 2. One TLS record message may have multiply handshake protocol.
+    // 3. Some errors may be happened in handshake.
+    // TlsDoHandshake() can handle all of those cases.
+    //
+    if (TlsInHandshake (Instance->TlsConn)) {
+      Status = TlsDoHandshake (
+                 Instance->TlsConn,
+                 RequestBuffer,
+                 RequestSize,
+                 Buffer,
+                 BufferSize
+                 );
+      if (EFI_ERROR (Status)) {
+        goto ON_EXIT;
+      }
+
+      if (!TlsInHandshake (Instance->TlsConn)) {
+        Instance->TlsSessionState = EfiTlsSessionDataTransferring;
+      }
+    } else {
+      //
+      // Must be alert message, Decrypt it and build the ResponsePacket.
+      //
+      ASSERT (((TLS_RECORD_HEADER *) RequestBuffer)->ContentType == TLS_CONTENT_TYPE_ALERT);
+
+      Status = TlsHandeAlert (
+                 Instance->TlsConn,
+                 RequestBuffer,
+                 RequestSize,
+                 Buffer,
+                 BufferSize
+                 );
+      if (EFI_ERROR (Status)) {
+        if (Status != EFI_BUFFER_TOO_SMALL) {
+          Instance->TlsSessionState = EfiTlsSessionError;
+        }
+
+        goto ON_EXIT;
+      }
+    }
+  }
+
+ON_EXIT:
+  gBS->RestoreTPL (OldTpl);
+  return Status;
+}
+
+/**
+  Decrypt or encrypt TLS packet during session. This function is only valid after
+  session connected and for application_data content type.
+
+  The ProcessPacket () function process each inbound or outbound TLS APP packet.
+
+  @param[in]       This           Pointer to the EFI_TLS_PROTOCOL instance.
+  @param[in, out]  FragmentTable  Pointer to a list of fragment. The caller will take
+                                  responsible to handle the original FragmentTable while
+                                  it may be reallocated in TLS driver. If CryptMode is
+                                  EfiTlsEncrypt, on input these fragments contain the TLS
+                                  header and plain text TLS APP payload; on output these
+                                  fragments contain the TLS header and cipher text TLS
+                                  APP payload. If CryptMode is EfiTlsDecrypt, on input
+                                  these fragments contain the TLS header and cipher text
+                                  TLS APP payload; on output these fragments contain the
+                                  TLS header and plain text TLS APP payload.
+  @param[in]       FragmentCount  Number of fragment.
+  @param[in]       CryptMode      Crypt mode.
+
+  @retval EFI_SUCCESS             The operation completed successfully.
+  @retval EFI_INVALID_PARAMETER   One or more of the following conditions is TRUE:
+                                  This is NULL.
+                                  FragmentTable is NULL.
+                                  FragmentCount is NULL.
+                                  CryptoMode is invalid.
+  @retval EFI_NOT_READY           Current TLS session state is NOT
+                                  EfiTlsSessionDataTransferring.
+  @retval EFI_ABORTED             Something wrong decryption the message. TLS session
+                                  status will become EfiTlsSessionError. The caller need
+                                  call BuildResponsePacket() to generate Error Alert
+                                  message and send it out.
+  @retval EFI_OUT_OF_RESOURCES    No enough resource to finish the operation.
+**/
+EFI_STATUS
+EFIAPI
+TlsProcessPacket (
+  IN     EFI_TLS_PROTOCOL              *This,
+  IN OUT EFI_TLS_FRAGMENT_DATA         **FragmentTable,
+  IN     UINT32                        *FragmentCount,
+  IN     EFI_TLS_CRYPT_MODE            CryptMode
+  )
+{
+  EFI_STATUS                Status;
+  TLS_INSTANCE              *Instance;
+
+  EFI_TPL                   OldTpl;
+
+  Status = EFI_SUCCESS;
+
+  if (This == NULL || FragmentTable == NULL || FragmentCount == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+  Instance = TLS_INSTANCE_FROM_PROTOCOL_THIS (This);
+
+  if (Instance->TlsSessionState != EfiTlsSessionDataTransferring) {
+    Status = EFI_NOT_READY;
+    goto ON_EXIT;
+  }
+
+  //
+  // Packet sent or received may have multiply TLS record message(Application data type).
+  // So,on input these fragments contain the TLS header and TLS APP payload;
+  // on output these fragments also contain the TLS header and TLS APP payload.
+  //
+  switch (CryptMode) {
+  case EfiTlsEncrypt:
+    Status = TlsEcryptPacket (Instance, FragmentTable, FragmentCount);
+    break;
+  case EfiTlsDecrypt:
+    Status = TlsDecryptPacket (Instance, FragmentTable, FragmentCount);
+    break;
+  default:
+    return EFI_INVALID_PARAMETER;
+  }
+
+ON_EXIT:
+  gBS->RestoreTPL (OldTpl);
+  return Status;
+}
-- 
1.9.5.msysgit.1



^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH v2 05/10] NetworkPkg/TlsDxe: TlsDxe driver implementation over OpenSSL
  2016-12-16  6:16 ` Ye, Ting
@ 2016-12-16  7:30   ` Wu, Jiaxin
  0 siblings, 0 replies; 3+ messages in thread
From: Wu, Jiaxin @ 2016-12-16  7:30 UTC (permalink / raw)
  To: Ye, Ting, edk2-devel@lists.01.org
  Cc: Fu, Siyuan, Zhang, Lubo, Long, Qin, Thomas Palmer

Thanks Ting, I have updated the patch according your comments.

    [PATCH v2 04/10] CryptoPkg: Add new TlsLib library
    [PATCH v3 05/10] NetworkPkg/TlsDxe: TlsDxe driver implementation over OpenSSL

Best Regards!
Jiaxin

> -----Original Message-----
> From: Ye, Ting
> Sent: Friday, December 16, 2016 2:16 PM
> To: Wu, Jiaxin <jiaxin.wu@intel.com>; edk2-devel@lists.01.org
> Cc: Fu, Siyuan <siyuan.fu@intel.com>; Zhang, Lubo <lubo.zhang@intel.com>;
> Long, Qin <qin.long@intel.com>; Thomas Palmer <thomas.palmer@hpe.com>
> Subject: RE: [PATCH v2 05/10] NetworkPkg/TlsDxe: TlsDxe driver
> implementation over OpenSSL
> 
> Hi Jiaxin,
> 
> Some comments included as below.
> 
> 1. In TlsCreateService
>      Line 325: ASSERT checks after assignment in line 323.  Should put ASSERT
> earlier.
>      'Status' looks useless.
> 
> 2. TlsDriver.h
>      I think the macros ' TLS_INSTANCE_FROM_PROTOCOL_THIS' and '
> TLS_INSTANCE_FROM_CONFIGURATION_THIS' are hard to read. Maybe we
> could remove the '_THIS' postfix?
>      Please define appropriate names.
> 
> 3. TlsImpl.c
>     I think it's better to update TlsEcryptPacket to TlsEncryptPacket
>     And also update "continue the other messages encryption\decryption." To
> "continue to encrypt/decrypt other messages."
> 	" The caller will take responsible to..." to " The caller will be
> responsible to... "
> 	"Received packet may have multiply TLS record message." To "
> Received packet may have multiple TLS record messages."
> 	Also update Multiply to multiple in other places.
> 
>    "Copy all TLS plain record header and payload to ProcessBuffer".
> ProcessBuffer looks a local variable but not exist. May update to BufferIn?
> Please double check.
> 
> Others are good to me.
> 
> Reviewed-by: Ye Ting <ting.ye@intel.com>
> 
> Thanks,
> Ting
> 
> -----Original Message-----
> From: Wu, Jiaxin
> Sent: Thursday, December 15, 2016 3:22 PM
> To: edk2-devel@lists.01.org
> Cc: Ye, Ting <ting.ye@intel.com>; Fu, Siyuan <siyuan.fu@intel.com>; Zhang,
> Lubo <lubo.zhang@intel.com>; Long, Qin <qin.long@intel.com>; Thomas
> Palmer <thomas.palmer@hpe.com>; Wu, Jiaxin <jiaxin.wu@intel.com>
> Subject: [PATCH v2 05/10] NetworkPkg/TlsDxe: TlsDxe driver implementation
> over OpenSSL
> 
> v2:
> * Refine the TlsEcryptPacket/TlsDecryptPacket function
> according the community feedback.
> 
> This patch is the implementation of EFI TLS Service Binding
> Protocol, EFI TLS Protocol and EFI TLS Configuration Protocol
> Interfaces.
> 
> Cc: Ye Ting <ting.ye@intel.com>
> Cc: Fu Siyuan <siyuan.fu@intel.com>
> Cc: Zhang Lubo <lubo.zhang@intel.com>
> Cc: Long Qin <qin.long@intel.com>
> Cc: Thomas Palmer <thomas.palmer@hpe.com>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Wu Jiaxin <jiaxin.wu@intel.com>
> ---
>  NetworkPkg/TlsDxe/TlsConfigProtocol.c | 152 ++++++++
>  NetworkPkg/TlsDxe/TlsDriver.c         | 498
> +++++++++++++++++++++++++++
>  NetworkPkg/TlsDxe/TlsDriver.h         | 237 +++++++++++++
>  NetworkPkg/TlsDxe/TlsDxe.inf          |  65 ++++
>  NetworkPkg/TlsDxe/TlsDxe.uni          |  25 ++
>  NetworkPkg/TlsDxe/TlsDxeExtra.uni     |  18 +
>  NetworkPkg/TlsDxe/TlsImpl.c           | 326 ++++++++++++++++++
>  NetworkPkg/TlsDxe/TlsImpl.h           | 315 +++++++++++++++++
>  NetworkPkg/TlsDxe/TlsProtocol.c       | 632
> ++++++++++++++++++++++++++++++++++
>  9 files changed, 2268 insertions(+)
>  create mode 100644 NetworkPkg/TlsDxe/TlsConfigProtocol.c
>  create mode 100644 NetworkPkg/TlsDxe/TlsDriver.c
>  create mode 100644 NetworkPkg/TlsDxe/TlsDriver.h
>  create mode 100644 NetworkPkg/TlsDxe/TlsDxe.inf
>  create mode 100644 NetworkPkg/TlsDxe/TlsDxe.uni
>  create mode 100644 NetworkPkg/TlsDxe/TlsDxeExtra.uni
>  create mode 100644 NetworkPkg/TlsDxe/TlsImpl.c
>  create mode 100644 NetworkPkg/TlsDxe/TlsImpl.h
>  create mode 100644 NetworkPkg/TlsDxe/TlsProtocol.c
> 
> diff --git a/NetworkPkg/TlsDxe/TlsConfigProtocol.c
> b/NetworkPkg/TlsDxe/TlsConfigProtocol.c
> new file mode 100644
> index 0000000..2ec79c9
> --- /dev/null
> +++ b/NetworkPkg/TlsDxe/TlsConfigProtocol.c
> @@ -0,0 +1,152 @@
> +/** @file
> +  Implementation of EFI TLS Configuration Protocol Interfaces.
> +
> +  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 "TlsImpl.h"
> +
> +EFI_TLS_CONFIGURATION_PROTOCOL  mTlsConfigurationProtocol = {
> +  TlsConfigurationSetData,
> +  TlsConfigurationGetData
> +};
> +
> +/**
> +  Set TLS configuration data.
> +
> +  The SetData() function sets TLS configuration to non-volatile storage or
> volatile
> +  storage.
> +
> +  @param[in]  This                Pointer to the
> EFI_TLS_CONFIGURATION_PROTOCOL instance.
> +  @param[in]  DataType            Configuration data type.
> +  @param[in]  Data                Pointer to configuration data.
> +  @param[in]  DataSize            Total size of configuration data.
> +
> +  @retval EFI_SUCCESS             The TLS configuration data is set successfully.
> +  @retval EFI_INVALID_PARAMETER   One or more of the following
> conditions is TRUE:
> +                                  This is NULL.
> +                                  Data is NULL.
> +                                  DataSize is 0.
> +  @retval EFI_UNSUPPORTED         The DataType is unsupported.
> +  @retval EFI_OUT_OF_RESOURCES    Required system resources could not
> be allocated.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsConfigurationSetData (
> +  IN     EFI_TLS_CONFIGURATION_PROTOCOL  *This,
> +  IN     EFI_TLS_CONFIG_DATA_TYPE        DataType,
> +  IN     VOID                            *Data,
> +  IN     UINTN                           DataSize
> +  )
> +{
> +  EFI_STATUS                Status;
> +  TLS_INSTANCE              *Instance;
> +  EFI_TPL                   OldTpl;
> +
> +  Status = EFI_SUCCESS;
> +
> +  if (This == NULL ||  Data == NULL || DataSize == 0) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
> +
> +  Instance = TLS_INSTANCE_FROM_CONFIGURATION_THIS (This);
> +
> +  switch (DataType) {
> +  case EfiTlsConfigDataTypeCACertificate:
> +    Status = TlsSetCaCertificate (Instance->TlsConn, Data, DataSize);
> +    break;
> +  case EfiTlsConfigDataTypeHostPublicCert:
> +    Status = TlsSetHostPublicCert (Instance->TlsConn, Data, DataSize);
> +    break;
> +  case EfiTlsConfigDataTypeHostPrivateKey:
> +    Status = TlsSetHostPrivateKey (Instance->TlsConn, Data, DataSize);
> +    break;
> +  case EfiTlsConfigDataTypeCertRevocationList:
> +    Status = TlsSetCertRevocationList (Data, DataSize);
> +    break;
> +  default:
> +     Status = EFI_UNSUPPORTED;
> +  }
> +
> +  gBS->RestoreTPL (OldTpl);
> +  return Status;
> +}
> +
> +/**
> +  Get TLS configuration data.
> +
> +  The GetData() function gets TLS configuration.
> +
> +  @param[in]       This           Pointer to the
> EFI_TLS_CONFIGURATION_PROTOCOL instance.
> +  @param[in]       DataType       Configuration data type.
> +  @param[in, out]  Data           Pointer to configuration data.
> +  @param[in, out]  DataSize       Total size of configuration data. On input, it
> means
> +                                  the size of Data buffer. On output, it means the size
> +                                  of copied Data buffer if EFI_SUCCESS, and means the
> +                                  size of desired Data buffer if EFI_BUFFER_TOO_SMALL.
> +
> +  @retval EFI_SUCCESS             The TLS configuration data is got successfully.
> +  @retval EFI_INVALID_PARAMETER   One or more of the following
> conditions is TRUE:
> +                                  This is NULL.
> +                                  DataSize is NULL.
> +                                  Data is NULL if *DataSize is not zero.
> +  @retval EFI_UNSUPPORTED         The DataType is unsupported.
> +  @retval EFI_NOT_FOUND           The TLS configuration data is not found.
> +  @retval EFI_BUFFER_TOO_SMALL    The buffer is too small to hold the data.
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsConfigurationGetData (
> +  IN     EFI_TLS_CONFIGURATION_PROTOCOL  *This,
> +  IN     EFI_TLS_CONFIG_DATA_TYPE        DataType,
> +  IN OUT VOID                            *Data, OPTIONAL
> +  IN OUT UINTN                           *DataSize
> +  )
> +{
> +  EFI_STATUS                Status;
> +  TLS_INSTANCE              *Instance;
> +
> +  EFI_TPL                   OldTpl;
> +
> +  Status = EFI_SUCCESS;
> +
> +  if (This == NULL || DataSize == NULL || (Data == NULL && *DataSize != 0))
> {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
> +
> +  Instance = TLS_INSTANCE_FROM_CONFIGURATION_THIS (This);
> +
> +  switch (DataType) {
> +  case EfiTlsConfigDataTypeCACertificate:
> +    Status = TlsGetCaCertificate (Instance->TlsConn, Data, DataSize);
> +    break;
> +  case EfiTlsConfigDataTypeHostPublicCert:
> +    Status = TlsGetHostPublicCert (Instance->TlsConn, Data, DataSize);
> +    break;
> +  case EfiTlsConfigDataTypeHostPrivateKey:
> +    Status = TlsGetHostPrivateKey (Instance->TlsConn, Data, DataSize);
> +    break;
> +  case EfiTlsConfigDataTypeCertRevocationList:
> +    Status = TlsGetCertRevocationList (Data, DataSize);
> +    break;
> +  default:
> +    Status = EFI_UNSUPPORTED;
> +  }
> +
> +  gBS->RestoreTPL (OldTpl);
> +  return Status;
> +}
> diff --git a/NetworkPkg/TlsDxe/TlsDriver.c b/NetworkPkg/TlsDxe/TlsDriver.c
> new file mode 100644
> index 0000000..0a75c39
> --- /dev/null
> +++ b/NetworkPkg/TlsDxe/TlsDriver.c
> @@ -0,0 +1,498 @@
> +/** @file
> +  The Driver Binding and Service Binding Protocol for TlsDxe 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 "TlsImpl.h"
> +
> +EFI_SERVICE_BINDING_PROTOCOL mTlsServiceBinding = {
> +  TlsServiceBindingCreateChild,
> +  TlsServiceBindingDestroyChild
> +};
> +
> +/**
> +  Release all the resources used by the TLS instance.
> +
> +  @param[in]  Instance        The TLS instance data.
> +
> +**/
> +VOID
> +TlsCleanInstance (
> +  IN TLS_INSTANCE           *Instance
> +  )
> +{
> +  if (Instance != NULL) {
> +    if (Instance->TlsConn != NULL) {
> +      TlsFree (Instance->TlsConn);
> +    }
> +
> +    FreePool (Instance);
> +  }
> +}
> +
> +/**
> +  Create the TLS instance and initialize it.
> +
> +  @param[in]  Service              The pointer to the TLS service.
> +  @param[out] Instance             The pointer to the TLS instance.
> +
> +  @retval EFI_OUT_OF_RESOURCES   Failed to allocate resources.
> +  @retval EFI_SUCCESS            The TLS instance is created.
> +
> +**/
> +EFI_STATUS
> +TlsCreateInstance (
> +  IN  TLS_SERVICE         *Service,
> +  OUT TLS_INSTANCE        **Instance
> +  )
> +{
> +  TLS_INSTANCE            *TlsInstance;
> +
> +  *Instance = NULL;
> +
> +  TlsInstance = AllocateZeroPool (sizeof (TLS_INSTANCE));
> +  if (TlsInstance == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  TlsInstance->Signature = TLS_INSTANCE_SIGNATURE;
> +  InitializeListHead (&TlsInstance->Link);
> +  TlsInstance->InDestroy = FALSE;
> +  TlsInstance->Service   = Service;
> +
> +  CopyMem (&TlsInstance->Tls, &mTlsProtocol, sizeof (TlsInstance->Tls));
> +  CopyMem (&TlsInstance->TlsConfig, &mTlsConfigurationProtocol, sizeof
> (TlsInstance->TlsConfig));
> +
> +  TlsInstance->TlsSessionState = EfiTlsSessionNotStarted;
> +
> +  *Instance = TlsInstance;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Release all the resources used by the TLS service binding instance.
> +
> +  @param[in]  Service        The TLS service data.
> +
> +**/
> +VOID
> +TlsCleanService (
> +  IN TLS_SERVICE     *Service
> +  )
> +{
> +  if (Service != NULL) {
> +    if (Service->TlsCtx != NULL) {
> +      TlsCtxFree (Service->TlsCtx);
> +    }
> +
> +    FreePool (Service);
> +  }
> +}
> +
> +/**
> +  Create then initialize a TLS service.
> +
> +  @param[in]  Image                  ImageHandle of the TLS driver
> +  @param[out] Service                The service for TLS driver
> +
> +  @retval EFI_OUT_OF_RESOURCES   Failed to allocate resource to create
> the service.
> +  @retval EFI_SUCCESS            The service is created for the driver.
> +
> +**/
> +EFI_STATUS
> +TlsCreateService (
> +  IN  EFI_HANDLE            Image,
> +  OUT TLS_SERVICE           **Service
> +  )
> +{
> +  EFI_STATUS             Status;
> +  TLS_SERVICE            *TlsService;
> +
> +  Status = EFI_SUCCESS;
> +  *Service = NULL;
> +
> +  ASSERT (Service != NULL);
> +
> +  //
> +  // Allocate a TLS Service Data
> +  //
> +  TlsService = AllocateZeroPool (sizeof (TLS_SERVICE));
> +  if (TlsService == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  //
> +  // Initialize TLS Service Data
> +  //
> +  TlsService->Signature        = TLS_SERVICE_SIGNATURE;
> +  CopyMem (&TlsService->ServiceBinding, &mTlsServiceBinding, sizeof
> (TlsService->ServiceBinding));
> +  TlsService->TlsChildrenNum   = 0;
> +  InitializeListHead (&TlsService->TlsChildrenList);
> +  TlsService->ImageHandle      = Image;
> +
> +  *Service = TlsService;
> +
> +  return Status;
> +}
> +
> +/**
> +  Unloads an image.
> +
> +  @param[in]  ImageHandle           Handle that identifies the image to be
> unloaded.
> +
> +  @retval EFI_SUCCESS           The image has been unloaded.
> +  @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image
> handle.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsUnload (
> +  IN EFI_HANDLE  ImageHandle
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  UINTN                           HandleNum;
> +  EFI_HANDLE                      *HandleBuffer;
> +  UINT32                          Index;
> +  EFI_SERVICE_BINDING_PROTOCOL    *ServiceBinding;
> +  TLS_SERVICE                     *TlsService;
> +
> +  HandleBuffer   = NULL;
> +  ServiceBinding = NULL;
> +  TlsService     = NULL;
> +
> +  //
> +  // Locate all the handles with Tls service binding protocol.
> +  //
> +  Status = gBS->LocateHandleBuffer (
> +                  ByProtocol,
> +                  &gEfiTlsServiceBindingProtocolGuid,
> +                  NULL,
> +                  &HandleNum,
> +                  &HandleBuffer
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  for (Index = 0; Index < HandleNum; Index++) {
> +    //
> +    // Firstly, find ServiceBinding interface
> +    //
> +    Status = gBS->OpenProtocol (
> +                    HandleBuffer[Index],
> +                    &gEfiTlsServiceBindingProtocolGuid,
> +                    (VOID **) &ServiceBinding,
> +                    ImageHandle,
> +                    NULL,
> +                    EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
> +                    );
> +    if (EFI_ERROR (Status)) {
> +      return Status;
> +    }
> +
> +    TlsService = TLS_SERVICE_FROM_THIS (ServiceBinding);
> +
> +    //
> +    // Then, uninstall ServiceBinding interface
> +    //
> +    Status = gBS->UninstallMultipleProtocolInterfaces (
> +                    HandleBuffer[Index],
> +                    &gEfiTlsServiceBindingProtocolGuid, ServiceBinding,
> +                    NULL
> +                    );
> +    if (EFI_ERROR (Status)) {
> +      return Status;
> +    }
> +
> +    TlsCleanService (TlsService);
> +  }
> +
> +  if (HandleBuffer != NULL) {
> +    FreePool (HandleBuffer);
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This is the declaration of an EFI image entry point. This entry point is
> +  the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
> +  both device drivers and bus drivers.
> +
> +  @param  ImageHandle           The firmware allocated handle for the UEFI
> image.
> +  @param  SystemTable           A pointer to the EFI System Table.
> +
> +  @retval EFI_SUCCESS           The operation completed successfully.
> +  @retval Others                An unexpected error occurred.
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsDriverEntryPoint (
> +  IN EFI_HANDLE        ImageHandle,
> +  IN EFI_SYSTEM_TABLE  *SystemTable
> +  )
> +{
> +  EFI_STATUS             Status;
> +
> +  TLS_SERVICE            *TlsService;
> +
> +  //
> +  // Create TLS Service
> +  //
> +  Status = TlsCreateService (ImageHandle, &TlsService);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  ASSERT (TlsService != NULL);
> +
> +  //
> +  // Initializes the OpenSSL library.
> +  //
> +  TlsInitialize ();
> +
> +  //
> +  // Create a new SSL_CTX object as framework to establish TLS/SSL enabled
> +  // connections. TLS 1.0 is used as the default version.
> +  //
> +  TlsService->TlsCtx = TlsCtxNew (TLS10_PROTOCOL_VERSION_MAJOR,
> TLS10_PROTOCOL_VERSION_MINOR);
> +  if (TlsService->TlsCtx == NULL) {
> +    FreePool (TlsService);
> +    return EFI_ABORTED;
> +  }
> +
> +  //
> +  // Install the TlsServiceBinding Protocol onto Handle
> +  //
> +  Status = gBS->InstallMultipleProtocolInterfaces (
> +                  &TlsService->Handle,
> +                  &gEfiTlsServiceBindingProtocolGuid,
> +                  &TlsService->ServiceBinding,
> +                  NULL
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    goto ON_CLEAN_SERVICE;
> +  }
> +
> +  return Status;
> +
> +ON_CLEAN_SERVICE:
> +  TlsCleanService (TlsService);
> +
> +  return Status;
> +}
> +
> +/**
> +  Creates a child handle and installs a protocol.
> +
> +  The CreateChild() function installs a protocol on ChildHandle.
> +  If ChildHandle is a pointer to NULL, then a new handle is created and
> returned in ChildHandle.
> +  If ChildHandle is not a pointer to NULL, then the protocol installs on the
> existing ChildHandle.
> +
> +  @param[in] This        Pointer to the EFI_SERVICE_BINDING_PROTOCOL
> instance.
> +  @param[in] ChildHandle Pointer to the handle of the child to create. If it is
> NULL,
> +                         then a new handle is created. If it is a pointer to an existing
> UEFI handle,
> +                         then the protocol is added to the existing UEFI handle.
> +
> +  @retval EFI_SUCCES            The protocol was added to ChildHandle.
> +  @retval EFI_INVALID_PARAMETER ChildHandle is NULL.
> +  @retval EFI_OUT_OF_RESOURCES  There are not enough resources
> available to create
> +                                the child.
> +  @retval other                 The child handle was not created.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsServiceBindingCreateChild (
> +  IN EFI_SERVICE_BINDING_PROTOCOL  *This,
> +  IN EFI_HANDLE                    *ChildHandle
> +  )
> +{
> +  TLS_SERVICE         *TlsService;
> +  TLS_INSTANCE        *TlsInstance;
> +  EFI_STATUS           Status;
> +  EFI_TPL              OldTpl;
> +
> +  if ((This == NULL) || (ChildHandle == NULL)) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  TlsService = TLS_SERVICE_FROM_THIS (This);
> +
> +  Status = TlsCreateInstance (TlsService, &TlsInstance);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  ASSERT (TlsInstance != NULL);
> +
> +  //
> +  // Create a new TLS connection object.
> +  //
> +  TlsInstance->TlsConn = TlsNew (TlsService->TlsCtx);
> +  if (TlsInstance->TlsConn == NULL) {
> +    Status = EFI_ABORTED;
> +    goto ON_ERROR;
> +  }
> +
> +  //
> +  // Set default ConnectionEnd to EfiTlsClient
> +  //
> +  Status = TlsSetConnectionEnd (TlsInstance->TlsConn, EfiTlsClient);
> +  if (EFI_ERROR (Status)) {
> +    goto ON_ERROR;
> +  }
> +
> +  //
> +  // Install TLS protocol and configuration protocol onto ChildHandle
> +  //
> +  Status = gBS->InstallMultipleProtocolInterfaces (
> +                  ChildHandle,
> +                  &gEfiTlsProtocolGuid,
> +                  &TlsInstance->Tls,
> +                  &gEfiTlsConfigurationProtocolGuid,
> +                  &TlsInstance->TlsConfig,
> +                  NULL
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    goto ON_ERROR;
> +  }
> +
> +  TlsInstance->ChildHandle = *ChildHandle;
> +
> +  //
> +  // Add it to the TLS service's child list.
> +  //
> +  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
> +
> +  InsertTailList (&TlsService->TlsChildrenList, &TlsInstance->Link);
> +  TlsService->TlsChildrenNum++;
> +
> +  gBS->RestoreTPL (OldTpl);
> +
> +  return EFI_SUCCESS;
> +
> +ON_ERROR:
> +  TlsCleanInstance (TlsInstance);
> +  return Status;
> +}
> +
> +/**
> +  Destroys a child handle with a protocol installed on it.
> +
> +  The DestroyChild() function does the opposite of CreateChild(). It removes
> a protocol
> +  that was installed by CreateChild() from ChildHandle. If the removed
> protocol is the
> +  last protocol on ChildHandle, then ChildHandle is destroyed.
> +
> +  @param  This        Pointer to the EFI_SERVICE_BINDING_PROTOCOL
> instance.
> +  @param  ChildHandle Handle of the child to destroy.
> +
> +  @retval EFI_SUCCES            The protocol was removed from ChildHandle.
> +  @retval EFI_UNSUPPORTED       ChildHandle does not support the protocol
> that is being removed.
> +  @retval EFI_INVALID_PARAMETER Child handle is NULL.
> +  @retval EFI_ACCESS_DENIED     The protocol could not be removed from
> the ChildHandle
> +                                because its services are being used.
> +  @retval other                 The child handle was not destroyed.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsServiceBindingDestroyChild (
> +  IN EFI_SERVICE_BINDING_PROTOCOL  *This,
> +  IN EFI_HANDLE                    ChildHandle
> +  )
> +{
> +  TLS_SERVICE                    *TlsService;
> +  TLS_INSTANCE                   *TlsInstance;
> +
> +  EFI_TLS_PROTOCOL               *Tls;
> +  EFI_TLS_CONFIGURATION_PROTOCOL *TlsConfig;
> +  EFI_STATUS                     Status;
> +  EFI_TPL                        OldTpl;
> +
> +  if ((This == NULL) || (ChildHandle == NULL)) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  TlsService = TLS_SERVICE_FROM_THIS (This);
> +
> +  //
> +  // Find TLS protocol interface installed in ChildHandle
> +  //
> +  Status = gBS->OpenProtocol (
> +                  ChildHandle,
> +                  &gEfiTlsProtocolGuid,
> +                  (VOID **) &Tls,
> +                  TlsService->ImageHandle,
> +                  NULL,
> +                  EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // Find TLS configuration protocol interface installed in ChildHandle
> +  //
> +  Status = gBS->OpenProtocol (
> +                  ChildHandle,
> +                  &gEfiTlsConfigurationProtocolGuid,
> +                  (VOID **) &TlsConfig,
> +                  TlsService->ImageHandle,
> +                  NULL,
> +                  EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  TlsInstance  = TLS_INSTANCE_FROM_PROTOCOL_THIS (Tls);
> +
> +  if (TlsInstance->Service != TlsService) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (TlsInstance->InDestroy) {
> +    return EFI_SUCCESS;
> +  }
> +
> +  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
> +
> +  TlsInstance->InDestroy = TRUE;
> +
> +  //
> +  // Uninstall the TLS protocol and TLS Configuration Protocol interface
> installed in ChildHandle.
> +  //
> +  Status = gBS->UninstallMultipleProtocolInterfaces (
> +                  ChildHandle,
> +                  &gEfiTlsProtocolGuid,
> +                  Tls,
> +                  &gEfiTlsConfigurationProtocolGuid,
> +                  TlsConfig,
> +                  NULL
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  RemoveEntryList (&TlsInstance->Link);
> +  TlsService->TlsChildrenNum--;
> +
> +  gBS->RestoreTPL (OldTpl);
> +
> +  TlsCleanInstance (TlsInstance);
> +
> +  return EFI_SUCCESS;
> +}
> diff --git a/NetworkPkg/TlsDxe/TlsDriver.h b/NetworkPkg/TlsDxe/TlsDriver.h
> new file mode 100644
> index 0000000..c3c30a8
> --- /dev/null
> +++ b/NetworkPkg/TlsDxe/TlsDriver.h
> @@ -0,0 +1,237 @@
> +/** @file
> +  Header file of the Driver Binding and Service Binding Protocol for TlsDxe
> 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_TLS_DRIVER_H__
> +#define __EFI_TLS_DRIVER_H__
> +
> +#include <Uefi.h>
> +
> +//
> +// Driver Protocols
> +//
> +#include <Protocol/ServiceBinding.h>
> +
> +//
> +// Driver Version
> +//
> +#define TLS_VERSION  0x00000000
> +
> +#define TLS_SERVICE_SIGNATURE    SIGNATURE_32 ('T', 'L', 'S', 'S')
> +
> +#define TLS_INSTANCE_SIGNATURE   SIGNATURE_32 ('T', 'L', 'S', 'I')
> +
> +///
> +/// TLS Service Data
> +///
> +typedef struct _TLS_SERVICE  TLS_SERVICE;
> +
> +///
> +/// TLS Instance Data
> +///
> +typedef struct _TLS_INSTANCE TLS_INSTANCE;
> +
> +
> +struct _TLS_SERVICE {
> +  UINT32                          Signature;
> +  EFI_SERVICE_BINDING_PROTOCOL    ServiceBinding;
> +
> +  UINT16                          TlsChildrenNum;
> +  LIST_ENTRY                      TlsChildrenList;
> +
> +  //
> +  // Handle to install TlsServiceBinding protocol.
> +  //
> +  EFI_HANDLE                      Handle;
> +  EFI_HANDLE                      ImageHandle;
> +
> +  //
> +  // Main SSL Context object which is created by a server or client once per
> program
> +  // life-time and which holds mainly default values for the SSL object which
> are later
> +  // created for the connections.
> +  //
> +  VOID                            *TlsCtx;
> +};
> +
> +struct _TLS_INSTANCE {
> +  UINT32                          Signature;
> +  LIST_ENTRY                      Link;
> +
> +  BOOLEAN                         InDestroy;
> +
> +  TLS_SERVICE                     *Service;
> +  EFI_HANDLE                      ChildHandle;
> +
> +  EFI_TLS_PROTOCOL                Tls;
> +  EFI_TLS_CONFIGURATION_PROTOCOL  TlsConfig;
> +
> +  EFI_TLS_SESSION_STATE           TlsSessionState;
> +
> +  //
> +  // Main SSL Connection which is created by a server or a client
> +  // per established connection.
> +  //
> +  VOID                            *TlsConn;
> +};
> +
> +
> +#define TLS_SERVICE_FROM_THIS(a)   \
> +  CR (a, TLS_SERVICE, ServiceBinding, TLS_SERVICE_SIGNATURE)
> +
> +#define TLS_INSTANCE_FROM_PROTOCOL_THIS(a)  \
> +  CR (a, TLS_INSTANCE, Tls, TLS_INSTANCE_SIGNATURE)
> +
> +#define TLS_INSTANCE_FROM_CONFIGURATION_THIS(a)  \
> +  CR (a, TLS_INSTANCE, TlsConfig, TLS_INSTANCE_SIGNATURE)
> +
> +
> +/**
> +  Release all the resources used by the TLS instance.
> +
> +  @param[in]  Instance        The TLS instance data.
> +
> +**/
> +VOID
> +TlsCleanInstance (
> +  IN TLS_INSTANCE           *Instance
> +  );
> +
> +/**
> +  Create the TLS instance and initialize it.
> +
> +  @param[in]  Service              The pointer to the TLS service.
> +  @param[out] Instance             The pointer to the TLS instance.
> +
> +  @retval EFI_OUT_OF_RESOURCES   Failed to allocate resources.
> +  @retval EFI_SUCCESS            The TLS instance is created.
> +
> +**/
> +EFI_STATUS
> +TlsCreateInstance (
> +  IN  TLS_SERVICE         *Service,
> +  OUT TLS_INSTANCE        **Instance
> +  );
> +
> +/**
> +  Release all the resources used by the TLS service binding instance.
> +
> +  @param[in]  Service        The TLS service data.
> +
> +**/
> +VOID
> +TlsCleanService (
> +  IN TLS_SERVICE     *Service
> +  );
> +
> +/**
> +  Create then initialize a TLS service.
> +
> +  @param[in]  Image                  ImageHandle of the TLS driver
> +  @param[out] Service                The service for TLS driver
> +
> +  @retval EFI_OUT_OF_RESOURCES   Failed to allocate resource to create
> the service.
> +  @retval EFI_SUCCESS            The service is created for the driver.
> +
> +**/
> +EFI_STATUS
> +TlsCreateService (
> +  IN  EFI_HANDLE            Image,
> +  OUT TLS_SERVICE           **Service
> +  );
> +
> +/**
> +  Unloads an image.
> +
> +  @param[in]  ImageHandle       Handle that identifies the image to be
> unloaded.
> +
> +  @retval EFI_SUCCESS           The image has been unloaded.
> +  @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image
> handle.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsUnload (
> +  IN EFI_HANDLE  ImageHandle
> +  );
> +
> +/**
> +  This is the declaration of an EFI image entry point. This entry point is
> +  the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
> +  both device drivers and bus drivers.
> +
> +  @param  ImageHandle           The firmware allocated handle for the UEFI
> image.
> +  @param  SystemTable           A pointer to the EFI System Table.
> +
> +  @retval EFI_SUCCESS           The operation completed successfully.
> +  @retval Others                An unexpected error occurred.
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsDriverEntryPoint (
> +  IN EFI_HANDLE        ImageHandle,
> +  IN EFI_SYSTEM_TABLE  *SystemTable
> +  );
> +
> +/**
> +  Creates a child handle and installs a protocol.
> +
> +  The CreateChild() function installs a protocol on ChildHandle.
> +  If ChildHandle is a pointer to NULL, then a new handle is created and
> returned in ChildHandle.
> +  If ChildHandle is not a pointer to NULL, then the protocol installs on the
> existing ChildHandle.
> +
> +  @param[in] This        Pointer to the EFI_SERVICE_BINDING_PROTOCOL
> instance.
> +  @param[in] ChildHandle Pointer to the handle of the child to create. If it is
> NULL,
> +                         then a new handle is created. If it is a pointer to an existing
> UEFI handle,
> +                         then the protocol is added to the existing UEFI handle.
> +
> +  @retval EFI_SUCCES            The protocol was added to ChildHandle.
> +  @retval EFI_INVALID_PARAMETER ChildHandle is NULL.
> +  @retval EFI_OUT_OF_RESOURCES  There are not enough resources
> available to create
> +                                the child.
> +  @retval other                 The child handle was not created.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsServiceBindingCreateChild (
> +  IN EFI_SERVICE_BINDING_PROTOCOL  *This,
> +  IN EFI_HANDLE                    *ChildHandle
> +  );
> +
> +/**
> +  Destroys a child handle with a protocol installed on it.
> +
> +  The DestroyChild() function does the opposite of CreateChild(). It removes
> a protocol
> +  that was installed by CreateChild() from ChildHandle. If the removed
> protocol is the
> +  last protocol on ChildHandle, then ChildHandle is destroyed.
> +
> +  @param  This        Pointer to the EFI_SERVICE_BINDING_PROTOCOL
> instance.
> +  @param  ChildHandle Handle of the child to destroy.
> +
> +  @retval EFI_SUCCES            The protocol was removed from ChildHandle.
> +  @retval EFI_UNSUPPORTED       ChildHandle does not support the protocol
> that is being removed.
> +  @retval EFI_INVALID_PARAMETER Child handle is NULL.
> +  @retval EFI_ACCESS_DENIED     The protocol could not be removed from
> the ChildHandle
> +                                because its services are being used.
> +  @retval other                 The child handle was not destroyed.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsServiceBindingDestroyChild (
> +  IN EFI_SERVICE_BINDING_PROTOCOL  *This,
> +  IN EFI_HANDLE                    ChildHandle
> +  );
> +
> +#endif
> diff --git a/NetworkPkg/TlsDxe/TlsDxe.inf b/NetworkPkg/TlsDxe/TlsDxe.inf
> new file mode 100644
> index 0000000..dba3257
> --- /dev/null
> +++ b/NetworkPkg/TlsDxe/TlsDxe.inf
> @@ -0,0 +1,65 @@
> +## @file
> +#  This module produces EFI TLS Protocol, EFI TLS Service Binding Protocol
> and
> +#  EFI TLS Configuration Protocol.
> +#
> +#  This module produces EFI TLS (Transport Layer Security) Protocol and EFI
> TLS
> +#  Service Binding Protocol, to provide TLS services.
> +#
> +#  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.
> +#
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION               = 0x00010005
> +  BASE_NAME                 = TlsDxe
> +  FILE_GUID                 = 3aceb0c0-3c72-11e4-9a56-74d435052646
> +  MODULE_TYPE               = UEFI_DRIVER
> +  VERSION_STRING            = 1.0
> +  ENTRY_POINT               = TlsDriverEntryPoint
> +  UNLOAD_IMAGE              = TlsUnload
> +  MODULE_UNI_FILE           = TlsDxe.uni
> +
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64
> +#
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  CryptoPkg/CryptoPkg.dec
> +
> +[Sources]
> +  TlsDriver.h
> +  TlsDriver.c
> +  TlsProtocol.c
> +  TlsConfigProtocol.c
> +  TlsImpl.h
> +  TlsImpl.c
> +
> +[LibraryClasses]
> +  UefiDriverEntryPoint
> +  UefiBootServicesTableLib
> +  MemoryAllocationLib
> +  BaseMemoryLib
> +  BaseLib
> +  UefiLib
> +  DebugLib
> +  NetLib
> +  BaseCryptLib
> +  TlsLib
> +
> +[Protocols]
> +  gEfiTlsServiceBindingProtocolGuid          ## PRODUCES
> +  gEfiTlsProtocolGuid                        ## PRODUCES
> +  gEfiTlsConfigurationProtocolGuid           ## PRODUCES
> +
> +[UserExtensions.TianoCore."ExtraFiles"]
> +  TlsDxeExtra.uni
> diff --git a/NetworkPkg/TlsDxe/TlsDxe.uni b/NetworkPkg/TlsDxe/TlsDxe.uni
> new file mode 100644
> index 0000000..98c41ca
> --- /dev/null
> +++ b/NetworkPkg/TlsDxe/TlsDxe.uni
> @@ -0,0 +1,25 @@
> +// /** @file
> +// This module produces EFI TLS Protocol, EFI TLS Service Binding Protocol
> and
> +// EFI TLS Configuration Protocol.
> +//
> +// This module produces EFI TLS (Transport Layer Security) Protocol, EFI TLS
> +// Service Binding Protocol, and EFI TLS Configuration Protocol to provide
> TLS
> +// services.
> +//
> +// 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.
> +//
> +// **/
> +
> +
> +#string STR_MODULE_ABSTRACT             #language en-US "UEFI TLS service"
> +
> +#string STR_MODULE_DESCRIPTION          #language en-US "This module
> produces EFI TLS Protocol, EFI TLS Service Binding Protocol and EFI TLS
> Configuration Protocol to provide EFI TLS services."
> +
> diff --git a/NetworkPkg/TlsDxe/TlsDxeExtra.uni
> b/NetworkPkg/TlsDxe/TlsDxeExtra.uni
> new file mode 100644
> index 0000000..a38582a
> --- /dev/null
> +++ b/NetworkPkg/TlsDxe/TlsDxeExtra.uni
> @@ -0,0 +1,18 @@
> +// /** @file
> +// TlsDxe Localized Strings and Content
> +//
> +// 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.
> +//
> +// **/
> +
> +#string STR_PROPERTIES_MODULE_NAME
> +#language en-US
> +"EFI TLS DXE Driver"
> diff --git a/NetworkPkg/TlsDxe/TlsImpl.c b/NetworkPkg/TlsDxe/TlsImpl.c
> new file mode 100644
> index 0000000..9b7bf7d
> --- /dev/null
> +++ b/NetworkPkg/TlsDxe/TlsImpl.c
> @@ -0,0 +1,326 @@
> +/** @file
> +  The Miscellaneous Routines for TlsDxe 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 "TlsImpl.h"
> +
> +/**
> +  Encrypt the message listed in fragment.
> +
> +  @param[in]       TlsInstance    The pointer to the TLS instance.
> +  @param[in, out]  FragmentTable  Pointer to a list of fragment.
> +                                  On input these fragments contain the TLS header and
> +                                  plain text TLS payload;
> +                                  On output these fragments contain the TLS header and
> +                                  cipher text TLS payload.
> +  @param[in]       FragmentCount  Number of fragment.
> +
> +  @retval EFI_SUCCESS             The operation completed successfully.
> +  @retval EFI_OUT_OF_RESOURCES    Can't allocate memory resources.
> +  @retval EFI_ABORTED             TLS session state is incorrect.
> +  @retval Others                  Other errors as indicated.
> +**/
> +EFI_STATUS
> +TlsEcryptPacket (
> +  IN     TLS_INSTANCE                  *TlsInstance,
> +  IN OUT EFI_TLS_FRAGMENT_DATA         **FragmentTable,
> +  IN     UINT32                        *FragmentCount
> +  )
> +{
> +  EFI_STATUS          Status;
> +  UINTN               Index;
> +  UINT32              BytesCopied;
> +  UINT32              BufferInSize;
> +  UINT8               *BufferIn;
> +  UINT8               *BufferInPtr;
> +  TLS_RECORD_HEADER   *RecordHeaderIn;
> +  UINT16              ThisPlainMessageSize;
> +  TLS_RECORD_HEADER   *TempRecordHeader;
> +  UINT16              ThisMessageSize;
> +  UINT32              BufferOutSize;
> +  UINT8               *BufferOut;
> +  INTN                Ret;
> +
> +  Status           = EFI_SUCCESS;
> +  BytesCopied      = 0;
> +  BufferInSize     = 0;
> +  BufferIn         = NULL;
> +  BufferInPtr      = NULL;
> +  RecordHeaderIn   = NULL;
> +  TempRecordHeader = NULL;
> +  BufferOutSize    = 0;
> +  BufferOut        = NULL;
> +  Ret              = 0;
> +
> +  //
> +  // Calculate the size according to the fragment table.
> +  //
> +  for (Index = 0; Index < *FragmentCount; Index++) {
> +    BufferInSize += (*FragmentTable)[Index].FragmentLength;
> +  }
> +
> +  //
> +  // Allocate buffer for processing data.
> +  //
> +  BufferIn = AllocateZeroPool (BufferInSize);
> +  if (BufferIn == NULL) {
> +    Status = EFI_OUT_OF_RESOURCES;
> +    goto ERROR;
> +  }
> +
> +  //
> +  // Copy all TLS plain record header and payload into ProcessBuffer.
> +  //
> +  for (Index = 0; Index < *FragmentCount; Index++) {
> +    CopyMem (
> +      (BufferIn + BytesCopied),
> +      (*FragmentTable)[Index].FragmentBuffer,
> +      (*FragmentTable)[Index].FragmentLength
> +      );
> +    BytesCopied += (*FragmentTable)[Index].FragmentLength;
> +  }
> +
> +  BufferOut = AllocateZeroPool (MAX_BUFFER_SIZE);
> +  if (BufferOut == NULL) {
> +    Status = EFI_OUT_OF_RESOURCES;
> +    goto ERROR;
> +  }
> +
> +  //
> +  // Parsing buffer.
> +  //
> +  BufferInPtr = BufferIn;
> +  TempRecordHeader = (TLS_RECORD_HEADER *) BufferOut;
> +  while ((UINTN) BufferInPtr < (UINTN) BufferIn + BufferInSize) {
> +    RecordHeaderIn = (TLS_RECORD_HEADER *) BufferInPtr;
> +
> +    if (RecordHeaderIn->ContentType !=
> TLS_CONTENT_TYPE_APPLICATION_DATA) {
> +      Status = EFI_INVALID_PARAMETER;
> +      goto ERROR;
> +    }
> +
> +    ThisPlainMessageSize = RecordHeaderIn->Length;
> +
> +    TlsWrite (TlsInstance->TlsConn, (UINT8 *) (RecordHeaderIn + 1),
> ThisPlainMessageSize);
> +
> +    Ret = TlsCtrlTrafficOut (TlsInstance->TlsConn, (UINT8
> *)(TempRecordHeader), MAX_BUFFER_SIZE - BufferOutSize);
> +
> +    if (Ret > 0) {
> +      ThisMessageSize = (UINT16) Ret;
> +    } else {
> +      //
> +      // No data was successfully encrypted, continue the other messages
> encryption.
> +      //
> +      DEBUG ((EFI_D_WARN, "TlsEcryptPacket: No data read from TLS
> object.\n"));
> +
> +      ThisMessageSize = 0;
> +    }
> +
> +    BufferOutSize += ThisMessageSize;
> +
> +    BufferInPtr += RECORD_HEADER_LEN + ThisPlainMessageSize;
> +    TempRecordHeader += ThisMessageSize;
> +  }
> +
> +  FreePool (BufferIn);
> +  BufferIn = NULL;
> +
> +  //
> +  // The caller will take responsible to handle the original fragment table.
> +  //
> +  *FragmentTable = AllocateZeroPool (sizeof (EFI_TLS_FRAGMENT_DATA));
> +  if (*FragmentTable == NULL) {
> +    Status = EFI_OUT_OF_RESOURCES;
> +    goto ERROR;
> +  }
> +
> +  (*FragmentTable)[0].FragmentBuffer  = BufferOut;
> +  (*FragmentTable)[0].FragmentLength  = BufferOutSize;
> +  *FragmentCount                      = 1;
> +
> +  return Status;
> +
> +ERROR:
> +
> +  if (BufferIn != NULL) {
> +    FreePool (BufferIn);
> +    BufferIn = NULL;
> +  }
> +
> +  if (BufferOut != NULL) {
> +    FreePool (BufferOut);
> +    BufferOut = NULL;
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  Decrypt the message listed in fragment.
> +
> +  @param[in]       TlsInstance    The pointer to the TLS instance.
> +  @param[in, out]  FragmentTable  Pointer to a list of fragment.
> +                                  On input these fragments contain the TLS header and
> +                                  cipher text TLS payload;
> +                                  On output these fragments contain the TLS header and
> +                                  plain text TLS payload.
> +  @param[in]       FragmentCount  Number of fragment.
> +
> +  @retval EFI_SUCCESS             The operation completed successfully.
> +  @retval EFI_OUT_OF_RESOURCES    Can't allocate memory resources.
> +  @retval EFI_ABORTED             TLS session state is incorrect.
> +  @retval Others                  Other errors as indicated.
> +**/
> +EFI_STATUS
> +TlsDecryptPacket (
> +  IN     TLS_INSTANCE                  *TlsInstance,
> +  IN OUT EFI_TLS_FRAGMENT_DATA         **FragmentTable,
> +  IN     UINT32                        *FragmentCount
> +  )
> +{
> +  EFI_STATUS          Status;
> +  UINTN               Index;
> +  UINT32              BytesCopied;
> +  UINT8               *BufferIn;
> +  UINT32              BufferInSize;
> +  UINT8               *BufferInPtr;
> +  TLS_RECORD_HEADER   *RecordHeaderIn;
> +  UINT16              ThisCipherMessageSize;
> +  TLS_RECORD_HEADER   *TempRecordHeader;
> +  UINT16              ThisPlainMessageSize;
> +  UINT8               *BufferOut;
> +  UINT32              BufferOutSize;
> +  INTN                Ret;
> +
> +  Status           = EFI_SUCCESS;
> +  BytesCopied      = 0;
> +  BufferIn         = NULL;
> +  BufferInSize     = 0;
> +  BufferInPtr      = NULL;
> +  RecordHeaderIn   = NULL;
> +  TempRecordHeader = NULL;
> +  BufferOut        = NULL;
> +  BufferOutSize    = 0;
> +  Ret              = 0;
> +
> +  //
> +  // Calculate the size according to the fragment table.
> +  //
> +  for (Index = 0; Index < *FragmentCount; Index++) {
> +    BufferInSize += (*FragmentTable)[Index].FragmentLength;
> +  }
> +
> +  //
> +  // Allocate buffer for processing data
> +  //
> +  BufferIn = AllocateZeroPool (BufferInSize);
> +  if (BufferIn == NULL) {
> +    Status = EFI_OUT_OF_RESOURCES;
> +    goto ERROR;
> +  }
> +
> +  //
> +  // Copy all TLS plain record header and payload to ProcessBuffer
> +  //
> +  for (Index = 0; Index < *FragmentCount; Index++) {
> +    CopyMem (
> +      (BufferIn + BytesCopied),
> +      (*FragmentTable)[Index].FragmentBuffer,
> +      (*FragmentTable)[Index].FragmentLength
> +      );
> +    BytesCopied += (*FragmentTable)[Index].FragmentLength;
> +  }
> +
> +  BufferOut = AllocateZeroPool (MAX_BUFFER_SIZE);
> +  if (BufferOut == NULL) {
> +    Status = EFI_OUT_OF_RESOURCES;
> +    goto ERROR;
> +  }
> +
> +  //
> +  // Parsing buffer. Received packet may have multiply TLS record message.
> +  //
> +  BufferInPtr = BufferIn;
> +  TempRecordHeader = (TLS_RECORD_HEADER *) BufferOut;
> +  while ((UINTN) BufferInPtr < (UINTN) BufferIn + BufferInSize) {
> +    RecordHeaderIn = (TLS_RECORD_HEADER *) BufferInPtr;
> +
> +    if (RecordHeaderIn->ContentType !=
> TLS_CONTENT_TYPE_APPLICATION_DATA) {
> +      Status = EFI_INVALID_PARAMETER;
> +      goto ERROR;
> +    }
> +
> +    ThisCipherMessageSize = NTOHS (RecordHeaderIn->Length);
> +
> +    Ret = TlsCtrlTrafficIn (TlsInstance->TlsConn, (UINT8 *) (RecordHeaderIn),
> RECORD_HEADER_LEN + ThisCipherMessageSize);
> +    if (Ret != RECORD_HEADER_LEN + ThisCipherMessageSize) {
> +      TlsInstance->TlsSessionState = EfiTlsSessionError;
> +      Status = EFI_ABORTED;
> +      goto ERROR;
> +    }
> +
> +    Ret = 0;
> +    Ret = TlsRead (TlsInstance->TlsConn, (UINT8 *) (TempRecordHeader + 1),
> MAX_BUFFER_SIZE - BufferOutSize);
> +
> +    if (Ret > 0) {
> +      ThisPlainMessageSize = (UINT16) Ret;
> +    } else {
> +      //
> +      // No data was successfully decrypted, continue the other messages
> decryption.
> +      //
> +      DEBUG ((EFI_D_WARN, "TlsDecryptPacket: No data read from TLS
> object.\n"));
> +
> +      ThisPlainMessageSize = 0;
> +    }
> +
> +    CopyMem (TempRecordHeader, RecordHeaderIn,
> RECORD_HEADER_LEN);
> +    TempRecordHeader->Length = ThisPlainMessageSize;
> +    BufferOutSize += RECORD_HEADER_LEN + ThisPlainMessageSize;
> +
> +    BufferInPtr += RECORD_HEADER_LEN + ThisCipherMessageSize;
> +    TempRecordHeader += RECORD_HEADER_LEN + ThisPlainMessageSize;
> +  }
> +
> +  FreePool (BufferIn);
> +  BufferIn = NULL;
> +
> +  //
> +  // The caller will take responsible to handle the original fragment table
> +  //
> +  *FragmentTable = AllocateZeroPool (sizeof (EFI_TLS_FRAGMENT_DATA));
> +  if (*FragmentTable == NULL) {
> +    Status = EFI_OUT_OF_RESOURCES;
> +    goto ERROR;
> +  }
> +
> +  (*FragmentTable)[0].FragmentBuffer  = BufferOut;
> +  (*FragmentTable)[0].FragmentLength  = BufferOutSize;
> +  *FragmentCount                      = 1;
> +
> +  return Status;
> +
> +ERROR:
> +
> +  if (BufferIn != NULL) {
> +    FreePool (BufferIn);
> +    BufferIn = NULL;
> +  }
> +
> +  if (BufferOut != NULL) {
> +    FreePool (BufferOut);
> +    BufferOut = NULL;
> +  }
> +
> +  return Status;
> +}
> diff --git a/NetworkPkg/TlsDxe/TlsImpl.h b/NetworkPkg/TlsDxe/TlsImpl.h
> new file mode 100644
> index 0000000..b0615cb
> --- /dev/null
> +++ b/NetworkPkg/TlsDxe/TlsImpl.h
> @@ -0,0 +1,315 @@
> +/** @file
> +  Header file of Miscellaneous Routines for TlsDxe 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_TLS_IMPL_H__
> +#define __EFI_TLS_IMPL_H__
> +
> +//
> +// Libraries
> +//
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/UefiLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/NetLib.h>
> +#include <Library/BaseCryptLib.h>
> +#include <Library/TlsLib.h>
> +
> +//
> +// Consumed Protocols
> +//
> +#include <Protocol/Tls.h>
> +#include <Protocol/TlsConfig.h>
> +
> +#include <IndustryStandard/Tls1.h>
> +
> +#include "TlsDriver.h"
> +
> +//
> +// Protocol instances
> +//
> +extern EFI_SERVICE_BINDING_PROTOCOL    mTlsServiceBinding;
> +extern EFI_TLS_PROTOCOL                mTlsProtocol;
> +extern EFI_TLS_CONFIGURATION_PROTOCOL  mTlsConfigurationProtocol;
> +
> +#define RECORD_HEADER_LEN 5 /// ContentType(1) + Version(2) +
> Length(2)
> +
> +#define MAX_BUFFER_SIZE   32768
> +
> +/**
> +  Encrypt the message listed in fragment.
> +
> +  @param[in]       TlsInstance    The pointer to the TLS instance.
> +  @param[in, out]  FragmentTable  Pointer to a list of fragment.
> +                                  On input these fragments contain the TLS header and
> +                                  plain text TLS payload;
> +                                  On output these fragments contain the TLS header and
> +                                  cipher text TLS payload.
> +  @param[in]       FragmentCount  Number of fragment.
> +
> +  @retval EFI_SUCCESS             The operation completed successfully.
> +  @retval EFI_OUT_OF_RESOURCES    Can't allocate memory resources.
> +  @retval EFI_ABORTED             TLS session state is incorrect.
> +  @retval Others                  Other errors as indicated.
> +**/
> +EFI_STATUS
> +TlsEcryptPacket (
> +  IN     TLS_INSTANCE                  *TlsInstance,
> +  IN OUT EFI_TLS_FRAGMENT_DATA         **FragmentTable,
> +  IN     UINT32                        *FragmentCount
> +  );
> +
> +/**
> +  Decrypt the message listed in fragment.
> +
> +  @param[in]       TlsInstance    The pointer to the TLS instance.
> +  @param[in, out]  FragmentTable  Pointer to a list of fragment.
> +                                  On input these fragments contain the TLS header and
> +                                  cipher text TLS payload;
> +                                  On output these fragments contain the TLS header and
> +                                  plain text TLS payload.
> +  @param[in]       FragmentCount  Number of fragment.
> +
> +  @retval EFI_SUCCESS             The operation completed successfully.
> +  @retval EFI_OUT_OF_RESOURCES    Can't allocate memory resources.
> +  @retval EFI_ABORTED             TLS session state is incorrect.
> +  @retval Others                  Other errors as indicated.
> +**/
> +EFI_STATUS
> +TlsDecryptPacket (
> +  IN     TLS_INSTANCE                  *TlsInstance,
> +  IN OUT EFI_TLS_FRAGMENT_DATA         **FragmentTable,
> +  IN     UINT32                        *FragmentCount
> +  );
> +
> +/**
> +  Set TLS session data.
> +
> +  The SetSessionData() function set data for a new TLS session. All session
> data should
> +  be set before BuildResponsePacket() invoked.
> +
> +  @param[in]  This                Pointer to the EFI_TLS_PROTOCOL instance.
> +  @param[in]  DataType            TLS session data type.
> +  @param[in]  Data                Pointer to session data.
> +  @param[in]  DataSize            Total size of session data.
> +
> +  @retval EFI_SUCCESS             The TLS session data is set successfully.
> +  @retval EFI_INVALID_PARAMETER   One or more of the following
> conditions is TRUE:
> +                                  This is NULL.
> +                                  Data is NULL.
> +                                  DataSize is 0.
> +  @retval EFI_UNSUPPORTED         The DataType is unsupported.
> +  @retval EFI_ACCESS_DENIED       If the DataType is one of below:
> +                                  EfiTlsClientRandom
> +                                  EfiTlsServerRandom
> +                                  EfiTlsKeyMaterial
> +  @retval EFI_NOT_READY           Current TLS session state is NOT
> +                                  EfiTlsSessionStateNotStarted.
> +  @retval EFI_OUT_OF_RESOURCES    Required system resources could not
> be allocated.
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsSetSessionData (
> +  IN     EFI_TLS_PROTOCOL              *This,
> +  IN     EFI_TLS_SESSION_DATA_TYPE     DataType,
> +  IN     VOID                          *Data,
> +  IN     UINTN                         DataSize
> +  );
> +
> +/**
> +  Get TLS session data.
> +
> +  The GetSessionData() function return the TLS session information.
> +
> +  @param[in]       This           Pointer to the EFI_TLS_PROTOCOL instance.
> +  @param[in]       DataType       TLS session data type.
> +  @param[in, out]  Data           Pointer to session data.
> +  @param[in, out]  DataSize       Total size of session data. On input, it means
> +                                  the size of Data buffer. On output, it means the size
> +                                  of copied Data buffer if EFI_SUCCESS, and means the
> +                                  size of desired Data buffer if EFI_BUFFER_TOO_SMALL.
> +
> +  @retval EFI_SUCCESS             The TLS session data is got successfully.
> +  @retval EFI_INVALID_PARAMETER   One or more of the following
> conditions is TRUE:
> +                                  This is NULL.
> +                                  DataSize is NULL.
> +                                  Data is NULL if *DataSize is not zero.
> +  @retval EFI_UNSUPPORTED         The DataType is unsupported.
> +  @retval EFI_NOT_FOUND           The TLS session data is not found.
> +  @retval EFI_NOT_READY           The DataType is not ready in current session
> state.
> +  @retval EFI_BUFFER_TOO_SMALL    The buffer is too small to hold the data.
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsGetSessionData (
> +  IN     EFI_TLS_PROTOCOL              *This,
> +  IN     EFI_TLS_SESSION_DATA_TYPE     DataType,
> +  IN OUT VOID                          *Data,  OPTIONAL
> +  IN OUT UINTN                         *DataSize
> +  );
> +
> +/**
> +  Build response packet according to TLS state machine. This function is only
> valid for
> +  alert, handshake and change_cipher_spec content type.
> +
> +  The BuildResponsePacket() function builds TLS response packet in
> response to the TLS
> +  request packet specified by RequestBuffer and RequestSize. If
> RequestBuffer is NULL and
> +  RequestSize is 0, and TLS session status is EfiTlsSessionNotStarted, the TLS
> session
> +  will be initiated and the response packet needs to be ClientHello. If
> RequestBuffer is
> +  NULL and RequestSize is 0, and TLS session status is EfiTlsSessionClosing,
> the TLS
> +  session will be closed and response packet needs to be CloseNotify. If
> RequestBuffer is
> +  NULL and RequestSize is 0, and TLS session status is EfiTlsSessionError, the
> TLS
> +  session has errors and the response packet needs to be Alert message
> based on error
> +  type.
> +
> +  @param[in]       This           Pointer to the EFI_TLS_PROTOCOL instance.
> +  @param[in]       RequestBuffer  Pointer to the most recently received TLS
> packet. NULL
> +                                  means TLS need initiate the TLS session and response
> +                                  packet need to be ClientHello.
> +  @param[in]       RequestSize    Packet size in bytes for the most recently
> received TLS
> +                                  packet. 0 is only valid when RequestBuffer is NULL.
> +  @param[out]      Buffer         Pointer to the buffer to hold the built packet.
> +  @param[in, out]  BufferSize     Pointer to the buffer size in bytes. On input,
> it is
> +                                  the buffer size provided by the caller. On output, it
> +                                  is the buffer size in fact needed to contain the
> +                                  packet.
> +
> +  @retval EFI_SUCCESS             The required TLS packet is built successfully.
> +  @retval EFI_INVALID_PARAMETER   One or more of the following
> conditions is TRUE:
> +                                  This is NULL.
> +                                  RequestBuffer is NULL but RequestSize is NOT 0.
> +                                  RequestSize is 0 but RequestBuffer is NOT NULL.
> +                                  BufferSize is NULL.
> +                                  Buffer is NULL if *BufferSize is not zero.
> +  @retval EFI_BUFFER_TOO_SMALL    BufferSize is too small to hold the
> response packet.
> +  @retval EFI_NOT_READY           Current TLS session state is NOT ready to
> build
> +                                  ResponsePacket.
> +  @retval EFI_ABORTED             Something wrong build response packet.
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsBuildResponsePacket (
> +  IN     EFI_TLS_PROTOCOL              *This,
> +  IN     UINT8                         *RequestBuffer, OPTIONAL
> +  IN     UINTN                         RequestSize, OPTIONAL
> +     OUT UINT8                         *Buffer, OPTIONAL
> +  IN OUT UINTN                         *BufferSize
> +  );
> +
> +/**
> +  Decrypt or encrypt TLS packet during session. This function is only valid
> after
> +  session connected and for application_data content type.
> +
> +  The ProcessPacket () function process each inbound or outbound TLS APP
> packet.
> +
> +  @param[in]       This           Pointer to the EFI_TLS_PROTOCOL instance.
> +  @param[in, out]  FragmentTable  Pointer to a list of fragment. The caller
> will take
> +                                  responsible to handle the original FragmentTable while
> +                                  it may be reallocated in TLS driver. If CryptMode is
> +                                  EfiTlsEncrypt, on input these fragments contain the TLS
> +                                  header and plain text TLS APP payload; on output these
> +                                  fragments contain the TLS header and cipher text TLS
> +                                  APP payload. If CryptMode is EfiTlsDecrypt, on input
> +                                  these fragments contain the TLS header and cipher text
> +                                  TLS APP payload; on output these fragments contain the
> +                                  TLS header and plain text TLS APP payload.
> +  @param[in]       FragmentCount  Number of fragment.
> +  @param[in]       CryptMode      Crypt mode.
> +
> +  @retval EFI_SUCCESS             The operation completed successfully.
> +  @retval EFI_INVALID_PARAMETER   One or more of the following
> conditions is TRUE:
> +                                  This is NULL.
> +                                  FragmentTable is NULL.
> +                                  FragmentCount is NULL.
> +                                  CryptoMode is invalid.
> +  @retval EFI_NOT_READY           Current TLS session state is NOT
> +                                  EfiTlsSessionDataTransferring.
> +  @retval EFI_ABORTED             Something wrong decryption the message.
> TLS session
> +                                  status will become EfiTlsSessionError. The caller need
> +                                  call BuildResponsePacket() to generate Error Alert
> +                                  message and send it out.
> +  @retval EFI_OUT_OF_RESOURCES    No enough resource to finish the
> operation.
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsProcessPacket (
> +  IN     EFI_TLS_PROTOCOL              *This,
> +  IN OUT EFI_TLS_FRAGMENT_DATA         **FragmentTable,
> +  IN     UINT32                        *FragmentCount,
> +  IN     EFI_TLS_CRYPT_MODE            CryptMode
> +  );
> +
> +/**
> +  Set TLS configuration data.
> +
> +  The SetData() function sets TLS configuration to non-volatile storage or
> volatile
> +  storage.
> +
> +  @param[in]  This                Pointer to the
> EFI_TLS_CONFIGURATION_PROTOCOL instance.
> +  @param[in]  DataType            Configuration data type.
> +  @param[in]  Data                Pointer to configuration data.
> +  @param[in]  DataSize            Total size of configuration data.
> +
> +  @retval EFI_SUCCESS             The TLS configuration data is set successfully.
> +  @retval EFI_INVALID_PARAMETER   One or more of the following
> conditions is TRUE:
> +                                  This is NULL.
> +                                  Data is NULL.
> +                                  DataSize is 0.
> +  @retval EFI_UNSUPPORTED         The DataType is unsupported.
> +  @retval EFI_OUT_OF_RESOURCES    Required system resources could not
> be allocated.
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsConfigurationSetData (
> +  IN     EFI_TLS_CONFIGURATION_PROTOCOL  *This,
> +  IN     EFI_TLS_CONFIG_DATA_TYPE        DataType,
> +  IN     VOID                            *Data,
> +  IN     UINTN                           DataSize
> +  );
> +
> +/**
> +  Get TLS configuration data.
> +
> +  The GetData() function gets TLS configuration.
> +
> +  @param[in]       This           Pointer to the
> EFI_TLS_CONFIGURATION_PROTOCOL instance.
> +  @param[in]       DataType       Configuration data type.
> +  @param[in, out]  Data           Pointer to configuration data.
> +  @param[in, out]  DataSize       Total size of configuration data. On input, it
> means
> +                                  the size of Data buffer. On output, it means the size
> +                                  of copied Data buffer if EFI_SUCCESS, and means the
> +                                  size of desired Data buffer if EFI_BUFFER_TOO_SMALL.
> +
> +  @retval EFI_SUCCESS             The TLS configuration data is got successfully.
> +  @retval EFI_INVALID_PARAMETER   One or more of the following
> conditions is TRUE:
> +                                  This is NULL.
> +                                  DataSize is NULL.
> +                                  Data is NULL if *DataSize is not zero.
> +  @retval EFI_UNSUPPORTED         The DataType is unsupported.
> +  @retval EFI_NOT_FOUND           The TLS configuration data is not found.
> +  @retval EFI_BUFFER_TOO_SMALL    The buffer is too small to hold the data.
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsConfigurationGetData (
> +  IN     EFI_TLS_CONFIGURATION_PROTOCOL  *This,
> +  IN     EFI_TLS_CONFIG_DATA_TYPE        DataType,
> +  IN OUT VOID                            *Data, OPTIONAL
> +  IN OUT UINTN                           *DataSize
> +  );
> +
> +#endif
> diff --git a/NetworkPkg/TlsDxe/TlsProtocol.c
> b/NetworkPkg/TlsDxe/TlsProtocol.c
> new file mode 100644
> index 0000000..bc617e1
> --- /dev/null
> +++ b/NetworkPkg/TlsDxe/TlsProtocol.c
> @@ -0,0 +1,632 @@
> +/** @file
> +  Implementation of EFI TLS Protocol Interfaces.
> +
> +  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 "TlsImpl.h"
> +
> +EFI_TLS_PROTOCOL  mTlsProtocol = {
> +  TlsSetSessionData,
> +  TlsGetSessionData,
> +  TlsBuildResponsePacket,
> +  TlsProcessPacket
> +};
> +
> +/**
> +  Set TLS session data.
> +
> +  The SetSessionData() function set data for a new TLS session. All session
> data should
> +  be set before BuildResponsePacket() invoked.
> +
> +  @param[in]  This                Pointer to the EFI_TLS_PROTOCOL instance.
> +  @param[in]  DataType            TLS session data type.
> +  @param[in]  Data                Pointer to session data.
> +  @param[in]  DataSize            Total size of session data.
> +
> +  @retval EFI_SUCCESS             The TLS session data is set successfully.
> +  @retval EFI_INVALID_PARAMETER   One or more of the following
> conditions is TRUE:
> +                                  This is NULL.
> +                                  Data is NULL.
> +                                  DataSize is 0.
> +  @retval EFI_UNSUPPORTED         The DataType is unsupported.
> +  @retval EFI_ACCESS_DENIED       If the DataType is one of below:
> +                                  EfiTlsClientRandom
> +                                  EfiTlsServerRandom
> +                                  EfiTlsKeyMaterial
> +  @retval EFI_NOT_READY           Current TLS session state is NOT
> +                                  EfiTlsSessionStateNotStarted.
> +  @retval EFI_OUT_OF_RESOURCES    Required system resources could not
> be allocated.
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsSetSessionData (
> +  IN     EFI_TLS_PROTOCOL              *This,
> +  IN     EFI_TLS_SESSION_DATA_TYPE     DataType,
> +  IN     VOID                          *Data,
> +  IN     UINTN                         DataSize
> +  )
> +{
> +  EFI_STATUS                Status;
> +  TLS_INSTANCE              *Instance;
> +  UINT16                    *CipherId;
> +  UINTN                     Index;
> +
> +  EFI_TPL                   OldTpl;
> +
> +  Status = EFI_SUCCESS;
> +  CipherId = NULL;
> +
> +  if (This == NULL || Data == NULL || DataSize == 0) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
> +
> +  Instance = TLS_INSTANCE_FROM_PROTOCOL_THIS (This);
> +
> +  if (DataType != EfiTlsSessionState  && Instance->TlsSessionState !=
> EfiTlsSessionNotStarted){
> +    Status = EFI_NOT_READY;
> +    goto ON_EXIT;
> +  }
> +
> +  switch (DataType) {
> +  //
> +  // Session Configuration
> +  //
> +  case EfiTlsVersion:
> +    if (DataSize != sizeof (EFI_TLS_VERSION)) {
> +      Status = EFI_INVALID_PARAMETER;
> +      goto ON_EXIT;
> +    }
> +
> +    Status = TlsSetVersion (Instance->TlsConn, ((EFI_TLS_VERSION *) Data)-
> >Major, ((EFI_TLS_VERSION *) Data)->Minor);
> +    break;
> +  case EfiTlsConnectionEnd:
> +    if (DataSize != sizeof (EFI_TLS_CONNECTION_END)) {
> +      Status = EFI_INVALID_PARAMETER;
> +      goto ON_EXIT;
> +    }
> +
> +    Status = TlsSetConnectionEnd (Instance->TlsConn,
> *((EFI_TLS_CONNECTION_END *) Data));
> +    break;
> +  case EfiTlsCipherList:
> +    CipherId = AllocatePool (DataSize);
> +    if (CipherId == NULL) {
> +      Status = EFI_OUT_OF_RESOURCES;
> +      goto ON_EXIT;
> +    }
> +
> +    for (Index = 0; Index < DataSize / sizeof (EFI_TLS_CIPHER); Index++) {
> +      *(CipherId +Index) = HTONS (*(((UINT16 *) Data) + Index));
> +    }
> +
> +    Status = TlsSetCipherList (Instance->TlsConn, CipherId, DataSize / sizeof
> (EFI_TLS_CIPHER));
> +
> +    FreePool (CipherId);
> +    break;
> +  case EfiTlsCompressionMethod:
> +    //
> +    // TLS seems only define one CompressionMethod.null, which specifies
> that data exchanged via the
> +    // record protocol will not be compressed.
> +    // More information from OpenSSL:
> http://www.openssl.org/docs/manmaster/ssl/SSL_COMP_add_compressio
> n_method.html
> +    // The TLS RFC does however not specify compression methods or their
> corresponding identifiers,
> +    // so there is currently no compatible way to integrate compression with
> unknown peers.
> +    // It is therefore currently not recommended to integrate compression
> into applications.
> +    // Applications for non-public use may agree on certain compression
> methods.
> +    // Using different compression methods with the same identifier will lead
> to connection failure.
> +    //
> +    for (Index = 0; Index < DataSize / sizeof (EFI_TLS_COMPRESSION);
> Index++) {
> +      Status = TlsSetCompressionMethod (*((UINT8 *) Data + Index));
> +      if (EFI_ERROR (Status)) {
> +        break;
> +      }
> +    }
> +
> +    break;
> +  case EfiTlsExtensionData:
> +    Status = EFI_UNSUPPORTED;
> +    goto ON_EXIT;
> +  case EfiTlsVerifyMethod:
> +    if (DataSize != sizeof (EFI_TLS_VERIFY)) {
> +      Status = EFI_INVALID_PARAMETER;
> +      goto ON_EXIT;
> +    }
> +
> +    TlsSetVerify (Instance->TlsConn, *((UINT32 *) Data));
> +    break;
> +  case EfiTlsSessionID:
> +    if (DataSize != sizeof (EFI_TLS_SESSION_ID)) {
> +      Status = EFI_INVALID_PARAMETER;
> +      goto ON_EXIT;
> +    }
> +
> +    Status = TlsSetSessionId (
> +               Instance->TlsConn,
> +               ((EFI_TLS_SESSION_ID *) Data)->Data,
> +               ((EFI_TLS_SESSION_ID *) Data)->Length
> +               );
> +    break;
> +  case EfiTlsSessionState:
> +    if (DataSize != sizeof (EFI_TLS_SESSION_STATE)) {
> +      Status = EFI_INVALID_PARAMETER;
> +      goto ON_EXIT;
> +    }
> +
> +    Instance->TlsSessionState = *(EFI_TLS_SESSION_STATE *) Data;
> +    break;
> +  //
> +  // Session information
> +  //
> +  case EfiTlsClientRandom:
> +    Status = EFI_ACCESS_DENIED;
> +    break;
> +  case EfiTlsServerRandom:
> +    Status = EFI_ACCESS_DENIED;
> +    break;
> +  case EfiTlsKeyMaterial:
> +    Status = EFI_ACCESS_DENIED;
> +    break;
> +  //
> +  // Unsupported type.
> +  //
> +  default:
> +    Status = EFI_UNSUPPORTED;
> +  }
> +
> +ON_EXIT:
> +  gBS->RestoreTPL (OldTpl);
> +  return Status;
> +}
> +
> +/**
> +  Get TLS session data.
> +
> +  The GetSessionData() function return the TLS session information.
> +
> +  @param[in]       This           Pointer to the EFI_TLS_PROTOCOL instance.
> +  @param[in]       DataType       TLS session data type.
> +  @param[in, out]  Data           Pointer to session data.
> +  @param[in, out]  DataSize       Total size of session data. On input, it means
> +                                  the size of Data buffer. On output, it means the size
> +                                  of copied Data buffer if EFI_SUCCESS, and means the
> +                                  size of desired Data buffer if EFI_BUFFER_TOO_SMALL.
> +
> +  @retval EFI_SUCCESS             The TLS session data is got successfully.
> +  @retval EFI_INVALID_PARAMETER   One or more of the following
> conditions is TRUE:
> +                                  This is NULL.
> +                                  DataSize is NULL.
> +                                  Data is NULL if *DataSize is not zero.
> +  @retval EFI_UNSUPPORTED         The DataType is unsupported.
> +  @retval EFI_NOT_FOUND           The TLS session data is not found.
> +  @retval EFI_NOT_READY           The DataType is not ready in current session
> state.
> +  @retval EFI_BUFFER_TOO_SMALL    The buffer is too small to hold the data.
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsGetSessionData (
> +  IN     EFI_TLS_PROTOCOL              *This,
> +  IN     EFI_TLS_SESSION_DATA_TYPE     DataType,
> +  IN OUT VOID                          *Data,  OPTIONAL
> +  IN OUT UINTN                         *DataSize
> +  )
> +{
> +  EFI_STATUS                Status;
> +  TLS_INSTANCE              *Instance;
> +
> +  EFI_TPL                   OldTpl;
> +
> +  Status = EFI_SUCCESS;
> +
> +  if (This == NULL || DataSize == NULL || (Data == NULL && *DataSize != 0))
> {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
> +
> +  Instance = TLS_INSTANCE_FROM_PROTOCOL_THIS (This);
> +
> +  if (Instance->TlsSessionState == EfiTlsSessionNotStarted &&
> +    (DataType == EfiTlsSessionID || DataType == EfiTlsClientRandom ||
> +    DataType == EfiTlsServerRandom || DataType == EfiTlsKeyMaterial)) {
> +    Status = EFI_NOT_READY;
> +    goto ON_EXIT;
> +  }
> +
> +  switch (DataType) {
> +  case EfiTlsVersion:
> +    if (*DataSize < sizeof (EFI_TLS_VERSION)) {
> +      *DataSize = sizeof (EFI_TLS_VERSION);
> +      Status = EFI_BUFFER_TOO_SMALL;
> +      goto ON_EXIT;
> +    }
> +    *DataSize = sizeof (EFI_TLS_VERSION);
> +    *((UINT16 *) Data) = HTONS (TlsGetVersion (Instance->TlsConn));
> +    break;
> +  case EfiTlsConnectionEnd:
> +    if (*DataSize < sizeof (EFI_TLS_CONNECTION_END)) {
> +      *DataSize = sizeof (EFI_TLS_CONNECTION_END);
> +      Status = EFI_BUFFER_TOO_SMALL;
> +      goto ON_EXIT;
> +    }
> +    *DataSize = sizeof (EFI_TLS_CONNECTION_END);
> +    *((UINT8 *) Data) = TlsGetConnectionEnd (Instance->TlsConn);
> +    break;
> +  case EfiTlsCipherList:
> +    //
> +    // Get the current session cipher suite.
> +    //
> +    if (*DataSize < sizeof (EFI_TLS_CIPHER)) {
> +      *DataSize = sizeof (EFI_TLS_CIPHER);
> +      Status = EFI_BUFFER_TOO_SMALL;
> +      goto ON_EXIT;
> +    }
> +    *DataSize = sizeof(EFI_TLS_CIPHER);
> +    Status = TlsGetCurrentCipher (Instance->TlsConn, (UINT16 *) Data);
> +    *((UINT16 *) Data) = HTONS (*((UINT16 *) Data));
> +    break;
> +  case EfiTlsCompressionMethod:
> +    //
> +    // Get the current session compression method.
> +    //
> +    if (*DataSize < sizeof (EFI_TLS_COMPRESSION)) {
> +      *DataSize = sizeof (EFI_TLS_COMPRESSION);
> +      Status = EFI_BUFFER_TOO_SMALL;
> +      goto ON_EXIT;
> +    }
> +    *DataSize = sizeof (EFI_TLS_COMPRESSION);
> +    Status = TlsGetCurrentCompressionId (Instance->TlsConn, (UINT8 *)
> Data);
> +    break;
> +  case EfiTlsExtensionData:
> +    Status = EFI_UNSUPPORTED;
> +    goto ON_EXIT;
> +  case EfiTlsVerifyMethod:
> +    if (*DataSize < sizeof (EFI_TLS_VERIFY)) {
> +      *DataSize = sizeof (EFI_TLS_VERIFY);
> +      Status = EFI_BUFFER_TOO_SMALL;
> +      goto ON_EXIT;
> +    }
> +    *DataSize = sizeof (EFI_TLS_VERIFY);
> +    *((UINT32 *) Data) = TlsGetVerify (Instance->TlsConn);
> +    break;
> +  case EfiTlsSessionID:
> +    if (*DataSize < sizeof (EFI_TLS_SESSION_ID)) {
> +      *DataSize = sizeof (EFI_TLS_SESSION_ID);
> +      Status = EFI_BUFFER_TOO_SMALL;
> +      goto ON_EXIT;
> +    }
> +    *DataSize = sizeof (EFI_TLS_SESSION_ID);
> +    Status = TlsGetSessionId (
> +               Instance->TlsConn,
> +               ((EFI_TLS_SESSION_ID *) Data)->Data,
> +               &(((EFI_TLS_SESSION_ID *) Data)->Length)
> +               );
> +    break;
> +  case EfiTlsSessionState:
> +    if (*DataSize < sizeof (EFI_TLS_SESSION_STATE)) {
> +      *DataSize = sizeof (EFI_TLS_SESSION_STATE);
> +      Status = EFI_BUFFER_TOO_SMALL;
> +      goto ON_EXIT;
> +    }
> +    *DataSize = sizeof (EFI_TLS_SESSION_STATE);
> +    CopyMem (Data, &Instance->TlsSessionState, *DataSize);
> +    break;
> +  case EfiTlsClientRandom:
> +    if (*DataSize < sizeof (EFI_TLS_RANDOM)) {
> +      *DataSize = sizeof (EFI_TLS_RANDOM);
> +      Status = EFI_BUFFER_TOO_SMALL;
> +      goto ON_EXIT;
> +    }
> +    *DataSize = sizeof (EFI_TLS_RANDOM);
> +    TlsGetClientRandom (Instance->TlsConn, (UINT8 *) Data);
> +    break;
> +  case EfiTlsServerRandom:
> +    if (*DataSize < sizeof (EFI_TLS_RANDOM)) {
> +      *DataSize = sizeof (EFI_TLS_RANDOM);
> +      Status = EFI_BUFFER_TOO_SMALL;
> +      goto ON_EXIT;
> +    }
> +    *DataSize = sizeof (EFI_TLS_RANDOM);
> +    TlsGetServerRandom (Instance->TlsConn, (UINT8 *) Data);
> +    break;
> +  case EfiTlsKeyMaterial:
> +    if (*DataSize < sizeof (EFI_TLS_MASTER_SECRET)) {
> +      *DataSize = sizeof (EFI_TLS_MASTER_SECRET);
> +      Status = EFI_BUFFER_TOO_SMALL;
> +      goto ON_EXIT;
> +    }
> +    *DataSize = sizeof (EFI_TLS_MASTER_SECRET);
> +    Status = TlsGetKeyMaterial (Instance->TlsConn, (UINT8 *) Data);
> +    break;
> +  //
> +  // Unsupported type.
> +  //
> +  default:
> +    Status = EFI_UNSUPPORTED;
> +  }
> +
> +ON_EXIT:
> +  gBS->RestoreTPL (OldTpl);
> +  return Status;
> +}
> +
> +/**
> +  Build response packet according to TLS state machine. This function is only
> valid for
> +  alert, handshake and change_cipher_spec content type.
> +
> +  The BuildResponsePacket() function builds TLS response packet in
> response to the TLS
> +  request packet specified by RequestBuffer and RequestSize. If
> RequestBuffer is NULL and
> +  RequestSize is 0, and TLS session status is EfiTlsSessionNotStarted, the TLS
> session
> +  will be initiated and the response packet needs to be ClientHello. If
> RequestBuffer is
> +  NULL and RequestSize is 0, and TLS session status is EfiTlsSessionClosing,
> the TLS
> +  session will be closed and response packet needs to be CloseNotify. If
> RequestBuffer is
> +  NULL and RequestSize is 0, and TLS session status is EfiTlsSessionError, the
> TLS
> +  session has errors and the response packet needs to be Alert message
> based on error
> +  type.
> +
> +  @param[in]       This           Pointer to the EFI_TLS_PROTOCOL instance.
> +  @param[in]       RequestBuffer  Pointer to the most recently received TLS
> packet. NULL
> +                                  means TLS need initiate the TLS session and response
> +                                  packet need to be ClientHello.
> +  @param[in]       RequestSize    Packet size in bytes for the most recently
> received TLS
> +                                  packet. 0 is only valid when RequestBuffer is NULL.
> +  @param[out]      Buffer         Pointer to the buffer to hold the built packet.
> +  @param[in, out]  BufferSize     Pointer to the buffer size in bytes. On input,
> it is
> +                                  the buffer size provided by the caller. On output, it
> +                                  is the buffer size in fact needed to contain the
> +                                  packet.
> +
> +  @retval EFI_SUCCESS             The required TLS packet is built successfully.
> +  @retval EFI_INVALID_PARAMETER   One or more of the following
> conditions is TRUE:
> +                                  This is NULL.
> +                                  RequestBuffer is NULL but RequestSize is NOT 0.
> +                                  RequestSize is 0 but RequestBuffer is NOT NULL.
> +                                  BufferSize is NULL.
> +                                  Buffer is NULL if *BufferSize is not zero.
> +  @retval EFI_BUFFER_TOO_SMALL    BufferSize is too small to hold the
> response packet.
> +  @retval EFI_NOT_READY           Current TLS session state is NOT ready to
> build
> +                                  ResponsePacket.
> +  @retval EFI_ABORTED             Something wrong build response packet.
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsBuildResponsePacket (
> +  IN     EFI_TLS_PROTOCOL              *This,
> +  IN     UINT8                         *RequestBuffer, OPTIONAL
> +  IN     UINTN                         RequestSize, OPTIONAL
> +     OUT UINT8                         *Buffer, OPTIONAL
> +  IN OUT UINTN                         *BufferSize
> +  )
> +{
> +  EFI_STATUS                Status;
> +  TLS_INSTANCE              *Instance;
> +  EFI_TPL                   OldTpl;
> +
> +  Status = EFI_SUCCESS;
> +
> +  if ((This == NULL) || (BufferSize == NULL) ||
> +      (RequestBuffer == NULL && RequestSize != 0) ||
> +      (RequestBuffer != NULL && RequestSize == 0) ||
> +      (Buffer == NULL && *BufferSize !=0)) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
> +
> +  Instance = TLS_INSTANCE_FROM_PROTOCOL_THIS (This);
> +
> +  if(RequestBuffer == NULL && RequestSize == 0) {
> +    switch (Instance->TlsSessionState) {
> +    case EfiTlsSessionNotStarted:
> +      //
> +      // ClientHello.
> +      //
> +      Status = TlsDoHandshake (
> +                 Instance->TlsConn,
> +                 NULL,
> +                 0,
> +                 Buffer,
> +                 BufferSize
> +                 );
> +      if (EFI_ERROR (Status)) {
> +        goto ON_EXIT;
> +      }
> +
> +      //
> +      // *BufferSize should not be zero when ClientHello.
> +      //
> +      if (*BufferSize == 0) {
> +        Status = EFI_ABORTED;
> +        goto ON_EXIT;
> +      }
> +
> +      Instance->TlsSessionState = EfiTlsSessionHandShaking;
> +
> +      break;
> +    case EfiTlsSessionClosing:
> +      //
> +      // TLS session will be closed and response packet needs to be
> CloseNotify.
> +      //
> +      Status = TlsCloseNotify (
> +                 Instance->TlsConn,
> +                 Buffer,
> +                 BufferSize
> +                 );
> +      if (EFI_ERROR (Status)) {
> +        goto ON_EXIT;
> +      }
> +
> +      //
> +      // *BufferSize should not be zero when build CloseNotify message.
> +      //
> +      if (*BufferSize == 0) {
> +        Status = EFI_ABORTED;
> +        goto ON_EXIT;
> +      }
> +
> +      break;
> +    case EfiTlsSessionError:
> +      //
> +      // TLS session has errors and the response packet needs to be Alert
> +      // message based on error type.
> +      //
> +      Status = TlsHandeAlert (
> +                 Instance->TlsConn,
> +                 NULL,
> +                 0,
> +                 Buffer,
> +                 BufferSize
> +                 );
> +      if (EFI_ERROR (Status)) {
> +        goto ON_EXIT;
> +      }
> +
> +      break;
> +    default:
> +      //
> +      // Current TLS session state is NOT ready to build ResponsePacket.
> +      //
> +      Status = EFI_NOT_READY;
> +    }
> +  } else {
> +    //
> +    // 1. Received packet may have multiply TLS record messages.
> +    // 2. One TLS record message may have multiply handshake protocol.
> +    // 3. Some errors may be happened in handshake.
> +    // TlsDoHandshake() can handle all of those cases.
> +    //
> +    if (TlsInHandshake (Instance->TlsConn)) {
> +      Status = TlsDoHandshake (
> +                 Instance->TlsConn,
> +                 RequestBuffer,
> +                 RequestSize,
> +                 Buffer,
> +                 BufferSize
> +                 );
> +      if (EFI_ERROR (Status)) {
> +        goto ON_EXIT;
> +      }
> +
> +      if (!TlsInHandshake (Instance->TlsConn)) {
> +        Instance->TlsSessionState = EfiTlsSessionDataTransferring;
> +      }
> +    } else {
> +      //
> +      // Must be alert message, Decrypt it and build the ResponsePacket.
> +      //
> +      ASSERT (((TLS_RECORD_HEADER *) RequestBuffer)->ContentType ==
> TLS_CONTENT_TYPE_ALERT);
> +
> +      Status = TlsHandeAlert (
> +                 Instance->TlsConn,
> +                 RequestBuffer,
> +                 RequestSize,
> +                 Buffer,
> +                 BufferSize
> +                 );
> +      if (EFI_ERROR (Status)) {
> +        if (Status != EFI_BUFFER_TOO_SMALL) {
> +          Instance->TlsSessionState = EfiTlsSessionError;
> +        }
> +
> +        goto ON_EXIT;
> +      }
> +    }
> +  }
> +
> +ON_EXIT:
> +  gBS->RestoreTPL (OldTpl);
> +  return Status;
> +}
> +
> +/**
> +  Decrypt or encrypt TLS packet during session. This function is only valid
> after
> +  session connected and for application_data content type.
> +
> +  The ProcessPacket () function process each inbound or outbound TLS APP
> packet.
> +
> +  @param[in]       This           Pointer to the EFI_TLS_PROTOCOL instance.
> +  @param[in, out]  FragmentTable  Pointer to a list of fragment. The caller
> will take
> +                                  responsible to handle the original FragmentTable while
> +                                  it may be reallocated in TLS driver. If CryptMode is
> +                                  EfiTlsEncrypt, on input these fragments contain the TLS
> +                                  header and plain text TLS APP payload; on output these
> +                                  fragments contain the TLS header and cipher text TLS
> +                                  APP payload. If CryptMode is EfiTlsDecrypt, on input
> +                                  these fragments contain the TLS header and cipher text
> +                                  TLS APP payload; on output these fragments contain the
> +                                  TLS header and plain text TLS APP payload.
> +  @param[in]       FragmentCount  Number of fragment.
> +  @param[in]       CryptMode      Crypt mode.
> +
> +  @retval EFI_SUCCESS             The operation completed successfully.
> +  @retval EFI_INVALID_PARAMETER   One or more of the following
> conditions is TRUE:
> +                                  This is NULL.
> +                                  FragmentTable is NULL.
> +                                  FragmentCount is NULL.
> +                                  CryptoMode is invalid.
> +  @retval EFI_NOT_READY           Current TLS session state is NOT
> +                                  EfiTlsSessionDataTransferring.
> +  @retval EFI_ABORTED             Something wrong decryption the message.
> TLS session
> +                                  status will become EfiTlsSessionError. The caller need
> +                                  call BuildResponsePacket() to generate Error Alert
> +                                  message and send it out.
> +  @retval EFI_OUT_OF_RESOURCES    No enough resource to finish the
> operation.
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsProcessPacket (
> +  IN     EFI_TLS_PROTOCOL              *This,
> +  IN OUT EFI_TLS_FRAGMENT_DATA         **FragmentTable,
> +  IN     UINT32                        *FragmentCount,
> +  IN     EFI_TLS_CRYPT_MODE            CryptMode
> +  )
> +{
> +  EFI_STATUS                Status;
> +  TLS_INSTANCE              *Instance;
> +
> +  EFI_TPL                   OldTpl;
> +
> +  Status = EFI_SUCCESS;
> +
> +  if (This == NULL || FragmentTable == NULL || FragmentCount == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
> +
> +  Instance = TLS_INSTANCE_FROM_PROTOCOL_THIS (This);
> +
> +  if (Instance->TlsSessionState != EfiTlsSessionDataTransferring) {
> +    Status = EFI_NOT_READY;
> +    goto ON_EXIT;
> +  }
> +
> +  //
> +  // Packet sent or received may have multiply TLS record
> message(Application data type).
> +  // So,on input these fragments contain the TLS header and TLS APP
> payload;
> +  // on output these fragments also contain the TLS header and TLS APP
> payload.
> +  //
> +  switch (CryptMode) {
> +  case EfiTlsEncrypt:
> +    Status = TlsEcryptPacket (Instance, FragmentTable, FragmentCount);
> +    break;
> +  case EfiTlsDecrypt:
> +    Status = TlsDecryptPacket (Instance, FragmentTable, FragmentCount);
> +    break;
> +  default:
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +ON_EXIT:
> +  gBS->RestoreTPL (OldTpl);
> +  return Status;
> +}
> --
> 1.9.5.msysgit.1



^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2016-12-16  7:30 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-12-15  7:22 [PATCH v2 05/10] NetworkPkg/TlsDxe: TlsDxe driver implementation over OpenSSL Jiaxin Wu
2016-12-16  6:16 ` Ye, Ting
2016-12-16  7:30   ` Wu, Jiaxin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox