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

v2:
* Code refine and Typo fix:
TlsHandeAlert -> TlsHandleAlert

This patch is used to add new TlsLib library, which is wrapped
over OpenSSL. The implementation provides TLS library functions
for EFI TLS protocol and EFI TLS Configuration Protocol.

Cc: Ye Ting <ting.ye@intel.com>
Cc: Long Qin <qin.long@intel.com>
Cc: Fu Siyuan <siyuan.fu@intel.com>
Cc: Zhang Lubo <lubo.zhang@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>
Reviewed-by: Ye Ting <ting.ye@intel.com>
---
 CryptoPkg/CryptoPkg.dec                   |    4 +
 CryptoPkg/CryptoPkg.dsc                   |    1 +
 CryptoPkg/Include/Library/TlsLib.h        |  787 +++++++++++++++++++++
 CryptoPkg/Library/TlsLib/InternalTlsLib.h |   35 +
 CryptoPkg/Library/TlsLib/TlsConfig.c      | 1054 +++++++++++++++++++++++++++++
 CryptoPkg/Library/TlsLib/TlsInit.c        |  291 ++++++++
 CryptoPkg/Library/TlsLib/TlsLib.inf       |   49 ++
 CryptoPkg/Library/TlsLib/TlsLib.uni       |   19 +
 CryptoPkg/Library/TlsLib/TlsProcess.c     |  462 +++++++++++++
 9 files changed, 2702 insertions(+)
 create mode 100644 CryptoPkg/Include/Library/TlsLib.h
 create mode 100644 CryptoPkg/Library/TlsLib/InternalTlsLib.h
 create mode 100644 CryptoPkg/Library/TlsLib/TlsConfig.c
 create mode 100644 CryptoPkg/Library/TlsLib/TlsInit.c
 create mode 100644 CryptoPkg/Library/TlsLib/TlsLib.inf
 create mode 100644 CryptoPkg/Library/TlsLib/TlsLib.uni
 create mode 100644 CryptoPkg/Library/TlsLib/TlsProcess.c

diff --git a/CryptoPkg/CryptoPkg.dec b/CryptoPkg/CryptoPkg.dec
index 80579b7..eee26cb 100644
--- a/CryptoPkg/CryptoPkg.dec
+++ b/CryptoPkg/CryptoPkg.dec
@@ -29,10 +29,14 @@
 [LibraryClasses]
   ##  @libraryclass  Provides basic library functions for cryptographic primitives.
   ##
   BaseCryptLib|Include/Library/BaseCryptLib.h
 
+  ##  @libraryclass  Provides TLS library functions for EFI TLS protocol.
+  ##
+  TlsLib|Include/Library/TlsLib.h
+
 [Protocols]
   ## Include/Protocol/RuntimeCrypt.h
   gEfiRuntimeCryptProtocolGuid = { 0xe1475e0c, 0x1746, 0x4802, {0x86, 0x2e, 0x1, 0x1c, 0x2c, 0x2d, 0x9d, 0x86 }}
 
 [UserExtensions.TianoCore."ExtraFiles"]
diff --git a/CryptoPkg/CryptoPkg.dsc b/CryptoPkg/CryptoPkg.dsc
index 3c3e444..468e60b 100644
--- a/CryptoPkg/CryptoPkg.dsc
+++ b/CryptoPkg/CryptoPkg.dsc
@@ -121,10 +121,11 @@
 ###################################################################################################
 [Components]
   CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
   CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf
   CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
+  CryptoPkg/Library/TlsLib/TlsLib.inf
 
   CryptoPkg/Application/Cryptest/Cryptest.inf
 
   CryptoPkg/CryptRuntimeDxe/CryptRuntimeDxe.inf
 
