1 /** @file 2 The general interfaces of the IKEv2. 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 "Utility.h" 17 #include "IpSecDebug.h" 18 #include "IkeService.h" 19 #include "IpSecConfigImpl.h" 20 21 /** 22 General interface to intialize a IKEv2 negotiation. 23 24 @param[in] UdpService Point to Udp Servcie used for the IKE packet sending. 25 @param[in] SpdEntry Point to SPD entry related to this IKE negotiation. 26 @param[in] PadEntry Point to PAD entry related to this IKE negotiation. 27 @param[in] RemoteIp Point to IP Address which the remote peer to negnotiate. 28 29 @retval EFI_SUCCESS The operation is successful. 30 @retval EFI_OUT_OF_RESOURCES The required system resource can't be allocated. 31 @retval EFI_INVALID_PARAMETER If UdpService or RemoteIp is NULL. 32 @return Others The operation is failed. 33 34 **/ 35 EFI_STATUS 36 Ikev2NegotiateSa ( 37 IN IKE_UDP_SERVICE *UdpService, 38 IN IPSEC_SPD_ENTRY *SpdEntry, 39 IN IPSEC_PAD_ENTRY *PadEntry, 40 IN EFI_IP_ADDRESS *RemoteIp 41 ) 42 { 43 IPSEC_PRIVATE_DATA *Private; 44 IKEV2_SA_SESSION *IkeSaSession; 45 IKEV2_SESSION_COMMON *SessionCommon; 46 IKEV2_PACKET_HANDLER Handler; 47 IKE_PACKET *IkePacket; 48 EFI_STATUS Status; 49 50 if (UdpService == NULL || RemoteIp == NULL) { 51 return EFI_INVALID_PARAMETER; 52 } 53 54 IkePacket = NULL; 55 Private = (UdpService->IpVersion == IP_VERSION_4) ? 56 IPSEC_PRIVATE_DATA_FROM_UDP4LIST(UdpService->ListHead) : 57 IPSEC_PRIVATE_DATA_FROM_UDP6LIST(UdpService->ListHead); 58 59 // 60 // Lookup the remote ip address in the processing IKE SA session list. 61 // 62 IkeSaSession = Ikev2SaSessionLookup (&Private->Ikev2SessionList, RemoteIp); 63 if (IkeSaSession != NULL) { 64 // 65 // Drop the packet if already in process. 66 // 67 return EFI_SUCCESS; 68 } 69 70 // 71 // Create a new IkeSaSession and initiate the common parameters. 72 // 73 IkeSaSession = Ikev2SaSessionAlloc (Private, UdpService); 74 if (IkeSaSession == NULL) { 75 return EFI_OUT_OF_RESOURCES; 76 } 77 78 // 79 // Set the specific parameters and state(IKE_STATE_INIT). 80 // 81 IkeSaSession->Spd = SpdEntry; 82 IkeSaSession->Pad = PadEntry; 83 SessionCommon = &IkeSaSession->SessionCommon; 84 SessionCommon->IsInitiator = TRUE; 85 SessionCommon->State = IkeStateInit; 86 // 87 // TODO: Get the prefer DH Group from the IPsec Configuration, after the IPsecconfig application update 88 // to support it. 89 // 90 SessionCommon->PreferDhGroup = IKEV2_TRANSFORM_ID_DH_1024MODP; 91 92 CopyMem ( 93 &SessionCommon->RemotePeerIp, 94 RemoteIp, 95 sizeof (EFI_IP_ADDRESS) 96 ); 97 98 CopyMem ( 99 &SessionCommon->LocalPeerIp, 100 &UdpService->DefaultAddress, 101 sizeof (EFI_IP_ADDRESS) 102 ); 103 104 IKEV2_DUMP_STATE (SessionCommon->State, IkeStateInit); 105 106 // 107 // Initiate the SAD data of the IkeSaSession. 108 // 109 IkeSaSession->SaData = Ikev2InitializeSaData (SessionCommon); 110 if (IkeSaSession->SaData == NULL) { 111 Status = EFI_OUT_OF_RESOURCES; 112 goto ON_ERROR; 113 } 114 115 // 116 // Generate an IKE request packet and send it out. 117 // 118 Handler = mIkev2Initial[IkeSaSession->Pad->Data->AuthMethod][SessionCommon->State]; 119 IkePacket = Handler.Generator ((UINT8 *) IkeSaSession, NULL); 120 if (IkePacket == NULL) { 121 Status = EFI_OUT_OF_RESOURCES; 122 goto ON_ERROR; 123 } 124 125 Status = Ikev2SendIkePacket (UdpService, (UINT8 *) SessionCommon, IkePacket, 0); 126 127 if (EFI_ERROR (Status)) { 128 goto ON_ERROR; 129 } 130 131 // 132 // Insert the current IkeSaSession into the processing IKE SA list. 133 // 134 Ikev2SaSessionInsert (&Private->Ikev2SessionList, IkeSaSession, RemoteIp); 135 136 return EFI_SUCCESS; 137 138 ON_ERROR: 139 140 if (IkePacket != NULL) { 141 IkePacketFree (IkePacket); 142 } 143 Ikev2SaSessionFree (IkeSaSession); 144 return Status; 145 } 146 147 /** 148 It is general interface to negotiate the Child SA. 149 150 There are three situations which will invoke this function. First, create a CHILD 151 SA if the input Context is NULL. Second, rekeying the existing IKE SA if the Context 152 is a IKEv2_SA_SESSION. Third, rekeying the existing CHILD SA if the context is a 153 IKEv2_CHILD_SA_SESSION. 154 155 @param[in] IkeSaSession Pointer to IKEv2_SA_SESSION related to this operation. 156 @param[in] SpdEntry Pointer to IPSEC_SPD_ENTRY related to this operation. 157 @param[in] Context The data pass from the caller. 158 159 @retval EFI_SUCCESS The operation is successful. 160 @retval EFI_OUT_OF_RESOURCES The required system resource can't be allocated. 161 @retval EFI_UNSUPPORTED The condition is not support yet. 162 @return Others The operation is failed. 163 164 **/ 165 EFI_STATUS 166 Ikev2NegotiateChildSa ( 167 IN UINT8 *IkeSaSession, 168 IN IPSEC_SPD_ENTRY *SpdEntry, 169 IN UINT8 *Context 170 ) 171 { 172 EFI_STATUS Status; 173 IKEV2_SA_SESSION *SaSession; 174 IKEV2_CHILD_SA_SESSION *ChildSaSession; 175 IKEV2_SESSION_COMMON *ChildSaCommon; 176 IKE_PACKET *IkePacket; 177 IKE_UDP_SERVICE *UdpService; 178 179 SaSession = (IKEV2_SA_SESSION*) IkeSaSession; 180 UdpService = SaSession->SessionCommon.UdpService; 181 IkePacket = NULL; 182 183 // 184 // 1. Create another child SA session if context is null. 185 // 2. Rekeying the IKE SA session if the context is IKE SA session. 186 // 3. Rekeying the child SA session if the context is child SA session. 187 // 188 if (Context == NULL) { 189 // 190 // Create a new ChildSaSession and initiate the common parameters. 191 // 192 ChildSaSession = Ikev2ChildSaSessionAlloc (UdpService, SaSession); 193 194 if (ChildSaSession == NULL) { 195 return EFI_OUT_OF_RESOURCES; 196 } 197 198 // 199 // Set the specific parameters and state as IKE_STATE_CREATE_CHILD. 200 // 201 ChildSaSession->Spd = SpdEntry; 202 ChildSaCommon = &ChildSaSession->SessionCommon; 203 ChildSaCommon->IsInitiator = TRUE; 204 ChildSaCommon->State = IkeStateCreateChild; 205 206 IKEV2_DUMP_STATE (ChildSaCommon->State, IkeStateCreateChild); 207 208 if (SpdEntry->Selector->NextLayerProtocol != EFI_IPSEC_ANY_PROTOCOL) { 209 ChildSaSession->ProtoId = SpdEntry->Selector->NextLayerProtocol; 210 } 211 212 if (SpdEntry->Selector->LocalPort != EFI_IPSEC_ANY_PORT) { 213 ChildSaSession->LocalPort = SpdEntry->Selector->LocalPort; 214 } 215 216 if (SpdEntry->Selector->RemotePort != EFI_IPSEC_ANY_PORT) { 217 ChildSaSession->RemotePort = SpdEntry->Selector->RemotePort; 218 } 219 // 220 // Initiate the SAD data parameters of the ChildSaSession. 221 // 222 ChildSaSession->SaData = Ikev2InitializeSaData (ChildSaCommon); 223 if (ChildSaSession->SaData == NULL) { 224 Status = EFI_OUT_OF_RESOURCES; 225 goto ON_ERROR; 226 } 227 // 228 // Generate an IKE request packet and send it out. 229 // 230 IkePacket = mIkev2CreateChild.Generator ((UINT8 *) ChildSaSession, NULL); 231 232 if (IkePacket == NULL) { 233 Status = EFI_OUT_OF_RESOURCES; 234 goto ON_ERROR; 235 } 236 237 Status = Ikev2SendIkePacket (UdpService, (UINT8 *) ChildSaCommon, IkePacket, 0); 238 239 if (EFI_ERROR (Status)) { 240 goto ON_ERROR; 241 } 242 243 // 244 // Insert the ChildSaSession into processing child SA list. 245 // 246 Ikev2ChildSaSessionInsert (&SaSession->ChildSaSessionList, ChildSaSession); 247 } else { 248 // 249 // TODO: Rekeying IkeSaSession or ChildSaSession, NOT support yet. 250 // 251 // Rekey IkeSa, set IkeSaSession->State and pass over IkeSaSession 252 // Rekey ChildSa, set ChildSaSession->State and pass over ChildSaSession 253 // 254 return EFI_UNSUPPORTED; 255 } 256 257 return EFI_SUCCESS; 258 259 ON_ERROR: 260 261 if (ChildSaSession->SaData != NULL) { 262 FreePool (ChildSaSession->SaData); 263 } 264 265 if (ChildSaSession->SessionCommon.TimeoutEvent != NULL) { 266 gBS->CloseEvent (ChildSaSession->SessionCommon.TimeoutEvent); 267 } 268 269 if (IkePacket != NULL) { 270 IkePacketFree (IkePacket); 271 } 272 273 Ikev2ChildSaSessionFree (ChildSaSession); 274 return Status; 275 } 276 277 /** 278 It is general interface to start the Information Exchange. 279 280 There are three situations which will invoke this function. First, deliver a Delete Information 281 to delete the IKE SA if the input Context is NULL and the state of related IkeSaSeesion's is on 282 deleting.Second, deliver a Notify Information without the contents if the input Context is NULL. 283 Third, deliver a Notify Information if the input Context is not NULL. 284 285 @param[in] IkeSaSession Pointer to IKEv2_SA_SESSION related to this operation. 286 @param[in] Context Data passed by caller. 287 288 @retval EFI_SUCCESS The operation is successful. 289 @retval EFI_OUT_OF_RESOURCES The required system resource can't be allocated. 290 @retval EFI_UNSUPPORTED The condition is not support yet. 291 @return Otherwise The operation is failed. 292 293 **/ 294 EFI_STATUS 295 Ikev2NegotiateInfo ( 296 IN UINT8 *IkeSaSession, 297 IN UINT8 *Context 298 ) 299 { 300 301 EFI_STATUS Status; 302 IKEV2_SA_SESSION *Ikev2SaSession; 303 IKEV2_CHILD_SA_SESSION *ChildSaSession; 304 IKEV2_SESSION_COMMON *SaCommon; 305 IKE_PACKET *IkePacket; 306 IKE_UDP_SERVICE *UdpService; 307 LIST_ENTRY *Entry; 308 LIST_ENTRY *NextEntry; 309 310 Ikev2SaSession = (IKEV2_SA_SESSION *) IkeSaSession; 311 UdpService = Ikev2SaSession->SessionCommon.UdpService; 312 SaCommon = &Ikev2SaSession->SessionCommon; 313 IkePacket = NULL; 314 Status = EFI_SUCCESS; 315 316 // 317 // Delete the IKE SA. 318 // 319 if (Ikev2SaSession->SessionCommon.State == IkeStateSaDeleting && Context == NULL) { 320 321 // 322 // Generate Information Packet which contains the Delete Payload. 323 // 324 IkePacket = mIkev2Info.Generator ((UINT8 *) Ikev2SaSession, NULL); 325 if (IkePacket == NULL) { 326 Status = EFI_OUT_OF_RESOURCES; 327 goto ON_ERROR; 328 } 329 330 // 331 // Send out the Packet 332 // 333 if (UdpService != NULL && UdpService->Output != NULL) { 334 Status = Ikev2SendIkePacket (UdpService, (UINT8 *) SaCommon, IkePacket, 0); 335 336 if (EFI_ERROR (Status)) { 337 goto ON_ERROR; 338 } 339 } 340 } else if (!IsListEmpty (&Ikev2SaSession->DeleteSaList)) { 341 // 342 // Iterate all Deleting Child SAs. 343 // 344 NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &Ikev2SaSession->DeleteSaList) { 345 ChildSaSession = IKEV2_CHILD_SA_SESSION_BY_DEL_SA (Entry); 346 ChildSaSession->SessionCommon.State = IkeStateSaDeleting; 347 348 // 349 // Generate Information Packet which contains the Child SA Delete Payload. 350 // 351 IkePacket = mIkev2Info.Generator ((UINT8 *) ChildSaSession, NULL); 352 if (IkePacket == NULL) { 353 Status = EFI_OUT_OF_RESOURCES; 354 goto ON_ERROR; 355 } 356 357 // 358 // Send out the Packet 359 // 360 if (UdpService != NULL && UdpService->Output != NULL) { 361 Status = Ikev2SendIkePacket (UdpService, (UINT8 *) &ChildSaSession->SessionCommon, IkePacket, 0); 362 363 if (EFI_ERROR (Status)) { 364 goto ON_ERROR; 365 } 366 } 367 } 368 } else if (Context == NULL) { 369 // 370 // TODO: Deliver null notification message. 371 // 372 } else if (Context != NULL) { 373 // 374 // TODO: Send out the Information Exchange which contains the Notify Payload. 375 // 376 } 377 ON_ERROR: 378 if (IkePacket != NULL) { 379 IkePacketFree (IkePacket); 380 } 381 return Status; 382 383 } 384 385 /** 386 The general interface when received a IKEv2 packet for the IKE SA establishing. 387 388 This function first find the related IKE SA Session according to the IKE packet's 389 remote IP. Then call the corresponding function to handle this IKE packet according 390 to the related IKE SA Session's State. 391 392 @param[in] UdpService Pointer of related UDP Service. 393 @param[in] IkePacket Data passed by caller. 394 395 **/ 396 VOID 397 Ikev2HandleSa ( 398 IN IKE_UDP_SERVICE *UdpService, 399 IN IKE_PACKET *IkePacket 400 ) 401 { 402 EFI_STATUS Status; 403 IKEV2_SA_SESSION *IkeSaSession; 404 IKEV2_CHILD_SA_SESSION *ChildSaSession; 405 IKEV2_SESSION_COMMON *IkeSaCommon; 406 IKEV2_SESSION_COMMON *ChildSaCommon; 407 IKEV2_PACKET_HANDLER Handler; 408 IKE_PACKET *Reply; 409 IPSEC_PAD_ENTRY *PadEntry; 410 IPSEC_PRIVATE_DATA *Private; 411 BOOLEAN IsNewSession; 412 413 Private = (UdpService->IpVersion == IP_VERSION_4) ? 414 IPSEC_PRIVATE_DATA_FROM_UDP4LIST(UdpService->ListHead) : 415 IPSEC_PRIVATE_DATA_FROM_UDP6LIST(UdpService->ListHead); 416 417 ChildSaSession = NULL; 418 ChildSaCommon = NULL; 419 420 // 421 // Lookup the remote ip address in the processing IKE SA session list. 422 // 423 IkeSaSession = Ikev2SaSessionLookup (&Private->Ikev2SessionList, &IkePacket->RemotePeerIp); 424 IsNewSession = FALSE; 425 426 if (IkeSaSession == NULL) { 427 // 428 // Lookup the remote ip address in the pad. 429 // 430 PadEntry = IpSecLookupPadEntry (UdpService->IpVersion, &IkePacket->RemotePeerIp); 431 if (PadEntry == NULL) { 432 // 433 // Drop the packet if no pad entry matched, this is the request from RFC 4301. 434 // 435 return ; 436 } 437 438 // 439 // Create a new IkeSaSession and initiate the common parameters. 440 // 441 IkeSaSession = Ikev2SaSessionAlloc (Private, UdpService); 442 if (IkeSaSession == NULL) { 443 return; 444 } 445 IkeSaSession->Pad = PadEntry; 446 IkeSaCommon = &IkeSaSession->SessionCommon; 447 IkeSaCommon->IsInitiator = FALSE; 448 IkeSaCommon->State = IkeStateInit; 449 450 IKEV2_DUMP_STATE (IkeSaCommon->State, IkeStateInit); 451 452 CopyMem ( 453 &IkeSaCommon->RemotePeerIp, 454 &IkePacket->RemotePeerIp, 455 sizeof (EFI_IP_ADDRESS) 456 ); 457 458 CopyMem ( 459 &IkeSaCommon->LocalPeerIp, 460 &UdpService->DefaultAddress, 461 sizeof (EFI_IP_ADDRESS) 462 ); 463 464 IsNewSession = TRUE; 465 } 466 467 // 468 // Validate the IKE packet header. 469 // 470 if (!Ikev2ValidateHeader (IkeSaSession, IkePacket->Header)) { 471 // 472 // Drop the packet if invalid IKE header. 473 // 474 goto ON_ERROR; 475 } 476 477 // 478 // Decode all the payloads in the IKE packet. 479 // 480 IkeSaCommon = &IkeSaSession->SessionCommon; 481 Status = Ikev2DecodePacket (IkeSaCommon, IkePacket, IkeSessionTypeIkeSa); 482 if (EFI_ERROR (Status)) { 483 goto ON_ERROR; 484 } 485 486 // 487 // Try to reate the first ChildSa Session of that IkeSaSession. 488 // If the IkeSaSession is responder, here will create the first ChildSaSession. 489 // 490 if (IkeSaCommon->State == IkeStateAuth && IsListEmpty(&IkeSaSession->ChildSaSessionList)) { 491 // 492 // Generate a piggyback child SA in IKE_STATE_AUTH state. 493 // 494 ASSERT (IsListEmpty (&IkeSaSession->ChildSaSessionList) && 495 IsListEmpty (&IkeSaSession->ChildSaEstablishSessionList)); 496 497 ChildSaSession = Ikev2ChildSaSessionCreate (IkeSaSession, UdpService); 498 if (ChildSaSession == NULL) { 499 goto ON_ERROR; 500 } 501 502 ChildSaCommon = &ChildSaSession->SessionCommon; 503 } 504 505 // 506 // Parse the IKE request packet according to the auth method and current state. 507 // 508 Handler = mIkev2Initial[IkeSaSession->Pad->Data->AuthMethod][IkeSaCommon->State]; 509 Status = Handler.Parser ((UINT8 *)IkeSaSession, IkePacket); 510 if (EFI_ERROR (Status)) { 511 goto ON_ERROR; 512 } 513 514 // 515 // Try to reate the first ChildSa Session of that IkeSaSession. 516 // If the IkeSaSession is initiator, here will create the first ChildSaSession. 517 // 518 if (IkeSaCommon->State == IkeStateAuth && IsListEmpty(&IkeSaSession->ChildSaSessionList)) { 519 // 520 // Generate a piggyback child SA in IKE_STATE_AUTH state. 521 // 522 ASSERT (IsListEmpty (&IkeSaSession->ChildSaSessionList) && 523 IsListEmpty (&IkeSaSession->ChildSaEstablishSessionList)); 524 525 ChildSaSession = Ikev2ChildSaSessionCreate (IkeSaSession, UdpService); 526 if (ChildSaSession == NULL) { 527 goto ON_ERROR; 528 } 529 530 ChildSaCommon = &ChildSaSession->SessionCommon; 531 532 // 533 // Initialize the SA data for Child SA. 534 // 535 ChildSaSession->SaData = Ikev2InitializeSaData (ChildSaCommon); 536 } 537 538 // 539 // Generate the IKE response packet and send it out if not established. 540 // 541 if (IkeSaCommon->State != IkeStateIkeSaEstablished) { 542 Handler = mIkev2Initial[IkeSaSession->Pad->Data->AuthMethod][IkeSaCommon->State]; 543 Reply = Handler.Generator ((UINT8 *) IkeSaSession, NULL); 544 if (Reply == NULL) { 545 goto ON_ERROR; 546 } 547 548 Status = Ikev2SendIkePacket (UdpService, (UINT8 *) IkeSaCommon, Reply, 0); 549 if (EFI_ERROR (Status)) { 550 goto ON_ERROR; 551 } 552 if (!IkeSaCommon->IsInitiator) { 553 IkeSaCommon->State ++; 554 IKEV2_DUMP_STATE (IkeSaCommon->State - 1, IkeSaCommon->State); 555 } 556 } 557 558 // 559 // Insert the new IkeSaSession into the Private processing IkeSaSession List. 560 // 561 if (IsNewSession) { 562 Ikev2SaSessionInsert (&Private->Ikev2SessionList, IkeSaSession, &IkePacket->RemotePeerIp); 563 } 564 565 // 566 // Register the IkeSaSession and remove it from processing list. 567 // 568 if (IkeSaCommon->State == IkeStateIkeSaEstablished) { 569 570 // 571 // Remove the Established IKE SA Session from the IKE SA Session Negotiating list 572 // and insert it into IKE SA Session Established list. 573 // 574 Ikev2SaSessionRemove (&Private->Ikev2SessionList, &IkePacket->RemotePeerIp); 575 Ikev2SaSessionReg (IkeSaSession, Private); 576 577 // 578 // Remove the Established Child SA Session from the IkeSaSession->ChildSaSessionList 579 // ,insert it into IkeSaSession->ChildSaEstablishSessionList and save this Child SA 580 // into SAD. 581 // 582 ChildSaSession = IKEV2_CHILD_SA_SESSION_BY_IKE_SA (IkeSaSession->ChildSaSessionList.BackLink); 583 Ikev2ChildSaSessionRemove ( 584 &IkeSaSession->ChildSaSessionList, 585 ChildSaSession->LocalPeerSpi, 586 IKEV2_ESTABLISHING_CHILDSA_LIST 587 ); 588 Ikev2ChildSaSessionReg (ChildSaSession, Private); 589 } 590 591 return ; 592 593 ON_ERROR: 594 if (ChildSaSession != NULL) { 595 // 596 // Remove the ChildSa from the list (Established list or Negotiating list). 597 // 598 RemoveEntryList (&ChildSaSession->ByIkeSa); 599 Ikev2ChildSaSessionFree (ChildSaSession); 600 } 601 602 if (IsNewSession && IkeSaSession != NULL) { 603 // 604 // Remove the IkeSa from the list (Established list or Negotiating list). 605 // 606 if ((&IkeSaSession->BySessionTable)->ForwardLink != NULL && 607 !IsListEmpty (&IkeSaSession->BySessionTable 608 )){ 609 RemoveEntryList (&IkeSaSession->BySessionTable); 610 } 611 Ikev2SaSessionFree (IkeSaSession); 612 } 613 614 return ; 615 } 616 617 /** 618 619 The general interface when received a IKEv2 packet for the IKE Child SA establishing 620 or IKE SA/CHILD SA rekeying. 621 622 This function first find the related IKE SA Session according to the IKE packet's 623 remote IP. Then call the corresponding function to handle this IKE packet according 624 to the related IKE Child Session's State. 625 626 @param[in] UdpService Pointer of related UDP Service. 627 @param[in] IkePacket Data passed by caller. 628 629 **/ 630 VOID 631 Ikev2HandleChildSa ( 632 IN IKE_UDP_SERVICE *UdpService, 633 IN IKE_PACKET *IkePacket 634 ) 635 { 636 EFI_STATUS Status; 637 IKEV2_SA_SESSION *IkeSaSession; 638 IKEV2_CREATE_CHILD_REQUEST_TYPE RequestType; 639 IKE_PACKET *Reply; 640 IPSEC_PRIVATE_DATA *Private; 641 642 Private = (UdpService->IpVersion == IP_VERSION_4) ? 643 IPSEC_PRIVATE_DATA_FROM_UDP4LIST(UdpService->ListHead) : 644 IPSEC_PRIVATE_DATA_FROM_UDP6LIST(UdpService->ListHead); 645 646 Reply = NULL; 647 648 // 649 // Lookup the remote ip address in the processing IKE SA session list. 650 // 651 IkeSaSession = Ikev2SaSessionLookup (&Private->Ikev2EstablishedList, &IkePacket->RemotePeerIp); 652 653 if (IkeSaSession == NULL) { 654 // 655 // Drop the packet if no IKE SA associated. 656 // 657 return ; 658 } 659 660 // 661 // Validate the IKE packet header. 662 // 663 if (!Ikev2ValidateHeader (IkeSaSession, IkePacket->Header)) { 664 // 665 // Drop the packet if invalid IKE header. 666 // 667 return; 668 } 669 670 // 671 // Decode all the payloads in the IKE packet. 672 // 673 Status = Ikev2DecodePacket (&IkeSaSession->SessionCommon, IkePacket, IkeSessionTypeIkeSa); 674 if (EFI_ERROR (Status)) { 675 return; 676 } 677 678 // 679 // Get the request type: CreateChildSa/RekeyChildSa/RekeyIkeSa. 680 // 681 RequestType = Ikev2ChildExchangeRequestType (IkePacket); 682 683 switch (RequestType) { 684 case IkeRequestTypeCreateChildSa: 685 case IkeRequestTypeRekeyChildSa: 686 case IkeRequestTypeRekeyIkeSa: 687 // 688 // Parse the IKE request packet. Not support CREATE_CHILD_SA exchange yet, so 689 // only EFI_UNSUPPORTED will be returned and that will trigger a reply with a 690 // Notify payload of type NO_ADDITIONAL_SAS. 691 // 692 Status = mIkev2CreateChild.Parser ((UINT8 *) IkeSaSession, IkePacket); 693 if (EFI_ERROR (Status)) { 694 goto ON_REPLY; 695 } 696 697 default: 698 // 699 // No support. 700 // 701 return ; 702 } 703 704 ON_REPLY: 705 // 706 // Generate the reply packet if needed and send it out. 707 // 708 if (!(IkePacket->Header->Flags & IKE_HEADER_FLAGS_RESPOND)) { 709 Reply = mIkev2CreateChild.Generator ((UINT8 *) IkeSaSession, &IkePacket->Header->MessageId); 710 if (Reply != NULL) { 711 Status = Ikev2SendIkePacket (UdpService, (UINT8 *) &(IkeSaSession->SessionCommon), Reply, 0); 712 if (EFI_ERROR (Status)) { 713 // 714 // Delete Reply payload. 715 // 716 if (Reply != NULL) { 717 IkePacketFree (Reply); 718 } 719 } 720 } 721 } 722 return ; 723 } 724 725 /** 726 727 It is general interface to handle IKEv2 information Exchange. 728 729 @param[in] UdpService Point to IKE UPD Service related to this information exchange. 730 @param[in] IkePacket The IKE packet to be parsed. 731 732 **/ 733 VOID 734 Ikev2HandleInfo ( 735 IN IKE_UDP_SERVICE *UdpService, 736 IN IKE_PACKET *IkePacket 737 ) 738 { 739 EFI_STATUS Status; 740 IKEV2_SESSION_COMMON *SessionCommon; 741 IKEV2_SA_SESSION *IkeSaSession; 742 IPSEC_PRIVATE_DATA *Private; 743 744 Private = (UdpService->IpVersion == IP_VERSION_4) ? 745 IPSEC_PRIVATE_DATA_FROM_UDP4LIST(UdpService->ListHead) : 746 IPSEC_PRIVATE_DATA_FROM_UDP6LIST(UdpService->ListHead); 747 748 // 749 // Lookup the remote ip address in the processing IKE SA session list. 750 // 751 IkeSaSession = Ikev2SaSessionLookup (&Private->Ikev2EstablishedList, &IkePacket->RemotePeerIp); 752 753 if (IkeSaSession == NULL) { 754 // 755 // Drop the packet if no IKE SA associated. 756 // 757 return ; 758 } 759 // 760 // Validate the IKE packet header. 761 // 762 if (!Ikev2ValidateHeader (IkeSaSession, IkePacket->Header)) { 763 764 // 765 // Drop the packet if invalid IKE header. 766 // 767 return; 768 } 769 770 SessionCommon = &IkeSaSession->SessionCommon; 771 772 // 773 // Decode all the payloads in the IKE packet. 774 // 775 Status = Ikev2DecodePacket (SessionCommon, IkePacket, IkeSessionTypeIkeSa); 776 if (EFI_ERROR (Status)) { 777 return; 778 } 779 780 Status = mIkev2Info.Parser ((UINT8 *)IkeSaSession, IkePacket); 781 782 if (EFI_ERROR (Status)) { 783 // 784 // Drop the packet if fail to parse. 785 // 786 return; 787 } 788 } 789 790 IKE_EXCHANGE_INTERFACE mIkev1Exchange = { 791 1, 792 NULL, //Ikev1NegotiateSa 793 NULL, //Ikev1NegotiateChildSa 794 NULL, 795 NULL, //Ikev1HandleSa, 796 NULL, //Ikev1HandleChildSa 797 NULL, //Ikev1HandleInfo 798 }; 799 800 IKE_EXCHANGE_INTERFACE mIkev2Exchange = { 801 2, 802 Ikev2NegotiateSa, 803 Ikev2NegotiateChildSa, 804 Ikev2NegotiateInfo, 805 Ikev2HandleSa, 806 Ikev2HandleChildSa, 807 Ikev2HandleInfo 808 }; 809 810