]> git.proxmox.com Git - mirror_edk2.git/blame - NetworkPkg/IpSecDxe/IkeService.c
NetworkPkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / NetworkPkg / IpSecDxe / IkeService.c
CommitLineData
9166f840 1/** @file\r
2 Provide IPsec Key Exchange (IKE) service general interfaces.\r
6cf9230f 3\r
f75a7f56 4 Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>\r
9166f840 5\r
ecf98fbc 6 SPDX-License-Identifier: BSD-2-Clause-Patent\r
9166f840 7\r
8**/\r
9\r
10#include "IkeService.h"\r
11#include "IpSecConfigImpl.h"\r
9166f840 12\r
13IKE_EXCHANGE_INTERFACE *mIkeExchange[] = {\r
14 &mIkev1Exchange,\r
15 &mIkev2Exchange\r
16};\r
17\r
18EFI_UDP4_CONFIG_DATA mUdp4Conf = {\r
19 FALSE,\r
20 FALSE,\r
21 FALSE,\r
22 TRUE,\r
23 //\r
24 // IO parameters\r
25 //\r
26 0,\r
27 64,\r
28 FALSE,\r
29 0,\r
30 1000000,\r
31 FALSE,\r
ce68d3bc
SZ
32 {{0,0,0,0}},\r
33 {{0,0,0,0}},\r
9166f840 34 IKE_DEFAULT_PORT,\r
ce68d3bc 35 {{0,0,0,0}},\r
9166f840 36 0\r
37};\r
38\r
39EFI_UDP6_CONFIG_DATA mUdp6Conf = {\r
40 FALSE,\r
41 FALSE,\r
42 TRUE,\r
43 //\r
44 // IO parameters\r
45 //\r
46 0,\r
47 128,\r
48 0,\r
49 1000000,\r
50 //Access Point\r
ce68d3bc 51 {{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},\r
9166f840 52 IKE_DEFAULT_PORT,\r
ce68d3bc 53 {{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},\r
9166f840 54 0\r
55};\r
56\r
57/**\r
58 Check if the NIC handle is binded to a Udp service.\r
59\r
60 @param[in] Private Pointer of IPSEC_PRIVATE_DATA.\r
76389e18 61 @param[in] Handle The Handle of the NIC card.\r
9166f840 62 @param[in] IpVersion The version of the IP stack.\r
63\r
64 @return a pointer of IKE_UDP_SERVICE.\r
65\r
66**/\r
67IKE_UDP_SERVICE *\r
68IkeLookupUdp (\r
69 IN IPSEC_PRIVATE_DATA *Private,\r
70 IN EFI_HANDLE Handle,\r
71 IN UINT8 IpVersion\r
72 )\r
73{\r
74 LIST_ENTRY *Head;\r
75 LIST_ENTRY *Entry;\r
76 LIST_ENTRY *Next;\r
77 IKE_UDP_SERVICE *Udp;\r
78\r
79 Udp = NULL;\r
80 Head = (IpVersion == IP_VERSION_4) ? &Private->Udp4List : &Private->Udp6List;\r
81\r
82 NET_LIST_FOR_EACH_SAFE (Entry, Next, Head) {\r
83\r
84 Udp = IPSEC_UDP_SERVICE_FROM_LIST (Entry);\r
85 //\r
86 // Find the right udp service which installed on the appointed NIC handle.\r
87 //\r
88 if (Handle == Udp->NicHandle) {\r
89 break;\r
90 } else {\r
91 Udp = NULL;\r
92 }\r
93 }\r
94\r
95 return Udp;\r
96}\r
97\r
98/**\r
99 Configure a UDPIO's UDP4 instance.\r
6cf9230f 100\r
101 This fuction is called by the UdpIoCreateIo() to configures a\r
9166f840 102 UDP4 instance.\r
6cf9230f 103\r
9166f840 104 @param[in] UdpIo The UDP_IO to be configured.\r
105 @param[in] Context User-defined data when calling UdpIoCreateIo().\r
6cf9230f 106\r
9166f840 107 @retval EFI_SUCCESS The configuration succeeded.\r
108 @retval Others The UDP4 instance fails to configure.\r
109\r
110**/\r
111EFI_STATUS\r
1d8fa5e9 112EFIAPI\r
9166f840 113IkeConfigUdp4 (\r
114 IN UDP_IO *UdpIo,\r
115 IN VOID *Context\r
116 )\r
117{\r
118 EFI_UDP4_CONFIG_DATA Udp4Cfg;\r
119 EFI_UDP4_PROTOCOL *Udp4;\r
120\r
121 ZeroMem (&Udp4Cfg, sizeof (EFI_UDP4_CONFIG_DATA));\r
122\r
123 Udp4 = UdpIo->Protocol.Udp4;\r
124 CopyMem (\r
125 &Udp4Cfg,\r
126 &mUdp4Conf,\r
127 sizeof (EFI_UDP4_CONFIG_DATA)\r
128 );\r
129\r
130 if (Context != NULL) {\r
131 //\r
132 // Configure udp4 io with local default address.\r
133 //\r
134 Udp4Cfg.UseDefaultAddress = TRUE;\r
135 }\r
136\r
137 return Udp4->Configure (Udp4, &Udp4Cfg);\r
138}\r
139\r
140/**\r
141 Configure a UDPIO's UDP6 instance.\r
6cf9230f 142\r
143 This fuction is called by the UdpIoCreateIo()to configure a\r
9166f840 144 UDP6 instance.\r
6cf9230f 145\r
9166f840 146 @param[in] UdpIo The UDP_IO to be configured.\r
147 @param[in] Context User-defined data when calling UdpIoCreateIo().\r
6cf9230f 148\r
9166f840 149 @retval EFI_SUCCESS The configuration succeeded.\r
150 @retval Others The configuration fails.\r
151\r
152**/\r
153EFI_STATUS\r
1d8fa5e9 154EFIAPI\r
9166f840 155IkeConfigUdp6 (\r
156 IN UDP_IO *UdpIo,\r
157 IN VOID *Context\r
158 )\r
159{\r
160 EFI_UDP6_PROTOCOL *Udp6;\r
161 EFI_UDP6_CONFIG_DATA Udp6Cfg;\r
162\r
163 ZeroMem (&Udp6Cfg, sizeof (EFI_UDP6_CONFIG_DATA));\r
164\r
165 Udp6 = UdpIo->Protocol.Udp6;\r
166 CopyMem (\r
167 &Udp6Cfg,\r
168 &mUdp6Conf,\r
169 sizeof (EFI_UDP6_CONFIG_DATA)\r
170 );\r
171\r
172 if (Context != NULL) {\r
173 //\r
174 // Configure instance with a destination address to start source address\r
175 // selection, and then get the configure data from the mode data to store\r
176 // the source address.\r
177 //\r
178 CopyMem (\r
179 &Udp6Cfg.RemoteAddress,\r
180 Context,\r
181 sizeof (EFI_IPv6_ADDRESS)\r
182 );\r
183 }\r
184\r
185 return Udp6->Configure (Udp6, &Udp6Cfg);\r
186}\r
187\r
188/**\r
189 Open and configure the related output UDPIO for IKE packet sending.\r
6cf9230f 190\r
191 If the UdpService is not configured, this fuction calls UdpIoCreatIo() to\r
9166f840 192 create UDPIO to bind this UdpService for IKE packet sending. If the UdpService\r
193 has already been configured, then return.\r
6cf9230f 194\r
9166f840 195 @param[in] UdpService The UDP_IO to be configured.\r
196 @param[in] RemoteIp User-defined data when calling UdpIoCreateIo().\r
6cf9230f 197\r
9166f840 198 @retval EFI_SUCCESS The configuration is successful.\r
199 @retval Others The configuration fails.\r
200\r
201**/\r
202EFI_STATUS\r
203IkeOpenOutputUdp (\r
204 IN IKE_UDP_SERVICE *UdpService,\r
205 IN EFI_IP_ADDRESS *RemoteIp\r
206 )\r
207{\r
39561686 208 EFI_STATUS Status;\r
209 EFI_IP4_CONFIG2_PROTOCOL *Ip4Cfg2;\r
210 EFI_IP4_CONFIG2_INTERFACE_INFO *IfInfo;\r
211 UINTN BufSize;\r
212 EFI_IP6_MODE_DATA Ip6ModeData;\r
213 EFI_UDP6_PROTOCOL *Udp6;\r
9166f840 214\r
215 Status = EFI_SUCCESS;\r
39561686 216 IfInfo = NULL;\r
9166f840 217 BufSize = 0;\r
218\r
219 //\r
220 // Check whether the input and output udp io are both configured.\r
221 //\r
222 if (UdpService->IsConfigured) {\r
223 goto ON_EXIT;\r
224 }\r
225\r
226 if (UdpService->IpVersion == UDP_IO_UDP4_VERSION) {\r
227 //\r
228 // Handle ip4config protocol to get local default address.\r
229 //\r
230 Status = gBS->HandleProtocol (\r
231 UdpService->NicHandle,\r
39561686 232 &gEfiIp4Config2ProtocolGuid,\r
233 (VOID **) &Ip4Cfg2\r
9166f840 234 );\r
235\r
236 if (EFI_ERROR (Status)) {\r
237 goto ON_EXIT;\r
238 }\r
239\r
39561686 240 //\r
241 // Get the interface information size.\r
242 //\r
243 Status = Ip4Cfg2->GetData (\r
244 Ip4Cfg2,\r
245 Ip4Config2DataTypeInterfaceInfo,\r
246 &BufSize,\r
247 NULL\r
248 );\r
9166f840 249\r
250 if (EFI_ERROR (Status) && Status != EFI_BUFFER_TOO_SMALL) {\r
251 goto ON_EXIT;\r
252 }\r
253\r
39561686 254 IfInfo = AllocateZeroPool (BufSize);\r
9166f840 255\r
39561686 256 if (IfInfo == NULL) {\r
9166f840 257 Status = EFI_OUT_OF_RESOURCES;\r
258 goto ON_EXIT;\r
259 }\r
260\r
39561686 261 //\r
262 // Get the interface info.\r
263 //\r
264 Status = Ip4Cfg2->GetData (\r
265 Ip4Cfg2,\r
266 Ip4Config2DataTypeInterfaceInfo,\r
267 &BufSize,\r
268 IfInfo\r
269 );\r
f75a7f56 270\r
9166f840 271 if (EFI_ERROR (Status)) {\r
272 goto ON_EXIT;\r
273 }\r
274\r
275 CopyMem (\r
276 &UdpService->DefaultAddress.v4,\r
39561686 277 &IfInfo->StationAddress,\r
9166f840 278 sizeof (EFI_IPv4_ADDRESS)\r
279 );\r
280\r
281 //\r
282 // Create udp4 io for output with local default address.\r
283 //\r
284 UdpService->Output = UdpIoCreateIo (\r
285 UdpService->NicHandle,\r
286 UdpService->ImageHandle,\r
287 IkeConfigUdp4,\r
288 UDP_IO_UDP4_VERSION,\r
289 &UdpService->DefaultAddress\r
290 );\r
291\r
292 if (UdpService->Output == NULL) {\r
293 Status = EFI_OUT_OF_RESOURCES;\r
294 goto ON_EXIT;\r
295 }\r
296\r
297 } else {\r
298 //\r
299 // Create udp6 io for output with remote address.\r
300 //\r
301 UdpService->Output = UdpIoCreateIo (\r
302 UdpService->NicHandle,\r
303 UdpService->ImageHandle,\r
304 IkeConfigUdp6,\r
305 UDP_IO_UDP6_VERSION,\r
306 RemoteIp\r
307 );\r
308\r
309 if (UdpService->Output == NULL) {\r
310 Status = EFI_OUT_OF_RESOURCES;\r
311 goto ON_EXIT;\r
312 }\r
313 //\r
314 // Get ip6 mode data to get the result of source address selection.\r
315 //\r
316 ZeroMem (&Ip6ModeData, sizeof (EFI_IP6_MODE_DATA));\r
317\r
318 Udp6 = UdpService->Output->Protocol.Udp6;\r
319 Status = Udp6->GetModeData (Udp6, NULL, &Ip6ModeData, NULL, NULL);\r
320\r
321 if (EFI_ERROR (Status)) {\r
322 UdpIoFreeIo (UdpService->Output);\r
323 goto ON_EXIT;\r
324 }\r
ce22514e
ZL
325\r
326 if (Ip6ModeData.AddressList != NULL) {\r
327 FreePool (Ip6ModeData.AddressList);\r
328 }\r
329\r
330 if (Ip6ModeData.GroupTable != NULL) {\r
331 FreePool (Ip6ModeData.GroupTable);\r
332 }\r
333\r
334 if (Ip6ModeData.RouteTable != NULL) {\r
335 FreePool (Ip6ModeData.RouteTable);\r
336 }\r
337\r
338 if (Ip6ModeData.NeighborCache != NULL) {\r
339 FreePool (Ip6ModeData.NeighborCache);\r
340 }\r
341\r
342 if (Ip6ModeData.PrefixTable != NULL) {\r
343 FreePool (Ip6ModeData.PrefixTable);\r
344 }\r
345\r
346 if (Ip6ModeData.IcmpTypeList != NULL) {\r
347 FreePool (Ip6ModeData.IcmpTypeList);\r
348 }\r
349\r
9166f840 350 //\r
351 // Reconfigure udp6 io without remote address.\r
352 //\r
353 Udp6->Configure (Udp6, NULL);\r
354 Status = IkeConfigUdp6 (UdpService->Output, NULL);\r
355\r
356 //\r
357 // Record the selected source address for ipsec process later.\r
358 //\r
359 CopyMem (\r
360 &UdpService->DefaultAddress.v6,\r
361 &Ip6ModeData.ConfigData.StationAddress,\r
362 sizeof (EFI_IPv6_ADDRESS)\r
363 );\r
364 }\r
365\r
366 UdpService->IsConfigured = TRUE;\r
367\r
368ON_EXIT:\r
39561686 369 if (IfInfo != NULL) {\r
370 FreePool (IfInfo);\r
9166f840 371 }\r
372\r
373 return Status;\r
374}\r
375\r
376/**\r
377 Open and configure a UDPIO of Udp4 for IKE packet receiving.\r
6cf9230f 378\r
379 This function is called at the IPsecDriverBinding start. IPsec create a UDP4 and\r
9166f840 380 UDP4 IO for each NIC handle.\r
6cf9230f 381\r
9166f840 382 @param[in] Private Point to IPSEC_PRIVATE_DATA\r
383 @param[in] Controller Handler for NIC card.\r
6879581d 384 @param[in] ImageHandle The handle that contains the EFI_DRIVER_BINDING_PROTOCOL instance.\r
6cf9230f 385\r
9166f840 386 @retval EFI_SUCCESS The Operation is successful.\r
387 @retval EFI_OUT_OF_RESOURCE The required system resource can't be allocated.\r
6cf9230f 388\r
9166f840 389**/\r
390EFI_STATUS\r
391IkeOpenInputUdp4 (\r
392 IN IPSEC_PRIVATE_DATA *Private,\r
6879581d 393 IN EFI_HANDLE Controller,\r
394 IN EFI_HANDLE ImageHandle\r
9166f840 395 )\r
396{\r
397 IKE_UDP_SERVICE *Udp4Srv;\r
398\r
399 //\r
400 // Check whether udp4 io of the controller has already been opened.\r
401 //\r
402 Udp4Srv = IkeLookupUdp (Private, Controller, IP_VERSION_4);\r
403\r
404 if (Udp4Srv != NULL) {\r
405 return EFI_ALREADY_STARTED;\r
406 }\r
407\r
408 Udp4Srv = AllocateZeroPool (sizeof (IKE_UDP_SERVICE));\r
409\r
410 if (Udp4Srv == NULL) {\r
411 return EFI_OUT_OF_RESOURCES;\r
412 }\r
413 //\r
414 // Create udp4 io for iutput.\r
415 //\r
416 Udp4Srv->Input = UdpIoCreateIo (\r
417 Controller,\r
6879581d 418 ImageHandle,\r
9166f840 419 IkeConfigUdp4,\r
420 UDP_IO_UDP4_VERSION,\r
421 NULL\r
422 );\r
423\r
424 if (Udp4Srv->Input == NULL) {\r
425 FreePool (Udp4Srv);\r
426 return EFI_OUT_OF_RESOURCES;\r
427 }\r
428\r
429 Udp4Srv->NicHandle = Controller;\r
6879581d 430 Udp4Srv->ImageHandle = ImageHandle;\r
9166f840 431 Udp4Srv->ListHead = &(Private->Udp4List);\r
432 Udp4Srv->IpVersion = UDP_IO_UDP4_VERSION;\r
433 Udp4Srv->IsConfigured = FALSE;\r
434\r
435 ZeroMem (&Udp4Srv->DefaultAddress, sizeof (EFI_IP_ADDRESS));\r
436\r
437 //\r
438 // Insert the udp4 io into the list and increase the count.\r
439 //\r
440 InsertTailList (&Private->Udp4List, &Udp4Srv->List);\r
441\r
442 Private->Udp4Num++;\r
443\r
444 UdpIoRecvDatagram (Udp4Srv->Input, IkeDispatch, Udp4Srv, 0);\r
445\r
446 return EFI_SUCCESS;\r
447}\r
448\r
449/**\r
450 Open and configure a UDPIO of Udp6 for IKE packet receiving.\r
6cf9230f 451\r
9166f840 452 This function is called at the IPsecDriverBinding start. IPsec create a UDP6 and UDP6\r
453 IO for each NIC handle.\r
6cf9230f 454\r
9166f840 455 @param[in] Private Point to IPSEC_PRIVATE_DATA\r
456 @param[in] Controller Handler for NIC card.\r
6879581d 457 @param[in] ImageHandle The handle that contains the EFI_DRIVER_BINDING_PROTOCOL instance.\r
6cf9230f 458\r
9166f840 459 @retval EFI_SUCCESS The Operation is successful.\r
460 @retval EFI_OUT_OF_RESOURCE The required system resource can't be allocated.\r
6cf9230f 461\r
9166f840 462**/\r
463EFI_STATUS\r
464IkeOpenInputUdp6 (\r
465 IN IPSEC_PRIVATE_DATA *Private,\r
6879581d 466 IN EFI_HANDLE Controller,\r
467 IN EFI_HANDLE ImageHandle\r
9166f840 468 )\r
469{\r
470 IKE_UDP_SERVICE *Udp6Srv;\r
471\r
472 Udp6Srv = IkeLookupUdp (Private, Controller, IP_VERSION_6);\r
473\r
474 if (Udp6Srv != NULL) {\r
475 return EFI_ALREADY_STARTED;\r
476 }\r
477\r
478 Udp6Srv = AllocateZeroPool (sizeof (IKE_UDP_SERVICE));\r
479\r
480 if (Udp6Srv == NULL) {\r
481 return EFI_OUT_OF_RESOURCES;\r
482 }\r
483 //\r
484 // Create udp6 io for input.\r
485 //\r
486 Udp6Srv->Input = UdpIoCreateIo (\r
487 Controller,\r
6879581d 488 ImageHandle,\r
9166f840 489 IkeConfigUdp6,\r
490 UDP_IO_UDP6_VERSION,\r
491 NULL\r
492 );\r
493\r
494 if (Udp6Srv->Input == NULL) {\r
495 FreePool (Udp6Srv);\r
496 return EFI_OUT_OF_RESOURCES;\r
497 }\r
498\r
499 Udp6Srv->NicHandle = Controller;\r
6879581d 500 Udp6Srv->ImageHandle = ImageHandle;\r
9166f840 501 Udp6Srv->ListHead = &(Private->Udp6List);\r
502 Udp6Srv->IpVersion = UDP_IO_UDP6_VERSION;\r
503 Udp6Srv->IsConfigured = FALSE;\r
504\r
505 ZeroMem (&Udp6Srv->DefaultAddress, sizeof (EFI_IP_ADDRESS));\r
506\r
507 //\r
508 // Insert the udp6 io into the list and increase the count.\r
509 //\r
510 InsertTailList (&Private->Udp6List, &Udp6Srv->List);\r
511\r
512 Private->Udp6Num++;\r
513\r
514 UdpIoRecvDatagram (Udp6Srv->Input, IkeDispatch, Udp6Srv, 0);\r
515\r
516 return EFI_SUCCESS;\r
517}\r
518\r
519/**\r
520 The general interface of starting IPsec Key Exchange.\r
6cf9230f 521\r
9166f840 522 This function is called when a IKE negotiation to start getting a Key.\r
6cf9230f 523\r
524 @param[in] UdpService Point to IKE_UDP_SERVICE which will be used for\r
9166f840 525 IKE packet sending.\r
526 @param[in] SpdEntry Point to the SPD entry related to the IKE negotiation.\r
527 @param[in] RemoteIp Point to EFI_IP_ADDRESS related to the IKE negotiation.\r
6cf9230f 528\r
9166f840 529 @retval EFI_SUCCESS The Operation is successful.\r
530 @retval EFI_ACCESS_DENIED No related PAD entry was found.\r
531 @retval EFI_INVALID_PARAMETER The IKE version is not supported.\r
6cf9230f 532\r
9166f840 533**/\r
534EFI_STATUS\r
535IkeNegotiate (\r
536 IN IKE_UDP_SERVICE *UdpService,\r
537 IN IPSEC_SPD_ENTRY *SpdEntry,\r
538 IN EFI_IP_ADDRESS *RemoteIp\r
539 )\r
540{\r
541 EFI_STATUS Status;\r
542 UINT8 *IkeSaSession;\r
543 IKE_EXCHANGE_INTERFACE *Exchange;\r
544 IPSEC_PRIVATE_DATA *Private;\r
545 IPSEC_PAD_ENTRY *PadEntry;\r
546 UINT8 IkeVersion;\r
547\r
548 Private = (UdpService->IpVersion == IP_VERSION_4) ?\r
549 IPSEC_PRIVATE_DATA_FROM_UDP4LIST(UdpService->ListHead) :\r
550 IPSEC_PRIVATE_DATA_FROM_UDP6LIST(UdpService->ListHead);\r
551\r
552 //\r
553 // Try to open udp io for output if it hasn't.\r
554 //\r
555 Status = IkeOpenOutputUdp (UdpService, RemoteIp);\r
556 if (EFI_ERROR (Status)) {\r
557 return Status;\r
558 }\r
559 //\r
560 // Try to find the IKE SA session in the IKEv1 and IKEv2 established SA session list.\r
6cf9230f 561 //\r
562 IkeSaSession = (UINT8 *) Ikev2SaSessionLookup (&Private->Ikev2EstablishedList, RemoteIp);\r
9166f840 563\r
564\r
565 if (IkeSaSession == NULL) {\r
566 //\r
567 // Find the pad entry by the remote ip address.\r
568 //\r
569 PadEntry = IpSecLookupPadEntry (UdpService->IpVersion, RemoteIp);\r
570 if (PadEntry == NULL) {\r
571 return EFI_ACCESS_DENIED;\r
572 }\r
573 //\r
574 // Determine the IKE exchange instance by the auth protocol in pad entry.\r
575 //\r
576 ASSERT (PadEntry->Data->AuthProtocol < EfiIPsecAuthProtocolMaximum);\r
577 if (PadEntry->Data->AuthProtocol == EfiIPsecAuthProtocolIKEv1) {\r
578 return EFI_INVALID_PARAMETER;\r
579 }\r
580 Exchange = mIkeExchange[PadEntry->Data->AuthProtocol];\r
581 //\r
582 // Start the main mode stage to negotiate IKE SA.\r
583 //\r
584 Status = Exchange->NegotiateSa (UdpService, SpdEntry, PadEntry, RemoteIp);\r
585 } else {\r
586 //\r
587 // Determine the IKE exchange instance by the IKE version in IKE SA session.\r
588 //\r
589 IkeVersion = IkeGetVersionFromSession (IkeSaSession);\r
590 if (IkeVersion != 2) {\r
591 return EFI_INVALID_PARAMETER;\r
592 }\r
6cf9230f 593\r
9166f840 594 Exchange = mIkeExchange[IkeVersion - 1];\r
595 //\r
596 // Start the quick mode stage to negotiate child SA.\r
597 //\r
598 Status = Exchange->NegotiateChildSa (IkeSaSession, SpdEntry, NULL);\r
599 }\r
600\r
601 return Status;\r
602}\r
603\r
604/**\r
605 The generic interface when receive a IKE packet.\r
6cf9230f 606\r
9166f840 607 This function is called when UDP IO receives a IKE packet.\r
6cf9230f 608\r
9166f840 609 @param[in] Packet Point to received IKE packet.\r
6cf9230f 610 @param[in] EndPoint Point to UDP_END_POINT which contains the information of\r
9166f840 611 Remote IP and Port.\r
612 @param[in] IoStatus The Status of Recieve Token.\r
613 @param[in] Context Point to data passed from the caller.\r
6cf9230f 614\r
9166f840 615**/\r
616VOID\r
1d8fa5e9 617EFIAPI\r
9166f840 618IkeDispatch (\r
619 IN NET_BUF *Packet,\r
620 IN UDP_END_POINT *EndPoint,\r
621 IN EFI_STATUS IoStatus,\r
622 IN VOID *Context\r
623 )\r
624{\r
625 IPSEC_PRIVATE_DATA *Private;\r
626 IKE_PACKET *IkePacket;\r
627 IKE_HEADER *IkeHdr;\r
628 IKE_UDP_SERVICE *UdpService;\r
629 IKE_EXCHANGE_INTERFACE *Exchange;\r
630 EFI_STATUS Status;\r
631\r
632 UdpService = (IKE_UDP_SERVICE *) Context;\r
633 IkePacket = NULL;\r
634 Private = (UdpService->IpVersion == IP_VERSION_4) ?\r
635 IPSEC_PRIVATE_DATA_FROM_UDP4LIST(UdpService->ListHead) :\r
636 IPSEC_PRIVATE_DATA_FROM_UDP6LIST(UdpService->ListHead);\r
637\r
638 if (EFI_ERROR (IoStatus)) {\r
639 goto ON_EXIT;\r
640 }\r
641 //\r
642 // Check whether the ipsec is enabled or not.\r
643 //\r
644 if (Private->IpSec.DisabledFlag == TRUE) {\r
645 goto ON_EXIT;\r
646 }\r
647\r
648 if (EndPoint->RemotePort != IKE_DEFAULT_PORT) {\r
649 goto ON_EXIT;\r
650 }\r
651\r
652 //\r
653 // Build IKE packet from the received netbuf.\r
654 //\r
655 IkePacket = IkePacketFromNetbuf (Packet);\r
656\r
657 if (IkePacket == NULL) {\r
658 goto ON_EXIT;\r
659 }\r
660 //\r
661 // Get the remote address from the IKE packet.\r
662 //\r
663 if (UdpService->IpVersion == IP_VERSION_4) {\r
664 *(UINT32 *) IkePacket->RemotePeerIp.Addr = HTONL ((*(UINT32 *) EndPoint->RemoteAddr.Addr));\r
665 } else {\r
666 CopyMem (\r
667 &IkePacket->RemotePeerIp,\r
668 NTOHLLL (&EndPoint->RemoteAddr.v6),\r
669 sizeof (EFI_IPv6_ADDRESS)\r
670 );\r
671 }\r
672 //\r
673 // Try to open udp io for output if hasn't.\r
674 //\r
675 Status = IkeOpenOutputUdp (UdpService, &IkePacket->RemotePeerIp);\r
676\r
677 if (EFI_ERROR (Status)) {\r
678 goto ON_EXIT;\r
679 }\r
680\r
681 IkeHdr = IkePacket->Header;\r
682\r
683 //\r
684 // Determine the IKE exchange instance by the IKE version in IKE header.\r
685 //\r
686 if (IKE_MAJOR_VERSION (IkeHdr->Version) == 2) {\r
687 Exchange = mIkeExchange[IKE_MAJOR_VERSION (IkeHdr->Version) - 1];\r
688 } else {\r
689 goto ON_EXIT;\r
690 }\r
691\r
692 switch (IkeHdr->ExchangeType) {\r
693 case IKE_XCG_TYPE_IDENTITY_PROTECT:\r
694 case IKE_XCG_TYPE_SA_INIT:\r
695 case IKE_XCG_TYPE_AUTH:\r
696 Exchange->HandleSa (UdpService, IkePacket);\r
697 break;\r
698\r
699 case IKE_XCG_TYPE_QM:\r
700 case IKE_XCG_TYPE_CREATE_CHILD_SA:\r
701 Exchange->HandleChildSa (UdpService, IkePacket);\r
702 break;\r
703\r
704 case IKE_XCG_TYPE_INFO:\r
705 case IKE_XCG_TYPE_INFO2:\r
706 Exchange->HandleInfo (UdpService, IkePacket);\r
707 break;\r
708\r
709 default:\r
710 break;\r
711 }\r
712\r
713ON_EXIT:\r
714 if (IkePacket != NULL) {\r
715 IkePacketFree (IkePacket);\r
716 }\r
717\r
718 if (Packet != NULL) {\r
719 NetbufFree (Packet);\r
720 }\r
721\r
722 UdpIoRecvDatagram (UdpService->Input, IkeDispatch, UdpService, 0);\r
723\r
724 return ;\r
725}\r
726\r
727/**\r
728 Delete all established IKE SAs and related Child SAs.\r
6cf9230f 729\r
730 This function is the subfunction of the IpSecCleanupAllSa(). It first calls\r
731 IkeDeleteChildSa() to delete all Child SAs then send out the related\r
9166f840 732 Information packet.\r
733\r
6cf9230f 734 @param[in] Private Pointer of the IPSEC_PRIVATE_DATA\r
4b0f5775 735 @param[in] IsDisableIpsec Indicate whether needs to disable IPsec.\r
9166f840 736\r
737**/\r
738VOID\r
739IkeDeleteAllSas (\r
6cf9230f 740 IN IPSEC_PRIVATE_DATA *Private,\r
741 IN BOOLEAN IsDisableIpsec\r
9166f840 742 )\r
743{\r
744 LIST_ENTRY *Entry;\r
745 LIST_ENTRY *NextEntry;\r
746 IKEV2_SA_SESSION *Ikev2SaSession;\r
747 UINT8 Value;\r
748 EFI_STATUS Status;\r
749 IKE_EXCHANGE_INTERFACE *Exchange;\r
750 UINT8 IkeVersion;\r
751\r
752 Exchange = NULL;\r
753\r
754 //\r
755 // If the IKEv1 is supported, first deal with the Ikev1Estatblished list.\r
756 //\r
757\r
758 //\r
759 // If IKEv2 SAs are under establishing, delete it directly.\r
760 //\r
761 if (!IsListEmpty (&Private->Ikev2SessionList)) {\r
762 NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &Private->Ikev2SessionList) {\r
6cf9230f 763 Ikev2SaSession = IKEV2_SA_SESSION_BY_SESSION (Entry);\r
9166f840 764 RemoveEntryList (Entry);\r
765 Ikev2SaSessionFree (Ikev2SaSession);\r
766 }\r
767 }\r
6cf9230f 768\r
9166f840 769 //\r
770 // If there is no existing established IKE SA, set the Ipsec DisableFlag to TRUE\r
771 // and turn off the IsIPsecDisabling flag.\r
772 //\r
6cf9230f 773 if (IsListEmpty (&Private->Ikev2EstablishedList) && IsDisableIpsec) {\r
9166f840 774 Value = IPSEC_STATUS_DISABLED;\r
775 Status = gRT->SetVariable (\r
776 IPSECCONFIG_STATUS_NAME,\r
777 &gEfiIpSecConfigProtocolGuid,\r
778 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
779 sizeof (Value),\r
780 &Value\r
781 );\r
782 if (!EFI_ERROR (Status)) {\r
783 Private->IpSec.DisabledFlag = TRUE;\r
784 Private->IsIPsecDisabling = FALSE;\r
785 return ;\r
786 }\r
787 }\r
788\r
789 //\r
790 // Delete established IKEv2 SAs.\r
791 //\r
792 if (!IsListEmpty (&Private->Ikev2EstablishedList)) {\r
793 for (Entry = Private->Ikev2EstablishedList.ForwardLink; Entry != &Private->Ikev2EstablishedList;) {\r
794 Ikev2SaSession = IKEV2_SA_SESSION_BY_SESSION (Entry);\r
795 Entry = Entry->ForwardLink;\r
6cf9230f 796\r
9166f840 797 Ikev2SaSession->SessionCommon.State = IkeStateSaDeleting;\r
798\r
799 //\r
800 // Call for Information Exchange.\r
801 //\r
802 IkeVersion = IkeGetVersionFromSession ((UINT8*)Ikev2SaSession);\r
803 if (IkeVersion == 2) {\r
804 Exchange = mIkeExchange[IkeVersion - 1];\r
805 Exchange->NegotiateInfo((UINT8*)Ikev2SaSession, NULL);\r
6cf9230f 806 }\r
9166f840 807 }\r
808 }\r
6cf9230f 809\r
9166f840 810}\r
811\r
812\r
813\r