diff --git a/CryptoPkg/Include/Library/TlsLib.h b/CryptoPkg/Include/Library/TlsLib.h
new file mode 100644
index 0000000..45564f1
--- /dev/null
+++ b/CryptoPkg/Include/Library/TlsLib.h
@@ -0,0 +1,787 @@
+/** @file
+  Defines TLS Library APIs.
+
+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 __TLS_LIB_H__
+#define __TLS_LIB_H__
+
+/**
+  Initializes the OpenSSL library.
+
+  This function registers ciphers and digests used directly and indirectly
+  by SSL/TLS, and initializes the readable error messages.
+  This function must be called before any other action takes places.
+
+**/
+VOID
+EFIAPI
+TlsInitialize (
+  VOID
+  );
+
+/**
+  Free an allocated SSL_CTX object.
+
+  @param[in]  TlsCtx    Pointer to the SSL_CTX object to be released.
+
+**/
+VOID
+EFIAPI
+TlsCtxFree (
+  IN   VOID                  *TlsCtx
+  );
+
+/**
+  Creates a new SSL_CTX object as framework to establish TLS/SSL enabled
+  connections.
+
+  @param[in]  MajorVer    Major Version of TLS/SSL Protocol.
+  @param[in]  MinorVer    Minor Version of TLS/SSL Protocol.
+
+  @return  Pointer to an allocated SSL_CTX object.
+           If the creation failed, TlsCtxNew() returns NULL.
+
+**/
+VOID *
+EFIAPI
+TlsCtxNew (
+  IN     UINT8                    MajorVer,
+  IN     UINT8                    MinorVer
+  );
+
+/**
+  Free an allocated TLS object.
+
+  This function removes the TLS object pointed to by Tls and frees up the
+  allocated memory. If Tls is NULL, nothing is done.
+
+  @param[in]  Tls    Pointer to the TLS object to be freed.
+
+**/
+VOID
+EFIAPI
+TlsFree (
+  IN     VOID                     *Tls
+  );
+
+/**
+  Create a new TLS object for a connection.
+
+  This function creates a new TLS object for a connection. The new object
+  inherits the setting of the underlying context TlsCtx: connection method,
+  options, verification setting.
+
+  @param[in]  TlsCtx    Pointer to the SSL_CTX object.
+
+  @return  Pointer to an allocated SSL object.
+           If the creation failed, TlsNew() returns NULL.
+
+**/
+VOID *
+EFIAPI
+TlsNew (
+  IN     VOID                     *TlsCtx
+  );
+
+/**
+  Checks if the TLS handshake was done.
+
+  This function will check if the specified TLS handshake was done.
+
+  @param[in]  Tls    Pointer to the TLS object for handshake state checking.
+
+  @retval  TRUE     The TLS handshake was done.
+  @retval  FALSE    The TLS handshake was not done.
+
+**/
+BOOLEAN
+EFIAPI
+TlsInHandshake (
+  IN     VOID                     *Tls
+  );
+
+/**
+  Perform a TLS/SSL handshake.
+
+  This function will perform a TLS/SSL handshake.
+
+  @param[in]       Tls            Pointer to the TLS object for handshake operation.
+  @param[in]       BufferIn       Pointer to the most recently received TLS Handshake packet.
+  @param[in]       BufferInSize   Packet size in bytes for the most recently received TLS
+                                  Handshake packet.
+  @param[out]      BufferOut      Pointer to the buffer to hold the built packet.
+  @param[in, out]  BufferOutSize  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:
+                                  Tls is NULL.
+                                  BufferIn is NULL but BufferInSize is NOT 0.
+                                  BufferInSize is 0 but BufferIn is NOT NULL.
+                                  BufferOutSize is NULL.
+                                  BufferOut is NULL if *BufferOutSize is not zero.
+  @retval EFI_BUFFER_TOO_SMALL    BufferOutSize is too small to hold the response packet.
+  @retval EFI_ABORTED             Something wrong during handshake.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsDoHandshake (
+  IN     VOID                     *Tls,
+  IN     UINT8                    *BufferIn, OPTIONAL
+  IN     UINTN                    BufferInSize, OPTIONAL
+     OUT UINT8                    *BufferOut, OPTIONAL
+  IN OUT UINTN                    *BufferOutSize
+  );
+
+/**
+  Handle Alert message recorded in BufferIn. If BufferIn is NULL and BufferInSize is zero,
+  TLS session has errors and the response packet needs to be Alert message based on error type.
+
+  @param[in]       Tls            Pointer to the TLS object for state checking.
+  @param[in]       BufferIn       Pointer to the most recently received TLS Alert packet.
+  @param[in]       BufferInSize   Packet size in bytes for the most recently received TLS
+                                  Alert packet.
+  @param[out]      BufferOut      Pointer to the buffer to hold the built packet.
+  @param[in, out]  BufferOutSize  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:
+                                  Tls is NULL.
+                                  BufferIn is NULL but BufferInSize is NOT 0.
+                                  BufferInSize is 0 but BufferIn is NOT NULL.
+                                  BufferOutSize is NULL.
+                                  BufferOut is NULL if *BufferOutSize is not zero.
+  @retval EFI_ABORTED             An error occurred.
+  @retval EFI_BUFFER_TOO_SMALL    BufferOutSize is too small to hold the response packet.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsHandleAlert (
+  IN     VOID                     *Tls,
+  IN     UINT8                    *BufferIn, OPTIONAL
+  IN     UINTN                    BufferInSize, OPTIONAL
+     OUT UINT8                    *BufferOut, OPTIONAL
+  IN OUT UINTN                    *BufferOutSize
+  );
+
+/**
+  Build the CloseNotify packet.
+
+  @param[in]       Tls            Pointer to the TLS object for state checking.
+  @param[in, 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:
+                                  Tls is 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.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsCloseNotify (
+  IN     VOID                     *Tls,
+  IN OUT UINT8                    *Buffer,
+  IN OUT UINTN                    *BufferSize
+  );
+
+/**
+  Attempts to read bytes from one TLS object and places the data in Buffer.
+
+  This function will attempt to read BufferSize bytes from the TLS object
+  and places the data in Buffer.
+
+  @param[in]      Tls           Pointer to the TLS object.
+  @param[in,out]  Buffer        Pointer to the buffer to store the data.
+  @param[in]      BufferSize    The size of Buffer in bytes.
+
+  @retval  >0    The amount of data successfully read from the TLS object.
+  @retval  <=0   No data was successfully read.
+
+**/
+INTN
+EFIAPI
+TlsCtrlTrafficOut (
+  IN     VOID                     *Tls,
+  IN OUT VOID                     *Buffer,
+  IN     UINTN                    BufferSize
+  );
+
+/**
+  Attempts to write data from the buffer to TLS object.
+
+  This function will attempt to write BufferSize bytes data from the Buffer
+  to the TLS object.
+
+  @param[in]  Tls           Pointer to the TLS object.
+  @param[in]  Buffer        Pointer to the data buffer.
+  @param[in]  BufferSize    The size of Buffer in bytes.
+
+  @retval  >0    The amount of data successfully written to the TLS object.
+  @retval <=0    No data was successfully written.
+
+**/
+INTN
+EFIAPI
+TlsCtrlTrafficIn (
+  IN     VOID                     *Tls,
+  IN     VOID                     *Buffer,
+  IN     UINTN                    BufferSize
+  );
+
+/**
+  Attempts to read bytes from the specified TLS connection into the buffer.
+
+  This function tries to read BufferSize bytes data from the specified TLS
+  connection into the Buffer.
+
+  @param[in]      Tls           Pointer to the TLS connection for data reading.
+  @param[in,out]  Buffer        Pointer to the data buffer.
+  @param[in]      BufferSize    The size of Buffer in bytes.
+
+  @retval  >0    The read operation was successful, and return value is the
+                 number of bytes actually read from the TLS connection.
+  @retval  <=0   The read operation was not successful.
+
+**/
+INTN
+EFIAPI
+TlsRead (
+  IN     VOID                     *Tls,
+  IN OUT VOID                     *Buffer,
+  IN     UINTN                    BufferSize
+  );
+
+/**
+  Attempts to write data to a TLS connection.
+
+  This function tries to write BufferSize bytes data from the Buffer into the
+  specified TLS connection.
+
+  @param[in]  Tls           Pointer to the TLS connection for data writing.
+  @param[in]  Buffer        Pointer to the data buffer.
+  @param[in]  BufferSize    The size of Buffer in bytes.
+
+  @retval  >0    The write operation was successful, and return value is the
+                 number of bytes actually written to the TLS connection.
+  @retval <=0    The write operation was not successful.
+
+**/
+INTN
+EFIAPI
+TlsWrite (
+  IN     VOID                     *Tls,
+  IN     VOID                     *Buffer,
+  IN     UINTN                    BufferSize
+  );
+
+/**
+  Set a new TLS/SSL method for a particular TLS object.
+
+  This function sets a new TLS/SSL method for a particular TLS object.
+
+  @param[in]  Tls         Pointer to a TLS object.
+  @param[in]  MajorVer    Major Version of TLS/SSL Protocol.
+  @param[in]  MinorVer    Minor Version of TLS/SSL Protocol.
+
+  @retval  EFI_SUCCESS           The TLS/SSL method was set successfully.
+  @retval  EFI_INVALID_PARAMETER The parameter is invalid.
+  @retval  EFI_UNSUPPORTED       Unsupported TLS/SSL method.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsSetVersion (
+  IN     VOID                     *Tls,
+  IN     UINT8                    MajorVer,
+  IN     UINT8                    MinorVer
+  );
+
+/**
+  Set TLS object to work in client or server mode.
+
+  This function prepares a TLS object to work in client or server mode.
+
+  @param[in]  Tls         Pointer to a TLS object.
+  @param[in]  IsServer    Work in server mode.
+
+  @retval  EFI_SUCCESS           The TLS/SSL work mode was set successfully.
+  @retval  EFI_INVALID_PARAMETER The parameter is invalid.
+  @retval  EFI_UNSUPPORTED       Unsupported TLS/SSL work mode.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsSetConnectionEnd (
+  IN     VOID                     *Tls,
+  IN     BOOLEAN                  IsServer
+  );
+
+/**
+  Set the ciphers list to be used by the TLS object.
+
+  This function sets the ciphers for use by a specified TLS object.
+
+  @param[in]  Tls          Pointer to a TLS object.
+  @param[in]  CipherId     Pointer to a string that contains one or more
+                           ciphers separated by a colon.
+  @param[in]  CipherNum    The number of cipher in the list.
+
+  @retval  EFI_SUCCESS           The ciphers list was set successfully.
+  @retval  EFI_INVALID_PARAMETER The parameter is invalid.
+  @retval  EFI_UNSUPPORTED       Unsupported TLS cipher in the list.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsSetCipherList (
+  IN     VOID                     *Tls,
+  IN     UINT16                   *CipherId,
+  IN     UINTN                    CipherNum
+  );
+
+/**
+  Set the compression method for TLS/SSL operations.
+
+  This function handles TLS/SSL integrated compression methods.
+
+  @param[in]  CompMethod    The compression method ID.
+
+  @retval  EFI_SUCCESS        The compression method for the communication was
+                              set successfully.
+  @retval  EFI_UNSUPPORTED    Unsupported compression method.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsSetCompressionMethod (
+  IN     UINT8                    CompMethod
+  );
+
+/**
+  Set peer certificate verification mode for the TLS connection.
+
+  This function sets the verification mode flags for the TLS connection.
+
+  @param[in]  Tls           Pointer to the TLS object.
+  @param[in]  VerifyMode    A set of logically or'ed verification mode flags.
+
+**/
+VOID
+EFIAPI
+TlsSetVerify (
+  IN     VOID                     *Tls,
+  IN     UINT32                   VerifyMode
+  );
+
+/**
+  Sets a TLS/SSL session ID to be used during TLS/SSL connect.
+
+  This function sets a session ID to be used when the TLS/SSL connection is
+  to be established.
+
+  @param[in]  Tls             Pointer to the TLS object.
+  @param[in]  SessionId       Session ID data used for session resumption.
+  @param[in]  SessionIdLen    Length of Session ID in bytes.
+
+  @retval  EFI_SUCCESS           Session ID was set successfully.
+  @retval  EFI_INVALID_PARAMETER The parameter is invalid.
+  @retval  EFI_UNSUPPORTED       No available session for ID setting.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsSetSessionId (
+  IN     VOID                     *Tls,
+  IN     UINT8                    *SessionId,
+  IN     UINT16                   SessionIdLen
+  );
+
+/**
+  Adds the CA to the cert store when requesting Server or Client authentication.
+
+  This function adds the CA certificate to the list of CAs when requesting
+  Server or Client authentication for the chosen TLS connection.
+
+  @param[in]  Tls         Pointer to the TLS object.
+  @param[in]  Data        Pointer to the data buffer of a DER-encoded binary
+                          X.509 certificate or PEM-encoded X.509 certificate.
+  @param[in]  DataSize    The size of data buffer in bytes.
+
+  @retval  EFI_SUCCESS             The operation succeeded.
+  @retval  EFI_INVALID_PARAMETER   The parameter is invalid.
+  @retval  EFI_OUT_OF_RESOURCES    Required resources could not be allocated.
+  @retval  EFI_ABORTED             Invalid X.509 certificate.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsSetCaCertificate (
+  IN     VOID                     *Tls,
+  IN     VOID                     *Data,
+  IN     UINTN                    DataSize
+  );
+
+/**
+  Loads the local public certificate into the specified TLS object.
+
+  This function loads the X.509 certificate into the specified TLS object
+  for TLS negotiation.
+
+  @param[in]  Tls         Pointer to the TLS object.
+  @param[in]  Data        Pointer to the data buffer of a DER-encoded binary
+                          X.509 certificate or PEM-encoded X.509 certificate.
+  @param[in]  DataSize    The size of data buffer in bytes.
+
+  @retval  EFI_SUCCESS             The operation succeeded.
+  @retval  EFI_INVALID_PARAMETER   The parameter is invalid.
+  @retval  EFI_OUT_OF_RESOURCES    Required resources could not be allocated.
+  @retval  EFI_ABORTED             Invalid X.509 certificate.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsSetHostPublicCert (
+  IN     VOID                     *Tls,
+  IN     VOID                     *Data,
+  IN     UINTN                    DataSize
+  );
+
+/**
+  Adds the local private key to the specified TLS object.
+
+  This function adds the local private key (PEM-encoded RSA or PKCS#8 private
+  key) into the specified TLS object for TLS negotiation.
+
+  @param[in]  Tls         Pointer to the TLS object.
+  @param[in]  Data        Pointer to the data buffer of a PEM-encoded RSA
+                          or PKCS#8 private key.
+  @param[in]  DataSize    The size of data buffer in bytes.
+
+  @retval  EFI_SUCCESS     The operation succeeded.
+  @retval  EFI_UNSUPPORTED This function is not supported.
+  @retval  EFI_ABORTED     Invalid private key data.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsSetHostPrivateKey (
+  IN     VOID                     *Tls,
+  IN     VOID                     *Data,
+  IN     UINTN                    DataSize
+  );
+
+/**
+  Adds the CA-supplied certificate revocation list for certificate validation.
+
+  This function adds the CA-supplied certificate revocation list data for
+  certificate validity checking.
+
+  @param[in]  Data        Pointer to the data buffer of a DER-encoded CRL data.
+  @param[in]  DataSize    The size of data buffer in bytes.
+
+  @retval  EFI_SUCCESS     The operation succeeded.
+  @retval  EFI_UNSUPPORTED This function is not supported.
+  @retval  EFI_ABORTED     Invalid CRL data.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsSetCertRevocationList (
+  IN     VOID                     *Data,
+  IN     UINTN                    DataSize
+  );
+
+/**
+  Gets the protocol version used by the specified TLS connection.
+
+  This function returns the protocol version used by the specified TLS
+  connection.
+
+  @param[in]  Tls    Pointer to the TLS object.
+
+  @return  The protocol version of the specified TLS connection.
+
+**/
+UINT16
+EFIAPI
+TlsGetVersion (
+  IN     VOID                     *Tls
+  );
+
+/**
+  Gets the connection end of the specified TLS connection.
+
+  This function returns the connection end (as client or as server) used by
+  the specified TLS connection.
+
+  @param[in]  Tls    Pointer to the TLS object.
+
+  @return  The connection end used by the specified TLS connection.
+
+**/
+UINT8
+EFIAPI
+TlsGetConnectionEnd (
+  IN     VOID                     *Tls
+  );
+
+/**
+  Gets the cipher suite used by the specified TLS connection.
+
+  This function returns current cipher suite used by the specified
+  TLS connection.
+
+  @param[in]      Tls         Pointer to the TLS object.
+  @param[in,out]  CipherId    The cipher suite used by the TLS object.
+
+  @retval  EFI_SUCCESS           The cipher suite was returned successfully.
+  @retval  EFI_INVALID_PARAMETER The parameter is invalid.
+  @retval  EFI_UNSUPPORTED       Unsupported cipher suite.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsGetCurrentCipher (
+  IN     VOID                     *Tls,
+  IN OUT UINT16                   *CipherId
+  );
+
+/**
+  Gets the compression methods used by the specified TLS connection.
+
+  This function returns current integrated compression methods used by
+  the specified TLS connection.
+
+  @param[in]      Tls              Pointer to the TLS object.
+  @param[in,out]  CompressionId    The current compression method used by
+                                   the TLS object.
+
+  @retval  EFI_SUCCESS           The compression method was returned successfully.
+  @retval  EFI_INVALID_PARAMETER The parameter is invalid.
+  @retval  EFI_ABORTED           Invalid Compression method.
+  @retval  EFI_UNSUPPORTED       This function is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsGetCurrentCompressionId (
+  IN     VOID                     *Tls,
+  IN OUT UINT8                    *CompressionId
+  );
+
+/**
+  Gets the verification mode currently set in the TLS connection.
+
+  This function returns the peer verification mode currently set in the
+  specified TLS connection.
+
+  @param[in]  Tls    Pointer to the TLS object.
+
+  @return  The verification mode set in the specified TLS connection.
+
+**/
+UINT32
+EFIAPI
+TlsGetVerify (
+  IN     VOID                     *Tls
+  );
+
+/**
+  Gets the session ID used by the specified TLS connection.
+
+  This function returns the TLS/SSL session ID currently used by the
+  specified TLS connection.
+
+  @param[in]      Tls             Pointer to the TLS object.
+  @param[in,out]  SessionId       Buffer to contain the returned session ID.
+  @param[in,out]  SessionIdLen    The length of Session ID in bytes.
+
+  @retval  EFI_SUCCESS           The Session ID was returned successfully.
+  @retval  EFI_INVALID_PARAMETER The parameter is invalid.
+  @retval  EFI_UNSUPPORTED       Invalid TLS/SSL session.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsGetSessionId (
+  IN     VOID                     *Tls,
+  IN OUT UINT8                    *SessionId,
+  IN OUT UINT16                   *SessionIdLen
+  );
+
+/**
+  Gets the client random data used in the specified TLS connection.
+
+  This function returns the TLS/SSL client random data currently used in
+  the specified TLS connection.
+
+  @param[in]      Tls             Pointer to the TLS object.
+  @param[in,out]  ClientRandom    Buffer to contain the returned client
+                                  random data (32 bytes).
+
+**/
+VOID
+EFIAPI
+TlsGetClientRandom (
+  IN     VOID                     *Tls,
+  IN OUT UINT8                    *ClientRandom
+  );
+
+/**
+  Gets the server random data used in the specified TLS connection.
+
+  This function returns the TLS/SSL server random data currently used in
+  the specified TLS connection.
+
+  @param[in]      Tls             Pointer to the TLS object.
+  @param[in,out]  ServerRandom    Buffer to contain the returned server
+                                  random data (32 bytes).
+
+**/
+VOID
+EFIAPI
+TlsGetServerRandom (
+  IN     VOID                     *Tls,
+  IN OUT UINT8                    *ServerRandom
+  );
+
+/**
+  Gets the master key data used in the specified TLS connection.
+
+  This function returns the TLS/SSL master key material currently used in
+  the specified TLS connection.
+
+  @param[in]      Tls            Pointer to the TLS object.
+  @param[in,out]  KeyMaterial    Buffer to contain the returned key material.
+
+  @retval  EFI_SUCCESS           Key material was returned successfully.
+  @retval  EFI_INVALID_PARAMETER The parameter is invalid.
+  @retval  EFI_UNSUPPORTED       Invalid TLS/SSL session.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsGetKeyMaterial (
+  IN     VOID                     *Tls,
+  IN OUT UINT8                    *KeyMaterial
+  );
+
+/**
+  Gets the CA Certificate from the cert store.
+
+  This function returns the CA certificate for the chosen
+  TLS connection.
+
+  @param[in]      Tls         Pointer to the TLS object.
+  @param[out]     Data        Pointer to the data buffer to receive the CA
+                              certificate data sent to the client.
+  @param[in,out]  DataSize    The size of data buffer in bytes.
+
+  @retval  EFI_SUCCESS             The operation succeeded.
+  @retval  EFI_UNSUPPORTED         This function is not supported.
+  @retval  EFI_BUFFER_TOO_SMALL    The Data is too small to hold the data.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsGetCaCertificate (
+  IN     VOID                     *Tls,
+  OUT    VOID                     *Data,
+  IN OUT UINTN                    *DataSize
+  );
+
+/**
+  Gets the local public Certificate set in the specified TLS object.
+
+  This function returns the local public certificate which was currently set
+  in the specified TLS object.
+
+  @param[in]      Tls         Pointer to the TLS object.
+  @param[out]     Data        Pointer to the data buffer to receive the local
+                              public certificate.
+  @param[in,out]  DataSize    The size of data buffer in bytes.
+
+  @retval  EFI_SUCCESS             The operation succeeded.
+  @retval  EFI_INVALID_PARAMETER   The parameter is invalid.
+  @retval  EFI_NOT_FOUND           The certificate is not found.
+  @retval  EFI_BUFFER_TOO_SMALL    The Data is too small to hold the data.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsGetHostPublicCert (
+  IN     VOID                     *Tls,
+  OUT    VOID                     *Data,
+  IN OUT UINTN                    *DataSize
+  );
+
+/**
+  Gets the local private key set in the specified TLS object.
+
+  This function returns the local private key data which was currently set
+  in the specified TLS object.
+
+  @param[in]      Tls         Pointer to the TLS object.
+  @param[out]     Data        Pointer to the data buffer to receive the local
+                              private key data.
+  @param[in,out]  DataSize    The size of data buffer in bytes.
+
+  @retval  EFI_SUCCESS             The operation succeeded.
+  @retval  EFI_UNSUPPORTED         This function is not supported.
+  @retval  EFI_BUFFER_TOO_SMALL    The Data is too small to hold the data.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsGetHostPrivateKey (
+  IN     VOID                     *Tls,
+  OUT    VOID                     *Data,
+  IN OUT UINTN                    *DataSize
+  );
+
+/**
+  Gets the CA-supplied certificate revocation list data set in the specified
+  TLS object.
+
+  This function returns the CA-supplied certificate revocation list data which
+  was currently set in the specified TLS object.
+
+  @param[out]     Data        Pointer to the data buffer to receive the CRL data.
+  @param[in,out]  DataSize    The size of data buffer in bytes.
+
+  @retval  EFI_SUCCESS             The operation succeeded.
+  @retval  EFI_UNSUPPORTED         This function is not supported.
+  @retval  EFI_BUFFER_TOO_SMALL    The Data is too small to hold the data.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsGetCertRevocationList (
+  OUT    VOID                     *Data,
+  IN OUT UINTN                    *DataSize
+  );
+
+#endif // __TLS_LIB_H__
diff --git a/CryptoPkg/Library/TlsLib/InternalTlsLib.h b/CryptoPkg/Library/TlsLib/InternalTlsLib.h
new file mode 100644
index 0000000..2438de9
--- /dev/null
+++ b/CryptoPkg/Library/TlsLib/InternalTlsLib.h
@@ -0,0 +1,35 @@
+/** @file
+  Internal include file for TlsLib.
+
+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 <Library/BaseCryptLib.h>
+#include <openssl/ssl.h>
+#include <openssl/bio.h>
+#include <openssl/err.h>
+
+typedef struct {
+  //
+  // Main SSL Connection which is created by a server or a client
+  // per established connection.
+  //
+  SSL                             *Ssl;
+  //
+  // Memory BIO for the TLS/SSL Reading operations.
+  //
+  BIO                             *InBio;
+  //
+  // Memory BIO for the TLS/SSL Writing operations.
+  //
+  BIO                             *OutBio;
+} TLS_CONNECTION;
+
diff --git a/CryptoPkg/Library/TlsLib/TlsConfig.c b/CryptoPkg/Library/TlsLib/TlsConfig.c
new file mode 100644
index 0000000..c2bec6c
--- /dev/null
+++ b/CryptoPkg/Library/TlsLib/TlsConfig.c
@@ -0,0 +1,1054 @@
+/** @file
+  SSL/TLS Configuration Library Wrapper Implementation over OpenSSL.
+
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution.  The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "InternalTlsLib.h"
+
+typedef struct {
+  //
+  // IANA/IETF defined Cipher Suite ID
+  //
+  UINT16                          IanaCipher;
+  //
+  // OpenSSL-used Cipher Suite String
+  //
+  CONST CHAR8                     *OpensslCipher;
+} TLS_CIPHER_PAIR;
+
+//
+// The mapping table between IANA/IETF Cipher Suite definitions and
+// OpenSSL-used Cipher Suite name.
+//
+STATIC CONST TLS_CIPHER_PAIR TlsCipherMappingTable[] = {
+  { 0x0001, "NULL-MD5" },                 /// TLS_RSA_WITH_NULL_MD5
+  { 0x0002, "NULL-SHA" },                 /// TLS_RSA_WITH_NULL_SHA
+  { 0x0004, "RC4-MD5" },                  /// TLS_RSA_WITH_RC4_128_MD5
+  { 0x0005, "RC4-SHA" },                  /// TLS_RSA_WITH_RC4_128_SHA
+  { 0x000A, "DES-CBC3-SHA" },             /// TLS_RSA_WITH_3DES_EDE_CBC_SHA, mandatory TLS 1.1
+  { 0x0016, "DHE-RSA-DES-CBC3-SHA" },     /// TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
+  { 0x002F, "AES128-SHA" },               /// TLS_RSA_WITH_AES_128_CBC_SHA, mandatory TLS 1.2
+  { 0x0030, "DH-DSS-AES128-SHA" },        /// TLS_DH_DSS_WITH_AES_128_CBC_SHA
+  { 0x0031, "DH-RSA-AES128-SHA" },        /// TLS_DH_RSA_WITH_AES_128_CBC_SHA
+  { 0x0033, "DHE-RSA-AES128-SHA" },       /// TLS_DHE_RSA_WITH_AES_128_CBC_SHA
+  { 0x0035, "AES256-SHA" },               /// TLS_RSA_WITH_AES_256_CBC_SHA
+  { 0x0036, "DH-DSS-AES256-SHA" },        /// TLS_DH_DSS_WITH_AES_256_CBC_SHA
+  { 0x0037, "DH-RSA-AES256-SHA" },        /// TLS_DH_RSA_WITH_AES_256_CBC_SHA
+  { 0x0039, "DHE-RSA-AES256-SHA" },       /// TLS_DHE_RSA_WITH_AES_256_CBC_SHA
+  { 0x003B, "NULL-SHA256" },              /// TLS_RSA_WITH_NULL_SHA256
+  { 0x003C, "AES128-SHA256" },            /// TLS_RSA_WITH_AES_128_CBC_SHA256
+  { 0x003D, "AES256-SHA256" },            /// TLS_RSA_WITH_AES_256_CBC_SHA256
+  { 0x003E, "DH-DSS-AES128-SHA256" },     /// TLS_DH_DSS_WITH_AES_128_CBC_SHA256
+  { 0x003F, "DH-RSA-AES128-SHA256" },     /// TLS_DH_RSA_WITH_AES_128_CBC_SHA256
+  { 0x0067, "DHE-RSA-AES128-SHA256" },    /// TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
+  { 0x0068, "DH-DSS-AES256-SHA256" },     /// TLS_DH_DSS_WITH_AES_256_CBC_SHA256
+  { 0x0069, "DH-RSA-AES256-SHA256" },     /// TLS_DH_RSA_WITH_AES_256_CBC_SHA256
+  { 0x006B, "DHE-RSA-AES256-SHA256" }     /// TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
+};
+
+/**
+  Gets the OpenSSL cipher suite string for the supplied IANA TLS cipher suite.
+
+  @param[in]  CipherId    The supplied IANA TLS cipher suite ID.
+
+  @return  The corresponding OpenSSL cipher suite string if found,
+           NULL otherwise.
+
+**/
+STATIC
+CONST CHAR8 *
+TlsGetCipherString (
+  IN     UINT16                   CipherId
+  )
+{
+  CONST TLS_CIPHER_PAIR  *CipherEntry;
+  UINTN                  TableSize;
+  UINTN                  Index;
+
+  CipherEntry = TlsCipherMappingTable;
+  TableSize = sizeof (TlsCipherMappingTable) / sizeof (TLS_CIPHER_PAIR);
+
+  //
+  // Search Cipher Mapping Table for IANA-OpenSSL Cipher Translation
+  //
+  for (Index = 0; Index < TableSize; Index++, CipherEntry++) {
+    //
+    // Translate IANA cipher suite name to OpenSSL name.
+    //
+    if (CipherEntry->IanaCipher == CipherId) {
+      return CipherEntry->OpensslCipher;
+    }
+  }
+
+  //
+  // No Cipher Mapping found, return NULL.
+  //
+  return NULL;
+}
+
+/**
+  Set a new TLS/SSL method for a particular TLS object.
+
+  This function sets a new TLS/SSL method for a particular TLS object.
+
+  @param[in]  Tls         Pointer to a TLS object.
+  @param[in]  MajorVer    Major Version of TLS/SSL Protocol.
+  @param[in]  MinorVer    Minor Version of TLS/SSL Protocol.
+
+  @retval  EFI_SUCCESS           The TLS/SSL method was set successfully.
+  @retval  EFI_INVALID_PARAMETER The parameter is invalid.
+  @retval  EFI_UNSUPPORTED       Unsupported TLS/SSL method.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsSetVersion (
+  IN     VOID                     *Tls,
+  IN     UINT8                    MajorVer,
+  IN     UINT8                    MinorVer
+  )
+{
+  TLS_CONNECTION  *TlsConn;
+  UINT16          ProtoVersion;
+
+  TlsConn = (TLS_CONNECTION *)Tls;
+  if (TlsConn == NULL || TlsConn->Ssl == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  ProtoVersion = (MajorVer << 8) | MinorVer;
+
+  switch (ProtoVersion) {
+  case TLS1_VERSION:
+    //
+    // TLS 1.0
+    //
+    SSL_set_ssl_method (TlsConn->Ssl, TLSv1_method ());
+    break;
+  case TLS1_1_VERSION:
+    //
+    // TLS 1.1
+    //
+    SSL_set_ssl_method (TlsConn->Ssl, TLSv1_1_method ());
+    break;
+  case TLS1_2_VERSION:
+    //
+    // TLS 1.2
+    //
+    SSL_set_ssl_method (TlsConn->Ssl, TLSv1_2_method ());
+    break;
+  default:
+    //
+    // Unsupported Protocol Version
+    //
+    return EFI_UNSUPPORTED;
+  }
+
+  return EFI_SUCCESS;;
+}
+
+/**
+  Set TLS object to work in client or server mode.
+
+  This function prepares a TLS object to work in client or server mode.
+
+  @param[in]  Tls         Pointer to a TLS object.
+  @param[in]  IsServer    Work in server mode.
+
+  @retval  EFI_SUCCESS           The TLS/SSL work mode was set successfully.
+  @retval  EFI_INVALID_PARAMETER The parameter is invalid.
+  @retval  EFI_UNSUPPORTED       Unsupported TLS/SSL work mode.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsSetConnectionEnd (
+  IN     VOID                     *Tls,
+  IN     BOOLEAN                  IsServer
+  )
+{
+  TLS_CONNECTION  *TlsConn;
+
+  TlsConn = (TLS_CONNECTION *) Tls;
+  if (TlsConn == NULL || TlsConn->Ssl == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (!IsServer) {
+    //
+    // Set TLS to work in Client mode.
+    //
+    SSL_set_connect_state (TlsConn->Ssl);
+  } else {
+    //
+    // Set TLS to work in Server mode.
+    // It is unsupported for UEFI version currently.
+    //
+    //SSL_set_accept_state (TlsConn->Ssl);
+    return EFI_UNSUPPORTED;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Set the ciphers list to be used by the TLS object.
+
+  This function sets the ciphers for use by a specified TLS object.
+
+  @param[in]  Tls          Pointer to a TLS object.
+  @param[in]  CipherId     Pointer to a UINT16 cipher Id.
+  @param[in]  CipherNum    The number of cipher in the list.
+
+  @retval  EFI_SUCCESS           The ciphers list was set successfully.
+  @retval  EFI_INVALID_PARAMETER The parameter is invalid.
+  @retval  EFI_UNSUPPORTED       Unsupported TLS cipher in the list.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsSetCipherList (
+  IN     VOID                     *Tls,
+  IN     UINT16                   *CipherId,
+  IN     UINTN                    CipherNum
+  )
+{
+  TLS_CONNECTION  *TlsConn;
+  UINTN           Index;
+  CONST CHAR8     *MappingName;
+  CHAR8           CipherString[500];
+
+  TlsConn = (TLS_CONNECTION *) Tls;
+  if (TlsConn == NULL || TlsConn->Ssl == NULL || CipherId == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  MappingName = NULL;
+
+  memset (CipherString, 0, sizeof (CipherString));
+
+  for (Index = 0; Index < CipherNum; Index++) {
+    //
+    // Handling OpenSSL / RFC Cipher name mapping.
+    //
+    MappingName = TlsGetCipherString (*(CipherId + Index));
+    if (MappingName == NULL) {
+      return EFI_UNSUPPORTED;
+    }
+
+    if (Index != 0) {
+      //
+      // The ciphers were separated by a colon.
+      //
+      AsciiStrCatS (CipherString, sizeof (CipherString), ":");
+    }
+
+    AsciiStrCatS (CipherString, sizeof (CipherString), MappingName);
+  }
+
+  AsciiStrCatS (CipherString, sizeof (CipherString), ":@STRENGTH");
+
+  //
+  // Sets the ciphers for use by the Tls object.
+  //
+  if (SSL_set_cipher_list (TlsConn->Ssl, CipherString) <= 0) {
+    return EFI_UNSUPPORTED;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Set the compression method for TLS/SSL operations.
+
+  This function handles TLS/SSL integrated compression methods.
+
+  @param[in]  CompMethod    The compression method ID.
+
+  @retval  EFI_SUCCESS        The compression method for the communication was
+                              set successfully.
+  @retval  EFI_UNSUPPORTED    Unsupported compression method.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsSetCompressionMethod (
+  IN     UINT8                    CompMethod
+  )
+{
+  COMP_METHOD  *Cm;
+  INTN         Ret;
+
+  Cm  = NULL;
+  Ret = 0;
+
+  if (CompMethod == 0) {
+    //
+    // TLS defines one standard compression method, CompressionMethod.null (0),
+    // which specifies that data exchanged via the record protocol will not be compressed.
+    // So, return EFI_SUCCESS directly (RFC 3749).
+    //
+    return EFI_SUCCESS;
+  } else if (CompMethod == 1) {
+    Cm = COMP_zlib();
+  } else {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Adds the compression method to the list of available
+  // compression methods.
+  //
+  Ret = SSL_COMP_add_compression_method (CompMethod, Cm);
+  if (Ret != 0) {
+    return EFI_UNSUPPORTED;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Set peer certificate verification mode for the TLS connection.
+
+  This function sets the verification mode flags for the TLS connection.
+
+  @param[in]  Tls           Pointer to the TLS object.
+  @param[in]  VerifyMode    A set of logically or'ed verification mode flags.
+
+**/
+VOID
+EFIAPI
+TlsSetVerify (
+  IN     VOID                     *Tls,
+  IN     UINT32                   VerifyMode
+  )
+{
+  TLS_CONNECTION  *TlsConn;
+
+  TlsConn = (TLS_CONNECTION *) Tls;
+  if (TlsConn == NULL || TlsConn->Ssl == NULL) {
+    return;
+  }
+
+  //
+  // Set peer certificate verification parameters with NULL callback.
+  //
+  SSL_set_verify (TlsConn->Ssl, VerifyMode, NULL);
+}
+
+/**
+  Sets a TLS/SSL session ID to be used during TLS/SSL connect.
+
+  This function sets a session ID to be used when the TLS/SSL connection is
+  to be established.
+
+  @param[in]  Tls             Pointer to the TLS object.
+  @param[in]  SessionId       Session ID data used for session resumption.
+  @param[in]  SessionIdLen    Length of Session ID in bytes.
+
+  @retval  EFI_SUCCESS           Session ID was set successfully.
+  @retval  EFI_INVALID_PARAMETER The parameter is invalid.
+  @retval  EFI_UNSUPPORTED       No available session for ID setting.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsSetSessionId (
+  IN     VOID                     *Tls,
+  IN     UINT8                    *SessionId,
+  IN     UINT16                   SessionIdLen
+  )
+{
+  TLS_CONNECTION  *TlsConn;
+  SSL_SESSION     *Session;
+
+  TlsConn = (TLS_CONNECTION *) Tls;
+  Session = NULL;
+
+  if (TlsConn == NULL || TlsConn->Ssl == NULL || SessionId == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Session = SSL_get_session (TlsConn->Ssl);
+  if (Session == NULL) {
+    return EFI_UNSUPPORTED;
+  }
+
+  Session->session_id_length = SessionIdLen;
+  CopyMem (Session->session_id, SessionId, Session->session_id_length);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Adds the CA to the cert store when requesting Server or Client authentication.
+
+  This function adds the CA certificate to the list of CAs when requesting
+  Server or Client authentication for the chosen TLS connection.
+
+  @param[in]  Tls         Pointer to the TLS object.
+  @param[in]  Data        Pointer to the data buffer of a DER-encoded binary
+                          X.509 certificate or PEM-encoded X.509 certificate.
+  @param[in]  DataSize    The size of data buffer in bytes.
+
+  @retval  EFI_SUCCESS             The operation succeeded.
+  @retval  EFI_INVALID_PARAMETER   The parameter is invalid.
+  @retval  EFI_OUT_OF_RESOURCES    Required resources could not be allocated.
+  @retval  EFI_ABORTED             Invalid X.509 certificate.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsSetCaCertificate (
+  IN     VOID                     *Tls,
+  IN     VOID                     *Data,
+  IN     UINTN                    DataSize
+  )
+{
+  BIO             *BioCert;
+  X509            *Cert;
+  X509_STORE      *X509Store;
+  EFI_STATUS      Status;
+  TLS_CONNECTION  *TlsConn;
+  SSL_CTX         *SslCtx;
+  INTN            Ret;
+  unsigned long   ErrorCode;
+
+  BioCert   = NULL;
+  Cert      = NULL;
+  X509Store = NULL;
+  Status    = EFI_SUCCESS;
+  TlsConn   = (TLS_CONNECTION *) Tls;
+  Ret       = 0;
+
+  if (TlsConn == NULL || TlsConn->Ssl == NULL || Data == NULL || DataSize == 0) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // DER-encoded binary X.509 certificate or PEM-encoded X.509 certificate.
+  // Determine whether certificate is from DER encoding, if so, translate it to X509 structure.
+  //
+  Cert = d2i_X509 (NULL, (const unsigned char ** )&Data, (long) DataSize);
+  if (Cert == NULL) {
+    //
+    // Certificate is from PEM encoding.
+    //
+    BioCert = BIO_new (BIO_s_mem ());
+    if (BioCert == NULL) {
+      Status = EFI_OUT_OF_RESOURCES;
+      goto ON_EXIT;
+    }
+
+    if (BIO_write (BioCert, Data, (UINT32) DataSize) <= 0) {
+      Status = EFI_ABORTED;
+      goto ON_EXIT;
+    }
+
+    Cert = PEM_read_bio_X509 (BioCert, NULL, NULL, NULL);
+    if (Cert == NULL) {
+      Status = EFI_ABORTED;
+      goto ON_EXIT;
+    }
+  }
+
+  SslCtx    = SSL_get_SSL_CTX (TlsConn->Ssl);
+  X509Store = SSL_CTX_get_cert_store (SslCtx);
+  if (X509Store == NULL) {
+      Status = EFI_ABORTED;
+      goto ON_EXIT;
+  }
+
+  //
+  // Add certificate to X509 store
+  //
+  Ret = X509_STORE_add_cert (X509Store, Cert);
+  if (Ret != 1) {
+    ErrorCode = ERR_peek_last_error ();
+    //
+    // Ignore "already in table" errors
+    //
+    if (!(ERR_GET_FUNC (ErrorCode) == X509_F_X509_STORE_ADD_CERT &&
+        ERR_GET_REASON (ErrorCode) == X509_R_CERT_ALREADY_IN_HASH_TABLE)) {
+      Status = EFI_ABORTED;
+      goto ON_EXIT;
+    }
+  }
+
+ON_EXIT:
+  if (BioCert != NULL) {
+    BIO_free (BioCert);
+  }
+
+  if (Cert != NULL) {
+    X509_free (Cert);
+  }
+
+  return Status;
+}
+
+/**
+  Loads the local public certificate into the specified TLS object.
+
+  This function loads the X.509 certificate into the specified TLS object
+  for TLS negotiation.
+
+  @param[in]  Tls         Pointer to the TLS object.
+  @param[in]  Data        Pointer to the data buffer of a DER-encoded binary
+                          X.509 certificate or PEM-encoded X.509 certificate.
+  @param[in]  DataSize    The size of data buffer in bytes.
+
+  @retval  EFI_SUCCESS             The operation succeeded.
+  @retval  EFI_INVALID_PARAMETER   The parameter is invalid.
+  @retval  EFI_OUT_OF_RESOURCES    Required resources could not be allocated.
+  @retval  EFI_ABORTED             Invalid X.509 certificate.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsSetHostPublicCert (
+  IN     VOID                     *Tls,
+  IN     VOID                     *Data,
+  IN     UINTN                    DataSize
+  )
+{
+  BIO             *BioCert;
+  X509            *Cert;
+  EFI_STATUS      Status;
+  TLS_CONNECTION  *TlsConn;
+
+  BioCert = NULL;
+  Cert    = NULL;
+  Status  = EFI_SUCCESS;
+  TlsConn = (TLS_CONNECTION *) Tls;
+
+  if (TlsConn == NULL || TlsConn->Ssl == NULL || Data == NULL || DataSize == 0) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // DER-encoded binary X.509 certificate or PEM-encoded X.509 certificate.
+  // Determine whether certificate is from DER encoding, if so, translate it to X509 structure.
+  //
+  Cert = d2i_X509 (NULL, (const unsigned char ** )&Data, (long) DataSize);
+  if (Cert == NULL) {
+    //
+    // Certificate is from PEM encoding.
+    //
+    BioCert = BIO_new (BIO_s_mem ());
+    if (BioCert == NULL) {
+      Status = EFI_OUT_OF_RESOURCES;
+      goto ON_EXIT;
+    }
+
+    if (BIO_write (BioCert, Data, (UINT32) DataSize) <= 0) {
+      Status = EFI_ABORTED;
+      goto ON_EXIT;
+    }
+
+    Cert = PEM_read_bio_X509 (BioCert, NULL, NULL, NULL);
+    if (Cert == NULL) {
+      Status = EFI_ABORTED;
+      goto ON_EXIT;
+    }
+  }
+
+  if (SSL_use_certificate (TlsConn->Ssl, Cert) != 1) {
+    Status = EFI_ABORTED;
+    goto ON_EXIT;
+  }
+
+ON_EXIT:
+  if (BioCert != NULL) {
+    BIO_free (BioCert);
+  }
+
+  if (Cert != NULL) {
+    X509_free (Cert);
+  }
+
+  return Status;
+}
+
+/**
+  Adds the local private key to the specified TLS object.
+
+  This function adds the local private key (PEM-encoded RSA or PKCS#8 private
+  key) into the specified TLS object for TLS negotiation.
+
+  @param[in]  Tls         Pointer to the TLS object.
+  @param[in]  Data        Pointer to the data buffer of a PEM-encoded RSA
+                          or PKCS#8 private key.
+  @param[in]  DataSize    The size of data buffer in bytes.
+
+  @retval  EFI_SUCCESS     The operation succeeded.
+  @retval  EFI_UNSUPPORTED This function is not supported.
+  @retval  EFI_ABORTED     Invalid private key data.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsSetHostPrivateKey (
+  IN     VOID                     *Tls,
+  IN     VOID                     *Data,
+  IN     UINTN                    DataSize
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Adds the CA-supplied certificate revocation list for certificate validation.
+
+  This function adds the CA-supplied certificate revocation list data for
+  certificate validity checking.
+
+  @param[in]  Data        Pointer to the data buffer of a DER-encoded CRL data.
+  @param[in]  DataSize    The size of data buffer in bytes.
+
+  @retval  EFI_SUCCESS     The operation succeeded.
+  @retval  EFI_UNSUPPORTED This function is not supported.
+  @retval  EFI_ABORTED     Invalid CRL data.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsSetCertRevocationList (
+  IN     VOID                     *Data,
+  IN     UINTN                    DataSize
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Gets the protocol version used by the specified TLS connection.
+
+  This function returns the protocol version used by the specified TLS
+  connection.
+
+  @param[in]  Tls    Pointer to the TLS object.
+
+  @return  The protocol version of the specified TLS connection.
+
+**/
+UINT16
+EFIAPI
+TlsGetVersion (
+  IN     VOID                     *Tls
+  )
+{
+  TLS_CONNECTION  *TlsConn;
+
+  TlsConn = (TLS_CONNECTION *) Tls;
+
+  ASSERT (TlsConn != NULL);
+
+  return (UINT16)(SSL_version (TlsConn->Ssl));
+}
+
+/**
+  Gets the connection end of the specified TLS connection.
+
+  This function returns the connection end (as client or as server) used by
+  the specified TLS connection.
+
+  @param[in]  Tls    Pointer to the TLS object.
+
+  @return  The connection end used by the specified TLS connection.
+
+**/
+UINT8
+EFIAPI
+TlsGetConnectionEnd (
+  IN     VOID                     *Tls
+  )
+{
+  TLS_CONNECTION  *TlsConn;
+
+  TlsConn = (TLS_CONNECTION *) Tls;
+
+  ASSERT (TlsConn != NULL);
+
+  return (UINT8)SSL_is_server (TlsConn->Ssl);
+}
+
+/**
+  Gets the cipher suite used by the specified TLS connection.
+
+  This function returns current cipher suite used by the specified
+  TLS connection.
+
+  @param[in]      Tls         Pointer to the TLS object.
+  @param[in,out]  CipherId    The cipher suite used by the TLS object.
+
+  @retval  EFI_SUCCESS           The cipher suite was returned successfully.
+  @retval  EFI_INVALID_PARAMETER The parameter is invalid.
+  @retval  EFI_UNSUPPORTED       Unsupported cipher suite.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsGetCurrentCipher (
+  IN     VOID                     *Tls,
+  IN OUT UINT16                   *CipherId
+  )
+{
+  TLS_CONNECTION    *TlsConn;
+  CONST SSL_CIPHER  *Cipher;
+
+  TlsConn = (TLS_CONNECTION *) Tls;
+  Cipher  = NULL;
+
+  if (TlsConn == NULL || TlsConn->Ssl == NULL || CipherId == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Cipher = SSL_get_current_cipher (TlsConn->Ssl);
+  if (Cipher == NULL) {
+    return EFI_UNSUPPORTED;
+  }
+
+  *CipherId = (SSL_CIPHER_get_id (Cipher)) & 0xFFFF;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Gets the compression methods used by the specified TLS connection.
+
+  This function returns current integrated compression methods used by
+  the specified TLS connection.
+
+  @param[in]      Tls              Pointer to the TLS object.
+  @param[in,out]  CompressionId    The current compression method used by
+                                   the TLS object.
+
+  @retval  EFI_SUCCESS           The compression method was returned successfully.
+  @retval  EFI_INVALID_PARAMETER The parameter is invalid.
+  @retval  EFI_ABORTED           Invalid Compression method.
+  @retval  EFI_UNSUPPORTED       This function is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsGetCurrentCompressionId (
+  IN     VOID                     *Tls,
+  IN OUT UINT8                    *CompressionId
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Gets the verification mode currently set in the TLS connection.
+
+  This function returns the peer verification mode currently set in the
+  specified TLS connection.
+
+  @param[in]  Tls    Pointer to the TLS object.
+
+  @return  The verification mode set in the specified TLS connection.
+
+**/
+UINT32
+EFIAPI
+TlsGetVerify (
+  IN     VOID                     *Tls
+  )
+{
+  TLS_CONNECTION  *TlsConn;
+
+  TlsConn = (TLS_CONNECTION *) Tls;
+
+  ASSERT (TlsConn != NULL);
+
+  return SSL_get_verify_mode (TlsConn->Ssl);
+}
+
+/**
+  Gets the session ID used by the specified TLS connection.
+
+  This function returns the TLS/SSL session ID currently used by the
+  specified TLS connection.
+
+  @param[in]      Tls             Pointer to the TLS object.
+  @param[in,out]  SessionId       Buffer to contain the returned session ID.
+  @param[in,out]  SessionIdLen    The length of Session ID in bytes.
+
+  @retval  EFI_SUCCESS           The Session ID was returned successfully.
+  @retval  EFI_INVALID_PARAMETER The parameter is invalid.
+  @retval  EFI_UNSUPPORTED       Invalid TLS/SSL session.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsGetSessionId (
+  IN     VOID                     *Tls,
+  IN OUT UINT8                    *SessionId,
+  IN OUT UINT16                   *SessionIdLen
+  )
+{
+  TLS_CONNECTION  *TlsConn;
+  SSL_SESSION     *Session;
+  CONST UINT8     *SslSessionId;
+
+  TlsConn = (TLS_CONNECTION *) Tls;
+  Session = NULL;
+
+  if (TlsConn == NULL || TlsConn->Ssl == NULL || SessionId == NULL || SessionIdLen == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Session = SSL_get_session (TlsConn->Ssl);
+  if (Session == NULL) {
+    return EFI_UNSUPPORTED;
+  }
+
+  SslSessionId = SSL_SESSION_get_id (Session, (unsigned int *)SessionIdLen);
+  CopyMem (SessionId, SslSessionId, *SessionIdLen);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Gets the client random data used in the specified TLS connection.
+
+  This function returns the TLS/SSL client random data currently used in
+  the specified TLS connection.
+
+  @param[in]      Tls             Pointer to the TLS object.
+  @param[in,out]  ClientRandom    Buffer to contain the returned client
+                                  random data (32 bytes).
+
+**/
+VOID
+EFIAPI
+TlsGetClientRandom (
+  IN     VOID                     *Tls,
+  IN OUT UINT8                    *ClientRandom
+  )
+{
+  TLS_CONNECTION  *TlsConn;
+
+  TlsConn = (TLS_CONNECTION *) Tls;
+
+  if (TlsConn == NULL || TlsConn->Ssl == NULL || ClientRandom == NULL) {
+    return;
+  }
+
+  CopyMem (ClientRandom, TlsConn->Ssl->s3->client_random, SSL3_RANDOM_SIZE);
+}
+
+/**
+  Gets the server random data used in the specified TLS connection.
+
+  This function returns the TLS/SSL server random data currently used in
+  the specified TLS connection.
+
+  @param[in]      Tls             Pointer to the TLS object.
+  @param[in,out]  ServerRandom    Buffer to contain the returned server
+                                  random data (32 bytes).
+
+**/
+VOID
+EFIAPI
+TlsGetServerRandom (
+  IN     VOID                     *Tls,
+  IN OUT UINT8                    *ServerRandom
+  )
+{
+  TLS_CONNECTION  *TlsConn;
+
+  TlsConn = (TLS_CONNECTION *) Tls;
+
+  if (TlsConn == NULL || TlsConn->Ssl == NULL || ServerRandom == NULL) {
+    return;
+  }
+
+  CopyMem (ServerRandom, TlsConn->Ssl->s3->server_random, SSL3_RANDOM_SIZE);
+}
+
+/**
+  Gets the master key data used in the specified TLS connection.
+
+  This function returns the TLS/SSL master key material currently used in
+  the specified TLS connection.
+
+  @param[in]      Tls            Pointer to the TLS object.
+  @param[in,out]  KeyMaterial    Buffer to contain the returned key material.
+
+  @retval  EFI_SUCCESS           Key material was returned successfully.
+  @retval  EFI_INVALID_PARAMETER The parameter is invalid.
+  @retval  EFI_UNSUPPORTED       Invalid TLS/SSL session.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsGetKeyMaterial (
+  IN     VOID                     *Tls,
+  IN OUT UINT8                    *KeyMaterial
+  )
+{
+  TLS_CONNECTION  *TlsConn;
+  SSL_SESSION     *Session;
+
+  TlsConn = (TLS_CONNECTION *) Tls;
+  Session = NULL;
+
+  if (TlsConn == NULL || TlsConn->Ssl == NULL || KeyMaterial == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Session = SSL_get_session (TlsConn->Ssl);
+
+  if (Session == NULL) {
+    return EFI_UNSUPPORTED;
+  }
+
+  CopyMem (KeyMaterial, Session->master_key, Session->master_key_length);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Gets the CA Certificate from the cert store.
+
+  This function returns the CA certificate for the chosen
+  TLS connection.
+
+  @param[in]      Tls         Pointer to the TLS object.
+  @param[out]     Data        Pointer to the data buffer to receive the CA
+                              certificate data sent to the client.
+  @param[in,out]  DataSize    The size of data buffer in bytes.
+
+  @retval  EFI_SUCCESS             The operation succeeded.
+  @retval  EFI_UNSUPPORTED         This function is not supported.
+  @retval  EFI_BUFFER_TOO_SMALL    The Data is too small to hold the data.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsGetCaCertificate (
+  IN     VOID                     *Tls,
+  OUT    VOID                     *Data,
+  IN OUT UINTN                    *DataSize
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Gets the local public Certificate set in the specified TLS object.
+
+  This function returns the local public certificate which was currently set
+  in the specified TLS object.
+
+  @param[in]      Tls         Pointer to the TLS object.
+  @param[out]     Data        Pointer to the data buffer to receive the local
+                              public certificate.
+  @param[in,out]  DataSize    The size of data buffer in bytes.
+
+  @retval  EFI_SUCCESS             The operation succeeded.
+  @retval  EFI_INVALID_PARAMETER   The parameter is invalid.
+  @retval  EFI_NOT_FOUND           The certificate is not found.
+  @retval  EFI_BUFFER_TOO_SMALL    The Data is too small to hold the data.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsGetHostPublicCert (
+  IN     VOID                     *Tls,
+  OUT    VOID                     *Data,
+  IN OUT UINTN                    *DataSize
+  )
+{
+  X509            *Cert;
+  TLS_CONNECTION  *TlsConn;
+
+  Cert    = NULL;
+  TlsConn = (TLS_CONNECTION *) Tls;
+
+  if (TlsConn == NULL || TlsConn->Ssl == NULL || DataSize == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Cert = SSL_get_certificate(TlsConn->Ssl);
+  if (Cert == NULL) {
+    return EFI_NOT_FOUND;
+  }
+
+  //
+  // Only DER encoding is supported currently.
+  //
+  if (*DataSize < (UINTN) i2d_X509 (Cert, NULL)) {
+    *DataSize = (UINTN) i2d_X509 (Cert, NULL);
+    return EFI_BUFFER_TOO_SMALL;
+  }
+
+  *DataSize = (UINTN) i2d_X509 (Cert, (unsigned char **) &Data);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Gets the local private key set in the specified TLS object.
+
+  This function returns the local private key data which was currently set
+  in the specified TLS object.
+
+  @param[in]      Tls         Pointer to the TLS object.
+  @param[out]     Data        Pointer to the data buffer to receive the local
+                              private key data.
+  @param[in,out]  DataSize    The size of data buffer in bytes.
+
+  @retval  EFI_SUCCESS             The operation succeeded.
+  @retval  EFI_UNSUPPORTED         This function is not supported.
+  @retval  EFI_BUFFER_TOO_SMALL    The Data is too small to hold the data.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsGetHostPrivateKey (
+  IN     VOID                     *Tls,
+  OUT    VOID                     *Data,
+  IN OUT UINTN                    *DataSize
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Gets the CA-supplied certificate revocation list data set in the specified
+  TLS object.
+
+  This function returns the CA-supplied certificate revocation list data which
+  was currently set in the specified TLS object.
+
+  @param[out]     Data        Pointer to the data buffer to receive the CRL data.
+  @param[in,out]  DataSize    The size of data buffer in bytes.
+
+  @retval  EFI_SUCCESS             The operation succeeded.
+  @retval  EFI_UNSUPPORTED         This function is not supported.
+  @retval  EFI_BUFFER_TOO_SMALL    The Data is too small to hold the data.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsGetCertRevocationList (
+  OUT    VOID                     *Data,
+  IN OUT UINTN                    *DataSize
+  )
+{
+  return EFI_UNSUPPORTED;
+}
diff --git a/CryptoPkg/Library/TlsLib/TlsInit.c b/CryptoPkg/Library/TlsLib/TlsInit.c
new file mode 100644
index 0000000..6b1fd93
--- /dev/null
+++ b/CryptoPkg/Library/TlsLib/TlsInit.c
@@ -0,0 +1,291 @@
+/** @file
+  SSL/TLS Initialization Library Wrapper Implementation over OpenSSL.
+
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution.  The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "InternalTlsLib.h"
+
+/**
+  Initializes the OpenSSL library.
+
+  This function registers ciphers and digests used directly and indirectly
+  by SSL/TLS, and initializes the readable error messages.
+  This function must be called before any other action takes places.
+
+**/
+VOID
+EFIAPI
+TlsInitialize (
+  VOID
+  )
+{
+  //
+  // Performs initialization of crypto and ssl library, and loads required
+  // algorithms.
+  //
+  SSL_library_init ();
+
+  //
+  // Loads error strings from both crypto and ssl library.
+  //
+  SSL_load_error_strings ();
+
+  /// OpenSSL_add_all_algorithms();
+
+  //
+  // Initialize the pseudorandom number generator.
+  //
+  RandomSeed (NULL, 0);
+}
+
+/**
+  Free an allocated SSL_CTX object.
+
+  @param[in]  TlsCtx    Pointer to the SSL_CTX object to be released.
+
+**/
+VOID
+EFIAPI
+TlsCtxFree (
+  IN   VOID                  *TlsCtx
+  )
+{
+  if (TlsCtx == NULL) {
+    return;
+  }
+
+  if (TlsCtx != NULL) {
+    SSL_CTX_free ((SSL_CTX *) (TlsCtx));
+  }
+}
+
+/**
+  Creates a new SSL_CTX object as framework to establish TLS/SSL enabled
+  connections.
+
+  @param[in]  MajorVer    Major Version of TLS/SSL Protocol.
+  @param[in]  MinorVer    Minor Version of TLS/SSL Protocol.
+
+  @return  Pointer to an allocated SSL_CTX object.
+           If the creation failed, TlsCtxNew() returns NULL.
+
+**/
+VOID *
+EFIAPI
+TlsCtxNew (
+  IN     UINT8                    MajorVer,
+  IN     UINT8                    MinorVer
+  )
+{
+  SSL_CTX  *TlsCtx;
+  UINT16   ProtoVersion;
+
+  ProtoVersion = (MajorVer << 8) | MinorVer;
+
+  TlsCtx = SSL_CTX_new (SSLv23_client_method ());
+  if (TlsCtx == NULL) {
+    return NULL;
+  }
+
+  //
+  // Ensure SSLv3 is disabled
+  //
+  SSL_CTX_set_options (TlsCtx, SSL_OP_NO_SSLv3);
+
+  //
+  // Treat as minimum accepted versions.  Client can use higher
+  // TLS version if server supports it
+  //
+  switch (ProtoVersion) {
+  case TLS1_VERSION:
+    //
+    // TLS 1.0
+    //
+    break;
+  case TLS1_1_VERSION:
+    //
+    // TLS 1.1
+    //
+    SSL_CTX_set_options (TlsCtx, SSL_OP_NO_TLSv1);
+    break;
+  case TLS1_2_VERSION:
+    //
+    // TLS 1.2
+    //
+    SSL_CTX_set_options (TlsCtx, SSL_OP_NO_TLSv1);
+    SSL_CTX_set_options (TlsCtx, SSL_OP_NO_TLSv1_1);
+    break;
+  default:
+    //
+    // Unsupported TLS/SSL Protocol Version.
+    //
+    break;
+  }
+
+  return (VOID *) TlsCtx;
+}
+
+/**
+  Free an allocated TLS object.
+
+  This function removes the TLS object pointed to by Tls and frees up the
+  allocated memory. If Tls is NULL, nothing is done.
+
+  @param[in]  Tls    Pointer to the TLS object to be freed.
+
+**/
+VOID
+EFIAPI
+TlsFree (
+  IN     VOID                     *Tls
+  )
+{
+  TLS_CONNECTION  *TlsConn;
+
+  TlsConn = (TLS_CONNECTION *) Tls;
+  if (TlsConn == NULL) {
+    return;
+  }
+
+  //
+  // Free the internal TLS and BIO objects.
+  //
+  if (TlsConn->Ssl != NULL) {
+    SSL_free (TlsConn->Ssl);
+  }
+
+  if (TlsConn->InBio != NULL) {
+    BIO_free (TlsConn->InBio);
+  }
+
+  if (TlsConn->OutBio != NULL) {
+    BIO_free (TlsConn->OutBio);
+  }
+
+  OPENSSL_free (Tls);
+}
+
+/**
+  Create a new TLS object for a connection.
+
+  This function creates a new TLS object for a connection. The new object
+  inherits the setting of the underlying context TlsCtx: connection method,
+  options, verification setting.
+
+  @param[in]  TlsCtx    Pointer to the SSL_CTX object.
+
+  @return  Pointer to an allocated SSL object.
+           If the creation failed, TlsNew() returns NULL.
+
+**/
+VOID *
+EFIAPI
+TlsNew (
+  IN     VOID                     *TlsCtx
+  )
+{
+  TLS_CONNECTION  *TlsConn;
+  SSL_CTX         *SslCtx;
+  X509_STORE      *X509Store;
+
+  TlsConn = NULL;
+
+  //
+  // Allocate one new TLS_CONNECTION object
+  //
+  TlsConn = (TLS_CONNECTION *) OPENSSL_malloc (sizeof (TLS_CONNECTION));
+  if (TlsConn == NULL) {
+    return NULL;
+  }
+
+  TlsConn->Ssl = NULL;
+
+  //
+  // Create a new SSL Object
+  //
+  TlsConn->Ssl = SSL_new ((SSL_CTX *) TlsCtx);
+  if (TlsConn->Ssl == NULL) {
+    TlsFree ((VOID *) TlsConn);
+    return NULL;
+  }
+
+  //
+  // Initialize the created SSL Object
+  //
+  SSL_set_info_callback (TlsConn->Ssl, NULL);
+
+  TlsConn->InBio = NULL;
+
+  //
+  // Set up Reading BIO for TLS connection
+  //
+  TlsConn->InBio = BIO_new (BIO_s_mem ());
+  if (TlsConn->InBio == NULL) {
+    TlsFree ((VOID *) TlsConn);
+    return NULL;
+  }
+
+  //
+  // Sets the behaviour of memory BIO when it is empty. It will set the
+  // read retry flag.
+  //
+  BIO_set_mem_eof_return (TlsConn->InBio, -1);
+
+  TlsConn->OutBio = NULL;
+
+  //
+  // Set up Writing BIO for TLS connection
+  //
+  TlsConn->OutBio = BIO_new (BIO_s_mem ());
+  if (TlsConn->OutBio == NULL) {
+    TlsFree ((VOID *) TlsConn);
+    return NULL;
+  }
+
+  //
+  // Sets the behaviour of memory BIO when it is empty. It will set the
+  // write retry flag.
+  //
+  BIO_set_mem_eof_return (TlsConn->OutBio, -1);
+
+  ASSERT (TlsConn->Ssl != NULL && TlsConn->InBio != NULL && TlsConn->OutBio != NULL);
+
+  //
+  // Connects the InBio and OutBio for the read and write operations.
+  //
+  SSL_set_bio (TlsConn->Ssl, TlsConn->InBio, TlsConn->OutBio);
+
+  //
+  // Create new X509 store if needed
+  //
+  SslCtx    = SSL_get_SSL_CTX (TlsConn->Ssl);
+  X509Store = SSL_CTX_get_cert_store (SslCtx);
+  if (X509Store == NULL) {
+    X509Store = X509_STORE_new ();
+    if (X509Store == NULL) {
+      TlsFree ((VOID *) TlsConn);
+      return NULL;
+    }
+    SSL_CTX_set1_verify_cert_store (SslCtx, X509Store);
+    X509_STORE_free (X509Store);
+  }
+
+  //
+  // Set X509_STORE flags used in certificate validation
+  //
+  X509_STORE_set_flags (
+    X509Store,
+    X509_V_FLAG_PARTIAL_CHAIN | X509_V_FLAG_NO_CHECK_TIME
+    );
+  return (VOID *) TlsConn;
+}
diff --git a/CryptoPkg/Library/TlsLib/TlsLib.inf b/CryptoPkg/Library/TlsLib/TlsLib.inf
new file mode 100644
index 0000000..2122b3b
--- /dev/null
+++ b/CryptoPkg/Library/TlsLib/TlsLib.inf
@@ -0,0 +1,49 @@
+## @file
+#  SSL/TLS Wrapper Library Instance based on OpenSSL.
+#
+#  Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+#  (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution.  The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = TlsLib
+  MODULE_UNI_FILE                = TlsLib.uni
+  FILE_GUID                      = CC729DC5-4E21-0B36-1A00-3A8E1B86A155
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = TlsLib|DXE_DRIVER DXE_CORE UEFI_APPLICATION UEFI_DRIVER
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 IPF ARM AARCH64
+#
+
+[Sources]
+  InternalTlsLib.h
+  TlsInit.c
+  TlsConfig.c
+  TlsProcess.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  CryptoPkg/CryptoPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  MemoryAllocationLib
+  UefiRuntimeServicesTableLib
+  DebugLib
+  OpensslLib
+  IntrinsicLib
+  PrintLib
diff --git a/CryptoPkg/Library/TlsLib/TlsLib.uni b/CryptoPkg/Library/TlsLib/TlsLib.uni
new file mode 100644
index 0000000..9b79287
--- /dev/null
+++ b/CryptoPkg/Library/TlsLib/TlsLib.uni
@@ -0,0 +1,19 @@
+// /** @file
+// SSL/TLS Wrapper Library Instance based on OpenSSL.
+//
+// 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 "SSL/TLS Wrapper Library Instance"
+
+#string STR_MODULE_DESCRIPTION          #language en-US "This module provides SSL/TLS Wrapper Library Instance."
\ No newline at end of file
diff --git a/CryptoPkg/Library/TlsLib/TlsProcess.c b/CryptoPkg/Library/TlsLib/TlsProcess.c
new file mode 100644
index 0000000..e47a46f
--- /dev/null
+++ b/CryptoPkg/Library/TlsLib/TlsProcess.c
@@ -0,0 +1,462 @@
+/** @file
+  SSL/TLS Process Library Wrapper Implementation over OpenSSL.
+  The process includes the TLS handshake and packet I/O.
+
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution.  The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "InternalTlsLib.h"
+
+#define MAX_BUFFER_SIZE   32768
+
+/**
+  Checks if the TLS handshake was done.
+
+  This function will check if the specified TLS handshake was done.
+
+  @param[in]  Tls    Pointer to the TLS object for handshake state checking.
+
+  @retval  TRUE     The TLS handshake was done.
+  @retval  FALSE    The TLS handshake was not done.
+
+**/
+BOOLEAN
+EFIAPI
+TlsInHandshake (
+  IN     VOID                     *Tls
+  )
+{
+  TLS_CONNECTION  *TlsConn;
+
+  TlsConn = (TLS_CONNECTION *) Tls;
+  if (TlsConn == NULL || TlsConn->Ssl == NULL) {
+    return FALSE;
+  }
+
+  //
+  // Return the status which indicates if the TLS handshake was done.
+  //
+  return !SSL_is_init_finished (TlsConn->Ssl);
+}
+
+/**
+  Perform a TLS/SSL handshake.
+
+  This function will perform a TLS/SSL handshake.
+
+  @param[in]       Tls            Pointer to the TLS object for handshake operation.
+  @param[in]       BufferIn       Pointer to the most recently received TLS Handshake packet.
+  @param[in]       BufferInSize   Packet size in bytes for the most recently received TLS
+                                  Handshake packet.
+  @param[out]      BufferOut      Pointer to the buffer to hold the built packet.
+  @param[in, out]  BufferOutSize  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:
+                                  Tls is NULL.
+                                  BufferIn is NULL but BufferInSize is NOT 0.
+                                  BufferInSize is 0 but BufferIn is NOT NULL.
+                                  BufferOutSize is NULL.
+                                  BufferOut is NULL if *BufferOutSize is not zero.
+  @retval EFI_BUFFER_TOO_SMALL    BufferOutSize is too small to hold the response packet.
+  @retval EFI_ABORTED             Something wrong during handshake.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsDoHandshake (
+  IN     VOID                     *Tls,
+  IN     UINT8                    *BufferIn, OPTIONAL
+  IN     UINTN                    BufferInSize, OPTIONAL
+     OUT UINT8                    *BufferOut, OPTIONAL
+  IN OUT UINTN                    *BufferOutSize
+  )
+{
+  TLS_CONNECTION  *TlsConn;
+  UINTN           PendingBufferSize;
+  INTN            Ret;
+  unsigned long   ErrorCode;
+
+  TlsConn           = (TLS_CONNECTION *) Tls;
+  PendingBufferSize = 0;
+  Ret               = 1;
+
+  if (TlsConn == NULL || \
+    TlsConn->Ssl == NULL || TlsConn->InBio == NULL || TlsConn->OutBio == NULL || \
+    BufferOutSize == NULL || \
+    (BufferIn == NULL && BufferInSize != 0) || \
+    (BufferIn != NULL && BufferInSize == 0) || \
+    (BufferOut == NULL && *BufferOutSize != 0)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if(BufferIn == NULL && BufferInSize == 0) {
+    //
+    // 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.
+    //
+    PendingBufferSize = (UINTN) BIO_ctrl_pending (TlsConn->OutBio);
+    if (PendingBufferSize == 0) {
+      SSL_set_connect_state (TlsConn->Ssl);
+      Ret = SSL_do_handshake (TlsConn->Ssl);
+      PendingBufferSize = (UINTN) BIO_ctrl_pending (TlsConn->OutBio);
+    }
+  } else {
+    PendingBufferSize = (UINTN) BIO_ctrl_pending (TlsConn->OutBio);
+    if (PendingBufferSize == 0) {
+      BIO_write (TlsConn->InBio, BufferIn, (UINT32) BufferInSize);
+      Ret = SSL_do_handshake (TlsConn->Ssl);
+      PendingBufferSize = (UINTN) BIO_ctrl_pending (TlsConn->OutBio);
+    }
+  }
+
+  if (Ret < 1) {
+    Ret = SSL_get_error (TlsConn->Ssl, (int) Ret);
+    if (Ret == SSL_ERROR_SSL ||
+        Ret == SSL_ERROR_SYSCALL ||
+        Ret == SSL_ERROR_ZERO_RETURN) {
+      DEBUG ((
+        DEBUG_ERROR,
+        "%a SSL_HANDSHAKE_ERROR State=0x%x SSL_ERROR_%a\n",
+        __FUNCTION__,
+        SSL_get_state (TlsConn->Ssl),
+        Ret == SSL_ERROR_SSL ? "SSL" : Ret == SSL_ERROR_SYSCALL ? "SYSCALL" : "ZERO_RETURN"
+        ));
+      DEBUG_CODE_BEGIN ();
+        while (TRUE) {
+          ErrorCode = ERR_get_error ();
+          if (ErrorCode == 0) {
+            break;
+          }
+          DEBUG ((
+            DEBUG_ERROR,
+            "%a ERROR 0x%x=L%x:F%x:R%x\n",
+            __FUNCTION__,
+            ErrorCode,
+            ERR_GET_LIB (ErrorCode),
+            ERR_GET_FUNC (ErrorCode),
+            ERR_GET_REASON (ErrorCode)
+            ));
+        }
+      DEBUG_CODE_END ();
+      return EFI_ABORTED;
+    }
+  }
+
+  if (PendingBufferSize > *BufferOutSize) {
+    *BufferOutSize = PendingBufferSize;
+    return EFI_BUFFER_TOO_SMALL;
+  }
+
+  if (PendingBufferSize > 0) {
+    *BufferOutSize = BIO_read (TlsConn->OutBio, BufferOut, (UINT32) PendingBufferSize);
+  } else {
+    *BufferOutSize = 0;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Handle Alert message recorded in BufferIn. If BufferIn is NULL and BufferInSize is zero,
+  TLS session has errors and the response packet needs to be Alert message based on error type.
+
+  @param[in]       Tls            Pointer to the TLS object for state checking.
+  @param[in]       BufferIn       Pointer to the most recently received TLS Alert packet.
+  @param[in]       BufferInSize   Packet size in bytes for the most recently received TLS
+                                  Alert packet.
+  @param[out]      BufferOut      Pointer to the buffer to hold the built packet.
+  @param[in, out]  BufferOutSize  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:
+                                  Tls is NULL.
+                                  BufferIn is NULL but BufferInSize is NOT 0.
+                                  BufferInSize is 0 but BufferIn is NOT NULL.
+                                  BufferOutSize is NULL.
+                                  BufferOut is NULL if *BufferOutSize is not zero.
+  @retval EFI_ABORTED             An error occurred.
+  @retval EFI_BUFFER_TOO_SMALL    BufferOutSize is too small to hold the response packet.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsHandleAlert (
+  IN     VOID                     *Tls,
+  IN     UINT8                    *BufferIn, OPTIONAL
+  IN     UINTN                    BufferInSize, OPTIONAL
+     OUT UINT8                    *BufferOut, OPTIONAL
+  IN OUT UINTN                    *BufferOutSize
+  )
+{
+  TLS_CONNECTION  *TlsConn;
+  UINTN           PendingBufferSize;
+  UINT8           *TempBuffer;
+  INTN            Ret;
+
+  TlsConn           = (TLS_CONNECTION *) Tls;
+  PendingBufferSize = 0;
+  TempBuffer        = NULL;
+  Ret               = 0;
+
+  if (TlsConn == NULL || \
+    TlsConn->Ssl == NULL || TlsConn->InBio == NULL || TlsConn->OutBio == NULL || \
+    BufferOutSize == NULL || \
+    (BufferIn == NULL && BufferInSize != 0) || \
+    (BufferIn != NULL && BufferInSize == 0) || \
+    (BufferOut == NULL && *BufferOutSize != 0)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  PendingBufferSize = (UINTN) BIO_ctrl_pending (TlsConn->OutBio);
+  if (PendingBufferSize == 0 && BufferIn != NULL && BufferInSize != 0) {
+    Ret = BIO_write (TlsConn->InBio, BufferIn, (UINT32) BufferInSize);
+    if (Ret != (INTN) BufferInSize) {
+      return EFI_ABORTED;
+    }
+
+    TempBuffer = (UINT8 *) OPENSSL_malloc (MAX_BUFFER_SIZE);
+
+    //
+    // ssl3_send_alert() will be called in ssl3_read_bytes() function.
+    // TempBuffer is invalid since it's a Alert message, so just ignore it.
+    //
+    SSL_read (TlsConn->Ssl, TempBuffer, MAX_BUFFER_SIZE);
+
+    OPENSSL_free (TempBuffer);
+
+    PendingBufferSize = (UINTN) BIO_ctrl_pending (TlsConn->OutBio);
+  }
+
+  if (PendingBufferSize > *BufferOutSize) {
+    *BufferOutSize = PendingBufferSize;
+    return EFI_BUFFER_TOO_SMALL;
+  }
+
+  if (PendingBufferSize > 0) {
+    *BufferOutSize = BIO_read (TlsConn->OutBio, BufferOut, (UINT32) PendingBufferSize);
+  } else {
+    *BufferOutSize = 0;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Build the CloseNotify packet.
+
+  @param[in]       Tls            Pointer to the TLS object for state checking.
+  @param[in, 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:
+                                  Tls is 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.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsCloseNotify (
+  IN     VOID                     *Tls,
+  IN OUT UINT8                    *Buffer,
+  IN OUT UINTN                    *BufferSize
+  )
+{
+  TLS_CONNECTION  *TlsConn;
+  UINTN           PendingBufferSize;
+
+  TlsConn           = (TLS_CONNECTION *) Tls;
+  PendingBufferSize = 0;
+
+  if (TlsConn == NULL || \
+    TlsConn->Ssl == NULL || TlsConn->InBio == NULL || TlsConn->OutBio == NULL || \
+    BufferSize == NULL || \
+    (Buffer == NULL && *BufferSize != 0)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  PendingBufferSize = (UINTN) BIO_ctrl_pending (TlsConn->OutBio);
+  if (PendingBufferSize == 0) {
+    //
+    // ssl3_send_alert() and ssl3_dispatch_alert() function will be called.
+    //
+    SSL_shutdown (TlsConn->Ssl);
+    PendingBufferSize = (UINTN) BIO_ctrl_pending (TlsConn->OutBio);
+  }
+
+  if (PendingBufferSize > *BufferSize) {
+    *BufferSize = PendingBufferSize;
+    return EFI_BUFFER_TOO_SMALL;
+  }
+
+  if (PendingBufferSize > 0) {
+    *BufferSize = BIO_read (TlsConn->OutBio, Buffer, (UINT32) PendingBufferSize);
+  } else {
+    *BufferSize = 0;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Attempts to read bytes from one TLS object and places the data in Buffer.
+
+  This function will attempt to read BufferSize bytes from the TLS object
+  and places the data in Buffer.
+
+  @param[in]      Tls           Pointer to the TLS object.
+  @param[in,out]  Buffer        Pointer to the buffer to store the data.
+  @param[in]      BufferSize    The size of Buffer in bytes.
+
+  @retval  >0    The amount of data successfully read from the TLS object.
+  @retval  <=0   No data was successfully read.
+
+**/
+INTN
+EFIAPI
+TlsCtrlTrafficOut (
+  IN     VOID                     *Tls,
+  IN OUT VOID                     *Buffer,
+  IN     UINTN                    BufferSize
+  )
+{
+  TLS_CONNECTION  *TlsConn;
+
+  TlsConn = (TLS_CONNECTION *) Tls;
+  if (TlsConn == NULL || TlsConn->OutBio == 0) {
+    return -1;
+  }
+
+  //
+  // Read and return the amount of data from the BIO.
+  //
+  return BIO_read (TlsConn->OutBio, Buffer, (UINT32) BufferSize);
+}
+
+/**
+  Attempts to write data from the buffer to TLS object.
+
+  This function will attempt to write BufferSize bytes data from the Buffer
+  to the TLS object.
+
+  @param[in]  Tls           Pointer to the TLS object.
+  @param[in]  Buffer        Pointer to the data buffer.
+  @param[in]  BufferSize    The size of Buffer in bytes.
+
+  @retval  >0    The amount of data successfully written to the TLS object.
+  @retval <=0    No data was successfully written.
+
+**/
+INTN
+EFIAPI
+TlsCtrlTrafficIn (
+  IN     VOID                     *Tls,
+  IN     VOID                     *Buffer,
+  IN     UINTN                    BufferSize
+  )
+{
+  TLS_CONNECTION  *TlsConn;
+
+  TlsConn = (TLS_CONNECTION *) Tls;
+  if (TlsConn == NULL || TlsConn->InBio == 0) {
+    return -1;
+  }
+
+  //
+  // Write and return the amount of data to the BIO.
+  //
+  return BIO_write (TlsConn->InBio, Buffer, (UINT32) BufferSize);
+}
+/**
+  Attempts to read bytes from the specified TLS connection into the buffer.
+
+  This function tries to read BufferSize bytes data from the specified TLS
+  connection into the Buffer.
+
+  @param[in]      Tls           Pointer to the TLS connection for data reading.
+  @param[in,out]  Buffer        Pointer to the data buffer.
+  @param[in]      BufferSize    The size of Buffer in bytes.
+
+  @retval  >0    The read operation was successful, and return value is the
+                 number of bytes actually read from the TLS connection.
+  @retval  <=0   The read operation was not successful.
+
+**/
+INTN
+EFIAPI
+TlsRead (
+  IN     VOID                     *Tls,
+  IN OUT VOID                     *Buffer,
+  IN     UINTN                    BufferSize
+  )
+{
+  TLS_CONNECTION  *TlsConn;
+
+  TlsConn = (TLS_CONNECTION *) Tls;
+  if (TlsConn == NULL || TlsConn->Ssl == NULL) {
+    return -1;
+  }
+
+  //
+  // Read bytes from the specified TLS connection.
+  //
+  return SSL_read (TlsConn->Ssl, Buffer, (UINT32) BufferSize);
+}
+
+/**
+  Attempts to write data to a TLS connection.
+
+  This function tries to write BufferSize bytes data from the Buffer into the
+  specified TLS connection.
+
+  @param[in]  Tls           Pointer to the TLS connection for data writing.
+  @param[in]  Buffer        Pointer to the data buffer.
+  @param[in]  BufferSize    The size of Buffer in bytes.
+
+  @retval  >0    The write operation was successful, and return value is the
+                 number of bytes actually written to the TLS connection.
+  @retval <=0    The write operation was not successful.
+
+**/
+INTN
+EFIAPI
+TlsWrite (
+  IN     VOID                     *Tls,
+  IN     VOID                     *Buffer,
+  IN     UINTN                    BufferSize
+  )
+{
+  TLS_CONNECTION  *TlsConn;
+
+  TlsConn = (TLS_CONNECTION *) Tls;
+  if (TlsConn == NULL || TlsConn->Ssl == NULL) {
+    return -1;
+  }
+
+  //
+  // Write bytes to the specified TLS connection.
+  //
+  return SSL_write (TlsConn->Ssl, Buffer, (UINT32) BufferSize);
+}
-- 
1.9.5.msysgit.1



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

