2 The Implementations for Information Exchange.
4 (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
5 Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
7 SPDX-License-Identifier: BSD-2-Clause-Patent
12 #include "IpSecDebug.h"
13 #include "IpSecConfigImpl.h"
16 Generate Information Packet.
18 The information Packet may contain one Delete Payload, or Notify Payload, which
19 dependes on the Context's parameters.
21 @param[in] SaSession Pointer to IKE SA Session or Child SA Session which is
22 related to the information Exchange.
23 @param[in] Context The Data passed from the caller. If the Context is not NULL
24 it should contain the information for Notification Data.
26 @retval Pointer of IKE_PACKET generated.
35 IKEV2_SA_SESSION
*IkeSaSession
;
36 IKEV2_CHILD_SA_SESSION
*ChildSaSession
;
37 IKE_PACKET
*IkePacket
;
38 IKE_PAYLOAD
*IkePayload
;
39 IKEV2_INFO_EXCHANGE_CONTEXT
*InfoContext
;
42 IkeSaSession
= (IKEV2_SA_SESSION
*) SaSession
;
43 IkePacket
= IkePacketAlloc ();
44 if (IkePacket
== NULL
) {
49 // Fill IkePacket Header.
51 IkePacket
->Header
->ExchangeType
= IKEV2_EXCHANGE_TYPE_INFO
;
52 IkePacket
->Header
->Version
= (UINT8
) (2 << 4);
54 if (Context
!= NULL
) {
55 InfoContext
= (IKEV2_INFO_EXCHANGE_CONTEXT
*) Context
;
61 if (InfoContext
!= NULL
&&
62 (InfoContext
->InfoType
== Ikev2InfoLiveCheck
|| InfoContext
->InfoType
== Ikev2InfoNotify
)
64 IkePacket
->Header
->MessageId
= InfoContext
->MessageId
;
65 IkePacket
->Header
->InitiatorCookie
= IkeSaSession
->InitiatorCookie
;
66 IkePacket
->Header
->ResponderCookie
= IkeSaSession
->ResponderCookie
;
67 IkePacket
->Header
->NextPayload
= IKEV2_PAYLOAD_TYPE_NONE
;
68 IkePacket
->Header
->Flags
= IKE_HEADER_FLAGS_RESPOND
;
70 // TODO: add Notify Payload for Notification Information.
78 if (IkeSaSession
->SessionCommon
.IkeSessionType
== IkeSessionTypeIkeSa
) {
80 IkePacket
->Header
->InitiatorCookie
= IkeSaSession
->InitiatorCookie
;
81 IkePacket
->Header
->ResponderCookie
= IkeSaSession
->ResponderCookie
;
84 // If the information message is response message,the MessageId should
85 // be same as the request MessageId which passed through the Context.
87 if (InfoContext
!= NULL
) {
88 IkePacket
->Header
->MessageId
= InfoContext
->MessageId
;
90 IkePacket
->Header
->MessageId
= IkeSaSession
->MessageId
;
91 Ikev2SaSessionIncreaseMessageId (IkeSaSession
);
94 // If the state is on deleting generate a Delete Payload for it.
96 if (IkeSaSession
->SessionCommon
.State
== IkeStateSaDeleting
) {
97 IkePayload
= Ikev2GenerateDeletePayload (
99 IKEV2_PAYLOAD_TYPE_NONE
,
104 if (IkePayload
== NULL
) {
108 // Fill the next payload in IkePacket's Header.
110 IkePacket
->Header
->NextPayload
= IKEV2_PAYLOAD_TYPE_DELETE
;
111 IKE_PACKET_APPEND_PAYLOAD (IkePacket
, IkePayload
);
112 IkePacket
->Private
= IkeSaSession
->SessionCommon
.Private
;
114 IkePacket
->IsDeleteInfo
= TRUE
;
116 } else if (Context
!= NULL
) {
118 // TODO: If contest is not NULL Generate a Notify Payload.
122 // The input parameter is not correct.
127 if (IkeSaSession
->SessionCommon
.IsInitiator
) {
128 IkePacket
->Header
->Flags
= IKE_HEADER_FLAGS_INIT
;
132 // Delete the Child SA Information Exchagne
134 ChildSaSession
= (IKEV2_CHILD_SA_SESSION
*) SaSession
;
135 IkeSaSession
= ChildSaSession
->IkeSaSession
;
136 IkePacket
->Header
->InitiatorCookie
= ChildSaSession
->IkeSaSession
->InitiatorCookie
;
137 IkePacket
->Header
->ResponderCookie
= ChildSaSession
->IkeSaSession
->ResponderCookie
;
140 // If the information message is response message,the MessageId should
141 // be same as the request MessageId which passed through the Context.
143 if (InfoContext
!= NULL
&& InfoContext
->MessageId
!= 0) {
144 IkePacket
->Header
->MessageId
= InfoContext
->MessageId
;
146 IkePacket
->Header
->MessageId
= ChildSaSession
->IkeSaSession
->MessageId
;
147 Ikev2SaSessionIncreaseMessageId (IkeSaSession
);
150 IkePayload
= Ikev2GenerateDeletePayload (
151 ChildSaSession
->IkeSaSession
,
152 IKEV2_PAYLOAD_TYPE_DELETE
,
155 (UINT8
*)&ChildSaSession
->LocalPeerSpi
157 if (IkePayload
== NULL
) {
161 // Fill the Next Payload in IkePacket's Header.
163 IkePacket
->Header
->NextPayload
= IKEV2_PAYLOAD_TYPE_DELETE
;
164 IKE_PACKET_APPEND_PAYLOAD (IkePacket
, IkePayload
);
166 IkePacket
->Private
= IkeSaSession
->SessionCommon
.Private
;
167 IkePacket
->Spi
= ChildSaSession
->LocalPeerSpi
;
168 IkePacket
->IsDeleteInfo
= TRUE
;
170 if (!ChildSaSession
->SessionCommon
.IsInitiator
) {
172 // If responder, use the MessageId fromt the initiator.
174 IkePacket
->Header
->MessageId
= ChildSaSession
->MessageId
;
178 // Change the IsOnDeleting Flag
180 ChildSaSession
->SessionCommon
.IsOnDeleting
= TRUE
;
182 if (ChildSaSession
->SessionCommon
.IsInitiator
) {
183 IkePacket
->Header
->Flags
= IKE_HEADER_FLAGS_INIT
;
187 if (InfoContext
!= NULL
) {
188 IkePacket
->Header
->Flags
|= IKE_HEADER_FLAGS_RESPOND
;
194 if (IkePacket
!= NULL
) {
195 FreePool (IkePacket
);
202 Parse the Info Exchange.
204 @param[in] SaSession Pointer to IKEV2_SA_SESSION.
205 @param[in] IkePacket Pointer to IkePacket related to the Information Exchange.
207 @retval EFI_SUCCESS The operation finised successed.
213 IN IKE_PACKET
*IkePacket
216 IKEV2_CHILD_SA_SESSION
*ChildSaSession
;
217 IKEV2_SA_SESSION
*IkeSaSession
;
218 IKE_PAYLOAD
*DeletePayload
;
219 IKE_PAYLOAD
*IkePayload
;
220 IKEV2_DELETE
*Delete
;
222 LIST_ENTRY
*ListEntry
;
226 IPSEC_PRIVATE_DATA
*Private
;
229 IKE_PACKET
*RespondPacket
;
231 IKEV2_INFO_EXCHANGE_CONTEXT Context
;
233 IkeSaSession
= (IKEV2_SA_SESSION
*) SaSession
;
235 DeletePayload
= NULL
;
237 RespondPacket
= NULL
;
238 Status
= EFI_SUCCESS
;
241 // For Liveness Check
243 if (IkePacket
->Header
->NextPayload
== IKEV2_PAYLOAD_TYPE_NONE
&&
244 (IkePacket
->PayloadTotalSize
== 0)
246 if (IkePacket
->Header
->Flags
== IKE_HEADER_FLAGS_INIT
) {
248 // If it is Liveness check request, reply it.
250 Context
.InfoType
= Ikev2InfoLiveCheck
;
251 Context
.MessageId
= IkePacket
->Header
->MessageId
;
252 RespondPacket
= Ikev2InfoGenerator ((UINT8
*)IkeSaSession
, &Context
);
254 if (RespondPacket
== NULL
) {
255 Status
= EFI_INVALID_PARAMETER
;
258 Status
= Ikev2SendIkePacket (
259 IkeSaSession
->SessionCommon
.UdpService
,
260 (UINT8
*)(&IkeSaSession
->SessionCommon
),
267 // Todo: verify the liveness check response packet.
276 NET_LIST_FOR_EACH (Entry
, &(IkePacket
)->PayloadList
) {
279 // Iterate payloads to find the Delete/Notify Payload.
281 IkePayload
= IKE_PAYLOAD_BY_PACKET (Entry
);
283 if (IkePayload
->PayloadType
== IKEV2_PAYLOAD_TYPE_DELETE
) {
284 DeletePayload
= IkePayload
;
285 Delete
= (IKEV2_DELETE
*)DeletePayload
->PayloadBuf
;
287 if (Delete
->SpiSize
== 0) {
291 if (IkeSaSession
->SessionCommon
.State
== IkeStateSaDeleting
) {
292 RemoveEntryList (&IkeSaSession
->BySessionTable
);
293 Ikev2SaSessionFree (IkeSaSession
);
295 // Checking the Private status.
298 // when all IKE SAs were disabled by calling "IPsecConfig -disable", the IPsec
299 // status should be changed.
301 Private
= IkeSaSession
->SessionCommon
.Private
;
302 if (Private
!= NULL
&& Private
->IsIPsecDisabling
) {
304 // After all IKE SAs were deleted, set the IPSEC_STATUS_DISABLED value in
305 // IPsec status variable.
307 if (IsListEmpty (&Private
->Ikev1EstablishedList
) &&
308 (IsListEmpty (&Private
->Ikev2EstablishedList
))
310 Value
= IPSEC_STATUS_DISABLED
;
311 Status
= gRT
->SetVariable (
312 IPSECCONFIG_STATUS_NAME
,
313 &gEfiIpSecConfigProtocolGuid
,
314 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
318 if (!EFI_ERROR (Status
)) {
320 // Set the DisabledFlag in Private data.
322 Private
->IpSec
.DisabledFlag
= TRUE
;
323 Private
->IsIPsecDisabling
= FALSE
;
328 IkeSaSession
->SessionCommon
.State
= IkeStateSaDeleting
;
329 Context
.InfoType
= Ikev2InfoDelete
;
330 Context
.MessageId
= IkePacket
->Header
->MessageId
;
332 RespondPacket
= Ikev2InfoGenerator ((UINT8
*)IkeSaSession
, &Context
);
333 if (RespondPacket
== NULL
) {
334 Status
= EFI_INVALID_PARAMETER
;
337 Status
= Ikev2SendIkePacket (
338 IkeSaSession
->SessionCommon
.UdpService
,
339 (UINT8
*)(&IkeSaSession
->SessionCommon
),
344 } else if (Delete
->SpiSize
== 4) {
346 // Move the Child SAs to DeleteList
348 SpiBuffer
= (UINT8
*)(Delete
+ 1);
349 for (Index
= 0; Index
< Delete
->NumSpis
; Index
++) {
350 Spi
= ReadUnaligned32 ((UINT32
*)SpiBuffer
);
351 for (ListEntry
= IkeSaSession
->ChildSaEstablishSessionList
.ForwardLink
;
352 ListEntry
!= &IkeSaSession
->ChildSaEstablishSessionList
;
354 ChildSaSession
= IKEV2_CHILD_SA_SESSION_BY_IKE_SA (ListEntry
);
355 ListEntry
= ListEntry
->ForwardLink
;
357 if (ChildSaSession
->RemotePeerSpi
== HTONL(Spi
)) {
358 if (ChildSaSession
->SessionCommon
.State
!= IkeStateSaDeleting
) {
361 // Insert the ChildSa Session into Delete List.
363 InsertTailList (&IkeSaSession
->DeleteSaList
, &ChildSaSession
->ByDelete
);
364 ChildSaSession
->SessionCommon
.State
= IkeStateSaDeleting
;
365 ChildSaSession
->SessionCommon
.IsInitiator
= FALSE
;
366 ChildSaSession
->MessageId
= IkePacket
->Header
->MessageId
;
368 Context
.InfoType
= Ikev2InfoDelete
;
369 Context
.MessageId
= IkePacket
->Header
->MessageId
;
371 RespondPacket
= Ikev2InfoGenerator ((UINT8
*)ChildSaSession
, &Context
);
372 if (RespondPacket
== NULL
) {
373 Status
= EFI_INVALID_PARAMETER
;
376 Status
= Ikev2SendIkePacket (
377 ChildSaSession
->SessionCommon
.UdpService
,
378 (UINT8
*)(&ChildSaSession
->SessionCommon
),
384 // Delete the Child SA.
386 Ikev2ChildSaSilentDelete (IkeSaSession
, Spi
);
387 RemoveEntryList (&ChildSaSession
->ByDelete
);
391 SpiBuffer
= SpiBuffer
+ sizeof (Spi
);
400 GLOBAL_REMOVE_IF_UNREFERENCED IKEV2_PACKET_HANDLER mIkev2Info
= {