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