2 The implementation of Payloads Creation.
4 Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php.
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #include "IpSecDebug.h"
18 #include "IpSecConfigImpl.h"
19 #include "IpSecCryptIo.h"
22 // The Constant String of "Key Pad for IKEv2" for Authentication Payload generation.
24 #define CONSTANT_KEY_SIZE 17
25 GLOBAL_REMOVE_IF_UNREFERENCED CHAR8 mConstantKey
[CONSTANT_KEY_SIZE
] =
27 'K', 'e', 'y', ' ', 'P', 'a', 'd', ' ', 'f', 'o', 'r', ' ', 'I', 'K', 'E', 'v', '2'
31 Generate Ikev2 SA payload according to SessionSaData
33 @param[in] SessionSaData The data used in SA payload.
34 @param[in] NextPayload The payload type presented in NextPayload field of
36 @param[in] Type The SA type. It MUST be neither (1) for IKE_SA or
37 (2) for CHILD_SA or (3) for INFO.
39 @retval a Pointer to SA IKE payload.
43 Ikev2GenerateSaPayload (
44 IN IKEV2_SA_DATA
*SessionSaData
,
46 IN IKE_SESSION_TYPE Type
49 IKE_PAYLOAD
*SaPayload
;
50 IKEV2_SA_DATA
*SaData
;
53 SaPayload
= IkePayloadAlloc ();
54 ASSERT (SaPayload
!= NULL
);
56 // TODO: Get the Proposal Number and Transform Number from IPsec Config,
57 // after the Ipsecconfig Application is support it.
60 if (Type
== IkeSessionTypeIkeSa
) {
61 SaDataSize
= sizeof (IKEV2_SA_DATA
) +
62 SessionSaData
->NumProposals
* sizeof (IKEV2_PROPOSAL_DATA
) +
63 sizeof (IKEV2_TRANSFORM_DATA
) * SessionSaData
->NumProposals
* 4;
65 SaDataSize
= sizeof (IKEV2_SA_DATA
) +
66 SessionSaData
->NumProposals
* sizeof (IKEV2_PROPOSAL_DATA
) +
67 sizeof (IKEV2_TRANSFORM_DATA
) * SessionSaData
->NumProposals
* 3;
71 SaData
= AllocateZeroPool (SaDataSize
);
72 ASSERT (SaData
!= NULL
);
74 CopyMem (SaData
, SessionSaData
, SaDataSize
);
75 SaData
->SaHeader
.Header
.NextPayload
= NextPayload
;
76 SaPayload
->PayloadType
= IKEV2_PAYLOAD_TYPE_SA
;
77 SaPayload
->PayloadBuf
= (UINT8
*) SaData
;
83 Generate a Nonce payload containing the input parameter NonceBuf.
85 @param[in] NonceBuf The nonce buffer contains the whole Nonce payload block
86 except the payload header.
87 @param[in] NonceSize The buffer size of the NonceBuf
88 @param[in] NextPayload The payload type presented in the NextPayload field
89 of Nonce Payload header.
91 @retval Pointer to Nonce IKE paload.
95 Ikev2GenerateNoncePayload (
101 IKE_PAYLOAD
*NoncePayload
;
107 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
108 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
109 // ! Next Payload !C! RESERVED ! Payload Length !
110 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
114 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
116 Size
= sizeof (IKEV2_NONCE
) + NonceSize
;
117 NonceBlock
= NonceBuf
;
119 Nonce
= AllocateZeroPool (Size
);
120 ASSERT (Nonce
!= NULL
);
121 CopyMem (Nonce
+ 1, NonceBlock
, Size
- sizeof (IKEV2_NONCE
));
123 Nonce
->Header
.NextPayload
= NextPayload
;
124 Nonce
->Header
.PayloadLength
= (UINT16
) Size
;
125 NoncePayload
= IkePayloadAlloc ();
127 ASSERT (NoncePayload
!= NULL
);
128 NoncePayload
->PayloadType
= IKEV2_PAYLOAD_TYPE_NONCE
;
129 NoncePayload
->PayloadBuf
= (UINT8
*) Nonce
;
130 NoncePayload
->PayloadSize
= Size
;
136 Generate a Key Exchange payload according to the DH group type and save the
137 public Key into IkeSaSession IkeKey field.
139 @param[in, out] IkeSaSession Pointer of the IKE_SA_SESSION.
140 @param[in] NextPayload The payload type presented in the NextPayload field of Key
141 Exchange Payload header.
143 @retval Pointer to Key IKE payload.
147 Ikev2GenerateKePayload (
148 IN OUT IKEV2_SA_SESSION
*IkeSaSession
,
152 IKE_PAYLOAD
*KePayload
;
153 IKEV2_KEY_EXCHANGE
*Ke
;
155 IKEV2_SESSION_KEYS
*IkeKeys
;
159 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
160 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
161 // ! Next Payload !C! RESERVED ! Payload Length !
162 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
163 // ! DH Group # ! RESERVED !
164 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
166 // ~ Key Exchange Data ~
168 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
170 IkeKeys
= IkeSaSession
->IkeKeys
;
172 if (IkeSaSession
->SessionCommon
.IsInitiator
) {
173 KeSize
= sizeof (IKEV2_KEY_EXCHANGE
) + IkeKeys
->DhBuffer
->GxSize
;
175 KeSize
= sizeof (IKEV2_KEY_EXCHANGE
) + IkeKeys
->DhBuffer
->GxSize
;
179 // Allocate buffer for Key Exchange
181 Ke
= AllocateZeroPool (KeSize
);
184 Ke
->Header
.NextPayload
= NextPayload
;
185 Ke
->Header
.PayloadLength
= (UINT16
) KeSize
;
186 Ke
->DhGroup
= IkeSaSession
->SessionCommon
.PreferDhGroup
;
188 CopyMem (Ke
+ 1, IkeKeys
->DhBuffer
->GxBuffer
, IkeKeys
->DhBuffer
->GxSize
);
191 // Create IKE_PAYLOAD to point to Key Exchange payload
193 KePayload
= IkePayloadAlloc ();
194 ASSERT (KePayload
!= NULL
);
196 KePayload
->PayloadType
= IKEV2_PAYLOAD_TYPE_KE
;
197 KePayload
->PayloadBuf
= (UINT8
*) Ke
;
198 KePayload
->PayloadSize
= KeSize
;
203 Generate a ID payload.
205 @param[in] CommonSession Pointer to IKEV2_SESSION_COMMON related to ID payload.
206 @param[in] NextPayload The payload type presented in the NextPayload field
207 of ID Payload header.
209 @retval Pointer to ID IKE payload.
213 Ikev2GenerateIdPayload (
214 IN IKEV2_SESSION_COMMON
*CommonSession
,
218 IKE_PAYLOAD
*IdPayload
;
226 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
227 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
228 // ! Next Payload ! RESERVED ! Payload Length !
229 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
230 // ! ID Type ! RESERVED !
231 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
233 // ~ Identification Data ~
235 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
238 IpVersion
= CommonSession
->UdpService
->IpVersion
;
239 AddrSize
= (UINT8
) ((IpVersion
== IP_VERSION_4
) ? sizeof(EFI_IPv4_ADDRESS
) : sizeof(EFI_IPv6_ADDRESS
));
240 IdSize
= sizeof (IKEV2_ID
) + AddrSize
;
242 Id
= (IKEV2_ID
*) AllocateZeroPool (IdSize
);
245 IdPayload
= IkePayloadAlloc ();
246 ASSERT (IdPayload
!= NULL
);
248 IdPayload
->PayloadType
= (UINT8
) ((CommonSession
->IsInitiator
) ? IKEV2_PAYLOAD_TYPE_ID_INIT
: IKEV2_PAYLOAD_TYPE_ID_RSP
);
249 IdPayload
->PayloadBuf
= (UINT8
*) Id
;
250 IdPayload
->PayloadSize
= IdSize
;
253 // Set generic header of identification payload
255 Id
->Header
.NextPayload
= NextPayload
;
256 Id
->Header
.PayloadLength
= (UINT16
) IdSize
;
257 Id
->IdType
= (UINT8
) ((IpVersion
== IP_VERSION_4
) ? IKEV2_ID_TYPE_IPV4_ADDR
: IKEV2_ID_TYPE_IPV6_ADDR
);
258 CopyMem (Id
+ 1, &CommonSession
->LocalPeerIp
, AddrSize
);
264 Generate a ID payload.
266 @param[in] CommonSession Pointer to IKEV2_SESSION_COMMON related to ID payload.
267 @param[in] NextPayload The payload type presented in the NextPayload field
268 of ID Payload header.
269 @param[in] InCert Pointer to the Certificate which distinguished name
270 will be added into the Id payload.
271 @param[in] CertSize Size of the Certificate.
273 @retval Pointer to ID IKE payload.
277 Ikev2GenerateCertIdPayload (
278 IN IKEV2_SESSION_COMMON
*CommonSession
,
279 IN UINT8 NextPayload
,
284 IKE_PAYLOAD
*IdPayload
;
293 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
294 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
295 // ! Next Payload ! RESERVED ! Payload Length !
296 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
297 // ! ID Type ! RESERVED !
298 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
300 // ~ Identification Data ~
302 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
307 IpVersion
= CommonSession
->UdpService
->IpVersion
;
308 IpSecCryptoIoGetSubjectFromCert (
314 if (SubjectSize
!= 0) {
315 ASSERT (CertSubject
!= NULL
);
318 IdSize
= sizeof (IKEV2_ID
) + SubjectSize
;
320 Id
= (IKEV2_ID
*) AllocateZeroPool (IdSize
);
323 IdPayload
= IkePayloadAlloc ();
324 ASSERT (IdPayload
!= NULL
);
326 IdPayload
->PayloadType
= (UINT8
) ((CommonSession
->IsInitiator
) ? IKEV2_PAYLOAD_TYPE_ID_INIT
: IKEV2_PAYLOAD_TYPE_ID_RSP
);
327 IdPayload
->PayloadBuf
= (UINT8
*) Id
;
328 IdPayload
->PayloadSize
= IdSize
;
331 // Set generic header of identification payload
333 Id
->Header
.NextPayload
= NextPayload
;
334 Id
->Header
.PayloadLength
= (UINT16
) IdSize
;
336 CopyMem (Id
+ 1, CertSubject
, SubjectSize
);
338 if (CertSubject
!= NULL
) {
339 FreePool (CertSubject
);
345 Generate a Authentication Payload.
347 This function is used for both Authentication generation and verification. When the
348 IsVerify is TRUE, it create a Auth Data for verification. This function choose the
349 related IKE_SA_INIT Message for Auth data creation according to the IKE Session's type
350 and the value of IsVerify parameter.
352 @param[in] IkeSaSession Pointer to IKEV2_SA_SESSION related to.
353 @param[in] IdPayload Pointer to the ID payload to be used for Authentication
355 @param[in] NextPayload The type filled into the Authentication Payload next
357 @param[in] IsVerify If it is TURE, the Authentication payload is used for
360 @return pointer to IKE Authentication payload for Pre-shared key method.
364 Ikev2PskGenerateAuthPayload (
365 IN IKEV2_SA_SESSION
*IkeSaSession
,
366 IN IKE_PAYLOAD
*IdPayload
,
367 IN UINT8 NextPayload
,
373 PRF_DATA_FRAGMENT Fragments
[3];
376 IKE_PAYLOAD
*AuthPayload
;
377 IKEV2_AUTH
*PayloadBuf
;
381 // Auth = Prf(Prf(Secret,"Key Pad for IKEv2),IKE_SA_INIi/r|Ni/r|Prf(SK_Pr, IDi/r))
384 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
385 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
386 // ! Next Payload !C! RESERVED ! Payload Length !
387 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
388 // ! Auth Method ! RESERVED !
389 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
391 // ~ Authentication Data ~
393 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
400 DigestSize
= IpSecGetHmacDigestLength ((UINT8
)IkeSaSession
->SessionCommon
.SaParams
->Prf
);
401 Digest
= AllocateZeroPool (DigestSize
);
403 if (Digest
== NULL
) {
406 if (IdPayload
== NULL
) {
410 // Calcualte Prf(Seceret, "Key Pad for IKEv2");
412 Fragments
[0].Data
= (UINT8
*) mConstantKey
;
413 Fragments
[0].DataSize
= CONSTANT_KEY_SIZE
;
415 Status
= IpSecCryptoIoHmac (
416 (UINT8
)IkeSaSession
->SessionCommon
.SaParams
->Prf
,
417 IkeSaSession
->Pad
->Data
->AuthData
,
418 IkeSaSession
->Pad
->Data
->AuthDataSize
,
419 (HASH_DATA_FRAGMENT
*)Fragments
,
424 if (EFI_ERROR (Status
)) {
429 // Store the AuthKey into KeyBuf
431 KeyBuf
= AllocateZeroPool (DigestSize
);
432 ASSERT (KeyBuf
!= NULL
);
433 CopyMem (KeyBuf
, Digest
, DigestSize
);
434 KeySize
= DigestSize
;
437 // Calculate Prf(SK_Pi/r, IDi/r)
439 Fragments
[0].Data
= IdPayload
->PayloadBuf
+ sizeof (IKEV2_COMMON_PAYLOAD_HEADER
);
440 Fragments
[0].DataSize
= IdPayload
->PayloadSize
- sizeof (IKEV2_COMMON_PAYLOAD_HEADER
);
442 if ((IkeSaSession
->SessionCommon
.IsInitiator
&& IsVerify
) ||
443 (!IkeSaSession
->SessionCommon
.IsInitiator
&& !IsVerify
)
445 Status
= IpSecCryptoIoHmac (
446 (UINT8
)IkeSaSession
->SessionCommon
.SaParams
->Prf
,
447 IkeSaSession
->IkeKeys
->SkPrKey
,
448 IkeSaSession
->IkeKeys
->SkPrKeySize
,
449 (HASH_DATA_FRAGMENT
*) Fragments
,
455 Status
= IpSecCryptoIoHmac (
456 (UINT8
)IkeSaSession
->SessionCommon
.SaParams
->Prf
,
457 IkeSaSession
->IkeKeys
->SkPiKey
,
458 IkeSaSession
->IkeKeys
->SkPiKeySize
,
459 (HASH_DATA_FRAGMENT
*) Fragments
,
465 if (EFI_ERROR (Status
)) {
470 // Copy data to Fragments.
472 if ((IkeSaSession
->SessionCommon
.IsInitiator
&& IsVerify
) ||
473 (!IkeSaSession
->SessionCommon
.IsInitiator
&& !IsVerify
)
475 Fragments
[0].Data
= IkeSaSession
->RespPacket
;
476 Fragments
[0].DataSize
= IkeSaSession
->RespPacketSize
;
477 Fragments
[1].Data
= IkeSaSession
->NiBlock
;
478 Fragments
[1].DataSize
= IkeSaSession
->NiBlkSize
;
480 Fragments
[0].Data
= IkeSaSession
->InitPacket
;
481 Fragments
[0].DataSize
= IkeSaSession
->InitPacketSize
;
482 Fragments
[1].Data
= IkeSaSession
->NrBlock
;
483 Fragments
[1].DataSize
= IkeSaSession
->NrBlkSize
;
487 // Copy the result of Prf(SK_Pr, IDi/r) to Fragments[2].
489 Fragments
[2].Data
= AllocateZeroPool (DigestSize
);
490 Fragments
[2].DataSize
= DigestSize
;
491 CopyMem (Fragments
[2].Data
, Digest
, DigestSize
);
494 // Calculate Prf(Key,IKE_SA_INIi/r|Ni/r|Prf(SK_Pr, IDi/r))
496 Status
= IpSecCryptoIoHmac (
497 (UINT8
)IkeSaSession
->SessionCommon
.SaParams
->Prf
,
500 (HASH_DATA_FRAGMENT
*) Fragments
,
505 if (EFI_ERROR (Status
)) {
510 // Allocate buffer for Auth Payload
512 AuthPayload
= IkePayloadAlloc ();
513 ASSERT (AuthPayload
!= NULL
);
515 AuthPayload
->PayloadSize
= sizeof (IKEV2_AUTH
) + DigestSize
;
516 PayloadBuf
= (IKEV2_AUTH
*) AllocateZeroPool (AuthPayload
->PayloadSize
);
517 ASSERT (PayloadBuf
!= NULL
);
519 // Fill in Auth payload.
521 PayloadBuf
->Header
.NextPayload
= NextPayload
;
522 PayloadBuf
->Header
.PayloadLength
= (UINT16
) (AuthPayload
->PayloadSize
);
523 if (IkeSaSession
->Pad
->Data
->AuthMethod
== EfiIPsecAuthMethodPreSharedSecret
) {
525 // Only support Shared Key Message Integrity
527 PayloadBuf
->AuthMethod
= IKEV2_AUTH_METHOD_SKMI
;
530 // Not support other Auth method.
532 Status
= EFI_UNSUPPORTED
;
537 // Copy the result of Prf(Key,IKE_SA_INIi/r|Ni/r|Prf(SK_Pr, IDi/r)) to Auth
547 // Fill in IKE_PACKET
549 AuthPayload
->PayloadBuf
= (UINT8
*) PayloadBuf
;
550 AuthPayload
->PayloadType
= IKEV2_PAYLOAD_TYPE_AUTH
;
553 if (KeyBuf
!= NULL
) {
556 if (Digest
!= NULL
) {
559 if (Fragments
[2].Data
!= NULL
) {
561 // Free the buffer which contains the result of Prf(SK_Pr, IDi/r)
563 FreePool (Fragments
[2].Data
);
566 if (EFI_ERROR (Status
)) {
567 if (AuthPayload
!= NULL
) {
568 IkePayloadFree (AuthPayload
);
577 Generate a Authentication Payload for Certificate Auth method.
579 This function has two functions. One is creating a local Authentication
580 Payload for sending and other is creating the remote Authentication data
581 for verification when the IsVerify is TURE.
583 @param[in] IkeSaSession Pointer to IKEV2_SA_SESSION related to.
584 @param[in] IdPayload Pointer to the ID payload to be used for Authentication
586 @param[in] NextPayload The type filled into the Authentication Payload
588 @param[in] IsVerify If it is TURE, the Authentication payload is used
590 @param[in] UefiPrivateKey Pointer to the UEFI private key. Ignore it when
591 verify the authenticate payload.
592 @param[in] UefiPrivateKeyLen The size of UefiPrivateKey in bytes. Ignore it
593 when verify the authenticate payload.
594 @param[in] UefiKeyPwd Pointer to the password of UEFI private key.
595 Ignore it when verify the authenticate payload.
596 @param[in] UefiKeyPwdLen The size of UefiKeyPwd in bytes.Ignore it when
597 verify the authenticate payload.
599 @return pointer to IKE Authentication payload for Cerifitcation method.
603 Ikev2CertGenerateAuthPayload (
604 IN IKEV2_SA_SESSION
*IkeSaSession
,
605 IN IKE_PAYLOAD
*IdPayload
,
606 IN UINT8 NextPayload
,
608 IN UINT8
*UefiPrivateKey
,
609 IN UINTN UefiPrivateKeyLen
,
610 IN UINT8
*UefiKeyPwd
,
611 IN UINTN UefiKeyPwdLen
616 PRF_DATA_FRAGMENT Fragments
[3];
619 IKE_PAYLOAD
*AuthPayload
;
620 IKEV2_AUTH
*PayloadBuf
;
626 // Auth = Prf(Scert,IKE_SA_INIi/r|Ni/r|Prf(SK_Pr, IDi/r))
629 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
630 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
631 // ! Next Payload !C! RESERVED ! Payload Length !
632 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
633 // ! Auth Method ! RESERVED !
634 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
636 // ~ Authentication Data ~
638 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
649 if (IdPayload
== NULL
) {
652 DigestSize
= IpSecGetHmacDigestLength ((UINT8
)IkeSaSession
->SessionCommon
.SaParams
->Prf
);
653 Digest
= AllocateZeroPool (DigestSize
);
655 if (Digest
== NULL
) {
660 // Store the AuthKey into KeyBuf
662 KeyBuf
= AllocateZeroPool (DigestSize
);
663 ASSERT (KeyBuf
!= NULL
);
665 CopyMem (KeyBuf
, Digest
, DigestSize
);
666 KeySize
= DigestSize
;
669 // Calculate Prf(SK_Pi/r, IDi/r)
671 Fragments
[0].Data
= IdPayload
->PayloadBuf
+ sizeof (IKEV2_COMMON_PAYLOAD_HEADER
);
672 Fragments
[0].DataSize
= IdPayload
->PayloadSize
- sizeof (IKEV2_COMMON_PAYLOAD_HEADER
);
674 IpSecDumpBuf ("RestofIDPayload", Fragments
[0].Data
, Fragments
[0].DataSize
);
676 if ((IkeSaSession
->SessionCommon
.IsInitiator
&& IsVerify
) ||
677 (!IkeSaSession
->SessionCommon
.IsInitiator
&& !IsVerify
)
679 Status
= IpSecCryptoIoHmac(
680 (UINT8
)IkeSaSession
->SessionCommon
.SaParams
->Prf
,
681 IkeSaSession
->IkeKeys
->SkPrKey
,
682 IkeSaSession
->IkeKeys
->SkPrKeySize
,
683 (HASH_DATA_FRAGMENT
*) Fragments
,
688 IpSecDumpBuf ("MACedIDForR", Digest
, DigestSize
);
690 Status
= IpSecCryptoIoHmac (
691 (UINT8
)IkeSaSession
->SessionCommon
.SaParams
->Prf
,
692 IkeSaSession
->IkeKeys
->SkPiKey
,
693 IkeSaSession
->IkeKeys
->SkPiKeySize
,
694 (HASH_DATA_FRAGMENT
*) Fragments
,
699 IpSecDumpBuf ("MACedIDForI", Digest
, DigestSize
);
701 if (EFI_ERROR (Status
)) {
706 // Copy data to Fragments.
708 if ((IkeSaSession
->SessionCommon
.IsInitiator
&& IsVerify
) ||
709 (!IkeSaSession
->SessionCommon
.IsInitiator
&& !IsVerify
)
711 Fragments
[0].Data
= IkeSaSession
->RespPacket
;
712 Fragments
[0].DataSize
= IkeSaSession
->RespPacketSize
;
713 Fragments
[1].Data
= IkeSaSession
->NiBlock
;
714 Fragments
[1].DataSize
= IkeSaSession
->NiBlkSize
;
715 IpSecDumpBuf ("RealMessage2", Fragments
[0].Data
, Fragments
[0].DataSize
);
716 IpSecDumpBuf ("NonceIDdata", Fragments
[1].Data
, Fragments
[1].DataSize
);
718 Fragments
[0].Data
= IkeSaSession
->InitPacket
;
719 Fragments
[0].DataSize
= IkeSaSession
->InitPacketSize
;
720 Fragments
[1].Data
= IkeSaSession
->NrBlock
;
721 Fragments
[1].DataSize
= IkeSaSession
->NrBlkSize
;
722 IpSecDumpBuf ("RealMessage1", Fragments
[0].Data
, Fragments
[0].DataSize
);
723 IpSecDumpBuf ("NonceRDdata", Fragments
[1].Data
, Fragments
[1].DataSize
);
727 // Copy the result of Prf(SK_Pr, IDi/r) to Fragments[2].
729 Fragments
[2].Data
= AllocateZeroPool (DigestSize
);
730 Fragments
[2].DataSize
= DigestSize
;
731 CopyMem (Fragments
[2].Data
, Digest
, DigestSize
);
734 // Calculate Prf(Key,IKE_SA_INIi/r|Ni/r|Prf(SK_Pr, IDi/r))
736 Status
= IpSecCryptoIoHash (
737 (UINT8
)IkeSaSession
->SessionCommon
.SaParams
->Prf
,
738 (HASH_DATA_FRAGMENT
*) Fragments
,
743 if (EFI_ERROR (Status
)) {
747 IpSecDumpBuf ("HashSignedOctects", Digest
, DigestSize
);
749 // Sign the data by the private Key
752 IpSecCryptoIoAuthDataWithCertificate (
763 if (SigSize
== 0 || Signature
== NULL
) {
769 // Allocate buffer for Auth Payload
771 AuthPayload
= IkePayloadAlloc ();
772 ASSERT (AuthPayload
!= NULL
);
775 AuthPayload
->PayloadSize
= sizeof (IKEV2_AUTH
) + SigSize
;
777 AuthPayload
->PayloadSize
= sizeof (IKEV2_AUTH
) + DigestSize
;
780 PayloadBuf
= (IKEV2_AUTH
*) AllocateZeroPool (AuthPayload
->PayloadSize
);
781 ASSERT (PayloadBuf
!= NULL
);
783 // Fill in Auth payload.
785 PayloadBuf
->Header
.NextPayload
= NextPayload
;
786 PayloadBuf
->Header
.PayloadLength
= (UINT16
) (AuthPayload
->PayloadSize
);
787 if (IkeSaSession
->Pad
->Data
->AuthMethod
== EfiIPsecAuthMethodCertificates
) {
788 PayloadBuf
->AuthMethod
= IKEV2_AUTH_METHOD_RSA
;
790 Status
= EFI_INVALID_PARAMETER
;
795 // Copy the result of Prf(Key,IKE_SA_INIi/r|Ni/r|Prf(SK_Pr, IDi/r)) to Auth
799 CopyMem (PayloadBuf
+ 1, Signature
, SigSize
);
801 CopyMem (PayloadBuf
+ 1, Digest
, DigestSize
);
805 // Fill in IKE_PACKET
807 AuthPayload
->PayloadBuf
= (UINT8
*) PayloadBuf
;
808 AuthPayload
->PayloadType
= IKEV2_PAYLOAD_TYPE_AUTH
;
811 if (KeyBuf
!= NULL
) {
814 if (Digest
!= NULL
) {
817 if (Signature
!= NULL
) {
818 FreePool (Signature
);
820 if (Fragments
[2].Data
!= NULL
) {
822 // Free the buffer which contains the result of Prf(SK_Pr, IDi/r)
824 FreePool (Fragments
[2].Data
);
827 if (EFI_ERROR (Status
)) {
828 if (AuthPayload
!= NULL
) {
829 IkePayloadFree (AuthPayload
);
840 This function generates TSi or TSr payload according to type of next payload.
841 If the next payload is Responder TS, gereate TSi Payload. Otherwise, generate
844 @param[in] ChildSa Pointer to IKEV2_CHILD_SA_SESSION related to this TS payload.
845 @param[in] NextPayload The payload type presented in the NextPayload field
846 of ID Payload header.
847 @param[in] IsTunnel It indicates that if the Ts Payload is after the CP payload.
848 If yes, it means the Tsi and Tsr payload should be with
849 Max port range and address range and protocol is marked
852 @retval Pointer to Ts IKE payload.
856 Ikev2GenerateTsPayload (
857 IN IKEV2_CHILD_SA_SESSION
*ChildSa
,
858 IN UINT8 NextPayload
,
862 IKE_PAYLOAD
*TsPayload
;
863 IKEV2_TS
*TsPayloadBuf
;
864 TRAFFIC_SELECTOR
*TsSelector
;
872 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
873 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
874 // ! Next Payload !C! RESERVED ! Payload Length !
875 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
876 // ! Number of TSs ! RESERVED !
877 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
879 // ~ <Traffic Selectors> ~
881 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
884 TsPayload
= IkePayloadAlloc();
885 ASSERT (TsPayload
!= NULL
);
887 IpVersion
= ChildSa
->SessionCommon
.UdpService
->IpVersion
;
889 // The Starting Address and Ending Address is variable length depends on
892 AddrSize
= (UINT8
)((IpVersion
== IP_VERSION_4
) ? sizeof (EFI_IPv4_ADDRESS
) : sizeof (EFI_IPv6_ADDRESS
));
893 SelectorSize
= sizeof (TRAFFIC_SELECTOR
) + 2 * AddrSize
;
894 TsPayloadSize
= sizeof (IKEV2_TS
) + SelectorSize
;
895 TsPayloadBuf
= AllocateZeroPool (TsPayloadSize
);
896 ASSERT (TsPayloadBuf
!= NULL
);
898 TsPayload
->PayloadBuf
= (UINT8
*) TsPayloadBuf
;
899 TsSelector
= (TRAFFIC_SELECTOR
*)(TsPayloadBuf
+ 1);
901 TsSelector
->TSType
= (UINT8
)((IpVersion
== IP_VERSION_4
) ? IKEV2_TS_TYPE_IPV4_ADDR_RANGE
: IKEV2_TS_TYPS_IPV6_ADDR_RANGE
);
907 TsSelector
->IpProtocolId
= IKEV2_TS_ANY_PROTOCOL
;
908 TsSelector
->SelecorLen
= (UINT16
) SelectorSize
;
909 TsSelector
->StartPort
= 0;
910 TsSelector
->EndPort
= IKEV2_TS_ANY_PORT
;
911 ZeroMem ((UINT8
*)TsSelector
+ sizeof(TRAFFIC_SELECTOR
), AddrSize
);
912 SetMem ((UINT8
*)TsSelector
+ sizeof(TRAFFIC_SELECTOR
) + AddrSize
, AddrSize
, 0xff);
916 // TODO: Support port range and address range
918 if (NextPayload
== IKEV2_PAYLOAD_TYPE_TS_RSP
){
920 // Create initiator Traffic Selector
922 TsSelector
->SelecorLen
= (UINT16
)SelectorSize
;
925 // Currently only support the port range from 0~0xffff. Don't support other
927 // TODO: support Port range
929 if (ChildSa
->SessionCommon
.IsInitiator
) {
930 if (ChildSa
->Spd
->Selector
->LocalPort
!= 0 &&
931 ChildSa
->Spd
->Selector
->LocalPortRange
== 0) {
933 // For not port range.
935 TsSelector
->StartPort
= ChildSa
->Spd
->Selector
->LocalPort
;
936 TsSelector
->EndPort
= ChildSa
->Spd
->Selector
->LocalPort
;
937 } else if (ChildSa
->Spd
->Selector
->LocalPort
== 0){
939 // For port from 0~0xffff
941 TsSelector
->StartPort
= 0;
942 TsSelector
->EndPort
= IKEV2_TS_ANY_PORT
;
950 if (ChildSa
->Spd
->Selector
->RemotePort
!= 0 &&
951 ChildSa
->Spd
->Selector
->RemotePortRange
== 0) {
953 // For not port range.
955 TsSelector
->StartPort
= ChildSa
->Spd
->Selector
->RemotePort
;
956 TsSelector
->EndPort
= ChildSa
->Spd
->Selector
->RemotePort
;
957 } else if (ChildSa
->Spd
->Selector
->RemotePort
== 0) {
959 // For port from 0~0xffff
961 TsSelector
->StartPort
= 0;
962 TsSelector
->EndPort
= IKEV2_TS_ANY_PORT
;
971 // Copy Address.Currently the address range is not supported.
972 // The Starting address is same as Ending address
973 // TODO: Support Address Range.
976 (UINT8
*)TsSelector
+ sizeof(TRAFFIC_SELECTOR
),
977 ChildSa
->SessionCommon
.IsInitiator
?
978 ChildSa
->Spd
->Selector
->LocalAddress
:
979 ChildSa
->Spd
->Selector
->RemoteAddress
,
983 (UINT8
*)TsSelector
+ sizeof(TRAFFIC_SELECTOR
) + AddrSize
,
984 ChildSa
->SessionCommon
.IsInitiator
?
985 ChildSa
->Spd
->Selector
->LocalAddress
:
986 ChildSa
->Spd
->Selector
->RemoteAddress
,
990 // If the Next Payload is not TS responder, this TS payload type is the TS responder.
992 TsPayload
->PayloadType
= IKEV2_PAYLOAD_TYPE_TS_INIT
;
995 // Create responder Traffic Selector
997 TsSelector
->SelecorLen
= (UINT16
)SelectorSize
;
1000 // Currently only support the port range from 0~0xffff. Don't support other
1002 // TODO: support Port range
1004 if (!ChildSa
->SessionCommon
.IsInitiator
) {
1005 if (ChildSa
->Spd
->Selector
->LocalPort
!= 0 &&
1006 ChildSa
->Spd
->Selector
->LocalPortRange
== 0) {
1008 // For not port range.
1010 TsSelector
->StartPort
= ChildSa
->Spd
->Selector
->LocalPort
;
1011 TsSelector
->EndPort
= ChildSa
->Spd
->Selector
->LocalPort
;
1012 } else if (ChildSa
->Spd
->Selector
->LocalPort
== 0){
1014 // For port from 0~0xffff
1016 TsSelector
->StartPort
= 0;
1017 TsSelector
->EndPort
= IKEV2_TS_ANY_PORT
;
1025 if (ChildSa
->Spd
->Selector
->RemotePort
!= 0 &&
1026 ChildSa
->Spd
->Selector
->RemotePortRange
== 0) {
1028 // For not port range.
1030 TsSelector
->StartPort
= ChildSa
->Spd
->Selector
->RemotePort
;
1031 TsSelector
->EndPort
= ChildSa
->Spd
->Selector
->RemotePort
;
1032 } else if (ChildSa
->Spd
->Selector
->RemotePort
== 0){
1034 // For port from 0~0xffff
1036 TsSelector
->StartPort
= 0;
1037 TsSelector
->EndPort
= IKEV2_TS_ANY_PORT
;
1046 // Copy Address.Currently the address range is not supported.
1047 // The Starting address is same as Ending address
1048 // TODO: Support Address Range.
1051 (UINT8
*)TsSelector
+ sizeof(TRAFFIC_SELECTOR
),
1052 ChildSa
->SessionCommon
.IsInitiator
?
1053 ChildSa
->Spd
->Selector
->RemoteAddress
:
1054 ChildSa
->Spd
->Selector
->LocalAddress
,
1058 (UINT8
*)TsSelector
+ sizeof(TRAFFIC_SELECTOR
) + AddrSize
,
1059 ChildSa
->SessionCommon
.IsInitiator
?
1060 ChildSa
->Spd
->Selector
->RemoteAddress
:
1061 ChildSa
->Spd
->Selector
->LocalAddress
,
1065 // If the Next Payload is not TS responder, this TS payload type is the TS responder.
1067 TsPayload
->PayloadType
= IKEV2_PAYLOAD_TYPE_TS_RSP
;
1071 if (ChildSa
->Spd
->Selector
->NextLayerProtocol
!= 0xffff) {
1072 TsSelector
->IpProtocolId
= (UINT8
)ChildSa
->Spd
->Selector
->NextLayerProtocol
;
1074 TsSelector
->IpProtocolId
= IKEV2_TS_ANY_PROTOCOL
;
1077 TsPayloadBuf
->Header
.NextPayload
= NextPayload
;
1078 TsPayloadBuf
->Header
.PayloadLength
= (UINT16
)TsPayloadSize
;
1079 TsPayloadBuf
->TSNumbers
= 1;
1080 TsPayload
->PayloadSize
= TsPayloadSize
;
1084 if (TsPayload
!= NULL
) {
1085 IkePayloadFree (TsPayload
);
1093 Generate the Notify payload.
1095 Since the structure of Notify payload which defined in RFC 4306 is simple, so
1096 there is no internal data structure for Notify payload. This function generate
1097 Notify payload defined in RFC 4306, but all the fields in this payload are still
1098 in host order and need call Ikev2EncodePayload() to convert those fields from
1099 the host order to network order beforing sending it.
1101 @param[in] ProtocolId The protocol type ID. For IKE_SA it MUST be one (1).
1102 For IPsec SAs it MUST be neither (2) for AH or (3)
1104 @param[in] NextPayload The next paylaod type in NextPayload field of
1106 @param[in] SpiSize Size of the SPI in SPI size field of the Notify Payload.
1107 @param[in] MessageType The message type in NotifyMessageType field of the
1109 @param[in] SpiBuf Pointer to buffer contains the SPI value.
1110 @param[in] NotifyData Pointer to buffer contains the notification data.
1111 @param[in] NotifyDataSize The size of NotifyData in bytes.
1114 @retval Pointer to IKE Notify Payload.
1118 Ikev2GenerateNotifyPayload (
1119 IN UINT8 ProtocolId
,
1120 IN UINT8 NextPayload
,
1122 IN UINT16 MessageType
,
1124 IN UINT8
*NotifyData
,
1125 IN UINTN NotifyDataSize
1128 IKE_PAYLOAD
*NotifyPayload
;
1129 IKEV2_NOTIFY
*Notify
;
1130 UINT16 NotifyPayloadLen
;
1134 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1135 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1136 // ! Next Payload !C! RESERVED ! Payload Length !
1137 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1138 // ! Protocol ID ! SPI Size ! Notify Message Type !
1139 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1141 // ~ Security Parameter Index (SPI) ~
1143 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1145 // ~ Notification Data ~
1147 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1150 NotifyPayloadLen
= (UINT16
) (sizeof (IKEV2_NOTIFY
) + NotifyDataSize
+ SpiSize
);
1151 Notify
= (IKEV2_NOTIFY
*) AllocateZeroPool (NotifyPayloadLen
);
1152 ASSERT (Notify
!= NULL
);
1155 // Set Delete Payload's Generic Header
1157 Notify
->Header
.NextPayload
= NextPayload
;
1158 Notify
->Header
.PayloadLength
= NotifyPayloadLen
;
1159 Notify
->SpiSize
= SpiSize
;
1160 Notify
->ProtocolId
= ProtocolId
;
1161 Notify
->MessageType
= MessageType
;
1164 // Copy Spi , for Cookie Notify, there is no SPI.
1166 if (SpiBuf
!= NULL
&& SpiSize
!= 0 ) {
1167 CopyMem (Notify
+ 1, SpiBuf
, SpiSize
);
1170 MessageData
= ((UINT8
*) (Notify
+ 1)) + SpiSize
;
1173 // Copy Notification Data
1175 if (NotifyDataSize
!= 0) {
1176 CopyMem (MessageData
, NotifyData
, NotifyDataSize
);
1180 // Create Payload for and set type as IKEV2_PAYLOAD_TYPE_NOTIFY
1182 NotifyPayload
= IkePayloadAlloc ();
1183 ASSERT (NotifyPayload
!= NULL
);
1184 NotifyPayload
->PayloadType
= IKEV2_PAYLOAD_TYPE_NOTIFY
;
1185 NotifyPayload
->PayloadBuf
= (UINT8
*) Notify
;
1186 NotifyPayload
->PayloadSize
= NotifyPayloadLen
;
1187 return NotifyPayload
;
1191 Generate the Delete payload.
1193 Since the structure of Delete payload which defined in RFC 4306 is simple,
1194 there is no internal data structure for Delete payload. This function generate
1195 Delete payload defined in RFC 4306, but all the fields in this payload are still
1196 in host order and need call Ikev2EncodePayload() to convert those fields from
1197 the host order to network order beforing sending it.
1199 @param[in] IkeSaSession Pointer to IKE SA Session to be used of Delete payload generation.
1200 @param[in] NextPayload The next paylaod type in NextPayload field of
1202 @param[in] SpiSize Size of the SPI in SPI size field of the Delete Payload.
1203 @param[in] SpiNum Number of SPI in NumofSPIs field of the Delete Payload.
1204 @param[in] SpiBuf Pointer to buffer contains the SPI value.
1206 @retval a Pointer of IKE Delete Payload.
1210 Ikev2GenerateDeletePayload (
1211 IN IKEV2_SA_SESSION
*IkeSaSession
,
1212 IN UINT8 NextPayload
,
1219 IKE_PAYLOAD
*DelPayload
;
1222 UINT16 DelPayloadLen
;
1225 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1226 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1227 // ! Next Payload !C! RESERVED ! Payload Length !
1228 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1229 // ! Protocol ID ! SPI Size ! # of SPIs !
1230 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1232 // ~ Security Parameter Index(es) (SPI) ~
1234 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1236 SpiBufSize
= (UINT16
) (SpiSize
* SpiNum
);
1237 if (SpiBufSize
!= 0 && SpiBuf
== NULL
) {
1241 DelPayloadLen
= (UINT16
) (sizeof (IKEV2_DELETE
) + SpiBufSize
);
1243 Del
= AllocateZeroPool (DelPayloadLen
);
1244 ASSERT (Del
!= NULL
);
1247 // Set Delete Payload's Generic Header
1249 Del
->Header
.NextPayload
= NextPayload
;
1250 Del
->Header
.PayloadLength
= DelPayloadLen
;
1251 Del
->NumSpis
= SpiNum
;
1252 Del
->SpiSize
= SpiSize
;
1256 // TODO: should consider the AH if needs to support.
1258 Del
->ProtocolId
= IPSEC_PROTO_IPSEC_ESP
;
1260 Del
->ProtocolId
= IPSEC_PROTO_ISAKMP
;
1264 // Set Del Payload's Idntification Data
1266 CopyMem (Del
+ 1, SpiBuf
, SpiBufSize
);
1267 DelPayload
= IkePayloadAlloc ();
1268 ASSERT (DelPayload
!= NULL
);
1269 DelPayload
->PayloadType
= IKEV2_PAYLOAD_TYPE_DELETE
;
1270 DelPayload
->PayloadBuf
= (UINT8
*) Del
;
1271 DelPayload
->PayloadSize
= DelPayloadLen
;
1276 Generate the Configuration payload.
1278 This function generate configuration payload defined in RFC 4306, but all the
1279 fields in this payload are still in host order and need call Ikev2EncodePayload()
1280 to convert those fields from the host order to network order beforing sending it.
1282 @param[in] IkeSaSession Pointer to IKE SA Session to be used for Delete payload
1284 @param[in] NextPayload The next paylaod type in NextPayload field of
1286 @param[in] CfgType The attribute type in the Configuration attribute.
1288 @retval Pointer to IKE CP Payload.
1292 Ikev2GenerateCpPayload (
1293 IN IKEV2_SA_SESSION
*IkeSaSession
,
1294 IN UINT8 NextPayload
,
1298 IKE_PAYLOAD
*CpPayload
;
1301 IKEV2_CFG_ATTRIBUTES
*CfgAttributes
;
1304 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1305 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1306 // ! Next Payload !C! RESERVED ! Payload Length !
1307 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1308 // ! CFG Type ! RESERVED !
1309 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1311 // ~ Configuration Attributes ~
1313 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1316 PayloadLen
= (UINT16
) (sizeof (IKEV2_CFG
) + sizeof (IKEV2_CFG_ATTRIBUTES
));
1317 Cfg
= (IKEV2_CFG
*) AllocateZeroPool (PayloadLen
);
1323 CfgAttributes
= (IKEV2_CFG_ATTRIBUTES
*)((UINT8
*)Cfg
+ sizeof (IKEV2_CFG
));
1326 // Only generate the configuration payload with an empty INTERNAL_IP4_ADDRESS
1327 // or INTERNAL_IP6_ADDRESS.
1330 Cfg
->Header
.NextPayload
= NextPayload
;
1331 Cfg
->Header
.PayloadLength
= PayloadLen
;
1332 Cfg
->CfgType
= IKEV2_CFG_TYPE_REQUEST
;
1334 CfgAttributes
->AttritType
= CfgType
;
1335 CfgAttributes
->ValueLength
= 0;
1337 CpPayload
= IkePayloadAlloc ();
1338 if (CpPayload
== NULL
) {
1345 CpPayload
->PayloadType
= IKEV2_PAYLOAD_TYPE_CP
;
1346 CpPayload
->PayloadBuf
= (UINT8
*) Cfg
;
1347 CpPayload
->PayloadSize
= PayloadLen
;
1352 Parser the Notify Cookie payload.
1354 This function parses the Notify Cookie payload.If the Notify ProtocolId is not
1355 IPSEC_PROTO_ISAKMP or if the SpiSize is not zero or if the MessageType is not
1356 the COOKIE, return EFI_INVALID_PARAMETER.
1358 @param[in] IkeNCookie Pointer to the IKE_PAYLOAD which contians the
1359 Notify Cookie payload.
1361 @param[in, out] IkeSaSession Pointer to the relevant IKE SA Session.
1363 @retval EFI_SUCCESS The Notify Cookie Payload is valid.
1364 @retval EFI_INVALID_PARAMETER The Notify Cookie Payload is invalid.
1365 @retval EFI_OUT_OF_RESOURCE The required resource can't be allocated.
1369 Ikev2ParserNotifyCookiePayload (
1370 IN IKE_PAYLOAD
*IkeNCookie
,
1371 IN OUT IKEV2_SA_SESSION
*IkeSaSession
1374 IKEV2_NOTIFY
*NotifyPayload
;
1375 UINTN NotifyDataSize
;
1377 NotifyPayload
= (IKEV2_NOTIFY
*)IkeNCookie
->PayloadBuf
;
1379 if ((NotifyPayload
->ProtocolId
!= IPSEC_PROTO_ISAKMP
) ||
1380 (NotifyPayload
->SpiSize
!= 0) ||
1381 (NotifyPayload
->MessageType
!= IKEV2_NOTIFICATION_COOKIE
)
1383 return EFI_INVALID_PARAMETER
;
1386 NotifyDataSize
= NotifyPayload
->Header
.PayloadLength
- sizeof (IKEV2_NOTIFY
);
1387 IkeSaSession
->NCookie
= AllocateZeroPool (NotifyDataSize
);
1388 if (IkeSaSession
->NCookie
== NULL
) {
1389 return EFI_OUT_OF_RESOURCES
;
1392 IkeSaSession
->NCookieSize
= NotifyDataSize
;
1395 IkeSaSession
->NCookie
,
1396 NotifyPayload
+ sizeof (IKEV2_NOTIFY
),
1405 Generate the Certificate payload or Certificate Request Payload.
1407 Since the Certificate Payload structure is same with Certificate Request Payload,
1408 the only difference is that one contains the Certificate Data, other contains
1409 the acceptable certificateion CA. This function generate Certificate payload
1410 or Certificate Request Payload defined in RFC 4306, but all the fields
1411 in the payload are still in host order and need call Ikev2EncodePayload()
1412 to convert those fields from the host order to network order beforing sending it.
1414 @param[in] IkeSaSession Pointer to IKE SA Session to be used of Delete payload
1416 @param[in] NextPayload The next paylaod type in NextPayload field of
1418 @param[in] Certificate Pointer of buffer contains the certification data.
1419 @param[in] CertificateLen The length of Certificate in byte.
1420 @param[in] EncodeType Specified the Certificate Encodeing which is defined
1422 @param[in] IsRequest To indicate create Certificate Payload or Certificate
1423 Request Payload. If it is TURE, create Certificate
1424 Payload. Otherwise, create Certificate Request Payload.
1426 @retval a Pointer to IKE Payload whose payload buffer containing the Certificate
1427 payload or Certificated Request payload.
1431 Ikev2GenerateCertificatePayload (
1432 IN IKEV2_SA_SESSION
*IkeSaSession
,
1433 IN UINT8 NextPayload
,
1434 IN UINT8
*Certificate
,
1435 IN UINTN CertificateLen
,
1436 IN UINT8 EncodeType
,
1437 IN BOOLEAN IsRequest
1440 IKE_PAYLOAD
*CertPayload
;
1445 HASH_DATA_FRAGMENT Fragment
[1];
1452 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1453 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1454 // ! Next Payload !C! RESERVED ! Payload Length !
1455 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1456 // ! Cert Encoding ! !
1457 // +-+-+-+-+-+-+-+-+ !
1458 // ~ Certificate Data/Authority ~
1460 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1463 Status
= EFI_SUCCESS
;
1468 PayloadLen
= (UINT16
) (sizeof (IKEV2_CERT
) + CertificateLen
);
1471 // SHA1 Hash length is 20.
1473 PayloadLen
= (UINT16
) (sizeof (IKEV2_CERT
) + 20);
1476 Cert
= AllocateZeroPool (PayloadLen
);
1482 // Generate Certificate Payload or Certificate Request Payload.
1484 Cert
->Header
.NextPayload
= NextPayload
;
1485 Cert
->Header
.PayloadLength
= PayloadLen
;
1486 Cert
->CertEncoding
= EncodeType
;
1489 ((UINT8
*)Cert
) + sizeof (IKEV2_CERT
),
1494 Status
= IpSecCryptoIoGetPublicKeyFromCert (
1500 if (EFI_ERROR (Status
)) {
1504 Fragment
[0].Data
= PublicKey
;
1505 Fragment
[0].DataSize
= PublicKeyLen
;
1506 HashDataSize
= IpSecGetHmacDigestLength (IKE_AALG_SHA1HMAC
);
1507 HashData
= AllocateZeroPool (HashDataSize
);
1508 if (HashData
== NULL
) {
1512 Status
= IpSecCryptoIoHash (
1519 if (EFI_ERROR (Status
)) {
1524 ((UINT8
*)Cert
) + sizeof (IKEV2_CERT
),
1530 CertPayload
= IkePayloadAlloc ();
1531 if (CertPayload
== NULL
) {
1536 CertPayload
->PayloadType
= IKEV2_PAYLOAD_TYPE_CERT
;
1538 CertPayload
->PayloadType
= IKEV2_PAYLOAD_TYPE_CERTREQ
;
1541 CertPayload
->PayloadBuf
= (UINT8
*) Cert
;
1542 CertPayload
->PayloadSize
= PayloadLen
;
1549 if (PublicKey
!= NULL
) {
1550 FreePool (PublicKey
);
1556 Remove and free all IkePayloads in the specified IkePacket.
1558 @param[in] IkePacket The pointer of IKE_PACKET.
1563 IN IKE_PACKET
*IkePacket
1566 LIST_ENTRY
*PayloadEntry
;
1567 IKE_PAYLOAD
*IkePayload
;
1569 // remove all payloads from list and free each payload.
1571 while (!IsListEmpty (&IkePacket
->PayloadList
)) {
1572 PayloadEntry
= IkePacket
->PayloadList
.ForwardLink
;
1573 IkePayload
= IKE_PAYLOAD_BY_PACKET (PayloadEntry
);
1574 IKE_PACKET_REMOVE_PAYLOAD (IkePacket
, IkePayload
);
1575 IkePayloadFree (IkePayload
);
1580 Transfer the intrnal data structure IKEV2_SA_DATA to IKEV2_SA structure defined in RFC.
1582 @param[in] SessionCommon Pointer to IKEV2_SESSION_COMMON related to the SA Session.
1583 @param[in] SaData Pointer to IKEV2_SA_DATA to be transfered.
1585 @retval return the pointer of IKEV2_SA.
1590 IN IKEV2_SESSION_COMMON
*SessionCommon
,
1591 IN IKEV2_SA_DATA
*SaData
1596 IKEV2_PROPOSAL_DATA
*ProposalData
;
1597 IKEV2_TRANSFORM_DATA
*TransformData
;
1598 UINTN TotalTransforms
;
1600 UINTN TransformsSize
;
1601 UINTN TransformSize
;
1602 UINTN ProposalsSize
;
1604 UINTN ProposalIndex
;
1605 UINTN TransformIndex
;
1606 IKE_SA_ATTRIBUTE
*SaAttribute
;
1607 IKEV2_PROPOSAL
*Proposal
;
1608 IKEV2_PROPOSAL
*LastProposal
;
1609 IKEV2_TRANSFORM
*Transform
;
1610 IKEV2_TRANSFORM
*LastTransform
;
1613 // Transform IKE_SA_DATA structure to IKE_SA Payload.
1614 // Header length is host order.
1615 // The returned IKE_SA struct should be freed by caller.
1617 TotalTransforms
= 0;
1619 // Caculate the Proposal numbers and Transform numbers.
1621 for (ProposalIndex
= 0; ProposalIndex
< SaData
->NumProposals
; ProposalIndex
++) {
1623 ProposalData
= (IKEV2_PROPOSAL_DATA
*) (SaData
+ 1) + ProposalIndex
;
1624 TotalTransforms
+= ProposalData
->NumTransforms
;
1627 SaSize
= sizeof (IKEV2_SA
) +
1628 SaData
->NumProposals
* sizeof (IKEV2_PROPOSAL
) +
1629 TotalTransforms
* (sizeof (IKEV2_TRANSFORM
) + MAX_SA_ATTRS_SIZE
);
1631 // Allocate buffer for IKE_SA.
1633 Sa
= AllocateZeroPool (SaSize
);
1634 ASSERT (Sa
!= NULL
);
1635 CopyMem (Sa
, SaData
, sizeof (IKEV2_SA
));
1636 Sa
->Header
.PayloadLength
= (UINT16
) sizeof (IKEV2_SA
);
1638 LastProposal
= NULL
;
1639 Proposal
= (IKEV2_PROPOSAL
*) (Sa
+ 1);
1644 ProposalData
= (IKEV2_PROPOSAL_DATA
*) (SaData
+ 1);
1645 for (ProposalIndex
= 0; ProposalIndex
< SaData
->NumProposals
; ProposalIndex
++) {
1646 Proposal
->ProposalIndex
= ProposalData
->ProposalIndex
;
1647 Proposal
->ProtocolId
= ProposalData
->ProtocolId
;
1648 Proposal
->NumTransforms
= ProposalData
->NumTransforms
;
1650 if (ProposalData
->Spi
== 0) {
1651 Proposal
->SpiSize
= 0;
1653 Proposal
->SpiSize
= 4;
1654 *(UINT32
*) (Proposal
+ 1) = HTONL (*((UINT32
*)ProposalData
->Spi
));
1658 LastTransform
= NULL
;
1659 Transform
= (IKEV2_TRANSFORM
*) ((UINT8
*) (Proposal
+ 1) + Proposal
->SpiSize
);
1662 // Set IKE_TRANSFORM
1664 for (TransformIndex
= 0; TransformIndex
< ProposalData
->NumTransforms
; TransformIndex
++) {
1665 TransformData
= (IKEV2_TRANSFORM_DATA
*) (ProposalData
+ 1) + TransformIndex
;
1666 Transform
->TransformType
= TransformData
->TransformType
;
1667 Transform
->TransformId
= HTONS (TransformData
->TransformId
);
1671 // If the Encryption Algorithm is variable key length set the key length in attribute.
1672 // Note that only a single attribute type (Key Length) is defined and it is fixed length.
1674 if (Transform
->TransformType
== IKEV2_TRANSFORM_TYPE_ENCR
&& TransformData
->Attribute
.Attr
.AttrValue
!= 0) {
1675 SaAttribute
= (IKE_SA_ATTRIBUTE
*) (Transform
+ 1);
1676 SaAttribute
->AttrType
= HTONS (IKEV2_ATTRIBUTE_TYPE_KEYLEN
| SA_ATTR_FORMAT_BIT
);
1677 SaAttribute
->Attr
.AttrValue
= HTONS (TransformData
->Attribute
.Attr
.AttrValue
);
1678 SaAttrsSize
= sizeof (IKE_SA_ATTRIBUTE
);
1682 // If the Integrity Algorithm is variable key length set the key length in attribute.
1684 if (Transform
->TransformType
== IKEV2_TRANSFORM_TYPE_INTEG
&& TransformData
->Attribute
.Attr
.AttrValue
!= 0) {
1685 SaAttribute
= (IKE_SA_ATTRIBUTE
*) (Transform
+ 1);
1686 SaAttribute
->AttrType
= HTONS (IKEV2_ATTRIBUTE_TYPE_KEYLEN
| SA_ATTR_FORMAT_BIT
);
1687 SaAttribute
->Attr
.AttrValue
= HTONS (TransformData
->Attribute
.Attr
.AttrValue
);
1688 SaAttrsSize
= sizeof (IKE_SA_ATTRIBUTE
);
1691 TransformSize
= sizeof (IKEV2_TRANSFORM
) + SaAttrsSize
;
1692 TransformsSize
+= TransformSize
;
1694 Transform
->Header
.NextPayload
= IKE_TRANSFORM_NEXT_PAYLOAD_MORE
;
1695 Transform
->Header
.PayloadLength
= HTONS ((UINT16
)TransformSize
);
1697 if (TransformIndex
== ProposalData
->NumTransforms
) {
1698 LastTransform
->Header
.NextPayload
= IKE_TRANSFORM_NEXT_PAYLOAD_NONE
;
1701 Transform
= (IKEV2_TRANSFORM
*)((UINT8
*) Transform
+ TransformSize
);
1705 // Set Proposal's Generic Header.
1707 ProposalSize
= sizeof (IKEV2_PROPOSAL
) + Proposal
->SpiSize
+ TransformsSize
;
1708 ProposalsSize
+= ProposalSize
;
1709 Proposal
->Header
.NextPayload
= IKE_PROPOSAL_NEXT_PAYLOAD_MORE
;
1710 Proposal
->Header
.PayloadLength
= HTONS ((UINT16
)ProposalSize
);
1712 if (ProposalIndex
== SaData
->NumProposals
) {
1713 LastProposal
->Header
.NextPayload
= IKE_PROPOSAL_NEXT_PAYLOAD_NONE
;
1717 // Point to next Proposal Payload
1719 Proposal
= (IKEV2_PROPOSAL
*) ((UINT8
*) Proposal
+ ProposalSize
);
1720 ProposalData
= (IKEV2_PROPOSAL_DATA
*)(((UINT8
*)ProposalData
) + sizeof (IKEV2_PROPOSAL_DATA
) + (TransformIndex
* sizeof (IKEV2_TRANSFORM_DATA
)));
1723 // Set SA's Generic Header.
1725 Sa
->Header
.PayloadLength
= (UINT16
) (Sa
->Header
.PayloadLength
+ ProposalsSize
);
1732 This function converts the received SA payload to internal data structure.
1734 @param[in] SessionCommon Pointer to IKE Common Session used to decode the SA
1736 @param[in] Sa Pointer to SA Payload
1738 @return a Pointer to internal data structure for SA payload.
1743 IN IKEV2_SESSION_COMMON
*SessionCommon
,
1747 IKEV2_SA_DATA
*SaData
;
1749 IKEV2_PROPOSAL
*Proposal
;
1750 IKEV2_TRANSFORM
*Transform
;
1751 UINTN TotalProposals
;
1752 UINTN TotalTransforms
;
1753 UINTN ProposalNextPayloadSum
;
1754 UINTN ProposalIndex
;
1755 UINTN TransformIndex
;
1757 UINT16 ProposalSize
;
1758 UINTN ProposalRemaining
;
1759 UINT16 TransformSize
;
1760 UINTN SaAttrRemaining
;
1761 IKE_SA_ATTRIBUTE
*SaAttribute
;
1762 IKEV2_PROPOSAL_DATA
*ProposalData
;
1763 IKEV2_TRANSFORM_DATA
*TransformData
;
1767 // Transfrom from IKE_SA payload to IKE_SA_DATA structure.
1768 // Header length NTOH is already done
1769 // The returned IKE_SA_DATA should be freed by caller
1772 Status
= EFI_SUCCESS
;
1775 // First round sanity check and size calculae
1778 TotalTransforms
= 0;
1779 ProposalNextPayloadSum
= 0;
1780 SaRemaining
= Sa
->Header
.PayloadLength
- sizeof (IKEV2_SA
);// Point to current position in SA
1781 Proposal
= (IKEV2_PROPOSAL
*)((IKEV2_SA
*)(Sa
)+1);
1784 // Caculate the number of Proposal payload and the total numbers of
1785 // Transforms payload (the transforms in all proposal payload).
1787 while (SaRemaining
> sizeof (IKEV2_PROPOSAL
)) {
1788 ProposalSize
= NTOHS (Proposal
->Header
.PayloadLength
);
1789 if (SaRemaining
< ProposalSize
) {
1790 Status
= EFI_INVALID_PARAMETER
;
1794 if (Proposal
->SpiSize
!= 0 && Proposal
->SpiSize
!= 4) {
1795 Status
= EFI_INVALID_PARAMETER
;
1800 TotalTransforms
+= Proposal
->NumTransforms
;
1801 SaRemaining
-= ProposalSize
;
1802 ProposalNextPayloadSum
+= Proposal
->Header
.NextPayload
;
1803 Proposal
= IKEV2_NEXT_PROPOSAL_WITH_SIZE (Proposal
, ProposalSize
);
1807 // Check the proposal number. The Proposal Payload type is 2. Nonce Paylod is 0.
1808 // SUM(ProposalNextPayload) = Proposal Num * 2 + Noce Payload Type (0).
1810 if (TotalProposals
== 0 ||
1811 (TotalProposals
- 1) * IKE_PROPOSAL_NEXT_PAYLOAD_MORE
+ IKE_PROPOSAL_NEXT_PAYLOAD_NONE
!= ProposalNextPayloadSum
1813 Status
= EFI_INVALID_PARAMETER
;
1818 // Second round sanity check and decode. Transform the SA payload into
1819 // a IKE_SA_DATA structure.
1821 SaData
= (IKEV2_SA_DATA
*) AllocateZeroPool (
1822 sizeof (IKEV2_SA_DATA
) +
1823 TotalProposals
* sizeof (IKEV2_PROPOSAL_DATA
) +
1824 TotalTransforms
* sizeof (IKEV2_TRANSFORM_DATA
)
1826 ASSERT (SaData
!= NULL
);
1827 CopyMem (SaData
, Sa
, sizeof (IKEV2_SA
));
1828 SaData
->NumProposals
= TotalProposals
;
1829 ProposalData
= (IKEV2_PROPOSAL_DATA
*) (SaData
+ 1);
1833 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1834 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1835 // ! Next Payload ! RESERVED ! Payload Length !
1836 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1837 // ! Proposal # ! Protocol-Id ! SPI Size !# of Transforms!
1838 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1839 // ! SPI (variable) !
1840 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1842 for (ProposalIndex
= 0, Proposal
= IKEV2_SA_FIRST_PROPOSAL (Sa
);
1843 ProposalIndex
< TotalProposals
;
1848 // TODO: check ProposalId
1850 ProposalData
->ProposalIndex
= Proposal
->ProposalIndex
;
1851 ProposalData
->ProtocolId
= Proposal
->ProtocolId
;
1852 if (Proposal
->SpiSize
== 0) {
1853 ProposalData
->Spi
= 0;
1858 Spi
= AllocateZeroPool (Proposal
->SpiSize
);
1859 ASSERT (Spi
!= NULL
);
1860 CopyMem (Spi
, (UINT32
*) (Proposal
+ 1), Proposal
->SpiSize
);
1861 *((UINT32
*) Spi
) = NTOHL (*((UINT32
*) Spi
));
1862 ProposalData
->Spi
= Spi
;
1865 ProposalData
->NumTransforms
= Proposal
->NumTransforms
;
1866 ProposalSize
= NTOHS (Proposal
->Header
.PayloadLength
);
1867 ProposalRemaining
= ProposalSize
;
1869 // Transform Payload
1870 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1871 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1872 // ! Next Payload ! RESERVED ! Payload Length !
1873 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1874 // !Transform Type ! RESERVED ! Transform ID !
1875 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1877 // ~ SA Attributes ~
1879 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1881 Transform
= IKEV2_PROPOSAL_FIRST_TRANSFORM (Proposal
);
1882 for (TransformIndex
= 0; TransformIndex
< Proposal
->NumTransforms
; TransformIndex
++) {
1885 // Transfer the IKEV2_TRANSFORM structure into internal IKEV2_TRANSFORM_DATA struture.
1887 TransformData
= (IKEV2_TRANSFORM_DATA
*) (ProposalData
+ 1) + TransformIndex
;
1888 TransformData
->TransformId
= NTOHS (Transform
->TransformId
);
1889 TransformData
->TransformType
= Transform
->TransformType
;
1890 TransformSize
= NTOHS (Transform
->Header
.PayloadLength
);
1892 // Check the Proposal Data is correct.
1894 if (ProposalRemaining
< TransformSize
) {
1895 Status
= EFI_INVALID_PARAMETER
;
1900 // Check if the Transform payload includes Attribution.
1902 SaAttrRemaining
= TransformSize
- sizeof (IKEV2_TRANSFORM
);
1905 // According to RFC 4603, currently only the Key length attribute type is
1906 // supported. For each Transform, there is only one attributeion.
1908 if (SaAttrRemaining
> 0) {
1909 if (SaAttrRemaining
!= sizeof (IKE_SA_ATTRIBUTE
)) {
1910 Status
= EFI_INVALID_PARAMETER
;
1913 SaAttribute
= (IKE_SA_ATTRIBUTE
*) ((IKEV2_TRANSFORM
*)(Transform
) + 1);
1914 TransformData
->Attribute
.AttrType
= (UINT16
)((NTOHS (SaAttribute
->AttrType
)) & ~SA_ATTR_FORMAT_BIT
);
1915 TransformData
->Attribute
.Attr
.AttrValue
= NTOHS (SaAttribute
->Attr
.AttrValue
);
1918 // Currently, only supports the Key Length Attribution.
1920 if (TransformData
->Attribute
.AttrType
!= IKEV2_ATTRIBUTE_TYPE_KEYLEN
) {
1921 Status
= EFI_INVALID_PARAMETER
;
1927 // Move to next Transform
1929 Transform
= IKEV2_NEXT_TRANSFORM_WITH_SIZE (Transform
, TransformSize
);
1931 Proposal
= IKEV2_NEXT_PROPOSAL_WITH_SIZE (Proposal
, ProposalSize
);
1932 ProposalData
= (IKEV2_PROPOSAL_DATA
*) ((UINT8
*)(ProposalData
+ 1) +
1933 ProposalData
->NumTransforms
*
1934 sizeof (IKEV2_TRANSFORM_DATA
));
1938 if (EFI_ERROR (Status
) && SaData
!= NULL
) {
1946 General interface of payload encoding.
1948 This function encodes the internal data structure into payload which
1949 is defined in RFC 4306. The IkePayload->PayloadBuf is used to store both the input
1950 payload and converted payload. Only the SA payload use the interal structure
1951 to store the attribute. Other payload use structure which is same with the RFC
1952 defined, for this kind payloads just do host order to network order change of
1955 @param[in] SessionCommon Pointer to IKE Session Common used to encode the payload.
1956 @param[in, out] IkePayload Pointer to IKE payload to be encoded as input, and
1957 store the encoded result as output.
1959 @retval EFI_INVALID_PARAMETER Meet error when encoding the SA payload.
1960 @retval EFI_SUCCESS Encoded successfully.
1964 Ikev2EncodePayload (
1965 IN UINT8
*SessionCommon
,
1966 IN OUT IKE_PAYLOAD
*IkePayload
1969 IKEV2_SA_DATA
*SaData
;
1970 IKEV2_SA
*SaPayload
;
1971 IKEV2_COMMON_PAYLOAD_HEADER
*PayloadHdr
;
1972 IKEV2_NOTIFY
*NotifyPayload
;
1973 IKEV2_DELETE
*DeletePayload
;
1974 IKEV2_KEY_EXCHANGE
*KeyPayload
;
1975 IKEV2_TS
*TsPayload
;
1976 IKEV2_CFG_ATTRIBUTES
*CfgAttribute
;
1979 TRAFFIC_SELECTOR
*TrafficSelector
;
1982 // Transform the Internal IKE structure to IKE payload.
1983 // Only the SA payload use the interal structure to store the attribute.
1984 // Other payload use structure which same with the RFC defined, so there is
1985 // no need to tranform them to IKE payload.
1987 switch (IkePayload
->PayloadType
) {
1988 case IKEV2_PAYLOAD_TYPE_SA
:
1990 // Transform IKE_SA_DATA to IK_SA payload
1992 SaData
= (IKEV2_SA_DATA
*) IkePayload
->PayloadBuf
;
1993 SaPayload
= Ikev2EncodeSa ((IKEV2_SESSION_COMMON
*) SessionCommon
, SaData
);
1995 if (SaPayload
== NULL
) {
1996 return EFI_INVALID_PARAMETER
;
1998 if (!IkePayload
->IsPayloadBufExt
) {
1999 FreePool (IkePayload
->PayloadBuf
);
2001 IkePayload
->PayloadBuf
= (UINT8
*) SaPayload
;
2002 IkePayload
->IsPayloadBufExt
= FALSE
;
2005 case IKEV2_PAYLOAD_TYPE_NOTIFY
:
2006 NotifyPayload
= (IKEV2_NOTIFY
*) IkePayload
->PayloadBuf
;
2007 NotifyPayload
->MessageType
= HTONS (NotifyPayload
->MessageType
);
2010 case IKEV2_PAYLOAD_TYPE_DELETE
:
2011 DeletePayload
= (IKEV2_DELETE
*) IkePayload
->PayloadBuf
;
2012 DeletePayload
->NumSpis
= HTONS (DeletePayload
->NumSpis
);
2015 case IKEV2_PAYLOAD_TYPE_KE
:
2016 KeyPayload
= (IKEV2_KEY_EXCHANGE
*) IkePayload
->PayloadBuf
;
2017 KeyPayload
->DhGroup
= HTONS (KeyPayload
->DhGroup
);
2020 case IKEV2_PAYLOAD_TYPE_TS_INIT
:
2021 case IKEV2_PAYLOAD_TYPE_TS_RSP
:
2022 TsPayload
= (IKEV2_TS
*) IkePayload
->PayloadBuf
;
2023 TsBuffer
= IkePayload
->PayloadBuf
+ sizeof (IKEV2_TS
);
2025 for (Index
= 0; Index
< TsPayload
->TSNumbers
; Index
++) {
2026 TrafficSelector
= (TRAFFIC_SELECTOR
*) TsBuffer
;
2027 TsBuffer
= TsBuffer
+ TrafficSelector
->SelecorLen
;
2029 // Host order to network order
2031 TrafficSelector
->SelecorLen
= HTONS (TrafficSelector
->SelecorLen
);
2032 TrafficSelector
->StartPort
= HTONS (TrafficSelector
->StartPort
);
2033 TrafficSelector
->EndPort
= HTONS (TrafficSelector
->EndPort
);
2039 case IKEV2_PAYLOAD_TYPE_CP
:
2040 CfgAttribute
= (IKEV2_CFG_ATTRIBUTES
*)(((IKEV2_CFG
*) IkePayload
->PayloadBuf
) + 1);
2041 CfgAttribute
->AttritType
= HTONS (CfgAttribute
->AttritType
);
2042 CfgAttribute
->ValueLength
= HTONS (CfgAttribute
->ValueLength
);
2044 case IKEV2_PAYLOAD_TYPE_ID_INIT
:
2045 case IKEV2_PAYLOAD_TYPE_ID_RSP
:
2046 case IKEV2_PAYLOAD_TYPE_AUTH
:
2051 PayloadHdr
= (IKEV2_COMMON_PAYLOAD_HEADER
*) IkePayload
->PayloadBuf
;
2052 IkePayload
->PayloadSize
= PayloadHdr
->PayloadLength
;
2053 PayloadHdr
->PayloadLength
= HTONS (PayloadHdr
->PayloadLength
);
2054 IKEV2_DUMP_PAYLOAD (IkePayload
);
2059 The general interface for decoding Payload.
2061 This function converts the received Payload into internal structure.
2063 @param[in] SessionCommon Pointer to IKE Session Common used for decoding.
2064 @param[in, out] IkePayload Pointer to IKE payload to be decoded as input, and
2065 store the decoded result as output.
2067 @retval EFI_INVALID_PARAMETER Meet error when decoding the SA payload.
2068 @retval EFI_SUCCESS Decoded successfully.
2072 Ikev2DecodePayload (
2073 IN UINT8
*SessionCommon
,
2074 IN OUT IKE_PAYLOAD
*IkePayload
2077 IKEV2_COMMON_PAYLOAD_HEADER
*PayloadHdr
;
2080 IKEV2_SA_DATA
*SaData
;
2082 IKEV2_NOTIFY
*NotifyPayload
;
2083 IKEV2_DELETE
*DeletePayload
;
2085 TRAFFIC_SELECTOR
*TsSelector
;
2086 IKEV2_TS
*TsPayload
;
2087 IKEV2_KEY_EXCHANGE
*KeyPayload
;
2088 IKEV2_CFG_ATTRIBUTES
*CfgAttribute
;
2092 // Transform the IKE payload to Internal IKE structure.
2093 // Only the SA payload and Hash Payload use the interal
2094 // structure to store the attribute. Other payloads use
2095 // structure which is same with the definitions in RFC,
2096 // so there is no need to tranform them to internal IKE
2099 Status
= EFI_SUCCESS
;
2100 PayloadSize
= (UINT16
) IkePayload
->PayloadSize
;
2101 PayloadType
= IkePayload
->PayloadType
;
2102 PayloadHdr
= (IKEV2_COMMON_PAYLOAD_HEADER
*) IkePayload
->PayloadBuf
;
2104 // The PayloadSize is the size of whole payload.
2105 // Replace HTONS operation to assignment statements, since the result is same.
2107 PayloadHdr
->PayloadLength
= PayloadSize
;
2109 IKEV2_DUMP_PAYLOAD (IkePayload
);
2110 switch (PayloadType
) {
2111 case IKEV2_PAYLOAD_TYPE_SA
:
2112 if (PayloadSize
< sizeof (IKEV2_SA
)) {
2113 Status
= EFI_INVALID_PARAMETER
;
2117 SaData
= Ikev2DecodeSa ((IKEV2_SESSION_COMMON
*) SessionCommon
, (IKEV2_SA
*) PayloadHdr
);
2118 if (SaData
== NULL
) {
2119 Status
= EFI_INVALID_PARAMETER
;
2123 if (!IkePayload
->IsPayloadBufExt
) {
2124 FreePool (IkePayload
->PayloadBuf
);
2127 IkePayload
->PayloadBuf
= (UINT8
*) SaData
;
2128 IkePayload
->IsPayloadBufExt
= FALSE
;
2131 case IKEV2_PAYLOAD_TYPE_ID_INIT
:
2132 case IKEV2_PAYLOAD_TYPE_ID_RSP
:
2133 if (PayloadSize
< sizeof (IKEV2_ID
)) {
2134 Status
= EFI_INVALID_PARAMETER
;
2139 case IKEV2_PAYLOAD_TYPE_NOTIFY
:
2140 if (PayloadSize
< sizeof (IKEV2_NOTIFY
)) {
2141 Status
= EFI_INVALID_PARAMETER
;
2145 NotifyPayload
= (IKEV2_NOTIFY
*) PayloadHdr
;
2146 NotifyPayload
->MessageType
= NTOHS (NotifyPayload
->MessageType
);
2149 case IKEV2_PAYLOAD_TYPE_DELETE
:
2150 if (PayloadSize
< sizeof (IKEV2_DELETE
)) {
2151 Status
= EFI_INVALID_PARAMETER
;
2155 DeletePayload
= (IKEV2_DELETE
*) PayloadHdr
;
2156 DeletePayload
->NumSpis
= NTOHS (DeletePayload
->NumSpis
);
2159 case IKEV2_PAYLOAD_TYPE_AUTH
:
2160 if (PayloadSize
< sizeof (IKEV2_AUTH
)) {
2161 Status
= EFI_INVALID_PARAMETER
;
2166 case IKEV2_PAYLOAD_TYPE_KE
:
2167 KeyPayload
= (IKEV2_KEY_EXCHANGE
*) IkePayload
->PayloadBuf
;
2168 KeyPayload
->DhGroup
= HTONS (KeyPayload
->DhGroup
);
2171 case IKEV2_PAYLOAD_TYPE_TS_INIT
:
2172 case IKEV2_PAYLOAD_TYPE_TS_RSP
:
2174 if (PayloadSize
< sizeof (IKEV2_TS
)) {
2175 Status
= EFI_INVALID_PARAMETER
;
2179 // Parse each traffic selector and transfer network-order to host-order
2181 TsPayload
= (IKEV2_TS
*) IkePayload
->PayloadBuf
;
2182 TsSelector
= (TRAFFIC_SELECTOR
*) (IkePayload
->PayloadBuf
+ sizeof (IKEV2_TS
));
2184 for (Index
= 0; Index
< TsPayload
->TSNumbers
; Index
++) {
2185 TsSelector
->SelecorLen
= NTOHS (TsSelector
->SelecorLen
);
2186 TsSelector
->StartPort
= NTOHS (TsSelector
->StartPort
);
2187 TsSelector
->EndPort
= NTOHS (TsSelector
->EndPort
);
2189 TsTotalSize
= (UINT16
) (TsTotalSize
+ TsSelector
->SelecorLen
);
2190 TsSelector
= (TRAFFIC_SELECTOR
*) ((UINT8
*) TsSelector
+ TsSelector
->SelecorLen
);
2193 // Check if the total size of Traffic Selectors is correct.
2195 if (TsTotalSize
!= PayloadSize
- sizeof(IKEV2_TS
)) {
2196 Status
= EFI_INVALID_PARAMETER
;
2199 case IKEV2_PAYLOAD_TYPE_CP
:
2200 CfgAttribute
= (IKEV2_CFG_ATTRIBUTES
*)(((IKEV2_CFG
*) IkePayload
->PayloadBuf
) + 1);
2201 CfgAttribute
->AttritType
= NTOHS (CfgAttribute
->AttritType
);
2202 CfgAttribute
->ValueLength
= NTOHS (CfgAttribute
->ValueLength
);
2213 Decode the IKE packet.
2215 This function first decrypts the IKE packet if needed , then separates the whole
2216 IKE packet from the IkePacket->PayloadBuf into IkePacket payload list.
2218 @param[in] SessionCommon Pointer to IKEV1_SESSION_COMMON containing
2219 some parameter used by IKE packet decoding.
2220 @param[in, out] IkePacket The IKE Packet to be decoded on input, and
2221 the decoded result on return.
2222 @param[in] IkeType The type of IKE. IKE_SA_TYPE, IKE_INFO_TYPE and
2223 IKE_CHILD_TYPE are supported.
2225 @retval EFI_SUCCESS The IKE packet is decoded successfully.
2226 @retval Otherwise The IKE packet decoding is failed.
2231 IN IKEV2_SESSION_COMMON
*SessionCommon
,
2232 IN OUT IKE_PACKET
*IkePacket
,
2237 IKEV2_COMMON_PAYLOAD_HEADER
*PayloadHdr
;
2241 IKE_PAYLOAD
*IkePayload
;
2242 IKE_HEADER
*IkeHeader
;
2243 IKEV2_SA_SESSION
*IkeSaSession
;
2248 // Check if the IkePacket need decrypt.
2250 if (SessionCommon
->State
>= IkeStateAuth
) {
2251 Status
= Ikev2DecryptPacket (SessionCommon
, IkePacket
, IkeType
);
2252 if (EFI_ERROR (Status
)) {
2257 Status
= EFI_SUCCESS
;
2260 // If the IkePacket doesn't contain any payload return invalid parameter.
2262 if (IkePacket
->Header
->NextPayload
== IKEV2_PAYLOAD_TYPE_NONE
) {
2263 if ((SessionCommon
->State
>= IkeStateAuth
) &&
2264 (IkePacket
->Header
->ExchangeType
== IKEV2_EXCHANGE_TYPE_INFO
)
2267 // If it is Liveness check, there will be no payload load in the encrypt payload.
2269 Status
= EFI_SUCCESS
;
2271 Status
= EFI_INVALID_PARAMETER
;
2276 // If the PayloadTotalSize < Header length, return invalid parameter.
2278 RemainBytes
= IkePacket
->PayloadTotalSize
;
2279 if (RemainBytes
< sizeof (IKEV2_COMMON_PAYLOAD_HEADER
)) {
2280 Status
= EFI_INVALID_PARAMETER
;
2285 // If the packet is first or second message, store whole message in
2286 // IkeSa->InitiPacket or IkeSa->RespPacket for following Auth Payload
2289 if (IkePacket
->Header
->ExchangeType
== IKEV2_EXCHANGE_TYPE_INIT
) {
2290 IkeHeader
= AllocateZeroPool (sizeof (IKE_HEADER
));
2291 ASSERT (IkeHeader
!= NULL
);
2292 CopyMem (IkeHeader
, IkePacket
->Header
, sizeof (IKE_HEADER
));
2295 // Before store the whole packet, roll back the host order to network order,
2296 // since the header order was changed in the IkePacketFromNetbuf.
2298 IkeHdrNetToHost (IkeHeader
);
2299 IkeSaSession
= IKEV2_SA_SESSION_FROM_COMMON (SessionCommon
);
2300 if (SessionCommon
->IsInitiator
) {
2301 IkeSaSession
->RespPacket
= AllocateZeroPool (IkePacket
->Header
->Length
);
2302 if (IkeSaSession
->RespPacket
== NULL
) {
2303 Status
= EFI_OUT_OF_RESOURCES
;
2306 IkeSaSession
->RespPacketSize
= IkePacket
->Header
->Length
;
2307 CopyMem (IkeSaSession
->RespPacket
, IkeHeader
, sizeof (IKE_HEADER
));
2309 IkeSaSession
->RespPacket
+ sizeof (IKE_HEADER
),
2310 IkePacket
->PayloadsBuf
,
2311 IkePacket
->Header
->Length
- sizeof (IKE_HEADER
)
2314 IkeSaSession
->InitPacket
= AllocateZeroPool (IkePacket
->Header
->Length
);
2315 if (IkeSaSession
->InitPacket
== NULL
) {
2316 Status
= EFI_OUT_OF_RESOURCES
;
2319 IkeSaSession
->InitPacketSize
= IkePacket
->Header
->Length
;
2320 CopyMem (IkeSaSession
->InitPacket
, IkeHeader
, sizeof (IKE_HEADER
));
2322 IkeSaSession
->InitPacket
+ sizeof (IKE_HEADER
),
2323 IkePacket
->PayloadsBuf
,
2324 IkePacket
->Header
->Length
- sizeof (IKE_HEADER
)
2330 // Point to the first Payload
2332 PayloadHdr
= (IKEV2_COMMON_PAYLOAD_HEADER
*) IkePacket
->PayloadsBuf
;
2333 PayloadType
= IkePacket
->Header
->NextPayload
;
2336 // Parse each payload
2338 while (RemainBytes
>= sizeof (IKEV2_COMMON_PAYLOAD_HEADER
)) {
2339 PayloadSize
= NTOHS (PayloadHdr
->PayloadLength
);
2342 //Check the size of the payload is correct.
2344 if (RemainBytes
< PayloadSize
) {
2345 Status
= EFI_INVALID_PARAMETER
;
2350 // At certain states, it should save some datas before decoding.
2352 if (SessionCommon
->BeforeDecodePayload
!= NULL
) {
2353 SessionCommon
->BeforeDecodePayload (
2354 (UINT8
*) SessionCommon
,
2355 (UINT8
*) PayloadHdr
,
2362 // Initial IkePayload
2364 IkePayload
= IkePayloadAlloc ();
2365 ASSERT (IkePayload
!= NULL
);
2367 IkePayload
->PayloadType
= PayloadType
;
2368 IkePayload
->PayloadBuf
= (UINT8
*) PayloadHdr
;
2369 IkePayload
->PayloadSize
= PayloadSize
;
2370 IkePayload
->IsPayloadBufExt
= TRUE
;
2372 Status
= Ikev2DecodePayload ((UINT8
*) SessionCommon
, IkePayload
);
2373 if (EFI_ERROR (Status
)) {
2377 IPSEC_DUMP_BUF ("After Decoding Payload", IkePayload
->PayloadBuf
, IkePayload
->PayloadSize
);
2379 // Add each payload into packet
2380 // Notice, the IkePacket->Hdr->Lenght still recode the whole IkePacket length
2381 // which is before the decoding.
2383 IKE_PACKET_APPEND_PAYLOAD (IkePacket
, IkePayload
);
2385 RemainBytes
-= PayloadSize
;
2386 PayloadType
= PayloadHdr
->NextPayload
;
2387 if (PayloadType
== IKEV2_PAYLOAD_TYPE_NONE
) {
2391 PayloadHdr
= (IKEV2_COMMON_PAYLOAD_HEADER
*) ((UINT8
*) PayloadHdr
+ PayloadSize
);
2394 if (PayloadType
!= IKEV2_PAYLOAD_TYPE_NONE
) {
2395 Status
= EFI_INVALID_PARAMETER
;
2400 if (EFI_ERROR (Status
)) {
2401 ClearAllPayloads (IkePacket
);
2404 if (IkeHeader
!= NULL
) {
2405 FreePool (IkeHeader
);
2411 Encode the IKE packet.
2413 This function puts all Payloads into one payload then encrypt it if needed.
2415 @param[in] SessionCommon Pointer to IKEV2_SESSION_COMMON containing
2416 some parameter used during IKE packet encoding.
2417 @param[in, out] IkePacket Pointer to IKE_PACKET to be encoded as input,
2418 and the encoded result as output.
2419 @param[in] IkeType The type of IKE. IKE_SA_TYPE, IKE_INFO_TYPE and
2420 IKE_CHILD_TYPE are supportted.
2422 @retval EFI_SUCCESS Encode IKE packet successfully.
2423 @retval Otherwise Encode IKE packet failed.
2428 IN IKEV2_SESSION_COMMON
*SessionCommon
,
2429 IN OUT IKE_PACKET
*IkePacket
,
2433 IKE_PAYLOAD
*IkePayload
;
2434 UINTN PayloadTotalSize
;
2437 IKEV2_SA_SESSION
*IkeSaSession
;
2439 PayloadTotalSize
= 0;
2441 // Encode each payload
2443 for (Entry
= IkePacket
->PayloadList
.ForwardLink
; Entry
!= &(IkePacket
->PayloadList
);) {
2444 IkePayload
= IKE_PAYLOAD_BY_PACKET (Entry
);
2445 Entry
= Entry
->ForwardLink
;
2446 Status
= Ikev2EncodePayload ((UINT8
*) SessionCommon
, IkePayload
);
2447 if (EFI_ERROR (Status
)) {
2451 if (SessionCommon
->AfterEncodePayload
!= NULL
) {
2453 // For certain states, save some payload for further calculation
2455 SessionCommon
->AfterEncodePayload (
2456 (UINT8
*) SessionCommon
,
2457 IkePayload
->PayloadBuf
,
2458 IkePayload
->PayloadSize
,
2459 IkePayload
->PayloadType
2463 PayloadTotalSize
+= IkePayload
->PayloadSize
;
2465 IkePacket
->PayloadTotalSize
= PayloadTotalSize
;
2467 Status
= EFI_SUCCESS
;
2468 if (SessionCommon
->State
>= IkeStateAuth
) {
2470 // Encrypt all payload and transfer IKE packet header from Host order to Network order.
2472 Status
= Ikev2EncryptPacket (SessionCommon
, IkePacket
);
2475 // Fill in the lenght into IkePacket header and transfer Host order to Network order.
2477 IkePacket
->Header
->Length
= (UINT32
) (sizeof (IKE_HEADER
) + IkePacket
->PayloadTotalSize
);
2478 IkeHdrHostToNet (IkePacket
->Header
);
2482 // If the packet is first message, store whole message in IkeSa->InitiPacket
2483 // for following Auth Payload calculation.
2485 if (IkePacket
->Header
->ExchangeType
== IKEV2_EXCHANGE_TYPE_INIT
) {
2486 IkeSaSession
= IKEV2_SA_SESSION_FROM_COMMON (SessionCommon
);
2487 if (SessionCommon
->IsInitiator
) {
2488 IkeSaSession
->InitPacketSize
= IkePacket
->PayloadTotalSize
+ sizeof (IKE_HEADER
);
2489 IkeSaSession
->InitPacket
= AllocateZeroPool (IkeSaSession
->InitPacketSize
);
2490 ASSERT (IkeSaSession
->InitPacket
!= NULL
);
2491 CopyMem (IkeSaSession
->InitPacket
, IkePacket
->Header
, sizeof (IKE_HEADER
));
2492 PayloadTotalSize
= 0;
2493 for (Entry
= IkePacket
->PayloadList
.ForwardLink
; Entry
!= &(IkePacket
->PayloadList
);) {
2494 IkePayload
= IKE_PAYLOAD_BY_PACKET (Entry
);
2495 Entry
= Entry
->ForwardLink
;
2497 IkeSaSession
->InitPacket
+ sizeof (IKE_HEADER
) + PayloadTotalSize
,
2498 IkePayload
->PayloadBuf
,
2499 IkePayload
->PayloadSize
2501 PayloadTotalSize
= PayloadTotalSize
+ IkePayload
->PayloadSize
;
2504 IkeSaSession
->RespPacketSize
= IkePacket
->PayloadTotalSize
+ sizeof(IKE_HEADER
);
2505 IkeSaSession
->RespPacket
= AllocateZeroPool (IkeSaSession
->RespPacketSize
);
2506 ASSERT (IkeSaSession
->RespPacket
!= NULL
);
2507 CopyMem (IkeSaSession
->RespPacket
, IkePacket
->Header
, sizeof (IKE_HEADER
));
2508 PayloadTotalSize
= 0;
2509 for (Entry
= IkePacket
->PayloadList
.ForwardLink
; Entry
!= &(IkePacket
->PayloadList
);) {
2510 IkePayload
= IKE_PAYLOAD_BY_PACKET (Entry
);
2511 Entry
= Entry
->ForwardLink
;
2514 IkeSaSession
->RespPacket
+ sizeof (IKE_HEADER
) + PayloadTotalSize
,
2515 IkePayload
->PayloadBuf
,
2516 IkePayload
->PayloadSize
2518 PayloadTotalSize
= PayloadTotalSize
+ IkePayload
->PayloadSize
;
2529 This function decrypts the Encrypted IKE packet and put the result into IkePacket->PayloadBuf.
2531 @param[in] SessionCommon Pointer to IKEV2_SESSION_COMMON containing
2532 some parameter used during decrypting.
2533 @param[in, out] IkePacket Pointer to IKE_PACKET to be decrypted as input,
2534 and the decrypted result as output.
2535 @param[in, out] IkeType The type of IKE. IKE_SA_TYPE, IKE_INFO_TYPE and
2536 IKE_CHILD_TYPE are supportted.
2538 @retval EFI_INVALID_PARAMETER If the IKE packet length is zero or the
2539 IKE packet length is not aligned with Algorithm Block Size
2540 @retval EFI_SUCCESS Decrypt IKE packet successfully.
2544 Ikev2DecryptPacket (
2545 IN IKEV2_SESSION_COMMON
*SessionCommon
,
2546 IN OUT IKE_PACKET
*IkePacket
,
2547 IN OUT UINTN IkeType
2550 UINT8 CryptBlockSize
; // Encrypt Block Size
2551 UINTN DecryptedSize
; // Encrypted IKE Payload Size
2552 UINT8
*DecryptedBuf
; // Encrypted IKE Payload buffer
2553 UINTN IntegritySize
;
2554 UINT8
*IntegrityBuffer
;
2555 UINTN IvSize
; // Iv Size
2556 UINT8 CheckSumSize
; // Integrity Check Sum Size depends on intergrity Auth
2557 UINT8
*CheckSumData
; // Check Sum data
2558 IKEV2_SA_SESSION
*IkeSaSession
;
2559 IKEV2_CHILD_SA_SESSION
*ChildSaSession
;
2562 UINTN CryptKeyLength
;
2563 HASH_DATA_FRAGMENT Fragments
[1];
2566 IkeSaSession
= NULL
;
2572 // Check if the first payload is the Encrypted payload
2574 if (IkePacket
->Header
->NextPayload
!= IKEV2_PAYLOAD_TYPE_ENCRYPT
) {
2575 return EFI_ACCESS_DENIED
;
2577 CheckSumData
= NULL
;
2578 DecryptedBuf
= NULL
;
2579 IntegrityBuffer
= NULL
;
2582 // Get the Block Size
2584 if (SessionCommon
->IkeSessionType
== IkeSessionTypeIkeSa
) {
2586 CryptBlockSize
= (UINT8
) IpSecGetEncryptBlockSize ((UINT8
) SessionCommon
->SaParams
->EncAlgId
);
2587 CryptKeyLength
= IpSecGetEncryptKeyLength ((UINT8
) SessionCommon
->SaParams
->EncAlgId
);
2588 CheckSumSize
= (UINT8
) IpSecGetIcvLength ((UINT8
) SessionCommon
->SaParams
->IntegAlgId
);
2589 IkeSaSession
= IKEV2_SA_SESSION_FROM_COMMON (SessionCommon
);
2591 } else if (SessionCommon
->IkeSessionType
== IkeSessionTypeChildSa
) {
2593 ChildSaSession
= IKEV2_CHILD_SA_SESSION_FROM_COMMON (SessionCommon
);
2594 IkeSaSession
= ChildSaSession
->IkeSaSession
;
2595 CryptBlockSize
= (UINT8
) IpSecGetEncryptBlockSize ((UINT8
) IkeSaSession
->SessionCommon
.SaParams
->EncAlgId
);
2596 CryptKeyLength
= IpSecGetEncryptKeyLength ((UINT8
) IkeSaSession
->SessionCommon
.SaParams
->EncAlgId
);
2597 CheckSumSize
= (UINT8
) IpSecGetIcvLength ((UINT8
) IkeSaSession
->SessionCommon
.SaParams
->IntegAlgId
);
2600 // The type of SA Session would either be IkeSa or ChildSa.
2602 return EFI_INVALID_PARAMETER
;
2605 CheckSumData
= AllocateZeroPool (CheckSumSize
);
2606 ASSERT (CheckSumData
!= NULL
);
2609 // Fill in the Integrity buffer
2611 IntegritySize
= IkePacket
->PayloadTotalSize
+ sizeof (IKE_HEADER
);
2612 IntegrityBuffer
= AllocateZeroPool (IntegritySize
);
2613 ASSERT (IntegrityBuffer
!= NULL
);
2614 CopyMem (IntegrityBuffer
, IkePacket
->Header
, sizeof(IKE_HEADER
));
2615 CopyMem (IntegrityBuffer
+ sizeof (IKE_HEADER
), IkePacket
->PayloadsBuf
, IkePacket
->PayloadTotalSize
);
2618 // Change Host order to Network order, since the header order was changed
2619 // in the IkePacketFromNetbuf.
2621 IkeHdrHostToNet ((IKE_HEADER
*)IntegrityBuffer
);
2624 // Calculate the Integrity CheckSum Data
2626 Fragments
[0].Data
= IntegrityBuffer
;
2627 Fragments
[0].DataSize
= IntegritySize
- CheckSumSize
;
2629 if (SessionCommon
->IsInitiator
) {
2630 Status
= IpSecCryptoIoHmac (
2631 (UINT8
)IkeSaSession
->SessionCommon
.SaParams
->IntegAlgId
,
2632 IkeSaSession
->IkeKeys
->SkArKey
,
2633 IkeSaSession
->IkeKeys
->SkArKeySize
,
2634 (HASH_DATA_FRAGMENT
*) Fragments
,
2640 Status
= IpSecCryptoIoHmac (
2641 (UINT8
)IkeSaSession
->SessionCommon
.SaParams
->IntegAlgId
,
2642 IkeSaSession
->IkeKeys
->SkAiKey
,
2643 IkeSaSession
->IkeKeys
->SkAiKeySize
,
2644 (HASH_DATA_FRAGMENT
*) Fragments
,
2651 if (EFI_ERROR (Status
)) {
2655 // Compare the Integrity CheckSum Data with the one in IkePacket
2658 IkePacket
->PayloadsBuf
+ IkePacket
->PayloadTotalSize
- CheckSumSize
,
2662 DEBUG ((DEBUG_ERROR
, "Error auth verify payload\n"));
2663 Status
= EFI_ACCESS_DENIED
;
2667 IvSize
= CryptBlockSize
;
2670 // Decrypt the payload with the key.
2672 DecryptedSize
= IkePacket
->PayloadTotalSize
- sizeof (IKEV2_COMMON_PAYLOAD_HEADER
) - IvSize
- CheckSumSize
;
2673 DecryptedBuf
= AllocateZeroPool (DecryptedSize
);
2674 ASSERT (DecryptedBuf
!= NULL
);
2678 IkePacket
->PayloadsBuf
+ sizeof (IKEV2_COMMON_PAYLOAD_HEADER
) + IvSize
,
2682 if (SessionCommon
->IsInitiator
) {
2683 Status
= IpSecCryptoIoDecrypt (
2684 (UINT8
) SessionCommon
->SaParams
->EncAlgId
,
2685 IkeSaSession
->IkeKeys
->SkErKey
,
2686 IkeSaSession
->IkeKeys
->SkErKeySize
<< 3,
2687 IkePacket
->PayloadsBuf
+ sizeof (IKEV2_COMMON_PAYLOAD_HEADER
),
2693 Status
= IpSecCryptoIoDecrypt (
2694 (UINT8
) SessionCommon
->SaParams
->EncAlgId
,
2695 IkeSaSession
->IkeKeys
->SkEiKey
,
2696 IkeSaSession
->IkeKeys
->SkEiKeySize
<< 3,
2697 IkePacket
->PayloadsBuf
+ sizeof (IKEV2_COMMON_PAYLOAD_HEADER
),
2704 if (EFI_ERROR (Status
)) {
2705 DEBUG ((DEBUG_ERROR
, "Error decrypt buffer with %r\n", Status
));
2710 // Get the Padding length
2713 PadLen
= (UINT8
) (*(DecryptedBuf
+ DecryptedSize
- sizeof (IKEV2_PAD_LEN
)));
2716 // Save the next payload of encrypted payload into IkePacket->Hdr->NextPayload
2718 IkePacket
->Header
->NextPayload
= ((IKEV2_ENCRYPTED
*) IkePacket
->PayloadsBuf
)->Header
.NextPayload
;
2721 // Free old IkePacket->PayloadBuf and point it to decrypted paylaod buffer.
2723 FreePool (IkePacket
->PayloadsBuf
);
2724 IkePacket
->PayloadsBuf
= DecryptedBuf
;
2725 IkePacket
->PayloadTotalSize
= DecryptedSize
- PadLen
;
2727 IPSEC_DUMP_BUF ("Decrypted Buffer", DecryptedBuf
, DecryptedSize
);
2731 if (CheckSumData
!= NULL
) {
2732 FreePool (CheckSumData
);
2735 if (EFI_ERROR (Status
) && DecryptedBuf
!= NULL
) {
2736 FreePool (DecryptedBuf
);
2739 if (IntegrityBuffer
!= NULL
) {
2740 FreePool (IntegrityBuffer
);
2749 This function encrypt IKE packet before sending it. The Encrypted IKE packet
2750 is put in to IKEV2 Encrypted Payload.
2752 @param[in] SessionCommon Pointer to IKEV2_SESSION_COMMON related to the IKE packet.
2753 @param[in, out] IkePacket Pointer to IKE packet to be encrypted.
2755 @retval EFI_SUCCESS Operation is successful.
2756 @retval Others Operation is failed.
2760 Ikev2EncryptPacket (
2761 IN IKEV2_SESSION_COMMON
*SessionCommon
,
2762 IN OUT IKE_PACKET
*IkePacket
2765 UINT8 CryptBlockSize
; // Encrypt Block Size
2766 UINT8 CryptBlockSizeMask
; // Block Mask
2767 UINTN EncryptedSize
; // Encrypted IKE Payload Size
2768 UINT8
*EncryptedBuf
; // Encrypted IKE Payload buffer
2769 UINT8
*EncryptPayloadBuf
; // Contain whole Encrypted Payload
2770 UINTN EncryptPayloadSize
; // Total size of the Encrypted payload
2771 UINT8
*IntegrityBuf
; // Buffer to be intergity
2772 UINT32 IntegrityBufSize
; // Buffer size of IntegrityBuf
2773 UINT8
*IvBuffer
; // Initialization Vector
2774 UINT8 IvSize
; // Iv Size
2775 UINT8 CheckSumSize
; // Integrity Check Sum Size depends on intergrity Auth
2776 UINT8
*CheckSumData
; // Check Sum data
2778 IKE_PAYLOAD
*EncryptPayload
;
2779 IKEV2_SA_SESSION
*IkeSaSession
;
2780 IKEV2_CHILD_SA_SESSION
*ChildSaSession
;
2783 IKE_PAYLOAD
*IkePayload
;
2784 UINTN CryptKeyLength
;
2785 HASH_DATA_FRAGMENT Fragments
[1];
2787 Status
= EFI_SUCCESS
;
2790 // Initial all buffers to NULL.
2792 EncryptedBuf
= NULL
;
2793 EncryptPayloadBuf
= NULL
;
2795 CheckSumData
= NULL
;
2796 IkeSaSession
= NULL
;
2800 IntegrityBuf
= NULL
;
2802 // Get the Block Size
2804 if (SessionCommon
->IkeSessionType
== IkeSessionTypeIkeSa
) {
2806 CryptBlockSize
= (UINT8
) IpSecGetEncryptBlockSize ((UINT8
) SessionCommon
->SaParams
->EncAlgId
);
2807 CryptKeyLength
= IpSecGetEncryptKeyLength ((UINT8
) SessionCommon
->SaParams
->EncAlgId
);
2808 CheckSumSize
= (UINT8
) IpSecGetIcvLength ((UINT8
) SessionCommon
->SaParams
->IntegAlgId
);
2809 IkeSaSession
= IKEV2_SA_SESSION_FROM_COMMON (SessionCommon
);
2811 } else if (SessionCommon
->IkeSessionType
== IkeSessionTypeChildSa
) {
2813 ChildSaSession
= IKEV2_CHILD_SA_SESSION_FROM_COMMON (SessionCommon
);
2814 IkeSaSession
= ChildSaSession
->IkeSaSession
;
2815 CryptBlockSize
= (UINT8
) IpSecGetEncryptBlockSize ((UINT8
) IkeSaSession
->SessionCommon
.SaParams
->EncAlgId
);
2816 CryptKeyLength
= IpSecGetEncryptKeyLength ((UINT8
) IkeSaSession
->SessionCommon
.SaParams
->EncAlgId
);
2817 CheckSumSize
= (UINT8
) IpSecGetIcvLength ((UINT8
) IkeSaSession
->SessionCommon
.SaParams
->IntegAlgId
);
2821 // Calcualte the EncryptPayloadSize and the PAD length
2823 CryptBlockSizeMask
= (UINT8
) (CryptBlockSize
- 1);
2824 EncryptedSize
= (IkePacket
->PayloadTotalSize
+ sizeof (IKEV2_PAD_LEN
) + CryptBlockSizeMask
) & ~CryptBlockSizeMask
;
2825 EncryptedBuf
= (UINT8
*) AllocateZeroPool (EncryptedSize
);
2826 ASSERT (EncryptedBuf
!= NULL
);
2829 // Copy all payload into EncryptedIkePayload
2832 NET_LIST_FOR_EACH (Entry
, &(IkePacket
)->PayloadList
) {
2833 IkePayload
= IKE_PAYLOAD_BY_PACKET (Entry
);
2835 CopyMem (EncryptedBuf
+ Index
, IkePayload
->PayloadBuf
, IkePayload
->PayloadSize
);
2836 Index
+= IkePayload
->PayloadSize
;
2841 // Fill in the Pading Length
2843 *(EncryptedBuf
+ EncryptedSize
- 1) = (UINT8
)(EncryptedSize
- IkePacket
->PayloadTotalSize
- 1);
2846 // The IV size is equal with block size
2848 IvSize
= CryptBlockSize
;
2849 IvBuffer
= (UINT8
*) AllocateZeroPool (IvSize
);
2850 if (IvBuffer
== NULL
) {
2851 Status
= EFI_OUT_OF_RESOURCES
;
2858 IkeGenerateIv (IvBuffer
, IvSize
);
2861 // Encrypt payload buf
2863 if (SessionCommon
->IsInitiator
) {
2864 Status
= IpSecCryptoIoEncrypt (
2865 (UINT8
) IkeSaSession
->SessionCommon
.SaParams
->EncAlgId
,
2866 IkeSaSession
->IkeKeys
->SkEiKey
,
2867 IkeSaSession
->IkeKeys
->SkEiKeySize
<< 3,
2874 Status
= IpSecCryptoIoEncrypt (
2875 (UINT8
) IkeSaSession
->SessionCommon
.SaParams
->EncAlgId
,
2876 IkeSaSession
->IkeKeys
->SkErKey
,
2877 IkeSaSession
->IkeKeys
->SkErKeySize
<< 3,
2884 if (EFI_ERROR (Status
)) {
2889 // Allocate the buffer for the whole IKE payload (Encrypted Payload).
2891 EncryptPayloadSize
= sizeof(IKEV2_ENCRYPTED
) + IvSize
+ EncryptedSize
+ CheckSumSize
;
2892 EncryptPayloadBuf
= AllocateZeroPool (EncryptPayloadSize
);
2893 ASSERT (EncryptPayloadBuf
!= NULL
);
2896 // Fill in Header of Encrypted Payload
2898 ((IKEV2_ENCRYPTED
*) EncryptPayloadBuf
)->Header
.NextPayload
= IkePacket
->Header
->NextPayload
;
2899 ((IKEV2_ENCRYPTED
*) EncryptPayloadBuf
)->Header
.PayloadLength
= HTONS ((UINT16
)EncryptPayloadSize
);
2904 CopyMem (EncryptPayloadBuf
+ sizeof (IKEV2_ENCRYPTED
), IvBuffer
, IvSize
);
2907 // Fill in encrypted data
2909 CopyMem (EncryptPayloadBuf
+ sizeof (IKEV2_ENCRYPTED
) + IvSize
, EncryptedBuf
, EncryptedSize
);
2912 // Fill in the IKE Packet header
2914 IkePacket
->PayloadTotalSize
= EncryptPayloadSize
;
2915 IkePacket
->Header
->Length
= (UINT32
) (sizeof (IKE_HEADER
) + IkePacket
->PayloadTotalSize
);
2916 IkePacket
->Header
->NextPayload
= IKEV2_PAYLOAD_TYPE_ENCRYPT
;
2918 IntegrityBuf
= AllocateZeroPool (IkePacket
->Header
->Length
);
2919 if (IntegrityBuf
== NULL
) {
2920 Status
= EFI_OUT_OF_RESOURCES
;
2923 IntegrityBufSize
= IkePacket
->Header
->Length
;
2924 IkeHdrHostToNet (IkePacket
->Header
);
2926 CopyMem (IntegrityBuf
, IkePacket
->Header
, sizeof (IKE_HEADER
));
2927 CopyMem (IntegrityBuf
+ sizeof (IKE_HEADER
), EncryptPayloadBuf
, EncryptPayloadSize
);
2930 // Calcualte Integrity CheckSum
2932 Fragments
[0].Data
= IntegrityBuf
;
2933 Fragments
[0].DataSize
= EncryptPayloadSize
+ sizeof (IKE_HEADER
) - CheckSumSize
;
2935 CheckSumData
= AllocateZeroPool (CheckSumSize
);
2936 if (CheckSumData
== NULL
) {
2937 Status
= EFI_OUT_OF_RESOURCES
;
2940 if (SessionCommon
->IsInitiator
) {
2943 (UINT8
)IkeSaSession
->SessionCommon
.SaParams
->IntegAlgId
,
2944 IkeSaSession
->IkeKeys
->SkAiKey
,
2945 IkeSaSession
->IkeKeys
->SkAiKeySize
,
2946 (HASH_DATA_FRAGMENT
*) Fragments
,
2954 (UINT8
)IkeSaSession
->SessionCommon
.SaParams
->IntegAlgId
,
2955 IkeSaSession
->IkeKeys
->SkArKey
,
2956 IkeSaSession
->IkeKeys
->SkArKeySize
,
2957 (HASH_DATA_FRAGMENT
*) Fragments
,
2965 // Copy CheckSum into Encrypted Payload
2967 CopyMem (EncryptPayloadBuf
+ EncryptPayloadSize
- CheckSumSize
, CheckSumData
, CheckSumSize
);
2969 IPSEC_DUMP_BUF ("Encrypted payload buffer", EncryptPayloadBuf
, EncryptPayloadSize
);
2970 IPSEC_DUMP_BUF ("Integrith CheckSum Data", CheckSumData
, CheckSumSize
);
2973 // Clean all payload under IkePacket->PayloadList.
2975 ClearAllPayloads (IkePacket
);
2978 // Create Encrypted Payload and add into IkePacket->PayloadList
2980 EncryptPayload
= IkePayloadAlloc ();
2981 ASSERT (EncryptPayload
!= NULL
);
2984 // Fill the encrypted payload into the IKE_PAYLOAD structure.
2986 EncryptPayload
->PayloadBuf
= EncryptPayloadBuf
;
2987 EncryptPayload
->PayloadSize
= EncryptPayloadSize
;
2988 EncryptPayload
->PayloadType
= IKEV2_PAYLOAD_TYPE_ENCRYPT
;
2990 IKE_PACKET_APPEND_PAYLOAD (IkePacket
, EncryptPayload
);
2993 if (EncryptedBuf
!= NULL
) {
2994 FreePool (EncryptedBuf
);
2997 if (EFI_ERROR (Status
) && EncryptPayloadBuf
!= NULL
) {
2998 FreePool (EncryptPayloadBuf
);
3001 if (IvBuffer
!= NULL
) {
3002 FreePool (IvBuffer
);
3005 if (CheckSumData
!= NULL
) {
3006 FreePool (CheckSumData
);
3009 if (IntegrityBuf
!= NULL
) {
3010 FreePool (IntegrityBuf
);
3017 Save some useful payloads after accepting the Packet.
3019 @param[in] SessionCommon Pointer to IKEV2_SESSION_COMMON related to the operation.
3020 @param[in] IkePacket Pointer to received IkePacet.
3021 @param[in] IkeType The type used to indicate it is in IkeSa or ChildSa or Info
3026 Ikev2OnPacketAccepted (
3027 IN IKEV2_SESSION_COMMON
*SessionCommon
,
3028 IN IKE_PACKET
*IkePacket
,
3037 The notification function. It will be called when the related UDP_TX_TOKEN's event
3040 This function frees the Net Buffer pointed to the input Packet.
3042 @param[in] Packet Pointer to Net buffer containing the sending IKE packet.
3043 @param[in] EndPoint Pointer to UDP_END_POINT containing the remote and local
3044 address information.
3045 @param[in] IoStatus The Status of the related UDP_TX_TOKEN.
3046 @param[in] Context Pointer to data passed from the caller.
3053 IN UDP_END_POINT
*EndPoint
,
3054 IN EFI_STATUS IoStatus
,
3058 IKE_PACKET
*IkePacket
;
3059 IKEV2_SA_SESSION
*IkeSaSession
;
3060 IKEV2_CHILD_SA_SESSION
*ChildSaSession
;
3062 IPSEC_PRIVATE_DATA
*Private
;
3065 IkePacket
= (IKE_PACKET
*) Context
;
3068 if (EFI_ERROR (IoStatus
)) {
3069 DEBUG ((DEBUG_ERROR
, "Error send the last packet in IkeSessionTypeIkeSa with %r\n", IoStatus
));
3072 NetbufFree (Packet
);
3074 if (IkePacket
->IsDeleteInfo
) {
3076 // For each RemotePeerIP, there are only one IKESA.
3078 IkeSaSession
= Ikev2SaSessionLookup (
3079 &IkePacket
->Private
->Ikev2EstablishedList
,
3080 &IkePacket
->RemotePeerIp
3082 if (IkeSaSession
== NULL
) {
3083 IkePacketFree (IkePacket
);
3087 Private
= IkePacket
->Private
;
3088 if (IkePacket
->Spi
!= 0 ) {
3090 // At that time, the established Child SA still in eht ChildSaEstablishSessionList.
3091 // And meanwhile, if the Child SA is in the the ChildSa in Delete list,
3092 // remove it from delete list and delete it direclty.
3094 ChildSaSession
= Ikev2ChildSaSessionLookupBySpi (
3095 &IkeSaSession
->ChildSaEstablishSessionList
,
3098 if (ChildSaSession
!= NULL
) {
3099 Ikev2ChildSaSessionRemove (
3100 &IkeSaSession
->DeleteSaList
,
3101 ChildSaSession
->LocalPeerSpi
,
3102 IKEV2_DELET_CHILDSA_LIST
3106 // Delete the Child SA.
3108 Ikev2ChildSaSilentDelete (
3116 // Delete the IKE SA
3120 "\n------ deleted Packet (cookie_i, cookie_r):(0x%lx, 0x%lx)------\n",
3121 IkeSaSession
->InitiatorCookie
,
3122 IkeSaSession
->ResponderCookie
)
3125 RemoveEntryList (&IkeSaSession
->BySessionTable
);
3126 Ikev2SaSessionFree (IkeSaSession
);
3129 IkePacketFree (IkePacket
);
3132 // when all IKE SAs were disabled by calling "IPsecConfig -disable", the IPsec status
3133 // should be changed.
3135 if (Private
!= NULL
&& Private
->IsIPsecDisabling
) {
3137 // After all IKE SAs were deleted, set the IPSEC_STATUS_DISABLED value in
3138 // IPsec status variable.
3140 if (IsListEmpty (&Private
->Ikev1EstablishedList
) && IsListEmpty (&Private
->Ikev2EstablishedList
)) {
3141 Value
= IPSEC_STATUS_DISABLED
;
3142 Status
= gRT
->SetVariable (
3143 IPSECCONFIG_STATUS_NAME
,
3144 &gEfiIpSecConfigProtocolGuid
,
3145 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
3149 if (!EFI_ERROR (Status
)) {
3151 // Set the DisabledFlag in Private data.
3153 Private
->IpSec
.DisabledFlag
= TRUE
;
3154 Private
->IsIPsecDisabling
= FALSE
;
3161 Send out IKEV2 packet.
3163 @param[in] IkeUdpService Pointer to IKE_UDP_SERVICE used to send the IKE packet.
3164 @param[in] SessionCommon Pointer to IKEV1_SESSION_COMMON related to the IKE packet.
3165 @param[in] IkePacket Pointer to IKE_PACKET to be sent out.
3166 @param[in] IkeType The type of IKE to point what's kind of the IKE
3167 packet is to be sent out. IKE_SA_TYPE, IKE_INFO_TYPE
3168 and IKE_CHILD_TYPE are supportted.
3170 @retval EFI_SUCCESS The operation complete successfully.
3171 @retval Otherwise The operation is failed.
3175 Ikev2SendIkePacket (
3176 IN IKE_UDP_SERVICE
*IkeUdpService
,
3177 IN UINT8
*SessionCommon
,
3178 IN IKE_PACKET
*IkePacket
,
3183 NET_BUF
*IkePacketNetbuf
;
3184 UDP_END_POINT EndPoint
;
3185 IKEV2_SESSION_COMMON
*Common
;
3187 Common
= (IKEV2_SESSION_COMMON
*) SessionCommon
;
3190 // Set the resend interval
3192 if (Common
->TimeoutInterval
== 0) {
3193 Common
->TimeoutInterval
= IKE_DEFAULT_TIMEOUT_INTERVAL
;
3197 // Retransfer the packet if it is initial packet.
3199 if (IkePacket
->Header
->Flags
== IKE_HEADER_FLAGS_INIT
) {
3201 // Set timer for next retry, this will cancel previous timer
3203 Status
= gBS
->SetTimer (
3204 Common
->TimeoutEvent
,
3206 MultU64x32 (Common
->TimeoutInterval
, 10000) // ms->100ns
3208 if (EFI_ERROR (Status
)) {
3213 IKE_PACKET_REF (IkePacket
);
3215 // If the last sent packet is same with this round packet, the packet is resent packet.
3217 if (IkePacket
!= Common
->LastSentPacket
&& Common
->LastSentPacket
!= NULL
) {
3218 IkePacketFree (Common
->LastSentPacket
);
3221 Common
->LastSentPacket
= IkePacket
;
3224 // Transform IkePacke to NetBuf
3226 IkePacketNetbuf
= IkeNetbufFromPacket ((UINT8
*) SessionCommon
, IkePacket
, IkeType
);
3227 ASSERT (IkePacketNetbuf
!= NULL
);
3229 ZeroMem (&EndPoint
, sizeof (UDP_END_POINT
));
3230 EndPoint
.RemotePort
= IKE_DEFAULT_PORT
;
3231 CopyMem (&IkePacket
->RemotePeerIp
, &Common
->RemotePeerIp
, sizeof (EFI_IP_ADDRESS
));
3232 CopyMem (&EndPoint
.RemoteAddr
, &Common
->RemotePeerIp
, sizeof (EFI_IP_ADDRESS
));
3233 CopyMem (&EndPoint
.LocalAddr
, &Common
->LocalPeerIp
, sizeof (EFI_IP_ADDRESS
));
3235 IPSEC_DUMP_PACKET (IkePacket
, EfiIPsecOutBound
, IkeUdpService
->IpVersion
);
3237 if (IkeUdpService
->IpVersion
== IP_VERSION_4
) {
3238 EndPoint
.RemoteAddr
.Addr
[0] = HTONL (EndPoint
.RemoteAddr
.Addr
[0]);
3239 EndPoint
.LocalAddr
.Addr
[0] = HTONL (EndPoint
.LocalAddr
.Addr
[0]);
3243 // Call UDPIO to send out the IKE packet.
3245 Status
= UdpIoSendDatagram (
3246 IkeUdpService
->Output
,
3254 if (EFI_ERROR (Status
)) {
3255 DEBUG ((DEBUG_ERROR
, "Error send packet with %r\n", Status
));