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 SPDX-License-Identifier: BSD-2-Clause-Patent
12 #include "IpSecDebug.h"
13 #include "IkeService.h"
19 This generates the DH local public key and store it in the IKEv2 SA Session's GxBuffer.
21 @param[in] IkeSaSession Pointer to related IKE SA Session.
23 @retval EFI_SUCCESS The operation succeeded.
24 @retval Others The operation failed.
28 Ikev2GenerateSaDhPublicKey (
29 IN IKEV2_SA_SESSION
*IkeSaSession
33 Generates the IKEv2 SA key for the furthure IKEv2 exchange.
35 @param[in] IkeSaSession Pointer to IKEv2 SA Session.
36 @param[in] KePayload Pointer to Key payload used to generate the Key.
38 @retval EFI_UNSUPPORTED If the Algorithm Id is not supported.
39 @retval EFI_SUCCESS The operation succeeded.
44 IN IKEV2_SA_SESSION
*IkeSaSession
,
45 IN IKE_PAYLOAD
*KePayload
49 Generates the Keys for the furthure IPsec Protocol.
51 @param[in] ChildSaSession Pointer to IKE Child SA Session.
52 @param[in] KePayload Pointer to Key payload used to generate the Key.
54 @retval EFI_UNSUPPORTED If one or more Algorithm Id is unsupported.
55 @retval EFI_SUCCESS The operation succeeded.
59 Ikev2GenerateChildSaKeys (
60 IN IKEV2_CHILD_SA_SESSION
*ChildSaSession
,
61 IN IKE_PAYLOAD
*KePayload
65 Gernerates IKEv2 packet for IKE_SA_INIT exchange.
67 @param[in] SaSession Pointer to IKEV2_SA_SESSION related to the exchange.
68 @param[in] Context Context Data passed by caller.
70 @retval EFI_SUCCESS The IKEv2 packet generation succeeded.
71 @retval Others The IKEv2 packet generation failed.
75 Ikev2InitPskGenerator (
80 IKE_PACKET
*IkePacket
;
81 IKEV2_SA_SESSION
*IkeSaSession
;
82 IKE_PAYLOAD
*SaPayload
;
83 IKE_PAYLOAD
*KePayload
;
84 IKE_PAYLOAD
*NoncePayload
;
85 IKE_PAYLOAD
*NotifyPayload
;
93 IkeSaSession
= (IKEV2_SA_SESSION
*) SaSession
;
96 // 1. Allocate IKE packet
98 IkePacket
= IkePacketAlloc ();
99 if (IkePacket
== NULL
) {
104 // 1.a Fill the IkePacket->Hdr
106 IkePacket
->Header
->ExchangeType
= IKEV2_EXCHANGE_TYPE_INIT
;
107 IkePacket
->Header
->InitiatorCookie
= IkeSaSession
->InitiatorCookie
;
108 IkePacket
->Header
->ResponderCookie
= IkeSaSession
->ResponderCookie
;
109 IkePacket
->Header
->Version
= (UINT8
) (2 << 4);
110 IkePacket
->Header
->MessageId
= 0;
112 if (IkeSaSession
->SessionCommon
.IsInitiator
) {
113 IkePacket
->Header
->Flags
= IKE_HEADER_FLAGS_INIT
;
115 IkePacket
->Header
->Flags
= IKE_HEADER_FLAGS_RESPOND
;
119 // If the NCookie is not NULL, this IKE_SA_INIT packet is resent by the NCookie
120 // and the NCookie payload should be the first payload in this packet.
122 if (IkeSaSession
->NCookie
!= NULL
) {
123 IkePacket
->Header
->NextPayload
= IKEV2_PAYLOAD_TYPE_NOTIFY
;
124 NotifyPayload
= Ikev2GenerateNotifyPayload (
126 IKEV2_PAYLOAD_TYPE_SA
,
128 IKEV2_NOTIFICATION_COOKIE
,
130 IkeSaSession
->NCookie
,
131 IkeSaSession
->NCookieSize
134 IkePacket
->Header
->NextPayload
= IKEV2_PAYLOAD_TYPE_SA
;
138 // 2. Generate SA Payload according to the SaData & SaParams
140 SaPayload
= Ikev2GenerateSaPayload (
141 IkeSaSession
->SaData
,
142 IKEV2_PAYLOAD_TYPE_KE
,
147 // 3. Generate DH public key.
148 // The DhPrivate Key has been generated in Ikev2InitPskParser, if the
149 // IkeSaSession is responder. If resending IKE_SA_INIT with Cookie Notify
150 // No need to recompute the Public key.
152 if ((IkeSaSession
->SessionCommon
.IsInitiator
) && (IkeSaSession
->NCookie
== NULL
)) {
153 Status
= Ikev2GenerateSaDhPublicKey (IkeSaSession
);
154 if (EFI_ERROR (Status
)) {
160 // 4. Generate KE Payload according to SaParams->DhGroup
162 KePayload
= Ikev2GenerateKePayload (
164 IKEV2_PAYLOAD_TYPE_NONCE
168 // 5. Generate Nonce Payload
169 // If resending IKE_SA_INIT with Cookie Notify paylaod, no need to regenerate
170 // the Nonce Payload.
172 if ((IkeSaSession
->SessionCommon
.IsInitiator
) && (IkeSaSession
->NCookie
== NULL
)) {
173 IkeSaSession
->NiBlkSize
= IKE_NONCE_SIZE
;
174 IkeSaSession
->NiBlock
= IkeGenerateNonce (IKE_NONCE_SIZE
);
175 if (IkeSaSession
->NiBlock
== NULL
) {
180 if (IkeSaSession
->SessionCommon
.IsInitiator
) {
181 NoncePayload
= Ikev2GenerateNoncePayload (
182 IkeSaSession
->NiBlock
,
183 IkeSaSession
->NiBlkSize
,
184 IKEV2_PAYLOAD_TYPE_NONE
188 // The Nonce Payload has been created in Ikev2PskParser if the IkeSaSession is
191 NoncePayload
= Ikev2GenerateNoncePayload (
192 IkeSaSession
->NrBlock
,
193 IkeSaSession
->NrBlkSize
,
194 IKEV2_PAYLOAD_TYPE_NONE
198 if (NotifyPayload
!= NULL
) {
199 IKE_PACKET_APPEND_PAYLOAD (IkePacket
, NotifyPayload
);
201 if (SaPayload
!= NULL
) {
202 IKE_PACKET_APPEND_PAYLOAD (IkePacket
, SaPayload
);
204 if (KePayload
!= NULL
) {
205 IKE_PACKET_APPEND_PAYLOAD (IkePacket
, KePayload
);
207 if (NoncePayload
!= NULL
) {
208 IKE_PACKET_APPEND_PAYLOAD (IkePacket
, NoncePayload
);
214 if (IkePacket
!= NULL
) {
215 IkePacketFree (IkePacket
);
217 if (SaPayload
!= NULL
) {
218 IkePayloadFree (SaPayload
);
224 Parses the IKEv2 packet for IKE_SA_INIT exchange.
226 @param[in] SaSession Pointer to IKEV2_SA_SESSION related to the exchange.
227 @param[in] IkePacket The received IKE packet to be parsed.
229 @retval EFI_SUCCESS The IKEv2 packet is acceptable and the relative data is
230 saved for furthure communication.
231 @retval EFI_INVALID_PARAMETER The IKEv2 packet is malformed or the SA proposal is unacceptable.
237 IN IKE_PACKET
*IkePacket
240 IKEV2_SA_SESSION
*IkeSaSession
;
241 IKE_PAYLOAD
*SaPayload
;
242 IKE_PAYLOAD
*KeyPayload
;
243 IKE_PAYLOAD
*IkePayload
;
244 IKE_PAYLOAD
*NoncePayload
;
245 IKE_PAYLOAD
*NotifyPayload
;
251 IkeSaSession
= (IKEV2_SA_SESSION
*) SaSession
;
256 NotifyPayload
= NULL
;
259 // Iterate payloads to find the SaPayload and KeyPayload.
261 NET_LIST_FOR_EACH (Entry
, &(IkePacket
)->PayloadList
) {
262 IkePayload
= IKE_PAYLOAD_BY_PACKET (Entry
);
263 if (IkePayload
->PayloadType
== IKEV2_PAYLOAD_TYPE_SA
) {
264 SaPayload
= IkePayload
;
266 if (IkePayload
->PayloadType
== IKEV2_PAYLOAD_TYPE_KE
) {
267 KeyPayload
= IkePayload
;
269 if (IkePayload
->PayloadType
== IKEV2_PAYLOAD_TYPE_NONCE
) {
270 NoncePayload
= IkePayload
;
272 if (IkePayload
->PayloadType
== IKEV2_PAYLOAD_TYPE_NOTIFY
) {
273 NotifyPayload
= IkePayload
;
278 // According to RFC 4306 - 2.6. If the responder responds with the COOKIE Notify
279 // payload with the cookie data, initiator MUST retry the IKE_SA_INIT with a
280 // Notify payload of type COOKIE containing the responder suppplied cookie data
281 // as first payload and all other payloads unchanged.
283 if (IkeSaSession
->SessionCommon
.IsInitiator
) {
284 if (NotifyPayload
!= NULL
&& !EFI_ERROR(Ikev2ParserNotifyCookiePayload (NotifyPayload
, IkeSaSession
))) {
289 if ((KeyPayload
== NULL
) || (SaPayload
== NULL
) || (NoncePayload
== NULL
)) {
290 return EFI_INVALID_PARAMETER
;
294 // Store NoncePayload for SKEYID computing.
296 NonceSize
= NoncePayload
->PayloadSize
- sizeof (IKEV2_COMMON_PAYLOAD_HEADER
);
297 NonceBuffer
= (UINT8
*) AllocatePool (NonceSize
);
298 if (NonceBuffer
== NULL
) {
299 Status
= EFI_OUT_OF_RESOURCES
;
305 NoncePayload
->PayloadBuf
+ sizeof (IKEV2_COMMON_PAYLOAD_HEADER
),
310 // Check if IkePacket Header matches the state
312 if (IkeSaSession
->SessionCommon
.IsInitiator
) {
314 // 1. Check the IkePacket->Hdr == IKE_HEADER_FLAGS_RESPOND
316 if (IkePacket
->Header
->Flags
!= IKE_HEADER_FLAGS_RESPOND
) {
317 Status
= EFI_INVALID_PARAMETER
;
322 // 2. Parse the SA Payload and Key Payload to find out the cryptographic
323 // suite and fill in the Sa paramse into CommonSession->SaParams
325 if (!Ikev2SaParseSaPayload (IkeSaSession
, SaPayload
, IkePacket
->Header
->Flags
)) {
326 Status
= EFI_INVALID_PARAMETER
;
331 // 3. If Initiator, the NoncePayload is Nr_b.
333 IKEV2_DUMP_STATE (IkeSaSession
->SessionCommon
.State
, IkeStateAuth
);
334 IkeSaSession
->NrBlock
= NonceBuffer
;
335 IkeSaSession
->NrBlkSize
= NonceSize
;
336 IkeSaSession
->SessionCommon
.State
= IkeStateAuth
;
337 IkeSaSession
->ResponderCookie
= IkePacket
->Header
->ResponderCookie
;
340 // 4. Change the state of IkeSaSession
342 IkeSaSession
->SessionCommon
.State
= IkeStateAuth
;
345 // 1. Check the IkePacket->Hdr == IKE_HEADER_FLAGS_INIT
347 if (IkePacket
->Header
->Flags
!= IKE_HEADER_FLAGS_INIT
) {
348 Status
= EFI_INVALID_PARAMETER
;
353 // 2. Parse the SA payload and find out the perfered one
354 // and fill in the SA parameters into CommonSession->SaParams and SaData into
355 // IkeSaSession for the responder SA payload generation.
357 if (!Ikev2SaParseSaPayload (IkeSaSession
, SaPayload
, IkePacket
->Header
->Flags
)) {
358 Status
= EFI_INVALID_PARAMETER
;
363 // 3. Generat Dh Y parivate Key
365 Status
= Ikev2GenerateSaDhPublicKey (IkeSaSession
);
366 if (EFI_ERROR (Status
)) {
371 // 4. If Responder, the NoncePayload is Ni_b and go to generate Nr_b.
373 IkeSaSession
->NiBlock
= NonceBuffer
;
374 IkeSaSession
->NiBlkSize
= NonceSize
;
379 IkeSaSession
->NrBlock
= IkeGenerateNonce (IKE_NONCE_SIZE
);
380 ASSERT (IkeSaSession
->NrBlock
!= NULL
);
381 IkeSaSession
->NrBlkSize
= IKE_NONCE_SIZE
;
384 // 6. Save the Cookies
386 IkeSaSession
->InitiatorCookie
= IkePacket
->Header
->InitiatorCookie
;
387 IkeSaSession
->ResponderCookie
= IkeGenerateCookie ();
390 if (IkeSaSession
->SessionCommon
.PreferDhGroup
!= ((IKEV2_KEY_EXCHANGE
*)KeyPayload
->PayloadBuf
)->DhGroup
) {
391 Status
= EFI_INVALID_PARAMETER
;
395 // Call Ikev2GenerateSaKeys to create SKEYID, SKEYID_d, SKEYID_a, SKEYID_e.
397 Status
= Ikev2GenerateSaKeys (IkeSaSession
, KeyPayload
);
398 if (EFI_ERROR(Status
)) {
404 if (NonceBuffer
!= NULL
) {
405 FreePool (NonceBuffer
);
412 Generates the IKEv2 packet for IKE_AUTH exchange.
414 @param[in] SaSession Pointer to IKEV2_SA_SESSION.
415 @param[in] Context Context data passed by caller.
417 @retval Pointer to IKE Packet to be sent out.
421 Ikev2AuthPskGenerator (
426 IKE_PACKET
*IkePacket
;
427 IKEV2_SA_SESSION
*IkeSaSession
;
428 IKE_PAYLOAD
*IdPayload
;
429 IKE_PAYLOAD
*AuthPayload
;
430 IKE_PAYLOAD
*SaPayload
;
431 IKE_PAYLOAD
*TsiPayload
;
432 IKE_PAYLOAD
*TsrPayload
;
433 IKE_PAYLOAD
*NotifyPayload
;
434 IKE_PAYLOAD
*CpPayload
;
435 IKEV2_CHILD_SA_SESSION
*ChildSaSession
;
438 IkeSaSession
= (IKEV2_SA_SESSION
*) SaSession
;
439 ChildSaSession
= IKEV2_CHILD_SA_SESSION_BY_IKE_SA (GetFirstNode (&IkeSaSession
->ChildSaSessionList
));
447 NotifyPayload
= NULL
;
449 NotifyPayload
= NULL
;
452 // 1. Allocate IKE Packet
454 IkePacket
= IkePacketAlloc ();
455 if (IkePacket
== NULL
) {
460 // 1.a Fill the IkePacket Header.
462 IkePacket
->Header
->ExchangeType
= IKEV2_EXCHANGE_TYPE_AUTH
;
463 IkePacket
->Header
->InitiatorCookie
= IkeSaSession
->InitiatorCookie
;
464 IkePacket
->Header
->ResponderCookie
= IkeSaSession
->ResponderCookie
;
465 IkePacket
->Header
->Version
= (UINT8
)(2 << 4);
466 if (ChildSaSession
->SessionCommon
.IsInitiator
) {
467 IkePacket
->Header
->NextPayload
= IKEV2_PAYLOAD_TYPE_ID_INIT
;
469 IkePacket
->Header
->NextPayload
= IKEV2_PAYLOAD_TYPE_ID_RSP
;
473 // According to RFC4306_2.2, For the IKE_SA_INIT message the MessageID should
474 // be always number 0 and 1;
476 IkePacket
->Header
->MessageId
= 1;
478 if (IkeSaSession
->SessionCommon
.IsInitiator
) {
479 IkePacket
->Header
->Flags
= IKE_HEADER_FLAGS_INIT
;
481 IkePacket
->Header
->Flags
= IKE_HEADER_FLAGS_RESPOND
;
485 // 2. Generate ID Payload according to IP version and address.
487 IdPayload
= Ikev2GenerateIdPayload (
488 &IkeSaSession
->SessionCommon
,
489 IKEV2_PAYLOAD_TYPE_AUTH
491 if (IdPayload
== NULL
) {
496 // 3. Generate Auth Payload
497 // If it is tunnel mode, should create the configuration payload after the
500 if (IkeSaSession
->Spd
->Data
->ProcessingPolicy
->Mode
== EfiIPsecTransport
) {
502 AuthPayload
= Ikev2PskGenerateAuthPayload (
503 ChildSaSession
->IkeSaSession
,
505 IKEV2_PAYLOAD_TYPE_SA
,
509 AuthPayload
= Ikev2PskGenerateAuthPayload (
510 ChildSaSession
->IkeSaSession
,
512 IKEV2_PAYLOAD_TYPE_CP
,
515 if (IkeSaSession
->SessionCommon
.UdpService
->IpVersion
== IP_VERSION_4
) {
516 CpPayload
= Ikev2GenerateCpPayload (
517 ChildSaSession
->IkeSaSession
,
518 IKEV2_PAYLOAD_TYPE_SA
,
519 IKEV2_CFG_ATTR_INTERNAL_IP4_ADDRESS
522 CpPayload
= Ikev2GenerateCpPayload (
523 ChildSaSession
->IkeSaSession
,
524 IKEV2_PAYLOAD_TYPE_SA
,
525 IKEV2_CFG_ATTR_INTERNAL_IP6_ADDRESS
529 if (CpPayload
== NULL
) {
534 if (AuthPayload
== NULL
) {
539 // 4. Generate SA Payload according to the SA Data in ChildSaSession
541 SaPayload
= Ikev2GenerateSaPayload (
542 ChildSaSession
->SaData
,
543 IKEV2_PAYLOAD_TYPE_TS_INIT
,
544 IkeSessionTypeChildSa
546 if (SaPayload
== NULL
) {
550 if (IkeSaSession
->Spd
->Data
->ProcessingPolicy
->Mode
== EfiIPsecTransport
) {
552 // Generate Tsi and Tsr.
554 TsiPayload
= Ikev2GenerateTsPayload (
556 IKEV2_PAYLOAD_TYPE_TS_RSP
,
560 TsrPayload
= Ikev2GenerateTsPayload (
562 IKEV2_PAYLOAD_TYPE_NOTIFY
,
567 // Generate Notify Payload. If transport mode, there should have Notify
568 // payload with TRANSPORT_MODE notification.
570 NotifyPayload
= Ikev2GenerateNotifyPayload (
572 IKEV2_PAYLOAD_TYPE_NONE
,
574 IKEV2_NOTIFICATION_USE_TRANSPORT_MODE
,
579 if (NotifyPayload
== NULL
) {
584 // Generate Tsr for Tunnel mode.
586 TsiPayload
= Ikev2GenerateTsPayload (
588 IKEV2_PAYLOAD_TYPE_TS_RSP
,
591 TsrPayload
= Ikev2GenerateTsPayload (
593 IKEV2_PAYLOAD_TYPE_NONE
,
598 if (TsiPayload
== NULL
|| TsrPayload
== NULL
) {
602 IKE_PACKET_APPEND_PAYLOAD (IkePacket
, IdPayload
);
603 IKE_PACKET_APPEND_PAYLOAD (IkePacket
, AuthPayload
);
604 if (IkeSaSession
->Spd
->Data
->ProcessingPolicy
->Mode
== EfiIPsecTunnel
) {
605 IKE_PACKET_APPEND_PAYLOAD (IkePacket
, CpPayload
);
607 IKE_PACKET_APPEND_PAYLOAD (IkePacket
, SaPayload
);
608 IKE_PACKET_APPEND_PAYLOAD (IkePacket
, TsiPayload
);
609 IKE_PACKET_APPEND_PAYLOAD (IkePacket
, TsrPayload
);
610 if (IkeSaSession
->Spd
->Data
->ProcessingPolicy
->Mode
== EfiIPsecTransport
) {
611 IKE_PACKET_APPEND_PAYLOAD (IkePacket
, NotifyPayload
);
617 if (IkePacket
!= NULL
) {
618 IkePacketFree (IkePacket
);
621 if (IdPayload
!= NULL
) {
622 IkePayloadFree (IdPayload
);
625 if (AuthPayload
!= NULL
) {
626 IkePayloadFree (AuthPayload
);
629 if (CpPayload
!= NULL
) {
630 IkePayloadFree (CpPayload
);
633 if (SaPayload
!= NULL
) {
634 IkePayloadFree (SaPayload
);
637 if (TsiPayload
!= NULL
) {
638 IkePayloadFree (TsiPayload
);
641 if (TsrPayload
!= NULL
) {
642 IkePayloadFree (TsrPayload
);
645 if (NotifyPayload
!= NULL
) {
646 IkePayloadFree (NotifyPayload
);
653 Parses IKE_AUTH packet.
655 @param[in] SaSession Pointer to the IKE_SA_SESSION related to this packet.
656 @param[in] IkePacket Pointer to the IKE_AUTH packet to be parsered.
658 @retval EFI_INVALID_PARAMETER The IKE packet is malformed or the SA
659 proposal is unacceptable.
660 @retval EFI_SUCCESS The IKE packet is acceptable and the
661 relative data is saved for furthure communication.
667 IN IKE_PACKET
*IkePacket
670 IKEV2_CHILD_SA_SESSION
*ChildSaSession
;
671 IKEV2_SA_SESSION
*IkeSaSession
;
672 IKE_PAYLOAD
*IkePayload
;
673 IKE_PAYLOAD
*SaPayload
;
674 IKE_PAYLOAD
*IdiPayload
;
675 IKE_PAYLOAD
*IdrPayload
;
676 IKE_PAYLOAD
*AuthPayload
;
677 IKE_PAYLOAD
*TsiPayload
;
678 IKE_PAYLOAD
*TsrPayload
;
679 IKE_PAYLOAD
*VerifiedAuthPayload
;
683 IkeSaSession
= (IKEV2_SA_SESSION
*) SaSession
;
684 ChildSaSession
= IKEV2_CHILD_SA_SESSION_BY_IKE_SA (GetFirstNode (&IkeSaSession
->ChildSaSessionList
));
694 // Iterate payloads to find the SaPayload/ID/AUTH/TS Payload.
696 NET_LIST_FOR_EACH (Entry
, &(IkePacket
)->PayloadList
) {
697 IkePayload
= IKE_PAYLOAD_BY_PACKET (Entry
);
699 if (IkePayload
->PayloadType
== IKEV2_PAYLOAD_TYPE_ID_INIT
) {
700 IdiPayload
= IkePayload
;
702 if (IkePayload
->PayloadType
== IKEV2_PAYLOAD_TYPE_ID_RSP
) {
703 IdrPayload
= IkePayload
;
705 if (IkePayload
->PayloadType
== IKEV2_PAYLOAD_TYPE_SA
) {
706 SaPayload
= IkePayload
;
708 if (IkePayload
->PayloadType
== IKEV2_PAYLOAD_TYPE_AUTH
) {
709 AuthPayload
= IkePayload
;
711 if (IkePayload
->PayloadType
== IKEV2_PAYLOAD_TYPE_TS_INIT
) {
712 TsiPayload
= IkePayload
;
714 if (IkePayload
->PayloadType
== IKEV2_PAYLOAD_TYPE_TS_RSP
) {
715 TsrPayload
= IkePayload
;
719 if ((SaPayload
== NULL
) || (AuthPayload
== NULL
) || (TsiPayload
== NULL
) || (TsrPayload
== NULL
)) {
720 return EFI_INVALID_PARAMETER
;
722 if ((IdiPayload
== NULL
) && (IdrPayload
== NULL
)) {
723 return EFI_INVALID_PARAMETER
;
727 // Check IkePacket Header is match the state
729 if (IkeSaSession
->SessionCommon
.IsInitiator
) {
732 // 1. Check the IkePacket->Hdr == IKE_HEADER_FLAGS_RESPOND
734 if ((IkePacket
->Header
->Flags
!= IKE_HEADER_FLAGS_RESPOND
) ||
735 (IkePacket
->Header
->ExchangeType
!= IKEV2_EXCHANGE_TYPE_AUTH
)
737 return EFI_INVALID_PARAMETER
;
742 // 1. Check the IkePacket->Hdr == IKE_HEADER_FLAGS_INIT
744 if ((IkePacket
->Header
->Flags
!= IKE_HEADER_FLAGS_INIT
) ||
745 (IkePacket
->Header
->ExchangeType
!= IKEV2_EXCHANGE_TYPE_AUTH
)
747 return EFI_INVALID_PARAMETER
;
751 // 2. Parse the SA payload and Key Payload and find out the perferable one
752 // and fill in the Sa paramse into CommonSession->SaParams and SaData into
753 // IkeSaSession for the responder SA payload generation.
758 // Verify the Auth Payload.
760 VerifiedAuthPayload
= Ikev2PskGenerateAuthPayload (
762 IkeSaSession
->SessionCommon
.IsInitiator
? IdrPayload
: IdiPayload
,
763 IKEV2_PAYLOAD_TYPE_SA
,
766 if ((VerifiedAuthPayload
!= NULL
) &&
768 VerifiedAuthPayload
->PayloadBuf
+ sizeof (IKEV2_COMMON_PAYLOAD_HEADER
),
769 AuthPayload
->PayloadBuf
+ sizeof (IKEV2_COMMON_PAYLOAD_HEADER
),
770 VerifiedAuthPayload
->PayloadSize
- sizeof (IKEV2_COMMON_PAYLOAD_HEADER
)
772 return EFI_INVALID_PARAMETER
;
776 // 3. Parse the SA Payload to find out the cryptographic suite
777 // and fill in the Sa paramse into CommonSession->SaParams. If no acceptable
778 // porposal found, return EFI_INVALID_PARAMETER.
780 if (!Ikev2ChildSaParseSaPayload (ChildSaSession
, SaPayload
, IkePacket
->Header
->Flags
)) {
781 return EFI_INVALID_PARAMETER
;
785 // 4. Parse TSi, TSr payloads.
787 if ((((TRAFFIC_SELECTOR
*)(TsiPayload
->PayloadBuf
+ sizeof (IKEV2_TS
)))->IpProtocolId
!=
788 ((TRAFFIC_SELECTOR
*)(TsrPayload
->PayloadBuf
+ sizeof (IKEV2_TS
)))->IpProtocolId
) &&
789 (((TRAFFIC_SELECTOR
*)(TsiPayload
->PayloadBuf
+ sizeof (IKEV2_TS
)))->IpProtocolId
!= 0) &&
790 (((TRAFFIC_SELECTOR
*)(TsrPayload
->PayloadBuf
+ sizeof (IKEV2_TS
)))->IpProtocolId
!= 0)
792 return EFI_INVALID_PARAMETER
;
795 if (!IkeSaSession
->SessionCommon
.IsInitiator
) {
797 //TODO:check the Port range. Only support any port and one certain port here.
799 ChildSaSession
->ProtoId
= ((TRAFFIC_SELECTOR
*)(TsrPayload
->PayloadBuf
+ sizeof (IKEV2_TS
)))->IpProtocolId
;
800 ChildSaSession
->LocalPort
= ((TRAFFIC_SELECTOR
*)(TsrPayload
->PayloadBuf
+ sizeof (IKEV2_TS
)))->StartPort
;
801 ChildSaSession
->RemotePort
= ((TRAFFIC_SELECTOR
*)(TsiPayload
->PayloadBuf
+ sizeof (IKEV2_TS
)))->StartPort
;
803 // Association a SPD with this SA.
805 Status
= Ikev2ChildSaAssociateSpdEntry (ChildSaSession
);
806 if (EFI_ERROR (Status
)) {
807 return EFI_INVALID_PARAMETER
;
810 // Associate the IkeSaSession's SPD to the first ChildSaSession's SPD.
812 if (ChildSaSession
->IkeSaSession
->Spd
== NULL
) {
813 ChildSaSession
->IkeSaSession
->Spd
= ChildSaSession
->Spd
;
814 Status
= Ikev2ChildSaSessionSpdSelectorCreate (ChildSaSession
);
815 if (EFI_ERROR (Status
)) {
821 //TODO:check the Port range.
823 if ((((TRAFFIC_SELECTOR
*)(TsrPayload
->PayloadBuf
+ sizeof (IKEV2_TS
)))->StartPort
!= 0) &&
824 (((TRAFFIC_SELECTOR
*)(TsrPayload
->PayloadBuf
+ sizeof (IKEV2_TS
)))->StartPort
!= ChildSaSession
->RemotePort
)
826 return EFI_INVALID_PARAMETER
;
828 if ((((TRAFFIC_SELECTOR
*)(TsiPayload
->PayloadBuf
+ sizeof (IKEV2_TS
)))->StartPort
!= 0) &&
829 (((TRAFFIC_SELECTOR
*)(TsiPayload
->PayloadBuf
+ sizeof (IKEV2_TS
)))->StartPort
!= ChildSaSession
->LocalPort
)
831 return EFI_INVALID_PARAMETER
;
834 // For the tunnel mode, it should add the vitual IP address into the SA's SPD Selector.
836 if (ChildSaSession
->Spd
->Data
->ProcessingPolicy
->Mode
== EfiIPsecTunnel
) {
837 if (!ChildSaSession
->IkeSaSession
->SessionCommon
.IsInitiator
) {
839 // If it is tunnel mode, the UEFI part must be the initiator.
841 return EFI_INVALID_PARAMETER
;
844 // Get the Virtual IP address from the Tsi traffic selector.
845 // TODO: check the CFG reply payload
848 &ChildSaSession
->SpdSelector
->LocalAddress
[0].Address
,
849 TsiPayload
->PayloadBuf
+ sizeof (IKEV2_TS
) + sizeof (TRAFFIC_SELECTOR
),
850 (ChildSaSession
->SessionCommon
.UdpService
->IpVersion
== IP_VERSION_4
) ?
851 sizeof (EFI_IPv4_ADDRESS
) : sizeof (EFI_IPv6_ADDRESS
)
857 // 5. Generate keymats for IPsec protocol.
859 Status
= Ikev2GenerateChildSaKeys (ChildSaSession
, NULL
);
860 if (EFI_ERROR (Status
)) {
864 if (IkeSaSession
->SessionCommon
.IsInitiator
) {
866 // 6. Change the state of IkeSaSession
868 IKEV2_DUMP_STATE (IkeSaSession
->SessionCommon
.State
, IkeStateIkeSaEstablished
);
869 IkeSaSession
->SessionCommon
.State
= IkeStateIkeSaEstablished
;
876 Gernerates IKEv2 packet for IKE_SA_INIT exchange.
878 @param[in] SaSession Pointer to IKEV2_SA_SESSION related to the exchange.
879 @param[in] Context Context Data passed by caller.
881 @retval EFI_SUCCESS The IKE packet generation succeeded.
882 @retval Others The IKE packet generation failed.
886 Ikev2InitCertGenerator (
891 IKE_PACKET
*IkePacket
;
892 IKE_PAYLOAD
*CertReqPayload
;
894 IKE_PAYLOAD
*NoncePayload
;
896 if (!FeaturePcdGet (PcdIpsecCertificateEnabled
)) {
901 // The first two messages exchange is same between PSK and Cert.
903 IkePacket
= Ikev2InitPskGenerator (SaSession
, Context
);
905 if ((IkePacket
!= NULL
) && (!((IKEV2_SA_SESSION
*)SaSession
)->SessionCommon
.IsInitiator
)) {
907 // Add the Certification Request Payload
909 CertReqPayload
= Ikev2GenerateCertificatePayload (
910 (IKEV2_SA_SESSION
*)SaSession
,
911 IKEV2_PAYLOAD_TYPE_NONE
,
912 (UINT8
*)PcdGetPtr(PcdIpsecUefiCaFile
),
913 PcdGet32(PcdIpsecUefiCaFileSize
),
914 IKEV2_CERT_ENCODEING_HASH_AND_URL_OF_X509_CERT
,
918 // Change Nonce Payload Next payload type.
920 IKE_PACKET_END_PAYLOAD (IkePacket
, Node
);
921 NoncePayload
= IKE_PAYLOAD_BY_PACKET (Node
);
922 ((IKEV2_NONCE
*)NoncePayload
->PayloadBuf
)->Header
.NextPayload
= IKEV2_PAYLOAD_TYPE_CERTREQ
;
925 // Add Certification Request Payload
927 IKE_PACKET_APPEND_PAYLOAD (IkePacket
, CertReqPayload
);
934 Parses the IKEv2 packet for IKE_SA_INIT exchange.
936 @param[in] SaSession Pointer to IKEV2_SA_SESSION related to the exchange.
937 @param[in] IkePacket The received IKEv2 packet to be parsed.
939 @retval EFI_SUCCESS The IKEv2 packet is acceptable and the relative data is
940 saved for furthure communication.
941 @retval EFI_INVALID_PARAMETER The IKE packet is malformed or the SA proposal is unacceptable.
942 @retval EFI_UNSUPPORTED The certificate authentication is not supported.
946 Ikev2InitCertParser (
948 IN IKE_PACKET
*IkePacket
951 if (!FeaturePcdGet (PcdIpsecCertificateEnabled
)) {
952 return EFI_UNSUPPORTED
;
956 // The first two messages exchange is same between PSK and Cert.
957 // Todo: Parse Certificate Request from responder Initial Exchange.
959 return Ikev2InitPskParser (SaSession
, IkePacket
);
963 Generates the IKEv2 packet for IKE_AUTH exchange.
965 @param[in] SaSession Pointer to IKEV2_SA_SESSION.
966 @param[in] Context Context data passed by caller.
968 @retval Pointer to IKEv2 Packet to be sent out.
972 Ikev2AuthCertGenerator (
977 IKE_PACKET
*IkePacket
;
978 IKEV2_SA_SESSION
*IkeSaSession
;
979 IKE_PAYLOAD
*IdPayload
;
980 IKE_PAYLOAD
*AuthPayload
;
981 IKE_PAYLOAD
*SaPayload
;
982 IKE_PAYLOAD
*TsiPayload
;
983 IKE_PAYLOAD
*TsrPayload
;
984 IKE_PAYLOAD
*NotifyPayload
;
985 IKE_PAYLOAD
*CpPayload
;
986 IKE_PAYLOAD
*CertPayload
;
987 IKE_PAYLOAD
*CertReqPayload
;
988 IKEV2_CHILD_SA_SESSION
*ChildSaSession
;
990 if (!FeaturePcdGet (PcdIpsecCertificateEnabled
)) {
994 IkeSaSession
= (IKEV2_SA_SESSION
*) SaSession
;
995 ChildSaSession
= IKEV2_CHILD_SA_SESSION_BY_IKE_SA (GetFirstNode (&IkeSaSession
->ChildSaSessionList
));
1004 NotifyPayload
= NULL
;
1006 CertReqPayload
= NULL
;
1009 // 1. Allocate IKE Packet
1011 IkePacket
= IkePacketAlloc ();
1012 if (IkePacket
== NULL
) {
1017 // 1.a Fill the IkePacket Header.
1019 IkePacket
->Header
->ExchangeType
= IKEV2_EXCHANGE_TYPE_AUTH
;
1020 IkePacket
->Header
->InitiatorCookie
= IkeSaSession
->InitiatorCookie
;
1021 IkePacket
->Header
->ResponderCookie
= IkeSaSession
->ResponderCookie
;
1022 IkePacket
->Header
->Version
= (UINT8
)(2 << 4);
1023 if (ChildSaSession
->SessionCommon
.IsInitiator
) {
1024 IkePacket
->Header
->NextPayload
= IKEV2_PAYLOAD_TYPE_ID_INIT
;
1026 IkePacket
->Header
->NextPayload
= IKEV2_PAYLOAD_TYPE_ID_RSP
;
1030 // According to RFC4306_2.2, For the IKE_SA_INIT message the MessageID should
1031 // be always number 0 and 1;
1033 IkePacket
->Header
->MessageId
= 1;
1035 if (IkeSaSession
->SessionCommon
.IsInitiator
) {
1036 IkePacket
->Header
->Flags
= IKE_HEADER_FLAGS_INIT
;
1038 IkePacket
->Header
->Flags
= IKE_HEADER_FLAGS_RESPOND
;
1042 // 2. Generate ID Payload according to IP version and address.
1044 IdPayload
= Ikev2GenerateCertIdPayload (
1045 &IkeSaSession
->SessionCommon
,
1046 IKEV2_PAYLOAD_TYPE_CERT
,
1047 (UINT8
*)PcdGetPtr (PcdIpsecUefiCertificate
),
1048 PcdGet32 (PcdIpsecUefiCertificateSize
)
1050 if (IdPayload
== NULL
) {
1055 // 3. Generate Certificate Payload
1057 CertPayload
= Ikev2GenerateCertificatePayload (
1059 (UINT8
)(IkeSaSession
->SessionCommon
.IsInitiator
? IKEV2_PAYLOAD_TYPE_CERTREQ
: IKEV2_PAYLOAD_TYPE_AUTH
),
1060 (UINT8
*)PcdGetPtr (PcdIpsecUefiCertificate
),
1061 PcdGet32 (PcdIpsecUefiCertificateSize
),
1062 IKEV2_CERT_ENCODEING_X509_CERT_SIGN
,
1065 if (CertPayload
== NULL
) {
1069 if (IkeSaSession
->SessionCommon
.IsInitiator
) {
1070 CertReqPayload
= Ikev2GenerateCertificatePayload (
1072 IKEV2_PAYLOAD_TYPE_AUTH
,
1073 (UINT8
*)PcdGetPtr (PcdIpsecUefiCertificate
),
1074 PcdGet32 (PcdIpsecUefiCertificateSize
),
1075 IKEV2_CERT_ENCODEING_HASH_AND_URL_OF_X509_CERT
,
1078 if (CertReqPayload
== NULL
) {
1084 // 4. Generate Auth Payload
1085 // If it is tunnel mode, should create the configuration payload after the
1088 if (IkeSaSession
->Spd
->Data
->ProcessingPolicy
->Mode
== EfiIPsecTransport
) {
1089 AuthPayload
= Ikev2CertGenerateAuthPayload (
1090 ChildSaSession
->IkeSaSession
,
1092 IKEV2_PAYLOAD_TYPE_SA
,
1094 (UINT8
*)PcdGetPtr (PcdIpsecUefiCertificateKey
),
1095 PcdGet32 (PcdIpsecUefiCertificateKeySize
),
1096 ChildSaSession
->IkeSaSession
->Pad
->Data
->AuthData
,
1097 ChildSaSession
->IkeSaSession
->Pad
->Data
->AuthDataSize
1100 AuthPayload
= Ikev2CertGenerateAuthPayload (
1101 ChildSaSession
->IkeSaSession
,
1103 IKEV2_PAYLOAD_TYPE_CP
,
1105 (UINT8
*)PcdGetPtr (PcdIpsecUefiCertificateKey
),
1106 PcdGet32 (PcdIpsecUefiCertificateKeySize
),
1107 ChildSaSession
->IkeSaSession
->Pad
->Data
->AuthData
,
1108 ChildSaSession
->IkeSaSession
->Pad
->Data
->AuthDataSize
1110 if (IkeSaSession
->SessionCommon
.UdpService
->IpVersion
== IP_VERSION_4
) {
1111 CpPayload
= Ikev2GenerateCpPayload (
1112 ChildSaSession
->IkeSaSession
,
1113 IKEV2_PAYLOAD_TYPE_SA
,
1114 IKEV2_CFG_ATTR_INTERNAL_IP4_ADDRESS
1117 CpPayload
= Ikev2GenerateCpPayload (
1118 ChildSaSession
->IkeSaSession
,
1119 IKEV2_PAYLOAD_TYPE_SA
,
1120 IKEV2_CFG_ATTR_INTERNAL_IP6_ADDRESS
1124 if (CpPayload
== NULL
) {
1129 if (AuthPayload
== NULL
) {
1134 // 5. Generate SA Payload according to the Sa Data in ChildSaSession
1136 SaPayload
= Ikev2GenerateSaPayload (
1137 ChildSaSession
->SaData
,
1138 IKEV2_PAYLOAD_TYPE_TS_INIT
,
1139 IkeSessionTypeChildSa
1141 if (SaPayload
== NULL
) {
1145 if (IkeSaSession
->Spd
->Data
->ProcessingPolicy
->Mode
== EfiIPsecTransport
) {
1147 // Generate Tsi and Tsr.
1149 TsiPayload
= Ikev2GenerateTsPayload (
1151 IKEV2_PAYLOAD_TYPE_TS_RSP
,
1155 TsrPayload
= Ikev2GenerateTsPayload (
1157 IKEV2_PAYLOAD_TYPE_NOTIFY
,
1162 // Generate Notify Payload. If transport mode, there should have Notify
1163 // payload with TRANSPORT_MODE notification.
1165 NotifyPayload
= Ikev2GenerateNotifyPayload (
1167 IKEV2_PAYLOAD_TYPE_NONE
,
1169 IKEV2_NOTIFICATION_USE_TRANSPORT_MODE
,
1174 if (NotifyPayload
== NULL
) {
1179 // Generate Tsr for Tunnel mode.
1181 TsiPayload
= Ikev2GenerateTsPayload (
1183 IKEV2_PAYLOAD_TYPE_TS_RSP
,
1186 TsrPayload
= Ikev2GenerateTsPayload (
1188 IKEV2_PAYLOAD_TYPE_NONE
,
1193 if (TsiPayload
== NULL
|| TsrPayload
== NULL
) {
1197 IKE_PACKET_APPEND_PAYLOAD (IkePacket
, IdPayload
);
1198 IKE_PACKET_APPEND_PAYLOAD (IkePacket
, CertPayload
);
1199 if (IkeSaSession
->SessionCommon
.IsInitiator
) {
1200 IKE_PACKET_APPEND_PAYLOAD (IkePacket
, CertReqPayload
);
1202 IKE_PACKET_APPEND_PAYLOAD (IkePacket
, AuthPayload
);
1203 if (IkeSaSession
->Spd
->Data
->ProcessingPolicy
->Mode
== EfiIPsecTunnel
) {
1204 IKE_PACKET_APPEND_PAYLOAD (IkePacket
, CpPayload
);
1206 IKE_PACKET_APPEND_PAYLOAD (IkePacket
, SaPayload
);
1207 IKE_PACKET_APPEND_PAYLOAD (IkePacket
, TsiPayload
);
1208 IKE_PACKET_APPEND_PAYLOAD (IkePacket
, TsrPayload
);
1209 if (IkeSaSession
->Spd
->Data
->ProcessingPolicy
->Mode
== EfiIPsecTransport
) {
1210 IKE_PACKET_APPEND_PAYLOAD (IkePacket
, NotifyPayload
);
1216 if (IkePacket
!= NULL
) {
1217 IkePacketFree (IkePacket
);
1220 if (IdPayload
!= NULL
) {
1221 IkePayloadFree (IdPayload
);
1224 if (CertPayload
!= NULL
) {
1225 IkePayloadFree (CertPayload
);
1228 if (CertReqPayload
!= NULL
) {
1229 IkePayloadFree (CertReqPayload
);
1232 if (AuthPayload
!= NULL
) {
1233 IkePayloadFree (AuthPayload
);
1236 if (CpPayload
!= NULL
) {
1237 IkePayloadFree (CpPayload
);
1240 if (SaPayload
!= NULL
) {
1241 IkePayloadFree (SaPayload
);
1244 if (TsiPayload
!= NULL
) {
1245 IkePayloadFree (TsiPayload
);
1248 if (TsrPayload
!= NULL
) {
1249 IkePayloadFree (TsrPayload
);
1252 if (NotifyPayload
!= NULL
) {
1253 IkePayloadFree (NotifyPayload
);
1260 Parses IKE_AUTH packet.
1262 @param[in] SaSession Pointer to the IKE_SA_SESSION related to this packet.
1263 @param[in] IkePacket Pointer to the IKE_AUTH packet to be parsered.
1265 @retval EFI_INVALID_PARAMETER The IKEv2 packet is malformed or the SA
1266 proposal is unacceptable.
1267 @retval EFI_SUCCESS The IKE packet is acceptable and the
1268 relative data is saved for furthure communication.
1269 @retval EFI_UNSUPPORTED The certificate authentication is not supported.
1273 Ikev2AuthCertParser (
1274 IN UINT8
*SaSession
,
1275 IN IKE_PACKET
*IkePacket
1278 IKEV2_CHILD_SA_SESSION
*ChildSaSession
;
1279 IKEV2_SA_SESSION
*IkeSaSession
;
1280 IKE_PAYLOAD
*IkePayload
;
1281 IKE_PAYLOAD
*SaPayload
;
1282 IKE_PAYLOAD
*IdiPayload
;
1283 IKE_PAYLOAD
*IdrPayload
;
1284 IKE_PAYLOAD
*AuthPayload
;
1285 IKE_PAYLOAD
*TsiPayload
;
1286 IKE_PAYLOAD
*TsrPayload
;
1287 IKE_PAYLOAD
*CertPayload
;
1288 IKE_PAYLOAD
*VerifiedAuthPayload
;
1292 if (!FeaturePcdGet (PcdIpsecCertificateEnabled
)) {
1293 return EFI_UNSUPPORTED
;
1296 IkeSaSession
= (IKEV2_SA_SESSION
*) SaSession
;
1297 ChildSaSession
= IKEV2_CHILD_SA_SESSION_BY_IKE_SA (GetFirstNode (&IkeSaSession
->ChildSaSessionList
));
1306 VerifiedAuthPayload
= NULL
;
1307 Status
= EFI_INVALID_PARAMETER
;
1310 // Iterate payloads to find the SaPayload/ID/AUTH/TS Payload.
1312 NET_LIST_FOR_EACH (Entry
, &(IkePacket
)->PayloadList
) {
1313 IkePayload
= IKE_PAYLOAD_BY_PACKET (Entry
);
1315 if (IkePayload
->PayloadType
== IKEV2_PAYLOAD_TYPE_ID_INIT
) {
1316 IdiPayload
= IkePayload
;
1318 if (IkePayload
->PayloadType
== IKEV2_PAYLOAD_TYPE_ID_RSP
) {
1319 IdrPayload
= IkePayload
;
1322 if (IkePayload
->PayloadType
== IKEV2_PAYLOAD_TYPE_SA
) {
1323 SaPayload
= IkePayload
;
1325 if (IkePayload
->PayloadType
== IKEV2_PAYLOAD_TYPE_AUTH
) {
1326 AuthPayload
= IkePayload
;
1328 if (IkePayload
->PayloadType
== IKEV2_PAYLOAD_TYPE_TS_INIT
) {
1329 TsiPayload
= IkePayload
;
1331 if (IkePayload
->PayloadType
== IKEV2_PAYLOAD_TYPE_TS_RSP
) {
1332 TsrPayload
= IkePayload
;
1334 if (IkePayload
->PayloadType
== IKEV2_PAYLOAD_TYPE_CERT
) {
1335 CertPayload
= IkePayload
;
1339 if ((SaPayload
== NULL
) || (AuthPayload
== NULL
) || (TsiPayload
== NULL
) ||
1340 (TsrPayload
== NULL
) || (CertPayload
== NULL
)) {
1343 if ((IdiPayload
== NULL
) && (IdrPayload
== NULL
)) {
1348 // Check IkePacket Header is match the state
1350 if (IkeSaSession
->SessionCommon
.IsInitiator
) {
1353 // 1. Check the IkePacket->Hdr == IKE_HEADER_FLAGS_RESPOND
1355 if ((IkePacket
->Header
->Flags
!= IKE_HEADER_FLAGS_RESPOND
) ||
1356 (IkePacket
->Header
->ExchangeType
!= IKEV2_EXCHANGE_TYPE_AUTH
)) {
1361 // 1. Check the IkePacket->Hdr == IKE_HEADER_FLAGS_INIT
1363 if ((IkePacket
->Header
->Flags
!= IKE_HEADER_FLAGS_INIT
) ||
1364 (IkePacket
->Header
->ExchangeType
!= IKEV2_EXCHANGE_TYPE_AUTH
)) {
1370 // Verify the Auth Payload.
1372 VerifiedAuthPayload
= Ikev2CertGenerateAuthPayload (
1374 IkeSaSession
->SessionCommon
.IsInitiator
? IdrPayload
:IdiPayload
,
1375 IKEV2_PAYLOAD_TYPE_SA
,
1383 if ((VerifiedAuthPayload
!= NULL
) &&
1384 (!IpSecCryptoIoVerifySignDataByCertificate (
1385 CertPayload
->PayloadBuf
+ sizeof (IKEV2_CERT
),
1386 CertPayload
->PayloadSize
- sizeof (IKEV2_CERT
),
1387 (UINT8
*)PcdGetPtr (PcdIpsecUefiCaFile
),
1388 PcdGet32 (PcdIpsecUefiCaFileSize
),
1389 VerifiedAuthPayload
->PayloadBuf
+ sizeof (IKEV2_AUTH
),
1390 VerifiedAuthPayload
->PayloadSize
- sizeof (IKEV2_AUTH
),
1391 AuthPayload
->PayloadBuf
+ sizeof (IKEV2_AUTH
),
1392 AuthPayload
->PayloadSize
- sizeof (IKEV2_AUTH
)
1398 // 3. Parse the SA Payload to find out the cryptographic suite
1399 // and fill in the SA paramse into CommonSession->SaParams. If no acceptable
1400 // porposal found, return EFI_INVALID_PARAMETER.
1402 if (!Ikev2ChildSaParseSaPayload (ChildSaSession
, SaPayload
, IkePacket
->Header
->Flags
)) {
1407 // 4. Parse TSi, TSr payloads.
1409 if ((((TRAFFIC_SELECTOR
*)(TsiPayload
->PayloadBuf
+ sizeof (IKEV2_TS
)))->IpProtocolId
!=
1410 ((TRAFFIC_SELECTOR
*)(TsrPayload
->PayloadBuf
+ sizeof (IKEV2_TS
)))->IpProtocolId
) &&
1411 (((TRAFFIC_SELECTOR
*)(TsiPayload
->PayloadBuf
+ sizeof (IKEV2_TS
)))->IpProtocolId
!= 0) &&
1412 (((TRAFFIC_SELECTOR
*)(TsrPayload
->PayloadBuf
+ sizeof (IKEV2_TS
)))->IpProtocolId
!= 0)
1417 if (!IkeSaSession
->SessionCommon
.IsInitiator
) {
1419 //Todo:check the Port range. Only support any port and one certain port here.
1421 ChildSaSession
->ProtoId
= ((TRAFFIC_SELECTOR
*)(TsrPayload
->PayloadBuf
+ sizeof (IKEV2_TS
)))->IpProtocolId
;
1422 ChildSaSession
->LocalPort
= ((TRAFFIC_SELECTOR
*)(TsrPayload
->PayloadBuf
+ sizeof (IKEV2_TS
)))->StartPort
;
1423 ChildSaSession
->RemotePort
= ((TRAFFIC_SELECTOR
*)(TsiPayload
->PayloadBuf
+ sizeof (IKEV2_TS
)))->StartPort
;
1425 // Association a SPD with this SA.
1427 if (EFI_ERROR (Ikev2ChildSaAssociateSpdEntry (ChildSaSession
))) {
1431 // Associate the IkeSaSession's SPD to the first ChildSaSession's SPD.
1433 if (ChildSaSession
->IkeSaSession
->Spd
== NULL
) {
1434 ChildSaSession
->IkeSaSession
->Spd
= ChildSaSession
->Spd
;
1435 Status
= Ikev2ChildSaSessionSpdSelectorCreate (ChildSaSession
);
1436 if (EFI_ERROR (Status
)) {
1442 // Todo:check the Port range.
1444 if ((((TRAFFIC_SELECTOR
*)(TsrPayload
->PayloadBuf
+ sizeof (IKEV2_TS
)))->StartPort
!= 0) &&
1445 (((TRAFFIC_SELECTOR
*)(TsrPayload
->PayloadBuf
+ sizeof (IKEV2_TS
)))->StartPort
!= ChildSaSession
->RemotePort
)
1449 if ((((TRAFFIC_SELECTOR
*)(TsiPayload
->PayloadBuf
+ sizeof (IKEV2_TS
)))->StartPort
!= 0) &&
1450 (((TRAFFIC_SELECTOR
*)(TsiPayload
->PayloadBuf
+ sizeof (IKEV2_TS
)))->StartPort
!= ChildSaSession
->LocalPort
)
1455 // For the tunnel mode, it should add the vitual IP address into the SA's SPD Selector.
1457 if (ChildSaSession
->Spd
->Data
->ProcessingPolicy
->Mode
== EfiIPsecTunnel
) {
1458 if (!ChildSaSession
->IkeSaSession
->SessionCommon
.IsInitiator
) {
1460 // If it is tunnel mode, the UEFI part must be the initiator.
1465 // Get the Virtual IP address from the Tsi traffic selector.
1466 // TODO: check the CFG reply payload
1469 &ChildSaSession
->SpdSelector
->LocalAddress
[0].Address
,
1470 TsiPayload
->PayloadBuf
+ sizeof (IKEV2_TS
) + sizeof (TRAFFIC_SELECTOR
),
1471 (ChildSaSession
->SessionCommon
.UdpService
->IpVersion
== IP_VERSION_4
) ?
1472 sizeof (EFI_IPv4_ADDRESS
) : sizeof (EFI_IPv6_ADDRESS
)
1478 // 5. Generat keymats for IPsec protocol.
1480 Status
= Ikev2GenerateChildSaKeys (ChildSaSession
, NULL
);
1481 if (EFI_ERROR (Status
)) {
1485 if (IkeSaSession
->SessionCommon
.IsInitiator
) {
1487 // 6. Change the state of IkeSaSession
1489 IKEV2_DUMP_STATE (IkeSaSession
->SessionCommon
.State
, IkeStateIkeSaEstablished
);
1490 IkeSaSession
->SessionCommon
.State
= IkeStateIkeSaEstablished
;
1493 Status
= EFI_SUCCESS
;
1496 if (VerifiedAuthPayload
!= NULL
) {
1497 IkePayloadFree (VerifiedAuthPayload
);
1503 Generates the DH Public Key.
1505 This generates the DH local public key and store it in the IKE SA Session's GxBuffer.
1507 @param[in] IkeSaSession Pointer to related IKE SA Session.
1509 @retval EFI_SUCCESS The operation succeeded.
1510 @retval Others The operation failed.
1514 Ikev2GenerateSaDhPublicKey (
1515 IN IKEV2_SA_SESSION
*IkeSaSession
1519 IKEV2_SESSION_KEYS
*IkeKeys
;
1521 IkeSaSession
->IkeKeys
= AllocateZeroPool (sizeof (IKEV2_SESSION_KEYS
));
1522 if (IkeSaSession
->IkeKeys
== NULL
) {
1523 return EFI_OUT_OF_RESOURCES
;
1526 IkeKeys
= IkeSaSession
->IkeKeys
;
1527 IkeKeys
->DhBuffer
= AllocateZeroPool (sizeof (IKEV2_DH_BUFFER
));
1528 if (IkeKeys
->DhBuffer
== NULL
) {
1529 FreePool (IkeSaSession
->IkeKeys
);
1530 return EFI_OUT_OF_RESOURCES
;
1534 // Init DH with the certain DH Group Description.
1536 IkeKeys
->DhBuffer
->GxSize
= OakleyModpGroup
[(UINT8
)IkeSaSession
->SessionCommon
.PreferDhGroup
].Size
>> 3;
1537 IkeKeys
->DhBuffer
->GxBuffer
= AllocateZeroPool (IkeKeys
->DhBuffer
->GxSize
);
1538 if (IkeKeys
->DhBuffer
->GxBuffer
== NULL
) {
1539 FreePool (IkeKeys
->DhBuffer
);
1540 FreePool (IkeSaSession
->IkeKeys
);
1541 return EFI_OUT_OF_RESOURCES
;
1547 Status
= IpSecCryptoIoDhGetPublicKey (
1548 &IkeKeys
->DhBuffer
->DhContext
,
1549 OakleyModpGroup
[(UINT8
)IkeSaSession
->SessionCommon
.PreferDhGroup
].GroupGenerator
,
1550 OakleyModpGroup
[(UINT8
)IkeSaSession
->SessionCommon
.PreferDhGroup
].Size
,
1551 OakleyModpGroup
[(UINT8
)IkeSaSession
->SessionCommon
.PreferDhGroup
].Modulus
,
1552 IkeKeys
->DhBuffer
->GxBuffer
,
1553 &IkeKeys
->DhBuffer
->GxSize
1555 if (EFI_ERROR (Status
)) {
1556 DEBUG ((DEBUG_ERROR
, "Error CPLKeyManGetKeyParam X public key error Status = %r\n", Status
));
1558 FreePool (IkeKeys
->DhBuffer
->GxBuffer
);
1560 FreePool (IkeKeys
->DhBuffer
);
1562 FreePool (IkeSaSession
->IkeKeys
);
1567 IPSEC_DUMP_BUF ("DH Public Key (g^x) Dump", IkeKeys
->DhBuffer
->GxBuffer
, IkeKeys
->DhBuffer
->GxSize
);
1573 Computes the DH Shared/Exchange Key.
1575 Given peer's public key, this function computes the exchanged common key and
1576 stores it in the IKEv2 SA Session's GxyBuffer.
1578 @param[in] DhBuffer Pointer to buffer of peer's puliic key.
1579 @param[in] KePayload Pointer to received key payload.
1581 @retval EFI_SUCCESS The operation succeeded.
1582 @retval Otherwise The operation failed.
1586 Ikev2GenerateSaDhComputeKey (
1587 IN IKEV2_DH_BUFFER
*DhBuffer
,
1588 IN IKE_PAYLOAD
*KePayload
1592 IKEV2_KEY_EXCHANGE
*Ke
;
1596 Ke
= (IKEV2_KEY_EXCHANGE
*) KePayload
->PayloadBuf
;
1597 PubKey
= (UINT8
*) (Ke
+ 1);
1598 PubKeySize
= KePayload
->PayloadSize
- sizeof (IKEV2_KEY_EXCHANGE
);
1599 DhBuffer
->GxySize
= DhBuffer
->GxSize
;
1600 DhBuffer
->GxyBuffer
= AllocateZeroPool (DhBuffer
->GxySize
);
1601 if (DhBuffer
->GxyBuffer
== NULL
) {
1602 return EFI_OUT_OF_RESOURCES
;
1608 Status
= IpSecCryptoIoDhComputeKey (
1609 DhBuffer
->DhContext
,
1612 DhBuffer
->GxyBuffer
,
1615 if (EFI_ERROR (Status
)) {
1616 DEBUG ((DEBUG_ERROR
, "Error CPLKeyManGetKeyParam Y session key error Status = %r\n", Status
));
1618 FreePool (DhBuffer
->GxyBuffer
);
1626 DhBuffer
->GySize
= PubKeySize
;
1627 DhBuffer
->GyBuffer
= AllocateZeroPool (DhBuffer
->GySize
);
1628 if (DhBuffer
->GyBuffer
== NULL
) {
1629 FreePool (DhBuffer
->GxyBuffer
);
1634 CopyMem (DhBuffer
->GyBuffer
, PubKey
, DhBuffer
->GySize
);
1636 IPSEC_DUMP_BUF ("DH Public Key (g^y) Dump", DhBuffer
->GyBuffer
, DhBuffer
->GySize
);
1637 IPSEC_DUMP_BUF ("DH Shared Key (g^xy) Dump", DhBuffer
->GxyBuffer
, DhBuffer
->GxySize
);
1643 Generates the IKE SKEYSEED and seven other secrets. SK_d, SK_ai, SK_ar, SK_ei, SK_er,
1644 SK_pi, SK_pr are keys for the furthure IKE exchange.
1646 @param[in] IkeSaSession Pointer to IKE SA Session.
1647 @param[in] KePayload Pointer to Key payload used to generate the Key.
1649 @retval EFI_UNSUPPORTED If one or more Algorithm Id is not supported.
1650 @retval EFI_OUT_OF_RESOURCES If there is no enough resource to be allocated to
1651 meet the requirement.
1652 @retval EFI_SUCCESS The operation succeeded.
1656 Ikev2GenerateSaKeys (
1657 IN IKEV2_SA_SESSION
*IkeSaSession
,
1658 IN IKE_PAYLOAD
*KePayload
1662 IKEV2_SA_PARAMS
*SaParams
;
1663 PRF_DATA_FRAGMENT Fragments
[4];
1664 UINT64 InitiatorCookieNet
;
1665 UINT64 ResponderCookieNet
;
1667 UINTN KeyBufferSize
;
1668 UINTN AuthAlgKeyLen
;
1669 UINTN EncryptAlgKeyLen
;
1670 UINTN IntegrityAlgKeyLen
;
1673 UINTN OutputKeyLength
;
1680 Status
= EFI_SUCCESS
;
1685 Status
= Ikev2GenerateSaDhComputeKey (IkeSaSession
->IkeKeys
->DhBuffer
, KePayload
);
1686 if (EFI_ERROR (Status
)) {
1691 // Get the key length of Authenticaion, Encryption, PRF, and Integrity.
1693 SaParams
= IkeSaSession
->SessionCommon
.SaParams
;
1694 AuthAlgKeyLen
= IpSecGetHmacDigestLength ((UINT8
)SaParams
->Prf
);
1695 EncryptAlgKeyLen
= IpSecGetEncryptKeyLength ((UINT8
)SaParams
->EncAlgId
);
1696 IntegrityAlgKeyLen
= IpSecGetHmacDigestLength ((UINT8
)SaParams
->IntegAlgId
);
1697 PrfAlgKeyLen
= IpSecGetHmacDigestLength ((UINT8
)SaParams
->Prf
);
1700 // If one or more algorithm is not support, return EFI_UNSUPPORTED.
1702 if (AuthAlgKeyLen
== 0 ||
1703 EncryptAlgKeyLen
== 0 ||
1704 IntegrityAlgKeyLen
== 0 ||
1707 Status
= EFI_UNSUPPORTED
;
1712 // Compute SKEYSEED = prf(Ni | Nr, g^ir)
1714 KeyBufferSize
= IkeSaSession
->NiBlkSize
+ IkeSaSession
->NrBlkSize
;
1715 KeyBuffer
= AllocateZeroPool (KeyBufferSize
);
1716 if (KeyBuffer
== NULL
) {
1717 Status
= EFI_OUT_OF_RESOURCES
;
1721 CopyMem (KeyBuffer
, IkeSaSession
->NiBlock
, IkeSaSession
->NiBlkSize
);
1722 CopyMem (KeyBuffer
+ IkeSaSession
->NiBlkSize
, IkeSaSession
->NrBlock
, IkeSaSession
->NrBlkSize
);
1724 Fragments
[0].Data
= IkeSaSession
->IkeKeys
->DhBuffer
->GxyBuffer
;
1725 Fragments
[0].DataSize
= IkeSaSession
->IkeKeys
->DhBuffer
->GxySize
;
1727 DigestSize
= IpSecGetHmacDigestLength ((UINT8
)SaParams
->Prf
);
1728 Digest
= AllocateZeroPool (DigestSize
);
1730 if (Digest
== NULL
) {
1731 Status
= EFI_OUT_OF_RESOURCES
;
1736 (UINT8
)SaParams
->Prf
,
1739 (HASH_DATA_FRAGMENT
*) Fragments
,
1746 // {SK_d | SK_ai | SK_ar | SK_ei | SK_er | SK_pi | SK_pr } = prf+
1747 // (SKEYSEED, Ni | Nr | SPIi | SPIr )
1749 Fragments
[0].Data
= IkeSaSession
->NiBlock
;
1750 Fragments
[0].DataSize
= IkeSaSession
->NiBlkSize
;
1751 Fragments
[1].Data
= IkeSaSession
->NrBlock
;
1752 Fragments
[1].DataSize
= IkeSaSession
->NrBlkSize
;
1753 InitiatorCookieNet
= HTONLL (IkeSaSession
->InitiatorCookie
);
1754 ResponderCookieNet
= HTONLL (IkeSaSession
->ResponderCookie
);
1755 Fragments
[2].Data
= (UINT8
*)(&InitiatorCookieNet
);
1756 Fragments
[2].DataSize
= sizeof (IkeSaSession
->InitiatorCookie
);
1757 Fragments
[3].Data
= (UINT8
*)(&ResponderCookieNet
);
1758 Fragments
[3].DataSize
= sizeof (IkeSaSession
->ResponderCookie
);
1760 IPSEC_DUMP_BUF (">>> NiBlock", IkeSaSession
->NiBlock
, IkeSaSession
->NiBlkSize
);
1761 IPSEC_DUMP_BUF (">>> NrBlock", IkeSaSession
->NrBlock
, IkeSaSession
->NrBlkSize
);
1762 IPSEC_DUMP_BUF (">>> InitiatorCookie", (UINT8
*)&IkeSaSession
->InitiatorCookie
, sizeof(UINT64
));
1763 IPSEC_DUMP_BUF (">>> ResponderCookie", (UINT8
*)&IkeSaSession
->ResponderCookie
, sizeof(UINT64
));
1765 OutputKeyLength
= PrfAlgKeyLen
+
1766 2 * EncryptAlgKeyLen
+
1768 2 * IntegrityAlgKeyLen
;
1769 OutputKey
= AllocateZeroPool (OutputKeyLength
);
1770 if (OutputKey
== NULL
) {
1771 Status
= EFI_OUT_OF_RESOURCES
;
1776 // Generate Seven Keymates.
1778 Status
= Ikev2SaGenerateKey (
1779 (UINT8
)SaParams
->Prf
,
1787 if (EFI_ERROR(Status
)) {
1792 // Save the seven keys into KeySession.
1795 IkeSaSession
->IkeKeys
->SkdKey
= AllocateZeroPool (PrfAlgKeyLen
);
1796 if (IkeSaSession
->IkeKeys
->SkdKey
== NULL
) {
1797 Status
= EFI_OUT_OF_RESOURCES
;
1800 IkeSaSession
->IkeKeys
->SkdKeySize
= PrfAlgKeyLen
;
1801 CopyMem (IkeSaSession
->IkeKeys
->SkdKey
, OutputKey
, PrfAlgKeyLen
);
1803 IPSEC_DUMP_BUF (">>> SK_D Key", IkeSaSession
->IkeKeys
->SkdKey
, PrfAlgKeyLen
);
1808 IkeSaSession
->IkeKeys
->SkAiKey
= AllocateZeroPool (IntegrityAlgKeyLen
);
1809 if (IkeSaSession
->IkeKeys
->SkAiKey
== NULL
) {
1810 Status
= EFI_OUT_OF_RESOURCES
;
1813 IkeSaSession
->IkeKeys
->SkAiKeySize
= IntegrityAlgKeyLen
;
1814 CopyMem (IkeSaSession
->IkeKeys
->SkAiKey
, OutputKey
+ PrfAlgKeyLen
, IntegrityAlgKeyLen
);
1816 IPSEC_DUMP_BUF (">>> SK_Ai Key", IkeSaSession
->IkeKeys
->SkAiKey
, IkeSaSession
->IkeKeys
->SkAiKeySize
);
1821 IkeSaSession
->IkeKeys
->SkArKey
= AllocateZeroPool (IntegrityAlgKeyLen
);
1822 if (IkeSaSession
->IkeKeys
->SkArKey
== NULL
) {
1823 Status
= EFI_OUT_OF_RESOURCES
;
1826 IkeSaSession
->IkeKeys
->SkArKeySize
= IntegrityAlgKeyLen
;
1828 IkeSaSession
->IkeKeys
->SkArKey
,
1829 OutputKey
+ PrfAlgKeyLen
+ IntegrityAlgKeyLen
,
1833 IPSEC_DUMP_BUF (">>> SK_Ar Key", IkeSaSession
->IkeKeys
->SkArKey
, IkeSaSession
->IkeKeys
->SkArKeySize
);
1838 IkeSaSession
->IkeKeys
->SkEiKey
= AllocateZeroPool (EncryptAlgKeyLen
);
1839 if (IkeSaSession
->IkeKeys
->SkEiKey
== NULL
) {
1840 Status
= EFI_OUT_OF_RESOURCES
;
1843 IkeSaSession
->IkeKeys
->SkEiKeySize
= EncryptAlgKeyLen
;
1846 IkeSaSession
->IkeKeys
->SkEiKey
,
1847 OutputKey
+ AuthAlgKeyLen
+ 2 * IntegrityAlgKeyLen
,
1852 OutputKey
+ AuthAlgKeyLen
+ 2 * IntegrityAlgKeyLen
,
1859 IkeSaSession
->IkeKeys
->SkErKey
= AllocateZeroPool (EncryptAlgKeyLen
);
1860 if (IkeSaSession
->IkeKeys
->SkErKey
== NULL
) {
1861 Status
= EFI_OUT_OF_RESOURCES
;
1864 IkeSaSession
->IkeKeys
->SkErKeySize
= EncryptAlgKeyLen
;
1867 IkeSaSession
->IkeKeys
->SkErKey
,
1868 OutputKey
+ AuthAlgKeyLen
+ 2 * IntegrityAlgKeyLen
+ EncryptAlgKeyLen
,
1873 OutputKey
+ AuthAlgKeyLen
+ 2 * IntegrityAlgKeyLen
+ EncryptAlgKeyLen
,
1880 IkeSaSession
->IkeKeys
->SkPiKey
= AllocateZeroPool (AuthAlgKeyLen
);
1881 if (IkeSaSession
->IkeKeys
->SkPiKey
== NULL
) {
1882 Status
= EFI_OUT_OF_RESOURCES
;
1885 IkeSaSession
->IkeKeys
->SkPiKeySize
= AuthAlgKeyLen
;
1888 IkeSaSession
->IkeKeys
->SkPiKey
,
1889 OutputKey
+ AuthAlgKeyLen
+ 2 * IntegrityAlgKeyLen
+ 2 * EncryptAlgKeyLen
,
1894 OutputKey
+ AuthAlgKeyLen
+ 2 * IntegrityAlgKeyLen
+ 2 * EncryptAlgKeyLen
,
1901 IkeSaSession
->IkeKeys
->SkPrKey
= AllocateZeroPool (AuthAlgKeyLen
);
1902 if (IkeSaSession
->IkeKeys
->SkPrKey
== NULL
) {
1903 Status
= EFI_OUT_OF_RESOURCES
;
1906 IkeSaSession
->IkeKeys
->SkPrKeySize
= AuthAlgKeyLen
;
1909 IkeSaSession
->IkeKeys
->SkPrKey
,
1910 OutputKey
+ AuthAlgKeyLen
+ 2 * IntegrityAlgKeyLen
+ 2 * EncryptAlgKeyLen
+ AuthAlgKeyLen
,
1915 OutputKey
+ AuthAlgKeyLen
+ 2 * IntegrityAlgKeyLen
+ 2 * EncryptAlgKeyLen
+ AuthAlgKeyLen
,
1921 if (Digest
!= NULL
) {
1924 if (KeyBuffer
!= NULL
) {
1925 FreePool (KeyBuffer
);
1927 if (OutputKey
!= NULL
) {
1928 FreePool (OutputKey
);
1931 if (EFI_ERROR(Status
)) {
1932 if (IkeSaSession
->IkeKeys
->SkdKey
!= NULL
) {
1933 FreePool (IkeSaSession
->IkeKeys
->SkdKey
);
1935 if (IkeSaSession
->IkeKeys
->SkAiKey
!= NULL
) {
1936 FreePool (IkeSaSession
->IkeKeys
->SkAiKey
);
1938 if (IkeSaSession
->IkeKeys
->SkArKey
!= NULL
) {
1939 FreePool (IkeSaSession
->IkeKeys
->SkArKey
);
1941 if (IkeSaSession
->IkeKeys
->SkEiKey
!= NULL
) {
1942 FreePool (IkeSaSession
->IkeKeys
->SkEiKey
);
1944 if (IkeSaSession
->IkeKeys
->SkErKey
!= NULL
) {
1945 FreePool (IkeSaSession
->IkeKeys
->SkErKey
);
1947 if (IkeSaSession
->IkeKeys
->SkPiKey
!= NULL
) {
1948 FreePool (IkeSaSession
->IkeKeys
->SkPiKey
);
1950 if (IkeSaSession
->IkeKeys
->SkPrKey
!= NULL
) {
1951 FreePool (IkeSaSession
->IkeKeys
->SkPrKey
);
1960 Generates the Keys for the furthure IPsec Protocol.
1962 @param[in] ChildSaSession Pointer to IKE Child SA Session.
1963 @param[in] KePayload Pointer to Key payload used to generate the Key.
1965 @retval EFI_UNSUPPORTED If one or more Algorithm Id is not supported.
1966 @retval EFI_SUCCESS The operation succeeded.
1970 Ikev2GenerateChildSaKeys (
1971 IN IKEV2_CHILD_SA_SESSION
*ChildSaSession
,
1972 IN IKE_PAYLOAD
*KePayload
1976 IKEV2_SA_PARAMS
*SaParams
;
1977 PRF_DATA_FRAGMENT Fragments
[3];
1978 UINTN EncryptAlgKeyLen
;
1979 UINTN IntegrityAlgKeyLen
;
1981 UINTN OutputKeyLength
;
1983 Status
= EFI_SUCCESS
;
1986 if (KePayload
!= NULL
) {
1990 Status
= Ikev2GenerateSaDhComputeKey (ChildSaSession
->DhBuffer
, KePayload
);
1991 if (EFI_ERROR (Status
)) {
1995 Fragments
[0].Data
= ChildSaSession
->DhBuffer
->GxyBuffer
;
1996 Fragments
[0].DataSize
= ChildSaSession
->DhBuffer
->GxySize
;
1999 Fragments
[1].Data
= ChildSaSession
->NiBlock
;
2000 Fragments
[1].DataSize
= ChildSaSession
->NiBlkSize
;
2001 Fragments
[2].Data
= ChildSaSession
->NrBlock
;
2002 Fragments
[2].DataSize
= ChildSaSession
->NrBlkSize
;
2005 // Get the key length of Authenticaion, Encryption, PRF, and Integrity.
2007 SaParams
= ChildSaSession
->SessionCommon
.SaParams
;
2008 EncryptAlgKeyLen
= IpSecGetEncryptKeyLength ((UINT8
)SaParams
->EncAlgId
);
2009 IntegrityAlgKeyLen
= IpSecGetHmacDigestLength ((UINT8
)SaParams
->IntegAlgId
);
2010 OutputKeyLength
= 2 * EncryptAlgKeyLen
+ 2 * IntegrityAlgKeyLen
;
2012 if ((EncryptAlgKeyLen
== 0) || (IntegrityAlgKeyLen
== 0)) {
2013 Status
= EFI_UNSUPPORTED
;
2019 // If KePayload is not NULL, calculate KEYMAT = prf+(SK_d, g^ir (new) | Ni | Nr ),
2020 // otherwise, KEYMAT = prf+(SK_d, Ni | Nr )
2022 OutputKey
= AllocateZeroPool (OutputKeyLength
);
2023 if (OutputKey
== NULL
) {
2024 Status
= EFI_OUT_OF_RESOURCES
;
2029 // Derive Key from the SkdKey Buffer.
2031 Status
= Ikev2SaGenerateKey (
2032 (UINT8
)ChildSaSession
->IkeSaSession
->SessionCommon
.SaParams
->Prf
,
2033 ChildSaSession
->IkeSaSession
->IkeKeys
->SkdKey
,
2034 ChildSaSession
->IkeSaSession
->IkeKeys
->SkdKeySize
,
2037 KePayload
== NULL
? &Fragments
[1] : Fragments
,
2038 KePayload
== NULL
? 2 : 3
2041 if (EFI_ERROR (Status
)) {
2046 // Copy KEYMATE (SK_ENCRYPT_i | SK_ENCRYPT_r | SK_INTEG_i | SK_INTEG_r) to
2049 if (!ChildSaSession
->SessionCommon
.IsInitiator
) {
2052 // Initiator Encryption Key
2054 ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.EncAlgoId
= (UINT8
)SaParams
->EncAlgId
;
2055 ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.EncKeyLength
= EncryptAlgKeyLen
;
2056 ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.EncKey
= AllocateZeroPool (EncryptAlgKeyLen
);
2057 if (ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.EncKey
== NULL
) {
2058 Status
= EFI_OUT_OF_RESOURCES
;
2063 ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.EncKey
,
2069 // Initiator Authentication Key
2071 ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.AuthAlgoId
= (UINT8
)SaParams
->IntegAlgId
;
2072 ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.AuthKeyLength
= IntegrityAlgKeyLen
;
2073 ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.AuthKey
= AllocateZeroPool (IntegrityAlgKeyLen
);
2074 if (ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.AuthKey
== NULL
) {
2075 Status
= EFI_OUT_OF_RESOURCES
;
2080 ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.AuthKey
,
2081 OutputKey
+ EncryptAlgKeyLen
,
2086 // Responder Encrypt Key
2088 ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.EncAlgoId
= (UINT8
)SaParams
->EncAlgId
;
2089 ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.EncKeyLength
= EncryptAlgKeyLen
;
2090 ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.EncKey
= AllocateZeroPool (EncryptAlgKeyLen
);
2091 if (ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.EncKey
== NULL
) {
2092 Status
= EFI_OUT_OF_RESOURCES
;
2097 ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.EncKey
,
2098 OutputKey
+ EncryptAlgKeyLen
+ IntegrityAlgKeyLen
,
2103 // Responder Authentication Key
2105 ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.AuthAlgoId
= (UINT8
)SaParams
->IntegAlgId
;
2106 ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.AuthKeyLength
= IntegrityAlgKeyLen
;
2107 ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.AuthKey
= AllocateZeroPool (IntegrityAlgKeyLen
);
2108 if (ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.AuthKey
== NULL
) {
2109 Status
= EFI_OUT_OF_RESOURCES
;
2114 ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.AuthKey
,
2115 OutputKey
+ 2 * EncryptAlgKeyLen
+ IntegrityAlgKeyLen
,
2120 // Initiator Encryption Key
2122 ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.EncAlgoId
= (UINT8
)SaParams
->EncAlgId
;
2123 ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.EncKeyLength
= EncryptAlgKeyLen
;
2124 ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.EncKey
= AllocateZeroPool (EncryptAlgKeyLen
);
2125 if (ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.EncKey
== NULL
) {
2126 Status
= EFI_OUT_OF_RESOURCES
;
2131 ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.EncKey
,
2137 // Initiator Authentication Key
2139 ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.AuthAlgoId
= (UINT8
)SaParams
->IntegAlgId
;
2140 ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.AuthKeyLength
= IntegrityAlgKeyLen
;
2141 ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.AuthKey
= AllocateZeroPool (IntegrityAlgKeyLen
);
2142 if (ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.AuthKey
== NULL
) {
2143 Status
= EFI_OUT_OF_RESOURCES
;
2148 ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.AuthKey
,
2149 OutputKey
+ EncryptAlgKeyLen
,
2154 // Responder Encryption Key
2156 ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.EncAlgoId
= (UINT8
)SaParams
->EncAlgId
;
2157 ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.EncKeyLength
= EncryptAlgKeyLen
;
2158 ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.EncKey
= AllocateZeroPool (EncryptAlgKeyLen
);
2159 if (ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.EncKey
== NULL
) {
2160 Status
= EFI_OUT_OF_RESOURCES
;
2165 ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.EncKey
,
2166 OutputKey
+ EncryptAlgKeyLen
+ IntegrityAlgKeyLen
,
2171 // Responder Authentication Key
2173 ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.AuthAlgoId
= (UINT8
)SaParams
->IntegAlgId
;
2174 ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.AuthKeyLength
= IntegrityAlgKeyLen
;
2175 ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.AuthKey
= AllocateZeroPool (IntegrityAlgKeyLen
);
2176 if (ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.AuthKey
== NULL
) {
2177 Status
= EFI_OUT_OF_RESOURCES
;
2182 ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.AuthKey
,
2183 OutputKey
+ 2 * EncryptAlgKeyLen
+ IntegrityAlgKeyLen
,
2189 " >>> Local Encryption Key",
2190 ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.EncKey
,
2194 " >>> Remote Encryption Key",
2195 ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.EncKey
,
2199 " >>> Local Authentication Key",
2200 ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.AuthKey
,
2204 " >>> Remote Authentication Key",
2205 ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.AuthKey
,
2212 if (EFI_ERROR (Status
)) {
2213 if (ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.EncKey
!= NULL
) {
2214 FreePool (ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.EncKey
);
2216 if (ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.AuthKey
!= NULL
) {
2217 FreePool (ChildSaSession
->ChildKeymats
.LocalPeerInfo
.EspAlgoInfo
.AuthKey
);
2219 if (ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.EncKey
!= NULL
) {
2220 FreePool (ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.EncKey
);
2222 if (ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.AuthKey
!= NULL
) {
2223 FreePool (ChildSaSession
->ChildKeymats
.RemotePeerInfo
.EspAlgoInfo
.AuthKey
);
2227 if (OutputKey
!= NULL
) {
2228 FreePool (OutputKey
);
2234 GLOBAL_REMOVE_IF_UNREFERENCED IKEV2_PACKET_HANDLER mIkev2Initial
[][2] = {
2238 Ikev2InitPskGenerator
2242 Ikev2AuthPskGenerator
2247 Ikev2InitCertParser
,
2248 Ikev2InitCertGenerator
2251 Ikev2AuthCertParser
,
2252 Ikev2AuthCertGenerator