2 The implementation of Payloads Creation.
4 Copyright (c) 2010, 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 (
315 IdSize
= sizeof (IKEV2_ID
) + SubjectSize
;
317 Id
= (IKEV2_ID
*) AllocateZeroPool (IdSize
);
320 IdPayload
= IkePayloadAlloc ();
321 ASSERT (IdPayload
!= NULL
);
323 IdPayload
->PayloadType
= (UINT8
) ((CommonSession
->IsInitiator
) ? IKEV2_PAYLOAD_TYPE_ID_INIT
: IKEV2_PAYLOAD_TYPE_ID_RSP
);
324 IdPayload
->PayloadBuf
= (UINT8
*) Id
;
325 IdPayload
->PayloadSize
= IdSize
;
328 // Set generic header of identification payload
330 Id
->Header
.NextPayload
= NextPayload
;
331 Id
->Header
.PayloadLength
= (UINT16
) IdSize
;
333 CopyMem (Id
+ 1, CertSubject
, SubjectSize
);
335 if (CertSubject
!= NULL
) {
336 FreePool (CertSubject
);
342 Generate a Authentication Payload.
344 This function is used for both Authentication generation and verification. When the
345 IsVerify is TRUE, it create a Auth Data for verification. This function choose the
346 related IKE_SA_INIT Message for Auth data creation according to the IKE Session's type
347 and the value of IsVerify parameter.
349 @param[in] IkeSaSession Pointer to IKEV2_SA_SESSION related to.
350 @param[in] IdPayload Pointer to the ID payload to be used for Authentication
352 @param[in] NextPayload The type filled into the Authentication Payload next
354 @param[in] IsVerify If it is TURE, the Authentication payload is used for
357 @return pointer to IKE Authentication payload for Pre-shared key method.
361 Ikev2PskGenerateAuthPayload (
362 IN IKEV2_SA_SESSION
*IkeSaSession
,
363 IN IKE_PAYLOAD
*IdPayload
,
364 IN UINT8 NextPayload
,
370 PRF_DATA_FRAGMENT Fragments
[3];
373 IKE_PAYLOAD
*AuthPayload
;
374 IKEV2_AUTH
*PayloadBuf
;
378 // Auth = Prf(Prf(Secret,"Key Pad for IKEv2),IKE_SA_INIi/r|Ni/r|Prf(SK_Pr, IDi/r))
381 // 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
382 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
383 // ! Next Payload !C! RESERVED ! Payload Length !
384 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
385 // ! Auth Method ! RESERVED !
386 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
388 // ~ Authentication Data ~
390 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
397 DigestSize
= IpSecGetHmacDigestLength ((UINT8
)IkeSaSession
->SessionCommon
.SaParams
->Prf
);
398 Digest
= AllocateZeroPool (DigestSize
);
400 if (Digest
== NULL
) {
403 if (IdPayload
== NULL
) {
407 // Calcualte Prf(Seceret, "Key Pad for IKEv2");
409 Fragments
[0].Data
= (UINT8
*) mConstantKey
;
410 Fragments
[0].DataSize
= CONSTANT_KEY_SIZE
;
412 Status
= IpSecCryptoIoHmac (
413 (UINT8
)IkeSaSession
->SessionCommon
.SaParams
->Prf
,
414 IkeSaSession
->Pad
->Data
->AuthData
,
415 IkeSaSession
->Pad
->Data
->AuthDataSize
,
416 (HASH_DATA_FRAGMENT
*)Fragments
,
421 if (EFI_ERROR (Status
)) {
426 // Store the AuthKey into KeyBuf
428 KeyBuf
= AllocateZeroPool (DigestSize
);
429 ASSERT (KeyBuf
!= NULL
);
430 CopyMem (KeyBuf
, Digest
, DigestSize
);
431 KeySize
= DigestSize
;
434 // Calculate Prf(SK_Pi/r, IDi/r)
436 Fragments
[0].Data
= IdPayload
->PayloadBuf
+ sizeof (IKEV2_COMMON_PAYLOAD_HEADER
);
437 Fragments
[0].DataSize
= IdPayload
->PayloadSize
- sizeof (IKEV2_COMMON_PAYLOAD_HEADER
);
439 if ((IkeSaSession
->SessionCommon
.IsInitiator
&& IsVerify
) ||
440 (!IkeSaSession
->SessionCommon
.IsInitiator
&& !IsVerify
)
442 Status
= IpSecCryptoIoHmac (
443 (UINT8
)IkeSaSession
->SessionCommon
.SaParams
->Prf
,
444 IkeSaSession
->IkeKeys
->SkPrKey
,
445 IkeSaSession
->IkeKeys
->SkPrKeySize
,
446 (HASH_DATA_FRAGMENT
*) Fragments
,
452 Status
= IpSecCryptoIoHmac (
453 (UINT8
)IkeSaSession
->SessionCommon
.SaParams
->Prf
,
454 IkeSaSession
->IkeKeys
->SkPiKey
,
455 IkeSaSession
->IkeKeys
->SkPiKeySize
,
456 (HASH_DATA_FRAGMENT
*) Fragments
,
462 if (EFI_ERROR (Status
)) {
467 // Copy data to Fragments.
469 if ((IkeSaSession
->SessionCommon
.IsInitiator
&& IsVerify
) ||
470 (!IkeSaSession
->SessionCommon
.IsInitiator
&& !IsVerify
)
472 Fragments
[0].Data
= IkeSaSession
->RespPacket
;
473 Fragments
[0].DataSize
= IkeSaSession
->RespPacketSize
;
474 Fragments
[1].Data
= IkeSaSession
->NiBlock
;
475 Fragments
[1].DataSize
= IkeSaSession
->NiBlkSize
;
477 Fragments
[0].Data
= IkeSaSession
->InitPacket
;
478 Fragments
[0].DataSize
= IkeSaSession
->InitPacketSize
;
479 Fragments
[1].Data
= IkeSaSession
->NrBlock
;
480 Fragments
[1].DataSize
= IkeSaSession
->NrBlkSize
;
484 // Copy the result of Prf(SK_Pr, IDi/r) to Fragments[2].
486 Fragments
[2].Data
= AllocateZeroPool (DigestSize
);
487 Fragments
[2].DataSize
= DigestSize
;
488 CopyMem (Fragments
[2].Data
, Digest
, DigestSize
);
491 // Calculate Prf(Key,IKE_SA_INIi/r|Ni/r|Prf(SK_Pr, IDi/r))
493 Status
= IpSecCryptoIoHmac (
494 (UINT8
)IkeSaSession
->SessionCommon
.SaParams
->Prf
,
497 (HASH_DATA_FRAGMENT
*) Fragments
,
502 if (EFI_ERROR (Status
)) {
507 // Allocate buffer for Auth Payload
509 AuthPayload
= IkePayloadAlloc ();
510 ASSERT (AuthPayload
!= NULL
);
512 AuthPayload
->PayloadSize
= sizeof (IKEV2_AUTH
) + DigestSize
;
513 PayloadBuf
= (IKEV2_AUTH
*) AllocateZeroPool (AuthPayload
->PayloadSize
);
514 ASSERT (PayloadBuf
!= NULL
);
516 // Fill in Auth payload.
518 PayloadBuf
->Header
.NextPayload
= NextPayload
;
519 PayloadBuf
->Header
.PayloadLength
= (UINT16
) (AuthPayload
->PayloadSize
);
520 if (IkeSaSession
->Pad
->Data
->AuthMethod
== EfiIPsecAuthMethodPreSharedSecret
) {
522 // Only support Shared Key Message Integrity
524 PayloadBuf
->AuthMethod
= IKEV2_AUTH_METHOD_SKMI
;
527 // Not support other Auth method.
529 Status
= EFI_UNSUPPORTED
;
534 // Copy the result of Prf(Key,IKE_SA_INIi/r|Ni/r|Prf(SK_Pr, IDi/r)) to Auth
544 // Fill in IKE_PACKET
546 AuthPayload
->PayloadBuf
= (UINT8
*) PayloadBuf
;
547 AuthPayload
->PayloadType
= IKEV2_PAYLOAD_TYPE_AUTH
;
550 if (KeyBuf
!= NULL
) {
553 if (Digest
!= NULL
) {
556 if (Fragments
[2].Data
!= NULL
) {
558 // Free the buffer which contains the result of Prf(SK_Pr, IDi/r)
560 FreePool (Fragments
[2].Data
);
563 if (EFI_ERROR (Status
)) {
564 if (AuthPayload
!= NULL
) {
565 IkePayloadFree (AuthPayload
);
574 Generate a Authentication Payload for Certificate Auth method.
576 This function has two functions. One is creating a local Authentication
577 Payload for sending and other is creating the remote Authentication data
578 for verification when the IsVerify is TURE.
580 @param[in] IkeSaSession Pointer to IKEV2_SA_SESSION related to.
581 @param[in] IdPayload Pointer to the ID payload to be used for Authentication
583 @param[in] NextPayload The type filled into the Authentication Payload
585 @param[in] IsVerify If it is TURE, the Authentication payload is used
587 @param[in] UefiPrivateKey Pointer to the UEFI private key. Ignore it when
588 verify the authenticate payload.
589 @param[in] UefiPrivateKeyLen The size of UefiPrivateKey in bytes. Ignore it
590 when verify the authenticate payload.
591 @param[in] UefiKeyPwd Pointer to the password of UEFI private key.
592 Ignore it when verify the authenticate payload.
593 @param[in] UefiKeyPwdLen The size of UefiKeyPwd in bytes.Ignore it when
594 verify the authenticate payload.
596 @return pointer to IKE Authentication payload for Cerifitcation method.
600 Ikev2CertGenerateAuthPayload (
601 IN IKEV2_SA_SESSION
*IkeSaSession
,
602 IN IKE_PAYLOAD
*IdPayload
,
603 IN UINT8 NextPayload
,
605 IN UINT8
*UefiPrivateKey
,
606 IN UINTN UefiPrivateKeyLen
,
607 IN UINT8
*UefiKeyPwd
,
608 IN UINTN UefiKeyPwdLen
613 PRF_DATA_FRAGMENT Fragments
[3];
616 IKE_PAYLOAD
*AuthPayload
;
617 IKEV2_AUTH
*PayloadBuf
;
623 // Auth = Prf(Scert,IKE_SA_INIi/r|Ni/r|Prf(SK_Pr, IDi/r))
626 // 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
627 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
628 // ! Next Payload !C! RESERVED ! Payload Length !
629 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
630 // ! Auth Method ! RESERVED !
631 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
633 // ~ Authentication Data ~
635 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
646 if (IdPayload
== NULL
) {
649 DigestSize
= IpSecGetHmacDigestLength ((UINT8
)IkeSaSession
->SessionCommon
.SaParams
->Prf
);
650 Digest
= AllocateZeroPool (DigestSize
);
652 if (Digest
== NULL
) {
657 // Store the AuthKey into KeyBuf
659 KeyBuf
= AllocateZeroPool (DigestSize
);
660 ASSERT (KeyBuf
!= NULL
);
662 CopyMem (KeyBuf
, Digest
, DigestSize
);
663 KeySize
= DigestSize
;
666 // Calculate Prf(SK_Pi/r, IDi/r)
668 Fragments
[0].Data
= IdPayload
->PayloadBuf
+ sizeof (IKEV2_COMMON_PAYLOAD_HEADER
);
669 Fragments
[0].DataSize
= IdPayload
->PayloadSize
- sizeof (IKEV2_COMMON_PAYLOAD_HEADER
);
671 IpSecDumpBuf ("RestofIDPayload", Fragments
[0].Data
, Fragments
[0].DataSize
);
673 if ((IkeSaSession
->SessionCommon
.IsInitiator
&& IsVerify
) ||
674 (!IkeSaSession
->SessionCommon
.IsInitiator
&& !IsVerify
)
676 Status
= IpSecCryptoIoHmac(
677 (UINT8
)IkeSaSession
->SessionCommon
.SaParams
->Prf
,
678 IkeSaSession
->IkeKeys
->SkPrKey
,
679 IkeSaSession
->IkeKeys
->SkPrKeySize
,
680 (HASH_DATA_FRAGMENT
*) Fragments
,
685 IpSecDumpBuf ("MACedIDForR", Digest
, DigestSize
);
687 Status
= IpSecCryptoIoHmac (
688 (UINT8
)IkeSaSession
->SessionCommon
.SaParams
->Prf
,
689 IkeSaSession
->IkeKeys
->SkPiKey
,
690 IkeSaSession
->IkeKeys
->SkPiKeySize
,
691 (HASH_DATA_FRAGMENT
*) Fragments
,
696 IpSecDumpBuf ("MACedIDForI", Digest
, DigestSize
);
698 if (EFI_ERROR (Status
)) {
703 // Copy data to Fragments.
705 if ((IkeSaSession
->SessionCommon
.IsInitiator
&& IsVerify
) ||
706 (!IkeSaSession
->SessionCommon
.IsInitiator
&& !IsVerify
)
708 Fragments
[0].Data
= IkeSaSession
->RespPacket
;
709 Fragments
[0].DataSize
= IkeSaSession
->RespPacketSize
;
710 Fragments
[1].Data
= IkeSaSession
->NiBlock
;
711 Fragments
[1].DataSize
= IkeSaSession
->NiBlkSize
;
712 IpSecDumpBuf ("RealMessage2", Fragments
[0].Data
, Fragments
[0].DataSize
);
713 IpSecDumpBuf ("NonceIDdata", Fragments
[1].Data
, Fragments
[1].DataSize
);
715 Fragments
[0].Data
= IkeSaSession
->InitPacket
;
716 Fragments
[0].DataSize
= IkeSaSession
->InitPacketSize
;
717 Fragments
[1].Data
= IkeSaSession
->NrBlock
;
718 Fragments
[1].DataSize
= IkeSaSession
->NrBlkSize
;
719 IpSecDumpBuf ("RealMessage1", Fragments
[0].Data
, Fragments
[0].DataSize
);
720 IpSecDumpBuf ("NonceRDdata", Fragments
[1].Data
, Fragments
[1].DataSize
);
724 // Copy the result of Prf(SK_Pr, IDi/r) to Fragments[2].
726 Fragments
[2].Data
= AllocateZeroPool (DigestSize
);
727 Fragments
[2].DataSize
= DigestSize
;
728 CopyMem (Fragments
[2].Data
, Digest
, DigestSize
);
731 // Calculate Prf(Key,IKE_SA_INIi/r|Ni/r|Prf(SK_Pr, IDi/r))
733 Status
= IpSecCryptoIoHash (
734 (UINT8
)IkeSaSession
->SessionCommon
.SaParams
->Prf
,
735 (HASH_DATA_FRAGMENT
*) Fragments
,
740 if (EFI_ERROR (Status
)) {
744 IpSecDumpBuf ("HashSignedOctects", Digest
, DigestSize
);
746 // Sign the data by the private Key
749 IpSecCryptoIoAuthDataWithCertificate (
766 // Allocate buffer for Auth Payload
768 AuthPayload
= IkePayloadAlloc ();
769 ASSERT (AuthPayload
!= NULL
);
772 AuthPayload
->PayloadSize
= sizeof (IKEV2_AUTH
) + SigSize
;
774 AuthPayload
->PayloadSize
= sizeof (IKEV2_AUTH
) + DigestSize
;
777 PayloadBuf
= (IKEV2_AUTH
*) AllocateZeroPool (AuthPayload
->PayloadSize
);
778 ASSERT (PayloadBuf
!= NULL
);
780 // Fill in Auth payload.
782 PayloadBuf
->Header
.NextPayload
= NextPayload
;
783 PayloadBuf
->Header
.PayloadLength
= (UINT16
) (AuthPayload
->PayloadSize
);
784 if (IkeSaSession
->Pad
->Data
->AuthMethod
== EfiIPsecAuthMethodCertificates
) {
785 PayloadBuf
->AuthMethod
= IKEV2_AUTH_METHOD_RSA
;
787 Status
= EFI_INVALID_PARAMETER
;
792 // Copy the result of Prf(Key,IKE_SA_INIi/r|Ni/r|Prf(SK_Pr, IDi/r)) to Auth
796 CopyMem (PayloadBuf
+ 1, Signature
, SigSize
);
798 CopyMem (PayloadBuf
+ 1, Digest
, DigestSize
);
802 // Fill in IKE_PACKET
804 AuthPayload
->PayloadBuf
= (UINT8
*) PayloadBuf
;
805 AuthPayload
->PayloadType
= IKEV2_PAYLOAD_TYPE_AUTH
;
808 if (KeyBuf
!= NULL
) {
811 if (Digest
!= NULL
) {
814 if (Signature
!= NULL
) {
815 FreePool (Signature
);
817 if (Fragments
[2].Data
!= NULL
) {
819 // Free the buffer which contains the result of Prf(SK_Pr, IDi/r)
821 FreePool (Fragments
[2].Data
);
824 if (EFI_ERROR (Status
)) {
825 if (AuthPayload
!= NULL
) {
826 IkePayloadFree (AuthPayload
);
837 This function generates TSi or TSr payload according to type of next payload.
838 If the next payload is Responder TS, gereate TSi Payload. Otherwise, generate
841 @param[in] ChildSa Pointer to IKEV2_CHILD_SA_SESSION related to this TS payload.
842 @param[in] NextPayload The payload type presented in the NextPayload field
843 of ID Payload header.
844 @param[in] IsTunnel It indicates that if the Ts Payload is after the CP payload.
845 If yes, it means the Tsi and Tsr payload should be with
846 Max port range and address range and protocol is marked
849 @retval Pointer to Ts IKE payload.
853 Ikev2GenerateTsPayload (
854 IN IKEV2_CHILD_SA_SESSION
*ChildSa
,
855 IN UINT8 NextPayload
,
859 IKE_PAYLOAD
*TsPayload
;
860 IKEV2_TS
*TsPayloadBuf
;
861 TRAFFIC_SELECTOR
*TsSelector
;
869 // 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
870 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
871 // ! Next Payload !C! RESERVED ! Payload Length !
872 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
873 // ! Number of TSs ! RESERVED !
874 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
876 // ~ <Traffic Selectors> ~
878 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
881 TsPayload
= IkePayloadAlloc();
882 ASSERT (TsPayload
!= NULL
);
884 IpVersion
= ChildSa
->SessionCommon
.UdpService
->IpVersion
;
886 // The Starting Address and Ending Address is variable length depends on
889 AddrSize
= (UINT8
)((IpVersion
== IP_VERSION_4
) ? sizeof (EFI_IPv4_ADDRESS
) : sizeof (EFI_IPv6_ADDRESS
));
890 SelectorSize
= sizeof (TRAFFIC_SELECTOR
) + 2 * AddrSize
;
891 TsPayloadSize
= sizeof (IKEV2_TS
) + SelectorSize
;
892 TsPayloadBuf
= AllocateZeroPool (TsPayloadSize
);
893 ASSERT (TsPayloadBuf
!= NULL
);
895 TsPayload
->PayloadBuf
= (UINT8
*) TsPayloadBuf
;
896 TsSelector
= (TRAFFIC_SELECTOR
*)(TsPayloadBuf
+ 1);
898 TsSelector
->TSType
= (UINT8
)((IpVersion
== IP_VERSION_4
) ? IKEV2_TS_TYPE_IPV4_ADDR_RANGE
: IKEV2_TS_TYPS_IPV6_ADDR_RANGE
);
904 TsSelector
->IpProtocolId
= IKEV2_TS_ANY_PROTOCOL
;
905 TsSelector
->SelecorLen
= (UINT16
) SelectorSize
;
906 TsSelector
->StartPort
= 0;
907 TsSelector
->EndPort
= IKEV2_TS_ANY_PORT
;
908 ZeroMem ((UINT8
*)TsSelector
+ sizeof(TRAFFIC_SELECTOR
), AddrSize
);
909 SetMem ((UINT8
*)TsSelector
+ sizeof(TRAFFIC_SELECTOR
) + AddrSize
, AddrSize
, 0xff);
913 // TODO: Support port range and address range
915 if (NextPayload
== IKEV2_PAYLOAD_TYPE_TS_RSP
){
917 // Create initiator Traffic Selector
919 TsSelector
->SelecorLen
= (UINT16
)SelectorSize
;
922 // Currently only support the port range from 0~0xffff. Don't support other
924 // TODO: support Port range
926 if (ChildSa
->SessionCommon
.IsInitiator
) {
927 if (ChildSa
->Spd
->Selector
->LocalPort
!= 0 &&
928 ChildSa
->Spd
->Selector
->LocalPortRange
== 0) {
930 // For not port range.
932 TsSelector
->StartPort
= ChildSa
->Spd
->Selector
->LocalPort
;
933 TsSelector
->EndPort
= ChildSa
->Spd
->Selector
->LocalPort
;
934 } else if (ChildSa
->Spd
->Selector
->LocalPort
== 0){
936 // For port from 0~0xffff
938 TsSelector
->StartPort
= 0;
939 TsSelector
->EndPort
= IKEV2_TS_ANY_PORT
;
947 if (ChildSa
->Spd
->Selector
->RemotePort
!= 0 &&
948 ChildSa
->Spd
->Selector
->RemotePortRange
== 0) {
950 // For not port range.
952 TsSelector
->StartPort
= ChildSa
->Spd
->Selector
->RemotePort
;
953 TsSelector
->EndPort
= ChildSa
->Spd
->Selector
->RemotePort
;
954 } else if (ChildSa
->Spd
->Selector
->RemotePort
== 0) {
956 // For port from 0~0xffff
958 TsSelector
->StartPort
= 0;
959 TsSelector
->EndPort
= IKEV2_TS_ANY_PORT
;
968 // Copy Address.Currently the address range is not supported.
969 // The Starting address is same as Ending address
970 // TODO: Support Address Range.
973 (UINT8
*)TsSelector
+ sizeof(TRAFFIC_SELECTOR
),
974 ChildSa
->SessionCommon
.IsInitiator
?
975 ChildSa
->Spd
->Selector
->LocalAddress
:
976 ChildSa
->Spd
->Selector
->RemoteAddress
,
980 (UINT8
*)TsSelector
+ sizeof(TRAFFIC_SELECTOR
) + AddrSize
,
981 ChildSa
->SessionCommon
.IsInitiator
?
982 ChildSa
->Spd
->Selector
->LocalAddress
:
983 ChildSa
->Spd
->Selector
->RemoteAddress
,
987 // If the Next Payload is not TS responder, this TS payload type is the TS responder.
989 TsPayload
->PayloadType
= IKEV2_PAYLOAD_TYPE_TS_INIT
;
992 // Create responder Traffic Selector
994 TsSelector
->SelecorLen
= (UINT16
)SelectorSize
;
997 // Currently only support the port range from 0~0xffff. Don't support other
999 // TODO: support Port range
1001 if (!ChildSa
->SessionCommon
.IsInitiator
) {
1002 if (ChildSa
->Spd
->Selector
->LocalPort
!= 0 &&
1003 ChildSa
->Spd
->Selector
->LocalPortRange
== 0) {
1005 // For not port range.
1007 TsSelector
->StartPort
= ChildSa
->Spd
->Selector
->LocalPort
;
1008 TsSelector
->EndPort
= ChildSa
->Spd
->Selector
->LocalPort
;
1009 } else if (ChildSa
->Spd
->Selector
->LocalPort
== 0){
1011 // For port from 0~0xffff
1013 TsSelector
->StartPort
= 0;
1014 TsSelector
->EndPort
= IKEV2_TS_ANY_PORT
;
1022 if (ChildSa
->Spd
->Selector
->RemotePort
!= 0 &&
1023 ChildSa
->Spd
->Selector
->RemotePortRange
== 0) {
1025 // For not port range.
1027 TsSelector
->StartPort
= ChildSa
->Spd
->Selector
->RemotePort
;
1028 TsSelector
->EndPort
= ChildSa
->Spd
->Selector
->RemotePort
;
1029 } else if (ChildSa
->Spd
->Selector
->RemotePort
== 0){
1031 // For port from 0~0xffff
1033 TsSelector
->StartPort
= 0;
1034 TsSelector
->EndPort
= IKEV2_TS_ANY_PORT
;
1043 // Copy Address.Currently the address range is not supported.
1044 // The Starting address is same as Ending address
1045 // TODO: Support Address Range.
1048 (UINT8
*)TsSelector
+ sizeof(TRAFFIC_SELECTOR
),
1049 ChildSa
->SessionCommon
.IsInitiator
?
1050 ChildSa
->Spd
->Selector
->RemoteAddress
:
1051 ChildSa
->Spd
->Selector
->LocalAddress
,
1055 (UINT8
*)TsSelector
+ sizeof(TRAFFIC_SELECTOR
) + AddrSize
,
1056 ChildSa
->SessionCommon
.IsInitiator
?
1057 ChildSa
->Spd
->Selector
->RemoteAddress
:
1058 ChildSa
->Spd
->Selector
->LocalAddress
,
1062 // If the Next Payload is not TS responder, this TS payload type is the TS responder.
1064 TsPayload
->PayloadType
= IKEV2_PAYLOAD_TYPE_TS_RSP
;
1068 if (ChildSa
->Spd
->Selector
->NextLayerProtocol
!= 0xffff) {
1069 TsSelector
->IpProtocolId
= (UINT8
)ChildSa
->Spd
->Selector
->NextLayerProtocol
;
1071 TsSelector
->IpProtocolId
= IKEV2_TS_ANY_PROTOCOL
;
1074 TsPayloadBuf
->Header
.NextPayload
= NextPayload
;
1075 TsPayloadBuf
->Header
.PayloadLength
= (UINT16
)TsPayloadSize
;
1076 TsPayloadBuf
->TSNumbers
= 1;
1077 TsPayload
->PayloadSize
= TsPayloadSize
;
1081 if (TsPayload
!= NULL
) {
1082 IkePayloadFree (TsPayload
);
1090 Generate the Notify payload.
1092 Since the structure of Notify payload which defined in RFC 4306 is simple, so
1093 there is no internal data structure for Notify payload. This function generate
1094 Notify payload defined in RFC 4306, but all the fields in this payload are still
1095 in host order and need call Ikev2EncodePayload() to convert those fields from
1096 the host order to network order beforing sending it.
1098 @param[in] ProtocolId The protocol type ID. For IKE_SA it MUST be one (1).
1099 For IPsec SAs it MUST be neither (2) for AH or (3)
1101 @param[in] NextPayload The next paylaod type in NextPayload field of
1103 @param[in] SpiSize Size of the SPI in SPI size field of the Notify Payload.
1104 @param[in] MessageType The message type in NotifyMessageType field of the
1106 @param[in] SpiBuf Pointer to buffer contains the SPI value.
1107 @param[in] NotifyData Pointer to buffer contains the notification data.
1108 @param[in] NotifyDataSize The size of NotifyData in bytes.
1111 @retval Pointer to IKE Notify Payload.
1115 Ikev2GenerateNotifyPayload (
1116 IN UINT8 ProtocolId
,
1117 IN UINT8 NextPayload
,
1119 IN UINT16 MessageType
,
1121 IN UINT8
*NotifyData
,
1122 IN UINTN NotifyDataSize
1125 IKE_PAYLOAD
*NotifyPayload
;
1126 IKEV2_NOTIFY
*Notify
;
1127 UINT16 NotifyPayloadLen
;
1131 // 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
1132 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1133 // ! Next Payload !C! RESERVED ! Payload Length !
1134 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1135 // ! Protocol ID ! SPI Size ! Notify Message Type !
1136 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1138 // ~ Security Parameter Index (SPI) ~
1140 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1142 // ~ Notification Data ~
1144 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1147 NotifyPayloadLen
= (UINT16
) (sizeof (IKEV2_NOTIFY
) + NotifyDataSize
+ SpiSize
);
1148 Notify
= (IKEV2_NOTIFY
*) AllocateZeroPool (NotifyPayloadLen
);
1149 ASSERT (Notify
!= NULL
);
1152 // Set Delete Payload's Generic Header
1154 Notify
->Header
.NextPayload
= NextPayload
;
1155 Notify
->Header
.PayloadLength
= NotifyPayloadLen
;
1156 Notify
->SpiSize
= SpiSize
;
1157 Notify
->ProtocolId
= ProtocolId
;
1158 Notify
->MessageType
= MessageType
;
1161 // Copy Spi , for Cookie Notify, there is no SPI.
1163 if (SpiBuf
!= NULL
&& SpiSize
!= 0 ) {
1164 CopyMem (Notify
+ 1, SpiBuf
, SpiSize
);
1167 MessageData
= ((UINT8
*) (Notify
+ 1)) + SpiSize
;
1170 // Copy Notification Data
1172 if (NotifyDataSize
!= 0) {
1173 CopyMem (MessageData
, NotifyData
, NotifyDataSize
);
1177 // Create Payload for and set type as IKEV2_PAYLOAD_TYPE_NOTIFY
1179 NotifyPayload
= IkePayloadAlloc ();
1180 ASSERT (NotifyPayload
!= NULL
);
1181 NotifyPayload
->PayloadType
= IKEV2_PAYLOAD_TYPE_NOTIFY
;
1182 NotifyPayload
->PayloadBuf
= (UINT8
*) Notify
;
1183 NotifyPayload
->PayloadSize
= NotifyPayloadLen
;
1184 return NotifyPayload
;
1188 Generate the Delete payload.
1190 Since the structure of Delete payload which defined in RFC 4306 is simple,
1191 there is no internal data structure for Delete payload. This function generate
1192 Delete payload defined in RFC 4306, but all the fields in this payload are still
1193 in host order and need call Ikev2EncodePayload() to convert those fields from
1194 the host order to network order beforing sending it.
1196 @param[in] IkeSaSession Pointer to IKE SA Session to be used of Delete payload generation.
1197 @param[in] NextPayload The next paylaod type in NextPayload field of
1199 @param[in] SpiSize Size of the SPI in SPI size field of the Delete Payload.
1200 @param[in] SpiNum Number of SPI in NumofSPIs field of the Delete Payload.
1201 @param[in] SpiBuf Pointer to buffer contains the SPI value.
1203 @retval a Pointer of IKE Delete Payload.
1207 Ikev2GenerateDeletePayload (
1208 IN IKEV2_SA_SESSION
*IkeSaSession
,
1209 IN UINT8 NextPayload
,
1216 IKE_PAYLOAD
*DelPayload
;
1219 UINT16 DelPayloadLen
;
1222 // 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
1223 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1224 // ! Next Payload !C! RESERVED ! Payload Length !
1225 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1226 // ! Protocol ID ! SPI Size ! # of SPIs !
1227 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1229 // ~ Security Parameter Index(es) (SPI) ~
1231 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1233 SpiBufSize
= (UINT16
) (SpiSize
* SpiNum
);
1234 DelPayloadLen
= (UINT16
) (sizeof (IKEV2_DELETE
) + SpiBufSize
);
1236 Del
= AllocateZeroPool (DelPayloadLen
);
1237 ASSERT (Del
!= NULL
);
1240 // Set Delete Payload's Generic Header
1242 Del
->Header
.NextPayload
= NextPayload
;
1243 Del
->Header
.PayloadLength
= DelPayloadLen
;
1244 Del
->NumSpis
= SpiNum
;
1245 Del
->SpiSize
= SpiSize
;
1249 // TODO: should consider the AH if needs to support.
1251 Del
->ProtocolId
= IPSEC_PROTO_IPSEC_ESP
;
1253 Del
->ProtocolId
= IPSEC_PROTO_ISAKMP
;
1257 // Set Del Payload's Idntification Data
1259 CopyMem (Del
+ 1, SpiBuf
, SpiBufSize
);
1260 DelPayload
= IkePayloadAlloc ();
1261 ASSERT (DelPayload
!= NULL
);
1262 DelPayload
->PayloadType
= IKEV2_PAYLOAD_TYPE_DELETE
;
1263 DelPayload
->PayloadBuf
= (UINT8
*) Del
;
1264 DelPayload
->PayloadSize
= DelPayloadLen
;
1269 Generate the Configuration payload.
1271 This function generate configuration payload defined in RFC 4306, but all the
1272 fields in this payload are still in host order and need call Ikev2EncodePayload()
1273 to convert those fields from the host order to network order beforing sending it.
1275 @param[in] IkeSaSession Pointer to IKE SA Session to be used for Delete payload
1277 @param[in] NextPayload The next paylaod type in NextPayload field of
1279 @param[in] CfgType The attribute type in the Configuration attribute.
1281 @retval Pointer to IKE CP Payload.
1285 Ikev2GenerateCpPayload (
1286 IN IKEV2_SA_SESSION
*IkeSaSession
,
1287 IN UINT8 NextPayload
,
1291 IKE_PAYLOAD
*CpPayload
;
1294 IKEV2_CFG_ATTRIBUTES
*CfgAttributes
;
1297 // 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
1298 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1299 // ! Next Payload !C! RESERVED ! Payload Length !
1300 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1301 // ! CFG Type ! RESERVED !
1302 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1304 // ~ Configuration Attributes ~
1306 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1309 PayloadLen
= (UINT16
) (sizeof (IKEV2_CFG
) + sizeof (IKEV2_CFG_ATTRIBUTES
));
1310 Cfg
= (IKEV2_CFG
*) AllocateZeroPool (PayloadLen
);
1316 CfgAttributes
= (IKEV2_CFG_ATTRIBUTES
*)((UINT8
*)Cfg
+ sizeof (IKEV2_CFG
));
1319 // Only generate the configuration payload with an empty INTERNAL_IP4_ADDRESS
1320 // or INTERNAL_IP6_ADDRESS.
1323 Cfg
->Header
.NextPayload
= NextPayload
;
1324 Cfg
->Header
.PayloadLength
= PayloadLen
;
1325 Cfg
->CfgType
= IKEV2_CFG_TYPE_REQUEST
;
1327 CfgAttributes
->AttritType
= CfgType
;
1328 CfgAttributes
->ValueLength
= 0;
1330 CpPayload
= IkePayloadAlloc ();
1331 if (CpPayload
== NULL
) {
1338 CpPayload
->PayloadType
= IKEV2_PAYLOAD_TYPE_CP
;
1339 CpPayload
->PayloadBuf
= (UINT8
*) Cfg
;
1340 CpPayload
->PayloadSize
= PayloadLen
;
1345 Parser the Notify Cookie payload.
1347 This function parses the Notify Cookie payload.If the Notify ProtocolId is not
1348 IPSEC_PROTO_ISAKMP or if the SpiSize is not zero or if the MessageType is not
1349 the COOKIE, return EFI_INVALID_PARAMETER.
1351 @param[in] IkeNCookie Pointer to the IKE_PAYLOAD which contians the
1352 Notify Cookie payload.
1354 @param[in, out] IkeSaSession Pointer to the relevant IKE SA Session.
1356 @retval EFI_SUCCESS The Notify Cookie Payload is valid.
1357 @retval EFI_INVALID_PARAMETER The Notify Cookie Payload is invalid.
1358 @retval EFI_OUT_OF_RESOURCE The required resource can't be allocated.
1362 Ikev2ParserNotifyCookiePayload (
1363 IN IKE_PAYLOAD
*IkeNCookie
,
1364 IN OUT IKEV2_SA_SESSION
*IkeSaSession
1367 IKEV2_NOTIFY
*NotifyPayload
;
1368 UINTN NotifyDataSize
;
1370 NotifyPayload
= (IKEV2_NOTIFY
*)IkeNCookie
->PayloadBuf
;
1372 if ((NotifyPayload
->ProtocolId
!= IPSEC_PROTO_ISAKMP
) ||
1373 (NotifyPayload
->SpiSize
!= 0) ||
1374 (NotifyPayload
->MessageType
!= IKEV2_NOTIFICATION_COOKIE
)
1376 return EFI_INVALID_PARAMETER
;
1379 NotifyDataSize
= NotifyPayload
->Header
.PayloadLength
- sizeof (IKEV2_NOTIFY
);
1380 IkeSaSession
->NCookie
= AllocateZeroPool (NotifyDataSize
);
1381 if (IkeSaSession
->NCookie
== NULL
) {
1382 return EFI_OUT_OF_RESOURCES
;
1385 IkeSaSession
->NCookieSize
= NotifyDataSize
;
1388 IkeSaSession
->NCookie
,
1389 NotifyPayload
+ sizeof (IKEV2_NOTIFY
),
1398 Generate the Certificate payload or Certificate Request Payload.
1400 Since the Certificate Payload structure is same with Certificate Request Payload,
1401 the only difference is that one contains the Certificate Data, other contains
1402 the acceptable certificateion CA. This function generate Certificate payload
1403 or Certificate Request Payload defined in RFC 4306, but all the fields
1404 in the payload are still in host order and need call Ikev2EncodePayload()
1405 to convert those fields from the host order to network order beforing sending it.
1407 @param[in] IkeSaSession Pointer to IKE SA Session to be used of Delete payload
1409 @param[in] NextPayload The next paylaod type in NextPayload field of
1411 @param[in] Certificate Pointer of buffer contains the certification data.
1412 @param[in] CertificateLen The length of Certificate in byte.
1413 @param[in] EncodeType Specified the Certificate Encodeing which is defined
1415 @param[in] IsRequest To indicate create Certificate Payload or Certificate
1416 Request Payload. If it is TURE, create Certificate
1417 Payload. Otherwise, create Certificate Request Payload.
1419 @retval a Pointer to IKE Payload whose payload buffer containing the Certificate
1420 payload or Certificated Request payload.
1424 Ikev2GenerateCertificatePayload (
1425 IN IKEV2_SA_SESSION
*IkeSaSession
,
1426 IN UINT8 NextPayload
,
1427 IN UINT8
*Certificate
,
1428 IN UINTN CertificateLen
,
1429 IN UINT8 EncodeType
,
1430 IN BOOLEAN IsRequest
1433 IKE_PAYLOAD
*CertPayload
;
1438 HASH_DATA_FRAGMENT Fragment
[1];
1445 // 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
1446 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1447 // ! Next Payload !C! RESERVED ! Payload Length !
1448 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1449 // ! Cert Encoding ! !
1450 // +-+-+-+-+-+-+-+-+ !
1451 // ~ Certificate Data/Authority ~
1453 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1456 Status
= EFI_SUCCESS
;
1461 PayloadLen
= (UINT16
) (sizeof (IKEV2_CERT
) + CertificateLen
);
1464 // SHA1 Hash length is 20.
1466 PayloadLen
= (UINT16
) (sizeof (IKEV2_CERT
) + 20);
1469 Cert
= AllocateZeroPool (PayloadLen
);
1475 // Generate Certificate Payload or Certificate Request Payload.
1477 Cert
->Header
.NextPayload
= NextPayload
;
1478 Cert
->Header
.PayloadLength
= PayloadLen
;
1479 Cert
->CertEncoding
= EncodeType
;
1482 ((UINT8
*)Cert
) + sizeof (IKEV2_CERT
),
1487 Status
= IpSecCryptoIoGetPublicKeyFromCert (
1493 if (EFI_ERROR (Status
)) {
1497 Fragment
[0].Data
= PublicKey
;
1498 Fragment
[0].DataSize
= PublicKeyLen
;
1499 HashDataSize
= IpSecGetHmacDigestLength (IKE_AALG_SHA1HMAC
);
1500 HashData
= AllocateZeroPool (HashDataSize
);
1502 Status
= IpSecCryptoIoHash (
1509 if (EFI_ERROR (Status
)) {
1514 ((UINT8
*)Cert
) + sizeof (IKEV2_CERT
),
1520 CertPayload
= IkePayloadAlloc ();
1521 if (CertPayload
== NULL
) {
1526 CertPayload
->PayloadType
= IKEV2_PAYLOAD_TYPE_CERT
;
1528 CertPayload
->PayloadType
= IKEV2_PAYLOAD_TYPE_CERTREQ
;
1531 CertPayload
->PayloadBuf
= (UINT8
*) Cert
;
1532 CertPayload
->PayloadSize
= PayloadLen
;
1539 if (PublicKey
!= NULL
) {
1540 FreePool (PublicKey
);
1546 Remove and free all IkePayloads in the specified IkePacket.
1548 @param[in] IkePacket The pointer of IKE_PACKET.
1553 IN IKE_PACKET
*IkePacket
1556 LIST_ENTRY
*PayloadEntry
;
1557 IKE_PAYLOAD
*IkePayload
;
1559 // remove all payloads from list and free each payload.
1561 while (!IsListEmpty (&IkePacket
->PayloadList
)) {
1562 PayloadEntry
= IkePacket
->PayloadList
.ForwardLink
;
1563 IkePayload
= IKE_PAYLOAD_BY_PACKET (PayloadEntry
);
1564 IKE_PACKET_REMOVE_PAYLOAD (IkePacket
, IkePayload
);
1565 IkePayloadFree (IkePayload
);
1570 Transfer the intrnal data structure IKEV2_SA_DATA to IKEV2_SA structure defined in RFC.
1572 @param[in] SessionCommon Pointer to IKEV2_SESSION_COMMON related to the SA Session.
1573 @param[in] SaData Pointer to IKEV2_SA_DATA to be transfered.
1575 @retval return the pointer of IKEV2_SA.
1580 IN IKEV2_SESSION_COMMON
*SessionCommon
,
1581 IN IKEV2_SA_DATA
*SaData
1586 IKEV2_PROPOSAL_DATA
*ProposalData
;
1587 IKEV2_TRANSFORM_DATA
*TransformData
;
1588 UINTN TotalTransforms
;
1590 UINTN TransformsSize
;
1591 UINTN TransformSize
;
1592 UINTN ProposalsSize
;
1594 UINTN ProposalIndex
;
1595 UINTN TransformIndex
;
1596 IKE_SA_ATTRIBUTE
*SaAttribute
;
1597 IKEV2_PROPOSAL
*Proposal
;
1598 IKEV2_PROPOSAL
*LastProposal
;
1599 IKEV2_TRANSFORM
*Transform
;
1600 IKEV2_TRANSFORM
*LastTransform
;
1603 // Transform IKE_SA_DATA structure to IKE_SA Payload.
1604 // Header length is host order.
1605 // The returned IKE_SA struct should be freed by caller.
1607 TotalTransforms
= 0;
1609 // Caculate the Proposal numbers and Transform numbers.
1611 for (ProposalIndex
= 0; ProposalIndex
< SaData
->NumProposals
; ProposalIndex
++) {
1613 ProposalData
= (IKEV2_PROPOSAL_DATA
*) (SaData
+ 1) + ProposalIndex
;
1614 TotalTransforms
+= ProposalData
->NumTransforms
;
1617 SaSize
= sizeof (IKEV2_SA
) +
1618 SaData
->NumProposals
* sizeof (IKEV2_PROPOSAL
) +
1619 TotalTransforms
* (sizeof (IKEV2_TRANSFORM
) + MAX_SA_ATTRS_SIZE
);
1621 // Allocate buffer for IKE_SA.
1623 Sa
= AllocateZeroPool (SaSize
);
1624 ASSERT (Sa
!= NULL
);
1625 CopyMem (Sa
, SaData
, sizeof (IKEV2_SA
));
1626 Sa
->Header
.PayloadLength
= (UINT16
) sizeof (IKEV2_SA
);
1628 LastProposal
= NULL
;
1629 Proposal
= (IKEV2_PROPOSAL
*) (Sa
+ 1);
1634 ProposalData
= (IKEV2_PROPOSAL_DATA
*) (SaData
+ 1);
1635 for (ProposalIndex
= 0; ProposalIndex
< SaData
->NumProposals
; ProposalIndex
++) {
1636 Proposal
->ProposalIndex
= ProposalData
->ProposalIndex
;
1637 Proposal
->ProtocolId
= ProposalData
->ProtocolId
;
1638 Proposal
->NumTransforms
= ProposalData
->NumTransforms
;
1640 if (ProposalData
->Spi
== 0) {
1641 Proposal
->SpiSize
= 0;
1643 Proposal
->SpiSize
= 4;
1644 *(UINT32
*) (Proposal
+ 1) = HTONL (*((UINT32
*)ProposalData
->Spi
));
1648 LastTransform
= NULL
;
1649 Transform
= (IKEV2_TRANSFORM
*) ((UINT8
*) (Proposal
+ 1) + Proposal
->SpiSize
);
1652 // Set IKE_TRANSFORM
1654 for (TransformIndex
= 0; TransformIndex
< ProposalData
->NumTransforms
; TransformIndex
++) {
1655 TransformData
= (IKEV2_TRANSFORM_DATA
*) (ProposalData
+ 1) + TransformIndex
;
1656 Transform
->TransformType
= TransformData
->TransformType
;
1657 Transform
->TransformId
= HTONS (TransformData
->TransformId
);
1661 // If the Encryption Algorithm is variable key length set the key length in attribute.
1662 // Note that only a single attribute type (Key Length) is defined and it is fixed length.
1664 if (Transform
->TransformType
== IKEV2_TRANSFORM_TYPE_ENCR
&& TransformData
->Attribute
.Attr
.AttrValue
!= 0) {
1665 SaAttribute
= (IKE_SA_ATTRIBUTE
*) (Transform
+ 1);
1666 SaAttribute
->AttrType
= HTONS (IKEV2_ATTRIBUTE_TYPE_KEYLEN
| SA_ATTR_FORMAT_BIT
);
1667 SaAttribute
->Attr
.AttrValue
= HTONS (TransformData
->Attribute
.Attr
.AttrValue
);
1668 SaAttrsSize
= sizeof (IKE_SA_ATTRIBUTE
);
1672 // If the Integrity Algorithm is variable key length set the key length in attribute.
1674 if (Transform
->TransformType
== IKEV2_TRANSFORM_TYPE_INTEG
&& 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
);
1681 TransformSize
= sizeof (IKEV2_TRANSFORM
) + SaAttrsSize
;
1682 TransformsSize
+= TransformSize
;
1684 Transform
->Header
.NextPayload
= IKE_TRANSFORM_NEXT_PAYLOAD_MORE
;
1685 Transform
->Header
.PayloadLength
= HTONS ((UINT16
)TransformSize
);
1687 if (TransformIndex
== ProposalData
->NumTransforms
) {
1688 LastTransform
->Header
.NextPayload
= IKE_TRANSFORM_NEXT_PAYLOAD_NONE
;
1691 Transform
= (IKEV2_TRANSFORM
*)((UINT8
*) Transform
+ TransformSize
);
1695 // Set Proposal's Generic Header.
1697 ProposalSize
= sizeof (IKEV2_PROPOSAL
) + Proposal
->SpiSize
+ TransformsSize
;
1698 ProposalsSize
+= ProposalSize
;
1699 Proposal
->Header
.NextPayload
= IKE_PROPOSAL_NEXT_PAYLOAD_MORE
;
1700 Proposal
->Header
.PayloadLength
= HTONS ((UINT16
)ProposalSize
);
1702 if (ProposalIndex
== SaData
->NumProposals
) {
1703 LastProposal
->Header
.NextPayload
= IKE_PROPOSAL_NEXT_PAYLOAD_NONE
;
1707 // Point to next Proposal Payload
1709 Proposal
= (IKEV2_PROPOSAL
*) ((UINT8
*) Proposal
+ ProposalSize
);
1710 ProposalData
= (IKEV2_PROPOSAL_DATA
*)(((UINT8
*)ProposalData
) + sizeof (IKEV2_PROPOSAL_DATA
) + (TransformIndex
* sizeof (IKEV2_TRANSFORM_DATA
)));
1713 // Set SA's Generic Header.
1715 Sa
->Header
.PayloadLength
= (UINT16
) (Sa
->Header
.PayloadLength
+ ProposalsSize
);
1722 This function converts the received SA payload to internal data structure.
1724 @param[in] SessionCommon Pointer to IKE Common Session used to decode the SA
1726 @param[in] Sa Pointer to SA Payload
1728 @return a Pointer to internal data structure for SA payload.
1733 IN IKEV2_SESSION_COMMON
*SessionCommon
,
1737 IKEV2_SA_DATA
*SaData
;
1739 IKEV2_PROPOSAL
*Proposal
;
1740 IKEV2_TRANSFORM
*Transform
;
1741 UINTN TotalProposals
;
1742 UINTN TotalTransforms
;
1743 UINTN ProposalNextPayloadSum
;
1744 UINTN ProposalIndex
;
1745 UINTN TransformIndex
;
1747 UINT16 ProposalSize
;
1748 UINTN ProposalRemaining
;
1749 UINT16 TransformSize
;
1750 UINTN SaAttrRemaining
;
1751 IKE_SA_ATTRIBUTE
*SaAttribute
;
1752 IKEV2_PROPOSAL_DATA
*ProposalData
;
1753 IKEV2_TRANSFORM_DATA
*TransformData
;
1757 // Transfrom from IKE_SA payload to IKE_SA_DATA structure.
1758 // Header length NTOH is already done
1759 // The returned IKE_SA_DATA should be freed by caller
1762 Status
= EFI_SUCCESS
;
1765 // First round sanity check and size calculae
1768 TotalTransforms
= 0;
1769 ProposalNextPayloadSum
= 0;
1770 SaRemaining
= Sa
->Header
.PayloadLength
- sizeof (IKEV2_SA
);// Point to current position in SA
1771 Proposal
= (IKEV2_PROPOSAL
*)((IKEV2_SA
*)(Sa
)+1);
1774 // Caculate the number of Proposal payload and the total numbers of
1775 // Transforms payload (the transforms in all proposal payload).
1777 while (SaRemaining
> sizeof (IKEV2_PROPOSAL
)) {
1778 ProposalSize
= NTOHS (Proposal
->Header
.PayloadLength
);
1779 if (SaRemaining
< ProposalSize
) {
1780 Status
= EFI_INVALID_PARAMETER
;
1784 if (Proposal
->SpiSize
!= 0 && Proposal
->SpiSize
!= 4) {
1785 Status
= EFI_INVALID_PARAMETER
;
1790 TotalTransforms
+= Proposal
->NumTransforms
;
1791 SaRemaining
-= ProposalSize
;
1792 ProposalNextPayloadSum
+= Proposal
->Header
.NextPayload
;
1793 Proposal
= IKEV2_NEXT_PROPOSAL_WITH_SIZE (Proposal
, ProposalSize
);
1797 // Check the proposal number. The Proposal Payload type is 2. Nonce Paylod is 0.
1798 // SUM(ProposalNextPayload) = Proposal Num * 2 + Noce Payload Type (0).
1800 if (TotalProposals
== 0 ||
1801 (TotalProposals
- 1) * IKE_PROPOSAL_NEXT_PAYLOAD_MORE
+ IKE_PROPOSAL_NEXT_PAYLOAD_NONE
!= ProposalNextPayloadSum
1803 Status
= EFI_INVALID_PARAMETER
;
1808 // Second round sanity check and decode. Transform the SA payload into
1809 // a IKE_SA_DATA structure.
1811 SaData
= (IKEV2_SA_DATA
*) AllocateZeroPool (
1812 sizeof (IKEV2_SA_DATA
) +
1813 TotalProposals
* sizeof (IKEV2_PROPOSAL_DATA
) +
1814 TotalTransforms
* sizeof (IKEV2_TRANSFORM_DATA
)
1816 ASSERT (SaData
!= NULL
);
1817 CopyMem (SaData
, Sa
, sizeof (IKEV2_SA
));
1818 SaData
->NumProposals
= TotalProposals
;
1819 ProposalData
= (IKEV2_PROPOSAL_DATA
*) (SaData
+ 1);
1823 // 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
1824 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1825 // ! Next Payload ! RESERVED ! Payload Length !
1826 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1827 // ! Proposal # ! Protocol-Id ! SPI Size !# of Transforms!
1828 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1829 // ! SPI (variable) !
1830 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1832 for (ProposalIndex
= 0, Proposal
= IKEV2_SA_FIRST_PROPOSAL (Sa
);
1833 ProposalIndex
< TotalProposals
;
1838 // TODO: check ProposalId
1840 ProposalData
->ProposalIndex
= Proposal
->ProposalIndex
;
1841 ProposalData
->ProtocolId
= Proposal
->ProtocolId
;
1842 if (Proposal
->SpiSize
== 0) {
1843 ProposalData
->Spi
= 0;
1848 Spi
= AllocateZeroPool (Proposal
->SpiSize
);
1849 ASSERT (Spi
!= NULL
);
1850 CopyMem (Spi
, (UINT32
*) (Proposal
+ 1), Proposal
->SpiSize
);
1851 *((UINT32
*) Spi
) = NTOHL (*((UINT32
*) Spi
));
1852 ProposalData
->Spi
= Spi
;
1855 ProposalData
->NumTransforms
= Proposal
->NumTransforms
;
1856 ProposalSize
= NTOHS (Proposal
->Header
.PayloadLength
);
1857 ProposalRemaining
= ProposalSize
;
1859 // Transform Payload
1860 // 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
1861 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1862 // ! Next Payload ! RESERVED ! Payload Length !
1863 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1864 // !Transform Type ! RESERVED ! Transform ID !
1865 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1867 // ~ SA Attributes ~
1869 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1871 Transform
= IKEV2_PROPOSAL_FIRST_TRANSFORM (Proposal
);
1872 for (TransformIndex
= 0; TransformIndex
< Proposal
->NumTransforms
; TransformIndex
++) {
1875 // Transfer the IKEV2_TRANSFORM structure into internal IKEV2_TRANSFORM_DATA struture.
1877 TransformData
= (IKEV2_TRANSFORM_DATA
*) (ProposalData
+ 1) + TransformIndex
;
1878 TransformData
->TransformId
= NTOHS (Transform
->TransformId
);
1879 TransformData
->TransformType
= Transform
->TransformType
;
1880 TransformSize
= NTOHS (Transform
->Header
.PayloadLength
);
1882 // Check the Proposal Data is correct.
1884 if (ProposalRemaining
< TransformSize
) {
1885 Status
= EFI_INVALID_PARAMETER
;
1890 // Check if the Transform payload includes Attribution.
1892 SaAttrRemaining
= TransformSize
- sizeof (IKEV2_TRANSFORM
);
1895 // According to RFC 4603, currently only the Key length attribute type is
1896 // supported. For each Transform, there is only one attributeion.
1898 if (SaAttrRemaining
> 0) {
1899 if (SaAttrRemaining
!= sizeof (IKE_SA_ATTRIBUTE
)) {
1900 Status
= EFI_INVALID_PARAMETER
;
1903 SaAttribute
= (IKE_SA_ATTRIBUTE
*) ((IKEV2_TRANSFORM
*)(Transform
) + 1);
1904 TransformData
->Attribute
.AttrType
= (UINT16
)((NTOHS (SaAttribute
->AttrType
)) & ~SA_ATTR_FORMAT_BIT
);
1905 TransformData
->Attribute
.Attr
.AttrValue
= NTOHS (SaAttribute
->Attr
.AttrValue
);
1908 // Currently, only supports the Key Length Attribution.
1910 if (TransformData
->Attribute
.AttrType
!= IKEV2_ATTRIBUTE_TYPE_KEYLEN
) {
1911 Status
= EFI_INVALID_PARAMETER
;
1917 // Move to next Transform
1919 Transform
= IKEV2_NEXT_TRANSFORM_WITH_SIZE (Transform
, TransformSize
);
1921 Proposal
= IKEV2_NEXT_PROPOSAL_WITH_SIZE (Proposal
, ProposalSize
);
1922 ProposalData
= (IKEV2_PROPOSAL_DATA
*) ((UINT8
*)(ProposalData
+ 1) +
1923 ProposalData
->NumTransforms
*
1924 sizeof (IKEV2_TRANSFORM_DATA
));
1928 if (EFI_ERROR (Status
) && SaData
!= NULL
) {
1936 General interface of payload encoding.
1938 This function encodes the internal data structure into payload which
1939 is defined in RFC 4306. The IkePayload->PayloadBuf is used to store both the input
1940 payload and converted payload. Only the SA payload use the interal structure
1941 to store the attribute. Other payload use structure which is same with the RFC
1942 defined, for this kind payloads just do host order to network order change of
1945 @param[in] SessionCommon Pointer to IKE Session Common used to encode the payload.
1946 @param[in, out] IkePayload Pointer to IKE payload to be encoded as input, and
1947 store the encoded result as output.
1949 @retval EFI_INVALID_PARAMETER Meet error when encoding the SA payload.
1950 @retval EFI_SUCCESS Encoded successfully.
1954 Ikev2EncodePayload (
1955 IN UINT8
*SessionCommon
,
1956 IN OUT IKE_PAYLOAD
*IkePayload
1959 IKEV2_SA_DATA
*SaData
;
1960 IKEV2_SA
*SaPayload
;
1961 IKEV2_COMMON_PAYLOAD_HEADER
*PayloadHdr
;
1962 IKEV2_NOTIFY
*NotifyPayload
;
1963 IKEV2_DELETE
*DeletePayload
;
1964 IKEV2_KEY_EXCHANGE
*KeyPayload
;
1965 IKEV2_TS
*TsPayload
;
1966 IKEV2_CFG_ATTRIBUTES
*CfgAttribute
;
1969 TRAFFIC_SELECTOR
*TrafficSelector
;
1972 // Transform the Internal IKE structure to IKE payload.
1973 // Only the SA payload use the interal structure to store the attribute.
1974 // Other payload use structure which same with the RFC defined, so there is
1975 // no need to tranform them to IKE payload.
1977 switch (IkePayload
->PayloadType
) {
1978 case IKEV2_PAYLOAD_TYPE_SA
:
1980 // Transform IKE_SA_DATA to IK_SA payload
1982 SaData
= (IKEV2_SA_DATA
*) IkePayload
->PayloadBuf
;
1983 SaPayload
= Ikev2EncodeSa ((IKEV2_SESSION_COMMON
*) SessionCommon
, SaData
);
1985 if (SaPayload
== NULL
) {
1986 return EFI_INVALID_PARAMETER
;
1988 if (!IkePayload
->IsPayloadBufExt
) {
1989 FreePool (IkePayload
->PayloadBuf
);
1991 IkePayload
->PayloadBuf
= (UINT8
*) SaPayload
;
1992 IkePayload
->IsPayloadBufExt
= FALSE
;
1995 case IKEV2_PAYLOAD_TYPE_NOTIFY
:
1996 NotifyPayload
= (IKEV2_NOTIFY
*) IkePayload
->PayloadBuf
;
1997 NotifyPayload
->MessageType
= HTONS (NotifyPayload
->MessageType
);
2000 case IKEV2_PAYLOAD_TYPE_DELETE
:
2001 DeletePayload
= (IKEV2_DELETE
*) IkePayload
->PayloadBuf
;
2002 DeletePayload
->NumSpis
= HTONS (DeletePayload
->NumSpis
);
2005 case IKEV2_PAYLOAD_TYPE_KE
:
2006 KeyPayload
= (IKEV2_KEY_EXCHANGE
*) IkePayload
->PayloadBuf
;
2007 KeyPayload
->DhGroup
= HTONS (KeyPayload
->DhGroup
);
2010 case IKEV2_PAYLOAD_TYPE_TS_INIT
:
2011 case IKEV2_PAYLOAD_TYPE_TS_RSP
:
2012 TsPayload
= (IKEV2_TS
*) IkePayload
->PayloadBuf
;
2013 TsBuffer
= IkePayload
->PayloadBuf
+ sizeof (IKEV2_TS
);
2015 for (Index
= 0; Index
< TsPayload
->TSNumbers
; Index
++) {
2016 TrafficSelector
= (TRAFFIC_SELECTOR
*) TsBuffer
;
2017 TsBuffer
= TsBuffer
+ TrafficSelector
->SelecorLen
;
2019 // Host order to network order
2021 TrafficSelector
->SelecorLen
= HTONS (TrafficSelector
->SelecorLen
);
2022 TrafficSelector
->StartPort
= HTONS (TrafficSelector
->StartPort
);
2023 TrafficSelector
->EndPort
= HTONS (TrafficSelector
->EndPort
);
2029 case IKEV2_PAYLOAD_TYPE_CP
:
2030 CfgAttribute
= (IKEV2_CFG_ATTRIBUTES
*)(((IKEV2_CFG
*) IkePayload
->PayloadBuf
) + 1);
2031 CfgAttribute
->AttritType
= HTONS (CfgAttribute
->AttritType
);
2032 CfgAttribute
->ValueLength
= HTONS (CfgAttribute
->ValueLength
);
2034 case IKEV2_PAYLOAD_TYPE_ID_INIT
:
2035 case IKEV2_PAYLOAD_TYPE_ID_RSP
:
2036 case IKEV2_PAYLOAD_TYPE_AUTH
:
2041 PayloadHdr
= (IKEV2_COMMON_PAYLOAD_HEADER
*) IkePayload
->PayloadBuf
;
2042 IkePayload
->PayloadSize
= PayloadHdr
->PayloadLength
;
2043 PayloadHdr
->PayloadLength
= HTONS (PayloadHdr
->PayloadLength
);
2044 IKEV2_DUMP_PAYLOAD (IkePayload
);
2049 The general interface for decoding Payload.
2051 This function converts the received Payload into internal structure.
2053 @param[in] SessionCommon Pointer to IKE Session Common used for decoding.
2054 @param[in, out] IkePayload Pointer to IKE payload to be decoded as input, and
2055 store the decoded result as output.
2057 @retval EFI_INVALID_PARAMETER Meet error when decoding the SA payload.
2058 @retval EFI_SUCCESS Decoded successfully.
2062 Ikev2DecodePayload (
2063 IN UINT8
*SessionCommon
,
2064 IN OUT IKE_PAYLOAD
*IkePayload
2067 IKEV2_COMMON_PAYLOAD_HEADER
*PayloadHdr
;
2070 IKEV2_SA_DATA
*SaData
;
2072 IKEV2_NOTIFY
*NotifyPayload
;
2073 IKEV2_DELETE
*DeletePayload
;
2075 TRAFFIC_SELECTOR
*TsSelector
;
2076 IKEV2_TS
*TsPayload
;
2077 IKEV2_KEY_EXCHANGE
*KeyPayload
;
2078 IKEV2_CFG_ATTRIBUTES
*CfgAttribute
;
2082 // Transform the IKE payload to Internal IKE structure.
2083 // Only the SA payload and Hash Payload use the interal
2084 // structure to store the attribute. Other payloads use
2085 // structure which is same with the definitions in RFC,
2086 // so there is no need to tranform them to internal IKE
2089 Status
= EFI_SUCCESS
;
2090 PayloadSize
= (UINT16
) IkePayload
->PayloadSize
;
2091 PayloadType
= IkePayload
->PayloadType
;
2092 PayloadHdr
= (IKEV2_COMMON_PAYLOAD_HEADER
*) IkePayload
->PayloadBuf
;
2094 // The PayloadSize is the size of whole payload.
2095 // Replace HTONS operation to assignment statements, since the result is same.
2097 PayloadHdr
->PayloadLength
= PayloadSize
;
2099 IKEV2_DUMP_PAYLOAD (IkePayload
);
2100 switch (PayloadType
) {
2101 case IKEV2_PAYLOAD_TYPE_SA
:
2102 if (PayloadSize
< sizeof (IKEV2_SA
)) {
2103 Status
= EFI_INVALID_PARAMETER
;
2107 SaData
= Ikev2DecodeSa ((IKEV2_SESSION_COMMON
*) SessionCommon
, (IKEV2_SA
*) PayloadHdr
);
2108 if (SaData
== NULL
) {
2109 Status
= EFI_INVALID_PARAMETER
;
2113 if (!IkePayload
->IsPayloadBufExt
) {
2114 FreePool (IkePayload
->PayloadBuf
);
2117 IkePayload
->PayloadBuf
= (UINT8
*) SaData
;
2118 IkePayload
->IsPayloadBufExt
= FALSE
;
2121 case IKEV2_PAYLOAD_TYPE_ID_INIT
:
2122 case IKEV2_PAYLOAD_TYPE_ID_RSP
:
2123 if (PayloadSize
< sizeof (IKEV2_ID
)) {
2124 Status
= EFI_INVALID_PARAMETER
;
2129 case IKEV2_PAYLOAD_TYPE_NOTIFY
:
2130 if (PayloadSize
< sizeof (IKEV2_NOTIFY
)) {
2131 Status
= EFI_INVALID_PARAMETER
;
2135 NotifyPayload
= (IKEV2_NOTIFY
*) PayloadHdr
;
2136 NotifyPayload
->MessageType
= NTOHS (NotifyPayload
->MessageType
);
2139 case IKEV2_PAYLOAD_TYPE_DELETE
:
2140 if (PayloadSize
< sizeof (IKEV2_DELETE
)) {
2141 Status
= EFI_INVALID_PARAMETER
;
2145 DeletePayload
= (IKEV2_DELETE
*) PayloadHdr
;
2146 DeletePayload
->NumSpis
= NTOHS (DeletePayload
->NumSpis
);
2149 case IKEV2_PAYLOAD_TYPE_AUTH
:
2150 if (PayloadSize
< sizeof (IKEV2_AUTH
)) {
2151 Status
= EFI_INVALID_PARAMETER
;
2156 case IKEV2_PAYLOAD_TYPE_KE
:
2157 KeyPayload
= (IKEV2_KEY_EXCHANGE
*) IkePayload
->PayloadBuf
;
2158 KeyPayload
->DhGroup
= HTONS (KeyPayload
->DhGroup
);
2161 case IKEV2_PAYLOAD_TYPE_TS_INIT
:
2162 case IKEV2_PAYLOAD_TYPE_TS_RSP
:
2164 if (PayloadSize
< sizeof (IKEV2_TS
)) {
2165 Status
= EFI_INVALID_PARAMETER
;
2169 // Parse each traffic selector and transfer network-order to host-order
2171 TsPayload
= (IKEV2_TS
*) IkePayload
->PayloadBuf
;
2172 TsSelector
= (TRAFFIC_SELECTOR
*) (IkePayload
->PayloadBuf
+ sizeof (IKEV2_TS
));
2174 for (Index
= 0; Index
< TsPayload
->TSNumbers
; Index
++) {
2175 TsSelector
->SelecorLen
= NTOHS (TsSelector
->SelecorLen
);
2176 TsSelector
->StartPort
= NTOHS (TsSelector
->StartPort
);
2177 TsSelector
->EndPort
= NTOHS (TsSelector
->EndPort
);
2179 TsTotalSize
= (UINT16
) (TsTotalSize
+ TsSelector
->SelecorLen
);
2180 TsSelector
= (TRAFFIC_SELECTOR
*) ((UINT8
*) TsSelector
+ TsSelector
->SelecorLen
);
2183 // Check if the total size of Traffic Selectors is correct.
2185 if (TsTotalSize
!= PayloadSize
- sizeof(IKEV2_TS
)) {
2186 Status
= EFI_INVALID_PARAMETER
;
2189 case IKEV2_PAYLOAD_TYPE_CP
:
2190 CfgAttribute
= (IKEV2_CFG_ATTRIBUTES
*)(((IKEV2_CFG
*) IkePayload
->PayloadBuf
) + 1);
2191 CfgAttribute
->AttritType
= NTOHS (CfgAttribute
->AttritType
);
2192 CfgAttribute
->ValueLength
= NTOHS (CfgAttribute
->ValueLength
);
2203 Decode the IKE packet.
2205 This function first decrypts the IKE packet if needed , then separates the whole
2206 IKE packet from the IkePacket->PayloadBuf into IkePacket payload list.
2208 @param[in] SessionCommon Pointer to IKEV1_SESSION_COMMON containing
2209 some parameter used by IKE packet decoding.
2210 @param[in, out] IkePacket The IKE Packet to be decoded on input, and
2211 the decoded result on return.
2212 @param[in] IkeType The type of IKE. IKE_SA_TYPE, IKE_INFO_TYPE and
2213 IKE_CHILD_TYPE are supported.
2215 @retval EFI_SUCCESS The IKE packet is decoded successfully.
2216 @retval Otherwise The IKE packet decoding is failed.
2221 IN IKEV2_SESSION_COMMON
*SessionCommon
,
2222 IN OUT IKE_PACKET
*IkePacket
,
2227 IKEV2_COMMON_PAYLOAD_HEADER
*PayloadHdr
;
2231 IKE_PAYLOAD
*IkePayload
;
2232 IKE_HEADER
*IkeHeader
;
2233 IKEV2_SA_SESSION
*IkeSaSession
;
2238 // Check if the IkePacket need decrypt.
2240 if (SessionCommon
->State
>= IkeStateAuth
) {
2241 Status
= Ikev2DecryptPacket (SessionCommon
, IkePacket
, IkeType
);
2242 if (EFI_ERROR (Status
)) {
2247 Status
= EFI_SUCCESS
;
2250 // If the IkePacket doesn't contain any payload return invalid parameter.
2252 if (IkePacket
->Header
->NextPayload
== IKEV2_PAYLOAD_TYPE_NONE
) {
2253 if ((SessionCommon
->State
>= IkeStateAuth
) &&
2254 (IkePacket
->Header
->ExchangeType
== IKEV2_EXCHANGE_TYPE_INFO
)
2257 // If it is Liveness check, there will be no payload load in the encrypt payload.
2259 Status
= EFI_SUCCESS
;
2261 Status
= EFI_INVALID_PARAMETER
;
2266 // If the PayloadTotalSize < Header length, return invalid parameter.
2268 RemainBytes
= IkePacket
->PayloadTotalSize
;
2269 if (RemainBytes
< sizeof (IKEV2_COMMON_PAYLOAD_HEADER
)) {
2270 Status
= EFI_INVALID_PARAMETER
;
2275 // If the packet is first or second message, store whole message in
2276 // IkeSa->InitiPacket or IkeSa->RespPacket for following Auth Payload
2279 if (IkePacket
->Header
->ExchangeType
== IKEV2_EXCHANGE_TYPE_INIT
) {
2280 IkeHeader
= AllocateZeroPool (sizeof (IKE_HEADER
));
2281 ASSERT (IkeHeader
!= NULL
);
2282 CopyMem (IkeHeader
, IkePacket
->Header
, sizeof (IKE_HEADER
));
2285 // Before store the whole packet, roll back the host order to network order,
2286 // since the header order was changed in the IkePacketFromNetbuf.
2288 IkeHdrNetToHost (IkeHeader
);
2289 IkeSaSession
= IKEV2_SA_SESSION_FROM_COMMON (SessionCommon
);
2290 if (SessionCommon
->IsInitiator
) {
2291 IkeSaSession
->RespPacket
= AllocateZeroPool (IkePacket
->Header
->Length
);
2292 IkeSaSession
->RespPacketSize
= IkePacket
->Header
->Length
;
2293 CopyMem (IkeSaSession
->RespPacket
, IkeHeader
, sizeof (IKE_HEADER
));
2295 IkeSaSession
->RespPacket
+ sizeof (IKE_HEADER
),
2296 IkePacket
->PayloadsBuf
,
2297 IkePacket
->Header
->Length
- sizeof (IKE_HEADER
)
2300 IkeSaSession
->InitPacket
= AllocateZeroPool (IkePacket
->Header
->Length
);
2301 IkeSaSession
->InitPacketSize
= IkePacket
->Header
->Length
;
2302 CopyMem (IkeSaSession
->InitPacket
, IkeHeader
, sizeof (IKE_HEADER
));
2304 IkeSaSession
->InitPacket
+ sizeof (IKE_HEADER
),
2305 IkePacket
->PayloadsBuf
,
2306 IkePacket
->Header
->Length
- sizeof (IKE_HEADER
)
2312 // Point to the first Payload
2314 PayloadHdr
= (IKEV2_COMMON_PAYLOAD_HEADER
*) IkePacket
->PayloadsBuf
;
2315 PayloadType
= IkePacket
->Header
->NextPayload
;
2318 // Parse each payload
2320 while (RemainBytes
>= sizeof (IKEV2_COMMON_PAYLOAD_HEADER
)) {
2321 PayloadSize
= NTOHS (PayloadHdr
->PayloadLength
);
2324 //Check the size of the payload is correct.
2326 if (RemainBytes
< PayloadSize
) {
2327 Status
= EFI_INVALID_PARAMETER
;
2332 // At certain states, it should save some datas before decoding.
2334 if (SessionCommon
->BeforeDecodePayload
!= NULL
) {
2335 SessionCommon
->BeforeDecodePayload (
2336 (UINT8
*) SessionCommon
,
2337 (UINT8
*) PayloadHdr
,
2344 // Initial IkePayload
2346 IkePayload
= IkePayloadAlloc ();
2347 ASSERT (IkePayload
!= NULL
);
2349 IkePayload
->PayloadType
= PayloadType
;
2350 IkePayload
->PayloadBuf
= (UINT8
*) PayloadHdr
;
2351 IkePayload
->PayloadSize
= PayloadSize
;
2352 IkePayload
->IsPayloadBufExt
= TRUE
;
2354 Status
= Ikev2DecodePayload ((UINT8
*) SessionCommon
, IkePayload
);
2355 if (EFI_ERROR (Status
)) {
2359 IPSEC_DUMP_BUF ("After Decoding Payload", IkePayload
->PayloadBuf
, IkePayload
->PayloadSize
);
2361 // Add each payload into packet
2362 // Notice, the IkePacket->Hdr->Lenght still recode the whole IkePacket length
2363 // which is before the decoding.
2365 IKE_PACKET_APPEND_PAYLOAD (IkePacket
, IkePayload
);
2367 RemainBytes
-= PayloadSize
;
2368 PayloadType
= PayloadHdr
->NextPayload
;
2369 if (PayloadType
== IKEV2_PAYLOAD_TYPE_NONE
) {
2373 PayloadHdr
= (IKEV2_COMMON_PAYLOAD_HEADER
*) ((UINT8
*) PayloadHdr
+ PayloadSize
);
2376 if (PayloadType
!= IKEV2_PAYLOAD_TYPE_NONE
) {
2377 Status
= EFI_INVALID_PARAMETER
;
2382 if (EFI_ERROR (Status
)) {
2383 ClearAllPayloads (IkePacket
);
2386 if (IkeHeader
!= NULL
) {
2387 FreePool (IkeHeader
);
2393 Encode the IKE packet.
2395 This function puts all Payloads into one payload then encrypt it if needed.
2397 @param[in] SessionCommon Pointer to IKEV2_SESSION_COMMON containing
2398 some parameter used during IKE packet encoding.
2399 @param[in, out] IkePacket Pointer to IKE_PACKET to be encoded as input,
2400 and the encoded result as output.
2401 @param[in] IkeType The type of IKE. IKE_SA_TYPE, IKE_INFO_TYPE and
2402 IKE_CHILD_TYPE are supportted.
2404 @retval EFI_SUCCESS Encode IKE packet successfully.
2405 @retval Otherwise Encode IKE packet failed.
2410 IN IKEV2_SESSION_COMMON
*SessionCommon
,
2411 IN OUT IKE_PACKET
*IkePacket
,
2415 IKE_PAYLOAD
*IkePayload
;
2416 UINTN PayloadTotalSize
;
2419 IKEV2_SA_SESSION
*IkeSaSession
;
2421 PayloadTotalSize
= 0;
2423 // Encode each payload
2425 for (Entry
= IkePacket
->PayloadList
.ForwardLink
; Entry
!= &(IkePacket
->PayloadList
);) {
2426 IkePayload
= IKE_PAYLOAD_BY_PACKET (Entry
);
2427 Entry
= Entry
->ForwardLink
;
2428 Status
= Ikev2EncodePayload ((UINT8
*) SessionCommon
, IkePayload
);
2429 if (EFI_ERROR (Status
)) {
2433 if (SessionCommon
->AfterEncodePayload
!= NULL
) {
2435 // For certain states, save some payload for further calculation
2437 SessionCommon
->AfterEncodePayload (
2438 (UINT8
*) SessionCommon
,
2439 IkePayload
->PayloadBuf
,
2440 IkePayload
->PayloadSize
,
2441 IkePayload
->PayloadType
2445 PayloadTotalSize
+= IkePayload
->PayloadSize
;
2447 IkePacket
->PayloadTotalSize
= PayloadTotalSize
;
2449 Status
= EFI_SUCCESS
;
2450 if (SessionCommon
->State
>= IkeStateAuth
) {
2452 // Encrypt all payload and transfer IKE packet header from Host order to Network order.
2454 Status
= Ikev2EncryptPacket (SessionCommon
, IkePacket
);
2457 // Fill in the lenght into IkePacket header and transfer Host order to Network order.
2459 IkePacket
->Header
->Length
= (UINT32
) (sizeof (IKE_HEADER
) + IkePacket
->PayloadTotalSize
);
2460 IkeHdrHostToNet (IkePacket
->Header
);
2464 // If the packet is first message, store whole message in IkeSa->InitiPacket
2465 // for following Auth Payload calculation.
2467 if (IkePacket
->Header
->ExchangeType
== IKEV2_EXCHANGE_TYPE_INIT
) {
2468 IkeSaSession
= IKEV2_SA_SESSION_FROM_COMMON (SessionCommon
);
2469 if (SessionCommon
->IsInitiator
) {
2470 IkeSaSession
->InitPacketSize
= IkePacket
->PayloadTotalSize
+ sizeof (IKE_HEADER
);
2471 IkeSaSession
->InitPacket
= AllocateZeroPool (IkeSaSession
->InitPacketSize
);
2472 ASSERT (IkeSaSession
->InitPacket
!= NULL
);
2473 CopyMem (IkeSaSession
->InitPacket
, IkePacket
->Header
, sizeof (IKE_HEADER
));
2474 PayloadTotalSize
= 0;
2475 for (Entry
= IkePacket
->PayloadList
.ForwardLink
; Entry
!= &(IkePacket
->PayloadList
);) {
2476 IkePayload
= IKE_PAYLOAD_BY_PACKET (Entry
);
2477 Entry
= Entry
->ForwardLink
;
2479 IkeSaSession
->InitPacket
+ sizeof (IKE_HEADER
) + PayloadTotalSize
,
2480 IkePayload
->PayloadBuf
,
2481 IkePayload
->PayloadSize
2483 PayloadTotalSize
= PayloadTotalSize
+ IkePayload
->PayloadSize
;
2486 IkeSaSession
->RespPacketSize
= IkePacket
->PayloadTotalSize
+ sizeof(IKE_HEADER
);
2487 IkeSaSession
->RespPacket
= AllocateZeroPool (IkeSaSession
->RespPacketSize
);
2488 ASSERT (IkeSaSession
->RespPacket
!= NULL
);
2489 CopyMem (IkeSaSession
->RespPacket
, IkePacket
->Header
, sizeof (IKE_HEADER
));
2490 PayloadTotalSize
= 0;
2491 for (Entry
= IkePacket
->PayloadList
.ForwardLink
; Entry
!= &(IkePacket
->PayloadList
);) {
2492 IkePayload
= IKE_PAYLOAD_BY_PACKET (Entry
);
2493 Entry
= Entry
->ForwardLink
;
2496 IkeSaSession
->RespPacket
+ sizeof (IKE_HEADER
) + PayloadTotalSize
,
2497 IkePayload
->PayloadBuf
,
2498 IkePayload
->PayloadSize
2500 PayloadTotalSize
= PayloadTotalSize
+ IkePayload
->PayloadSize
;
2511 This function decrypts the Encrypted IKE packet and put the result into IkePacket->PayloadBuf.
2513 @param[in] SessionCommon Pointer to IKEV2_SESSION_COMMON containing
2514 some parameter used during decrypting.
2515 @param[in, out] IkePacket Pointer to IKE_PACKET to be decrypted as input,
2516 and the decrypted result as output.
2517 @param[in, out] IkeType The type of IKE. IKE_SA_TYPE, IKE_INFO_TYPE and
2518 IKE_CHILD_TYPE are supportted.
2520 @retval EFI_INVALID_PARAMETER If the IKE packet length is zero or the
2521 IKE packet length is not aligned with Algorithm Block Size
2522 @retval EFI_SUCCESS Decrypt IKE packet successfully.
2526 Ikev2DecryptPacket (
2527 IN IKEV2_SESSION_COMMON
*SessionCommon
,
2528 IN OUT IKE_PACKET
*IkePacket
,
2529 IN OUT UINTN IkeType
2532 UINT8 CryptBlockSize
; // Encrypt Block Size
2533 UINTN DecryptedSize
; // Encrypted IKE Payload Size
2534 UINT8
*DecryptedBuf
; // Encrypted IKE Payload buffer
2535 UINTN IntegritySize
;
2536 UINT8
*IntegrityBuffer
;
2537 UINTN IvSize
; // Iv Size
2538 UINT8 CheckSumSize
; // Integrity Check Sum Size depends on intergrity Auth
2539 UINT8
*CheckSumData
; // Check Sum data
2540 IKEV2_SA_SESSION
*IkeSaSession
;
2541 IKEV2_CHILD_SA_SESSION
*ChildSaSession
;
2544 UINTN CryptKeyLength
;
2545 HASH_DATA_FRAGMENT Fragments
[1];
2548 IkeSaSession
= NULL
;
2554 // Check if the first payload is the Encrypted payload
2556 if (IkePacket
->Header
->NextPayload
!= IKEV2_PAYLOAD_TYPE_ENCRYPT
) {
2557 return EFI_ACCESS_DENIED
;
2559 CheckSumData
= NULL
;
2560 DecryptedBuf
= NULL
;
2561 IntegrityBuffer
= NULL
;
2564 // Get the Block Size
2566 if (SessionCommon
->IkeSessionType
== IkeSessionTypeIkeSa
) {
2568 CryptBlockSize
= (UINT8
) IpSecGetEncryptBlockSize ((UINT8
) SessionCommon
->SaParams
->EncAlgId
);
2569 CryptKeyLength
= IpSecGetEncryptKeyLength ((UINT8
) SessionCommon
->SaParams
->EncAlgId
);
2570 CheckSumSize
= (UINT8
) IpSecGetIcvLength ((UINT8
) SessionCommon
->SaParams
->IntegAlgId
);
2571 IkeSaSession
= IKEV2_SA_SESSION_FROM_COMMON (SessionCommon
);
2573 } else if (SessionCommon
->IkeSessionType
== IkeSessionTypeChildSa
) {
2575 ChildSaSession
= IKEV2_CHILD_SA_SESSION_FROM_COMMON (SessionCommon
);
2576 IkeSaSession
= ChildSaSession
->IkeSaSession
;
2577 CryptBlockSize
= (UINT8
) IpSecGetEncryptBlockSize ((UINT8
) IkeSaSession
->SessionCommon
.SaParams
->EncAlgId
);
2578 CryptKeyLength
= IpSecGetEncryptKeyLength ((UINT8
) IkeSaSession
->SessionCommon
.SaParams
->EncAlgId
);
2579 CheckSumSize
= (UINT8
) IpSecGetIcvLength ((UINT8
) IkeSaSession
->SessionCommon
.SaParams
->IntegAlgId
);
2582 // The type of SA Session would either be IkeSa or ChildSa.
2584 return EFI_INVALID_PARAMETER
;
2587 CheckSumData
= AllocateZeroPool (CheckSumSize
);
2588 ASSERT (CheckSumData
!= NULL
);
2591 // Fill in the Integrity buffer
2593 IntegritySize
= IkePacket
->PayloadTotalSize
+ sizeof (IKE_HEADER
);
2594 IntegrityBuffer
= AllocateZeroPool (IntegritySize
);
2595 ASSERT (IntegrityBuffer
!= NULL
);
2596 CopyMem (IntegrityBuffer
, IkePacket
->Header
, sizeof(IKE_HEADER
));
2597 CopyMem (IntegrityBuffer
+ sizeof (IKE_HEADER
), IkePacket
->PayloadsBuf
, IkePacket
->PayloadTotalSize
);
2600 // Change Host order to Network order, since the header order was changed
2601 // in the IkePacketFromNetbuf.
2603 IkeHdrHostToNet ((IKE_HEADER
*)IntegrityBuffer
);
2606 // Calculate the Integrity CheckSum Data
2608 Fragments
[0].Data
= IntegrityBuffer
;
2609 Fragments
[0].DataSize
= IntegritySize
- CheckSumSize
;
2611 if (SessionCommon
->IsInitiator
) {
2612 Status
= IpSecCryptoIoHmac (
2613 (UINT8
)IkeSaSession
->SessionCommon
.SaParams
->IntegAlgId
,
2614 IkeSaSession
->IkeKeys
->SkArKey
,
2615 IkeSaSession
->IkeKeys
->SkArKeySize
,
2616 (HASH_DATA_FRAGMENT
*) Fragments
,
2622 Status
= IpSecCryptoIoHmac (
2623 (UINT8
)IkeSaSession
->SessionCommon
.SaParams
->IntegAlgId
,
2624 IkeSaSession
->IkeKeys
->SkAiKey
,
2625 IkeSaSession
->IkeKeys
->SkAiKeySize
,
2626 (HASH_DATA_FRAGMENT
*) Fragments
,
2633 if (EFI_ERROR (Status
)) {
2637 // Compare the Integrity CheckSum Data with the one in IkePacket
2640 IkePacket
->PayloadsBuf
+ IkePacket
->PayloadTotalSize
- CheckSumSize
,
2644 DEBUG ((DEBUG_ERROR
, "Error auth verify payload\n"));
2645 Status
= EFI_ACCESS_DENIED
;
2649 IvSize
= CryptBlockSize
;
2652 // Decrypt the payload with the key.
2654 DecryptedSize
= IkePacket
->PayloadTotalSize
- sizeof (IKEV2_COMMON_PAYLOAD_HEADER
) - IvSize
- CheckSumSize
;
2655 DecryptedBuf
= AllocateZeroPool (DecryptedSize
);
2656 ASSERT (DecryptedBuf
!= NULL
);
2660 IkePacket
->PayloadsBuf
+ sizeof (IKEV2_COMMON_PAYLOAD_HEADER
) + IvSize
,
2664 if (SessionCommon
->IsInitiator
) {
2665 Status
= IpSecCryptoIoDecrypt (
2666 (UINT8
) SessionCommon
->SaParams
->EncAlgId
,
2667 IkeSaSession
->IkeKeys
->SkErKey
,
2668 IkeSaSession
->IkeKeys
->SkErKeySize
<< 3,
2669 IkePacket
->PayloadsBuf
+ sizeof (IKEV2_COMMON_PAYLOAD_HEADER
),
2675 Status
= IpSecCryptoIoDecrypt (
2676 (UINT8
) SessionCommon
->SaParams
->EncAlgId
,
2677 IkeSaSession
->IkeKeys
->SkEiKey
,
2678 IkeSaSession
->IkeKeys
->SkEiKeySize
<< 3,
2679 IkePacket
->PayloadsBuf
+ sizeof (IKEV2_COMMON_PAYLOAD_HEADER
),
2686 if (EFI_ERROR (Status
)) {
2687 DEBUG ((DEBUG_ERROR
, "Error decrypt buffer with %r\n", Status
));
2692 // Get the Padding length
2695 PadLen
= (UINT8
) (*(DecryptedBuf
+ DecryptedSize
- sizeof (IKEV2_PAD_LEN
)));
2698 // Save the next payload of encrypted payload into IkePacket->Hdr->NextPayload
2700 IkePacket
->Header
->NextPayload
= ((IKEV2_ENCRYPTED
*) IkePacket
->PayloadsBuf
)->Header
.NextPayload
;
2703 // Free old IkePacket->PayloadBuf and point it to decrypted paylaod buffer.
2705 FreePool (IkePacket
->PayloadsBuf
);
2706 IkePacket
->PayloadsBuf
= DecryptedBuf
;
2707 IkePacket
->PayloadTotalSize
= DecryptedSize
- PadLen
;
2709 IPSEC_DUMP_BUF ("Decrypted Buffer", DecryptedBuf
, DecryptedSize
);
2713 if (CheckSumData
!= NULL
) {
2714 FreePool (CheckSumData
);
2717 if (EFI_ERROR (Status
) && DecryptedBuf
!= NULL
) {
2718 FreePool (DecryptedBuf
);
2721 if (IntegrityBuffer
!= NULL
) {
2722 FreePool (IntegrityBuffer
);
2731 This function encrypt IKE packet before sending it. The Encrypted IKE packet
2732 is put in to IKEV2 Encrypted Payload.
2734 @param[in] SessionCommon Pointer to IKEV2_SESSION_COMMON related to the IKE packet.
2735 @param[in, out] IkePacket Pointer to IKE packet to be encrypted.
2737 @retval EFI_SUCCESS Operation is successful.
2738 @retval Others Operation is failed.
2742 Ikev2EncryptPacket (
2743 IN IKEV2_SESSION_COMMON
*SessionCommon
,
2744 IN OUT IKE_PACKET
*IkePacket
2747 UINT8 CryptBlockSize
; // Encrypt Block Size
2748 UINT8 CryptBlockSizeMask
; // Block Mask
2749 UINTN EncryptedSize
; // Encrypted IKE Payload Size
2750 UINT8
*EncryptedBuf
; // Encrypted IKE Payload buffer
2751 UINT8
*EncryptPayloadBuf
; // Contain whole Encrypted Payload
2752 UINTN EncryptPayloadSize
; // Total size of the Encrypted payload
2753 UINT8
*IntegrityBuf
; // Buffer to be intergity
2754 UINT32 IntegrityBufSize
; // Buffer size of IntegrityBuf
2755 UINT8
*IvBuffer
; // Initialization Vector
2756 UINT8 IvSize
; // Iv Size
2757 UINT8 CheckSumSize
; // Integrity Check Sum Size depends on intergrity Auth
2758 UINT8
*CheckSumData
; // Check Sum data
2760 IKE_PAYLOAD
*EncryptPayload
;
2761 IKEV2_SA_SESSION
*IkeSaSession
;
2762 IKEV2_CHILD_SA_SESSION
*ChildSaSession
;
2765 IKE_PAYLOAD
*IkePayload
;
2766 UINTN CryptKeyLength
;
2767 HASH_DATA_FRAGMENT Fragments
[1];
2770 // Initial all buffers to NULL.
2772 EncryptedBuf
= NULL
;
2773 EncryptPayloadBuf
= NULL
;
2775 CheckSumData
= NULL
;
2776 IkeSaSession
= NULL
;
2780 IntegrityBuf
= NULL
;
2782 // Get the Block Size
2784 if (SessionCommon
->IkeSessionType
== IkeSessionTypeIkeSa
) {
2786 CryptBlockSize
= (UINT8
) IpSecGetEncryptBlockSize ((UINT8
) SessionCommon
->SaParams
->EncAlgId
);
2787 CryptKeyLength
= IpSecGetEncryptKeyLength ((UINT8
) SessionCommon
->SaParams
->EncAlgId
);
2788 CheckSumSize
= (UINT8
) IpSecGetIcvLength ((UINT8
) SessionCommon
->SaParams
->IntegAlgId
);
2789 IkeSaSession
= IKEV2_SA_SESSION_FROM_COMMON (SessionCommon
);
2791 } else if (SessionCommon
->IkeSessionType
== IkeSessionTypeChildSa
) {
2793 ChildSaSession
= IKEV2_CHILD_SA_SESSION_FROM_COMMON (SessionCommon
);
2794 IkeSaSession
= ChildSaSession
->IkeSaSession
;
2795 CryptBlockSize
= (UINT8
) IpSecGetEncryptBlockSize ((UINT8
) IkeSaSession
->SessionCommon
.SaParams
->EncAlgId
);
2796 CryptKeyLength
= IpSecGetEncryptKeyLength ((UINT8
) IkeSaSession
->SessionCommon
.SaParams
->EncAlgId
);
2797 CheckSumSize
= (UINT8
) IpSecGetIcvLength ((UINT8
) IkeSaSession
->SessionCommon
.SaParams
->IntegAlgId
);
2801 // Calcualte the EncryptPayloadSize and the PAD length
2803 CryptBlockSizeMask
= (UINT8
) (CryptBlockSize
- 1);
2804 EncryptedSize
= (IkePacket
->PayloadTotalSize
+ sizeof (IKEV2_PAD_LEN
) + CryptBlockSizeMask
) & ~CryptBlockSizeMask
;
2805 EncryptedBuf
= (UINT8
*) AllocateZeroPool (EncryptedSize
);
2806 ASSERT (EncryptedBuf
!= NULL
);
2809 // Copy all payload into EncryptedIkePayload
2812 NET_LIST_FOR_EACH (Entry
, &(IkePacket
)->PayloadList
) {
2813 IkePayload
= IKE_PAYLOAD_BY_PACKET (Entry
);
2815 CopyMem (EncryptedBuf
+ Index
, IkePayload
->PayloadBuf
, IkePayload
->PayloadSize
);
2816 Index
+= IkePayload
->PayloadSize
;
2821 // Fill in the Pading Length
2823 *(EncryptedBuf
+ EncryptedSize
- 1) = (UINT8
)(EncryptedSize
- IkePacket
->PayloadTotalSize
- 1);
2826 // The IV size is equal with block size
2828 IvSize
= CryptBlockSize
;
2829 IvBuffer
= (UINT8
*) AllocateZeroPool (IvSize
);
2834 IkeGenerateIv (IvBuffer
, IvSize
);
2837 // Encrypt payload buf
2839 if (SessionCommon
->IsInitiator
) {
2840 Status
= IpSecCryptoIoEncrypt (
2841 (UINT8
) IkeSaSession
->SessionCommon
.SaParams
->EncAlgId
,
2842 IkeSaSession
->IkeKeys
->SkEiKey
,
2843 IkeSaSession
->IkeKeys
->SkEiKeySize
<< 3,
2850 Status
= IpSecCryptoIoEncrypt (
2851 (UINT8
) IkeSaSession
->SessionCommon
.SaParams
->EncAlgId
,
2852 IkeSaSession
->IkeKeys
->SkErKey
,
2853 IkeSaSession
->IkeKeys
->SkErKeySize
<< 3,
2860 if (EFI_ERROR (Status
)) {
2865 // Allocate the buffer for the whole IKE payload (Encrypted Payload).
2867 EncryptPayloadSize
= sizeof(IKEV2_ENCRYPTED
) + IvSize
+ EncryptedSize
+ CheckSumSize
;
2868 EncryptPayloadBuf
= AllocateZeroPool (EncryptPayloadSize
);
2869 ASSERT (EncryptPayloadBuf
!= NULL
);
2872 // Fill in Header of Encrypted Payload
2874 ((IKEV2_ENCRYPTED
*) EncryptPayloadBuf
)->Header
.NextPayload
= IkePacket
->Header
->NextPayload
;
2875 ((IKEV2_ENCRYPTED
*) EncryptPayloadBuf
)->Header
.PayloadLength
= HTONS ((UINT16
)EncryptPayloadSize
);
2880 CopyMem (EncryptPayloadBuf
+ sizeof (IKEV2_ENCRYPTED
), IvBuffer
, IvSize
);
2883 // Fill in encrypted data
2885 CopyMem (EncryptPayloadBuf
+ sizeof (IKEV2_ENCRYPTED
) + IvSize
, EncryptedBuf
, EncryptedSize
);
2888 // Fill in the IKE Packet header
2890 IkePacket
->PayloadTotalSize
= EncryptPayloadSize
;
2891 IkePacket
->Header
->Length
= (UINT32
) (sizeof (IKE_HEADER
) + IkePacket
->PayloadTotalSize
);
2892 IkePacket
->Header
->NextPayload
= IKEV2_PAYLOAD_TYPE_ENCRYPT
;
2894 IntegrityBuf
= AllocateZeroPool (IkePacket
->Header
->Length
);
2895 IntegrityBufSize
= IkePacket
->Header
->Length
;
2896 IkeHdrHostToNet (IkePacket
->Header
);
2898 CopyMem (IntegrityBuf
, IkePacket
->Header
, sizeof (IKE_HEADER
));
2899 CopyMem (IntegrityBuf
+ sizeof (IKE_HEADER
), EncryptPayloadBuf
, EncryptPayloadSize
);
2902 // Calcualte Integrity CheckSum
2904 Fragments
[0].Data
= IntegrityBuf
;
2905 Fragments
[0].DataSize
= EncryptPayloadSize
+ sizeof (IKE_HEADER
) - CheckSumSize
;
2907 CheckSumData
= AllocateZeroPool (CheckSumSize
);
2908 if (SessionCommon
->IsInitiator
) {
2911 (UINT8
)IkeSaSession
->SessionCommon
.SaParams
->IntegAlgId
,
2912 IkeSaSession
->IkeKeys
->SkAiKey
,
2913 IkeSaSession
->IkeKeys
->SkAiKeySize
,
2914 (HASH_DATA_FRAGMENT
*) Fragments
,
2922 (UINT8
)IkeSaSession
->SessionCommon
.SaParams
->IntegAlgId
,
2923 IkeSaSession
->IkeKeys
->SkArKey
,
2924 IkeSaSession
->IkeKeys
->SkArKeySize
,
2925 (HASH_DATA_FRAGMENT
*) Fragments
,
2933 // Copy CheckSum into Encrypted Payload
2935 CopyMem (EncryptPayloadBuf
+ EncryptPayloadSize
- CheckSumSize
, CheckSumData
, CheckSumSize
);
2937 IPSEC_DUMP_BUF ("Encrypted payload buffer", EncryptPayloadBuf
, EncryptPayloadSize
);
2938 IPSEC_DUMP_BUF ("Integrith CheckSum Data", CheckSumData
, CheckSumSize
);
2941 // Clean all payload under IkePacket->PayloadList.
2943 ClearAllPayloads (IkePacket
);
2946 // Create Encrypted Payload and add into IkePacket->PayloadList
2948 EncryptPayload
= IkePayloadAlloc ();
2949 ASSERT (EncryptPayload
!= NULL
);
2952 // Fill the encrypted payload into the IKE_PAYLOAD structure.
2954 EncryptPayload
->PayloadBuf
= EncryptPayloadBuf
;
2955 EncryptPayload
->PayloadSize
= EncryptPayloadSize
;
2956 EncryptPayload
->PayloadType
= IKEV2_PAYLOAD_TYPE_ENCRYPT
;
2958 IKE_PACKET_APPEND_PAYLOAD (IkePacket
, EncryptPayload
);
2961 if (EncryptedBuf
!= NULL
) {
2962 FreePool (EncryptedBuf
);
2965 if (EFI_ERROR (Status
) && EncryptPayloadBuf
!= NULL
) {
2966 FreePool (EncryptPayloadBuf
);
2969 if (IvBuffer
!= NULL
) {
2970 FreePool (IvBuffer
);
2973 if (CheckSumData
!= NULL
) {
2974 FreePool (CheckSumData
);
2977 if (IntegrityBuf
!= NULL
) {
2978 FreePool (IntegrityBuf
);
2985 Save some useful payloads after accepting the Packet.
2987 @param[in] SessionCommon Pointer to IKEV2_SESSION_COMMON related to the operation.
2988 @param[in] IkePacket Pointer to received IkePacet.
2989 @param[in] IkeType The type used to indicate it is in IkeSa or ChildSa or Info
2994 Ikev2OnPacketAccepted (
2995 IN IKEV2_SESSION_COMMON
*SessionCommon
,
2996 IN IKE_PACKET
*IkePacket
,
3005 The notification function. It will be called when the related UDP_TX_TOKEN's event
3008 This function frees the Net Buffer pointed to the input Packet.
3010 @param[in] Packet Pointer to Net buffer containing the sending IKE packet.
3011 @param[in] EndPoint Pointer to UDP_END_POINT containing the remote and local
3012 address information.
3013 @param[in] IoStatus The Status of the related UDP_TX_TOKEN.
3014 @param[in] Context Pointer to data passed from the caller.
3021 IN UDP_END_POINT
*EndPoint
,
3022 IN EFI_STATUS IoStatus
,
3026 IKE_PACKET
*IkePacket
;
3027 IKEV2_SA_SESSION
*IkeSaSession
;
3028 IKEV2_CHILD_SA_SESSION
*ChildSaSession
;
3030 IPSEC_PRIVATE_DATA
*Private
;
3033 IkePacket
= (IKE_PACKET
*) Context
;
3036 if (EFI_ERROR (IoStatus
)) {
3037 DEBUG ((DEBUG_ERROR
, "Error send the last packet in IkeSessionTypeIkeSa with %r\n", IoStatus
));
3040 NetbufFree (Packet
);
3042 if (IkePacket
->IsDeleteInfo
) {
3044 // For each RemotePeerIP, there are only one IKESA.
3046 IkeSaSession
= Ikev2SaSessionLookup (
3047 &IkePacket
->Private
->Ikev2EstablishedList
,
3048 &IkePacket
->RemotePeerIp
3050 if (IkeSaSession
== NULL
) {
3051 IkePacketFree (IkePacket
);
3055 Private
= IkePacket
->Private
;
3056 if (IkePacket
->Spi
!= 0 ) {
3058 // At that time, the established Child SA still in eht ChildSaEstablishSessionList.
3059 // And meanwhile, if the Child SA is in the the ChildSa in Delete list,
3060 // remove it from delete list and delete it direclty.
3062 ChildSaSession
= Ikev2ChildSaSessionLookupBySpi (
3063 &IkeSaSession
->ChildSaEstablishSessionList
,
3066 if (ChildSaSession
!= NULL
) {
3067 Ikev2ChildSaSessionRemove (
3068 &IkeSaSession
->DeleteSaList
,
3069 ChildSaSession
->LocalPeerSpi
,
3070 IKEV2_DELET_CHILDSA_LIST
3074 // Delete the Child SA.
3076 Ikev2ChildSaSilentDelete (
3084 // Delete the IKE SA
3088 "\n------ deleted Packet (cookie_i, cookie_r):(0x%lx, 0x%lx)------\n",
3089 IkeSaSession
->InitiatorCookie
,
3090 IkeSaSession
->ResponderCookie
)
3093 RemoveEntryList (&IkeSaSession
->BySessionTable
);
3094 Ikev2SaSessionFree (IkeSaSession
);
3097 IkePacketFree (IkePacket
);
3100 // when all IKE SAs were disabled by calling "IPsecConfig -disable", the IPsec status
3101 // should be changed.
3103 if (Private
!= NULL
&& Private
->IsIPsecDisabling
) {
3105 // After all IKE SAs were deleted, set the IPSEC_STATUS_DISABLED value in
3106 // IPsec status variable.
3108 if (IsListEmpty (&Private
->Ikev1EstablishedList
) && IsListEmpty (&Private
->Ikev2EstablishedList
)) {
3109 Value
= IPSEC_STATUS_DISABLED
;
3110 Status
= gRT
->SetVariable (
3111 IPSECCONFIG_STATUS_NAME
,
3112 &gEfiIpSecConfigProtocolGuid
,
3113 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
3117 if (!EFI_ERROR (Status
)) {
3119 // Set the DisabledFlag in Private data.
3121 Private
->IpSec
.DisabledFlag
= TRUE
;
3122 Private
->IsIPsecDisabling
= FALSE
;
3129 Send out IKEV2 packet.
3131 @param[in] IkeUdpService Pointer to IKE_UDP_SERVICE used to send the IKE packet.
3132 @param[in] SessionCommon Pointer to IKEV1_SESSION_COMMON related to the IKE packet.
3133 @param[in] IkePacket Pointer to IKE_PACKET to be sent out.
3134 @param[in] IkeType The type of IKE to point what's kind of the IKE
3135 packet is to be sent out. IKE_SA_TYPE, IKE_INFO_TYPE
3136 and IKE_CHILD_TYPE are supportted.
3138 @retval EFI_SUCCESS The operation complete successfully.
3139 @retval Otherwise The operation is failed.
3143 Ikev2SendIkePacket (
3144 IN IKE_UDP_SERVICE
*IkeUdpService
,
3145 IN UINT8
*SessionCommon
,
3146 IN IKE_PACKET
*IkePacket
,
3151 NET_BUF
*IkePacketNetbuf
;
3152 UDP_END_POINT EndPoint
;
3153 IKEV2_SESSION_COMMON
*Common
;
3155 Common
= (IKEV2_SESSION_COMMON
*) SessionCommon
;
3158 // Set the resend interval
3160 if (Common
->TimeoutInterval
== 0) {
3161 Common
->TimeoutInterval
= IKE_DEFAULT_TIMEOUT_INTERVAL
;
3165 // Retransfer the packet if it is initial packet.
3167 if (IkePacket
->Header
->Flags
== IKE_HEADER_FLAGS_INIT
) {
3169 // Set timer for next retry, this will cancel previous timer
3171 Status
= gBS
->SetTimer (
3172 Common
->TimeoutEvent
,
3174 MultU64x32 (Common
->TimeoutInterval
, 10000) // ms->100ns
3176 if (EFI_ERROR (Status
)) {
3181 IKE_PACKET_REF (IkePacket
);
3183 // If the last sent packet is same with this round packet, the packet is resent packet.
3185 if (IkePacket
!= Common
->LastSentPacket
&& Common
->LastSentPacket
!= NULL
) {
3186 IkePacketFree (Common
->LastSentPacket
);
3189 Common
->LastSentPacket
= IkePacket
;
3192 // Transform IkePacke to NetBuf
3194 IkePacketNetbuf
= IkeNetbufFromPacket ((UINT8
*) SessionCommon
, IkePacket
, IkeType
);
3195 ASSERT (IkePacketNetbuf
!= NULL
);
3197 ZeroMem (&EndPoint
, sizeof (UDP_END_POINT
));
3198 EndPoint
.RemotePort
= IKE_DEFAULT_PORT
;
3199 CopyMem (&IkePacket
->RemotePeerIp
, &Common
->RemotePeerIp
, sizeof (EFI_IP_ADDRESS
));
3200 CopyMem (&EndPoint
.RemoteAddr
, &Common
->RemotePeerIp
, sizeof (EFI_IP_ADDRESS
));
3201 CopyMem (&EndPoint
.LocalAddr
, &Common
->LocalPeerIp
, sizeof (EFI_IP_ADDRESS
));
3203 IPSEC_DUMP_PACKET (IkePacket
, EfiIPsecOutBound
, IkeUdpService
->IpVersion
);
3205 if (IkeUdpService
->IpVersion
== IP_VERSION_4
) {
3206 EndPoint
.RemoteAddr
.Addr
[0] = HTONL (EndPoint
.RemoteAddr
.Addr
[0]);
3207 EndPoint
.LocalAddr
.Addr
[0] = HTONL (EndPoint
.LocalAddr
.Addr
[0]);
3211 // Call UDPIO to send out the IKE packet.
3213 Status
= UdpIoSendDatagram (
3214 IkeUdpService
->Output
,
3222 if (EFI_ERROR (Status
)) {
3223 DEBUG ((DEBUG_ERROR
, "Error send packet with %r\n", Status
));