1 /** @file
2   The implementation of dump policy entry function in IpSecConfig application.
3 
4   Copyright (c) 2009 - 2011, 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 "Dump.h"
18 #include "ForEach.h"
19 #include "Helper.h"
20 
21 /**
22   Private function called to get the version infomation from an EFI_IP_ADDRESS_INFO structure.
23 
24   @param[in] AddressInfo    The pointer to the EFI_IP_ADDRESS_INFO structure.
25 
26   @return the value of version.
27 **/
28 UINTN
GetVerFromAddrInfo(IN EFI_IP_ADDRESS_INFO * AddressInfo)29 GetVerFromAddrInfo (
30   IN EFI_IP_ADDRESS_INFO    *AddressInfo
31 )
32 {
33   if((AddressInfo->PrefixLength <= 32) && (AddressInfo->Address.Addr[1] == 0) &&
34      (AddressInfo->Address.Addr[2] == 0) && (AddressInfo->Address.Addr[3] == 0)) {
35     return IP_VERSION_4;
36   } else {
37     return IP_VERSION_6;
38   }
39 }
40 
41 /**
42   Private function called to get the version information from a EFI_IP_ADDRESS structure.
43 
44   @param[in] Address    The pointer to the EFI_IP_ADDRESS structure.
45 
46   @return The value of the version.
47 **/
48 UINTN
GetVerFromIpAddr(IN EFI_IP_ADDRESS * Address)49 GetVerFromIpAddr (
50   IN EFI_IP_ADDRESS    *Address
51 )
52 {
53   if ((Address->Addr[1] == 0) && (Address->Addr[2] == 0) && (Address->Addr[3] == 0)) {
54     return IP_VERSION_4;
55   } else {
56     return IP_VERSION_6;
57   }
58 }
59 
60 /**
61   Private function called to print an ASCII string in unicode char format.
62 
63   @param[in] Str       The pointer to the ASCII string.
64   @param[in] Length    The value of the ASCII string length.
65 **/
66 VOID
DumpAsciiString(IN CHAR8 * Str,IN UINTN Length)67 DumpAsciiString (
68   IN CHAR8    *Str,
69   IN UINTN    Length
70   )
71 {
72   UINTN    Index;
73   Print (L"\"");
74   for (Index = 0; Index < Length; Index++) {
75     Print (L"%c", (CHAR16) Str[Index]);
76   }
77   Print (L"\"");
78 }
79 
80 /**
81   Private function called to print a buffer in Hex format.
82 
83   @param[in] Data      The pointer to the buffer.
84   @param[in] Length    The size of the buffer.
85 
86 **/
87 VOID
DumpBuf(IN UINT8 * Data,IN UINTN Length)88 DumpBuf (
89   IN UINT8    *Data,
90   IN UINTN    Length
91   )
92 {
93   UINTN    Index;
94   for (Index = 0; Index < Length; Index++) {
95     Print (L"%02x ", Data[Index]);
96   }
97 }
98 
99 /**
100   Private function called to print EFI_IP_ADDRESS_INFO content.
101 
102   @param[in] AddressInfo    The pointer to the EFI_IP_ADDRESS_INFO structure.
103 **/
104 VOID
DumpAddressInfo(IN EFI_IP_ADDRESS_INFO * AddressInfo)105 DumpAddressInfo (
106   IN EFI_IP_ADDRESS_INFO    *AddressInfo
107   )
108 {
109   if (IP_VERSION_4 == GetVerFromAddrInfo (AddressInfo)) {
110     Print (
111       L"%d.%d.%d.%d",
112       (UINTN) AddressInfo->Address.v4.Addr[0],
113       (UINTN) AddressInfo->Address.v4.Addr[1],
114       (UINTN) AddressInfo->Address.v4.Addr[2],
115       (UINTN) AddressInfo->Address.v4.Addr[3]
116       );
117     if (AddressInfo->PrefixLength != 32) {
118       Print (L"/%d", (UINTN) AddressInfo->PrefixLength);
119     }
120   }
121 
122   if (IP_VERSION_6 == GetVerFromAddrInfo (AddressInfo)) {
123     Print (
124       L"%x:%x:%x:%x:%x:%x:%x:%x",
125       (((UINT16) AddressInfo->Address.v6.Addr[0]) << 8) | ((UINT16) AddressInfo->Address.v6.Addr[1]),
126       (((UINT16) AddressInfo->Address.v6.Addr[2]) << 8) | ((UINT16) AddressInfo->Address.v6.Addr[3]),
127       (((UINT16) AddressInfo->Address.v6.Addr[4]) << 8) | ((UINT16) AddressInfo->Address.v6.Addr[5]),
128       (((UINT16) AddressInfo->Address.v6.Addr[6]) << 8) | ((UINT16) AddressInfo->Address.v6.Addr[7]),
129       (((UINT16) AddressInfo->Address.v6.Addr[8]) << 8) | ((UINT16) AddressInfo->Address.v6.Addr[9]),
130       (((UINT16) AddressInfo->Address.v6.Addr[10]) << 8) | ((UINT16) AddressInfo->Address.v6.Addr[11]),
131       (((UINT16) AddressInfo->Address.v6.Addr[12]) << 8) | ((UINT16) AddressInfo->Address.v6.Addr[13]),
132       (((UINT16) AddressInfo->Address.v6.Addr[14]) << 8) | ((UINT16) AddressInfo->Address.v6.Addr[15])
133       );
134     if (AddressInfo->PrefixLength != 128) {
135       Print (L"/%d", AddressInfo->PrefixLength);
136     }
137   }
138 }
139 
140 /**
141   Private function called to print EFI_IP_ADDRESS content.
142 
143   @param[in] IpAddress    The pointer to the EFI_IP_ADDRESS structure.
144 **/
145 VOID
DumpIpAddress(IN EFI_IP_ADDRESS * IpAddress)146 DumpIpAddress (
147   IN EFI_IP_ADDRESS    *IpAddress
148   )
149 {
150   if (IP_VERSION_4 == GetVerFromIpAddr (IpAddress)) {
151     Print (
152       L"%d.%d.%d.%d",
153       (UINTN) IpAddress->v4.Addr[0],
154       (UINTN) IpAddress->v4.Addr[1],
155       (UINTN) IpAddress->v4.Addr[2],
156       (UINTN) IpAddress->v4.Addr[3]
157       );
158   }
159 
160   if (IP_VERSION_6 == GetVerFromIpAddr (IpAddress)) {
161     Print (
162       L"%x:%x:%x:%x:%x:%x:%x:%x",
163       (((UINT16) IpAddress->v6.Addr[0]) << 8) | ((UINT16) IpAddress->v6.Addr[1]),
164       (((UINT16) IpAddress->v6.Addr[2]) << 8) | ((UINT16) IpAddress->v6.Addr[3]),
165       (((UINT16) IpAddress->v6.Addr[4]) << 8) | ((UINT16) IpAddress->v6.Addr[5]),
166       (((UINT16) IpAddress->v6.Addr[6]) << 8) | ((UINT16) IpAddress->v6.Addr[7]),
167       (((UINT16) IpAddress->v6.Addr[8]) << 8) | ((UINT16) IpAddress->v6.Addr[9]),
168       (((UINT16) IpAddress->v6.Addr[10]) << 8) | ((UINT16) IpAddress->v6.Addr[11]),
169       (((UINT16) IpAddress->v6.Addr[12]) << 8) | ((UINT16) IpAddress->v6.Addr[13]),
170       (((UINT16) IpAddress->v6.Addr[14]) << 8) | ((UINT16) IpAddress->v6.Addr[15])
171       );
172   }
173 
174 }
175 
176 /**
177   Private function called to print EFI_IPSEC_SPD_SELECTOR content.
178 
179   @param[in] Selector    The pointer to the EFI_IPSEC_SPD_SELECTOR structure.
180 **/
181 VOID
DumpSpdSelector(IN EFI_IPSEC_SPD_SELECTOR * Selector)182 DumpSpdSelector (
183   IN EFI_IPSEC_SPD_SELECTOR    *Selector
184   )
185 {
186   UINT32    Index;
187   CHAR16    *Str;
188 
189   for (Index = 0; Index < Selector->LocalAddressCount; Index++) {
190     if (Index > 0) {
191       Print (L",");
192     }
193 
194     DumpAddressInfo (&Selector->LocalAddress[Index]);
195   }
196 
197   if (Index == 0) {
198     Print (L"localhost");
199   }
200 
201   Print (L" -> ");
202 
203   for (Index = 0; Index < Selector->RemoteAddressCount; Index++) {
204     if (Index > 0) {
205       Print (L",");
206     }
207 
208     DumpAddressInfo (&Selector->RemoteAddress[Index]);
209   }
210 
211   Str = MapIntegerToString (Selector->NextLayerProtocol, mMapIpProtocol);
212   if (Str != NULL) {
213     Print (L" %s", Str);
214   } else {
215     Print (L" proto:%d", (UINTN) Selector->NextLayerProtocol);
216   }
217 
218   if ((Selector->NextLayerProtocol == EFI_IP4_PROTO_TCP) || (Selector->NextLayerProtocol == EFI_IP4_PROTO_UDP)) {
219     Print (L" port:");
220     if (Selector->LocalPort != EFI_IPSEC_ANY_PORT) {
221       Print (L"%d", Selector->LocalPort);
222       if (Selector->LocalPortRange != 0) {
223         Print (L"~%d", (UINTN) Selector->LocalPort + Selector->LocalPortRange);
224       }
225     } else {
226       Print (L"any");
227     }
228 
229     Print (L" -> ");
230     if (Selector->RemotePort != EFI_IPSEC_ANY_PORT) {
231       Print (L"%d", Selector->RemotePort);
232       if (Selector->RemotePortRange != 0) {
233         Print (L"~%d", (UINTN) Selector->RemotePort + Selector->RemotePortRange);
234       }
235     } else {
236       Print (L"any");
237     }
238   } else if (Selector->NextLayerProtocol == EFI_IP4_PROTO_ICMP) {
239     Print (L" class/code:");
240     if (Selector->LocalPort != 0) {
241       Print (L"%d", (UINTN) (UINT8) Selector->LocalPort);
242     } else {
243       Print (L"any");
244     }
245 
246     Print (L"/");
247     if (Selector->RemotePort != 0) {
248       Print (L"%d", (UINTN) (UINT8) Selector->RemotePort);
249     } else {
250       Print (L"any");
251     }
252   }
253 }
254 
255 /**
256   Print EFI_IPSEC_SPD_SELECTOR and EFI_IPSEC_SPD_DATA content.
257 
258   @param[in] Selector      The pointer to the EFI_IPSEC_SPD_SELECTOR structure.
259   @param[in] Data          The pointer to the EFI_IPSEC_SPD_DATA structure.
260   @param[in] EntryIndex    The pointer to the Index in SPD Database.
261 
262   @retval EFI_SUCCESS    Dump SPD information successfully.
263 **/
264 EFI_STATUS
DumpSpdEntry(IN EFI_IPSEC_SPD_SELECTOR * Selector,IN EFI_IPSEC_SPD_DATA * Data,IN UINTN * EntryIndex)265 DumpSpdEntry (
266   IN EFI_IPSEC_SPD_SELECTOR    *Selector,
267   IN EFI_IPSEC_SPD_DATA        *Data,
268   IN UINTN                     *EntryIndex
269   )
270 {
271   BOOLEAN    HasPre;
272   CHAR16     DataName[128];
273   CHAR16     *String1;
274   CHAR16     *String2;
275   CHAR16     *String3;
276   UINT8      Index;
277 
278   Print (L"%d.", (*EntryIndex)++);
279 
280   //
281   // xxx.xxx.xxx.xxx/yy -> xxx.xxx.xxx.xx/yy proto:23 port:100~300 -> 300~400
282   // Protect  PF:0x34323423 Name:First Entry
283   // ext-sequence sequence-overflow fragcheck life:[B0,S1024,H3600]
284   // ESP algo1 algo2 Tunnel [xxx.xxx.xxx.xxx xxx.xxx.xxx.xxx set]
285   //
286 
287   DumpSpdSelector (Selector);
288   Print (L"\n  ");
289 
290   Print (L"%s ", MapIntegerToString (Data->Action, mMapIpSecAction));
291   Print (L"PF:%08x ", Data->PackageFlag);
292 
293   Index = 0;
294   while (Data->Name[Index] != 0) {
295     DataName[Index] = (CHAR16) Data->Name[Index];
296     Index++;
297     ASSERT (Index < 128);
298   }
299   DataName[Index] = L'\0';
300 
301   Print (L"Name:%s", DataName);
302 
303   if (Data->Action == EfiIPsecActionProtect) {
304     Print (L"\n  ");
305     if (Data->ProcessingPolicy->ExtSeqNum) {
306       Print (L"ext-sequence ");
307     }
308 
309     if (Data->ProcessingPolicy->SeqOverflow) {
310       Print (L"sequence-overflow ");
311     }
312 
313     if (Data->ProcessingPolicy->FragCheck) {
314       Print (L"fragment-check ");
315     }
316 
317     HasPre = FALSE;
318     if (Data->ProcessingPolicy->SaLifetime.ByteCount != 0) {
319       Print (HasPre ? L"," : L"life:[");
320       Print (L"%lxB", Data->ProcessingPolicy->SaLifetime.ByteCount);
321       HasPre = TRUE;
322     }
323 
324     if (Data->ProcessingPolicy->SaLifetime.SoftLifetime != 0) {
325       Print (HasPre ? L"," : L"life:[");
326       Print (L"%lxs", Data->ProcessingPolicy->SaLifetime.SoftLifetime);
327       HasPre = TRUE;
328     }
329 
330     if (Data->ProcessingPolicy->SaLifetime.HardLifetime != 0) {
331       Print (HasPre ? L"," : L"life:[");
332       Print (L"%lxS", Data->ProcessingPolicy->SaLifetime.HardLifetime);
333       HasPre = TRUE;
334     }
335 
336     if (HasPre) {
337       Print (L"]");
338     }
339 
340     if (HasPre || Data->ProcessingPolicy->ExtSeqNum ||
341         Data->ProcessingPolicy->SeqOverflow || Data->ProcessingPolicy->FragCheck) {
342       Print (L"\n  ");
343     }
344 
345     String1 = MapIntegerToString (Data->ProcessingPolicy->Proto, mMapIpSecProtocol);
346     String2 = MapIntegerToString (Data->ProcessingPolicy->AuthAlgoId, mMapAuthAlgo);
347     String3 = MapIntegerToString (Data->ProcessingPolicy->EncAlgoId, mMapEncAlgo);
348     Print (
349       L"%s Auth:%s Encrypt:%s ",
350       String1,
351       String2,
352       String3
353       );
354 
355     Print (L"%s ", MapIntegerToString (Data->ProcessingPolicy->Mode, mMapIpSecMode));
356     if (Data->ProcessingPolicy->Mode == EfiIPsecTunnel) {
357       Print (L"[");
358       DumpIpAddress (&Data->ProcessingPolicy->TunnelOption->LocalTunnelAddress);
359       Print (L" -> ");
360       DumpIpAddress (&Data->ProcessingPolicy->TunnelOption->RemoteTunnelAddress);
361       Print (L" %s]", MapIntegerToString (Data->ProcessingPolicy->TunnelOption->DF, mMapDfOption));
362     }
363   }
364 
365   Print (L"\n");
366 
367   return EFI_SUCCESS;
368 }
369 
370 /**
371   Print EFI_IPSEC_SA_ID and EFI_IPSEC_SA_DATA2 content.
372 
373   @param[in] SaId          The pointer to the EFI_IPSEC_SA_ID structure.
374   @param[in] Data          The pointer to the EFI_IPSEC_SA_DATA2 structure.
375   @param[in] EntryIndex    The pointer to the Index in the SAD Database.
376 
377   @retval EFI_SUCCESS    Dump SAD information successfully.
378 **/
379 EFI_STATUS
DumpSadEntry(IN EFI_IPSEC_SA_ID * SaId,IN EFI_IPSEC_SA_DATA2 * Data,IN UINTN * EntryIndex)380 DumpSadEntry (
381   IN EFI_IPSEC_SA_ID      *SaId,
382   IN EFI_IPSEC_SA_DATA2   *Data,
383   IN UINTN                *EntryIndex
384   )
385 {
386   BOOLEAN    HasPre;
387   CHAR16     *AuthAlgoStr;
388   CHAR16     *EncAlgoStr;
389 
390   AuthAlgoStr      = NULL;
391   EncAlgoStr       = NULL;
392 
393   //
394   // SPI:1234 ESP Destination:xxx.xxx.xxx.xxx
395   //  Mode:Transport SeqNum:134 AntiReplayWin:64 life:[0B,1023s,3400S] PathMTU:34
396   //  Auth:xxxx/password Encrypt:yyyy/password
397   //  xxx.xxx.xxx.xxx/yy -> xxx.xxx.xxx.xx/yy proto:23 port:100~300 -> 300~400
398   //
399 
400   Print (L"%d.", (*EntryIndex)++);
401   Print (L"0x%x %s ", (UINTN) SaId->Spi, MapIntegerToString (SaId->Proto, mMapIpSecProtocol));
402   if (Data->Mode == EfiIPsecTunnel) {
403     Print (L"TunnelSourceAddress:");
404     DumpIpAddress (&Data->TunnelSourceAddress);
405     Print (L"\n");
406     Print (L"  TunnelDestination:");
407     DumpIpAddress (&Data->TunnelDestinationAddress);
408     Print (L"\n");
409   }
410 
411   Print (
412     L"  Mode:%s SeqNum:%lx AntiReplayWin:%d ",
413     MapIntegerToString (Data->Mode, mMapIpSecMode),
414     Data->SNCount,
415     (UINTN) Data->AntiReplayWindows
416     );
417 
418   HasPre = FALSE;
419   if (Data->SaLifetime.ByteCount != 0) {
420     Print (HasPre ? L"," : L"life:[");
421     Print (L"%lxB", Data->SaLifetime.ByteCount);
422     HasPre = TRUE;
423   }
424 
425   if (Data->SaLifetime.SoftLifetime != 0) {
426     Print (HasPre ? L"," : L"life:[");
427     Print (L"%lxs", Data->SaLifetime.SoftLifetime);
428     HasPre = TRUE;
429   }
430 
431   if (Data->SaLifetime.HardLifetime != 0) {
432     Print (HasPre ? L"," : L"life:[");
433     Print (L"%lxS", Data->SaLifetime.HardLifetime);
434     HasPre = TRUE;
435   }
436 
437   if (HasPre) {
438     Print (L"] ");
439   }
440 
441   Print (L"PathMTU:%d\n", (UINTN) Data->PathMTU);
442 
443   if (SaId->Proto == EfiIPsecAH) {
444     Print (
445       L"  Auth:%s/%s\n",
446       MapIntegerToString (Data->AlgoInfo.AhAlgoInfo.AuthAlgoId, mMapAuthAlgo),
447       Data->AlgoInfo.AhAlgoInfo.AuthKey
448       );
449   } else {
450     AuthAlgoStr = MapIntegerToString (Data->AlgoInfo.EspAlgoInfo.AuthAlgoId, mMapAuthAlgo);
451     EncAlgoStr  = MapIntegerToString (Data->AlgoInfo.EspAlgoInfo.EncAlgoId, mMapEncAlgo);
452 
453     if (Data->ManualSet) {
454       //
455       // if the SAD is set manually the key is a Ascii string in most of time.
456       // Print the Key in Ascii string format.
457       //
458       Print (L"  Auth:%s/",AuthAlgoStr);
459       DumpAsciiString (
460         Data->AlgoInfo.EspAlgoInfo.AuthKey,
461         Data->AlgoInfo.EspAlgoInfo.AuthKeyLength
462         );
463       Print (L"\n  Encrypt:%s/",EncAlgoStr);
464       DumpAsciiString (
465         Data->AlgoInfo.EspAlgoInfo.EncKey,
466         Data->AlgoInfo.EspAlgoInfo.EncKeyLength
467         );
468     } else {
469       //
470       // if the SAD is created by IKE, the key is a set of hex value in buffer.
471       // Print the Key in Hex format.
472       //
473       Print (L"  Auth:%s/",AuthAlgoStr);
474       DumpBuf ((UINT8 *)(Data->AlgoInfo.EspAlgoInfo.AuthKey), Data->AlgoInfo.EspAlgoInfo.AuthKeyLength);
475 
476       Print (L"\n  Encrypt:%s/",EncAlgoStr);
477       DumpBuf ((UINT8 *)(Data->AlgoInfo.EspAlgoInfo.EncKey), Data->AlgoInfo.EspAlgoInfo.EncKeyLength);
478     }
479   }
480   Print (L"\n");
481   if (Data->SpdSelector != NULL) {
482     Print (L"  ");
483     DumpSpdSelector (Data->SpdSelector);
484     Print (L"\n");
485   }
486 
487   return EFI_SUCCESS;
488 }
489 
490 /**
491   Print EFI_IPSEC_PAD_ID and EFI_IPSEC_PAD_DATA content.
492 
493   @param[in] PadId         The pointer to the EFI_IPSEC_PAD_ID structure.
494   @param[in] Data          The pointer to the EFI_IPSEC_PAD_DATA structure.
495   @param[in] EntryIndex    The pointer to the Index in the PAD Database.
496 
497   @retval EFI_SUCCESS    Dump PAD information successfully.
498 **/
499 EFI_STATUS
DumpPadEntry(IN EFI_IPSEC_PAD_ID * PadId,IN EFI_IPSEC_PAD_DATA * Data,IN UINTN * EntryIndex)500 DumpPadEntry (
501   IN EFI_IPSEC_PAD_ID      *PadId,
502   IN EFI_IPSEC_PAD_DATA    *Data,
503   IN UINTN                 *EntryIndex
504   )
505 {
506   CHAR16    *String1;
507   CHAR16    *String2;
508 
509   //
510   // ADDR:10.23.17.34/15
511   // IDEv1 PreSharedSecret IKE-ID
512   // password
513   //
514 
515   Print (L"%d.", (*EntryIndex)++);
516 
517   if (PadId->PeerIdValid) {
518     Print (L"ID:%s", PadId->Id.PeerId);
519   } else {
520     Print (L"ADDR:");
521     DumpAddressInfo (&PadId->Id.IpAddress);
522   }
523 
524   Print (L"\n");
525 
526   String1 = MapIntegerToString (Data->AuthProtocol, mMapAuthProto);
527   String2 = MapIntegerToString (Data->AuthMethod, mMapAuthMethod);
528   Print (
529     L"  %s %s",
530     String1,
531     String2
532     );
533 
534   if (Data->IkeIdFlag) {
535     Print (L"IKE-ID");
536   }
537 
538   Print (L"\n");
539 
540   if (Data->AuthData != NULL) {
541     DumpAsciiString (Data->AuthData, Data->AuthDataSize);
542     Print (L"\n");
543   }
544 
545   if (Data->RevocationData != NULL) {
546     Print (L"  %s\n", Data->RevocationData);
547   }
548 
549   return EFI_SUCCESS;
550 
551 }
552 
553 VISIT_POLICY_ENTRY  mDumpPolicyEntry[] = {
554   (VISIT_POLICY_ENTRY) DumpSpdEntry,
555   (VISIT_POLICY_ENTRY) DumpSadEntry,
556   (VISIT_POLICY_ENTRY) DumpPadEntry
557 };
558 
559 /**
560   Print all entry information in the database according to datatype.
561 
562   @param[in] DataType        The value of EFI_IPSEC_CONFIG_DATA_TYPE.
563   @param[in] ParamPackage    The pointer to the ParamPackage list.
564 
565   @retval EFI_SUCCESS    Dump all information successfully.
566   @retval Others         Some mistaken case.
567 **/
568 EFI_STATUS
ListPolicyEntry(IN EFI_IPSEC_CONFIG_DATA_TYPE DataType,IN LIST_ENTRY * ParamPackage)569 ListPolicyEntry (
570   IN EFI_IPSEC_CONFIG_DATA_TYPE    DataType,
571   IN LIST_ENTRY                    *ParamPackage
572   )
573 {
574   UINTN  EntryIndex;
575 
576   EntryIndex = 0;
577   return ForeachPolicyEntry (DataType, mDumpPolicyEntry[DataType], &EntryIndex);
578 }
579 
580