]> git.proxmox.com Git - mirror_edk2.git/blobdiff - CryptoPkg/Library/TlsLib/TlsConfig.c
CryptoPkg/TlsLib: pre-compute OpensslCipherLength in TlsCipherMappingTable
[mirror_edk2.git] / CryptoPkg / Library / TlsLib / TlsConfig.c
index c2bec6cba364ed92d738863b17874e8fc4a100eb..e2f819b9035f0883c6cd18d97c4963047b0902ed 100644 (file)
-/** @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;
-}
+/** @file\r
+  SSL/TLS Configuration Library Wrapper Implementation over OpenSSL.\r
+\r
+Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.<BR>\r
+(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "InternalTlsLib.h"\r
+\r
+typedef struct {\r
+  //\r
+  // IANA/IETF defined Cipher Suite ID\r
+  //\r
+  UINT16                          IanaCipher;\r
+  //\r
+  // OpenSSL-used Cipher Suite String\r
+  //\r
+  CONST CHAR8                     *OpensslCipher;\r
+  //\r
+  // Length of OpensslCipher\r
+  //\r
+  UINTN                           OpensslCipherLength;\r
+} TLS_CIPHER_MAPPING;\r
+\r
+//\r
+// Create a TLS_CIPHER_MAPPING initializer from IanaCipher and OpensslCipher so\r
+// that OpensslCipherLength is filled in automatically. IanaCipher must be an\r
+// integer constant expression, and OpensslCipher must be a string literal.\r
+//\r
+#define MAP(IanaCipher, OpensslCipher) \\r
+  { (IanaCipher), (OpensslCipher), sizeof (OpensslCipher) - 1 }\r
+\r
+//\r
+// The mapping table between IANA/IETF Cipher Suite definitions and\r
+// OpenSSL-used Cipher Suite name.\r
+//\r
+// Keep the table uniquely sorted by the IanaCipher field, in increasing order.\r
+//\r
+STATIC CONST TLS_CIPHER_MAPPING TlsCipherMappingTable[] = {\r
+  MAP ( 0x0001, "NULL-MD5" ),                       /// TLS_RSA_WITH_NULL_MD5\r
+  MAP ( 0x0002, "NULL-SHA" ),                       /// TLS_RSA_WITH_NULL_SHA\r
+  MAP ( 0x0004, "RC4-MD5" ),                        /// TLS_RSA_WITH_RC4_128_MD5\r
+  MAP ( 0x0005, "RC4-SHA" ),                        /// TLS_RSA_WITH_RC4_128_SHA\r
+  MAP ( 0x000A, "DES-CBC3-SHA" ),                   /// TLS_RSA_WITH_3DES_EDE_CBC_SHA, mandatory TLS 1.1\r
+  MAP ( 0x0016, "DHE-RSA-DES-CBC3-SHA" ),           /// TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA\r
+  MAP ( 0x002F, "AES128-SHA" ),                     /// TLS_RSA_WITH_AES_128_CBC_SHA, mandatory TLS 1.2\r
+  MAP ( 0x0030, "DH-DSS-AES128-SHA" ),              /// TLS_DH_DSS_WITH_AES_128_CBC_SHA\r
+  MAP ( 0x0031, "DH-RSA-AES128-SHA" ),              /// TLS_DH_RSA_WITH_AES_128_CBC_SHA\r
+  MAP ( 0x0033, "DHE-RSA-AES128-SHA" ),             /// TLS_DHE_RSA_WITH_AES_128_CBC_SHA\r
+  MAP ( 0x0035, "AES256-SHA" ),                     /// TLS_RSA_WITH_AES_256_CBC_SHA\r
+  MAP ( 0x0036, "DH-DSS-AES256-SHA" ),              /// TLS_DH_DSS_WITH_AES_256_CBC_SHA\r
+  MAP ( 0x0037, "DH-RSA-AES256-SHA" ),              /// TLS_DH_RSA_WITH_AES_256_CBC_SHA\r
+  MAP ( 0x0039, "DHE-RSA-AES256-SHA" ),             /// TLS_DHE_RSA_WITH_AES_256_CBC_SHA\r
+  MAP ( 0x003B, "NULL-SHA256" ),                    /// TLS_RSA_WITH_NULL_SHA256\r
+  MAP ( 0x003C, "AES128-SHA256" ),                  /// TLS_RSA_WITH_AES_128_CBC_SHA256\r
+  MAP ( 0x003D, "AES256-SHA256" ),                  /// TLS_RSA_WITH_AES_256_CBC_SHA256\r
+  MAP ( 0x003E, "DH-DSS-AES128-SHA256" ),           /// TLS_DH_DSS_WITH_AES_128_CBC_SHA256\r
+  MAP ( 0x003F, "DH-RSA-AES128-SHA256" ),           /// TLS_DH_RSA_WITH_AES_128_CBC_SHA256\r
+  MAP ( 0x0067, "DHE-RSA-AES128-SHA256" ),          /// TLS_DHE_RSA_WITH_AES_128_CBC_SHA256\r
+  MAP ( 0x0068, "DH-DSS-AES256-SHA256" ),           /// TLS_DH_DSS_WITH_AES_256_CBC_SHA256\r
+  MAP ( 0x0069, "DH-RSA-AES256-SHA256" ),           /// TLS_DH_RSA_WITH_AES_256_CBC_SHA256\r
+  MAP ( 0x006B, "DHE-RSA-AES256-SHA256" ),          /// TLS_DHE_RSA_WITH_AES_256_CBC_SHA256\r
+};\r
+\r
+/**\r
+  Gets the OpenSSL cipher suite mapping for the supplied IANA TLS cipher suite.\r
+\r
+  @param[in]  CipherId    The supplied IANA TLS cipher suite ID.\r
+\r
+  @return  The corresponding OpenSSL cipher suite mapping if found,\r
+           NULL otherwise.\r
+\r
+**/\r
+STATIC\r
+CONST TLS_CIPHER_MAPPING *\r
+TlsGetCipherMapping (\r
+  IN     UINT16                   CipherId\r
+  )\r
+{\r
+  INTN                      Left;\r
+  INTN                      Right;\r
+  INTN                      Middle;\r
+\r
+  //\r
+  // Binary Search Cipher Mapping Table for IANA-OpenSSL Cipher Translation\r
+  //\r
+  Left  = 0;\r
+  Right = ARRAY_SIZE (TlsCipherMappingTable) - 1;\r
+\r
+  while (Right >= Left) {\r
+    Middle = (Left + Right) / 2;\r
+\r
+    if (CipherId == TlsCipherMappingTable[Middle].IanaCipher) {\r
+      //\r
+      // Translate IANA cipher suite ID to OpenSSL name.\r
+      //\r
+      return &TlsCipherMappingTable[Middle];\r
+    }\r
+\r
+    if (CipherId < TlsCipherMappingTable[Middle].IanaCipher) {\r
+      Right = Middle - 1;\r
+    } else {\r
+      Left  = Middle + 1;\r
+    }\r
+  }\r
+\r
+  //\r
+  // No Cipher Mapping found, return NULL.\r
+  //\r
+  return NULL;\r
+}\r
+\r
+/**\r
+  Set a new TLS/SSL method for a particular TLS object.\r
+\r
+  This function sets a new TLS/SSL method for a particular TLS object.\r
+\r
+  @param[in]  Tls         Pointer to a TLS object.\r
+  @param[in]  MajorVer    Major Version of TLS/SSL Protocol.\r
+  @param[in]  MinorVer    Minor Version of TLS/SSL Protocol.\r
+\r
+  @retval  EFI_SUCCESS           The TLS/SSL method was set successfully.\r
+  @retval  EFI_INVALID_PARAMETER The parameter is invalid.\r
+  @retval  EFI_UNSUPPORTED       Unsupported TLS/SSL method.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+TlsSetVersion (\r
+  IN     VOID                     *Tls,\r
+  IN     UINT8                    MajorVer,\r
+  IN     UINT8                    MinorVer\r
+  )\r
+{\r
+  TLS_CONNECTION  *TlsConn;\r
+  UINT16          ProtoVersion;\r
+\r
+  TlsConn = (TLS_CONNECTION *)Tls;\r
+  if (TlsConn == NULL || TlsConn->Ssl == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  ProtoVersion = (MajorVer << 8) | MinorVer;\r
+\r
+  //\r
+  // Bound TLS method to the particular specified version.\r
+  //\r
+  switch (ProtoVersion) {\r
+  case TLS1_VERSION:\r
+    //\r
+    // TLS 1.0\r
+    //\r
+    SSL_set_min_proto_version (TlsConn->Ssl, TLS1_VERSION);\r
+    SSL_set_max_proto_version (TlsConn->Ssl, TLS1_VERSION);\r
+    break;\r
+  case TLS1_1_VERSION:\r
+    //\r
+    // TLS 1.1\r
+    //\r
+    SSL_set_min_proto_version (TlsConn->Ssl, TLS1_1_VERSION);\r
+    SSL_set_max_proto_version (TlsConn->Ssl, TLS1_1_VERSION);\r
+    break;\r
+  case TLS1_2_VERSION:\r
+    //\r
+    // TLS 1.2\r
+    //\r
+    SSL_set_min_proto_version (TlsConn->Ssl, TLS1_2_VERSION);\r
+    SSL_set_max_proto_version (TlsConn->Ssl, TLS1_2_VERSION);\r
+    break;\r
+  default:\r
+    //\r
+    // Unsupported Protocol Version\r
+    //\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  return EFI_SUCCESS;;\r
+}\r
+\r
+/**\r
+  Set TLS object to work in client or server mode.\r
+\r
+  This function prepares a TLS object to work in client or server mode.\r
+\r
+  @param[in]  Tls         Pointer to a TLS object.\r
+  @param[in]  IsServer    Work in server mode.\r
+\r
+  @retval  EFI_SUCCESS           The TLS/SSL work mode was set successfully.\r
+  @retval  EFI_INVALID_PARAMETER The parameter is invalid.\r
+  @retval  EFI_UNSUPPORTED       Unsupported TLS/SSL work mode.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+TlsSetConnectionEnd (\r
+  IN     VOID                     *Tls,\r
+  IN     BOOLEAN                  IsServer\r
+  )\r
+{\r
+  TLS_CONNECTION  *TlsConn;\r
+\r
+  TlsConn = (TLS_CONNECTION *) Tls;\r
+  if (TlsConn == NULL || TlsConn->Ssl == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (!IsServer) {\r
+    //\r
+    // Set TLS to work in Client mode.\r
+    //\r
+    SSL_set_connect_state (TlsConn->Ssl);\r
+  } else {\r
+    //\r
+    // Set TLS to work in Server mode.\r
+    // It is unsupported for UEFI version currently.\r
+    //\r
+    //SSL_set_accept_state (TlsConn->Ssl);\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Set the ciphers list to be used by the TLS object.\r
+\r
+  This function sets the ciphers for use by a specified TLS object.\r
+\r
+  @param[in]  Tls          Pointer to a TLS object.\r
+  @param[in]  CipherId     Pointer to a UINT16 cipher Id.\r
+  @param[in]  CipherNum    The number of cipher in the list.\r
+\r
+  @retval  EFI_SUCCESS           The ciphers list was set successfully.\r
+  @retval  EFI_INVALID_PARAMETER The parameter is invalid.\r
+  @retval  EFI_UNSUPPORTED       Unsupported TLS cipher in the list.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+TlsSetCipherList (\r
+  IN     VOID                     *Tls,\r
+  IN     UINT16                   *CipherId,\r
+  IN     UINTN                    CipherNum\r
+  )\r
+{\r
+  TLS_CONNECTION           *TlsConn;\r
+  UINTN                    Index;\r
+  CONST TLS_CIPHER_MAPPING *Mapping;\r
+  CONST CHAR8              *MappingName;\r
+  CHAR8                    CipherString[500];\r
+\r
+  TlsConn = (TLS_CONNECTION *) Tls;\r
+  if (TlsConn == NULL || TlsConn->Ssl == NULL || CipherId == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Mapping     = NULL;\r
+  MappingName = NULL;\r
+\r
+  memset (CipherString, 0, sizeof (CipherString));\r
+\r
+  for (Index = 0; Index < CipherNum; Index++) {\r
+    //\r
+    // Handling OpenSSL / RFC Cipher name mapping.\r
+    //\r
+    Mapping = TlsGetCipherMapping (*(CipherId + Index));\r
+    if (Mapping == NULL) {\r
+      return EFI_UNSUPPORTED;\r
+    }\r
+    MappingName = Mapping->OpensslCipher;\r
+\r
+    if (Index != 0) {\r
+      //\r
+      // The ciphers were separated by a colon.\r
+      //\r
+      AsciiStrCatS (CipherString, sizeof (CipherString), ":");\r
+    }\r
+\r
+    AsciiStrCatS (CipherString, sizeof (CipherString), MappingName);\r
+  }\r
+\r
+  AsciiStrCatS (CipherString, sizeof (CipherString), ":@STRENGTH");\r
+\r
+  //\r
+  // Sets the ciphers for use by the Tls object.\r
+  //\r
+  if (SSL_set_cipher_list (TlsConn->Ssl, CipherString) <= 0) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Set the compression method for TLS/SSL operations.\r
+\r
+  This function handles TLS/SSL integrated compression methods.\r
+\r
+  @param[in]  CompMethod    The compression method ID.\r
+\r
+  @retval  EFI_SUCCESS        The compression method for the communication was\r
+                              set successfully.\r
+  @retval  EFI_UNSUPPORTED    Unsupported compression method.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+TlsSetCompressionMethod (\r
+  IN     UINT8                    CompMethod\r
+  )\r
+{\r
+  COMP_METHOD  *Cm;\r
+  INTN         Ret;\r
+\r
+  Cm  = NULL;\r
+  Ret = 0;\r
+\r
+  if (CompMethod == 0) {\r
+    //\r
+    // TLS defines one standard compression method, CompressionMethod.null (0),\r
+    // which specifies that data exchanged via the record protocol will not be compressed.\r
+    // So, return EFI_SUCCESS directly (RFC 3749).\r
+    //\r
+    return EFI_SUCCESS;\r
+  } else if (CompMethod == 1) {\r
+    Cm = COMP_zlib();\r
+  } else {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  //\r
+  // Adds the compression method to the list of available\r
+  // compression methods.\r
+  //\r
+  Ret = SSL_COMP_add_compression_method (CompMethod, Cm);\r
+  if (Ret != 0) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Set peer certificate verification mode for the TLS connection.\r
+\r
+  This function sets the verification mode flags for the TLS connection.\r
+\r
+  @param[in]  Tls           Pointer to the TLS object.\r
+  @param[in]  VerifyMode    A set of logically or'ed verification mode flags.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+TlsSetVerify (\r
+  IN     VOID                     *Tls,\r
+  IN     UINT32                   VerifyMode\r
+  )\r
+{\r
+  TLS_CONNECTION  *TlsConn;\r
+\r
+  TlsConn = (TLS_CONNECTION *) Tls;\r
+  if (TlsConn == NULL || TlsConn->Ssl == NULL) {\r
+    return;\r
+  }\r
+\r
+  //\r
+  // Set peer certificate verification parameters with NULL callback.\r
+  //\r
+  SSL_set_verify (TlsConn->Ssl, VerifyMode, NULL);\r
+}\r
+\r
+/**\r
+  Sets a TLS/SSL session ID to be used during TLS/SSL connect.\r
+\r
+  This function sets a session ID to be used when the TLS/SSL connection is\r
+  to be established.\r
+\r
+  @param[in]  Tls             Pointer to the TLS object.\r
+  @param[in]  SessionId       Session ID data used for session resumption.\r
+  @param[in]  SessionIdLen    Length of Session ID in bytes.\r
+\r
+  @retval  EFI_SUCCESS           Session ID was set successfully.\r
+  @retval  EFI_INVALID_PARAMETER The parameter is invalid.\r
+  @retval  EFI_UNSUPPORTED       No available session for ID setting.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+TlsSetSessionId (\r
+  IN     VOID                     *Tls,\r
+  IN     UINT8                    *SessionId,\r
+  IN     UINT16                   SessionIdLen\r
+  )\r
+{\r
+  TLS_CONNECTION  *TlsConn;\r
+  SSL_SESSION     *Session;\r
+\r
+  TlsConn = (TLS_CONNECTION *) Tls;\r
+  Session = NULL;\r
+\r
+  if (TlsConn == NULL || TlsConn->Ssl == NULL || SessionId == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Session = SSL_get_session (TlsConn->Ssl);\r
+  if (Session == NULL) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  SSL_SESSION_set1_id (Session, (const unsigned char *)SessionId, SessionIdLen);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Adds the CA to the cert store when requesting Server or Client authentication.\r
+\r
+  This function adds the CA certificate to the list of CAs when requesting\r
+  Server or Client authentication for the chosen TLS connection.\r
+\r
+  @param[in]  Tls         Pointer to the TLS object.\r
+  @param[in]  Data        Pointer to the data buffer of a DER-encoded binary\r
+                          X.509 certificate or PEM-encoded X.509 certificate.\r
+  @param[in]  DataSize    The size of data buffer in bytes.\r
+\r
+  @retval  EFI_SUCCESS             The operation succeeded.\r
+  @retval  EFI_INVALID_PARAMETER   The parameter is invalid.\r
+  @retval  EFI_OUT_OF_RESOURCES    Required resources could not be allocated.\r
+  @retval  EFI_ABORTED             Invalid X.509 certificate.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+TlsSetCaCertificate (\r
+  IN     VOID                     *Tls,\r
+  IN     VOID                     *Data,\r
+  IN     UINTN                    DataSize\r
+  )\r
+{\r
+  BIO             *BioCert;\r
+  X509            *Cert;\r
+  X509_STORE      *X509Store;\r
+  EFI_STATUS      Status;\r
+  TLS_CONNECTION  *TlsConn;\r
+  SSL_CTX         *SslCtx;\r
+  INTN            Ret;\r
+  UINTN           ErrorCode;\r
+\r
+  BioCert   = NULL;\r
+  Cert      = NULL;\r
+  X509Store = NULL;\r
+  Status    = EFI_SUCCESS;\r
+  TlsConn   = (TLS_CONNECTION *) Tls;\r
+  Ret       = 0;\r
+\r
+  if (TlsConn == NULL || TlsConn->Ssl == NULL || Data == NULL || DataSize == 0) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // DER-encoded binary X.509 certificate or PEM-encoded X.509 certificate.\r
+  // Determine whether certificate is from DER encoding, if so, translate it to X509 structure.\r
+  //\r
+  Cert = d2i_X509 (NULL, (const unsigned char ** )&Data, (long) DataSize);\r
+  if (Cert == NULL) {\r
+    //\r
+    // Certificate is from PEM encoding.\r
+    //\r
+    BioCert = BIO_new (BIO_s_mem ());\r
+    if (BioCert == NULL) {\r
+      Status = EFI_OUT_OF_RESOURCES;\r
+      goto ON_EXIT;\r
+    }\r
+\r
+    if (BIO_write (BioCert, Data, (UINT32) DataSize) <= 0) {\r
+      Status = EFI_ABORTED;\r
+      goto ON_EXIT;\r
+    }\r
+\r
+    Cert = PEM_read_bio_X509 (BioCert, NULL, NULL, NULL);\r
+    if (Cert == NULL) {\r
+      Status = EFI_ABORTED;\r
+      goto ON_EXIT;\r
+    }\r
+  }\r
+\r
+  SslCtx    = SSL_get_SSL_CTX (TlsConn->Ssl);\r
+  X509Store = SSL_CTX_get_cert_store (SslCtx);\r
+  if (X509Store == NULL) {\r
+      Status = EFI_ABORTED;\r
+      goto ON_EXIT;\r
+  }\r
+\r
+  //\r
+  // Add certificate to X509 store\r
+  //\r
+  Ret = X509_STORE_add_cert (X509Store, Cert);\r
+  if (Ret != 1) {\r
+    ErrorCode = ERR_peek_last_error ();\r
+    //\r
+    // Ignore "already in table" errors\r
+    //\r
+    if (!(ERR_GET_FUNC (ErrorCode) == X509_F_X509_STORE_ADD_CERT &&\r
+        ERR_GET_REASON (ErrorCode) == X509_R_CERT_ALREADY_IN_HASH_TABLE)) {\r
+      Status = EFI_ABORTED;\r
+      goto ON_EXIT;\r
+    }\r
+  }\r
+\r
+ON_EXIT:\r
+  if (BioCert != NULL) {\r
+    BIO_free (BioCert);\r
+  }\r
+\r
+  if (Cert != NULL) {\r
+    X509_free (Cert);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Loads the local public certificate into the specified TLS object.\r
+\r
+  This function loads the X.509 certificate into the specified TLS object\r
+  for TLS negotiation.\r
+\r
+  @param[in]  Tls         Pointer to the TLS object.\r
+  @param[in]  Data        Pointer to the data buffer of a DER-encoded binary\r
+                          X.509 certificate or PEM-encoded X.509 certificate.\r
+  @param[in]  DataSize    The size of data buffer in bytes.\r
+\r
+  @retval  EFI_SUCCESS             The operation succeeded.\r
+  @retval  EFI_INVALID_PARAMETER   The parameter is invalid.\r
+  @retval  EFI_OUT_OF_RESOURCES    Required resources could not be allocated.\r
+  @retval  EFI_ABORTED             Invalid X.509 certificate.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+TlsSetHostPublicCert (\r
+  IN     VOID                     *Tls,\r
+  IN     VOID                     *Data,\r
+  IN     UINTN                    DataSize\r
+  )\r
+{\r
+  BIO             *BioCert;\r
+  X509            *Cert;\r
+  EFI_STATUS      Status;\r
+  TLS_CONNECTION  *TlsConn;\r
+\r
+  BioCert = NULL;\r
+  Cert    = NULL;\r
+  Status  = EFI_SUCCESS;\r
+  TlsConn = (TLS_CONNECTION *) Tls;\r
+\r
+  if (TlsConn == NULL || TlsConn->Ssl == NULL || Data == NULL || DataSize == 0) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // DER-encoded binary X.509 certificate or PEM-encoded X.509 certificate.\r
+  // Determine whether certificate is from DER encoding, if so, translate it to X509 structure.\r
+  //\r
+  Cert = d2i_X509 (NULL, (const unsigned char ** )&Data, (long) DataSize);\r
+  if (Cert == NULL) {\r
+    //\r
+    // Certificate is from PEM encoding.\r
+    //\r
+    BioCert = BIO_new (BIO_s_mem ());\r
+    if (BioCert == NULL) {\r
+      Status = EFI_OUT_OF_RESOURCES;\r
+      goto ON_EXIT;\r
+    }\r
+\r
+    if (BIO_write (BioCert, Data, (UINT32) DataSize) <= 0) {\r
+      Status = EFI_ABORTED;\r
+      goto ON_EXIT;\r
+    }\r
+\r
+    Cert = PEM_read_bio_X509 (BioCert, NULL, NULL, NULL);\r
+    if (Cert == NULL) {\r
+      Status = EFI_ABORTED;\r
+      goto ON_EXIT;\r
+    }\r
+  }\r
+\r
+  if (SSL_use_certificate (TlsConn->Ssl, Cert) != 1) {\r
+    Status = EFI_ABORTED;\r
+    goto ON_EXIT;\r
+  }\r
+\r
+ON_EXIT:\r
+  if (BioCert != NULL) {\r
+    BIO_free (BioCert);\r
+  }\r
+\r
+  if (Cert != NULL) {\r
+    X509_free (Cert);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Adds the local private key to the specified TLS object.\r
+\r
+  This function adds the local private key (PEM-encoded RSA or PKCS#8 private\r
+  key) into the specified TLS object for TLS negotiation.\r
+\r
+  @param[in]  Tls         Pointer to the TLS object.\r
+  @param[in]  Data        Pointer to the data buffer of a PEM-encoded RSA\r
+                          or PKCS#8 private key.\r
+  @param[in]  DataSize    The size of data buffer in bytes.\r
+\r
+  @retval  EFI_SUCCESS     The operation succeeded.\r
+  @retval  EFI_UNSUPPORTED This function is not supported.\r
+  @retval  EFI_ABORTED     Invalid private key data.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+TlsSetHostPrivateKey (\r
+  IN     VOID                     *Tls,\r
+  IN     VOID                     *Data,\r
+  IN     UINTN                    DataSize\r
+  )\r
+{\r
+  return EFI_UNSUPPORTED;\r
+}\r
+\r
+/**\r
+  Adds the CA-supplied certificate revocation list for certificate validation.\r
+\r
+  This function adds the CA-supplied certificate revocation list data for\r
+  certificate validity checking.\r
+\r
+  @param[in]  Data        Pointer to the data buffer of a DER-encoded CRL data.\r
+  @param[in]  DataSize    The size of data buffer in bytes.\r
+\r
+  @retval  EFI_SUCCESS     The operation succeeded.\r
+  @retval  EFI_UNSUPPORTED This function is not supported.\r
+  @retval  EFI_ABORTED     Invalid CRL data.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+TlsSetCertRevocationList (\r
+  IN     VOID                     *Data,\r
+  IN     UINTN                    DataSize\r
+  )\r
+{\r
+  return EFI_UNSUPPORTED;\r
+}\r
+\r
+/**\r
+  Gets the protocol version used by the specified TLS connection.\r
+\r
+  This function returns the protocol version used by the specified TLS\r
+  connection.\r
+\r
+  If Tls is NULL, then ASSERT().\r
+\r
+  @param[in]  Tls    Pointer to the TLS object.\r
+\r
+  @return  The protocol version of the specified TLS connection.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+TlsGetVersion (\r
+  IN     VOID                     *Tls\r
+  )\r
+{\r
+  TLS_CONNECTION  *TlsConn;\r
+\r
+  TlsConn = (TLS_CONNECTION *) Tls;\r
+\r
+  ASSERT (TlsConn != NULL);\r
+\r
+  return (UINT16)(SSL_version (TlsConn->Ssl));\r
+}\r
+\r
+/**\r
+  Gets the connection end of the specified TLS connection.\r
+\r
+  This function returns the connection end (as client or as server) used by\r
+  the specified TLS connection.\r
+\r
+  If Tls is NULL, then ASSERT().\r
+\r
+  @param[in]  Tls    Pointer to the TLS object.\r
+\r
+  @return  The connection end used by the specified TLS connection.\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+TlsGetConnectionEnd (\r
+  IN     VOID                     *Tls\r
+  )\r
+{\r
+  TLS_CONNECTION  *TlsConn;\r
+\r
+  TlsConn = (TLS_CONNECTION *) Tls;\r
+\r
+  ASSERT (TlsConn != NULL);\r
+\r
+  return (UINT8)SSL_is_server (TlsConn->Ssl);\r
+}\r
+\r
+/**\r
+  Gets the cipher suite used by the specified TLS connection.\r
+\r
+  This function returns current cipher suite used by the specified\r
+  TLS connection.\r
+\r
+  @param[in]      Tls         Pointer to the TLS object.\r
+  @param[in,out]  CipherId    The cipher suite used by the TLS object.\r
+\r
+  @retval  EFI_SUCCESS           The cipher suite was returned successfully.\r
+  @retval  EFI_INVALID_PARAMETER The parameter is invalid.\r
+  @retval  EFI_UNSUPPORTED       Unsupported cipher suite.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+TlsGetCurrentCipher (\r
+  IN     VOID                     *Tls,\r
+  IN OUT UINT16                   *CipherId\r
+  )\r
+{\r
+  TLS_CONNECTION    *TlsConn;\r
+  CONST SSL_CIPHER  *Cipher;\r
+\r
+  TlsConn = (TLS_CONNECTION *) Tls;\r
+  Cipher  = NULL;\r
+\r
+  if (TlsConn == NULL || TlsConn->Ssl == NULL || CipherId == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Cipher = SSL_get_current_cipher (TlsConn->Ssl);\r
+  if (Cipher == NULL) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  *CipherId = (SSL_CIPHER_get_id (Cipher)) & 0xFFFF;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Gets the compression methods used by the specified TLS connection.\r
+\r
+  This function returns current integrated compression methods used by\r
+  the specified TLS connection.\r
+\r
+  @param[in]      Tls              Pointer to the TLS object.\r
+  @param[in,out]  CompressionId    The current compression method used by\r
+                                   the TLS object.\r
+\r
+  @retval  EFI_SUCCESS           The compression method was returned successfully.\r
+  @retval  EFI_INVALID_PARAMETER The parameter is invalid.\r
+  @retval  EFI_ABORTED           Invalid Compression method.\r
+  @retval  EFI_UNSUPPORTED       This function is not supported.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+TlsGetCurrentCompressionId (\r
+  IN     VOID                     *Tls,\r
+  IN OUT UINT8                    *CompressionId\r
+  )\r
+{\r
+  return EFI_UNSUPPORTED;\r
+}\r
+\r
+/**\r
+  Gets the verification mode currently set in the TLS connection.\r
+\r
+  This function returns the peer verification mode currently set in the\r
+  specified TLS connection.\r
+\r
+  If Tls is NULL, then ASSERT().\r
+\r
+  @param[in]  Tls    Pointer to the TLS object.\r
+\r
+  @return  The verification mode set in the specified TLS connection.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+TlsGetVerify (\r
+  IN     VOID                     *Tls\r
+  )\r
+{\r
+  TLS_CONNECTION  *TlsConn;\r
+\r
+  TlsConn = (TLS_CONNECTION *) Tls;\r
+\r
+  ASSERT (TlsConn != NULL);\r
+\r
+  return SSL_get_verify_mode (TlsConn->Ssl);\r
+}\r
+\r
+/**\r
+  Gets the session ID used by the specified TLS connection.\r
+\r
+  This function returns the TLS/SSL session ID currently used by the\r
+  specified TLS connection.\r
+\r
+  @param[in]      Tls             Pointer to the TLS object.\r
+  @param[in,out]  SessionId       Buffer to contain the returned session ID.\r
+  @param[in,out]  SessionIdLen    The length of Session ID in bytes.\r
+\r
+  @retval  EFI_SUCCESS           The Session ID was returned successfully.\r
+  @retval  EFI_INVALID_PARAMETER The parameter is invalid.\r
+  @retval  EFI_UNSUPPORTED       Invalid TLS/SSL session.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+TlsGetSessionId (\r
+  IN     VOID                     *Tls,\r
+  IN OUT UINT8                    *SessionId,\r
+  IN OUT UINT16                   *SessionIdLen\r
+  )\r
+{\r
+  TLS_CONNECTION  *TlsConn;\r
+  SSL_SESSION     *Session;\r
+  CONST UINT8     *SslSessionId;\r
+\r
+  TlsConn = (TLS_CONNECTION *) Tls;\r
+  Session = NULL;\r
+\r
+  if (TlsConn == NULL || TlsConn->Ssl == NULL || SessionId == NULL || SessionIdLen == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Session = SSL_get_session (TlsConn->Ssl);\r
+  if (Session == NULL) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  SslSessionId = SSL_SESSION_get_id (Session, (unsigned int *)SessionIdLen);\r
+  CopyMem (SessionId, SslSessionId, *SessionIdLen);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Gets the client random data used in the specified TLS connection.\r
+\r
+  This function returns the TLS/SSL client random data currently used in\r
+  the specified TLS connection.\r
+\r
+  @param[in]      Tls             Pointer to the TLS object.\r
+  @param[in,out]  ClientRandom    Buffer to contain the returned client\r
+                                  random data (32 bytes).\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+TlsGetClientRandom (\r
+  IN     VOID                     *Tls,\r
+  IN OUT UINT8                    *ClientRandom\r
+  )\r
+{\r
+  TLS_CONNECTION  *TlsConn;\r
+\r
+  TlsConn = (TLS_CONNECTION *) Tls;\r
+\r
+  if (TlsConn == NULL || TlsConn->Ssl == NULL || ClientRandom == NULL) {\r
+    return;\r
+  }\r
+\r
+  SSL_get_client_random (TlsConn->Ssl, ClientRandom, SSL3_RANDOM_SIZE);\r
+}\r
+\r
+/**\r
+  Gets the server random data used in the specified TLS connection.\r
+\r
+  This function returns the TLS/SSL server random data currently used in\r
+  the specified TLS connection.\r
+\r
+  @param[in]      Tls             Pointer to the TLS object.\r
+  @param[in,out]  ServerRandom    Buffer to contain the returned server\r
+                                  random data (32 bytes).\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+TlsGetServerRandom (\r
+  IN     VOID                     *Tls,\r
+  IN OUT UINT8                    *ServerRandom\r
+  )\r
+{\r
+  TLS_CONNECTION  *TlsConn;\r
+\r
+  TlsConn = (TLS_CONNECTION *) Tls;\r
+\r
+  if (TlsConn == NULL || TlsConn->Ssl == NULL || ServerRandom == NULL) {\r
+    return;\r
+  }\r
+\r
+  SSL_get_server_random (TlsConn->Ssl, ServerRandom, SSL3_RANDOM_SIZE);\r
+}\r
+\r
+/**\r
+  Gets the master key data used in the specified TLS connection.\r
+\r
+  This function returns the TLS/SSL master key material currently used in\r
+  the specified TLS connection.\r
+\r
+  @param[in]      Tls            Pointer to the TLS object.\r
+  @param[in,out]  KeyMaterial    Buffer to contain the returned key material.\r
+\r
+  @retval  EFI_SUCCESS           Key material was returned successfully.\r
+  @retval  EFI_INVALID_PARAMETER The parameter is invalid.\r
+  @retval  EFI_UNSUPPORTED       Invalid TLS/SSL session.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+TlsGetKeyMaterial (\r
+  IN     VOID                     *Tls,\r
+  IN OUT UINT8                    *KeyMaterial\r
+  )\r
+{\r
+  TLS_CONNECTION  *TlsConn;\r
+  SSL_SESSION     *Session;\r
+\r
+  TlsConn = (TLS_CONNECTION *) Tls;\r
+  Session = NULL;\r
+\r
+  if (TlsConn == NULL || TlsConn->Ssl == NULL || KeyMaterial == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Session = SSL_get_session (TlsConn->Ssl);\r
+\r
+  if (Session == NULL) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  SSL_SESSION_get_master_key (Session, KeyMaterial, SSL3_MASTER_SECRET_SIZE);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Gets the CA Certificate from the cert store.\r
+\r
+  This function returns the CA certificate for the chosen\r
+  TLS connection.\r
+\r
+  @param[in]      Tls         Pointer to the TLS object.\r
+  @param[out]     Data        Pointer to the data buffer to receive the CA\r
+                              certificate data sent to the client.\r
+  @param[in,out]  DataSize    The size of data buffer in bytes.\r
+\r
+  @retval  EFI_SUCCESS             The operation succeeded.\r
+  @retval  EFI_UNSUPPORTED         This function is not supported.\r
+  @retval  EFI_BUFFER_TOO_SMALL    The Data is too small to hold the data.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+TlsGetCaCertificate (\r
+  IN     VOID                     *Tls,\r
+  OUT    VOID                     *Data,\r
+  IN OUT UINTN                    *DataSize\r
+  )\r
+{\r
+  return EFI_UNSUPPORTED;\r
+}\r
+\r
+/**\r
+  Gets the local public Certificate set in the specified TLS object.\r
+\r
+  This function returns the local public certificate which was currently set\r
+  in the specified TLS object.\r
+\r
+  @param[in]      Tls         Pointer to the TLS object.\r
+  @param[out]     Data        Pointer to the data buffer to receive the local\r
+                              public certificate.\r
+  @param[in,out]  DataSize    The size of data buffer in bytes.\r
+\r
+  @retval  EFI_SUCCESS             The operation succeeded.\r
+  @retval  EFI_INVALID_PARAMETER   The parameter is invalid.\r
+  @retval  EFI_NOT_FOUND           The certificate is not found.\r
+  @retval  EFI_BUFFER_TOO_SMALL    The Data is too small to hold the data.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+TlsGetHostPublicCert (\r
+  IN     VOID                     *Tls,\r
+  OUT    VOID                     *Data,\r
+  IN OUT UINTN                    *DataSize\r
+  )\r
+{\r
+  X509            *Cert;\r
+  TLS_CONNECTION  *TlsConn;\r
+\r
+  Cert    = NULL;\r
+  TlsConn = (TLS_CONNECTION *) Tls;\r
+\r
+  if (TlsConn == NULL || TlsConn->Ssl == NULL || DataSize == NULL || (*DataSize != 0 && Data == NULL)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Cert = SSL_get_certificate(TlsConn->Ssl);\r
+  if (Cert == NULL) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  //\r
+  // Only DER encoding is supported currently.\r
+  //\r
+  if (*DataSize < (UINTN) i2d_X509 (Cert, NULL)) {\r
+    *DataSize = (UINTN) i2d_X509 (Cert, NULL);\r
+    return EFI_BUFFER_TOO_SMALL;\r
+  }\r
+\r
+  *DataSize = (UINTN) i2d_X509 (Cert, (unsigned char **) &Data);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Gets the local private key set in the specified TLS object.\r
+\r
+  This function returns the local private key data which was currently set\r
+  in the specified TLS object.\r
+\r
+  @param[in]      Tls         Pointer to the TLS object.\r
+  @param[out]     Data        Pointer to the data buffer to receive the local\r
+                              private key data.\r
+  @param[in,out]  DataSize    The size of data buffer in bytes.\r
+\r
+  @retval  EFI_SUCCESS             The operation succeeded.\r
+  @retval  EFI_UNSUPPORTED         This function is not supported.\r
+  @retval  EFI_BUFFER_TOO_SMALL    The Data is too small to hold the data.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+TlsGetHostPrivateKey (\r
+  IN     VOID                     *Tls,\r
+  OUT    VOID                     *Data,\r
+  IN OUT UINTN                    *DataSize\r
+  )\r
+{\r
+  return EFI_UNSUPPORTED;\r
+}\r
+\r
+/**\r
+  Gets the CA-supplied certificate revocation list data set in the specified\r
+  TLS object.\r
+\r
+  This function returns the CA-supplied certificate revocation list data which\r
+  was currently set in the specified TLS object.\r
+\r
+  @param[out]     Data        Pointer to the data buffer to receive the CRL data.\r
+  @param[in,out]  DataSize    The size of data buffer in bytes.\r
+\r
+  @retval  EFI_SUCCESS             The operation succeeded.\r
+  @retval  EFI_UNSUPPORTED         This function is not supported.\r
+  @retval  EFI_BUFFER_TOO_SMALL    The Data is too small to hold the data.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+TlsGetCertRevocationList (\r
+  OUT    VOID                     *Data,\r
+  IN OUT UINTN                    *DataSize\r
+  )\r
+{\r
+  return EFI_UNSUPPORTED;\r
+}\r
+\r