]> git.proxmox.com Git - mirror_edk2.git/blob - NetworkPkg/IpSecDxe/Ikev2/Info.c
NetworkPkg: Remove unused variables from IpSecDxe to fix GCC build.
[mirror_edk2.git] / NetworkPkg / IpSecDxe / Ikev2 / Info.c
1 /** @file
2 The Implementations for Information Exchange.
3
4 (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
5 Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
6
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.
11
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.
14
15 **/
16
17 #include "Utility.h"
18 #include "IpSecDebug.h"
19 #include "IpSecConfigImpl.h"
20
21 /**
22 Generate Information Packet.
23
24 The information Packet may contain one Delete Payload, or Notify Payload, which
25 dependes on the Context's parameters.
26
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.
31
32 @retval Pointer of IKE_PACKET generated.
33
34 **/
35 IKE_PACKET *
36 Ikev2InfoGenerator (
37 IN UINT8 *SaSession,
38 IN VOID *Context
39 )
40 {
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;
46
47 InfoContext = NULL;
48 IkeSaSession = (IKEV2_SA_SESSION *) SaSession;
49 IkePacket = IkePacketAlloc ();
50 ASSERT (IkePacket != NULL);
51
52 //
53 // Fill IkePacket Header.
54 //
55 IkePacket->Header->ExchangeType = IKEV2_EXCHANGE_TYPE_INFO;
56 IkePacket->Header->Version = (UINT8) (2 << 4);
57
58 if (Context != NULL) {
59 InfoContext = (IKEV2_INFO_EXCHANGE_CONTEXT *) Context;
60 }
61
62 //
63 // For Liveness Check
64 //
65 if (InfoContext != NULL &&
66 (InfoContext->InfoType == Ikev2InfoLiveCheck || InfoContext->InfoType == Ikev2InfoNotify)
67 ) {
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;
73 //
74 // TODO: add Notify Payload for Notification Information.
75 //
76 return IkePacket;
77 }
78
79 //
80 // For delete SAs
81 //
82 if (IkeSaSession->SessionCommon.IkeSessionType == IkeSessionTypeIkeSa) {
83
84 IkePacket->Header->InitiatorCookie = IkeSaSession->InitiatorCookie;
85 IkePacket->Header->ResponderCookie = IkeSaSession->ResponderCookie;
86
87 //
88 // If the information message is response message,the MessageId should
89 // be same as the request MessageId which passed through the Context.
90 //
91 if (InfoContext != NULL) {
92 IkePacket->Header->MessageId = InfoContext->MessageId;
93 } else {
94 IkePacket->Header->MessageId = IkeSaSession->MessageId;
95 Ikev2SaSessionIncreaseMessageId (IkeSaSession);
96 }
97 //
98 // If the state is on deleting generate a Delete Payload for it.
99 //
100 if (IkeSaSession->SessionCommon.State == IkeStateSaDeleting ) {
101 IkePayload = Ikev2GenerateDeletePayload (
102 IkeSaSession,
103 IKEV2_PAYLOAD_TYPE_NONE,
104 0,
105 0,
106 NULL
107 );
108 if (IkePayload == NULL) {
109 goto ERROR_EXIT;
110 }
111 //
112 // Fill the next payload in IkePacket's Header.
113 //
114 IkePacket->Header->NextPayload = IKEV2_PAYLOAD_TYPE_DELETE;
115 IKE_PACKET_APPEND_PAYLOAD (IkePacket, IkePayload);
116 IkePacket->Private = IkeSaSession->SessionCommon.Private;
117 IkePacket->Spi = 0;
118 IkePacket->IsDeleteInfo = TRUE;
119
120 } else if (Context != NULL) {
121 //
122 // TODO: If contest is not NULL Generate a Notify Payload.
123 //
124 } else {
125 //
126 // The input parameter is not correct.
127 //
128 goto ERROR_EXIT;
129 }
130 } else {
131 //
132 // Delete the Child SA Information Exchagne
133 //
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;
138
139 //
140 // If the information message is response message,the MessageId should
141 // be same as the request MessageId which passed through the Context.
142 //
143 if (InfoContext != NULL && InfoContext->MessageId != 0) {
144 IkePacket->Header->MessageId = InfoContext->MessageId;
145 } else {
146 IkePacket->Header->MessageId = ChildSaSession->IkeSaSession->MessageId;
147 Ikev2SaSessionIncreaseMessageId (IkeSaSession);
148 }
149
150 IkePayload = Ikev2GenerateDeletePayload (
151 ChildSaSession->IkeSaSession,
152 IKEV2_PAYLOAD_TYPE_DELETE,
153 4,
154 1,
155 (UINT8 *)&ChildSaSession->LocalPeerSpi
156 );
157 if (IkePayload == NULL) {
158 goto ERROR_EXIT;
159 }
160 //
161 // Fill the Next Payload in IkePacket's Header.
162 //
163 IkePacket->Header->NextPayload = IKEV2_PAYLOAD_TYPE_DELETE;
164 IKE_PACKET_APPEND_PAYLOAD (IkePacket, IkePayload);
165
166 IkePacket->Private = IkeSaSession->SessionCommon.Private;
167 IkePacket->Spi = ChildSaSession->LocalPeerSpi;
168 IkePacket->IsDeleteInfo = TRUE;
169
170 if (!ChildSaSession->SessionCommon.IsInitiator) {
171 //
172 // If responder, use the MessageId fromt the initiator.
173 //
174 IkePacket->Header->MessageId = ChildSaSession->MessageId;
175 }
176
177 //
178 // Change the IsOnDeleting Flag
179 //
180 ChildSaSession->SessionCommon.IsOnDeleting = TRUE;
181 }
182
183 if (InfoContext == NULL) {
184 IkePacket->Header->Flags = IKE_HEADER_FLAGS_INIT;
185 } else {
186 IkePacket->Header->Flags = IKE_HEADER_FLAGS_RESPOND;
187 }
188 return IkePacket;
189
190 ERROR_EXIT:
191 if (IkePacket != NULL) {
192 FreePool (IkePacket);
193 }
194 return NULL;
195
196 }
197
198 /**
199 Parse the Info Exchange.
200
201 @param[in] SaSession Pointer to IKEV2_SA_SESSION.
202 @param[in] IkePacket Pointer to IkePacket related to the Information Exchange.
203
204 @retval EFI_SUCCESS The operation finised successed.
205
206 **/
207 EFI_STATUS
208 Ikev2InfoParser (
209 IN UINT8 *SaSession,
210 IN IKE_PACKET *IkePacket
211 )
212 {
213 IKEV2_CHILD_SA_SESSION *ChildSaSession;
214 IKEV2_SA_SESSION *IkeSaSession;
215 IKE_PAYLOAD *DeletePayload;
216 IKE_PAYLOAD *IkePayload;
217 IKEV2_DELETE *Delete;
218 LIST_ENTRY *Entry;
219 LIST_ENTRY *ListEntry;
220 UINT8 Index;
221 UINT32 Spi;
222 UINT8 *SpiBuffer;
223 IPSEC_PRIVATE_DATA *Private;
224 UINT8 Value;
225 EFI_STATUS Status;
226 IKE_PACKET *RespondPacket;
227
228 IKEV2_INFO_EXCHANGE_CONTEXT Context;
229
230 IkeSaSession = (IKEV2_SA_SESSION *) SaSession;
231
232 DeletePayload = NULL;
233 Private = NULL;
234 RespondPacket = NULL;
235 Status = EFI_SUCCESS;
236
237 //
238 // For Liveness Check
239 //
240 if (IkePacket->Header->NextPayload == IKEV2_PAYLOAD_TYPE_NONE &&
241 (IkePacket->PayloadTotalSize == 0)
242 ) {
243 if (IkePacket->Header->Flags == IKE_HEADER_FLAGS_INIT) {
244 //
245 // If it is Liveness check request, reply it.
246 //
247 Context.InfoType = Ikev2InfoLiveCheck;
248 Context.MessageId = IkePacket->Header->MessageId;
249 RespondPacket = Ikev2InfoGenerator ((UINT8 *)IkeSaSession, &Context);
250
251 if (RespondPacket == NULL) {
252 Status = EFI_INVALID_PARAMETER;
253 return Status;
254 }
255 Status = Ikev2SendIkePacket (
256 IkeSaSession->SessionCommon.UdpService,
257 (UINT8 *)(&IkeSaSession->SessionCommon),
258 RespondPacket,
259 0
260 );
261
262 } else {
263 //
264 // Todo: verify the liveness check response packet.
265 //
266 }
267 return Status;
268 }
269
270 //
271 // For SA Delete
272 //
273 NET_LIST_FOR_EACH (Entry, &(IkePacket)->PayloadList) {
274
275 //
276 // Iterate payloads to find the Delete/Notify Payload.
277 //
278 IkePayload = IKE_PAYLOAD_BY_PACKET (Entry);
279
280 if (IkePayload->PayloadType == IKEV2_PAYLOAD_TYPE_DELETE) {
281 DeletePayload = IkePayload;
282 Delete = (IKEV2_DELETE *)DeletePayload->PayloadBuf;
283
284 if (Delete->SpiSize == 0) {
285 //
286 // Delete IKE SA.
287 //
288 if (IkeSaSession->SessionCommon.State == IkeStateSaDeleting) {
289 RemoveEntryList (&IkeSaSession->BySessionTable);
290 Ikev2SaSessionFree (IkeSaSession);
291 //
292 // Checking the Private status.
293 //
294 //
295 // when all IKE SAs were disabled by calling "IPsecConfig -disable", the IPsec
296 // status should be changed.
297 //
298 Private = IkeSaSession->SessionCommon.Private;
299 if (Private != NULL && Private->IsIPsecDisabling) {
300 //
301 // After all IKE SAs were deleted, set the IPSEC_STATUS_DISABLED value in
302 // IPsec status variable.
303 //
304 if (IsListEmpty (&Private->Ikev1EstablishedList) &&
305 (IsListEmpty (&Private->Ikev2EstablishedList))
306 ) {
307 Value = IPSEC_STATUS_DISABLED;
308 Status = gRT->SetVariable (
309 IPSECCONFIG_STATUS_NAME,
310 &gEfiIpSecConfigProtocolGuid,
311 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
312 sizeof (Value),
313 &Value
314 );
315 if (!EFI_ERROR (Status)) {
316 //
317 // Set the DisabledFlag in Private data.
318 //
319 Private->IpSec.DisabledFlag = TRUE;
320 Private->IsIPsecDisabling = FALSE;
321 }
322 }
323 }
324 } else {
325 IkeSaSession->SessionCommon.State = IkeStateSaDeleting;
326 Context.InfoType = Ikev2InfoDelete;
327 Context.MessageId = IkePacket->Header->MessageId;
328
329 RespondPacket = Ikev2InfoGenerator ((UINT8 *)IkeSaSession, &Context);
330 if (RespondPacket == NULL) {
331 Status = EFI_INVALID_PARAMETER;
332 return Status;
333 }
334 Status = Ikev2SendIkePacket (
335 IkeSaSession->SessionCommon.UdpService,
336 (UINT8 *)(&IkeSaSession->SessionCommon),
337 RespondPacket,
338 0
339 );
340 }
341 } else if (Delete->SpiSize == 4) {
342 //
343 // Move the Child SAs to DeleteList
344 //
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;
350 ) {
351 ChildSaSession = IKEV2_CHILD_SA_SESSION_BY_IKE_SA (ListEntry);
352 ListEntry = ListEntry->ForwardLink;
353
354 if (ChildSaSession->RemotePeerSpi == HTONL(Spi)) {
355 if (ChildSaSession->SessionCommon.State != IkeStateSaDeleting) {
356
357 //
358 // Insert the ChildSa Session into Delete List.
359 //
360 InsertTailList (&IkeSaSession->DeleteSaList, &ChildSaSession->ByDelete);
361 ChildSaSession->SessionCommon.State = IkeStateSaDeleting;
362 ChildSaSession->SessionCommon.IsInitiator = FALSE;
363 ChildSaSession->MessageId = IkePacket->Header->MessageId;
364
365 Context.InfoType = Ikev2InfoDelete;
366 Context.MessageId = IkePacket->Header->MessageId;
367
368 RespondPacket = Ikev2InfoGenerator ((UINT8 *)ChildSaSession, &Context);
369 if (RespondPacket == NULL) {
370 Status = EFI_INVALID_PARAMETER;
371 return Status;
372 }
373 Status = Ikev2SendIkePacket (
374 ChildSaSession->SessionCommon.UdpService,
375 (UINT8 *)(&ChildSaSession->SessionCommon),
376 RespondPacket,
377 0
378 );
379 } else {
380 //
381 // Delete the Child SA.
382 //
383 Ikev2ChildSaSilentDelete (IkeSaSession, Spi);
384 RemoveEntryList (&ChildSaSession->ByDelete);
385 }
386 }
387 }
388 SpiBuffer = SpiBuffer + sizeof (Spi);
389 }
390 }
391 }
392 }
393
394 return Status;
395 }
396
397 GLOBAL_REMOVE_IF_UNREFERENCED IKEV2_PACKET_HANDLER mIkev2Info = {
398 Ikev2InfoParser,
399 Ikev2InfoGenerator
400 };