2 Provide IPsec Key Exchange (IKE) service general interfaces.
4 Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
10 #include "IkeService.h"
11 #include "IpSecConfigImpl.h"
13 IKE_EXCHANGE_INTERFACE
*mIkeExchange
[] = {
18 EFI_UDP4_CONFIG_DATA mUdp4Conf
= {
39 EFI_UDP6_CONFIG_DATA mUdp6Conf
= {
51 {{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},
53 {{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},
58 Check if the NIC handle is binded to a Udp service.
60 @param[in] Private Pointer of IPSEC_PRIVATE_DATA.
61 @param[in] Handle The Handle of the NIC card.
62 @param[in] IpVersion The version of the IP stack.
64 @return a pointer of IKE_UDP_SERVICE.
69 IN IPSEC_PRIVATE_DATA
*Private
,
80 Head
= (IpVersion
== IP_VERSION_4
) ? &Private
->Udp4List
: &Private
->Udp6List
;
82 NET_LIST_FOR_EACH_SAFE (Entry
, Next
, Head
) {
84 Udp
= IPSEC_UDP_SERVICE_FROM_LIST (Entry
);
86 // Find the right udp service which installed on the appointed NIC handle.
88 if (Handle
== Udp
->NicHandle
) {
99 Configure a UDPIO's UDP4 instance.
101 This fuction is called by the UdpIoCreateIo() to configures a
104 @param[in] UdpIo The UDP_IO to be configured.
105 @param[in] Context User-defined data when calling UdpIoCreateIo().
107 @retval EFI_SUCCESS The configuration succeeded.
108 @retval Others The UDP4 instance fails to configure.
118 EFI_UDP4_CONFIG_DATA Udp4Cfg
;
119 EFI_UDP4_PROTOCOL
*Udp4
;
121 ZeroMem (&Udp4Cfg
, sizeof (EFI_UDP4_CONFIG_DATA
));
123 Udp4
= UdpIo
->Protocol
.Udp4
;
127 sizeof (EFI_UDP4_CONFIG_DATA
)
130 if (Context
!= NULL
) {
132 // Configure udp4 io with local default address.
134 Udp4Cfg
.UseDefaultAddress
= TRUE
;
137 return Udp4
->Configure (Udp4
, &Udp4Cfg
);
141 Configure a UDPIO's UDP6 instance.
143 This fuction is called by the UdpIoCreateIo()to configure a
146 @param[in] UdpIo The UDP_IO to be configured.
147 @param[in] Context User-defined data when calling UdpIoCreateIo().
149 @retval EFI_SUCCESS The configuration succeeded.
150 @retval Others The configuration fails.
160 EFI_UDP6_PROTOCOL
*Udp6
;
161 EFI_UDP6_CONFIG_DATA Udp6Cfg
;
163 ZeroMem (&Udp6Cfg
, sizeof (EFI_UDP6_CONFIG_DATA
));
165 Udp6
= UdpIo
->Protocol
.Udp6
;
169 sizeof (EFI_UDP6_CONFIG_DATA
)
172 if (Context
!= NULL
) {
174 // Configure instance with a destination address to start source address
175 // selection, and then get the configure data from the mode data to store
176 // the source address.
179 &Udp6Cfg
.RemoteAddress
,
181 sizeof (EFI_IPv6_ADDRESS
)
185 return Udp6
->Configure (Udp6
, &Udp6Cfg
);
189 Open and configure the related output UDPIO for IKE packet sending.
191 If the UdpService is not configured, this fuction calls UdpIoCreatIo() to
192 create UDPIO to bind this UdpService for IKE packet sending. If the UdpService
193 has already been configured, then return.
195 @param[in] UdpService The UDP_IO to be configured.
196 @param[in] RemoteIp User-defined data when calling UdpIoCreateIo().
198 @retval EFI_SUCCESS The configuration is successful.
199 @retval Others The configuration fails.
204 IN IKE_UDP_SERVICE
*UdpService
,
205 IN EFI_IP_ADDRESS
*RemoteIp
209 EFI_IP4_CONFIG2_PROTOCOL
*Ip4Cfg2
;
210 EFI_IP4_CONFIG2_INTERFACE_INFO
*IfInfo
;
212 EFI_IP6_MODE_DATA Ip6ModeData
;
213 EFI_UDP6_PROTOCOL
*Udp6
;
215 Status
= EFI_SUCCESS
;
220 // Check whether the input and output udp io are both configured.
222 if (UdpService
->IsConfigured
) {
226 if (UdpService
->IpVersion
== UDP_IO_UDP4_VERSION
) {
228 // Handle ip4config protocol to get local default address.
230 Status
= gBS
->HandleProtocol (
231 UdpService
->NicHandle
,
232 &gEfiIp4Config2ProtocolGuid
,
236 if (EFI_ERROR (Status
)) {
241 // Get the interface information size.
243 Status
= Ip4Cfg2
->GetData (
245 Ip4Config2DataTypeInterfaceInfo
,
250 if (EFI_ERROR (Status
) && Status
!= EFI_BUFFER_TOO_SMALL
) {
254 IfInfo
= AllocateZeroPool (BufSize
);
256 if (IfInfo
== NULL
) {
257 Status
= EFI_OUT_OF_RESOURCES
;
262 // Get the interface info.
264 Status
= Ip4Cfg2
->GetData (
266 Ip4Config2DataTypeInterfaceInfo
,
271 if (EFI_ERROR (Status
)) {
276 &UdpService
->DefaultAddress
.v4
,
277 &IfInfo
->StationAddress
,
278 sizeof (EFI_IPv4_ADDRESS
)
282 // Create udp4 io for output with local default address.
284 UdpService
->Output
= UdpIoCreateIo (
285 UdpService
->NicHandle
,
286 UdpService
->ImageHandle
,
289 &UdpService
->DefaultAddress
292 if (UdpService
->Output
== NULL
) {
293 Status
= EFI_OUT_OF_RESOURCES
;
299 // Create udp6 io for output with remote address.
301 UdpService
->Output
= UdpIoCreateIo (
302 UdpService
->NicHandle
,
303 UdpService
->ImageHandle
,
309 if (UdpService
->Output
== NULL
) {
310 Status
= EFI_OUT_OF_RESOURCES
;
314 // Get ip6 mode data to get the result of source address selection.
316 ZeroMem (&Ip6ModeData
, sizeof (EFI_IP6_MODE_DATA
));
318 Udp6
= UdpService
->Output
->Protocol
.Udp6
;
319 Status
= Udp6
->GetModeData (Udp6
, NULL
, &Ip6ModeData
, NULL
, NULL
);
321 if (EFI_ERROR (Status
)) {
322 UdpIoFreeIo (UdpService
->Output
);
326 if (Ip6ModeData
.AddressList
!= NULL
) {
327 FreePool (Ip6ModeData
.AddressList
);
330 if (Ip6ModeData
.GroupTable
!= NULL
) {
331 FreePool (Ip6ModeData
.GroupTable
);
334 if (Ip6ModeData
.RouteTable
!= NULL
) {
335 FreePool (Ip6ModeData
.RouteTable
);
338 if (Ip6ModeData
.NeighborCache
!= NULL
) {
339 FreePool (Ip6ModeData
.NeighborCache
);
342 if (Ip6ModeData
.PrefixTable
!= NULL
) {
343 FreePool (Ip6ModeData
.PrefixTable
);
346 if (Ip6ModeData
.IcmpTypeList
!= NULL
) {
347 FreePool (Ip6ModeData
.IcmpTypeList
);
351 // Reconfigure udp6 io without remote address.
353 Udp6
->Configure (Udp6
, NULL
);
354 Status
= IkeConfigUdp6 (UdpService
->Output
, NULL
);
357 // Record the selected source address for ipsec process later.
360 &UdpService
->DefaultAddress
.v6
,
361 &Ip6ModeData
.ConfigData
.StationAddress
,
362 sizeof (EFI_IPv6_ADDRESS
)
366 UdpService
->IsConfigured
= TRUE
;
369 if (IfInfo
!= NULL
) {
377 Open and configure a UDPIO of Udp4 for IKE packet receiving.
379 This function is called at the IPsecDriverBinding start. IPsec create a UDP4 and
380 UDP4 IO for each NIC handle.
382 @param[in] Private Point to IPSEC_PRIVATE_DATA
383 @param[in] Controller Handler for NIC card.
384 @param[in] ImageHandle The handle that contains the EFI_DRIVER_BINDING_PROTOCOL instance.
386 @retval EFI_SUCCESS The Operation is successful.
387 @retval EFI_OUT_OF_RESOURCE The required system resource can't be allocated.
392 IN IPSEC_PRIVATE_DATA
*Private
,
393 IN EFI_HANDLE Controller
,
394 IN EFI_HANDLE ImageHandle
397 IKE_UDP_SERVICE
*Udp4Srv
;
400 // Check whether udp4 io of the controller has already been opened.
402 Udp4Srv
= IkeLookupUdp (Private
, Controller
, IP_VERSION_4
);
404 if (Udp4Srv
!= NULL
) {
405 return EFI_ALREADY_STARTED
;
408 Udp4Srv
= AllocateZeroPool (sizeof (IKE_UDP_SERVICE
));
410 if (Udp4Srv
== NULL
) {
411 return EFI_OUT_OF_RESOURCES
;
414 // Create udp4 io for iutput.
416 Udp4Srv
->Input
= UdpIoCreateIo (
424 if (Udp4Srv
->Input
== NULL
) {
426 return EFI_OUT_OF_RESOURCES
;
429 Udp4Srv
->NicHandle
= Controller
;
430 Udp4Srv
->ImageHandle
= ImageHandle
;
431 Udp4Srv
->ListHead
= &(Private
->Udp4List
);
432 Udp4Srv
->IpVersion
= UDP_IO_UDP4_VERSION
;
433 Udp4Srv
->IsConfigured
= FALSE
;
435 ZeroMem (&Udp4Srv
->DefaultAddress
, sizeof (EFI_IP_ADDRESS
));
438 // Insert the udp4 io into the list and increase the count.
440 InsertTailList (&Private
->Udp4List
, &Udp4Srv
->List
);
444 UdpIoRecvDatagram (Udp4Srv
->Input
, IkeDispatch
, Udp4Srv
, 0);
450 Open and configure a UDPIO of Udp6 for IKE packet receiving.
452 This function is called at the IPsecDriverBinding start. IPsec create a UDP6 and UDP6
453 IO for each NIC handle.
455 @param[in] Private Point to IPSEC_PRIVATE_DATA
456 @param[in] Controller Handler for NIC card.
457 @param[in] ImageHandle The handle that contains the EFI_DRIVER_BINDING_PROTOCOL instance.
459 @retval EFI_SUCCESS The Operation is successful.
460 @retval EFI_OUT_OF_RESOURCE The required system resource can't be allocated.
465 IN IPSEC_PRIVATE_DATA
*Private
,
466 IN EFI_HANDLE Controller
,
467 IN EFI_HANDLE ImageHandle
470 IKE_UDP_SERVICE
*Udp6Srv
;
472 Udp6Srv
= IkeLookupUdp (Private
, Controller
, IP_VERSION_6
);
474 if (Udp6Srv
!= NULL
) {
475 return EFI_ALREADY_STARTED
;
478 Udp6Srv
= AllocateZeroPool (sizeof (IKE_UDP_SERVICE
));
480 if (Udp6Srv
== NULL
) {
481 return EFI_OUT_OF_RESOURCES
;
484 // Create udp6 io for input.
486 Udp6Srv
->Input
= UdpIoCreateIo (
494 if (Udp6Srv
->Input
== NULL
) {
496 return EFI_OUT_OF_RESOURCES
;
499 Udp6Srv
->NicHandle
= Controller
;
500 Udp6Srv
->ImageHandle
= ImageHandle
;
501 Udp6Srv
->ListHead
= &(Private
->Udp6List
);
502 Udp6Srv
->IpVersion
= UDP_IO_UDP6_VERSION
;
503 Udp6Srv
->IsConfigured
= FALSE
;
505 ZeroMem (&Udp6Srv
->DefaultAddress
, sizeof (EFI_IP_ADDRESS
));
508 // Insert the udp6 io into the list and increase the count.
510 InsertTailList (&Private
->Udp6List
, &Udp6Srv
->List
);
514 UdpIoRecvDatagram (Udp6Srv
->Input
, IkeDispatch
, Udp6Srv
, 0);
520 The general interface of starting IPsec Key Exchange.
522 This function is called when a IKE negotiation to start getting a Key.
524 @param[in] UdpService Point to IKE_UDP_SERVICE which will be used for
526 @param[in] SpdEntry Point to the SPD entry related to the IKE negotiation.
527 @param[in] RemoteIp Point to EFI_IP_ADDRESS related to the IKE negotiation.
529 @retval EFI_SUCCESS The Operation is successful.
530 @retval EFI_ACCESS_DENIED No related PAD entry was found.
531 @retval EFI_INVALID_PARAMETER The IKE version is not supported.
536 IN IKE_UDP_SERVICE
*UdpService
,
537 IN IPSEC_SPD_ENTRY
*SpdEntry
,
538 IN EFI_IP_ADDRESS
*RemoteIp
543 IKE_EXCHANGE_INTERFACE
*Exchange
;
544 IPSEC_PRIVATE_DATA
*Private
;
545 IPSEC_PAD_ENTRY
*PadEntry
;
548 Private
= (UdpService
->IpVersion
== IP_VERSION_4
) ?
549 IPSEC_PRIVATE_DATA_FROM_UDP4LIST(UdpService
->ListHead
) :
550 IPSEC_PRIVATE_DATA_FROM_UDP6LIST(UdpService
->ListHead
);
553 // Try to open udp io for output if it hasn't.
555 Status
= IkeOpenOutputUdp (UdpService
, RemoteIp
);
556 if (EFI_ERROR (Status
)) {
560 // Try to find the IKE SA session in the IKEv1 and IKEv2 established SA session list.
562 IkeSaSession
= (UINT8
*) Ikev2SaSessionLookup (&Private
->Ikev2EstablishedList
, RemoteIp
);
565 if (IkeSaSession
== NULL
) {
567 // Find the pad entry by the remote ip address.
569 PadEntry
= IpSecLookupPadEntry (UdpService
->IpVersion
, RemoteIp
);
570 if (PadEntry
== NULL
) {
571 return EFI_ACCESS_DENIED
;
574 // Determine the IKE exchange instance by the auth protocol in pad entry.
576 ASSERT (PadEntry
->Data
->AuthProtocol
< EfiIPsecAuthProtocolMaximum
);
577 if (PadEntry
->Data
->AuthProtocol
== EfiIPsecAuthProtocolIKEv1
) {
578 return EFI_INVALID_PARAMETER
;
580 Exchange
= mIkeExchange
[PadEntry
->Data
->AuthProtocol
];
582 // Start the main mode stage to negotiate IKE SA.
584 Status
= Exchange
->NegotiateSa (UdpService
, SpdEntry
, PadEntry
, RemoteIp
);
587 // Determine the IKE exchange instance by the IKE version in IKE SA session.
589 IkeVersion
= IkeGetVersionFromSession (IkeSaSession
);
590 if (IkeVersion
!= 2) {
591 return EFI_INVALID_PARAMETER
;
594 Exchange
= mIkeExchange
[IkeVersion
- 1];
596 // Start the quick mode stage to negotiate child SA.
598 Status
= Exchange
->NegotiateChildSa (IkeSaSession
, SpdEntry
, NULL
);
605 The generic interface when receive a IKE packet.
607 This function is called when UDP IO receives a IKE packet.
609 @param[in] Packet Point to received IKE packet.
610 @param[in] EndPoint Point to UDP_END_POINT which contains the information of
612 @param[in] IoStatus The Status of Recieve Token.
613 @param[in] Context Point to data passed from the caller.
620 IN UDP_END_POINT
*EndPoint
,
621 IN EFI_STATUS IoStatus
,
625 IPSEC_PRIVATE_DATA
*Private
;
626 IKE_PACKET
*IkePacket
;
628 IKE_UDP_SERVICE
*UdpService
;
629 IKE_EXCHANGE_INTERFACE
*Exchange
;
632 UdpService
= (IKE_UDP_SERVICE
*) Context
;
634 Private
= (UdpService
->IpVersion
== IP_VERSION_4
) ?
635 IPSEC_PRIVATE_DATA_FROM_UDP4LIST(UdpService
->ListHead
) :
636 IPSEC_PRIVATE_DATA_FROM_UDP6LIST(UdpService
->ListHead
);
638 if (EFI_ERROR (IoStatus
)) {
642 // Check whether the ipsec is enabled or not.
644 if (Private
->IpSec
.DisabledFlag
== TRUE
) {
648 if (EndPoint
->RemotePort
!= IKE_DEFAULT_PORT
) {
653 // Build IKE packet from the received netbuf.
655 IkePacket
= IkePacketFromNetbuf (Packet
);
657 if (IkePacket
== NULL
) {
661 // Get the remote address from the IKE packet.
663 if (UdpService
->IpVersion
== IP_VERSION_4
) {
664 *(UINT32
*) IkePacket
->RemotePeerIp
.Addr
= HTONL ((*(UINT32
*) EndPoint
->RemoteAddr
.Addr
));
667 &IkePacket
->RemotePeerIp
,
668 NTOHLLL (&EndPoint
->RemoteAddr
.v6
),
669 sizeof (EFI_IPv6_ADDRESS
)
673 // Try to open udp io for output if hasn't.
675 Status
= IkeOpenOutputUdp (UdpService
, &IkePacket
->RemotePeerIp
);
677 if (EFI_ERROR (Status
)) {
681 IkeHdr
= IkePacket
->Header
;
684 // Determine the IKE exchange instance by the IKE version in IKE header.
686 if (IKE_MAJOR_VERSION (IkeHdr
->Version
) == 2) {
687 Exchange
= mIkeExchange
[IKE_MAJOR_VERSION (IkeHdr
->Version
) - 1];
692 switch (IkeHdr
->ExchangeType
) {
693 case IKE_XCG_TYPE_IDENTITY_PROTECT
:
694 case IKE_XCG_TYPE_SA_INIT
:
695 case IKE_XCG_TYPE_AUTH
:
696 Exchange
->HandleSa (UdpService
, IkePacket
);
699 case IKE_XCG_TYPE_QM
:
700 case IKE_XCG_TYPE_CREATE_CHILD_SA
:
701 Exchange
->HandleChildSa (UdpService
, IkePacket
);
704 case IKE_XCG_TYPE_INFO
:
705 case IKE_XCG_TYPE_INFO2
:
706 Exchange
->HandleInfo (UdpService
, IkePacket
);
714 if (IkePacket
!= NULL
) {
715 IkePacketFree (IkePacket
);
718 if (Packet
!= NULL
) {
722 UdpIoRecvDatagram (UdpService
->Input
, IkeDispatch
, UdpService
, 0);
728 Delete all established IKE SAs and related Child SAs.
730 This function is the subfunction of the IpSecCleanupAllSa(). It first calls
731 IkeDeleteChildSa() to delete all Child SAs then send out the related
734 @param[in] Private Pointer of the IPSEC_PRIVATE_DATA
735 @param[in] IsDisableIpsec Indicate whether needs to disable IPsec.
740 IN IPSEC_PRIVATE_DATA
*Private
,
741 IN BOOLEAN IsDisableIpsec
745 LIST_ENTRY
*NextEntry
;
746 IKEV2_SA_SESSION
*Ikev2SaSession
;
749 IKE_EXCHANGE_INTERFACE
*Exchange
;
755 // If the IKEv1 is supported, first deal with the Ikev1Estatblished list.
759 // If IKEv2 SAs are under establishing, delete it directly.
761 if (!IsListEmpty (&Private
->Ikev2SessionList
)) {
762 NET_LIST_FOR_EACH_SAFE (Entry
, NextEntry
, &Private
->Ikev2SessionList
) {
763 Ikev2SaSession
= IKEV2_SA_SESSION_BY_SESSION (Entry
);
764 RemoveEntryList (Entry
);
765 Ikev2SaSessionFree (Ikev2SaSession
);
770 // If there is no existing established IKE SA, set the Ipsec DisableFlag to TRUE
771 // and turn off the IsIPsecDisabling flag.
773 if (IsListEmpty (&Private
->Ikev2EstablishedList
) && IsDisableIpsec
) {
774 Value
= IPSEC_STATUS_DISABLED
;
775 Status
= gRT
->SetVariable (
776 IPSECCONFIG_STATUS_NAME
,
777 &gEfiIpSecConfigProtocolGuid
,
778 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
782 if (!EFI_ERROR (Status
)) {
783 Private
->IpSec
.DisabledFlag
= TRUE
;
784 Private
->IsIPsecDisabling
= FALSE
;
790 // Delete established IKEv2 SAs.
792 if (!IsListEmpty (&Private
->Ikev2EstablishedList
)) {
793 for (Entry
= Private
->Ikev2EstablishedList
.ForwardLink
; Entry
!= &Private
->Ikev2EstablishedList
;) {
794 Ikev2SaSession
= IKEV2_SA_SESSION_BY_SESSION (Entry
);
795 Entry
= Entry
->ForwardLink
;
797 Ikev2SaSession
->SessionCommon
.State
= IkeStateSaDeleting
;
800 // Call for Information Exchange.
802 IkeVersion
= IkeGetVersionFromSession ((UINT8
*)Ikev2SaSession
);
803 if (IkeVersion
== 2) {
804 Exchange
= mIkeExchange
[IkeVersion
- 1];
805 Exchange
->NegotiateInfo((UINT8
*)Ikev2SaSession
, NULL
);