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