2 Driver Binding Protocol for IPsec Driver.
4 Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
10 #include <Library/BaseCryptLib.h>
12 #include "IpSecConfigImpl.h"
13 #include "IkeService.h"
14 #include "IpSecDebug.h"
17 Test to see if this driver supports ControllerHandle. This is the worker function
18 for IpSec4(6)DriverbindingSupported.
20 @param[in] This Protocol instance pointer.
21 @param[in] ControllerHandle Handle of device to test.
22 @param[in] RemainingDevicePath Optional parameter used to pick a specific child
24 @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6.
26 @retval EFI_SUCCES This driver supports this device.
27 @retval EFI_ALREADY_STARTED This driver is already running on this device.
28 @retval other This driver does not support this device.
34 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
35 IN EFI_HANDLE ControllerHandle
,
36 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
,
41 EFI_GUID
*UdpServiceBindingGuid
;
43 if (IpVersion
== IP_VERSION_4
) {
44 UdpServiceBindingGuid
= &gEfiUdp4ServiceBindingProtocolGuid
;
46 UdpServiceBindingGuid
= &gEfiUdp6ServiceBindingProtocolGuid
;
49 Status
= gBS
->OpenProtocol (
51 UdpServiceBindingGuid
,
53 This
->DriverBindingHandle
,
55 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
57 if (EFI_ERROR (Status
)) {
58 return EFI_UNSUPPORTED
;
64 Start this driver on ControllerHandle. This is the worker function
65 for IpSec4(6)DriverbindingStart.
67 @param[in] This Protocol instance pointer.
68 @param[in] ControllerHandle Handle of device to bind driver to.
69 @param[in] RemainingDevicePath Optional parameter used to pick a specific child
71 @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6.
73 @retval EFI_SUCCES This driver is added to ControllerHandle
74 @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle
75 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.
76 Currently not implemented.
77 @retval other This driver does not support this device
83 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
84 IN EFI_HANDLE ControllerHandle
,
85 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
,
89 EFI_IPSEC2_PROTOCOL
*IpSec
;
91 IPSEC_PRIVATE_DATA
*Private
;
94 // Ipsec protocol should be installed when load image.
96 Status
= gBS
->LocateProtocol (&gEfiIpSec2ProtocolGuid
, NULL
, (VOID
**) &IpSec
);
98 if (EFI_ERROR (Status
)) {
102 Private
= IPSEC_PRIVATE_DATA_FROM_IPSEC (IpSec
);
104 if (IpVersion
== IP_VERSION_4
) {
106 // Try to open a udp4 io for input.
108 Status
= gBS
->OpenProtocol (
110 &gEfiUdp4ServiceBindingProtocolGuid
,
112 This
->DriverBindingHandle
,
114 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
117 if (!EFI_ERROR (Status
)) {
118 Status
= IkeOpenInputUdp4 (Private
, ControllerHandle
, This
->DriverBindingHandle
);
122 // Try to open a udp6 io for input.
124 Status
= gBS
->OpenProtocol (
126 &gEfiUdp6ServiceBindingProtocolGuid
,
128 This
->DriverBindingHandle
,
130 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
133 if (!EFI_ERROR (Status
)) {
134 Status
= IkeOpenInputUdp6 (Private
, ControllerHandle
, This
->DriverBindingHandle
);
138 if (EFI_ERROR (Status
)) {
139 return EFI_DEVICE_ERROR
;
145 Stop this driver on ControllerHandle. This is the worker function
146 for IpSec4(6)DriverbindingStop.
148 @param[in] This Protocol instance pointer.
149 @param[in] ControllerHandle Handle of a device to stop the driver on.
150 @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If the number of
151 children is zero, stop the entire bus driver.
152 @param[in] ChildHandleBuffer List of Child Handles to Stop.
153 @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6.
155 @retval EFI_SUCCES This driver removed ControllerHandle.
156 @retval other This driver was not removed from this device.
162 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
163 IN EFI_HANDLE ControllerHandle
,
164 IN UINTN NumberOfChildren
,
165 IN EFI_HANDLE
*ChildHandleBuffer
,
169 EFI_IPSEC2_PROTOCOL
*IpSec
;
171 IPSEC_PRIVATE_DATA
*Private
;
172 IKE_UDP_SERVICE
*UdpSrv
;
175 IKEV2_SA_SESSION
*Ikev2SaSession
;
178 // Locate ipsec protocol to get private data.
180 Status
= gBS
->LocateProtocol (&gEfiIpSec2ProtocolGuid
, NULL
, (VOID
**) &IpSec
);
182 if (EFI_ERROR (Status
)) {
186 Private
= IPSEC_PRIVATE_DATA_FROM_IPSEC (IpSec
);
189 // The SAs are shared by both IP4 and IP6 stack. So we skip the cleanup
190 // and leave the SAs unchanged if the other IP stack is still running.
192 if ((IpVersion
== IP_VERSION_4
&& Private
->Udp6Num
==0) ||
193 (IpVersion
== IP_VERSION_6
&& Private
->Udp4Num
==0)) {
195 // If IKEv2 SAs are under establishing, delete it directly.
197 if (!IsListEmpty (&Private
->Ikev2SessionList
)) {
198 NET_LIST_FOR_EACH_SAFE (Entry
, Next
, &Private
->Ikev2SessionList
) {
199 Ikev2SaSession
= IKEV2_SA_SESSION_BY_SESSION (Entry
);
200 RemoveEntryList (&Ikev2SaSession
->BySessionTable
);
201 Ikev2SaSessionFree (Ikev2SaSession
);
206 // Delete established IKEv2 SAs.
208 if (!IsListEmpty (&Private
->Ikev2EstablishedList
)) {
209 NET_LIST_FOR_EACH_SAFE (Entry
, Next
, &Private
->Ikev2EstablishedList
) {
210 Ikev2SaSession
= IKEV2_SA_SESSION_BY_SESSION (Entry
);
211 RemoveEntryList (&Ikev2SaSession
->BySessionTable
);
212 Ikev2SaSessionFree (Ikev2SaSession
);
217 if (IpVersion
== IP_VERSION_4
) {
219 // If has udp4 io opened on the controller, close and free it.
221 NET_LIST_FOR_EACH_SAFE (Entry
, Next
, &Private
->Udp4List
) {
223 UdpSrv
= IPSEC_UDP_SERVICE_FROM_LIST (Entry
);
225 // Find the right udp service which installed on the appointed nic handle.
227 if (UdpSrv
->Input
!= NULL
&& ControllerHandle
== UdpSrv
->Input
->UdpHandle
) {
228 UdpIoFreeIo (UdpSrv
->Input
);
229 UdpSrv
->Input
= NULL
;
232 if (UdpSrv
->Output
!= NULL
&& ControllerHandle
== UdpSrv
->Output
->UdpHandle
) {
233 UdpIoFreeIo (UdpSrv
->Output
);
234 UdpSrv
->Output
= NULL
;
237 if (UdpSrv
->Input
== NULL
&& UdpSrv
->Output
== NULL
) {
238 RemoveEntryList (&UdpSrv
->List
);
240 ASSERT (Private
->Udp4Num
> 0);
246 // If has udp6 io opened on the controller, close and free it.
248 NET_LIST_FOR_EACH_SAFE (Entry
, Next
, &Private
->Udp6List
) {
250 UdpSrv
= IPSEC_UDP_SERVICE_FROM_LIST (Entry
);
252 // Find the right udp service which installed on the appointed nic handle.
254 if (UdpSrv
->Input
!= NULL
&& ControllerHandle
== UdpSrv
->Input
->UdpHandle
) {
255 UdpIoFreeIo (UdpSrv
->Input
);
256 UdpSrv
->Input
= NULL
;
259 if (UdpSrv
->Output
!= NULL
&& ControllerHandle
== UdpSrv
->Output
->UdpHandle
) {
260 UdpIoFreeIo (UdpSrv
->Output
);
261 UdpSrv
->Output
= NULL
;
264 if (UdpSrv
->Input
== NULL
&& UdpSrv
->Output
== NULL
) {
265 RemoveEntryList (&UdpSrv
->List
);
267 ASSERT (Private
->Udp6Num
> 0);
277 Test to see if this driver supports ControllerHandle.
279 @param[in] This Protocol instance pointer.
280 @param[in] ControllerHandle Handle of device to test.
281 @param[in] RemainingDevicePath Optional parameter used to pick a specific child
284 @retval EFI_SUCCES This driver supports this device.
285 @retval EFI_ALREADY_STARTED This driver is already running on this device.
286 @retval other This driver does not support this device.
291 IpSec4DriverBindingSupported (
292 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
293 IN EFI_HANDLE ControllerHandle
,
294 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
297 return IpSecSupported (
306 Start this driver on ControllerHandle.
308 @param[in] This Protocol instance pointer.
309 @param[in] ControllerHandle Handle of device to bind driver to.
310 @param[in] RemainingDevicePath Optional parameter used to pick a specific child
313 @retval EFI_SUCCES This driver is added to ControllerHandle
314 @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle
315 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.
316 Currently not implemented.
317 @retval other This driver does not support this device
322 IpSec4DriverBindingStart (
323 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
324 IN EFI_HANDLE ControllerHandle
,
325 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
337 Stop this driver on ControllerHandle.
339 @param[in] This Protocol instance pointer.
340 @param[in] ControllerHandle Handle of a device to stop the driver on.
341 @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If the number of
342 children is zero, stop the entire bus driver.
343 @param[in] ChildHandleBuffer List of Child Handles to Stop.
345 @retval EFI_SUCCES This driver removed ControllerHandle.
346 @retval other This driver was not removed from this device.
351 IpSec4DriverBindingStop (
352 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
353 IN EFI_HANDLE ControllerHandle
,
354 IN UINTN NumberOfChildren
,
355 IN EFI_HANDLE
*ChildHandleBuffer
368 Test to see if this driver supports ControllerHandle.
370 @param[in] This Protocol instance pointer.
371 @param[in] ControllerHandle Handle of device to test.
372 @param[in] RemainingDevicePath Optional parameter used to pick a specific child
375 @retval EFI_SUCCES This driver supports this device.
376 @retval EFI_ALREADY_STARTED This driver is already running on this device.
377 @retval other This driver does not support this device.
382 IpSec6DriverBindingSupported (
383 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
384 IN EFI_HANDLE ControllerHandle
,
385 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
388 return IpSecSupported (
397 Start this driver on ControllerHandle.
399 @param[in] This Protocol instance pointer.
400 @param[in] ControllerHandle Handle of device to bind driver to.
401 @param[in] RemainingDevicePath Optional parameter used to pick a specific child
404 @retval EFI_SUCCES This driver is added to ControllerHandle
405 @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle
406 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.
407 Currently not implemented.
408 @retval other This driver does not support this device
413 IpSec6DriverBindingStart (
414 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
415 IN EFI_HANDLE ControllerHandle
,
416 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
428 Stop this driver on ControllerHandle.
430 @param[in] This Protocol instance pointer.
431 @param[in] ControllerHandle Handle of a device to stop the driver on.
432 @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If the number of
433 children is zero, stop the entire bus driver.
434 @param[in] ChildHandleBuffer List of Child Handles to Stop.
436 @retval EFI_SUCCES This driver removed ControllerHandle.
437 @retval other This driver was not removed from this device.
442 IpSec6DriverBindingStop (
443 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
444 IN EFI_HANDLE ControllerHandle
,
445 IN UINTN NumberOfChildren
,
446 IN EFI_HANDLE
*ChildHandleBuffer
458 EFI_DRIVER_BINDING_PROTOCOL gIpSec4DriverBinding
= {
459 IpSec4DriverBindingSupported
,
460 IpSec4DriverBindingStart
,
461 IpSec4DriverBindingStop
,
467 EFI_DRIVER_BINDING_PROTOCOL gIpSec6DriverBinding
= {
468 IpSec6DriverBindingSupported
,
469 IpSec6DriverBindingStart
,
470 IpSec6DriverBindingStop
,
477 This is a callback function when the mIpSecInstance.DisabledEvent is signaled.
479 @param[in] Event Event whose notification function is being invoked.
480 @param[in] Context Pointer to the notification function's context.
490 IPSEC_PRIVATE_DATA
*Private
;
491 Private
= (IPSEC_PRIVATE_DATA
*) Context
;
492 Private
->IsIPsecDisabling
= TRUE
;
493 IkeDeleteAllSas (Private
, TRUE
);
497 This is the declaration of an EFI image entry point. This entry point is
498 the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers, including
499 both device drivers and bus drivers.
501 The entry point for IPsec driver which installs the driver binding,
502 component name protocol, IPsec Config protcolon, and IPsec protocol in
505 @param[in] ImageHandle The firmware allocated handle for the UEFI image.
506 @param[in] SystemTable A pointer to the EFI System Table.
508 @retval EFI_SUCCESS The operation completed successfully.
509 @retval EFI_ALREADY_STARTED The IPsec driver has been already loaded.
510 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
511 @retval Others The operation is failed.
516 IpSecDriverEntryPoint (
517 IN EFI_HANDLE ImageHandle
,
518 IN EFI_SYSTEM_TABLE
*SystemTable
522 IPSEC_PRIVATE_DATA
*Private
;
523 EFI_IPSEC2_PROTOCOL
*IpSec
;
526 // Check whether ipsec protocol has already been installed.
528 Status
= gBS
->LocateProtocol (&gEfiIpSec2ProtocolGuid
, NULL
, (VOID
**) &IpSec
);
530 if (!EFI_ERROR (Status
)) {
531 DEBUG ((DEBUG_WARN
, "_ModuleEntryPoint: IpSec has been already loaded\n"));
532 Status
= EFI_ALREADY_STARTED
;
536 Status
= gBS
->LocateProtocol (&gEfiDpcProtocolGuid
, NULL
, (VOID
**) &mDpc
);
538 if (EFI_ERROR (Status
)) {
539 DEBUG ((DEBUG_ERROR
, "_ModuleEntryPoint: Failed to locate EfiDpcProtocol\n"));
543 Private
= AllocateZeroPool (sizeof (IPSEC_PRIVATE_DATA
));
545 if (Private
== NULL
) {
546 DEBUG ((DEBUG_ERROR
, "_ModuleEntryPoint: Failed to allocate private data\n"));
547 Status
= EFI_OUT_OF_RESOURCES
;
551 // Create disable event to cleanup all SA when ipsec disabled by user.
553 Status
= gBS
->CreateEvent (
558 &mIpSecInstance
.DisabledEvent
560 if (EFI_ERROR (Status
)) {
561 DEBUG ((DEBUG_ERROR
, "_ModuleEntryPoint: Failed to create disable event\n"));
562 goto ON_FREE_PRIVATE
;
565 Private
->Signature
= IPSEC_PRIVATE_DATA_SIGNATURE
;
566 Private
->ImageHandle
= ImageHandle
;
567 CopyMem (&Private
->IpSec
, &mIpSecInstance
, sizeof (EFI_IPSEC2_PROTOCOL
));
570 // Initilize Private's members. Thess members is used for IKE.
572 InitializeListHead (&Private
->Udp4List
);
573 InitializeListHead (&Private
->Udp6List
);
574 InitializeListHead (&Private
->Ikev1SessionList
);
575 InitializeListHead (&Private
->Ikev1EstablishedList
);
576 InitializeListHead (&Private
->Ikev2SessionList
);
577 InitializeListHead (&Private
->Ikev2EstablishedList
);
579 RandomSeed (NULL
, 0);
581 // Initialize the ipsec config data and restore it from variable.
583 Status
= IpSecConfigInitialize (Private
);
584 if (EFI_ERROR (Status
)) {
585 DEBUG ((DEBUG_ERROR
, "_ModuleEntryPoint: Failed to initialize IpSecConfig\n"));
589 // Install ipsec protocol which is used by ip driver to process ipsec header.
591 Status
= gBS
->InstallMultipleProtocolInterfaces (
593 &gEfiIpSec2ProtocolGuid
,
597 if (EFI_ERROR (Status
)) {
598 goto ON_UNINSTALL_CONFIG
;
601 Status
= EfiLibInstallDriverBindingComponentName2 (
604 &gIpSec4DriverBinding
,
606 &gIpSecComponentName
,
607 &gIpSecComponentName2
609 if (EFI_ERROR (Status
)) {
610 goto ON_UNINSTALL_IPSEC
;
613 Status
= EfiLibInstallDriverBindingComponentName2 (
616 &gIpSec6DriverBinding
,
618 &gIpSecComponentName
,
619 &gIpSecComponentName2
621 if (EFI_ERROR (Status
)) {
622 goto ON_UNINSTALL_IPSEC4_DB
;
627 ON_UNINSTALL_IPSEC4_DB
:
628 EfiLibUninstallDriverBindingComponentName2 (
629 &gIpSec4DriverBinding
,
630 &gIpSecComponentName
,
631 &gIpSecComponentName2
635 gBS
->UninstallProtocolInterface (
637 &gEfiIpSec2ProtocolGuid
,
641 gBS
->UninstallProtocolInterface (
643 &gEfiIpSecConfigProtocolGuid
,
644 &Private
->IpSecConfig
647 gBS
->CloseEvent (mIpSecInstance
.DisabledEvent
);
648 mIpSecInstance
.DisabledEvent
= NULL
;