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