/** @file\r
Driver Binding Protocol for IPsec Driver.\r
\r
- Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.<BR>\r
\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
\r
**/\r
\r
-#include <Library/UdpIoLib.h>\r
+#include <Library/BaseCryptLib.h>\r
+\r
#include "IpSecConfigImpl.h"\r
+#include "IkeService.h"\r
#include "IpSecDebug.h"\r
\r
+/**\r
+ Test to see if this driver supports ControllerHandle. This is the worker function\r
+ for IpSec4(6)DriverbindingSupported.\r
+\r
+ @param[in] This Protocol instance pointer.\r
+ @param[in] ControllerHandle Handle of device to test.\r
+ @param[in] RemainingDevicePath Optional parameter used to pick a specific child\r
+ device to start.\r
+ @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6.\r
+ \r
+ @retval EFI_SUCCES This driver supports this device.\r
+ @retval EFI_ALREADY_STARTED This driver is already running on this device.\r
+ @retval other This driver does not support this device.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IpSecSupported (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL,\r
+ IN UINT8 IpVersion\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_GUID *UdpServiceBindingGuid;\r
+ \r
+ if (IpVersion == IP_VERSION_4) {\r
+ UdpServiceBindingGuid = &gEfiUdp4ServiceBindingProtocolGuid;\r
+ } else {\r
+ UdpServiceBindingGuid = &gEfiUdp6ServiceBindingProtocolGuid;\r
+ }\r
+\r
+ Status = gBS->OpenProtocol (\r
+ ControllerHandle,\r
+ UdpServiceBindingGuid,\r
+ NULL,\r
+ This->DriverBindingHandle,\r
+ ControllerHandle,\r
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Start this driver on ControllerHandle. This is the worker function\r
+ for IpSec4(6)DriverbindingStart.\r
+\r
+ @param[in] This Protocol instance pointer.\r
+ @param[in] ControllerHandle Handle of device to bind driver to.\r
+ @param[in] RemainingDevicePath Optional parameter used to pick a specific child\r
+ device to start.\r
+ @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6.\r
+\r
+ @retval EFI_SUCCES This driver is added to ControllerHandle\r
+ @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle\r
+ @retval EFI_DEVICE_ERROR The device could not be started due to a device error.\r
+ Currently not implemented.\r
+ @retval other This driver does not support this device\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IpSecStart (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL,\r
+ IN UINT8 IpVersion\r
+ )\r
+{\r
+ EFI_IPSEC2_PROTOCOL *IpSec;\r
+ EFI_STATUS Status;\r
+ IPSEC_PRIVATE_DATA *Private;\r
+\r
+ //\r
+ // Ipsec protocol should be installed when load image.\r
+ //\r
+ Status = gBS->LocateProtocol (&gEfiIpSec2ProtocolGuid, NULL, (VOID **) &IpSec);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Private = IPSEC_PRIVATE_DATA_FROM_IPSEC (IpSec);\r
+\r
+ if (IpVersion == IP_VERSION_4) {\r
+ //\r
+ // Try to open a udp4 io for input.\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ ControllerHandle,\r
+ &gEfiUdp4ServiceBindingProtocolGuid,\r
+ NULL,\r
+ This->DriverBindingHandle,\r
+ ControllerHandle,\r
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
+ );\r
+\r
+ if (!EFI_ERROR (Status)) {\r
+ Status = IkeOpenInputUdp4 (Private, ControllerHandle, This->DriverBindingHandle);\r
+ }\r
+ } else {\r
+ //\r
+ // Try to open a udp6 io for input.\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ ControllerHandle,\r
+ &gEfiUdp6ServiceBindingProtocolGuid,\r
+ NULL,\r
+ This->DriverBindingHandle,\r
+ ControllerHandle,\r
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
+ );\r
+\r
+ if (!EFI_ERROR (Status)) {\r
+ Status = IkeOpenInputUdp6 (Private, ControllerHandle, This->DriverBindingHandle);\r
+ }\r
+ }\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Stop this driver on ControllerHandle. This is the worker function\r
+ for IpSec4(6)DriverbindingStop.\r
+\r
+ @param[in] This Protocol instance pointer.\r
+ @param[in] ControllerHandle Handle of a device to stop the driver on.\r
+ @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If the number of\r
+ children is zero, stop the entire bus driver.\r
+ @param[in] ChildHandleBuffer List of Child Handles to Stop.\r
+ @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6.\r
+\r
+ @retval EFI_SUCCES This driver removed ControllerHandle.\r
+ @retval other This driver was not removed from this device.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IpSecStop (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN UINTN NumberOfChildren,\r
+ IN EFI_HANDLE *ChildHandleBuffer,\r
+ IN UINT8 IpVersion\r
+ )\r
+{\r
+ EFI_IPSEC2_PROTOCOL *IpSec;\r
+ EFI_STATUS Status;\r
+ IPSEC_PRIVATE_DATA *Private;\r
+ IKE_UDP_SERVICE *UdpSrv;\r
+ LIST_ENTRY *Entry;\r
+ LIST_ENTRY *Next;\r
+\r
+ //\r
+ // Locate ipsec protocol to get private data.\r
+ //\r
+ Status = gBS->LocateProtocol (&gEfiIpSec2ProtocolGuid, NULL, (VOID **) &IpSec);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Private = IPSEC_PRIVATE_DATA_FROM_IPSEC (IpSec);\r
+\r
+ //\r
+ // The SAs are shared by both IP4 and IP6 stack. So we skip the cleanup\r
+ // and leave the SAs unchanged if the other IP stack is still running.\r
+ //\r
+ if ((IpVersion == IP_VERSION_4 && Private->Udp6Num ==0) ||\r
+ (IpVersion == IP_VERSION_6 && Private->Udp4Num ==0)) {\r
+ IkeDeleteAllSas (Private, FALSE);\r
+ }\r
+\r
+ if (IpVersion == IP_VERSION_4) {\r
+ //\r
+ // If has udp4 io opened on the controller, close and free it.\r
+ //\r
+ NET_LIST_FOR_EACH_SAFE (Entry, Next, &Private->Udp4List) {\r
+\r
+ UdpSrv = IPSEC_UDP_SERVICE_FROM_LIST (Entry);\r
+ //\r
+ // Find the right udp service which installed on the appointed nic handle.\r
+ //\r
+ if (UdpSrv->Input != NULL && ControllerHandle == UdpSrv->Input->UdpHandle) {\r
+ UdpIoFreeIo (UdpSrv->Input);\r
+ UdpSrv->Input = NULL;\r
+ }\r
+\r
+ if (UdpSrv->Output != NULL && ControllerHandle == UdpSrv->Output->UdpHandle) {\r
+ UdpIoFreeIo (UdpSrv->Output);\r
+ UdpSrv->Output = NULL;\r
+ }\r
+\r
+ if (UdpSrv->Input == NULL && UdpSrv->Output == NULL) {\r
+ RemoveEntryList (&UdpSrv->List);\r
+ FreePool (UdpSrv);\r
+ ASSERT (Private->Udp4Num > 0);\r
+ Private->Udp4Num--;\r
+ }\r
+ }\r
+ } else {\r
+ //\r
+ // If has udp6 io opened on the controller, close and free it.\r
+ //\r
+ NET_LIST_FOR_EACH_SAFE (Entry, Next, &Private->Udp6List) {\r
+\r
+ UdpSrv = IPSEC_UDP_SERVICE_FROM_LIST (Entry);\r
+ //\r
+ // Find the right udp service which installed on the appointed nic handle.\r
+ //\r
+ if (UdpSrv->Input != NULL && ControllerHandle == UdpSrv->Input->UdpHandle) {\r
+ UdpIoFreeIo (UdpSrv->Input);\r
+ UdpSrv->Input = NULL;\r
+ }\r
+\r
+ if (UdpSrv->Output != NULL && ControllerHandle == UdpSrv->Output->UdpHandle) {\r
+ UdpIoFreeIo (UdpSrv->Output);\r
+ UdpSrv->Output = NULL;\r
+ }\r
+\r
+ if (UdpSrv->Input == NULL && UdpSrv->Output == NULL) {\r
+ RemoveEntryList (&UdpSrv->List);\r
+ FreePool (UdpSrv);\r
+ ASSERT (Private->Udp6Num > 0);\r
+ Private->Udp6Num--;\r
+ }\r
+ }\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
/**\r
Test to see if this driver supports ControllerHandle.\r
\r
**/\r
EFI_STATUS\r
EFIAPI\r
-IpSecDriverBindingSupported (\r
+IpSec4DriverBindingSupported (\r
IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
IN EFI_HANDLE ControllerHandle,\r
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
)\r
{\r
- //\r
- //TODO: Add Udp4Protocol and Udp6Protocol testing.\r
- //\r
- return EFI_UNSUPPORTED;\r
+ return IpSecSupported (\r
+ This,\r
+ ControllerHandle,\r
+ RemainingDevicePath,\r
+ IP_VERSION_4\r
+ );\r
}\r
\r
/**\r
**/\r
EFI_STATUS\r
EFIAPI\r
-IpSecDriverBindingStart (\r
+IpSec4DriverBindingStart (\r
IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
IN EFI_HANDLE ControllerHandle,\r
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
)\r
{\r
- //\r
- //TODO: Add Udp4Io and Udp6Io creation for the IKE.\r
- //\r
- return EFI_SUCCESS;\r
+ return IpSecStart (\r
+ This,\r
+ ControllerHandle,\r
+ RemainingDevicePath,\r
+ IP_VERSION_4\r
+ );\r
}\r
\r
/**\r
**/\r
EFI_STATUS\r
EFIAPI\r
-IpSecDriverBindingStop (\r
+IpSec4DriverBindingStop (\r
IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
IN EFI_HANDLE ControllerHandle,\r
IN UINTN NumberOfChildren,\r
IN EFI_HANDLE *ChildHandleBuffer\r
)\r
{\r
- //\r
- //TODO: Add UdpIo4 and UdpIo6 destruction when the Udp driver unload or stop.\r
- //\r
- return EFI_UNSUPPORTED;\r
+ return IpSecStop (\r
+ This,\r
+ ControllerHandle,\r
+ NumberOfChildren,\r
+ ChildHandleBuffer,\r
+ IP_VERSION_4\r
+ );\r
+}\r
+\r
+/**\r
+ Test to see if this driver supports ControllerHandle.\r
+\r
+ @param[in] This Protocol instance pointer.\r
+ @param[in] ControllerHandle Handle of device to test.\r
+ @param[in] RemainingDevicePath Optional parameter used to pick a specific child\r
+ device to start.\r
+\r
+ @retval EFI_SUCCES This driver supports this device.\r
+ @retval EFI_ALREADY_STARTED This driver is already running on this device.\r
+ @retval other This driver does not support this device.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IpSec6DriverBindingSupported (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
+ )\r
+{\r
+ return IpSecSupported (\r
+ This,\r
+ ControllerHandle,\r
+ RemainingDevicePath,\r
+ IP_VERSION_6\r
+ );\r
+}\r
+\r
+/**\r
+ Start this driver on ControllerHandle.\r
+\r
+ @param[in] This Protocol instance pointer.\r
+ @param[in] ControllerHandle Handle of device to bind driver to.\r
+ @param[in] RemainingDevicePath Optional parameter used to pick a specific child\r
+ device to start.\r
+\r
+ @retval EFI_SUCCES This driver is added to ControllerHandle\r
+ @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle\r
+ @retval EFI_DEVICE_ERROR The device could not be started due to a device error.\r
+ Currently not implemented.\r
+ @retval other This driver does not support this device\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IpSec6DriverBindingStart (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
+ )\r
+{\r
+ return IpSecStart (\r
+ This,\r
+ ControllerHandle,\r
+ RemainingDevicePath,\r
+ IP_VERSION_6\r
+ );\r
+}\r
+\r
+/**\r
+ Stop this driver on ControllerHandle.\r
+\r
+ @param[in] This Protocol instance pointer.\r
+ @param[in] ControllerHandle Handle of a device to stop the driver on.\r
+ @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If the number of\r
+ children is zero, stop the entire bus driver.\r
+ @param[in] ChildHandleBuffer List of Child Handles to Stop.\r
+\r
+ @retval EFI_SUCCES This driver removed ControllerHandle.\r
+ @retval other This driver was not removed from this device.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IpSec6DriverBindingStop (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN UINTN NumberOfChildren,\r
+ IN EFI_HANDLE *ChildHandleBuffer\r
+ )\r
+{\r
+ return IpSecStop (\r
+ This,\r
+ ControllerHandle,\r
+ NumberOfChildren,\r
+ ChildHandleBuffer,\r
+ IP_VERSION_6\r
+ );\r
}\r
\r
-EFI_DRIVER_BINDING_PROTOCOL gIpSecDriverBinding = {\r
- IpSecDriverBindingSupported,\r
- IpSecDriverBindingStart,\r
- IpSecDriverBindingStop,\r
+EFI_DRIVER_BINDING_PROTOCOL gIpSec4DriverBinding = {\r
+ IpSec4DriverBindingSupported,\r
+ IpSec4DriverBindingStart,\r
+ IpSec4DriverBindingStop,\r
+ 0xa,\r
+ NULL,\r
+ NULL\r
+};\r
+\r
+EFI_DRIVER_BINDING_PROTOCOL gIpSec6DriverBinding = {\r
+ IpSec6DriverBindingSupported,\r
+ IpSec6DriverBindingStart,\r
+ IpSec6DriverBindingStop,\r
0xa,\r
NULL,\r
NULL\r
)\r
{\r
IPSEC_PRIVATE_DATA *Private;\r
- UINT8 Value;\r
- EFI_STATUS Status;\r
-\r
- Private = (IPSEC_PRIVATE_DATA *) Context;\r
-\r
- //\r
- // Set the Status Variable\r
- //\r
- Value = IPSEC_STATUS_DISABLED;\r
- Status = gRT->SetVariable (\r
- IPSECCONFIG_STATUS_NAME,\r
- &gEfiIpSecConfigProtocolGuid,\r
- EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
- sizeof (Value),\r
- &Value\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- Private->IpSec.DisabledFlag = TRUE;\r
- }\r
-\r
+ Private = (IPSEC_PRIVATE_DATA *) Context;\r
+ Private->IsIPsecDisabling = TRUE;\r
+ IkeDeleteAllSas (Private, TRUE);\r
}\r
\r
/**\r
{\r
EFI_STATUS Status;\r
IPSEC_PRIVATE_DATA *Private;\r
- EFI_IPSEC_PROTOCOL *IpSec;\r
+ EFI_IPSEC2_PROTOCOL *IpSec;\r
\r
//\r
// Check whether ipsec protocol has already been installed.\r
//\r
- Status = gBS->LocateProtocol (&gEfiIpSecProtocolGuid, NULL, (VOID **) &IpSec);\r
+ Status = gBS->LocateProtocol (&gEfiIpSec2ProtocolGuid, NULL, (VOID **) &IpSec);\r
\r
if (!EFI_ERROR (Status)) {\r
DEBUG ((DEBUG_WARN, "_ModuleEntryPoint: IpSec has been already loaded\n"));\r
goto ON_EXIT;\r
}\r
//\r
- // Create disable event to cleanup all sa when ipsec disabled by user.\r
+ // Create disable event to cleanup all SA when ipsec disabled by user.\r
//\r
Status = gBS->CreateEvent (\r
EVT_NOTIFY_SIGNAL,\r
\r
Private->Signature = IPSEC_PRIVATE_DATA_SIGNATURE;\r
Private->ImageHandle = ImageHandle;\r
- CopyMem (&Private->IpSec, &mIpSecInstance, sizeof (EFI_IPSEC_PROTOCOL));\r
+ CopyMem (&Private->IpSec, &mIpSecInstance, sizeof (EFI_IPSEC2_PROTOCOL));\r
\r
//\r
// Initilize Private's members. Thess members is used for IKE.\r
InitializeListHead (&Private->Ikev2SessionList);\r
InitializeListHead (&Private->Ikev2EstablishedList);\r
\r
+ RandomSeed (NULL, 0);\r
//\r
// Initialize the ipsec config data and restore it from variable.\r
//\r
//\r
Status = gBS->InstallMultipleProtocolInterfaces (\r
&Private->Handle,\r
- &gEfiIpSecProtocolGuid,\r
+ &gEfiIpSec2ProtocolGuid,\r
&Private->IpSec,\r
NULL\r
);\r
Status = EfiLibInstallDriverBindingComponentName2 (\r
ImageHandle,\r
SystemTable,\r
- &gIpSecDriverBinding,\r
+ &gIpSec4DriverBinding,\r
ImageHandle,\r
&gIpSecComponentName,\r
&gIpSecComponentName2\r
);\r
if (EFI_ERROR (Status)) {\r
- goto ON_UNINSTALL_CONFIG;\r
+ goto ON_UNINSTALL_IPSEC;\r
+ }\r
+\r
+ Status = EfiLibInstallDriverBindingComponentName2 (\r
+ ImageHandle,\r
+ SystemTable,\r
+ &gIpSec6DriverBinding,\r
+ NULL,\r
+ &gIpSecComponentName,\r
+ &gIpSecComponentName2\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_UNINSTALL_IPSEC4_DB;\r
}\r
\r
return Status;\r
\r
+ON_UNINSTALL_IPSEC4_DB:\r
+ gBS->UninstallMultipleProtocolInterfaces (\r
+ ImageHandle,\r
+ &gEfiDriverBindingProtocolGuid,\r
+ &gIpSec4DriverBinding,\r
+ &gEfiComponentName2ProtocolGuid,\r
+ &gIpSecComponentName2,\r
+ &gEfiComponentNameProtocolGuid,\r
+ &gIpSecComponentName,\r
+ NULL\r
+ );\r
+\r
+ON_UNINSTALL_IPSEC:\r
+ gBS->UninstallProtocolInterface (\r
+ Private->Handle,\r
+ &gEfiIpSec2ProtocolGuid,\r
+ &Private->IpSec\r
+ );\r
ON_UNINSTALL_CONFIG:\r
gBS->UninstallProtocolInterface (\r
Private->Handle,\r