2 Provide IPsec Key Exchange (IKE) service general interfaces.
4 Copyright (c) 2010 - 2016, 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 "IkeService.h"
17 #include "IpSecConfigImpl.h"
19 IKE_EXCHANGE_INTERFACE
*mIkeExchange
[] = {
24 EFI_UDP4_CONFIG_DATA mUdp4Conf
= {
45 EFI_UDP6_CONFIG_DATA mUdp6Conf
= {
57 {{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},
59 {{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},
64 Check if the NIC handle is binded to a Udp service.
66 @param[in] Private Pointer of IPSEC_PRIVATE_DATA.
67 @param[in] Handle The Handle of the NIC card.
68 @param[in] IpVersion The version of the IP stack.
70 @return a pointer of IKE_UDP_SERVICE.
75 IN IPSEC_PRIVATE_DATA
*Private
,
86 Head
= (IpVersion
== IP_VERSION_4
) ? &Private
->Udp4List
: &Private
->Udp6List
;
88 NET_LIST_FOR_EACH_SAFE (Entry
, Next
, Head
) {
90 Udp
= IPSEC_UDP_SERVICE_FROM_LIST (Entry
);
92 // Find the right udp service which installed on the appointed NIC handle.
94 if (Handle
== Udp
->NicHandle
) {
105 Configure a UDPIO's UDP4 instance.
107 This fuction is called by the UdpIoCreateIo() to configures a
110 @param[in] UdpIo The UDP_IO to be configured.
111 @param[in] Context User-defined data when calling UdpIoCreateIo().
113 @retval EFI_SUCCESS The configuration succeeded.
114 @retval Others The UDP4 instance fails to configure.
124 EFI_UDP4_CONFIG_DATA Udp4Cfg
;
125 EFI_UDP4_PROTOCOL
*Udp4
;
127 ZeroMem (&Udp4Cfg
, sizeof (EFI_UDP4_CONFIG_DATA
));
129 Udp4
= UdpIo
->Protocol
.Udp4
;
133 sizeof (EFI_UDP4_CONFIG_DATA
)
136 if (Context
!= NULL
) {
138 // Configure udp4 io with local default address.
140 Udp4Cfg
.UseDefaultAddress
= TRUE
;
143 return Udp4
->Configure (Udp4
, &Udp4Cfg
);
147 Configure a UDPIO's UDP6 instance.
149 This fuction is called by the UdpIoCreateIo()to configure a
152 @param[in] UdpIo The UDP_IO to be configured.
153 @param[in] Context User-defined data when calling UdpIoCreateIo().
155 @retval EFI_SUCCESS The configuration succeeded.
156 @retval Others The configuration fails.
166 EFI_UDP6_PROTOCOL
*Udp6
;
167 EFI_UDP6_CONFIG_DATA Udp6Cfg
;
169 ZeroMem (&Udp6Cfg
, sizeof (EFI_UDP6_CONFIG_DATA
));
171 Udp6
= UdpIo
->Protocol
.Udp6
;
175 sizeof (EFI_UDP6_CONFIG_DATA
)
178 if (Context
!= NULL
) {
180 // Configure instance with a destination address to start source address
181 // selection, and then get the configure data from the mode data to store
182 // the source address.
185 &Udp6Cfg
.RemoteAddress
,
187 sizeof (EFI_IPv6_ADDRESS
)
191 return Udp6
->Configure (Udp6
, &Udp6Cfg
);
195 Open and configure the related output UDPIO for IKE packet sending.
197 If the UdpService is not configured, this fuction calls UdpIoCreatIo() to
198 create UDPIO to bind this UdpService for IKE packet sending. If the UdpService
199 has already been configured, then return.
201 @param[in] UdpService The UDP_IO to be configured.
202 @param[in] RemoteIp User-defined data when calling UdpIoCreateIo().
204 @retval EFI_SUCCESS The configuration is successful.
205 @retval Others The configuration fails.
210 IN IKE_UDP_SERVICE
*UdpService
,
211 IN EFI_IP_ADDRESS
*RemoteIp
215 EFI_IP4_CONFIG2_PROTOCOL
*Ip4Cfg2
;
216 EFI_IP4_CONFIG2_INTERFACE_INFO
*IfInfo
;
218 EFI_IP6_MODE_DATA Ip6ModeData
;
219 EFI_UDP6_PROTOCOL
*Udp6
;
221 Status
= EFI_SUCCESS
;
226 // Check whether the input and output udp io are both configured.
228 if (UdpService
->IsConfigured
) {
232 if (UdpService
->IpVersion
== UDP_IO_UDP4_VERSION
) {
234 // Handle ip4config protocol to get local default address.
236 Status
= gBS
->HandleProtocol (
237 UdpService
->NicHandle
,
238 &gEfiIp4Config2ProtocolGuid
,
242 if (EFI_ERROR (Status
)) {
247 // Get the interface information size.
249 Status
= Ip4Cfg2
->GetData (
251 Ip4Config2DataTypeInterfaceInfo
,
256 if (EFI_ERROR (Status
) && Status
!= EFI_BUFFER_TOO_SMALL
) {
260 IfInfo
= AllocateZeroPool (BufSize
);
262 if (IfInfo
== NULL
) {
263 Status
= EFI_OUT_OF_RESOURCES
;
268 // Get the interface info.
270 Status
= Ip4Cfg2
->GetData (
272 Ip4Config2DataTypeInterfaceInfo
,
277 if (EFI_ERROR (Status
)) {
282 &UdpService
->DefaultAddress
.v4
,
283 &IfInfo
->StationAddress
,
284 sizeof (EFI_IPv4_ADDRESS
)
288 // Create udp4 io for output with local default address.
290 UdpService
->Output
= UdpIoCreateIo (
291 UdpService
->NicHandle
,
292 UdpService
->ImageHandle
,
295 &UdpService
->DefaultAddress
298 if (UdpService
->Output
== NULL
) {
299 Status
= EFI_OUT_OF_RESOURCES
;
305 // Create udp6 io for output with remote address.
307 UdpService
->Output
= UdpIoCreateIo (
308 UdpService
->NicHandle
,
309 UdpService
->ImageHandle
,
315 if (UdpService
->Output
== NULL
) {
316 Status
= EFI_OUT_OF_RESOURCES
;
320 // Get ip6 mode data to get the result of source address selection.
322 ZeroMem (&Ip6ModeData
, sizeof (EFI_IP6_MODE_DATA
));
324 Udp6
= UdpService
->Output
->Protocol
.Udp6
;
325 Status
= Udp6
->GetModeData (Udp6
, NULL
, &Ip6ModeData
, NULL
, NULL
);
327 if (EFI_ERROR (Status
)) {
328 UdpIoFreeIo (UdpService
->Output
);
332 if (Ip6ModeData
.AddressList
!= NULL
) {
333 FreePool (Ip6ModeData
.AddressList
);
336 if (Ip6ModeData
.GroupTable
!= NULL
) {
337 FreePool (Ip6ModeData
.GroupTable
);
340 if (Ip6ModeData
.RouteTable
!= NULL
) {
341 FreePool (Ip6ModeData
.RouteTable
);
344 if (Ip6ModeData
.NeighborCache
!= NULL
) {
345 FreePool (Ip6ModeData
.NeighborCache
);
348 if (Ip6ModeData
.PrefixTable
!= NULL
) {
349 FreePool (Ip6ModeData
.PrefixTable
);
352 if (Ip6ModeData
.IcmpTypeList
!= NULL
) {
353 FreePool (Ip6ModeData
.IcmpTypeList
);
357 // Reconfigure udp6 io without remote address.
359 Udp6
->Configure (Udp6
, NULL
);
360 Status
= IkeConfigUdp6 (UdpService
->Output
, NULL
);
363 // Record the selected source address for ipsec process later.
366 &UdpService
->DefaultAddress
.v6
,
367 &Ip6ModeData
.ConfigData
.StationAddress
,
368 sizeof (EFI_IPv6_ADDRESS
)
372 UdpService
->IsConfigured
= TRUE
;
375 if (IfInfo
!= NULL
) {
383 Open and configure a UDPIO of Udp4 for IKE packet receiving.
385 This function is called at the IPsecDriverBinding start. IPsec create a UDP4 and
386 UDP4 IO for each NIC handle.
388 @param[in] Private Point to IPSEC_PRIVATE_DATA
389 @param[in] Controller Handler for NIC card.
390 @param[in] ImageHandle The handle that contains the EFI_DRIVER_BINDING_PROTOCOL instance.
392 @retval EFI_SUCCESS The Operation is successful.
393 @retval EFI_OUT_OF_RESOURCE The required system resource can't be allocated.
398 IN IPSEC_PRIVATE_DATA
*Private
,
399 IN EFI_HANDLE Controller
,
400 IN EFI_HANDLE ImageHandle
403 IKE_UDP_SERVICE
*Udp4Srv
;
406 // Check whether udp4 io of the controller has already been opened.
408 Udp4Srv
= IkeLookupUdp (Private
, Controller
, IP_VERSION_4
);
410 if (Udp4Srv
!= NULL
) {
411 return EFI_ALREADY_STARTED
;
414 Udp4Srv
= AllocateZeroPool (sizeof (IKE_UDP_SERVICE
));
416 if (Udp4Srv
== NULL
) {
417 return EFI_OUT_OF_RESOURCES
;
420 // Create udp4 io for iutput.
422 Udp4Srv
->Input
= UdpIoCreateIo (
430 if (Udp4Srv
->Input
== NULL
) {
432 return EFI_OUT_OF_RESOURCES
;
435 Udp4Srv
->NicHandle
= Controller
;
436 Udp4Srv
->ImageHandle
= ImageHandle
;
437 Udp4Srv
->ListHead
= &(Private
->Udp4List
);
438 Udp4Srv
->IpVersion
= UDP_IO_UDP4_VERSION
;
439 Udp4Srv
->IsConfigured
= FALSE
;
441 ZeroMem (&Udp4Srv
->DefaultAddress
, sizeof (EFI_IP_ADDRESS
));
444 // Insert the udp4 io into the list and increase the count.
446 InsertTailList (&Private
->Udp4List
, &Udp4Srv
->List
);
450 UdpIoRecvDatagram (Udp4Srv
->Input
, IkeDispatch
, Udp4Srv
, 0);
456 Open and configure a UDPIO of Udp6 for IKE packet receiving.
458 This function is called at the IPsecDriverBinding start. IPsec create a UDP6 and UDP6
459 IO for each NIC handle.
461 @param[in] Private Point to IPSEC_PRIVATE_DATA
462 @param[in] Controller Handler for NIC card.
463 @param[in] ImageHandle The handle that contains the EFI_DRIVER_BINDING_PROTOCOL instance.
465 @retval EFI_SUCCESS The Operation is successful.
466 @retval EFI_OUT_OF_RESOURCE The required system resource can't be allocated.
471 IN IPSEC_PRIVATE_DATA
*Private
,
472 IN EFI_HANDLE Controller
,
473 IN EFI_HANDLE ImageHandle
476 IKE_UDP_SERVICE
*Udp6Srv
;
478 Udp6Srv
= IkeLookupUdp (Private
, Controller
, IP_VERSION_6
);
480 if (Udp6Srv
!= NULL
) {
481 return EFI_ALREADY_STARTED
;
484 Udp6Srv
= AllocateZeroPool (sizeof (IKE_UDP_SERVICE
));
486 if (Udp6Srv
== NULL
) {
487 return EFI_OUT_OF_RESOURCES
;
490 // Create udp6 io for input.
492 Udp6Srv
->Input
= UdpIoCreateIo (
500 if (Udp6Srv
->Input
== NULL
) {
502 return EFI_OUT_OF_RESOURCES
;
505 Udp6Srv
->NicHandle
= Controller
;
506 Udp6Srv
->ImageHandle
= ImageHandle
;
507 Udp6Srv
->ListHead
= &(Private
->Udp6List
);
508 Udp6Srv
->IpVersion
= UDP_IO_UDP6_VERSION
;
509 Udp6Srv
->IsConfigured
= FALSE
;
511 ZeroMem (&Udp6Srv
->DefaultAddress
, sizeof (EFI_IP_ADDRESS
));
514 // Insert the udp6 io into the list and increase the count.
516 InsertTailList (&Private
->Udp6List
, &Udp6Srv
->List
);
520 UdpIoRecvDatagram (Udp6Srv
->Input
, IkeDispatch
, Udp6Srv
, 0);
526 The general interface of starting IPsec Key Exchange.
528 This function is called when a IKE negotiation to start getting a Key.
530 @param[in] UdpService Point to IKE_UDP_SERVICE which will be used for
532 @param[in] SpdEntry Point to the SPD entry related to the IKE negotiation.
533 @param[in] RemoteIp Point to EFI_IP_ADDRESS related to the IKE negotiation.
535 @retval EFI_SUCCESS The Operation is successful.
536 @retval EFI_ACCESS_DENIED No related PAD entry was found.
537 @retval EFI_INVALID_PARAMETER The IKE version is not supported.
542 IN IKE_UDP_SERVICE
*UdpService
,
543 IN IPSEC_SPD_ENTRY
*SpdEntry
,
544 IN EFI_IP_ADDRESS
*RemoteIp
549 IKE_EXCHANGE_INTERFACE
*Exchange
;
550 IPSEC_PRIVATE_DATA
*Private
;
551 IPSEC_PAD_ENTRY
*PadEntry
;
554 Private
= (UdpService
->IpVersion
== IP_VERSION_4
) ?
555 IPSEC_PRIVATE_DATA_FROM_UDP4LIST(UdpService
->ListHead
) :
556 IPSEC_PRIVATE_DATA_FROM_UDP6LIST(UdpService
->ListHead
);
559 // Try to open udp io for output if it hasn't.
561 Status
= IkeOpenOutputUdp (UdpService
, RemoteIp
);
562 if (EFI_ERROR (Status
)) {
566 // Try to find the IKE SA session in the IKEv1 and IKEv2 established SA session list.
568 IkeSaSession
= (UINT8
*) Ikev2SaSessionLookup (&Private
->Ikev2EstablishedList
, RemoteIp
);
571 if (IkeSaSession
== NULL
) {
573 // Find the pad entry by the remote ip address.
575 PadEntry
= IpSecLookupPadEntry (UdpService
->IpVersion
, RemoteIp
);
576 if (PadEntry
== NULL
) {
577 return EFI_ACCESS_DENIED
;
580 // Determine the IKE exchange instance by the auth protocol in pad entry.
582 ASSERT (PadEntry
->Data
->AuthProtocol
< EfiIPsecAuthProtocolMaximum
);
583 if (PadEntry
->Data
->AuthProtocol
== EfiIPsecAuthProtocolIKEv1
) {
584 return EFI_INVALID_PARAMETER
;
586 Exchange
= mIkeExchange
[PadEntry
->Data
->AuthProtocol
];
588 // Start the main mode stage to negotiate IKE SA.
590 Status
= Exchange
->NegotiateSa (UdpService
, SpdEntry
, PadEntry
, RemoteIp
);
593 // Determine the IKE exchange instance by the IKE version in IKE SA session.
595 IkeVersion
= IkeGetVersionFromSession (IkeSaSession
);
596 if (IkeVersion
!= 2) {
597 return EFI_INVALID_PARAMETER
;
600 Exchange
= mIkeExchange
[IkeVersion
- 1];
602 // Start the quick mode stage to negotiate child SA.
604 Status
= Exchange
->NegotiateChildSa (IkeSaSession
, SpdEntry
, NULL
);
611 The generic interface when receive a IKE packet.
613 This function is called when UDP IO receives a IKE packet.
615 @param[in] Packet Point to received IKE packet.
616 @param[in] EndPoint Point to UDP_END_POINT which contains the information of
618 @param[in] IoStatus The Status of Recieve Token.
619 @param[in] Context Point to data passed from the caller.
626 IN UDP_END_POINT
*EndPoint
,
627 IN EFI_STATUS IoStatus
,
631 IPSEC_PRIVATE_DATA
*Private
;
632 IKE_PACKET
*IkePacket
;
634 IKE_UDP_SERVICE
*UdpService
;
635 IKE_EXCHANGE_INTERFACE
*Exchange
;
638 UdpService
= (IKE_UDP_SERVICE
*) Context
;
640 Private
= (UdpService
->IpVersion
== IP_VERSION_4
) ?
641 IPSEC_PRIVATE_DATA_FROM_UDP4LIST(UdpService
->ListHead
) :
642 IPSEC_PRIVATE_DATA_FROM_UDP6LIST(UdpService
->ListHead
);
644 if (EFI_ERROR (IoStatus
)) {
648 // Check whether the ipsec is enabled or not.
650 if (Private
->IpSec
.DisabledFlag
== TRUE
) {
654 if (EndPoint
->RemotePort
!= IKE_DEFAULT_PORT
) {
659 // Build IKE packet from the received netbuf.
661 IkePacket
= IkePacketFromNetbuf (Packet
);
663 if (IkePacket
== NULL
) {
667 // Get the remote address from the IKE packet.
669 if (UdpService
->IpVersion
== IP_VERSION_4
) {
670 *(UINT32
*) IkePacket
->RemotePeerIp
.Addr
= HTONL ((*(UINT32
*) EndPoint
->RemoteAddr
.Addr
));
673 &IkePacket
->RemotePeerIp
,
674 NTOHLLL (&EndPoint
->RemoteAddr
.v6
),
675 sizeof (EFI_IPv6_ADDRESS
)
679 // Try to open udp io for output if hasn't.
681 Status
= IkeOpenOutputUdp (UdpService
, &IkePacket
->RemotePeerIp
);
683 if (EFI_ERROR (Status
)) {
687 IkeHdr
= IkePacket
->Header
;
690 // Determine the IKE exchange instance by the IKE version in IKE header.
692 if (IKE_MAJOR_VERSION (IkeHdr
->Version
) == 2) {
693 Exchange
= mIkeExchange
[IKE_MAJOR_VERSION (IkeHdr
->Version
) - 1];
698 switch (IkeHdr
->ExchangeType
) {
699 case IKE_XCG_TYPE_IDENTITY_PROTECT
:
700 case IKE_XCG_TYPE_SA_INIT
:
701 case IKE_XCG_TYPE_AUTH
:
702 Exchange
->HandleSa (UdpService
, IkePacket
);
705 case IKE_XCG_TYPE_QM
:
706 case IKE_XCG_TYPE_CREATE_CHILD_SA
:
707 Exchange
->HandleChildSa (UdpService
, IkePacket
);
710 case IKE_XCG_TYPE_INFO
:
711 case IKE_XCG_TYPE_INFO2
:
712 Exchange
->HandleInfo (UdpService
, IkePacket
);
720 if (IkePacket
!= NULL
) {
721 IkePacketFree (IkePacket
);
724 if (Packet
!= NULL
) {
728 UdpIoRecvDatagram (UdpService
->Input
, IkeDispatch
, UdpService
, 0);
734 Delete all established IKE SAs and related Child SAs.
736 This function is the subfunction of the IpSecCleanupAllSa(). It first calls
737 IkeDeleteChildSa() to delete all Child SAs then send out the related
740 @param[in] Private Pointer of the IPSEC_PRIVATE_DATA
741 @param[in] IsDisableIpsec Indicate whether needs to disable IPsec.
746 IN IPSEC_PRIVATE_DATA
*Private
,
747 IN BOOLEAN IsDisableIpsec
751 LIST_ENTRY
*NextEntry
;
752 IKEV2_SA_SESSION
*Ikev2SaSession
;
755 IKE_EXCHANGE_INTERFACE
*Exchange
;
761 // If the IKEv1 is supported, first deal with the Ikev1Estatblished list.
765 // If IKEv2 SAs are under establishing, delete it directly.
767 if (!IsListEmpty (&Private
->Ikev2SessionList
)) {
768 NET_LIST_FOR_EACH_SAFE (Entry
, NextEntry
, &Private
->Ikev2SessionList
) {
769 Ikev2SaSession
= IKEV2_SA_SESSION_BY_SESSION (Entry
);
770 RemoveEntryList (Entry
);
771 Ikev2SaSessionFree (Ikev2SaSession
);
776 // If there is no existing established IKE SA, set the Ipsec DisableFlag to TRUE
777 // and turn off the IsIPsecDisabling flag.
779 if (IsListEmpty (&Private
->Ikev2EstablishedList
) && IsDisableIpsec
) {
780 Value
= IPSEC_STATUS_DISABLED
;
781 Status
= gRT
->SetVariable (
782 IPSECCONFIG_STATUS_NAME
,
783 &gEfiIpSecConfigProtocolGuid
,
784 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
788 if (!EFI_ERROR (Status
)) {
789 Private
->IpSec
.DisabledFlag
= TRUE
;
790 Private
->IsIPsecDisabling
= FALSE
;
796 // Delete established IKEv2 SAs.
798 if (!IsListEmpty (&Private
->Ikev2EstablishedList
)) {
799 for (Entry
= Private
->Ikev2EstablishedList
.ForwardLink
; Entry
!= &Private
->Ikev2EstablishedList
;) {
800 Ikev2SaSession
= IKEV2_SA_SESSION_BY_SESSION (Entry
);
801 Entry
= Entry
->ForwardLink
;
803 Ikev2SaSession
->SessionCommon
.State
= IkeStateSaDeleting
;
806 // Call for Information Exchange.
808 IkeVersion
= IkeGetVersionFromSession ((UINT8
*)Ikev2SaSession
);
809 if (IkeVersion
== 2) {
810 Exchange
= mIkeExchange
[IkeVersion
- 1];
811 Exchange
->NegotiateInfo((UINT8
*)Ikev2SaSession
, NULL
);