2 Driver Binding Protocol for IPsec Driver.
4 Copyright (c) 2009 - 2015, 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
;
181 IKEV2_SA_SESSION
*Ikev2SaSession
;
184 // Locate ipsec protocol to get private data.
186 Status
= gBS
->LocateProtocol (&gEfiIpSec2ProtocolGuid
, NULL
, (VOID
**) &IpSec
);
188 if (EFI_ERROR (Status
)) {
192 Private
= IPSEC_PRIVATE_DATA_FROM_IPSEC (IpSec
);
195 // The SAs are shared by both IP4 and IP6 stack. So we skip the cleanup
196 // and leave the SAs unchanged if the other IP stack is still running.
198 if ((IpVersion
== IP_VERSION_4
&& Private
->Udp6Num
==0) ||
199 (IpVersion
== IP_VERSION_6
&& Private
->Udp4Num
==0)) {
201 // If IKEv2 SAs are under establishing, delete it directly.
203 if (!IsListEmpty (&Private
->Ikev2SessionList
)) {
204 NET_LIST_FOR_EACH_SAFE (Entry
, Next
, &Private
->Ikev2SessionList
) {
205 Ikev2SaSession
= IKEV2_SA_SESSION_BY_SESSION (Entry
);
206 RemoveEntryList (&Ikev2SaSession
->BySessionTable
);
207 Ikev2SaSessionFree (Ikev2SaSession
);
212 // Delete established IKEv2 SAs.
214 if (!IsListEmpty (&Private
->Ikev2EstablishedList
)) {
215 NET_LIST_FOR_EACH_SAFE (Entry
, Next
, &Private
->Ikev2EstablishedList
) {
216 Ikev2SaSession
= IKEV2_SA_SESSION_BY_SESSION (Entry
);
217 RemoveEntryList (&Ikev2SaSession
->BySessionTable
);
218 Ikev2SaSessionFree (Ikev2SaSession
);
223 if (IpVersion
== IP_VERSION_4
) {
225 // If has udp4 io opened on the controller, close and free it.
227 NET_LIST_FOR_EACH_SAFE (Entry
, Next
, &Private
->Udp4List
) {
229 UdpSrv
= IPSEC_UDP_SERVICE_FROM_LIST (Entry
);
231 // Find the right udp service which installed on the appointed nic handle.
233 if (UdpSrv
->Input
!= NULL
&& ControllerHandle
== UdpSrv
->Input
->UdpHandle
) {
234 UdpIoFreeIo (UdpSrv
->Input
);
235 UdpSrv
->Input
= NULL
;
238 if (UdpSrv
->Output
!= NULL
&& ControllerHandle
== UdpSrv
->Output
->UdpHandle
) {
239 UdpIoFreeIo (UdpSrv
->Output
);
240 UdpSrv
->Output
= NULL
;
243 if (UdpSrv
->Input
== NULL
&& UdpSrv
->Output
== NULL
) {
244 RemoveEntryList (&UdpSrv
->List
);
246 ASSERT (Private
->Udp4Num
> 0);
252 // If has udp6 io opened on the controller, close and free it.
254 NET_LIST_FOR_EACH_SAFE (Entry
, Next
, &Private
->Udp6List
) {
256 UdpSrv
= IPSEC_UDP_SERVICE_FROM_LIST (Entry
);
258 // Find the right udp service which installed on the appointed nic handle.
260 if (UdpSrv
->Input
!= NULL
&& ControllerHandle
== UdpSrv
->Input
->UdpHandle
) {
261 UdpIoFreeIo (UdpSrv
->Input
);
262 UdpSrv
->Input
= NULL
;
265 if (UdpSrv
->Output
!= NULL
&& ControllerHandle
== UdpSrv
->Output
->UdpHandle
) {
266 UdpIoFreeIo (UdpSrv
->Output
);
267 UdpSrv
->Output
= NULL
;
270 if (UdpSrv
->Input
== NULL
&& UdpSrv
->Output
== NULL
) {
271 RemoveEntryList (&UdpSrv
->List
);
273 ASSERT (Private
->Udp6Num
> 0);
283 Test to see if this driver supports ControllerHandle.
285 @param[in] This Protocol instance pointer.
286 @param[in] ControllerHandle Handle of device to test.
287 @param[in] RemainingDevicePath Optional parameter used to pick a specific child
290 @retval EFI_SUCCES This driver supports this device.
291 @retval EFI_ALREADY_STARTED This driver is already running on this device.
292 @retval other This driver does not support this device.
297 IpSec4DriverBindingSupported (
298 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
299 IN EFI_HANDLE ControllerHandle
,
300 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
303 return IpSecSupported (
312 Start this driver on ControllerHandle.
314 @param[in] This Protocol instance pointer.
315 @param[in] ControllerHandle Handle of device to bind driver to.
316 @param[in] RemainingDevicePath Optional parameter used to pick a specific child
319 @retval EFI_SUCCES This driver is added to ControllerHandle
320 @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle
321 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.
322 Currently not implemented.
323 @retval other This driver does not support this device
328 IpSec4DriverBindingStart (
329 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
330 IN EFI_HANDLE ControllerHandle
,
331 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
343 Stop this driver on ControllerHandle.
345 @param[in] This Protocol instance pointer.
346 @param[in] ControllerHandle Handle of a device to stop the driver on.
347 @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If the number of
348 children is zero, stop the entire bus driver.
349 @param[in] ChildHandleBuffer List of Child Handles to Stop.
351 @retval EFI_SUCCES This driver removed ControllerHandle.
352 @retval other This driver was not removed from this device.
357 IpSec4DriverBindingStop (
358 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
359 IN EFI_HANDLE ControllerHandle
,
360 IN UINTN NumberOfChildren
,
361 IN EFI_HANDLE
*ChildHandleBuffer
374 Test to see if this driver supports ControllerHandle.
376 @param[in] This Protocol instance pointer.
377 @param[in] ControllerHandle Handle of device to test.
378 @param[in] RemainingDevicePath Optional parameter used to pick a specific child
381 @retval EFI_SUCCES This driver supports this device.
382 @retval EFI_ALREADY_STARTED This driver is already running on this device.
383 @retval other This driver does not support this device.
388 IpSec6DriverBindingSupported (
389 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
390 IN EFI_HANDLE ControllerHandle
,
391 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
394 return IpSecSupported (
403 Start this driver on ControllerHandle.
405 @param[in] This Protocol instance pointer.
406 @param[in] ControllerHandle Handle of device to bind driver to.
407 @param[in] RemainingDevicePath Optional parameter used to pick a specific child
410 @retval EFI_SUCCES This driver is added to ControllerHandle
411 @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle
412 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.
413 Currently not implemented.
414 @retval other This driver does not support this device
419 IpSec6DriverBindingStart (
420 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
421 IN EFI_HANDLE ControllerHandle
,
422 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
434 Stop this driver on ControllerHandle.
436 @param[in] This Protocol instance pointer.
437 @param[in] ControllerHandle Handle of a device to stop the driver on.
438 @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If the number of
439 children is zero, stop the entire bus driver.
440 @param[in] ChildHandleBuffer List of Child Handles to Stop.
442 @retval EFI_SUCCES This driver removed ControllerHandle.
443 @retval other This driver was not removed from this device.
448 IpSec6DriverBindingStop (
449 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
450 IN EFI_HANDLE ControllerHandle
,
451 IN UINTN NumberOfChildren
,
452 IN EFI_HANDLE
*ChildHandleBuffer
464 EFI_DRIVER_BINDING_PROTOCOL gIpSec4DriverBinding
= {
465 IpSec4DriverBindingSupported
,
466 IpSec4DriverBindingStart
,
467 IpSec4DriverBindingStop
,
473 EFI_DRIVER_BINDING_PROTOCOL gIpSec6DriverBinding
= {
474 IpSec6DriverBindingSupported
,
475 IpSec6DriverBindingStart
,
476 IpSec6DriverBindingStop
,
483 This is a callback function when the mIpSecInstance.DisabledEvent is signaled.
485 @param[in] Event Event whose notification function is being invoked.
486 @param[in] Context Pointer to the notification function's context.
496 IPSEC_PRIVATE_DATA
*Private
;
497 Private
= (IPSEC_PRIVATE_DATA
*) Context
;
498 Private
->IsIPsecDisabling
= TRUE
;
499 IkeDeleteAllSas (Private
, TRUE
);
503 This is the declaration of an EFI image entry point. This entry point is
504 the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers, including
505 both device drivers and bus drivers.
507 The entry point for IPsec driver which installs the driver binding,
508 component name protocol, IPsec Config protcolon, and IPsec protocol in
511 @param[in] ImageHandle The firmware allocated handle for the UEFI image.
512 @param[in] SystemTable A pointer to the EFI System Table.
514 @retval EFI_SUCCESS The operation completed successfully.
515 @retval EFI_ALREADY_STARTED The IPsec driver has been already loaded.
516 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
517 @retval Others The operation is failed.
522 IpSecDriverEntryPoint (
523 IN EFI_HANDLE ImageHandle
,
524 IN EFI_SYSTEM_TABLE
*SystemTable
528 IPSEC_PRIVATE_DATA
*Private
;
529 EFI_IPSEC2_PROTOCOL
*IpSec
;
532 // Check whether ipsec protocol has already been installed.
534 Status
= gBS
->LocateProtocol (&gEfiIpSec2ProtocolGuid
, NULL
, (VOID
**) &IpSec
);
536 if (!EFI_ERROR (Status
)) {
537 DEBUG ((DEBUG_WARN
, "_ModuleEntryPoint: IpSec has been already loaded\n"));
538 Status
= EFI_ALREADY_STARTED
;
542 Status
= gBS
->LocateProtocol (&gEfiDpcProtocolGuid
, NULL
, (VOID
**) &mDpc
);
544 if (EFI_ERROR (Status
)) {
545 DEBUG ((DEBUG_ERROR
, "_ModuleEntryPoint: Failed to locate EfiDpcProtocol\n"));
549 Private
= AllocateZeroPool (sizeof (IPSEC_PRIVATE_DATA
));
551 if (Private
== NULL
) {
552 DEBUG ((DEBUG_ERROR
, "_ModuleEntryPoint: Failed to allocate private data\n"));
553 Status
= EFI_OUT_OF_RESOURCES
;
557 // Create disable event to cleanup all SA when ipsec disabled by user.
559 Status
= gBS
->CreateEvent (
564 &mIpSecInstance
.DisabledEvent
566 if (EFI_ERROR (Status
)) {
567 DEBUG ((DEBUG_ERROR
, "_ModuleEntryPoint: Failed to create disable event\n"));
568 goto ON_FREE_PRIVATE
;
571 Private
->Signature
= IPSEC_PRIVATE_DATA_SIGNATURE
;
572 Private
->ImageHandle
= ImageHandle
;
573 CopyMem (&Private
->IpSec
, &mIpSecInstance
, sizeof (EFI_IPSEC2_PROTOCOL
));
576 // Initilize Private's members. Thess members is used for IKE.
578 InitializeListHead (&Private
->Udp4List
);
579 InitializeListHead (&Private
->Udp6List
);
580 InitializeListHead (&Private
->Ikev1SessionList
);
581 InitializeListHead (&Private
->Ikev1EstablishedList
);
582 InitializeListHead (&Private
->Ikev2SessionList
);
583 InitializeListHead (&Private
->Ikev2EstablishedList
);
585 RandomSeed (NULL
, 0);
587 // Initialize the ipsec config data and restore it from variable.
589 Status
= IpSecConfigInitialize (Private
);
590 if (EFI_ERROR (Status
)) {
591 DEBUG ((DEBUG_ERROR
, "_ModuleEntryPoint: Failed to initialize IpSecConfig\n"));
595 // Install ipsec protocol which is used by ip driver to process ipsec header.
597 Status
= gBS
->InstallMultipleProtocolInterfaces (
599 &gEfiIpSec2ProtocolGuid
,
603 if (EFI_ERROR (Status
)) {
604 goto ON_UNINSTALL_CONFIG
;
607 Status
= EfiLibInstallDriverBindingComponentName2 (
610 &gIpSec4DriverBinding
,
612 &gIpSecComponentName
,
613 &gIpSecComponentName2
615 if (EFI_ERROR (Status
)) {
616 goto ON_UNINSTALL_IPSEC
;
619 Status
= EfiLibInstallDriverBindingComponentName2 (
622 &gIpSec6DriverBinding
,
624 &gIpSecComponentName
,
625 &gIpSecComponentName2
627 if (EFI_ERROR (Status
)) {
628 goto ON_UNINSTALL_IPSEC4_DB
;
633 ON_UNINSTALL_IPSEC4_DB
:
634 gBS
->UninstallMultipleProtocolInterfaces (
636 &gEfiDriverBindingProtocolGuid
,
637 &gIpSec4DriverBinding
,
638 &gEfiComponentName2ProtocolGuid
,
639 &gIpSecComponentName2
,
640 &gEfiComponentNameProtocolGuid
,
641 &gIpSecComponentName
,
646 gBS
->UninstallProtocolInterface (
648 &gEfiIpSec2ProtocolGuid
,
652 gBS
->UninstallProtocolInterface (
654 &gEfiIpSecConfigProtocolGuid
,
655 &Private
->IpSecConfig
658 gBS
->CloseEvent (mIpSecInstance
.DisabledEvent
);
659 mIpSecInstance
.DisabledEvent
= NULL
;