1 /** @file 2 The operations for IKEv2 SA. 3 4 (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR> 5 Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.<BR> 6 7 This program and the accompanying materials 8 are licensed and made available under the terms and conditions of the BSD License 9 which accompanies this distribution. The full text of the license may be found at 10 http://opensource.org/licenses/bsd-license.php. 11 12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 14 15 **/ 16 17 #include "Utility.h" 18 #include "IpSecDebug.h" 19 #include "IkeService.h" 20 #include "Ikev2.h" 21 22 /** 23 Generates the DH Key. 24 25 This generates the DH local public key and store it in the IKEv2 SA Session's GxBuffer. 26 27 @param[in] IkeSaSession Pointer to related IKE SA Session. 28 29 @retval EFI_SUCCESS The operation succeeded. 30 @retval Others The operation failed. 31 32 **/ 33 EFI_STATUS 34 Ikev2GenerateSaDhPublicKey ( 35 IN IKEV2_SA_SESSION *IkeSaSession 36 ); 37 38 /** 39 Generates the IKEv2 SA key for the furthure IKEv2 exchange. 40 41 @param[in] IkeSaSession Pointer to IKEv2 SA Session. 42 @param[in] KePayload Pointer to Key payload used to generate the Key. 43 44 @retval EFI_UNSUPPORTED If the Algorithm Id is not supported. 45 @retval EFI_SUCCESS The operation succeeded. 46 47 **/ 48 EFI_STATUS 49 Ikev2GenerateSaKeys ( 50 IN IKEV2_SA_SESSION *IkeSaSession, 51 IN IKE_PAYLOAD *KePayload 52 ); 53 54 /** 55 Generates the Keys for the furthure IPsec Protocol. 56 57 @param[in] ChildSaSession Pointer to IKE Child SA Session. 58 @param[in] KePayload Pointer to Key payload used to generate the Key. 59 60 @retval EFI_UNSUPPORTED If one or more Algorithm Id is unsupported. 61 @retval EFI_SUCCESS The operation succeeded. 62 63 **/ 64 EFI_STATUS 65 Ikev2GenerateChildSaKeys ( 66 IN IKEV2_CHILD_SA_SESSION *ChildSaSession, 67 IN IKE_PAYLOAD *KePayload 68 ); 69 70 /** 71 Gernerates IKEv2 packet for IKE_SA_INIT exchange. 72 73 @param[in] SaSession Pointer to IKEV2_SA_SESSION related to the exchange. 74 @param[in] Context Context Data passed by caller. 75 76 @retval EFI_SUCCESS The IKEv2 packet generation succeeded. 77 @retval Others The IKEv2 packet generation failed. 78 79 **/ 80 IKE_PACKET * 81 Ikev2InitPskGenerator ( 82 IN UINT8 *SaSession, 83 IN VOID *Context 84 ) 85 { 86 IKE_PACKET *IkePacket; 87 IKEV2_SA_SESSION *IkeSaSession; 88 IKE_PAYLOAD *SaPayload; 89 IKE_PAYLOAD *KePayload; 90 IKE_PAYLOAD *NoncePayload; 91 IKE_PAYLOAD *NotifyPayload; 92 EFI_STATUS Status; 93 94 SaPayload = NULL; 95 KePayload = NULL; 96 NoncePayload = NULL; 97 NotifyPayload = NULL; 98 99 IkeSaSession = (IKEV2_SA_SESSION *) SaSession; 100 101 // 102 // 1. Allocate IKE packet 103 // 104 IkePacket = IkePacketAlloc (); 105 if (IkePacket == NULL) { 106 goto CheckError; 107 } 108 109 // 110 // 1.a Fill the IkePacket->Hdr 111 // 112 IkePacket->Header->ExchangeType = IKEV2_EXCHANGE_TYPE_INIT; 113 IkePacket->Header->InitiatorCookie = IkeSaSession->InitiatorCookie; 114 IkePacket->Header->ResponderCookie = IkeSaSession->ResponderCookie; 115 IkePacket->Header->Version = (UINT8) (2 << 4); 116 IkePacket->Header->MessageId = 0; 117 118 if (IkeSaSession->SessionCommon.IsInitiator) { 119 IkePacket->Header->Flags = IKE_HEADER_FLAGS_INIT; 120 } else { 121 IkePacket->Header->Flags = IKE_HEADER_FLAGS_RESPOND; 122 } 123 124 // 125 // If the NCookie is not NULL, this IKE_SA_INIT packet is resent by the NCookie 126 // and the NCookie payload should be the first payload in this packet. 127 // 128 if (IkeSaSession->NCookie != NULL) { 129 IkePacket->Header->NextPayload = IKEV2_PAYLOAD_TYPE_NOTIFY; 130 NotifyPayload = Ikev2GenerateNotifyPayload ( 131 IPSEC_PROTO_ISAKMP, 132 IKEV2_PAYLOAD_TYPE_SA, 133 0, 134 IKEV2_NOTIFICATION_COOKIE, 135 NULL, 136 IkeSaSession->NCookie, 137 IkeSaSession->NCookieSize 138 ); 139 } else { 140 IkePacket->Header->NextPayload = IKEV2_PAYLOAD_TYPE_SA; 141 } 142 143 // 144 // 2. Generate SA Payload according to the SaData & SaParams 145 // 146 SaPayload = Ikev2GenerateSaPayload ( 147 IkeSaSession->SaData, 148 IKEV2_PAYLOAD_TYPE_KE, 149 IkeSessionTypeIkeSa 150 ); 151 152 // 153 // 3. Generate DH public key. 154 // The DhPrivate Key has been generated in Ikev2InitPskParser, if the 155 // IkeSaSession is responder. If resending IKE_SA_INIT with Cookie Notify 156 // No need to recompute the Public key. 157 // 158 if ((IkeSaSession->SessionCommon.IsInitiator) && (IkeSaSession->NCookie == NULL)) { 159 Status = Ikev2GenerateSaDhPublicKey (IkeSaSession); 160 if (EFI_ERROR (Status)) { 161 goto CheckError; 162 } 163 } 164 165 // 166 // 4. Generate KE Payload according to SaParams->DhGroup 167 // 168 KePayload = Ikev2GenerateKePayload ( 169 IkeSaSession, 170 IKEV2_PAYLOAD_TYPE_NONCE 171 ); 172 173 // 174 // 5. Generate Nonce Payload 175 // If resending IKE_SA_INIT with Cookie Notify paylaod, no need to regenerate 176 // the Nonce Payload. 177 // 178 if ((IkeSaSession->SessionCommon.IsInitiator) && (IkeSaSession->NCookie == NULL)) { 179 IkeSaSession->NiBlkSize = IKE_NONCE_SIZE; 180 IkeSaSession->NiBlock = IkeGenerateNonce (IKE_NONCE_SIZE); 181 if (IkeSaSession->NiBlock == NULL) { 182 goto CheckError; 183 } 184 } 185 186 if (IkeSaSession->SessionCommon.IsInitiator) { 187 NoncePayload = Ikev2GenerateNoncePayload ( 188 IkeSaSession->NiBlock, 189 IkeSaSession->NiBlkSize, 190 IKEV2_PAYLOAD_TYPE_NONE 191 ); 192 } else { 193 // 194 // The Nonce Payload has been created in Ikev2PskParser if the IkeSaSession is 195 // responder. 196 // 197 NoncePayload = Ikev2GenerateNoncePayload ( 198 IkeSaSession->NrBlock, 199 IkeSaSession->NrBlkSize, 200 IKEV2_PAYLOAD_TYPE_NONE 201 ); 202 } 203 204 if (NotifyPayload != NULL) { 205 IKE_PACKET_APPEND_PAYLOAD (IkePacket, NotifyPayload); 206 } 207 if (SaPayload != NULL) { 208 IKE_PACKET_APPEND_PAYLOAD (IkePacket, SaPayload); 209 } 210 if (KePayload != NULL) { 211 IKE_PACKET_APPEND_PAYLOAD (IkePacket, KePayload); 212 } 213 if (NoncePayload != NULL) { 214 IKE_PACKET_APPEND_PAYLOAD (IkePacket, NoncePayload); 215 } 216 217 return IkePacket; 218 219 CheckError: 220 if (IkePacket != NULL) { 221 IkePacketFree (IkePacket); 222 } 223 if (SaPayload != NULL) { 224 IkePayloadFree (SaPayload); 225 } 226 return NULL; 227 } 228 229 /** 230 Parses the IKEv2 packet for IKE_SA_INIT exchange. 231 232 @param[in] SaSession Pointer to IKEV2_SA_SESSION related to the exchange. 233 @param[in] IkePacket The received IKE packet to be parsed. 234 235 @retval EFI_SUCCESS The IKEv2 packet is acceptable and the relative data is 236 saved for furthure communication. 237 @retval EFI_INVALID_PARAMETER The IKEv2 packet is malformed or the SA proposal is unacceptable. 238 239 **/ 240 EFI_STATUS 241 Ikev2InitPskParser ( 242 IN UINT8 *SaSession, 243 IN IKE_PACKET *IkePacket 244 ) 245 { 246 IKEV2_SA_SESSION *IkeSaSession; 247 IKE_PAYLOAD *SaPayload; 248 IKE_PAYLOAD *KeyPayload; 249 IKE_PAYLOAD *IkePayload; 250 IKE_PAYLOAD *NoncePayload; 251 IKE_PAYLOAD *NotifyPayload; 252 UINT8 *NonceBuffer; 253 UINTN NonceSize; 254 LIST_ENTRY *Entry; 255 EFI_STATUS Status; 256 257 IkeSaSession = (IKEV2_SA_SESSION *) SaSession; 258 KeyPayload = NULL; 259 SaPayload = NULL; 260 NoncePayload = NULL; 261 IkePayload = NULL; 262 NotifyPayload = NULL; 263 264 // 265 // Iterate payloads to find the SaPayload and KeyPayload. 266 // 267 NET_LIST_FOR_EACH (Entry, &(IkePacket)->PayloadList) { 268 IkePayload = IKE_PAYLOAD_BY_PACKET (Entry); 269 if (IkePayload->PayloadType == IKEV2_PAYLOAD_TYPE_SA) { 270 SaPayload = IkePayload; 271 } 272 if (IkePayload->PayloadType == IKEV2_PAYLOAD_TYPE_KE) { 273 KeyPayload = IkePayload; 274 } 275 if (IkePayload->PayloadType == IKEV2_PAYLOAD_TYPE_NONCE) { 276 NoncePayload = IkePayload; 277 } 278 if (IkePayload->PayloadType == IKEV2_PAYLOAD_TYPE_NOTIFY) { 279 NotifyPayload = IkePayload; 280 } 281 } 282 283 // 284 // According to RFC 4306 - 2.6. If the responder responds with the COOKIE Notify 285 // payload with the cookie data, initiator MUST retry the IKE_SA_INIT with a 286 // Notify payload of type COOKIE containing the responder suppplied cookie data 287 // as first payload and all other payloads unchanged. 288 // 289 if (IkeSaSession->SessionCommon.IsInitiator) { 290 if (NotifyPayload != NULL && !EFI_ERROR(Ikev2ParserNotifyCookiePayload (NotifyPayload, IkeSaSession))) { 291 return EFI_SUCCESS; 292 } 293 } 294 295 if ((KeyPayload == NULL) || (SaPayload == NULL) || (NoncePayload == NULL)) { 296 return EFI_INVALID_PARAMETER; 297 } 298 299 // 300 // Store NoncePayload for SKEYID computing. 301 // 302 NonceSize = NoncePayload->PayloadSize - sizeof (IKEV2_COMMON_PAYLOAD_HEADER); 303 NonceBuffer = (UINT8 *) AllocatePool (NonceSize); 304 if (NonceBuffer == NULL) { 305 Status = EFI_OUT_OF_RESOURCES; 306 goto CheckError; 307 } 308 309 CopyMem ( 310 NonceBuffer, 311 NoncePayload->PayloadBuf + sizeof (IKEV2_COMMON_PAYLOAD_HEADER), 312 NonceSize 313 ); 314 315 // 316 // Check if IkePacket Header matches the state 317 // 318 if (IkeSaSession->SessionCommon.IsInitiator) { 319 // 320 // 1. Check the IkePacket->Hdr == IKE_HEADER_FLAGS_RESPOND 321 // 322 if (IkePacket->Header->Flags != IKE_HEADER_FLAGS_RESPOND) { 323 Status = EFI_INVALID_PARAMETER; 324 goto CheckError; 325 } 326 327 // 328 // 2. Parse the SA Payload and Key Payload to find out the cryptographic 329 // suite and fill in the Sa paramse into CommonSession->SaParams 330 // 331 if (!Ikev2SaParseSaPayload (IkeSaSession, SaPayload, IkePacket->Header->Flags)) { 332 Status = EFI_INVALID_PARAMETER; 333 goto CheckError; 334 } 335 336 // 337 // 3. If Initiator, the NoncePayload is Nr_b. 338 // 339 IKEV2_DUMP_STATE (IkeSaSession->SessionCommon.State, IkeStateAuth); 340 IkeSaSession->NrBlock = NonceBuffer; 341 IkeSaSession->NrBlkSize = NonceSize; 342 IkeSaSession->SessionCommon.State = IkeStateAuth; 343 IkeSaSession->ResponderCookie = IkePacket->Header->ResponderCookie; 344 345 // 346 // 4. Change the state of IkeSaSession 347 // 348 IkeSaSession->SessionCommon.State = IkeStateAuth; 349 } else { 350 // 351 // 1. Check the IkePacket->Hdr == IKE_HEADER_FLAGS_INIT 352 // 353 if (IkePacket->Header->Flags != IKE_HEADER_FLAGS_INIT) { 354 Status = EFI_INVALID_PARAMETER; 355 goto CheckError; 356 } 357 358 // 359 // 2. Parse the SA payload and find out the perfered one 360 // and fill in the SA parameters into CommonSession->SaParams and SaData into 361 // IkeSaSession for the responder SA payload generation. 362 // 363 if (!Ikev2SaParseSaPayload (IkeSaSession, SaPayload, IkePacket->Header->Flags)) { 364 Status = EFI_INVALID_PARAMETER; 365 goto CheckError; 366 } 367 368 // 369 // 3. Generat Dh Y parivate Key 370 // 371 Status = Ikev2GenerateSaDhPublicKey (IkeSaSession); 372 if (EFI_ERROR (Status)) { 373 goto CheckError; 374 } 375 376 // 377 // 4. If Responder, the NoncePayload is Ni_b and go to generate Nr_b. 378 // 379 IkeSaSession->NiBlock = NonceBuffer; 380 IkeSaSession->NiBlkSize = NonceSize; 381 382 // 383 // 5. Generate Nr_b 384 // 385 IkeSaSession->NrBlock = IkeGenerateNonce (IKE_NONCE_SIZE); 386 ASSERT (IkeSaSession->NrBlock != NULL); 387 IkeSaSession->NrBlkSize = IKE_NONCE_SIZE; 388 389 // 390 // 6. Save the Cookies 391 // 392 IkeSaSession->InitiatorCookie = IkePacket->Header->InitiatorCookie; 393 IkeSaSession->ResponderCookie = IkeGenerateCookie (); 394 } 395 396 if (IkeSaSession->SessionCommon.PreferDhGroup != ((IKEV2_KEY_EXCHANGE *)KeyPayload->PayloadBuf)->DhGroup) { 397 Status = EFI_INVALID_PARAMETER; 398 goto CheckError; 399 } 400 // 401 // Call Ikev2GenerateSaKeys to create SKEYID, SKEYID_d, SKEYID_a, SKEYID_e. 402 // 403 Status = Ikev2GenerateSaKeys (IkeSaSession, KeyPayload); 404 if (EFI_ERROR(Status)) { 405 goto CheckError; 406 } 407 return EFI_SUCCESS; 408 409 CheckError: 410 if (NonceBuffer != NULL) { 411 FreePool (NonceBuffer); 412 } 413 414 return Status; 415 } 416 417 /** 418 Generates the IKEv2 packet for IKE_AUTH exchange. 419 420 @param[in] SaSession Pointer to IKEV2_SA_SESSION. 421 @param[in] Context Context data passed by caller. 422 423 @retval Pointer to IKE Packet to be sent out. 424 425 **/ 426 IKE_PACKET * 427 Ikev2AuthPskGenerator ( 428 IN UINT8 *SaSession, 429 IN VOID *Context 430 ) 431 { 432 IKE_PACKET *IkePacket; 433 IKEV2_SA_SESSION *IkeSaSession; 434 IKE_PAYLOAD *IdPayload; 435 IKE_PAYLOAD *AuthPayload; 436 IKE_PAYLOAD *SaPayload; 437 IKE_PAYLOAD *TsiPayload; 438 IKE_PAYLOAD *TsrPayload; 439 IKE_PAYLOAD *NotifyPayload; 440 IKE_PAYLOAD *CpPayload; 441 IKEV2_CHILD_SA_SESSION *ChildSaSession; 442 443 444 IkeSaSession = (IKEV2_SA_SESSION *) SaSession; 445 ChildSaSession = IKEV2_CHILD_SA_SESSION_BY_IKE_SA (GetFirstNode (&IkeSaSession->ChildSaSessionList)); 446 447 IkePacket = NULL; 448 IdPayload = NULL; 449 AuthPayload = NULL; 450 SaPayload = NULL; 451 TsiPayload = NULL; 452 TsrPayload = NULL; 453 NotifyPayload = NULL; 454 CpPayload = NULL; 455 NotifyPayload = NULL; 456 457 // 458 // 1. Allocate IKE Packet 459 // 460 IkePacket= IkePacketAlloc (); 461 if (IkePacket == NULL) { 462 return NULL; 463 } 464 465 // 466 // 1.a Fill the IkePacket Header. 467 // 468 IkePacket->Header->ExchangeType = IKEV2_EXCHANGE_TYPE_AUTH; 469 IkePacket->Header->InitiatorCookie = IkeSaSession->InitiatorCookie; 470 IkePacket->Header->ResponderCookie = IkeSaSession->ResponderCookie; 471 IkePacket->Header->Version = (UINT8)(2 << 4); 472 if (ChildSaSession->SessionCommon.IsInitiator) { 473 IkePacket->Header->NextPayload = IKEV2_PAYLOAD_TYPE_ID_INIT; 474 } else { 475 IkePacket->Header->NextPayload = IKEV2_PAYLOAD_TYPE_ID_RSP; 476 } 477 478 // 479 // According to RFC4306_2.2, For the IKE_SA_INIT message the MessageID should 480 // be always number 0 and 1; 481 // 482 IkePacket->Header->MessageId = 1; 483 484 if (IkeSaSession->SessionCommon.IsInitiator) { 485 IkePacket->Header->Flags = IKE_HEADER_FLAGS_INIT; 486 } else { 487 IkePacket->Header->Flags = IKE_HEADER_FLAGS_RESPOND; 488 } 489 490 // 491 // 2. Generate ID Payload according to IP version and address. 492 // 493 IdPayload = Ikev2GenerateIdPayload ( 494 &IkeSaSession->SessionCommon, 495 IKEV2_PAYLOAD_TYPE_AUTH 496 ); 497 if (IdPayload == NULL) { 498 goto CheckError; 499 } 500 501 // 502 // 3. Generate Auth Payload 503 // If it is tunnel mode, should create the configuration payload after the 504 // Auth payload. 505 // 506 if (IkeSaSession->Spd->Data->ProcessingPolicy->Mode == EfiIPsecTransport) { 507 508 AuthPayload = Ikev2PskGenerateAuthPayload ( 509 ChildSaSession->IkeSaSession, 510 IdPayload, 511 IKEV2_PAYLOAD_TYPE_SA, 512 FALSE 513 ); 514 } else { 515 AuthPayload = Ikev2PskGenerateAuthPayload ( 516 ChildSaSession->IkeSaSession, 517 IdPayload, 518 IKEV2_PAYLOAD_TYPE_CP, 519 FALSE 520 ); 521 if (IkeSaSession->SessionCommon.UdpService->IpVersion == IP_VERSION_4) { 522 CpPayload = Ikev2GenerateCpPayload ( 523 ChildSaSession->IkeSaSession, 524 IKEV2_PAYLOAD_TYPE_SA, 525 IKEV2_CFG_ATTR_INTERNAL_IP4_ADDRESS 526 ); 527 } else { 528 CpPayload = Ikev2GenerateCpPayload ( 529 ChildSaSession->IkeSaSession, 530 IKEV2_PAYLOAD_TYPE_SA, 531 IKEV2_CFG_ATTR_INTERNAL_IP6_ADDRESS 532 ); 533 } 534 535 if (CpPayload == NULL) { 536 goto CheckError; 537 } 538 } 539 540 if (AuthPayload == NULL) { 541 goto CheckError; 542 } 543 544 // 545 // 4. Generate SA Payload according to the SA Data in ChildSaSession 546 // 547 SaPayload = Ikev2GenerateSaPayload ( 548 ChildSaSession->SaData, 549 IKEV2_PAYLOAD_TYPE_TS_INIT, 550 IkeSessionTypeChildSa 551 ); 552 if (SaPayload == NULL) { 553 goto CheckError; 554 } 555 556 if (IkeSaSession->Spd->Data->ProcessingPolicy->Mode == EfiIPsecTransport) { 557 // 558 // Generate Tsi and Tsr. 559 // 560 TsiPayload = Ikev2GenerateTsPayload ( 561 ChildSaSession, 562 IKEV2_PAYLOAD_TYPE_TS_RSP, 563 FALSE 564 ); 565 566 TsrPayload = Ikev2GenerateTsPayload ( 567 ChildSaSession, 568 IKEV2_PAYLOAD_TYPE_NOTIFY, 569 FALSE 570 ); 571 572 // 573 // Generate Notify Payload. If transport mode, there should have Notify 574 // payload with TRANSPORT_MODE notification. 575 // 576 NotifyPayload = Ikev2GenerateNotifyPayload ( 577 0, 578 IKEV2_PAYLOAD_TYPE_NONE, 579 0, 580 IKEV2_NOTIFICATION_USE_TRANSPORT_MODE, 581 NULL, 582 NULL, 583 0 584 ); 585 if (NotifyPayload == NULL) { 586 goto CheckError; 587 } 588 } else { 589 // 590 // Generate Tsr for Tunnel mode. 591 // 592 TsiPayload = Ikev2GenerateTsPayload ( 593 ChildSaSession, 594 IKEV2_PAYLOAD_TYPE_TS_RSP, 595 TRUE 596 ); 597 TsrPayload = Ikev2GenerateTsPayload ( 598 ChildSaSession, 599 IKEV2_PAYLOAD_TYPE_NONE, 600 FALSE 601 ); 602 } 603 604 if (TsiPayload == NULL || TsrPayload == NULL) { 605 goto CheckError; 606 } 607 608 IKE_PACKET_APPEND_PAYLOAD (IkePacket, IdPayload); 609 IKE_PACKET_APPEND_PAYLOAD (IkePacket, AuthPayload); 610 if (IkeSaSession->Spd->Data->ProcessingPolicy->Mode == EfiIPsecTunnel) { 611 IKE_PACKET_APPEND_PAYLOAD (IkePacket, CpPayload); 612 } 613 IKE_PACKET_APPEND_PAYLOAD (IkePacket, SaPayload); 614 IKE_PACKET_APPEND_PAYLOAD (IkePacket, TsiPayload); 615 IKE_PACKET_APPEND_PAYLOAD (IkePacket, TsrPayload); 616 if (IkeSaSession->Spd->Data->ProcessingPolicy->Mode == EfiIPsecTransport) { 617 IKE_PACKET_APPEND_PAYLOAD (IkePacket, NotifyPayload); 618 } 619 620 return IkePacket; 621 622 CheckError: 623 if (IkePacket != NULL) { 624 IkePacketFree (IkePacket); 625 } 626 627 if (IdPayload != NULL) { 628 IkePayloadFree (IdPayload); 629 } 630 631 if (AuthPayload != NULL) { 632 IkePayloadFree (AuthPayload); 633 } 634 635 if (CpPayload != NULL) { 636 IkePayloadFree (CpPayload); 637 } 638 639 if (SaPayload != NULL) { 640 IkePayloadFree (SaPayload); 641 } 642 643 if (TsiPayload != NULL) { 644 IkePayloadFree (TsiPayload); 645 } 646 647 if (TsrPayload != NULL) { 648 IkePayloadFree (TsrPayload); 649 } 650 651 if (NotifyPayload != NULL) { 652 IkePayloadFree (NotifyPayload); 653 } 654 655 return NULL; 656 } 657 658 /** 659 Parses IKE_AUTH packet. 660 661 @param[in] SaSession Pointer to the IKE_SA_SESSION related to this packet. 662 @param[in] IkePacket Pointer to the IKE_AUTH packet to be parsered. 663 664 @retval EFI_INVALID_PARAMETER The IKE packet is malformed or the SA 665 proposal is unacceptable. 666 @retval EFI_SUCCESS The IKE packet is acceptable and the 667 relative data is saved for furthure communication. 668 669 **/ 670 EFI_STATUS 671 Ikev2AuthPskParser ( 672 IN UINT8 *SaSession, 673 IN IKE_PACKET *IkePacket 674 ) 675 { 676 IKEV2_CHILD_SA_SESSION *ChildSaSession; 677 IKEV2_SA_SESSION *IkeSaSession; 678 IKE_PAYLOAD *IkePayload; 679 IKE_PAYLOAD *SaPayload; 680 IKE_PAYLOAD *IdiPayload; 681 IKE_PAYLOAD *IdrPayload; 682 IKE_PAYLOAD *AuthPayload; 683 IKE_PAYLOAD *TsiPayload; 684 IKE_PAYLOAD *TsrPayload; 685 IKE_PAYLOAD *VerifiedAuthPayload; 686 LIST_ENTRY *Entry; 687 EFI_STATUS Status; 688 689 IkeSaSession = (IKEV2_SA_SESSION *) SaSession; 690 ChildSaSession = IKEV2_CHILD_SA_SESSION_BY_IKE_SA (GetFirstNode (&IkeSaSession->ChildSaSessionList)); 691 692 SaPayload = NULL; 693 IdiPayload = NULL; 694 IdrPayload = NULL; 695 AuthPayload = NULL; 696 TsiPayload = NULL; 697 TsrPayload = NULL; 698 699 // 700 // Iterate payloads to find the SaPayload/ID/AUTH/TS Payload. 701 // 702 NET_LIST_FOR_EACH (Entry, &(IkePacket)->PayloadList) { 703 IkePayload = IKE_PAYLOAD_BY_PACKET (Entry); 704 705 if (IkePayload->PayloadType == IKEV2_PAYLOAD_TYPE_ID_INIT) { 706 IdiPayload = IkePayload; 707 } 708 if (IkePayload->PayloadType == IKEV2_PAYLOAD_TYPE_ID_RSP) { 709 IdrPayload = IkePayload; 710 } 711 if (IkePayload->PayloadType == IKEV2_PAYLOAD_TYPE_SA) { 712 SaPayload = IkePayload; 713 } 714 if (IkePayload->PayloadType == IKEV2_PAYLOAD_TYPE_AUTH) { 715 AuthPayload = IkePayload; 716 } 717 if (IkePayload->PayloadType == IKEV2_PAYLOAD_TYPE_TS_INIT) { 718 TsiPayload = IkePayload; 719 } 720 if (IkePayload->PayloadType == IKEV2_PAYLOAD_TYPE_TS_RSP) { 721 TsrPayload = IkePayload; 722 } 723 } 724 725 if ((SaPayload == NULL) || (AuthPayload == NULL) || (TsiPayload == NULL) || (TsrPayload == NULL)) { 726 return EFI_INVALID_PARAMETER; 727 } 728 if ((IdiPayload == NULL) && (IdrPayload == NULL)) { 729 return EFI_INVALID_PARAMETER; 730 } 731 732 // 733 // Check IkePacket Header is match the state 734 // 735 if (IkeSaSession->SessionCommon.IsInitiator) { 736 737 // 738 // 1. Check the IkePacket->Hdr == IKE_HEADER_FLAGS_RESPOND 739 // 740 if ((IkePacket->Header->Flags != IKE_HEADER_FLAGS_RESPOND) || 741 (IkePacket->Header->ExchangeType != IKEV2_EXCHANGE_TYPE_AUTH) 742 ) { 743 return EFI_INVALID_PARAMETER; 744 } 745 746 } else { 747 // 748 // 1. Check the IkePacket->Hdr == IKE_HEADER_FLAGS_INIT 749 // 750 if ((IkePacket->Header->Flags != IKE_HEADER_FLAGS_INIT) || 751 (IkePacket->Header->ExchangeType != IKEV2_EXCHANGE_TYPE_AUTH) 752 ) { 753 return EFI_INVALID_PARAMETER; 754 } 755 756 // 757 // 2. Parse the SA payload and Key Payload and find out the perferable one 758 // and fill in the Sa paramse into CommonSession->SaParams and SaData into 759 // IkeSaSession for the responder SA payload generation. 760 // 761 } 762 763 // 764 // Verify the Auth Payload. 765 // 766 VerifiedAuthPayload = Ikev2PskGenerateAuthPayload ( 767 IkeSaSession, 768 IkeSaSession->SessionCommon.IsInitiator ? IdrPayload : IdiPayload, 769 IKEV2_PAYLOAD_TYPE_SA, 770 TRUE 771 ); 772 if ((VerifiedAuthPayload != NULL) && 773 (0 != CompareMem ( 774 VerifiedAuthPayload->PayloadBuf + sizeof (IKEV2_COMMON_PAYLOAD_HEADER), 775 AuthPayload->PayloadBuf + sizeof (IKEV2_COMMON_PAYLOAD_HEADER), 776 VerifiedAuthPayload->PayloadSize - sizeof (IKEV2_COMMON_PAYLOAD_HEADER) 777 ))) { 778 return EFI_INVALID_PARAMETER; 779 }; 780 781 // 782 // 3. Parse the SA Payload to find out the cryptographic suite 783 // and fill in the Sa paramse into CommonSession->SaParams. If no acceptable 784 // porposal found, return EFI_INVALID_PARAMETER. 785 // 786 if (!Ikev2ChildSaParseSaPayload (ChildSaSession, SaPayload, IkePacket->Header->Flags)) { 787 return EFI_INVALID_PARAMETER; 788 } 789 790 // 791 // 4. Parse TSi, TSr payloads. 792 // 793 if ((((TRAFFIC_SELECTOR *)(TsiPayload->PayloadBuf + sizeof (IKEV2_TS)))->IpProtocolId != 794 ((TRAFFIC_SELECTOR *)(TsrPayload->PayloadBuf + sizeof (IKEV2_TS)))->IpProtocolId) && 795 (((TRAFFIC_SELECTOR *)(TsiPayload->PayloadBuf + sizeof (IKEV2_TS)))->IpProtocolId != 0) && 796 (((TRAFFIC_SELECTOR *)(TsrPayload->PayloadBuf + sizeof (IKEV2_TS)))->IpProtocolId != 0) 797 ) { 798 return EFI_INVALID_PARAMETER; 799 } 800 801 if (!IkeSaSession->SessionCommon.IsInitiator) { 802 // 803 //TODO:check the Port range. Only support any port and one certain port here. 804 // 805 ChildSaSession->ProtoId = ((TRAFFIC_SELECTOR *)(TsrPayload->PayloadBuf + sizeof (IKEV2_TS)))->IpProtocolId; 806 ChildSaSession->LocalPort = ((TRAFFIC_SELECTOR *)(TsrPayload->PayloadBuf + sizeof (IKEV2_TS)))->StartPort; 807 ChildSaSession->RemotePort = ((TRAFFIC_SELECTOR *)(TsiPayload->PayloadBuf + sizeof (IKEV2_TS)))->StartPort; 808 // 809 // Association a SPD with this SA. 810 // 811 Status = Ikev2ChildSaAssociateSpdEntry (ChildSaSession); 812 if (EFI_ERROR (Status)) { 813 return EFI_INVALID_PARAMETER; 814 } 815 // 816 // Associate the IkeSaSession's SPD to the first ChildSaSession's SPD. 817 // 818 if (ChildSaSession->IkeSaSession->Spd == NULL) { 819 ChildSaSession->IkeSaSession->Spd = ChildSaSession->Spd; 820 Status = Ikev2ChildSaSessionSpdSelectorCreate (ChildSaSession); 821 if (EFI_ERROR (Status)) { 822 return Status; 823 } 824 } 825 } else { 826 // 827 //TODO:check the Port range. 828 // 829 if ((((TRAFFIC_SELECTOR *)(TsrPayload->PayloadBuf + sizeof (IKEV2_TS)))->StartPort != 0) && 830 (((TRAFFIC_SELECTOR *)(TsrPayload->PayloadBuf + sizeof (IKEV2_TS)))->StartPort != ChildSaSession->RemotePort) 831 ) { 832 return EFI_INVALID_PARAMETER; 833 } 834 if ((((TRAFFIC_SELECTOR *)(TsiPayload->PayloadBuf + sizeof (IKEV2_TS)))->StartPort != 0) && 835 (((TRAFFIC_SELECTOR *)(TsiPayload->PayloadBuf + sizeof (IKEV2_TS)))->StartPort != ChildSaSession->LocalPort) 836 ) { 837 return EFI_INVALID_PARAMETER; 838 } 839 // 840 // For the tunnel mode, it should add the vitual IP address into the SA's SPD Selector. 841 // 842 if (ChildSaSession->Spd->Data->ProcessingPolicy->Mode == EfiIPsecTunnel) { 843 if (!ChildSaSession->IkeSaSession->SessionCommon.IsInitiator) { 844 // 845 // If it is tunnel mode, the UEFI part must be the initiator. 846 // 847 return EFI_INVALID_PARAMETER; 848 } 849 // 850 // Get the Virtual IP address from the Tsi traffic selector. 851 // TODO: check the CFG reply payload 852 // 853 CopyMem ( 854 &ChildSaSession->SpdSelector->LocalAddress[0].Address, 855 TsiPayload->PayloadBuf + sizeof (IKEV2_TS) + sizeof (TRAFFIC_SELECTOR), 856 (ChildSaSession->SessionCommon.UdpService->IpVersion == IP_VERSION_4) ? 857 sizeof (EFI_IPv4_ADDRESS) : sizeof (EFI_IPv6_ADDRESS) 858 ); 859 } 860 } 861 862 // 863 // 5. Generate keymats for IPsec protocol. 864 // 865 Status = Ikev2GenerateChildSaKeys (ChildSaSession, NULL); 866 if (EFI_ERROR (Status)) { 867 return Status; 868 } 869 870 if (IkeSaSession->SessionCommon.IsInitiator) { 871 // 872 // 6. Change the state of IkeSaSession 873 // 874 IKEV2_DUMP_STATE (IkeSaSession->SessionCommon.State, IkeStateIkeSaEstablished); 875 IkeSaSession->SessionCommon.State = IkeStateIkeSaEstablished; 876 } 877 878 return EFI_SUCCESS; 879 } 880 881 /** 882 Gernerates IKEv2 packet for IKE_SA_INIT exchange. 883 884 @param[in] SaSession Pointer to IKEV2_SA_SESSION related to the exchange. 885 @param[in] Context Context Data passed by caller. 886 887 @retval EFI_SUCCESS The IKE packet generation succeeded. 888 @retval Others The IKE packet generation failed. 889 890 **/ 891 IKE_PACKET* 892 Ikev2InitCertGenerator ( 893 IN UINT8 *SaSession, 894 IN VOID *Context 895 ) 896 { 897 IKE_PACKET *IkePacket; 898 IKE_PAYLOAD *CertReqPayload; 899 LIST_ENTRY *Node; 900 IKE_PAYLOAD *NoncePayload; 901 902 if (!FeaturePcdGet (PcdIpsecCertificateEnabled)) { 903 return NULL; 904 } 905 906 // 907 // The first two messages exchange is same between PSK and Cert. 908 // 909 IkePacket = Ikev2InitPskGenerator (SaSession, Context); 910 911 if ((IkePacket != NULL) && (!((IKEV2_SA_SESSION *)SaSession)->SessionCommon.IsInitiator)) { 912 // 913 // Add the Certification Request Payload 914 // 915 CertReqPayload = Ikev2GenerateCertificatePayload ( 916 (IKEV2_SA_SESSION *)SaSession, 917 IKEV2_PAYLOAD_TYPE_NONE, 918 (UINT8*)PcdGetPtr(PcdIpsecUefiCaFile), 919 PcdGet32(PcdIpsecUefiCaFileSize), 920 IKEV2_CERT_ENCODEING_HASH_AND_URL_OF_X509_CERT, 921 TRUE 922 ); 923 // 924 // Change Nonce Payload Next payload type. 925 // 926 IKE_PACKET_END_PAYLOAD (IkePacket, Node); 927 NoncePayload = IKE_PAYLOAD_BY_PACKET (Node); 928 ((IKEV2_NONCE *)NoncePayload->PayloadBuf)->Header.NextPayload = IKEV2_PAYLOAD_TYPE_CERTREQ; 929 930 // 931 // Add Certification Request Payload 932 // 933 IKE_PACKET_APPEND_PAYLOAD (IkePacket, CertReqPayload); 934 } 935 936 return IkePacket; 937 } 938 939 /** 940 Parses the IKEv2 packet for IKE_SA_INIT exchange. 941 942 @param[in] SaSession Pointer to IKEV2_SA_SESSION related to the exchange. 943 @param[in] IkePacket The received IKEv2 packet to be parsed. 944 945 @retval EFI_SUCCESS The IKEv2 packet is acceptable and the relative data is 946 saved for furthure communication. 947 @retval EFI_INVALID_PARAMETER The IKE packet is malformed or the SA proposal is unacceptable. 948 @retval EFI_UNSUPPORTED The certificate authentication is not supported. 949 950 **/ 951 EFI_STATUS 952 Ikev2InitCertParser ( 953 IN UINT8 *SaSession, 954 IN IKE_PACKET *IkePacket 955 ) 956 { 957 if (!FeaturePcdGet (PcdIpsecCertificateEnabled)) { 958 return EFI_UNSUPPORTED; 959 } 960 961 // 962 // The first two messages exchange is same between PSK and Cert. 963 // Todo: Parse Certificate Request from responder Initial Exchange. 964 // 965 return Ikev2InitPskParser (SaSession, IkePacket); 966 } 967 968 /** 969 Generates the IKEv2 packet for IKE_AUTH exchange. 970 971 @param[in] SaSession Pointer to IKEV2_SA_SESSION. 972 @param[in] Context Context data passed by caller. 973 974 @retval Pointer to IKEv2 Packet to be sent out. 975 976 **/ 977 IKE_PACKET * 978 Ikev2AuthCertGenerator ( 979 IN UINT8 *SaSession, 980 IN VOID *Context 981 ) 982 { 983 IKE_PACKET *IkePacket; 984 IKEV2_SA_SESSION *IkeSaSession; 985 IKE_PAYLOAD *IdPayload; 986 IKE_PAYLOAD *AuthPayload; 987 IKE_PAYLOAD *SaPayload; 988 IKE_PAYLOAD *TsiPayload; 989 IKE_PAYLOAD *TsrPayload; 990 IKE_PAYLOAD *NotifyPayload; 991 IKE_PAYLOAD *CpPayload; 992 IKE_PAYLOAD *CertPayload; 993 IKE_PAYLOAD *CertReqPayload; 994 IKEV2_CHILD_SA_SESSION *ChildSaSession; 995 996 if (!FeaturePcdGet (PcdIpsecCertificateEnabled)) { 997 return NULL; 998 } 999 1000 IkeSaSession = (IKEV2_SA_SESSION *) SaSession; 1001 ChildSaSession = IKEV2_CHILD_SA_SESSION_BY_IKE_SA (GetFirstNode (&IkeSaSession->ChildSaSessionList)); 1002 1003 IkePacket = NULL; 1004 IdPayload = NULL; 1005 AuthPayload = NULL; 1006 CpPayload = NULL; 1007 SaPayload = NULL; 1008 TsiPayload = NULL; 1009 TsrPayload = NULL; 1010 NotifyPayload = NULL; 1011 CertPayload = NULL; 1012 CertReqPayload = NULL; 1013 1014 // 1015 // 1. Allocate IKE Packet 1016 // 1017 IkePacket= IkePacketAlloc (); 1018 if (IkePacket == NULL) { 1019 return NULL; 1020 } 1021 1022 // 1023 // 1.a Fill the IkePacket Header. 1024 // 1025 IkePacket->Header->ExchangeType = IKEV2_EXCHANGE_TYPE_AUTH; 1026 IkePacket->Header->InitiatorCookie = IkeSaSession->InitiatorCookie; 1027 IkePacket->Header->ResponderCookie = IkeSaSession->ResponderCookie; 1028 IkePacket->Header->Version = (UINT8)(2 << 4); 1029 if (ChildSaSession->SessionCommon.IsInitiator) { 1030 IkePacket->Header->NextPayload = IKEV2_PAYLOAD_TYPE_ID_INIT; 1031 } else { 1032 IkePacket->Header->NextPayload = IKEV2_PAYLOAD_TYPE_ID_RSP; 1033 } 1034 1035 // 1036 // According to RFC4306_2.2, For the IKE_SA_INIT message the MessageID should 1037 // be always number 0 and 1; 1038 // 1039 IkePacket->Header->MessageId = 1; 1040 1041 if (IkeSaSession->SessionCommon.IsInitiator) { 1042 IkePacket->Header->Flags = IKE_HEADER_FLAGS_INIT; 1043 } else { 1044 IkePacket->Header->Flags = IKE_HEADER_FLAGS_RESPOND; 1045 } 1046 1047 // 1048 // 2. Generate ID Payload according to IP version and address. 1049 // 1050 IdPayload = Ikev2GenerateCertIdPayload ( 1051 &IkeSaSession->SessionCommon, 1052 IKEV2_PAYLOAD_TYPE_CERT, 1053 (UINT8 *)PcdGetPtr (PcdIpsecUefiCertificate), 1054 PcdGet32 (PcdIpsecUefiCertificateSize) 1055 ); 1056 if (IdPayload == NULL) { 1057 goto CheckError; 1058 } 1059 1060 // 1061 // 3. Generate Certificate Payload 1062 // 1063 CertPayload = Ikev2GenerateCertificatePayload ( 1064 IkeSaSession, 1065 (UINT8)(IkeSaSession->SessionCommon.IsInitiator ? IKEV2_PAYLOAD_TYPE_CERTREQ : IKEV2_PAYLOAD_TYPE_AUTH), 1066 (UINT8 *)PcdGetPtr (PcdIpsecUefiCertificate), 1067 PcdGet32 (PcdIpsecUefiCertificateSize), 1068 IKEV2_CERT_ENCODEING_X509_CERT_SIGN, 1069 FALSE 1070 ); 1071 if (CertPayload == NULL) { 1072 goto CheckError; 1073 } 1074 1075 if (IkeSaSession->SessionCommon.IsInitiator) { 1076 CertReqPayload = Ikev2GenerateCertificatePayload ( 1077 IkeSaSession, 1078 IKEV2_PAYLOAD_TYPE_AUTH, 1079 (UINT8 *)PcdGetPtr (PcdIpsecUefiCertificate), 1080 PcdGet32 (PcdIpsecUefiCertificateSize), 1081 IKEV2_CERT_ENCODEING_HASH_AND_URL_OF_X509_CERT, 1082 TRUE 1083 ); 1084 if (CertReqPayload == NULL) { 1085 goto CheckError; 1086 } 1087 } 1088 1089 // 1090 // 4. Generate Auth Payload 1091 // If it is tunnel mode, should create the configuration payload after the 1092 // Auth payload. 1093 // 1094 if (IkeSaSession->Spd->Data->ProcessingPolicy->Mode == EfiIPsecTransport) { 1095 AuthPayload = Ikev2CertGenerateAuthPayload ( 1096 ChildSaSession->IkeSaSession, 1097 IdPayload, 1098 IKEV2_PAYLOAD_TYPE_SA, 1099 FALSE, 1100 (UINT8 *)PcdGetPtr (PcdIpsecUefiCertificateKey), 1101 PcdGet32 (PcdIpsecUefiCertificateKeySize), 1102 ChildSaSession->IkeSaSession->Pad->Data->AuthData, 1103 ChildSaSession->IkeSaSession->Pad->Data->AuthDataSize 1104 ); 1105 } else { 1106 AuthPayload = Ikev2CertGenerateAuthPayload ( 1107 ChildSaSession->IkeSaSession, 1108 IdPayload, 1109 IKEV2_PAYLOAD_TYPE_CP, 1110 FALSE, 1111 (UINT8 *)PcdGetPtr (PcdIpsecUefiCertificateKey), 1112 PcdGet32 (PcdIpsecUefiCertificateKeySize), 1113 ChildSaSession->IkeSaSession->Pad->Data->AuthData, 1114 ChildSaSession->IkeSaSession->Pad->Data->AuthDataSize 1115 ); 1116 if (IkeSaSession->SessionCommon.UdpService->IpVersion == IP_VERSION_4) { 1117 CpPayload = Ikev2GenerateCpPayload ( 1118 ChildSaSession->IkeSaSession, 1119 IKEV2_PAYLOAD_TYPE_SA, 1120 IKEV2_CFG_ATTR_INTERNAL_IP4_ADDRESS 1121 ); 1122 } else { 1123 CpPayload = Ikev2GenerateCpPayload ( 1124 ChildSaSession->IkeSaSession, 1125 IKEV2_PAYLOAD_TYPE_SA, 1126 IKEV2_CFG_ATTR_INTERNAL_IP6_ADDRESS 1127 ); 1128 } 1129 1130 if (CpPayload == NULL) { 1131 goto CheckError; 1132 } 1133 } 1134 1135 if (AuthPayload == NULL) { 1136 goto CheckError; 1137 } 1138 1139 // 1140 // 5. Generate SA Payload according to the Sa Data in ChildSaSession 1141 // 1142 SaPayload = Ikev2GenerateSaPayload ( 1143 ChildSaSession->SaData, 1144 IKEV2_PAYLOAD_TYPE_TS_INIT, 1145 IkeSessionTypeChildSa 1146 ); 1147 if (SaPayload == NULL) { 1148 goto CheckError; 1149 } 1150 1151 if (IkeSaSession->Spd->Data->ProcessingPolicy->Mode == EfiIPsecTransport) { 1152 // 1153 // Generate Tsi and Tsr. 1154 // 1155 TsiPayload = Ikev2GenerateTsPayload ( 1156 ChildSaSession, 1157 IKEV2_PAYLOAD_TYPE_TS_RSP, 1158 FALSE 1159 ); 1160 1161 TsrPayload = Ikev2GenerateTsPayload ( 1162 ChildSaSession, 1163 IKEV2_PAYLOAD_TYPE_NOTIFY, 1164 FALSE 1165 ); 1166 1167 // 1168 // Generate Notify Payload. If transport mode, there should have Notify 1169 // payload with TRANSPORT_MODE notification. 1170 // 1171 NotifyPayload = Ikev2GenerateNotifyPayload ( 1172 0, 1173 IKEV2_PAYLOAD_TYPE_NONE, 1174 0, 1175 IKEV2_NOTIFICATION_USE_TRANSPORT_MODE, 1176 NULL, 1177 NULL, 1178 0 1179 ); 1180 if (NotifyPayload == NULL) { 1181 goto CheckError; 1182 } 1183 } else { 1184 // 1185 // Generate Tsr for Tunnel mode. 1186 // 1187 TsiPayload = Ikev2GenerateTsPayload ( 1188 ChildSaSession, 1189 IKEV2_PAYLOAD_TYPE_TS_RSP, 1190 TRUE 1191 ); 1192 TsrPayload = Ikev2GenerateTsPayload ( 1193 ChildSaSession, 1194 IKEV2_PAYLOAD_TYPE_NONE, 1195 FALSE 1196 ); 1197 } 1198 1199 if (TsiPayload == NULL || TsrPayload == NULL) { 1200 goto CheckError; 1201 } 1202 1203 IKE_PACKET_APPEND_PAYLOAD (IkePacket, IdPayload); 1204 IKE_PACKET_APPEND_PAYLOAD (IkePacket, CertPayload); 1205 if (IkeSaSession->SessionCommon.IsInitiator) { 1206 IKE_PACKET_APPEND_PAYLOAD (IkePacket, CertReqPayload); 1207 } 1208 IKE_PACKET_APPEND_PAYLOAD (IkePacket, AuthPayload); 1209 if (IkeSaSession->Spd->Data->ProcessingPolicy->Mode == EfiIPsecTunnel) { 1210 IKE_PACKET_APPEND_PAYLOAD (IkePacket, CpPayload); 1211 } 1212 IKE_PACKET_APPEND_PAYLOAD (IkePacket, SaPayload); 1213 IKE_PACKET_APPEND_PAYLOAD (IkePacket, TsiPayload); 1214 IKE_PACKET_APPEND_PAYLOAD (IkePacket, TsrPayload); 1215 if (IkeSaSession->Spd->Data->ProcessingPolicy->Mode == EfiIPsecTransport) { 1216 IKE_PACKET_APPEND_PAYLOAD (IkePacket, NotifyPayload); 1217 } 1218 1219 return IkePacket; 1220 1221 CheckError: 1222 if (IkePacket != NULL) { 1223 IkePacketFree (IkePacket); 1224 } 1225 1226 if (IdPayload != NULL) { 1227 IkePayloadFree (IdPayload); 1228 } 1229 1230 if (CertPayload != NULL) { 1231 IkePayloadFree (CertPayload); 1232 } 1233 1234 if (CertReqPayload != NULL) { 1235 IkePayloadFree (CertReqPayload); 1236 } 1237 1238 if (AuthPayload != NULL) { 1239 IkePayloadFree (AuthPayload); 1240 } 1241 1242 if (CpPayload != NULL) { 1243 IkePayloadFree (CpPayload); 1244 } 1245 1246 if (SaPayload != NULL) { 1247 IkePayloadFree (SaPayload); 1248 } 1249 1250 if (TsiPayload != NULL) { 1251 IkePayloadFree (TsiPayload); 1252 } 1253 1254 if (TsrPayload != NULL) { 1255 IkePayloadFree (TsrPayload); 1256 } 1257 1258 if (NotifyPayload != NULL) { 1259 IkePayloadFree (NotifyPayload); 1260 } 1261 1262 return NULL; 1263 } 1264 1265 /** 1266 Parses IKE_AUTH packet. 1267 1268 @param[in] SaSession Pointer to the IKE_SA_SESSION related to this packet. 1269 @param[in] IkePacket Pointer to the IKE_AUTH packet to be parsered. 1270 1271 @retval EFI_INVALID_PARAMETER The IKEv2 packet is malformed or the SA 1272 proposal is unacceptable. 1273 @retval EFI_SUCCESS The IKE packet is acceptable and the 1274 relative data is saved for furthure communication. 1275 @retval EFI_UNSUPPORTED The certificate authentication is not supported. 1276 1277 **/ 1278 EFI_STATUS 1279 Ikev2AuthCertParser ( 1280 IN UINT8 *SaSession, 1281 IN IKE_PACKET *IkePacket 1282 ) 1283 { 1284 IKEV2_CHILD_SA_SESSION *ChildSaSession; 1285 IKEV2_SA_SESSION *IkeSaSession; 1286 IKE_PAYLOAD *IkePayload; 1287 IKE_PAYLOAD *SaPayload; 1288 IKE_PAYLOAD *IdiPayload; 1289 IKE_PAYLOAD *IdrPayload; 1290 IKE_PAYLOAD *AuthPayload; 1291 IKE_PAYLOAD *TsiPayload; 1292 IKE_PAYLOAD *TsrPayload; 1293 IKE_PAYLOAD *CertPayload; 1294 IKE_PAYLOAD *VerifiedAuthPayload; 1295 LIST_ENTRY *Entry; 1296 EFI_STATUS Status; 1297 1298 if (!FeaturePcdGet (PcdIpsecCertificateEnabled)) { 1299 return EFI_UNSUPPORTED; 1300 } 1301 1302 IkeSaSession = (IKEV2_SA_SESSION *) SaSession; 1303 ChildSaSession = IKEV2_CHILD_SA_SESSION_BY_IKE_SA (GetFirstNode (&IkeSaSession->ChildSaSessionList)); 1304 1305 SaPayload = NULL; 1306 IdiPayload = NULL; 1307 IdrPayload = NULL; 1308 AuthPayload = NULL; 1309 TsiPayload = NULL; 1310 TsrPayload = NULL; 1311 CertPayload = NULL; 1312 VerifiedAuthPayload = NULL; 1313 Status = EFI_INVALID_PARAMETER; 1314 1315 // 1316 // Iterate payloads to find the SaPayload/ID/AUTH/TS Payload. 1317 // 1318 NET_LIST_FOR_EACH (Entry, &(IkePacket)->PayloadList) { 1319 IkePayload = IKE_PAYLOAD_BY_PACKET (Entry); 1320 1321 if (IkePayload->PayloadType == IKEV2_PAYLOAD_TYPE_ID_INIT) { 1322 IdiPayload = IkePayload; 1323 } 1324 if (IkePayload->PayloadType == IKEV2_PAYLOAD_TYPE_ID_RSP) { 1325 IdrPayload = IkePayload; 1326 } 1327 1328 if (IkePayload->PayloadType == IKEV2_PAYLOAD_TYPE_SA) { 1329 SaPayload = IkePayload; 1330 } 1331 if (IkePayload->PayloadType == IKEV2_PAYLOAD_TYPE_AUTH) { 1332 AuthPayload = IkePayload; 1333 } 1334 if (IkePayload->PayloadType == IKEV2_PAYLOAD_TYPE_TS_INIT) { 1335 TsiPayload = IkePayload; 1336 } 1337 if (IkePayload->PayloadType == IKEV2_PAYLOAD_TYPE_TS_RSP) { 1338 TsrPayload = IkePayload; 1339 } 1340 if (IkePayload->PayloadType == IKEV2_PAYLOAD_TYPE_CERT) { 1341 CertPayload = IkePayload; 1342 } 1343 } 1344 1345 if ((SaPayload == NULL) || (AuthPayload == NULL) || (TsiPayload == NULL) || 1346 (TsrPayload == NULL) || (CertPayload == NULL)) { 1347 goto Exit; 1348 } 1349 if ((IdiPayload == NULL) && (IdrPayload == NULL)) { 1350 goto Exit; 1351 } 1352 1353 // 1354 // Check IkePacket Header is match the state 1355 // 1356 if (IkeSaSession->SessionCommon.IsInitiator) { 1357 1358 // 1359 // 1. Check the IkePacket->Hdr == IKE_HEADER_FLAGS_RESPOND 1360 // 1361 if ((IkePacket->Header->Flags != IKE_HEADER_FLAGS_RESPOND) || 1362 (IkePacket->Header->ExchangeType != IKEV2_EXCHANGE_TYPE_AUTH)) { 1363 goto Exit; 1364 } 1365 } else { 1366 // 1367 // 1. Check the IkePacket->Hdr == IKE_HEADER_FLAGS_INIT 1368 // 1369 if ((IkePacket->Header->Flags != IKE_HEADER_FLAGS_INIT) || 1370 (IkePacket->Header->ExchangeType != IKEV2_EXCHANGE_TYPE_AUTH)) { 1371 goto Exit; 1372 } 1373 } 1374 1375 // 1376 // Verify the Auth Payload. 1377 // 1378 VerifiedAuthPayload = Ikev2CertGenerateAuthPayload ( 1379 IkeSaSession, 1380 IkeSaSession->SessionCommon.IsInitiator ? IdrPayload:IdiPayload, 1381 IKEV2_PAYLOAD_TYPE_SA, 1382 TRUE, 1383 NULL, 1384 0, 1385 NULL, 1386 0 1387 ); 1388 1389 if ((VerifiedAuthPayload != NULL) && 1390 (!IpSecCryptoIoVerifySignDataByCertificate ( 1391 CertPayload->PayloadBuf + sizeof (IKEV2_CERT), 1392 CertPayload->PayloadSize - sizeof (IKEV2_CERT), 1393 (UINT8 *)PcdGetPtr (PcdIpsecUefiCaFile), 1394 PcdGet32 (PcdIpsecUefiCaFileSize), 1395 VerifiedAuthPayload->PayloadBuf + sizeof (IKEV2_AUTH), 1396 VerifiedAuthPayload->PayloadSize - sizeof (IKEV2_AUTH), 1397 AuthPayload->PayloadBuf + sizeof (IKEV2_AUTH), 1398 AuthPayload->PayloadSize - sizeof (IKEV2_AUTH) 1399 ))) { 1400 goto Exit; 1401 } 1402 1403 // 1404 // 3. Parse the SA Payload to find out the cryptographic suite 1405 // and fill in the SA paramse into CommonSession->SaParams. If no acceptable 1406 // porposal found, return EFI_INVALID_PARAMETER. 1407 // 1408 if (!Ikev2ChildSaParseSaPayload (ChildSaSession, SaPayload, IkePacket->Header->Flags)) { 1409 goto Exit; 1410 } 1411 1412 // 1413 // 4. Parse TSi, TSr payloads. 1414 // 1415 if ((((TRAFFIC_SELECTOR *)(TsiPayload->PayloadBuf + sizeof (IKEV2_TS)))->IpProtocolId != 1416 ((TRAFFIC_SELECTOR *)(TsrPayload->PayloadBuf + sizeof (IKEV2_TS)))->IpProtocolId) && 1417 (((TRAFFIC_SELECTOR *)(TsiPayload->PayloadBuf + sizeof (IKEV2_TS)))->IpProtocolId != 0) && 1418 (((TRAFFIC_SELECTOR *)(TsrPayload->PayloadBuf + sizeof (IKEV2_TS)))->IpProtocolId != 0) 1419 ) { 1420 goto Exit; 1421 } 1422 1423 if (!IkeSaSession->SessionCommon.IsInitiator) { 1424 // 1425 //Todo:check the Port range. Only support any port and one certain port here. 1426 // 1427 ChildSaSession->ProtoId = ((TRAFFIC_SELECTOR *)(TsrPayload->PayloadBuf + sizeof (IKEV2_TS)))->IpProtocolId; 1428 ChildSaSession->LocalPort = ((TRAFFIC_SELECTOR *)(TsrPayload->PayloadBuf + sizeof (IKEV2_TS)))->StartPort; 1429 ChildSaSession->RemotePort = ((TRAFFIC_SELECTOR *)(TsiPayload->PayloadBuf + sizeof (IKEV2_TS)))->StartPort; 1430 // 1431 // Association a SPD with this SA. 1432 // 1433 if (EFI_ERROR (Ikev2ChildSaAssociateSpdEntry (ChildSaSession))) { 1434 goto Exit; 1435 } 1436 // 1437 // Associate the IkeSaSession's SPD to the first ChildSaSession's SPD. 1438 // 1439 if (ChildSaSession->IkeSaSession->Spd == NULL) { 1440 ChildSaSession->IkeSaSession->Spd = ChildSaSession->Spd; 1441 Status = Ikev2ChildSaSessionSpdSelectorCreate (ChildSaSession); 1442 if (EFI_ERROR (Status)) { 1443 goto Exit; 1444 } 1445 } 1446 } else { 1447 // 1448 // Todo:check the Port range. 1449 // 1450 if ((((TRAFFIC_SELECTOR *)(TsrPayload->PayloadBuf + sizeof (IKEV2_TS)))->StartPort != 0) && 1451 (((TRAFFIC_SELECTOR *)(TsrPayload->PayloadBuf + sizeof (IKEV2_TS)))->StartPort != ChildSaSession->RemotePort) 1452 ) { 1453 goto Exit; 1454 } 1455 if ((((TRAFFIC_SELECTOR *)(TsiPayload->PayloadBuf + sizeof (IKEV2_TS)))->StartPort != 0) && 1456 (((TRAFFIC_SELECTOR *)(TsiPayload->PayloadBuf + sizeof (IKEV2_TS)))->StartPort != ChildSaSession->LocalPort) 1457 ) { 1458 goto Exit; 1459 } 1460 // 1461 // For the tunnel mode, it should add the vitual IP address into the SA's SPD Selector. 1462 // 1463 if (ChildSaSession->Spd->Data->ProcessingPolicy->Mode == EfiIPsecTunnel) { 1464 if (!ChildSaSession->IkeSaSession->SessionCommon.IsInitiator) { 1465 // 1466 // If it is tunnel mode, the UEFI part must be the initiator. 1467 // 1468 goto Exit; 1469 } 1470 // 1471 // Get the Virtual IP address from the Tsi traffic selector. 1472 // TODO: check the CFG reply payload 1473 // 1474 CopyMem ( 1475 &ChildSaSession->SpdSelector->LocalAddress[0].Address, 1476 TsiPayload->PayloadBuf + sizeof (IKEV2_TS) + sizeof (TRAFFIC_SELECTOR), 1477 (ChildSaSession->SessionCommon.UdpService->IpVersion == IP_VERSION_4) ? 1478 sizeof (EFI_IPv4_ADDRESS) : sizeof (EFI_IPv6_ADDRESS) 1479 ); 1480 } 1481 } 1482 1483 // 1484 // 5. Generat keymats for IPsec protocol. 1485 // 1486 Status = Ikev2GenerateChildSaKeys (ChildSaSession, NULL); 1487 if (EFI_ERROR (Status)) { 1488 goto Exit; 1489 } 1490 1491 if (IkeSaSession->SessionCommon.IsInitiator) { 1492 // 1493 // 6. Change the state of IkeSaSession 1494 // 1495 IKEV2_DUMP_STATE (IkeSaSession->SessionCommon.State, IkeStateIkeSaEstablished); 1496 IkeSaSession->SessionCommon.State = IkeStateIkeSaEstablished; 1497 } 1498 1499 Status = EFI_SUCCESS; 1500 1501 Exit: 1502 if (VerifiedAuthPayload != NULL) { 1503 IkePayloadFree (VerifiedAuthPayload); 1504 } 1505 return Status; 1506 } 1507 1508 /** 1509 Generates the DH Public Key. 1510 1511 This generates the DH local public key and store it in the IKE SA Session's GxBuffer. 1512 1513 @param[in] IkeSaSession Pointer to related IKE SA Session. 1514 1515 @retval EFI_SUCCESS The operation succeeded. 1516 @retval Others The operation failed. 1517 1518 **/ 1519 EFI_STATUS 1520 Ikev2GenerateSaDhPublicKey ( 1521 IN IKEV2_SA_SESSION *IkeSaSession 1522 ) 1523 { 1524 EFI_STATUS Status; 1525 IKEV2_SESSION_KEYS *IkeKeys; 1526 1527 IkeSaSession->IkeKeys = AllocateZeroPool (sizeof (IKEV2_SESSION_KEYS)); 1528 if (IkeSaSession->IkeKeys == NULL) { 1529 return EFI_OUT_OF_RESOURCES; 1530 } 1531 1532 IkeKeys = IkeSaSession->IkeKeys; 1533 IkeKeys->DhBuffer = AllocateZeroPool (sizeof (IKEV2_DH_BUFFER)); 1534 if (IkeKeys->DhBuffer == NULL) { 1535 FreePool (IkeSaSession->IkeKeys); 1536 return EFI_OUT_OF_RESOURCES; 1537 } 1538 1539 // 1540 // Init DH with the certain DH Group Description. 1541 // 1542 IkeKeys->DhBuffer->GxSize = OakleyModpGroup[(UINT8)IkeSaSession->SessionCommon.PreferDhGroup].Size >> 3; 1543 IkeKeys->DhBuffer->GxBuffer = AllocateZeroPool (IkeKeys->DhBuffer->GxSize); 1544 if (IkeKeys->DhBuffer->GxBuffer == NULL) { 1545 FreePool (IkeKeys->DhBuffer); 1546 FreePool (IkeSaSession->IkeKeys); 1547 return EFI_OUT_OF_RESOURCES; 1548 } 1549 1550 // 1551 // Get X PublicKey 1552 // 1553 Status = IpSecCryptoIoDhGetPublicKey ( 1554 &IkeKeys->DhBuffer->DhContext, 1555 OakleyModpGroup[(UINT8)IkeSaSession->SessionCommon.PreferDhGroup].GroupGenerator, 1556 OakleyModpGroup[(UINT8)IkeSaSession->SessionCommon.PreferDhGroup].Size, 1557 OakleyModpGroup[(UINT8)IkeSaSession->SessionCommon.PreferDhGroup].Modulus, 1558 IkeKeys->DhBuffer->GxBuffer, 1559 &IkeKeys->DhBuffer->GxSize 1560 ); 1561 if (EFI_ERROR (Status)) { 1562 DEBUG ((DEBUG_ERROR, "Error CPLKeyManGetKeyParam X public key error Status = %r\n", Status)); 1563 1564 FreePool (IkeKeys->DhBuffer->GxBuffer); 1565 1566 FreePool (IkeKeys->DhBuffer); 1567 1568 FreePool (IkeSaSession->IkeKeys); 1569 1570 return Status; 1571 } 1572 1573 IPSEC_DUMP_BUF ("DH Public Key (g^x) Dump", IkeKeys->DhBuffer->GxBuffer, IkeKeys->DhBuffer->GxSize); 1574 1575 return EFI_SUCCESS; 1576 } 1577 1578 /** 1579 Computes the DH Shared/Exchange Key. 1580 1581 Given peer's public key, this function computes the exchanged common key and 1582 stores it in the IKEv2 SA Session's GxyBuffer. 1583 1584 @param[in] DhBuffer Pointer to buffer of peer's puliic key. 1585 @param[in] KePayload Pointer to received key payload. 1586 1587 @retval EFI_SUCCESS The operation succeeded. 1588 @retval Otherwise The operation failed. 1589 1590 **/ 1591 EFI_STATUS 1592 Ikev2GenerateSaDhComputeKey ( 1593 IN IKEV2_DH_BUFFER *DhBuffer, 1594 IN IKE_PAYLOAD *KePayload 1595 ) 1596 { 1597 EFI_STATUS Status; 1598 IKEV2_KEY_EXCHANGE *Ke; 1599 UINT8 *PubKey; 1600 UINTN PubKeySize; 1601 1602 Ke = (IKEV2_KEY_EXCHANGE *) KePayload->PayloadBuf; 1603 PubKey = (UINT8 *) (Ke + 1); 1604 PubKeySize = KePayload->PayloadSize - sizeof (IKEV2_KEY_EXCHANGE); 1605 DhBuffer->GxySize = DhBuffer->GxSize; 1606 DhBuffer->GxyBuffer = AllocateZeroPool (DhBuffer->GxySize); 1607 if (DhBuffer->GxyBuffer == NULL) { 1608 return EFI_OUT_OF_RESOURCES; 1609 } 1610 1611 // 1612 // Get GxyBuf 1613 // 1614 Status = IpSecCryptoIoDhComputeKey ( 1615 DhBuffer->DhContext, 1616 PubKey, 1617 PubKeySize, 1618 DhBuffer->GxyBuffer, 1619 &DhBuffer->GxySize 1620 ); 1621 if (EFI_ERROR (Status)) { 1622 DEBUG ((DEBUG_ERROR, "Error CPLKeyManGetKeyParam Y session key error Status = %r\n", Status)); 1623 1624 FreePool (DhBuffer->GxyBuffer); 1625 1626 return Status; 1627 } 1628 1629 // 1630 // Create GxyBuf. 1631 // 1632 DhBuffer->GySize = PubKeySize; 1633 DhBuffer->GyBuffer = AllocateZeroPool (DhBuffer->GySize); 1634 if (DhBuffer->GyBuffer == NULL) { 1635 FreePool (DhBuffer->GxyBuffer); 1636 1637 return Status; 1638 } 1639 1640 CopyMem (DhBuffer->GyBuffer, PubKey, DhBuffer->GySize); 1641 1642 IPSEC_DUMP_BUF ("DH Public Key (g^y) Dump", DhBuffer->GyBuffer, DhBuffer->GySize); 1643 IPSEC_DUMP_BUF ("DH Shared Key (g^xy) Dump", DhBuffer->GxyBuffer, DhBuffer->GxySize); 1644 1645 return EFI_SUCCESS; 1646 } 1647 1648 /** 1649 Generates the IKE SKEYSEED and seven other secrets. SK_d, SK_ai, SK_ar, SK_ei, SK_er, 1650 SK_pi, SK_pr are keys for the furthure IKE exchange. 1651 1652 @param[in] IkeSaSession Pointer to IKE SA Session. 1653 @param[in] KePayload Pointer to Key payload used to generate the Key. 1654 1655 @retval EFI_UNSUPPORTED If one or more Algorithm Id is not supported. 1656 @retval EFI_OUT_OF_RESOURCES If there is no enough resource to be allocated to 1657 meet the requirement. 1658 @retval EFI_SUCCESS The operation succeeded. 1659 1660 **/ 1661 EFI_STATUS 1662 Ikev2GenerateSaKeys ( 1663 IN IKEV2_SA_SESSION *IkeSaSession, 1664 IN IKE_PAYLOAD *KePayload 1665 ) 1666 { 1667 EFI_STATUS Status; 1668 IKEV2_SA_PARAMS *SaParams; 1669 PRF_DATA_FRAGMENT Fragments[4]; 1670 UINT64 InitiatorCookieNet; 1671 UINT64 ResponderCookieNet; 1672 UINT8 *KeyBuffer; 1673 UINTN KeyBufferSize; 1674 UINTN AuthAlgKeyLen; 1675 UINTN EncryptAlgKeyLen; 1676 UINTN IntegrityAlgKeyLen; 1677 UINTN PrfAlgKeyLen; 1678 UINT8 *OutputKey; 1679 UINTN OutputKeyLength; 1680 UINT8 *Digest; 1681 UINTN DigestSize; 1682 1683 Digest = NULL; 1684 OutputKey = NULL; 1685 KeyBuffer = NULL; 1686 Status = EFI_SUCCESS; 1687 1688 // 1689 // Generate Gxy 1690 // 1691 Status = Ikev2GenerateSaDhComputeKey (IkeSaSession->IkeKeys->DhBuffer, KePayload); 1692 if (EFI_ERROR (Status)) { 1693 goto Exit; 1694 } 1695 1696 // 1697 // Get the key length of Authenticaion, Encryption, PRF, and Integrity. 1698 // 1699 SaParams = IkeSaSession->SessionCommon.SaParams; 1700 AuthAlgKeyLen = IpSecGetHmacDigestLength ((UINT8)SaParams->Prf); 1701 EncryptAlgKeyLen = IpSecGetEncryptKeyLength ((UINT8)SaParams->EncAlgId); 1702 IntegrityAlgKeyLen = IpSecGetHmacDigestLength ((UINT8)SaParams->IntegAlgId); 1703 PrfAlgKeyLen = IpSecGetHmacDigestLength ((UINT8)SaParams->Prf); 1704 1705 // 1706 // If one or more algorithm is not support, return EFI_UNSUPPORTED. 1707 // 1708 if (AuthAlgKeyLen == 0 || 1709 EncryptAlgKeyLen == 0 || 1710 IntegrityAlgKeyLen == 0 || 1711 PrfAlgKeyLen == 0 1712 ) { 1713 Status = EFI_UNSUPPORTED; 1714 goto Exit; 1715 } 1716 1717 // 1718 // Compute SKEYSEED = prf(Ni | Nr, g^ir) 1719 // 1720 KeyBufferSize = IkeSaSession->NiBlkSize + IkeSaSession->NrBlkSize; 1721 KeyBuffer = AllocateZeroPool (KeyBufferSize); 1722 if (KeyBuffer == NULL) { 1723 Status = EFI_OUT_OF_RESOURCES; 1724 goto Exit; 1725 } 1726 1727 CopyMem (KeyBuffer, IkeSaSession->NiBlock, IkeSaSession->NiBlkSize); 1728 CopyMem (KeyBuffer + IkeSaSession->NiBlkSize, IkeSaSession->NrBlock, IkeSaSession->NrBlkSize); 1729 1730 Fragments[0].Data = IkeSaSession->IkeKeys->DhBuffer->GxyBuffer; 1731 Fragments[0].DataSize = IkeSaSession->IkeKeys->DhBuffer->GxySize; 1732 1733 DigestSize = IpSecGetHmacDigestLength ((UINT8)SaParams->Prf); 1734 Digest = AllocateZeroPool (DigestSize); 1735 1736 if (Digest == NULL) { 1737 Status = EFI_OUT_OF_RESOURCES; 1738 goto Exit; 1739 } 1740 1741 IpSecCryptoIoHmac ( 1742 (UINT8)SaParams->Prf, 1743 KeyBuffer, 1744 KeyBufferSize, 1745 (HASH_DATA_FRAGMENT *) Fragments, 1746 1, 1747 Digest, 1748 DigestSize 1749 ); 1750 1751 // 1752 // {SK_d | SK_ai | SK_ar | SK_ei | SK_er | SK_pi | SK_pr } = prf+ 1753 // (SKEYSEED, Ni | Nr | SPIi | SPIr ) 1754 // 1755 Fragments[0].Data = IkeSaSession->NiBlock; 1756 Fragments[0].DataSize = IkeSaSession->NiBlkSize; 1757 Fragments[1].Data = IkeSaSession->NrBlock; 1758 Fragments[1].DataSize = IkeSaSession->NrBlkSize; 1759 InitiatorCookieNet = HTONLL (IkeSaSession->InitiatorCookie); 1760 ResponderCookieNet = HTONLL (IkeSaSession->ResponderCookie); 1761 Fragments[2].Data = (UINT8 *)(&InitiatorCookieNet); 1762 Fragments[2].DataSize = sizeof (IkeSaSession->InitiatorCookie); 1763 Fragments[3].Data = (UINT8 *)(&ResponderCookieNet); 1764 Fragments[3].DataSize = sizeof (IkeSaSession->ResponderCookie); 1765 1766 IPSEC_DUMP_BUF (">>> NiBlock", IkeSaSession->NiBlock, IkeSaSession->NiBlkSize); 1767 IPSEC_DUMP_BUF (">>> NrBlock", IkeSaSession->NrBlock, IkeSaSession->NrBlkSize); 1768 IPSEC_DUMP_BUF (">>> InitiatorCookie", (UINT8 *)&IkeSaSession->InitiatorCookie, sizeof(UINT64)); 1769 IPSEC_DUMP_BUF (">>> ResponderCookie", (UINT8 *)&IkeSaSession->ResponderCookie, sizeof(UINT64)); 1770 1771 OutputKeyLength = PrfAlgKeyLen + 1772 2 * EncryptAlgKeyLen + 1773 2 * AuthAlgKeyLen + 1774 2 * IntegrityAlgKeyLen; 1775 OutputKey = AllocateZeroPool (OutputKeyLength); 1776 if (OutputKey == NULL) { 1777 Status = EFI_OUT_OF_RESOURCES; 1778 goto Exit; 1779 } 1780 1781 // 1782 // Generate Seven Keymates. 1783 // 1784 Status = Ikev2SaGenerateKey ( 1785 (UINT8)SaParams->Prf, 1786 Digest, 1787 DigestSize, 1788 OutputKey, 1789 OutputKeyLength, 1790 Fragments, 1791 4 1792 ); 1793 if (EFI_ERROR(Status)) { 1794 goto Exit; 1795 } 1796 1797 // 1798 // Save the seven keys into KeySession. 1799 // First, SK_d 1800 // 1801 IkeSaSession->IkeKeys->SkdKey = AllocateZeroPool (PrfAlgKeyLen); 1802 if (IkeSaSession->IkeKeys->SkdKey == NULL) { 1803 Status = EFI_OUT_OF_RESOURCES; 1804 goto Exit; 1805 } 1806 IkeSaSession->IkeKeys->SkdKeySize = PrfAlgKeyLen; 1807 CopyMem (IkeSaSession->IkeKeys->SkdKey, OutputKey, PrfAlgKeyLen); 1808 1809 IPSEC_DUMP_BUF (">>> SK_D Key", IkeSaSession->IkeKeys->SkdKey, PrfAlgKeyLen); 1810 1811 // 1812 // Second, Sk_ai 1813 // 1814 IkeSaSession->IkeKeys->SkAiKey = AllocateZeroPool (IntegrityAlgKeyLen); 1815 if (IkeSaSession->IkeKeys->SkAiKey == NULL) { 1816 Status = EFI_OUT_OF_RESOURCES; 1817 goto Exit; 1818 } 1819 IkeSaSession->IkeKeys->SkAiKeySize = IntegrityAlgKeyLen; 1820 CopyMem (IkeSaSession->IkeKeys->SkAiKey, OutputKey + PrfAlgKeyLen, IntegrityAlgKeyLen); 1821 1822 IPSEC_DUMP_BUF (">>> SK_Ai Key", IkeSaSession->IkeKeys->SkAiKey, IkeSaSession->IkeKeys->SkAiKeySize); 1823 1824 // 1825 // Third, Sk_ar 1826 // 1827 IkeSaSession->IkeKeys->SkArKey = AllocateZeroPool (IntegrityAlgKeyLen); 1828 if (IkeSaSession->IkeKeys->SkArKey == NULL) { 1829 Status = EFI_OUT_OF_RESOURCES; 1830 goto Exit; 1831 } 1832 IkeSaSession->IkeKeys->SkArKeySize = IntegrityAlgKeyLen; 1833 CopyMem ( 1834 IkeSaSession->IkeKeys->SkArKey, 1835 OutputKey + PrfAlgKeyLen + IntegrityAlgKeyLen, 1836 IntegrityAlgKeyLen 1837 ); 1838 1839 IPSEC_DUMP_BUF (">>> SK_Ar Key", IkeSaSession->IkeKeys->SkArKey, IkeSaSession->IkeKeys->SkArKeySize); 1840 1841 // 1842 // Fourth, Sk_ei 1843 // 1844 IkeSaSession->IkeKeys->SkEiKey = AllocateZeroPool (EncryptAlgKeyLen); 1845 if (IkeSaSession->IkeKeys->SkEiKey == NULL) { 1846 Status = EFI_OUT_OF_RESOURCES; 1847 goto Exit; 1848 } 1849 IkeSaSession->IkeKeys->SkEiKeySize = EncryptAlgKeyLen; 1850 1851 CopyMem ( 1852 IkeSaSession->IkeKeys->SkEiKey, 1853 OutputKey + AuthAlgKeyLen + 2 * IntegrityAlgKeyLen, 1854 EncryptAlgKeyLen 1855 ); 1856 IPSEC_DUMP_BUF ( 1857 ">>> SK_Ei Key", 1858 OutputKey + AuthAlgKeyLen + 2 * IntegrityAlgKeyLen, 1859 EncryptAlgKeyLen 1860 ); 1861 1862 // 1863 // Fifth, Sk_er 1864 // 1865 IkeSaSession->IkeKeys->SkErKey = AllocateZeroPool (EncryptAlgKeyLen); 1866 if (IkeSaSession->IkeKeys->SkErKey == NULL) { 1867 Status = EFI_OUT_OF_RESOURCES; 1868 goto Exit; 1869 } 1870 IkeSaSession->IkeKeys->SkErKeySize = EncryptAlgKeyLen; 1871 1872 CopyMem ( 1873 IkeSaSession->IkeKeys->SkErKey, 1874 OutputKey + AuthAlgKeyLen + 2 * IntegrityAlgKeyLen + EncryptAlgKeyLen, 1875 EncryptAlgKeyLen 1876 ); 1877 IPSEC_DUMP_BUF ( 1878 ">>> SK_Er Key", 1879 OutputKey + AuthAlgKeyLen + 2 * IntegrityAlgKeyLen + EncryptAlgKeyLen, 1880 EncryptAlgKeyLen 1881 ); 1882 1883 // 1884 // Sixth, Sk_pi 1885 // 1886 IkeSaSession->IkeKeys->SkPiKey = AllocateZeroPool (AuthAlgKeyLen); 1887 if (IkeSaSession->IkeKeys->SkPiKey == NULL) { 1888 Status = EFI_OUT_OF_RESOURCES; 1889 goto Exit; 1890 } 1891 IkeSaSession->IkeKeys->SkPiKeySize = AuthAlgKeyLen; 1892 1893 CopyMem ( 1894 IkeSaSession->IkeKeys->SkPiKey, 1895 OutputKey + AuthAlgKeyLen + 2 * IntegrityAlgKeyLen + 2 * EncryptAlgKeyLen, 1896 AuthAlgKeyLen 1897 ); 1898 IPSEC_DUMP_BUF ( 1899 ">>> SK_Pi Key", 1900 OutputKey + AuthAlgKeyLen + 2 * IntegrityAlgKeyLen + 2 * EncryptAlgKeyLen, 1901 AuthAlgKeyLen 1902 ); 1903 1904 // 1905 // Seventh, Sk_pr 1906 // 1907 IkeSaSession->IkeKeys->SkPrKey = AllocateZeroPool (AuthAlgKeyLen); 1908 if (IkeSaSession->IkeKeys->SkPrKey == NULL) { 1909 Status = EFI_OUT_OF_RESOURCES; 1910 goto Exit; 1911 } 1912 IkeSaSession->IkeKeys->SkPrKeySize = AuthAlgKeyLen; 1913 1914 CopyMem ( 1915 IkeSaSession->IkeKeys->SkPrKey, 1916 OutputKey + AuthAlgKeyLen + 2 * IntegrityAlgKeyLen + 2 * EncryptAlgKeyLen + AuthAlgKeyLen, 1917 AuthAlgKeyLen 1918 ); 1919 IPSEC_DUMP_BUF ( 1920 ">>> SK_Pr Key", 1921 OutputKey + AuthAlgKeyLen + 2 * IntegrityAlgKeyLen + 2 * EncryptAlgKeyLen + AuthAlgKeyLen, 1922 AuthAlgKeyLen 1923 ); 1924 1925 1926 Exit: 1927 if (Digest != NULL) { 1928 FreePool (Digest); 1929 } 1930 if (KeyBuffer != NULL) { 1931 FreePool (KeyBuffer); 1932 } 1933 if (OutputKey != NULL) { 1934 FreePool (OutputKey); 1935 } 1936 1937 if (EFI_ERROR(Status)) { 1938 if (IkeSaSession->IkeKeys->SkdKey != NULL) { 1939 FreePool (IkeSaSession->IkeKeys->SkdKey); 1940 } 1941 if (IkeSaSession->IkeKeys->SkAiKey != NULL) { 1942 FreePool (IkeSaSession->IkeKeys->SkAiKey); 1943 } 1944 if (IkeSaSession->IkeKeys->SkArKey != NULL) { 1945 FreePool (IkeSaSession->IkeKeys->SkArKey); 1946 } 1947 if (IkeSaSession->IkeKeys->SkEiKey != NULL) { 1948 FreePool (IkeSaSession->IkeKeys->SkEiKey); 1949 } 1950 if (IkeSaSession->IkeKeys->SkErKey != NULL) { 1951 FreePool (IkeSaSession->IkeKeys->SkErKey); 1952 } 1953 if (IkeSaSession->IkeKeys->SkPiKey != NULL) { 1954 FreePool (IkeSaSession->IkeKeys->SkPiKey); 1955 } 1956 if (IkeSaSession->IkeKeys->SkPrKey != NULL) { 1957 FreePool (IkeSaSession->IkeKeys->SkPrKey); 1958 } 1959 } 1960 1961 1962 return Status; 1963 } 1964 1965 /** 1966 Generates the Keys for the furthure IPsec Protocol. 1967 1968 @param[in] ChildSaSession Pointer to IKE Child SA Session. 1969 @param[in] KePayload Pointer to Key payload used to generate the Key. 1970 1971 @retval EFI_UNSUPPORTED If one or more Algorithm Id is not supported. 1972 @retval EFI_SUCCESS The operation succeeded. 1973 1974 **/ 1975 EFI_STATUS 1976 Ikev2GenerateChildSaKeys ( 1977 IN IKEV2_CHILD_SA_SESSION *ChildSaSession, 1978 IN IKE_PAYLOAD *KePayload 1979 ) 1980 { 1981 EFI_STATUS Status; 1982 IKEV2_SA_PARAMS *SaParams; 1983 PRF_DATA_FRAGMENT Fragments[3]; 1984 UINTN EncryptAlgKeyLen; 1985 UINTN IntegrityAlgKeyLen; 1986 UINT8* OutputKey; 1987 UINTN OutputKeyLength; 1988 1989 Status = EFI_SUCCESS; 1990 OutputKey = NULL; 1991 1992 if (KePayload != NULL) { 1993 // 1994 // Generate Gxy 1995 // 1996 Status = Ikev2GenerateSaDhComputeKey (ChildSaSession->DhBuffer, KePayload); 1997 if (EFI_ERROR (Status)) { 1998 goto Exit; 1999 } 2000 2001 Fragments[0].Data = ChildSaSession->DhBuffer->GxyBuffer; 2002 Fragments[0].DataSize = ChildSaSession->DhBuffer->GxySize; 2003 } 2004 2005 Fragments[1].Data = ChildSaSession->NiBlock; 2006 Fragments[1].DataSize = ChildSaSession->NiBlkSize; 2007 Fragments[2].Data = ChildSaSession->NrBlock; 2008 Fragments[2].DataSize = ChildSaSession->NrBlkSize; 2009 2010 // 2011 // Get the key length of Authenticaion, Encryption, PRF, and Integrity. 2012 // 2013 SaParams = ChildSaSession->SessionCommon.SaParams; 2014 EncryptAlgKeyLen = IpSecGetEncryptKeyLength ((UINT8)SaParams->EncAlgId); 2015 IntegrityAlgKeyLen = IpSecGetHmacDigestLength ((UINT8)SaParams->IntegAlgId); 2016 OutputKeyLength = 2 * EncryptAlgKeyLen + 2 * IntegrityAlgKeyLen; 2017 2018 if ((EncryptAlgKeyLen == 0) || (IntegrityAlgKeyLen == 0)) { 2019 Status = EFI_UNSUPPORTED; 2020 goto Exit; 2021 } 2022 2023 // 2024 // 2025 // If KePayload is not NULL, calculate KEYMAT = prf+(SK_d, g^ir (new) | Ni | Nr ), 2026 // otherwise, KEYMAT = prf+(SK_d, Ni | Nr ) 2027 // 2028 OutputKey = AllocateZeroPool (OutputKeyLength); 2029 if (OutputKey == NULL) { 2030 Status = EFI_OUT_OF_RESOURCES; 2031 goto Exit; 2032 } 2033 2034 // 2035 // Derive Key from the SkdKey Buffer. 2036 // 2037 Status = Ikev2SaGenerateKey ( 2038 (UINT8)ChildSaSession->IkeSaSession->SessionCommon.SaParams->Prf, 2039 ChildSaSession->IkeSaSession->IkeKeys->SkdKey, 2040 ChildSaSession->IkeSaSession->IkeKeys->SkdKeySize, 2041 OutputKey, 2042 OutputKeyLength, 2043 KePayload == NULL ? &Fragments[1] : Fragments, 2044 KePayload == NULL ? 2 : 3 2045 ); 2046 2047 if (EFI_ERROR (Status)) { 2048 goto Exit; 2049 } 2050 2051 // 2052 // Copy KEYMATE (SK_ENCRYPT_i | SK_ENCRYPT_r | SK_INTEG_i | SK_INTEG_r) to 2053 // ChildKeyMates. 2054 // 2055 if (!ChildSaSession->SessionCommon.IsInitiator) { 2056 2057 // 2058 // Initiator Encryption Key 2059 // 2060 ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.EncAlgoId = (UINT8)SaParams->EncAlgId; 2061 ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.EncKeyLength = EncryptAlgKeyLen; 2062 ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.EncKey = AllocateZeroPool (EncryptAlgKeyLen); 2063 if (ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.EncKey == NULL) { 2064 Status = EFI_OUT_OF_RESOURCES; 2065 goto Exit; 2066 } 2067 2068 CopyMem ( 2069 ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.EncKey, 2070 OutputKey, 2071 EncryptAlgKeyLen 2072 ); 2073 2074 // 2075 // Initiator Authentication Key 2076 // 2077 ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.AuthAlgoId = (UINT8)SaParams->IntegAlgId; 2078 ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.AuthKeyLength = IntegrityAlgKeyLen; 2079 ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.AuthKey = AllocateZeroPool (IntegrityAlgKeyLen); 2080 if (ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.AuthKey == NULL) { 2081 Status = EFI_OUT_OF_RESOURCES; 2082 goto Exit; 2083 } 2084 2085 CopyMem ( 2086 ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.AuthKey, 2087 OutputKey + EncryptAlgKeyLen, 2088 IntegrityAlgKeyLen 2089 ); 2090 2091 // 2092 // Responder Encrypt Key 2093 // 2094 ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.EncAlgoId = (UINT8)SaParams->EncAlgId; 2095 ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.EncKeyLength = EncryptAlgKeyLen; 2096 ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.EncKey = AllocateZeroPool (EncryptAlgKeyLen); 2097 if (ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.EncKey == NULL) { 2098 Status = EFI_OUT_OF_RESOURCES; 2099 goto Exit; 2100 } 2101 2102 CopyMem ( 2103 ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.EncKey, 2104 OutputKey + EncryptAlgKeyLen + IntegrityAlgKeyLen, 2105 EncryptAlgKeyLen 2106 ); 2107 2108 // 2109 // Responder Authentication Key 2110 // 2111 ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.AuthAlgoId = (UINT8)SaParams->IntegAlgId; 2112 ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.AuthKeyLength = IntegrityAlgKeyLen; 2113 ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.AuthKey = AllocateZeroPool (IntegrityAlgKeyLen); 2114 if (ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.AuthKey == NULL) { 2115 Status = EFI_OUT_OF_RESOURCES; 2116 goto Exit; 2117 } 2118 2119 CopyMem ( 2120 ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.AuthKey, 2121 OutputKey + 2 * EncryptAlgKeyLen + IntegrityAlgKeyLen, 2122 IntegrityAlgKeyLen 2123 ); 2124 } else { 2125 // 2126 // Initiator Encryption Key 2127 // 2128 ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.EncAlgoId = (UINT8)SaParams->EncAlgId; 2129 ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.EncKeyLength = EncryptAlgKeyLen; 2130 ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.EncKey = AllocateZeroPool (EncryptAlgKeyLen); 2131 if (ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.EncKey == NULL) { 2132 Status = EFI_OUT_OF_RESOURCES; 2133 goto Exit; 2134 } 2135 2136 CopyMem ( 2137 ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.EncKey, 2138 OutputKey, 2139 EncryptAlgKeyLen 2140 ); 2141 2142 // 2143 // Initiator Authentication Key 2144 // 2145 ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.AuthAlgoId = (UINT8)SaParams->IntegAlgId; 2146 ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.AuthKeyLength = IntegrityAlgKeyLen; 2147 ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.AuthKey = AllocateZeroPool (IntegrityAlgKeyLen); 2148 if (ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.AuthKey == NULL) { 2149 Status = EFI_OUT_OF_RESOURCES; 2150 goto Exit; 2151 } 2152 2153 CopyMem ( 2154 ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.AuthKey, 2155 OutputKey + EncryptAlgKeyLen, 2156 IntegrityAlgKeyLen 2157 ); 2158 2159 // 2160 // Responder Encryption Key 2161 // 2162 ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.EncAlgoId = (UINT8)SaParams->EncAlgId; 2163 ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.EncKeyLength = EncryptAlgKeyLen; 2164 ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.EncKey = AllocateZeroPool (EncryptAlgKeyLen); 2165 if (ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.EncKey == NULL) { 2166 Status = EFI_OUT_OF_RESOURCES; 2167 goto Exit; 2168 } 2169 2170 CopyMem ( 2171 ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.EncKey, 2172 OutputKey + EncryptAlgKeyLen + IntegrityAlgKeyLen, 2173 EncryptAlgKeyLen 2174 ); 2175 2176 // 2177 // Responder Authentication Key 2178 // 2179 ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.AuthAlgoId = (UINT8)SaParams->IntegAlgId; 2180 ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.AuthKeyLength = IntegrityAlgKeyLen; 2181 ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.AuthKey = AllocateZeroPool (IntegrityAlgKeyLen); 2182 if (ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.AuthKey == NULL) { 2183 Status = EFI_OUT_OF_RESOURCES; 2184 goto Exit; 2185 } 2186 2187 CopyMem ( 2188 ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.AuthKey, 2189 OutputKey + 2 * EncryptAlgKeyLen + IntegrityAlgKeyLen, 2190 IntegrityAlgKeyLen 2191 ); 2192 } 2193 2194 IPSEC_DUMP_BUF ( 2195 " >>> Local Encryption Key", 2196 ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.EncKey, 2197 EncryptAlgKeyLen 2198 ); 2199 IPSEC_DUMP_BUF ( 2200 " >>> Remote Encryption Key", 2201 ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.EncKey, 2202 EncryptAlgKeyLen 2203 ); 2204 IPSEC_DUMP_BUF ( 2205 " >>> Local Authentication Key", 2206 ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.AuthKey, 2207 IntegrityAlgKeyLen 2208 ); 2209 IPSEC_DUMP_BUF ( 2210 " >>> Remote Authentication Key", 2211 ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.AuthKey, 2212 IntegrityAlgKeyLen 2213 ); 2214 2215 2216 2217 Exit: 2218 if (EFI_ERROR (Status)) { 2219 if (ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.EncKey != NULL) { 2220 FreePool (ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.EncKey); 2221 } 2222 if (ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.AuthKey != NULL) { 2223 FreePool (ChildSaSession->ChildKeymats.LocalPeerInfo.EspAlgoInfo.AuthKey); 2224 } 2225 if (ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.EncKey != NULL) { 2226 FreePool (ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.EncKey); 2227 } 2228 if (ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.AuthKey != NULL) { 2229 FreePool (ChildSaSession->ChildKeymats.RemotePeerInfo.EspAlgoInfo.AuthKey); 2230 } 2231 } 2232 2233 if (OutputKey != NULL) { 2234 FreePool (OutputKey); 2235 } 2236 2237 return EFI_SUCCESS; 2238 } 2239 2240 GLOBAL_REMOVE_IF_UNREFERENCED IKEV2_PACKET_HANDLER mIkev2Initial[][2] = { 2241 { //PSK 2242 { // IKEV2_INIT 2243 Ikev2InitPskParser, 2244 Ikev2InitPskGenerator 2245 }, 2246 { //IKEV2_AUTH 2247 Ikev2AuthPskParser, 2248 Ikev2AuthPskGenerator 2249 } 2250 }, 2251 { // CERT 2252 { // IKEV2_INIT 2253 Ikev2InitCertParser, 2254 Ikev2InitCertGenerator 2255 }, 2256 { // IKEV2_AUTH 2257 Ikev2AuthCertParser, 2258 Ikev2AuthCertGenerator 2259 }, 2260 }, 2261 }; 2262