]> git.proxmox.com Git - mirror_edk2.git/blob - NetworkPkg/IpSecDxe/IkeService.c
BaseTools/Capsule: Do not support -o with --dump-info
[mirror_edk2.git] / NetworkPkg / IpSecDxe / IkeService.c
1 /** @file
2 Provide IPsec Key Exchange (IKE) service general interfaces.
3
4 Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
5
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.
10
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.
13
14 **/
15
16 #include "IkeService.h"
17 #include "IpSecConfigImpl.h"
18
19 IKE_EXCHANGE_INTERFACE *mIkeExchange[] = {
20 &mIkev1Exchange,
21 &mIkev2Exchange
22 };
23
24 EFI_UDP4_CONFIG_DATA mUdp4Conf = {
25 FALSE,
26 FALSE,
27 FALSE,
28 TRUE,
29 //
30 // IO parameters
31 //
32 0,
33 64,
34 FALSE,
35 0,
36 1000000,
37 FALSE,
38 {{0,0,0,0}},
39 {{0,0,0,0}},
40 IKE_DEFAULT_PORT,
41 {{0,0,0,0}},
42 0
43 };
44
45 EFI_UDP6_CONFIG_DATA mUdp6Conf = {
46 FALSE,
47 FALSE,
48 TRUE,
49 //
50 // IO parameters
51 //
52 0,
53 128,
54 0,
55 1000000,
56 //Access Point
57 {{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},
58 IKE_DEFAULT_PORT,
59 {{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},
60 0
61 };
62
63 /**
64 Check if the NIC handle is binded to a Udp service.
65
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.
69
70 @return a pointer of IKE_UDP_SERVICE.
71
72 **/
73 IKE_UDP_SERVICE *
74 IkeLookupUdp (
75 IN IPSEC_PRIVATE_DATA *Private,
76 IN EFI_HANDLE Handle,
77 IN UINT8 IpVersion
78 )
79 {
80 LIST_ENTRY *Head;
81 LIST_ENTRY *Entry;
82 LIST_ENTRY *Next;
83 IKE_UDP_SERVICE *Udp;
84
85 Udp = NULL;
86 Head = (IpVersion == IP_VERSION_4) ? &Private->Udp4List : &Private->Udp6List;
87
88 NET_LIST_FOR_EACH_SAFE (Entry, Next, Head) {
89
90 Udp = IPSEC_UDP_SERVICE_FROM_LIST (Entry);
91 //
92 // Find the right udp service which installed on the appointed NIC handle.
93 //
94 if (Handle == Udp->NicHandle) {
95 break;
96 } else {
97 Udp = NULL;
98 }
99 }
100
101 return Udp;
102 }
103
104 /**
105 Configure a UDPIO's UDP4 instance.
106
107 This fuction is called by the UdpIoCreateIo() to configures a
108 UDP4 instance.
109
110 @param[in] UdpIo The UDP_IO to be configured.
111 @param[in] Context User-defined data when calling UdpIoCreateIo().
112
113 @retval EFI_SUCCESS The configuration succeeded.
114 @retval Others The UDP4 instance fails to configure.
115
116 **/
117 EFI_STATUS
118 EFIAPI
119 IkeConfigUdp4 (
120 IN UDP_IO *UdpIo,
121 IN VOID *Context
122 )
123 {
124 EFI_UDP4_CONFIG_DATA Udp4Cfg;
125 EFI_UDP4_PROTOCOL *Udp4;
126
127 ZeroMem (&Udp4Cfg, sizeof (EFI_UDP4_CONFIG_DATA));
128
129 Udp4 = UdpIo->Protocol.Udp4;
130 CopyMem (
131 &Udp4Cfg,
132 &mUdp4Conf,
133 sizeof (EFI_UDP4_CONFIG_DATA)
134 );
135
136 if (Context != NULL) {
137 //
138 // Configure udp4 io with local default address.
139 //
140 Udp4Cfg.UseDefaultAddress = TRUE;
141 }
142
143 return Udp4->Configure (Udp4, &Udp4Cfg);
144 }
145
146 /**
147 Configure a UDPIO's UDP6 instance.
148
149 This fuction is called by the UdpIoCreateIo()to configure a
150 UDP6 instance.
151
152 @param[in] UdpIo The UDP_IO to be configured.
153 @param[in] Context User-defined data when calling UdpIoCreateIo().
154
155 @retval EFI_SUCCESS The configuration succeeded.
156 @retval Others The configuration fails.
157
158 **/
159 EFI_STATUS
160 EFIAPI
161 IkeConfigUdp6 (
162 IN UDP_IO *UdpIo,
163 IN VOID *Context
164 )
165 {
166 EFI_UDP6_PROTOCOL *Udp6;
167 EFI_UDP6_CONFIG_DATA Udp6Cfg;
168
169 ZeroMem (&Udp6Cfg, sizeof (EFI_UDP6_CONFIG_DATA));
170
171 Udp6 = UdpIo->Protocol.Udp6;
172 CopyMem (
173 &Udp6Cfg,
174 &mUdp6Conf,
175 sizeof (EFI_UDP6_CONFIG_DATA)
176 );
177
178 if (Context != NULL) {
179 //
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.
183 //
184 CopyMem (
185 &Udp6Cfg.RemoteAddress,
186 Context,
187 sizeof (EFI_IPv6_ADDRESS)
188 );
189 }
190
191 return Udp6->Configure (Udp6, &Udp6Cfg);
192 }
193
194 /**
195 Open and configure the related output UDPIO for IKE packet sending.
196
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.
200
201 @param[in] UdpService The UDP_IO to be configured.
202 @param[in] RemoteIp User-defined data when calling UdpIoCreateIo().
203
204 @retval EFI_SUCCESS The configuration is successful.
205 @retval Others The configuration fails.
206
207 **/
208 EFI_STATUS
209 IkeOpenOutputUdp (
210 IN IKE_UDP_SERVICE *UdpService,
211 IN EFI_IP_ADDRESS *RemoteIp
212 )
213 {
214 EFI_STATUS Status;
215 EFI_IP4_CONFIG2_PROTOCOL *Ip4Cfg2;
216 EFI_IP4_CONFIG2_INTERFACE_INFO *IfInfo;
217 UINTN BufSize;
218 EFI_IP6_MODE_DATA Ip6ModeData;
219 EFI_UDP6_PROTOCOL *Udp6;
220
221 Status = EFI_SUCCESS;
222 IfInfo = NULL;
223 BufSize = 0;
224
225 //
226 // Check whether the input and output udp io are both configured.
227 //
228 if (UdpService->IsConfigured) {
229 goto ON_EXIT;
230 }
231
232 if (UdpService->IpVersion == UDP_IO_UDP4_VERSION) {
233 //
234 // Handle ip4config protocol to get local default address.
235 //
236 Status = gBS->HandleProtocol (
237 UdpService->NicHandle,
238 &gEfiIp4Config2ProtocolGuid,
239 (VOID **) &Ip4Cfg2
240 );
241
242 if (EFI_ERROR (Status)) {
243 goto ON_EXIT;
244 }
245
246 //
247 // Get the interface information size.
248 //
249 Status = Ip4Cfg2->GetData (
250 Ip4Cfg2,
251 Ip4Config2DataTypeInterfaceInfo,
252 &BufSize,
253 NULL
254 );
255
256 if (EFI_ERROR (Status) && Status != EFI_BUFFER_TOO_SMALL) {
257 goto ON_EXIT;
258 }
259
260 IfInfo = AllocateZeroPool (BufSize);
261
262 if (IfInfo == NULL) {
263 Status = EFI_OUT_OF_RESOURCES;
264 goto ON_EXIT;
265 }
266
267 //
268 // Get the interface info.
269 //
270 Status = Ip4Cfg2->GetData (
271 Ip4Cfg2,
272 Ip4Config2DataTypeInterfaceInfo,
273 &BufSize,
274 IfInfo
275 );
276
277 if (EFI_ERROR (Status)) {
278 goto ON_EXIT;
279 }
280
281 CopyMem (
282 &UdpService->DefaultAddress.v4,
283 &IfInfo->StationAddress,
284 sizeof (EFI_IPv4_ADDRESS)
285 );
286
287 //
288 // Create udp4 io for output with local default address.
289 //
290 UdpService->Output = UdpIoCreateIo (
291 UdpService->NicHandle,
292 UdpService->ImageHandle,
293 IkeConfigUdp4,
294 UDP_IO_UDP4_VERSION,
295 &UdpService->DefaultAddress
296 );
297
298 if (UdpService->Output == NULL) {
299 Status = EFI_OUT_OF_RESOURCES;
300 goto ON_EXIT;
301 }
302
303 } else {
304 //
305 // Create udp6 io for output with remote address.
306 //
307 UdpService->Output = UdpIoCreateIo (
308 UdpService->NicHandle,
309 UdpService->ImageHandle,
310 IkeConfigUdp6,
311 UDP_IO_UDP6_VERSION,
312 RemoteIp
313 );
314
315 if (UdpService->Output == NULL) {
316 Status = EFI_OUT_OF_RESOURCES;
317 goto ON_EXIT;
318 }
319 //
320 // Get ip6 mode data to get the result of source address selection.
321 //
322 ZeroMem (&Ip6ModeData, sizeof (EFI_IP6_MODE_DATA));
323
324 Udp6 = UdpService->Output->Protocol.Udp6;
325 Status = Udp6->GetModeData (Udp6, NULL, &Ip6ModeData, NULL, NULL);
326
327 if (EFI_ERROR (Status)) {
328 UdpIoFreeIo (UdpService->Output);
329 goto ON_EXIT;
330 }
331
332 if (Ip6ModeData.AddressList != NULL) {
333 FreePool (Ip6ModeData.AddressList);
334 }
335
336 if (Ip6ModeData.GroupTable != NULL) {
337 FreePool (Ip6ModeData.GroupTable);
338 }
339
340 if (Ip6ModeData.RouteTable != NULL) {
341 FreePool (Ip6ModeData.RouteTable);
342 }
343
344 if (Ip6ModeData.NeighborCache != NULL) {
345 FreePool (Ip6ModeData.NeighborCache);
346 }
347
348 if (Ip6ModeData.PrefixTable != NULL) {
349 FreePool (Ip6ModeData.PrefixTable);
350 }
351
352 if (Ip6ModeData.IcmpTypeList != NULL) {
353 FreePool (Ip6ModeData.IcmpTypeList);
354 }
355
356 //
357 // Reconfigure udp6 io without remote address.
358 //
359 Udp6->Configure (Udp6, NULL);
360 Status = IkeConfigUdp6 (UdpService->Output, NULL);
361
362 //
363 // Record the selected source address for ipsec process later.
364 //
365 CopyMem (
366 &UdpService->DefaultAddress.v6,
367 &Ip6ModeData.ConfigData.StationAddress,
368 sizeof (EFI_IPv6_ADDRESS)
369 );
370 }
371
372 UdpService->IsConfigured = TRUE;
373
374 ON_EXIT:
375 if (IfInfo != NULL) {
376 FreePool (IfInfo);
377 }
378
379 return Status;
380 }
381
382 /**
383 Open and configure a UDPIO of Udp4 for IKE packet receiving.
384
385 This function is called at the IPsecDriverBinding start. IPsec create a UDP4 and
386 UDP4 IO for each NIC handle.
387
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.
391
392 @retval EFI_SUCCESS The Operation is successful.
393 @retval EFI_OUT_OF_RESOURCE The required system resource can't be allocated.
394
395 **/
396 EFI_STATUS
397 IkeOpenInputUdp4 (
398 IN IPSEC_PRIVATE_DATA *Private,
399 IN EFI_HANDLE Controller,
400 IN EFI_HANDLE ImageHandle
401 )
402 {
403 IKE_UDP_SERVICE *Udp4Srv;
404
405 //
406 // Check whether udp4 io of the controller has already been opened.
407 //
408 Udp4Srv = IkeLookupUdp (Private, Controller, IP_VERSION_4);
409
410 if (Udp4Srv != NULL) {
411 return EFI_ALREADY_STARTED;
412 }
413
414 Udp4Srv = AllocateZeroPool (sizeof (IKE_UDP_SERVICE));
415
416 if (Udp4Srv == NULL) {
417 return EFI_OUT_OF_RESOURCES;
418 }
419 //
420 // Create udp4 io for iutput.
421 //
422 Udp4Srv->Input = UdpIoCreateIo (
423 Controller,
424 ImageHandle,
425 IkeConfigUdp4,
426 UDP_IO_UDP4_VERSION,
427 NULL
428 );
429
430 if (Udp4Srv->Input == NULL) {
431 FreePool (Udp4Srv);
432 return EFI_OUT_OF_RESOURCES;
433 }
434
435 Udp4Srv->NicHandle = Controller;
436 Udp4Srv->ImageHandle = ImageHandle;
437 Udp4Srv->ListHead = &(Private->Udp4List);
438 Udp4Srv->IpVersion = UDP_IO_UDP4_VERSION;
439 Udp4Srv->IsConfigured = FALSE;
440
441 ZeroMem (&Udp4Srv->DefaultAddress, sizeof (EFI_IP_ADDRESS));
442
443 //
444 // Insert the udp4 io into the list and increase the count.
445 //
446 InsertTailList (&Private->Udp4List, &Udp4Srv->List);
447
448 Private->Udp4Num++;
449
450 UdpIoRecvDatagram (Udp4Srv->Input, IkeDispatch, Udp4Srv, 0);
451
452 return EFI_SUCCESS;
453 }
454
455 /**
456 Open and configure a UDPIO of Udp6 for IKE packet receiving.
457
458 This function is called at the IPsecDriverBinding start. IPsec create a UDP6 and UDP6
459 IO for each NIC handle.
460
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.
464
465 @retval EFI_SUCCESS The Operation is successful.
466 @retval EFI_OUT_OF_RESOURCE The required system resource can't be allocated.
467
468 **/
469 EFI_STATUS
470 IkeOpenInputUdp6 (
471 IN IPSEC_PRIVATE_DATA *Private,
472 IN EFI_HANDLE Controller,
473 IN EFI_HANDLE ImageHandle
474 )
475 {
476 IKE_UDP_SERVICE *Udp6Srv;
477
478 Udp6Srv = IkeLookupUdp (Private, Controller, IP_VERSION_6);
479
480 if (Udp6Srv != NULL) {
481 return EFI_ALREADY_STARTED;
482 }
483
484 Udp6Srv = AllocateZeroPool (sizeof (IKE_UDP_SERVICE));
485
486 if (Udp6Srv == NULL) {
487 return EFI_OUT_OF_RESOURCES;
488 }
489 //
490 // Create udp6 io for input.
491 //
492 Udp6Srv->Input = UdpIoCreateIo (
493 Controller,
494 ImageHandle,
495 IkeConfigUdp6,
496 UDP_IO_UDP6_VERSION,
497 NULL
498 );
499
500 if (Udp6Srv->Input == NULL) {
501 FreePool (Udp6Srv);
502 return EFI_OUT_OF_RESOURCES;
503 }
504
505 Udp6Srv->NicHandle = Controller;
506 Udp6Srv->ImageHandle = ImageHandle;
507 Udp6Srv->ListHead = &(Private->Udp6List);
508 Udp6Srv->IpVersion = UDP_IO_UDP6_VERSION;
509 Udp6Srv->IsConfigured = FALSE;
510
511 ZeroMem (&Udp6Srv->DefaultAddress, sizeof (EFI_IP_ADDRESS));
512
513 //
514 // Insert the udp6 io into the list and increase the count.
515 //
516 InsertTailList (&Private->Udp6List, &Udp6Srv->List);
517
518 Private->Udp6Num++;
519
520 UdpIoRecvDatagram (Udp6Srv->Input, IkeDispatch, Udp6Srv, 0);
521
522 return EFI_SUCCESS;
523 }
524
525 /**
526 The general interface of starting IPsec Key Exchange.
527
528 This function is called when a IKE negotiation to start getting a Key.
529
530 @param[in] UdpService Point to IKE_UDP_SERVICE which will be used for
531 IKE packet sending.
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.
534
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.
538
539 **/
540 EFI_STATUS
541 IkeNegotiate (
542 IN IKE_UDP_SERVICE *UdpService,
543 IN IPSEC_SPD_ENTRY *SpdEntry,
544 IN EFI_IP_ADDRESS *RemoteIp
545 )
546 {
547 EFI_STATUS Status;
548 UINT8 *IkeSaSession;
549 IKE_EXCHANGE_INTERFACE *Exchange;
550 IPSEC_PRIVATE_DATA *Private;
551 IPSEC_PAD_ENTRY *PadEntry;
552 UINT8 IkeVersion;
553
554 Private = (UdpService->IpVersion == IP_VERSION_4) ?
555 IPSEC_PRIVATE_DATA_FROM_UDP4LIST(UdpService->ListHead) :
556 IPSEC_PRIVATE_DATA_FROM_UDP6LIST(UdpService->ListHead);
557
558 //
559 // Try to open udp io for output if it hasn't.
560 //
561 Status = IkeOpenOutputUdp (UdpService, RemoteIp);
562 if (EFI_ERROR (Status)) {
563 return Status;
564 }
565 //
566 // Try to find the IKE SA session in the IKEv1 and IKEv2 established SA session list.
567 //
568 IkeSaSession = (UINT8 *) Ikev2SaSessionLookup (&Private->Ikev2EstablishedList, RemoteIp);
569
570
571 if (IkeSaSession == NULL) {
572 //
573 // Find the pad entry by the remote ip address.
574 //
575 PadEntry = IpSecLookupPadEntry (UdpService->IpVersion, RemoteIp);
576 if (PadEntry == NULL) {
577 return EFI_ACCESS_DENIED;
578 }
579 //
580 // Determine the IKE exchange instance by the auth protocol in pad entry.
581 //
582 ASSERT (PadEntry->Data->AuthProtocol < EfiIPsecAuthProtocolMaximum);
583 if (PadEntry->Data->AuthProtocol == EfiIPsecAuthProtocolIKEv1) {
584 return EFI_INVALID_PARAMETER;
585 }
586 Exchange = mIkeExchange[PadEntry->Data->AuthProtocol];
587 //
588 // Start the main mode stage to negotiate IKE SA.
589 //
590 Status = Exchange->NegotiateSa (UdpService, SpdEntry, PadEntry, RemoteIp);
591 } else {
592 //
593 // Determine the IKE exchange instance by the IKE version in IKE SA session.
594 //
595 IkeVersion = IkeGetVersionFromSession (IkeSaSession);
596 if (IkeVersion != 2) {
597 return EFI_INVALID_PARAMETER;
598 }
599
600 Exchange = mIkeExchange[IkeVersion - 1];
601 //
602 // Start the quick mode stage to negotiate child SA.
603 //
604 Status = Exchange->NegotiateChildSa (IkeSaSession, SpdEntry, NULL);
605 }
606
607 return Status;
608 }
609
610 /**
611 The generic interface when receive a IKE packet.
612
613 This function is called when UDP IO receives a IKE packet.
614
615 @param[in] Packet Point to received IKE packet.
616 @param[in] EndPoint Point to UDP_END_POINT which contains the information of
617 Remote IP and Port.
618 @param[in] IoStatus The Status of Recieve Token.
619 @param[in] Context Point to data passed from the caller.
620
621 **/
622 VOID
623 EFIAPI
624 IkeDispatch (
625 IN NET_BUF *Packet,
626 IN UDP_END_POINT *EndPoint,
627 IN EFI_STATUS IoStatus,
628 IN VOID *Context
629 )
630 {
631 IPSEC_PRIVATE_DATA *Private;
632 IKE_PACKET *IkePacket;
633 IKE_HEADER *IkeHdr;
634 IKE_UDP_SERVICE *UdpService;
635 IKE_EXCHANGE_INTERFACE *Exchange;
636 EFI_STATUS Status;
637
638 UdpService = (IKE_UDP_SERVICE *) Context;
639 IkePacket = NULL;
640 Private = (UdpService->IpVersion == IP_VERSION_4) ?
641 IPSEC_PRIVATE_DATA_FROM_UDP4LIST(UdpService->ListHead) :
642 IPSEC_PRIVATE_DATA_FROM_UDP6LIST(UdpService->ListHead);
643
644 if (EFI_ERROR (IoStatus)) {
645 goto ON_EXIT;
646 }
647 //
648 // Check whether the ipsec is enabled or not.
649 //
650 if (Private->IpSec.DisabledFlag == TRUE) {
651 goto ON_EXIT;
652 }
653
654 if (EndPoint->RemotePort != IKE_DEFAULT_PORT) {
655 goto ON_EXIT;
656 }
657
658 //
659 // Build IKE packet from the received netbuf.
660 //
661 IkePacket = IkePacketFromNetbuf (Packet);
662
663 if (IkePacket == NULL) {
664 goto ON_EXIT;
665 }
666 //
667 // Get the remote address from the IKE packet.
668 //
669 if (UdpService->IpVersion == IP_VERSION_4) {
670 *(UINT32 *) IkePacket->RemotePeerIp.Addr = HTONL ((*(UINT32 *) EndPoint->RemoteAddr.Addr));
671 } else {
672 CopyMem (
673 &IkePacket->RemotePeerIp,
674 NTOHLLL (&EndPoint->RemoteAddr.v6),
675 sizeof (EFI_IPv6_ADDRESS)
676 );
677 }
678 //
679 // Try to open udp io for output if hasn't.
680 //
681 Status = IkeOpenOutputUdp (UdpService, &IkePacket->RemotePeerIp);
682
683 if (EFI_ERROR (Status)) {
684 goto ON_EXIT;
685 }
686
687 IkeHdr = IkePacket->Header;
688
689 //
690 // Determine the IKE exchange instance by the IKE version in IKE header.
691 //
692 if (IKE_MAJOR_VERSION (IkeHdr->Version) == 2) {
693 Exchange = mIkeExchange[IKE_MAJOR_VERSION (IkeHdr->Version) - 1];
694 } else {
695 goto ON_EXIT;
696 }
697
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);
703 break;
704
705 case IKE_XCG_TYPE_QM:
706 case IKE_XCG_TYPE_CREATE_CHILD_SA:
707 Exchange->HandleChildSa (UdpService, IkePacket);
708 break;
709
710 case IKE_XCG_TYPE_INFO:
711 case IKE_XCG_TYPE_INFO2:
712 Exchange->HandleInfo (UdpService, IkePacket);
713 break;
714
715 default:
716 break;
717 }
718
719 ON_EXIT:
720 if (IkePacket != NULL) {
721 IkePacketFree (IkePacket);
722 }
723
724 if (Packet != NULL) {
725 NetbufFree (Packet);
726 }
727
728 UdpIoRecvDatagram (UdpService->Input, IkeDispatch, UdpService, 0);
729
730 return ;
731 }
732
733 /**
734 Delete all established IKE SAs and related Child SAs.
735
736 This function is the subfunction of the IpSecCleanupAllSa(). It first calls
737 IkeDeleteChildSa() to delete all Child SAs then send out the related
738 Information packet.
739
740 @param[in] Private Pointer of the IPSEC_PRIVATE_DATA
741 @param[in] IsDisableIpsec Indicate whether needs to disable IPsec.
742
743 **/
744 VOID
745 IkeDeleteAllSas (
746 IN IPSEC_PRIVATE_DATA *Private,
747 IN BOOLEAN IsDisableIpsec
748 )
749 {
750 LIST_ENTRY *Entry;
751 LIST_ENTRY *NextEntry;
752 IKEV2_SA_SESSION *Ikev2SaSession;
753 UINT8 Value;
754 EFI_STATUS Status;
755 IKE_EXCHANGE_INTERFACE *Exchange;
756 UINT8 IkeVersion;
757
758 Exchange = NULL;
759
760 //
761 // If the IKEv1 is supported, first deal with the Ikev1Estatblished list.
762 //
763
764 //
765 // If IKEv2 SAs are under establishing, delete it directly.
766 //
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);
772 }
773 }
774
775 //
776 // If there is no existing established IKE SA, set the Ipsec DisableFlag to TRUE
777 // and turn off the IsIPsecDisabling flag.
778 //
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,
785 sizeof (Value),
786 &Value
787 );
788 if (!EFI_ERROR (Status)) {
789 Private->IpSec.DisabledFlag = TRUE;
790 Private->IsIPsecDisabling = FALSE;
791 return ;
792 }
793 }
794
795 //
796 // Delete established IKEv2 SAs.
797 //
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;
802
803 Ikev2SaSession->SessionCommon.State = IkeStateSaDeleting;
804
805 //
806 // Call for Information Exchange.
807 //
808 IkeVersion = IkeGetVersionFromSession ((UINT8*)Ikev2SaSession);
809 if (IkeVersion == 2) {
810 Exchange = mIkeExchange[IkeVersion - 1];
811 Exchange->NegotiateInfo((UINT8*)Ikev2SaSession, NULL);
812 }
813 }
814 }
815
816 }
817
818
819