]> git.proxmox.com Git - mirror_edk2.git/blame - NetworkPkg/IpSecDxe/IpSecConfigImpl.c
NetworkPkg: Refine casting expression result to bigger size
[mirror_edk2.git] / NetworkPkg / IpSecDxe / IpSecConfigImpl.c
CommitLineData
a3bcde70
HT
1/** @file\r
2 The implementation of IPSEC_CONFIG_PROTOCOL.\r
3\r
ce5c3273 4 Copyright (c) 2009 - 2017, Intel Corporation. All rights reserved.<BR>\r
a3bcde70
HT
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 "IpSecConfigImpl.h"\r
17#include "IpSecDebug.h"\r
18\r
19LIST_ENTRY mConfigData[IPsecConfigDataTypeMaximum];\r
20BOOLEAN mSetBySelf = FALSE;\r
21\r
22//\r
9166f840 23// Common CompareSelector routine entry for SPD/SAD/PAD.\r
a3bcde70
HT
24//\r
25IPSEC_COMPARE_SELECTOR mCompareSelector[] = {\r
26 (IPSEC_COMPARE_SELECTOR) CompareSpdSelector,\r
27 (IPSEC_COMPARE_SELECTOR) CompareSaId,\r
28 (IPSEC_COMPARE_SELECTOR) ComparePadId\r
29};\r
30\r
31//\r
9166f840 32// Common IsZeroSelector routine entry for SPD/SAD/PAD.\r
a3bcde70
HT
33//\r
34IPSEC_IS_ZERO_SELECTOR mIsZeroSelector[] = {\r
35 (IPSEC_IS_ZERO_SELECTOR) IsZeroSpdSelector,\r
36 (IPSEC_IS_ZERO_SELECTOR) IsZeroSaId,\r
37 (IPSEC_IS_ZERO_SELECTOR) IsZeroPadId\r
38};\r
39\r
40//\r
9166f840 41// Common DuplicateSelector routine entry for SPD/SAD/PAD.\r
a3bcde70
HT
42//\r
43IPSEC_DUPLICATE_SELECTOR mDuplicateSelector[] = {\r
44 (IPSEC_DUPLICATE_SELECTOR) DuplicateSpdSelector,\r
45 (IPSEC_DUPLICATE_SELECTOR) DuplicateSaId,\r
46 (IPSEC_DUPLICATE_SELECTOR) DuplicatePadId\r
47};\r
48\r
49//\r
9166f840 50// Common FixPolicyEntry routine entry for SPD/SAD/PAD.\r
a3bcde70
HT
51//\r
52IPSEC_FIX_POLICY_ENTRY mFixPolicyEntry[] = {\r
53 (IPSEC_FIX_POLICY_ENTRY) FixSpdEntry,\r
54 (IPSEC_FIX_POLICY_ENTRY) FixSadEntry,\r
55 (IPSEC_FIX_POLICY_ENTRY) FixPadEntry\r
56};\r
57\r
58//\r
9166f840 59// Common UnfixPolicyEntry routine entry for SPD/SAD/PAD.\r
a3bcde70
HT
60//\r
61IPSEC_FIX_POLICY_ENTRY mUnfixPolicyEntry[] = {\r
62 (IPSEC_FIX_POLICY_ENTRY) UnfixSpdEntry,\r
63 (IPSEC_FIX_POLICY_ENTRY) UnfixSadEntry,\r
64 (IPSEC_FIX_POLICY_ENTRY) UnfixPadEntry\r
65};\r
66\r
67//\r
9166f840 68// Common SetPolicyEntry routine entry for SPD/SAD/PAD.\r
a3bcde70
HT
69//\r
70IPSEC_SET_POLICY_ENTRY mSetPolicyEntry[] = {\r
71 (IPSEC_SET_POLICY_ENTRY) SetSpdEntry,\r
72 (IPSEC_SET_POLICY_ENTRY) SetSadEntry,\r
73 (IPSEC_SET_POLICY_ENTRY) SetPadEntry\r
74};\r
75\r
76//\r
9166f840 77// Common GetPolicyEntry routine entry for SPD/SAD/PAD.\r
a3bcde70
HT
78//\r
79IPSEC_GET_POLICY_ENTRY mGetPolicyEntry[] = {\r
80 (IPSEC_GET_POLICY_ENTRY) GetSpdEntry,\r
81 (IPSEC_GET_POLICY_ENTRY) GetSadEntry,\r
82 (IPSEC_GET_POLICY_ENTRY) GetPadEntry\r
83};\r
84\r
85//\r
86// Routine entry for IpSecConfig protocol.\r
87//\r
88EFI_IPSEC_CONFIG_PROTOCOL mIpSecConfigInstance = {\r
89 EfiIpSecConfigSetData,\r
90 EfiIpSecConfigGetData,\r
91 EfiIpSecConfigGetNextSelector,\r
92 EfiIpSecConfigRegisterNotify,\r
93 EfiIpSecConfigUnregisterNotify\r
94};\r
95\r
96/**\r
97 Get the all IPSec configuration variables and store those variables\r
98 to the internal data structure.\r
99\r
9166f840 100 This founction is called by IpSecConfigInitialize() that is to intialize the \r
a3bcde70
HT
101 IPsecConfiguration Protocol.\r
102\r
103 @param[in] Private Point to IPSEC_PRIVATE_DATA.\r
104\r
105 @retval EFI_OUT_OF_RESOURCES The required system resource could not be allocated.\r
106 @retval EFI_SUCCESS Restore the IPsec Configuration successfully.\r
107 @retval others Other errors is found during the variable getting.\r
108\r
109**/\r
110EFI_STATUS\r
111IpSecConfigRestore (\r
112 IN IPSEC_PRIVATE_DATA *Private\r
113 );\r
114\r
115/**\r
116 Check if the specified EFI_IP_ADDRESS_INFO is in EFI_IP_ADDRESS_INFO list.\r
117\r
118 @param[in] AddressInfo Pointer of IP_ADDRESS_INFO to be search in AddressInfo list.\r
119 @param[in] AddressInfoList A list that contains IP_ADDRESS_INFOs.\r
120 @param[in] AddressCount Point out how many IP_ADDRESS_INFO in the list.\r
121\r
122 @retval TRUE The specified AddressInfo is in the AddressInfoList.\r
123 @retval FALSE The specified AddressInfo is not in the AddressInfoList.\r
9166f840 124 \r
a3bcde70
HT
125**/\r
126BOOLEAN\r
127IsInAddressInfoList(\r
128 IN EFI_IP_ADDRESS_INFO *AddressInfo,\r
129 IN EFI_IP_ADDRESS_INFO *AddressInfoList,\r
130 IN UINT32 AddressCount\r
131 )\r
132{\r
9166f840 133 UINT8 Index;\r
134 EFI_IP_ADDRESS ZeroAddress;\r
135\r
136 ZeroMem(&ZeroAddress, sizeof (EFI_IP_ADDRESS));\r
a3bcde70 137\r
9166f840 138 //\r
139 // Zero Address means any address is matched.\r
140 //\r
141 if (AddressCount == 1) {\r
142 if (CompareMem (\r
143 &AddressInfoList[0].Address,\r
144 &ZeroAddress,\r
145 sizeof (EFI_IP_ADDRESS)\r
146 ) == 0) {\r
147 return TRUE;\r
148 }\r
149 }\r
a3bcde70
HT
150 for (Index = 0; Index < AddressCount ; Index++) {\r
151 if (CompareMem (\r
152 AddressInfo,\r
153 &AddressInfoList[Index].Address,\r
154 sizeof (EFI_IP_ADDRESS)\r
9166f840 155 ) == 0 && \r
a3bcde70 156 AddressInfo->PrefixLength == AddressInfoList[Index].PrefixLength\r
9166f840 157 ) { \r
a3bcde70
HT
158 return TRUE;\r
159 }\r
160 }\r
161 return FALSE;\r
162}\r
9166f840 163 \r
a3bcde70
HT
164/**\r
165 Compare two SPD Selectors.\r
166\r
167 Compare two SPD Selector by the fields of LocalAddressCount/RemoteAddressCount/\r
9166f840 168 NextLayerProtocol/LocalPort/LocalPortRange/RemotePort/RemotePortRange and the \r
a3bcde70
HT
169 Local Addresses and remote Addresses.\r
170\r
171 @param[in] Selector1 Pointer of first SPD Selector.\r
172 @param[in] Selector2 Pointer of second SPD Selector.\r
173\r
174 @retval TRUE This two Selector have the same value in above fields.\r
175 @retval FALSE Not all above fields have the same value in these two Selectors.\r
9166f840 176 \r
a3bcde70
HT
177**/\r
178BOOLEAN\r
179CompareSpdSelector (\r
180 IN EFI_IPSEC_CONFIG_SELECTOR *Selector1,\r
181 IN EFI_IPSEC_CONFIG_SELECTOR *Selector2\r
182 )\r
183{\r
184 EFI_IPSEC_SPD_SELECTOR *SpdSel1;\r
185 EFI_IPSEC_SPD_SELECTOR *SpdSel2;\r
186 BOOLEAN IsMatch;\r
187 UINTN Index;\r
188\r
189 SpdSel1 = &Selector1->SpdSelector;\r
190 SpdSel2 = &Selector2->SpdSelector;\r
191 IsMatch = TRUE;\r
192\r
193 //\r
194 // Compare the LocalAddressCount/RemoteAddressCount/NextLayerProtocol/\r
195 // LocalPort/LocalPortRange/RemotePort/RemotePortRange fields in the\r
9166f840 196 // two Spdselectors. Since the SPD supports two directions, it needs to \r
a3bcde70
HT
197 // compare two directions.\r
198 //\r
199 if ((SpdSel1->LocalAddressCount != SpdSel2->LocalAddressCount &&\r
200 SpdSel1->LocalAddressCount != SpdSel2->RemoteAddressCount) ||\r
201 (SpdSel1->RemoteAddressCount != SpdSel2->RemoteAddressCount &&\r
202 SpdSel1->RemoteAddressCount != SpdSel2->LocalAddressCount) ||\r
203 SpdSel1->NextLayerProtocol != SpdSel2->NextLayerProtocol ||\r
204 SpdSel1->LocalPort != SpdSel2->LocalPort ||\r
205 SpdSel1->LocalPortRange != SpdSel2->LocalPortRange ||\r
206 SpdSel1->RemotePort != SpdSel2->RemotePort ||\r
207 SpdSel1->RemotePortRange != SpdSel2->RemotePortRange\r
208 ) {\r
209 IsMatch = FALSE;\r
210 return IsMatch;\r
211 }\r
9166f840 212 \r
a3bcde70 213 //\r
4991eeff 214 // Compare the all LocalAddress and RemoteAddress fields in the two Spdselectors.\r
9166f840 215 // First, SpdSel1->LocalAddress to SpdSel2->LocalAddress && Compare \r
a3bcde70
HT
216 // SpdSel1->RemoteAddress to SpdSel2->RemoteAddress. If all match, return\r
217 // TRUE.\r
218 //\r
219 for (Index = 0; Index < SpdSel1->LocalAddressCount; Index++) {\r
220 if (!IsInAddressInfoList (\r
221 &SpdSel1->LocalAddress[Index],\r
222 SpdSel2->LocalAddress,\r
223 SpdSel2->LocalAddressCount\r
224 )) {\r
225 IsMatch = FALSE;\r
226 break;\r
227 }\r
228 }\r
229 if (IsMatch) {\r
230 for (Index = 0; Index < SpdSel2->LocalAddressCount; Index++) {\r
231 if (!IsInAddressInfoList (\r
232 &SpdSel2->LocalAddress[Index],\r
233 SpdSel1->LocalAddress,\r
234 SpdSel1->LocalAddressCount\r
235 )) {\r
236 IsMatch = FALSE;\r
237 break;\r
238 }\r
239 }\r
240 }\r
241 if (IsMatch) {\r
242 for (Index = 0; Index < SpdSel1->RemoteAddressCount; Index++) {\r
243 if (!IsInAddressInfoList (\r
244 &SpdSel1->RemoteAddress[Index],\r
245 SpdSel2->RemoteAddress,\r
246 SpdSel2->RemoteAddressCount\r
247 )) {\r
248 IsMatch = FALSE;\r
249 break;\r
250 }\r
251 }\r
252 }\r
253 if (IsMatch) {\r
254 for (Index = 0; Index < SpdSel2->RemoteAddressCount; Index++) {\r
255 if (!IsInAddressInfoList (\r
256 &SpdSel2->RemoteAddress[Index],\r
257 SpdSel1->RemoteAddress,\r
258 SpdSel1->RemoteAddressCount\r
259 )) {\r
260 IsMatch = FALSE;\r
261 break;\r
262 }\r
263 }\r
264 }\r
265 //\r
9166f840 266 // Finish the one direction compare. If it is matched, return; otherwise, \r
a3bcde70
HT
267 // compare the other direction.\r
268 //\r
269 if (IsMatch) {\r
270 return IsMatch;\r
271 }\r
272 //\r
9166f840 273 // Secondly, the SpdSel1->LocalAddress doesn't equal to SpdSel2->LocalAddress and \r
a3bcde70
HT
274 // SpdSel1->RemoteAddress doesn't equal to SpdSel2->RemoteAddress. Try to compare\r
275 // the RemoteAddress to LocalAddress.\r
276 //\r
277 IsMatch = TRUE;\r
278 for (Index = 0; Index < SpdSel1->RemoteAddressCount; Index++) {\r
279 if (!IsInAddressInfoList (\r
280 &SpdSel1->RemoteAddress[Index],\r
281 SpdSel2->LocalAddress,\r
282 SpdSel2->LocalAddressCount\r
283 )) {\r
284 IsMatch = FALSE;\r
285 break;\r
286 }\r
287 }\r
288 if (IsMatch) {\r
289 for (Index = 0; Index < SpdSel2->RemoteAddressCount; Index++) {\r
290 if (!IsInAddressInfoList (\r
291 &SpdSel2->RemoteAddress[Index],\r
292 SpdSel1->LocalAddress,\r
293 SpdSel1->LocalAddressCount\r
294 )) {\r
295 IsMatch = FALSE;\r
296 break;\r
297 }\r
298 }\r
299 }\r
300 if (IsMatch) {\r
301 for (Index = 0; Index < SpdSel1->LocalAddressCount; Index++) {\r
302 if (!IsInAddressInfoList (\r
303 &SpdSel1->LocalAddress[Index],\r
304 SpdSel2->RemoteAddress,\r
305 SpdSel2->RemoteAddressCount\r
306 )) {\r
307 IsMatch = FALSE;\r
308 break;\r
309 }\r
310 }\r
311 }\r
312 if (IsMatch) {\r
313 for (Index = 0; Index < SpdSel2->LocalAddressCount; Index++) {\r
314 if (!IsInAddressInfoList (\r
315 &SpdSel2->LocalAddress[Index],\r
316 SpdSel1->RemoteAddress,\r
317 SpdSel1->RemoteAddressCount\r
318 )) {\r
319 IsMatch = FALSE;\r
320 break;\r
321 }\r
322 }\r
323 }\r
324 return IsMatch;\r
325}\r
326\r
9166f840 327/**\r
328 Find if the two SPD Selectors has subordinative.\r
329\r
330 Compare two SPD Selector by the fields of LocalAddressCount/RemoteAddressCount/\r
331 NextLayerProtocol/LocalPort/LocalPortRange/RemotePort/RemotePortRange and the \r
332 Local Addresses and remote Addresses.\r
333\r
334 @param[in] Selector1 Pointer of first SPD Selector.\r
335 @param[in] Selector2 Pointer of second SPD Selector.\r
336\r
337 @retval TRUE The first SPD Selector is subordinate Selector of second SPD Selector.\r
338 @retval FALSE The first SPD Selector is not subordinate Selector of second \r
339 SPD Selector.\r
340 \r
341**/\r
342BOOLEAN\r
343IsSubSpdSelector (\r
344 IN EFI_IPSEC_CONFIG_SELECTOR *Selector1,\r
345 IN EFI_IPSEC_CONFIG_SELECTOR *Selector2\r
346 )\r
347{\r
348 EFI_IPSEC_SPD_SELECTOR *SpdSel1;\r
349 EFI_IPSEC_SPD_SELECTOR *SpdSel2;\r
350 BOOLEAN IsMatch;\r
351 UINTN Index;\r
352\r
353 SpdSel1 = &Selector1->SpdSelector;\r
354 SpdSel2 = &Selector2->SpdSelector;\r
355 IsMatch = TRUE;\r
356\r
357 //\r
358 // Compare the LocalAddressCount/RemoteAddressCount/NextLayerProtocol/\r
359 // LocalPort/LocalPortRange/RemotePort/RemotePortRange fields in the\r
360 // two Spdselectors. Since the SPD supports two directions, it needs to \r
361 // compare two directions.\r
362 //\r
363 if (SpdSel1->LocalAddressCount > SpdSel2->LocalAddressCount ||\r
364 SpdSel1->RemoteAddressCount > SpdSel2->RemoteAddressCount ||\r
365 (SpdSel1->NextLayerProtocol != SpdSel2->NextLayerProtocol && SpdSel2->NextLayerProtocol != 0xffff) ||\r
366 (SpdSel1->LocalPort > SpdSel2->LocalPort && SpdSel2->LocalPort != 0)||\r
367 (SpdSel1->LocalPortRange > SpdSel2->LocalPortRange && SpdSel1->LocalPort != 0)||\r
368 (SpdSel1->RemotePort > SpdSel2->RemotePort && SpdSel2->RemotePort != 0) ||\r
369 (SpdSel1->RemotePortRange > SpdSel2->RemotePortRange && SpdSel2->RemotePort != 0)\r
370 ) {\r
371 IsMatch = FALSE;\r
372 }\r
373 \r
374 //\r
4991eeff 375 // Compare the all LocalAddress and RemoteAddress fields in the two Spdselectors.\r
9166f840 376 // First, SpdSel1->LocalAddress to SpdSel2->LocalAddress && Compare \r
377 // SpdSel1->RemoteAddress to SpdSel2->RemoteAddress. If all match, return\r
378 // TRUE.\r
379 //\r
380 if (IsMatch) {\r
381 for (Index = 0; Index < SpdSel1->LocalAddressCount; Index++) {\r
382 if (!IsInAddressInfoList (\r
383 &SpdSel1->LocalAddress[Index],\r
384 SpdSel2->LocalAddress,\r
385 SpdSel2->LocalAddressCount\r
386 )) {\r
387 IsMatch = FALSE;\r
388 break;\r
389 }\r
390 }\r
391\r
392 if (IsMatch) {\r
393 for (Index = 0; Index < SpdSel1->RemoteAddressCount; Index++) {\r
394 if (!IsInAddressInfoList (\r
395 &SpdSel1->RemoteAddress[Index],\r
396 SpdSel2->RemoteAddress,\r
397 SpdSel2->RemoteAddressCount\r
398 )) {\r
399 IsMatch = FALSE;\r
400 break;\r
401 }\r
402 }\r
403 }\r
404 }\r
405 if (IsMatch) {\r
406 return IsMatch;\r
407 }\r
408 \r
409 //\r
410 //\r
411 // The SPD selector in SPD entry is two way.\r
412 //\r
413 // Compare the LocalAddressCount/RemoteAddressCount/NextLayerProtocol/\r
414 // LocalPort/LocalPortRange/RemotePort/RemotePortRange fields in the\r
415 // two Spdselectors. Since the SPD supports two directions, it needs to \r
416 // compare two directions.\r
417 //\r
418 IsMatch = TRUE;\r
419 if (SpdSel1->LocalAddressCount > SpdSel2->RemoteAddressCount ||\r
420 SpdSel1->RemoteAddressCount > SpdSel2->LocalAddressCount ||\r
421 (SpdSel1->NextLayerProtocol != SpdSel2->NextLayerProtocol && SpdSel2->NextLayerProtocol != 0xffff) ||\r
422 (SpdSel1->LocalPort > SpdSel2->RemotePort && SpdSel2->RemotePort != 0)||\r
423 (SpdSel1->LocalPortRange > SpdSel2->RemotePortRange && SpdSel1->RemotePort != 0)||\r
424 (SpdSel1->RemotePort > SpdSel2->LocalPort && SpdSel2->LocalPort != 0) ||\r
425 (SpdSel1->RemotePortRange > SpdSel2->LocalPortRange && SpdSel2->LocalPort != 0)\r
426 ) {\r
427 IsMatch = FALSE;\r
428 return IsMatch;\r
429 }\r
430 \r
431 //\r
4991eeff
JW
432 // Compare the all LocalAddress and RemoteAddress fields in the two Spdselectors.\r
433 // First, SpdSel1->LocalAddress to SpdSel2->RemoteAddress && Compare \r
434 // SpdSel1->RemoteAddress to SpdSel2->LocalAddress. If all match, return\r
9166f840 435 // TRUE.\r
436 //\r
437 for (Index = 0; Index < SpdSel1->LocalAddressCount; Index++) {\r
438 if (!IsInAddressInfoList (\r
439 &SpdSel1->LocalAddress[Index],\r
440 SpdSel2->RemoteAddress,\r
441 SpdSel2->RemoteAddressCount\r
442 )) {\r
443 IsMatch = FALSE;\r
444 break;\r
445 }\r
446 }\r
447\r
448 if (IsMatch) {\r
449 for (Index = 0; Index < SpdSel1->RemoteAddressCount; Index++) {\r
450 if (!IsInAddressInfoList (\r
451 &SpdSel1->RemoteAddress[Index],\r
452 SpdSel2->LocalAddress,\r
453 SpdSel2->LocalAddressCount\r
454 )) {\r
455 IsMatch = FALSE;\r
456 break;\r
457 }\r
458 }\r
459 }\r
460 return IsMatch;\r
461 \r
462}\r
463\r
a3bcde70
HT
464/**\r
465 Compare two SA IDs.\r
466\r
467 @param[in] Selector1 Pointer of first SA ID.\r
468 @param[in] Selector2 Pointer of second SA ID.\r
469\r
470 @retval TRUE This two Selectors have the same SA ID.\r
471 @retval FALSE This two Selecotrs don't have the same SA ID.\r
9166f840 472 \r
a3bcde70
HT
473**/\r
474BOOLEAN\r
475CompareSaId (\r
476 IN EFI_IPSEC_CONFIG_SELECTOR *Selector1,\r
477 IN EFI_IPSEC_CONFIG_SELECTOR *Selector2\r
478 )\r
479{\r
480 EFI_IPSEC_SA_ID *SaId1;\r
481 EFI_IPSEC_SA_ID *SaId2;\r
482 BOOLEAN IsMatch;\r
483\r
484 SaId1 = &Selector1->SaId;\r
485 SaId2 = &Selector2->SaId;\r
486 IsMatch = TRUE;\r
487\r
488 if (CompareMem (SaId1, SaId2, sizeof (EFI_IPSEC_SA_ID)) != 0) {\r
489 IsMatch = FALSE;\r
490 }\r
491\r
492 return IsMatch;\r
493}\r
494\r
495/**\r
496 Compare two PAD IDs.\r
497\r
498 @param[in] Selector1 Pointer of first PAD ID.\r
499 @param[in] Selector2 Pointer of second PAD ID.\r
500\r
501 @retval TRUE This two Selectors have the same PAD ID.\r
502 @retval FALSE This two Selecotrs don't have the same PAD ID.\r
9166f840 503 \r
a3bcde70
HT
504**/\r
505BOOLEAN\r
506ComparePadId (\r
507 IN EFI_IPSEC_CONFIG_SELECTOR *Selector1,\r
508 IN EFI_IPSEC_CONFIG_SELECTOR *Selector2\r
509 )\r
510{\r
511 EFI_IPSEC_PAD_ID *PadId1;\r
512 EFI_IPSEC_PAD_ID *PadId2;\r
513 BOOLEAN IsMatch;\r
514\r
515 PadId1 = &Selector1->PadId;\r
516 PadId2 = &Selector2->PadId;\r
517 IsMatch = TRUE;\r
518\r
519 //\r
520 // Compare the PeerIdValid fields in PadId.\r
521 //\r
522 if (PadId1->PeerIdValid != PadId2->PeerIdValid) {\r
523 IsMatch = FALSE;\r
524 }\r
525 //\r
526 // Compare the PeerId fields in PadId if PeerIdValid is true.\r
527 //\r
528 if (IsMatch &&\r
529 PadId1->PeerIdValid &&\r
530 AsciiStriCmp ((CONST CHAR8 *) PadId1->Id.PeerId, (CONST CHAR8 *) PadId2->Id.PeerId) != 0\r
531 ) {\r
532 IsMatch = FALSE;\r
533 }\r
534 //\r
535 // Compare the IpAddress fields in PadId if PeerIdValid is false.\r
536 //\r
537 if (IsMatch &&\r
538 !PadId1->PeerIdValid &&\r
539 (PadId1->Id.IpAddress.PrefixLength != PadId2->Id.IpAddress.PrefixLength ||\r
540 CompareMem (&PadId1->Id.IpAddress.Address, &PadId2->Id.IpAddress.Address, sizeof (EFI_IP_ADDRESS)) != 0)\r
541 ) {\r
542 IsMatch = FALSE;\r
543 }\r
544\r
545 return IsMatch;\r
546}\r
547\r
548/**\r
549 Check if the SPD Selector is Zero by its LocalAddressCount and RemoteAddressCount\r
550 fields.\r
551\r
552 @param[in] Selector Pointer of the SPD Selector.\r
553\r
554 @retval TRUE If the SPD Selector is Zero.\r
555 @retval FALSE If the SPD Selector is not Zero.\r
556\r
557**/\r
558BOOLEAN\r
559IsZeroSpdSelector (\r
560 IN EFI_IPSEC_CONFIG_SELECTOR *Selector\r
561 )\r
562{\r
563 EFI_IPSEC_SPD_SELECTOR *SpdSel;\r
564 BOOLEAN IsZero;\r
565\r
566 SpdSel = &Selector->SpdSelector;\r
567 IsZero = FALSE;\r
568\r
569 if (SpdSel->LocalAddressCount == 0 && SpdSel->RemoteAddressCount == 0) {\r
570 IsZero = TRUE;\r
571 }\r
572\r
573 return IsZero;\r
574}\r
575\r
576/**\r
577 Check if the SA ID is Zero by its DestAddress.\r
578\r
579 @param[in] Selector Pointer of the SA ID.\r
580\r
581 @retval TRUE If the SA ID is Zero.\r
582 @retval FALSE If the SA ID is not Zero.\r
583\r
584**/\r
585BOOLEAN\r
586IsZeroSaId (\r
587 IN EFI_IPSEC_CONFIG_SELECTOR *Selector\r
588 )\r
589{\r
9166f840 590 BOOLEAN IsZero;\r
591 EFI_IPSEC_CONFIG_SELECTOR ZeroSelector;\r
592 \r
a3bcde70
HT
593 IsZero = FALSE;\r
594\r
9166f840 595 ZeroMem (&ZeroSelector, sizeof (EFI_IPSEC_CONFIG_SELECTOR));\r
a3bcde70 596\r
9166f840 597 if (CompareMem (&ZeroSelector, Selector, sizeof (EFI_IPSEC_CONFIG_SELECTOR)) == 0) {\r
a3bcde70
HT
598 IsZero = TRUE;\r
599 }\r
600\r
601 return IsZero;\r
602}\r
603\r
604/**\r
605 Check if the PAD ID is Zero.\r
606\r
607 @param[in] Selector Pointer of the PAD ID.\r
608\r
609 @retval TRUE If the PAD ID is Zero.\r
610 @retval FALSE If the PAD ID is not Zero.\r
611\r
612**/\r
613BOOLEAN\r
614IsZeroPadId (\r
615 IN EFI_IPSEC_CONFIG_SELECTOR *Selector\r
616 )\r
617{\r
618 EFI_IPSEC_PAD_ID *PadId;\r
619 EFI_IPSEC_PAD_ID ZeroId;\r
620 BOOLEAN IsZero;\r
621\r
622 PadId = &Selector->PadId;\r
623 IsZero = FALSE;\r
624\r
625 ZeroMem (&ZeroId, sizeof (EFI_IPSEC_PAD_ID));\r
626\r
627 if (CompareMem (PadId, &ZeroId, sizeof (EFI_IPSEC_PAD_ID)) == 0) {\r
628 IsZero = TRUE;\r
629 }\r
630\r
631 return IsZero;\r
632}\r
633\r
634/**\r
635 Copy Source SPD Selector to the Destination SPD Selector.\r
636\r
637 @param[in, out] DstSel Pointer of Destination SPD Selector.\r
638 @param[in] SrcSel Pointer of Source SPD Selector.\r
9166f840 639 @param[in, out] Size The size of the Destination SPD Selector. If it \r
640 not NULL and its value less than the size of \r
641 Source SPD Selector, the value of Source SPD \r
a3bcde70
HT
642 Selector's size will be passed to caller by this\r
643 parameter.\r
644\r
645 @retval EFI_INVALID_PARAMETER If the Destination or Source SPD Selector is NULL\r
9166f840 646 @retval EFI_BUFFER_TOO_SMALL If the input Size is less than size of the Source SPD Selector. \r
a3bcde70
HT
647 @retval EFI_SUCCESS Copy Source SPD Selector to the Destination SPD\r
648 Selector successfully.\r
649\r
650**/\r
651EFI_STATUS\r
652DuplicateSpdSelector (\r
653 IN OUT EFI_IPSEC_CONFIG_SELECTOR *DstSel,\r
654 IN EFI_IPSEC_CONFIG_SELECTOR *SrcSel,\r
655 IN OUT UINTN *Size\r
656 )\r
657{\r
658 EFI_IPSEC_SPD_SELECTOR *Dst;\r
659 EFI_IPSEC_SPD_SELECTOR *Src;\r
660\r
661 Dst = &DstSel->SpdSelector;\r
662 Src = &SrcSel->SpdSelector;\r
663\r
664 if (Dst == NULL || Src == NULL) {\r
665 return EFI_INVALID_PARAMETER;\r
666 }\r
667\r
668 if (Size != NULL && (*Size) < SIZE_OF_SPD_SELECTOR (Src)) {\r
669 *Size = SIZE_OF_SPD_SELECTOR (Src);\r
670 return EFI_BUFFER_TOO_SMALL;\r
671 }\r
672 //\r
9166f840 673 // Copy the base structure of SPD selector.\r
a3bcde70
HT
674 //\r
675 CopyMem (Dst, Src, sizeof (EFI_IPSEC_SPD_SELECTOR));\r
676\r
677 //\r
9166f840 678 // Copy the local address array of SPD selector.\r
a3bcde70
HT
679 //\r
680 Dst->LocalAddress = (EFI_IP_ADDRESS_INFO *) (Dst + 1);\r
681 CopyMem (\r
682 Dst->LocalAddress,\r
683 Src->LocalAddress,\r
684 sizeof (EFI_IP_ADDRESS_INFO) * Dst->LocalAddressCount\r
685 );\r
686\r
687 //\r
9166f840 688 // Copy the remote address array of SPD selector.\r
a3bcde70
HT
689 //\r
690 Dst->RemoteAddress = Dst->LocalAddress + Dst->LocalAddressCount;\r
691 CopyMem (\r
692 Dst->RemoteAddress,\r
693 Src->RemoteAddress,\r
694 sizeof (EFI_IP_ADDRESS_INFO) * Dst->RemoteAddressCount\r
695 );\r
696\r
697 return EFI_SUCCESS;\r
698}\r
699\r
700/**\r
701 Copy Source SA ID to the Destination SA ID.\r
702\r
703 @param[in, out] DstSel Pointer of Destination SA ID.\r
704 @param[in] SrcSel Pointer of Source SA ID.\r
9166f840 705 @param[in, out] Size The size of the Destination SA ID. If it \r
706 not NULL and its value less than the size of \r
707 Source SA ID, the value of Source SA ID's size \r
a3bcde70
HT
708 will be passed to caller by this parameter.\r
709\r
710 @retval EFI_INVALID_PARAMETER If the Destination or Source SA ID is NULL.\r
9166f840 711 @retval EFI_BUFFER_TOO_SMALL If the input Size less than size of source SA ID. \r
a3bcde70
HT
712 @retval EFI_SUCCESS Copy Source SA ID to the Destination SA ID successfully.\r
713\r
714**/\r
715EFI_STATUS\r
716DuplicateSaId (\r
717 IN OUT EFI_IPSEC_CONFIG_SELECTOR *DstSel,\r
718 IN EFI_IPSEC_CONFIG_SELECTOR *SrcSel,\r
719 IN OUT UINTN *Size\r
720 )\r
721{\r
722 EFI_IPSEC_SA_ID *Dst;\r
723 EFI_IPSEC_SA_ID *Src;\r
724\r
725 Dst = &DstSel->SaId;\r
726 Src = &SrcSel->SaId;\r
727\r
728 if (Dst == NULL || Src == NULL) {\r
729 return EFI_INVALID_PARAMETER;\r
730 }\r
731\r
732 if (Size != NULL && *Size < sizeof (EFI_IPSEC_SA_ID)) {\r
733 *Size = sizeof (EFI_IPSEC_SA_ID);\r
734 return EFI_BUFFER_TOO_SMALL;\r
735 }\r
736\r
737 CopyMem (Dst, Src, sizeof (EFI_IPSEC_SA_ID));\r
738\r
739 return EFI_SUCCESS;\r
740}\r
741\r
742/**\r
743 Copy Source PAD ID to the Destination PAD ID.\r
744\r
745 @param[in, out] DstSel Pointer of Destination PAD ID.\r
746 @param[in] SrcSel Pointer of Source PAD ID.\r
9166f840 747 @param[in, out] Size The size of the Destination PAD ID. If it \r
748 not NULL and its value less than the size of \r
749 Source PAD ID, the value of Source PAD ID's size \r
a3bcde70
HT
750 will be passed to caller by this parameter.\r
751\r
752 @retval EFI_INVALID_PARAMETER If the Destination or Source PAD ID is NULL.\r
753 @retval EFI_BUFFER_TOO_SMALL If the input Size less than size of source PAD ID .\r
754 @retval EFI_SUCCESS Copy Source PAD ID to the Destination PAD ID successfully.\r
755\r
756**/\r
757EFI_STATUS\r
758DuplicatePadId (\r
759 IN OUT EFI_IPSEC_CONFIG_SELECTOR *DstSel,\r
760 IN EFI_IPSEC_CONFIG_SELECTOR *SrcSel,\r
761 IN OUT UINTN *Size\r
762 )\r
763{\r
764 EFI_IPSEC_PAD_ID *Dst;\r
765 EFI_IPSEC_PAD_ID *Src;\r
766\r
767 Dst = &DstSel->PadId;\r
768 Src = &SrcSel->PadId;\r
769\r
770 if (Dst == NULL || Src == NULL) {\r
771 return EFI_INVALID_PARAMETER;\r
772 }\r
773\r
774 if (Size != NULL && *Size < sizeof (EFI_IPSEC_PAD_ID)) {\r
775 *Size = sizeof (EFI_IPSEC_PAD_ID);\r
776 return EFI_BUFFER_TOO_SMALL;\r
777 }\r
778\r
779 CopyMem (Dst, Src, sizeof (EFI_IPSEC_PAD_ID));\r
780\r
781 return EFI_SUCCESS;\r
782}\r
783\r
784/**\r
9166f840 785 Fix the value of some members of SPD Selector. \r
a3bcde70 786\r
9166f840 787 This function is called by IpSecCopyPolicyEntry()which copy the Policy \r
788 Entry into the Variable. Since some members in SPD Selector are pointers, \r
789 a physical address to relative address convertion is required before copying \r
a3bcde70
HT
790 this SPD entry into the variable.\r
791\r
792 @param[in] Selector Pointer of SPD Selector.\r
793 @param[in, out] Data Pointer of SPD Data.\r
794\r
795**/\r
796VOID\r
797FixSpdEntry (\r
798 IN EFI_IPSEC_SPD_SELECTOR *Selector,\r
799 IN OUT EFI_IPSEC_SPD_DATA *Data\r
800 )\r
801{\r
802 //\r
9166f840 803 // It assumes that all ref buffers in SPD selector and data are\r
a3bcde70
HT
804 // stored in the continous memory and close to the base structure.\r
805 //\r
806 FIX_REF_BUF_ADDR (Selector->LocalAddress, Selector);\r
807 FIX_REF_BUF_ADDR (Selector->RemoteAddress, Selector);\r
808\r
809 if (Data->ProcessingPolicy != NULL) {\r
810 if (Data->ProcessingPolicy->TunnelOption != NULL) {\r
811 FIX_REF_BUF_ADDR (Data->ProcessingPolicy->TunnelOption, Data);\r
812 }\r
813\r
814 FIX_REF_BUF_ADDR (Data->ProcessingPolicy, Data);\r
815 }\r
816\r
817}\r
818\r
819/**\r
9166f840 820 Fix the value of some members of SA ID. \r
a3bcde70 821\r
9166f840 822 This function is called by IpSecCopyPolicyEntry()which copy the Policy \r
823 Entry into the Variable. Since some members in SA ID are pointers, \r
824 a physical address to relative address conversion is required before copying \r
a3bcde70
HT
825 this SAD into the variable.\r
826\r
827 @param[in] SaId Pointer of SA ID\r
828 @param[in, out] Data Pointer of SA Data.\r
829\r
830**/\r
831VOID\r
832FixSadEntry (\r
833 IN EFI_IPSEC_SA_ID *SaId,\r
9166f840 834 IN OUT EFI_IPSEC_SA_DATA2 *Data\r
a3bcde70
HT
835 )\r
836{\r
837 //\r
9166f840 838 // It assumes that all ref buffers in SAD selector and data are\r
a3bcde70
HT
839 // stored in the continous memory and close to the base structure.\r
840 //\r
841 if (Data->AlgoInfo.EspAlgoInfo.AuthKey != NULL) {\r
842 FIX_REF_BUF_ADDR (Data->AlgoInfo.EspAlgoInfo.AuthKey, Data);\r
843 }\r
844\r
845 if (SaId->Proto == EfiIPsecESP && Data->AlgoInfo.EspAlgoInfo.EncKey != NULL) {\r
846 FIX_REF_BUF_ADDR (Data->AlgoInfo.EspAlgoInfo.EncKey, Data);\r
847 }\r
848\r
849 if (Data->SpdSelector != NULL) {\r
850 if (Data->SpdSelector->LocalAddress != NULL) {\r
851 FIX_REF_BUF_ADDR (Data->SpdSelector->LocalAddress, Data);\r
852 }\r
853\r
854 FIX_REF_BUF_ADDR (Data->SpdSelector->RemoteAddress, Data);\r
855 FIX_REF_BUF_ADDR (Data->SpdSelector, Data);\r
856 }\r
857\r
858}\r
859\r
860/**\r
9166f840 861 Fix the value of some members of PAD ID. \r
a3bcde70 862\r
9166f840 863 This function is called by IpSecCopyPolicyEntry()which copy the Policy \r
864 Entry into the Variable. Since some members in PAD ID are pointers, \r
a3bcde70
HT
865 a physical address to relative address conversion is required before copying\r
866 this PAD into the variable.\r
867\r
868 @param[in] PadId Pointer of PAD ID.\r
869 @param[in, out] Data Pointer of PAD Data.\r
870\r
871**/\r
872VOID\r
873FixPadEntry (\r
874 IN EFI_IPSEC_PAD_ID *PadId,\r
875 IN OUT EFI_IPSEC_PAD_DATA *Data\r
876 )\r
877{\r
878 //\r
879 // It assumes that all ref buffers in pad selector and data are\r
880 // stored in the continous memory and close to the base structure.\r
881 //\r
882 if (Data->AuthData != NULL) {\r
883 FIX_REF_BUF_ADDR (Data->AuthData, Data);\r
884 }\r
885\r
886 if (Data->RevocationData != NULL) {\r
887 FIX_REF_BUF_ADDR (Data->RevocationData, Data);\r
888 }\r
889\r
890}\r
891\r
892/**\r
9166f840 893 Recover the value of some members of SPD Selector. \r
a3bcde70
HT
894\r
895 This function is corresponding to FixSpdEntry(). It recovers the value of members\r
896 of SPD Selector that are fixed by FixSpdEntry().\r
897\r
898 @param[in, out] Selector Pointer of SPD Selector.\r
899 @param[in, out] Data Pointer of SPD Data.\r
900\r
901**/\r
902VOID\r
903UnfixSpdEntry (\r
904 IN OUT EFI_IPSEC_SPD_SELECTOR *Selector,\r
905 IN OUT EFI_IPSEC_SPD_DATA *Data\r
906 )\r
907{\r
908 //\r
9166f840 909 // It assumes that all ref buffers in SPD selector and data are\r
a3bcde70
HT
910 // stored in the continous memory and close to the base structure.\r
911 //\r
912 UNFIX_REF_BUF_ADDR (Selector->LocalAddress, Selector);\r
913 UNFIX_REF_BUF_ADDR (Selector->RemoteAddress, Selector);\r
914\r
915 if (Data->ProcessingPolicy != NULL) {\r
916 UNFIX_REF_BUF_ADDR (Data->ProcessingPolicy, Data);\r
917 if (Data->ProcessingPolicy->TunnelOption != NULL) {\r
918 UNFIX_REF_BUF_ADDR (Data->ProcessingPolicy->TunnelOption, Data);\r
919 }\r
920 }\r
9166f840 921 \r
a3bcde70
HT
922}\r
923\r
924/**\r
9166f840 925 Recover the value of some members of SA ID. \r
a3bcde70
HT
926\r
927 This function is corresponding to FixSadEntry(). It recovers the value of members\r
928 of SAD ID that are fixed by FixSadEntry().\r
929\r
930 @param[in, out] SaId Pointer of SAD ID.\r
931 @param[in, out] Data Pointer of SAD Data.\r
932\r
933**/\r
934VOID\r
935UnfixSadEntry (\r
936 IN OUT EFI_IPSEC_SA_ID *SaId,\r
9166f840 937 IN OUT EFI_IPSEC_SA_DATA2 *Data\r
a3bcde70
HT
938 )\r
939{\r
940 //\r
9166f840 941 // It assumes that all ref buffers in SAD selector and data are\r
a3bcde70
HT
942 // stored in the continous memory and close to the base structure.\r
943 //\r
944 if (Data->AlgoInfo.EspAlgoInfo.AuthKey != NULL) {\r
945 UNFIX_REF_BUF_ADDR (Data->AlgoInfo.EspAlgoInfo.AuthKey, Data);\r
946 }\r
947\r
948 if (SaId->Proto == EfiIPsecESP && Data->AlgoInfo.EspAlgoInfo.EncKey != NULL) {\r
949 UNFIX_REF_BUF_ADDR (Data->AlgoInfo.EspAlgoInfo.EncKey, Data);\r
950 }\r
951\r
952 if (Data->SpdSelector != NULL) {\r
953 UNFIX_REF_BUF_ADDR (Data->SpdSelector, Data);\r
954 if (Data->SpdSelector->LocalAddress != NULL) {\r
955 UNFIX_REF_BUF_ADDR (Data->SpdSelector->LocalAddress, Data);\r
956 }\r
957\r
958 UNFIX_REF_BUF_ADDR (Data->SpdSelector->RemoteAddress, Data);\r
959 }\r
960\r
961}\r
962\r
963/**\r
9166f840 964 Recover the value of some members of PAD ID. \r
a3bcde70
HT
965\r
966 This function is corresponding to FixPadEntry(). It recovers the value of members\r
967 of PAD ID that are fixed by FixPadEntry().\r
968\r
969 @param[in] PadId Pointer of PAD ID.\r
970 @param[in, out] Data Pointer of PAD Data.\r
971\r
972**/\r
973VOID\r
974UnfixPadEntry (\r
975 IN EFI_IPSEC_PAD_ID *PadId,\r
976 IN OUT EFI_IPSEC_PAD_DATA *Data\r
977 )\r
978{\r
979 //\r
980 // It assumes that all ref buffers in pad selector and data are\r
981 // stored in the continous memory and close to the base structure.\r
982 //\r
983 if (Data->AuthData != NULL) {\r
984 UNFIX_REF_BUF_ADDR (Data->AuthData, Data);\r
985 }\r
986\r
987 if (Data->RevocationData != NULL) {\r
988 UNFIX_REF_BUF_ADDR (Data->RevocationData, Data);\r
989 }\r
990\r
991}\r
992\r
993/**\r
994 Set the security policy information for the EFI IPsec driver.\r
995\r
9166f840 996 The IPsec configuration data has a unique selector/identifier separately to \r
a3bcde70
HT
997 identify a data entry.\r
998\r
9166f840 999 @param[in] Selector Pointer to an entry selector on operated \r
1000 configuration data specified by DataType. \r
1001 A NULL Selector causes the entire specified-type \r
a3bcde70 1002 configuration information to be flushed.\r
9166f840 1003 @param[in] Data The data buffer to be set. The structure \r
a3bcde70 1004 of the data buffer should be EFI_IPSEC_SPD_DATA.\r
9166f840 1005 @param[in] Context Pointer to one entry selector that describes \r
1006 the expected position the new data entry will \r
a3bcde70
HT
1007 be added. If Context is NULL, the new entry will\r
1008 be appended the end of database.\r
1009\r
1010 @retval EFI_INVALID_PARAMETER One or more of the following are TRUE:\r
9166f840 1011 - Selector is not NULL and its LocalAddress \r
a3bcde70 1012 is NULL or its RemoteAddress is NULL.\r
9166f840 1013 - Data is not NULL and its Action is Protected \r
a3bcde70
HT
1014 and its plolicy is NULL.\r
1015 - Data is not NULL, its Action is not protected,\r
1016 and its policy is not NULL.\r
9166f840 1017 - The Action of Data is Protected, its policy \r
a3bcde70 1018 mode is Tunnel, and its tunnel option is NULL.\r
9166f840 1019 - The Action of Data is protected and its policy \r
a3bcde70 1020 mode is not Tunnel and it tunnel option is not NULL.\r
4991eeff
JW
1021 - SadEntry requied to be set into new SpdEntry's Sas has \r
1022 been found but it is invalid.\r
a3bcde70
HT
1023 @retval EFI_OUT_OF_RESOURCED The required system resource could not be allocated.\r
1024 @retval EFI_SUCCESS The specified configuration data was obtained successfully.\r
1025\r
1026**/\r
1027EFI_STATUS\r
1028SetSpdEntry (\r
1029 IN EFI_IPSEC_CONFIG_SELECTOR *Selector,\r
1030 IN VOID *Data,\r
1031 IN VOID *Context OPTIONAL\r
1032 )\r
1033{\r
1034 EFI_IPSEC_SPD_SELECTOR *SpdSel;\r
1035 EFI_IPSEC_SPD_DATA *SpdData;\r
1036 EFI_IPSEC_SPD_SELECTOR *InsertBefore;\r
1037 LIST_ENTRY *SpdList;\r
1038 LIST_ENTRY *SadList;\r
1039 LIST_ENTRY *SpdSas;\r
1040 LIST_ENTRY *EntryInsertBefore;\r
1041 LIST_ENTRY *Entry;\r
a3bcde70 1042 LIST_ENTRY *Entry2;\r
9166f840 1043 LIST_ENTRY *NextEntry;\r
4991eeff 1044 LIST_ENTRY *NextEntry2;\r
a3bcde70
HT
1045 IPSEC_SPD_ENTRY *SpdEntry;\r
1046 IPSEC_SAD_ENTRY *SadEntry;\r
1047 UINTN SpdEntrySize;\r
1048 UINTN Index;\r
1049\r
1050 SpdSel = (Selector == NULL) ? NULL : &Selector->SpdSelector;\r
1051 SpdData = (Data == NULL) ? NULL : (EFI_IPSEC_SPD_DATA *) Data;\r
1052 InsertBefore = (Context == NULL) ? NULL : &((EFI_IPSEC_CONFIG_SELECTOR *) Context)->SpdSelector;\r
1053 SpdList = &mConfigData[IPsecConfigDataTypeSpd];\r
1054\r
1055 if (SpdSel != NULL) {\r
1056 if (SpdSel->LocalAddress == NULL || SpdSel->RemoteAddress == NULL) {\r
1057 return EFI_INVALID_PARAMETER;\r
1058 }\r
1059 }\r
1060\r
1061 if (SpdData != NULL) {\r
1062 if ((SpdData->Action == EfiIPsecActionProtect && SpdData->ProcessingPolicy == NULL) ||\r
1063 (SpdData->Action != EfiIPsecActionProtect && SpdData->ProcessingPolicy != NULL)\r
1064 ) {\r
1065 return EFI_INVALID_PARAMETER;\r
1066 }\r
1067\r
1068 if (SpdData->Action == EfiIPsecActionProtect) {\r
1069 if ((SpdData->ProcessingPolicy->Mode == EfiIPsecTunnel && SpdData->ProcessingPolicy->TunnelOption == NULL) ||\r
1070 (SpdData->ProcessingPolicy->Mode != EfiIPsecTunnel && SpdData->ProcessingPolicy->TunnelOption != NULL)\r
1071 ) {\r
1072 return EFI_INVALID_PARAMETER;\r
1073 }\r
1074 }\r
1075 }\r
1076 //\r
1077 // The default behavior is to insert the node ahead of the header.\r
1078 //\r
1079 EntryInsertBefore = SpdList;\r
1080\r
1081 //\r
9166f840 1082 // Remove the existed SPD entry.\r
a3bcde70
HT
1083 //\r
1084 NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, SpdList) {\r
1085\r
1086 SpdEntry = IPSEC_SPD_ENTRY_FROM_LIST (Entry);\r
1087\r
9166f840 1088 if (SpdSel == NULL || \r
a3bcde70
HT
1089 CompareSpdSelector ((EFI_IPSEC_CONFIG_SELECTOR *) SpdEntry->Selector, (EFI_IPSEC_CONFIG_SELECTOR *) SpdSel)\r
1090 ) {\r
1091 //\r
1092 // Record the existed entry position to keep the original order.\r
1093 //\r
1094 EntryInsertBefore = SpdEntry->List.ForwardLink;\r
1095 RemoveEntryList (&SpdEntry->List);\r
1096\r
1097 //\r
9166f840 1098 // Update the reverse ref of SAD entry in the SPD.sas list.\r
a3bcde70
HT
1099 //\r
1100 SpdSas = &SpdEntry->Data->Sas;\r
9166f840 1101 \r
1102 //\r
4991eeff
JW
1103 // Remove the related SAs from Sas(SadEntry->BySpd). If the SA entry is established by \r
1104 // IKE, remove from mConfigData list(SadEntry->List) and then free it directly since its \r
1105 // SpdEntry will be freed later.\r
9166f840 1106 //\r
4991eeff
JW
1107 NET_LIST_FOR_EACH_SAFE (Entry2, NextEntry2, SpdSas) {\r
1108 SadEntry = IPSEC_SAD_ENTRY_FROM_SPD (Entry2);\r
1109 \r
1110 if (SadEntry->Data->SpdEntry != NULL) {\r
1111 RemoveEntryList (&SadEntry->BySpd);\r
1112 SadEntry->Data->SpdEntry = NULL;\r
1113 }\r
1114 \r
1115 if (!(SadEntry->Data->ManualSet)) {\r
1116 RemoveEntryList (&SadEntry->List);\r
1117 FreePool (SadEntry);\r
1118 }\r
a3bcde70 1119 }\r
9166f840 1120 \r
a3bcde70 1121 //\r
9166f840 1122 // Free the existed SPD entry\r
a3bcde70
HT
1123 //\r
1124 FreePool (SpdEntry);\r
1125 }\r
1126 }\r
1127 //\r
9166f840 1128 // Return success here if only want to remove the SPD entry.\r
a3bcde70
HT
1129 //\r
1130 if (SpdData == NULL || SpdSel == NULL) {\r
1131 return EFI_SUCCESS;\r
1132 }\r
1133 //\r
1134 // Search the appointed entry position if InsertBefore is not NULL.\r
1135 //\r
1136 if (InsertBefore != NULL) {\r
1137\r
1138 NET_LIST_FOR_EACH (Entry, SpdList) {\r
1139 SpdEntry = IPSEC_SPD_ENTRY_FROM_LIST (Entry);\r
1140\r
1141 if (CompareSpdSelector (\r
1142 (EFI_IPSEC_CONFIG_SELECTOR *) SpdEntry->Selector,\r
1143 (EFI_IPSEC_CONFIG_SELECTOR *) InsertBefore\r
1144 )) {\r
1145 EntryInsertBefore = Entry;\r
1146 break;\r
1147 }\r
1148 }\r
1149 }\r
1150\r
1151 //\r
1152 // Do Padding for the different Arch.\r
1153 //\r
1154 SpdEntrySize = ALIGN_VARIABLE (sizeof (IPSEC_SPD_ENTRY));\r
ce5c3273 1155 SpdEntrySize = ALIGN_VARIABLE (SpdEntrySize + SIZE_OF_SPD_SELECTOR (SpdSel));\r
a3bcde70
HT
1156 SpdEntrySize += IpSecGetSizeOfEfiSpdData (SpdData);\r
1157\r
1158 SpdEntry = AllocateZeroPool (SpdEntrySize);\r
1159\r
1160 if (SpdEntry == NULL) {\r
1161 return EFI_OUT_OF_RESOURCES;\r
1162 }\r
1163 //\r
1164 // Fix the address of Selector and Data buffer and copy them, which is\r
9166f840 1165 // continous memory and close to the base structure of SPD entry.\r
a3bcde70
HT
1166 //\r
1167 SpdEntry->Selector = (EFI_IPSEC_SPD_SELECTOR *) ALIGN_POINTER ((SpdEntry + 1), sizeof (UINTN));\r
1168 SpdEntry->Data = (IPSEC_SPD_DATA *) ALIGN_POINTER (\r
1169 ((UINT8 *) SpdEntry->Selector + SIZE_OF_SPD_SELECTOR (SpdSel)),\r
1170 sizeof (UINTN)\r
1171 );\r
1172\r
1173 DuplicateSpdSelector (\r
1174 (EFI_IPSEC_CONFIG_SELECTOR *) SpdEntry->Selector,\r
1175 (EFI_IPSEC_CONFIG_SELECTOR *) SpdSel,\r
1176 NULL\r
1177 );\r
1178\r
1179 CopyMem (\r
1180 SpdEntry->Data->Name,\r
1181 SpdData->Name,\r
1182 sizeof (SpdData->Name)\r
1183 );\r
96702f88
FS
1184 SpdEntry->Data->PackageFlag = SpdData->PackageFlag;\r
1185 SpdEntry->Data->TrafficDirection = SpdData->TrafficDirection;\r
1186 SpdEntry->Data->Action = SpdData->Action;\r
1187 \r
a3bcde70
HT
1188 //\r
1189 // Fix the address of ProcessingPolicy and copy it if need, which is continous\r
9166f840 1190 // memory and close to the base structure of SAD data.\r
a3bcde70
HT
1191 //\r
1192 if (SpdData->Action != EfiIPsecActionProtect) {\r
1193 SpdEntry->Data->ProcessingPolicy = NULL;\r
1194 } else {\r
1195 SpdEntry->Data->ProcessingPolicy = (EFI_IPSEC_PROCESS_POLICY *) ALIGN_POINTER (\r
1196 SpdEntry->Data + 1,\r
1197 sizeof (UINTN)\r
1198 );\r
1199 IpSecDuplicateProcessPolicy (SpdEntry->Data->ProcessingPolicy, SpdData->ProcessingPolicy);\r
1200 }\r
1201 //\r
9166f840 1202 // Update the sas list of the new SPD entry.\r
a3bcde70
HT
1203 //\r
1204 InitializeListHead (&SpdEntry->Data->Sas);\r
1205\r
1206 SadList = &mConfigData[IPsecConfigDataTypeSad];\r
1207\r
1208 NET_LIST_FOR_EACH (Entry, SadList) {\r
1209 SadEntry = IPSEC_SAD_ENTRY_FROM_LIST (Entry);\r
1210\r
4991eeff
JW
1211 for (Index = 0; Index < SpdData->SaIdCount; Index++) {\r
1212 if (CompareSaId (\r
1213 (EFI_IPSEC_CONFIG_SELECTOR *) &SpdData->SaId[Index],\r
1214 (EFI_IPSEC_CONFIG_SELECTOR *) SadEntry->Id\r
1215 )) {\r
1216 //\r
1217 // Check whether the found SadEntry is vaild.\r
1218 //\r
1219 if (IsSubSpdSelector (\r
1220 (EFI_IPSEC_CONFIG_SELECTOR *) SadEntry->Data->SpdSelector,\r
1221 (EFI_IPSEC_CONFIG_SELECTOR *) SpdEntry->Selector\r
1222 )) {\r
1223 if (SadEntry->Data->SpdEntry != NULL) {\r
1224 RemoveEntryList (&SadEntry->BySpd);\r
1225 }\r
1226 InsertTailList (&SpdEntry->Data->Sas, &SadEntry->BySpd);\r
1227 SadEntry->Data->SpdEntry = SpdEntry;\r
1228 } else {\r
1229 return EFI_INVALID_PARAMETER;\r
1230 }\r
60cbd7fb 1231 }\r
4991eeff 1232 } \r
a3bcde70 1233 }\r
4991eeff 1234 \r
a3bcde70 1235 //\r
9166f840 1236 // Insert the new SPD entry.\r
a3bcde70
HT
1237 //\r
1238 InsertTailList (EntryInsertBefore, &SpdEntry->List);\r
1239\r
1240 return EFI_SUCCESS;\r
1241}\r
1242\r
1243/**\r
1244 Set the security association information for the EFI IPsec driver.\r
1245\r
9166f840 1246 The IPsec configuration data has a unique selector/identifier separately to \r
a3bcde70
HT
1247 identify a data entry.\r
1248\r
9166f840 1249 @param[in] Selector Pointer to an entry selector on operated \r
1250 configuration data specified by DataType. \r
1251 A NULL Selector causes the entire specified-type \r
a3bcde70 1252 configuration information to be flushed.\r
9166f840 1253 @param[in] Data The data buffer to be set. The structure \r
a3bcde70 1254 of the data buffer should be EFI_IPSEC_SA_DATA.\r
9166f840 1255 @param[in] Context Pointer to one entry selector which describes \r
1256 the expected position the new data entry will \r
a3bcde70
HT
1257 be added. If Context is NULL,the new entry will\r
1258 be appended the end of database.\r
1259\r
1260 @retval EFI_OUT_OF_RESOURCED The required system resource could not be allocated.\r
1261 @retval EFI_SUCCESS The specified configuration data was obtained successfully.\r
1262\r
1263**/\r
1264EFI_STATUS\r
1265SetSadEntry (\r
1266 IN EFI_IPSEC_CONFIG_SELECTOR *Selector,\r
1267 IN VOID *Data,\r
1268 IN VOID *Context OPTIONAL\r
1269 )\r
1270{\r
1271 IPSEC_SAD_ENTRY *SadEntry;\r
1272 IPSEC_SPD_ENTRY *SpdEntry;\r
1273 LIST_ENTRY *Entry;\r
1274 LIST_ENTRY *NextEntry;\r
1275 LIST_ENTRY *SadList;\r
1276 LIST_ENTRY *SpdList;\r
1277 EFI_IPSEC_SA_ID *SaId;\r
9166f840 1278 EFI_IPSEC_SA_DATA2 *SaData;\r
a3bcde70
HT
1279 EFI_IPSEC_SA_ID *InsertBefore;\r
1280 LIST_ENTRY *EntryInsertBefore;\r
1281 UINTN SadEntrySize;\r
9166f840 1282 \r
a3bcde70 1283 SaId = (Selector == NULL) ? NULL : &Selector->SaId;\r
9166f840 1284 SaData = (Data == NULL) ? NULL : (EFI_IPSEC_SA_DATA2 *) Data;\r
a3bcde70
HT
1285 InsertBefore = (Context == NULL) ? NULL : &((EFI_IPSEC_CONFIG_SELECTOR *) Context)->SaId;\r
1286 SadList = &mConfigData[IPsecConfigDataTypeSad];\r
1287\r
1288 //\r
1289 // The default behavior is to insert the node ahead of the header.\r
1290 //\r
1291 EntryInsertBefore = SadList;\r
1292\r
1293 //\r
9166f840 1294 // Remove the existed SAD entry.\r
a3bcde70
HT
1295 //\r
1296 NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, SadList) {\r
1297\r
1298 SadEntry = IPSEC_SAD_ENTRY_FROM_LIST (Entry);\r
1299\r
9166f840 1300 if (SaId == NULL || \r
a3bcde70
HT
1301 CompareSaId (\r
1302 (EFI_IPSEC_CONFIG_SELECTOR *) SadEntry->Id,\r
1303 (EFI_IPSEC_CONFIG_SELECTOR *) SaId\r
1304 )) {\r
1305 //\r
1306 // Record the existed entry position to keep the original order.\r
1307 //\r
1308 EntryInsertBefore = SadEntry->List.ForwardLink;\r
1309\r
1310 //\r
9166f840 1311 // Update the related SAD.byspd field.\r
a3bcde70
HT
1312 //\r
1313 if (SadEntry->Data->SpdEntry != NULL) {\r
1314 RemoveEntryList (&SadEntry->BySpd);\r
1315 }\r
1316\r
1317 RemoveEntryList (&SadEntry->List);\r
1318 FreePool (SadEntry);\r
1319 }\r
1320 }\r
1321 //\r
9166f840 1322 // Return success here if only want to remove the SAD entry\r
a3bcde70
HT
1323 //\r
1324 if (SaData == NULL || SaId == NULL) {\r
1325 return EFI_SUCCESS;\r
1326 }\r
1327 //\r
1328 // Search the appointed entry position if InsertBefore is not NULL.\r
1329 //\r
1330 if (InsertBefore != NULL) {\r
1331\r
1332 NET_LIST_FOR_EACH (Entry, SadList) {\r
1333 SadEntry = IPSEC_SAD_ENTRY_FROM_LIST (Entry);\r
1334\r
1335 if (CompareSaId (\r
1336 (EFI_IPSEC_CONFIG_SELECTOR *) SadEntry->Id,\r
1337 (EFI_IPSEC_CONFIG_SELECTOR *) InsertBefore\r
1338 )) {\r
1339 EntryInsertBefore = Entry;\r
1340 break;\r
1341 }\r
1342 }\r
1343 }\r
1344\r
1345 //\r
1346 // Do Padding for different Arch.\r
1347 //\r
1348 SadEntrySize = ALIGN_VARIABLE (sizeof (IPSEC_SAD_ENTRY));\r
9166f840 1349 SadEntrySize = ALIGN_VARIABLE (SadEntrySize + sizeof (EFI_IPSEC_SA_ID));\r
a3bcde70 1350 SadEntrySize = ALIGN_VARIABLE (SadEntrySize + sizeof (IPSEC_SAD_DATA));\r
9166f840 1351 \r
a3bcde70
HT
1352 if (SaId->Proto == EfiIPsecAH) {\r
1353 SadEntrySize += SaData->AlgoInfo.AhAlgoInfo.AuthKeyLength;\r
1354 } else {\r
1355 SadEntrySize = ALIGN_VARIABLE (SadEntrySize + SaData->AlgoInfo.EspAlgoInfo.AuthKeyLength);\r
9166f840 1356 SadEntrySize += ALIGN_VARIABLE (SaData->AlgoInfo.EspAlgoInfo.EncKeyLength);\r
a3bcde70
HT
1357 }\r
1358\r
9166f840 1359 if (SaData->SpdSelector != NULL) {\r
ce5c3273 1360 SadEntrySize += SadEntrySize + SIZE_OF_SPD_SELECTOR (SaData->SpdSelector);\r
9166f840 1361 }\r
a3bcde70
HT
1362 SadEntry = AllocateZeroPool (SadEntrySize);\r
1363\r
1364 if (SadEntry == NULL) {\r
1365 return EFI_OUT_OF_RESOURCES;\r
1366 }\r
1367 //\r
1368 // Fix the address of Id and Data buffer and copy them, which is\r
9166f840 1369 // continous memory and close to the base structure of SAD entry.\r
a3bcde70
HT
1370 //\r
1371 SadEntry->Id = (EFI_IPSEC_SA_ID *) ALIGN_POINTER ((SadEntry + 1), sizeof (UINTN));\r
1372 SadEntry->Data = (IPSEC_SAD_DATA *) ALIGN_POINTER ((SadEntry->Id + 1), sizeof (UINTN));\r
1373\r
1374 CopyMem (SadEntry->Id, SaId, sizeof (EFI_IPSEC_SA_ID));\r
1375\r
1376 SadEntry->Data->Mode = SaData->Mode;\r
1377 SadEntry->Data->SequenceNumber = SaData->SNCount;\r
1378 SadEntry->Data->AntiReplayWindowSize = SaData->AntiReplayWindows;\r
1379\r
1380 ZeroMem (\r
1381 &SadEntry->Data->AntiReplayBitmap,\r
1382 sizeof (SadEntry->Data->AntiReplayBitmap)\r
1383 );\r
1384\r
1385 ZeroMem (\r
1386 &SadEntry->Data->AlgoInfo,\r
1387 sizeof (EFI_IPSEC_ALGO_INFO)\r
1388 );\r
1389\r
1390 SadEntry->Data->AlgoInfo.EspAlgoInfo.AuthAlgoId = SaData->AlgoInfo.EspAlgoInfo.AuthAlgoId;\r
1391 SadEntry->Data->AlgoInfo.EspAlgoInfo.AuthKeyLength = SaData->AlgoInfo.EspAlgoInfo.AuthKeyLength;\r
1392\r
1393 if (SadEntry->Data->AlgoInfo.EspAlgoInfo.AuthKeyLength != 0) {\r
1394 SadEntry->Data->AlgoInfo.EspAlgoInfo.AuthKey = (VOID *) ALIGN_POINTER ((SadEntry->Data + 1), sizeof (UINTN));\r
1395 CopyMem (\r
1396 SadEntry->Data->AlgoInfo.EspAlgoInfo.AuthKey,\r
1397 SaData->AlgoInfo.EspAlgoInfo.AuthKey,\r
1398 SadEntry->Data->AlgoInfo.EspAlgoInfo.AuthKeyLength\r
1399 );\r
1400 }\r
1401\r
1402 if (SaId->Proto == EfiIPsecESP) {\r
1403 SadEntry->Data->AlgoInfo.EspAlgoInfo.EncAlgoId = SaData->AlgoInfo.EspAlgoInfo.EncAlgoId;\r
1404 SadEntry->Data->AlgoInfo.EspAlgoInfo.EncKeyLength = SaData->AlgoInfo.EspAlgoInfo.EncKeyLength;\r
1405\r
1406 if (SadEntry->Data->AlgoInfo.EspAlgoInfo.EncKeyLength != 0) {\r
1407 SadEntry->Data->AlgoInfo.EspAlgoInfo.EncKey = (VOID *) ALIGN_POINTER (\r
9166f840 1408 ((UINT8 *) (SadEntry->Data + 1) + \r
a3bcde70
HT
1409 SadEntry->Data->AlgoInfo.EspAlgoInfo.AuthKeyLength),\r
1410 sizeof (UINTN)\r
1411 );\r
1412 CopyMem (\r
1413 SadEntry->Data->AlgoInfo.EspAlgoInfo.EncKey,\r
1414 SaData->AlgoInfo.EspAlgoInfo.EncKey,\r
1415 SadEntry->Data->AlgoInfo.EspAlgoInfo.EncKeyLength\r
1416 );\r
1417 }\r
1418 }\r
1419\r
1420 CopyMem (\r
1421 &SadEntry->Data->SaLifetime,\r
1422 &SaData->SaLifetime,\r
1423 sizeof (EFI_IPSEC_SA_LIFETIME)\r
1424 );\r
1425\r
1426 SadEntry->Data->PathMTU = SaData->PathMTU;\r
9166f840 1427 SadEntry->Data->SpdSelector = NULL;\r
a3bcde70
HT
1428 SadEntry->Data->ESNEnabled = FALSE;\r
1429 SadEntry->Data->ManualSet = SaData->ManualSet;\r
1430\r
1431 //\r
9166f840 1432 // Copy Tunnel Source/Destination Address\r
1433 //\r
1434 if (SaData->Mode == EfiIPsecTunnel) {\r
1435 CopyMem (\r
1436 &SadEntry->Data->TunnelDestAddress,\r
1437 &SaData->TunnelDestinationAddress,\r
1438 sizeof (EFI_IP_ADDRESS)\r
1439 );\r
1440 CopyMem (\r
1441 &SadEntry->Data->TunnelSourceAddress,\r
1442 &SaData->TunnelSourceAddress,\r
1443 sizeof (EFI_IP_ADDRESS)\r
1444 );\r
1445 }\r
1446 //\r
1447 // Update the spd.sas list of the spd entry specified by SAD selector\r
a3bcde70
HT
1448 //\r
1449 SpdList = &mConfigData[IPsecConfigDataTypeSpd];\r
1450\r
1451 for (Entry = SpdList->ForwardLink; Entry != SpdList && SaData->SpdSelector != NULL; Entry = Entry->ForwardLink) {\r
1452\r
1453 SpdEntry = IPSEC_SPD_ENTRY_FROM_LIST (Entry);\r
9166f840 1454 if (IsSubSpdSelector (\r
1455 (EFI_IPSEC_CONFIG_SELECTOR *) SaData->SpdSelector,\r
1456 (EFI_IPSEC_CONFIG_SELECTOR *) SpdEntry->Selector\r
a3bcde70
HT
1457 ) && SpdEntry->Data->Action == EfiIPsecActionProtect) {\r
1458 SadEntry->Data->SpdEntry = SpdEntry;\r
9166f840 1459 SadEntry->Data->SpdSelector = (EFI_IPSEC_SPD_SELECTOR *)((UINT8 *)SadEntry +\r
1460 SadEntrySize -\r
ce5c3273 1461 SIZE_OF_SPD_SELECTOR (SaData->SpdSelector)\r
9166f840 1462 );\r
1463 DuplicateSpdSelector (\r
1464 (EFI_IPSEC_CONFIG_SELECTOR *) SadEntry->Data->SpdSelector,\r
1465 (EFI_IPSEC_CONFIG_SELECTOR *) SaData->SpdSelector,\r
1466 NULL\r
1467 );\r
a3bcde70
HT
1468 InsertTailList (&SpdEntry->Data->Sas, &SadEntry->BySpd);\r
1469 }\r
1470 }\r
1471 //\r
9166f840 1472 // Insert the new SAD entry.\r
a3bcde70
HT
1473 //\r
1474 InsertTailList (EntryInsertBefore, &SadEntry->List);\r
1475\r
1476 return EFI_SUCCESS;\r
1477}\r
1478\r
1479/**\r
1480 Set the peer authorization configuration information for the EFI IPsec driver.\r
1481\r
9166f840 1482 The IPsec configuration data has a unique selector/identifier separately to \r
a3bcde70
HT
1483 identify a data entry.\r
1484\r
9166f840 1485 @param[in] Selector Pointer to an entry selector on operated \r
1486 configuration data specified by DataType. \r
1487 A NULL Selector causes the entire specified-type \r
a3bcde70 1488 configuration information to be flushed.\r
9166f840 1489 @param[in] Data The data buffer to be set. The structure \r
a3bcde70 1490 of the data buffer should be EFI_IPSEC_PAD_DATA.\r
9166f840 1491 @param[in] Context Pointer to one entry selector that describes \r
1492 the expected position the new data entry will \r
a3bcde70
HT
1493 be added. If Context is NULL, the new entry will\r
1494 be appended the end of database.\r
1495\r
1496 @retval EFI_OUT_OF_RESOURCES The required system resources could not be allocated.\r
1497 @retval EFI_SUCCESS The specified configuration data was obtained successfully.\r
1498\r
1499**/\r
1500EFI_STATUS\r
1501SetPadEntry (\r
1502 IN EFI_IPSEC_CONFIG_SELECTOR *Selector,\r
1503 IN VOID *Data,\r
1504 IN VOID *Context OPTIONAL\r
1505 )\r
1506{\r
1507 IPSEC_PAD_ENTRY *PadEntry;\r
1508 EFI_IPSEC_PAD_ID *PadId;\r
1509 EFI_IPSEC_PAD_DATA *PadData;\r
1510 LIST_ENTRY *PadList;\r
1511 LIST_ENTRY *Entry;\r
1512 LIST_ENTRY *NextEntry;\r
1513 EFI_IPSEC_PAD_ID *InsertBefore;\r
1514 LIST_ENTRY *EntryInsertBefore;\r
1515 UINTN PadEntrySize;\r
9166f840 1516 \r
a3bcde70
HT
1517 PadId = (Selector == NULL) ? NULL : &Selector->PadId;\r
1518 PadData = (Data == NULL) ? NULL : (EFI_IPSEC_PAD_DATA *) Data;\r
1519 InsertBefore = (Context == NULL) ? NULL : &((EFI_IPSEC_CONFIG_SELECTOR *) Context)->PadId;\r
1520 PadList = &mConfigData[IPsecConfigDataTypePad];\r
1521\r
1522 //\r
1523 // The default behavior is to insert the node ahead of the header.\r
1524 //\r
1525 EntryInsertBefore = PadList;\r
1526\r
1527 //\r
1528 // Remove the existed pad entry.\r
1529 //\r
1530 NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, PadList) {\r
1531\r
1532 PadEntry = IPSEC_PAD_ENTRY_FROM_LIST (Entry);\r
1533\r
9166f840 1534 if (PadId == NULL || \r
a3bcde70
HT
1535 ComparePadId ((EFI_IPSEC_CONFIG_SELECTOR *) PadEntry->Id, (EFI_IPSEC_CONFIG_SELECTOR *) PadId)\r
1536 ) {\r
1537 //\r
1538 // Record the existed entry position to keep the original order.\r
1539 //\r
1540 EntryInsertBefore = PadEntry->List.ForwardLink;\r
1541 RemoveEntryList (&PadEntry->List);\r
1542\r
1543 FreePool (PadEntry);\r
1544 }\r
1545 }\r
1546 //\r
1547 // Return success here if only want to remove the pad entry\r
1548 //\r
1549 if (PadData == NULL || PadId == NULL) {\r
1550 return EFI_SUCCESS;\r
1551 }\r
1552 //\r
1553 // Search the appointed entry position if InsertBefore is not NULL.\r
1554 //\r
1555 if (InsertBefore != NULL) {\r
1556\r
1557 NET_LIST_FOR_EACH (Entry, PadList) {\r
1558 PadEntry = IPSEC_PAD_ENTRY_FROM_LIST (Entry);\r
1559\r
1560 if (ComparePadId (\r
1561 (EFI_IPSEC_CONFIG_SELECTOR *) PadEntry->Id,\r
1562 (EFI_IPSEC_CONFIG_SELECTOR *) InsertBefore\r
1563 )) {\r
1564 EntryInsertBefore = Entry;\r
1565 break;\r
1566 }\r
1567 }\r
1568 }\r
1569\r
1570 //\r
1571 // Do PADDING for different arch.\r
1572 //\r
1573 PadEntrySize = ALIGN_VARIABLE (sizeof (IPSEC_PAD_ENTRY));\r
1574 PadEntrySize = ALIGN_VARIABLE (PadEntrySize + sizeof (EFI_IPSEC_PAD_ID));\r
1575 PadEntrySize = ALIGN_VARIABLE (PadEntrySize + sizeof (EFI_IPSEC_PAD_DATA));\r
1576 PadEntrySize = ALIGN_VARIABLE (PadEntrySize + (PadData->AuthData != NULL ? PadData->AuthDataSize : 0));\r
1577 PadEntrySize += PadData->RevocationData != NULL ? PadData->RevocationDataSize : 0;\r
1578\r
1579 PadEntry = AllocateZeroPool (PadEntrySize);\r
1580\r
1581 if (PadEntry == NULL) {\r
1582 return EFI_OUT_OF_RESOURCES;\r
1583 }\r
1584 //\r
1585 // Fix the address of Id and Data buffer and copy them, which is\r
1586 // continous memory and close to the base structure of pad entry.\r
1587 //\r
1588 PadEntry->Id = (EFI_IPSEC_PAD_ID *) ALIGN_POINTER ((PadEntry + 1), sizeof (UINTN));\r
1589 PadEntry->Data = (EFI_IPSEC_PAD_DATA *) ALIGN_POINTER ((PadEntry->Id + 1), sizeof (UINTN));\r
1590\r
1591 CopyMem (PadEntry->Id, PadId, sizeof (EFI_IPSEC_PAD_ID));\r
1592\r
1593 PadEntry->Data->AuthProtocol = PadData->AuthProtocol;\r
1594 PadEntry->Data->AuthMethod = PadData->AuthMethod;\r
1595 PadEntry->Data->IkeIdFlag = PadData->IkeIdFlag;\r
1596\r
1597 if (PadData->AuthData != NULL) {\r
1598 PadEntry->Data->AuthDataSize = PadData->AuthDataSize;\r
1599 PadEntry->Data->AuthData = (VOID *) ALIGN_POINTER (PadEntry->Data + 1, sizeof (UINTN));\r
1600 CopyMem (\r
1601 PadEntry->Data->AuthData,\r
1602 PadData->AuthData,\r
1603 PadData->AuthDataSize\r
1604 );\r
1605 } else {\r
1606 PadEntry->Data->AuthDataSize = 0;\r
1607 PadEntry->Data->AuthData = NULL;\r
1608 }\r
1609\r
1610 if (PadData->RevocationData != NULL) {\r
1611 PadEntry->Data->RevocationDataSize = PadData->RevocationDataSize;\r
1612 PadEntry->Data->RevocationData = (VOID *) ALIGN_POINTER (\r
1613 ((UINT8 *) (PadEntry->Data + 1) + PadData->AuthDataSize),\r
1614 sizeof (UINTN)\r
1615 );\r
1616 CopyMem (\r
1617 PadEntry->Data->RevocationData,\r
1618 PadData->RevocationData,\r
1619 PadData->RevocationDataSize\r
1620 );\r
1621 } else {\r
1622 PadEntry->Data->RevocationDataSize = 0;\r
1623 PadEntry->Data->RevocationData = NULL;\r
1624 }\r
1625 //\r
1626 // Insert the new pad entry.\r
1627 //\r
1628 InsertTailList (EntryInsertBefore, &PadEntry->List);\r
1629\r
1630 return EFI_SUCCESS;\r
1631}\r
1632\r
1633/**\r
9166f840 1634 This function lookup the data entry from IPsec SPD. Return the configuration \r
a3bcde70
HT
1635 value of the specified SPD Entry.\r
1636\r
9166f840 1637 @param[in] Selector Pointer to an entry selector which is an identifier \r
a3bcde70
HT
1638 of the SPD entry.\r
1639 @param[in, out] DataSize On output the size of data returned in Data.\r
9166f840 1640 @param[out] Data The buffer to return the contents of the IPsec \r
1641 configuration data. The type of the data buffer \r
1642 is associated with the DataType. \r
1643 \r
a3bcde70
HT
1644 @retval EFI_SUCCESS The specified configuration data was obtained successfully.\r
1645 @retval EFI_INVALID_PARAMETER Data is NULL and *DataSize is not zero.\r
1646 @retval EFI_NOT_FOUND The configuration data specified by Selector is not found.\r
1647 @retval EFI_BUFFER_TOO_SMALL The DataSize is too small for the result. DataSize has been\r
1648 updated with the size needed to complete the request.\r
1649\r
1650**/\r
1651EFI_STATUS\r
1652GetSpdEntry (\r
1653 IN EFI_IPSEC_CONFIG_SELECTOR *Selector,\r
1654 IN OUT UINTN *DataSize,\r
1655 OUT VOID *Data\r
1656 )\r
1657{\r
1658 IPSEC_SPD_ENTRY *SpdEntry;\r
1659 IPSEC_SAD_ENTRY *SadEntry;\r
1660 EFI_IPSEC_SPD_SELECTOR *SpdSel;\r
1661 EFI_IPSEC_SPD_DATA *SpdData;\r
1662 LIST_ENTRY *SpdList;\r
1663 LIST_ENTRY *SpdSas;\r
1664 LIST_ENTRY *Entry;\r
1665 UINTN RequiredSize;\r
1666\r
1667 SpdSel = &Selector->SpdSelector;\r
1668 SpdData = (EFI_IPSEC_SPD_DATA *) Data;\r
1669 SpdList = &mConfigData[IPsecConfigDataTypeSpd];\r
1670\r
1671 NET_LIST_FOR_EACH (Entry, SpdList) {\r
1672 SpdEntry = IPSEC_SPD_ENTRY_FROM_LIST (Entry);\r
1673\r
1674 //\r
9166f840 1675 // Find the required SPD entry\r
a3bcde70
HT
1676 //\r
1677 if (CompareSpdSelector (\r
1678 (EFI_IPSEC_CONFIG_SELECTOR *) SpdSel,\r
1679 (EFI_IPSEC_CONFIG_SELECTOR *) SpdEntry->Selector\r
1680 )) {\r
1681\r
1682 RequiredSize = IpSecGetSizeOfSpdData (SpdEntry->Data);\r
1683 if (*DataSize < RequiredSize) {\r
1684 *DataSize = RequiredSize;\r
1685 return EFI_BUFFER_TOO_SMALL;\r
1686 }\r
1687\r
1688 if (SpdData == NULL) {\r
1689 return EFI_INVALID_PARAMETER;\r
1690 }\r
1691\r
1692 *DataSize = RequiredSize;\r
1693\r
1694 //\r
9166f840 1695 // Extract and fill all SaId array from the SPD.sas list\r
a3bcde70
HT
1696 //\r
1697 SpdSas = &SpdEntry->Data->Sas;\r
1698 SpdData->SaIdCount = 0;\r
1699\r
1700 NET_LIST_FOR_EACH (Entry, SpdSas) {\r
1701 SadEntry = IPSEC_SAD_ENTRY_FROM_SPD (Entry);\r
1702 CopyMem (\r
1703 &SpdData->SaId[SpdData->SaIdCount++],\r
1704 SadEntry->Id,\r
1705 sizeof (EFI_IPSEC_SA_ID)\r
1706 );\r
1707 }\r
1708 //\r
9166f840 1709 // Fill the other fields in SPD data.\r
a3bcde70
HT
1710 //\r
1711 CopyMem (SpdData->Name, SpdEntry->Data->Name, sizeof (SpdData->Name));\r
1712\r
96702f88
FS
1713 SpdData->PackageFlag = SpdEntry->Data->PackageFlag;\r
1714 SpdData->TrafficDirection = SpdEntry->Data->TrafficDirection;\r
1715 SpdData->Action = SpdEntry->Data->Action;\r
1716 \r
a3bcde70
HT
1717 if (SpdData->Action != EfiIPsecActionProtect) {\r
1718 SpdData->ProcessingPolicy = NULL;\r
1719 } else {\r
1720 SpdData->ProcessingPolicy = (EFI_IPSEC_PROCESS_POLICY *) ((UINT8 *) SpdData + sizeof (EFI_IPSEC_SPD_DATA) + (SpdData->SaIdCount - 1) * sizeof (EFI_IPSEC_SA_ID));\r
1721\r
1722 IpSecDuplicateProcessPolicy (\r
1723 SpdData->ProcessingPolicy,\r
1724 SpdEntry->Data->ProcessingPolicy\r
1725 );\r
1726 }\r
1727\r
1728 return EFI_SUCCESS;\r
1729 }\r
1730 }\r
1731\r
1732 return EFI_NOT_FOUND;\r
1733}\r
1734\r
1735/**\r
9166f840 1736 This function lookup the data entry from IPsec SAD. Return the configuration \r
a3bcde70
HT
1737 value of the specified SAD Entry.\r
1738\r
9166f840 1739 @param[in] Selector Pointer to an entry selector which is an identifier \r
a3bcde70
HT
1740 of the SAD entry.\r
1741 @param[in, out] DataSize On output, the size of data returned in Data.\r
9166f840 1742 @param[out] Data The buffer to return the contents of the IPsec \r
1743 configuration data. The type of the data buffer \r
1744 is associated with the DataType. \r
1745 \r
a3bcde70
HT
1746 @retval EFI_SUCCESS The specified configuration data was obtained successfully.\r
1747 @retval EFI_NOT_FOUND The configuration data specified by Selector is not found.\r
1748 @retval EFI_BUFFER_TOO_SMALL The DataSize is too small for the result. DataSize has been\r
1749 updated with the size needed to complete the request.\r
1750\r
1751**/\r
1752EFI_STATUS\r
1753GetSadEntry (\r
1754 IN EFI_IPSEC_CONFIG_SELECTOR *Selector,\r
1755 IN OUT UINTN *DataSize,\r
1756 OUT VOID *Data\r
1757 )\r
1758{\r
1759 IPSEC_SAD_ENTRY *SadEntry;\r
1760 LIST_ENTRY *Entry;\r
1761 LIST_ENTRY *SadList;\r
1762 EFI_IPSEC_SA_ID *SaId;\r
9166f840 1763 EFI_IPSEC_SA_DATA2 *SaData;\r
a3bcde70
HT
1764 UINTN RequiredSize;\r
1765\r
1766 SaId = &Selector->SaId;\r
9166f840 1767 SaData = (EFI_IPSEC_SA_DATA2 *) Data;\r
a3bcde70
HT
1768 SadList = &mConfigData[IPsecConfigDataTypeSad];\r
1769\r
1770 NET_LIST_FOR_EACH (Entry, SadList) {\r
1771 SadEntry = IPSEC_SAD_ENTRY_FROM_LIST (Entry);\r
1772\r
1773 //\r
9166f840 1774 // Find the required SAD entry.\r
a3bcde70
HT
1775 //\r
1776 if (CompareSaId (\r
1777 (EFI_IPSEC_CONFIG_SELECTOR *) SaId,\r
1778 (EFI_IPSEC_CONFIG_SELECTOR *) SadEntry->Id\r
1779 )) {\r
1780 //\r
9166f840 1781 // Calculate the required size of the SAD entry.\r
a3bcde70
HT
1782 // Data Layout is follows:\r
1783 // |EFI_IPSEC_SA_DATA\r
1784 // |AuthKey\r
1785 // |EncryptKey (Optional)\r
9166f840 1786 // |SpdSelector (Optional) \r
1787 // \r
1788 RequiredSize = ALIGN_VARIABLE (sizeof (EFI_IPSEC_SA_DATA2));\r
a3bcde70
HT
1789\r
1790 if (SaId->Proto == EfiIPsecAH) {\r
1791 RequiredSize = ALIGN_VARIABLE (RequiredSize + SadEntry->Data->AlgoInfo.AhAlgoInfo.AuthKeyLength);\r
1792 } else {\r
1793 RequiredSize = ALIGN_VARIABLE (RequiredSize + SadEntry->Data->AlgoInfo.EspAlgoInfo.AuthKeyLength);\r
1794 RequiredSize = ALIGN_VARIABLE (RequiredSize + SadEntry->Data->AlgoInfo.EspAlgoInfo.EncKeyLength);\r
1795 }\r
1796\r
9166f840 1797 if (SadEntry->Data->SpdSelector != NULL) {\r
1798 RequiredSize += SIZE_OF_SPD_SELECTOR (SadEntry->Data->SpdSelector);\r
a3bcde70 1799 }\r
9166f840 1800 \r
a3bcde70
HT
1801 if (*DataSize < RequiredSize) {\r
1802 *DataSize = RequiredSize;\r
1803 return EFI_BUFFER_TOO_SMALL;\r
1804 }\r
9166f840 1805 \r
a3bcde70 1806 //\r
9166f840 1807 // Fill the data fields of SAD entry.\r
a3bcde70
HT
1808 //\r
1809 *DataSize = RequiredSize;\r
1810 SaData->Mode = SadEntry->Data->Mode;\r
1811 SaData->SNCount = SadEntry->Data->SequenceNumber;\r
1812 SaData->AntiReplayWindows = SadEntry->Data->AntiReplayWindowSize;\r
1813\r
1814 CopyMem (\r
1815 &SaData->SaLifetime,\r
1816 &SadEntry->Data->SaLifetime,\r
1817 sizeof (EFI_IPSEC_SA_LIFETIME)\r
1818 );\r
1819\r
1820 ZeroMem (\r
1821 &SaData->AlgoInfo,\r
1822 sizeof (EFI_IPSEC_ALGO_INFO)\r
1823 );\r
1824\r
1825 if (SaId->Proto == EfiIPsecAH) {\r
1826 //\r
1827 // Copy AH alogrithm INFO to SaData\r
1828 //\r
1829 SaData->AlgoInfo.AhAlgoInfo.AuthAlgoId = SadEntry->Data->AlgoInfo.AhAlgoInfo.AuthAlgoId;\r
1830 SaData->AlgoInfo.AhAlgoInfo.AuthKeyLength = SadEntry->Data->AlgoInfo.AhAlgoInfo.AuthKeyLength;\r
1831 if (SaData->AlgoInfo.AhAlgoInfo.AuthKeyLength != 0) {\r
1832 SaData->AlgoInfo.AhAlgoInfo.AuthKey = (VOID *) ALIGN_POINTER ((SaData + 1), sizeof (UINTN));\r
1833 CopyMem (\r
1834 SaData->AlgoInfo.AhAlgoInfo.AuthKey,\r
1835 SadEntry->Data->AlgoInfo.AhAlgoInfo.AuthKey,\r
1836 SaData->AlgoInfo.AhAlgoInfo.AuthKeyLength\r
1837 );\r
1838 }\r
1839 } else if (SaId->Proto == EfiIPsecESP) {\r
1840 //\r
1841 // Copy ESP alogrithem INFO to SaData\r
1842 //\r
1843 SaData->AlgoInfo.EspAlgoInfo.AuthAlgoId = SadEntry->Data->AlgoInfo.EspAlgoInfo.AuthAlgoId;\r
1844 SaData->AlgoInfo.EspAlgoInfo.AuthKeyLength = SadEntry->Data->AlgoInfo.EspAlgoInfo.AuthKeyLength;\r
1845 if (SaData->AlgoInfo.EspAlgoInfo.AuthKeyLength != 0) {\r
1846 SaData->AlgoInfo.EspAlgoInfo.AuthKey = (VOID *) ALIGN_POINTER ((SaData + 1), sizeof (UINTN));\r
1847 CopyMem (\r
1848 SaData->AlgoInfo.EspAlgoInfo.AuthKey,\r
1849 SadEntry->Data->AlgoInfo.EspAlgoInfo.AuthKey,\r
1850 SaData->AlgoInfo.EspAlgoInfo.AuthKeyLength\r
1851 );\r
1852 }\r
1853\r
1854 SaData->AlgoInfo.EspAlgoInfo.EncAlgoId = SadEntry->Data->AlgoInfo.EspAlgoInfo.EncAlgoId;\r
1855 SaData->AlgoInfo.EspAlgoInfo.EncKeyLength = SadEntry->Data->AlgoInfo.EspAlgoInfo.EncKeyLength;\r
1856\r
1857 if (SaData->AlgoInfo.EspAlgoInfo.EncKeyLength != 0) {\r
1858 SaData->AlgoInfo.EspAlgoInfo.EncKey = (VOID *) ALIGN_POINTER (\r
1859 ((UINT8 *) (SaData + 1) +\r
1860 SaData->AlgoInfo.EspAlgoInfo.AuthKeyLength),\r
1861 sizeof (UINTN)\r
1862 );\r
1863 CopyMem (\r
1864 SaData->AlgoInfo.EspAlgoInfo.EncKey,\r
1865 SadEntry->Data->AlgoInfo.EspAlgoInfo.EncKey,\r
1866 SaData->AlgoInfo.EspAlgoInfo.EncKeyLength\r
1867 );\r
1868 }\r
1869 }\r
1870\r
1871 SaData->PathMTU = SadEntry->Data->PathMTU;\r
1872\r
1873 //\r
9166f840 1874 // Fill Tunnel Address if it is Tunnel Mode\r
a3bcde70 1875 //\r
9166f840 1876 if (SadEntry->Data->Mode == EfiIPsecTunnel) {\r
1877 CopyMem (\r
1878 &SaData->TunnelDestinationAddress,\r
1879 &SadEntry->Data->TunnelDestAddress,\r
1880 sizeof (EFI_IP_ADDRESS)\r
1881 );\r
1882 CopyMem (\r
1883 &SaData->TunnelSourceAddress,\r
1884 &SadEntry->Data->TunnelSourceAddress,\r
1885 sizeof (EFI_IP_ADDRESS)\r
1886 );\r
1887 }\r
1888 //\r
1889 // Fill the spd selector field of SAD data\r
1890 //\r
1891 if (SadEntry->Data->SpdSelector != NULL) {\r
a3bcde70
HT
1892\r
1893 SaData->SpdSelector = (EFI_IPSEC_SPD_SELECTOR *) (\r
1894 (UINT8 *)SaData +\r
1895 RequiredSize -\r
9166f840 1896 SIZE_OF_SPD_SELECTOR (SadEntry->Data->SpdSelector)\r
a3bcde70 1897 );\r
9166f840 1898 \r
a3bcde70
HT
1899 DuplicateSpdSelector (\r
1900 (EFI_IPSEC_CONFIG_SELECTOR *) SaData->SpdSelector,\r
9166f840 1901 (EFI_IPSEC_CONFIG_SELECTOR *) SadEntry->Data->SpdSelector,\r
a3bcde70
HT
1902 NULL\r
1903 );\r
1904\r
1905 } else {\r
1906\r
1907 SaData->SpdSelector = NULL;\r
1908 }\r
1909\r
1910 SaData->ManualSet = SadEntry->Data->ManualSet;\r
1911\r
1912 return EFI_SUCCESS;\r
1913 }\r
1914 }\r
1915\r
1916 return EFI_NOT_FOUND;\r
1917}\r
1918\r
1919/**\r
9166f840 1920 This function lookup the data entry from IPsec PAD. Return the configuration \r
a3bcde70
HT
1921 value of the specified PAD Entry.\r
1922\r
9166f840 1923 @param[in] Selector Pointer to an entry selector which is an identifier \r
a3bcde70
HT
1924 of the PAD entry.\r
1925 @param[in, out] DataSize On output the size of data returned in Data.\r
9166f840 1926 @param[out] Data The buffer to return the contents of the IPsec \r
1927 configuration data. The type of the data buffer \r
1928 is associated with the DataType. \r
1929 \r
a3bcde70
HT
1930 @retval EFI_SUCCESS The specified configuration data was obtained successfully.\r
1931 @retval EFI_NOT_FOUND The configuration data specified by Selector is not found.\r
1932 @retval EFI_BUFFER_TOO_SMALL The DataSize is too small for the result. DataSize has been\r
1933 updated with the size needed to complete the request.\r
1934\r
1935**/\r
1936EFI_STATUS\r
1937GetPadEntry (\r
1938 IN EFI_IPSEC_CONFIG_SELECTOR *Selector,\r
1939 IN OUT UINTN *DataSize,\r
1940 OUT VOID *Data\r
1941 )\r
1942{\r
1943 IPSEC_PAD_ENTRY *PadEntry;\r
1944 LIST_ENTRY *PadList;\r
1945 LIST_ENTRY *Entry;\r
1946 EFI_IPSEC_PAD_ID *PadId;\r
1947 EFI_IPSEC_PAD_DATA *PadData;\r
1948 UINTN RequiredSize;\r
1949\r
1950 PadId = &Selector->PadId;\r
1951 PadData = (EFI_IPSEC_PAD_DATA *) Data;\r
1952 PadList = &mConfigData[IPsecConfigDataTypePad];\r
1953\r
1954 NET_LIST_FOR_EACH (Entry, PadList) {\r
1955 PadEntry = IPSEC_PAD_ENTRY_FROM_LIST (Entry);\r
1956\r
1957 //\r
1958 // Find the required pad entry.\r
1959 //\r
1960 if (ComparePadId (\r
1961 (EFI_IPSEC_CONFIG_SELECTOR *) PadId,\r
1962 (EFI_IPSEC_CONFIG_SELECTOR *) PadEntry->Id\r
1963 )) {\r
1964 //\r
1965 // Calculate the required size of the pad entry.\r
1966 //\r
1967 RequiredSize = ALIGN_VARIABLE (sizeof (EFI_IPSEC_PAD_DATA));\r
1968 RequiredSize = ALIGN_VARIABLE (RequiredSize + PadEntry->Data->AuthDataSize);\r
1969 RequiredSize += PadEntry->Data->RevocationDataSize;\r
1970\r
1971 if (*DataSize < RequiredSize) {\r
1972 *DataSize = RequiredSize;\r
1973 return EFI_BUFFER_TOO_SMALL;\r
1974 }\r
1975 //\r
1976 // Fill the data fields of pad entry\r
1977 //\r
1978 *DataSize = RequiredSize;\r
1979 PadData->AuthProtocol = PadEntry->Data->AuthProtocol;\r
1980 PadData->AuthMethod = PadEntry->Data->AuthMethod;\r
1981 PadData->IkeIdFlag = PadEntry->Data->IkeIdFlag;\r
1982\r
1983 //\r
1984 // Copy Authentication data.\r
1985 //\r
1986 if (PadEntry->Data->AuthData != NULL) {\r
1987\r
1988 PadData->AuthDataSize = PadEntry->Data->AuthDataSize;\r
1989 PadData->AuthData = (VOID *) ALIGN_POINTER ((PadData + 1), sizeof (UINTN));\r
1990 CopyMem (\r
1991 PadData->AuthData,\r
1992 PadEntry->Data->AuthData,\r
1993 PadData->AuthDataSize\r
1994 );\r
1995 } else {\r
1996\r
1997 PadData->AuthDataSize = 0;\r
1998 PadData->AuthData = NULL;\r
1999 }\r
2000 //\r
2001 // Copy Revocation Data.\r
2002 //\r
2003 if (PadEntry->Data->RevocationData != NULL) {\r
2004\r
2005 PadData->RevocationDataSize = PadEntry->Data->RevocationDataSize;\r
2006 PadData->RevocationData = (VOID *) ALIGN_POINTER (\r
2007 ((UINT8 *) (PadData + 1) + PadData->AuthDataSize),\r
2008 sizeof (UINTN)\r
2009 );\r
2010 CopyMem (\r
2011 PadData->RevocationData,\r
2012 PadEntry->Data->RevocationData,\r
2013 PadData->RevocationDataSize\r
2014 );\r
2015 } else {\r
2016\r
2017 PadData->RevocationDataSize = 0;\r
2018 PadData->RevocationData = NULL;\r
2019 }\r
2020\r
2021 return EFI_SUCCESS;\r
2022 }\r
2023 }\r
2024\r
2025 return EFI_NOT_FOUND;\r
2026}\r
2027\r
2028/**\r
2029 Copy Source Process Policy to the Destination Process Policy.\r
2030\r
2031 @param[in] Dst Pointer to the Source Process Policy.\r
2032 @param[in] Src Pointer to the Destination Process Policy.\r
2033\r
2034**/\r
2035VOID\r
2036IpSecDuplicateProcessPolicy (\r
2037 IN EFI_IPSEC_PROCESS_POLICY *Dst,\r
2038 IN EFI_IPSEC_PROCESS_POLICY *Src\r
2039 )\r
2040{\r
2041 //\r
2042 // Firstly copy the structure content itself.\r
2043 //\r
2044 CopyMem (Dst, Src, sizeof (EFI_IPSEC_PROCESS_POLICY));\r
2045\r
2046 //\r
2047 // Recursively copy the tunnel option if needed.\r
2048 //\r
2049 if (Dst->Mode != EfiIPsecTunnel) {\r
2050 ASSERT (Dst->TunnelOption == NULL);\r
2051 } else {\r
2052 Dst->TunnelOption = (EFI_IPSEC_TUNNEL_OPTION *) ALIGN_POINTER ((Dst + 1), sizeof (UINTN));\r
2053 CopyMem (\r
2054 Dst->TunnelOption,\r
2055 Src->TunnelOption,\r
2056 sizeof (EFI_IPSEC_TUNNEL_OPTION)\r
2057 );\r
2058 }\r
2059}\r
2060\r
2061/**\r
2062 Calculate the a whole size of EFI_IPSEC_SPD_DATA, which includes the buffer size pointed\r
2063 to by the pointer members.\r
2064\r
2065 @param[in] SpdData Pointer to a specified EFI_IPSEC_SPD_DATA.\r
2066\r
2067 @return the whole size the specified EFI_IPSEC_SPD_DATA.\r
2068\r
2069**/\r
2070UINTN\r
2071IpSecGetSizeOfEfiSpdData (\r
2072 IN EFI_IPSEC_SPD_DATA *SpdData\r
2073 )\r
2074{\r
2075 UINTN Size;\r
2076\r
2077 Size = ALIGN_VARIABLE (sizeof (IPSEC_SPD_DATA));\r
2078\r
2079 if (SpdData->Action == EfiIPsecActionProtect) {\r
2080 Size = ALIGN_VARIABLE (Size + sizeof (EFI_IPSEC_PROCESS_POLICY));\r
2081\r
2082 if (SpdData->ProcessingPolicy->Mode == EfiIPsecTunnel) {\r
2083 Size = ALIGN_VARIABLE (Size + sizeof (EFI_IPSEC_TUNNEL_OPTION));\r
2084 }\r
2085 }\r
2086\r
2087 return Size;\r
2088}\r
2089\r
2090/**\r
2091 Calculate the a whole size of IPSEC_SPD_DATA which includes the buffer size pointed\r
9166f840 2092 to by the pointer members and the buffer size used by the Sa List. \r
a3bcde70
HT
2093\r
2094 @param[in] SpdData Pointer to the specified IPSEC_SPD_DATA.\r
2095\r
2096 @return the whole size of IPSEC_SPD_DATA.\r
2097\r
2098**/\r
2099UINTN\r
2100IpSecGetSizeOfSpdData (\r
2101 IN IPSEC_SPD_DATA *SpdData\r
2102 )\r
2103{\r
2104 UINTN Size;\r
2105 LIST_ENTRY *Link;\r
2106\r
2107 Size = sizeof (EFI_IPSEC_SPD_DATA) - sizeof (EFI_IPSEC_SA_ID);\r
2108\r
2109 if (SpdData->Action == EfiIPsecActionProtect) {\r
2110 Size += sizeof (EFI_IPSEC_PROCESS_POLICY);\r
2111\r
2112 if (SpdData->ProcessingPolicy->Mode == EfiIPsecTunnel) {\r
2113 Size += sizeof (EFI_IPSEC_TUNNEL_OPTION);\r
2114 }\r
2115 }\r
2116\r
2117 NET_LIST_FOR_EACH (Link, &SpdData->Sas) {\r
2118 Size += sizeof (EFI_IPSEC_SA_ID);\r
2119 }\r
2120\r
2121 return Size;\r
2122}\r
2123\r
2124/**\r
2125 Get the IPsec Variable.\r
2126\r
2127 Get the all variables which start with the string contained in VaraiableName.\r
9166f840 2128 Since all IPsec related variable store in continual space, those kinds of \r
2129 variable can be searched by the EfiGetNextVariableName. Those variables also are \r
a3bcde70 2130 returned in a continual buffer.\r
9166f840 2131 \r
a3bcde70
HT
2132 @param[in] VariableName Pointer to a specified Variable Name.\r
2133 @param[in] VendorGuid Pointer to a specified Vendor Guid.\r
9166f840 2134 @param[in] Attributes Point to memory location to return the attributes \r
2135 of variable. If the point is NULL, the parameter \r
a3bcde70 2136 would be ignored.\r
9166f840 2137 @param[in, out] DataSize As input, point to the maximum size of return \r
2138 Data-Buffer. As output, point to the actual \r
a3bcde70
HT
2139 size of the returned Data-Buffer.\r
2140 @param[in] Data Point to return Data-Buffer.\r
9166f840 2141 \r
a3bcde70 2142 @retval EFI_ABORTED If the Variable size which contained in the variable\r
9166f840 2143 structure doesn't match the variable size obtained \r
a3bcde70
HT
2144 from the EFIGetVariable.\r
2145 @retval EFI_BUFFER_TOO_SMALL The DataSize is too small for the result. DataSize has\r
9166f840 2146 been updated with the size needed to complete the request. \r
a3bcde70
HT
2147 @retval EFI_SUCCESS The function completed successfully.\r
2148 @retval others Other errors found during the variable getting.\r
2149**/\r
2150EFI_STATUS\r
2151IpSecGetVariable (\r
2152 IN CHAR16 *VariableName,\r
2153 IN EFI_GUID *VendorGuid,\r
2154 IN UINT32 *Attributes, OPTIONAL\r
2155 IN OUT UINTN *DataSize,\r
2156 IN VOID *Data\r
2157 )\r
2158{\r
2159 EFI_STATUS Status;\r
2160 EFI_GUID VendorGuidI;\r
2161 UINTN VariableNameLength;\r
2162 CHAR16 *VariableNameI;\r
2163 UINTN VariableNameISize;\r
2164 UINTN VariableNameISizeNew;\r
2165 UINTN VariableIndex;\r
2166 UINTN VariableCount;\r
2167 IP_SEC_VARIABLE_INFO IpSecVariableInfo;\r
2168 UINTN DataSizeI;\r
2169\r
2170 //\r
2171 // The variable name constructor is "VariableName + Info/0001/0002/... + NULL".\r
2172 // So the varialbe name is like "VariableNameInfo", "VariableName0001", ...\r
2173 // "VariableNameNULL".\r
2174 //\r
2175 VariableNameLength = StrLen (VariableName);\r
2176 VariableNameISize = (VariableNameLength + 5) * sizeof (CHAR16);\r
2177 VariableNameI = AllocateZeroPool (VariableNameISize);\r
6b16c9e7
JW
2178 if (VariableNameI == NULL) {\r
2179 Status = EFI_OUT_OF_RESOURCES;\r
2180 goto ON_EXIT;\r
2181 }\r
9166f840 2182 \r
a3bcde70
HT
2183 //\r
2184 // Construct the varible name of ipsecconfig meta data.\r
2185 //\r
2186 UnicodeSPrint (VariableNameI, VariableNameISize, L"%s%s", VariableName, L"Info");\r
2187\r
2188 DataSizeI = sizeof (IpSecVariableInfo);\r
2189\r
2190 Status = gRT->GetVariable (\r
2191 VariableNameI,\r
2192 VendorGuid,\r
2193 Attributes,\r
2194 &DataSizeI,\r
2195 &IpSecVariableInfo\r
2196 );\r
2197 if (EFI_ERROR (Status)) {\r
2198 goto ON_EXIT;\r
2199 }\r
2200\r
2201 if (*DataSize < IpSecVariableInfo.VariableSize) {\r
2202 *DataSize = IpSecVariableInfo.VariableSize;\r
2203 Status = EFI_BUFFER_TOO_SMALL;\r
2204 goto ON_EXIT;\r
2205 }\r
2206\r
2207 VariableCount = IpSecVariableInfo.VariableCount;\r
2208 VariableNameI[0] = L'\0';\r
2209\r
2210 while (VariableCount != 0) {\r
2211 //\r
2212 // Get the variable name one by one in the variable database.\r
2213 //\r
2214 VariableNameISizeNew = VariableNameISize;\r
2215 Status = gRT->GetNextVariableName (\r
2216 &VariableNameISizeNew,\r
2217 VariableNameI,\r
2218 &VendorGuidI\r
2219 );\r
2220 if (Status == EFI_BUFFER_TOO_SMALL) {\r
2221 VariableNameI = ReallocatePool (\r
2222 VariableNameISize,\r
2223 VariableNameISizeNew,\r
2224 VariableNameI\r
2225 );\r
02a758cb 2226 if (VariableNameI == NULL) {\r
2227 Status = EFI_OUT_OF_RESOURCES;\r
2228 break;\r
2229 }\r
a3bcde70
HT
2230 VariableNameISize = VariableNameISizeNew;\r
2231\r
2232 Status = gRT->GetNextVariableName (\r
2233 &VariableNameISizeNew,\r
2234 VariableNameI,\r
2235 &VendorGuidI\r
2236 );\r
2237 }\r
2238\r
2239 if (EFI_ERROR (Status)) {\r
2240 break;\r
2241 }\r
2242 //\r
2243 // Check whether the current variable is the required "ipsecconfig".\r
2244 //\r
2245 if (StrnCmp (VariableNameI, VariableName, VariableNameLength) == 0 ||\r
2246 CompareGuid (VendorGuid, &VendorGuidI)\r
2247 ) {\r
2248 //\r
2249 // Parse the variable count of the current ipsecconfig data.\r
2250 //\r
2251 VariableIndex = StrDecimalToUintn (VariableNameI + VariableNameLength);\r
2252 if (VariableIndex!= 0 && VariableIndex <= IpSecVariableInfo.VariableCount) {\r
2253 //\r
2254 // Get the variable size of the current ipsecconfig data.\r
2255 //\r
2256 DataSizeI = 0;\r
2257 Status = gRT->GetVariable (\r
2258 VariableNameI,\r
2259 VendorGuid,\r
2260 Attributes,\r
2261 &DataSizeI,\r
2262 NULL\r
2263 );\r
2264 ASSERT (Status == EFI_BUFFER_TOO_SMALL);\r
2265 //\r
2266 // Validate the variable count and variable size.\r
2267 //\r
2268 if (VariableIndex != IpSecVariableInfo.VariableCount) {\r
2269 //\r
2270 // If the varaibe is not the last one, its size should be the max\r
2271 // size of the single variable.\r
2272 //\r
2273 if (DataSizeI != IpSecVariableInfo.SingleVariableSize) {\r
2274 return EFI_ABORTED;\r
2275 }\r
2276 } else {\r
2277 if (DataSizeI != IpSecVariableInfo.VariableSize % IpSecVariableInfo.SingleVariableSize) {\r
2278 return EFI_ABORTED;\r
2279 }\r
2280 }\r
2281 //\r
2282 // Get the variable data of the current ipsecconfig data and\r
2283 // store it into user buffer continously.\r
2284 //\r
2285 Status = gRT->GetVariable (\r
2286 VariableNameI,\r
2287 VendorGuid,\r
2288 Attributes,\r
2289 &DataSizeI,\r
2290 (UINT8 *) Data + (VariableIndex - 1) * IpSecVariableInfo.SingleVariableSize\r
2291 );\r
2292 ASSERT_EFI_ERROR (Status);\r
2293 VariableCount--;\r
2294 }\r
2295 }\r
2296 }\r
2297 //\r
2298 // The VariableCount in "VariableNameInfo" varaible should have the correct\r
2299 // numbers of variables which name starts with VariableName.\r
2300 //\r
2301 if (VariableCount != 0) {\r
2302 Status = EFI_ABORTED;\r
2303 }\r
2304\r
2305ON_EXIT:\r
02a758cb 2306 if (VariableNameI != NULL) {\r
2307 FreePool (VariableNameI);\r
2308 }\r
a3bcde70
HT
2309 return Status;\r
2310}\r
2311\r
2312/**\r
2313 Set the IPsec variables.\r
2314\r
2315 Set all IPsec variables which start with the specified variable name. Those variables\r
2316 are set one by one.\r
2317\r
2318 @param[in] VariableName The name of the vendor's variable. It is a\r
2319 Null-Terminated Unicode String.\r
2320 @param[in] VendorGuid Unify identifier for vendor.\r
9166f840 2321 @param[in] Attributes Point to memory location to return the attributes of \r
a3bcde70
HT
2322 variable. If the point is NULL, the parameter would be ignored.\r
2323 @param[in] DataSize The size in bytes of Data-Buffer.\r
2324 @param[in] Data Points to the content of the variable.\r
2325\r
2326 @retval EFI_SUCCESS The firmware successfully stored the variable and its data, as\r
2327 defined by the Attributes.\r
9166f840 2328 @retval others Storing the variables failed. \r
a3bcde70
HT
2329\r
2330**/\r
2331EFI_STATUS\r
2332IpSecSetVariable (\r
2333 IN CHAR16 *VariableName,\r
2334 IN EFI_GUID *VendorGuid,\r
2335 IN UINT32 Attributes,\r
2336 IN UINTN DataSize,\r
2337 IN VOID *Data\r
2338 )\r
2339{\r
2340 EFI_STATUS Status;\r
2341 CHAR16 *VariableNameI;\r
2342 UINTN VariableNameSize;\r
2343 UINTN VariableIndex;\r
2344 IP_SEC_VARIABLE_INFO IpSecVariableInfo;\r
2345 UINT64 MaximumVariableStorageSize;\r
2346 UINT64 RemainingVariableStorageSize;\r
2347 UINT64 MaximumVariableSize;\r
2348\r
2349 Status = gRT->QueryVariableInfo (\r
2350 Attributes,\r
2351 &MaximumVariableStorageSize,\r
2352 &RemainingVariableStorageSize,\r
2353 &MaximumVariableSize\r
2354 );\r
2355 if (EFI_ERROR (Status)) {\r
2356 return Status;\r
2357 }\r
9166f840 2358 \r
a3bcde70
HT
2359 //\r
2360 // "VariableName + Info/0001/0002/... + NULL"\r
2361 //\r
2362 VariableNameSize = (StrLen (VariableName) + 5) * sizeof (CHAR16);\r
2363 VariableNameI = AllocateZeroPool (VariableNameSize);\r
2364\r
2365 if (VariableNameI == NULL) {\r
2366 Status = EFI_OUT_OF_RESOURCES;\r
2367 goto ON_EXIT;\r
2368 }\r
2369 //\r
2370 // Construct the variable of ipsecconfig general information. Like the total\r
2371 // numbers of the Ipsecconfig variables, the total size of all ipsecconfig variables.\r
2372 //\r
2373 UnicodeSPrint (VariableNameI, VariableNameSize, L"%s%s", VariableName, L"Info");\r
2374 MaximumVariableSize -= VariableNameSize;\r
9166f840 2375 \r
a3bcde70
HT
2376 IpSecVariableInfo.VariableCount = (UINT32) ((DataSize + (UINTN) MaximumVariableSize - 1) / (UINTN) MaximumVariableSize);\r
2377 IpSecVariableInfo.VariableSize = (UINT32) DataSize;\r
2378 IpSecVariableInfo.SingleVariableSize = (UINT32) MaximumVariableSize;\r
2379\r
2380 //\r
2381 // Set the variable of ipsecconfig general information.\r
2382 //\r
2383 Status = gRT->SetVariable (\r
2384 VariableNameI,\r
2385 VendorGuid,\r
2386 Attributes,\r
2387 sizeof (IpSecVariableInfo),\r
2388 &IpSecVariableInfo\r
2389 );\r
2390 if (EFI_ERROR (Status)) {\r
2391 DEBUG ((DEBUG_ERROR, "Error set ipsecconfig meta data with %r\n", Status));\r
2392 goto ON_EXIT;\r
2393 }\r
2394\r
2395 for (VariableIndex = 0; VariableIndex < IpSecVariableInfo.VariableCount; VariableIndex++) {\r
2396 //\r
2397 // Construct and set the variable of ipsecconfig data one by one.\r
2398 // The index of variable name begin from 0001, and the varaible name\r
2399 // likes "VariableName0001", "VaraiableName0002"....\r
9166f840 2400 // \r
a3bcde70
HT
2401 UnicodeSPrint (VariableNameI, VariableNameSize, L"%s%04d", VariableName, VariableIndex + 1);\r
2402 Status = gRT->SetVariable (\r
2403 VariableNameI,\r
2404 VendorGuid,\r
2405 Attributes,\r
2406 (VariableIndex == IpSecVariableInfo.VariableCount - 1) ?\r
2407 (DataSize % (UINTN) MaximumVariableSize) :\r
2408 (UINTN) MaximumVariableSize,\r
2409 (UINT8 *) Data + VariableIndex * (UINTN) MaximumVariableSize\r
2410 );\r
2411\r
2412 if (EFI_ERROR (Status)) {\r
2413 DEBUG ((DEBUG_ERROR, "Error set ipsecconfig variable data with %r\n", Status));\r
2414 goto ON_EXIT;\r
2415 }\r
2416 }\r
2417\r
2418ON_EXIT:\r
2419 if (VariableNameI != NULL) {\r
2420 FreePool (VariableNameI);\r
2421 }\r
2422\r
2423 return Status;\r
2424}\r
2425\r
2426/**\r
9166f840 2427 Return the configuration value for the EFI IPsec driver. \r
a3bcde70
HT
2428\r
2429 This function lookup the data entry from IPsec database or IKEv2 configuration\r
2430 information. The expected data type and unique identification are described in\r
9166f840 2431 DataType and Selector parameters. \r
a3bcde70
HT
2432\r
2433 @param[in] This Pointer to the EFI_IPSEC_CONFIG_PROTOCOL instance.\r
2434 @param[in] DataType The type of data to retrieve.\r
9166f840 2435 @param[in] Selector Pointer to an entry selector that is an identifier of the IPsec \r
a3bcde70
HT
2436 configuration data entry.\r
2437 @param[in, out] DataSize On output the size of data returned in Data.\r
9166f840 2438 @param[out] Data The buffer to return the contents of the IPsec configuration data. \r
2439 The type of the data buffer associated with the DataType. \r
2440 \r
a3bcde70
HT
2441 @retval EFI_SUCCESS The specified configuration data was obtained successfully.\r
2442 @retval EFI_INVALID_PARAMETER One or more of the followings are TRUE:\r
2443 - This is NULL.\r
2444 - Selector is NULL.\r
2445 - DataSize is NULL.\r
2446 - Data is NULL and *DataSize is not zero\r
2447 @retval EFI_NOT_FOUND The configuration data specified by Selector is not found.\r
2448 @retval EFI_UNSUPPORTED The specified DataType is not supported.\r
2449 @retval EFI_BUFFER_TOO_SMALL The DataSize is too small for the result. DataSize has been\r
2450 updated with the size needed to complete the request.\r
2451\r
2452**/\r
2453EFI_STATUS\r
2454EFIAPI\r
2455EfiIpSecConfigGetData (\r
2456 IN EFI_IPSEC_CONFIG_PROTOCOL *This,\r
2457 IN EFI_IPSEC_CONFIG_DATA_TYPE DataType,\r
2458 IN EFI_IPSEC_CONFIG_SELECTOR *Selector,\r
2459 IN OUT UINTN *DataSize,\r
2460 OUT VOID *Data\r
2461 )\r
2462{\r
2463 if (This == NULL || Selector == NULL || DataSize == NULL) {\r
2464 return EFI_INVALID_PARAMETER;\r
2465 }\r
2466\r
2467 if (*DataSize != 0 && Data == NULL) {\r
2468 return EFI_INVALID_PARAMETER;\r
2469 }\r
2470\r
2471 if (DataType >= IPsecConfigDataTypeMaximum) {\r
2472 return EFI_UNSUPPORTED;\r
2473 }\r
2474\r
2475 return mGetPolicyEntry[DataType](Selector, DataSize, Data);\r
2476}\r
2477\r
2478/**\r
2479 Set the security association, security policy and peer authorization configuration\r
9166f840 2480 information for the EFI IPsec driver. \r
a3bcde70
HT
2481\r
2482 This function is used to set the IPsec configuration information of type DataType for\r
2483 the EFI IPsec driver.\r
2484 The IPsec configuration data has a unique selector/identifier separately to identify\r
2485 a data entry. The selector structure depends on DataType's definition.\r
2486 Using SetData() with a Data of NULL causes the IPsec configuration data entry identified\r
9166f840 2487 by DataType and Selector to be deleted. \r
a3bcde70
HT
2488\r
2489 @param[in] This Pointer to the EFI_IPSEC_CONFIG_PROTOCOL instance.\r
2490 @param[in] DataType The type of data to be set.\r
9166f840 2491 @param[in] Selector Pointer to an entry selector on operated configuration data \r
2492 specified by DataType. A NULL Selector causes the entire \r
a3bcde70 2493 specified-type configuration information to be flushed.\r
9166f840 2494 @param[in] Data The data buffer to be set. The structure of the data buffer is \r
a3bcde70
HT
2495 associated with the DataType.\r
2496 @param[in] InsertBefore Pointer to one entry selector which describes the expected\r
2497 position the new data entry will be added. If InsertBefore is NULL,\r
2498 the new entry will be appended to the end of the database.\r
9166f840 2499 \r
a3bcde70
HT
2500 @retval EFI_SUCCESS The specified configuration entry data was set successfully.\r
2501 @retval EFI_INVALID_PARAMETER One or more of the following are TRUE:\r
2502 - This is NULL.\r
2503 @retval EFI_UNSUPPORTED The specified DataType is not supported.\r
2504 @retval EFI_OUT_OF_RESOURCED The required system resource could not be allocated.\r
2505\r
2506**/\r
2507EFI_STATUS\r
2508EFIAPI\r
2509EfiIpSecConfigSetData (\r
2510 IN EFI_IPSEC_CONFIG_PROTOCOL *This,\r
2511 IN EFI_IPSEC_CONFIG_DATA_TYPE DataType,\r
2512 IN EFI_IPSEC_CONFIG_SELECTOR *Selector,\r
2513 IN VOID *Data,\r
2514 IN EFI_IPSEC_CONFIG_SELECTOR *InsertBefore OPTIONAL\r
2515 )\r
2516{\r
2517 EFI_STATUS Status;\r
2518\r
2519 if (This == NULL) {\r
2520 return EFI_INVALID_PARAMETER;\r
2521 }\r
2522\r
2523 if (DataType >= IPsecConfigDataTypeMaximum) {\r
2524 return EFI_UNSUPPORTED;\r
2525 }\r
9166f840 2526 \r
a3bcde70
HT
2527 Status = mSetPolicyEntry[DataType](Selector, Data, InsertBefore);\r
2528\r
2529 if (!EFI_ERROR (Status) && !mSetBySelf) {\r
2530 //\r
2531 // Save the updated config data into variable.\r
2532 //\r
2533 IpSecConfigSave ();\r
2534 }\r
2535\r
2536 return Status;\r
2537}\r
2538\r
2539/**\r
9166f840 2540 Enumerates the current selector for IPsec configuration data entry. \r
a3bcde70
HT
2541\r
2542 This function is called multiple times to retrieve the entry Selector in IPsec\r
9166f840 2543 configuration database. On each call to GetNextSelector(), the next entry \r
a3bcde70 2544 Selector are retrieved into the output interface.\r
9166f840 2545 \r
2546 If the entire IPsec configuration database has been iterated, the error \r
a3bcde70 2547 EFI_NOT_FOUND is returned.\r
9166f840 2548 If the Selector buffer is too small for the next Selector copy, an \r
2549 EFI_BUFFER_TOO_SMALL error is returned, and SelectorSize is updated to reflect \r
a3bcde70
HT
2550 the size of buffer needed.\r
2551\r
2552 On the initial call to GetNextSelector() to start the IPsec configuration database\r
9166f840 2553 search, a pointer to the buffer with all zero value is passed in Selector. Calls \r
2554 to SetData() between calls to GetNextSelector may produce unpredictable results. \r
a3bcde70
HT
2555\r
2556 @param[in] This Pointer to the EFI_IPSEC_CONFIG_PROTOCOL instance.\r
2557 @param[in] DataType The type of IPsec configuration data to retrieve.\r
2558 @param[in, out] SelectorSize The size of the Selector buffer.\r
9166f840 2559 @param[in, out] Selector On input, supplies the pointer to last Selector that was \r
a3bcde70
HT
2560 returned by GetNextSelector().\r
2561 On output, returns one copy of the current entry Selector\r
9166f840 2562 of a given DataType. \r
2563 \r
a3bcde70
HT
2564 @retval EFI_SUCCESS The specified configuration data was obtained successfully.\r
2565 @retval EFI_INVALID_PARAMETER One or more of the followings are TRUE:\r
2566 - This is NULL.\r
2567 - SelectorSize is NULL.\r
2568 - Selector is NULL.\r
2569 @retval EFI_NOT_FOUND The next configuration data entry was not found.\r
2570 @retval EFI_UNSUPPORTED The specified DataType is not supported.\r
2571 @retval EFI_BUFFER_TOO_SMALL The SelectorSize is too small for the result. This parameter\r
9166f840 2572 has been updated with the size needed to complete the search \r
a3bcde70
HT
2573 request.\r
2574\r
2575**/\r
2576EFI_STATUS\r
2577EFIAPI\r
2578EfiIpSecConfigGetNextSelector (\r
2579 IN EFI_IPSEC_CONFIG_PROTOCOL *This,\r
2580 IN EFI_IPSEC_CONFIG_DATA_TYPE DataType,\r
2581 IN OUT UINTN *SelectorSize,\r
2582 IN OUT EFI_IPSEC_CONFIG_SELECTOR *Selector\r
2583 )\r
2584{\r
2585 LIST_ENTRY *Link;\r
2586 IPSEC_COMMON_POLICY_ENTRY *CommonEntry;\r
2587 BOOLEAN IsFound;\r
2588\r
2589 if (This == NULL || Selector == NULL || SelectorSize == NULL) {\r
2590 return EFI_INVALID_PARAMETER;\r
2591 }\r
2592\r
2593 if (DataType >= IPsecConfigDataTypeMaximum) {\r
2594 return EFI_UNSUPPORTED;\r
2595 }\r
2596\r
2597 IsFound = FALSE;\r
2598\r
2599 NET_LIST_FOR_EACH (Link, &mConfigData[DataType]) {\r
2600 CommonEntry = BASE_CR (Link, IPSEC_COMMON_POLICY_ENTRY, List);\r
2601\r
68d3f2fb 2602 if (IsFound || (BOOLEAN)(mIsZeroSelector[DataType](Selector))) {\r
a3bcde70
HT
2603 //\r
2604 // If found the appointed entry, then duplicate the next one and return,\r
2605 // or if the appointed entry is zero, then return the first one directly.\r
2606 //\r
2607 return mDuplicateSelector[DataType](Selector, CommonEntry->Selector, SelectorSize);\r
2608 } else {\r
2609 //\r
2610 // Set the flag if find the appointed entry.\r
2611 //\r
2612 IsFound = mCompareSelector[DataType](Selector, CommonEntry->Selector);\r
2613 }\r
2614 }\r
2615\r
2616 return EFI_NOT_FOUND;\r
2617}\r
2618\r
2619/**\r
2620 Register an event that is to be signaled whenever a configuration process on the\r
9166f840 2621 specified IPsec configuration information is done. \r
a3bcde70
HT
2622\r
2623 The register function is not surpport now and always returns EFI_UNSUPPORTED.\r
9166f840 2624 \r
a3bcde70
HT
2625 @param[in] This Pointer to the EFI_IPSEC_CONFIG_PROTOCOL instance.\r
2626 @param[in] DataType The type of data to be registered the event for.\r
2627 @param[in] Event The event to be registered.\r
9166f840 2628 \r
a3bcde70
HT
2629 @retval EFI_SUCCESS The event is registered successfully.\r
2630 @retval EFI_INVALID_PARAMETER This is NULL or Event is NULL.\r
2631 @retval EFI_ACCESS_DENIED The Event is already registered for the DataType.\r
2632 @retval EFI_UNSUPPORTED The notify registration is unsupported, or the specified\r
2633 DataType is not supported.\r
2634\r
2635**/\r
2636EFI_STATUS\r
2637EFIAPI\r
2638EfiIpSecConfigRegisterNotify (\r
2639 IN EFI_IPSEC_CONFIG_PROTOCOL *This,\r
2640 IN EFI_IPSEC_CONFIG_DATA_TYPE DataType,\r
2641 IN EFI_EVENT Event\r
2642 )\r
2643{\r
2644 return EFI_UNSUPPORTED;\r
2645}\r
2646\r
2647/**\r
2648 Remove the specified event that was previously registered on the specified IPsec\r
9166f840 2649 configuration data. \r
a3bcde70
HT
2650\r
2651 This function is not support now and alwasy return EFI_UNSUPPORTED.\r
2652\r
2653 @param[in] This Pointer to the EFI_IPSEC_CONFIG_PROTOCOL instance.\r
2654 @param[in] DataType The configuration data type to remove the registered event for.\r
2655 @param[in] Event The event to be unregistered.\r
9166f840 2656 \r
a3bcde70 2657 @retval EFI_SUCCESS The event was removed successfully.\r
9166f840 2658 @retval EFI_NOT_FOUND The Event specified by DataType could not be found in the \r
a3bcde70
HT
2659 database.\r
2660 @retval EFI_INVALID_PARAMETER This is NULL or Event is NULL.\r
2661 @retval EFI_UNSUPPORTED The notify registration is unsupported, or the specified\r
2662 DataType is not supported.\r
2663\r
2664**/\r
2665EFI_STATUS\r
2666EFIAPI\r
2667EfiIpSecConfigUnregisterNotify (\r
2668 IN EFI_IPSEC_CONFIG_PROTOCOL *This,\r
2669 IN EFI_IPSEC_CONFIG_DATA_TYPE DataType,\r
2670 IN EFI_EVENT Event\r
2671 )\r
2672{\r
2673 return EFI_UNSUPPORTED;\r
2674}\r
2675\r
2676/**\r
2677 Copy whole data in specified EFI_SIPEC_CONFIG_SELECTOR and the Data to a buffer.\r
2678\r
2679 This function is a caller defined function, and it is called by the IpSecVisitConfigData().\r
9166f840 2680 The orignal caller is IpSecConfigSave(), which calls the IpsecVisitConfigData() to \r
a3bcde70
HT
2681 copy all types of IPsec Config datas into one buffer and store this buffer into firmware in\r
2682 the form of several variables.\r
9166f840 2683 \r
a3bcde70
HT
2684 @param[in] Type A specified IPSEC_CONFIG_DATA_TYPE.\r
2685 @param[in] Selector Points to a EFI_IPSEC_CONFIG_SELECTOR to be copied\r
2686 to the buffer.\r
2687 @param[in] Data Points to data to be copied to the buffer. The\r
2688 Data type is related to the Type.\r
2689 @param[in] SelectorSize The size of the Selector.\r
2690 @param[in] DataSize The size of the Data.\r
2691 @param[in, out] Buffer The buffer to store the Selector and Data.\r
2692\r
2693 @retval EFI_SUCCESS Copy the Selector and Data to a buffer successfully.\r
2694 @retval EFI_OUT_OF_RESOURCES The required system resource could not be allocated.\r
2695\r
2696**/\r
2697EFI_STATUS\r
2698IpSecCopyPolicyEntry (\r
2699 IN EFI_IPSEC_CONFIG_DATA_TYPE Type,\r
2700 IN EFI_IPSEC_CONFIG_SELECTOR *Selector,\r
2701 IN VOID *Data,\r
2702 IN UINTN SelectorSize,\r
2703 IN UINTN DataSize,\r
2704 IN OUT IPSEC_VARIABLE_BUFFER *Buffer\r
2705 )\r
2706{\r
2707 IPSEC_VAR_ITEM_HEADER SelectorHeader;\r
2708 IPSEC_VAR_ITEM_HEADER DataHeader;\r
2709 UINTN EntrySize;\r
2710 UINT8 *TempPoint;\r
9166f840 2711 \r
a3bcde70
HT
2712 if (Type == IPsecConfigDataTypeSad) {\r
2713 //\r
9166f840 2714 // Don't save automatically-generated SA entry into variable.\r
a3bcde70 2715 //\r
9166f840 2716 if (((EFI_IPSEC_SA_DATA2 *) Data)->ManualSet == FALSE) {\r
a3bcde70
HT
2717 return EFI_SUCCESS;\r
2718 }\r
2719 }\r
2720 //\r
2721 // Increase the capacity size of the buffer if needed.\r
2722 //\r
2723 EntrySize = ALIGN_VARIABLE (sizeof (SelectorHeader));\r
2724 EntrySize = ALIGN_VARIABLE (EntrySize + SelectorSize);\r
2725 EntrySize = ALIGN_VARIABLE (EntrySize + sizeof (SelectorHeader));\r
2726 EntrySize = ALIGN_VARIABLE (EntrySize + DataSize);\r
9166f840 2727 \r
a3bcde70
HT
2728 //EntrySize = SelectorSize + DataSize + 2 * sizeof (SelectorHeader);\r
2729 if (Buffer->Capacity - Buffer->Size < EntrySize) {\r
2730 //\r
2731 // Calculate the required buffer\r
2732 //\r
2733 Buffer->Capacity += EntrySize;\r
2734 TempPoint = AllocatePool (Buffer->Capacity);\r
9166f840 2735 \r
02a758cb 2736 if (TempPoint == NULL) {\r
a3bcde70
HT
2737 return EFI_OUT_OF_RESOURCES;\r
2738 }\r
2739 //\r
2740 // Copy the old Buffer to new buffer and free the old one.\r
2741 //\r
2742 CopyMem (TempPoint, Buffer->Ptr, Buffer->Size);\r
2743 FreePool (Buffer->Ptr);\r
9166f840 2744 \r
2745 Buffer->Ptr = TempPoint; \r
a3bcde70
HT
2746 }\r
2747\r
2748 mFixPolicyEntry[Type](Selector, Data);\r
2749\r
2750 //\r
2751 // Fill the selector header and copy it into buffer.\r
2752 //\r
2753 SelectorHeader.Type = (UINT8) (Type | IPSEC_VAR_ITEM_HEADER_LOGO_BIT);\r
2754 SelectorHeader.Size = (UINT16) SelectorSize;\r
2755\r
2756 CopyMem (\r
2757 Buffer->Ptr + Buffer->Size,\r
2758 &SelectorHeader,\r
2759 sizeof (SelectorHeader)\r
2760 );\r
2761 Buffer->Size = ALIGN_VARIABLE (Buffer->Size + sizeof (SelectorHeader));\r
9166f840 2762 \r
a3bcde70
HT
2763 //\r
2764 // Copy the selector into buffer.\r
2765 //\r
2766 CopyMem (\r
2767 Buffer->Ptr + Buffer->Size,\r
2768 Selector,\r
2769 SelectorSize\r
2770 );\r
2771 Buffer->Size = ALIGN_VARIABLE (Buffer->Size + SelectorSize);\r
2772\r
2773 //\r
2774 // Fill the data header and copy it into buffer.\r
2775 //\r
2776 DataHeader.Type = (UINT8) Type;\r
2777 DataHeader.Size = (UINT16) DataSize;\r
2778\r
2779 CopyMem (\r
2780 Buffer->Ptr + Buffer->Size,\r
2781 &DataHeader,\r
2782 sizeof (DataHeader)\r
2783 );\r
2784 Buffer->Size = ALIGN_VARIABLE (Buffer->Size + sizeof (DataHeader));\r
2785 //\r
2786 // Copy the data into buffer.\r
2787 //\r
2788 CopyMem (\r
2789 Buffer->Ptr + Buffer->Size,\r
2790 Data,\r
2791 DataSize\r
2792 );\r
2793 Buffer->Size = ALIGN_VARIABLE (Buffer->Size + DataSize);\r
9166f840 2794 \r
a3bcde70
HT
2795 mUnfixPolicyEntry[Type](Selector, Data);\r
2796\r
2797 return EFI_SUCCESS;\r
2798}\r
2799\r
2800/**\r
2801 Visit all IPsec Configurations of specified Type and call the caller defined\r
2802 interface.\r
2803\r
2804 @param[in] DataType The specified IPsec Config Data Type.\r
2805 @param[in] Routine The function defined by the caller.\r
2806 @param[in] Context The data passed to the Routine.\r
2807\r
2808 @retval EFI_OUT_OF_RESOURCES The required system resource could not be allocated\r
2809 @retval EFI_SUCCESS This function completed successfully.\r
2810\r
2811**/\r
2812EFI_STATUS\r
2813IpSecVisitConfigData (\r
2814 IN EFI_IPSEC_CONFIG_DATA_TYPE DataType,\r
2815 IN IPSEC_COPY_POLICY_ENTRY Routine,\r
2816 IN VOID *Context\r
2817 )\r
2818{\r
2819 EFI_STATUS GetNextStatus;\r
2820 EFI_STATUS GetDataStatus;\r
2821 EFI_STATUS RoutineStatus;\r
2822 EFI_IPSEC_CONFIG_SELECTOR *Selector;\r
2823 VOID *Data;\r
2824 UINTN SelectorSize;\r
2825 UINTN DataSize;\r
2826 UINTN SelectorBufferSize;\r
2827 UINTN DataBufferSize;\r
2828 BOOLEAN FirstGetNext;\r
2829\r
2830 FirstGetNext = TRUE;\r
2831 DataBufferSize = 0;\r
2832 Data = NULL;\r
2833 SelectorBufferSize = sizeof (EFI_IPSEC_CONFIG_SELECTOR);\r
2834 Selector = AllocateZeroPool (SelectorBufferSize);\r
2835\r
2836 if (Selector == NULL) {\r
2837 return EFI_OUT_OF_RESOURCES;\r
2838 }\r
2839\r
2840 while (TRUE) {\r
2841 //\r
2842 // Get the real size of the selector.\r
2843 //\r
2844 SelectorSize = SelectorBufferSize;\r
2845 GetNextStatus = EfiIpSecConfigGetNextSelector (\r
2846 &mIpSecConfigInstance,\r
2847 DataType,\r
2848 &SelectorSize,\r
2849 Selector\r
2850 );\r
2851 if (GetNextStatus == EFI_BUFFER_TOO_SMALL) {\r
2852 FreePool (Selector);\r
2853 SelectorBufferSize = SelectorSize;\r
2854 //\r
2855 // Allocate zero pool for the first selector, while store the last\r
2856 // selector content for the other selectors.\r
2857 //\r
2858 if (FirstGetNext) {\r
2859 Selector = AllocateZeroPool (SelectorBufferSize);\r
2860 } else {\r
2861 Selector = AllocateCopyPool (SelectorBufferSize, Selector);\r
2862 }\r
2863\r
2864 if (Selector == NULL) {\r
2865 return EFI_OUT_OF_RESOURCES;\r
2866 }\r
2867 //\r
2868 // Get the content of the selector.\r
2869 //\r
2870 GetNextStatus = EfiIpSecConfigGetNextSelector (\r
2871 &mIpSecConfigInstance,\r
2872 DataType,\r
2873 &SelectorSize,\r
2874 Selector\r
2875 );\r
2876 }\r
2877\r
2878 if (EFI_ERROR (GetNextStatus)) {\r
2879 break;\r
2880 }\r
2881\r
2882 FirstGetNext = FALSE;\r
2883\r
2884 //\r
2885 // Get the real size of the policy entry according to the selector.\r
2886 //\r
2887 DataSize = DataBufferSize;\r
2888 GetDataStatus = EfiIpSecConfigGetData (\r
2889 &mIpSecConfigInstance,\r
2890 DataType,\r
2891 Selector,\r
2892 &DataSize,\r
2893 Data\r
2894 );\r
2895 if (GetDataStatus == EFI_BUFFER_TOO_SMALL) {\r
2896 if (Data != NULL) {\r
2897 FreePool (Data);\r
2898 }\r
2899\r
2900 DataBufferSize = DataSize;\r
2901 Data = AllocateZeroPool (DataBufferSize);\r
2902\r
2903 if (Data == NULL) {\r
2904 return EFI_OUT_OF_RESOURCES;\r
2905 }\r
2906 //\r
2907 // Get the content of the policy entry according to the selector.\r
2908 //\r
2909 GetDataStatus = EfiIpSecConfigGetData (\r
2910 &mIpSecConfigInstance,\r
2911 DataType,\r
2912 Selector,\r
2913 &DataSize,\r
2914 Data\r
2915 );\r
2916 }\r
2917\r
2918 if (EFI_ERROR (GetDataStatus)) {\r
2919 break;\r
2920 }\r
2921 //\r
2922 // Prepare the buffer of updated policy entry, which is stored in\r
2923 // the continous memory, and then save into variable later.\r
2924 //\r
2925 RoutineStatus = Routine (\r
2926 DataType,\r
2927 Selector,\r
2928 Data,\r
2929 SelectorSize,\r
2930 DataSize,\r
2931 Context\r
2932 );\r
2933 if (EFI_ERROR (RoutineStatus)) {\r
2934 break;\r
2935 }\r
2936 }\r
2937\r
2938 if (Data != NULL) {\r
2939 FreePool (Data);\r
2940 }\r
2941\r
2942 if (Selector != NULL) {\r
2943 FreePool (Selector);\r
2944 }\r
2945\r
2946 return EFI_SUCCESS;\r
2947}\r
2948\r
2949/**\r
2950 This function is the subfunction of EFIIpSecConfigSetData.\r
2951\r
2952 This function call IpSecSetVaraible to set the IPsec Configuration into the firmware.\r
2953\r
2954 @retval EFI_OUT_OF_RESOURCES The required system resource could not be allocated.\r
2955 @retval EFI_SUCCESS Saved the configration successfully.\r
2956 @retval Others Other errors were found while obtaining the variable.\r
2957\r
2958**/\r
2959EFI_STATUS\r
2960IpSecConfigSave (\r
2961 VOID\r
2962 )\r
2963{\r
2964 IPSEC_VARIABLE_BUFFER Buffer;\r
2965 EFI_STATUS Status;\r
2966 EFI_IPSEC_CONFIG_DATA_TYPE Type;\r
2967\r
2968 Buffer.Size = 0;\r
2969 Buffer.Capacity = IPSEC_DEFAULT_VARIABLE_SIZE;\r
2970 Buffer.Ptr = AllocateZeroPool (Buffer.Capacity);\r
2971\r
2972 if (Buffer.Ptr == NULL) {\r
2973 return EFI_OUT_OF_RESOURCES;\r
2974 }\r
2975 //\r
2976 // For each policy database, prepare the contious buffer to save into variable.\r
2977 //\r
2978 for (Type = IPsecConfigDataTypeSpd; Type < IPsecConfigDataTypeMaximum; Type++) {\r
2979 IpSecVisitConfigData (\r
2980 Type,\r
2981 (IPSEC_COPY_POLICY_ENTRY) IpSecCopyPolicyEntry,\r
2982 &Buffer\r
2983 );\r
2984 }\r
2985 //\r
2986 // Save the updated policy database into variable.\r
2987 //\r
2988 Status = IpSecSetVariable (\r
2989 IPSECCONFIG_VARIABLE_NAME,\r
2990 &gEfiIpSecConfigProtocolGuid,\r
2991 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
2992 Buffer.Size,\r
2993 Buffer.Ptr\r
2994 );\r
2995\r
2996 FreePool (Buffer.Ptr);\r
2997\r
2998 return Status;\r
2999}\r
3000\r
3001/**\r
3002 Get the all IPSec configuration variables and store those variables\r
3003 to the internal data structure.\r
3004\r
9166f840 3005 This founction is called by IpSecConfigInitialize() which is to intialize the \r
a3bcde70
HT
3006 IPsecConfiguration Protocol.\r
3007\r
3008 @param[in] Private Point to IPSEC_PRIVATE_DATA.\r
3009\r
3010 @retval EFI_OUT_OF_RESOURCES The required system resource could not be allocated\r
3011 @retval EFI_SUCCESS Restore the IPsec Configuration successfully.\r
3012 @retval others Other errors is found while obtaining the variable.\r
3013\r
3014**/\r
3015EFI_STATUS\r
3016IpSecConfigRestore (\r
3017 IN IPSEC_PRIVATE_DATA *Private\r
3018 )\r
3019{\r
3020 EFI_STATUS Status;\r
3021 UINTN BufferSize;\r
3022 UINT8 *Buffer;\r
3023 IPSEC_VAR_ITEM_HEADER *Header;\r
3024 UINT8 *Ptr;\r
3025 EFI_IPSEC_CONFIG_SELECTOR *Selector;\r
3026 EFI_IPSEC_CONFIG_DATA_TYPE Type;\r
3027 VOID *Data;\r
3028 UINT8 Value;\r
3029 UINTN Size;\r
3030\r
3031 Value = 0;\r
3032 Size = sizeof (Value);\r
3033 BufferSize = 0;\r
3034 Buffer = NULL;\r
3035\r
3036 Status = gRT->GetVariable (\r
3037 IPSECCONFIG_STATUS_NAME,\r
3038 &gEfiIpSecConfigProtocolGuid,\r
3039 NULL,\r
3040 &Size,\r
3041 &Value\r
3042 );\r
3043\r
3044 if (!EFI_ERROR (Status) && Value == IPSEC_STATUS_ENABLED) {\r
3045 Private->IpSec.DisabledFlag = FALSE;\r
3046 }\r
3047 //\r
3048 // Get the real size of policy database in variable.\r
3049 //\r
3050 Status = IpSecGetVariable (\r
3051 IPSECCONFIG_VARIABLE_NAME,\r
3052 &gEfiIpSecConfigProtocolGuid,\r
3053 NULL,\r
3054 &BufferSize,\r
3055 Buffer\r
3056 );\r
3057 if (Status == EFI_BUFFER_TOO_SMALL) {\r
3058\r
3059 Buffer = AllocateZeroPool (BufferSize);\r
3060 if (Buffer == NULL) {\r
3061 return EFI_OUT_OF_RESOURCES;\r
3062 }\r
3063 //\r
3064 // Get the content of policy database in variable.\r
3065 //\r
3066 Status = IpSecGetVariable (\r
3067 IPSECCONFIG_VARIABLE_NAME,\r
3068 &gEfiIpSecConfigProtocolGuid,\r
3069 NULL,\r
3070 &BufferSize,\r
3071 Buffer\r
3072 );\r
3073 if (EFI_ERROR (Status)) {\r
3074 FreePool (Buffer);\r
3075 return Status;\r
3076 }\r
3077\r
3078 for (Ptr = Buffer; Ptr < Buffer + BufferSize;) {\r
3079\r
3080 Header = (IPSEC_VAR_ITEM_HEADER *) Ptr;\r
3081 Type = (EFI_IPSEC_CONFIG_DATA_TYPE) (Header->Type & IPSEC_VAR_ITEM_HEADER_CONTENT_BIT);\r
3082 ASSERT (((Header->Type & 0x80) == IPSEC_VAR_ITEM_HEADER_LOGO_BIT) && (Type < IPsecConfigDataTypeMaximum));\r
9166f840 3083 \r
a3bcde70
HT
3084 Selector = (EFI_IPSEC_CONFIG_SELECTOR *) ALIGN_POINTER (Header + 1, sizeof (UINTN));\r
3085 Header = (IPSEC_VAR_ITEM_HEADER *) ALIGN_POINTER (\r
9166f840 3086 (UINT8 *) Selector + Header->Size, \r
a3bcde70
HT
3087 sizeof (UINTN)\r
3088 );\r
3089 ASSERT (Header->Type == Type);\r
3090\r
3091 Data = ALIGN_POINTER (Header + 1, sizeof (UINTN));\r
3092\r
3093 mUnfixPolicyEntry[Type](Selector, Data);\r
3094\r
3095 //\r
3096 // Update each policy entry according to the content in variable.\r
3097 //\r
3098 mSetBySelf = TRUE;\r
3099 Status = EfiIpSecConfigSetData (\r
3100 &Private->IpSecConfig,\r
3101 Type,\r
3102 Selector,\r
3103 Data,\r
3104 NULL\r
3105 );\r
3106 mSetBySelf = FALSE;\r
3107\r
3108 if (EFI_ERROR (Status)) {\r
3109 FreePool (Buffer);\r
3110 return Status;\r
3111 }\r
3112\r
3113 Ptr = ALIGN_POINTER ((UINT8 *) Data + Header->Size, sizeof (UINTN));\r
3114 }\r
3115\r
3116 FreePool (Buffer);\r
3117 }\r
3118\r
3119 return EFI_SUCCESS;\r
3120}\r
3121\r
3122/**\r
3123 Install and Initialize IPsecConfig protocol\r
3124\r
3125 @param[in, out] Private Pointer to IPSEC_PRIVATE_DATA. After this function finish,\r
3126 the pointer of IPsecConfig Protocol implementation will copy\r
3127 into its IPsecConfig member.\r
3128\r
3129 @retval EFI_SUCCESS Initialized the IPsecConfig Protocol successfully.\r
3130 @retval Others Initializing the IPsecConfig Protocol failed.\r
3131**/\r
3132EFI_STATUS\r
3133IpSecConfigInitialize (\r
3134 IN OUT IPSEC_PRIVATE_DATA *Private\r
3135 )\r
3136{\r
3137 EFI_IPSEC_CONFIG_DATA_TYPE Type;\r
3138\r
3139 CopyMem (\r
3140 &Private->IpSecConfig,\r
3141 &mIpSecConfigInstance,\r
3142 sizeof (EFI_IPSEC_CONFIG_PROTOCOL)\r
3143 );\r
3144\r
3145 //\r
3146 // Initialize the list head of policy database.\r
3147 //\r
3148 for (Type = IPsecConfigDataTypeSpd; Type < IPsecConfigDataTypeMaximum; Type++) {\r
3149 InitializeListHead (&mConfigData[Type]);\r
3150 }\r
3151 //\r
3152 // Restore the content of policy database according to the variable.\r
3153 //\r
3154 IpSecConfigRestore (Private);\r
3155\r
3156 return gBS->InstallMultipleProtocolInterfaces (\r
3157 &Private->Handle,\r
3158 &gEfiIpSecConfigProtocolGuid,\r
3159 &Private->IpSecConfig,\r
3160 NULL\r
3161 );\r
3162}\r