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