]> git.proxmox.com Git - mirror_edk2.git/blame - NetworkPkg/IpSecDxe/IkeService.c
NetworkPkg: comments clean up.
[mirror_edk2.git] / NetworkPkg / IpSecDxe / IkeService.c
CommitLineData
9166f840 1/** @file\r
2 Provide IPsec Key Exchange (IKE) service general interfaces.\r
3 \r
76389e18 4 Copyright (c) 2010 - 2011, 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
39 {0,0,0,0},\r
40 {0,0,0,0},\r
41 IKE_DEFAULT_PORT,\r
42 {0,0,0,0},\r
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
58 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},\r
59 IKE_DEFAULT_PORT,\r
60 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},\r
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
107 \r
108 This fuction is called by the UdpIoCreateIo() to configures a \r
109 UDP4 instance.\r
110 \r
111 @param[in] UdpIo The UDP_IO to be configured.\r
112 @param[in] Context User-defined data when calling UdpIoCreateIo().\r
113 \r
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
149 \r
150 This fuction is called by the UdpIoCreateIo()to configure a \r
151 UDP6 instance.\r
152 \r
153 @param[in] UdpIo The UDP_IO to be configured.\r
154 @param[in] Context User-defined data when calling UdpIoCreateIo().\r
155 \r
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
197 \r
198 If the UdpService is not configured, this fuction calls UdpIoCreatIo() to \r
199 create UDPIO to bind this UdpService for IKE packet sending. If the UdpService\r
200 has already been configured, then return.\r
201 \r
202 @param[in] UdpService The UDP_IO to be configured.\r
203 @param[in] RemoteIp User-defined data when calling UdpIoCreateIo().\r
204 \r
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
215 EFI_STATUS Status;\r
216 EFI_IP4_CONFIG_PROTOCOL *Ip4Cfg;\r
217 EFI_IP4_IPCONFIG_DATA *Ip4CfgData;\r
218 UINTN BufSize;\r
219 EFI_IP6_MODE_DATA Ip6ModeData;\r
220 EFI_UDP6_PROTOCOL *Udp6;\r
221\r
222 Status = EFI_SUCCESS;\r
223 Ip4CfgData = NULL;\r
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
239 &gEfiIp4ConfigProtocolGuid,\r
240 (VOID **) &Ip4Cfg\r
241 );\r
242\r
243 if (EFI_ERROR (Status)) {\r
244 goto ON_EXIT;\r
245 }\r
246\r
247 Status = Ip4Cfg->GetData (Ip4Cfg, &BufSize, NULL);\r
248\r
249 if (EFI_ERROR (Status) && Status != EFI_BUFFER_TOO_SMALL) {\r
250 goto ON_EXIT;\r
251 }\r
252\r
253 Ip4CfgData = AllocateZeroPool (BufSize);\r
254\r
255 if (Ip4CfgData == NULL) {\r
256 Status = EFI_OUT_OF_RESOURCES;\r
257 goto ON_EXIT;\r
258 }\r
259\r
260 Status = Ip4Cfg->GetData (Ip4Cfg, &BufSize, Ip4CfgData);\r
261 if (EFI_ERROR (Status)) {\r
262 goto ON_EXIT;\r
263 }\r
264\r
265 CopyMem (\r
266 &UdpService->DefaultAddress.v4,\r
267 &Ip4CfgData->StationAddress,\r
268 sizeof (EFI_IPv4_ADDRESS)\r
269 );\r
270\r
271 //\r
272 // Create udp4 io for output with local default address.\r
273 //\r
274 UdpService->Output = UdpIoCreateIo (\r
275 UdpService->NicHandle,\r
276 UdpService->ImageHandle,\r
277 IkeConfigUdp4,\r
278 UDP_IO_UDP4_VERSION,\r
279 &UdpService->DefaultAddress\r
280 );\r
281\r
282 if (UdpService->Output == NULL) {\r
283 Status = EFI_OUT_OF_RESOURCES;\r
284 goto ON_EXIT;\r
285 }\r
286\r
287 } else {\r
288 //\r
289 // Create udp6 io for output with remote address.\r
290 //\r
291 UdpService->Output = UdpIoCreateIo (\r
292 UdpService->NicHandle,\r
293 UdpService->ImageHandle,\r
294 IkeConfigUdp6,\r
295 UDP_IO_UDP6_VERSION,\r
296 RemoteIp\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 // Get ip6 mode data to get the result of source address selection.\r
305 //\r
306 ZeroMem (&Ip6ModeData, sizeof (EFI_IP6_MODE_DATA));\r
307\r
308 Udp6 = UdpService->Output->Protocol.Udp6;\r
309 Status = Udp6->GetModeData (Udp6, NULL, &Ip6ModeData, NULL, NULL);\r
310\r
311 if (EFI_ERROR (Status)) {\r
312 UdpIoFreeIo (UdpService->Output);\r
313 goto ON_EXIT;\r
314 }\r
315 //\r
316 // Reconfigure udp6 io without remote address.\r
317 //\r
318 Udp6->Configure (Udp6, NULL);\r
319 Status = IkeConfigUdp6 (UdpService->Output, NULL);\r
320\r
321 //\r
322 // Record the selected source address for ipsec process later.\r
323 //\r
324 CopyMem (\r
325 &UdpService->DefaultAddress.v6,\r
326 &Ip6ModeData.ConfigData.StationAddress,\r
327 sizeof (EFI_IPv6_ADDRESS)\r
328 );\r
329 }\r
330\r
331 UdpService->IsConfigured = TRUE;\r
332\r
333ON_EXIT:\r
334 if (Ip4CfgData != NULL) {\r
335 FreePool (Ip4CfgData);\r
336 }\r
337\r
338 return Status;\r
339}\r
340\r
341/**\r
342 Open and configure a UDPIO of Udp4 for IKE packet receiving.\r
343 \r
344 This function is called at the IPsecDriverBinding start. IPsec create a UDP4 and \r
345 UDP4 IO for each NIC handle.\r
346 \r
347 @param[in] Private Point to IPSEC_PRIVATE_DATA\r
348 @param[in] Controller Handler for NIC card.\r
349 \r
350 @retval EFI_SUCCESS The Operation is successful.\r
351 @retval EFI_OUT_OF_RESOURCE The required system resource can't be allocated.\r
352 \r
353**/\r
354EFI_STATUS\r
355IkeOpenInputUdp4 (\r
356 IN IPSEC_PRIVATE_DATA *Private,\r
357 IN EFI_HANDLE Controller\r
358 )\r
359{\r
360 IKE_UDP_SERVICE *Udp4Srv;\r
361\r
362 //\r
363 // Check whether udp4 io of the controller has already been opened.\r
364 //\r
365 Udp4Srv = IkeLookupUdp (Private, Controller, IP_VERSION_4);\r
366\r
367 if (Udp4Srv != NULL) {\r
368 return EFI_ALREADY_STARTED;\r
369 }\r
370\r
371 Udp4Srv = AllocateZeroPool (sizeof (IKE_UDP_SERVICE));\r
372\r
373 if (Udp4Srv == NULL) {\r
374 return EFI_OUT_OF_RESOURCES;\r
375 }\r
376 //\r
377 // Create udp4 io for iutput.\r
378 //\r
379 Udp4Srv->Input = UdpIoCreateIo (\r
380 Controller,\r
381 Private->ImageHandle,\r
382 IkeConfigUdp4,\r
383 UDP_IO_UDP4_VERSION,\r
384 NULL\r
385 );\r
386\r
387 if (Udp4Srv->Input == NULL) {\r
388 FreePool (Udp4Srv);\r
389 return EFI_OUT_OF_RESOURCES;\r
390 }\r
391\r
392 Udp4Srv->NicHandle = Controller;\r
393 Udp4Srv->ImageHandle = Private->ImageHandle;\r
394 Udp4Srv->ListHead = &(Private->Udp4List);\r
395 Udp4Srv->IpVersion = UDP_IO_UDP4_VERSION;\r
396 Udp4Srv->IsConfigured = FALSE;\r
397\r
398 ZeroMem (&Udp4Srv->DefaultAddress, sizeof (EFI_IP_ADDRESS));\r
399\r
400 //\r
401 // Insert the udp4 io into the list and increase the count.\r
402 //\r
403 InsertTailList (&Private->Udp4List, &Udp4Srv->List);\r
404\r
405 Private->Udp4Num++;\r
406\r
407 UdpIoRecvDatagram (Udp4Srv->Input, IkeDispatch, Udp4Srv, 0);\r
408\r
409 return EFI_SUCCESS;\r
410}\r
411\r
412/**\r
413 Open and configure a UDPIO of Udp6 for IKE packet receiving.\r
414 \r
415 This function is called at the IPsecDriverBinding start. IPsec create a UDP6 and UDP6\r
416 IO for each NIC handle.\r
417 \r
418 @param[in] Private Point to IPSEC_PRIVATE_DATA\r
419 @param[in] Controller Handler for NIC card.\r
420 \r
421 @retval EFI_SUCCESS The Operation is successful.\r
422 @retval EFI_OUT_OF_RESOURCE The required system resource can't be allocated.\r
423 \r
424**/\r
425EFI_STATUS\r
426IkeOpenInputUdp6 (\r
427 IN IPSEC_PRIVATE_DATA *Private,\r
428 IN EFI_HANDLE Controller\r
429 )\r
430{\r
431 IKE_UDP_SERVICE *Udp6Srv;\r
432\r
433 Udp6Srv = IkeLookupUdp (Private, Controller, IP_VERSION_6);\r
434\r
435 if (Udp6Srv != NULL) {\r
436 return EFI_ALREADY_STARTED;\r
437 }\r
438\r
439 Udp6Srv = AllocateZeroPool (sizeof (IKE_UDP_SERVICE));\r
440\r
441 if (Udp6Srv == NULL) {\r
442 return EFI_OUT_OF_RESOURCES;\r
443 }\r
444 //\r
445 // Create udp6 io for input.\r
446 //\r
447 Udp6Srv->Input = UdpIoCreateIo (\r
448 Controller,\r
449 Private->ImageHandle,\r
450 IkeConfigUdp6,\r
451 UDP_IO_UDP6_VERSION,\r
452 NULL\r
453 );\r
454\r
455 if (Udp6Srv->Input == NULL) {\r
456 FreePool (Udp6Srv);\r
457 return EFI_OUT_OF_RESOURCES;\r
458 }\r
459\r
460 Udp6Srv->NicHandle = Controller;\r
461 Udp6Srv->ImageHandle = Private->ImageHandle;\r
462 Udp6Srv->ListHead = &(Private->Udp6List);\r
463 Udp6Srv->IpVersion = UDP_IO_UDP6_VERSION;\r
464 Udp6Srv->IsConfigured = FALSE;\r
465\r
466 ZeroMem (&Udp6Srv->DefaultAddress, sizeof (EFI_IP_ADDRESS));\r
467\r
468 //\r
469 // Insert the udp6 io into the list and increase the count.\r
470 //\r
471 InsertTailList (&Private->Udp6List, &Udp6Srv->List);\r
472\r
473 Private->Udp6Num++;\r
474\r
475 UdpIoRecvDatagram (Udp6Srv->Input, IkeDispatch, Udp6Srv, 0);\r
476\r
477 return EFI_SUCCESS;\r
478}\r
479\r
480/**\r
481 The general interface of starting IPsec Key Exchange.\r
482 \r
483 This function is called when a IKE negotiation to start getting a Key.\r
484 \r
485 @param[in] UdpService Point to IKE_UDP_SERVICE which will be used for \r
486 IKE packet sending.\r
487 @param[in] SpdEntry Point to the SPD entry related to the IKE negotiation.\r
488 @param[in] RemoteIp Point to EFI_IP_ADDRESS related to the IKE negotiation.\r
489 \r
490 @retval EFI_SUCCESS The Operation is successful.\r
491 @retval EFI_ACCESS_DENIED No related PAD entry was found.\r
492 @retval EFI_INVALID_PARAMETER The IKE version is not supported.\r
493 \r
494**/\r
495EFI_STATUS\r
496IkeNegotiate (\r
497 IN IKE_UDP_SERVICE *UdpService,\r
498 IN IPSEC_SPD_ENTRY *SpdEntry,\r
499 IN EFI_IP_ADDRESS *RemoteIp\r
500 )\r
501{\r
502 EFI_STATUS Status;\r
503 UINT8 *IkeSaSession;\r
504 IKE_EXCHANGE_INTERFACE *Exchange;\r
505 IPSEC_PRIVATE_DATA *Private;\r
506 IPSEC_PAD_ENTRY *PadEntry;\r
507 UINT8 IkeVersion;\r
508\r
509 Private = (UdpService->IpVersion == IP_VERSION_4) ?\r
510 IPSEC_PRIVATE_DATA_FROM_UDP4LIST(UdpService->ListHead) :\r
511 IPSEC_PRIVATE_DATA_FROM_UDP6LIST(UdpService->ListHead);\r
512\r
513 //\r
514 // Try to open udp io for output if it hasn't.\r
515 //\r
516 Status = IkeOpenOutputUdp (UdpService, RemoteIp);\r
517 if (EFI_ERROR (Status)) {\r
518 return Status;\r
519 }\r
520 //\r
521 // Try to find the IKE SA session in the IKEv1 and IKEv2 established SA session list.\r
522 // \r
523 IkeSaSession = (UINT8 *) Ikev2SaSessionLookup (&Private->Ikev2EstablishedList, RemoteIp); \r
524\r
525\r
526 if (IkeSaSession == NULL) {\r
527 //\r
528 // Find the pad entry by the remote ip address.\r
529 //\r
530 PadEntry = IpSecLookupPadEntry (UdpService->IpVersion, RemoteIp);\r
531 if (PadEntry == NULL) {\r
532 return EFI_ACCESS_DENIED;\r
533 }\r
534 //\r
535 // Determine the IKE exchange instance by the auth protocol in pad entry.\r
536 //\r
537 ASSERT (PadEntry->Data->AuthProtocol < EfiIPsecAuthProtocolMaximum);\r
538 if (PadEntry->Data->AuthProtocol == EfiIPsecAuthProtocolIKEv1) {\r
539 return EFI_INVALID_PARAMETER;\r
540 }\r
541 Exchange = mIkeExchange[PadEntry->Data->AuthProtocol];\r
542 //\r
543 // Start the main mode stage to negotiate IKE SA.\r
544 //\r
545 Status = Exchange->NegotiateSa (UdpService, SpdEntry, PadEntry, RemoteIp);\r
546 } else {\r
547 //\r
548 // Determine the IKE exchange instance by the IKE version in IKE SA session.\r
549 //\r
550 IkeVersion = IkeGetVersionFromSession (IkeSaSession);\r
551 if (IkeVersion != 2) {\r
552 return EFI_INVALID_PARAMETER;\r
553 }\r
554 \r
555 Exchange = mIkeExchange[IkeVersion - 1];\r
556 //\r
557 // Start the quick mode stage to negotiate child SA.\r
558 //\r
559 Status = Exchange->NegotiateChildSa (IkeSaSession, SpdEntry, NULL);\r
560 }\r
561\r
562 return Status;\r
563}\r
564\r
565/**\r
566 The generic interface when receive a IKE packet.\r
567 \r
568 This function is called when UDP IO receives a IKE packet.\r
569 \r
570 @param[in] Packet Point to received IKE packet.\r
571 @param[in] EndPoint Point to UDP_END_POINT which contains the information of \r
572 Remote IP and Port.\r
573 @param[in] IoStatus The Status of Recieve Token.\r
574 @param[in] Context Point to data passed from the caller.\r
575 \r
576**/\r
577VOID\r
1d8fa5e9 578EFIAPI\r
9166f840 579IkeDispatch (\r
580 IN NET_BUF *Packet,\r
581 IN UDP_END_POINT *EndPoint,\r
582 IN EFI_STATUS IoStatus,\r
583 IN VOID *Context\r
584 )\r
585{\r
586 IPSEC_PRIVATE_DATA *Private;\r
587 IKE_PACKET *IkePacket;\r
588 IKE_HEADER *IkeHdr;\r
589 IKE_UDP_SERVICE *UdpService;\r
590 IKE_EXCHANGE_INTERFACE *Exchange;\r
591 EFI_STATUS Status;\r
592\r
593 UdpService = (IKE_UDP_SERVICE *) Context;\r
594 IkePacket = NULL;\r
595 Private = (UdpService->IpVersion == IP_VERSION_4) ?\r
596 IPSEC_PRIVATE_DATA_FROM_UDP4LIST(UdpService->ListHead) :\r
597 IPSEC_PRIVATE_DATA_FROM_UDP6LIST(UdpService->ListHead);\r
598\r
599 if (EFI_ERROR (IoStatus)) {\r
600 goto ON_EXIT;\r
601 }\r
602 //\r
603 // Check whether the ipsec is enabled or not.\r
604 //\r
605 if (Private->IpSec.DisabledFlag == TRUE) {\r
606 goto ON_EXIT;\r
607 }\r
608\r
609 if (EndPoint->RemotePort != IKE_DEFAULT_PORT) {\r
610 goto ON_EXIT;\r
611 }\r
612\r
613 //\r
614 // Build IKE packet from the received netbuf.\r
615 //\r
616 IkePacket = IkePacketFromNetbuf (Packet);\r
617\r
618 if (IkePacket == NULL) {\r
619 goto ON_EXIT;\r
620 }\r
621 //\r
622 // Get the remote address from the IKE packet.\r
623 //\r
624 if (UdpService->IpVersion == IP_VERSION_4) {\r
625 *(UINT32 *) IkePacket->RemotePeerIp.Addr = HTONL ((*(UINT32 *) EndPoint->RemoteAddr.Addr));\r
626 } else {\r
627 CopyMem (\r
628 &IkePacket->RemotePeerIp,\r
629 NTOHLLL (&EndPoint->RemoteAddr.v6),\r
630 sizeof (EFI_IPv6_ADDRESS)\r
631 );\r
632 }\r
633 //\r
634 // Try to open udp io for output if hasn't.\r
635 //\r
636 Status = IkeOpenOutputUdp (UdpService, &IkePacket->RemotePeerIp);\r
637\r
638 if (EFI_ERROR (Status)) {\r
639 goto ON_EXIT;\r
640 }\r
641\r
642 IkeHdr = IkePacket->Header;\r
643\r
644 //\r
645 // Determine the IKE exchange instance by the IKE version in IKE header.\r
646 //\r
647 if (IKE_MAJOR_VERSION (IkeHdr->Version) == 2) {\r
648 Exchange = mIkeExchange[IKE_MAJOR_VERSION (IkeHdr->Version) - 1];\r
649 } else {\r
650 goto ON_EXIT;\r
651 }\r
652\r
653 switch (IkeHdr->ExchangeType) {\r
654 case IKE_XCG_TYPE_IDENTITY_PROTECT:\r
655 case IKE_XCG_TYPE_SA_INIT:\r
656 case IKE_XCG_TYPE_AUTH:\r
657 Exchange->HandleSa (UdpService, IkePacket);\r
658 break;\r
659\r
660 case IKE_XCG_TYPE_QM:\r
661 case IKE_XCG_TYPE_CREATE_CHILD_SA:\r
662 Exchange->HandleChildSa (UdpService, IkePacket);\r
663 break;\r
664\r
665 case IKE_XCG_TYPE_INFO:\r
666 case IKE_XCG_TYPE_INFO2:\r
667 Exchange->HandleInfo (UdpService, IkePacket);\r
668 break;\r
669\r
670 default:\r
671 break;\r
672 }\r
673\r
674ON_EXIT:\r
675 if (IkePacket != NULL) {\r
676 IkePacketFree (IkePacket);\r
677 }\r
678\r
679 if (Packet != NULL) {\r
680 NetbufFree (Packet);\r
681 }\r
682\r
683 UdpIoRecvDatagram (UdpService->Input, IkeDispatch, UdpService, 0);\r
684\r
685 return ;\r
686}\r
687\r
688/**\r
689 Delete all established IKE SAs and related Child SAs.\r
690 \r
691 This function is the subfunction of the IpSecCleanupAllSa(). It first calls \r
692 IkeDeleteChildSa() to delete all Child SAs then send out the related \r
693 Information packet.\r
694\r
695 @param[in] Private Pointer of the IPSEC_PRIVATE_DATA\r
696\r
697**/\r
698VOID\r
699IkeDeleteAllSas (\r
700 IN IPSEC_PRIVATE_DATA *Private\r
701 )\r
702{\r
703 LIST_ENTRY *Entry;\r
704 LIST_ENTRY *NextEntry;\r
705 IKEV2_SA_SESSION *Ikev2SaSession;\r
706 UINT8 Value;\r
707 EFI_STATUS Status;\r
708 IKE_EXCHANGE_INTERFACE *Exchange;\r
709 UINT8 IkeVersion;\r
710\r
711 Exchange = NULL;\r
712\r
713 //\r
714 // If the IKEv1 is supported, first deal with the Ikev1Estatblished list.\r
715 //\r
716\r
717 //\r
718 // If IKEv2 SAs are under establishing, delete it directly.\r
719 //\r
720 if (!IsListEmpty (&Private->Ikev2SessionList)) {\r
721 NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &Private->Ikev2SessionList) {\r
722 Ikev2SaSession = IKEV2_SA_SESSION_BY_SESSION (Entry); \r
723 RemoveEntryList (Entry);\r
724 Ikev2SaSessionFree (Ikev2SaSession);\r
725 }\r
726 }\r
727 \r
728 //\r
729 // If there is no existing established IKE SA, set the Ipsec DisableFlag to TRUE\r
730 // and turn off the IsIPsecDisabling flag.\r
731 //\r
732 if (IsListEmpty (&Private->Ikev2EstablishedList)) {\r
733 Value = IPSEC_STATUS_DISABLED;\r
734 Status = gRT->SetVariable (\r
735 IPSECCONFIG_STATUS_NAME,\r
736 &gEfiIpSecConfigProtocolGuid,\r
737 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
738 sizeof (Value),\r
739 &Value\r
740 );\r
741 if (!EFI_ERROR (Status)) {\r
742 Private->IpSec.DisabledFlag = TRUE;\r
743 Private->IsIPsecDisabling = FALSE;\r
744 return ;\r
745 }\r
746 }\r
747\r
748 //\r
749 // Delete established IKEv2 SAs.\r
750 //\r
751 if (!IsListEmpty (&Private->Ikev2EstablishedList)) {\r
752 for (Entry = Private->Ikev2EstablishedList.ForwardLink; Entry != &Private->Ikev2EstablishedList;) {\r
753 Ikev2SaSession = IKEV2_SA_SESSION_BY_SESSION (Entry);\r
754 Entry = Entry->ForwardLink;\r
755 \r
756 Ikev2SaSession->SessionCommon.State = IkeStateSaDeleting;\r
757\r
758 //\r
759 // Call for Information Exchange.\r
760 //\r
761 IkeVersion = IkeGetVersionFromSession ((UINT8*)Ikev2SaSession);\r
762 if (IkeVersion == 2) {\r
763 Exchange = mIkeExchange[IkeVersion - 1];\r
764 Exchange->NegotiateInfo((UINT8*)Ikev2SaSession, NULL);\r
765 } \r
766 }\r
767 }\r
768 \r
769}\r
770\r
771\r
772\r