/** @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;
}

