/** @file
  The Driver Binding and Service Binding Protocol for TlsDxe driver.

  Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#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_SUCCESS           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_SUCCESS           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;
}
