2 The operations for IKEv2 SA.
4 (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
5 Copyright (c) 2010 - 2016, 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
) {
291 Status
= Ikev2ParserNotifyCookiePayload (NotifyPayload
, IkeSaSession
);
296 if ((KeyPayload
== NULL
) || (SaPayload
== NULL
) || (NoncePayload
== NULL
)) {
297 return EFI_INVALID_PARAMETER
;
301 // Store NoncePayload for SKEYID computing.
303 NonceSize
= NoncePayload
->PayloadSize
- sizeof (IKEV2_COMMON_PAYLOAD_HEADER
);
304 NonceBuffer
= (UINT8
*) AllocatePool (NonceSize
);
305 if (NonceBuffer
== NULL
) {
306 Status
= EFI_OUT_OF_RESOURCES
;
312 NoncePayload
->PayloadBuf
+ sizeof (IKEV2_COMMON_PAYLOAD_HEADER
),
317 // Check if IkePacket Header matches the state
319 if (IkeSaSession
->SessionCommon
.IsInitiator
) {
321 // 1. Check the IkePacket->Hdr == IKE_HEADER_FLAGS_RESPOND
323 if (IkePacket
->Header
->Flags
!= IKE_HEADER_FLAGS_RESPOND
) {
324 Status
= EFI_INVALID_PARAMETER
;
329 // 2. Parse the SA Payload and Key Payload to find out the cryptographic
330 // suite and fill in the Sa paramse into CommonSession->SaParams
332 if (!Ikev2SaParseSaPayload (IkeSaSession
, SaPayload
, IkePacket
->Header
->Flags
)) {
333 Status
= EFI_INVALID_PARAMETER
;
338 // 3. If Initiator, the NoncePayload is Nr_b.
340 IKEV2_DUMP_STATE (IkeSaSession
->SessionCommon
.State
, IkeStateAuth
);
341 IkeSaSession
->NrBlock
= NonceBuffer
;
342 IkeSaSession
->NrBlkSize
= NonceSize
;
343 IkeSaSession
->SessionCommon
.State
= IkeStateAuth
;
344 IkeSaSession
->ResponderCookie
= IkePacket
->Header
->ResponderCookie
;
347 // 4. Change the state of IkeSaSession
349 IkeSaSession
->SessionCommon
.State
= IkeStateAuth
;
352 // 1. Check the IkePacket->Hdr == IKE_HEADER_FLAGS_INIT
354 if (IkePacket
->Header
->Flags
!= IKE_HEADER_FLAGS_INIT
) {
355 Status
= EFI_INVALID_PARAMETER
;
360 // 2. Parse the SA payload and find out the perfered one
361 // and fill in the SA parameters into CommonSession->SaParams and SaData into
362 // IkeSaSession for the responder SA payload generation.
364 if (!Ikev2SaParseSaPayload (IkeSaSession
, SaPayload
, IkePacket
->Header
->Flags
)) {
365 Status
= EFI_INVALID_PARAMETER
;
370 // 3. Generat Dh Y parivate Key
372 Status
= Ikev2GenerateSaDhPublicKey (IkeSaSession
);
373 if (EFI_ERROR (Status
)) {
378 // 4. If Responder, the NoncePayload is Ni_b and go to generate Nr_b.
380 IkeSaSession
->NiBlock
= NonceBuffer
;
381 IkeSaSession
->NiBlkSize
= NonceSize
;
386 IkeSaSession
->NrBlock
= IkeGenerateNonce (IKE_NONCE_SIZE
);
387 ASSERT (IkeSaSession
->NrBlock
!= NULL
);
388 IkeSaSession
->NrBlkSize
= IKE_NONCE_SIZE
;
391 // 6. Save the Cookies
393 IkeSaSession
->InitiatorCookie
= IkePacket
->Header
->InitiatorCookie
;
394 IkeSaSession
->ResponderCookie
= IkeGenerateCookie ();
397 if (IkeSaSession
->SessionCommon
.PreferDhGroup
!= ((IKEV2_KEY_EXCHANGE
*)KeyPayload
->PayloadBuf
)->DhGroup
) {
398 Status
= EFI_INVALID_PARAMETER
;
402 // Call Ikev2GenerateSaKeys to create SKEYID, SKEYID_d, SKEYID_a, SKEYID_e.
404 Status
= Ikev2GenerateSaKeys (IkeSaSession
, KeyPayload
);
405 if (EFI_ERROR(Status
)) {
411 if (NonceBuffer
!= NULL
) {
412 FreePool (NonceBuffer
);
419 Generates the IKEv2 packet for IKE_AUTH exchange.
421 @param[in] SaSession Pointer to IKEV2_SA_SESSION.
422 @param[in] Context Context data passed by caller.
424 @retval Pointer to IKE Packet to be sent out.
428 Ikev2AuthPskGenerator (
433 IKE_PACKET
*IkePacket
;
434 IKEV2_SA_SESSION
*IkeSaSession
;
435 IKE_PAYLOAD
*IdPayload
;
436 IKE_PAYLOAD
*AuthPayload
;
437 IKE_PAYLOAD
*SaPayload
;
438 IKE_PAYLOAD
*TsiPayload
;
439 IKE_PAYLOAD
*TsrPayload
;
440 IKE_PAYLOAD
*NotifyPayload
;
441 IKE_PAYLOAD
*CpPayload
;
442 IKEV2_CHILD_SA_SESSION
*ChildSaSession
;
445 IkeSaSession
= (IKEV2_SA_SESSION
*) SaSession
;
446 ChildSaSession
= IKEV2_CHILD_SA_SESSION_BY_IKE_SA (GetFirstNode (&IkeSaSession
->ChildSaSessionList
));
454 NotifyPayload
= NULL
;
456 NotifyPayload
= NULL
;
459 // 1. Allocate IKE Packet
461 IkePacket
= IkePacketAlloc ();
462 if (IkePacket
== NULL
) {
467 // 1.a Fill the IkePacket Header.
469 IkePacket
->Header
->ExchangeType
= IKEV2_EXCHANGE_TYPE_AUTH
;
470 IkePacket
->Header
->InitiatorCookie
= IkeSaSession
->InitiatorCookie
;
471 IkePacket
->Header
->ResponderCookie
= IkeSaSession
->ResponderCookie
;
472 IkePacket
->Header
->Version
= (UINT8
)(2 << 4);
473 if (ChildSaSession
->SessionCommon
.IsInitiator
) {
474 IkePacket
->Header
->NextPayload
= IKEV2_PAYLOAD_TYPE_ID_INIT
;
476 IkePacket
->Header
->NextPayload
= IKEV2_PAYLOAD_TYPE_ID_RSP
;
480 // According to RFC4306_2.2, For the IKE_SA_INIT message the MessageID should
481 // be always number 0 and 1;
483 IkePacket
->Header
->MessageId
= 1;
485 if (IkeSaSession
->SessionCommon
.IsInitiator
) {
486 IkePacket
->Header
->Flags
= IKE_HEADER_FLAGS_INIT
;
488 IkePacket
->Header
->Flags
= IKE_HEADER_FLAGS_RESPOND
;
492 // 2. Generate ID Payload according to IP version and address.
494 IdPayload
= Ikev2GenerateIdPayload (
495 &IkeSaSession
->SessionCommon
,
496 IKEV2_PAYLOAD_TYPE_AUTH
498 if (IdPayload
== NULL
) {
503 // 3. Generate Auth Payload
504 // If it is tunnel mode, should create the configuration payload after the
507 if (IkeSaSession
->Spd
->Data
->ProcessingPolicy
->Mode
== EfiIPsecTransport
) {
509 AuthPayload
= Ikev2PskGenerateAuthPayload (
510 ChildSaSession
->IkeSaSession
,
512 IKEV2_PAYLOAD_TYPE_SA
,
516 AuthPayload
= Ikev2PskGenerateAuthPayload (
517 ChildSaSession
->IkeSaSession
,
519 IKEV2_PAYLOAD_TYPE_CP
,
522 if (IkeSaSession
->SessionCommon
.UdpService
->IpVersion
== IP_VERSION_4
) {
523 CpPayload
= Ikev2GenerateCpPayload (
524 ChildSaSession
->IkeSaSession
,
525 IKEV2_PAYLOAD_TYPE_SA
,
526 IKEV2_CFG_ATTR_INTERNAL_IP4_ADDRESS
529 CpPayload
= Ikev2GenerateCpPayload (
530 ChildSaSession
->IkeSaSession
,
531 IKEV2_PAYLOAD_TYPE_SA
,
532 IKEV2_CFG_ATTR_INTERNAL_IP6_ADDRESS
536 if (CpPayload
== NULL
) {
541 if (AuthPayload
== NULL
) {
546 // 4. Generate SA Payload according to the SA Data in ChildSaSession
548 SaPayload
= Ikev2GenerateSaPayload (
549 ChildSaSession
->SaData
,
550 IKEV2_PAYLOAD_TYPE_TS_INIT
,
551 IkeSessionTypeChildSa
553 if (SaPayload
== NULL
) {
557 if (IkeSaSession
->Spd
->Data
->ProcessingPolicy
->Mode
== EfiIPsecTransport
) {
559 // Generate Tsi and Tsr.
561 TsiPayload
= Ikev2GenerateTsPayload (
563 IKEV2_PAYLOAD_TYPE_TS_RSP
,
567 TsrPayload
= Ikev2GenerateTsPayload (
569 IKEV2_PAYLOAD_TYPE_NOTIFY
,
574 // Generate Notify Payload. If transport mode, there should have Notify
575 // payload with TRANSPORT_MODE notification.
577 NotifyPayload
= Ikev2GenerateNotifyPayload (
579 IKEV2_PAYLOAD_TYPE_NONE
,
581 IKEV2_NOTIFICATION_USE_TRANSPORT_MODE
,
586 if (NotifyPayload
== NULL
) {
591 // Generate Tsr for Tunnel mode.
593 TsiPayload
= Ikev2GenerateTsPayload (
595 IKEV2_PAYLOAD_TYPE_TS_RSP
,
598 TsrPayload
= Ikev2GenerateTsPayload (
600 IKEV2_PAYLOAD_TYPE_NONE
,
605 if (TsiPayload
== NULL
|| TsrPayload
== NULL
) {
609 IKE_PACKET_APPEND_PAYLOAD (IkePacket
, IdPayload
);
610 IKE_PACKET_APPEND_PAYLOAD (IkePacket
, AuthPayload
);
611 if (IkeSaSession
->Spd
->Data
->ProcessingPolicy
->Mode
== EfiIPsecTunnel
) {
612 IKE_PACKET_APPEND_PAYLOAD (IkePacket
, CpPayload
);
614 IKE_PACKET_APPEND_PAYLOAD (IkePacket
, SaPayload
);
615 IKE_PACKET_APPEND_PAYLOAD (IkePacket
, TsiPayload
);
616 IKE_PACKET_APPEND_PAYLOAD (IkePacket
, TsrPayload
);
617 if (IkeSaSession
->Spd
->Data
->ProcessingPolicy
->Mode
== EfiIPsecTransport
) {
618 IKE_PACKET_APPEND_PAYLOAD (IkePacket
, NotifyPayload
);
624 if (IkePacket
!= NULL
) {
625 IkePacketFree (IkePacket
);
628 if (IdPayload
!= NULL
) {
629 IkePayloadFree (IdPayload
);
632 if (AuthPayload
!= NULL
) {
633 IkePayloadFree (AuthPayload
);
636 if (CpPayload
!= NULL
) {
637 IkePayloadFree (CpPayload
);
640 if (SaPayload
!= NULL
) {
641 IkePayloadFree (SaPayload
);
644 if (TsiPayload
!= NULL
) {
645 IkePayloadFree (TsiPayload
);
648 if (TsrPayload
!= NULL
) {
649 IkePayloadFree (TsrPayload
);
652 if (NotifyPayload
!= NULL
) {
653 IkePayloadFree (NotifyPayload
);
660 Parses IKE_AUTH packet.
662 @param[in] SaSession Pointer to the IKE_SA_SESSION related to this packet.
663 @param[in] IkePacket Pointer to the IKE_AUTH packet to be parsered.
665 @retval EFI_INVALID_PARAMETER The IKE packet is malformed or the SA
666 proposal is unacceptable.
667 @retval EFI_SUCCESS The IKE packet is acceptable and the
668 relative data is saved for furthure communication.
674 IN IKE_PACKET
*IkePacket
677 IKEV2_CHILD_SA_SESSION
*ChildSaSession
;
678 IKEV2_SA_SESSION
*IkeSaSession
;
679 IKE_PAYLOAD
*IkePayload
;
680 IKE_PAYLOAD
*SaPayload
;
681 IKE_PAYLOAD
*IdiPayload
;
682 IKE_PAYLOAD
*IdrPayload
;
683 IKE_PAYLOAD
*AuthPayload
;
684 IKE_PAYLOAD
*TsiPayload
;
685 IKE_PAYLOAD
*TsrPayload
;
686 IKE_PAYLOAD
*VerifiedAuthPayload
;
690 IkeSaSession
= (IKEV2_SA_SESSION
*) SaSession
;
691 ChildSaSession
= IKEV2_CHILD_SA_SESSION_BY_IKE_SA (GetFirstNode (&IkeSaSession
->ChildSaSessionList
));
701 // Iterate payloads to find the SaPayload/ID/AUTH/TS Payload.
703 NET_LIST_FOR_EACH (Entry
, &(IkePacket
)->PayloadList
) {
704 IkePayload
= IKE_PAYLOAD_BY_PACKET (Entry
);
706 if (IkePayload
->PayloadType
== IKEV2_PAYLOAD_TYPE_ID_INIT
) {
707 IdiPayload
= IkePayload
;
709 if (IkePayload
->PayloadType
== IKEV2_PAYLOAD_TYPE_ID_RSP
) {
710 IdrPayload
= IkePayload
;
712 if (IkePayload
->PayloadType
== IKEV2_PAYLOAD_TYPE_SA
) {
713 SaPayload
= IkePayload
;
715 if (IkePayload
->PayloadType
== IKEV2_PAYLOAD_TYPE_AUTH
) {
716 AuthPayload
= IkePayload
;
718 if (IkePayload
->PayloadType
== IKEV2_PAYLOAD_TYPE_TS_INIT
) {
719 TsiPayload
= IkePayload
;
721 if (IkePayload
->PayloadType
== IKEV2_PAYLOAD_TYPE_TS_RSP
) {
722 TsrPayload
= IkePayload
;
726 if ((SaPayload
== NULL
) || (AuthPayload
== NULL
) || (TsiPayload
== NULL
) || (TsrPayload
== NULL
)) {
727 return EFI_INVALID_PARAMETER
;
729 if ((IdiPayload
== NULL
) && (IdrPayload
== NULL
)) {
730 return EFI_INVALID_PARAMETER
;
734 // Check IkePacket Header is match the state
736 if (IkeSaSession
->SessionCommon
.IsInitiator
) {
739 // 1. Check the IkePacket->Hdr == IKE_HEADER_FLAGS_RESPOND
741 if ((IkePacket
->Header
->Flags
!= IKE_HEADER_FLAGS_RESPOND
) ||
742 (IkePacket
->Header
->ExchangeType
!= IKEV2_EXCHANGE_TYPE_AUTH
)
744 return EFI_INVALID_PARAMETER
;
749 // 1. Check the IkePacket->Hdr == IKE_HEADER_FLAGS_INIT
751 if ((IkePacket
->Header
->Flags
!= IKE_HEADER_FLAGS_INIT
) ||
752 (IkePacket
->Header
->ExchangeType
!= IKEV2_EXCHANGE_TYPE_AUTH
)
754 return EFI_INVALID_PARAMETER
;
758 // 2. Parse the SA payload and Key Payload and find out the perferable one
759 // and fill in the Sa paramse into CommonSession->SaParams and SaData into
760 // IkeSaSession for the responder SA payload generation.
765 // Verify the Auth Payload.
767 VerifiedAuthPayload
= Ikev2PskGenerateAuthPayload (
769 IkeSaSession
->SessionCommon
.IsInitiator
? IdrPayload
: IdiPayload
,
770 IKEV2_PAYLOAD_TYPE_SA
,
773 if ((VerifiedAuthPayload
!= NULL
) &&
775 VerifiedAuthPayload
->PayloadBuf
+ sizeof (IKEV2_COMMON_PAYLOAD_HEADER
),
776 AuthPayload
->PayloadBuf
+ sizeof (IKEV2_COMMON_PAYLOAD_HEADER
),
777 VerifiedAuthPayload
->PayloadSize
- sizeof (IKEV2_COMMON_PAYLOAD_HEADER
)
779 return EFI_INVALID_PARAMETER
;
783 // 3. Parse the SA Payload to find out the cryptographic suite
784 // and fill in the Sa paramse into CommonSession->SaParams. If no acceptable
785 // porposal found, return EFI_INVALID_PARAMETER.
787 if (!Ikev2ChildSaParseSaPayload (ChildSaSession
, SaPayload
, IkePacket
->Header
->Flags
)) {
788 return EFI_INVALID_PARAMETER
;
792 // 4. Parse TSi, TSr payloads.
794 if ((((TRAFFIC_SELECTOR
*)(TsiPayload
->PayloadBuf
+ sizeof (IKEV2_TS
)))->IpProtocolId
!=
795 ((TRAFFIC_SELECTOR
*)(TsrPayload
->PayloadBuf
+ sizeof (IKEV2_TS
)))->IpProtocolId
) &&
796 (((TRAFFIC_SELECTOR
*)(TsiPayload
->PayloadBuf
+ sizeof (IKEV2_TS
)))->IpProtocolId
!= 0) &&
797 (((TRAFFIC_SELECTOR
*)(TsrPayload
->PayloadBuf
+ sizeof (IKEV2_TS
)))->IpProtocolId
!= 0)
799 return EFI_INVALID_PARAMETER
;
802 if (!IkeSaSession
->SessionCommon
.IsInitiator
) {
804 //TODO:check the Port range. Only support any port and one certain port here.
806 ChildSaSession
->ProtoId
= ((TRAFFIC_SELECTOR
*)(TsrPayload
->PayloadBuf
+ sizeof (IKEV2_TS
)))->IpProtocolId
;
807 ChildSaSession
->LocalPort
= ((TRAFFIC_SELECTOR
*)(TsrPayload
->PayloadBuf
+ sizeof (IKEV2_TS
)))->StartPort
;
808 ChildSaSession
->RemotePort
= ((TRAFFIC_SELECTOR
*)(TsiPayload
->PayloadBuf
+ sizeof (IKEV2_TS
)))->StartPort
;
810 // Association a SPD with this SA.
812 Status
= Ikev2ChildSaAssociateSpdEntry (ChildSaSession
);
813 if (EFI_ERROR (Status
)) {
814 return EFI_INVALID_PARAMETER
;
817 // Associate the IkeSaSession's SPD to the first ChildSaSession's SPD.
819 if (ChildSaSession
->IkeSaSession
->Spd
== NULL
) {
820 ChildSaSession
->IkeSaSession
->Spd
= ChildSaSession
->Spd
;
821 Status
= Ikev2ChildSaSessionSpdSelectorCreate (ChildSaSession
);
822 if (EFI_ERROR (Status
)) {
828 //TODO:check the Port range.
830 if ((((TRAFFIC_SELECTOR
*)(TsrPayload
->PayloadBuf
+ sizeof (IKEV2_TS
)))->StartPort
!= 0) &&
831 (((TRAFFIC_SELECTOR
*)(TsrPayload
->PayloadBuf
+ sizeof (IKEV2_TS
)))->StartPort
!= ChildSaSession
->RemotePort
)
833 return EFI_INVALID_PARAMETER
;
835 if ((((TRAFFIC_SELECTOR
*)(TsiPayload
->PayloadBuf
+ sizeof (IKEV2_TS
)))->StartPort
!= 0) &&
836 (((TRAFFIC_SELECTOR
*)(TsiPayload
->PayloadBuf
+ sizeof (IKEV2_TS
)))->StartPort
!= ChildSaSession
->LocalPort
)
838 return EFI_INVALID_PARAMETER
;
841 // For the tunnel mode, it should add the vitual IP address into the SA's SPD Selector.
843 if (ChildSaSession
->Spd
->Data
->ProcessingPolicy
->Mode
== EfiIPsecTunnel
) {
844 if (!ChildSaSession
->IkeSaSession
->SessionCommon
.IsInitiator
) {
846 // If it is tunnel mode, the UEFI part must be the initiator.
848 return EFI_INVALID_PARAMETER
;
851 // Get the Virtual IP address from the Tsi traffic selector.
852 // TODO: check the CFG reply payload
855 &ChildSaSession
->SpdSelector
->LocalAddress
[0].Address
,
856 TsiPayload
->PayloadBuf
+ sizeof (IKEV2_TS
) + sizeof (TRAFFIC_SELECTOR
),
857 (ChildSaSession
->SessionCommon
.UdpService
->IpVersion
== IP_VERSION_4
) ?
858 sizeof (EFI_IPv4_ADDRESS
) : sizeof (EFI_IPv6_ADDRESS
)
864 // 5. Generate keymats for IPsec protocol.
866 Status
= Ikev2GenerateChildSaKeys (ChildSaSession
, NULL
);
867 if (EFI_ERROR (Status
)) {
871 if (IkeSaSession
->SessionCommon
.IsInitiator
) {
873 // 6. Change the state of IkeSaSession
875 IKEV2_DUMP_STATE (IkeSaSession
->SessionCommon
.State
, IkeStateIkeSaEstablished
);
876 IkeSaSession
->SessionCommon
.State
= IkeStateIkeSaEstablished
;
883 Gernerates IKEv2 packet for IKE_SA_INIT exchange.
885 @param[in] SaSession Pointer to IKEV2_SA_SESSION related to the exchange.
886 @param[in] Context Context Data passed by caller.
888 @retval EFI_SUCCESS The IKE packet generation succeeded.
889 @retval Others The IKE packet generation failed.
893 Ikev2InitCertGenerator (
898 IKE_PACKET
*IkePacket
;
899 IKE_PAYLOAD
*CertReqPayload
;
901 IKE_PAYLOAD
*NoncePayload
;
903 if (!FeaturePcdGet (PcdIpsecCertificateEnabled
)) {
908 // The first two messages exchange is same between PSK and Cert.
910 IkePacket
= Ikev2InitPskGenerator (SaSession
, Context
);
912 if ((IkePacket
!= NULL
) && (!((IKEV2_SA_SESSION
*)SaSession
)->SessionCommon
.IsInitiator
)) {
914 // Add the Certification Request Payload
916 CertReqPayload
= Ikev2GenerateCertificatePayload (
917 (IKEV2_SA_SESSION
*)SaSession
,
918 IKEV2_PAYLOAD_TYPE_NONE
,
919 (UINT8
*)PcdGetPtr(PcdIpsecUefiCaFile
),
920 PcdGet32(PcdIpsecUefiCaFileSize
),
921 IKEV2_CERT_ENCODEING_HASH_AND_URL_OF_X509_CERT
,
925 // Change Nonce Payload Next payload type.
927 IKE_PACKET_END_PAYLOAD (IkePacket
, Node
);
928 NoncePayload
= IKE_PAYLOAD_BY_PACKET (Node
);
929 ((IKEV2_NONCE
*)NoncePayload
->PayloadBuf
)->Header
.NextPayload
= IKEV2_PAYLOAD_TYPE_CERTREQ
;
932 // Add Certification Request Payload
934 IKE_PACKET_APPEND_PAYLOAD (IkePacket
, CertReqPayload
);
941 Parses the IKEv2 packet for IKE_SA_INIT exchange.
943 @param[in] SaSession Pointer to IKEV2_SA_SESSION related to the exchange.
944 @param[in] IkePacket The received IKEv2 packet to be parsed.
946 @retval EFI_SUCCESS The IKEv2 packet is acceptable and the relative data is
947 saved for furthure communication.
948 @retval EFI_INVALID_PARAMETER The IKE packet is malformed or the SA proposal is unacceptable.
949 @retval EFI_UNSUPPORTED The certificate authentication is not supported.
953 Ikev2InitCertParser (
955 IN IKE_PACKET
*IkePacket
958 if (!FeaturePcdGet (PcdIpsecCertificateEnabled
)) {
959 return EFI_UNSUPPORTED
;
963 // The first two messages exchange is same between PSK and Cert.
964 // Todo: Parse Certificate Request from responder Initial Exchange.
966 return Ikev2InitPskParser (SaSession
, IkePacket
);
970 Generates the IKEv2 packet for IKE_AUTH exchange.
972 @param[in] SaSession Pointer to IKEV2_SA_SESSION.
973 @param[in] Context Context data passed by caller.
975 @retval Pointer to IKEv2 Packet to be sent out.
979 Ikev2AuthCertGenerator (
984 IKE_PACKET
*IkePacket
;
985 IKEV2_SA_SESSION
*IkeSaSession
;
986 IKE_PAYLOAD
*IdPayload
;
987 IKE_PAYLOAD
*AuthPayload
;
988 IKE_PAYLOAD
*SaPayload
;
989 IKE_PAYLOAD
*TsiPayload
;
990 IKE_PAYLOAD
*TsrPayload
;
991 IKE_PAYLOAD
*NotifyPayload
;
992 IKE_PAYLOAD
*CpPayload
;
993 IKE_PAYLOAD
*CertPayload
;
994 IKE_PAYLOAD
*CertReqPayload
;
995 IKEV2_CHILD_SA_SESSION
*ChildSaSession
;
997 if (!FeaturePcdGet (PcdIpsecCertificateEnabled
)) {
1001 IkeSaSession
= (IKEV2_SA_SESSION
*) SaSession
;
1002 ChildSaSession
= IKEV2_CHILD_SA_SESSION_BY_IKE_SA (GetFirstNode (&IkeSaSession
->ChildSaSessionList
));
1011 NotifyPayload
= NULL
;
1013 CertReqPayload
= NULL
;
1016 // 1. Allocate IKE Packet
1018 IkePacket
= IkePacketAlloc ();
1019 if (IkePacket
== NULL
) {
1024 // 1.a Fill the IkePacket Header.
1026 IkePacket
->Header
->ExchangeType
= IKEV2_EXCHANGE_TYPE_AUTH
;
1027 IkePacket
->Header
->InitiatorCookie
= IkeSaSession
->InitiatorCookie
;
1028 IkePacket
->Header
->ResponderCookie
= IkeSaSession
->ResponderCookie
;
1029 IkePacket
->Header
->Version
= (UINT8
)(2 << 4);
1030 if (ChildSaSession
->SessionCommon
.IsInitiator
) {
1031 IkePacket
->Header
->NextPayload
= IKEV2_PAYLOAD_TYPE_ID_INIT
;
1033 IkePacket
->Header
->NextPayload
= IKEV2_PAYLOAD_TYPE_ID_RSP
;
1037 // According to RFC4306_2.2, For the IKE_SA_INIT message the MessageID should
1038 // be always number 0 and 1;
1040 IkePacket
->Header
->MessageId
= 1;
1042 if (IkeSaSession
->SessionCommon
.IsInitiator
) {
1043 IkePacket
->Header
->Flags
= IKE_HEADER_FLAGS_INIT
;
1045 IkePacket
->Header
->Flags
= IKE_HEADER_FLAGS_RESPOND
;
1049 // 2. Generate ID Payload according to IP version and address.
1051 IdPayload
= Ikev2GenerateCertIdPayload (
1052 &IkeSaSession
->SessionCommon
,
1053 IKEV2_PAYLOAD_TYPE_CERT
,
1054 (UINT8
*)PcdGetPtr (PcdIpsecUefiCertificate
),
1055 PcdGet32 (PcdIpsecUefiCertificateSize
)
1057 if (IdPayload
== NULL
) {
1062 // 3. Generate Certificate Payload
1064 CertPayload
= Ikev2GenerateCertificatePayload (
1066 (UINT8
)(IkeSaSession
->SessionCommon
.IsInitiator
? IKEV2_PAYLOAD_TYPE_CERTREQ
: IKEV2_PAYLOAD_TYPE_AUTH
),
1067 (UINT8
*)PcdGetPtr (PcdIpsecUefiCertificate
),
1068 PcdGet32 (PcdIpsecUefiCertificateSize
),
1069 IKEV2_CERT_ENCODEING_X509_CERT_SIGN
,
1072 if (CertPayload
== NULL
) {
1076 if (IkeSaSession
->SessionCommon
.IsInitiator
) {
1077 CertReqPayload
= Ikev2GenerateCertificatePayload (
1079 IKEV2_PAYLOAD_TYPE_AUTH
,
1080 (UINT8
*)PcdGetPtr (PcdIpsecUefiCertificate
),
1081 PcdGet32 (PcdIpsecUefiCertificateSize
),
1082 IKEV2_CERT_ENCODEING_HASH_AND_URL_OF_X509_CERT
,
1085 if (CertReqPayload
== NULL
) {
1091 // 4. Generate Auth Payload
1092 // If it is tunnel mode, should create the configuration payload after the
1095 if (IkeSaSession
->Spd
->Data
->ProcessingPolicy
->Mode
== EfiIPsecTransport
) {
1096 AuthPayload
= Ikev2CertGenerateAuthPayload (
1097 ChildSaSession
->IkeSaSession
,
1099 IKEV2_PAYLOAD_TYPE_SA
,
1101 (UINT8
*)PcdGetPtr (PcdIpsecUefiCertificateKey
),
1102 PcdGet32 (PcdIpsecUefiCertificateKeySize
),
1103 ChildSaSession
->IkeSaSession
->Pad
->Data
->AuthData
,
1104 ChildSaSession
->IkeSaSession
->Pad
->Data
->AuthDataSize
1107 AuthPayload
= Ikev2CertGenerateAuthPayload (
1108 ChildSaSession
->IkeSaSession
,
1110 IKEV2_PAYLOAD_TYPE_CP
,
1112 (UINT8
*)PcdGetPtr (PcdIpsecUefiCertificateKey
),
1113 PcdGet32 (PcdIpsecUefiCertificateKeySize
),
1114 ChildSaSession
->IkeSaSession
->Pad
->Data
->AuthData
,
1115 ChildSaSession
->IkeSaSession
->Pad
->Data
->AuthDataSize
1117 if (IkeSaSession
->SessionCommon
.UdpService
->IpVersion
== IP_VERSION_4
) {
1118 CpPayload
= Ikev2GenerateCpPayload (
1119 ChildSaSession
->IkeSaSession
,
1120 IKEV2_PAYLOAD_TYPE_SA
,
1121 IKEV2_CFG_ATTR_INTERNAL_IP4_ADDRESS
1124 CpPayload
= Ikev2GenerateCpPayload (
1125 ChildSaSession
->IkeSaSession
,
1126 IKEV2_PAYLOAD_TYPE_SA
,
1127 IKEV2_CFG_ATTR_INTERNAL_IP6_ADDRESS
1131 if (CpPayload
== NULL
) {
1136 if (AuthPayload
== NULL
) {
1141 // 5. Generate SA Payload according to the Sa Data in ChildSaSession
1143 SaPayload
= Ikev2GenerateSaPayload (
1144 ChildSaSession
->SaData
,
1145 IKEV2_PAYLOAD_TYPE_TS_INIT
,
1146 IkeSessionTypeChildSa
1148 if (SaPayload
== NULL
) {
1152 if (IkeSaSession
->Spd
->Data
->ProcessingPolicy
->Mode
== EfiIPsecTransport
) {
1154 // Generate Tsi and Tsr.
1156 TsiPayload
= Ikev2GenerateTsPayload (
1158 IKEV2_PAYLOAD_TYPE_TS_RSP
,
1162 TsrPayload
= Ikev2GenerateTsPayload (
1164 IKEV2_PAYLOAD_TYPE_NOTIFY
,
1169 // Generate Notify Payload. If transport mode, there should have Notify
1170 // payload with TRANSPORT_MODE notification.
1172 NotifyPayload
= Ikev2GenerateNotifyPayload (
1174 IKEV2_PAYLOAD_TYPE_NONE
,
1176 IKEV2_NOTIFICATION_USE_TRANSPORT_MODE
,
1181 if (NotifyPayload
== NULL
) {
1186 // Generate Tsr for Tunnel mode.
1188 TsiPayload
= Ikev2GenerateTsPayload (
1190 IKEV2_PAYLOAD_TYPE_TS_RSP
,
1193 TsrPayload
= Ikev2GenerateTsPayload (
1195 IKEV2_PAYLOAD_TYPE_NONE
,
1200 if (TsiPayload
== NULL
|| TsrPayload
== NULL
) {
1204 IKE_PACKET_APPEND_PAYLOAD (IkePacket
, IdPayload
);
1205 IKE_PACKET_APPEND_PAYLOAD (IkePacket
, CertPayload
);
1206 if (IkeSaSession
->SessionCommon
.IsInitiator
) {
1207 IKE_PACKET_APPEND_PAYLOAD (IkePacket
, CertReqPayload
);
1209 IKE_PACKET_APPEND_PAYLOAD (IkePacket
, AuthPayload
);
1210 if (IkeSaSession
->Spd
->Data
->ProcessingPolicy
->Mode
== EfiIPsecTunnel
) {
1211 IKE_PACKET_APPEND_PAYLOAD (IkePacket
, CpPayload
);
1213 IKE_PACKET_APPEND_PAYLOAD (IkePacket
, SaPayload
);
1214 IKE_PACKET_APPEND_PAYLOAD (IkePacket
, TsiPayload
);
1215 IKE_PACKET_APPEND_PAYLOAD (IkePacket
, TsrPayload
);
1216 if (IkeSaSession
->Spd
->Data
->ProcessingPolicy
->Mode
== EfiIPsecTransport
) {
1217 IKE_PACKET_APPEND_PAYLOAD (IkePacket
, NotifyPayload
);
1223 if (IkePacket
!= NULL
) {
1224 IkePacketFree (IkePacket
);
1227 if (IdPayload
!= NULL
) {
1228 IkePayloadFree (IdPayload
);
1231 if (CertPayload
!= NULL
) {
1232 IkePayloadFree (CertPayload
);
1235 if (CertReqPayload
!= NULL
) {
1236 IkePayloadFree (CertReqPayload
);
1239 if (AuthPayload
!= NULL
) {
1240 IkePayloadFree (AuthPayload
);
1243 if (CpPayload
!= NULL
) {
1244 IkePayloadFree (CpPayload
);
1247 if (SaPayload
!= NULL
) {
1248 IkePayloadFree (SaPayload
);
1251 if (TsiPayload
!= NULL
) {
1252 IkePayloadFree (TsiPayload
);
1255 if (TsrPayload
!= NULL
) {
1256 IkePayloadFree (TsrPayload
);
1259 if (NotifyPayload
!= NULL
) {
1260 IkePayloadFree (NotifyPayload
);
1267 Parses IKE_AUTH packet.
1269 @param[in] SaSession Pointer to the IKE_SA_SESSION related to this packet.
1270 @param[in] IkePacket Pointer to the IKE_AUTH packet to be parsered.
1272 @retval EFI_INVALID_PARAMETER The IKEv2 packet is malformed or the SA
1273 proposal is unacceptable.
1274 @retval EFI_SUCCESS The IKE packet is acceptable and the
1275 relative data is saved for furthure communication.
1276 @retval EFI_UNSUPPORTED The certificate authentication is not supported.
1280 Ikev2AuthCertParser (
1281 IN UINT8
*SaSession
,
1282 IN IKE_PACKET
*IkePacket
1285 IKEV2_CHILD_SA_SESSION
*ChildSaSession
;
1286 IKEV2_SA_SESSION
*IkeSaSession
;
1287 IKE_PAYLOAD
*IkePayload
;
1288 IKE_PAYLOAD
*SaPayload
;
1289 IKE_PAYLOAD
*IdiPayload
;
1290 IKE_PAYLOAD
*IdrPayload
;
1291 IKE_PAYLOAD
*AuthPayload
;
1292 IKE_PAYLOAD
*TsiPayload
;
1293 IKE_PAYLOAD
*TsrPayload
;
1294 IKE_PAYLOAD
*CertPayload
;
1295 IKE_PAYLOAD
*VerifiedAuthPayload
;
1299 if (!FeaturePcdGet (PcdIpsecCertificateEnabled
)) {
1300 return EFI_UNSUPPORTED
;
1303 IkeSaSession
= (IKEV2_SA_SESSION
*) SaSession
;
1304 ChildSaSession
= IKEV2_CHILD_SA_SESSION_BY_IKE_SA (GetFirstNode (&IkeSaSession
->ChildSaSessionList
));
1313 VerifiedAuthPayload
= NULL
;
1314 Status
= EFI_INVALID_PARAMETER
;
1317 // Iterate payloads to find the SaPayload/ID/AUTH/TS Payload.
1319 NET_LIST_FOR_EACH (Entry
, &(IkePacket
)->PayloadList
) {
1320 IkePayload
= IKE_PAYLOAD_BY_PACKET (Entry
);
1322 if (IkePayload
->PayloadType
== IKEV2_PAYLOAD_TYPE_ID_INIT
) {
1323 IdiPayload
= IkePayload
;
1325 if (IkePayload
->PayloadType
== IKEV2_PAYLOAD_TYPE_ID_RSP
) {
1326 IdrPayload
= IkePayload
;
1329 if (IkePayload
->PayloadType
== IKEV2_PAYLOAD_TYPE_SA
) {
1330 SaPayload
= IkePayload
;
1332 if (IkePayload
->PayloadType
== IKEV2_PAYLOAD_TYPE_AUTH
) {
1333 AuthPayload
= IkePayload
;
1335 if (IkePayload
->PayloadType
== IKEV2_PAYLOAD_TYPE_TS_INIT
) {
1336 TsiPayload
= IkePayload
;
1338 if (IkePayload
->PayloadType
== IKEV2_PAYLOAD_TYPE_TS_RSP
) {
1339 TsrPayload
= IkePayload
;
1341 if (IkePayload
->PayloadType
== IKEV2_PAYLOAD_TYPE_CERT
) {
1342 CertPayload
= IkePayload
;
1346 if ((SaPayload
== NULL
) || (AuthPayload
== NULL
) || (TsiPayload
== NULL
) ||
1347 (TsrPayload
== NULL
) || (CertPayload
== NULL
)) {
1350 if ((IdiPayload
== NULL
) && (IdrPayload
== NULL
)) {
1355 // Check IkePacket Header is match the state
1357 if (IkeSaSession
->SessionCommon
.IsInitiator
) {
1360 // 1. Check the IkePacket->Hdr == IKE_HEADER_FLAGS_RESPOND
1362 if ((IkePacket
->Header
->Flags
!= IKE_HEADER_FLAGS_RESPOND
) ||
1363 (IkePacket
->Header
->ExchangeType
!= IKEV2_EXCHANGE_TYPE_AUTH
)) {
1368 // 1. Check the IkePacket->Hdr == IKE_HEADER_FLAGS_INIT
1370 if ((IkePacket
->Header
->Flags
!= IKE_HEADER_FLAGS_INIT
) ||
1371 (IkePacket
->Header
->ExchangeType
!= IKEV2_EXCHANGE_TYPE_AUTH
)) {
1377 // Verify the Auth Payload.
1379 VerifiedAuthPayload
= Ikev2CertGenerateAuthPayload (
1381 IkeSaSession
->SessionCommon
.IsInitiator
? IdrPayload
:IdiPayload
,
1382 IKEV2_PAYLOAD_TYPE_SA
,
1390 if ((VerifiedAuthPayload
!= NULL
) &&
1391 (!IpSecCryptoIoVerifySignDataByCertificate (
1392 CertPayload
->PayloadBuf
+ sizeof (IKEV2_CERT
),
1393 CertPayload
->PayloadSize
- sizeof (IKEV2_CERT
),
1394 (UINT8
*)PcdGetPtr (PcdIpsecUefiCaFile
),
1395 PcdGet32 (PcdIpsecUefiCaFileSize
),
1396 VerifiedAuthPayload
->PayloadBuf
+ sizeof (IKEV2_AUTH
),
1397 VerifiedAuthPayload
->PayloadSize
- sizeof (IKEV2_AUTH
),
1398 AuthPayload
->PayloadBuf
+ sizeof (IKEV2_AUTH
),
1399 AuthPayload
->PayloadSize
- sizeof (IKEV2_AUTH
)
1405 // 3. Parse the SA Payload to find out the cryptographic suite
1406 // and fill in the SA paramse into CommonSession->SaParams. If no acceptable
1407 // porposal found, return EFI_INVALID_PARAMETER.
1409 if (!Ikev2ChildSaParseSaPayload (ChildSaSession
, SaPayload
, IkePacket
->Header
->Flags
)) {
1414 // 4. Parse TSi, TSr payloads.
1416 if ((((TRAFFIC_SELECTOR
*)(TsiPayload
->PayloadBuf
+ sizeof (IKEV2_TS
)))->IpProtocolId
!=
1417 ((TRAFFIC_SELECTOR
*)(TsrPayload
->PayloadBuf
+ sizeof (IKEV2_TS
)))->IpProtocolId
) &&
1418 (((TRAFFIC_SELECTOR
*)(TsiPayload
->PayloadBuf
+ sizeof (IKEV2_TS
)))->IpProtocolId
!= 0) &&
1419 (((TRAFFIC_SELECTOR
*)(TsrPayload
->PayloadBuf
+ sizeof (IKEV2_TS
)))->IpProtocolId
!= 0)
1424 if (!IkeSaSession
->SessionCommon
.IsInitiator
) {
1426 //Todo:check the Port range. Only support any port and one certain port here.
1428 ChildSaSession
->ProtoId
= ((TRAFFIC_SELECTOR
*)(TsrPayload
->PayloadBuf
+ sizeof (IKEV2_TS
)))->IpProtocolId
;
1429 ChildSaSession
->LocalPort
= ((TRAFFIC_SELECTOR
*)(TsrPayload
->PayloadBuf
+ sizeof (IKEV2_TS
)))->StartPort
;
1430 ChildSaSession
->RemotePort
= ((TRAFFIC_SELECTOR
*)(TsiPayload
->PayloadBuf
+ sizeof (IKEV2_TS
)))->StartPort
;
1432 // Association a SPD with this SA.
1434 if (EFI_ERROR (Ikev2ChildSaAssociateSpdEntry (ChildSaSession
))) {
1438 // Associate the IkeSaSession's SPD to the first ChildSaSession's SPD.
1440 if (ChildSaSession
->IkeSaSession
->Spd
== NULL
) {
1441 ChildSaSession
->IkeSaSession
->Spd
= ChildSaSession
->Spd
;
1442 Status
= Ikev2ChildSaSessionSpdSelectorCreate (ChildSaSession
);
1443 if (EFI_ERROR (Status
)) {
1449 // Todo:check the Port range.
1451 if ((((TRAFFIC_SELECTOR
*)(TsrPayload
->PayloadBuf
+ sizeof (IKEV2_TS
)))->StartPort
!= 0) &&
1452 (((TRAFFIC_SELECTOR
*)(TsrPayload
->PayloadBuf
+ sizeof (IKEV2_TS
)))->StartPort
!= ChildSaSession
->RemotePort
)
1456 if ((((TRAFFIC_SELECTOR
*)(TsiPayload
->PayloadBuf
+ sizeof (IKEV2_TS
)))->StartPort
!= 0) &&
1457 (((TRAFFIC_SELECTOR
*)(TsiPayload
->PayloadBuf
+ sizeof (IKEV2_TS
)))->StartPort
!= ChildSaSession
->LocalPort
)
1462 // For the tunnel mode, it should add the vitual IP address into the SA's SPD Selector.
1464 if (ChildSaSession
->Spd
->Data
->ProcessingPolicy
->Mode
== EfiIPsecTunnel
) {
1465 if (!ChildSaSession
->IkeSaSession
->SessionCommon
.IsInitiator
) {
1467 // If it is tunnel mode, the UEFI part must be the initiator.
1472 // Get the Virtual IP address from the Tsi traffic selector.
1473 // TODO: check the CFG reply payload
1476 &ChildSaSession
->SpdSelector
->LocalAddress
[0].Address
,
1477 TsiPayload
->PayloadBuf
+ sizeof (IKEV2_TS
) + sizeof (TRAFFIC_SELECTOR
),
1478 (ChildSaSession
->SessionCommon
.UdpService
->IpVersion
== IP_VERSION_4
) ?
1479 sizeof (EFI_IPv4_ADDRESS
) : sizeof (EFI_IPv6_ADDRESS
)
1485 // 5. Generat keymats for IPsec protocol.
1487 Status
= Ikev2GenerateChildSaKeys (ChildSaSession
, NULL
);
1488 if (EFI_ERROR (Status
)) {
1492 if (IkeSaSession
->SessionCommon
.IsInitiator
) {
1494 // 6. Change the state of IkeSaSession
1496 IKEV2_DUMP_STATE (IkeSaSession
->SessionCommon
.State
, IkeStateIkeSaEstablished
);
1497 IkeSaSession
->SessionCommon
.State
= IkeStateIkeSaEstablished
;
1500 Status
= EFI_SUCCESS
;
1503 if (VerifiedAuthPayload
!= NULL
) {
1504 IkePayloadFree (VerifiedAuthPayload
);
1510 Generates the DH Public Key.
1512 This generates the DH local public key and store it in the IKE SA Session's GxBuffer.
1514 @param[in] IkeSaSession Pointer to related IKE SA Session.
1516 @retval EFI_SUCCESS The operation succeeded.
1517 @retval Others The operation failed.
1521 Ikev2GenerateSaDhPublicKey (
1522 IN IKEV2_SA_SESSION
*IkeSaSession
1526 IKEV2_SESSION_KEYS
*IkeKeys
;
1528 IkeSaSession
->IkeKeys
= AllocateZeroPool (sizeof (IKEV2_SESSION_KEYS
));
1529 if (IkeSaSession
->IkeKeys
== NULL
) {
1530 return EFI_OUT_OF_RESOURCES
;
1533 IkeKeys
= IkeSaSession
->IkeKeys
;
1534 IkeKeys
->DhBuffer
= AllocateZeroPool (sizeof (IKEV2_DH_BUFFER
));
1535 if (IkeKeys
->DhBuffer
== NULL
) {
1536 FreePool (IkeSaSession
->IkeKeys
);
1537 return EFI_OUT_OF_RESOURCES
;
1541 // Init DH with the certain DH Group Description.
1543 IkeKeys
->DhBuffer
->GxSize
= OakleyModpGroup
[(UINT8
)IkeSaSession
->SessionCommon
.PreferDhGroup
].Size
>> 3;
1544 IkeKeys
->DhBuffer
->GxBuffer
= AllocateZeroPool (IkeKeys
->DhBuffer
->GxSize
);
1545 if (IkeKeys
->DhBuffer
->GxBuffer
== NULL
) {
1546 FreePool (IkeKeys
->DhBuffer
);
1547 FreePool (IkeSaSession
->IkeKeys
);
1548 return EFI_OUT_OF_RESOURCES
;
1554 Status
= IpSecCryptoIoDhGetPublicKey (
1555 &IkeKeys
->DhBuffer
->DhContext
,
1556 OakleyModpGroup
[(UINT8
)IkeSaSession
->SessionCommon
.PreferDhGroup
].GroupGenerator
,
1557 OakleyModpGroup
[(UINT8
)IkeSaSession
->SessionCommon
.PreferDhGroup
].Size
,
1558 OakleyModpGroup
[(UINT8
)IkeSaSession
->SessionCommon
.PreferDhGroup
].Modulus
,
1559 IkeKeys
->DhBuffer
->GxBuffer
,
1560 &IkeKeys
->DhBuffer
->GxSize
1562 if (EFI_ERROR (Status
)) {
1563 DEBUG ((DEBUG_ERROR
, "Error CPLKeyManGetKeyParam X public key error Status = %r\n", Status
));
1565 FreePool (IkeKeys
->DhBuffer
->GxBuffer
);
1567 FreePool (IkeKeys
->DhBuffer
);
1569 FreePool (IkeSaSession
->IkeKeys
);
1574 IPSEC_DUMP_BUF ("DH Public Key (g^x) Dump", IkeKeys
->DhBuffer
->GxBuffer
, IkeKeys
->DhBuffer
->GxSize
);
1580 Computes the DH Shared/Exchange Key.
1582 Given peer's public key, this function computes the exchanged common key and
1583 stores it in the IKEv2 SA Session's GxyBuffer.
1585 @param[in] DhBuffer Pointer to buffer of peer's puliic key.
1586 @param[in] KePayload Pointer to received key payload.
1588 @retval EFI_SUCCESS The operation succeeded.
1589 @retval Otherwise The operation failed.
1593 Ikev2GenerateSaDhComputeKey (
1594 IN IKEV2_DH_BUFFER
*DhBuffer
,
1595 IN IKE_PAYLOAD
*KePayload
1599 IKEV2_KEY_EXCHANGE
*Ke
;
1603 Ke
= (IKEV2_KEY_EXCHANGE
*) KePayload
->PayloadBuf
;
1604 PubKey
= (UINT8
*) (Ke
+ 1);
1605 PubKeySize
= KePayload
->PayloadSize
- sizeof (IKEV2_KEY_EXCHANGE
);
1606 DhBuffer
->GxySize
= DhBuffer
->GxSize
;
1607 DhBuffer
->GxyBuffer
= AllocateZeroPool (DhBuffer
->GxySize
);
1608 if (DhBuffer
->GxyBuffer
== NULL
) {
1609 return EFI_OUT_OF_RESOURCES
;
1615 Status
= IpSecCryptoIoDhComputeKey (
1616 DhBuffer
->DhContext
,
1619 DhBuffer
->GxyBuffer
,
1622 if (EFI_ERROR (Status
)) {
1623 DEBUG ((DEBUG_ERROR
, "Error CPLKeyManGetKeyParam Y session key error Status = %r\n", Status
));
1625 FreePool (DhBuffer
->GxyBuffer
);
1633 DhBuffer
->GySize
= PubKeySize
;
1634 DhBuffer
->GyBuffer
= AllocateZeroPool (DhBuffer
->GySize
);
1635 if (DhBuffer
->GyBuffer
== NULL
) {
1636 FreePool (DhBuffer
->GxyBuffer
);
1641 CopyMem (DhBuffer
->GyBuffer
, PubKey
, DhBuffer
->GySize
);
1643 IPSEC_DUMP_BUF ("DH Public Key (g^y) Dump", DhBuffer
->GyBuffer
, DhBuffer
->GySize
);
1644 IPSEC_DUMP_BUF ("DH Shared Key (g^xy) Dump", DhBuffer
->GxyBuffer
, DhBuffer
->GxySize
);
1650 Generates the IKE SKEYSEED and seven other secrets. SK_d, SK_ai, SK_ar, SK_ei, SK_er,
1651 SK_pi, SK_pr are keys for the furthure IKE exchange.
1653 @param[in] IkeSaSession Pointer to IKE SA Session.
1654 @param[in] KePayload Pointer to Key payload used to generate the Key.
1656 @retval EFI_UNSUPPORTED If one or more Algorithm Id is not supported.
1657 @retval EFI_OUT_OF_RESOURCES If there is no enough resource to be allocated to
1658 meet the requirement.
1659 @retval EFI_SUCCESS The operation succeeded.
1663 Ikev2GenerateSaKeys (
1664 IN IKEV2_SA_SESSION
*IkeSaSession
,
1665 IN IKE_PAYLOAD
*KePayload
1669 IKEV2_SA_PARAMS
*SaParams
;
1670 PRF_DATA_FRAGMENT Fragments
[4];
1671 UINT64 InitiatorCookieNet
;
1672 UINT64 ResponderCookieNet
;
1674 UINTN KeyBufferSize
;
1675 UINTN AuthAlgKeyLen
;
1676 UINTN EncryptAlgKeyLen
;
1677 UINTN IntegrityAlgKeyLen
;
1680 UINTN OutputKeyLength
;
1687 Status
= EFI_SUCCESS
;
1692 Status
= Ikev2GenerateSaDhComputeKey (IkeSaSession
->IkeKeys
->DhBuffer
, KePayload
);
1693 if (EFI_ERROR (Status
)) {
1698 // Get the key length of Authenticaion, Encryption, PRF, and Integrity.
1700 SaParams
= IkeSaSession
->SessionCommon
.SaParams
;
1701 AuthAlgKeyLen
= IpSecGetHmacDigestLength ((UINT8
)SaParams
->Prf
);
1702 EncryptAlgKeyLen
= IpSecGetEncryptKeyLength ((UINT8
)SaParams
->EncAlgId
);
1703 IntegrityAlgKeyLen
= IpSecGetHmacDigestLength ((UINT8
)SaParams
->IntegAlgId
);
1704 PrfAlgKeyLen
= IpSecGetHmacDigestLength ((UINT8
)SaParams
->Prf
);
1707 // If one or more algorithm is not support, return EFI_UNSUPPORTED.
1709 if (AuthAlgKeyLen
== 0 ||
1710 EncryptAlgKeyLen
== 0 ||
1711 IntegrityAlgKeyLen
== 0 ||
1714 Status
= EFI_UNSUPPORTED
;
1719 // Compute SKEYSEED = prf(Ni | Nr, g^ir)
1721 KeyBufferSize
= IkeSaSession
->NiBlkSize
+ IkeSaSession
->NrBlkSize
;
1722 KeyBuffer
= AllocateZeroPool (KeyBufferSize
);
1723 if (KeyBuffer
== NULL
) {
1724 Status
= EFI_OUT_OF_RESOURCES
;
1728 CopyMem (KeyBuffer
, IkeSaSession
->NiBlock
, IkeSaSession
->NiBlkSize
);
1729 CopyMem (KeyBuffer
+ IkeSaSession
->NiBlkSize
, IkeSaSession
->NrBlock
, IkeSaSession
->NrBlkSize
);
1731 Fragments
[0].Data
= IkeSaSession
->IkeKeys
->DhBuffer
->GxyBuffer
;
1732 Fragments
[0].DataSize
= IkeSaSession
->IkeKeys
->DhBuffer
->GxySize
;
1734 DigestSize
= IpSecGetHmacDigestLength ((UINT8
)SaParams
->Prf
);
1735 Digest
= AllocateZeroPool (DigestSize
);
1737 if (Digest
== NULL
) {
1738 Status
= EFI_OUT_OF_RESOURCES
;
1743 (UINT8
)SaParams
->Prf
,
1746 (HASH_DATA_FRAGMENT
*) Fragments
,
1753 // {SK_d | SK_ai | SK_ar | SK_ei | SK_er | SK_pi | SK_pr } = prf+
1754 // (SKEYSEED, Ni | Nr | SPIi | SPIr )
1756 Fragments
[0].Data
= IkeSaSession
->NiBlock
;
1757 Fragments
[0].DataSize
= IkeSaSession
->NiBlkSize
;
1758 Fragments
[1].Data
= IkeSaSession
->NrBlock
;
1759 Fragments
[1].DataSize
= IkeSaSession
->NrBlkSize
;
1760 InitiatorCookieNet
= HTONLL (IkeSaSession
->InitiatorCookie
);
1761 ResponderCookieNet
= HTONLL (IkeSaSession
->ResponderCookie
);
1762 Fragments
[2].Data
= (UINT8
*)(&InitiatorCookieNet
);
1763 Fragments
[2].DataSize
= sizeof (IkeSaSession
->InitiatorCookie
);
1764 Fragments
[3].Data
= (UINT8
*)(&ResponderCookieNet
);
1765 Fragments
[3].DataSize
= sizeof (IkeSaSession
->ResponderCookie
);
1767 IPSEC_DUMP_BUF (">>> NiBlock", IkeSaSession
->NiBlock
, IkeSaSession
->NiBlkSize
);
1768 IPSEC_DUMP_BUF (">>> NrBlock", IkeSaSession
->NrBlock
, IkeSaSession
->NrBlkSize
);
1769 IPSEC_DUMP_BUF (">>> InitiatorCookie", (UINT8
*)&IkeSaSession
->InitiatorCookie
, sizeof(UINT64
));
1770 IPSEC_DUMP_BUF (">>> ResponderCookie", (UINT8
*)&IkeSaSession
->ResponderCookie
, sizeof(UINT64
));
1772 OutputKeyLength
= PrfAlgKeyLen
+
1773 2 * EncryptAlgKeyLen
+
1775 2 * IntegrityAlgKeyLen
;
1776 OutputKey
= AllocateZeroPool (OutputKeyLength
);
1777 if (OutputKey
== NULL
) {
1778 Status
= EFI_OUT_OF_RESOURCES
;
1783 // Generate Seven Keymates.
1785 Status
= Ikev2SaGenerateKey (
1786 (UINT8
)SaParams
->Prf
,
1794 if (EFI_ERROR(Status
)) {
1799 // Save the seven keys into KeySession.
1802 IkeSaSession
->IkeKeys
->SkdKey
= AllocateZeroPool (PrfAlgKeyLen
);
1803 if (IkeSaSession
->IkeKeys
->SkdKey
== NULL
) {
1804 Status
= EFI_OUT_OF_RESOURCES
;
1807 IkeSaSession
->IkeKeys
->SkdKeySize
= PrfAlgKeyLen
;
1808 CopyMem (IkeSaSession
->IkeKeys
->SkdKey
, OutputKey
, PrfAlgKeyLen
);
1810 IPSEC_DUMP_BUF (">>> SK_D Key", IkeSaSession
->IkeKeys
->SkdKey
, PrfAlgKeyLen
);
1815 IkeSaSession
->IkeKeys
->SkAiKey
= AllocateZeroPool (IntegrityAlgKeyLen
);
1816 if (IkeSaSession
->IkeKeys
->SkAiKey
== NULL
) {
1817 Status
= EFI_OUT_OF_RESOURCES
;
1820 IkeSaSession
->IkeKeys
->SkAiKeySize
= IntegrityAlgKeyLen
;
1821 CopyMem (IkeSaSession
->IkeKeys
->SkAiKey
, OutputKey
+ PrfAlgKeyLen
, IntegrityAlgKeyLen
);
1823 IPSEC_DUMP_BUF (">>> SK_Ai Key", IkeSaSession
->IkeKeys
->SkAiKey
, IkeSaSession
->IkeKeys
->SkAiKeySize
);
1828 IkeSaSession
->IkeKeys
->SkArKey
= AllocateZeroPool (IntegrityAlgKeyLen
);
1829 if (IkeSaSession
->IkeKeys
->SkArKey
== NULL
) {
1830 Status
= EFI_OUT_OF_RESOURCES
;
1833 IkeSaSession
->IkeKeys
->SkArKeySize
= IntegrityAlgKeyLen
;
1835 IkeSaSession
->IkeKeys
->SkArKey
,
1836 OutputKey
+ PrfAlgKeyLen
+ IntegrityAlgKeyLen
,
1840 IPSEC_DUMP_BUF (">>> SK_Ar Key", IkeSaSession
->IkeKeys
->SkArKey
, IkeSaSession
->IkeKeys
->SkArKeySize
);
1845 IkeSaSession
->IkeKeys
->SkEiKey
= AllocateZeroPool (EncryptAlgKeyLen
);
1846 if (IkeSaSession
->IkeKeys
->SkEiKey
== NULL
) {
1847 Status
= EFI_OUT_OF_RESOURCES
;
1850 IkeSaSession
->IkeKeys
->SkEiKeySize
= EncryptAlgKeyLen
;
1853 IkeSaSession
->IkeKeys
->SkEiKey
,
1854 OutputKey
+ AuthAlgKeyLen
+ 2 * IntegrityAlgKeyLen
,
1859 OutputKey
+ AuthAlgKeyLen
+ 2 * IntegrityAlgKeyLen
,
1866 IkeSaSession
->IkeKeys
->SkErKey
= AllocateZeroPool (EncryptAlgKeyLen
);
1867 if (IkeSaSession
->IkeKeys
->SkErKey
== NULL
) {
1868 Status
= EFI_OUT_OF_RESOURCES
;
1871 IkeSaSession
->IkeKeys
->SkErKeySize
= EncryptAlgKeyLen
;
1874 IkeSaSession
->IkeKeys
->SkErKey
,
1875 OutputKey
+ AuthAlgKeyLen
+ 2 * IntegrityAlgKeyLen
+ EncryptAlgKeyLen
,
1880 OutputKey
+ AuthAlgKeyLen
+ 2 * IntegrityAlgKeyLen
+ EncryptAlgKeyLen
,
1887 IkeSaSession
->IkeKeys
->SkPiKey
= AllocateZeroPool (AuthAlgKeyLen
);
1888 if (IkeSaSession
->IkeKeys
->SkPiKey
== NULL
) {
1889 Status
= EFI_OUT_OF_RESOURCES
;
1892 IkeSaSession
->IkeKeys
->SkPiKeySize
= AuthAlgKeyLen
;
1895 IkeSaSession
->IkeKeys
->SkPiKey
,
1896 OutputKey
+ AuthAlgKeyLen
+ 2 * IntegrityAlgKeyLen
+ 2 * EncryptAlgKeyLen
,
1901 OutputKey
+ AuthAlgKeyLen
+ 2 * IntegrityAlgKeyLen
+ 2 * EncryptAlgKeyLen
,
1908 IkeSaSession
->IkeKeys
->SkPrKey
= AllocateZeroPool (AuthAlgKeyLen
);
1909 if (IkeSaSession
->IkeKeys
->SkPrKey
== NULL
) {
1910 Status
= EFI_OUT_OF_RESOURCES
;
1913 IkeSaSession
->IkeKeys
->SkPrKeySize
= AuthAlgKeyLen
;
1916 IkeSaSession
->IkeKeys
->SkPrKey
,
1917 OutputKey
+ AuthAlgKeyLen
+ 2 * IntegrityAlgKeyLen
+ 2 * EncryptAlgKeyLen
+ AuthAlgKeyLen
,
1922 OutputKey
+ AuthAlgKeyLen
+ 2 * IntegrityAlgKeyLen
+ 2 * EncryptAlgKeyLen
+ AuthAlgKeyLen
,
1928 if (Digest
!= NULL
) {
1931 if (KeyBuffer
!= NULL
) {
1932 FreePool (KeyBuffer
);
1934 if (OutputKey
!= NULL
) {
1935 FreePool (OutputKey
);
1938 if (EFI_ERROR(Status
)) {
1939 if (IkeSaSession
->IkeKeys
->SkdKey
!= NULL
) {
1940 FreePool (IkeSaSession
->IkeKeys
->SkdKey
);
1942 if (IkeSaSession
->IkeKeys
->SkAiKey
!= NULL
) {
1943 FreePool (IkeSaSession
->IkeKeys
->SkAiKey
);
1945 if (IkeSaSession
->IkeKeys
->SkArKey
!= NULL
) {
1946 FreePool (IkeSaSession
->IkeKeys
->SkArKey
);
1948 if (IkeSaSession
->IkeKeys
->SkEiKey
!= NULL
) {
1949 FreePool (IkeSaSession
->IkeKeys
->SkEiKey
);
1951 if (IkeSaSession
->IkeKeys
->SkErKey
!= NULL
) {
1952 FreePool (IkeSaSession
->IkeKeys
->SkErKey
);
1954 if (IkeSaSession
->IkeKeys
->SkPiKey
!= NULL
) {
1955 FreePool (IkeSaSession
->IkeKeys
->SkPiKey
);
1957 if (IkeSaSession
->IkeKeys
->SkPrKey
!= NULL
) {
1958 FreePool (IkeSaSession
->IkeKeys
->SkPrKey
);
1967 Generates the Keys for the furthure IPsec Protocol.
1969 @param[in] ChildSaSession Pointer to IKE Child SA Session.
1970 @param[in] KePayload Pointer to Key payload used to generate the Key.
1972 @retval EFI_UNSUPPORTED If one or more Algorithm Id is not supported.
1973 @retval EFI_SUCCESS The operation succeeded.
1977 Ikev2GenerateChildSaKeys (
1978 IN IKEV2_CHILD_SA_SESSION
*ChildSaSession
,
1979 IN IKE_PAYLOAD
*KePayload
1983 IKEV2_SA_PARAMS
*SaParams
;
1984 PRF_DATA_FRAGMENT Fragments
[3];
1985 UINTN EncryptAlgKeyLen
;
1986 UINTN IntegrityAlgKeyLen
;
1988 UINTN OutputKeyLength
;
1990 Status
= EFI_SUCCESS
;
1993 if (KePayload
!= NULL
) {
1997 Status
= Ikev2GenerateSaDhComputeKey (ChildSaSession
->DhBuffer
, KePayload
);
1998 if (EFI_ERROR (Status
)) {
2002 Fragments
[0].Data
= ChildSaSession
->DhBuffer
->GxyBuffer
;
2003 Fragments
[0].DataSize
= ChildSaSession
->DhBuffer
->GxySize
;
2006 Fragments
[1].Data
= ChildSaSession
->NiBlock
;
2007 Fragments
[1].DataSize
= ChildSaSession
->NiBlkSize
;
2008 Fragments
[2].Data
= ChildSaSession
->NrBlock
;
2009 Fragments
[2].DataSize
= ChildSaSession
->NrBlkSize
;
2012 // Get the key length of Authenticaion, Encryption, PRF, and Integrity.
2014 SaParams
= ChildSaSession
->SessionCommon
.SaParams
;
2015 EncryptAlgKeyLen
= IpSecGetEncryptKeyLength ((UINT8
)SaParams
->EncAlgId
);
2016 IntegrityAlgKeyLen
= IpSecGetHmacDigestLength ((UINT8
)SaParams
->IntegAlgId
);
2017 OutputKeyLength
= 2 * EncryptAlgKeyLen
+ 2 * IntegrityAlgKeyLen
;
2019 if ((EncryptAlgKeyLen
== 0) || (IntegrityAlgKeyLen
== 0)) {
2020 Status
= EFI_UNSUPPORTED
;
2026 // If KePayload is not NULL, calculate KEYMAT = prf+(SK_d, g^ir (new) | Ni | Nr ),
2027 // otherwise, KEYMAT = prf+(SK_d, Ni | Nr )
2029 OutputKey
= AllocateZeroPool (OutputKeyLength
);
2030 if (OutputKey
== NULL
) {
2031 Status
= EFI_OUT_OF_RESOURCES
;
2036 // Derive Key from the SkdKey Buffer.
2038 Status
= Ikev2SaGenerateKey (
2039 (UINT8
)ChildSaSession
->IkeSaSession
->SessionCommon
.SaParams
->Prf
,
2040 ChildSaSession
->IkeSaSession
->IkeKeys
->SkdKey
,
2041 ChildSaSession
->IkeSaSession
->IkeKeys
->SkdKeySize
,
2044 KePayload
== NULL
? &Fragments
[1] : Fragments
,
2045 KePayload
== NULL
? 2 : 3
2048 if (EFI_ERROR (Status
)) {
2053 // Copy KEYMATE (SK_ENCRYPT_i | SK_ENCRYPT_r | SK_INTEG_i | SK_INTEG_r) to
2056 if (!ChildSaSession
->SessionCommon
.IsInitiator
) {
2059 // Initiator Encryption Key
2061 ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.EncAlgoId
= (UINT8
)SaParams
->EncAlgId
;
2062 ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.EncKeyLength
= EncryptAlgKeyLen
;
2063 ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.EncKey
= AllocateZeroPool (EncryptAlgKeyLen
);
2064 if (ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.EncKey
== NULL
) {
2065 Status
= EFI_OUT_OF_RESOURCES
;
2070 ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.EncKey
,
2076 // Initiator Authentication Key
2078 ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.AuthAlgoId
= (UINT8
)SaParams
->IntegAlgId
;
2079 ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.AuthKeyLength
= IntegrityAlgKeyLen
;
2080 ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.AuthKey
= AllocateZeroPool (IntegrityAlgKeyLen
);
2081 if (ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.AuthKey
== NULL
) {
2082 Status
= EFI_OUT_OF_RESOURCES
;
2087 ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.AuthKey
,
2088 OutputKey
+ EncryptAlgKeyLen
,
2093 // Responder Encrypt Key
2095 ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.EncAlgoId
= (UINT8
)SaParams
->EncAlgId
;
2096 ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.EncKeyLength
= EncryptAlgKeyLen
;
2097 ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.EncKey
= AllocateZeroPool (EncryptAlgKeyLen
);
2098 if (ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.EncKey
== NULL
) {
2099 Status
= EFI_OUT_OF_RESOURCES
;
2104 ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.EncKey
,
2105 OutputKey
+ EncryptAlgKeyLen
+ IntegrityAlgKeyLen
,
2110 // Responder Authentication Key
2112 ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.AuthAlgoId
= (UINT8
)SaParams
->IntegAlgId
;
2113 ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.AuthKeyLength
= IntegrityAlgKeyLen
;
2114 ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.AuthKey
= AllocateZeroPool (IntegrityAlgKeyLen
);
2115 if (ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.AuthKey
== NULL
) {
2116 Status
= EFI_OUT_OF_RESOURCES
;
2121 ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.AuthKey
,
2122 OutputKey
+ 2 * EncryptAlgKeyLen
+ IntegrityAlgKeyLen
,
2127 // Initiator Encryption Key
2129 ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.EncAlgoId
= (UINT8
)SaParams
->EncAlgId
;
2130 ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.EncKeyLength
= EncryptAlgKeyLen
;
2131 ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.EncKey
= AllocateZeroPool (EncryptAlgKeyLen
);
2132 if (ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.EncKey
== NULL
) {
2133 Status
= EFI_OUT_OF_RESOURCES
;
2138 ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.EncKey
,
2144 // Initiator Authentication Key
2146 ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.AuthAlgoId
= (UINT8
)SaParams
->IntegAlgId
;
2147 ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.AuthKeyLength
= IntegrityAlgKeyLen
;
2148 ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.AuthKey
= AllocateZeroPool (IntegrityAlgKeyLen
);
2149 if (ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.AuthKey
== NULL
) {
2150 Status
= EFI_OUT_OF_RESOURCES
;
2155 ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.AuthKey
,
2156 OutputKey
+ EncryptAlgKeyLen
,
2161 // Responder Encryption Key
2163 ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.EncAlgoId
= (UINT8
)SaParams
->EncAlgId
;
2164 ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.EncKeyLength
= EncryptAlgKeyLen
;
2165 ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.EncKey
= AllocateZeroPool (EncryptAlgKeyLen
);
2166 if (ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.EncKey
== NULL
) {
2167 Status
= EFI_OUT_OF_RESOURCES
;
2172 ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.EncKey
,
2173 OutputKey
+ EncryptAlgKeyLen
+ IntegrityAlgKeyLen
,
2178 // Responder Authentication Key
2180 ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.AuthAlgoId
= (UINT8
)SaParams
->IntegAlgId
;
2181 ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.AuthKeyLength
= IntegrityAlgKeyLen
;
2182 ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.AuthKey
= AllocateZeroPool (IntegrityAlgKeyLen
);
2183 if (ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.AuthKey
== NULL
) {
2184 Status
= EFI_OUT_OF_RESOURCES
;
2189 ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.AuthKey
,
2190 OutputKey
+ 2 * EncryptAlgKeyLen
+ IntegrityAlgKeyLen
,
2196 " >>> Local Encryption Key",
2197 ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.EncKey
,
2201 " >>> Remote Encryption Key",
2202 ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.EncKey
,
2206 " >>> Local Authentication Key",
2207 ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.AuthKey
,
2211 " >>> Remote Authentication Key",
2212 ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.AuthKey
,
2219 if (EFI_ERROR (Status
)) {
2220 if (ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.EncKey
!= NULL
) {
2221 FreePool (ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.EncKey
);
2223 if (ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.AuthKey
!= NULL
) {
2224 FreePool (ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.AuthKey
);
2226 if (ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.EncKey
!= NULL
) {
2227 FreePool (ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.EncKey
);
2229 if (ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.AuthKey
!= NULL
) {
2230 FreePool (ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.AuthKey
);
2234 if (OutputKey
!= NULL
) {
2235 FreePool (OutputKey
);
2241 GLOBAL_REMOVE_IF_UNREFERENCED IKEV2_PACKET_HANDLER mIkev2Initial
[][2] = {
2245 Ikev2InitPskGenerator
2249 Ikev2AuthPskGenerator
2254 Ikev2InitCertParser
,
2255 Ikev2InitCertGenerator
2258 Ikev2AuthCertParser
,
2259 Ikev2AuthCertGenerator