From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) (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 6243082051 for ; Thu, 15 Dec 2016 23:30:45 -0800 (PST) Received: from orsmga004.jf.intel.com ([10.7.209.38]) by fmsmga102.fm.intel.com with ESMTP; 15 Dec 2016 23:30:44 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.33,356,1477983600"; d="scan'208";a="40467400" Received: from fmsmsx108.amr.corp.intel.com ([10.18.124.206]) by orsmga004.jf.intel.com with ESMTP; 15 Dec 2016 23:30:43 -0800 Received: from fmsmsx125.amr.corp.intel.com (10.18.125.40) by FMSMSX108.amr.corp.intel.com (10.18.124.206) with Microsoft SMTP Server (TLS) id 14.3.248.2; Thu, 15 Dec 2016 23:30:43 -0800 Received: from shsmsx151.ccr.corp.intel.com (10.239.6.50) by FMSMSX125.amr.corp.intel.com (10.18.125.40) with Microsoft SMTP Server (TLS) id 14.3.248.2; Thu, 15 Dec 2016 23:30:37 -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 15:30:33 +0800 From: "Wu, Jiaxin" To: "Ye, Ting" , "edk2-devel@lists.01.org" CC: "Fu, Siyuan" , "Zhang, Lubo" , "Long, Qin" , Thomas Palmer Thread-Topic: [PATCH v2 05/10] NetworkPkg/TlsDxe: TlsDxe driver implementation over OpenSSL Thread-Index: AQHSVqP/dbU0ZQTuGE2zx7R2QvMyiaEJlHMAgACaPhA= Date: Fri, 16 Dec 2016 07:30:32 +0000 Message-ID: <895558F6EA4E3B41AC93A00D163B727416280BF9@SHSMSX103.ccr.corp.intel.com> References: <1481786530-153704-1-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: eyJDYXRlZ29yeUxhYmVscyI6IiIsIk1ldGFkYXRhIjp7Im5zIjoiaHR0cDpcL1wvd3d3LnRpdHVzLmNvbVwvbnNcL0ludGVsMyIsImlkIjoiZWNiMmE3MDgtZGM1Zi00YzZjLWIzYzUtYjJmMDdhYzZmYzg2IiwicHJvcHMiOlt7Im4iOiJDVFBDbGFzc2lmaWNhdGlvbiIsInZhbHMiOlt7InZhbHVlIjoiQ1RQX0lDIn1dfV19LCJTdWJqZWN0TGFiZWxzIjpbXSwiVE1DVmVyc2lvbiI6IjE1LjkuNi42IiwiVHJ1c3RlZExhYmVsSGFzaCI6ImxqWFQ0YzRMMVcrb2xSMCtTV0pDZzJRYlwvdFFcL09scm1GVWx5cFZJcWRPdz0ifQ== x-ctpclassification: CTP_IC x-originating-ip: [10.239.127.40] MIME-Version: 1.0 Subject: Re: [PATCH v2 05/10] NetworkPkg/TlsDxe: TlsDxe driver implementation over OpenSSL 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 07:30:45 -0000 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Thanks Ting, I have updated the patch according your comments. [PATCH v2 04/10] CryptoPkg: Add new TlsLib library [PATCH v3 05/10] NetworkPkg/TlsDxe: TlsDxe driver implementation over O= penSSL Best Regards! Jiaxin > -----Original Message----- > From: Ye, Ting > Sent: Friday, December 16, 2016 2:16 PM > To: Wu, Jiaxin ; edk2-devel@lists.01.org > Cc: Fu, Siyuan ; Zhang, Lubo ; > Long, Qin ; Thomas Palmer > Subject: RE: [PATCH v2 05/10] NetworkPkg/TlsDxe: TlsDxe driver > implementation over OpenSSL >=20 > Hi Jiaxin, >=20 > Some comments included as below. >=20 > 1. In TlsCreateService > Line 325: ASSERT checks after assignment in line 323. Should put AS= SERT > earlier. > 'Status' looks useless. >=20 > 2. TlsDriver.h > I think the macros ' TLS_INSTANCE_FROM_PROTOCOL_THIS' and ' > TLS_INSTANCE_FROM_CONFIGURATION_THIS' are hard to read. Maybe we > could remove the '_THIS' postfix? > Please define appropriate names. >=20 > 3. TlsImpl.c > I think it's better to update TlsEcryptPacket to TlsEncryptPacket > And also update "continue the other messages encryption\decryption." = To > "continue to encrypt/decrypt other messages." > " The caller will take responsible to..." to " The caller will be > responsible to... " > "Received packet may have multiply TLS record message." To " > Received packet may have multiple TLS record messages." > Also update Multiply to multiple in other places. >=20 > "Copy all TLS plain record header and payload to ProcessBuffer". > ProcessBuffer looks a local variable but not exist. May update to BufferI= n? > Please double check. >=20 > Others are good to me. >=20 > Reviewed-by: Ye Ting >=20 > Thanks, > Ting >=20 > -----Original Message----- > From: Wu, Jiaxin > Sent: Thursday, December 15, 2016 3:22 PM > To: edk2-devel@lists.01.org > Cc: Ye, Ting ; Fu, Siyuan ; Zhang= , > Lubo ; Long, Qin ; Thomas > Palmer ; Wu, Jiaxin > Subject: [PATCH v2 05/10] NetworkPkg/TlsDxe: TlsDxe driver implementation > over OpenSSL >=20 > v2: > * Refine the TlsEcryptPacket/TlsDecryptPacket function > according the community feedback. >=20 > This patch is the implementation of EFI TLS Service Binding > Protocol, EFI TLS Protocol and EFI TLS Configuration Protocol > Interfaces. >=20 > Cc: Ye Ting > Cc: Fu Siyuan > Cc: Zhang Lubo > Cc: Long Qin > Cc: Thomas Palmer > Contributed-under: TianoCore Contribution Agreement 1.0 > Signed-off-by: Wu Jiaxin > --- > NetworkPkg/TlsDxe/TlsConfigProtocol.c | 152 ++++++++ > NetworkPkg/TlsDxe/TlsDriver.c | 498 > +++++++++++++++++++++++++++ > NetworkPkg/TlsDxe/TlsDriver.h | 237 +++++++++++++ > NetworkPkg/TlsDxe/TlsDxe.inf | 65 ++++ > NetworkPkg/TlsDxe/TlsDxe.uni | 25 ++ > NetworkPkg/TlsDxe/TlsDxeExtra.uni | 18 + > NetworkPkg/TlsDxe/TlsImpl.c | 326 ++++++++++++++++++ > NetworkPkg/TlsDxe/TlsImpl.h | 315 +++++++++++++++++ > NetworkPkg/TlsDxe/TlsProtocol.c | 632 > ++++++++++++++++++++++++++++++++++ > 9 files changed, 2268 insertions(+) > create mode 100644 NetworkPkg/TlsDxe/TlsConfigProtocol.c > create mode 100644 NetworkPkg/TlsDxe/TlsDriver.c > create mode 100644 NetworkPkg/TlsDxe/TlsDriver.h > create mode 100644 NetworkPkg/TlsDxe/TlsDxe.inf > create mode 100644 NetworkPkg/TlsDxe/TlsDxe.uni > create mode 100644 NetworkPkg/TlsDxe/TlsDxeExtra.uni > create mode 100644 NetworkPkg/TlsDxe/TlsImpl.c > create mode 100644 NetworkPkg/TlsDxe/TlsImpl.h > create mode 100644 NetworkPkg/TlsDxe/TlsProtocol.c >=20 > diff --git a/NetworkPkg/TlsDxe/TlsConfigProtocol.c > b/NetworkPkg/TlsDxe/TlsConfigProtocol.c > new file mode 100644 > index 0000000..2ec79c9 > --- /dev/null > +++ b/NetworkPkg/TlsDxe/TlsConfigProtocol.c > @@ -0,0 +1,152 @@ > +/** @file > + Implementation of EFI TLS Configuration Protocol Interfaces. > + > + Copyright (c) 2016, Intel Corporation. All rights reserved.
> + > + This program and the accompanying materials > + are licensed and made available under the terms and conditions of the = BSD > License > + which accompanies this distribution. The full text of the license may= be > found at > + http://opensource.org/licenses/bsd-license.php. > + > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > + > +**/ > + > +#include "TlsImpl.h" > + > +EFI_TLS_CONFIGURATION_PROTOCOL mTlsConfigurationProtocol =3D { > + TlsConfigurationSetData, > + TlsConfigurationGetData > +}; > + > +/** > + Set TLS configuration data. > + > + The SetData() function sets TLS configuration to non-volatile storage = or > volatile > + storage. > + > + @param[in] This Pointer to the > EFI_TLS_CONFIGURATION_PROTOCOL instance. > + @param[in] DataType Configuration data type. > + @param[in] Data Pointer to configuration data. > + @param[in] DataSize Total size of configuration data. > + > + @retval EFI_SUCCESS The TLS configuration data is set succ= essfully. > + @retval EFI_INVALID_PARAMETER One or more of the following > conditions is TRUE: > + This is NULL. > + Data is NULL. > + DataSize is 0. > + @retval EFI_UNSUPPORTED The DataType is unsupported. > + @retval EFI_OUT_OF_RESOURCES Required system resources could not > be allocated. > + > +**/ > +EFI_STATUS > +EFIAPI > +TlsConfigurationSetData ( > + IN EFI_TLS_CONFIGURATION_PROTOCOL *This, > + IN EFI_TLS_CONFIG_DATA_TYPE DataType, > + IN VOID *Data, > + IN UINTN DataSize > + ) > +{ > + EFI_STATUS Status; > + TLS_INSTANCE *Instance; > + EFI_TPL OldTpl; > + > + Status =3D EFI_SUCCESS; > + > + if (This =3D=3D NULL || Data =3D=3D NULL || DataSize =3D=3D 0) { > + return EFI_INVALID_PARAMETER; > + } > + > + OldTpl =3D gBS->RaiseTPL (TPL_CALLBACK); > + > + Instance =3D TLS_INSTANCE_FROM_CONFIGURATION_THIS (This); > + > + switch (DataType) { > + case EfiTlsConfigDataTypeCACertificate: > + Status =3D TlsSetCaCertificate (Instance->TlsConn, Data, DataSize); > + break; > + case EfiTlsConfigDataTypeHostPublicCert: > + Status =3D TlsSetHostPublicCert (Instance->TlsConn, Data, DataSize); > + break; > + case EfiTlsConfigDataTypeHostPrivateKey: > + Status =3D TlsSetHostPrivateKey (Instance->TlsConn, Data, DataSize); > + break; > + case EfiTlsConfigDataTypeCertRevocationList: > + Status =3D TlsSetCertRevocationList (Data, DataSize); > + break; > + default: > + Status =3D EFI_UNSUPPORTED; > + } > + > + gBS->RestoreTPL (OldTpl); > + return Status; > +} > + > +/** > + Get TLS configuration data. > + > + The GetData() function gets TLS configuration. > + > + @param[in] This Pointer to the > EFI_TLS_CONFIGURATION_PROTOCOL instance. > + @param[in] DataType Configuration data type. > + @param[in, out] Data Pointer to configuration data. > + @param[in, out] DataSize Total size of configuration data. On i= nput, it > means > + the size of Data buffer. On output, it= means the size > + of copied Data buffer if EFI_SUCCESS, = and means the > + size of desired Data buffer if EFI_BUF= FER_TOO_SMALL. > + > + @retval EFI_SUCCESS The TLS configuration data is got succ= essfully. > + @retval EFI_INVALID_PARAMETER One or more of the following > conditions is TRUE: > + This is NULL. > + DataSize is NULL. > + Data is NULL if *DataSize is not zero. > + @retval EFI_UNSUPPORTED The DataType is unsupported. > + @retval EFI_NOT_FOUND The TLS configuration data is not foun= d. > + @retval EFI_BUFFER_TOO_SMALL The buffer is too small to hold the da= ta. > +**/ > +EFI_STATUS > +EFIAPI > +TlsConfigurationGetData ( > + IN EFI_TLS_CONFIGURATION_PROTOCOL *This, > + IN EFI_TLS_CONFIG_DATA_TYPE DataType, > + IN OUT VOID *Data, OPTIONAL > + IN OUT UINTN *DataSize > + ) > +{ > + EFI_STATUS Status; > + TLS_INSTANCE *Instance; > + > + EFI_TPL OldTpl; > + > + Status =3D EFI_SUCCESS; > + > + if (This =3D=3D NULL || DataSize =3D=3D NULL || (Data =3D=3D NULL && *= DataSize !=3D 0)) > { > + return EFI_INVALID_PARAMETER; > + } > + > + OldTpl =3D gBS->RaiseTPL (TPL_CALLBACK); > + > + Instance =3D TLS_INSTANCE_FROM_CONFIGURATION_THIS (This); > + > + switch (DataType) { > + case EfiTlsConfigDataTypeCACertificate: > + Status =3D TlsGetCaCertificate (Instance->TlsConn, Data, DataSize); > + break; > + case EfiTlsConfigDataTypeHostPublicCert: > + Status =3D TlsGetHostPublicCert (Instance->TlsConn, Data, DataSize); > + break; > + case EfiTlsConfigDataTypeHostPrivateKey: > + Status =3D TlsGetHostPrivateKey (Instance->TlsConn, Data, DataSize); > + break; > + case EfiTlsConfigDataTypeCertRevocationList: > + Status =3D TlsGetCertRevocationList (Data, DataSize); > + break; > + default: > + Status =3D EFI_UNSUPPORTED; > + } > + > + gBS->RestoreTPL (OldTpl); > + return Status; > +} > diff --git a/NetworkPkg/TlsDxe/TlsDriver.c b/NetworkPkg/TlsDxe/TlsDriver.= c > new file mode 100644 > index 0000000..0a75c39 > --- /dev/null > +++ b/NetworkPkg/TlsDxe/TlsDriver.c > @@ -0,0 +1,498 @@ > +/** @file > + The Driver Binding and Service Binding Protocol for TlsDxe driver. > + > + Copyright (c) 2016, Intel Corporation. All rights reserved.
> + > + This program and the accompanying materials > + are licensed and made available under the terms and conditions of the = BSD > License > + which accompanies this distribution. The full text of the license may= be > found at > + http://opensource.org/licenses/bsd-license.php. > + > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > + > +**/ > + > +#include "TlsImpl.h" > + > +EFI_SERVICE_BINDING_PROTOCOL mTlsServiceBinding =3D { > + TlsServiceBindingCreateChild, > + TlsServiceBindingDestroyChild > +}; > + > +/** > + Release all the resources used by the TLS instance. > + > + @param[in] Instance The TLS instance data. > + > +**/ > +VOID > +TlsCleanInstance ( > + IN TLS_INSTANCE *Instance > + ) > +{ > + if (Instance !=3D NULL) { > + if (Instance->TlsConn !=3D NULL) { > + TlsFree (Instance->TlsConn); > + } > + > + FreePool (Instance); > + } > +} > + > +/** > + Create the TLS instance and initialize it. > + > + @param[in] Service The pointer to the TLS service. > + @param[out] Instance The pointer to the TLS instance. > + > + @retval EFI_OUT_OF_RESOURCES Failed to allocate resources. > + @retval EFI_SUCCESS The TLS instance is created. > + > +**/ > +EFI_STATUS > +TlsCreateInstance ( > + IN TLS_SERVICE *Service, > + OUT TLS_INSTANCE **Instance > + ) > +{ > + TLS_INSTANCE *TlsInstance; > + > + *Instance =3D NULL; > + > + TlsInstance =3D AllocateZeroPool (sizeof (TLS_INSTANCE)); > + if (TlsInstance =3D=3D NULL) { > + return EFI_OUT_OF_RESOURCES; > + } > + > + TlsInstance->Signature =3D TLS_INSTANCE_SIGNATURE; > + InitializeListHead (&TlsInstance->Link); > + TlsInstance->InDestroy =3D FALSE; > + TlsInstance->Service =3D Service; > + > + CopyMem (&TlsInstance->Tls, &mTlsProtocol, sizeof (TlsInstance->Tls)); > + CopyMem (&TlsInstance->TlsConfig, &mTlsConfigurationProtocol, sizeof > (TlsInstance->TlsConfig)); > + > + TlsInstance->TlsSessionState =3D EfiTlsSessionNotStarted; > + > + *Instance =3D TlsInstance; > + > + return EFI_SUCCESS; > +} > + > +/** > + Release all the resources used by the TLS service binding instance. > + > + @param[in] Service The TLS service data. > + > +**/ > +VOID > +TlsCleanService ( > + IN TLS_SERVICE *Service > + ) > +{ > + if (Service !=3D NULL) { > + if (Service->TlsCtx !=3D NULL) { > + TlsCtxFree (Service->TlsCtx); > + } > + > + FreePool (Service); > + } > +} > + > +/** > + Create then initialize a TLS service. > + > + @param[in] Image ImageHandle of the TLS driver > + @param[out] Service The service for TLS driver > + > + @retval EFI_OUT_OF_RESOURCES Failed to allocate resource to create > the service. > + @retval EFI_SUCCESS The service is created for the driver. > + > +**/ > +EFI_STATUS > +TlsCreateService ( > + IN EFI_HANDLE Image, > + OUT TLS_SERVICE **Service > + ) > +{ > + EFI_STATUS Status; > + TLS_SERVICE *TlsService; > + > + Status =3D EFI_SUCCESS; > + *Service =3D NULL; > + > + ASSERT (Service !=3D NULL); > + > + // > + // Allocate a TLS Service Data > + // > + TlsService =3D AllocateZeroPool (sizeof (TLS_SERVICE)); > + if (TlsService =3D=3D NULL) { > + return EFI_OUT_OF_RESOURCES; > + } > + > + // > + // Initialize TLS Service Data > + // > + TlsService->Signature =3D TLS_SERVICE_SIGNATURE; > + CopyMem (&TlsService->ServiceBinding, &mTlsServiceBinding, sizeof > (TlsService->ServiceBinding)); > + TlsService->TlsChildrenNum =3D 0; > + InitializeListHead (&TlsService->TlsChildrenList); > + TlsService->ImageHandle =3D Image; > + > + *Service =3D TlsService; > + > + return Status; > +} > + > +/** > + Unloads an image. > + > + @param[in] ImageHandle Handle that identifies the image to = be > unloaded. > + > + @retval EFI_SUCCESS The image has been unloaded. > + @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image > handle. > + > +**/ > +EFI_STATUS > +EFIAPI > +TlsUnload ( > + IN EFI_HANDLE ImageHandle > + ) > +{ > + EFI_STATUS Status; > + UINTN HandleNum; > + EFI_HANDLE *HandleBuffer; > + UINT32 Index; > + EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; > + TLS_SERVICE *TlsService; > + > + HandleBuffer =3D NULL; > + ServiceBinding =3D NULL; > + TlsService =3D NULL; > + > + // > + // Locate all the handles with Tls service binding protocol. > + // > + Status =3D gBS->LocateHandleBuffer ( > + ByProtocol, > + &gEfiTlsServiceBindingProtocolGuid, > + NULL, > + &HandleNum, > + &HandleBuffer > + ); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + for (Index =3D 0; Index < HandleNum; Index++) { > + // > + // Firstly, find ServiceBinding interface > + // > + Status =3D gBS->OpenProtocol ( > + HandleBuffer[Index], > + &gEfiTlsServiceBindingProtocolGuid, > + (VOID **) &ServiceBinding, > + ImageHandle, > + NULL, > + EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL > + ); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + TlsService =3D TLS_SERVICE_FROM_THIS (ServiceBinding); > + > + // > + // Then, uninstall ServiceBinding interface > + // > + Status =3D gBS->UninstallMultipleProtocolInterfaces ( > + HandleBuffer[Index], > + &gEfiTlsServiceBindingProtocolGuid, ServiceBinding, > + NULL > + ); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + TlsCleanService (TlsService); > + } > + > + if (HandleBuffer !=3D NULL) { > + FreePool (HandleBuffer); > + } > + > + return EFI_SUCCESS; > +} > + > +/** > + This is the declaration of an EFI image entry point. This entry point = is > + the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers incl= uding > + both device drivers and bus drivers. > + > + @param ImageHandle The firmware allocated handle for the UE= FI > image. > + @param SystemTable A pointer to the EFI System Table. > + > + @retval EFI_SUCCESS The operation completed successfully. > + @retval Others An unexpected error occurred. > +**/ > +EFI_STATUS > +EFIAPI > +TlsDriverEntryPoint ( > + IN EFI_HANDLE ImageHandle, > + IN EFI_SYSTEM_TABLE *SystemTable > + ) > +{ > + EFI_STATUS Status; > + > + TLS_SERVICE *TlsService; > + > + // > + // Create TLS Service > + // > + Status =3D TlsCreateService (ImageHandle, &TlsService); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + ASSERT (TlsService !=3D NULL); > + > + // > + // Initializes the OpenSSL library. > + // > + TlsInitialize (); > + > + // > + // Create a new SSL_CTX object as framework to establish TLS/SSL enabl= ed > + // connections. TLS 1.0 is used as the default version. > + // > + TlsService->TlsCtx =3D TlsCtxNew (TLS10_PROTOCOL_VERSION_MAJOR, > TLS10_PROTOCOL_VERSION_MINOR); > + if (TlsService->TlsCtx =3D=3D NULL) { > + FreePool (TlsService); > + return EFI_ABORTED; > + } > + > + // > + // Install the TlsServiceBinding Protocol onto Handle > + // > + Status =3D gBS->InstallMultipleProtocolInterfaces ( > + &TlsService->Handle, > + &gEfiTlsServiceBindingProtocolGuid, > + &TlsService->ServiceBinding, > + NULL > + ); > + if (EFI_ERROR (Status)) { > + goto ON_CLEAN_SERVICE; > + } > + > + return Status; > + > +ON_CLEAN_SERVICE: > + TlsCleanService (TlsService); > + > + return Status; > +} > + > +/** > + Creates a child handle and installs a protocol. > + > + The CreateChild() function installs a protocol on ChildHandle. > + If ChildHandle is a pointer to NULL, then a new handle is created and > returned in ChildHandle. > + If ChildHandle is not a pointer to NULL, then the protocol installs on= the > existing ChildHandle. > + > + @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL > instance. > + @param[in] ChildHandle Pointer to the handle of the child to create. I= f it is > NULL, > + then a new handle is created. If it is a pointe= r to an existing > UEFI handle, > + then the protocol is added to the existing UEFI= handle. > + > + @retval EFI_SUCCES The protocol was added to ChildHandle. > + @retval EFI_INVALID_PARAMETER ChildHandle is NULL. > + @retval EFI_OUT_OF_RESOURCES There are not enough resources > available to create > + the child. > + @retval other The child handle was not created. > + > +**/ > +EFI_STATUS > +EFIAPI > +TlsServiceBindingCreateChild ( > + IN EFI_SERVICE_BINDING_PROTOCOL *This, > + IN EFI_HANDLE *ChildHandle > + ) > +{ > + TLS_SERVICE *TlsService; > + TLS_INSTANCE *TlsInstance; > + EFI_STATUS Status; > + EFI_TPL OldTpl; > + > + if ((This =3D=3D NULL) || (ChildHandle =3D=3D NULL)) { > + return EFI_INVALID_PARAMETER; > + } > + > + TlsService =3D TLS_SERVICE_FROM_THIS (This); > + > + Status =3D TlsCreateInstance (TlsService, &TlsInstance); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + ASSERT (TlsInstance !=3D NULL); > + > + // > + // Create a new TLS connection object. > + // > + TlsInstance->TlsConn =3D TlsNew (TlsService->TlsCtx); > + if (TlsInstance->TlsConn =3D=3D NULL) { > + Status =3D EFI_ABORTED; > + goto ON_ERROR; > + } > + > + // > + // Set default ConnectionEnd to EfiTlsClient > + // > + Status =3D TlsSetConnectionEnd (TlsInstance->TlsConn, EfiTlsClient); > + if (EFI_ERROR (Status)) { > + goto ON_ERROR; > + } > + > + // > + // Install TLS protocol and configuration protocol onto ChildHandle > + // > + Status =3D gBS->InstallMultipleProtocolInterfaces ( > + ChildHandle, > + &gEfiTlsProtocolGuid, > + &TlsInstance->Tls, > + &gEfiTlsConfigurationProtocolGuid, > + &TlsInstance->TlsConfig, > + NULL > + ); > + if (EFI_ERROR (Status)) { > + goto ON_ERROR; > + } > + > + TlsInstance->ChildHandle =3D *ChildHandle; > + > + // > + // Add it to the TLS service's child list. > + // > + OldTpl =3D gBS->RaiseTPL (TPL_CALLBACK); > + > + InsertTailList (&TlsService->TlsChildrenList, &TlsInstance->Link); > + TlsService->TlsChildrenNum++; > + > + gBS->RestoreTPL (OldTpl); > + > + return EFI_SUCCESS; > + > +ON_ERROR: > + TlsCleanInstance (TlsInstance); > + return Status; > +} > + > +/** > + Destroys a child handle with a protocol installed on it. > + > + The DestroyChild() function does the opposite of CreateChild(). It rem= oves > a protocol > + that was installed by CreateChild() from ChildHandle. If the removed > protocol is the > + last protocol on ChildHandle, then ChildHandle is destroyed. > + > + @param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL > instance. > + @param ChildHandle Handle of the child to destroy. > + > + @retval EFI_SUCCES The protocol was removed from ChildHandl= e. > + @retval EFI_UNSUPPORTED ChildHandle does not support the protoco= l > that is being removed. > + @retval EFI_INVALID_PARAMETER Child handle is NULL. > + @retval EFI_ACCESS_DENIED The protocol could not be removed from > the ChildHandle > + because its services are being used. > + @retval other The child handle was not destroyed. > + > +**/ > +EFI_STATUS > +EFIAPI > +TlsServiceBindingDestroyChild ( > + IN EFI_SERVICE_BINDING_PROTOCOL *This, > + IN EFI_HANDLE ChildHandle > + ) > +{ > + TLS_SERVICE *TlsService; > + TLS_INSTANCE *TlsInstance; > + > + EFI_TLS_PROTOCOL *Tls; > + EFI_TLS_CONFIGURATION_PROTOCOL *TlsConfig; > + EFI_STATUS Status; > + EFI_TPL OldTpl; > + > + if ((This =3D=3D NULL) || (ChildHandle =3D=3D NULL)) { > + return EFI_INVALID_PARAMETER; > + } > + > + TlsService =3D TLS_SERVICE_FROM_THIS (This); > + > + // > + // Find TLS protocol interface installed in ChildHandle > + // > + Status =3D gBS->OpenProtocol ( > + ChildHandle, > + &gEfiTlsProtocolGuid, > + (VOID **) &Tls, > + TlsService->ImageHandle, > + NULL, > + EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL > + ); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + // > + // Find TLS configuration protocol interface installed in ChildHandle > + // > + Status =3D gBS->OpenProtocol ( > + ChildHandle, > + &gEfiTlsConfigurationProtocolGuid, > + (VOID **) &TlsConfig, > + TlsService->ImageHandle, > + NULL, > + EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL > + ); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + TlsInstance =3D TLS_INSTANCE_FROM_PROTOCOL_THIS (Tls); > + > + if (TlsInstance->Service !=3D TlsService) { > + return EFI_INVALID_PARAMETER; > + } > + > + if (TlsInstance->InDestroy) { > + return EFI_SUCCESS; > + } > + > + OldTpl =3D gBS->RaiseTPL (TPL_CALLBACK); > + > + TlsInstance->InDestroy =3D TRUE; > + > + // > + // Uninstall the TLS protocol and TLS Configuration Protocol interface > installed in ChildHandle. > + // > + Status =3D gBS->UninstallMultipleProtocolInterfaces ( > + ChildHandle, > + &gEfiTlsProtocolGuid, > + Tls, > + &gEfiTlsConfigurationProtocolGuid, > + TlsConfig, > + NULL > + ); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + RemoveEntryList (&TlsInstance->Link); > + TlsService->TlsChildrenNum--; > + > + gBS->RestoreTPL (OldTpl); > + > + TlsCleanInstance (TlsInstance); > + > + return EFI_SUCCESS; > +} > diff --git a/NetworkPkg/TlsDxe/TlsDriver.h b/NetworkPkg/TlsDxe/TlsDriver.= h > new file mode 100644 > index 0000000..c3c30a8 > --- /dev/null > +++ b/NetworkPkg/TlsDxe/TlsDriver.h > @@ -0,0 +1,237 @@ > +/** @file > + Header file of the Driver Binding and Service Binding Protocol for Tls= Dxe > driver. > + > + 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 may= be > found at > + http://opensource.org/licenses/bsd-license.php. > + > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > + > +**/ > + > +#ifndef __EFI_TLS_DRIVER_H__ > +#define __EFI_TLS_DRIVER_H__ > + > +#include > + > +// > +// Driver Protocols > +// > +#include > + > +// > +// Driver Version > +// > +#define TLS_VERSION 0x00000000 > + > +#define TLS_SERVICE_SIGNATURE SIGNATURE_32 ('T', 'L', 'S', 'S') > + > +#define TLS_INSTANCE_SIGNATURE SIGNATURE_32 ('T', 'L', 'S', 'I') > + > +/// > +/// TLS Service Data > +/// > +typedef struct _TLS_SERVICE TLS_SERVICE; > + > +/// > +/// TLS Instance Data > +/// > +typedef struct _TLS_INSTANCE TLS_INSTANCE; > + > + > +struct _TLS_SERVICE { > + UINT32 Signature; > + EFI_SERVICE_BINDING_PROTOCOL ServiceBinding; > + > + UINT16 TlsChildrenNum; > + LIST_ENTRY TlsChildrenList; > + > + // > + // Handle to install TlsServiceBinding protocol. > + // > + EFI_HANDLE Handle; > + EFI_HANDLE ImageHandle; > + > + // > + // Main SSL Context object which is created by a server or client once= per > program > + // life-time and which holds mainly default values for the SSL object = which > are later > + // created for the connections. > + // > + VOID *TlsCtx; > +}; > + > +struct _TLS_INSTANCE { > + UINT32 Signature; > + LIST_ENTRY Link; > + > + BOOLEAN InDestroy; > + > + TLS_SERVICE *Service; > + EFI_HANDLE ChildHandle; > + > + EFI_TLS_PROTOCOL Tls; > + EFI_TLS_CONFIGURATION_PROTOCOL TlsConfig; > + > + EFI_TLS_SESSION_STATE TlsSessionState; > + > + // > + // Main SSL Connection which is created by a server or a client > + // per established connection. > + // > + VOID *TlsConn; > +}; > + > + > +#define TLS_SERVICE_FROM_THIS(a) \ > + CR (a, TLS_SERVICE, ServiceBinding, TLS_SERVICE_SIGNATURE) > + > +#define TLS_INSTANCE_FROM_PROTOCOL_THIS(a) \ > + CR (a, TLS_INSTANCE, Tls, TLS_INSTANCE_SIGNATURE) > + > +#define TLS_INSTANCE_FROM_CONFIGURATION_THIS(a) \ > + CR (a, TLS_INSTANCE, TlsConfig, TLS_INSTANCE_SIGNATURE) > + > + > +/** > + Release all the resources used by the TLS instance. > + > + @param[in] Instance The TLS instance data. > + > +**/ > +VOID > +TlsCleanInstance ( > + IN TLS_INSTANCE *Instance > + ); > + > +/** > + Create the TLS instance and initialize it. > + > + @param[in] Service The pointer to the TLS service. > + @param[out] Instance The pointer to the TLS instance. > + > + @retval EFI_OUT_OF_RESOURCES Failed to allocate resources. > + @retval EFI_SUCCESS The TLS instance is created. > + > +**/ > +EFI_STATUS > +TlsCreateInstance ( > + IN TLS_SERVICE *Service, > + OUT TLS_INSTANCE **Instance > + ); > + > +/** > + Release all the resources used by the TLS service binding instance. > + > + @param[in] Service The TLS service data. > + > +**/ > +VOID > +TlsCleanService ( > + IN TLS_SERVICE *Service > + ); > + > +/** > + Create then initialize a TLS service. > + > + @param[in] Image ImageHandle of the TLS driver > + @param[out] Service The service for TLS driver > + > + @retval EFI_OUT_OF_RESOURCES Failed to allocate resource to create > the service. > + @retval EFI_SUCCESS The service is created for the driver. > + > +**/ > +EFI_STATUS > +TlsCreateService ( > + IN EFI_HANDLE Image, > + OUT TLS_SERVICE **Service > + ); > + > +/** > + Unloads an image. > + > + @param[in] ImageHandle Handle that identifies the image to be > unloaded. > + > + @retval EFI_SUCCESS The image has been unloaded. > + @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image > handle. > + > +**/ > +EFI_STATUS > +EFIAPI > +TlsUnload ( > + IN EFI_HANDLE ImageHandle > + ); > + > +/** > + This is the declaration of an EFI image entry point. This entry point = is > + the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers incl= uding > + both device drivers and bus drivers. > + > + @param ImageHandle The firmware allocated handle for the UE= FI > image. > + @param SystemTable A pointer to the EFI System Table. > + > + @retval EFI_SUCCESS The operation completed successfully. > + @retval Others An unexpected error occurred. > +**/ > +EFI_STATUS > +EFIAPI > +TlsDriverEntryPoint ( > + IN EFI_HANDLE ImageHandle, > + IN EFI_SYSTEM_TABLE *SystemTable > + ); > + > +/** > + Creates a child handle and installs a protocol. > + > + The CreateChild() function installs a protocol on ChildHandle. > + If ChildHandle is a pointer to NULL, then a new handle is created and > returned in ChildHandle. > + If ChildHandle is not a pointer to NULL, then the protocol installs on= the > existing ChildHandle. > + > + @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL > instance. > + @param[in] ChildHandle Pointer to the handle of the child to create. I= f it is > NULL, > + then a new handle is created. If it is a pointe= r to an existing > UEFI handle, > + then the protocol is added to the existing UEFI= handle. > + > + @retval EFI_SUCCES The protocol was added to ChildHandle. > + @retval EFI_INVALID_PARAMETER ChildHandle is NULL. > + @retval EFI_OUT_OF_RESOURCES There are not enough resources > available to create > + the child. > + @retval other The child handle was not created. > + > +**/ > +EFI_STATUS > +EFIAPI > +TlsServiceBindingCreateChild ( > + IN EFI_SERVICE_BINDING_PROTOCOL *This, > + IN EFI_HANDLE *ChildHandle > + ); > + > +/** > + Destroys a child handle with a protocol installed on it. > + > + The DestroyChild() function does the opposite of CreateChild(). It rem= oves > a protocol > + that was installed by CreateChild() from ChildHandle. If the removed > protocol is the > + last protocol on ChildHandle, then ChildHandle is destroyed. > + > + @param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL > instance. > + @param ChildHandle Handle of the child to destroy. > + > + @retval EFI_SUCCES The protocol was removed from ChildHandl= e. > + @retval EFI_UNSUPPORTED ChildHandle does not support the protoco= l > that is being removed. > + @retval EFI_INVALID_PARAMETER Child handle is NULL. > + @retval EFI_ACCESS_DENIED The protocol could not be removed from > the ChildHandle > + because its services are being used. > + @retval other The child handle was not destroyed. > + > +**/ > +EFI_STATUS > +EFIAPI > +TlsServiceBindingDestroyChild ( > + IN EFI_SERVICE_BINDING_PROTOCOL *This, > + IN EFI_HANDLE ChildHandle > + ); > + > +#endif > diff --git a/NetworkPkg/TlsDxe/TlsDxe.inf b/NetworkPkg/TlsDxe/TlsDxe.inf > new file mode 100644 > index 0000000..dba3257 > --- /dev/null > +++ b/NetworkPkg/TlsDxe/TlsDxe.inf > @@ -0,0 +1,65 @@ > +## @file > +# This module produces EFI TLS Protocol, EFI TLS Service Binding Protoc= ol > and > +# EFI TLS Configuration Protocol. > +# > +# This module produces EFI TLS (Transport Layer Security) Protocol and = EFI > TLS > +# Service Binding Protocol, to provide TLS services. > +# > +# Copyright (c) 2016, Intel Corporation. All rights reserved.
> +# > +# This program and the accompanying materials > +# are licensed and made available under the terms and conditions of the > BSD License > +# which accompanies this distribution. The full text of the license may= be > found at > +# http://opensource.org/licenses/bsd-license.php. > +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > +# > +# > +## > + > +[Defines] > + INF_VERSION =3D 0x00010005 > + BASE_NAME =3D TlsDxe > + FILE_GUID =3D 3aceb0c0-3c72-11e4-9a56-74d435052646 > + MODULE_TYPE =3D UEFI_DRIVER > + VERSION_STRING =3D 1.0 > + ENTRY_POINT =3D TlsDriverEntryPoint > + UNLOAD_IMAGE =3D TlsUnload > + MODULE_UNI_FILE =3D TlsDxe.uni > + > +# > +# VALID_ARCHITECTURES =3D IA32 X64 > +# > + > +[Packages] > + MdePkg/MdePkg.dec > + MdeModulePkg/MdeModulePkg.dec > + CryptoPkg/CryptoPkg.dec > + > +[Sources] > + TlsDriver.h > + TlsDriver.c > + TlsProtocol.c > + TlsConfigProtocol.c > + TlsImpl.h > + TlsImpl.c > + > +[LibraryClasses] > + UefiDriverEntryPoint > + UefiBootServicesTableLib > + MemoryAllocationLib > + BaseMemoryLib > + BaseLib > + UefiLib > + DebugLib > + NetLib > + BaseCryptLib > + TlsLib > + > +[Protocols] > + gEfiTlsServiceBindingProtocolGuid ## PRODUCES > + gEfiTlsProtocolGuid ## PRODUCES > + gEfiTlsConfigurationProtocolGuid ## PRODUCES > + > +[UserExtensions.TianoCore."ExtraFiles"] > + TlsDxeExtra.uni > diff --git a/NetworkPkg/TlsDxe/TlsDxe.uni b/NetworkPkg/TlsDxe/TlsDxe.uni > new file mode 100644 > index 0000000..98c41ca > --- /dev/null > +++ b/NetworkPkg/TlsDxe/TlsDxe.uni > @@ -0,0 +1,25 @@ > +// /** @file > +// This module produces EFI TLS Protocol, EFI TLS Service Binding Protoc= ol > and > +// EFI TLS Configuration Protocol. > +// > +// This module produces EFI TLS (Transport Layer Security) Protocol, EFI= TLS > +// Service Binding Protocol, and EFI TLS Configuration Protocol to provi= de > TLS > +// services. > +// > +// 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 "UEFI TLS servic= e" > + > +#string STR_MODULE_DESCRIPTION #language en-US "This module > produces EFI TLS Protocol, EFI TLS Service Binding Protocol and EFI TLS > Configuration Protocol to provide EFI TLS services." > + > diff --git a/NetworkPkg/TlsDxe/TlsDxeExtra.uni > b/NetworkPkg/TlsDxe/TlsDxeExtra.uni > new file mode 100644 > index 0000000..a38582a > --- /dev/null > +++ b/NetworkPkg/TlsDxe/TlsDxeExtra.uni > @@ -0,0 +1,18 @@ > +// /** @file > +// TlsDxe Localized Strings and Content > +// > +// Copyright (c) 2016, Intel Corporation. All rights reserved.
> +// > +// This program and the accompanying materials > +// are licensed and made available under the terms and conditions of the > BSD License > +// which accompanies this distribution. The full text of the license may= be > found at > +// http://opensource.org/licenses/bsd-license.php. > +// > +// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > +// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > +// > +// **/ > + > +#string STR_PROPERTIES_MODULE_NAME > +#language en-US > +"EFI TLS DXE Driver" > diff --git a/NetworkPkg/TlsDxe/TlsImpl.c b/NetworkPkg/TlsDxe/TlsImpl.c > new file mode 100644 > index 0000000..9b7bf7d > --- /dev/null > +++ b/NetworkPkg/TlsDxe/TlsImpl.c > @@ -0,0 +1,326 @@ > +/** @file > + The Miscellaneous Routines for TlsDxe driver. > + > +Copyright (c) 2016, Intel Corporation. All rights reserved.
> + > +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 "TlsImpl.h" > + > +/** > + Encrypt the message listed in fragment. > + > + @param[in] TlsInstance The pointer to the TLS instance. > + @param[in, out] FragmentTable Pointer to a list of fragment. > + On input these fragments contain the T= LS header and > + plain text TLS payload; > + On output these fragments contain the = TLS header and > + cipher text TLS payload. > + @param[in] FragmentCount Number of fragment. > + > + @retval EFI_SUCCESS The operation completed successfully. > + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. > + @retval EFI_ABORTED TLS session state is incorrect. > + @retval Others Other errors as indicated. > +**/ > +EFI_STATUS > +TlsEcryptPacket ( > + IN TLS_INSTANCE *TlsInstance, > + IN OUT EFI_TLS_FRAGMENT_DATA **FragmentTable, > + IN UINT32 *FragmentCount > + ) > +{ > + EFI_STATUS Status; > + UINTN Index; > + UINT32 BytesCopied; > + UINT32 BufferInSize; > + UINT8 *BufferIn; > + UINT8 *BufferInPtr; > + TLS_RECORD_HEADER *RecordHeaderIn; > + UINT16 ThisPlainMessageSize; > + TLS_RECORD_HEADER *TempRecordHeader; > + UINT16 ThisMessageSize; > + UINT32 BufferOutSize; > + UINT8 *BufferOut; > + INTN Ret; > + > + Status =3D EFI_SUCCESS; > + BytesCopied =3D 0; > + BufferInSize =3D 0; > + BufferIn =3D NULL; > + BufferInPtr =3D NULL; > + RecordHeaderIn =3D NULL; > + TempRecordHeader =3D NULL; > + BufferOutSize =3D 0; > + BufferOut =3D NULL; > + Ret =3D 0; > + > + // > + // Calculate the size according to the fragment table. > + // > + for (Index =3D 0; Index < *FragmentCount; Index++) { > + BufferInSize +=3D (*FragmentTable)[Index].FragmentLength; > + } > + > + // > + // Allocate buffer for processing data. > + // > + BufferIn =3D AllocateZeroPool (BufferInSize); > + if (BufferIn =3D=3D NULL) { > + Status =3D EFI_OUT_OF_RESOURCES; > + goto ERROR; > + } > + > + // > + // Copy all TLS plain record header and payload into ProcessBuffer. > + // > + for (Index =3D 0; Index < *FragmentCount; Index++) { > + CopyMem ( > + (BufferIn + BytesCopied), > + (*FragmentTable)[Index].FragmentBuffer, > + (*FragmentTable)[Index].FragmentLength > + ); > + BytesCopied +=3D (*FragmentTable)[Index].FragmentLength; > + } > + > + BufferOut =3D AllocateZeroPool (MAX_BUFFER_SIZE); > + if (BufferOut =3D=3D NULL) { > + Status =3D EFI_OUT_OF_RESOURCES; > + goto ERROR; > + } > + > + // > + // Parsing buffer. > + // > + BufferInPtr =3D BufferIn; > + TempRecordHeader =3D (TLS_RECORD_HEADER *) BufferOut; > + while ((UINTN) BufferInPtr < (UINTN) BufferIn + BufferInSize) { > + RecordHeaderIn =3D (TLS_RECORD_HEADER *) BufferInPtr; > + > + if (RecordHeaderIn->ContentType !=3D > TLS_CONTENT_TYPE_APPLICATION_DATA) { > + Status =3D EFI_INVALID_PARAMETER; > + goto ERROR; > + } > + > + ThisPlainMessageSize =3D RecordHeaderIn->Length; > + > + TlsWrite (TlsInstance->TlsConn, (UINT8 *) (RecordHeaderIn + 1), > ThisPlainMessageSize); > + > + Ret =3D TlsCtrlTrafficOut (TlsInstance->TlsConn, (UINT8 > *)(TempRecordHeader), MAX_BUFFER_SIZE - BufferOutSize); > + > + if (Ret > 0) { > + ThisMessageSize =3D (UINT16) Ret; > + } else { > + // > + // No data was successfully encrypted, continue the other messages > encryption. > + // > + DEBUG ((EFI_D_WARN, "TlsEcryptPacket: No data read from TLS > object.\n")); > + > + ThisMessageSize =3D 0; > + } > + > + BufferOutSize +=3D ThisMessageSize; > + > + BufferInPtr +=3D RECORD_HEADER_LEN + ThisPlainMessageSize; > + TempRecordHeader +=3D ThisMessageSize; > + } > + > + FreePool (BufferIn); > + BufferIn =3D NULL; > + > + // > + // The caller will take responsible to handle the original fragment ta= ble. > + // > + *FragmentTable =3D AllocateZeroPool (sizeof (EFI_TLS_FRAGMENT_DATA)); > + if (*FragmentTable =3D=3D NULL) { > + Status =3D EFI_OUT_OF_RESOURCES; > + goto ERROR; > + } > + > + (*FragmentTable)[0].FragmentBuffer =3D BufferOut; > + (*FragmentTable)[0].FragmentLength =3D BufferOutSize; > + *FragmentCount =3D 1; > + > + return Status; > + > +ERROR: > + > + if (BufferIn !=3D NULL) { > + FreePool (BufferIn); > + BufferIn =3D NULL; > + } > + > + if (BufferOut !=3D NULL) { > + FreePool (BufferOut); > + BufferOut =3D NULL; > + } > + > + return Status; > +} > + > +/** > + Decrypt the message listed in fragment. > + > + @param[in] TlsInstance The pointer to the TLS instance. > + @param[in, out] FragmentTable Pointer to a list of fragment. > + On input these fragments contain the T= LS header and > + cipher text TLS payload; > + On output these fragments contain the = TLS header and > + plain text TLS payload. > + @param[in] FragmentCount Number of fragment. > + > + @retval EFI_SUCCESS The operation completed successfully. > + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. > + @retval EFI_ABORTED TLS session state is incorrect. > + @retval Others Other errors as indicated. > +**/ > +EFI_STATUS > +TlsDecryptPacket ( > + IN TLS_INSTANCE *TlsInstance, > + IN OUT EFI_TLS_FRAGMENT_DATA **FragmentTable, > + IN UINT32 *FragmentCount > + ) > +{ > + EFI_STATUS Status; > + UINTN Index; > + UINT32 BytesCopied; > + UINT8 *BufferIn; > + UINT32 BufferInSize; > + UINT8 *BufferInPtr; > + TLS_RECORD_HEADER *RecordHeaderIn; > + UINT16 ThisCipherMessageSize; > + TLS_RECORD_HEADER *TempRecordHeader; > + UINT16 ThisPlainMessageSize; > + UINT8 *BufferOut; > + UINT32 BufferOutSize; > + INTN Ret; > + > + Status =3D EFI_SUCCESS; > + BytesCopied =3D 0; > + BufferIn =3D NULL; > + BufferInSize =3D 0; > + BufferInPtr =3D NULL; > + RecordHeaderIn =3D NULL; > + TempRecordHeader =3D NULL; > + BufferOut =3D NULL; > + BufferOutSize =3D 0; > + Ret =3D 0; > + > + // > + // Calculate the size according to the fragment table. > + // > + for (Index =3D 0; Index < *FragmentCount; Index++) { > + BufferInSize +=3D (*FragmentTable)[Index].FragmentLength; > + } > + > + // > + // Allocate buffer for processing data > + // > + BufferIn =3D AllocateZeroPool (BufferInSize); > + if (BufferIn =3D=3D NULL) { > + Status =3D EFI_OUT_OF_RESOURCES; > + goto ERROR; > + } > + > + // > + // Copy all TLS plain record header and payload to ProcessBuffer > + // > + for (Index =3D 0; Index < *FragmentCount; Index++) { > + CopyMem ( > + (BufferIn + BytesCopied), > + (*FragmentTable)[Index].FragmentBuffer, > + (*FragmentTable)[Index].FragmentLength > + ); > + BytesCopied +=3D (*FragmentTable)[Index].FragmentLength; > + } > + > + BufferOut =3D AllocateZeroPool (MAX_BUFFER_SIZE); > + if (BufferOut =3D=3D NULL) { > + Status =3D EFI_OUT_OF_RESOURCES; > + goto ERROR; > + } > + > + // > + // Parsing buffer. Received packet may have multiply TLS record messag= e. > + // > + BufferInPtr =3D BufferIn; > + TempRecordHeader =3D (TLS_RECORD_HEADER *) BufferOut; > + while ((UINTN) BufferInPtr < (UINTN) BufferIn + BufferInSize) { > + RecordHeaderIn =3D (TLS_RECORD_HEADER *) BufferInPtr; > + > + if (RecordHeaderIn->ContentType !=3D > TLS_CONTENT_TYPE_APPLICATION_DATA) { > + Status =3D EFI_INVALID_PARAMETER; > + goto ERROR; > + } > + > + ThisCipherMessageSize =3D NTOHS (RecordHeaderIn->Length); > + > + Ret =3D TlsCtrlTrafficIn (TlsInstance->TlsConn, (UINT8 *) (RecordHea= derIn), > RECORD_HEADER_LEN + ThisCipherMessageSize); > + if (Ret !=3D RECORD_HEADER_LEN + ThisCipherMessageSize) { > + TlsInstance->TlsSessionState =3D EfiTlsSessionError; > + Status =3D EFI_ABORTED; > + goto ERROR; > + } > + > + Ret =3D 0; > + Ret =3D TlsRead (TlsInstance->TlsConn, (UINT8 *) (TempRecordHeader += 1), > MAX_BUFFER_SIZE - BufferOutSize); > + > + if (Ret > 0) { > + ThisPlainMessageSize =3D (UINT16) Ret; > + } else { > + // > + // No data was successfully decrypted, continue the other messages > decryption. > + // > + DEBUG ((EFI_D_WARN, "TlsDecryptPacket: No data read from TLS > object.\n")); > + > + ThisPlainMessageSize =3D 0; > + } > + > + CopyMem (TempRecordHeader, RecordHeaderIn, > RECORD_HEADER_LEN); > + TempRecordHeader->Length =3D ThisPlainMessageSize; > + BufferOutSize +=3D RECORD_HEADER_LEN + ThisPlainMessageSize; > + > + BufferInPtr +=3D RECORD_HEADER_LEN + ThisCipherMessageSize; > + TempRecordHeader +=3D RECORD_HEADER_LEN + ThisPlainMessageSize; > + } > + > + FreePool (BufferIn); > + BufferIn =3D NULL; > + > + // > + // The caller will take responsible to handle the original fragment ta= ble > + // > + *FragmentTable =3D AllocateZeroPool (sizeof (EFI_TLS_FRAGMENT_DATA)); > + if (*FragmentTable =3D=3D NULL) { > + Status =3D EFI_OUT_OF_RESOURCES; > + goto ERROR; > + } > + > + (*FragmentTable)[0].FragmentBuffer =3D BufferOut; > + (*FragmentTable)[0].FragmentLength =3D BufferOutSize; > + *FragmentCount =3D 1; > + > + return Status; > + > +ERROR: > + > + if (BufferIn !=3D NULL) { > + FreePool (BufferIn); > + BufferIn =3D NULL; > + } > + > + if (BufferOut !=3D NULL) { > + FreePool (BufferOut); > + BufferOut =3D NULL; > + } > + > + return Status; > +} > diff --git a/NetworkPkg/TlsDxe/TlsImpl.h b/NetworkPkg/TlsDxe/TlsImpl.h > new file mode 100644 > index 0000000..b0615cb > --- /dev/null > +++ b/NetworkPkg/TlsDxe/TlsImpl.h > @@ -0,0 +1,315 @@ > +/** @file > + Header file of Miscellaneous Routines for TlsDxe driver. > + > +Copyright (c) 2016, Intel Corporation. All rights reserved.
> + > +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 __EFI_TLS_IMPL_H__ > +#define __EFI_TLS_IMPL_H__ > + > +// > +// Libraries > +// > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +// > +// Consumed Protocols > +// > +#include > +#include > + > +#include > + > +#include "TlsDriver.h" > + > +// > +// Protocol instances > +// > +extern EFI_SERVICE_BINDING_PROTOCOL mTlsServiceBinding; > +extern EFI_TLS_PROTOCOL mTlsProtocol; > +extern EFI_TLS_CONFIGURATION_PROTOCOL mTlsConfigurationProtocol; > + > +#define RECORD_HEADER_LEN 5 /// ContentType(1) + Version(2) + > Length(2) > + > +#define MAX_BUFFER_SIZE 32768 > + > +/** > + Encrypt the message listed in fragment. > + > + @param[in] TlsInstance The pointer to the TLS instance. > + @param[in, out] FragmentTable Pointer to a list of fragment. > + On input these fragments contain the T= LS header and > + plain text TLS payload; > + On output these fragments contain the = TLS header and > + cipher text TLS payload. > + @param[in] FragmentCount Number of fragment. > + > + @retval EFI_SUCCESS The operation completed successfully. > + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. > + @retval EFI_ABORTED TLS session state is incorrect. > + @retval Others Other errors as indicated. > +**/ > +EFI_STATUS > +TlsEcryptPacket ( > + IN TLS_INSTANCE *TlsInstance, > + IN OUT EFI_TLS_FRAGMENT_DATA **FragmentTable, > + IN UINT32 *FragmentCount > + ); > + > +/** > + Decrypt the message listed in fragment. > + > + @param[in] TlsInstance The pointer to the TLS instance. > + @param[in, out] FragmentTable Pointer to a list of fragment. > + On input these fragments contain the T= LS header and > + cipher text TLS payload; > + On output these fragments contain the = TLS header and > + plain text TLS payload. > + @param[in] FragmentCount Number of fragment. > + > + @retval EFI_SUCCESS The operation completed successfully. > + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. > + @retval EFI_ABORTED TLS session state is incorrect. > + @retval Others Other errors as indicated. > +**/ > +EFI_STATUS > +TlsDecryptPacket ( > + IN TLS_INSTANCE *TlsInstance, > + IN OUT EFI_TLS_FRAGMENT_DATA **FragmentTable, > + IN UINT32 *FragmentCount > + ); > + > +/** > + Set TLS session data. > + > + The SetSessionData() function set data for a new TLS session. All sess= ion > data should > + be set before BuildResponsePacket() invoked. > + > + @param[in] This Pointer to the EFI_TLS_PROTOCOL instan= ce. > + @param[in] DataType TLS session data type. > + @param[in] Data Pointer to session data. > + @param[in] DataSize Total size of session data. > + > + @retval EFI_SUCCESS The TLS session data is set successful= ly. > + @retval EFI_INVALID_PARAMETER One or more of the following > conditions is TRUE: > + This is NULL. > + Data is NULL. > + DataSize is 0. > + @retval EFI_UNSUPPORTED The DataType is unsupported. > + @retval EFI_ACCESS_DENIED If the DataType is one of below: > + EfiTlsClientRandom > + EfiTlsServerRandom > + EfiTlsKeyMaterial > + @retval EFI_NOT_READY Current TLS session state is NOT > + EfiTlsSessionStateNotStarted. > + @retval EFI_OUT_OF_RESOURCES Required system resources could not > be allocated. > +**/ > +EFI_STATUS > +EFIAPI > +TlsSetSessionData ( > + IN EFI_TLS_PROTOCOL *This, > + IN EFI_TLS_SESSION_DATA_TYPE DataType, > + IN VOID *Data, > + IN UINTN DataSize > + ); > + > +/** > + Get TLS session data. > + > + The GetSessionData() function return the TLS session information. > + > + @param[in] This Pointer to the EFI_TLS_PROTOCOL instan= ce. > + @param[in] DataType TLS session data type. > + @param[in, out] Data Pointer to session data. > + @param[in, out] DataSize Total size of session data. On input, = it means > + the size of Data buffer. On output, it= means the size > + of copied Data buffer if EFI_SUCCESS, = and means the > + size of desired Data buffer if EFI_BUF= FER_TOO_SMALL. > + > + @retval EFI_SUCCESS The TLS session data is got successful= ly. > + @retval EFI_INVALID_PARAMETER One or more of the following > conditions is TRUE: > + This is NULL. > + DataSize is NULL. > + Data is NULL if *DataSize is not zero. > + @retval EFI_UNSUPPORTED The DataType is unsupported. > + @retval EFI_NOT_FOUND The TLS session data is not found. > + @retval EFI_NOT_READY The DataType is not ready in current s= ession > state. > + @retval EFI_BUFFER_TOO_SMALL The buffer is too small to hold the da= ta. > +**/ > +EFI_STATUS > +EFIAPI > +TlsGetSessionData ( > + IN EFI_TLS_PROTOCOL *This, > + IN EFI_TLS_SESSION_DATA_TYPE DataType, > + IN OUT VOID *Data, OPTIONAL > + IN OUT UINTN *DataSize > + ); > + > +/** > + Build response packet according to TLS state machine. This function is= only > valid for > + alert, handshake and change_cipher_spec content type. > + > + The BuildResponsePacket() function builds TLS response packet in > response to the TLS > + request packet specified by RequestBuffer and RequestSize. If > RequestBuffer is NULL and > + RequestSize is 0, and TLS session status is EfiTlsSessionNotStarted, t= he TLS > session > + will be initiated and the response packet needs to be ClientHello. If > RequestBuffer is > + NULL and RequestSize is 0, and TLS session status is EfiTlsSessionClos= ing, > the TLS > + session will be closed and response packet needs to be CloseNotify. If > RequestBuffer is > + NULL and RequestSize is 0, and TLS session status is EfiTlsSessionErro= r, the > TLS > + session has errors and the response packet needs to be Alert message > based on error > + type. > + > + @param[in] This Pointer to the EFI_TLS_PROTOCOL instan= ce. > + @param[in] RequestBuffer Pointer to the most recently received = TLS > packet. NULL > + means TLS need initiate the TLS sessio= n and response > + packet need to be ClientHello. > + @param[in] RequestSize Packet size in bytes for the most rece= ntly > received TLS > + packet. 0 is only valid when RequestBu= ffer is NULL. > + @param[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: > + This is NULL. > + RequestBuffer is NULL but RequestSize = is NOT 0. > + RequestSize is 0 but RequestBuffer is = NOT NULL. > + BufferSize is NULL. > + Buffer is NULL if *BufferSize is not z= ero. > + @retval EFI_BUFFER_TOO_SMALL BufferSize is too small to hold the > response packet. > + @retval EFI_NOT_READY Current TLS session state is NOT ready= to > build > + ResponsePacket. > + @retval EFI_ABORTED Something wrong build response packet. > +**/ > +EFI_STATUS > +EFIAPI > +TlsBuildResponsePacket ( > + IN EFI_TLS_PROTOCOL *This, > + IN UINT8 *RequestBuffer, OPTIONAL > + IN UINTN RequestSize, OPTIONAL > + OUT UINT8 *Buffer, OPTIONAL > + IN OUT UINTN *BufferSize > + ); > + > +/** > + Decrypt or encrypt TLS packet during session. This function is only va= lid > after > + session connected and for application_data content type. > + > + The ProcessPacket () function process each inbound or outbound TLS APP > packet. > + > + @param[in] This Pointer to the EFI_TLS_PROTOCOL instan= ce. > + @param[in, out] FragmentTable Pointer to a list of fragment. The cal= ler > will take > + responsible to handle the original Fra= gmentTable while > + it may be reallocated in TLS driver. I= f CryptMode is > + EfiTlsEncrypt, on input these fragment= s contain the TLS > + header and plain text TLS APP payload;= on output these > + fragments contain the TLS header and c= ipher text TLS > + APP payload. If CryptMode is EfiTlsDec= rypt, on input > + these fragments contain the TLS header= and cipher text > + TLS APP payload; on output these fragm= ents contain the > + TLS header and plain text TLS APP payl= oad. > + @param[in] FragmentCount Number of fragment. > + @param[in] CryptMode Crypt mode. > + > + @retval EFI_SUCCESS The operation completed successfully. > + @retval EFI_INVALID_PARAMETER One or more of the following > conditions is TRUE: > + This is NULL. > + FragmentTable is NULL. > + FragmentCount is NULL. > + CryptoMode is invalid. > + @retval EFI_NOT_READY Current TLS session state is NOT > + EfiTlsSessionDataTransferring. > + @retval EFI_ABORTED Something wrong decryption the message= . > TLS session > + status will become EfiTlsSessionError.= The caller need > + call BuildResponsePacket() to generate= Error Alert > + message and send it out. > + @retval EFI_OUT_OF_RESOURCES No enough resource to finish the > operation. > +**/ > +EFI_STATUS > +EFIAPI > +TlsProcessPacket ( > + IN EFI_TLS_PROTOCOL *This, > + IN OUT EFI_TLS_FRAGMENT_DATA **FragmentTable, > + IN UINT32 *FragmentCount, > + IN EFI_TLS_CRYPT_MODE CryptMode > + ); > + > +/** > + Set TLS configuration data. > + > + The SetData() function sets TLS configuration to non-volatile storage = or > volatile > + storage. > + > + @param[in] This Pointer to the > EFI_TLS_CONFIGURATION_PROTOCOL instance. > + @param[in] DataType Configuration data type. > + @param[in] Data Pointer to configuration data. > + @param[in] DataSize Total size of configuration data. > + > + @retval EFI_SUCCESS The TLS configuration data is set succ= essfully. > + @retval EFI_INVALID_PARAMETER One or more of the following > conditions is TRUE: > + This is NULL. > + Data is NULL. > + DataSize is 0. > + @retval EFI_UNSUPPORTED The DataType is unsupported. > + @retval EFI_OUT_OF_RESOURCES Required system resources could not > be allocated. > +**/ > +EFI_STATUS > +EFIAPI > +TlsConfigurationSetData ( > + IN EFI_TLS_CONFIGURATION_PROTOCOL *This, > + IN EFI_TLS_CONFIG_DATA_TYPE DataType, > + IN VOID *Data, > + IN UINTN DataSize > + ); > + > +/** > + Get TLS configuration data. > + > + The GetData() function gets TLS configuration. > + > + @param[in] This Pointer to the > EFI_TLS_CONFIGURATION_PROTOCOL instance. > + @param[in] DataType Configuration data type. > + @param[in, out] Data Pointer to configuration data. > + @param[in, out] DataSize Total size of configuration data. On i= nput, it > means > + the size of Data buffer. On output, it= means the size > + of copied Data buffer if EFI_SUCCESS, = and means the > + size of desired Data buffer if EFI_BUF= FER_TOO_SMALL. > + > + @retval EFI_SUCCESS The TLS configuration data is got succ= essfully. > + @retval EFI_INVALID_PARAMETER One or more of the following > conditions is TRUE: > + This is NULL. > + DataSize is NULL. > + Data is NULL if *DataSize is not zero. > + @retval EFI_UNSUPPORTED The DataType is unsupported. > + @retval EFI_NOT_FOUND The TLS configuration data is not foun= d. > + @retval EFI_BUFFER_TOO_SMALL The buffer is too small to hold the da= ta. > +**/ > +EFI_STATUS > +EFIAPI > +TlsConfigurationGetData ( > + IN EFI_TLS_CONFIGURATION_PROTOCOL *This, > + IN EFI_TLS_CONFIG_DATA_TYPE DataType, > + IN OUT VOID *Data, OPTIONAL > + IN OUT UINTN *DataSize > + ); > + > +#endif > diff --git a/NetworkPkg/TlsDxe/TlsProtocol.c > b/NetworkPkg/TlsDxe/TlsProtocol.c > new file mode 100644 > index 0000000..bc617e1 > --- /dev/null > +++ b/NetworkPkg/TlsDxe/TlsProtocol.c > @@ -0,0 +1,632 @@ > +/** @file > + Implementation of EFI TLS Protocol Interfaces. > + > + Copyright (c) 2016, Intel Corporation. All rights reserved.
> + > + This program and the accompanying materials > + are licensed and made available under the terms and conditions of the = BSD > License > + which accompanies this distribution. The full text of the license may= be > found at > + http://opensource.org/licenses/bsd-license.php. > + > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > + > +**/ > + > +#include "TlsImpl.h" > + > +EFI_TLS_PROTOCOL mTlsProtocol =3D { > + TlsSetSessionData, > + TlsGetSessionData, > + TlsBuildResponsePacket, > + TlsProcessPacket > +}; > + > +/** > + Set TLS session data. > + > + The SetSessionData() function set data for a new TLS session. All sess= ion > data should > + be set before BuildResponsePacket() invoked. > + > + @param[in] This Pointer to the EFI_TLS_PROTOCOL instan= ce. > + @param[in] DataType TLS session data type. > + @param[in] Data Pointer to session data. > + @param[in] DataSize Total size of session data. > + > + @retval EFI_SUCCESS The TLS session data is set successful= ly. > + @retval EFI_INVALID_PARAMETER One or more of the following > conditions is TRUE: > + This is NULL. > + Data is NULL. > + DataSize is 0. > + @retval EFI_UNSUPPORTED The DataType is unsupported. > + @retval EFI_ACCESS_DENIED If the DataType is one of below: > + EfiTlsClientRandom > + EfiTlsServerRandom > + EfiTlsKeyMaterial > + @retval EFI_NOT_READY Current TLS session state is NOT > + EfiTlsSessionStateNotStarted. > + @retval EFI_OUT_OF_RESOURCES Required system resources could not > be allocated. > +**/ > +EFI_STATUS > +EFIAPI > +TlsSetSessionData ( > + IN EFI_TLS_PROTOCOL *This, > + IN EFI_TLS_SESSION_DATA_TYPE DataType, > + IN VOID *Data, > + IN UINTN DataSize > + ) > +{ > + EFI_STATUS Status; > + TLS_INSTANCE *Instance; > + UINT16 *CipherId; > + UINTN Index; > + > + EFI_TPL OldTpl; > + > + Status =3D EFI_SUCCESS; > + CipherId =3D NULL; > + > + if (This =3D=3D NULL || Data =3D=3D NULL || DataSize =3D=3D 0) { > + return EFI_INVALID_PARAMETER; > + } > + > + OldTpl =3D gBS->RaiseTPL (TPL_CALLBACK); > + > + Instance =3D TLS_INSTANCE_FROM_PROTOCOL_THIS (This); > + > + if (DataType !=3D EfiTlsSessionState && Instance->TlsSessionState != =3D > EfiTlsSessionNotStarted){ > + Status =3D EFI_NOT_READY; > + goto ON_EXIT; > + } > + > + switch (DataType) { > + // > + // Session Configuration > + // > + case EfiTlsVersion: > + if (DataSize !=3D sizeof (EFI_TLS_VERSION)) { > + Status =3D EFI_INVALID_PARAMETER; > + goto ON_EXIT; > + } > + > + Status =3D TlsSetVersion (Instance->TlsConn, ((EFI_TLS_VERSION *) Da= ta)- > >Major, ((EFI_TLS_VERSION *) Data)->Minor); > + break; > + case EfiTlsConnectionEnd: > + if (DataSize !=3D sizeof (EFI_TLS_CONNECTION_END)) { > + Status =3D EFI_INVALID_PARAMETER; > + goto ON_EXIT; > + } > + > + Status =3D TlsSetConnectionEnd (Instance->TlsConn, > *((EFI_TLS_CONNECTION_END *) Data)); > + break; > + case EfiTlsCipherList: > + CipherId =3D AllocatePool (DataSize); > + if (CipherId =3D=3D NULL) { > + Status =3D EFI_OUT_OF_RESOURCES; > + goto ON_EXIT; > + } > + > + for (Index =3D 0; Index < DataSize / sizeof (EFI_TLS_CIPHER); Index+= +) { > + *(CipherId +Index) =3D HTONS (*(((UINT16 *) Data) + Index)); > + } > + > + Status =3D TlsSetCipherList (Instance->TlsConn, CipherId, DataSize /= sizeof > (EFI_TLS_CIPHER)); > + > + FreePool (CipherId); > + break; > + case EfiTlsCompressionMethod: > + // > + // TLS seems only define one CompressionMethod.null, which specifies > that data exchanged via the > + // record protocol will not be compressed. > + // More information from OpenSSL: > http://www.openssl.org/docs/manmaster/ssl/SSL_COMP_add_compressio > n_method.html > + // The TLS RFC does however not specify compression methods or their > corresponding identifiers, > + // so there is currently no compatible way to integrate compression = with > unknown peers. > + // It is therefore currently not recommended to integrate compressio= n > into applications. > + // Applications for non-public use may agree on certain compression > methods. > + // Using different compression methods with the same identifier will= lead > to connection failure. > + // > + for (Index =3D 0; Index < DataSize / sizeof (EFI_TLS_COMPRESSION); > Index++) { > + Status =3D TlsSetCompressionMethod (*((UINT8 *) Data + Index)); > + if (EFI_ERROR (Status)) { > + break; > + } > + } > + > + break; > + case EfiTlsExtensionData: > + Status =3D EFI_UNSUPPORTED; > + goto ON_EXIT; > + case EfiTlsVerifyMethod: > + if (DataSize !=3D sizeof (EFI_TLS_VERIFY)) { > + Status =3D EFI_INVALID_PARAMETER; > + goto ON_EXIT; > + } > + > + TlsSetVerify (Instance->TlsConn, *((UINT32 *) Data)); > + break; > + case EfiTlsSessionID: > + if (DataSize !=3D sizeof (EFI_TLS_SESSION_ID)) { > + Status =3D EFI_INVALID_PARAMETER; > + goto ON_EXIT; > + } > + > + Status =3D TlsSetSessionId ( > + Instance->TlsConn, > + ((EFI_TLS_SESSION_ID *) Data)->Data, > + ((EFI_TLS_SESSION_ID *) Data)->Length > + ); > + break; > + case EfiTlsSessionState: > + if (DataSize !=3D sizeof (EFI_TLS_SESSION_STATE)) { > + Status =3D EFI_INVALID_PARAMETER; > + goto ON_EXIT; > + } > + > + Instance->TlsSessionState =3D *(EFI_TLS_SESSION_STATE *) Data; > + break; > + // > + // Session information > + // > + case EfiTlsClientRandom: > + Status =3D EFI_ACCESS_DENIED; > + break; > + case EfiTlsServerRandom: > + Status =3D EFI_ACCESS_DENIED; > + break; > + case EfiTlsKeyMaterial: > + Status =3D EFI_ACCESS_DENIED; > + break; > + // > + // Unsupported type. > + // > + default: > + Status =3D EFI_UNSUPPORTED; > + } > + > +ON_EXIT: > + gBS->RestoreTPL (OldTpl); > + return Status; > +} > + > +/** > + Get TLS session data. > + > + The GetSessionData() function return the TLS session information. > + > + @param[in] This Pointer to the EFI_TLS_PROTOCOL instan= ce. > + @param[in] DataType TLS session data type. > + @param[in, out] Data Pointer to session data. > + @param[in, out] DataSize Total size of session data. On input, = it means > + the size of Data buffer. On output, it= means the size > + of copied Data buffer if EFI_SUCCESS, = and means the > + size of desired Data buffer if EFI_BUF= FER_TOO_SMALL. > + > + @retval EFI_SUCCESS The TLS session data is got successful= ly. > + @retval EFI_INVALID_PARAMETER One or more of the following > conditions is TRUE: > + This is NULL. > + DataSize is NULL. > + Data is NULL if *DataSize is not zero. > + @retval EFI_UNSUPPORTED The DataType is unsupported. > + @retval EFI_NOT_FOUND The TLS session data is not found. > + @retval EFI_NOT_READY The DataType is not ready in current s= ession > state. > + @retval EFI_BUFFER_TOO_SMALL The buffer is too small to hold the da= ta. > +**/ > +EFI_STATUS > +EFIAPI > +TlsGetSessionData ( > + IN EFI_TLS_PROTOCOL *This, > + IN EFI_TLS_SESSION_DATA_TYPE DataType, > + IN OUT VOID *Data, OPTIONAL > + IN OUT UINTN *DataSize > + ) > +{ > + EFI_STATUS Status; > + TLS_INSTANCE *Instance; > + > + EFI_TPL OldTpl; > + > + Status =3D EFI_SUCCESS; > + > + if (This =3D=3D NULL || DataSize =3D=3D NULL || (Data =3D=3D NULL && *= DataSize !=3D 0)) > { > + return EFI_INVALID_PARAMETER; > + } > + > + OldTpl =3D gBS->RaiseTPL (TPL_CALLBACK); > + > + Instance =3D TLS_INSTANCE_FROM_PROTOCOL_THIS (This); > + > + if (Instance->TlsSessionState =3D=3D EfiTlsSessionNotStarted && > + (DataType =3D=3D EfiTlsSessionID || DataType =3D=3D EfiTlsClientRand= om || > + DataType =3D=3D EfiTlsServerRandom || DataType =3D=3D EfiTlsKeyMater= ial)) { > + Status =3D EFI_NOT_READY; > + goto ON_EXIT; > + } > + > + switch (DataType) { > + case EfiTlsVersion: > + if (*DataSize < sizeof (EFI_TLS_VERSION)) { > + *DataSize =3D sizeof (EFI_TLS_VERSION); > + Status =3D EFI_BUFFER_TOO_SMALL; > + goto ON_EXIT; > + } > + *DataSize =3D sizeof (EFI_TLS_VERSION); > + *((UINT16 *) Data) =3D HTONS (TlsGetVersion (Instance->TlsConn)); > + break; > + case EfiTlsConnectionEnd: > + if (*DataSize < sizeof (EFI_TLS_CONNECTION_END)) { > + *DataSize =3D sizeof (EFI_TLS_CONNECTION_END); > + Status =3D EFI_BUFFER_TOO_SMALL; > + goto ON_EXIT; > + } > + *DataSize =3D sizeof (EFI_TLS_CONNECTION_END); > + *((UINT8 *) Data) =3D TlsGetConnectionEnd (Instance->TlsConn); > + break; > + case EfiTlsCipherList: > + // > + // Get the current session cipher suite. > + // > + if (*DataSize < sizeof (EFI_TLS_CIPHER)) { > + *DataSize =3D sizeof (EFI_TLS_CIPHER); > + Status =3D EFI_BUFFER_TOO_SMALL; > + goto ON_EXIT; > + } > + *DataSize =3D sizeof(EFI_TLS_CIPHER); > + Status =3D TlsGetCurrentCipher (Instance->TlsConn, (UINT16 *) Data); > + *((UINT16 *) Data) =3D HTONS (*((UINT16 *) Data)); > + break; > + case EfiTlsCompressionMethod: > + // > + // Get the current session compression method. > + // > + if (*DataSize < sizeof (EFI_TLS_COMPRESSION)) { > + *DataSize =3D sizeof (EFI_TLS_COMPRESSION); > + Status =3D EFI_BUFFER_TOO_SMALL; > + goto ON_EXIT; > + } > + *DataSize =3D sizeof (EFI_TLS_COMPRESSION); > + Status =3D TlsGetCurrentCompressionId (Instance->TlsConn, (UINT8 *) > Data); > + break; > + case EfiTlsExtensionData: > + Status =3D EFI_UNSUPPORTED; > + goto ON_EXIT; > + case EfiTlsVerifyMethod: > + if (*DataSize < sizeof (EFI_TLS_VERIFY)) { > + *DataSize =3D sizeof (EFI_TLS_VERIFY); > + Status =3D EFI_BUFFER_TOO_SMALL; > + goto ON_EXIT; > + } > + *DataSize =3D sizeof (EFI_TLS_VERIFY); > + *((UINT32 *) Data) =3D TlsGetVerify (Instance->TlsConn); > + break; > + case EfiTlsSessionID: > + if (*DataSize < sizeof (EFI_TLS_SESSION_ID)) { > + *DataSize =3D sizeof (EFI_TLS_SESSION_ID); > + Status =3D EFI_BUFFER_TOO_SMALL; > + goto ON_EXIT; > + } > + *DataSize =3D sizeof (EFI_TLS_SESSION_ID); > + Status =3D TlsGetSessionId ( > + Instance->TlsConn, > + ((EFI_TLS_SESSION_ID *) Data)->Data, > + &(((EFI_TLS_SESSION_ID *) Data)->Length) > + ); > + break; > + case EfiTlsSessionState: > + if (*DataSize < sizeof (EFI_TLS_SESSION_STATE)) { > + *DataSize =3D sizeof (EFI_TLS_SESSION_STATE); > + Status =3D EFI_BUFFER_TOO_SMALL; > + goto ON_EXIT; > + } > + *DataSize =3D sizeof (EFI_TLS_SESSION_STATE); > + CopyMem (Data, &Instance->TlsSessionState, *DataSize); > + break; > + case EfiTlsClientRandom: > + if (*DataSize < sizeof (EFI_TLS_RANDOM)) { > + *DataSize =3D sizeof (EFI_TLS_RANDOM); > + Status =3D EFI_BUFFER_TOO_SMALL; > + goto ON_EXIT; > + } > + *DataSize =3D sizeof (EFI_TLS_RANDOM); > + TlsGetClientRandom (Instance->TlsConn, (UINT8 *) Data); > + break; > + case EfiTlsServerRandom: > + if (*DataSize < sizeof (EFI_TLS_RANDOM)) { > + *DataSize =3D sizeof (EFI_TLS_RANDOM); > + Status =3D EFI_BUFFER_TOO_SMALL; > + goto ON_EXIT; > + } > + *DataSize =3D sizeof (EFI_TLS_RANDOM); > + TlsGetServerRandom (Instance->TlsConn, (UINT8 *) Data); > + break; > + case EfiTlsKeyMaterial: > + if (*DataSize < sizeof (EFI_TLS_MASTER_SECRET)) { > + *DataSize =3D sizeof (EFI_TLS_MASTER_SECRET); > + Status =3D EFI_BUFFER_TOO_SMALL; > + goto ON_EXIT; > + } > + *DataSize =3D sizeof (EFI_TLS_MASTER_SECRET); > + Status =3D TlsGetKeyMaterial (Instance->TlsConn, (UINT8 *) Data); > + break; > + // > + // Unsupported type. > + // > + default: > + Status =3D EFI_UNSUPPORTED; > + } > + > +ON_EXIT: > + gBS->RestoreTPL (OldTpl); > + return Status; > +} > + > +/** > + Build response packet according to TLS state machine. This function is= only > valid for > + alert, handshake and change_cipher_spec content type. > + > + The BuildResponsePacket() function builds TLS response packet in > response to the TLS > + request packet specified by RequestBuffer and RequestSize. If > RequestBuffer is NULL and > + RequestSize is 0, and TLS session status is EfiTlsSessionNotStarted, t= he TLS > session > + will be initiated and the response packet needs to be ClientHello. If > RequestBuffer is > + NULL and RequestSize is 0, and TLS session status is EfiTlsSessionClos= ing, > the TLS > + session will be closed and response packet needs to be CloseNotify. If > RequestBuffer is > + NULL and RequestSize is 0, and TLS session status is EfiTlsSessionErro= r, the > TLS > + session has errors and the response packet needs to be Alert message > based on error > + type. > + > + @param[in] This Pointer to the EFI_TLS_PROTOCOL instan= ce. > + @param[in] RequestBuffer Pointer to the most recently received = TLS > packet. NULL > + means TLS need initiate the TLS sessio= n and response > + packet need to be ClientHello. > + @param[in] RequestSize Packet size in bytes for the most rece= ntly > received TLS > + packet. 0 is only valid when RequestBu= ffer is NULL. > + @param[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: > + This is NULL. > + RequestBuffer is NULL but RequestSize = is NOT 0. > + RequestSize is 0 but RequestBuffer is = NOT NULL. > + BufferSize is NULL. > + Buffer is NULL if *BufferSize is not z= ero. > + @retval EFI_BUFFER_TOO_SMALL BufferSize is too small to hold the > response packet. > + @retval EFI_NOT_READY Current TLS session state is NOT ready= to > build > + ResponsePacket. > + @retval EFI_ABORTED Something wrong build response packet. > +**/ > +EFI_STATUS > +EFIAPI > +TlsBuildResponsePacket ( > + IN EFI_TLS_PROTOCOL *This, > + IN UINT8 *RequestBuffer, OPTIONAL > + IN UINTN RequestSize, OPTIONAL > + OUT UINT8 *Buffer, OPTIONAL > + IN OUT UINTN *BufferSize > + ) > +{ > + EFI_STATUS Status; > + TLS_INSTANCE *Instance; > + EFI_TPL OldTpl; > + > + Status =3D EFI_SUCCESS; > + > + if ((This =3D=3D NULL) || (BufferSize =3D=3D NULL) || > + (RequestBuffer =3D=3D NULL && RequestSize !=3D 0) || > + (RequestBuffer !=3D NULL && RequestSize =3D=3D 0) || > + (Buffer =3D=3D NULL && *BufferSize !=3D0)) { > + return EFI_INVALID_PARAMETER; > + } > + > + OldTpl =3D gBS->RaiseTPL (TPL_CALLBACK); > + > + Instance =3D TLS_INSTANCE_FROM_PROTOCOL_THIS (This); > + > + if(RequestBuffer =3D=3D NULL && RequestSize =3D=3D 0) { > + switch (Instance->TlsSessionState) { > + case EfiTlsSessionNotStarted: > + // > + // ClientHello. > + // > + Status =3D TlsDoHandshake ( > + Instance->TlsConn, > + NULL, > + 0, > + Buffer, > + BufferSize > + ); > + if (EFI_ERROR (Status)) { > + goto ON_EXIT; > + } > + > + // > + // *BufferSize should not be zero when ClientHello. > + // > + if (*BufferSize =3D=3D 0) { > + Status =3D EFI_ABORTED; > + goto ON_EXIT; > + } > + > + Instance->TlsSessionState =3D EfiTlsSessionHandShaking; > + > + break; > + case EfiTlsSessionClosing: > + // > + // TLS session will be closed and response packet needs to be > CloseNotify. > + // > + Status =3D TlsCloseNotify ( > + Instance->TlsConn, > + Buffer, > + BufferSize > + ); > + if (EFI_ERROR (Status)) { > + goto ON_EXIT; > + } > + > + // > + // *BufferSize should not be zero when build CloseNotify message. > + // > + if (*BufferSize =3D=3D 0) { > + Status =3D EFI_ABORTED; > + goto ON_EXIT; > + } > + > + break; > + case EfiTlsSessionError: > + // > + // TLS session has errors and the response packet needs to be Aler= t > + // message based on error type. > + // > + Status =3D TlsHandeAlert ( > + Instance->TlsConn, > + NULL, > + 0, > + Buffer, > + BufferSize > + ); > + if (EFI_ERROR (Status)) { > + goto ON_EXIT; > + } > + > + break; > + default: > + // > + // Current TLS session state is NOT ready to build ResponsePacket. > + // > + Status =3D EFI_NOT_READY; > + } > + } else { > + // > + // 1. Received packet may have multiply TLS record messages. > + // 2. One TLS record message may have multiply handshake protocol. > + // 3. Some errors may be happened in handshake. > + // TlsDoHandshake() can handle all of those cases. > + // > + if (TlsInHandshake (Instance->TlsConn)) { > + Status =3D TlsDoHandshake ( > + Instance->TlsConn, > + RequestBuffer, > + RequestSize, > + Buffer, > + BufferSize > + ); > + if (EFI_ERROR (Status)) { > + goto ON_EXIT; > + } > + > + if (!TlsInHandshake (Instance->TlsConn)) { > + Instance->TlsSessionState =3D EfiTlsSessionDataTransferring; > + } > + } else { > + // > + // Must be alert message, Decrypt it and build the ResponsePacket. > + // > + ASSERT (((TLS_RECORD_HEADER *) RequestBuffer)->ContentType =3D=3D > TLS_CONTENT_TYPE_ALERT); > + > + Status =3D TlsHandeAlert ( > + Instance->TlsConn, > + RequestBuffer, > + RequestSize, > + Buffer, > + BufferSize > + ); > + if (EFI_ERROR (Status)) { > + if (Status !=3D EFI_BUFFER_TOO_SMALL) { > + Instance->TlsSessionState =3D EfiTlsSessionError; > + } > + > + goto ON_EXIT; > + } > + } > + } > + > +ON_EXIT: > + gBS->RestoreTPL (OldTpl); > + return Status; > +} > + > +/** > + Decrypt or encrypt TLS packet during session. This function is only va= lid > after > + session connected and for application_data content type. > + > + The ProcessPacket () function process each inbound or outbound TLS APP > packet. > + > + @param[in] This Pointer to the EFI_TLS_PROTOCOL instan= ce. > + @param[in, out] FragmentTable Pointer to a list of fragment. The cal= ler > will take > + responsible to handle the original Fra= gmentTable while > + it may be reallocated in TLS driver. I= f CryptMode is > + EfiTlsEncrypt, on input these fragment= s contain the TLS > + header and plain text TLS APP payload;= on output these > + fragments contain the TLS header and c= ipher text TLS > + APP payload. If CryptMode is EfiTlsDec= rypt, on input > + these fragments contain the TLS header= and cipher text > + TLS APP payload; on output these fragm= ents contain the > + TLS header and plain text TLS APP payl= oad. > + @param[in] FragmentCount Number of fragment. > + @param[in] CryptMode Crypt mode. > + > + @retval EFI_SUCCESS The operation completed successfully. > + @retval EFI_INVALID_PARAMETER One or more of the following > conditions is TRUE: > + This is NULL. > + FragmentTable is NULL. > + FragmentCount is NULL. > + CryptoMode is invalid. > + @retval EFI_NOT_READY Current TLS session state is NOT > + EfiTlsSessionDataTransferring. > + @retval EFI_ABORTED Something wrong decryption the message= . > TLS session > + status will become EfiTlsSessionError.= The caller need > + call BuildResponsePacket() to generate= Error Alert > + message and send it out. > + @retval EFI_OUT_OF_RESOURCES No enough resource to finish the > operation. > +**/ > +EFI_STATUS > +EFIAPI > +TlsProcessPacket ( > + IN EFI_TLS_PROTOCOL *This, > + IN OUT EFI_TLS_FRAGMENT_DATA **FragmentTable, > + IN UINT32 *FragmentCount, > + IN EFI_TLS_CRYPT_MODE CryptMode > + ) > +{ > + EFI_STATUS Status; > + TLS_INSTANCE *Instance; > + > + EFI_TPL OldTpl; > + > + Status =3D EFI_SUCCESS; > + > + if (This =3D=3D NULL || FragmentTable =3D=3D NULL || FragmentCount =3D= =3D NULL) { > + return EFI_INVALID_PARAMETER; > + } > + > + OldTpl =3D gBS->RaiseTPL (TPL_CALLBACK); > + > + Instance =3D TLS_INSTANCE_FROM_PROTOCOL_THIS (This); > + > + if (Instance->TlsSessionState !=3D EfiTlsSessionDataTransferring) { > + Status =3D EFI_NOT_READY; > + goto ON_EXIT; > + } > + > + // > + // Packet sent or received may have multiply TLS record > message(Application data type). > + // So,on input these fragments contain the TLS header and TLS APP > payload; > + // on output these fragments also contain the TLS header and TLS APP > payload. > + // > + switch (CryptMode) { > + case EfiTlsEncrypt: > + Status =3D TlsEcryptPacket (Instance, FragmentTable, FragmentCount); > + break; > + case EfiTlsDecrypt: > + Status =3D TlsDecryptPacket (Instance, FragmentTable, FragmentCount)= ; > + break; > + default: > + return EFI_INVALID_PARAMETER; > + } > + > +ON_EXIT: > + gBS->RestoreTPL (OldTpl); > + return Status; > +} > -- > 1.9.5.msysgit.1