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