From: "Wu, Jiaxin" <jiaxin.wu@intel.com>
To: "Fu, Siyuan" <siyuan.fu@intel.com>,
"edk2-devel@lists.01.org" <edk2-devel@lists.01.org>
Cc: "Ye, Ting" <ting.ye@intel.com>,
"Zhang, Lubo" <lubo.zhang@intel.com>,
"Long, Qin" <qin.long@intel.com>,
Thomas Palmer <thomas.palmer@hpe.com>
Subject: Re: [Patch 05/10] NetworkPkg/TlsDxe: TlsDxe driver implementation over OpenSSL
Date: Thu, 15 Dec 2016 07:24:50 +0000 [thread overview]
Message-ID: <895558F6EA4E3B41AC93A00D163B72741627F566@SHSMSX103.ccr.corp.intel.com> (raw)
In-Reply-To: <B1FF2E9001CE9041BD10B825821D5BC58A884AD5@SHSMSX151.ccr.corp.intel.com>
Thanks Siyuan, I have refined the TlsEcryptPacket/TlsDecryptPacket function according your feedback.
[PATCH v2 05/10] NetworkPkg/TlsDxe: TlsDxe driver implementation over OpenSSL
Thanks,
Jiaxin
> -----Original Message-----
> From: Fu, Siyuan
> Sent: Wednesday, December 14, 2016 4:41 PM
> To: Wu, Jiaxin <jiaxin.wu@intel.com>; edk2-devel@lists.01.org
> Cc: Ye, Ting <ting.ye@intel.com>; Zhang, Lubo <lubo.zhang@intel.com>;
> Long, Qin <qin.long@intel.com>; Thomas Palmer <thomas.palmer@hpe.com>
> Subject: RE: [Patch 05/10] NetworkPkg/TlsDxe: TlsDxe driver implementation
> over OpenSSL
>
> Hi, Jiaxin
>
> Some comments as below:
>
> In TlsImpl.c
>
> Should the ASSERT in line 104 be an error handling? I mean is the input buffer
> coming from external input, and have we checked ContentType within it?
>
> Seems the TempRecordHeader pointer will be modified in the while loop,
> shouldn't the 3rd parameter be the reminding buffer size of the output
> buffer?
>
> Should we return error if the TlsCtrlTrafficOut return a failure?
>
> Similar questions for the decrypt packet function.
>
>
> Best Regards,
> Siyuan
>
> -----Original Message-----
> From: Wu, Jiaxin
> Sent: 2016年12月14日 15:34
> To: edk2-devel@lists.01.org
> Cc: Ye, Ting <ting.ye@intel.com>; Fu, Siyuan <siyuan.fu@intel.com>; Zhang,
> Lubo <lubo.zhang@intel.com>; Long, Qin <qin.long@intel.com>; Thomas
> Palmer <thomas.palmer@hpe.com>; Wu, Jiaxin <jiaxin.wu@intel.com>
> Subject: [Patch 05/10] NetworkPkg/TlsDxe: TlsDxe driver implementation
> over OpenSSL
>
> This patch is the implementation of EFI TLS Service Binding
> Protocol, EFI TLS Protocol and EFI TLS Configuration Protocol
> Interfaces.
>
> Cc: Ye Ting <ting.ye@intel.com>
> Cc: Fu Siyuan <siyuan.fu@intel.com>
> Cc: Zhang Lubo <lubo.zhang@intel.com>
> Cc: Long Qin <qin.long@intel.com>
> Cc: Thomas Palmer <thomas.palmer@hpe.com>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Wu Jiaxin <jiaxin.wu@intel.com>
> ---
> NetworkPkg/TlsDxe/TlsConfigProtocol.c | 152 ++++++++
> NetworkPkg/TlsDxe/TlsDriver.c | 498
> +++++++++++++++++++++++++++
> NetworkPkg/TlsDxe/TlsDriver.h | 237 +++++++++++++
> NetworkPkg/TlsDxe/TlsDxe.inf | 65 ++++
> NetworkPkg/TlsDxe/TlsDxe.uni | 25 ++
> NetworkPkg/TlsDxe/TlsDxeExtra.uni | 18 +
> NetworkPkg/TlsDxe/TlsImpl.c | 270 +++++++++++++++
> NetworkPkg/TlsDxe/TlsImpl.h | 315 +++++++++++++++++
> NetworkPkg/TlsDxe/TlsProtocol.c | 632
> ++++++++++++++++++++++++++++++++++
> 9 files changed, 2212 insertions(+)
> create mode 100644 NetworkPkg/TlsDxe/TlsConfigProtocol.c
> create mode 100644 NetworkPkg/TlsDxe/TlsDriver.c
> create mode 100644 NetworkPkg/TlsDxe/TlsDriver.h
> create mode 100644 NetworkPkg/TlsDxe/TlsDxe.inf
> create mode 100644 NetworkPkg/TlsDxe/TlsDxe.uni
> create mode 100644 NetworkPkg/TlsDxe/TlsDxeExtra.uni
> create mode 100644 NetworkPkg/TlsDxe/TlsImpl.c
> create mode 100644 NetworkPkg/TlsDxe/TlsImpl.h
> create mode 100644 NetworkPkg/TlsDxe/TlsProtocol.c
>
> diff --git a/NetworkPkg/TlsDxe/TlsConfigProtocol.c
> b/NetworkPkg/TlsDxe/TlsConfigProtocol.c
> new file mode 100644
> index 0000000..2ec79c9
> --- /dev/null
> +++ b/NetworkPkg/TlsDxe/TlsConfigProtocol.c
> @@ -0,0 +1,152 @@
> +/** @file
> + Implementation of EFI TLS Configuration Protocol Interfaces.
> +
> + Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> +
> + This program and the accompanying materials
> + are licensed and made available under the terms and conditions of the BSD
> License
> + which accompanies this distribution. The full text of the license may be
> found at
> + http://opensource.org/licenses/bsd-license.php.
> +
> + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> +
> +**/
> +
> +#include "TlsImpl.h"
> +
> +EFI_TLS_CONFIGURATION_PROTOCOL mTlsConfigurationProtocol = {
> + TlsConfigurationSetData,
> + TlsConfigurationGetData
> +};
> +
> +/**
> + Set TLS configuration data.
> +
> + The SetData() function sets TLS configuration to non-volatile storage or
> volatile
> + storage.
> +
> + @param[in] This Pointer to the
> EFI_TLS_CONFIGURATION_PROTOCOL instance.
> + @param[in] DataType Configuration data type.
> + @param[in] Data Pointer to configuration data.
> + @param[in] DataSize Total size of configuration data.
> +
> + @retval EFI_SUCCESS The TLS configuration data is set successfully.
> + @retval EFI_INVALID_PARAMETER One or more of the following
> conditions is TRUE:
> + This is NULL.
> + Data is NULL.
> + DataSize is 0.
> + @retval EFI_UNSUPPORTED The DataType is unsupported.
> + @retval EFI_OUT_OF_RESOURCES Required system resources could not
> be allocated.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsConfigurationSetData (
> + IN EFI_TLS_CONFIGURATION_PROTOCOL *This,
> + IN EFI_TLS_CONFIG_DATA_TYPE DataType,
> + IN VOID *Data,
> + IN UINTN DataSize
> + )
> +{
> + EFI_STATUS Status;
> + TLS_INSTANCE *Instance;
> + EFI_TPL OldTpl;
> +
> + Status = EFI_SUCCESS;
> +
> + if (This == NULL || Data == NULL || DataSize == 0) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
> +
> + Instance = TLS_INSTANCE_FROM_CONFIGURATION_THIS (This);
> +
> + switch (DataType) {
> + case EfiTlsConfigDataTypeCACertificate:
> + Status = TlsSetCaCertificate (Instance->TlsConn, Data, DataSize);
> + break;
> + case EfiTlsConfigDataTypeHostPublicCert:
> + Status = TlsSetHostPublicCert (Instance->TlsConn, Data, DataSize);
> + break;
> + case EfiTlsConfigDataTypeHostPrivateKey:
> + Status = TlsSetHostPrivateKey (Instance->TlsConn, Data, DataSize);
> + break;
> + case EfiTlsConfigDataTypeCertRevocationList:
> + Status = TlsSetCertRevocationList (Data, DataSize);
> + break;
> + default:
> + Status = EFI_UNSUPPORTED;
> + }
> +
> + gBS->RestoreTPL (OldTpl);
> + return Status;
> +}
> +
> +/**
> + Get TLS configuration data.
> +
> + The GetData() function gets TLS configuration.
> +
> + @param[in] This Pointer to the
> EFI_TLS_CONFIGURATION_PROTOCOL instance.
> + @param[in] DataType Configuration data type.
> + @param[in, out] Data Pointer to configuration data.
> + @param[in, out] DataSize Total size of configuration data. On input, it
> means
> + the size of Data buffer. On output, it means the size
> + of copied Data buffer if EFI_SUCCESS, and means the
> + size of desired Data buffer if EFI_BUFFER_TOO_SMALL.
> +
> + @retval EFI_SUCCESS The TLS configuration data is got successfully.
> + @retval EFI_INVALID_PARAMETER One or more of the following
> conditions is TRUE:
> + This is NULL.
> + DataSize is NULL.
> + Data is NULL if *DataSize is not zero.
> + @retval EFI_UNSUPPORTED The DataType is unsupported.
> + @retval EFI_NOT_FOUND The TLS configuration data is not found.
> + @retval EFI_BUFFER_TOO_SMALL The buffer is too small to hold the data.
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsConfigurationGetData (
> + IN EFI_TLS_CONFIGURATION_PROTOCOL *This,
> + IN EFI_TLS_CONFIG_DATA_TYPE DataType,
> + IN OUT VOID *Data, OPTIONAL
> + IN OUT UINTN *DataSize
> + )
> +{
> + EFI_STATUS Status;
> + TLS_INSTANCE *Instance;
> +
> + EFI_TPL OldTpl;
> +
> + Status = EFI_SUCCESS;
> +
> + if (This == NULL || DataSize == NULL || (Data == NULL && *DataSize != 0))
> {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
> +
> + Instance = TLS_INSTANCE_FROM_CONFIGURATION_THIS (This);
> +
> + switch (DataType) {
> + case EfiTlsConfigDataTypeCACertificate:
> + Status = TlsGetCaCertificate (Instance->TlsConn, Data, DataSize);
> + break;
> + case EfiTlsConfigDataTypeHostPublicCert:
> + Status = TlsGetHostPublicCert (Instance->TlsConn, Data, DataSize);
> + break;
> + case EfiTlsConfigDataTypeHostPrivateKey:
> + Status = TlsGetHostPrivateKey (Instance->TlsConn, Data, DataSize);
> + break;
> + case EfiTlsConfigDataTypeCertRevocationList:
> + Status = TlsGetCertRevocationList (Data, DataSize);
> + break;
> + default:
> + Status = EFI_UNSUPPORTED;
> + }
> +
> + gBS->RestoreTPL (OldTpl);
> + return Status;
> +}
> diff --git a/NetworkPkg/TlsDxe/TlsDriver.c b/NetworkPkg/TlsDxe/TlsDriver.c
> new file mode 100644
> index 0000000..0a75c39
> --- /dev/null
> +++ b/NetworkPkg/TlsDxe/TlsDriver.c
> @@ -0,0 +1,498 @@
> +/** @file
> + The Driver Binding and Service Binding Protocol for TlsDxe driver.
> +
> + Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> +
> + This program and the accompanying materials
> + are licensed and made available under the terms and conditions of the BSD
> License
> + which accompanies this distribution. The full text of the license may be
> found at
> + http://opensource.org/licenses/bsd-license.php.
> +
> + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> +
> +**/
> +
> +#include "TlsImpl.h"
> +
> +EFI_SERVICE_BINDING_PROTOCOL mTlsServiceBinding = {
> + TlsServiceBindingCreateChild,
> + TlsServiceBindingDestroyChild
> +};
> +
> +/**
> + Release all the resources used by the TLS instance.
> +
> + @param[in] Instance The TLS instance data.
> +
> +**/
> +VOID
> +TlsCleanInstance (
> + IN TLS_INSTANCE *Instance
> + )
> +{
> + if (Instance != NULL) {
> + if (Instance->TlsConn != NULL) {
> + TlsFree (Instance->TlsConn);
> + }
> +
> + FreePool (Instance);
> + }
> +}
> +
> +/**
> + Create the TLS instance and initialize it.
> +
> + @param[in] Service The pointer to the TLS service.
> + @param[out] Instance The pointer to the TLS instance.
> +
> + @retval EFI_OUT_OF_RESOURCES Failed to allocate resources.
> + @retval EFI_SUCCESS The TLS instance is created.
> +
> +**/
> +EFI_STATUS
> +TlsCreateInstance (
> + IN TLS_SERVICE *Service,
> + OUT TLS_INSTANCE **Instance
> + )
> +{
> + TLS_INSTANCE *TlsInstance;
> +
> + *Instance = NULL;
> +
> + TlsInstance = AllocateZeroPool (sizeof (TLS_INSTANCE));
> + if (TlsInstance == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + TlsInstance->Signature = TLS_INSTANCE_SIGNATURE;
> + InitializeListHead (&TlsInstance->Link);
> + TlsInstance->InDestroy = FALSE;
> + TlsInstance->Service = Service;
> +
> + CopyMem (&TlsInstance->Tls, &mTlsProtocol, sizeof (TlsInstance->Tls));
> + CopyMem (&TlsInstance->TlsConfig, &mTlsConfigurationProtocol, sizeof
> (TlsInstance->TlsConfig));
> +
> + TlsInstance->TlsSessionState = EfiTlsSessionNotStarted;
> +
> + *Instance = TlsInstance;
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Release all the resources used by the TLS service binding instance.
> +
> + @param[in] Service The TLS service data.
> +
> +**/
> +VOID
> +TlsCleanService (
> + IN TLS_SERVICE *Service
> + )
> +{
> + if (Service != NULL) {
> + if (Service->TlsCtx != NULL) {
> + TlsCtxFree (Service->TlsCtx);
> + }
> +
> + FreePool (Service);
> + }
> +}
> +
> +/**
> + Create then initialize a TLS service.
> +
> + @param[in] Image ImageHandle of the TLS driver
> + @param[out] Service The service for TLS driver
> +
> + @retval EFI_OUT_OF_RESOURCES Failed to allocate resource to create
> the service.
> + @retval EFI_SUCCESS The service is created for the driver.
> +
> +**/
> +EFI_STATUS
> +TlsCreateService (
> + IN EFI_HANDLE Image,
> + OUT TLS_SERVICE **Service
> + )
> +{
> + EFI_STATUS Status;
> + TLS_SERVICE *TlsService;
> +
> + Status = EFI_SUCCESS;
> + *Service = NULL;
> +
> + ASSERT (Service != NULL);
> +
> + //
> + // Allocate a TLS Service Data
> + //
> + TlsService = AllocateZeroPool (sizeof (TLS_SERVICE));
> + if (TlsService == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + //
> + // Initialize TLS Service Data
> + //
> + TlsService->Signature = TLS_SERVICE_SIGNATURE;
> + CopyMem (&TlsService->ServiceBinding, &mTlsServiceBinding, sizeof
> (TlsService->ServiceBinding));
> + TlsService->TlsChildrenNum = 0;
> + InitializeListHead (&TlsService->TlsChildrenList);
> + TlsService->ImageHandle = Image;
> +
> + *Service = TlsService;
> +
> + return Status;
> +}
> +
> +/**
> + Unloads an image.
> +
> + @param[in] ImageHandle Handle that identifies the image to be
> unloaded.
> +
> + @retval EFI_SUCCESS The image has been unloaded.
> + @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image
> handle.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsUnload (
> + IN EFI_HANDLE ImageHandle
> + )
> +{
> + EFI_STATUS Status;
> + UINTN HandleNum;
> + EFI_HANDLE *HandleBuffer;
> + UINT32 Index;
> + EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
> + TLS_SERVICE *TlsService;
> +
> + HandleBuffer = NULL;
> + ServiceBinding = NULL;
> + TlsService = NULL;
> +
> + //
> + // Locate all the handles with Tls service binding protocol.
> + //
> + Status = gBS->LocateHandleBuffer (
> + ByProtocol,
> + &gEfiTlsServiceBindingProtocolGuid,
> + NULL,
> + &HandleNum,
> + &HandleBuffer
> + );
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + for (Index = 0; Index < HandleNum; Index++) {
> + //
> + // Firstly, find ServiceBinding interface
> + //
> + Status = gBS->OpenProtocol (
> + HandleBuffer[Index],
> + &gEfiTlsServiceBindingProtocolGuid,
> + (VOID **) &ServiceBinding,
> + ImageHandle,
> + NULL,
> + EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
> + );
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + TlsService = TLS_SERVICE_FROM_THIS (ServiceBinding);
> +
> + //
> + // Then, uninstall ServiceBinding interface
> + //
> + Status = gBS->UninstallMultipleProtocolInterfaces (
> + HandleBuffer[Index],
> + &gEfiTlsServiceBindingProtocolGuid, ServiceBinding,
> + NULL
> + );
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + TlsCleanService (TlsService);
> + }
> +
> + if (HandleBuffer != NULL) {
> + FreePool (HandleBuffer);
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + This is the declaration of an EFI image entry point. This entry point is
> + the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
> + both device drivers and bus drivers.
> +
> + @param ImageHandle The firmware allocated handle for the UEFI
> image.
> + @param SystemTable A pointer to the EFI System Table.
> +
> + @retval EFI_SUCCESS The operation completed successfully.
> + @retval Others An unexpected error occurred.
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsDriverEntryPoint (
> + IN EFI_HANDLE ImageHandle,
> + IN EFI_SYSTEM_TABLE *SystemTable
> + )
> +{
> + EFI_STATUS Status;
> +
> + TLS_SERVICE *TlsService;
> +
> + //
> + // Create TLS Service
> + //
> + Status = TlsCreateService (ImageHandle, &TlsService);
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + ASSERT (TlsService != NULL);
> +
> + //
> + // Initializes the OpenSSL library.
> + //
> + TlsInitialize ();
> +
> + //
> + // Create a new SSL_CTX object as framework to establish TLS/SSL enabled
> + // connections. TLS 1.0 is used as the default version.
> + //
> + TlsService->TlsCtx = TlsCtxNew (TLS10_PROTOCOL_VERSION_MAJOR,
> TLS10_PROTOCOL_VERSION_MINOR);
> + if (TlsService->TlsCtx == NULL) {
> + FreePool (TlsService);
> + return EFI_ABORTED;
> + }
> +
> + //
> + // Install the TlsServiceBinding Protocol onto Handle
> + //
> + Status = gBS->InstallMultipleProtocolInterfaces (
> + &TlsService->Handle,
> + &gEfiTlsServiceBindingProtocolGuid,
> + &TlsService->ServiceBinding,
> + NULL
> + );
> + if (EFI_ERROR (Status)) {
> + goto ON_CLEAN_SERVICE;
> + }
> +
> + return Status;
> +
> +ON_CLEAN_SERVICE:
> + TlsCleanService (TlsService);
> +
> + return Status;
> +}
> +
> +/**
> + Creates a child handle and installs a protocol.
> +
> + The CreateChild() function installs a protocol on ChildHandle.
> + If ChildHandle is a pointer to NULL, then a new handle is created and
> returned in ChildHandle.
> + If ChildHandle is not a pointer to NULL, then the protocol installs on the
> existing ChildHandle.
> +
> + @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL
> instance.
> + @param[in] ChildHandle Pointer to the handle of the child to create. If it is
> NULL,
> + then a new handle is created. If it is a pointer to an existing
> UEFI handle,
> + then the protocol is added to the existing UEFI handle.
> +
> + @retval EFI_SUCCES The protocol was added to ChildHandle.
> + @retval EFI_INVALID_PARAMETER ChildHandle is NULL.
> + @retval EFI_OUT_OF_RESOURCES There are not enough resources
> available to create
> + the child.
> + @retval other The child handle was not created.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsServiceBindingCreateChild (
> + IN EFI_SERVICE_BINDING_PROTOCOL *This,
> + IN EFI_HANDLE *ChildHandle
> + )
> +{
> + TLS_SERVICE *TlsService;
> + TLS_INSTANCE *TlsInstance;
> + EFI_STATUS Status;
> + EFI_TPL OldTpl;
> +
> + if ((This == NULL) || (ChildHandle == NULL)) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + TlsService = TLS_SERVICE_FROM_THIS (This);
> +
> + Status = TlsCreateInstance (TlsService, &TlsInstance);
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + ASSERT (TlsInstance != NULL);
> +
> + //
> + // Create a new TLS connection object.
> + //
> + TlsInstance->TlsConn = TlsNew (TlsService->TlsCtx);
> + if (TlsInstance->TlsConn == NULL) {
> + Status = EFI_ABORTED;
> + goto ON_ERROR;
> + }
> +
> + //
> + // Set default ConnectionEnd to EfiTlsClient
> + //
> + Status = TlsSetConnectionEnd (TlsInstance->TlsConn, EfiTlsClient);
> + if (EFI_ERROR (Status)) {
> + goto ON_ERROR;
> + }
> +
> + //
> + // Install TLS protocol and configuration protocol onto ChildHandle
> + //
> + Status = gBS->InstallMultipleProtocolInterfaces (
> + ChildHandle,
> + &gEfiTlsProtocolGuid,
> + &TlsInstance->Tls,
> + &gEfiTlsConfigurationProtocolGuid,
> + &TlsInstance->TlsConfig,
> + NULL
> + );
> + if (EFI_ERROR (Status)) {
> + goto ON_ERROR;
> + }
> +
> + TlsInstance->ChildHandle = *ChildHandle;
> +
> + //
> + // Add it to the TLS service's child list.
> + //
> + OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
> +
> + InsertTailList (&TlsService->TlsChildrenList, &TlsInstance->Link);
> + TlsService->TlsChildrenNum++;
> +
> + gBS->RestoreTPL (OldTpl);
> +
> + return EFI_SUCCESS;
> +
> +ON_ERROR:
> + TlsCleanInstance (TlsInstance);
> + return Status;
> +}
> +
> +/**
> + Destroys a child handle with a protocol installed on it.
> +
> + The DestroyChild() function does the opposite of CreateChild(). It removes
> a protocol
> + that was installed by CreateChild() from ChildHandle. If the removed
> protocol is the
> + last protocol on ChildHandle, then ChildHandle is destroyed.
> +
> + @param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL
> instance.
> + @param ChildHandle Handle of the child to destroy.
> +
> + @retval EFI_SUCCES The protocol was removed from ChildHandle.
> + @retval EFI_UNSUPPORTED ChildHandle does not support the protocol
> that is being removed.
> + @retval EFI_INVALID_PARAMETER Child handle is NULL.
> + @retval EFI_ACCESS_DENIED The protocol could not be removed from
> the ChildHandle
> + because its services are being used.
> + @retval other The child handle was not destroyed.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsServiceBindingDestroyChild (
> + IN EFI_SERVICE_BINDING_PROTOCOL *This,
> + IN EFI_HANDLE ChildHandle
> + )
> +{
> + TLS_SERVICE *TlsService;
> + TLS_INSTANCE *TlsInstance;
> +
> + EFI_TLS_PROTOCOL *Tls;
> + EFI_TLS_CONFIGURATION_PROTOCOL *TlsConfig;
> + EFI_STATUS Status;
> + EFI_TPL OldTpl;
> +
> + if ((This == NULL) || (ChildHandle == NULL)) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + TlsService = TLS_SERVICE_FROM_THIS (This);
> +
> + //
> + // Find TLS protocol interface installed in ChildHandle
> + //
> + Status = gBS->OpenProtocol (
> + ChildHandle,
> + &gEfiTlsProtocolGuid,
> + (VOID **) &Tls,
> + TlsService->ImageHandle,
> + NULL,
> + EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
> + );
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + //
> + // Find TLS configuration protocol interface installed in ChildHandle
> + //
> + Status = gBS->OpenProtocol (
> + ChildHandle,
> + &gEfiTlsConfigurationProtocolGuid,
> + (VOID **) &TlsConfig,
> + TlsService->ImageHandle,
> + NULL,
> + EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
> + );
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + TlsInstance = TLS_INSTANCE_FROM_PROTOCOL_THIS (Tls);
> +
> + if (TlsInstance->Service != TlsService) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + if (TlsInstance->InDestroy) {
> + return EFI_SUCCESS;
> + }
> +
> + OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
> +
> + TlsInstance->InDestroy = TRUE;
> +
> + //
> + // Uninstall the TLS protocol and TLS Configuration Protocol interface
> installed in ChildHandle.
> + //
> + Status = gBS->UninstallMultipleProtocolInterfaces (
> + ChildHandle,
> + &gEfiTlsProtocolGuid,
> + Tls,
> + &gEfiTlsConfigurationProtocolGuid,
> + TlsConfig,
> + NULL
> + );
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + RemoveEntryList (&TlsInstance->Link);
> + TlsService->TlsChildrenNum--;
> +
> + gBS->RestoreTPL (OldTpl);
> +
> + TlsCleanInstance (TlsInstance);
> +
> + return EFI_SUCCESS;
> +}
> diff --git a/NetworkPkg/TlsDxe/TlsDriver.h b/NetworkPkg/TlsDxe/TlsDriver.h
> new file mode 100644
> index 0000000..c3c30a8
> --- /dev/null
> +++ b/NetworkPkg/TlsDxe/TlsDriver.h
> @@ -0,0 +1,237 @@
> +/** @file
> + Header file of the Driver Binding and Service Binding Protocol for TlsDxe
> driver.
> +
> + Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> +
> + This program and the accompanying materials
> + are licensed and made available under the terms and conditions of the BSD
> License
> + which accompanies this distribution. The full text of the license may be
> found at
> + http://opensource.org/licenses/bsd-license.php.
> +
> + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> +
> +**/
> +
> +#ifndef __EFI_TLS_DRIVER_H__
> +#define __EFI_TLS_DRIVER_H__
> +
> +#include <Uefi.h>
> +
> +//
> +// Driver Protocols
> +//
> +#include <Protocol/ServiceBinding.h>
> +
> +//
> +// Driver Version
> +//
> +#define TLS_VERSION 0x00000000
> +
> +#define TLS_SERVICE_SIGNATURE SIGNATURE_32 ('T', 'L', 'S', 'S')
> +
> +#define TLS_INSTANCE_SIGNATURE SIGNATURE_32 ('T', 'L', 'S', 'I')
> +
> +///
> +/// TLS Service Data
> +///
> +typedef struct _TLS_SERVICE TLS_SERVICE;
> +
> +///
> +/// TLS Instance Data
> +///
> +typedef struct _TLS_INSTANCE TLS_INSTANCE;
> +
> +
> +struct _TLS_SERVICE {
> + UINT32 Signature;
> + EFI_SERVICE_BINDING_PROTOCOL ServiceBinding;
> +
> + UINT16 TlsChildrenNum;
> + LIST_ENTRY TlsChildrenList;
> +
> + //
> + // Handle to install TlsServiceBinding protocol.
> + //
> + EFI_HANDLE Handle;
> + EFI_HANDLE ImageHandle;
> +
> + //
> + // Main SSL Context object which is created by a server or client once per
> program
> + // life-time and which holds mainly default values for the SSL object which
> are later
> + // created for the connections.
> + //
> + VOID *TlsCtx;
> +};
> +
> +struct _TLS_INSTANCE {
> + UINT32 Signature;
> + LIST_ENTRY Link;
> +
> + BOOLEAN InDestroy;
> +
> + TLS_SERVICE *Service;
> + EFI_HANDLE ChildHandle;
> +
> + EFI_TLS_PROTOCOL Tls;
> + EFI_TLS_CONFIGURATION_PROTOCOL TlsConfig;
> +
> + EFI_TLS_SESSION_STATE TlsSessionState;
> +
> + //
> + // Main SSL Connection which is created by a server or a client
> + // per established connection.
> + //
> + VOID *TlsConn;
> +};
> +
> +
> +#define TLS_SERVICE_FROM_THIS(a) \
> + CR (a, TLS_SERVICE, ServiceBinding, TLS_SERVICE_SIGNATURE)
> +
> +#define TLS_INSTANCE_FROM_PROTOCOL_THIS(a) \
> + CR (a, TLS_INSTANCE, Tls, TLS_INSTANCE_SIGNATURE)
> +
> +#define TLS_INSTANCE_FROM_CONFIGURATION_THIS(a) \
> + CR (a, TLS_INSTANCE, TlsConfig, TLS_INSTANCE_SIGNATURE)
> +
> +
> +/**
> + Release all the resources used by the TLS instance.
> +
> + @param[in] Instance The TLS instance data.
> +
> +**/
> +VOID
> +TlsCleanInstance (
> + IN TLS_INSTANCE *Instance
> + );
> +
> +/**
> + Create the TLS instance and initialize it.
> +
> + @param[in] Service The pointer to the TLS service.
> + @param[out] Instance The pointer to the TLS instance.
> +
> + @retval EFI_OUT_OF_RESOURCES Failed to allocate resources.
> + @retval EFI_SUCCESS The TLS instance is created.
> +
> +**/
> +EFI_STATUS
> +TlsCreateInstance (
> + IN TLS_SERVICE *Service,
> + OUT TLS_INSTANCE **Instance
> + );
> +
> +/**
> + Release all the resources used by the TLS service binding instance.
> +
> + @param[in] Service The TLS service data.
> +
> +**/
> +VOID
> +TlsCleanService (
> + IN TLS_SERVICE *Service
> + );
> +
> +/**
> + Create then initialize a TLS service.
> +
> + @param[in] Image ImageHandle of the TLS driver
> + @param[out] Service The service for TLS driver
> +
> + @retval EFI_OUT_OF_RESOURCES Failed to allocate resource to create
> the service.
> + @retval EFI_SUCCESS The service is created for the driver.
> +
> +**/
> +EFI_STATUS
> +TlsCreateService (
> + IN EFI_HANDLE Image,
> + OUT TLS_SERVICE **Service
> + );
> +
> +/**
> + Unloads an image.
> +
> + @param[in] ImageHandle Handle that identifies the image to be
> unloaded.
> +
> + @retval EFI_SUCCESS The image has been unloaded.
> + @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image
> handle.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsUnload (
> + IN EFI_HANDLE ImageHandle
> + );
> +
> +/**
> + This is the declaration of an EFI image entry point. This entry point is
> + the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
> + both device drivers and bus drivers.
> +
> + @param ImageHandle The firmware allocated handle for the UEFI
> image.
> + @param SystemTable A pointer to the EFI System Table.
> +
> + @retval EFI_SUCCESS The operation completed successfully.
> + @retval Others An unexpected error occurred.
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsDriverEntryPoint (
> + IN EFI_HANDLE ImageHandle,
> + IN EFI_SYSTEM_TABLE *SystemTable
> + );
> +
> +/**
> + Creates a child handle and installs a protocol.
> +
> + The CreateChild() function installs a protocol on ChildHandle.
> + If ChildHandle is a pointer to NULL, then a new handle is created and
> returned in ChildHandle.
> + If ChildHandle is not a pointer to NULL, then the protocol installs on the
> existing ChildHandle.
> +
> + @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL
> instance.
> + @param[in] ChildHandle Pointer to the handle of the child to create. If it is
> NULL,
> + then a new handle is created. If it is a pointer to an existing
> UEFI handle,
> + then the protocol is added to the existing UEFI handle.
> +
> + @retval EFI_SUCCES The protocol was added to ChildHandle.
> + @retval EFI_INVALID_PARAMETER ChildHandle is NULL.
> + @retval EFI_OUT_OF_RESOURCES There are not enough resources
> available to create
> + the child.
> + @retval other The child handle was not created.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsServiceBindingCreateChild (
> + IN EFI_SERVICE_BINDING_PROTOCOL *This,
> + IN EFI_HANDLE *ChildHandle
> + );
> +
> +/**
> + Destroys a child handle with a protocol installed on it.
> +
> + The DestroyChild() function does the opposite of CreateChild(). It removes
> a protocol
> + that was installed by CreateChild() from ChildHandle. If the removed
> protocol is the
> + last protocol on ChildHandle, then ChildHandle is destroyed.
> +
> + @param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL
> instance.
> + @param ChildHandle Handle of the child to destroy.
> +
> + @retval EFI_SUCCES The protocol was removed from ChildHandle.
> + @retval EFI_UNSUPPORTED ChildHandle does not support the protocol
> that is being removed.
> + @retval EFI_INVALID_PARAMETER Child handle is NULL.
> + @retval EFI_ACCESS_DENIED The protocol could not be removed from
> the ChildHandle
> + because its services are being used.
> + @retval other The child handle was not destroyed.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsServiceBindingDestroyChild (
> + IN EFI_SERVICE_BINDING_PROTOCOL *This,
> + IN EFI_HANDLE ChildHandle
> + );
> +
> +#endif
> diff --git a/NetworkPkg/TlsDxe/TlsDxe.inf b/NetworkPkg/TlsDxe/TlsDxe.inf
> new file mode 100644
> index 0000000..dba3257
> --- /dev/null
> +++ b/NetworkPkg/TlsDxe/TlsDxe.inf
> @@ -0,0 +1,65 @@
> +## @file
> +# This module produces EFI TLS Protocol, EFI TLS Service Binding Protocol
> and
> +# EFI TLS Configuration Protocol.
> +#
> +# This module produces EFI TLS (Transport Layer Security) Protocol and EFI
> TLS
> +# Service Binding Protocol, to provide TLS services.
> +#
> +# Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> +#
> +# This program and the accompanying materials
> +# are licensed and made available under the terms and conditions of the
> BSD License
> +# which accompanies this distribution. The full text of the license may be
> found at
> +# http://opensource.org/licenses/bsd-license.php.
> +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> +#
> +#
> +##
> +
> +[Defines]
> + INF_VERSION = 0x00010005
> + BASE_NAME = TlsDxe
> + FILE_GUID = 3aceb0c0-3c72-11e4-9a56-74d435052646
> + MODULE_TYPE = UEFI_DRIVER
> + VERSION_STRING = 1.0
> + ENTRY_POINT = TlsDriverEntryPoint
> + UNLOAD_IMAGE = TlsUnload
> + MODULE_UNI_FILE = TlsDxe.uni
> +
> +#
> +# VALID_ARCHITECTURES = IA32 X64
> +#
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> + MdeModulePkg/MdeModulePkg.dec
> + CryptoPkg/CryptoPkg.dec
> +
> +[Sources]
> + TlsDriver.h
> + TlsDriver.c
> + TlsProtocol.c
> + TlsConfigProtocol.c
> + TlsImpl.h
> + TlsImpl.c
> +
> +[LibraryClasses]
> + UefiDriverEntryPoint
> + UefiBootServicesTableLib
> + MemoryAllocationLib
> + BaseMemoryLib
> + BaseLib
> + UefiLib
> + DebugLib
> + NetLib
> + BaseCryptLib
> + TlsLib
> +
> +[Protocols]
> + gEfiTlsServiceBindingProtocolGuid ## PRODUCES
> + gEfiTlsProtocolGuid ## PRODUCES
> + gEfiTlsConfigurationProtocolGuid ## PRODUCES
> +
> +[UserExtensions.TianoCore."ExtraFiles"]
> + TlsDxeExtra.uni
> diff --git a/NetworkPkg/TlsDxe/TlsDxe.uni b/NetworkPkg/TlsDxe/TlsDxe.uni
> new file mode 100644
> index 0000000..98c41ca
> --- /dev/null
> +++ b/NetworkPkg/TlsDxe/TlsDxe.uni
> @@ -0,0 +1,25 @@
> +// /** @file
> +// This module produces EFI TLS Protocol, EFI TLS Service Binding Protocol
> and
> +// EFI TLS Configuration Protocol.
> +//
> +// This module produces EFI TLS (Transport Layer Security) Protocol, EFI TLS
> +// Service Binding Protocol, and EFI TLS Configuration Protocol to provide
> TLS
> +// services.
> +//
> +// Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> +//
> +// This program and the accompanying materials
> +// are licensed and made available under the terms and conditions of the
> BSD License
> +// which accompanies this distribution. The full text of the license may be
> found at
> +// http://opensource.org/licenses/bsd-license.php
> +//
> +// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> +// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> +//
> +// **/
> +
> +
> +#string STR_MODULE_ABSTRACT #language en-US "UEFI TLS service"
> +
> +#string STR_MODULE_DESCRIPTION #language en-US "This module
> produces EFI TLS Protocol, EFI TLS Service Binding Protocol and EFI TLS
> Configuration Protocol to provide EFI TLS services."
> +
> diff --git a/NetworkPkg/TlsDxe/TlsDxeExtra.uni
> b/NetworkPkg/TlsDxe/TlsDxeExtra.uni
> new file mode 100644
> index 0000000..a38582a
> --- /dev/null
> +++ b/NetworkPkg/TlsDxe/TlsDxeExtra.uni
> @@ -0,0 +1,18 @@
> +// /** @file
> +// TlsDxe Localized Strings and Content
> +//
> +// Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> +//
> +// This program and the accompanying materials
> +// are licensed and made available under the terms and conditions of the
> BSD License
> +// which accompanies this distribution. The full text of the license may be
> found at
> +// http://opensource.org/licenses/bsd-license.php.
> +//
> +// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> +// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> +//
> +// **/
> +
> +#string STR_PROPERTIES_MODULE_NAME
> +#language en-US
> +"EFI TLS DXE Driver"
> diff --git a/NetworkPkg/TlsDxe/TlsImpl.c b/NetworkPkg/TlsDxe/TlsImpl.c
> new file mode 100644
> index 0000000..5fb1e78
> --- /dev/null
> +++ b/NetworkPkg/TlsDxe/TlsImpl.c
> @@ -0,0 +1,270 @@
> +/** @file
> + The Miscellaneous Routines for TlsDxe driver.
> +
> +Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> +
> +This program and the accompanying materials
> +are licensed and made available under the terms and conditions of the BSD
> License
> +which accompanies this distribution. The full text of the license may be
> found at
> +http://opensource.org/licenses/bsd-license.php
> +
> +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> +
> +**/
> +
> +#include "TlsImpl.h"
> +
> +/**
> + Encrypt the message listed in fragment.
> +
> + @param[in] TlsInstance The pointer to the TLS instance.
> + @param[in, out] FragmentTable Pointer to a list of fragment.
> + On input these fragments contain the TLS header and
> + plain text TLS payload;
> + On output these fragments contain the TLS header and
> + cipher text TLS payload.
> + @param[in] FragmentCount Number of fragment.
> +
> + @retval EFI_SUCCESS The operation completed successfully.
> + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
> + @retval EFI_ABORTED TLS session state is incorrect.
> + @retval Others Other errors as indicated.
> +**/
> +EFI_STATUS
> +TlsEcryptPacket (
> + IN TLS_INSTANCE *TlsInstance,
> + IN OUT EFI_TLS_FRAGMENT_DATA **FragmentTable,
> + IN UINT32 *FragmentCount
> + )
> +{
> + 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;
> +
> + BytesCopied = 0;
> + BufferInSize = 0;
> + BufferIn = NULL;
> + BufferInPtr = NULL;
> + RecordHeaderIn = NULL;
> + TempRecordHeader = NULL;
> + BufferOutSize = 0;
> + BufferOut = NULL;
> + Ret = 0;
> +
> + //
> + // Calculate the size according to the fragment table.
> + //
> + for (Index = 0; Index < *FragmentCount; Index++) {
> + BufferInSize += (*FragmentTable)[Index].FragmentLength;
> + }
> +
> + //
> + // Allocate buffer for processing data.
> + //
> + BufferIn = AllocateZeroPool (BufferInSize);
> + if (BufferIn == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + //
> + // Copy all TLS plain record header and payload into ProcessBuffer.
> + //
> + for (Index = 0; Index < *FragmentCount; Index++) {
> + CopyMem (
> + (BufferIn + BytesCopied),
> + (*FragmentTable)[Index].FragmentBuffer,
> + (*FragmentTable)[Index].FragmentLength
> + );
> + BytesCopied += (*FragmentTable)[Index].FragmentLength;
> + }
> +
> + BufferOut = AllocateZeroPool (MAX_BUFFER_SIZE);
> + if (BufferOut == NULL) {
> + FreePool (BufferIn);
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + //
> + // Parsing buffer.
> + //
> + BufferInPtr = BufferIn;
> + TempRecordHeader = (TLS_RECORD_HEADER *) BufferOut;
> + while ((UINTN) BufferInPtr < (UINTN) BufferIn + BufferInSize) {
> + RecordHeaderIn = (TLS_RECORD_HEADER *) BufferInPtr;
> + ASSERT (RecordHeaderIn->ContentType ==
> TLS_CONTENT_TYPE_APPLICATION_DATA);
> + ThisPlainMessageSize = RecordHeaderIn->Length;
> +
> + TlsWrite (TlsInstance->TlsConn, (UINT8 *) (RecordHeaderIn + 1),
> ThisPlainMessageSize);
> +
> + Ret = TlsCtrlTrafficOut (TlsInstance->TlsConn, (UINT8
> *)(TempRecordHeader), MAX_BUFFER_SIZE);
> +
> + if (Ret > 0) {
> + ThisMessageSize = (UINT16) Ret;
> + } else {
> + ThisMessageSize = 0;
> + }
> +
> + BufferOutSize += ThisMessageSize;
> +
> + BufferInPtr += RECORD_HEADER_LEN + ThisPlainMessageSize;
> + TempRecordHeader += ThisMessageSize;
> + }
> +
> + FreePool (BufferIn);
> +
> + //
> + // The caller will take responsible to handle the original fragment table.
> + //
> + *FragmentTable = AllocateZeroPool (sizeof (EFI_TLS_FRAGMENT_DATA));
> + if (*FragmentTable == NULL) {
> + FreePool (BufferOut);
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + (*FragmentTable)[0].FragmentBuffer = BufferOut;
> + (*FragmentTable)[0].FragmentLength = BufferOutSize;
> + *FragmentCount = 1;
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Decrypt the message listed in fragment.
> +
> + @param[in] TlsInstance The pointer to the TLS instance.
> + @param[in, out] FragmentTable Pointer to a list of fragment.
> + On input these fragments contain the TLS header and
> + cipher text TLS payload;
> + On output these fragments contain the TLS header and
> + plain text TLS payload.
> + @param[in] FragmentCount Number of fragment.
> +
> + @retval EFI_SUCCESS The operation completed successfully.
> + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
> + @retval EFI_ABORTED TLS session state is incorrect.
> + @retval Others Other errors as indicated.
> +**/
> +EFI_STATUS
> +TlsDecryptPacket (
> + IN TLS_INSTANCE *TlsInstance,
> + IN OUT EFI_TLS_FRAGMENT_DATA **FragmentTable,
> + IN UINT32 *FragmentCount
> + )
> +{
> + 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;
> +
> + BytesCopied = 0;
> + BufferIn = NULL;
> + BufferInSize = 0;
> + BufferInPtr = NULL;
> + RecordHeaderIn = NULL;
> + TempRecordHeader = NULL;
> + BufferOut = NULL;
> + BufferOutSize = 0;
> + Ret = 0;
> +
> + //
> + // Calculate the size according to the fragment table.
> + //
> + for (Index = 0; Index < *FragmentCount; Index++) {
> + BufferInSize += (*FragmentTable)[Index].FragmentLength;
> + }
> +
> + //
> + // Allocate buffer for processing data
> + //
> + BufferIn = AllocateZeroPool (BufferInSize);
> + if (BufferIn == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + //
> + // Copy all TLS plain record header and payload to ProcessBuffer
> + //
> + for (Index = 0; Index < *FragmentCount; Index++) {
> + CopyMem (
> + (BufferIn + BytesCopied),
> + (*FragmentTable)[Index].FragmentBuffer,
> + (*FragmentTable)[Index].FragmentLength
> + );
> + BytesCopied += (*FragmentTable)[Index].FragmentLength;
> + }
> +
> + BufferOut = AllocateZeroPool (MAX_BUFFER_SIZE);
> + if (BufferOut == NULL) {
> + FreePool (BufferIn);
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + //
> + // Parsing buffer. Received packet may have multiply TLS record message.
> + //
> + BufferInPtr = BufferIn;
> + TempRecordHeader = (TLS_RECORD_HEADER *) BufferOut;
> + while ((UINTN) BufferInPtr < (UINTN) BufferIn + BufferInSize) {
> + RecordHeaderIn = (TLS_RECORD_HEADER *) BufferInPtr;
> + ASSERT (RecordHeaderIn->ContentType ==
> TLS_CONTENT_TYPE_APPLICATION_DATA);
> + ThisCipherMessageSize = NTOHS (RecordHeaderIn->Length);
> +
> + Ret = TlsCtrlTrafficIn (TlsInstance->TlsConn, (UINT8 *) (RecordHeaderIn),
> RECORD_HEADER_LEN + ThisCipherMessageSize);
> + if (Ret != RECORD_HEADER_LEN + ThisCipherMessageSize) {
> + FreePool (BufferIn);
> + TlsInstance->TlsSessionState = EfiTlsSessionError;
> + return EFI_ABORTED;
> + }
> +
> + Ret = 0;
> + Ret = TlsRead (TlsInstance->TlsConn, (UINT8 *) (TempRecordHeader + 1),
> MAX_BUFFER_SIZE);
> +
> + if (Ret > 0) {
> + ThisPlainMessageSize = (UINT16) Ret;
> + } else {
> + ThisPlainMessageSize = 0;
> + }
> +
> + CopyMem (TempRecordHeader, RecordHeaderIn,
> RECORD_HEADER_LEN);
> + TempRecordHeader->Length = ThisPlainMessageSize;
> + BufferOutSize += RECORD_HEADER_LEN + ThisPlainMessageSize;
> +
> + BufferInPtr += RECORD_HEADER_LEN + ThisCipherMessageSize;
> + TempRecordHeader += RECORD_HEADER_LEN + ThisPlainMessageSize;
> + }
> +
> + FreePool (BufferIn);
> +
> + //
> + // The caller will take responsible to handle the original fragment table
> + //
> + *FragmentTable = AllocateZeroPool (sizeof (EFI_TLS_FRAGMENT_DATA));
> + if (*FragmentTable == NULL) {
> + FreePool (BufferOut);
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + (*FragmentTable)[0].FragmentBuffer = BufferOut;
> + (*FragmentTable)[0].FragmentLength = BufferOutSize;
> + *FragmentCount = 1;
> +
> + return EFI_SUCCESS;
> +}
> diff --git a/NetworkPkg/TlsDxe/TlsImpl.h b/NetworkPkg/TlsDxe/TlsImpl.h
> new file mode 100644
> index 0000000..b0615cb
> --- /dev/null
> +++ b/NetworkPkg/TlsDxe/TlsImpl.h
> @@ -0,0 +1,315 @@
> +/** @file
> + Header file of Miscellaneous Routines for TlsDxe driver.
> +
> +Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> +
> +This program and the accompanying materials
> +are licensed and made available under the terms and conditions of the BSD
> License
> +which accompanies this distribution. The full text of the license may be
> found at
> +http://opensource.org/licenses/bsd-license.php
> +
> +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> +
> +**/
> +
> +#ifndef __EFI_TLS_IMPL_H__
> +#define __EFI_TLS_IMPL_H__
> +
> +//
> +// Libraries
> +//
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/UefiLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/NetLib.h>
> +#include <Library/BaseCryptLib.h>
> +#include <Library/TlsLib.h>
> +
> +//
> +// Consumed Protocols
> +//
> +#include <Protocol/Tls.h>
> +#include <Protocol/TlsConfig.h>
> +
> +#include <IndustryStandard/Tls1.h>
> +
> +#include "TlsDriver.h"
> +
> +//
> +// Protocol instances
> +//
> +extern EFI_SERVICE_BINDING_PROTOCOL mTlsServiceBinding;
> +extern EFI_TLS_PROTOCOL mTlsProtocol;
> +extern EFI_TLS_CONFIGURATION_PROTOCOL mTlsConfigurationProtocol;
> +
> +#define RECORD_HEADER_LEN 5 /// ContentType(1) + Version(2) +
> Length(2)
> +
> +#define MAX_BUFFER_SIZE 32768
> +
> +/**
> + Encrypt the message listed in fragment.
> +
> + @param[in] TlsInstance The pointer to the TLS instance.
> + @param[in, out] FragmentTable Pointer to a list of fragment.
> + On input these fragments contain the TLS header and
> + plain text TLS payload;
> + On output these fragments contain the TLS header and
> + cipher text TLS payload.
> + @param[in] FragmentCount Number of fragment.
> +
> + @retval EFI_SUCCESS The operation completed successfully.
> + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
> + @retval EFI_ABORTED TLS session state is incorrect.
> + @retval Others Other errors as indicated.
> +**/
> +EFI_STATUS
> +TlsEcryptPacket (
> + IN TLS_INSTANCE *TlsInstance,
> + IN OUT EFI_TLS_FRAGMENT_DATA **FragmentTable,
> + IN UINT32 *FragmentCount
> + );
> +
> +/**
> + Decrypt the message listed in fragment.
> +
> + @param[in] TlsInstance The pointer to the TLS instance.
> + @param[in, out] FragmentTable Pointer to a list of fragment.
> + On input these fragments contain the TLS header and
> + cipher text TLS payload;
> + On output these fragments contain the TLS header and
> + plain text TLS payload.
> + @param[in] FragmentCount Number of fragment.
> +
> + @retval EFI_SUCCESS The operation completed successfully.
> + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
> + @retval EFI_ABORTED TLS session state is incorrect.
> + @retval Others Other errors as indicated.
> +**/
> +EFI_STATUS
> +TlsDecryptPacket (
> + IN TLS_INSTANCE *TlsInstance,
> + IN OUT EFI_TLS_FRAGMENT_DATA **FragmentTable,
> + IN UINT32 *FragmentCount
> + );
> +
> +/**
> + Set TLS session data.
> +
> + The SetSessionData() function set data for a new TLS session. All session
> data should
> + be set before BuildResponsePacket() invoked.
> +
> + @param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
> + @param[in] DataType TLS session data type.
> + @param[in] Data Pointer to session data.
> + @param[in] DataSize Total size of session data.
> +
> + @retval EFI_SUCCESS The TLS session data is set successfully.
> + @retval EFI_INVALID_PARAMETER One or more of the following
> conditions is TRUE:
> + This is NULL.
> + Data is NULL.
> + DataSize is 0.
> + @retval EFI_UNSUPPORTED The DataType is unsupported.
> + @retval EFI_ACCESS_DENIED If the DataType is one of below:
> + EfiTlsClientRandom
> + EfiTlsServerRandom
> + EfiTlsKeyMaterial
> + @retval EFI_NOT_READY Current TLS session state is NOT
> + EfiTlsSessionStateNotStarted.
> + @retval EFI_OUT_OF_RESOURCES Required system resources could not
> be allocated.
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsSetSessionData (
> + IN EFI_TLS_PROTOCOL *This,
> + IN EFI_TLS_SESSION_DATA_TYPE DataType,
> + IN VOID *Data,
> + IN UINTN DataSize
> + );
> +
> +/**
> + Get TLS session data.
> +
> + The GetSessionData() function return the TLS session information.
> +
> + @param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
> + @param[in] DataType TLS session data type.
> + @param[in, out] Data Pointer to session data.
> + @param[in, out] DataSize Total size of session data. On input, it means
> + the size of Data buffer. On output, it means the size
> + of copied Data buffer if EFI_SUCCESS, and means the
> + size of desired Data buffer if EFI_BUFFER_TOO_SMALL.
> +
> + @retval EFI_SUCCESS The TLS session data is got successfully.
> + @retval EFI_INVALID_PARAMETER One or more of the following
> conditions is TRUE:
> + This is NULL.
> + DataSize is NULL.
> + Data is NULL if *DataSize is not zero.
> + @retval EFI_UNSUPPORTED The DataType is unsupported.
> + @retval EFI_NOT_FOUND The TLS session data is not found.
> + @retval EFI_NOT_READY The DataType is not ready in current session
> state.
> + @retval EFI_BUFFER_TOO_SMALL The buffer is too small to hold the data.
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsGetSessionData (
> + IN EFI_TLS_PROTOCOL *This,
> + IN EFI_TLS_SESSION_DATA_TYPE DataType,
> + IN OUT VOID *Data, OPTIONAL
> + IN OUT UINTN *DataSize
> + );
> +
> +/**
> + Build response packet according to TLS state machine. This function is only
> valid for
> + alert, handshake and change_cipher_spec content type.
> +
> + The BuildResponsePacket() function builds TLS response packet in
> response to the TLS
> + request packet specified by RequestBuffer and RequestSize. If
> RequestBuffer is NULL and
> + RequestSize is 0, and TLS session status is EfiTlsSessionNotStarted, the TLS
> session
> + will be initiated and the response packet needs to be ClientHello. If
> RequestBuffer is
> + NULL and RequestSize is 0, and TLS session status is EfiTlsSessionClosing,
> the TLS
> + session will be closed and response packet needs to be CloseNotify. If
> RequestBuffer is
> + NULL and RequestSize is 0, and TLS session status is EfiTlsSessionError, the
> TLS
> + session has errors and the response packet needs to be Alert message
> based on error
> + type.
> +
> + @param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
> + @param[in] RequestBuffer Pointer to the most recently received TLS
> packet. NULL
> + means TLS need initiate the TLS session and response
> + packet need to be ClientHello.
> + @param[in] RequestSize Packet size in bytes for the most recently
> received TLS
> + packet. 0 is only valid when RequestBuffer is NULL.
> + @param[out] Buffer Pointer to the buffer to hold the built packet.
> + @param[in, out] BufferSize Pointer to the buffer size in bytes. On input,
> it is
> + the buffer size provided by the caller. On output, it
> + is the buffer size in fact needed to contain the
> + packet.
> +
> + @retval EFI_SUCCESS The required TLS packet is built successfully.
> + @retval EFI_INVALID_PARAMETER One or more of the following
> conditions is TRUE:
> + This is NULL.
> + RequestBuffer is NULL but RequestSize is NOT 0.
> + RequestSize is 0 but RequestBuffer is NOT NULL.
> + BufferSize is NULL.
> + Buffer is NULL if *BufferSize is not zero.
> + @retval EFI_BUFFER_TOO_SMALL BufferSize is too small to hold the
> response packet.
> + @retval EFI_NOT_READY Current TLS session state is NOT ready to
> build
> + ResponsePacket.
> + @retval EFI_ABORTED Something wrong build response packet.
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsBuildResponsePacket (
> + IN EFI_TLS_PROTOCOL *This,
> + IN UINT8 *RequestBuffer, OPTIONAL
> + IN UINTN RequestSize, OPTIONAL
> + OUT UINT8 *Buffer, OPTIONAL
> + IN OUT UINTN *BufferSize
> + );
> +
> +/**
> + Decrypt or encrypt TLS packet during session. This function is only valid
> after
> + session connected and for application_data content type.
> +
> + The ProcessPacket () function process each inbound or outbound TLS APP
> packet.
> +
> + @param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
> + @param[in, out] FragmentTable Pointer to a list of fragment. The caller
> will take
> + responsible to handle the original FragmentTable while
> + it may be reallocated in TLS driver. If CryptMode is
> + EfiTlsEncrypt, on input these fragments contain the TLS
> + header and plain text TLS APP payload; on output these
> + fragments contain the TLS header and cipher text TLS
> + APP payload. If CryptMode is EfiTlsDecrypt, on input
> + these fragments contain the TLS header and cipher text
> + TLS APP payload; on output these fragments contain the
> + TLS header and plain text TLS APP payload.
> + @param[in] FragmentCount Number of fragment.
> + @param[in] CryptMode Crypt mode.
> +
> + @retval EFI_SUCCESS The operation completed successfully.
> + @retval EFI_INVALID_PARAMETER One or more of the following
> conditions is TRUE:
> + This is NULL.
> + FragmentTable is NULL.
> + FragmentCount is NULL.
> + CryptoMode is invalid.
> + @retval EFI_NOT_READY Current TLS session state is NOT
> + EfiTlsSessionDataTransferring.
> + @retval EFI_ABORTED Something wrong decryption the message.
> TLS session
> + status will become EfiTlsSessionError. The caller need
> + call BuildResponsePacket() to generate Error Alert
> + message and send it out.
> + @retval EFI_OUT_OF_RESOURCES No enough resource to finish the
> operation.
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsProcessPacket (
> + IN EFI_TLS_PROTOCOL *This,
> + IN OUT EFI_TLS_FRAGMENT_DATA **FragmentTable,
> + IN UINT32 *FragmentCount,
> + IN EFI_TLS_CRYPT_MODE CryptMode
> + );
> +
> +/**
> + Set TLS configuration data.
> +
> + The SetData() function sets TLS configuration to non-volatile storage or
> volatile
> + storage.
> +
> + @param[in] This Pointer to the
> EFI_TLS_CONFIGURATION_PROTOCOL instance.
> + @param[in] DataType Configuration data type.
> + @param[in] Data Pointer to configuration data.
> + @param[in] DataSize Total size of configuration data.
> +
> + @retval EFI_SUCCESS The TLS configuration data is set successfully.
> + @retval EFI_INVALID_PARAMETER One or more of the following
> conditions is TRUE:
> + This is NULL.
> + Data is NULL.
> + DataSize is 0.
> + @retval EFI_UNSUPPORTED The DataType is unsupported.
> + @retval EFI_OUT_OF_RESOURCES Required system resources could not
> be allocated.
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsConfigurationSetData (
> + IN EFI_TLS_CONFIGURATION_PROTOCOL *This,
> + IN EFI_TLS_CONFIG_DATA_TYPE DataType,
> + IN VOID *Data,
> + IN UINTN DataSize
> + );
> +
> +/**
> + Get TLS configuration data.
> +
> + The GetData() function gets TLS configuration.
> +
> + @param[in] This Pointer to the
> EFI_TLS_CONFIGURATION_PROTOCOL instance.
> + @param[in] DataType Configuration data type.
> + @param[in, out] Data Pointer to configuration data.
> + @param[in, out] DataSize Total size of configuration data. On input, it
> means
> + the size of Data buffer. On output, it means the size
> + of copied Data buffer if EFI_SUCCESS, and means the
> + size of desired Data buffer if EFI_BUFFER_TOO_SMALL.
> +
> + @retval EFI_SUCCESS The TLS configuration data is got successfully.
> + @retval EFI_INVALID_PARAMETER One or more of the following
> conditions is TRUE:
> + This is NULL.
> + DataSize is NULL.
> + Data is NULL if *DataSize is not zero.
> + @retval EFI_UNSUPPORTED The DataType is unsupported.
> + @retval EFI_NOT_FOUND The TLS configuration data is not found.
> + @retval EFI_BUFFER_TOO_SMALL The buffer is too small to hold the data.
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsConfigurationGetData (
> + IN EFI_TLS_CONFIGURATION_PROTOCOL *This,
> + IN EFI_TLS_CONFIG_DATA_TYPE DataType,
> + IN OUT VOID *Data, OPTIONAL
> + IN OUT UINTN *DataSize
> + );
> +
> +#endif
> diff --git a/NetworkPkg/TlsDxe/TlsProtocol.c
> b/NetworkPkg/TlsDxe/TlsProtocol.c
> new file mode 100644
> index 0000000..bc617e1
> --- /dev/null
> +++ b/NetworkPkg/TlsDxe/TlsProtocol.c
> @@ -0,0 +1,632 @@
> +/** @file
> + Implementation of EFI TLS Protocol Interfaces.
> +
> + Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> +
> + This program and the accompanying materials
> + are licensed and made available under the terms and conditions of the BSD
> License
> + which accompanies this distribution. The full text of the license may be
> found at
> + http://opensource.org/licenses/bsd-license.php.
> +
> + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> +
> +**/
> +
> +#include "TlsImpl.h"
> +
> +EFI_TLS_PROTOCOL mTlsProtocol = {
> + TlsSetSessionData,
> + TlsGetSessionData,
> + TlsBuildResponsePacket,
> + TlsProcessPacket
> +};
> +
> +/**
> + Set TLS session data.
> +
> + The SetSessionData() function set data for a new TLS session. All session
> data should
> + be set before BuildResponsePacket() invoked.
> +
> + @param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
> + @param[in] DataType TLS session data type.
> + @param[in] Data Pointer to session data.
> + @param[in] DataSize Total size of session data.
> +
> + @retval EFI_SUCCESS The TLS session data is set successfully.
> + @retval EFI_INVALID_PARAMETER One or more of the following
> conditions is TRUE:
> + This is NULL.
> + Data is NULL.
> + DataSize is 0.
> + @retval EFI_UNSUPPORTED The DataType is unsupported.
> + @retval EFI_ACCESS_DENIED If the DataType is one of below:
> + EfiTlsClientRandom
> + EfiTlsServerRandom
> + EfiTlsKeyMaterial
> + @retval EFI_NOT_READY Current TLS session state is NOT
> + EfiTlsSessionStateNotStarted.
> + @retval EFI_OUT_OF_RESOURCES Required system resources could not
> be allocated.
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsSetSessionData (
> + IN EFI_TLS_PROTOCOL *This,
> + IN EFI_TLS_SESSION_DATA_TYPE DataType,
> + IN VOID *Data,
> + IN UINTN DataSize
> + )
> +{
> + EFI_STATUS Status;
> + TLS_INSTANCE *Instance;
> + UINT16 *CipherId;
> + UINTN Index;
> +
> + EFI_TPL OldTpl;
> +
> + Status = EFI_SUCCESS;
> + CipherId = NULL;
> +
> + if (This == NULL || Data == NULL || DataSize == 0) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
> +
> + Instance = TLS_INSTANCE_FROM_PROTOCOL_THIS (This);
> +
> + if (DataType != EfiTlsSessionState && Instance->TlsSessionState !=
> EfiTlsSessionNotStarted){
> + Status = EFI_NOT_READY;
> + goto ON_EXIT;
> + }
> +
> + switch (DataType) {
> + //
> + // Session Configuration
> + //
> + case EfiTlsVersion:
> + if (DataSize != sizeof (EFI_TLS_VERSION)) {
> + Status = EFI_INVALID_PARAMETER;
> + goto ON_EXIT;
> + }
> +
> + Status = TlsSetVersion (Instance->TlsConn, ((EFI_TLS_VERSION *) Data)-
> >Major, ((EFI_TLS_VERSION *) Data)->Minor);
> + break;
> + case EfiTlsConnectionEnd:
> + if (DataSize != sizeof (EFI_TLS_CONNECTION_END)) {
> + Status = EFI_INVALID_PARAMETER;
> + goto ON_EXIT;
> + }
> +
> + Status = TlsSetConnectionEnd (Instance->TlsConn,
> *((EFI_TLS_CONNECTION_END *) Data));
> + break;
> + case EfiTlsCipherList:
> + CipherId = AllocatePool (DataSize);
> + if (CipherId == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + goto ON_EXIT;
> + }
> +
> + for (Index = 0; Index < DataSize / sizeof (EFI_TLS_CIPHER); Index++) {
> + *(CipherId +Index) = HTONS (*(((UINT16 *) Data) + Index));
> + }
> +
> + Status = TlsSetCipherList (Instance->TlsConn, CipherId, DataSize / sizeof
> (EFI_TLS_CIPHER));
> +
> + FreePool (CipherId);
> + break;
> + case EfiTlsCompressionMethod:
> + //
> + // TLS seems only define one CompressionMethod.null, which specifies
> that data exchanged via the
> + // record protocol will not be compressed.
> + // More information from OpenSSL:
> http://www.openssl.org/docs/manmaster/ssl/SSL_COMP_add_compressio
> n_method.html
> + // The TLS RFC does however not specify compression methods or their
> corresponding identifiers,
> + // so there is currently no compatible way to integrate compression with
> unknown peers.
> + // It is therefore currently not recommended to integrate compression
> into applications.
> + // Applications for non-public use may agree on certain compression
> methods.
> + // Using different compression methods with the same identifier will lead
> to connection failure.
> + //
> + for (Index = 0; Index < DataSize / sizeof (EFI_TLS_COMPRESSION);
> Index++) {
> + Status = TlsSetCompressionMethod (*((UINT8 *) Data + Index));
> + if (EFI_ERROR (Status)) {
> + break;
> + }
> + }
> +
> + break;
> + case EfiTlsExtensionData:
> + Status = EFI_UNSUPPORTED;
> + goto ON_EXIT;
> + case EfiTlsVerifyMethod:
> + if (DataSize != sizeof (EFI_TLS_VERIFY)) {
> + Status = EFI_INVALID_PARAMETER;
> + goto ON_EXIT;
> + }
> +
> + TlsSetVerify (Instance->TlsConn, *((UINT32 *) Data));
> + break;
> + case EfiTlsSessionID:
> + if (DataSize != sizeof (EFI_TLS_SESSION_ID)) {
> + Status = EFI_INVALID_PARAMETER;
> + goto ON_EXIT;
> + }
> +
> + Status = TlsSetSessionId (
> + Instance->TlsConn,
> + ((EFI_TLS_SESSION_ID *) Data)->Data,
> + ((EFI_TLS_SESSION_ID *) Data)->Length
> + );
> + break;
> + case EfiTlsSessionState:
> + if (DataSize != sizeof (EFI_TLS_SESSION_STATE)) {
> + Status = EFI_INVALID_PARAMETER;
> + goto ON_EXIT;
> + }
> +
> + Instance->TlsSessionState = *(EFI_TLS_SESSION_STATE *) Data;
> + break;
> + //
> + // Session information
> + //
> + case EfiTlsClientRandom:
> + Status = EFI_ACCESS_DENIED;
> + break;
> + case EfiTlsServerRandom:
> + Status = EFI_ACCESS_DENIED;
> + break;
> + case EfiTlsKeyMaterial:
> + Status = EFI_ACCESS_DENIED;
> + break;
> + //
> + // Unsupported type.
> + //
> + default:
> + Status = EFI_UNSUPPORTED;
> + }
> +
> +ON_EXIT:
> + gBS->RestoreTPL (OldTpl);
> + return Status;
> +}
> +
> +/**
> + Get TLS session data.
> +
> + The GetSessionData() function return the TLS session information.
> +
> + @param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
> + @param[in] DataType TLS session data type.
> + @param[in, out] Data Pointer to session data.
> + @param[in, out] DataSize Total size of session data. On input, it means
> + the size of Data buffer. On output, it means the size
> + of copied Data buffer if EFI_SUCCESS, and means the
> + size of desired Data buffer if EFI_BUFFER_TOO_SMALL.
> +
> + @retval EFI_SUCCESS The TLS session data is got successfully.
> + @retval EFI_INVALID_PARAMETER One or more of the following
> conditions is TRUE:
> + This is NULL.
> + DataSize is NULL.
> + Data is NULL if *DataSize is not zero.
> + @retval EFI_UNSUPPORTED The DataType is unsupported.
> + @retval EFI_NOT_FOUND The TLS session data is not found.
> + @retval EFI_NOT_READY The DataType is not ready in current session
> state.
> + @retval EFI_BUFFER_TOO_SMALL The buffer is too small to hold the data.
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsGetSessionData (
> + IN EFI_TLS_PROTOCOL *This,
> + IN EFI_TLS_SESSION_DATA_TYPE DataType,
> + IN OUT VOID *Data, OPTIONAL
> + IN OUT UINTN *DataSize
> + )
> +{
> + EFI_STATUS Status;
> + TLS_INSTANCE *Instance;
> +
> + EFI_TPL OldTpl;
> +
> + Status = EFI_SUCCESS;
> +
> + if (This == NULL || DataSize == NULL || (Data == NULL && *DataSize != 0))
> {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
> +
> + Instance = TLS_INSTANCE_FROM_PROTOCOL_THIS (This);
> +
> + if (Instance->TlsSessionState == EfiTlsSessionNotStarted &&
> + (DataType == EfiTlsSessionID || DataType == EfiTlsClientRandom ||
> + DataType == EfiTlsServerRandom || DataType == EfiTlsKeyMaterial)) {
> + Status = EFI_NOT_READY;
> + goto ON_EXIT;
> + }
> +
> + switch (DataType) {
> + case EfiTlsVersion:
> + if (*DataSize < sizeof (EFI_TLS_VERSION)) {
> + *DataSize = sizeof (EFI_TLS_VERSION);
> + Status = EFI_BUFFER_TOO_SMALL;
> + goto ON_EXIT;
> + }
> + *DataSize = sizeof (EFI_TLS_VERSION);
> + *((UINT16 *) Data) = HTONS (TlsGetVersion (Instance->TlsConn));
> + break;
> + case EfiTlsConnectionEnd:
> + if (*DataSize < sizeof (EFI_TLS_CONNECTION_END)) {
> + *DataSize = sizeof (EFI_TLS_CONNECTION_END);
> + Status = EFI_BUFFER_TOO_SMALL;
> + goto ON_EXIT;
> + }
> + *DataSize = sizeof (EFI_TLS_CONNECTION_END);
> + *((UINT8 *) Data) = TlsGetConnectionEnd (Instance->TlsConn);
> + break;
> + case EfiTlsCipherList:
> + //
> + // Get the current session cipher suite.
> + //
> + if (*DataSize < sizeof (EFI_TLS_CIPHER)) {
> + *DataSize = sizeof (EFI_TLS_CIPHER);
> + Status = EFI_BUFFER_TOO_SMALL;
> + goto ON_EXIT;
> + }
> + *DataSize = sizeof(EFI_TLS_CIPHER);
> + Status = TlsGetCurrentCipher (Instance->TlsConn, (UINT16 *) Data);
> + *((UINT16 *) Data) = HTONS (*((UINT16 *) Data));
> + break;
> + case EfiTlsCompressionMethod:
> + //
> + // Get the current session compression method.
> + //
> + if (*DataSize < sizeof (EFI_TLS_COMPRESSION)) {
> + *DataSize = sizeof (EFI_TLS_COMPRESSION);
> + Status = EFI_BUFFER_TOO_SMALL;
> + goto ON_EXIT;
> + }
> + *DataSize = sizeof (EFI_TLS_COMPRESSION);
> + Status = TlsGetCurrentCompressionId (Instance->TlsConn, (UINT8 *)
> Data);
> + break;
> + case EfiTlsExtensionData:
> + Status = EFI_UNSUPPORTED;
> + goto ON_EXIT;
> + case EfiTlsVerifyMethod:
> + if (*DataSize < sizeof (EFI_TLS_VERIFY)) {
> + *DataSize = sizeof (EFI_TLS_VERIFY);
> + Status = EFI_BUFFER_TOO_SMALL;
> + goto ON_EXIT;
> + }
> + *DataSize = sizeof (EFI_TLS_VERIFY);
> + *((UINT32 *) Data) = TlsGetVerify (Instance->TlsConn);
> + break;
> + case EfiTlsSessionID:
> + if (*DataSize < sizeof (EFI_TLS_SESSION_ID)) {
> + *DataSize = sizeof (EFI_TLS_SESSION_ID);
> + Status = EFI_BUFFER_TOO_SMALL;
> + goto ON_EXIT;
> + }
> + *DataSize = sizeof (EFI_TLS_SESSION_ID);
> + Status = TlsGetSessionId (
> + Instance->TlsConn,
> + ((EFI_TLS_SESSION_ID *) Data)->Data,
> + &(((EFI_TLS_SESSION_ID *) Data)->Length)
> + );
> + break;
> + case EfiTlsSessionState:
> + if (*DataSize < sizeof (EFI_TLS_SESSION_STATE)) {
> + *DataSize = sizeof (EFI_TLS_SESSION_STATE);
> + Status = EFI_BUFFER_TOO_SMALL;
> + goto ON_EXIT;
> + }
> + *DataSize = sizeof (EFI_TLS_SESSION_STATE);
> + CopyMem (Data, &Instance->TlsSessionState, *DataSize);
> + break;
> + case EfiTlsClientRandom:
> + if (*DataSize < sizeof (EFI_TLS_RANDOM)) {
> + *DataSize = sizeof (EFI_TLS_RANDOM);
> + Status = EFI_BUFFER_TOO_SMALL;
> + goto ON_EXIT;
> + }
> + *DataSize = sizeof (EFI_TLS_RANDOM);
> + TlsGetClientRandom (Instance->TlsConn, (UINT8 *) Data);
> + break;
> + case EfiTlsServerRandom:
> + if (*DataSize < sizeof (EFI_TLS_RANDOM)) {
> + *DataSize = sizeof (EFI_TLS_RANDOM);
> + Status = EFI_BUFFER_TOO_SMALL;
> + goto ON_EXIT;
> + }
> + *DataSize = sizeof (EFI_TLS_RANDOM);
> + TlsGetServerRandom (Instance->TlsConn, (UINT8 *) Data);
> + break;
> + case EfiTlsKeyMaterial:
> + if (*DataSize < sizeof (EFI_TLS_MASTER_SECRET)) {
> + *DataSize = sizeof (EFI_TLS_MASTER_SECRET);
> + Status = EFI_BUFFER_TOO_SMALL;
> + goto ON_EXIT;
> + }
> + *DataSize = sizeof (EFI_TLS_MASTER_SECRET);
> + Status = TlsGetKeyMaterial (Instance->TlsConn, (UINT8 *) Data);
> + break;
> + //
> + // Unsupported type.
> + //
> + default:
> + Status = EFI_UNSUPPORTED;
> + }
> +
> +ON_EXIT:
> + gBS->RestoreTPL (OldTpl);
> + return Status;
> +}
> +
> +/**
> + Build response packet according to TLS state machine. This function is only
> valid for
> + alert, handshake and change_cipher_spec content type.
> +
> + The BuildResponsePacket() function builds TLS response packet in
> response to the TLS
> + request packet specified by RequestBuffer and RequestSize. If
> RequestBuffer is NULL and
> + RequestSize is 0, and TLS session status is EfiTlsSessionNotStarted, the TLS
> session
> + will be initiated and the response packet needs to be ClientHello. If
> RequestBuffer is
> + NULL and RequestSize is 0, and TLS session status is EfiTlsSessionClosing,
> the TLS
> + session will be closed and response packet needs to be CloseNotify. If
> RequestBuffer is
> + NULL and RequestSize is 0, and TLS session status is EfiTlsSessionError, the
> TLS
> + session has errors and the response packet needs to be Alert message
> based on error
> + type.
> +
> + @param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
> + @param[in] RequestBuffer Pointer to the most recently received TLS
> packet. NULL
> + means TLS need initiate the TLS session and response
> + packet need to be ClientHello.
> + @param[in] RequestSize Packet size in bytes for the most recently
> received TLS
> + packet. 0 is only valid when RequestBuffer is NULL.
> + @param[out] Buffer Pointer to the buffer to hold the built packet.
> + @param[in, out] BufferSize Pointer to the buffer size in bytes. On input,
> it is
> + the buffer size provided by the caller. On output, it
> + is the buffer size in fact needed to contain the
> + packet.
> +
> + @retval EFI_SUCCESS The required TLS packet is built successfully.
> + @retval EFI_INVALID_PARAMETER One or more of the following
> conditions is TRUE:
> + This is NULL.
> + RequestBuffer is NULL but RequestSize is NOT 0.
> + RequestSize is 0 but RequestBuffer is NOT NULL.
> + BufferSize is NULL.
> + Buffer is NULL if *BufferSize is not zero.
> + @retval EFI_BUFFER_TOO_SMALL BufferSize is too small to hold the
> response packet.
> + @retval EFI_NOT_READY Current TLS session state is NOT ready to
> build
> + ResponsePacket.
> + @retval EFI_ABORTED Something wrong build response packet.
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsBuildResponsePacket (
> + IN EFI_TLS_PROTOCOL *This,
> + IN UINT8 *RequestBuffer, OPTIONAL
> + IN UINTN RequestSize, OPTIONAL
> + OUT UINT8 *Buffer, OPTIONAL
> + IN OUT UINTN *BufferSize
> + )
> +{
> + EFI_STATUS Status;
> + TLS_INSTANCE *Instance;
> + EFI_TPL OldTpl;
> +
> + Status = EFI_SUCCESS;
> +
> + if ((This == NULL) || (BufferSize == NULL) ||
> + (RequestBuffer == NULL && RequestSize != 0) ||
> + (RequestBuffer != NULL && RequestSize == 0) ||
> + (Buffer == NULL && *BufferSize !=0)) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
> +
> + Instance = TLS_INSTANCE_FROM_PROTOCOL_THIS (This);
> +
> + if(RequestBuffer == NULL && RequestSize == 0) {
> + switch (Instance->TlsSessionState) {
> + case EfiTlsSessionNotStarted:
> + //
> + // ClientHello.
> + //
> + Status = TlsDoHandshake (
> + Instance->TlsConn,
> + NULL,
> + 0,
> + Buffer,
> + BufferSize
> + );
> + if (EFI_ERROR (Status)) {
> + goto ON_EXIT;
> + }
> +
> + //
> + // *BufferSize should not be zero when ClientHello.
> + //
> + if (*BufferSize == 0) {
> + Status = EFI_ABORTED;
> + goto ON_EXIT;
> + }
> +
> + Instance->TlsSessionState = EfiTlsSessionHandShaking;
> +
> + break;
> + case EfiTlsSessionClosing:
> + //
> + // TLS session will be closed and response packet needs to be
> CloseNotify.
> + //
> + Status = TlsCloseNotify (
> + Instance->TlsConn,
> + Buffer,
> + BufferSize
> + );
> + if (EFI_ERROR (Status)) {
> + goto ON_EXIT;
> + }
> +
> + //
> + // *BufferSize should not be zero when build CloseNotify message.
> + //
> + if (*BufferSize == 0) {
> + Status = EFI_ABORTED;
> + goto ON_EXIT;
> + }
> +
> + break;
> + case EfiTlsSessionError:
> + //
> + // TLS session has errors and the response packet needs to be Alert
> + // message based on error type.
> + //
> + Status = TlsHandeAlert (
> + Instance->TlsConn,
> + NULL,
> + 0,
> + Buffer,
> + BufferSize
> + );
> + if (EFI_ERROR (Status)) {
> + goto ON_EXIT;
> + }
> +
> + break;
> + default:
> + //
> + // Current TLS session state is NOT ready to build ResponsePacket.
> + //
> + Status = EFI_NOT_READY;
> + }
> + } else {
> + //
> + // 1. Received packet may have multiply TLS record messages.
> + // 2. One TLS record message may have multiply handshake protocol.
> + // 3. Some errors may be happened in handshake.
> + // TlsDoHandshake() can handle all of those cases.
> + //
> + if (TlsInHandshake (Instance->TlsConn)) {
> + Status = TlsDoHandshake (
> + Instance->TlsConn,
> + RequestBuffer,
> + RequestSize,
> + Buffer,
> + BufferSize
> + );
> + if (EFI_ERROR (Status)) {
> + goto ON_EXIT;
> + }
> +
> + if (!TlsInHandshake (Instance->TlsConn)) {
> + Instance->TlsSessionState = EfiTlsSessionDataTransferring;
> + }
> + } else {
> + //
> + // Must be alert message, Decrypt it and build the ResponsePacket.
> + //
> + ASSERT (((TLS_RECORD_HEADER *) RequestBuffer)->ContentType ==
> TLS_CONTENT_TYPE_ALERT);
> +
> + Status = TlsHandeAlert (
> + Instance->TlsConn,
> + RequestBuffer,
> + RequestSize,
> + Buffer,
> + BufferSize
> + );
> + if (EFI_ERROR (Status)) {
> + if (Status != EFI_BUFFER_TOO_SMALL) {
> + Instance->TlsSessionState = EfiTlsSessionError;
> + }
> +
> + goto ON_EXIT;
> + }
> + }
> + }
> +
> +ON_EXIT:
> + gBS->RestoreTPL (OldTpl);
> + return Status;
> +}
> +
> +/**
> + Decrypt or encrypt TLS packet during session. This function is only valid
> after
> + session connected and for application_data content type.
> +
> + The ProcessPacket () function process each inbound or outbound TLS APP
> packet.
> +
> + @param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
> + @param[in, out] FragmentTable Pointer to a list of fragment. The caller
> will take
> + responsible to handle the original FragmentTable while
> + it may be reallocated in TLS driver. If CryptMode is
> + EfiTlsEncrypt, on input these fragments contain the TLS
> + header and plain text TLS APP payload; on output these
> + fragments contain the TLS header and cipher text TLS
> + APP payload. If CryptMode is EfiTlsDecrypt, on input
> + these fragments contain the TLS header and cipher text
> + TLS APP payload; on output these fragments contain the
> + TLS header and plain text TLS APP payload.
> + @param[in] FragmentCount Number of fragment.
> + @param[in] CryptMode Crypt mode.
> +
> + @retval EFI_SUCCESS The operation completed successfully.
> + @retval EFI_INVALID_PARAMETER One or more of the following
> conditions is TRUE:
> + This is NULL.
> + FragmentTable is NULL.
> + FragmentCount is NULL.
> + CryptoMode is invalid.
> + @retval EFI_NOT_READY Current TLS session state is NOT
> + EfiTlsSessionDataTransferring.
> + @retval EFI_ABORTED Something wrong decryption the message.
> TLS session
> + status will become EfiTlsSessionError. The caller need
> + call BuildResponsePacket() to generate Error Alert
> + message and send it out.
> + @retval EFI_OUT_OF_RESOURCES No enough resource to finish the
> operation.
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsProcessPacket (
> + IN EFI_TLS_PROTOCOL *This,
> + IN OUT EFI_TLS_FRAGMENT_DATA **FragmentTable,
> + IN UINT32 *FragmentCount,
> + IN EFI_TLS_CRYPT_MODE CryptMode
> + )
> +{
> + EFI_STATUS Status;
> + TLS_INSTANCE *Instance;
> +
> + EFI_TPL OldTpl;
> +
> + Status = EFI_SUCCESS;
> +
> + if (This == NULL || FragmentTable == NULL || FragmentCount == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
> +
> + Instance = TLS_INSTANCE_FROM_PROTOCOL_THIS (This);
> +
> + if (Instance->TlsSessionState != EfiTlsSessionDataTransferring) {
> + Status = EFI_NOT_READY;
> + goto ON_EXIT;
> + }
> +
> + //
> + // Packet sent or received may have multiply TLS record
> message(Application data type).
> + // So,on input these fragments contain the TLS header and TLS APP
> payload;
> + // on output these fragments also contain the TLS header and TLS APP
> payload.
> + //
> + switch (CryptMode) {
> + case EfiTlsEncrypt:
> + Status = TlsEcryptPacket (Instance, FragmentTable, FragmentCount);
> + break;
> + case EfiTlsDecrypt:
> + Status = TlsDecryptPacket (Instance, FragmentTable, FragmentCount);
> + break;
> + default:
> + return EFI_INVALID_PARAMETER;
> + }
> +
> +ON_EXIT:
> + gBS->RestoreTPL (OldTpl);
> + return Status;
> +}
> --
> 1.9.5.msysgit.1
next prev parent reply other threads:[~2016-12-15 7:24 UTC|newest]
Thread overview: 37+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-12-14 7:34 [Patch 00/10] Sync staging/HTTPS-TLS feature into edk2 master Jiaxin Wu
2016-12-14 7:34 ` [Patch 01/10] MdePkg: Add TLS related protocol definition Jiaxin Wu
2016-12-14 8:36 ` Long, Qin
2016-12-14 8:39 ` Wu, Jiaxin
2016-12-15 8:34 ` Ye, Ting
2016-12-14 8:43 ` Fu, Siyuan
2016-12-14 7:34 ` [Patch 02/10] MdePkg: Add a header to standardize TLS definitions Jiaxin Wu
2016-12-14 8:42 ` Long, Qin
2016-12-14 8:43 ` Fu, Siyuan
2016-12-15 8:35 ` Ye, Ting
2016-12-14 7:34 ` [Patch 03/10] CryptoPkg: Enable ssl build in OpensslLib directly Jiaxin Wu
2016-12-15 8:37 ` Ye, Ting
2016-12-14 7:34 ` [Patch 04/10] CryptoPkg: Add new TlsLib library Jiaxin Wu
2016-12-16 2:10 ` Ye, Ting
2016-12-16 2:51 ` Wu, Jiaxin
2016-12-14 7:34 ` [Patch 05/10] NetworkPkg/TlsDxe: TlsDxe driver implementation over OpenSSL Jiaxin Wu
2016-12-14 8:41 ` Fu, Siyuan
2016-12-15 7:24 ` Wu, Jiaxin [this message]
2016-12-14 7:34 ` [Patch 06/10] NetworkPkg/TlsAuthConfigDxe: Provide the UI to support TLS auth configuration Jiaxin Wu
2016-12-15 2:22 ` Fu, Siyuan
2016-12-22 2:52 ` Ye, Ting
2016-12-22 3:13 ` Wu, Jiaxin
2016-12-14 7:34 ` [Patch 07/10] NetworkPkg/HttpDxe: HTTPS support over IPv4 and IPv6 Jiaxin Wu
2016-12-15 2:39 ` Fu, Siyuan
2016-12-15 7:14 ` Wu, Jiaxin
2016-12-22 7:33 ` Ye, Ting
2016-12-22 8:30 ` Wu, Jiaxin
2016-12-14 7:34 ` [Patch 08/10] NetworkPkg/NetworkPkg.dsc: Enable TlsDxe and TlsAuthConfigDxe module Jiaxin Wu
2016-12-15 2:39 ` Fu, Siyuan
2016-12-22 7:37 ` Ye, Ting
2016-12-14 7:34 ` [Patch 09/10] Nt32Pkg/Nt32Pkg.dsc: Remove the flag for OpensslLib and BaseCryptLib Jiaxin Wu
2016-12-14 7:56 ` Ni, Ruiyu
2016-12-15 8:25 ` Long, Qin
2016-12-22 7:39 ` Ye, Ting
2016-12-14 7:34 ` [Patch 10/10] Nt32Pkg: Enable HTTPS boot feature for Nt32 platform Jiaxin Wu
2016-12-14 7:44 ` Yao, Jiewen
2016-12-14 7:46 ` Wu, Jiaxin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=895558F6EA4E3B41AC93A00D163B72741627F566@SHSMSX103.ccr.corp.intel.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox