2 Driver Binding Protocol for IPsec Driver.
4 Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php.
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include <Library/BaseCryptLib.h>
18 #include "IpSecConfigImpl.h"
19 #include "IkeService.h"
20 #include "IpSecDebug.h"
23 Test to see if this driver supports ControllerHandle. This is the worker function
24 for IpSec4(6)DriverbindingSupported.
26 @param[in] This Protocol instance pointer.
27 @param[in] ControllerHandle Handle of device to test.
28 @param[in] RemainingDevicePath Optional parameter used to pick a specific child
30 @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6.
32 @retval EFI_SUCCES This driver supports this device.
33 @retval EFI_ALREADY_STARTED This driver is already running on this device.
34 @retval other This driver does not support this device.
40 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
41 IN EFI_HANDLE ControllerHandle
,
42 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
,
47 EFI_GUID
*UdpServiceBindingGuid
;
49 if (IpVersion
== IP_VERSION_4
) {
50 UdpServiceBindingGuid
= &gEfiUdp4ServiceBindingProtocolGuid
;
52 UdpServiceBindingGuid
= &gEfiUdp6ServiceBindingProtocolGuid
;
55 Status
= gBS
->OpenProtocol (
57 UdpServiceBindingGuid
,
59 This
->DriverBindingHandle
,
61 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
63 if (EFI_ERROR (Status
)) {
64 return EFI_UNSUPPORTED
;
70 Start this driver on ControllerHandle. This is the worker function
71 for IpSec4(6)DriverbindingStart.
73 @param[in] This Protocol instance pointer.
74 @param[in] ControllerHandle Handle of device to bind driver to.
75 @param[in] RemainingDevicePath Optional parameter used to pick a specific child
77 @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6.
79 @retval EFI_SUCCES This driver is added to ControllerHandle
80 @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle
81 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.
82 Currently not implemented.
83 @retval other This driver does not support this device
89 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
90 IN EFI_HANDLE ControllerHandle
,
91 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
,
95 EFI_IPSEC2_PROTOCOL
*IpSec
;
97 IPSEC_PRIVATE_DATA
*Private
;
100 // Ipsec protocol should be installed when load image.
102 Status
= gBS
->LocateProtocol (&gEfiIpSec2ProtocolGuid
, NULL
, (VOID
**) &IpSec
);
104 if (EFI_ERROR (Status
)) {
108 Private
= IPSEC_PRIVATE_DATA_FROM_IPSEC (IpSec
);
110 if (IpVersion
== IP_VERSION_4
) {
112 // Try to open a udp4 io for input.
114 Status
= gBS
->OpenProtocol (
116 &gEfiUdp4ServiceBindingProtocolGuid
,
118 This
->DriverBindingHandle
,
120 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
123 if (!EFI_ERROR (Status
)) {
124 Status
= IkeOpenInputUdp4 (Private
, ControllerHandle
, This
->DriverBindingHandle
);
128 // Try to open a udp6 io for input.
130 Status
= gBS
->OpenProtocol (
132 &gEfiUdp6ServiceBindingProtocolGuid
,
134 This
->DriverBindingHandle
,
136 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
139 if (!EFI_ERROR (Status
)) {
140 Status
= IkeOpenInputUdp6 (Private
, ControllerHandle
, This
->DriverBindingHandle
);
144 if (EFI_ERROR (Status
)) {
145 return EFI_DEVICE_ERROR
;
151 Stop this driver on ControllerHandle. This is the worker function
152 for IpSec4(6)DriverbindingStop.
154 @param[in] This Protocol instance pointer.
155 @param[in] ControllerHandle Handle of a device to stop the driver on.
156 @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If the number of
157 children is zero, stop the entire bus driver.
158 @param[in] ChildHandleBuffer List of Child Handles to Stop.
159 @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6.
161 @retval EFI_SUCCES This driver removed ControllerHandle.
162 @retval other This driver was not removed from this device.
168 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
169 IN EFI_HANDLE ControllerHandle
,
170 IN UINTN NumberOfChildren
,
171 IN EFI_HANDLE
*ChildHandleBuffer
,
175 EFI_IPSEC2_PROTOCOL
*IpSec
;
177 IPSEC_PRIVATE_DATA
*Private
;
178 IKE_UDP_SERVICE
*UdpSrv
;
183 // Locate ipsec protocol to get private data.
185 Status
= gBS
->LocateProtocol (&gEfiIpSec2ProtocolGuid
, NULL
, (VOID
**) &IpSec
);
187 if (EFI_ERROR (Status
)) {
191 Private
= IPSEC_PRIVATE_DATA_FROM_IPSEC (IpSec
);
194 // The SAs are shared by both IP4 and IP6 stack. So we skip the cleanup
195 // and leave the SAs unchanged if the other IP stack is still running.
197 if ((IpVersion
== IP_VERSION_4
&& Private
->Udp6Num
==0) ||
198 (IpVersion
== IP_VERSION_6
&& Private
->Udp4Num
==0)) {
199 IkeDeleteAllSas (Private
, FALSE
);
202 if (IpVersion
== IP_VERSION_4
) {
204 // If has udp4 io opened on the controller, close and free it.
206 NET_LIST_FOR_EACH_SAFE (Entry
, Next
, &Private
->Udp4List
) {
208 UdpSrv
= IPSEC_UDP_SERVICE_FROM_LIST (Entry
);
210 // Find the right udp service which installed on the appointed nic handle.
212 if (UdpSrv
->Input
!= NULL
&& ControllerHandle
== UdpSrv
->Input
->UdpHandle
) {
213 UdpIoFreeIo (UdpSrv
->Input
);
214 UdpSrv
->Input
= NULL
;
217 if (UdpSrv
->Output
!= NULL
&& ControllerHandle
== UdpSrv
->Output
->UdpHandle
) {
218 UdpIoFreeIo (UdpSrv
->Output
);
219 UdpSrv
->Output
= NULL
;
222 if (UdpSrv
->Input
== NULL
&& UdpSrv
->Output
== NULL
) {
223 RemoveEntryList (&UdpSrv
->List
);
225 ASSERT (Private
->Udp4Num
> 0);
231 // If has udp6 io opened on the controller, close and free it.
233 NET_LIST_FOR_EACH_SAFE (Entry
, Next
, &Private
->Udp6List
) {
235 UdpSrv
= IPSEC_UDP_SERVICE_FROM_LIST (Entry
);
237 // Find the right udp service which installed on the appointed nic handle.
239 if (UdpSrv
->Input
!= NULL
&& ControllerHandle
== UdpSrv
->Input
->UdpHandle
) {
240 UdpIoFreeIo (UdpSrv
->Input
);
241 UdpSrv
->Input
= NULL
;
244 if (UdpSrv
->Output
!= NULL
&& ControllerHandle
== UdpSrv
->Output
->UdpHandle
) {
245 UdpIoFreeIo (UdpSrv
->Output
);
246 UdpSrv
->Output
= NULL
;
249 if (UdpSrv
->Input
== NULL
&& UdpSrv
->Output
== NULL
) {
250 RemoveEntryList (&UdpSrv
->List
);
252 ASSERT (Private
->Udp6Num
> 0);
262 Test to see if this driver supports ControllerHandle.
264 @param[in] This Protocol instance pointer.
265 @param[in] ControllerHandle Handle of device to test.
266 @param[in] RemainingDevicePath Optional parameter used to pick a specific child
269 @retval EFI_SUCCES This driver supports this device.
270 @retval EFI_ALREADY_STARTED This driver is already running on this device.
271 @retval other This driver does not support this device.
276 IpSec4DriverBindingSupported (
277 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
278 IN EFI_HANDLE ControllerHandle
,
279 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
282 return IpSecSupported (
291 Start this driver on ControllerHandle.
293 @param[in] This Protocol instance pointer.
294 @param[in] ControllerHandle Handle of device to bind driver to.
295 @param[in] RemainingDevicePath Optional parameter used to pick a specific child
298 @retval EFI_SUCCES This driver is added to ControllerHandle
299 @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle
300 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.
301 Currently not implemented.
302 @retval other This driver does not support this device
307 IpSec4DriverBindingStart (
308 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
309 IN EFI_HANDLE ControllerHandle
,
310 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
322 Stop this driver on ControllerHandle.
324 @param[in] This Protocol instance pointer.
325 @param[in] ControllerHandle Handle of a device to stop the driver on.
326 @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If the number of
327 children is zero, stop the entire bus driver.
328 @param[in] ChildHandleBuffer List of Child Handles to Stop.
330 @retval EFI_SUCCES This driver removed ControllerHandle.
331 @retval other This driver was not removed from this device.
336 IpSec4DriverBindingStop (
337 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
338 IN EFI_HANDLE ControllerHandle
,
339 IN UINTN NumberOfChildren
,
340 IN EFI_HANDLE
*ChildHandleBuffer
353 Test to see if this driver supports ControllerHandle.
355 @param[in] This Protocol instance pointer.
356 @param[in] ControllerHandle Handle of device to test.
357 @param[in] RemainingDevicePath Optional parameter used to pick a specific child
360 @retval EFI_SUCCES This driver supports this device.
361 @retval EFI_ALREADY_STARTED This driver is already running on this device.
362 @retval other This driver does not support this device.
367 IpSec6DriverBindingSupported (
368 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
369 IN EFI_HANDLE ControllerHandle
,
370 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
373 return IpSecSupported (
382 Start this driver on ControllerHandle.
384 @param[in] This Protocol instance pointer.
385 @param[in] ControllerHandle Handle of device to bind driver to.
386 @param[in] RemainingDevicePath Optional parameter used to pick a specific child
389 @retval EFI_SUCCES This driver is added to ControllerHandle
390 @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle
391 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.
392 Currently not implemented.
393 @retval other This driver does not support this device
398 IpSec6DriverBindingStart (
399 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
400 IN EFI_HANDLE ControllerHandle
,
401 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
413 Stop this driver on ControllerHandle.
415 @param[in] This Protocol instance pointer.
416 @param[in] ControllerHandle Handle of a device to stop the driver on.
417 @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If the number of
418 children is zero, stop the entire bus driver.
419 @param[in] ChildHandleBuffer List of Child Handles to Stop.
421 @retval EFI_SUCCES This driver removed ControllerHandle.
422 @retval other This driver was not removed from this device.
427 IpSec6DriverBindingStop (
428 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
429 IN EFI_HANDLE ControllerHandle
,
430 IN UINTN NumberOfChildren
,
431 IN EFI_HANDLE
*ChildHandleBuffer
443 EFI_DRIVER_BINDING_PROTOCOL gIpSec4DriverBinding
= {
444 IpSec4DriverBindingSupported
,
445 IpSec4DriverBindingStart
,
446 IpSec4DriverBindingStop
,
452 EFI_DRIVER_BINDING_PROTOCOL gIpSec6DriverBinding
= {
453 IpSec6DriverBindingSupported
,
454 IpSec6DriverBindingStart
,
455 IpSec6DriverBindingStop
,
462 This is a callback function when the mIpSecInstance.DisabledEvent is signaled.
464 @param[in] Event Event whose notification function is being invoked.
465 @param[in] Context Pointer to the notification function's context.
475 IPSEC_PRIVATE_DATA
*Private
;
476 Private
= (IPSEC_PRIVATE_DATA
*) Context
;
477 Private
->IsIPsecDisabling
= TRUE
;
478 IkeDeleteAllSas (Private
, TRUE
);
482 This is the declaration of an EFI image entry point. This entry point is
483 the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers, including
484 both device drivers and bus drivers.
486 The entry point for IPsec driver which installs the driver binding,
487 component name protocol, IPsec Config protcolon, and IPsec protocol in
490 @param[in] ImageHandle The firmware allocated handle for the UEFI image.
491 @param[in] SystemTable A pointer to the EFI System Table.
493 @retval EFI_SUCCESS The operation completed successfully.
494 @retval EFI_ALREADY_STARTED The IPsec driver has been already loaded.
495 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
496 @retval Others The operation is failed.
501 IpSecDriverEntryPoint (
502 IN EFI_HANDLE ImageHandle
,
503 IN EFI_SYSTEM_TABLE
*SystemTable
507 IPSEC_PRIVATE_DATA
*Private
;
508 EFI_IPSEC2_PROTOCOL
*IpSec
;
511 // Check whether ipsec protocol has already been installed.
513 Status
= gBS
->LocateProtocol (&gEfiIpSec2ProtocolGuid
, NULL
, (VOID
**) &IpSec
);
515 if (!EFI_ERROR (Status
)) {
516 DEBUG ((DEBUG_WARN
, "_ModuleEntryPoint: IpSec has been already loaded\n"));
517 Status
= EFI_ALREADY_STARTED
;
521 Status
= gBS
->LocateProtocol (&gEfiDpcProtocolGuid
, NULL
, (VOID
**) &mDpc
);
523 if (EFI_ERROR (Status
)) {
524 DEBUG ((DEBUG_ERROR
, "_ModuleEntryPoint: Failed to locate EfiDpcProtocol\n"));
528 Private
= AllocateZeroPool (sizeof (IPSEC_PRIVATE_DATA
));
530 if (Private
== NULL
) {
531 DEBUG ((DEBUG_ERROR
, "_ModuleEntryPoint: Failed to allocate private data\n"));
532 Status
= EFI_OUT_OF_RESOURCES
;
536 // Create disable event to cleanup all SA when ipsec disabled by user.
538 Status
= gBS
->CreateEvent (
543 &mIpSecInstance
.DisabledEvent
545 if (EFI_ERROR (Status
)) {
546 DEBUG ((DEBUG_ERROR
, "_ModuleEntryPoint: Failed to create disable event\n"));
547 goto ON_FREE_PRIVATE
;
550 Private
->Signature
= IPSEC_PRIVATE_DATA_SIGNATURE
;
551 Private
->ImageHandle
= ImageHandle
;
552 CopyMem (&Private
->IpSec
, &mIpSecInstance
, sizeof (EFI_IPSEC2_PROTOCOL
));
555 // Initilize Private's members. Thess members is used for IKE.
557 InitializeListHead (&Private
->Udp4List
);
558 InitializeListHead (&Private
->Udp6List
);
559 InitializeListHead (&Private
->Ikev1SessionList
);
560 InitializeListHead (&Private
->Ikev1EstablishedList
);
561 InitializeListHead (&Private
->Ikev2SessionList
);
562 InitializeListHead (&Private
->Ikev2EstablishedList
);
564 RandomSeed (NULL
, 0);
566 // Initialize the ipsec config data and restore it from variable.
568 Status
= IpSecConfigInitialize (Private
);
569 if (EFI_ERROR (Status
)) {
570 DEBUG ((DEBUG_ERROR
, "_ModuleEntryPoint: Failed to initialize IpSecConfig\n"));
574 // Install ipsec protocol which is used by ip driver to process ipsec header.
576 Status
= gBS
->InstallMultipleProtocolInterfaces (
578 &gEfiIpSec2ProtocolGuid
,
582 if (EFI_ERROR (Status
)) {
583 goto ON_UNINSTALL_CONFIG
;
586 Status
= EfiLibInstallDriverBindingComponentName2 (
589 &gIpSec4DriverBinding
,
591 &gIpSecComponentName
,
592 &gIpSecComponentName2
594 if (EFI_ERROR (Status
)) {
595 goto ON_UNINSTALL_IPSEC
;
598 Status
= EfiLibInstallDriverBindingComponentName2 (
601 &gIpSec6DriverBinding
,
603 &gIpSecComponentName
,
604 &gIpSecComponentName2
606 if (EFI_ERROR (Status
)) {
607 goto ON_UNINSTALL_IPSEC4_DB
;
612 ON_UNINSTALL_IPSEC4_DB
:
613 gBS
->UninstallMultipleProtocolInterfaces (
615 &gEfiDriverBindingProtocolGuid
,
616 &gIpSec4DriverBinding
,
617 &gEfiComponentName2ProtocolGuid
,
618 &gIpSecComponentName2
,
619 &gEfiComponentNameProtocolGuid
,
620 &gIpSecComponentName
,
625 gBS
->UninstallProtocolInterface (
627 &gEfiIpSec2ProtocolGuid
,
631 gBS
->UninstallProtocolInterface (
633 &gEfiIpSecConfigProtocolGuid
,
634 &Private
->IpSecConfig
637 gBS
->CloseEvent (mIpSecInstance
.DisabledEvent
);
638 mIpSecInstance
.DisabledEvent
= NULL
;