NetworkPkg: Fix SPD entry edit policy issue in IPSecConfig.
[mirror_edk2.git] / NetworkPkg / Application / IpsecConfig / PolicyEntryOperation.c
1 /** @file
2 The implementation of policy entry operation function in IpSecConfig application.
3
4 Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
5
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php.
10
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13
14 **/
15
16 #include "IpSecConfig.h"
17 #include "Indexer.h"
18 #include "Match.h"
19 #include "Helper.h"
20 #include "ForEach.h"
21 #include "PolicyEntryOperation.h"
22
23 /**
24 Fill in EFI_IPSEC_SPD_SELECTOR through ParamPackage list.
25
26 @param[out] Selector The pointer to the EFI_IPSEC_SPD_SELECTOR structure.
27 @param[in] ParamPackage The pointer to the ParamPackage list.
28 @param[in, out] Mask The pointer to the Mask.
29
30 @retval EFI_SUCCESS Fill in EFI_IPSEC_SPD_SELECTOR successfully.
31 @retval EFI_INVALID_PARAMETER Invalid user input parameter.
32
33 **/
34 EFI_STATUS
35 CreateSpdSelector (
36 OUT EFI_IPSEC_SPD_SELECTOR *Selector,
37 IN LIST_ENTRY *ParamPackage,
38 IN OUT UINT32 *Mask
39 )
40 {
41 EFI_STATUS Status;
42 EFI_STATUS ReturnStatus;
43 CONST CHAR16 *ValueStr;
44
45 Status = EFI_SUCCESS;
46 ReturnStatus = EFI_SUCCESS;
47
48 //
49 // Convert user imput from string to integer, and fill in the member in EFI_IPSEC_SPD_SELECTOR.
50 //
51 ValueStr = ShellCommandLineGetValue (ParamPackage, L"--local");
52 if (ValueStr != NULL) {
53 Selector->LocalAddressCount = 1;
54 Status = EfiInetAddrRange ((CHAR16 *) ValueStr, Selector->LocalAddress);
55 if (EFI_ERROR (Status)) {
56 ShellPrintHiiEx (
57 -1,
58 -1,
59 NULL,
60 STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE),
61 mHiiHandle,
62 mAppName,
63 L"--local",
64 ValueStr
65 );
66 ReturnStatus = EFI_INVALID_PARAMETER;
67 } else {
68 *Mask |= LOCAL;
69 }
70 }
71
72 //
73 // Convert user imput from string to integer, and fill in the member in EFI_IPSEC_SPD_SELECTOR.
74 //
75 ValueStr = ShellCommandLineGetValue (ParamPackage, L"--remote");
76 if (ValueStr != NULL) {
77 Selector->RemoteAddressCount = 1;
78 Status = EfiInetAddrRange ((CHAR16 *) ValueStr, Selector->RemoteAddress);
79 if (EFI_ERROR (Status)) {
80 ShellPrintHiiEx (
81 -1,
82 -1,
83 NULL,
84 STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE),
85 mHiiHandle,
86 mAppName,
87 L"--remote",
88 ValueStr
89 );
90 ReturnStatus = EFI_INVALID_PARAMETER;
91 } else {
92 *Mask |= REMOTE;
93 }
94 }
95
96 Selector->NextLayerProtocol = EFI_IPSEC_ANY_PROTOCOL;
97
98 //
99 // Convert user imput from string to integer, and fill in the member in EFI_IPSEC_SPD_SELECTOR.
100 //
101 Status = GetNumber (
102 L"--proto",
103 (UINT16) -1,
104 &Selector->NextLayerProtocol,
105 sizeof (UINT16),
106 mMapIpProtocol,
107 ParamPackage,
108 FORMAT_NUMBER | FORMAT_STRING
109 );
110 if (!EFI_ERROR (Status)) {
111 *Mask |= PROTO;
112 }
113
114 if (Status == EFI_INVALID_PARAMETER) {
115 ReturnStatus = EFI_INVALID_PARAMETER;
116 }
117
118 Selector->LocalPort = EFI_IPSEC_ANY_PORT;
119 Selector->RemotePort = EFI_IPSEC_ANY_PORT;
120
121 //
122 // Convert user imput from string to integer, and fill in the member in EFI_IPSEC_SPD_SELECTOR.
123 //
124 ValueStr = ShellCommandLineGetValue (ParamPackage, L"--local-port");
125 if (ValueStr != NULL) {
126 Status = EfiInetPortRange ((CHAR16 *) ValueStr, &Selector->LocalPort, &Selector->LocalPortRange);
127 if (EFI_ERROR (Status)) {
128 ShellPrintHiiEx (
129 -1,
130 -1,
131 NULL,
132 STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE),
133 mHiiHandle,
134 mAppName,
135 L"--local-port",
136 ValueStr
137 );
138 ReturnStatus = EFI_INVALID_PARAMETER;
139 } else {
140 *Mask |= LOCAL_PORT;
141 }
142 }
143
144 //
145 // Convert user imput from string to integer, and fill in the member in EFI_IPSEC_SPD_SELECTOR.
146 //
147 ValueStr = ShellCommandLineGetValue (ParamPackage, L"--remote-port");
148 if (ValueStr != NULL) {
149 Status = EfiInetPortRange ((CHAR16 *) ValueStr, &Selector->RemotePort, &Selector->RemotePortRange);
150 if (EFI_ERROR (Status)) {
151 ShellPrintHiiEx (
152 -1,
153 -1,
154 NULL,
155 STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE),
156 mHiiHandle,
157 mAppName,
158 L"--remote-port",
159 ValueStr
160 );
161 ReturnStatus = EFI_INVALID_PARAMETER;
162 } else {
163 *Mask |= REMOTE_PORT;
164 }
165 }
166
167 //
168 // Convert user imput from string to integer, and fill in the member in EFI_IPSEC_SPD_SELECTOR.
169 //
170 Status = GetNumber (
171 L"--icmp-type",
172 (UINT8) -1,
173 &Selector->LocalPort,
174 sizeof (UINT16),
175 NULL,
176 ParamPackage,
177 FORMAT_NUMBER
178 );
179 if (!EFI_ERROR (Status)) {
180 *Mask |= ICMP_TYPE;
181 }
182
183 if (Status == EFI_INVALID_PARAMETER) {
184 ReturnStatus = EFI_INVALID_PARAMETER;
185 }
186
187 //
188 // Convert user imput from string to integer, and fill in the member in EFI_IPSEC_SPD_SELECTOR.
189 //
190 Status = GetNumber (
191 L"--icmp-code",
192 (UINT8) -1,
193 &Selector->RemotePort,
194 sizeof (UINT16),
195 NULL,
196 ParamPackage,
197 FORMAT_NUMBER
198 );
199 if (!EFI_ERROR (Status)) {
200 *Mask |= ICMP_CODE;
201 }
202
203 if (Status == EFI_INVALID_PARAMETER) {
204 ReturnStatus = EFI_INVALID_PARAMETER;
205 }
206
207 return ReturnStatus;
208 }
209
210 /**
211 Fill in EFI_IPSEC_SPD_SELECTOR and EFI_IPSEC_SPD_DATA through ParamPackage list.
212
213 @param[out] Selector The pointer to the EFI_IPSEC_SPD_SELECTOR structure.
214 @param[out] Data The pointer to the EFI_IPSEC_SPD_DATA structure.
215 @param[in] ParamPackage The pointer to the ParamPackage list.
216 @param[out] Mask The pointer to the Mask.
217 @param[in] CreateNew The switch to create new.
218
219 @retval EFI_SUCCESS Fill in EFI_IPSEC_SPD_SELECTOR and EFI_IPSEC_SPD_DATA successfully.
220 @retval EFI_INVALID_PARAMETER Invalid user input parameter.
221
222 **/
223 EFI_STATUS
224 CreateSpdEntry (
225 OUT EFI_IPSEC_SPD_SELECTOR **Selector,
226 OUT EFI_IPSEC_SPD_DATA **Data,
227 IN LIST_ENTRY *ParamPackage,
228 OUT UINT32 *Mask,
229 IN BOOLEAN CreateNew
230 )
231 {
232 EFI_STATUS Status;
233 EFI_STATUS ReturnStatus;
234 CONST CHAR16 *ValueStr;
235 UINTN DataSize;
236
237 Status = EFI_SUCCESS;
238 *Mask = 0;
239
240 *Selector = AllocateZeroPool (sizeof (EFI_IPSEC_SPD_SELECTOR) + 2 * sizeof (EFI_IP_ADDRESS_INFO));
241 ASSERT (*Selector != NULL);
242
243 (*Selector)->LocalAddress = (EFI_IP_ADDRESS_INFO *) (*Selector + 1);
244 (*Selector)->RemoteAddress = (*Selector)->LocalAddress + 1;
245
246 ReturnStatus = CreateSpdSelector (*Selector, ParamPackage, Mask);
247
248 //
249 // SPD DATA
250 // NOTE: Allocate enough memory and add padding for different arch.
251 //
252 DataSize = ALIGN_VARIABLE (sizeof (EFI_IPSEC_SPD_DATA));
253 DataSize = ALIGN_VARIABLE (DataSize + sizeof (EFI_IPSEC_PROCESS_POLICY));
254 DataSize += sizeof (EFI_IPSEC_TUNNEL_OPTION);
255
256 *Data = AllocateZeroPool (DataSize);
257 ASSERT (*Data != NULL);
258
259 (*Data)->ProcessingPolicy = (EFI_IPSEC_PROCESS_POLICY *) ALIGN_POINTER (
260 (*Data + 1),
261 sizeof (UINTN)
262 );
263 (*Data)->ProcessingPolicy->TunnelOption = (EFI_IPSEC_TUNNEL_OPTION *) ALIGN_POINTER (
264 ((*Data)->ProcessingPolicy + 1),
265 sizeof (UINTN)
266 );
267
268
269 //
270 // Convert user imput from string to integer, and fill in the Name in EFI_IPSEC_SPD_DATA.
271 //
272 ValueStr = ShellCommandLineGetValue (ParamPackage, L"--name");
273 if (ValueStr != NULL) {
274 UnicodeStrToAsciiStr (ValueStr, (CHAR8 *) (*Data)->Name);
275 *Mask |= NAME;
276 }
277
278 //
279 // Convert user imput from string to integer, and fill in the PackageFlag in EFI_IPSEC_SPD_DATA.
280 //
281 Status = GetNumber (
282 L"--packet-flag",
283 (UINT8) -1,
284 &(*Data)->PackageFlag,
285 sizeof (UINT32),
286 NULL,
287 ParamPackage,
288 FORMAT_NUMBER
289 );
290 if (!EFI_ERROR (Status)) {
291 *Mask |= PACKET_FLAG;
292 }
293
294 if (Status == EFI_INVALID_PARAMETER) {
295 ReturnStatus = EFI_INVALID_PARAMETER;
296 }
297
298 //
299 // Convert user imput from string to integer, and fill in the Action in EFI_IPSEC_SPD_DATA.
300 //
301 Status = GetNumber (
302 L"--action",
303 (UINT8) -1,
304 &(*Data)->Action,
305 sizeof (UINT32),
306 mMapIpSecAction,
307 ParamPackage,
308 FORMAT_STRING
309 );
310 if (!EFI_ERROR (Status)) {
311 *Mask |= ACTION;
312 }
313
314 if (Status == EFI_INVALID_PARAMETER) {
315 ReturnStatus = EFI_INVALID_PARAMETER;
316 }
317
318 //
319 // Convert user imput from string to integer, and fill in the ExtSeqNum in EFI_IPSEC_SPD_DATA.
320 //
321 if (ShellCommandLineGetFlag (ParamPackage, L"--ext-sequence")) {
322 (*Data)->ProcessingPolicy->ExtSeqNum = TRUE;
323 *Mask |= EXT_SEQUENCE;
324 } else if (ShellCommandLineGetFlag (ParamPackage, L"--ext-sequence-")) {
325 (*Data)->ProcessingPolicy->ExtSeqNum = FALSE;
326 *Mask |= EXT_SEQUENCE;
327 }
328
329 //
330 // Convert user imput from string to integer, and fill in the SeqOverflow in EFI_IPSEC_SPD_DATA.
331 //
332 if (ShellCommandLineGetFlag (ParamPackage, L"--sequence-overflow")) {
333 (*Data)->ProcessingPolicy->SeqOverflow = TRUE;
334 *Mask |= SEQUENCE_OVERFLOW;
335 } else if (ShellCommandLineGetFlag (ParamPackage, L"--sequence-overflow-")) {
336 (*Data)->ProcessingPolicy->SeqOverflow = FALSE;
337 *Mask |= SEQUENCE_OVERFLOW;
338 }
339
340 //
341 // Convert user imput from string to integer, and fill in the FragCheck in EFI_IPSEC_SPD_DATA.
342 //
343 if (ShellCommandLineGetFlag (ParamPackage, L"--fragment-check")) {
344 (*Data)->ProcessingPolicy->FragCheck = TRUE;
345 *Mask |= FRAGMENT_CHECK;
346 } else if (ShellCommandLineGetFlag (ParamPackage, L"--fragment-check-")) {
347 (*Data)->ProcessingPolicy->FragCheck = FALSE;
348 *Mask |= FRAGMENT_CHECK;
349 }
350
351 //
352 // Convert user imput from string to integer, and fill in the ProcessingPolicy in EFI_IPSEC_SPD_DATA.
353 //
354 Status = GetNumber (
355 L"--lifebyte",
356 (UINT64) -1,
357 &(*Data)->ProcessingPolicy->SaLifetime.ByteCount,
358 sizeof (UINT64),
359 NULL,
360 ParamPackage,
361 FORMAT_NUMBER
362 );
363 if (!EFI_ERROR (Status)) {
364 *Mask |= LIFEBYTE;
365 }
366
367 if (Status == EFI_INVALID_PARAMETER) {
368 ReturnStatus = EFI_INVALID_PARAMETER;
369 }
370
371 Status = GetNumber (
372 L"--lifetime",
373 (UINT64) -1,
374 &(*Data)->ProcessingPolicy->SaLifetime.HardLifetime,
375 sizeof (UINT64),
376 NULL,
377 ParamPackage,
378 FORMAT_NUMBER
379 );
380 if (!EFI_ERROR (Status)) {
381 *Mask |= LIFETIME;
382 }
383 if (Status == EFI_INVALID_PARAMETER) {
384 ReturnStatus = EFI_INVALID_PARAMETER;
385 }
386
387 Status = GetNumber (
388 L"--lifetime-soft",
389 (UINT64) -1,
390 &(*Data)->ProcessingPolicy->SaLifetime.SoftLifetime,
391 sizeof (UINT64),
392 NULL,
393 ParamPackage,
394 FORMAT_NUMBER
395 );
396 if (!EFI_ERROR (Status)) {
397 *Mask |= LIFETIME_SOFT;
398 }
399
400 if (Status == EFI_INVALID_PARAMETER) {
401 ReturnStatus = EFI_INVALID_PARAMETER;
402 }
403
404 (*Data)->ProcessingPolicy->Mode = EfiIPsecTransport;
405 Status = GetNumber (
406 L"--mode",
407 0,
408 &(*Data)->ProcessingPolicy->Mode,
409 sizeof (UINT32),
410 mMapIpSecMode,
411 ParamPackage,
412 FORMAT_STRING
413 );
414 if (!EFI_ERROR (Status)) {
415 *Mask |= MODE;
416 }
417
418 if (Status == EFI_INVALID_PARAMETER) {
419 ReturnStatus = EFI_INVALID_PARAMETER;
420 }
421
422 ValueStr = ShellCommandLineGetValue (ParamPackage, L"--tunnel-local");
423 if (ValueStr != NULL) {
424 Status = EfiInetAddr2 ((CHAR16 *) ValueStr, &(*Data)->ProcessingPolicy->TunnelOption->LocalTunnelAddress);
425 if (EFI_ERROR (Status)) {
426 ShellPrintHiiEx (
427 -1,
428 -1,
429 NULL,
430 STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE),
431 mHiiHandle,
432 mAppName,
433 L"--tunnel-local",
434 ValueStr
435 );
436 ReturnStatus = EFI_INVALID_PARAMETER;
437 } else {
438 *Mask |= TUNNEL_LOCAL;
439 }
440 }
441
442 ValueStr = ShellCommandLineGetValue (ParamPackage, L"--tunnel-remote");
443 if (ValueStr != NULL) {
444 Status = EfiInetAddr2 ((CHAR16 *) ValueStr, &(*Data)->ProcessingPolicy->TunnelOption->RemoteTunnelAddress);
445 if (EFI_ERROR (Status)) {
446 ShellPrintHiiEx (
447 -1,
448 -1,
449 NULL,
450 STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE),
451 mHiiHandle,
452 mAppName,
453 L"--tunnel-remote",
454 ValueStr
455 );
456 ReturnStatus = EFI_INVALID_PARAMETER;
457 } else {
458 *Mask |= TUNNEL_REMOTE;
459 }
460 }
461
462 (*Data)->ProcessingPolicy->TunnelOption->DF = EfiIPsecTunnelCopyDf;
463 Status = GetNumber (
464 L"--dont-fragment",
465 0,
466 &(*Data)->ProcessingPolicy->TunnelOption->DF,
467 sizeof (UINT32),
468 mMapDfOption,
469 ParamPackage,
470 FORMAT_STRING
471 );
472 if (!EFI_ERROR (Status)) {
473 *Mask |= DONT_FRAGMENT;
474 }
475
476 if (Status == EFI_INVALID_PARAMETER) {
477 ReturnStatus = EFI_INVALID_PARAMETER;
478 }
479
480 (*Data)->ProcessingPolicy->Proto = EfiIPsecESP;
481 Status = GetNumber (
482 L"--ipsec-proto",
483 0,
484 &(*Data)->ProcessingPolicy->Proto,
485 sizeof (UINT32),
486 mMapIpSecProtocol,
487 ParamPackage,
488 FORMAT_STRING
489 );
490 if (!EFI_ERROR (Status)) {
491 *Mask |= IPSEC_PROTO;
492 }
493
494 if (Status == EFI_INVALID_PARAMETER) {
495 ReturnStatus = EFI_INVALID_PARAMETER;
496 }
497
498 Status = GetNumber (
499 L"--encrypt-algo",
500 0,
501 &(*Data)->ProcessingPolicy->EncAlgoId,
502 sizeof (UINT8),
503 mMapEncAlgo,
504 ParamPackage,
505 FORMAT_STRING
506 );
507 if (!EFI_ERROR (Status)) {
508 *Mask |= ENCRYPT_ALGO;
509 }
510
511 if (Status == EFI_INVALID_PARAMETER) {
512 ReturnStatus = EFI_INVALID_PARAMETER;
513 }
514
515 Status = GetNumber (
516 L"--auth-algo",
517 0,
518 &(*Data)->ProcessingPolicy->AuthAlgoId,
519 sizeof (UINT8),
520 mMapAuthAlgo,
521 ParamPackage,
522 FORMAT_STRING
523 );
524 if (!EFI_ERROR (Status)) {
525 *Mask |= AUTH_ALGO;
526 }
527
528 if (Status == EFI_INVALID_PARAMETER) {
529 ReturnStatus = EFI_INVALID_PARAMETER;
530 }
531
532 //
533 // Cannot check Mode against EfiIPsecTunnel, because user may want to change tunnel_remote only so the Mode is not set.
534 //
535 if ((*Mask & (TUNNEL_LOCAL | TUNNEL_REMOTE | DONT_FRAGMENT)) == 0) {
536 (*Data)->ProcessingPolicy->TunnelOption = NULL;
537 }
538
539 if ((*Mask & (EXT_SEQUENCE | SEQUENCE_OVERFLOW | FRAGMENT_CHECK | LIFEBYTE |
540 LIFETIME_SOFT | LIFETIME | MODE | TUNNEL_LOCAL | TUNNEL_REMOTE |
541 DONT_FRAGMENT | IPSEC_PROTO | AUTH_ALGO | ENCRYPT_ALGO)) == 0) {
542 if ((*Data)->Action != EfiIPsecActionProtect) {
543 //
544 // User may not provide additional parameter for Protect action, so we cannot simply set ProcessingPolicy to NULL.
545 //
546 (*Data)->ProcessingPolicy = NULL;
547 }
548 }
549
550 if (CreateNew) {
551 if ((*Mask & (LOCAL | REMOTE | PROTO | ACTION)) != (LOCAL | REMOTE | PROTO | ACTION)) {
552 ShellPrintHiiEx (
553 -1,
554 -1,
555 NULL,
556 STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_ONE_OF_PARAMETERS),
557 mHiiHandle,
558 mAppName,
559 L"--local --remote --proto --action"
560 );
561 ReturnStatus = EFI_INVALID_PARAMETER;
562 } else if (((*Data)->Action == EfiIPsecActionProtect) &&
563 ((*Data)->ProcessingPolicy->Mode == EfiIPsecTunnel) &&
564 ((*Mask & (TUNNEL_LOCAL | TUNNEL_REMOTE)) != (TUNNEL_LOCAL | TUNNEL_REMOTE))) {
565 ShellPrintHiiEx (
566 -1,
567 -1,
568 NULL,
569 STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_ONE_OF_PARAMETERS),
570 mHiiHandle,
571 mAppName,
572 L"--tunnel-local --tunnel-remote"
573 );
574 ReturnStatus = EFI_INVALID_PARAMETER;
575 }
576 }
577
578 return ReturnStatus;
579 }
580
581 /**
582 Fill in EFI_IPSEC_SA_ID and EFI_IPSEC_SA_DATA2 through ParamPackage list.
583
584 @param[out] SaId The pointer to the EFI_IPSEC_SA_ID structure.
585 @param[out] Data The pointer to the EFI_IPSEC_SA_DATA2 structure.
586 @param[in] ParamPackage The pointer to the ParamPackage list.
587 @param[out] Mask The pointer to the Mask.
588 @param[in] CreateNew The switch to create new.
589
590 @retval EFI_SUCCESS Fill in EFI_IPSEC_SA_ID and EFI_IPSEC_SA_DATA2 successfully.
591 @retval EFI_INVALID_PARAMETER Invalid user input parameter.
592
593 **/
594 EFI_STATUS
595 CreateSadEntry (
596 OUT EFI_IPSEC_SA_ID **SaId,
597 OUT EFI_IPSEC_SA_DATA2 **Data,
598 IN LIST_ENTRY *ParamPackage,
599 OUT UINT32 *Mask,
600 IN BOOLEAN CreateNew
601 )
602 {
603 EFI_STATUS Status;
604 EFI_STATUS ReturnStatus;
605 UINTN AuthKeyLength;
606 UINTN EncKeyLength;
607 CONST CHAR16 *ValueStr;
608 CHAR8 *AsciiStr;
609 UINTN DataSize;
610
611 Status = EFI_SUCCESS;
612 ReturnStatus = EFI_SUCCESS;
613 *Mask = 0;
614 AuthKeyLength = 0;
615 EncKeyLength = 0;
616
617 *SaId = AllocateZeroPool (sizeof (EFI_IPSEC_SA_ID));
618 ASSERT (*SaId != NULL);
619
620 //
621 // Convert user imput from string to integer, and fill in the Spi in EFI_IPSEC_SA_ID.
622 //
623 Status = GetNumber (L"--spi", (UINT32) -1, &(*SaId)->Spi, sizeof (UINT32), NULL, ParamPackage, FORMAT_NUMBER);
624 if (!EFI_ERROR (Status)) {
625 *Mask |= SPI;
626 }
627
628 if (Status == EFI_INVALID_PARAMETER) {
629 ReturnStatus = EFI_INVALID_PARAMETER;
630 }
631
632 //
633 // Convert user imput from string to integer, and fill in the Proto in EFI_IPSEC_SA_ID.
634 //
635 Status = GetNumber (
636 L"--ipsec-proto",
637 0,
638 &(*SaId)->Proto,
639 sizeof (EFI_IPSEC_PROTOCOL_TYPE),
640 mMapIpSecProtocol,
641 ParamPackage,
642 FORMAT_STRING
643 );
644 if (!EFI_ERROR (Status)) {
645 *Mask |= IPSEC_PROTO;
646 }
647
648 if (Status == EFI_INVALID_PARAMETER) {
649 ReturnStatus = EFI_INVALID_PARAMETER;
650 }
651
652 //
653 // Convert user imput from string to integer, and fill in EFI_IPSEC_SA_DATA2.
654 //
655 ValueStr = ShellCommandLineGetValue (ParamPackage, L"--auth-key");
656 if (ValueStr != NULL) {
657 AuthKeyLength = StrLen (ValueStr);
658 }
659
660 ValueStr = ShellCommandLineGetValue (ParamPackage, L"--encrypt-key");
661 if (ValueStr != NULL) {
662 EncKeyLength = StrLen (ValueStr);
663 }
664
665 //
666 // EFI_IPSEC_SA_DATA2:
667 // +------------
668 // | EFI_IPSEC_SA_DATA2
669 // +-----------------------
670 // | AuthKey
671 // +-------------------------
672 // | EncKey
673 // +-------------------------
674 // | SpdSelector
675 //
676 // Notes: To make sure the address alignment add padding after each data if needed.
677 //
678 DataSize = ALIGN_VARIABLE (sizeof (EFI_IPSEC_SA_DATA2));
679 DataSize = ALIGN_VARIABLE (DataSize + AuthKeyLength);
680 DataSize = ALIGN_VARIABLE (DataSize + EncKeyLength);
681 DataSize = ALIGN_VARIABLE (DataSize + sizeof (EFI_IPSEC_SPD_SELECTOR));
682 DataSize = ALIGN_VARIABLE (DataSize + sizeof (EFI_IP_ADDRESS_INFO));
683 DataSize += sizeof (EFI_IP_ADDRESS_INFO);
684
685
686
687 *Data = AllocateZeroPool (DataSize);
688 ASSERT (*Data != NULL);
689
690 (*Data)->ManualSet = TRUE;
691 (*Data)->AlgoInfo.EspAlgoInfo.AuthKey = (VOID *) ALIGN_POINTER (((*Data) + 1), sizeof (UINTN));
692 (*Data)->AlgoInfo.EspAlgoInfo.EncKey = (VOID *) ALIGN_POINTER (
693 ((UINT8 *) (*Data)->AlgoInfo.EspAlgoInfo.AuthKey + AuthKeyLength),
694 sizeof (UINTN)
695 );
696 (*Data)->SpdSelector = (EFI_IPSEC_SPD_SELECTOR *) ALIGN_POINTER (
697 ((UINT8 *) (*Data)->AlgoInfo.EspAlgoInfo.EncKey + EncKeyLength),
698 sizeof (UINTN)
699 );
700 (*Data)->SpdSelector->LocalAddress = (EFI_IP_ADDRESS_INFO *) ALIGN_POINTER (
701 ((UINT8 *) (*Data)->SpdSelector + sizeof (EFI_IPSEC_SPD_SELECTOR)),
702 sizeof (UINTN));
703 (*Data)->SpdSelector->RemoteAddress = (EFI_IP_ADDRESS_INFO *) ALIGN_POINTER (
704 (*Data)->SpdSelector->LocalAddress + 1,
705 sizeof (UINTN)
706 );
707
708 (*Data)->Mode = EfiIPsecTransport;
709 Status = GetNumber (
710 L"--mode",
711 0,
712 &(*Data)->Mode,
713 sizeof (EFI_IPSEC_MODE),
714 mMapIpSecMode,
715 ParamPackage,
716 FORMAT_STRING
717 );
718 if (!EFI_ERROR (Status)) {
719 *Mask |= MODE;
720 }
721
722 if (Status == EFI_INVALID_PARAMETER) {
723 ReturnStatus = EFI_INVALID_PARAMETER;
724 }
725
726 //
727 // According to RFC 4303-3.3.3. The first packet sent using a given SA
728 // will contain a sequence number of 1.
729 //
730 (*Data)->SNCount = 1;
731 Status = GetNumber (
732 L"--sequence-number",
733 (UINT64) -1,
734 &(*Data)->SNCount,
735 sizeof (UINT64),
736 NULL,
737 ParamPackage,
738 FORMAT_NUMBER
739 );
740 if (!EFI_ERROR (Status)) {
741 *Mask |= SEQUENCE_NUMBER;
742 }
743
744 if (Status == EFI_INVALID_PARAMETER) {
745 ReturnStatus = EFI_INVALID_PARAMETER;
746 }
747
748 (*Data)->AntiReplayWindows = 0;
749 Status = GetNumber (
750 L"--antireplay-window",
751 (UINT8) -1,
752 &(*Data)->AntiReplayWindows,
753 sizeof (UINT8),
754 NULL,
755 ParamPackage,
756 FORMAT_NUMBER
757 );
758 if (!EFI_ERROR (Status)) {
759 *Mask |= SEQUENCE_NUMBER;
760 }
761
762 if (Status == EFI_INVALID_PARAMETER) {
763 ReturnStatus = EFI_INVALID_PARAMETER;
764 }
765
766 Status = GetNumber (
767 L"--encrypt-algo",
768 0,
769 &(*Data)->AlgoInfo.EspAlgoInfo.EncAlgoId,
770 sizeof (UINT8),
771 mMapEncAlgo,
772 ParamPackage,
773 FORMAT_STRING
774 );
775 if (!EFI_ERROR (Status)) {
776 *Mask |= ENCRYPT_ALGO;
777 }
778
779 if (Status == EFI_INVALID_PARAMETER) {
780 ReturnStatus = EFI_INVALID_PARAMETER;
781 }
782
783 ValueStr = ShellCommandLineGetValue (ParamPackage, L"--encrypt-key");
784 if (ValueStr != NULL ) {
785 (*Data)->AlgoInfo.EspAlgoInfo.EncKeyLength = EncKeyLength;
786 AsciiStr = AllocateZeroPool (EncKeyLength + 1);
787 ASSERT (AsciiStr != NULL);
788 UnicodeStrToAsciiStr (ValueStr, AsciiStr);
789 CopyMem ((*Data)->AlgoInfo.EspAlgoInfo.EncKey, AsciiStr, EncKeyLength);
790 FreePool (AsciiStr);
791 *Mask |= ENCRYPT_KEY;
792 } else {
793 (*Data)->AlgoInfo.EspAlgoInfo.EncKey = NULL;
794 }
795
796 Status = GetNumber (
797 L"--auth-algo",
798 0,
799 &(*Data)->AlgoInfo.EspAlgoInfo.AuthAlgoId,
800 sizeof (UINT8),
801 mMapAuthAlgo,
802 ParamPackage,
803 FORMAT_STRING
804 );
805 if (!EFI_ERROR (Status)) {
806 *Mask |= AUTH_ALGO;
807 }
808
809 if (Status == EFI_INVALID_PARAMETER) {
810 ReturnStatus = EFI_INVALID_PARAMETER;
811 }
812
813 ValueStr = ShellCommandLineGetValue (ParamPackage, L"--auth-key");
814 if (ValueStr != NULL) {
815 (*Data)->AlgoInfo.EspAlgoInfo.AuthKeyLength = AuthKeyLength;
816 AsciiStr = AllocateZeroPool (AuthKeyLength + 1);
817 ASSERT (AsciiStr != NULL);
818 UnicodeStrToAsciiStr (ValueStr, AsciiStr);
819 CopyMem ((*Data)->AlgoInfo.EspAlgoInfo.AuthKey, AsciiStr, AuthKeyLength);
820 FreePool (AsciiStr);
821 *Mask |= AUTH_KEY;
822 } else {
823 (*Data)->AlgoInfo.EspAlgoInfo.AuthKey = NULL;
824 }
825
826 Status = GetNumber (
827 L"--lifebyte",
828 (UINT64) -1,
829 &(*Data)->SaLifetime.ByteCount,
830 sizeof (UINT64),
831 NULL,
832 ParamPackage,
833 FORMAT_NUMBER
834 );
835 if (!EFI_ERROR (Status)) {
836 *Mask |= LIFEBYTE;
837 }
838
839 if (Status == EFI_INVALID_PARAMETER) {
840 ReturnStatus = EFI_INVALID_PARAMETER;
841 }
842
843 Status = GetNumber (
844 L"--lifetime",
845 (UINT64) -1,
846 &(*Data)->SaLifetime.HardLifetime,
847 sizeof (UINT64),
848 NULL,
849 ParamPackage,
850 FORMAT_NUMBER
851 );
852 if (!EFI_ERROR (Status)) {
853 *Mask |= LIFETIME;
854 }
855
856 if (Status == EFI_INVALID_PARAMETER) {
857 ReturnStatus = EFI_INVALID_PARAMETER;
858 }
859
860 Status = GetNumber (
861 L"--lifetime-soft",
862 (UINT64) -1,
863 &(*Data)->SaLifetime.SoftLifetime,
864 sizeof (UINT64),
865 NULL,
866 ParamPackage,
867 FORMAT_NUMBER
868 );
869 if (!EFI_ERROR (Status)) {
870 *Mask |= LIFETIME_SOFT;
871 }
872
873 if (Status == EFI_INVALID_PARAMETER) {
874 ReturnStatus = EFI_INVALID_PARAMETER;
875 }
876
877 Status = GetNumber (
878 L"--path-mtu",
879 (UINT32) -1,
880 &(*Data)->PathMTU,
881 sizeof (UINT32),
882 NULL,
883 ParamPackage,
884 FORMAT_NUMBER
885 );
886 if (!EFI_ERROR (Status)) {
887 *Mask |= PATH_MTU;
888 }
889
890 if (Status == EFI_INVALID_PARAMETER) {
891 ReturnStatus = EFI_INVALID_PARAMETER;
892 }
893
894 //
895 // Convert user imput from string to integer, and fill in the DestAddress in EFI_IPSEC_SA_ID.
896 //
897 ValueStr = ShellCommandLineGetValue (ParamPackage, L"--tunnel-dest");
898 if (ValueStr != NULL) {
899 Status = EfiInetAddr2 ((CHAR16 *) ValueStr, &(*Data)->TunnelDestinationAddress);
900 if (EFI_ERROR (Status)) {
901 ShellPrintHiiEx (
902 -1,
903 -1,
904 NULL,
905 STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE),
906 mHiiHandle,
907 mAppName,
908 L"--tunnel-dest",
909 ValueStr
910 );
911 ReturnStatus = EFI_INVALID_PARAMETER;
912 } else {
913 *Mask |= DEST;
914 }
915 }
916
917 //
918 // Convert user input from string to integer, and fill in the DestAddress in EFI_IPSEC_SA_ID.
919 //
920 ValueStr = ShellCommandLineGetValue (ParamPackage, L"--tunnel-source");
921 if (ValueStr != NULL) {
922 Status = EfiInetAddr2 ((CHAR16 *) ValueStr, &(*Data)->TunnelSourceAddress);
923 if (EFI_ERROR (Status)) {
924 ShellPrintHiiEx (
925 -1,
926 -1,
927 NULL,
928 STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE),
929 mHiiHandle,
930 mAppName,
931 L"--tunnel-source",
932 ValueStr
933 );
934 ReturnStatus = EFI_INVALID_PARAMETER;
935 } else {
936 *Mask |= SOURCE;
937 }
938 }
939
940 //
941 // If it is TunnelMode, then check if the tunnel-source and --tunnel-dest are set
942 //
943 if ((*Data)->Mode == EfiIPsecTunnel) {
944 if ((*Mask & (DEST|SOURCE)) != (DEST|SOURCE)) {
945 ShellPrintHiiEx (
946 -1,
947 -1,
948 NULL,
949 STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_ONE_OF_PARAMETERS),
950 mHiiHandle,
951 mAppName,
952 L"--tunnel-source --tunnel-dest"
953 );
954 ReturnStatus = EFI_INVALID_PARAMETER;
955 }
956 }
957 ReturnStatus = CreateSpdSelector ((*Data)->SpdSelector, ParamPackage, Mask);
958
959 if (CreateNew) {
960 if ((*Mask & (SPI|IPSEC_PROTO|LOCAL|REMOTE)) != (SPI|IPSEC_PROTO|LOCAL|REMOTE)) {
961 ShellPrintHiiEx (
962 -1,
963 -1,
964 NULL,
965 STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_ONE_OF_PARAMETERS),
966 mHiiHandle,
967 mAppName,
968 L"--spi --ipsec-proto --local --remote"
969 );
970 ReturnStatus = EFI_INVALID_PARAMETER;
971 } else {
972 if ((*SaId)->Proto == EfiIPsecAH) {
973 if ((*Mask & AUTH_ALGO) == 0) {
974 ShellPrintHiiEx (
975 -1,
976 -1,
977 NULL,
978 STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_PARAMETER),
979 mHiiHandle,
980 mAppName,
981 L"--auth-algo"
982 );
983 ReturnStatus = EFI_INVALID_PARAMETER;
984 } else if ((*Data)->AlgoInfo.EspAlgoInfo.AuthAlgoId != IPSEC_AALG_NONE && (*Mask & AUTH_KEY) == 0) {
985 ShellPrintHiiEx (
986 -1,
987 -1,
988 NULL,
989 STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_PARAMETER),
990 mHiiHandle,
991 mAppName,
992 L"--auth-key"
993 );
994 ReturnStatus = EFI_INVALID_PARAMETER;
995 }
996 } else {
997 if ((*Mask & (ENCRYPT_ALGO|AUTH_ALGO)) != (ENCRYPT_ALGO|AUTH_ALGO) ) {
998 ShellPrintHiiEx (
999 -1,
1000 -1,
1001 NULL,
1002 STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_PARAMETER),
1003 mHiiHandle,
1004 mAppName,
1005 L"--encrypt-algo --auth-algo"
1006 );
1007 ReturnStatus = EFI_INVALID_PARAMETER;
1008 } else if ((*Data)->AlgoInfo.EspAlgoInfo.EncAlgoId != IPSEC_EALG_NONE && (*Mask & ENCRYPT_KEY) == 0) {
1009 ShellPrintHiiEx (
1010 -1,
1011 -1,
1012 NULL,
1013 STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_PARAMETER),
1014 mHiiHandle,
1015 mAppName,
1016 L"--encrypt-key"
1017 );
1018 ReturnStatus = EFI_INVALID_PARAMETER;
1019 } else if ((*Data)->AlgoInfo.EspAlgoInfo.AuthAlgoId != IPSEC_AALG_NONE && (*Mask & AUTH_KEY) == 0) {
1020 ShellPrintHiiEx (
1021 -1,
1022 -1,
1023 NULL,
1024 STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_PARAMETER),
1025 mHiiHandle,
1026 mAppName,
1027 L"--auth-key"
1028 );
1029 ReturnStatus = EFI_INVALID_PARAMETER;
1030 }
1031 }
1032 }
1033 }
1034
1035 return ReturnStatus;
1036 }
1037
1038 /**
1039 Fill in EFI_IPSEC_PAD_ID and EFI_IPSEC_PAD_DATA through ParamPackage list.
1040
1041 @param[out] PadId The pointer to the EFI_IPSEC_PAD_ID structure.
1042 @param[out] Data The pointer to the EFI_IPSEC_PAD_DATA structure.
1043 @param[in] ParamPackage The pointer to the ParamPackage list.
1044 @param[out] Mask The pointer to the Mask.
1045 @param[in] CreateNew The switch to create new.
1046
1047 @retval EFI_SUCCESS Fill in EFI_IPSEC_PAD_ID and EFI_IPSEC_PAD_DATA successfully.
1048 @retval EFI_INVALID_PARAMETER Invalid user input parameter.
1049
1050 **/
1051 EFI_STATUS
1052 CreatePadEntry (
1053 OUT EFI_IPSEC_PAD_ID **PadId,
1054 OUT EFI_IPSEC_PAD_DATA **Data,
1055 IN LIST_ENTRY *ParamPackage,
1056 OUT UINT32 *Mask,
1057 IN BOOLEAN CreateNew
1058 )
1059 {
1060 EFI_STATUS Status;
1061 EFI_STATUS ReturnStatus;
1062 SHELL_FILE_HANDLE FileHandle;
1063 UINT64 FileSize;
1064 UINTN AuthDataLength;
1065 UINTN RevocationDataLength;
1066 UINTN DataLength;
1067 UINTN Index;
1068 CONST CHAR16 *ValueStr;
1069 UINTN DataSize;
1070
1071 Status = EFI_SUCCESS;
1072 ReturnStatus = EFI_SUCCESS;
1073 *Mask = 0;
1074 AuthDataLength = 0;
1075 RevocationDataLength = 0;
1076
1077 *PadId = AllocateZeroPool (sizeof (EFI_IPSEC_PAD_ID));
1078 ASSERT (*PadId != NULL);
1079
1080 //
1081 // Convert user imput from string to integer, and fill in EFI_IPSEC_PAD_ID.
1082 //
1083 ValueStr = ShellCommandLineGetValue (ParamPackage, L"--peer-address");
1084 if (ValueStr != NULL) {
1085 (*PadId)->PeerIdValid = FALSE;
1086 Status = EfiInetAddrRange ((CHAR16 *) ValueStr, &(*PadId)->Id.IpAddress);
1087 if (EFI_ERROR (Status)) {
1088 ShellPrintHiiEx (
1089 -1,
1090 -1,
1091 NULL,
1092 STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE),
1093 mHiiHandle,
1094 mAppName,
1095 L"--peer-address",
1096 ValueStr
1097 );
1098 ReturnStatus = EFI_INVALID_PARAMETER;
1099 } else {
1100 *Mask |= PEER_ADDRESS;
1101 }
1102 }
1103
1104 ValueStr = ShellCommandLineGetValue (ParamPackage, L"--peer-id");
1105 if (ValueStr != NULL) {
1106 (*PadId)->PeerIdValid = TRUE;
1107 StrnCpyS ((CHAR16 *) (*PadId)->Id.PeerId, MAX_PEERID_LEN / sizeof (CHAR16), ValueStr, MAX_PEERID_LEN / sizeof (CHAR16) - 1);
1108 *Mask |= PEER_ID;
1109 }
1110
1111 ValueStr = ShellCommandLineGetValue (ParamPackage, L"--auth-data");
1112 if (ValueStr != NULL) {
1113 if (ValueStr[0] == L'@') {
1114 //
1115 // Input is a file: --auth-data "@fs1:\My Certificates\tom.dat"
1116 //
1117 Status = ShellOpenFileByName (&ValueStr[1], &FileHandle, EFI_FILE_MODE_READ, 0);
1118 if (EFI_ERROR (Status)) {
1119 ShellPrintHiiEx (
1120 -1,
1121 -1,
1122 NULL,
1123 STRING_TOKEN (STR_IPSEC_CONFIG_FILE_OPEN_FAILED),
1124 mHiiHandle,
1125 mAppName,
1126 &ValueStr[1]
1127 );
1128 ReturnStatus = EFI_INVALID_PARAMETER;
1129 } else {
1130 Status = ShellGetFileSize (FileHandle, &FileSize);
1131 ShellCloseFile (&FileHandle);
1132 if (EFI_ERROR (Status)) {
1133 ShellPrintHiiEx (
1134 -1,
1135 -1,
1136 NULL,
1137 STRING_TOKEN (STR_IPSEC_CONFIG_FILE_OPEN_FAILED),
1138 mHiiHandle,
1139 mAppName,
1140 &ValueStr[1]
1141 );
1142 ReturnStatus = EFI_INVALID_PARAMETER;
1143 } else {
1144 AuthDataLength = (UINTN) FileSize;
1145 }
1146 }
1147 } else {
1148 AuthDataLength = StrLen (ValueStr);
1149 }
1150 }
1151
1152 ValueStr = ShellCommandLineGetValue (ParamPackage, L"--revocation-data");
1153 if (ValueStr != NULL) {
1154 RevocationDataLength = (StrLen (ValueStr) + 1) * sizeof (CHAR16);
1155 }
1156
1157 //
1158 // Allocate Buffer for Data. Add padding after each struct to make sure the alignment
1159 // in different Arch.
1160 //
1161 DataSize = ALIGN_VARIABLE (sizeof (EFI_IPSEC_PAD_DATA));
1162 DataSize = ALIGN_VARIABLE (DataSize + AuthDataLength);
1163 DataSize += RevocationDataLength;
1164
1165 *Data = AllocateZeroPool (DataSize);
1166 ASSERT (*Data != NULL);
1167
1168 (*Data)->AuthData = (VOID *) ALIGN_POINTER ((*Data + 1), sizeof (UINTN));
1169 (*Data)->RevocationData = (VOID *) ALIGN_POINTER (((UINT8 *) (*Data + 1) + AuthDataLength), sizeof (UINTN));
1170 (*Data)->AuthProtocol = EfiIPsecAuthProtocolIKEv1;
1171
1172 //
1173 // Convert user imput from string to integer, and fill in EFI_IPSEC_PAD_DATA.
1174 //
1175 Status = GetNumber (
1176 L"--auth-proto",
1177 0,
1178 &(*Data)->AuthProtocol,
1179 sizeof (EFI_IPSEC_AUTH_PROTOCOL_TYPE),
1180 mMapAuthProto,
1181 ParamPackage,
1182 FORMAT_STRING
1183 );
1184 if (!EFI_ERROR (Status)) {
1185 *Mask |= AUTH_PROTO;
1186 }
1187
1188 if (Status == EFI_INVALID_PARAMETER) {
1189 ReturnStatus = EFI_INVALID_PARAMETER;
1190 }
1191
1192 Status = GetNumber (
1193 L"--auth-method",
1194 0,
1195 &(*Data)->AuthMethod,
1196 sizeof (EFI_IPSEC_AUTH_METHOD),
1197 mMapAuthMethod,
1198 ParamPackage,
1199 FORMAT_STRING
1200 );
1201 if (!EFI_ERROR (Status)) {
1202 *Mask |= AUTH_METHOD;
1203 }
1204
1205 if (Status == EFI_INVALID_PARAMETER) {
1206 ReturnStatus = EFI_INVALID_PARAMETER;
1207 }
1208
1209 if (ShellCommandLineGetFlag (ParamPackage, L"--ike-id")) {
1210 (*Data)->IkeIdFlag = TRUE;
1211 *Mask |= IKE_ID;
1212 }
1213
1214 if (ShellCommandLineGetFlag (ParamPackage, L"--ike-id-")) {
1215 (*Data)->IkeIdFlag = FALSE;
1216 *Mask |= IKE_ID;
1217 }
1218
1219 ValueStr = ShellCommandLineGetValue (ParamPackage, L"--auth-data");
1220 if (ValueStr != NULL) {
1221 if (ValueStr[0] == L'@') {
1222 //
1223 // Input is a file: --auth-data "@fs1:\My Certificates\tom.dat"
1224 //
1225
1226 Status = ShellOpenFileByName (&ValueStr[1], &FileHandle, EFI_FILE_MODE_READ, 0);
1227 if (EFI_ERROR (Status)) {
1228 ShellPrintHiiEx (
1229 -1,
1230 -1,
1231 NULL,
1232 STRING_TOKEN (STR_IPSEC_CONFIG_FILE_OPEN_FAILED),
1233 mHiiHandle,
1234 mAppName,
1235 &ValueStr[1]
1236 );
1237 ReturnStatus = EFI_INVALID_PARAMETER;
1238 (*Data)->AuthData = NULL;
1239 } else {
1240 DataLength = AuthDataLength;
1241 Status = ShellReadFile (FileHandle, &DataLength, (*Data)->AuthData);
1242 ShellCloseFile (&FileHandle);
1243 if (EFI_ERROR (Status)) {
1244 ShellPrintHiiEx (
1245 -1,
1246 -1,
1247 NULL,
1248 STRING_TOKEN (STR_IPSEC_CONFIG_FILE_OPEN_FAILED),
1249 mHiiHandle,
1250 mAppName,
1251 &ValueStr[1]
1252 );
1253 ReturnStatus = EFI_INVALID_PARAMETER;
1254 (*Data)->AuthData = NULL;
1255 } else {
1256 ASSERT (DataLength == AuthDataLength);
1257 *Mask |= AUTH_DATA;
1258 }
1259 }
1260 } else {
1261 for (Index = 0; Index < AuthDataLength; Index++) {
1262 ((CHAR8 *) (*Data)->AuthData)[Index] = (CHAR8) ValueStr[Index];
1263 }
1264 (*Data)->AuthDataSize = AuthDataLength;
1265 *Mask |= AUTH_DATA;
1266 }
1267 }
1268
1269 ValueStr = ShellCommandLineGetValue (ParamPackage, L"--revocation-data");
1270 if (ValueStr != NULL) {
1271 CopyMem ((*Data)->RevocationData, ValueStr, RevocationDataLength);
1272 (*Data)->RevocationDataSize = RevocationDataLength;
1273 *Mask |= REVOCATION_DATA;
1274 } else {
1275 (*Data)->RevocationData = NULL;
1276 }
1277
1278 if (CreateNew) {
1279 if ((*Mask & (PEER_ID | PEER_ADDRESS)) == 0) {
1280 ShellPrintHiiEx (
1281 -1,
1282 -1,
1283 NULL,
1284 STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_ONE_OF_PARAMETERS),
1285 mHiiHandle,
1286 mAppName,
1287 L"--peer-id --peer-address"
1288 );
1289 ReturnStatus = EFI_INVALID_PARAMETER;
1290 } else if ((*Mask & (AUTH_METHOD | AUTH_DATA)) != (AUTH_METHOD | AUTH_DATA)) {
1291 ShellPrintHiiEx (
1292 -1,
1293 -1,
1294 NULL,
1295 STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_ONE_OF_PARAMETERS),
1296 mHiiHandle,
1297 mAppName,
1298 L"--auth-method --auth-data"
1299 );
1300 ReturnStatus = EFI_INVALID_PARAMETER;
1301 }
1302 }
1303
1304 return ReturnStatus;
1305 }
1306
1307 CREATE_POLICY_ENTRY mCreatePolicyEntry[] = {
1308 (CREATE_POLICY_ENTRY) CreateSpdEntry,
1309 (CREATE_POLICY_ENTRY) CreateSadEntry,
1310 (CREATE_POLICY_ENTRY) CreatePadEntry
1311 };
1312
1313 /**
1314 Combine old SPD entry with new SPD entry.
1315
1316 @param[in, out] OldSelector The pointer to the EFI_IPSEC_SPD_SELECTOR structure.
1317 @param[in, out] OldData The pointer to the EFI_IPSEC_SPD_DATA structure.
1318 @param[in] NewSelector The pointer to the EFI_IPSEC_SPD_SELECTOR structure.
1319 @param[in] NewData The pointer to the EFI_IPSEC_SPD_DATA structure.
1320 @param[in] Mask The pointer to the Mask.
1321 @param[out] CreateNew The switch to create new.
1322
1323 @retval EFI_SUCCESS Combined successfully.
1324 @retval EFI_INVALID_PARAMETER Invalid user input parameter.
1325
1326 **/
1327 EFI_STATUS
1328 CombineSpdEntry (
1329 IN OUT EFI_IPSEC_SPD_SELECTOR *OldSelector,
1330 IN OUT EFI_IPSEC_SPD_DATA *OldData,
1331 IN EFI_IPSEC_SPD_SELECTOR *NewSelector,
1332 IN EFI_IPSEC_SPD_DATA *NewData,
1333 IN UINT32 Mask,
1334 OUT BOOLEAN *CreateNew
1335 )
1336 {
1337
1338 //
1339 // Process Selector
1340 //
1341 *CreateNew = FALSE;
1342 if ((Mask & LOCAL) == 0) {
1343 NewSelector->LocalAddressCount = OldSelector->LocalAddressCount;
1344 NewSelector->LocalAddress = OldSelector->LocalAddress;
1345 } else if ((NewSelector->LocalAddressCount != OldSelector->LocalAddressCount) ||
1346 (CompareMem (NewSelector->LocalAddress, OldSelector->LocalAddress, NewSelector->LocalAddressCount * sizeof (EFI_IP_ADDRESS_INFO)) != 0)) {
1347 *CreateNew = TRUE;
1348 }
1349
1350 if ((Mask & REMOTE) == 0) {
1351 NewSelector->RemoteAddressCount = OldSelector->RemoteAddressCount;
1352 NewSelector->RemoteAddress = OldSelector->RemoteAddress;
1353 } else if ((NewSelector->RemoteAddressCount != OldSelector->RemoteAddressCount) ||
1354 (CompareMem (NewSelector->RemoteAddress, OldSelector->RemoteAddress, NewSelector->RemoteAddressCount * sizeof (EFI_IP_ADDRESS_INFO)) != 0)) {
1355 *CreateNew = TRUE;
1356 }
1357
1358 if ((Mask & PROTO) == 0) {
1359 NewSelector->NextLayerProtocol = OldSelector->NextLayerProtocol;
1360 } else if (NewSelector->NextLayerProtocol != OldSelector->NextLayerProtocol) {
1361 *CreateNew = TRUE;
1362 }
1363
1364 switch (NewSelector->NextLayerProtocol) {
1365 case EFI_IP4_PROTO_TCP:
1366 case EFI_IP4_PROTO_UDP:
1367 if ((Mask & LOCAL_PORT) == 0) {
1368 NewSelector->LocalPort = OldSelector->LocalPort;
1369 NewSelector->LocalPortRange = OldSelector->LocalPortRange;
1370 } else if ((NewSelector->LocalPort != OldSelector->LocalPort) ||
1371 (NewSelector->LocalPortRange != OldSelector->LocalPortRange)) {
1372 *CreateNew = TRUE;
1373 }
1374
1375 if ((Mask & REMOTE_PORT) == 0) {
1376 NewSelector->RemotePort = OldSelector->RemotePort;
1377 NewSelector->RemotePortRange = OldSelector->RemotePortRange;
1378 } else if ((NewSelector->RemotePort != OldSelector->RemotePort) ||
1379 (NewSelector->RemotePortRange != OldSelector->RemotePortRange)) {
1380 *CreateNew = TRUE;
1381 }
1382 break;
1383
1384 case EFI_IP4_PROTO_ICMP:
1385 if ((Mask & ICMP_TYPE) == 0) {
1386 NewSelector->LocalPort = OldSelector->LocalPort;
1387 } else if (NewSelector->LocalPort != OldSelector->LocalPort) {
1388 *CreateNew = TRUE;
1389 }
1390
1391 if ((Mask & ICMP_CODE) == 0) {
1392 NewSelector->RemotePort = OldSelector->RemotePort;
1393 } else if (NewSelector->RemotePort != OldSelector->RemotePort) {
1394 *CreateNew = TRUE;
1395 }
1396 break;
1397 }
1398 //
1399 // Process Data
1400 //
1401 OldData->SaIdCount = 0;
1402
1403 if ((Mask & NAME) != 0) {
1404 AsciiStrCpyS ((CHAR8 *) OldData->Name, MAX_PEERID_LEN, (CHAR8 *) NewData->Name);
1405 }
1406
1407 if ((Mask & PACKET_FLAG) != 0) {
1408 OldData->PackageFlag = NewData->PackageFlag;
1409 }
1410
1411 if ((Mask & ACTION) != 0) {
1412 OldData->Action = NewData->Action;
1413 }
1414
1415 if (OldData->Action != EfiIPsecActionProtect) {
1416 OldData->ProcessingPolicy = NULL;
1417 } else {
1418 //
1419 // Protect
1420 //
1421 if (OldData->ProcessingPolicy == NULL) {
1422 //
1423 // Just point to new data if originally NULL.
1424 //
1425 OldData->ProcessingPolicy = NewData->ProcessingPolicy;
1426 if (OldData->ProcessingPolicy->Mode == EfiIPsecTunnel &&
1427 (Mask & (TUNNEL_LOCAL | TUNNEL_REMOTE)) != (TUNNEL_LOCAL | TUNNEL_REMOTE)
1428 ) {
1429 //
1430 // Change to Protect action and Tunnel mode, but without providing local/remote tunnel address.
1431 //
1432 ShellPrintHiiEx (
1433 -1,
1434 -1,
1435 NULL,
1436 STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_ONE_OF_PARAMETERS),
1437 mHiiHandle,
1438 mAppName,
1439 L"--tunnel-local --tunnel-remote"
1440 );
1441 return EFI_INVALID_PARAMETER;
1442 }
1443 } else {
1444 //
1445 // Modify some of the data.
1446 //
1447 if ((Mask & EXT_SEQUENCE) != 0) {
1448 OldData->ProcessingPolicy->ExtSeqNum = NewData->ProcessingPolicy->ExtSeqNum;
1449 }
1450
1451 if ((Mask & SEQUENCE_OVERFLOW) != 0) {
1452 OldData->ProcessingPolicy->SeqOverflow = NewData->ProcessingPolicy->SeqOverflow;
1453 }
1454
1455 if ((Mask & FRAGMENT_CHECK) != 0) {
1456 OldData->ProcessingPolicy->FragCheck = NewData->ProcessingPolicy->FragCheck;
1457 }
1458
1459 if ((Mask & LIFEBYTE) != 0) {
1460 OldData->ProcessingPolicy->SaLifetime.ByteCount = NewData->ProcessingPolicy->SaLifetime.ByteCount;
1461 }
1462
1463 if ((Mask & LIFETIME_SOFT) != 0) {
1464 OldData->ProcessingPolicy->SaLifetime.SoftLifetime = NewData->ProcessingPolicy->SaLifetime.SoftLifetime;
1465 }
1466
1467 if ((Mask & LIFETIME) != 0) {
1468 OldData->ProcessingPolicy->SaLifetime.HardLifetime = NewData->ProcessingPolicy->SaLifetime.HardLifetime;
1469 }
1470
1471 if ((Mask & MODE) != 0) {
1472 OldData->ProcessingPolicy->Mode = NewData->ProcessingPolicy->Mode;
1473 }
1474
1475 if ((Mask & IPSEC_PROTO) != 0) {
1476 OldData->ProcessingPolicy->Proto = NewData->ProcessingPolicy->Proto;
1477 }
1478
1479 if ((Mask & AUTH_ALGO) != 0) {
1480 OldData->ProcessingPolicy->AuthAlgoId = NewData->ProcessingPolicy->AuthAlgoId;
1481 }
1482
1483 if ((Mask & ENCRYPT_ALGO) != 0) {
1484 OldData->ProcessingPolicy->EncAlgoId = NewData->ProcessingPolicy->EncAlgoId;
1485 }
1486
1487 if (OldData->ProcessingPolicy->Mode != EfiIPsecTunnel) {
1488 OldData->ProcessingPolicy->TunnelOption = NULL;
1489 } else {
1490 if (OldData->ProcessingPolicy->TunnelOption == NULL) {
1491 //
1492 // Set from Transport mode to Tunnel mode, should ensure TUNNEL_LOCAL & TUNNEL_REMOTE both exists.
1493 //
1494 if ((Mask & (TUNNEL_LOCAL | TUNNEL_REMOTE)) != (TUNNEL_LOCAL | TUNNEL_REMOTE)) {
1495 ShellPrintHiiEx (
1496 -1,
1497 -1,
1498 NULL,
1499 STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_ONE_OF_PARAMETERS),
1500 mHiiHandle,
1501 mAppName,
1502 L"--tunnel-local --tunnel-remote"
1503 );
1504 return EFI_INVALID_PARAMETER;
1505 }
1506
1507 OldData->ProcessingPolicy->TunnelOption = NewData->ProcessingPolicy->TunnelOption;
1508 } else {
1509 if ((Mask & TUNNEL_LOCAL) != 0) {
1510 CopyMem (
1511 &OldData->ProcessingPolicy->TunnelOption->LocalTunnelAddress,
1512 &NewData->ProcessingPolicy->TunnelOption->LocalTunnelAddress,
1513 sizeof (EFI_IP_ADDRESS)
1514 );
1515 }
1516
1517 if ((Mask & TUNNEL_REMOTE) != 0) {
1518 CopyMem (
1519 &OldData->ProcessingPolicy->TunnelOption->RemoteTunnelAddress,
1520 &NewData->ProcessingPolicy->TunnelOption->RemoteTunnelAddress,
1521 sizeof (EFI_IP_ADDRESS)
1522 );
1523 }
1524
1525 if ((Mask & DONT_FRAGMENT) != 0) {
1526 OldData->ProcessingPolicy->TunnelOption->DF = NewData->ProcessingPolicy->TunnelOption->DF;
1527 }
1528 }
1529 }
1530 }
1531 }
1532
1533 return EFI_SUCCESS;
1534 }
1535
1536 /**
1537 Combine old SAD entry with new SAD entry.
1538
1539 @param[in, out] OldSaId The pointer to the EFI_IPSEC_SA_ID structure.
1540 @param[in, out] OldData The pointer to the EFI_IPSEC_SA_DATA2 structure.
1541 @param[in] NewSaId The pointer to the EFI_IPSEC_SA_ID structure.
1542 @param[in] NewData The pointer to the EFI_IPSEC_SA_DATA2 structure.
1543 @param[in] Mask The pointer to the Mask.
1544 @param[out] CreateNew The switch to create new.
1545
1546 @retval EFI_SUCCESS Combined successfully.
1547 @retval EFI_INVALID_PARAMETER Invalid user input parameter.
1548
1549 **/
1550 EFI_STATUS
1551 CombineSadEntry (
1552 IN OUT EFI_IPSEC_SA_ID *OldSaId,
1553 IN OUT EFI_IPSEC_SA_DATA2 *OldData,
1554 IN EFI_IPSEC_SA_ID *NewSaId,
1555 IN EFI_IPSEC_SA_DATA2 *NewData,
1556 IN UINT32 Mask,
1557 OUT BOOLEAN *CreateNew
1558 )
1559 {
1560
1561 *CreateNew = FALSE;
1562
1563 if ((Mask & SPI) == 0) {
1564 NewSaId->Spi = OldSaId->Spi;
1565 } else if (NewSaId->Spi != OldSaId->Spi) {
1566 *CreateNew = TRUE;
1567 }
1568
1569 if ((Mask & IPSEC_PROTO) == 0) {
1570 NewSaId->Proto = OldSaId->Proto;
1571 } else if (NewSaId->Proto != OldSaId->Proto) {
1572 *CreateNew = TRUE;
1573 }
1574
1575 if ((Mask & DEST) == 0) {
1576 CopyMem (&NewData->TunnelDestinationAddress, &OldData->TunnelDestinationAddress, sizeof (EFI_IP_ADDRESS));
1577 } else if (CompareMem (&NewData->TunnelDestinationAddress, &OldData->TunnelDestinationAddress, sizeof (EFI_IP_ADDRESS)) != 0) {
1578 *CreateNew = TRUE;
1579 }
1580
1581 if ((Mask & SOURCE) == 0) {
1582 CopyMem (&NewData->TunnelSourceAddress, &OldData->TunnelSourceAddress, sizeof (EFI_IP_ADDRESS));
1583 } else if (CompareMem (&NewData->TunnelSourceAddress, &OldData->TunnelSourceAddress, sizeof (EFI_IP_ADDRESS)) != 0) {
1584 *CreateNew = TRUE;
1585 }
1586 //
1587 // Process SA_DATA.
1588 //
1589 if ((Mask & MODE) != 0) {
1590 OldData->Mode = NewData->Mode;
1591 }
1592
1593 if ((Mask & SEQUENCE_NUMBER) != 0) {
1594 OldData->SNCount = NewData->SNCount;
1595 }
1596
1597 if ((Mask & ANTIREPLAY_WINDOW) != 0) {
1598 OldData->AntiReplayWindows = NewData->AntiReplayWindows;
1599 }
1600
1601 if ((Mask & AUTH_ALGO) != 0) {
1602 OldData->AlgoInfo.EspAlgoInfo.AuthAlgoId = NewData->AlgoInfo.EspAlgoInfo.AuthAlgoId;
1603 }
1604
1605 if ((Mask & AUTH_KEY) != 0) {
1606 OldData->AlgoInfo.EspAlgoInfo.AuthKey = NewData->AlgoInfo.EspAlgoInfo.AuthKey;
1607 OldData->AlgoInfo.EspAlgoInfo.AuthKeyLength = NewData->AlgoInfo.EspAlgoInfo.AuthKeyLength;
1608 }
1609
1610 if ((Mask & ENCRYPT_ALGO) != 0) {
1611 OldData->AlgoInfo.EspAlgoInfo.EncAlgoId = NewData->AlgoInfo.EspAlgoInfo.EncAlgoId;
1612 }
1613
1614 if ((Mask & ENCRYPT_KEY) != 0) {
1615 OldData->AlgoInfo.EspAlgoInfo.EncKey = NewData->AlgoInfo.EspAlgoInfo.EncKey;
1616 OldData->AlgoInfo.EspAlgoInfo.EncKeyLength = NewData->AlgoInfo.EspAlgoInfo.EncKeyLength;
1617 }
1618
1619 if (NewSaId->Proto == EfiIPsecAH) {
1620 if ((Mask & (ENCRYPT_ALGO | ENCRYPT_KEY)) != 0) {
1621 //
1622 // Should not provide encrypt_* if AH.
1623 //
1624 ShellPrintHiiEx (
1625 -1,
1626 -1,
1627 NULL,
1628 STRING_TOKEN (STR_IPSEC_CONFIG_UNWANTED_PARAMETER),
1629 mHiiHandle,
1630 mAppName,
1631 L"--encrypt-algo --encrypt-key"
1632 );
1633 return EFI_INVALID_PARAMETER;
1634 }
1635 }
1636
1637 if (NewSaId->Proto == EfiIPsecESP && OldSaId->Proto == EfiIPsecAH) {
1638 //
1639 // AH -> ESP
1640 // Should provide encrypt_algo at least.
1641 //
1642 if ((Mask & ENCRYPT_ALGO) == 0) {
1643 ShellPrintHiiEx (
1644 -1,
1645 -1,
1646 NULL,
1647 STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_PARAMETER),
1648 mHiiHandle,
1649 mAppName,
1650 L"--encrypt-algo"
1651 );
1652 return EFI_INVALID_PARAMETER;
1653 }
1654
1655 //
1656 // Encrypt_key should be provided if algorithm is not NONE.
1657 //
1658 if (NewData->AlgoInfo.EspAlgoInfo.EncAlgoId != IPSEC_EALG_NONE && (Mask & ENCRYPT_KEY) == 0) {
1659 ShellPrintHiiEx (
1660 -1,
1661 -1,
1662 NULL,
1663 STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_PARAMETER),
1664 mHiiHandle,
1665 mAppName,
1666 L"--encrypt-algo"
1667 );
1668 return EFI_INVALID_PARAMETER;
1669 }
1670 }
1671
1672 if ((Mask & LIFEBYTE) != 0) {
1673 OldData->SaLifetime.ByteCount = NewData->SaLifetime.ByteCount;
1674 }
1675
1676 if ((Mask & LIFETIME_SOFT) != 0) {
1677 OldData->SaLifetime.SoftLifetime = NewData->SaLifetime.SoftLifetime;
1678 }
1679
1680 if ((Mask & LIFETIME) != 0) {
1681 OldData->SaLifetime.HardLifetime = NewData->SaLifetime.HardLifetime;
1682 }
1683
1684 if ((Mask & PATH_MTU) != 0) {
1685 OldData->PathMTU = NewData->PathMTU;
1686 }
1687 //
1688 // Process SpdSelector.
1689 //
1690 if (OldData->SpdSelector == NULL) {
1691 if ((Mask & (LOCAL | REMOTE | PROTO | LOCAL_PORT | REMOTE_PORT | ICMP_TYPE | ICMP_CODE)) != 0) {
1692 if ((Mask & (LOCAL | REMOTE | PROTO)) != (LOCAL | REMOTE | PROTO)) {
1693 ShellPrintHiiEx (
1694 -1,
1695 -1,
1696 NULL,
1697 STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_ONE_OF_PARAMETERS),
1698 mHiiHandle,
1699 mAppName,
1700 L"--local --remote --proto"
1701 );
1702 return EFI_INVALID_PARAMETER;
1703 }
1704
1705 OldData->SpdSelector = NewData->SpdSelector;
1706 }
1707 } else {
1708 if ((Mask & LOCAL) != 0) {
1709 OldData->SpdSelector->LocalAddressCount = NewData->SpdSelector->LocalAddressCount;
1710 OldData->SpdSelector->LocalAddress = NewData->SpdSelector->LocalAddress;
1711 }
1712
1713 if ((Mask & REMOTE) != 0) {
1714 OldData->SpdSelector->RemoteAddressCount = NewData->SpdSelector->RemoteAddressCount;
1715 OldData->SpdSelector->RemoteAddress = NewData->SpdSelector->RemoteAddress;
1716 }
1717
1718 if ((Mask & PROTO) != 0) {
1719 OldData->SpdSelector->NextLayerProtocol = NewData->SpdSelector->NextLayerProtocol;
1720 }
1721
1722 if (OldData->SpdSelector != NULL) {
1723 switch (OldData->SpdSelector->NextLayerProtocol) {
1724 case EFI_IP4_PROTO_TCP:
1725 case EFI_IP4_PROTO_UDP:
1726 if ((Mask & LOCAL_PORT) != 0) {
1727 OldData->SpdSelector->LocalPort = NewData->SpdSelector->LocalPort;
1728 }
1729
1730 if ((Mask & REMOTE_PORT) != 0) {
1731 OldData->SpdSelector->RemotePort = NewData->SpdSelector->RemotePort;
1732 }
1733 break;
1734
1735 case EFI_IP4_PROTO_ICMP:
1736 if ((Mask & ICMP_TYPE) != 0) {
1737 OldData->SpdSelector->LocalPort = (UINT8) NewData->SpdSelector->LocalPort;
1738 }
1739
1740 if ((Mask & ICMP_CODE) != 0) {
1741 OldData->SpdSelector->RemotePort = (UINT8) NewData->SpdSelector->RemotePort;
1742 }
1743 break;
1744 }
1745 }
1746 }
1747
1748 return EFI_SUCCESS;
1749 }
1750
1751 /**
1752 Combine old PAD entry with new PAD entry.
1753
1754 @param[in, out] OldPadId The pointer to the EFI_IPSEC_PAD_ID structure.
1755 @param[in, out] OldData The pointer to the EFI_IPSEC_PAD_DATA structure.
1756 @param[in] NewPadId The pointer to the EFI_IPSEC_PAD_ID structure.
1757 @param[in] NewData The pointer to the EFI_IPSEC_PAD_DATA structure.
1758 @param[in] Mask The pointer to the Mask.
1759 @param[out] CreateNew The switch to create new.
1760
1761 @retval EFI_SUCCESS Combined successfully.
1762 @retval EFI_INVALID_PARAMETER Invalid user input parameter.
1763
1764 **/
1765 EFI_STATUS
1766 CombinePadEntry (
1767 IN OUT EFI_IPSEC_PAD_ID *OldPadId,
1768 IN OUT EFI_IPSEC_PAD_DATA *OldData,
1769 IN EFI_IPSEC_PAD_ID *NewPadId,
1770 IN EFI_IPSEC_PAD_DATA *NewData,
1771 IN UINT32 Mask,
1772 OUT BOOLEAN *CreateNew
1773 )
1774 {
1775
1776 *CreateNew = FALSE;
1777
1778 if ((Mask & (PEER_ID | PEER_ADDRESS)) == 0) {
1779 CopyMem (NewPadId, OldPadId, sizeof (EFI_IPSEC_PAD_ID));
1780 } else {
1781 if ((Mask & PEER_ID) != 0) {
1782 if (OldPadId->PeerIdValid) {
1783 if (StrCmp ((CONST CHAR16 *) OldPadId->Id.PeerId, (CONST CHAR16 *) NewPadId->Id.PeerId) != 0) {
1784 *CreateNew = TRUE;
1785 }
1786 } else {
1787 *CreateNew = TRUE;
1788 }
1789 } else {
1790 //
1791 // MASK & PEER_ADDRESS
1792 //
1793 if (OldPadId->PeerIdValid) {
1794 *CreateNew = TRUE;
1795 } else {
1796 if ((CompareMem (&OldPadId->Id.IpAddress.Address, &NewPadId->Id.IpAddress.Address, sizeof (EFI_IP_ADDRESS)) != 0) ||
1797 (OldPadId->Id.IpAddress.PrefixLength != NewPadId->Id.IpAddress.PrefixLength)) {
1798 *CreateNew = TRUE;
1799 }
1800 }
1801 }
1802 }
1803
1804 if ((Mask & AUTH_PROTO) != 0) {
1805 OldData->AuthProtocol = NewData->AuthProtocol;
1806 }
1807
1808 if ((Mask & AUTH_METHOD) != 0) {
1809 OldData->AuthMethod = NewData->AuthMethod;
1810 }
1811
1812 if ((Mask & IKE_ID) != 0) {
1813 OldData->IkeIdFlag = NewData->IkeIdFlag;
1814 }
1815
1816 if ((Mask & AUTH_DATA) != 0) {
1817 OldData->AuthDataSize = NewData->AuthDataSize;
1818 OldData->AuthData = NewData->AuthData;
1819 }
1820
1821 if ((Mask & REVOCATION_DATA) != 0) {
1822 OldData->RevocationDataSize = NewData->RevocationDataSize;
1823 OldData->RevocationData = NewData->RevocationData;
1824 }
1825
1826 return EFI_SUCCESS;
1827 }
1828
1829 COMBINE_POLICY_ENTRY mCombinePolicyEntry[] = {
1830 (COMBINE_POLICY_ENTRY) CombineSpdEntry,
1831 (COMBINE_POLICY_ENTRY) CombineSadEntry,
1832 (COMBINE_POLICY_ENTRY) CombinePadEntry
1833 };
1834
1835 /**
1836 Edit entry information in the database.
1837
1838 @param[in] Selector The pointer to the EFI_IPSEC_CONFIG_SELECTOR structure.
1839 @param[in] Data The pointer to the data.
1840 @param[in] Context The pointer to the INSERT_POLICY_ENTRY_CONTEXT structure.
1841
1842 @retval EFI_SUCCESS Continue the iteration.
1843 @retval EFI_ABORTED Abort the iteration.
1844 **/
1845 EFI_STATUS
1846 EditOperatePolicyEntry (
1847 IN EFI_IPSEC_CONFIG_SELECTOR *Selector,
1848 IN VOID *Data,
1849 IN EDIT_POLICY_ENTRY_CONTEXT *Context
1850 )
1851 {
1852 EFI_STATUS Status;
1853 BOOLEAN CreateNew;
1854
1855 if (mMatchPolicyEntry[Context->DataType] (Selector, Data, &Context->Indexer)) {
1856 ASSERT (Context->DataType < 3);
1857
1858 Status = mCombinePolicyEntry[Context->DataType] (
1859 Selector,
1860 Data,
1861 Context->Selector,
1862 Context->Data,
1863 Context->Mask,
1864 &CreateNew
1865 );
1866 if (!EFI_ERROR (Status)) {
1867 //
1868 // If the Selector already existed, this Entry will be updated by set data.
1869 //
1870 Status = mIpSecConfig->SetData (
1871 mIpSecConfig,
1872 Context->DataType,
1873 Context->Selector, /// New created selector.
1874 Data, /// Old date which has been modified, need to be set data.
1875 Selector
1876 );
1877 ASSERT_EFI_ERROR (Status);
1878
1879 if (CreateNew) {
1880 //
1881 // Edit the entry to a new one. So, we need delete the old entry.
1882 //
1883 Status = mIpSecConfig->SetData (
1884 mIpSecConfig,
1885 Context->DataType,
1886 Selector, /// Old selector.
1887 NULL, /// NULL means to delete this Entry specified by Selector.
1888 NULL
1889 );
1890 ASSERT_EFI_ERROR (Status);
1891 }
1892 }
1893
1894 Context->Status = Status;
1895 return EFI_ABORTED;
1896 }
1897
1898 return EFI_SUCCESS;
1899 }
1900
1901 /**
1902 Edit entry information in database according to datatype.
1903
1904 @param[in] DataType The value of EFI_IPSEC_CONFIG_DATA_TYPE.
1905 @param[in] ParamPackage The pointer to the ParamPackage list.
1906
1907 @retval EFI_SUCCESS Edit entry information successfully.
1908 @retval EFI_NOT_FOUND Can't find the specified entry.
1909 @retval Others Some mistaken case.
1910 **/
1911 EFI_STATUS
1912 EditPolicyEntry (
1913 IN EFI_IPSEC_CONFIG_DATA_TYPE DataType,
1914 IN LIST_ENTRY *ParamPackage
1915 )
1916 {
1917 EFI_STATUS Status;
1918 EDIT_POLICY_ENTRY_CONTEXT Context;
1919 CONST CHAR16 *ValueStr;
1920
1921 ValueStr = ShellCommandLineGetValue (ParamPackage, L"-e");
1922 if (ValueStr == NULL) {
1923 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_INDEX_NOT_SPECIFIED), mHiiHandle, mAppName, ValueStr);
1924 return EFI_NOT_FOUND;
1925 }
1926
1927 Status = mConstructPolicyEntryIndexer[DataType] (&Context.Indexer, ParamPackage);
1928 if (!EFI_ERROR (Status)) {
1929 Context.DataType = DataType;
1930 Context.Status = EFI_NOT_FOUND;
1931 Status = mCreatePolicyEntry[DataType] (&Context.Selector, &Context.Data, ParamPackage, &Context.Mask, FALSE);
1932 if (!EFI_ERROR (Status)) {
1933 ForeachPolicyEntry (DataType, (VISIT_POLICY_ENTRY) EditOperatePolicyEntry, &Context);
1934 Status = Context.Status;
1935 }
1936
1937 if (Context.Selector != NULL) {
1938 gBS->FreePool (Context.Selector);
1939 }
1940
1941 if (Context.Data != NULL) {
1942 gBS->FreePool (Context.Data);
1943 }
1944 }
1945
1946 if (Status == EFI_NOT_FOUND) {
1947 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_INDEX_NOT_FOUND), mHiiHandle, mAppName, ValueStr);
1948 } else if (EFI_ERROR (Status)) {
1949 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_EDIT_FAILED), mHiiHandle, mAppName);
1950 }
1951
1952 return Status;
1953
1954 }
1955
1956 /**
1957 Insert entry information in database.
1958
1959 @param[in] Selector The pointer to the EFI_IPSEC_CONFIG_SELECTOR structure.
1960 @param[in] Data The pointer to the data.
1961 @param[in] Context The pointer to the INSERT_POLICY_ENTRY_CONTEXT structure.
1962
1963 @retval EFI_SUCCESS Continue the iteration.
1964 @retval EFI_ABORTED Abort the iteration.
1965 **/
1966 EFI_STATUS
1967 InsertPolicyEntry (
1968 IN EFI_IPSEC_CONFIG_SELECTOR *Selector,
1969 IN VOID *Data,
1970 IN INSERT_POLICY_ENTRY_CONTEXT *Context
1971 )
1972 {
1973 //
1974 // Found the entry which we want to insert before.
1975 //
1976 if (mMatchPolicyEntry[Context->DataType] (Selector, Data, &Context->Indexer)) {
1977
1978 Context->Status = mIpSecConfig->SetData (
1979 mIpSecConfig,
1980 Context->DataType,
1981 Context->Selector,
1982 Context->Data,
1983 Selector
1984 );
1985 //
1986 // Abort the iteration after the insertion.
1987 //
1988 return EFI_ABORTED;
1989 }
1990
1991 return EFI_SUCCESS;
1992 }
1993
1994 /**
1995 Insert or add entry information in database according to datatype.
1996
1997 @param[in] DataType The value of EFI_IPSEC_CONFIG_DATA_TYPE.
1998 @param[in] ParamPackage The pointer to the ParamPackage list.
1999
2000 @retval EFI_SUCCESS Insert or add entry information successfully.
2001 @retval EFI_NOT_FOUND Can't find the specified entry.
2002 @retval EFI_BUFFER_TOO_SMALL The entry already existed.
2003 @retval EFI_UNSUPPORTED The operation is not supported.
2004 @retval Others Some mistaken case.
2005 **/
2006 EFI_STATUS
2007 AddOrInsertPolicyEntry (
2008 IN EFI_IPSEC_CONFIG_DATA_TYPE DataType,
2009 IN LIST_ENTRY *ParamPackage
2010 )
2011 {
2012 EFI_STATUS Status;
2013 EFI_IPSEC_CONFIG_SELECTOR *Selector;
2014 VOID *Data;
2015 INSERT_POLICY_ENTRY_CONTEXT Context;
2016 UINT32 Mask;
2017 UINTN DataSize;
2018 CONST CHAR16 *ValueStr;
2019
2020 Status = mCreatePolicyEntry[DataType] (&Selector, &Data, ParamPackage, &Mask, TRUE);
2021 if (!EFI_ERROR (Status)) {
2022 //
2023 // Find if the Selector to be inserted already exists.
2024 //
2025 DataSize = 0;
2026 Status = mIpSecConfig->GetData (
2027 mIpSecConfig,
2028 DataType,
2029 Selector,
2030 &DataSize,
2031 NULL
2032 );
2033 if (Status == EFI_BUFFER_TOO_SMALL) {
2034 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_ALREADY_EXISTS), mHiiHandle, mAppName);
2035 } else if (ShellCommandLineGetFlag (ParamPackage, L"-a")) {
2036 Status = mIpSecConfig->SetData (
2037 mIpSecConfig,
2038 DataType,
2039 Selector,
2040 Data,
2041 NULL
2042 );
2043 } else {
2044 ValueStr = ShellCommandLineGetValue (ParamPackage, L"-i");
2045 if (ValueStr == NULL) {
2046 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_INDEX_NOT_SPECIFIED), mHiiHandle, mAppName, ValueStr);
2047 return EFI_NOT_FOUND;
2048 }
2049
2050 Status = mConstructPolicyEntryIndexer[DataType] (&Context.Indexer, ParamPackage);
2051 if (!EFI_ERROR (Status)) {
2052 Context.DataType = DataType;
2053 Context.Status = EFI_NOT_FOUND;
2054 Context.Selector = Selector;
2055 Context.Data = Data;
2056
2057 ForeachPolicyEntry (DataType, (VISIT_POLICY_ENTRY) InsertPolicyEntry, &Context);
2058 Status = Context.Status;
2059 if (Status == EFI_NOT_FOUND) {
2060 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_INDEX_NOT_FOUND), mHiiHandle, mAppName, ValueStr);
2061 }
2062 }
2063 }
2064
2065 gBS->FreePool (Selector);
2066 gBS->FreePool (Data);
2067 }
2068
2069 if (Status == EFI_UNSUPPORTED) {
2070 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_INSERT_UNSUPPORT), mHiiHandle, mAppName);
2071 } else if (EFI_ERROR (Status)) {
2072 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_INSERT_FAILED), mHiiHandle, mAppName);
2073 }
2074
2075 return Status;
2076 }