1 /** @file 2 Provide IPsec Key Exchange (IKE) service general interfaces. 3 4 Copyright (c) 2010 - 2016, 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 820