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