2 The Implementations for Information Exchange.
4 (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
5 Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
7 This program and the accompanying materials
8 are licensed and made available under the terms and conditions of the BSD License
9 which accompanies this distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php.
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 #include "IpSecDebug.h"
19 #include "IpSecConfigImpl.h"
22 Generate Information Packet.
24 The information Packet may contain one Delete Payload, or Notify Payload, which
25 dependes on the Context's parameters.
27 @param[in] SaSession Pointer to IKE SA Session or Child SA Session which is
28 related to the information Exchange.
29 @param[in] Context The Data passed from the caller. If the Context is not NULL
30 it should contain the information for Notification Data.
32 @retval Pointer of IKE_PACKET generated.
41 IKEV2_SA_SESSION
*IkeSaSession
;
42 IKEV2_CHILD_SA_SESSION
*ChildSaSession
;
43 IKE_PACKET
*IkePacket
;
44 IKE_PAYLOAD
*IkePayload
;
45 IKEV2_INFO_EXCHANGE_CONTEXT
*InfoContext
;
48 IkeSaSession
= (IKEV2_SA_SESSION
*) SaSession
;
49 IkePacket
= IkePacketAlloc ();
50 ASSERT (IkePacket
!= NULL
);
53 // Fill IkePacket Header.
55 IkePacket
->Header
->ExchangeType
= IKEV2_EXCHANGE_TYPE_INFO
;
56 IkePacket
->Header
->Version
= (UINT8
) (2 << 4);
58 if (Context
!= NULL
) {
59 InfoContext
= (IKEV2_INFO_EXCHANGE_CONTEXT
*) Context
;
65 if (InfoContext
!= NULL
&&
66 (InfoContext
->InfoType
== Ikev2InfoLiveCheck
|| InfoContext
->InfoType
== Ikev2InfoNotify
)
68 IkePacket
->Header
->MessageId
= InfoContext
->MessageId
;
69 IkePacket
->Header
->InitiatorCookie
= IkeSaSession
->InitiatorCookie
;
70 IkePacket
->Header
->ResponderCookie
= IkeSaSession
->ResponderCookie
;
71 IkePacket
->Header
->NextPayload
= IKEV2_PAYLOAD_TYPE_NONE
;
72 IkePacket
->Header
->Flags
= IKE_HEADER_FLAGS_RESPOND
;
74 // TODO: add Notify Payload for Notification Information.
82 if (IkeSaSession
->SessionCommon
.IkeSessionType
== IkeSessionTypeIkeSa
) {
84 IkePacket
->Header
->InitiatorCookie
= IkeSaSession
->InitiatorCookie
;
85 IkePacket
->Header
->ResponderCookie
= IkeSaSession
->ResponderCookie
;
88 // If the information message is response message,the MessageId should
89 // be same as the request MessageId which passed through the Context.
91 if (InfoContext
!= NULL
) {
92 IkePacket
->Header
->MessageId
= InfoContext
->MessageId
;
94 IkePacket
->Header
->MessageId
= IkeSaSession
->MessageId
;
95 Ikev2SaSessionIncreaseMessageId (IkeSaSession
);
98 // If the state is on deleting generate a Delete Payload for it.
100 if (IkeSaSession
->SessionCommon
.State
== IkeStateSaDeleting
) {
101 IkePayload
= Ikev2GenerateDeletePayload (
103 IKEV2_PAYLOAD_TYPE_NONE
,
108 if (IkePayload
== NULL
) {
112 // Fill the next payload in IkePacket's Header.
114 IkePacket
->Header
->NextPayload
= IKEV2_PAYLOAD_TYPE_DELETE
;
115 IKE_PACKET_APPEND_PAYLOAD (IkePacket
, IkePayload
);
116 IkePacket
->Private
= IkeSaSession
->SessionCommon
.Private
;
118 IkePacket
->IsDeleteInfo
= TRUE
;
120 } else if (Context
!= NULL
) {
122 // TODO: If contest is not NULL Generate a Notify Payload.
126 // The input parameter is not correct.
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
;
183 if (InfoContext
== NULL
) {
184 IkePacket
->Header
->Flags
= IKE_HEADER_FLAGS_INIT
;
186 IkePacket
->Header
->Flags
= IKE_HEADER_FLAGS_RESPOND
;
191 if (IkePacket
!= NULL
) {
192 FreePool (IkePacket
);
199 Parse the Info Exchange.
201 @param[in] SaSession Pointer to IKEV2_SA_SESSION.
202 @param[in] IkePacket Pointer to IkePacket related to the Information Exchange.
204 @retval EFI_SUCCESS The operation finised successed.
210 IN IKE_PACKET
*IkePacket
213 IKEV2_CHILD_SA_SESSION
*ChildSaSession
;
214 IKEV2_SA_SESSION
*IkeSaSession
;
215 IKE_PAYLOAD
*DeletePayload
;
216 IKE_PAYLOAD
*IkePayload
;
217 IKEV2_DELETE
*Delete
;
219 LIST_ENTRY
*ListEntry
;
223 IPSEC_PRIVATE_DATA
*Private
;
226 IKE_PACKET
*RespondPacket
;
228 IKEV2_INFO_EXCHANGE_CONTEXT Context
;
230 IkeSaSession
= (IKEV2_SA_SESSION
*) SaSession
;
232 DeletePayload
= NULL
;
234 RespondPacket
= NULL
;
235 Status
= EFI_SUCCESS
;
238 // For Liveness Check
240 if (IkePacket
->Header
->NextPayload
== IKEV2_PAYLOAD_TYPE_NONE
&&
241 (IkePacket
->PayloadTotalSize
== 0)
243 if (IkePacket
->Header
->Flags
== IKE_HEADER_FLAGS_INIT
) {
245 // If it is Liveness check request, reply it.
247 Context
.InfoType
= Ikev2InfoLiveCheck
;
248 Context
.MessageId
= IkePacket
->Header
->MessageId
;
249 RespondPacket
= Ikev2InfoGenerator ((UINT8
*)IkeSaSession
, &Context
);
251 if (RespondPacket
== NULL
) {
252 Status
= EFI_INVALID_PARAMETER
;
255 Status
= Ikev2SendIkePacket (
256 IkeSaSession
->SessionCommon
.UdpService
,
257 (UINT8
*)(&IkeSaSession
->SessionCommon
),
264 // Todo: verify the liveness check response packet.
273 NET_LIST_FOR_EACH (Entry
, &(IkePacket
)->PayloadList
) {
276 // Iterate payloads to find the Delete/Notify Payload.
278 IkePayload
= IKE_PAYLOAD_BY_PACKET (Entry
);
280 if (IkePayload
->PayloadType
== IKEV2_PAYLOAD_TYPE_DELETE
) {
281 DeletePayload
= IkePayload
;
282 Delete
= (IKEV2_DELETE
*)DeletePayload
->PayloadBuf
;
284 if (Delete
->SpiSize
== 0) {
288 if (IkeSaSession
->SessionCommon
.State
== IkeStateSaDeleting
) {
289 RemoveEntryList (&IkeSaSession
->BySessionTable
);
290 Ikev2SaSessionFree (IkeSaSession
);
292 // Checking the Private status.
295 // when all IKE SAs were disabled by calling "IPsecConfig -disable", the IPsec
296 // status should be changed.
298 Private
= IkeSaSession
->SessionCommon
.Private
;
299 if (Private
!= NULL
&& Private
->IsIPsecDisabling
) {
301 // After all IKE SAs were deleted, set the IPSEC_STATUS_DISABLED value in
302 // IPsec status variable.
304 if (IsListEmpty (&Private
->Ikev1EstablishedList
) &&
305 (IsListEmpty (&Private
->Ikev2EstablishedList
))
307 Value
= IPSEC_STATUS_DISABLED
;
308 Status
= gRT
->SetVariable (
309 IPSECCONFIG_STATUS_NAME
,
310 &gEfiIpSecConfigProtocolGuid
,
311 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
315 if (!EFI_ERROR (Status
)) {
317 // Set the DisabledFlag in Private data.
319 Private
->IpSec
.DisabledFlag
= TRUE
;
320 Private
->IsIPsecDisabling
= FALSE
;
325 IkeSaSession
->SessionCommon
.State
= IkeStateSaDeleting
;
326 Context
.InfoType
= Ikev2InfoDelete
;
327 Context
.MessageId
= IkePacket
->Header
->MessageId
;
329 RespondPacket
= Ikev2InfoGenerator ((UINT8
*)IkeSaSession
, &Context
);
330 if (RespondPacket
== NULL
) {
331 Status
= EFI_INVALID_PARAMETER
;
334 Status
= Ikev2SendIkePacket (
335 IkeSaSession
->SessionCommon
.UdpService
,
336 (UINT8
*)(&IkeSaSession
->SessionCommon
),
341 } else if (Delete
->SpiSize
== 4) {
343 // Move the Child SAs to DeleteList
345 SpiBuffer
= (UINT8
*)(Delete
+ 1);
346 for (Index
= 0; Index
< Delete
->NumSpis
; Index
++) {
347 Spi
= ReadUnaligned32 ((UINT32
*)SpiBuffer
);
348 for (ListEntry
= IkeSaSession
->ChildSaEstablishSessionList
.ForwardLink
;
349 ListEntry
!= &IkeSaSession
->ChildSaEstablishSessionList
;
351 ChildSaSession
= IKEV2_CHILD_SA_SESSION_BY_IKE_SA (ListEntry
);
352 ListEntry
= ListEntry
->ForwardLink
;
354 if (ChildSaSession
->RemotePeerSpi
== HTONL(Spi
)) {
355 if (ChildSaSession
->SessionCommon
.State
!= IkeStateSaDeleting
) {
358 // Insert the ChildSa Session into Delete List.
360 InsertTailList (&IkeSaSession
->DeleteSaList
, &ChildSaSession
->ByDelete
);
361 ChildSaSession
->SessionCommon
.State
= IkeStateSaDeleting
;
362 ChildSaSession
->SessionCommon
.IsInitiator
= FALSE
;
363 ChildSaSession
->MessageId
= IkePacket
->Header
->MessageId
;
365 Context
.InfoType
= Ikev2InfoDelete
;
366 Context
.MessageId
= IkePacket
->Header
->MessageId
;
368 RespondPacket
= Ikev2InfoGenerator ((UINT8
*)ChildSaSession
, &Context
);
369 if (RespondPacket
== NULL
) {
370 Status
= EFI_INVALID_PARAMETER
;
373 Status
= Ikev2SendIkePacket (
374 ChildSaSession
->SessionCommon
.UdpService
,
375 (UINT8
*)(&ChildSaSession
->SessionCommon
),
381 // Delete the Child SA.
383 Ikev2ChildSaSilentDelete (IkeSaSession
, Spi
);
384 RemoveEntryList (&ChildSaSession
->ByDelete
);
388 SpiBuffer
= SpiBuffer
+ sizeof (Spi
);
397 GLOBAL_REMOVE_IF_UNREFERENCED IKEV2_PACKET_HANDLER mIkev2Info
= {