From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id C8FD681FCD for ; Thu, 15 Dec 2016 18:51:25 -0800 (PST) Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga103.jf.intel.com with ESMTP; 15 Dec 2016 18:51:25 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.33,355,1477983600"; d="scan'208";a="18774077" Received: from fmsmsx107.amr.corp.intel.com ([10.18.124.205]) by orsmga002.jf.intel.com with ESMTP; 15 Dec 2016 18:51:24 -0800 Received: from shsmsx151.ccr.corp.intel.com (10.239.6.50) by fmsmsx107.amr.corp.intel.com (10.18.124.205) with Microsoft SMTP Server (TLS) id 14.3.248.2; Thu, 15 Dec 2016 18:51:24 -0800 Received: from shsmsx103.ccr.corp.intel.com ([169.254.4.11]) by SHSMSX151.ccr.corp.intel.com ([169.254.3.77]) with mapi id 14.03.0248.002; Fri, 16 Dec 2016 10:51:20 +0800 From: "Wu, Jiaxin" To: "Ye, Ting" , "edk2-devel@lists.01.org" CC: "Long, Qin" , "Fu, Siyuan" , "Zhang, Lubo" , Thomas Palmer Thread-Topic: [Patch 04/10] CryptoPkg: Add new TlsLib library Thread-Index: AQHSVdyHsGq6/G65vUOwJ+++ERbxyqEJUWYAgACNkVA= Date: Fri, 16 Dec 2016 02:51:20 +0000 Message-ID: <895558F6EA4E3B41AC93A00D163B72741627F978@SHSMSX103.ccr.corp.intel.com> References: <1481700859-76060-1-git-send-email-jiaxin.wu@intel.com> <1481700859-76060-5-git-send-email-jiaxin.wu@intel.com> In-Reply-To: Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-titus-metadata-40: eyJDYXRlZ29yeUxhYmVscyI6IiIsIk1ldGFkYXRhIjp7Im5zIjoiaHR0cDpcL1wvd3d3LnRpdHVzLmNvbVwvbnNcL0ludGVsMyIsImlkIjoiZDdhZTAwYWMtNzQ2Ny00OTg1LTkwYjYtNTA0ZThhMDdiYTMwIiwicHJvcHMiOlt7Im4iOiJDVFBDbGFzc2lmaWNhdGlvbiIsInZhbHMiOlt7InZhbHVlIjoiQ1RQX1BVQkxJQyJ9XX1dfSwiU3ViamVjdExhYmVscyI6W10sIlRNQ1ZlcnNpb24iOiIxNS45LjYuNiIsIlRydXN0ZWRMYWJlbEhhc2giOiJYXC9hZVhXNjlpQ2ZMcFYycDZ6Z0s4eStLU3pzUlJ5YjlLaWN4ckUwNDI0VT0ifQ== x-ctpclassification: CTP_PUBLIC x-originating-ip: [10.239.127.40] MIME-Version: 1.0 Subject: Re: [Patch 04/10] CryptoPkg: Add new TlsLib library X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 16 Dec 2016 02:51:25 -0000 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable > Some comments included as following: >=20 > 1. In TlsGetHostPublicCert, line 1892: > The status is set to EFI_NOT_FOUND but not returned. Does it make > sense to update *DataSize in that case? You are right, EFI_NOT_FOUND should be returned directly. > 2. TlsDoHandshake uses EFI_PROTOCOL_ERROR but not record in function > header. > 3. TlsGetCurrentCompressionId uses EFI_UNSUPPROTED but not record in > function header. > 4. Typo in TlsHandeAlert, should be TlsHandleAlert? Please also update t= he > function description. It's the typo. Thanks for the correction. >=20 > Others look good to me. >=20 > Reviewed-by: Ye Ting Thanks Ting, I will correct it before commit the patch.=20 >=20 > Thanks, > Ting >=20 >=20 > -----Original Message----- > From: Wu, Jiaxin > Sent: Wednesday, December 14, 2016 3:34 PM > To: edk2-devel@lists.01.org > Cc: Ye, Ting ; Long, Qin ; Fu, Siy= uan > ; Zhang, Lubo ; Thomas > Palmer ; Wu, Jiaxin > Subject: [Patch 04/10] CryptoPkg: Add new TlsLib library >=20 > 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. >=20 > Cc: Ye Ting > Cc: Long Qin > Cc: Fu Siyuan > Cc: Zhang Lubo > Cc: Thomas Palmer > Contributed-under: TianoCore Contribution Agreement 1.0 > Signed-off-by: Wu Jiaxin > --- > CryptoPkg/CryptoPkg.dec | 4 + > CryptoPkg/CryptoPkg.dsc | 1 + > CryptoPkg/Include/Library/TlsLib.h | 785 +++++++++++++++++++++ > CryptoPkg/Library/TlsLib/InternalTlsLib.h | 35 + > CryptoPkg/Library/TlsLib/TlsConfig.c | 1055 > +++++++++++++++++++++++++++++ > CryptoPkg/Library/TlsLib/TlsInit.c | 291 ++++++++ > CryptoPkg/Library/TlsLib/TlsLib.inf | 49 ++ > CryptoPkg/Library/TlsLib/TlsLib.uni | 19 + > CryptoPkg/Library/TlsLib/TlsProcess.c | 461 +++++++++++++ > 9 files changed, 2700 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 >=20 > 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 >=20 > + ## @libraryclass Provides TLS library functions for EFI TLS protocol= . > + ## > + TlsLib|Include/Library/TlsLib.h > + > [Protocols] > ## Include/Protocol/RuntimeCrypt.h > gEfiRuntimeCryptProtocolGuid =3D { 0xe1475e0c, 0x1746, 0x4802, {0x86, = 0x2e, > 0x1, 0x1c, 0x2c, 0x2d, 0x9d, 0x86 }} >=20 > [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 @@ >=20 > ########################################################## > ######################################### > [Components] > CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf > CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf > CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf > + CryptoPkg/Library/TlsLib/TlsLib.inf >=20 > CryptoPkg/Application/Cryptest/Cryptest.inf >=20 > CryptoPkg/CryptRuntimeDxe/CryptRuntimeDxe.inf >=20 > diff --git a/CryptoPkg/Include/Library/TlsLib.h > b/CryptoPkg/Include/Library/TlsLib.h > new file mode 100644 > index 0000000..38b861e > --- /dev/null > +++ b/CryptoPkg/Include/Library/TlsLib.h > @@ -0,0 +1,785 @@ > +/** @file > + Defines TLS Library APIs. > + > +Copyright (c) 2016, Intel Corporation. All rights reserved.
> +This program and the accompanying materials > +are licensed and made available under the terms and conditions of the BS= D > License > +which accompanies this distribution. The full text of the license may b= e > 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 indirect= ly > + 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 th= e > + 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 objec= t > + inherits the setting of the underlying context TlsCtx: connection meth= od, > + 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 check= ing. > + > + @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 handshak= e operation. > + @param[in] BufferIn Pointer to the most recently received = TLS > Handshake packet. > + @param[in] BufferInSize Packet size in bytes for the most rece= ntly > received TLS > + Handshake packet. > + @param[out] BufferOut Pointer to the buffer to hold the buil= t packet. > + @param[in, out] BufferOutSize Pointer to the buffer size in bytes. O= n > input, it is > + the buffer size provided by the caller= . On output, it > + is the buffer size in fact needed to c= ontain the > + packet. > + > + @retval EFI_SUCCESS The required TLS packet is built succe= ssfully. > + @retval EFI_INVALID_PARAMETER One or more of the following > conditions is TRUE: > + Tls is NULL. > + BufferIn is NULL but BufferInSize is N= OT 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. > + > +**/ > +EFI_STATUS > +EFIAPI > +TlsDoHandshake ( > + IN VOID *Tls, > + IN UINT8 *BufferIn, OPTIONAL > + IN UINTN BufferInSize, OPTIONAL > + OUT UINT8 *BufferOut, OPTIONAL > + IN OUT UINTN *BufferOutSize > + ); > + > +/** > + Hande 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 messa= ge > based on error type. > + > + @param[in] Tls Pointer to the TLS object for state ch= ecking. > + @param[in] BufferIn Pointer to the most recently received = TLS Alert > packet. > + @param[in] BufferInSize Packet size in bytes for the most rece= ntly > received TLS > + Alert packet. > + @param[out] BufferOut Pointer to the buffer to hold the buil= t packet. > + @param[in, out] BufferOutSize Pointer to the buffer size in bytes. O= n > input, it is > + the buffer size provided by the caller= . On output, it > + is the buffer size in fact needed to c= ontain the > + packet. > + > + @retval EFI_SUCCESS The required TLS packet is built succe= ssfully. > + @retval EFI_INVALID_PARAMETER One or more of the following > conditions is TRUE: > + Tls is NULL. > + BufferIn is NULL but BufferInSize is N= OT 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 > +TlsHandeAlert ( > + 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 ch= ecking. > + @param[in, out] Buffer Pointer to the buffer to hold the buil= t packet. > + @param[in, out] BufferSize Pointer to the buffer size in bytes. O= n input, > it is > + the buffer size provided by the caller= . On output, it > + is the buffer size in fact needed to c= ontain the > + packet. > + > + @retval EFI_SUCCESS The required TLS packet is built succe= ssfully. > + @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 z= ero. > + @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 Buff= er. > + > + This function will attempt to read BufferSize bytes from the TLS objec= t > + 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 objec= t. > + @retval <=3D0 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 Buf= fer > + 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 obje= ct. > + @retval <=3D0 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 buff= er. > + > + This function tries to read BufferSize bytes data from the specified T= LS > + connection into the Buffer. > + > + @param[in] Tls Pointer to the TLS connection for data r= eading. > + @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 <=3D0 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 int= o the > + specified TLS connection. > + > + @param[in] Tls Pointer to the TLS connection for data writi= ng. > + @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 <=3D0 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 successfu= lly. > + @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 communicati= on > 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 f= lags. > + > +**/ > +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 resumptio= n. > + @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 requesti= ng > + 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 bi= nary > + X.509 certificate or PEM-encoded X.509 certifi= cate. > + @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 objec= t > + for TLS negotiation. > + > + @param[in] Tls Pointer to the TLS object. > + @param[in] Data Pointer to the data buffer of a DER-encoded bi= nary > + X.509 certificate or PEM-encoded X.509 certifi= cate. > + @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 RS= A > + 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 valid= ation. > + > + This function adds the CA-supplied certificate revocation list data fo= r > + certificate validity checking. > + > + @param[in] Data Pointer to the data buffer of a DER-encoded CR= L 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 successfu= lly. > + @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. > + > +**/ > +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 successfull= y. > + @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 i= n > + the specified TLS connection. > + > + @param[in] Tls Pointer to the TLS object. > + @param[in,out] KeyMaterial Buffer to contain the returned key mate= rial. > + > + @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 dat= a. > + > +**/ > +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 dat= a. > + > +**/ > +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 s= et > + 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 dat= a. > + > +**/ > +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 speci= fied > + 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 dat= a. > + > +**/ > +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.
> +This program and the accompanying materials > +are licensed and made available under the terms and conditions of the BS= D > License > +which accompanies this distribution. The full text of the license may b= e > 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 > +#include > +#include > +#include > + > +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..31220b3 > --- /dev/null > +++ b/CryptoPkg/Library/TlsLib/TlsConfig.c > @@ -0,0 +1,1055 @@ > +/** @file > + SSL/TLS Configuration Library Wrapper Implementation over OpenSSL. > + > +Copyright (c) 2016, Intel Corporation. All rights reserved.
> +(C) Copyright 2016 Hewlett Packard Enterprise Development LP
> +This program and the accompanying materials > +are licensed and made available under the terms and conditions of the BS= D > License > +which accompanies this distribution. The full text of the license may b= e > 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[] =3D { > + { 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_S= HA, > 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_S= HA > + { 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 =3D TlsCipherMappingTable; > + TableSize =3D sizeof (TlsCipherMappingTable) / sizeof (TLS_CIPHER_PAIR= ); > + > + // > + // Search Cipher Mapping Table for IANA-OpenSSL Cipher Translation > + // > + for (Index =3D 0; Index < TableSize; Index++, CipherEntry++) { > + // > + // Translate IANA cipher suite name to OpenSSL name. > + // > + if (CipherEntry->IanaCipher =3D=3D 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 =3D (TLS_CONNECTION *)Tls; > + if (TlsConn =3D=3D NULL || TlsConn->Ssl =3D=3D NULL) { > + return EFI_INVALID_PARAMETER; > + } > + > + ProtoVersion =3D (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 successfu= lly. > + @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 =3D (TLS_CONNECTION *) Tls; > + if (TlsConn =3D=3D NULL || TlsConn->Ssl =3D=3D 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 =3D (TLS_CONNECTION *) Tls; > + if (TlsConn =3D=3D NULL || TlsConn->Ssl =3D=3D NULL || CipherId =3D=3D= NULL) { > + return EFI_INVALID_PARAMETER; > + } > + > + MappingName =3D NULL; > + > + memset (CipherString, 0, sizeof (CipherString)); > + > + for (Index =3D 0; Index < CipherNum; Index++) { > + // > + // Handling OpenSSL / RFC Cipher name mapping. > + // > + MappingName =3D TlsGetCipherString (*(CipherId + Index)); > + if (MappingName =3D=3D NULL) { > + return EFI_UNSUPPORTED; > + } > + > + if (Index !=3D 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) <=3D 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 communicati= on > was > + set successfully. > + @retval EFI_UNSUPPORTED Unsupported compression method. > + > +**/ > +EFI_STATUS > +EFIAPI > +TlsSetCompressionMethod ( > + IN UINT8 CompMethod > + ) > +{ > + COMP_METHOD *Cm; > + INTN Ret; > + > + Cm =3D NULL; > + Ret =3D 0; > + > + if (CompMethod =3D=3D 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 =3D=3D 1) { > + Cm =3D COMP_zlib(); > + } else { > + return EFI_UNSUPPORTED; > + } > + > + // > + // Adds the compression method to the list of available > + // compression methods. > + // > + Ret =3D SSL_COMP_add_compression_method (CompMethod, Cm); > + if (Ret !=3D 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 f= lags. > + > +**/ > +VOID > +EFIAPI > +TlsSetVerify ( > + IN VOID *Tls, > + IN UINT32 VerifyMode > + ) > +{ > + TLS_CONNECTION *TlsConn; > + > + TlsConn =3D (TLS_CONNECTION *) Tls; > + if (TlsConn =3D=3D NULL || TlsConn->Ssl =3D=3D 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 resumptio= n. > + @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 =3D (TLS_CONNECTION *) Tls; > + Session =3D NULL; > + > + if (TlsConn =3D=3D NULL || TlsConn->Ssl =3D=3D NULL || SessionId =3D= =3D NULL) { > + return EFI_INVALID_PARAMETER; > + } > + > + Session =3D SSL_get_session (TlsConn->Ssl); > + if (Session =3D=3D NULL) { > + return EFI_UNSUPPORTED; > + } > + > + Session->session_id_length =3D 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 requesti= ng > + 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 bi= nary > + X.509 certificate or PEM-encoded X.509 certifi= cate. > + @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 =3D NULL; > + Cert =3D NULL; > + X509Store =3D NULL; > + Status =3D EFI_SUCCESS; > + TlsConn =3D (TLS_CONNECTION *) Tls; > + Ret =3D 0; > + > + if (TlsConn =3D=3D NULL || TlsConn->Ssl =3D=3D NULL || Data =3D=3D NUL= L || DataSize > =3D=3D 0) { > + return EFI_INVALID_PARAMETER; > + } > + > + // > + // DER-encoded binary X.509 certificate or PEM-encoded X.509 certifica= te. > + // Determine whether certificate is from DER encoding, if so, translat= e it to > X509 structure. > + // > + Cert =3D d2i_X509 (NULL, (const unsigned char ** )&Data, (long) DataSi= ze); > + if (Cert =3D=3D NULL) { > + // > + // Certificate is from PEM encoding. > + // > + BioCert =3D BIO_new (BIO_s_mem ()); > + if (BioCert =3D=3D NULL) { > + Status =3D EFI_OUT_OF_RESOURCES; > + goto ON_EXIT; > + } > + > + if (BIO_write (BioCert, Data, (UINT32) DataSize) <=3D 0) { > + Status =3D EFI_ABORTED; > + goto ON_EXIT; > + } > + > + Cert =3D PEM_read_bio_X509 (BioCert, NULL, NULL, NULL); > + if (Cert =3D=3D NULL) { > + Status =3D EFI_ABORTED; > + goto ON_EXIT; > + } > + } > + > + SslCtx =3D SSL_get_SSL_CTX (TlsConn->Ssl); > + X509Store =3D SSL_CTX_get_cert_store (SslCtx); > + if (X509Store =3D=3D NULL) { > + Status =3D EFI_ABORTED; > + goto ON_EXIT; > + } > + > + // > + // Add certificate to X509 store > + // > + Ret =3D X509_STORE_add_cert (X509Store, Cert); > + if (Ret !=3D 1) { > + ErrorCode =3D ERR_peek_last_error (); > + // > + // Ignore "already in table" errors > + // > + if (!(ERR_GET_FUNC (ErrorCode) =3D=3D X509_F_X509_STORE_ADD_CERT && > + ERR_GET_REASON (ErrorCode) =3D=3D > X509_R_CERT_ALREADY_IN_HASH_TABLE)) { > + Status =3D EFI_ABORTED; > + goto ON_EXIT; > + } > + } > + > +ON_EXIT: > + if (BioCert !=3D NULL) { > + BIO_free (BioCert); > + } > + > + if (Cert !=3D 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 objec= t > + for TLS negotiation. > + > + @param[in] Tls Pointer to the TLS object. > + @param[in] Data Pointer to the data buffer of a DER-encoded bi= nary > + X.509 certificate or PEM-encoded X.509 certifi= cate. > + @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 =3D NULL; > + Cert =3D NULL; > + Status =3D EFI_SUCCESS; > + TlsConn =3D (TLS_CONNECTION *) Tls; > + > + if (TlsConn =3D=3D NULL || TlsConn->Ssl =3D=3D NULL || Data =3D=3D NUL= L || DataSize > =3D=3D 0) { > + return EFI_INVALID_PARAMETER; > + } > + > + // > + // DER-encoded binary X.509 certificate or PEM-encoded X.509 certifica= te. > + // Determine whether certificate is from DER encoding, if so, translat= e it to > X509 structure. > + // > + Cert =3D d2i_X509 (NULL, (const unsigned char ** )&Data, (long) DataSi= ze); > + if (Cert =3D=3D NULL) { > + // > + // Certificate is from PEM encoding. > + // > + BioCert =3D BIO_new (BIO_s_mem ()); > + if (BioCert =3D=3D NULL) { > + Status =3D EFI_OUT_OF_RESOURCES; > + goto ON_EXIT; > + } > + > + if (BIO_write (BioCert, Data, (UINT32) DataSize) <=3D 0) { > + Status =3D EFI_ABORTED; > + goto ON_EXIT; > + } > + > + Cert =3D PEM_read_bio_X509 (BioCert, NULL, NULL, NULL); > + if (Cert =3D=3D NULL) { > + Status =3D EFI_ABORTED; > + goto ON_EXIT; > + } > + } > + > + if (SSL_use_certificate (TlsConn->Ssl, Cert) !=3D 1) { > + Status =3D EFI_ABORTED; > + goto ON_EXIT; > + } > + > +ON_EXIT: > + if (BioCert !=3D NULL) { > + BIO_free (BioCert); > + } > + > + if (Cert !=3D 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 RS= A > + 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 valid= ation. > + > + This function adds the CA-supplied certificate revocation list data fo= r > + certificate validity checking. > + > + @param[in] Data Pointer to the data buffer of a DER-encoded CR= L 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 =3D (TLS_CONNECTION *) Tls; > + > + ASSERT (TlsConn !=3D 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 =3D (TLS_CONNECTION *) Tls; > + > + ASSERT (TlsConn !=3D 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 successfu= lly. > + @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 =3D (TLS_CONNECTION *) Tls; > + Cipher =3D NULL; > + > + if (TlsConn =3D=3D NULL || TlsConn->Ssl =3D=3D NULL || CipherId =3D=3D= NULL) { > + return EFI_INVALID_PARAMETER; > + } > + > + Cipher =3D SSL_get_current_cipher (TlsConn->Ssl); > + if (Cipher =3D=3D NULL) { > + return EFI_UNSUPPORTED; > + } > + > + *CipherId =3D (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. > + > +**/ > +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 =3D (TLS_CONNECTION *) Tls; > + > + ASSERT (TlsConn !=3D 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 successfull= y. > + @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 =3D (TLS_CONNECTION *) Tls; > + Session =3D NULL; > + > + if (TlsConn =3D=3D NULL || TlsConn->Ssl =3D=3D NULL || SessionId =3D= =3D NULL || > SessionIdLen =3D=3D NULL) { > + return EFI_INVALID_PARAMETER; > + } > + > + Session =3D SSL_get_session (TlsConn->Ssl); > + if (Session =3D=3D NULL) { > + return EFI_UNSUPPORTED; > + } > + > + SslSessionId =3D 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 =3D (TLS_CONNECTION *) Tls; > + > + if (TlsConn =3D=3D NULL || TlsConn->Ssl =3D=3D NULL || ClientRandom = =3D=3D 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 =3D (TLS_CONNECTION *) Tls; > + > + if (TlsConn =3D=3D NULL || TlsConn->Ssl =3D=3D NULL || ServerRandom = =3D=3D 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 i= n > + the specified TLS connection. > + > + @param[in] Tls Pointer to the TLS object. > + @param[in,out] KeyMaterial Buffer to contain the returned key mate= rial. > + > + @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 =3D (TLS_CONNECTION *) Tls; > + Session =3D NULL; > + > + if (TlsConn =3D=3D NULL || TlsConn->Ssl =3D=3D NULL || KeyMaterial =3D= =3D NULL) { > + return EFI_INVALID_PARAMETER; > + } > + > + Session =3D SSL_get_session (TlsConn->Ssl); > + > + if (Session =3D=3D 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 dat= a. > + > +**/ > +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 dat= a. > + > +**/ > +EFI_STATUS > +EFIAPI > +TlsGetHostPublicCert ( > + IN VOID *Tls, > + OUT VOID *Data, > + IN OUT UINTN *DataSize > + ) > +{ > + X509 *Cert; > + EFI_STATUS Status; > + TLS_CONNECTION *TlsConn; > + > + Cert =3D NULL; > + Status =3D EFI_SUCCESS; > + TlsConn =3D (TLS_CONNECTION *) Tls; > + > + if (TlsConn =3D=3D NULL || TlsConn->Ssl =3D=3D NULL || DataSize =3D=3D= NULL) { > + return EFI_INVALID_PARAMETER; > + } > + > + Cert =3D SSL_get_certificate(TlsConn->Ssl); > + if (Cert =3D=3D NULL) { > + Status =3D EFI_NOT_FOUND; > + } > + > + // > + // Only DER encoding is supported currently. > + // > + if (*DataSize < (UINTN) i2d_X509 (Cert, NULL)) { > + *DataSize =3D (UINTN) i2d_X509 (Cert, NULL); > + return EFI_BUFFER_TOO_SMALL; > + } > + > + *DataSize =3D (UINTN) i2d_X509 (Cert, (unsigned char **) &Data); > + > + return Status; > +} > + > +/** > + Gets the local private key set in the specified TLS object. > + > + This function returns the local private key data which was currently s= et > + 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 dat= a. > + > +**/ > +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 speci= fied > + 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 dat= a. > + > +**/ > +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.
> +(C) Copyright 2016 Hewlett Packard Enterprise Development LP
> +This program and the accompanying materials > +are licensed and made available under the terms and conditions of the BS= D > License > +which accompanies this distribution. The full text of the license may b= e > 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 indirect= ly > + 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 requir= ed > + // 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 =3D=3D NULL) { > + return; > + } > + > + if (TlsCtx !=3D 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 =3D (MajorVer << 8) | MinorVer; > + > + TlsCtx =3D SSL_CTX_new (SSLv23_client_method ()); > + if (TlsCtx =3D=3D 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 th= e > + 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 =3D (TLS_CONNECTION *) Tls; > + if (TlsConn =3D=3D NULL) { > + return; > + } > + > + // > + // Free the internal TLS and BIO objects. > + // > + if (TlsConn->Ssl !=3D NULL) { > + SSL_free (TlsConn->Ssl); > + } > + > + if (TlsConn->InBio !=3D NULL) { > + BIO_free (TlsConn->InBio); > + } > + > + if (TlsConn->OutBio !=3D 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 objec= t > + inherits the setting of the underlying context TlsCtx: connection meth= od, > + 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 =3D NULL; > + > + // > + // Allocate one new TLS_CONNECTION object > + // > + TlsConn =3D (TLS_CONNECTION *) OPENSSL_malloc (sizeof > (TLS_CONNECTION)); > + if (TlsConn =3D=3D NULL) { > + return NULL; > + } > + > + TlsConn->Ssl =3D NULL; > + > + // > + // Create a new SSL Object > + // > + TlsConn->Ssl =3D SSL_new ((SSL_CTX *) TlsCtx); > + if (TlsConn->Ssl =3D=3D NULL) { > + TlsFree ((VOID *) TlsConn); > + return NULL; > + } > + > + // > + // Initialize the created SSL Object > + // > + SSL_set_info_callback (TlsConn->Ssl, NULL); > + > + TlsConn->InBio =3D NULL; > + > + // > + // Set up Reading BIO for TLS connection > + // > + TlsConn->InBio =3D BIO_new (BIO_s_mem ()); > + if (TlsConn->InBio =3D=3D 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 =3D NULL; > + > + // > + // Set up Writing BIO for TLS connection > + // > + TlsConn->OutBio =3D BIO_new (BIO_s_mem ()); > + if (TlsConn->OutBio =3D=3D 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 !=3D NULL && TlsConn->InBio !=3D NULL && TlsConn- > >OutBio !=3D 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 =3D SSL_get_SSL_CTX (TlsConn->Ssl); > + X509Store =3D SSL_CTX_get_cert_store (SslCtx); > + if (X509Store =3D=3D NULL) { > + X509Store =3D X509_STORE_new (); > + if (X509Store =3D=3D 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.
> +# (C) Copyright 2016 Hewlett Packard Enterprise Development LP
> +# 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 ma= y 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 =3D 0x00010005 > + BASE_NAME =3D TlsLib > + MODULE_UNI_FILE =3D TlsLib.uni > + FILE_GUID =3D CC729DC5-4E21-0B36-1A00-3A8E1B86A15= 5 > + MODULE_TYPE =3D DXE_DRIVER > + VERSION_STRING =3D 1.0 > + LIBRARY_CLASS =3D TlsLib|DXE_DRIVER DXE_CORE > UEFI_APPLICATION UEFI_DRIVER > + > +# > +# The following information is for reference only and not required by th= e > build tools. > +# > +# VALID_ARCHITECTURES =3D 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.
> +// > +// 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 ma= y 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..52b55d7 > --- /dev/null > +++ b/CryptoPkg/Library/TlsLib/TlsProcess.c > @@ -0,0 +1,461 @@ > +/** @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.
> +(C) Copyright 2016 Hewlett Packard Enterprise Development LP
> +This program and the accompanying materials > +are licensed and made available under the terms and conditions of the BS= D > License > +which accompanies this distribution. The full text of the license may b= e > 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 check= ing. > + > + @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 =3D (TLS_CONNECTION *) Tls; > + if (TlsConn =3D=3D NULL || TlsConn->Ssl =3D=3D 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 handshak= e operation. > + @param[in] BufferIn Pointer to the most recently received = TLS > Handshake packet. > + @param[in] BufferInSize Packet size in bytes for the most rece= ntly > received TLS > + Handshake packet. > + @param[out] BufferOut Pointer to the buffer to hold the buil= t packet. > + @param[in, out] BufferOutSize Pointer to the buffer size in bytes. O= n > input, it is > + the buffer size provided by the caller= . On output, it > + is the buffer size in fact needed to c= ontain the > + packet. > + > + @retval EFI_SUCCESS The required TLS packet is built succe= ssfully. > + @retval EFI_INVALID_PARAMETER One or more of the following > conditions is TRUE: > + Tls is NULL. > + BufferIn is NULL but BufferInSize is N= OT 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. > + > +**/ > +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 =3D (TLS_CONNECTION *) Tls; > + PendingBufferSize =3D 0; > + Ret =3D 1; > + > + if (TlsConn =3D=3D NULL || \ > + TlsConn->Ssl =3D=3D NULL || TlsConn->InBio =3D=3D NULL || TlsConn->O= utBio =3D=3D > NULL || \ > + BufferOutSize =3D=3D NULL || \ > + (BufferIn =3D=3D NULL && BufferInSize !=3D 0) || \ > + (BufferIn !=3D NULL && BufferInSize =3D=3D 0) || \ > + (BufferOut =3D=3D NULL && *BufferOutSize !=3D 0)) { > + return EFI_INVALID_PARAMETER; > + } > + > + if(BufferIn =3D=3D NULL && BufferInSize =3D=3D 0) { > + // > + // If RequestBuffer is NULL and RequestSize is 0, and TLS session > + // status is EfiTlsSessionNotStarted, the TLS session will be initia= ted > + // and the response packet needs to be ClientHello. > + // > + PendingBufferSize =3D (UINTN) BIO_ctrl_pending (TlsConn->OutBio); > + if (PendingBufferSize =3D=3D 0) { > + SSL_set_connect_state (TlsConn->Ssl); > + Ret =3D SSL_do_handshake (TlsConn->Ssl); > + PendingBufferSize =3D (UINTN) BIO_ctrl_pending (TlsConn->OutBio); > + } > + } else { > + PendingBufferSize =3D (UINTN) BIO_ctrl_pending (TlsConn->OutBio); > + if (PendingBufferSize =3D=3D 0) { > + BIO_write (TlsConn->InBio, BufferIn, (UINT32) BufferInSize); > + Ret =3D SSL_do_handshake (TlsConn->Ssl); > + PendingBufferSize =3D (UINTN) BIO_ctrl_pending (TlsConn->OutBio); > + } > + } > + > + if (Ret < 1) { > + Ret =3D SSL_get_error (TlsConn->Ssl, (int) Ret); > + if (Ret =3D=3D SSL_ERROR_SSL || > + Ret =3D=3D SSL_ERROR_SYSCALL || > + Ret =3D=3D SSL_ERROR_ZERO_RETURN) { > + DEBUG (( > + DEBUG_ERROR, > + "%a SSL_HANDSHAKE_ERROR State=3D0x%x SSL_ERROR_%a\n", > + __FUNCTION__, > + SSL_get_state (TlsConn->Ssl), > + Ret =3D=3D SSL_ERROR_SSL ? "SSL" : Ret =3D=3D SSL_ERROR_SYSCALL = ? > "SYSCALL" : "ZERO_RETURN" > + )); > + DEBUG_CODE_BEGIN (); > + while (TRUE) { > + ErrorCode =3D ERR_get_error (); > + if (ErrorCode =3D=3D 0) { > + break; > + } > + DEBUG (( > + DEBUG_ERROR, > + "%a ERROR 0x%x=3DL%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_PROTOCOL_ERROR; > + } > + } > + > + if (PendingBufferSize > *BufferOutSize) { > + *BufferOutSize =3D PendingBufferSize; > + return EFI_BUFFER_TOO_SMALL; > + } > + > + if (PendingBufferSize > 0) { > + *BufferOutSize =3D BIO_read (TlsConn->OutBio, BufferOut, (UINT32) > PendingBufferSize); > + } else { > + *BufferOutSize =3D 0; > + } > + > + return EFI_SUCCESS; > +} > + > +/** > + Hande 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 messa= ge > based on error type. > + > + @param[in] Tls Pointer to the TLS object for state ch= ecking. > + @param[in] BufferIn Pointer to the most recently received = TLS Alert > packet. > + @param[in] BufferInSize Packet size in bytes for the most rece= ntly > received TLS > + Alert packet. > + @param[out] BufferOut Pointer to the buffer to hold the buil= t packet. > + @param[in, out] BufferOutSize Pointer to the buffer size in bytes. O= n > input, it is > + the buffer size provided by the caller= . On output, it > + is the buffer size in fact needed to c= ontain the > + packet. > + > + @retval EFI_SUCCESS The required TLS packet is built succe= ssfully. > + @retval EFI_INVALID_PARAMETER One or more of the following > conditions is TRUE: > + Tls is NULL. > + BufferIn is NULL but BufferInSize is N= OT 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 > +TlsHandeAlert ( > + 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 =3D (TLS_CONNECTION *) Tls; > + PendingBufferSize =3D 0; > + TempBuffer =3D NULL; > + Ret =3D 0; > + > + if (TlsConn =3D=3D NULL || \ > + TlsConn->Ssl =3D=3D NULL || TlsConn->InBio =3D=3D NULL || TlsConn->O= utBio =3D=3D > NULL || \ > + BufferOutSize =3D=3D NULL || \ > + (BufferIn =3D=3D NULL && BufferInSize !=3D 0) || \ > + (BufferIn !=3D NULL && BufferInSize =3D=3D 0) || \ > + (BufferOut =3D=3D NULL && *BufferOutSize !=3D 0)) { > + return EFI_INVALID_PARAMETER; > + } > + > + PendingBufferSize =3D (UINTN) BIO_ctrl_pending (TlsConn->OutBio); > + if (PendingBufferSize =3D=3D 0 && BufferIn !=3D NULL && BufferInSize != =3D 0) { > + Ret =3D BIO_write (TlsConn->InBio, BufferIn, (UINT32) BufferInSize); > + if (Ret !=3D (INTN) BufferInSize) { > + return EFI_ABORTED; > + } > + > + TempBuffer =3D (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 =3D (UINTN) BIO_ctrl_pending (TlsConn->OutBio); > + } > + > + if (PendingBufferSize > *BufferOutSize) { > + *BufferOutSize =3D PendingBufferSize; > + return EFI_BUFFER_TOO_SMALL; > + } > + > + if (PendingBufferSize > 0) { > + *BufferOutSize =3D BIO_read (TlsConn->OutBio, BufferOut, (UINT32) > PendingBufferSize); > + } else { > + *BufferOutSize =3D 0; > + } > + > + return EFI_SUCCESS; > +} > + > +/** > + Build the CloseNotify packet. > + > + @param[in] Tls Pointer to the TLS object for state ch= ecking. > + @param[in, out] Buffer Pointer to the buffer to hold the buil= t packet. > + @param[in, out] BufferSize Pointer to the buffer size in bytes. O= n input, > it is > + the buffer size provided by the caller= . On output, it > + is the buffer size in fact needed to c= ontain the > + packet. > + > + @retval EFI_SUCCESS The required TLS packet is built succe= ssfully. > + @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 z= ero. > + @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 =3D (TLS_CONNECTION *) Tls; > + PendingBufferSize =3D 0; > + > + if (TlsConn =3D=3D NULL || \ > + TlsConn->Ssl =3D=3D NULL || TlsConn->InBio =3D=3D NULL || TlsConn->O= utBio =3D=3D > NULL || \ > + BufferSize =3D=3D NULL || \ > + (Buffer =3D=3D NULL && *BufferSize !=3D 0)) { > + return EFI_INVALID_PARAMETER; > + } > + > + PendingBufferSize =3D (UINTN) BIO_ctrl_pending (TlsConn->OutBio); > + if (PendingBufferSize =3D=3D 0) { > + // > + // ssl3_send_alert() and ssl3_dispatch_alert() function will be call= ed. > + // > + SSL_shutdown (TlsConn->Ssl); > + PendingBufferSize =3D (UINTN) BIO_ctrl_pending (TlsConn->OutBio); > + } > + > + if (PendingBufferSize > *BufferSize) { > + *BufferSize =3D PendingBufferSize; > + return EFI_BUFFER_TOO_SMALL; > + } > + > + if (PendingBufferSize > 0) { > + *BufferSize =3D BIO_read (TlsConn->OutBio, Buffer, (UINT32) > PendingBufferSize); > + } else { > + *BufferSize =3D 0; > + } > + > + return EFI_SUCCESS; > +} > + > +/** > + Attempts to read bytes from one TLS object and places the data in Buff= er. > + > + This function will attempt to read BufferSize bytes from the TLS objec= t > + 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 objec= t. > + @retval <=3D0 No data was successfully read. > + > +**/ > +INTN > +EFIAPI > +TlsCtrlTrafficOut ( > + IN VOID *Tls, > + IN OUT VOID *Buffer, > + IN UINTN BufferSize > + ) > +{ > + TLS_CONNECTION *TlsConn; > + > + TlsConn =3D (TLS_CONNECTION *) Tls; > + if (TlsConn =3D=3D NULL || TlsConn->OutBio =3D=3D 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 Buf= fer > + 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 obje= ct. > + @retval <=3D0 No data was successfully written. > + > +**/ > +INTN > +EFIAPI > +TlsCtrlTrafficIn ( > + IN VOID *Tls, > + IN VOID *Buffer, > + IN UINTN BufferSize > + ) > +{ > + TLS_CONNECTION *TlsConn; > + > + TlsConn =3D (TLS_CONNECTION *) Tls; > + if (TlsConn =3D=3D NULL || TlsConn->InBio =3D=3D 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 buff= er. > + > + This function tries to read BufferSize bytes data from the specified T= LS > + connection into the Buffer. > + > + @param[in] Tls Pointer to the TLS connection for data r= eading. > + @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 <=3D0 The read operation was not successful. > + > +**/ > +INTN > +EFIAPI > +TlsRead ( > + IN VOID *Tls, > + IN OUT VOID *Buffer, > + IN UINTN BufferSize > + ) > +{ > + TLS_CONNECTION *TlsConn; > + > + TlsConn =3D (TLS_CONNECTION *) Tls; > + if (TlsConn =3D=3D NULL || TlsConn->Ssl =3D=3D 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 int= o the > + specified TLS connection. > + > + @param[in] Tls Pointer to the TLS connection for data writi= ng. > + @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 <=3D0 The write operation was not successful. > + > +**/ > +INTN > +EFIAPI > +TlsWrite ( > + IN VOID *Tls, > + IN VOID *Buffer, > + IN UINTN BufferSize > + ) > +{ > + TLS_CONNECTION *TlsConn; > + > + TlsConn =3D (TLS_CONNECTION *) Tls; > + if (TlsConn =3D=3D NULL || TlsConn->Ssl =3D=3D NULL) { > + return -1; > + } > + > + // > + // Write bytes to the specified TLS connection. > + // > + return SSL_write (TlsConn->Ssl, Buffer, (UINT32) BufferSize); > +} > -- > 1.9.5.msysgit.1