2 The operations for IKEv2 SA.
4 (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
5 Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
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.
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.
18 #include "IpSecDebug.h"
19 #include "IkeService.h"
25 This generates the DH local public key and store it in the IKEv2 SA Session's GxBuffer.
27 @param[in] IkeSaSession Pointer to related IKE SA Session.
29 @retval EFI_SUCCESS The operation succeeded.
30 @retval Others The operation failed.
34 Ikev2GenerateSaDhPublicKey (
35 IN IKEV2_SA_SESSION
*IkeSaSession
39 Generates the IKEv2 SA key for the furthure IKEv2 exchange.
41 @param[in] IkeSaSession Pointer to IKEv2 SA Session.
42 @param[in] KePayload Pointer to Key payload used to generate the Key.
44 @retval EFI_UNSUPPORTED If the Algorithm Id is not supported.
45 @retval EFI_SUCCESS The operation succeeded.
50 IN IKEV2_SA_SESSION
*IkeSaSession
,
51 IN IKE_PAYLOAD
*KePayload
55 Generates the Keys for the furthure IPsec Protocol.
57 @param[in] ChildSaSession Pointer to IKE Child SA Session.
58 @param[in] KePayload Pointer to Key payload used to generate the Key.
60 @retval EFI_UNSUPPORTED If one or more Algorithm Id is unsupported.
61 @retval EFI_SUCCESS The operation succeeded.
65 Ikev2GenerateChildSaKeys (
66 IN IKEV2_CHILD_SA_SESSION
*ChildSaSession
,
67 IN IKE_PAYLOAD
*KePayload
71 Gernerates IKEv2 packet for IKE_SA_INIT exchange.
73 @param[in] SaSession Pointer to IKEV2_SA_SESSION related to the exchange.
74 @param[in] Context Context Data passed by caller.
76 @retval EFI_SUCCESS The IKEv2 packet generation succeeded.
77 @retval Others The IKEv2 packet generation failed.
81 Ikev2InitPskGenerator (
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
;
99 IkeSaSession
= (IKEV2_SA_SESSION
*) SaSession
;
102 // 1. Allocate IKE packet
104 IkePacket
= IkePacketAlloc ();
105 if (IkePacket
== NULL
) {
110 // 1.a Fill the IkePacket->Hdr
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;
118 if (IkeSaSession
->SessionCommon
.IsInitiator
) {
119 IkePacket
->Header
->Flags
= IKE_HEADER_FLAGS_INIT
;
121 IkePacket
->Header
->Flags
= IKE_HEADER_FLAGS_RESPOND
;
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.
128 if (IkeSaSession
->NCookie
!= NULL
) {
129 IkePacket
->Header
->NextPayload
= IKEV2_PAYLOAD_TYPE_NOTIFY
;
130 NotifyPayload
= Ikev2GenerateNotifyPayload (
132 IKEV2_PAYLOAD_TYPE_SA
,
134 IKEV2_NOTIFICATION_COOKIE
,
136 IkeSaSession
->NCookie
,
137 IkeSaSession
->NCookieSize
140 IkePacket
->Header
->NextPayload
= IKEV2_PAYLOAD_TYPE_SA
;
144 // 2. Generate SA Payload according to the SaData & SaParams
146 SaPayload
= Ikev2GenerateSaPayload (
147 IkeSaSession
->SaData
,
148 IKEV2_PAYLOAD_TYPE_KE
,
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.
158 if ((IkeSaSession
->SessionCommon
.IsInitiator
) && (IkeSaSession
->NCookie
== NULL
)) {
159 Status
= Ikev2GenerateSaDhPublicKey (IkeSaSession
);
160 if (EFI_ERROR (Status
)) {
166 // 4. Generate KE Payload according to SaParams->DhGroup
168 KePayload
= Ikev2GenerateKePayload (
170 IKEV2_PAYLOAD_TYPE_NONCE
174 // 5. Generate Nonce Payload
175 // If resending IKE_SA_INIT with Cookie Notify paylaod, no need to regenerate
176 // the Nonce Payload.
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
) {
186 if (IkeSaSession
->SessionCommon
.IsInitiator
) {
187 NoncePayload
= Ikev2GenerateNoncePayload (
188 IkeSaSession
->NiBlock
,
189 IkeSaSession
->NiBlkSize
,
190 IKEV2_PAYLOAD_TYPE_NONE
194 // The Nonce Payload has been created in Ikev2PskParser if the IkeSaSession is
197 NoncePayload
= Ikev2GenerateNoncePayload (
198 IkeSaSession
->NrBlock
,
199 IkeSaSession
->NrBlkSize
,
200 IKEV2_PAYLOAD_TYPE_NONE
204 if (NotifyPayload
!= NULL
) {
205 IKE_PACKET_APPEND_PAYLOAD (IkePacket
, NotifyPayload
);
207 if (SaPayload
!= NULL
) {
208 IKE_PACKET_APPEND_PAYLOAD (IkePacket
, SaPayload
);
210 if (KePayload
!= NULL
) {
211 IKE_PACKET_APPEND_PAYLOAD (IkePacket
, KePayload
);
213 if (NoncePayload
!= NULL
) {
214 IKE_PACKET_APPEND_PAYLOAD (IkePacket
, NoncePayload
);
220 if (IkePacket
!= NULL
) {
221 IkePacketFree (IkePacket
);
223 if (SaPayload
!= NULL
) {
224 IkePayloadFree (SaPayload
);
230 Parses the IKEv2 packet for IKE_SA_INIT exchange.
232 @param[in] SaSession Pointer to IKEV2_SA_SESSION related to the exchange.
233 @param[in] IkePacket The received IKE packet to be parsed.
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.
243 IN IKE_PACKET
*IkePacket
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
;
257 IkeSaSession
= (IKEV2_SA_SESSION
*) SaSession
;
262 NotifyPayload
= NULL
;
265 // Iterate payloads to find the SaPayload and KeyPayload.
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
;
272 if (IkePayload
->PayloadType
== IKEV2_PAYLOAD_TYPE_KE
) {
273 KeyPayload
= IkePayload
;
275 if (IkePayload
->PayloadType
== IKEV2_PAYLOAD_TYPE_NONCE
) {
276 NoncePayload
= IkePayload
;
278 if (IkePayload
->PayloadType
== IKEV2_PAYLOAD_TYPE_NOTIFY
) {
279 NotifyPayload
= IkePayload
;
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.
289 if (IkeSaSession
->SessionCommon
.IsInitiator
) {
290 if (NotifyPayload
!= NULL
&& !EFI_ERROR(Ikev2ParserNotifyCookiePayload (NotifyPayload
, IkeSaSession
))) {
295 if ((KeyPayload
== NULL
) || (SaPayload
== NULL
) || (NoncePayload
== NULL
)) {
296 return EFI_INVALID_PARAMETER
;
300 // Store NoncePayload for SKEYID computing.
302 NonceSize
= NoncePayload
->PayloadSize
- sizeof (IKEV2_COMMON_PAYLOAD_HEADER
);
303 NonceBuffer
= (UINT8
*) AllocatePool (NonceSize
);
304 if (NonceBuffer
== NULL
) {
305 Status
= EFI_OUT_OF_RESOURCES
;
311 NoncePayload
->PayloadBuf
+ sizeof (IKEV2_COMMON_PAYLOAD_HEADER
),
316 // Check if IkePacket Header matches the state
318 if (IkeSaSession
->SessionCommon
.IsInitiator
) {
320 // 1. Check the IkePacket->Hdr == IKE_HEADER_FLAGS_RESPOND
322 if (IkePacket
->Header
->Flags
!= IKE_HEADER_FLAGS_RESPOND
) {
323 Status
= EFI_INVALID_PARAMETER
;
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
331 if (!Ikev2SaParseSaPayload (IkeSaSession
, SaPayload
, IkePacket
->Header
->Flags
)) {
332 Status
= EFI_INVALID_PARAMETER
;
337 // 3. If Initiator, the NoncePayload is Nr_b.
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
;
346 // 4. Change the state of IkeSaSession
348 IkeSaSession
->SessionCommon
.State
= IkeStateAuth
;
351 // 1. Check the IkePacket->Hdr == IKE_HEADER_FLAGS_INIT
353 if (IkePacket
->Header
->Flags
!= IKE_HEADER_FLAGS_INIT
) {
354 Status
= EFI_INVALID_PARAMETER
;
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.
363 if (!Ikev2SaParseSaPayload (IkeSaSession
, SaPayload
, IkePacket
->Header
->Flags
)) {
364 Status
= EFI_INVALID_PARAMETER
;
369 // 3. Generat Dh Y parivate Key
371 Status
= Ikev2GenerateSaDhPublicKey (IkeSaSession
);
372 if (EFI_ERROR (Status
)) {
377 // 4. If Responder, the NoncePayload is Ni_b and go to generate Nr_b.
379 IkeSaSession
->NiBlock
= NonceBuffer
;
380 IkeSaSession
->NiBlkSize
= NonceSize
;
385 IkeSaSession
->NrBlock
= IkeGenerateNonce (IKE_NONCE_SIZE
);
386 ASSERT (IkeSaSession
->NrBlock
!= NULL
);
387 IkeSaSession
->NrBlkSize
= IKE_NONCE_SIZE
;
390 // 6. Save the Cookies
392 IkeSaSession
->InitiatorCookie
= IkePacket
->Header
->InitiatorCookie
;
393 IkeSaSession
->ResponderCookie
= IkeGenerateCookie ();
396 if (IkeSaSession
->SessionCommon
.PreferDhGroup
!= ((IKEV2_KEY_EXCHANGE
*)KeyPayload
->PayloadBuf
)->DhGroup
) {
397 Status
= EFI_INVALID_PARAMETER
;
401 // Call Ikev2GenerateSaKeys to create SKEYID, SKEYID_d, SKEYID_a, SKEYID_e.
403 Status
= Ikev2GenerateSaKeys (IkeSaSession
, KeyPayload
);
404 if (EFI_ERROR(Status
)) {
410 if (NonceBuffer
!= NULL
) {
411 FreePool (NonceBuffer
);
418 Generates the IKEv2 packet for IKE_AUTH exchange.
420 @param[in] SaSession Pointer to IKEV2_SA_SESSION.
421 @param[in] Context Context data passed by caller.
423 @retval Pointer to IKE Packet to be sent out.
427 Ikev2AuthPskGenerator (
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
;
444 IkeSaSession
= (IKEV2_SA_SESSION
*) SaSession
;
445 ChildSaSession
= IKEV2_CHILD_SA_SESSION_BY_IKE_SA (GetFirstNode (&IkeSaSession
->ChildSaSessionList
));
453 NotifyPayload
= NULL
;
455 NotifyPayload
= NULL
;
458 // 1. Allocate IKE Packet
460 IkePacket
= IkePacketAlloc ();
461 if (IkePacket
== NULL
) {
466 // 1.a Fill the IkePacket Header.
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
;
475 IkePacket
->Header
->NextPayload
= IKEV2_PAYLOAD_TYPE_ID_RSP
;
479 // According to RFC4306_2.2, For the IKE_SA_INIT message the MessageID should
480 // be always number 0 and 1;
482 IkePacket
->Header
->MessageId
= 1;
484 if (IkeSaSession
->SessionCommon
.IsInitiator
) {
485 IkePacket
->Header
->Flags
= IKE_HEADER_FLAGS_INIT
;
487 IkePacket
->Header
->Flags
= IKE_HEADER_FLAGS_RESPOND
;
491 // 2. Generate ID Payload according to IP version and address.
493 IdPayload
= Ikev2GenerateIdPayload (
494 &IkeSaSession
->SessionCommon
,
495 IKEV2_PAYLOAD_TYPE_AUTH
497 if (IdPayload
== NULL
) {
502 // 3. Generate Auth Payload
503 // If it is tunnel mode, should create the configuration payload after the
506 if (IkeSaSession
->Spd
->Data
->ProcessingPolicy
->Mode
== EfiIPsecTransport
) {
508 AuthPayload
= Ikev2PskGenerateAuthPayload (
509 ChildSaSession
->IkeSaSession
,
511 IKEV2_PAYLOAD_TYPE_SA
,
515 AuthPayload
= Ikev2PskGenerateAuthPayload (
516 ChildSaSession
->IkeSaSession
,
518 IKEV2_PAYLOAD_TYPE_CP
,
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
528 CpPayload
= Ikev2GenerateCpPayload (
529 ChildSaSession
->IkeSaSession
,
530 IKEV2_PAYLOAD_TYPE_SA
,
531 IKEV2_CFG_ATTR_INTERNAL_IP6_ADDRESS
535 if (CpPayload
== NULL
) {
540 if (AuthPayload
== NULL
) {
545 // 4. Generate SA Payload according to the SA Data in ChildSaSession
547 SaPayload
= Ikev2GenerateSaPayload (
548 ChildSaSession
->SaData
,
549 IKEV2_PAYLOAD_TYPE_TS_INIT
,
550 IkeSessionTypeChildSa
552 if (SaPayload
== NULL
) {
556 if (IkeSaSession
->Spd
->Data
->ProcessingPolicy
->Mode
== EfiIPsecTransport
) {
558 // Generate Tsi and Tsr.
560 TsiPayload
= Ikev2GenerateTsPayload (
562 IKEV2_PAYLOAD_TYPE_TS_RSP
,
566 TsrPayload
= Ikev2GenerateTsPayload (
568 IKEV2_PAYLOAD_TYPE_NOTIFY
,
573 // Generate Notify Payload. If transport mode, there should have Notify
574 // payload with TRANSPORT_MODE notification.
576 NotifyPayload
= Ikev2GenerateNotifyPayload (
578 IKEV2_PAYLOAD_TYPE_NONE
,
580 IKEV2_NOTIFICATION_USE_TRANSPORT_MODE
,
585 if (NotifyPayload
== NULL
) {
590 // Generate Tsr for Tunnel mode.
592 TsiPayload
= Ikev2GenerateTsPayload (
594 IKEV2_PAYLOAD_TYPE_TS_RSP
,
597 TsrPayload
= Ikev2GenerateTsPayload (
599 IKEV2_PAYLOAD_TYPE_NONE
,
604 if (TsiPayload
== NULL
|| TsrPayload
== NULL
) {
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
);
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
);
623 if (IkePacket
!= NULL
) {
624 IkePacketFree (IkePacket
);
627 if (IdPayload
!= NULL
) {
628 IkePayloadFree (IdPayload
);
631 if (AuthPayload
!= NULL
) {
632 IkePayloadFree (AuthPayload
);
635 if (CpPayload
!= NULL
) {
636 IkePayloadFree (CpPayload
);
639 if (SaPayload
!= NULL
) {
640 IkePayloadFree (SaPayload
);
643 if (TsiPayload
!= NULL
) {
644 IkePayloadFree (TsiPayload
);
647 if (TsrPayload
!= NULL
) {
648 IkePayloadFree (TsrPayload
);
651 if (NotifyPayload
!= NULL
) {
652 IkePayloadFree (NotifyPayload
);
659 Parses IKE_AUTH packet.
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.
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.
673 IN IKE_PACKET
*IkePacket
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
;
689 IkeSaSession
= (IKEV2_SA_SESSION
*) SaSession
;
690 ChildSaSession
= IKEV2_CHILD_SA_SESSION_BY_IKE_SA (GetFirstNode (&IkeSaSession
->ChildSaSessionList
));
700 // Iterate payloads to find the SaPayload/ID/AUTH/TS Payload.
702 NET_LIST_FOR_EACH (Entry
, &(IkePacket
)->PayloadList
) {
703 IkePayload
= IKE_PAYLOAD_BY_PACKET (Entry
);
705 if (IkePayload
->PayloadType
== IKEV2_PAYLOAD_TYPE_ID_INIT
) {
706 IdiPayload
= IkePayload
;
708 if (IkePayload
->PayloadType
== IKEV2_PAYLOAD_TYPE_ID_RSP
) {
709 IdrPayload
= IkePayload
;
711 if (IkePayload
->PayloadType
== IKEV2_PAYLOAD_TYPE_SA
) {
712 SaPayload
= IkePayload
;
714 if (IkePayload
->PayloadType
== IKEV2_PAYLOAD_TYPE_AUTH
) {
715 AuthPayload
= IkePayload
;
717 if (IkePayload
->PayloadType
== IKEV2_PAYLOAD_TYPE_TS_INIT
) {
718 TsiPayload
= IkePayload
;
720 if (IkePayload
->PayloadType
== IKEV2_PAYLOAD_TYPE_TS_RSP
) {
721 TsrPayload
= IkePayload
;
725 if ((SaPayload
== NULL
) || (AuthPayload
== NULL
) || (TsiPayload
== NULL
) || (TsrPayload
== NULL
)) {
726 return EFI_INVALID_PARAMETER
;
728 if ((IdiPayload
== NULL
) && (IdrPayload
== NULL
)) {
729 return EFI_INVALID_PARAMETER
;
733 // Check IkePacket Header is match the state
735 if (IkeSaSession
->SessionCommon
.IsInitiator
) {
738 // 1. Check the IkePacket->Hdr == IKE_HEADER_FLAGS_RESPOND
740 if ((IkePacket
->Header
->Flags
!= IKE_HEADER_FLAGS_RESPOND
) ||
741 (IkePacket
->Header
->ExchangeType
!= IKEV2_EXCHANGE_TYPE_AUTH
)
743 return EFI_INVALID_PARAMETER
;
748 // 1. Check the IkePacket->Hdr == IKE_HEADER_FLAGS_INIT
750 if ((IkePacket
->Header
->Flags
!= IKE_HEADER_FLAGS_INIT
) ||
751 (IkePacket
->Header
->ExchangeType
!= IKEV2_EXCHANGE_TYPE_AUTH
)
753 return EFI_INVALID_PARAMETER
;
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.
764 // Verify the Auth Payload.
766 VerifiedAuthPayload
= Ikev2PskGenerateAuthPayload (
768 IkeSaSession
->SessionCommon
.IsInitiator
? IdrPayload
: IdiPayload
,
769 IKEV2_PAYLOAD_TYPE_SA
,
772 if ((VerifiedAuthPayload
!= NULL
) &&
774 VerifiedAuthPayload
->PayloadBuf
+ sizeof (IKEV2_COMMON_PAYLOAD_HEADER
),
775 AuthPayload
->PayloadBuf
+ sizeof (IKEV2_COMMON_PAYLOAD_HEADER
),
776 VerifiedAuthPayload
->PayloadSize
- sizeof (IKEV2_COMMON_PAYLOAD_HEADER
)
778 return EFI_INVALID_PARAMETER
;
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.
786 if (!Ikev2ChildSaParseSaPayload (ChildSaSession
, SaPayload
, IkePacket
->Header
->Flags
)) {
787 return EFI_INVALID_PARAMETER
;
791 // 4. Parse TSi, TSr payloads.
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)
798 return EFI_INVALID_PARAMETER
;
801 if (!IkeSaSession
->SessionCommon
.IsInitiator
) {
803 //TODO:check the Port range. Only support any port and one certain port here.
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
;
809 // Association a SPD with this SA.
811 Status
= Ikev2ChildSaAssociateSpdEntry (ChildSaSession
);
812 if (EFI_ERROR (Status
)) {
813 return EFI_INVALID_PARAMETER
;
816 // Associate the IkeSaSession's SPD to the first ChildSaSession's SPD.
818 if (ChildSaSession
->IkeSaSession
->Spd
== NULL
) {
819 ChildSaSession
->IkeSaSession
->Spd
= ChildSaSession
->Spd
;
820 Status
= Ikev2ChildSaSessionSpdSelectorCreate (ChildSaSession
);
821 if (EFI_ERROR (Status
)) {
827 //TODO:check the Port range.
829 if ((((TRAFFIC_SELECTOR
*)(TsrPayload
->PayloadBuf
+ sizeof (IKEV2_TS
)))->StartPort
!= 0) &&
830 (((TRAFFIC_SELECTOR
*)(TsrPayload
->PayloadBuf
+ sizeof (IKEV2_TS
)))->StartPort
!= ChildSaSession
->RemotePort
)
832 return EFI_INVALID_PARAMETER
;
834 if ((((TRAFFIC_SELECTOR
*)(TsiPayload
->PayloadBuf
+ sizeof (IKEV2_TS
)))->StartPort
!= 0) &&
835 (((TRAFFIC_SELECTOR
*)(TsiPayload
->PayloadBuf
+ sizeof (IKEV2_TS
)))->StartPort
!= ChildSaSession
->LocalPort
)
837 return EFI_INVALID_PARAMETER
;
840 // For the tunnel mode, it should add the vitual IP address into the SA's SPD Selector.
842 if (ChildSaSession
->Spd
->Data
->ProcessingPolicy
->Mode
== EfiIPsecTunnel
) {
843 if (!ChildSaSession
->IkeSaSession
->SessionCommon
.IsInitiator
) {
845 // If it is tunnel mode, the UEFI part must be the initiator.
847 return EFI_INVALID_PARAMETER
;
850 // Get the Virtual IP address from the Tsi traffic selector.
851 // TODO: check the CFG reply payload
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
)
863 // 5. Generate keymats for IPsec protocol.
865 Status
= Ikev2GenerateChildSaKeys (ChildSaSession
, NULL
);
866 if (EFI_ERROR (Status
)) {
870 if (IkeSaSession
->SessionCommon
.IsInitiator
) {
872 // 6. Change the state of IkeSaSession
874 IKEV2_DUMP_STATE (IkeSaSession
->SessionCommon
.State
, IkeStateIkeSaEstablished
);
875 IkeSaSession
->SessionCommon
.State
= IkeStateIkeSaEstablished
;
882 Gernerates IKEv2 packet for IKE_SA_INIT exchange.
884 @param[in] SaSession Pointer to IKEV2_SA_SESSION related to the exchange.
885 @param[in] Context Context Data passed by caller.
887 @retval EFI_SUCCESS The IKE packet generation succeeded.
888 @retval Others The IKE packet generation failed.
892 Ikev2InitCertGenerator (
897 IKE_PACKET
*IkePacket
;
898 IKE_PAYLOAD
*CertReqPayload
;
900 IKE_PAYLOAD
*NoncePayload
;
902 if (!FeaturePcdGet (PcdIpsecCertificateEnabled
)) {
907 // The first two messages exchange is same between PSK and Cert.
909 IkePacket
= Ikev2InitPskGenerator (SaSession
, Context
);
911 if ((IkePacket
!= NULL
) && (!((IKEV2_SA_SESSION
*)SaSession
)->SessionCommon
.IsInitiator
)) {
913 // Add the Certification Request Payload
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
,
924 // Change Nonce Payload Next payload type.
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
;
931 // Add Certification Request Payload
933 IKE_PACKET_APPEND_PAYLOAD (IkePacket
, CertReqPayload
);
940 Parses the IKEv2 packet for IKE_SA_INIT exchange.
942 @param[in] SaSession Pointer to IKEV2_SA_SESSION related to the exchange.
943 @param[in] IkePacket The received IKEv2 packet to be parsed.
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.
952 Ikev2InitCertParser (
954 IN IKE_PACKET
*IkePacket
957 if (!FeaturePcdGet (PcdIpsecCertificateEnabled
)) {
958 return EFI_UNSUPPORTED
;
962 // The first two messages exchange is same between PSK and Cert.
963 // Todo: Parse Certificate Request from responder Initial Exchange.
965 return Ikev2InitPskParser (SaSession
, IkePacket
);
969 Generates the IKEv2 packet for IKE_AUTH exchange.
971 @param[in] SaSession Pointer to IKEV2_SA_SESSION.
972 @param[in] Context Context data passed by caller.
974 @retval Pointer to IKEv2 Packet to be sent out.
978 Ikev2AuthCertGenerator (
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
;
996 if (!FeaturePcdGet (PcdIpsecCertificateEnabled
)) {
1000 IkeSaSession
= (IKEV2_SA_SESSION
*) SaSession
;
1001 ChildSaSession
= IKEV2_CHILD_SA_SESSION_BY_IKE_SA (GetFirstNode (&IkeSaSession
->ChildSaSessionList
));
1010 NotifyPayload
= NULL
;
1012 CertReqPayload
= NULL
;
1015 // 1. Allocate IKE Packet
1017 IkePacket
= IkePacketAlloc ();
1018 if (IkePacket
== NULL
) {
1023 // 1.a Fill the IkePacket Header.
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
;
1032 IkePacket
->Header
->NextPayload
= IKEV2_PAYLOAD_TYPE_ID_RSP
;
1036 // According to RFC4306_2.2, For the IKE_SA_INIT message the MessageID should
1037 // be always number 0 and 1;
1039 IkePacket
->Header
->MessageId
= 1;
1041 if (IkeSaSession
->SessionCommon
.IsInitiator
) {
1042 IkePacket
->Header
->Flags
= IKE_HEADER_FLAGS_INIT
;
1044 IkePacket
->Header
->Flags
= IKE_HEADER_FLAGS_RESPOND
;
1048 // 2. Generate ID Payload according to IP version and address.
1050 IdPayload
= Ikev2GenerateCertIdPayload (
1051 &IkeSaSession
->SessionCommon
,
1052 IKEV2_PAYLOAD_TYPE_CERT
,
1053 (UINT8
*)PcdGetPtr (PcdIpsecUefiCertificate
),
1054 PcdGet32 (PcdIpsecUefiCertificateSize
)
1056 if (IdPayload
== NULL
) {
1061 // 3. Generate Certificate Payload
1063 CertPayload
= Ikev2GenerateCertificatePayload (
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
,
1071 if (CertPayload
== NULL
) {
1075 if (IkeSaSession
->SessionCommon
.IsInitiator
) {
1076 CertReqPayload
= Ikev2GenerateCertificatePayload (
1078 IKEV2_PAYLOAD_TYPE_AUTH
,
1079 (UINT8
*)PcdGetPtr (PcdIpsecUefiCertificate
),
1080 PcdGet32 (PcdIpsecUefiCertificateSize
),
1081 IKEV2_CERT_ENCODEING_HASH_AND_URL_OF_X509_CERT
,
1084 if (CertReqPayload
== NULL
) {
1090 // 4. Generate Auth Payload
1091 // If it is tunnel mode, should create the configuration payload after the
1094 if (IkeSaSession
->Spd
->Data
->ProcessingPolicy
->Mode
== EfiIPsecTransport
) {
1095 AuthPayload
= Ikev2CertGenerateAuthPayload (
1096 ChildSaSession
->IkeSaSession
,
1098 IKEV2_PAYLOAD_TYPE_SA
,
1100 (UINT8
*)PcdGetPtr (PcdIpsecUefiCertificateKey
),
1101 PcdGet32 (PcdIpsecUefiCertificateKeySize
),
1102 ChildSaSession
->IkeSaSession
->Pad
->Data
->AuthData
,
1103 ChildSaSession
->IkeSaSession
->Pad
->Data
->AuthDataSize
1106 AuthPayload
= Ikev2CertGenerateAuthPayload (
1107 ChildSaSession
->IkeSaSession
,
1109 IKEV2_PAYLOAD_TYPE_CP
,
1111 (UINT8
*)PcdGetPtr (PcdIpsecUefiCertificateKey
),
1112 PcdGet32 (PcdIpsecUefiCertificateKeySize
),
1113 ChildSaSession
->IkeSaSession
->Pad
->Data
->AuthData
,
1114 ChildSaSession
->IkeSaSession
->Pad
->Data
->AuthDataSize
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
1123 CpPayload
= Ikev2GenerateCpPayload (
1124 ChildSaSession
->IkeSaSession
,
1125 IKEV2_PAYLOAD_TYPE_SA
,
1126 IKEV2_CFG_ATTR_INTERNAL_IP6_ADDRESS
1130 if (CpPayload
== NULL
) {
1135 if (AuthPayload
== NULL
) {
1140 // 5. Generate SA Payload according to the Sa Data in ChildSaSession
1142 SaPayload
= Ikev2GenerateSaPayload (
1143 ChildSaSession
->SaData
,
1144 IKEV2_PAYLOAD_TYPE_TS_INIT
,
1145 IkeSessionTypeChildSa
1147 if (SaPayload
== NULL
) {
1151 if (IkeSaSession
->Spd
->Data
->ProcessingPolicy
->Mode
== EfiIPsecTransport
) {
1153 // Generate Tsi and Tsr.
1155 TsiPayload
= Ikev2GenerateTsPayload (
1157 IKEV2_PAYLOAD_TYPE_TS_RSP
,
1161 TsrPayload
= Ikev2GenerateTsPayload (
1163 IKEV2_PAYLOAD_TYPE_NOTIFY
,
1168 // Generate Notify Payload. If transport mode, there should have Notify
1169 // payload with TRANSPORT_MODE notification.
1171 NotifyPayload
= Ikev2GenerateNotifyPayload (
1173 IKEV2_PAYLOAD_TYPE_NONE
,
1175 IKEV2_NOTIFICATION_USE_TRANSPORT_MODE
,
1180 if (NotifyPayload
== NULL
) {
1185 // Generate Tsr for Tunnel mode.
1187 TsiPayload
= Ikev2GenerateTsPayload (
1189 IKEV2_PAYLOAD_TYPE_TS_RSP
,
1192 TsrPayload
= Ikev2GenerateTsPayload (
1194 IKEV2_PAYLOAD_TYPE_NONE
,
1199 if (TsiPayload
== NULL
|| TsrPayload
== NULL
) {
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
);
1208 IKE_PACKET_APPEND_PAYLOAD (IkePacket
, AuthPayload
);
1209 if (IkeSaSession
->Spd
->Data
->ProcessingPolicy
->Mode
== EfiIPsecTunnel
) {
1210 IKE_PACKET_APPEND_PAYLOAD (IkePacket
, CpPayload
);
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
);
1222 if (IkePacket
!= NULL
) {
1223 IkePacketFree (IkePacket
);
1226 if (IdPayload
!= NULL
) {
1227 IkePayloadFree (IdPayload
);
1230 if (CertPayload
!= NULL
) {
1231 IkePayloadFree (CertPayload
);
1234 if (CertReqPayload
!= NULL
) {
1235 IkePayloadFree (CertReqPayload
);
1238 if (AuthPayload
!= NULL
) {
1239 IkePayloadFree (AuthPayload
);
1242 if (CpPayload
!= NULL
) {
1243 IkePayloadFree (CpPayload
);
1246 if (SaPayload
!= NULL
) {
1247 IkePayloadFree (SaPayload
);
1250 if (TsiPayload
!= NULL
) {
1251 IkePayloadFree (TsiPayload
);
1254 if (TsrPayload
!= NULL
) {
1255 IkePayloadFree (TsrPayload
);
1258 if (NotifyPayload
!= NULL
) {
1259 IkePayloadFree (NotifyPayload
);
1266 Parses IKE_AUTH packet.
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.
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.
1279 Ikev2AuthCertParser (
1280 IN UINT8
*SaSession
,
1281 IN IKE_PACKET
*IkePacket
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
;
1298 if (!FeaturePcdGet (PcdIpsecCertificateEnabled
)) {
1299 return EFI_UNSUPPORTED
;
1302 IkeSaSession
= (IKEV2_SA_SESSION
*) SaSession
;
1303 ChildSaSession
= IKEV2_CHILD_SA_SESSION_BY_IKE_SA (GetFirstNode (&IkeSaSession
->ChildSaSessionList
));
1312 VerifiedAuthPayload
= NULL
;
1313 Status
= EFI_INVALID_PARAMETER
;
1316 // Iterate payloads to find the SaPayload/ID/AUTH/TS Payload.
1318 NET_LIST_FOR_EACH (Entry
, &(IkePacket
)->PayloadList
) {
1319 IkePayload
= IKE_PAYLOAD_BY_PACKET (Entry
);
1321 if (IkePayload
->PayloadType
== IKEV2_PAYLOAD_TYPE_ID_INIT
) {
1322 IdiPayload
= IkePayload
;
1324 if (IkePayload
->PayloadType
== IKEV2_PAYLOAD_TYPE_ID_RSP
) {
1325 IdrPayload
= IkePayload
;
1328 if (IkePayload
->PayloadType
== IKEV2_PAYLOAD_TYPE_SA
) {
1329 SaPayload
= IkePayload
;
1331 if (IkePayload
->PayloadType
== IKEV2_PAYLOAD_TYPE_AUTH
) {
1332 AuthPayload
= IkePayload
;
1334 if (IkePayload
->PayloadType
== IKEV2_PAYLOAD_TYPE_TS_INIT
) {
1335 TsiPayload
= IkePayload
;
1337 if (IkePayload
->PayloadType
== IKEV2_PAYLOAD_TYPE_TS_RSP
) {
1338 TsrPayload
= IkePayload
;
1340 if (IkePayload
->PayloadType
== IKEV2_PAYLOAD_TYPE_CERT
) {
1341 CertPayload
= IkePayload
;
1345 if ((SaPayload
== NULL
) || (AuthPayload
== NULL
) || (TsiPayload
== NULL
) ||
1346 (TsrPayload
== NULL
) || (CertPayload
== NULL
)) {
1349 if ((IdiPayload
== NULL
) && (IdrPayload
== NULL
)) {
1354 // Check IkePacket Header is match the state
1356 if (IkeSaSession
->SessionCommon
.IsInitiator
) {
1359 // 1. Check the IkePacket->Hdr == IKE_HEADER_FLAGS_RESPOND
1361 if ((IkePacket
->Header
->Flags
!= IKE_HEADER_FLAGS_RESPOND
) ||
1362 (IkePacket
->Header
->ExchangeType
!= IKEV2_EXCHANGE_TYPE_AUTH
)) {
1367 // 1. Check the IkePacket->Hdr == IKE_HEADER_FLAGS_INIT
1369 if ((IkePacket
->Header
->Flags
!= IKE_HEADER_FLAGS_INIT
) ||
1370 (IkePacket
->Header
->ExchangeType
!= IKEV2_EXCHANGE_TYPE_AUTH
)) {
1376 // Verify the Auth Payload.
1378 VerifiedAuthPayload
= Ikev2CertGenerateAuthPayload (
1380 IkeSaSession
->SessionCommon
.IsInitiator
? IdrPayload
:IdiPayload
,
1381 IKEV2_PAYLOAD_TYPE_SA
,
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
)
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.
1408 if (!Ikev2ChildSaParseSaPayload (ChildSaSession
, SaPayload
, IkePacket
->Header
->Flags
)) {
1413 // 4. Parse TSi, TSr payloads.
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)
1423 if (!IkeSaSession
->SessionCommon
.IsInitiator
) {
1425 //Todo:check the Port range. Only support any port and one certain port here.
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
;
1431 // Association a SPD with this SA.
1433 if (EFI_ERROR (Ikev2ChildSaAssociateSpdEntry (ChildSaSession
))) {
1437 // Associate the IkeSaSession's SPD to the first ChildSaSession's SPD.
1439 if (ChildSaSession
->IkeSaSession
->Spd
== NULL
) {
1440 ChildSaSession
->IkeSaSession
->Spd
= ChildSaSession
->Spd
;
1441 Status
= Ikev2ChildSaSessionSpdSelectorCreate (ChildSaSession
);
1442 if (EFI_ERROR (Status
)) {
1448 // Todo:check the Port range.
1450 if ((((TRAFFIC_SELECTOR
*)(TsrPayload
->PayloadBuf
+ sizeof (IKEV2_TS
)))->StartPort
!= 0) &&
1451 (((TRAFFIC_SELECTOR
*)(TsrPayload
->PayloadBuf
+ sizeof (IKEV2_TS
)))->StartPort
!= ChildSaSession
->RemotePort
)
1455 if ((((TRAFFIC_SELECTOR
*)(TsiPayload
->PayloadBuf
+ sizeof (IKEV2_TS
)))->StartPort
!= 0) &&
1456 (((TRAFFIC_SELECTOR
*)(TsiPayload
->PayloadBuf
+ sizeof (IKEV2_TS
)))->StartPort
!= ChildSaSession
->LocalPort
)
1461 // For the tunnel mode, it should add the vitual IP address into the SA's SPD Selector.
1463 if (ChildSaSession
->Spd
->Data
->ProcessingPolicy
->Mode
== EfiIPsecTunnel
) {
1464 if (!ChildSaSession
->IkeSaSession
->SessionCommon
.IsInitiator
) {
1466 // If it is tunnel mode, the UEFI part must be the initiator.
1471 // Get the Virtual IP address from the Tsi traffic selector.
1472 // TODO: check the CFG reply payload
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
)
1484 // 5. Generat keymats for IPsec protocol.
1486 Status
= Ikev2GenerateChildSaKeys (ChildSaSession
, NULL
);
1487 if (EFI_ERROR (Status
)) {
1491 if (IkeSaSession
->SessionCommon
.IsInitiator
) {
1493 // 6. Change the state of IkeSaSession
1495 IKEV2_DUMP_STATE (IkeSaSession
->SessionCommon
.State
, IkeStateIkeSaEstablished
);
1496 IkeSaSession
->SessionCommon
.State
= IkeStateIkeSaEstablished
;
1499 Status
= EFI_SUCCESS
;
1502 if (VerifiedAuthPayload
!= NULL
) {
1503 IkePayloadFree (VerifiedAuthPayload
);
1509 Generates the DH Public Key.
1511 This generates the DH local public key and store it in the IKE SA Session's GxBuffer.
1513 @param[in] IkeSaSession Pointer to related IKE SA Session.
1515 @retval EFI_SUCCESS The operation succeeded.
1516 @retval Others The operation failed.
1520 Ikev2GenerateSaDhPublicKey (
1521 IN IKEV2_SA_SESSION
*IkeSaSession
1525 IKEV2_SESSION_KEYS
*IkeKeys
;
1527 IkeSaSession
->IkeKeys
= AllocateZeroPool (sizeof (IKEV2_SESSION_KEYS
));
1528 if (IkeSaSession
->IkeKeys
== NULL
) {
1529 return EFI_OUT_OF_RESOURCES
;
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
;
1540 // Init DH with the certain DH Group Description.
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
;
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
1561 if (EFI_ERROR (Status
)) {
1562 DEBUG ((DEBUG_ERROR
, "Error CPLKeyManGetKeyParam X public key error Status = %r\n", Status
));
1564 FreePool (IkeKeys
->DhBuffer
->GxBuffer
);
1566 FreePool (IkeKeys
->DhBuffer
);
1568 FreePool (IkeSaSession
->IkeKeys
);
1573 IPSEC_DUMP_BUF ("DH Public Key (g^x) Dump", IkeKeys
->DhBuffer
->GxBuffer
, IkeKeys
->DhBuffer
->GxSize
);
1579 Computes the DH Shared/Exchange Key.
1581 Given peer's public key, this function computes the exchanged common key and
1582 stores it in the IKEv2 SA Session's GxyBuffer.
1584 @param[in] DhBuffer Pointer to buffer of peer's puliic key.
1585 @param[in] KePayload Pointer to received key payload.
1587 @retval EFI_SUCCESS The operation succeeded.
1588 @retval Otherwise The operation failed.
1592 Ikev2GenerateSaDhComputeKey (
1593 IN IKEV2_DH_BUFFER
*DhBuffer
,
1594 IN IKE_PAYLOAD
*KePayload
1598 IKEV2_KEY_EXCHANGE
*Ke
;
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
;
1614 Status
= IpSecCryptoIoDhComputeKey (
1615 DhBuffer
->DhContext
,
1618 DhBuffer
->GxyBuffer
,
1621 if (EFI_ERROR (Status
)) {
1622 DEBUG ((DEBUG_ERROR
, "Error CPLKeyManGetKeyParam Y session key error Status = %r\n", Status
));
1624 FreePool (DhBuffer
->GxyBuffer
);
1632 DhBuffer
->GySize
= PubKeySize
;
1633 DhBuffer
->GyBuffer
= AllocateZeroPool (DhBuffer
->GySize
);
1634 if (DhBuffer
->GyBuffer
== NULL
) {
1635 FreePool (DhBuffer
->GxyBuffer
);
1640 CopyMem (DhBuffer
->GyBuffer
, PubKey
, DhBuffer
->GySize
);
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
);
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.
1652 @param[in] IkeSaSession Pointer to IKE SA Session.
1653 @param[in] KePayload Pointer to Key payload used to generate the Key.
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.
1662 Ikev2GenerateSaKeys (
1663 IN IKEV2_SA_SESSION
*IkeSaSession
,
1664 IN IKE_PAYLOAD
*KePayload
1668 IKEV2_SA_PARAMS
*SaParams
;
1669 PRF_DATA_FRAGMENT Fragments
[4];
1670 UINT64 InitiatorCookieNet
;
1671 UINT64 ResponderCookieNet
;
1673 UINTN KeyBufferSize
;
1674 UINTN AuthAlgKeyLen
;
1675 UINTN EncryptAlgKeyLen
;
1676 UINTN IntegrityAlgKeyLen
;
1679 UINTN OutputKeyLength
;
1686 Status
= EFI_SUCCESS
;
1691 Status
= Ikev2GenerateSaDhComputeKey (IkeSaSession
->IkeKeys
->DhBuffer
, KePayload
);
1692 if (EFI_ERROR (Status
)) {
1697 // Get the key length of Authenticaion, Encryption, PRF, and Integrity.
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
);
1706 // If one or more algorithm is not support, return EFI_UNSUPPORTED.
1708 if (AuthAlgKeyLen
== 0 ||
1709 EncryptAlgKeyLen
== 0 ||
1710 IntegrityAlgKeyLen
== 0 ||
1713 Status
= EFI_UNSUPPORTED
;
1718 // Compute SKEYSEED = prf(Ni | Nr, g^ir)
1720 KeyBufferSize
= IkeSaSession
->NiBlkSize
+ IkeSaSession
->NrBlkSize
;
1721 KeyBuffer
= AllocateZeroPool (KeyBufferSize
);
1722 if (KeyBuffer
== NULL
) {
1723 Status
= EFI_OUT_OF_RESOURCES
;
1727 CopyMem (KeyBuffer
, IkeSaSession
->NiBlock
, IkeSaSession
->NiBlkSize
);
1728 CopyMem (KeyBuffer
+ IkeSaSession
->NiBlkSize
, IkeSaSession
->NrBlock
, IkeSaSession
->NrBlkSize
);
1730 Fragments
[0].Data
= IkeSaSession
->IkeKeys
->DhBuffer
->GxyBuffer
;
1731 Fragments
[0].DataSize
= IkeSaSession
->IkeKeys
->DhBuffer
->GxySize
;
1733 DigestSize
= IpSecGetHmacDigestLength ((UINT8
)SaParams
->Prf
);
1734 Digest
= AllocateZeroPool (DigestSize
);
1736 if (Digest
== NULL
) {
1737 Status
= EFI_OUT_OF_RESOURCES
;
1742 (UINT8
)SaParams
->Prf
,
1745 (HASH_DATA_FRAGMENT
*) Fragments
,
1752 // {SK_d | SK_ai | SK_ar | SK_ei | SK_er | SK_pi | SK_pr } = prf+
1753 // (SKEYSEED, Ni | Nr | SPIi | SPIr )
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
);
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
));
1771 OutputKeyLength
= PrfAlgKeyLen
+
1772 2 * EncryptAlgKeyLen
+
1774 2 * IntegrityAlgKeyLen
;
1775 OutputKey
= AllocateZeroPool (OutputKeyLength
);
1776 if (OutputKey
== NULL
) {
1777 Status
= EFI_OUT_OF_RESOURCES
;
1782 // Generate Seven Keymates.
1784 Status
= Ikev2SaGenerateKey (
1785 (UINT8
)SaParams
->Prf
,
1793 if (EFI_ERROR(Status
)) {
1798 // Save the seven keys into KeySession.
1801 IkeSaSession
->IkeKeys
->SkdKey
= AllocateZeroPool (PrfAlgKeyLen
);
1802 if (IkeSaSession
->IkeKeys
->SkdKey
== NULL
) {
1803 Status
= EFI_OUT_OF_RESOURCES
;
1806 IkeSaSession
->IkeKeys
->SkdKeySize
= PrfAlgKeyLen
;
1807 CopyMem (IkeSaSession
->IkeKeys
->SkdKey
, OutputKey
, PrfAlgKeyLen
);
1809 IPSEC_DUMP_BUF (">>> SK_D Key", IkeSaSession
->IkeKeys
->SkdKey
, PrfAlgKeyLen
);
1814 IkeSaSession
->IkeKeys
->SkAiKey
= AllocateZeroPool (IntegrityAlgKeyLen
);
1815 if (IkeSaSession
->IkeKeys
->SkAiKey
== NULL
) {
1816 Status
= EFI_OUT_OF_RESOURCES
;
1819 IkeSaSession
->IkeKeys
->SkAiKeySize
= IntegrityAlgKeyLen
;
1820 CopyMem (IkeSaSession
->IkeKeys
->SkAiKey
, OutputKey
+ PrfAlgKeyLen
, IntegrityAlgKeyLen
);
1822 IPSEC_DUMP_BUF (">>> SK_Ai Key", IkeSaSession
->IkeKeys
->SkAiKey
, IkeSaSession
->IkeKeys
->SkAiKeySize
);
1827 IkeSaSession
->IkeKeys
->SkArKey
= AllocateZeroPool (IntegrityAlgKeyLen
);
1828 if (IkeSaSession
->IkeKeys
->SkArKey
== NULL
) {
1829 Status
= EFI_OUT_OF_RESOURCES
;
1832 IkeSaSession
->IkeKeys
->SkArKeySize
= IntegrityAlgKeyLen
;
1834 IkeSaSession
->IkeKeys
->SkArKey
,
1835 OutputKey
+ PrfAlgKeyLen
+ IntegrityAlgKeyLen
,
1839 IPSEC_DUMP_BUF (">>> SK_Ar Key", IkeSaSession
->IkeKeys
->SkArKey
, IkeSaSession
->IkeKeys
->SkArKeySize
);
1844 IkeSaSession
->IkeKeys
->SkEiKey
= AllocateZeroPool (EncryptAlgKeyLen
);
1845 if (IkeSaSession
->IkeKeys
->SkEiKey
== NULL
) {
1846 Status
= EFI_OUT_OF_RESOURCES
;
1849 IkeSaSession
->IkeKeys
->SkEiKeySize
= EncryptAlgKeyLen
;
1852 IkeSaSession
->IkeKeys
->SkEiKey
,
1853 OutputKey
+ AuthAlgKeyLen
+ 2 * IntegrityAlgKeyLen
,
1858 OutputKey
+ AuthAlgKeyLen
+ 2 * IntegrityAlgKeyLen
,
1865 IkeSaSession
->IkeKeys
->SkErKey
= AllocateZeroPool (EncryptAlgKeyLen
);
1866 if (IkeSaSession
->IkeKeys
->SkErKey
== NULL
) {
1867 Status
= EFI_OUT_OF_RESOURCES
;
1870 IkeSaSession
->IkeKeys
->SkErKeySize
= EncryptAlgKeyLen
;
1873 IkeSaSession
->IkeKeys
->SkErKey
,
1874 OutputKey
+ AuthAlgKeyLen
+ 2 * IntegrityAlgKeyLen
+ EncryptAlgKeyLen
,
1879 OutputKey
+ AuthAlgKeyLen
+ 2 * IntegrityAlgKeyLen
+ EncryptAlgKeyLen
,
1886 IkeSaSession
->IkeKeys
->SkPiKey
= AllocateZeroPool (AuthAlgKeyLen
);
1887 if (IkeSaSession
->IkeKeys
->SkPiKey
== NULL
) {
1888 Status
= EFI_OUT_OF_RESOURCES
;
1891 IkeSaSession
->IkeKeys
->SkPiKeySize
= AuthAlgKeyLen
;
1894 IkeSaSession
->IkeKeys
->SkPiKey
,
1895 OutputKey
+ AuthAlgKeyLen
+ 2 * IntegrityAlgKeyLen
+ 2 * EncryptAlgKeyLen
,
1900 OutputKey
+ AuthAlgKeyLen
+ 2 * IntegrityAlgKeyLen
+ 2 * EncryptAlgKeyLen
,
1907 IkeSaSession
->IkeKeys
->SkPrKey
= AllocateZeroPool (AuthAlgKeyLen
);
1908 if (IkeSaSession
->IkeKeys
->SkPrKey
== NULL
) {
1909 Status
= EFI_OUT_OF_RESOURCES
;
1912 IkeSaSession
->IkeKeys
->SkPrKeySize
= AuthAlgKeyLen
;
1915 IkeSaSession
->IkeKeys
->SkPrKey
,
1916 OutputKey
+ AuthAlgKeyLen
+ 2 * IntegrityAlgKeyLen
+ 2 * EncryptAlgKeyLen
+ AuthAlgKeyLen
,
1921 OutputKey
+ AuthAlgKeyLen
+ 2 * IntegrityAlgKeyLen
+ 2 * EncryptAlgKeyLen
+ AuthAlgKeyLen
,
1927 if (Digest
!= NULL
) {
1930 if (KeyBuffer
!= NULL
) {
1931 FreePool (KeyBuffer
);
1933 if (OutputKey
!= NULL
) {
1934 FreePool (OutputKey
);
1937 if (EFI_ERROR(Status
)) {
1938 if (IkeSaSession
->IkeKeys
->SkdKey
!= NULL
) {
1939 FreePool (IkeSaSession
->IkeKeys
->SkdKey
);
1941 if (IkeSaSession
->IkeKeys
->SkAiKey
!= NULL
) {
1942 FreePool (IkeSaSession
->IkeKeys
->SkAiKey
);
1944 if (IkeSaSession
->IkeKeys
->SkArKey
!= NULL
) {
1945 FreePool (IkeSaSession
->IkeKeys
->SkArKey
);
1947 if (IkeSaSession
->IkeKeys
->SkEiKey
!= NULL
) {
1948 FreePool (IkeSaSession
->IkeKeys
->SkEiKey
);
1950 if (IkeSaSession
->IkeKeys
->SkErKey
!= NULL
) {
1951 FreePool (IkeSaSession
->IkeKeys
->SkErKey
);
1953 if (IkeSaSession
->IkeKeys
->SkPiKey
!= NULL
) {
1954 FreePool (IkeSaSession
->IkeKeys
->SkPiKey
);
1956 if (IkeSaSession
->IkeKeys
->SkPrKey
!= NULL
) {
1957 FreePool (IkeSaSession
->IkeKeys
->SkPrKey
);
1966 Generates the Keys for the furthure IPsec Protocol.
1968 @param[in] ChildSaSession Pointer to IKE Child SA Session.
1969 @param[in] KePayload Pointer to Key payload used to generate the Key.
1971 @retval EFI_UNSUPPORTED If one or more Algorithm Id is not supported.
1972 @retval EFI_SUCCESS The operation succeeded.
1976 Ikev2GenerateChildSaKeys (
1977 IN IKEV2_CHILD_SA_SESSION
*ChildSaSession
,
1978 IN IKE_PAYLOAD
*KePayload
1982 IKEV2_SA_PARAMS
*SaParams
;
1983 PRF_DATA_FRAGMENT Fragments
[3];
1984 UINTN EncryptAlgKeyLen
;
1985 UINTN IntegrityAlgKeyLen
;
1987 UINTN OutputKeyLength
;
1989 Status
= EFI_SUCCESS
;
1992 if (KePayload
!= NULL
) {
1996 Status
= Ikev2GenerateSaDhComputeKey (ChildSaSession
->DhBuffer
, KePayload
);
1997 if (EFI_ERROR (Status
)) {
2001 Fragments
[0].Data
= ChildSaSession
->DhBuffer
->GxyBuffer
;
2002 Fragments
[0].DataSize
= ChildSaSession
->DhBuffer
->GxySize
;
2005 Fragments
[1].Data
= ChildSaSession
->NiBlock
;
2006 Fragments
[1].DataSize
= ChildSaSession
->NiBlkSize
;
2007 Fragments
[2].Data
= ChildSaSession
->NrBlock
;
2008 Fragments
[2].DataSize
= ChildSaSession
->NrBlkSize
;
2011 // Get the key length of Authenticaion, Encryption, PRF, and Integrity.
2013 SaParams
= ChildSaSession
->SessionCommon
.SaParams
;
2014 EncryptAlgKeyLen
= IpSecGetEncryptKeyLength ((UINT8
)SaParams
->EncAlgId
);
2015 IntegrityAlgKeyLen
= IpSecGetHmacDigestLength ((UINT8
)SaParams
->IntegAlgId
);
2016 OutputKeyLength
= 2 * EncryptAlgKeyLen
+ 2 * IntegrityAlgKeyLen
;
2018 if ((EncryptAlgKeyLen
== 0) || (IntegrityAlgKeyLen
== 0)) {
2019 Status
= EFI_UNSUPPORTED
;
2025 // If KePayload is not NULL, calculate KEYMAT = prf+(SK_d, g^ir (new) | Ni | Nr ),
2026 // otherwise, KEYMAT = prf+(SK_d, Ni | Nr )
2028 OutputKey
= AllocateZeroPool (OutputKeyLength
);
2029 if (OutputKey
== NULL
) {
2030 Status
= EFI_OUT_OF_RESOURCES
;
2035 // Derive Key from the SkdKey Buffer.
2037 Status
= Ikev2SaGenerateKey (
2038 (UINT8
)ChildSaSession
->IkeSaSession
->SessionCommon
.SaParams
->Prf
,
2039 ChildSaSession
->IkeSaSession
->IkeKeys
->SkdKey
,
2040 ChildSaSession
->IkeSaSession
->IkeKeys
->SkdKeySize
,
2043 KePayload
== NULL
? &Fragments
[1] : Fragments
,
2044 KePayload
== NULL
? 2 : 3
2047 if (EFI_ERROR (Status
)) {
2052 // Copy KEYMATE (SK_ENCRYPT_i | SK_ENCRYPT_r | SK_INTEG_i | SK_INTEG_r) to
2055 if (!ChildSaSession
->SessionCommon
.IsInitiator
) {
2058 // Initiator Encryption Key
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
;
2069 ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.EncKey
,
2075 // Initiator Authentication Key
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
;
2086 ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.AuthKey
,
2087 OutputKey
+ EncryptAlgKeyLen
,
2092 // Responder Encrypt Key
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
;
2103 ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.EncKey
,
2104 OutputKey
+ EncryptAlgKeyLen
+ IntegrityAlgKeyLen
,
2109 // Responder Authentication Key
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
;
2120 ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.AuthKey
,
2121 OutputKey
+ 2 * EncryptAlgKeyLen
+ IntegrityAlgKeyLen
,
2126 // Initiator Encryption Key
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
;
2137 ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.EncKey
,
2143 // Initiator Authentication Key
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
;
2154 ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.AuthKey
,
2155 OutputKey
+ EncryptAlgKeyLen
,
2160 // Responder Encryption Key
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
;
2171 ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.EncKey
,
2172 OutputKey
+ EncryptAlgKeyLen
+ IntegrityAlgKeyLen
,
2177 // Responder Authentication Key
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
;
2188 ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.AuthKey
,
2189 OutputKey
+ 2 * EncryptAlgKeyLen
+ IntegrityAlgKeyLen
,
2195 " >>> Local Encryption Key",
2196 ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.EncKey
,
2200 " >>> Remote Encryption Key",
2201 ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.EncKey
,
2205 " >>> Local Authentication Key",
2206 ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.AuthKey
,
2210 " >>> Remote Authentication Key",
2211 ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.AuthKey
,
2218 if (EFI_ERROR (Status
)) {
2219 if (ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.EncKey
!= NULL
) {
2220 FreePool (ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.EncKey
);
2222 if (ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.AuthKey
!= NULL
) {
2223 FreePool (ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.AuthKey
);
2225 if (ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.EncKey
!= NULL
) {
2226 FreePool (ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.EncKey
);
2228 if (ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.AuthKey
!= NULL
) {
2229 FreePool (ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.AuthKey
);
2233 if (OutputKey
!= NULL
) {
2234 FreePool (OutputKey
);
2240 GLOBAL_REMOVE_IF_UNREFERENCED IKEV2_PACKET_HANDLER mIkev2Initial
[][2] = {
2244 Ikev2InitPskGenerator
2248 Ikev2AuthPskGenerator
2253 Ikev2InitCertParser
,
2254 Ikev2InitCertGenerator
2257 Ikev2AuthCertParser
,
2258 Ikev2AuthCertGenerator