diff options
Diffstat (limited to 'src/VBox/Devices/EFI/Firmware/SecurityPkg/Hash2DxeCrypto/Driver.c')
-rw-r--r-- | src/VBox/Devices/EFI/Firmware/SecurityPkg/Hash2DxeCrypto/Driver.c | 236 |
1 files changed, 236 insertions, 0 deletions
diff --git a/src/VBox/Devices/EFI/Firmware/SecurityPkg/Hash2DxeCrypto/Driver.c b/src/VBox/Devices/EFI/Firmware/SecurityPkg/Hash2DxeCrypto/Driver.c new file mode 100644 index 00000000..06ae8121 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/SecurityPkg/Hash2DxeCrypto/Driver.c @@ -0,0 +1,236 @@ +/** @file + This is service binding for Hash driver. + +Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "Driver.h" + +EFI_SERVICE_BINDING_PROTOCOL mHash2ServiceBindingProtocol = { + Hash2ServiceBindingCreateChild, + Hash2ServiceBindingDestroyChild +}; + +/** + Creates a child handle with a set of I/O services. + + @param[in] This Protocol instance pointer. + @param[in, out] ChildHandle Pointer to the handle of the child to create. If + it is NULL, then a new handle is created. If + it is not NULL, then the I/O services are added + to the existing child 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 Others The child handle was not created. + +**/ +EFI_STATUS +EFIAPI +Hash2ServiceBindingCreateChild ( + IN EFI_SERVICE_BINDING_PROTOCOL *This, + IN OUT EFI_HANDLE *ChildHandle + ) +{ + EFI_STATUS Status; + HASH2_SERVICE_DATA *Hash2ServiceData; + HASH2_INSTANCE_DATA *Instance; + EFI_TPL OldTpl; + + if ((This == NULL) || (ChildHandle == NULL)) { + return EFI_INVALID_PARAMETER; + } + + Hash2ServiceData = HASH2_SERVICE_DATA_FROM_THIS (This); + + // + // Allocate buffer for the new instance. + // + Instance = AllocateZeroPool (sizeof (HASH2_INSTANCE_DATA)); + if (Instance == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + // + // Init the instance data. + // + Instance->Signature = HASH2_INSTANCE_DATA_SIGNATURE; + CopyMem (&Instance->Hash2Protocol, &mHash2Protocol, sizeof (Instance->Hash2Protocol)); + Instance->Hash2ServiceData = Hash2ServiceData; + + Status = gBS->InstallMultipleProtocolInterfaces ( + ChildHandle, + &gEfiHash2ProtocolGuid, + &Instance->Hash2Protocol, + NULL + ); + if (EFI_ERROR (Status)) { + FreePool (Instance); + return Status; + } + + Instance->Handle = *ChildHandle; + + // + // Add the child instance into ChildrenList. + // + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + + InsertTailList (&Hash2ServiceData->ChildrenList, &Instance->InstEntry); + + gBS->RestoreTPL (OldTpl); + + return Status; +} + + +/** + Destroys a child handle with a set of I/O services. + + 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[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL + instance. + @param[in] 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 ChildHandle is NULL. + @retval EFI_ACCESS_DENIED The protocol could not be removed from the + ChildHandle because its services are being + used. + @retval Others The child handle was not destroyed. + +**/ +EFI_STATUS +EFIAPI +Hash2ServiceBindingDestroyChild ( + IN EFI_SERVICE_BINDING_PROTOCOL *This, + IN EFI_HANDLE ChildHandle + ) +{ + EFI_STATUS Status; + HASH2_SERVICE_DATA *Hash2ServiceData; + EFI_HASH2_PROTOCOL *Hash2Protocol; + HASH2_INSTANCE_DATA *Instance; + EFI_TPL OldTpl; + LIST_ENTRY *Entry; + + if ((This == NULL) || (ChildHandle == NULL)) { + return EFI_INVALID_PARAMETER; + } + + Hash2ServiceData = HASH2_SERVICE_DATA_FROM_THIS (This); + + // + // Check if this ChildHandle is valid + // + Instance = NULL; + for(Entry = (&Hash2ServiceData->ChildrenList)->ForwardLink; Entry != (&Hash2ServiceData->ChildrenList); Entry = Entry->ForwardLink) { + Instance = HASH2_INSTANCE_DATA_FROM_LINK (Entry); + if (Instance->Handle == ChildHandle) { + break; + } else { + Instance = NULL; + } + } + if (Instance == NULL) { + DEBUG ((EFI_D_ERROR, "Hash2ServiceBindingDestroyChild - Invalid handle\n")); + return EFI_UNSUPPORTED; + } + + // + // Get HashProtocol + // + Status = gBS->HandleProtocol ( + ChildHandle, + &gEfiHash2ProtocolGuid, + (VOID **)&Hash2Protocol + ); + if (EFI_ERROR (Status)) { + return Status; + } + + ASSERT (Hash2Protocol == &Instance->Hash2Protocol); + + // + // Uninstall the Hash protocol. + // + Status = gBS->UninstallMultipleProtocolInterfaces ( + ChildHandle, + &gEfiHash2ProtocolGuid, + &Instance->Hash2Protocol, + NULL + ); + if (EFI_ERROR (Status)) { + return Status; + } + + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + + // + // Remove this instance from the ChildrenList. + // + RemoveEntryList (&Instance->InstEntry); + + gBS->RestoreTPL (OldTpl); + + FreePool (Instance); + + return Status; +} + +/** + The entry point for Hash driver which installs the service binding protocol. + + @param[in] ImageHandle The image handle of the driver. + @param[in] SystemTable The system table. + + @retval EFI_SUCCESS The service binding protocols is successfully installed. + @retval Others Other errors as indicated. + +**/ +EFI_STATUS +EFIAPI +Hash2DriverEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + HASH2_SERVICE_DATA *Hash2ServiceData; + + // + // Initialize the Hash Service Data. + // + Hash2ServiceData = AllocateZeroPool (sizeof (HASH2_SERVICE_DATA)); + if (Hash2ServiceData == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Hash2ServiceData->Signature = HASH2_SERVICE_DATA_SIGNATURE; + CopyMem (&Hash2ServiceData->ServiceBinding, &mHash2ServiceBindingProtocol, sizeof (EFI_SERVICE_BINDING_PROTOCOL)); + InitializeListHead (&Hash2ServiceData->ChildrenList); + + // + // Install the HASH Service Binding Protocol + // + Status = gBS->InstallMultipleProtocolInterfaces ( + &Hash2ServiceData->ServiceHandle, + &gEfiHash2ServiceBindingProtocolGuid, + &Hash2ServiceData->ServiceBinding, + NULL + ); + if (EFI_ERROR (Status)) { + FreePool (Hash2ServiceData); + } + + return Status; +} |