2 The Implementations for Information Exchange.
4 (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
5 Copyright (c) 2010 - 2016, 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 if (IkePacket
== NULL
) {
55 // Fill IkePacket Header.
57 IkePacket
->Header
->ExchangeType
= IKEV2_EXCHANGE_TYPE_INFO
;
58 IkePacket
->Header
->Version
= (UINT8
) (2 << 4);
60 if (Context
!= NULL
) {
61 InfoContext
= (IKEV2_INFO_EXCHANGE_CONTEXT
*) Context
;
67 if (InfoContext
!= NULL
&&
68 (InfoContext
->InfoType
== Ikev2InfoLiveCheck
|| InfoContext
->InfoType
== Ikev2InfoNotify
)
70 IkePacket
->Header
->MessageId
= InfoContext
->MessageId
;
71 IkePacket
->Header
->InitiatorCookie
= IkeSaSession
->InitiatorCookie
;
72 IkePacket
->Header
->ResponderCookie
= IkeSaSession
->ResponderCookie
;
73 IkePacket
->Header
->NextPayload
= IKEV2_PAYLOAD_TYPE_NONE
;
74 IkePacket
->Header
->Flags
= IKE_HEADER_FLAGS_RESPOND
;
76 // TODO: add Notify Payload for Notification Information.
84 if (IkeSaSession
->SessionCommon
.IkeSessionType
== IkeSessionTypeIkeSa
) {
86 IkePacket
->Header
->InitiatorCookie
= IkeSaSession
->InitiatorCookie
;
87 IkePacket
->Header
->ResponderCookie
= IkeSaSession
->ResponderCookie
;
90 // If the information message is response message,the MessageId should
91 // be same as the request MessageId which passed through the Context.
93 if (InfoContext
!= NULL
) {
94 IkePacket
->Header
->MessageId
= InfoContext
->MessageId
;
96 IkePacket
->Header
->MessageId
= IkeSaSession
->MessageId
;
97 Ikev2SaSessionIncreaseMessageId (IkeSaSession
);
100 // If the state is on deleting generate a Delete Payload for it.
102 if (IkeSaSession
->SessionCommon
.State
== IkeStateSaDeleting
) {
103 IkePayload
= Ikev2GenerateDeletePayload (
105 IKEV2_PAYLOAD_TYPE_NONE
,
110 if (IkePayload
== NULL
) {
114 // Fill the next payload in IkePacket's Header.
116 IkePacket
->Header
->NextPayload
= IKEV2_PAYLOAD_TYPE_DELETE
;
117 IKE_PACKET_APPEND_PAYLOAD (IkePacket
, IkePayload
);
118 IkePacket
->Private
= IkeSaSession
->SessionCommon
.Private
;
120 IkePacket
->IsDeleteInfo
= TRUE
;
122 } else if (Context
!= NULL
) {
124 // TODO: If contest is not NULL Generate a Notify Payload.
128 // The input parameter is not correct.
134 // Delete the Child SA Information Exchagne
136 ChildSaSession
= (IKEV2_CHILD_SA_SESSION
*) SaSession
;
137 IkeSaSession
= ChildSaSession
->IkeSaSession
;
138 IkePacket
->Header
->InitiatorCookie
= ChildSaSession
->IkeSaSession
->InitiatorCookie
;
139 IkePacket
->Header
->ResponderCookie
= ChildSaSession
->IkeSaSession
->ResponderCookie
;
142 // If the information message is response message,the MessageId should
143 // be same as the request MessageId which passed through the Context.
145 if (InfoContext
!= NULL
&& InfoContext
->MessageId
!= 0) {
146 IkePacket
->Header
->MessageId
= InfoContext
->MessageId
;
148 IkePacket
->Header
->MessageId
= ChildSaSession
->IkeSaSession
->MessageId
;
149 Ikev2SaSessionIncreaseMessageId (IkeSaSession
);
152 IkePayload
= Ikev2GenerateDeletePayload (
153 ChildSaSession
->IkeSaSession
,
154 IKEV2_PAYLOAD_TYPE_DELETE
,
157 (UINT8
*)&ChildSaSession
->LocalPeerSpi
159 if (IkePayload
== NULL
) {
163 // Fill the Next Payload in IkePacket's Header.
165 IkePacket
->Header
->NextPayload
= IKEV2_PAYLOAD_TYPE_DELETE
;
166 IKE_PACKET_APPEND_PAYLOAD (IkePacket
, IkePayload
);
168 IkePacket
->Private
= IkeSaSession
->SessionCommon
.Private
;
169 IkePacket
->Spi
= ChildSaSession
->LocalPeerSpi
;
170 IkePacket
->IsDeleteInfo
= TRUE
;
172 if (!ChildSaSession
->SessionCommon
.IsInitiator
) {
174 // If responder, use the MessageId fromt the initiator.
176 IkePacket
->Header
->MessageId
= ChildSaSession
->MessageId
;
180 // Change the IsOnDeleting Flag
182 ChildSaSession
->SessionCommon
.IsOnDeleting
= TRUE
;
185 if (InfoContext
== NULL
) {
186 IkePacket
->Header
->Flags
= IKE_HEADER_FLAGS_INIT
;
188 IkePacket
->Header
->Flags
= IKE_HEADER_FLAGS_RESPOND
;
193 if (IkePacket
!= NULL
) {
194 FreePool (IkePacket
);
201 Parse the Info Exchange.
203 @param[in] SaSession Pointer to IKEV2_SA_SESSION.
204 @param[in] IkePacket Pointer to IkePacket related to the Information Exchange.
206 @retval EFI_SUCCESS The operation finised successed.
212 IN IKE_PACKET
*IkePacket
215 IKEV2_CHILD_SA_SESSION
*ChildSaSession
;
216 IKEV2_SA_SESSION
*IkeSaSession
;
217 IKE_PAYLOAD
*DeletePayload
;
218 IKE_PAYLOAD
*IkePayload
;
219 IKEV2_DELETE
*Delete
;
221 LIST_ENTRY
*ListEntry
;
225 IPSEC_PRIVATE_DATA
*Private
;
228 IKE_PACKET
*RespondPacket
;
230 IKEV2_INFO_EXCHANGE_CONTEXT Context
;
232 IkeSaSession
= (IKEV2_SA_SESSION
*) SaSession
;
234 DeletePayload
= NULL
;
236 RespondPacket
= NULL
;
237 Status
= EFI_SUCCESS
;
240 // For Liveness Check
242 if (IkePacket
->Header
->NextPayload
== IKEV2_PAYLOAD_TYPE_NONE
&&
243 (IkePacket
->PayloadTotalSize
== 0)
245 if (IkePacket
->Header
->Flags
== IKE_HEADER_FLAGS_INIT
) {
247 // If it is Liveness check request, reply it.
249 Context
.InfoType
= Ikev2InfoLiveCheck
;
250 Context
.MessageId
= IkePacket
->Header
->MessageId
;
251 RespondPacket
= Ikev2InfoGenerator ((UINT8
*)IkeSaSession
, &Context
);
253 if (RespondPacket
== NULL
) {
254 Status
= EFI_INVALID_PARAMETER
;
257 Status
= Ikev2SendIkePacket (
258 IkeSaSession
->SessionCommon
.UdpService
,
259 (UINT8
*)(&IkeSaSession
->SessionCommon
),
266 // Todo: verify the liveness check response packet.
275 NET_LIST_FOR_EACH (Entry
, &(IkePacket
)->PayloadList
) {
278 // Iterate payloads to find the Delete/Notify Payload.
280 IkePayload
= IKE_PAYLOAD_BY_PACKET (Entry
);
282 if (IkePayload
->PayloadType
== IKEV2_PAYLOAD_TYPE_DELETE
) {
283 DeletePayload
= IkePayload
;
284 Delete
= (IKEV2_DELETE
*)DeletePayload
->PayloadBuf
;
286 if (Delete
->SpiSize
== 0) {
290 if (IkeSaSession
->SessionCommon
.State
== IkeStateSaDeleting
) {
291 RemoveEntryList (&IkeSaSession
->BySessionTable
);
292 Ikev2SaSessionFree (IkeSaSession
);
294 // Checking the Private status.
297 // when all IKE SAs were disabled by calling "IPsecConfig -disable", the IPsec
298 // status should be changed.
300 Private
= IkeSaSession
->SessionCommon
.Private
;
301 if (Private
!= NULL
&& Private
->IsIPsecDisabling
) {
303 // After all IKE SAs were deleted, set the IPSEC_STATUS_DISABLED value in
304 // IPsec status variable.
306 if (IsListEmpty (&Private
->Ikev1EstablishedList
) &&
307 (IsListEmpty (&Private
->Ikev2EstablishedList
))
309 Value
= IPSEC_STATUS_DISABLED
;
310 Status
= gRT
->SetVariable (
311 IPSECCONFIG_STATUS_NAME
,
312 &gEfiIpSecConfigProtocolGuid
,
313 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
317 if (!EFI_ERROR (Status
)) {
319 // Set the DisabledFlag in Private data.
321 Private
->IpSec
.DisabledFlag
= TRUE
;
322 Private
->IsIPsecDisabling
= FALSE
;
327 IkeSaSession
->SessionCommon
.State
= IkeStateSaDeleting
;
328 Context
.InfoType
= Ikev2InfoDelete
;
329 Context
.MessageId
= IkePacket
->Header
->MessageId
;
331 RespondPacket
= Ikev2InfoGenerator ((UINT8
*)IkeSaSession
, &Context
);
332 if (RespondPacket
== NULL
) {
333 Status
= EFI_INVALID_PARAMETER
;
336 Status
= Ikev2SendIkePacket (
337 IkeSaSession
->SessionCommon
.UdpService
,
338 (UINT8
*)(&IkeSaSession
->SessionCommon
),
343 } else if (Delete
->SpiSize
== 4) {
345 // Move the Child SAs to DeleteList
347 SpiBuffer
= (UINT8
*)(Delete
+ 1);
348 for (Index
= 0; Index
< Delete
->NumSpis
; Index
++) {
349 Spi
= ReadUnaligned32 ((UINT32
*)SpiBuffer
);
350 for (ListEntry
= IkeSaSession
->ChildSaEstablishSessionList
.ForwardLink
;
351 ListEntry
!= &IkeSaSession
->ChildSaEstablishSessionList
;
353 ChildSaSession
= IKEV2_CHILD_SA_SESSION_BY_IKE_SA (ListEntry
);
354 ListEntry
= ListEntry
->ForwardLink
;
356 if (ChildSaSession
->RemotePeerSpi
== HTONL(Spi
)) {
357 if (ChildSaSession
->SessionCommon
.State
!= IkeStateSaDeleting
) {
360 // Insert the ChildSa Session into Delete List.
362 InsertTailList (&IkeSaSession
->DeleteSaList
, &ChildSaSession
->ByDelete
);
363 ChildSaSession
->SessionCommon
.State
= IkeStateSaDeleting
;
364 ChildSaSession
->SessionCommon
.IsInitiator
= FALSE
;
365 ChildSaSession
->MessageId
= IkePacket
->Header
->MessageId
;
367 Context
.InfoType
= Ikev2InfoDelete
;
368 Context
.MessageId
= IkePacket
->Header
->MessageId
;
370 RespondPacket
= Ikev2InfoGenerator ((UINT8
*)ChildSaSession
, &Context
);
371 if (RespondPacket
== NULL
) {
372 Status
= EFI_INVALID_PARAMETER
;
375 Status
= Ikev2SendIkePacket (
376 ChildSaSession
->SessionCommon
.UdpService
,
377 (UINT8
*)(&ChildSaSession
->SessionCommon
),
383 // Delete the Child SA.
385 Ikev2ChildSaSilentDelete (IkeSaSession
, Spi
);
386 RemoveEntryList (&ChildSaSession
->ByDelete
);
390 SpiBuffer
= SpiBuffer
+ sizeof (Spi
);
399 GLOBAL_REMOVE_IF_UNREFERENCED IKEV2_PACKET_HANDLER mIkev2Info
= {