* [PATCH v3 05/10] NetworkPkg/TlsDxe: TlsDxe driver implementation over OpenSSL
  2016-12-16  7:28 [PATCH v2 04/10] CryptoPkg: Add new TlsLib library Jiaxin Wu
@ 2016-12-16  7:28 ` Jiaxin Wu
  0 siblings, 0 replies; 2+ messages in thread
From: Jiaxin Wu @ 2016-12-16  7:28 UTC (permalink / raw)
  To: edk2-devel
  Cc: Ye Ting, Fu Siyuan, Zhang Lubo, Long Qin, Thomas Palmer,
	Wu Jiaxin

v3:
* Typo fix and code refine.
* Rename the internal macros and function:
TLS_INSTANCE_FROM_PROTOCOL_THIS -> TLS_INSTANCE_FROM_PROTOCOL
TLS_INSTANCE_FROM_CONFIGURATION_THIS -> TLS_INSTANCE_FROM_CONFIGURATION
TlsEcryptPacket -> TlsEncryptPacket

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>
Reviewed-by: Ye Ting <ting.ye@intel.com>
---
 NetworkPkg/TlsDxe/TlsConfigProtocol.c | 152 ++++++++
 NetworkPkg/TlsDxe/TlsDriver.c         | 496 ++++++++++++++++++++++++++
 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, 2266 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..5292433
--- /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);
+
+  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);
+
+  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..38bf599
--- /dev/null
+++ b/NetworkPkg/TlsDxe/TlsDriver.c
@@ -0,0 +1,496 @@
+/** @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
+  )
+{
+  TLS_SERVICE            *TlsService;
+
+  ASSERT (Service != NULL);
+
+  *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 EFI_SUCCESS;
+}
+
+/**
+  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 (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..a9e55ba
--- /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(a)  \
+  CR (a, TLS_INSTANCE, Tls, TLS_INSTANCE_SIGNATURE)
+
+#define TLS_INSTANCE_FROM_CONFIGURATION(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..bb71bd8
--- /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
+TlsEncryptPacket (
+  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 BufferIn.
+  //
+  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 to encrypt other messages.
+      //
+      DEBUG ((EFI_D_WARN, "TlsEncryptPacket: 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 be 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 BufferIn
+  //
+  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 multiple TLS record messages.
+  //
+  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 to decrypt other messages.
+      //
+      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 be 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..71b1bdb
--- /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
+TlsEncryptPacket (
+  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..ee1c496
--- /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);
+
+  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);
+
+  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);
+
+  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 = TlsHandleAlert (
+                 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 multiple TLS record messages.
+    // 2. One TLS record message may have multiple 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 = TlsHandleAlert (
+                 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);
+
+  if (Instance->TlsSessionState != EfiTlsSessionDataTransferring) {
+    Status = EFI_NOT_READY;
+    goto ON_EXIT;
+  }
+
+  //
+  // Packet sent or received may have multiple TLS record messages (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 = TlsEncryptPacket (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] 2+ messages in thread

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

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-12-16  7:28 [PATCH v2 04/10] CryptoPkg: Add new TlsLib library Jiaxin Wu
2016-12-16  7:28 ` [PATCH v3 05/10] NetworkPkg/TlsDxe: TlsDxe driver implementation over OpenSSL Jiaxin Wu

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