summaryrefslogtreecommitdiffstats
path: root/NetworkPkg/TlsDxe/TlsDriver.c
diff options
context:
space:
mode:
Diffstat (limited to 'NetworkPkg/TlsDxe/TlsDriver.c')
-rw-r--r--NetworkPkg/TlsDxe/TlsDriver.c993
1 files changed, 497 insertions, 496 deletions
diff --git a/NetworkPkg/TlsDxe/TlsDriver.c b/NetworkPkg/TlsDxe/TlsDriver.c
index 38bf5993ce..29bc966c3e 100644
--- a/NetworkPkg/TlsDxe/TlsDriver.c
+++ b/NetworkPkg/TlsDxe/TlsDriver.c
@@ -1,496 +1,497 @@
-/** @file
- The Driver Binding and Service Binding Protocol for TlsDxe driver.
-
- Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
-
- This program and the accompanying materials
- are licensed and made available under the terms and conditions of the BSD License
- which accompanies this distribution. The full text of the license may be found at
- http://opensource.org/licenses/bsd-license.php.
-
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-**/
-
-#include "TlsImpl.h"
-
-EFI_SERVICE_BINDING_PROTOCOL mTlsServiceBinding = {
- TlsServiceBindingCreateChild,
- TlsServiceBindingDestroyChild
-};
-
-/**
- Release all the resources used by the TLS instance.
-
- @param[in] Instance The TLS instance data.
-
-**/
-VOID
-TlsCleanInstance (
- IN TLS_INSTANCE *Instance
- )
-{
- if (Instance != NULL) {
- if (Instance->TlsConn != NULL) {
- TlsFree (Instance->TlsConn);
- }
-
- FreePool (Instance);
- }
-}
-
-/**
- Create the TLS instance and initialize it.
-
- @param[in] Service The pointer to the TLS service.
- @param[out] Instance The pointer to the TLS instance.
-
- @retval EFI_OUT_OF_RESOURCES Failed to allocate resources.
- @retval EFI_SUCCESS The TLS instance is created.
-
-**/
-EFI_STATUS
-TlsCreateInstance (
- IN TLS_SERVICE *Service,
- OUT TLS_INSTANCE **Instance
- )
-{
- TLS_INSTANCE *TlsInstance;
-
- *Instance = NULL;
-
- TlsInstance = AllocateZeroPool (sizeof (TLS_INSTANCE));
- if (TlsInstance == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- TlsInstance->Signature = TLS_INSTANCE_SIGNATURE;
- InitializeListHead (&TlsInstance->Link);
- TlsInstance->InDestroy = FALSE;
- TlsInstance->Service = Service;
-
- CopyMem (&TlsInstance->Tls, &mTlsProtocol, sizeof (TlsInstance->Tls));
- CopyMem (&TlsInstance->TlsConfig, &mTlsConfigurationProtocol, sizeof (TlsInstance->TlsConfig));
-
- TlsInstance->TlsSessionState = EfiTlsSessionNotStarted;
-
- *Instance = TlsInstance;
-
- return EFI_SUCCESS;
-}
-
-/**
- Release all the resources used by the TLS service binding instance.
-
- @param[in] Service The TLS service data.
-
-**/
-VOID
-TlsCleanService (
- IN TLS_SERVICE *Service
- )
-{
- if (Service != NULL) {
- if (Service->TlsCtx != NULL) {
- TlsCtxFree (Service->TlsCtx);
- }
-
- FreePool (Service);
- }
-}
-
-/**
- Create then initialize a TLS service.
-
- @param[in] Image ImageHandle of the TLS driver
- @param[out] Service The service for TLS driver
-
- @retval EFI_OUT_OF_RESOURCES Failed to allocate resource to create the service.
- @retval EFI_SUCCESS The service is created for the driver.
-
-**/
-EFI_STATUS
-TlsCreateService (
- IN EFI_HANDLE Image,
- OUT TLS_SERVICE **Service
- )
-{
- TLS_SERVICE *TlsService;
-
- ASSERT (Service != NULL);
-
- *Service = NULL;
-
- //
- // Allocate a TLS Service Data
- //
- TlsService = AllocateZeroPool (sizeof (TLS_SERVICE));
- if (TlsService == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- //
- // Initialize TLS Service Data
- //
- TlsService->Signature = TLS_SERVICE_SIGNATURE;
- CopyMem (&TlsService->ServiceBinding, &mTlsServiceBinding, sizeof (TlsService->ServiceBinding));
- TlsService->TlsChildrenNum = 0;
- InitializeListHead (&TlsService->TlsChildrenList);
- TlsService->ImageHandle = Image;
-
- *Service = TlsService;
-
- return EFI_SUCCESS;
-}
-
-/**
- Unloads an image.
-
- @param[in] ImageHandle Handle that identifies the image to be unloaded.
-
- @retval EFI_SUCCESS The image has been unloaded.
- @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle.
-
-**/
-EFI_STATUS
-EFIAPI
-TlsUnload (
- IN EFI_HANDLE ImageHandle
- )
-{
- EFI_STATUS Status;
- UINTN HandleNum;
- EFI_HANDLE *HandleBuffer;
- UINT32 Index;
- EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
- TLS_SERVICE *TlsService;
-
- HandleBuffer = NULL;
- ServiceBinding = NULL;
- TlsService = NULL;
-
- //
- // Locate all the handles with Tls service binding protocol.
- //
- Status = gBS->LocateHandleBuffer (
- ByProtocol,
- &gEfiTlsServiceBindingProtocolGuid,
- NULL,
- &HandleNum,
- &HandleBuffer
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- for (Index = 0; Index < HandleNum; Index++) {
- //
- // Firstly, find ServiceBinding interface
- //
- Status = gBS->OpenProtocol (
- HandleBuffer[Index],
- &gEfiTlsServiceBindingProtocolGuid,
- (VOID **) &ServiceBinding,
- ImageHandle,
- NULL,
- EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- TlsService = TLS_SERVICE_FROM_THIS (ServiceBinding);
-
- //
- // Then, uninstall ServiceBinding interface
- //
- Status = gBS->UninstallMultipleProtocolInterfaces (
- HandleBuffer[Index],
- &gEfiTlsServiceBindingProtocolGuid, ServiceBinding,
- NULL
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- TlsCleanService (TlsService);
- }
-
- if (HandleBuffer != NULL) {
- FreePool (HandleBuffer);
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- This is the declaration of an EFI image entry point. This entry point is
- the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
- both device drivers and bus drivers.
-
- @param ImageHandle The firmware allocated handle for the UEFI image.
- @param SystemTable A pointer to the EFI System Table.
-
- @retval EFI_SUCCESS The operation completed successfully.
- @retval Others An unexpected error occurred.
-**/
-EFI_STATUS
-EFIAPI
-TlsDriverEntryPoint (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- EFI_STATUS Status;
-
- TLS_SERVICE *TlsService;
-
- //
- // Create TLS Service
- //
- Status = TlsCreateService (ImageHandle, &TlsService);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- ASSERT (TlsService != NULL);
-
- //
- // Initializes the OpenSSL library.
- //
- TlsInitialize ();
-
- //
- // Create a new SSL_CTX object as framework to establish TLS/SSL enabled
- // connections. TLS 1.0 is used as the default version.
- //
- TlsService->TlsCtx = TlsCtxNew (TLS10_PROTOCOL_VERSION_MAJOR, TLS10_PROTOCOL_VERSION_MINOR);
- if (TlsService->TlsCtx == NULL) {
- FreePool (TlsService);
- return EFI_ABORTED;
- }
-
- //
- // Install the TlsServiceBinding Protocol onto Handle
- //
- Status = gBS->InstallMultipleProtocolInterfaces (
- &TlsService->Handle,
- &gEfiTlsServiceBindingProtocolGuid,
- &TlsService->ServiceBinding,
- NULL
- );
- if (EFI_ERROR (Status)) {
- goto ON_CLEAN_SERVICE;
- }
-
- return Status;
-
-ON_CLEAN_SERVICE:
- TlsCleanService (TlsService);
-
- return Status;
-}
-
-/**
- Creates a child handle and installs a protocol.
-
- The CreateChild() function installs a protocol on ChildHandle.
- If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle.
- If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle.
-
- @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
- @param[in] ChildHandle Pointer to the handle of the child to create. If it is NULL,
- then a new handle is created. If it is a pointer to an existing UEFI handle,
- then the protocol is added to the existing UEFI handle.
-
- @retval EFI_SUCCES The protocol was added to ChildHandle.
- @retval EFI_INVALID_PARAMETER ChildHandle is NULL.
- @retval EFI_OUT_OF_RESOURCES There are not enough resources available to create
- the child.
- @retval other The child handle was not created.
-
-**/
-EFI_STATUS
-EFIAPI
-TlsServiceBindingCreateChild (
- IN EFI_SERVICE_BINDING_PROTOCOL *This,
- IN EFI_HANDLE *ChildHandle
- )
-{
- TLS_SERVICE *TlsService;
- TLS_INSTANCE *TlsInstance;
- EFI_STATUS Status;
- EFI_TPL OldTpl;
-
- if ((This == NULL) || (ChildHandle == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
-
- TlsService = TLS_SERVICE_FROM_THIS (This);
-
- Status = TlsCreateInstance (TlsService, &TlsInstance);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- ASSERT (TlsInstance != NULL);
-
- //
- // Create a new TLS connection object.
- //
- TlsInstance->TlsConn = TlsNew (TlsService->TlsCtx);
- if (TlsInstance->TlsConn == NULL) {
- Status = EFI_ABORTED;
- goto ON_ERROR;
- }
-
- //
- // Set default ConnectionEnd to EfiTlsClient
- //
- Status = TlsSetConnectionEnd (TlsInstance->TlsConn, EfiTlsClient);
- if (EFI_ERROR (Status)) {
- goto ON_ERROR;
- }
-
- //
- // Install TLS protocol and configuration protocol onto ChildHandle
- //
- Status = gBS->InstallMultipleProtocolInterfaces (
- ChildHandle,
- &gEfiTlsProtocolGuid,
- &TlsInstance->Tls,
- &gEfiTlsConfigurationProtocolGuid,
- &TlsInstance->TlsConfig,
- NULL
- );
- if (EFI_ERROR (Status)) {
- goto ON_ERROR;
- }
-
- TlsInstance->ChildHandle = *ChildHandle;
-
- //
- // Add it to the TLS service's child list.
- //
- OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
-
- InsertTailList (&TlsService->TlsChildrenList, &TlsInstance->Link);
- TlsService->TlsChildrenNum++;
-
- gBS->RestoreTPL (OldTpl);
-
- return EFI_SUCCESS;
-
-ON_ERROR:
- TlsCleanInstance (TlsInstance);
- return Status;
-}
-
-/**
- Destroys a child handle with a protocol installed on it.
-
- The DestroyChild() function does the opposite of CreateChild(). It removes a protocol
- that was installed by CreateChild() from ChildHandle. If the removed protocol is the
- last protocol on ChildHandle, then ChildHandle is destroyed.
-
- @param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
- @param ChildHandle Handle of the child to destroy.
-
- @retval EFI_SUCCES The protocol was removed from ChildHandle.
- @retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is being removed.
- @retval EFI_INVALID_PARAMETER Child handle is NULL.
- @retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle
- because its services are being used.
- @retval other The child handle was not destroyed.
-
-**/
-EFI_STATUS
-EFIAPI
-TlsServiceBindingDestroyChild (
- IN EFI_SERVICE_BINDING_PROTOCOL *This,
- IN EFI_HANDLE ChildHandle
- )
-{
- TLS_SERVICE *TlsService;
- TLS_INSTANCE *TlsInstance;
-
- EFI_TLS_PROTOCOL *Tls;
- EFI_TLS_CONFIGURATION_PROTOCOL *TlsConfig;
- EFI_STATUS Status;
- EFI_TPL OldTpl;
-
- if ((This == NULL) || (ChildHandle == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
-
- TlsService = TLS_SERVICE_FROM_THIS (This);
-
- //
- // Find TLS protocol interface installed in ChildHandle
- //
- Status = gBS->OpenProtocol (
- ChildHandle,
- &gEfiTlsProtocolGuid,
- (VOID **) &Tls,
- TlsService->ImageHandle,
- NULL,
- EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- //
- // Find TLS configuration protocol interface installed in ChildHandle
- //
- Status = gBS->OpenProtocol (
- ChildHandle,
- &gEfiTlsConfigurationProtocolGuid,
- (VOID **) &TlsConfig,
- TlsService->ImageHandle,
- NULL,
- EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- TlsInstance = TLS_INSTANCE_FROM_PROTOCOL (Tls);
-
- if (TlsInstance->Service != TlsService) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (TlsInstance->InDestroy) {
- return EFI_SUCCESS;
- }
-
- OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
-
- TlsInstance->InDestroy = TRUE;
-
- //
- // Uninstall the TLS protocol and TLS Configuration Protocol interface installed in ChildHandle.
- //
- Status = gBS->UninstallMultipleProtocolInterfaces (
- ChildHandle,
- &gEfiTlsProtocolGuid,
- Tls,
- &gEfiTlsConfigurationProtocolGuid,
- TlsConfig,
- NULL
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- RemoveEntryList (&TlsInstance->Link);
- TlsService->TlsChildrenNum--;
-
- gBS->RestoreTPL (OldTpl);
-
- TlsCleanInstance (TlsInstance);
-
- return EFI_SUCCESS;
-}
+/** @file
+ The Driver Binding and Service Binding Protocol for TlsDxe driver.
+
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "TlsImpl.h"
+
+EFI_SERVICE_BINDING_PROTOCOL mTlsServiceBinding = {
+ TlsServiceBindingCreateChild,
+ TlsServiceBindingDestroyChild
+};
+
+/**
+ Release all the resources used by the TLS instance.
+
+ @param[in] Instance The TLS instance data.
+
+**/
+VOID
+TlsCleanInstance (
+ IN TLS_INSTANCE *Instance
+ )
+{
+ if (Instance != NULL) {
+ if (Instance->TlsConn != NULL) {
+ TlsFree (Instance->TlsConn);
+ }
+
+ FreePool (Instance);
+ }
+}
+
+/**
+ Create the TLS instance and initialize it.
+
+ @param[in] Service The pointer to the TLS service.
+ @param[out] Instance The pointer to the TLS instance.
+
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate resources.
+ @retval EFI_SUCCESS The TLS instance is created.
+
+**/
+EFI_STATUS
+TlsCreateInstance (
+ IN TLS_SERVICE *Service,
+ OUT TLS_INSTANCE **Instance
+ )
+{
+ TLS_INSTANCE *TlsInstance;
+
+ *Instance = NULL;
+
+ TlsInstance = AllocateZeroPool (sizeof (TLS_INSTANCE));
+ if (TlsInstance == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ TlsInstance->Signature = TLS_INSTANCE_SIGNATURE;
+ InitializeListHead (&TlsInstance->Link);
+ TlsInstance->InDestroy = FALSE;
+ TlsInstance->Service = Service;
+
+ CopyMem (&TlsInstance->Tls, &mTlsProtocol, sizeof (TlsInstance->Tls));
+ CopyMem (&TlsInstance->TlsConfig, &mTlsConfigurationProtocol, sizeof (TlsInstance->TlsConfig));
+
+ TlsInstance->TlsSessionState = EfiTlsSessionNotStarted;
+
+ *Instance = TlsInstance;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Release all the resources used by the TLS service binding instance.
+
+ @param[in] Service The TLS service data.
+
+**/
+VOID
+TlsCleanService (
+ IN TLS_SERVICE *Service
+ )
+{
+ if (Service != NULL) {
+ if (Service->TlsCtx != NULL) {
+ TlsCtxFree (Service->TlsCtx);
+ }
+
+ FreePool (Service);
+ }
+}
+
+/**
+ Create then initialize a TLS service.
+
+ @param[in] Image ImageHandle of the TLS driver
+ @param[out] Service The service for TLS driver
+
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate resource to create the service.
+ @retval EFI_SUCCESS The service is created for the driver.
+
+**/
+EFI_STATUS
+TlsCreateService (
+ IN EFI_HANDLE Image,
+ OUT TLS_SERVICE **Service
+ )
+{
+ TLS_SERVICE *TlsService;
+
+ ASSERT (Service != NULL);
+
+ *Service = NULL;
+
+ //
+ // Allocate a TLS Service Data
+ //
+ TlsService = AllocateZeroPool (sizeof (TLS_SERVICE));
+ if (TlsService == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Initialize TLS Service Data
+ //
+ TlsService->Signature = TLS_SERVICE_SIGNATURE;
+ CopyMem (&TlsService->ServiceBinding, &mTlsServiceBinding, sizeof (TlsService->ServiceBinding));
+ TlsService->TlsChildrenNum = 0;
+ InitializeListHead (&TlsService->TlsChildrenList);
+ TlsService->ImageHandle = Image;
+
+ *Service = TlsService;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Unloads an image.
+
+ @param[in] ImageHandle Handle that identifies the image to be unloaded.
+
+ @retval EFI_SUCCESS The image has been unloaded.
+ @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsUnload (
+ IN EFI_HANDLE ImageHandle
+ )
+{
+ EFI_STATUS Status;
+ UINTN HandleNum;
+ EFI_HANDLE *HandleBuffer;
+ UINT32 Index;
+ EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
+ TLS_SERVICE *TlsService;
+
+ HandleBuffer = NULL;
+ ServiceBinding = NULL;
+ TlsService = NULL;
+
+ //
+ // Locate all the handles with Tls service binding protocol.
+ //
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiTlsServiceBindingProtocolGuid,
+ NULL,
+ &HandleNum,
+ &HandleBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ for (Index = 0; Index < HandleNum; Index++) {
+ //
+ // Firstly, find ServiceBinding interface
+ //
+ Status = gBS->OpenProtocol (
+ HandleBuffer[Index],
+ &gEfiTlsServiceBindingProtocolGuid,
+ (VOID **) &ServiceBinding,
+ ImageHandle,
+ NULL,
+ EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ TlsService = TLS_SERVICE_FROM_THIS (ServiceBinding);
+
+ //
+ // Then, uninstall ServiceBinding interface
+ //
+ Status = gBS->UninstallMultipleProtocolInterfaces (
+ HandleBuffer[Index],
+ &gEfiTlsServiceBindingProtocolGuid, ServiceBinding,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ TlsCleanService (TlsService);
+ }
+
+ if (HandleBuffer != NULL) {
+ FreePool (HandleBuffer);
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This is the declaration of an EFI image entry point. This entry point is
+ the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
+ both device drivers and bus drivers.
+
+ @param ImageHandle The firmware allocated handle for the UEFI image.
+ @param SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @retval Others An unexpected error occurred.
+**/
+EFI_STATUS
+EFIAPI
+TlsDriverEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ TLS_SERVICE *TlsService;
+
+ //
+ // Create TLS Service
+ //
+ Status = TlsCreateService (ImageHandle, &TlsService);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ ASSERT (TlsService != NULL);
+
+ //
+ // Initializes the OpenSSL library.
+ //
+ TlsInitialize ();
+
+ //
+ // Create a new SSL_CTX object as framework to establish TLS/SSL enabled
+ // connections. TLS 1.0 is used as the default version.
+ //
+ TlsService->TlsCtx = TlsCtxNew (TLS10_PROTOCOL_VERSION_MAJOR, TLS10_PROTOCOL_VERSION_MINOR);
+ if (TlsService->TlsCtx == NULL) {
+ FreePool (TlsService);
+ return EFI_ABORTED;
+ }
+
+ //
+ // Install the TlsServiceBinding Protocol onto Handle
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &TlsService->Handle,
+ &gEfiTlsServiceBindingProtocolGuid,
+ &TlsService->ServiceBinding,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_CLEAN_SERVICE;
+ }
+
+ return Status;
+
+ON_CLEAN_SERVICE:
+ TlsCleanService (TlsService);
+
+ return Status;
+}
+
+/**
+ Creates a child handle and installs a protocol.
+
+ The CreateChild() function installs a protocol on ChildHandle.
+ If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle.
+ If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle.
+
+ @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
+ @param[in] ChildHandle Pointer to the handle of the child to create. If it is NULL,
+ then a new handle is created. If it is a pointer to an existing UEFI handle,
+ then the protocol is added to the existing UEFI handle.
+
+ @retval EFI_SUCCES The protocol was added to ChildHandle.
+ @retval EFI_INVALID_PARAMETER ChildHandle is NULL.
+ @retval EFI_OUT_OF_RESOURCES There are not enough resources available to create
+ the child.
+ @retval other The child handle was not created.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsServiceBindingCreateChild (
+ IN EFI_SERVICE_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE *ChildHandle
+ )
+{
+ TLS_SERVICE *TlsService;
+ TLS_INSTANCE *TlsInstance;
+ EFI_STATUS Status;
+ EFI_TPL OldTpl;
+
+ if ((This == NULL) || (ChildHandle == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ TlsService = TLS_SERVICE_FROM_THIS (This);
+
+ Status = TlsCreateInstance (TlsService, &TlsInstance);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ ASSERT (TlsInstance != NULL);
+
+ //
+ // Create a new TLS connection object.
+ //
+ TlsInstance->TlsConn = TlsNew (TlsService->TlsCtx);
+ if (TlsInstance->TlsConn == NULL) {
+ Status = EFI_ABORTED;
+ goto ON_ERROR;
+ }
+
+ //
+ // Set default ConnectionEnd to EfiTlsClient
+ //
+ Status = TlsSetConnectionEnd (TlsInstance->TlsConn, EfiTlsClient);
+ if (EFI_ERROR (Status)) {
+ goto ON_ERROR;
+ }
+
+ //
+ // Install TLS protocol and configuration protocol onto ChildHandle
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ ChildHandle,
+ &gEfiTlsProtocolGuid,
+ &TlsInstance->Tls,
+ &gEfiTlsConfigurationProtocolGuid,
+ &TlsInstance->TlsConfig,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_ERROR;
+ }
+
+ TlsInstance->ChildHandle = *ChildHandle;
+
+ //
+ // Add it to the TLS service's child list.
+ //
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+ InsertTailList (&TlsService->TlsChildrenList, &TlsInstance->Link);
+ TlsService->TlsChildrenNum++;
+
+ gBS->RestoreTPL (OldTpl);
+
+ return EFI_SUCCESS;
+
+ON_ERROR:
+ TlsCleanInstance (TlsInstance);
+ return Status;
+}
+
+/**
+ Destroys a child handle with a protocol installed on it.
+
+ The DestroyChild() function does the opposite of CreateChild(). It removes a protocol
+ that was installed by CreateChild() from ChildHandle. If the removed protocol is the
+ last protocol on ChildHandle, then ChildHandle is destroyed.
+
+ @param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
+ @param ChildHandle Handle of the child to destroy.
+
+ @retval EFI_SUCCES The protocol was removed from ChildHandle.
+ @retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is being removed.
+ @retval EFI_INVALID_PARAMETER Child handle is NULL.
+ @retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle
+ because its services are being used.
+ @retval other The child handle was not destroyed.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsServiceBindingDestroyChild (
+ IN EFI_SERVICE_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ChildHandle
+ )
+{
+ TLS_SERVICE *TlsService;
+ TLS_INSTANCE *TlsInstance;
+
+ EFI_TLS_PROTOCOL *Tls;
+ EFI_TLS_CONFIGURATION_PROTOCOL *TlsConfig;
+ EFI_STATUS Status;
+ EFI_TPL OldTpl;
+
+ if ((This == NULL) || (ChildHandle == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ TlsService = TLS_SERVICE_FROM_THIS (This);
+
+ //
+ // Find TLS protocol interface installed in ChildHandle
+ //
+ Status = gBS->OpenProtocol (
+ ChildHandle,
+ &gEfiTlsProtocolGuid,
+ (VOID **) &Tls,
+ TlsService->ImageHandle,
+ NULL,
+ EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Find TLS configuration protocol interface installed in ChildHandle
+ //
+ Status = gBS->OpenProtocol (
+ ChildHandle,
+ &gEfiTlsConfigurationProtocolGuid,
+ (VOID **) &TlsConfig,
+ TlsService->ImageHandle,
+ NULL,
+ EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ TlsInstance = TLS_INSTANCE_FROM_PROTOCOL (Tls);
+
+ if (TlsInstance->Service != TlsService) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (TlsInstance->InDestroy) {
+ return EFI_SUCCESS;
+ }
+
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+ TlsInstance->InDestroy = TRUE;
+
+ //
+ // Uninstall the TLS protocol and TLS Configuration Protocol interface installed in ChildHandle.
+ //
+ Status = gBS->UninstallMultipleProtocolInterfaces (
+ ChildHandle,
+ &gEfiTlsProtocolGuid,
+ Tls,
+ &gEfiTlsConfigurationProtocolGuid,
+ TlsConfig,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ RemoveEntryList (&TlsInstance->Link);
+ TlsService->TlsChildrenNum--;
+
+ gBS->RestoreTPL (OldTpl);
+
+ TlsCleanInstance (TlsInstance);
+
+ return EFI_SUCCESS;
+}
+