From 098f8621634f1cbdd1253c9957eed09a505223f5 Mon Sep 17 00:00:00 2001 From: Guo Mang Date: Thu, 27 Apr 2017 11:16:34 +0800 Subject: NetWorkPkg: Move to new location Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Guo Mang --- Core/NetworkPkg/Application/IpsecConfig/Delete.c | 110 ++ Core/NetworkPkg/Application/IpsecConfig/Delete.h | 42 + Core/NetworkPkg/Application/IpsecConfig/Dump.c | 579 ++++++ Core/NetworkPkg/Application/IpsecConfig/Dump.h | 34 + Core/NetworkPkg/Application/IpsecConfig/ForEach.c | 115 ++ Core/NetworkPkg/Application/IpsecConfig/ForEach.h | 54 + Core/NetworkPkg/Application/IpsecConfig/Helper.c | 420 ++++ Core/NetworkPkg/Application/IpsecConfig/Helper.h | 143 ++ Core/NetworkPkg/Application/IpsecConfig/Indexer.c | 255 +++ Core/NetworkPkg/Application/IpsecConfig/Indexer.h | 58 + .../Application/IpsecConfig/IpSecConfig.c | 812 ++++++++ .../Application/IpsecConfig/IpSecConfig.h | 149 ++ .../Application/IpsecConfig/IpSecConfig.inf | 76 + .../Application/IpsecConfig/IpSecConfig.uni | 23 + .../Application/IpsecConfig/IpSecConfigExtra.uni | 20 + .../Application/IpsecConfig/IpSecConfigStrings.uni | 133 ++ Core/NetworkPkg/Application/IpsecConfig/Match.c | 163 ++ Core/NetworkPkg/Application/IpsecConfig/Match.h | 41 + .../Application/IpsecConfig/PolicyEntryOperation.c | 2076 ++++++++++++++++++++ .../Application/IpsecConfig/PolicyEntryOperation.h | 159 ++ 20 files changed, 5462 insertions(+) create mode 100644 Core/NetworkPkg/Application/IpsecConfig/Delete.c create mode 100644 Core/NetworkPkg/Application/IpsecConfig/Delete.h create mode 100644 Core/NetworkPkg/Application/IpsecConfig/Dump.c create mode 100644 Core/NetworkPkg/Application/IpsecConfig/Dump.h create mode 100644 Core/NetworkPkg/Application/IpsecConfig/ForEach.c create mode 100644 Core/NetworkPkg/Application/IpsecConfig/ForEach.h create mode 100644 Core/NetworkPkg/Application/IpsecConfig/Helper.c create mode 100644 Core/NetworkPkg/Application/IpsecConfig/Helper.h create mode 100644 Core/NetworkPkg/Application/IpsecConfig/Indexer.c create mode 100644 Core/NetworkPkg/Application/IpsecConfig/Indexer.h create mode 100644 Core/NetworkPkg/Application/IpsecConfig/IpSecConfig.c create mode 100644 Core/NetworkPkg/Application/IpsecConfig/IpSecConfig.h create mode 100644 Core/NetworkPkg/Application/IpsecConfig/IpSecConfig.inf create mode 100644 Core/NetworkPkg/Application/IpsecConfig/IpSecConfig.uni create mode 100644 Core/NetworkPkg/Application/IpsecConfig/IpSecConfigExtra.uni create mode 100644 Core/NetworkPkg/Application/IpsecConfig/IpSecConfigStrings.uni create mode 100644 Core/NetworkPkg/Application/IpsecConfig/Match.c create mode 100644 Core/NetworkPkg/Application/IpsecConfig/Match.h create mode 100644 Core/NetworkPkg/Application/IpsecConfig/PolicyEntryOperation.c create mode 100644 Core/NetworkPkg/Application/IpsecConfig/PolicyEntryOperation.h (limited to 'Core/NetworkPkg/Application/IpsecConfig') diff --git a/Core/NetworkPkg/Application/IpsecConfig/Delete.c b/Core/NetworkPkg/Application/IpsecConfig/Delete.c new file mode 100644 index 0000000000..caeb1c8350 --- /dev/null +++ b/Core/NetworkPkg/Application/IpsecConfig/Delete.c @@ -0,0 +1,110 @@ +/** @file + The implementation of delete policy entry function in IpSecConfig application. + + Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "IpSecConfig.h" +#include "Indexer.h" +#include "Delete.h" +#include "Match.h" +#include "ForEach.h" + +/** + Private function to delete entry information in database. + + @param[in] Selector The pointer to EFI_IPSEC_CONFIG_SELECTOR structure. + @param[in] Data The pointer to Data. + @param[in] Context The pointer to DELETE_POLICY_ENTRY_CONTEXT. + + @retval EFI_ABORTED Abort the iteration. + @retval EFI_SUCCESS Continue the iteration. +**/ +EFI_STATUS +DeletePolicyEntry ( + IN EFI_IPSEC_CONFIG_SELECTOR *Selector, + IN VOID *Data, + IN DELETE_POLICY_ENTRY_CONTEXT *Context + ) +{ + if (mMatchPolicyEntry[Context->DataType] (Selector, Data, &Context->Indexer)) { + Context->Status = mIpSecConfig->SetData ( + mIpSecConfig, + Context->DataType, + Selector, + NULL, + NULL + ); + // + // Abort the iteration after the insertion. + // + return EFI_ABORTED; + } + + return EFI_SUCCESS; +} + +/** + Flush or delete entry information in the database according to datatype. + + @param[in] DataType The value of EFI_IPSEC_CONFIG_DATA_TYPE. + @param[in] ParamPackage The pointer to the ParamPackage list. + + @retval EFI_SUCCESS Delete entry information successfully. + @retval EFI_NOT_FOUND Can't find the specified entry. + @retval Others Some mistaken case. +**/ +EFI_STATUS +FlushOrDeletePolicyEntry ( + IN EFI_IPSEC_CONFIG_DATA_TYPE DataType, + IN LIST_ENTRY *ParamPackage + ) +{ + EFI_STATUS Status; + DELETE_POLICY_ENTRY_CONTEXT Context; + CONST CHAR16 *ValueStr; + + // + // If user wants to remove all. + // + if (ShellCommandLineGetFlag (ParamPackage, L"-f")) { + Status = mIpSecConfig->SetData ( + mIpSecConfig, + DataType, + NULL, + NULL, + NULL + ); + } else { + ValueStr = ShellCommandLineGetValue (ParamPackage, L"-d"); + if (ValueStr == NULL) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_INDEX_NOT_SPECIFIED), mHiiHandle, mAppName, ValueStr); + return EFI_NOT_FOUND; + } + + Status = mConstructPolicyEntryIndexer[DataType] (&Context.Indexer, ParamPackage); + if (!EFI_ERROR (Status)) { + Context.DataType = DataType; + Context.Status = EFI_NOT_FOUND; + ForeachPolicyEntry (DataType, (VISIT_POLICY_ENTRY) DeletePolicyEntry, &Context); + Status = Context.Status; + + if (Status == EFI_NOT_FOUND) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_INDEX_NOT_FOUND), mHiiHandle, mAppName, ValueStr); + } else if (EFI_ERROR (Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_DELETE_FAILED), mHiiHandle, mAppName); + } + } + } + + return Status; +} diff --git a/Core/NetworkPkg/Application/IpsecConfig/Delete.h b/Core/NetworkPkg/Application/IpsecConfig/Delete.h new file mode 100644 index 0000000000..49f3b0d5fa --- /dev/null +++ b/Core/NetworkPkg/Application/IpsecConfig/Delete.h @@ -0,0 +1,42 @@ +/** @file + The internal structure and function declaration of delete policy entry function + in IpSecConfig application. + + Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef __DELETE_H_ +#define __DELETE_H_ + +typedef struct { + EFI_IPSEC_CONFIG_DATA_TYPE DataType; + POLICY_ENTRY_INDEXER Indexer; + EFI_STATUS Status; //Indicate whether deletion succeeds. +} DELETE_POLICY_ENTRY_CONTEXT; + +/** + Flush or delete entry information in the database according to datatype. + + @param[in] DataType The value of EFI_IPSEC_CONFIG_DATA_TYPE. + @param[in] ParamPackage The pointer to the ParamPackage list. + + @retval EFI_SUCCESS Delete entry information successfully. + @retval EFI_NOT_FOUND Can't find the specified entry. + @retval Others Some mistaken case. +**/ +EFI_STATUS +FlushOrDeletePolicyEntry ( + IN EFI_IPSEC_CONFIG_DATA_TYPE DataType, + IN LIST_ENTRY *ParamPackage + ); + +#endif diff --git a/Core/NetworkPkg/Application/IpsecConfig/Dump.c b/Core/NetworkPkg/Application/IpsecConfig/Dump.c new file mode 100644 index 0000000000..1a82a63df3 --- /dev/null +++ b/Core/NetworkPkg/Application/IpsecConfig/Dump.c @@ -0,0 +1,579 @@ +/** @file + The implementation of dump policy entry function in IpSecConfig application. + + Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "IpSecConfig.h" +#include "Dump.h" +#include "ForEach.h" +#include "Helper.h" + +/** + Private function called to get the version infomation from an EFI_IP_ADDRESS_INFO structure. + + @param[in] AddressInfo The pointer to the EFI_IP_ADDRESS_INFO structure. + + @return the value of version. +**/ +UINTN +GetVerFromAddrInfo ( + IN EFI_IP_ADDRESS_INFO *AddressInfo +) +{ + if((AddressInfo->PrefixLength <= 32) && (AddressInfo->Address.Addr[1] == 0) && + (AddressInfo->Address.Addr[2] == 0) && (AddressInfo->Address.Addr[3] == 0)) { + return IP_VERSION_4; + } else { + return IP_VERSION_6; + } +} + +/** + Private function called to get the version information from a EFI_IP_ADDRESS structure. + + @param[in] Address The pointer to the EFI_IP_ADDRESS structure. + + @return The value of the version. +**/ +UINTN +GetVerFromIpAddr ( + IN EFI_IP_ADDRESS *Address +) +{ + if ((Address->Addr[1] == 0) && (Address->Addr[2] == 0) && (Address->Addr[3] == 0)) { + return IP_VERSION_4; + } else { + return IP_VERSION_6; + } +} + +/** + Private function called to print an ASCII string in unicode char format. + + @param[in] Str The pointer to the ASCII string. + @param[in] Length The value of the ASCII string length. +**/ +VOID +DumpAsciiString ( + IN CHAR8 *Str, + IN UINTN Length + ) +{ + UINTN Index; + Print (L"\""); + for (Index = 0; Index < Length; Index++) { + Print (L"%c", (CHAR16) Str[Index]); + } + Print (L"\""); +} + +/** + Private function called to print a buffer in Hex format. + + @param[in] Data The pointer to the buffer. + @param[in] Length The size of the buffer. + +**/ +VOID +DumpBuf ( + IN UINT8 *Data, + IN UINTN Length + ) +{ + UINTN Index; + for (Index = 0; Index < Length; Index++) { + Print (L"%02x ", Data[Index]); + } +} + +/** + Private function called to print EFI_IP_ADDRESS_INFO content. + + @param[in] AddressInfo The pointer to the EFI_IP_ADDRESS_INFO structure. +**/ +VOID +DumpAddressInfo ( + IN EFI_IP_ADDRESS_INFO *AddressInfo + ) +{ + if (IP_VERSION_4 == GetVerFromAddrInfo (AddressInfo)) { + Print ( + L"%d.%d.%d.%d", + (UINTN) AddressInfo->Address.v4.Addr[0], + (UINTN) AddressInfo->Address.v4.Addr[1], + (UINTN) AddressInfo->Address.v4.Addr[2], + (UINTN) AddressInfo->Address.v4.Addr[3] + ); + if (AddressInfo->PrefixLength != 32) { + Print (L"/%d", (UINTN) AddressInfo->PrefixLength); + } + } + + if (IP_VERSION_6 == GetVerFromAddrInfo (AddressInfo)) { + Print ( + L"%x:%x:%x:%x:%x:%x:%x:%x", + (((UINT16) AddressInfo->Address.v6.Addr[0]) << 8) | ((UINT16) AddressInfo->Address.v6.Addr[1]), + (((UINT16) AddressInfo->Address.v6.Addr[2]) << 8) | ((UINT16) AddressInfo->Address.v6.Addr[3]), + (((UINT16) AddressInfo->Address.v6.Addr[4]) << 8) | ((UINT16) AddressInfo->Address.v6.Addr[5]), + (((UINT16) AddressInfo->Address.v6.Addr[6]) << 8) | ((UINT16) AddressInfo->Address.v6.Addr[7]), + (((UINT16) AddressInfo->Address.v6.Addr[8]) << 8) | ((UINT16) AddressInfo->Address.v6.Addr[9]), + (((UINT16) AddressInfo->Address.v6.Addr[10]) << 8) | ((UINT16) AddressInfo->Address.v6.Addr[11]), + (((UINT16) AddressInfo->Address.v6.Addr[12]) << 8) | ((UINT16) AddressInfo->Address.v6.Addr[13]), + (((UINT16) AddressInfo->Address.v6.Addr[14]) << 8) | ((UINT16) AddressInfo->Address.v6.Addr[15]) + ); + if (AddressInfo->PrefixLength != 128) { + Print (L"/%d", AddressInfo->PrefixLength); + } + } +} + +/** + Private function called to print EFI_IP_ADDRESS content. + + @param[in] IpAddress The pointer to the EFI_IP_ADDRESS structure. +**/ +VOID +DumpIpAddress ( + IN EFI_IP_ADDRESS *IpAddress + ) +{ + if (IP_VERSION_4 == GetVerFromIpAddr (IpAddress)) { + Print ( + L"%d.%d.%d.%d", + (UINTN) IpAddress->v4.Addr[0], + (UINTN) IpAddress->v4.Addr[1], + (UINTN) IpAddress->v4.Addr[2], + (UINTN) IpAddress->v4.Addr[3] + ); + } + + if (IP_VERSION_6 == GetVerFromIpAddr (IpAddress)) { + Print ( + L"%x:%x:%x:%x:%x:%x:%x:%x", + (((UINT16) IpAddress->v6.Addr[0]) << 8) | ((UINT16) IpAddress->v6.Addr[1]), + (((UINT16) IpAddress->v6.Addr[2]) << 8) | ((UINT16) IpAddress->v6.Addr[3]), + (((UINT16) IpAddress->v6.Addr[4]) << 8) | ((UINT16) IpAddress->v6.Addr[5]), + (((UINT16) IpAddress->v6.Addr[6]) << 8) | ((UINT16) IpAddress->v6.Addr[7]), + (((UINT16) IpAddress->v6.Addr[8]) << 8) | ((UINT16) IpAddress->v6.Addr[9]), + (((UINT16) IpAddress->v6.Addr[10]) << 8) | ((UINT16) IpAddress->v6.Addr[11]), + (((UINT16) IpAddress->v6.Addr[12]) << 8) | ((UINT16) IpAddress->v6.Addr[13]), + (((UINT16) IpAddress->v6.Addr[14]) << 8) | ((UINT16) IpAddress->v6.Addr[15]) + ); + } + +} + +/** + Private function called to print EFI_IPSEC_SPD_SELECTOR content. + + @param[in] Selector The pointer to the EFI_IPSEC_SPD_SELECTOR structure. +**/ +VOID +DumpSpdSelector ( + IN EFI_IPSEC_SPD_SELECTOR *Selector + ) +{ + UINT32 Index; + CHAR16 *Str; + + for (Index = 0; Index < Selector->LocalAddressCount; Index++) { + if (Index > 0) { + Print (L","); + } + + DumpAddressInfo (&Selector->LocalAddress[Index]); + } + + if (Index == 0) { + Print (L"localhost"); + } + + Print (L" -> "); + + for (Index = 0; Index < Selector->RemoteAddressCount; Index++) { + if (Index > 0) { + Print (L","); + } + + DumpAddressInfo (&Selector->RemoteAddress[Index]); + } + + Str = MapIntegerToString (Selector->NextLayerProtocol, mMapIpProtocol); + if (Str != NULL) { + Print (L" %s", Str); + } else { + Print (L" proto:%d", (UINTN) Selector->NextLayerProtocol); + } + + if ((Selector->NextLayerProtocol == EFI_IP4_PROTO_TCP) || (Selector->NextLayerProtocol == EFI_IP4_PROTO_UDP)) { + Print (L" port:"); + if (Selector->LocalPort != EFI_IPSEC_ANY_PORT) { + Print (L"%d", Selector->LocalPort); + if (Selector->LocalPortRange != 0) { + Print (L"~%d", (UINTN) Selector->LocalPort + Selector->LocalPortRange); + } + } else { + Print (L"any"); + } + + Print (L" -> "); + if (Selector->RemotePort != EFI_IPSEC_ANY_PORT) { + Print (L"%d", Selector->RemotePort); + if (Selector->RemotePortRange != 0) { + Print (L"~%d", (UINTN) Selector->RemotePort + Selector->RemotePortRange); + } + } else { + Print (L"any"); + } + } else if (Selector->NextLayerProtocol == EFI_IP4_PROTO_ICMP) { + Print (L" class/code:"); + if (Selector->LocalPort != 0) { + Print (L"%d", (UINTN) (UINT8) Selector->LocalPort); + } else { + Print (L"any"); + } + + Print (L"/"); + if (Selector->RemotePort != 0) { + Print (L"%d", (UINTN) (UINT8) Selector->RemotePort); + } else { + Print (L"any"); + } + } +} + +/** + Print EFI_IPSEC_SPD_SELECTOR and EFI_IPSEC_SPD_DATA content. + + @param[in] Selector The pointer to the EFI_IPSEC_SPD_SELECTOR structure. + @param[in] Data The pointer to the EFI_IPSEC_SPD_DATA structure. + @param[in] EntryIndex The pointer to the Index in SPD Database. + + @retval EFI_SUCCESS Dump SPD information successfully. +**/ +EFI_STATUS +DumpSpdEntry ( + IN EFI_IPSEC_SPD_SELECTOR *Selector, + IN EFI_IPSEC_SPD_DATA *Data, + IN UINTN *EntryIndex + ) +{ + BOOLEAN HasPre; + CHAR16 DataName[128]; + CHAR16 *String1; + CHAR16 *String2; + CHAR16 *String3; + UINT8 Index; + + Print (L"%d.", (*EntryIndex)++); + + // + // xxx.xxx.xxx.xxx/yy -> xxx.xxx.xxx.xx/yy proto:23 port:100~300 -> 300~400 + // Protect PF:0x34323423 Name:First Entry + // ext-sequence sequence-overflow fragcheck life:[B0,S1024,H3600] + // ESP algo1 algo2 Tunnel [xxx.xxx.xxx.xxx xxx.xxx.xxx.xxx set] + // + + DumpSpdSelector (Selector); + Print (L"\n "); + + Print (L"%s ", MapIntegerToString (Data->Action, mMapIpSecAction)); + Print (L"PF:%08x ", Data->PackageFlag); + + Index = 0; + while (Data->Name[Index] != 0) { + DataName[Index] = (CHAR16) Data->Name[Index]; + Index++; + ASSERT (Index < 128); + } + DataName[Index] = L'\0'; + + Print (L"Name:%s", DataName); + + if (Data->Action == EfiIPsecActionProtect) { + Print (L"\n "); + if (Data->ProcessingPolicy->ExtSeqNum) { + Print (L"ext-sequence "); + } + + if (Data->ProcessingPolicy->SeqOverflow) { + Print (L"sequence-overflow "); + } + + if (Data->ProcessingPolicy->FragCheck) { + Print (L"fragment-check "); + } + + HasPre = FALSE; + if (Data->ProcessingPolicy->SaLifetime.ByteCount != 0) { + Print (HasPre ? L"," : L"life:["); + Print (L"%lxB", Data->ProcessingPolicy->SaLifetime.ByteCount); + HasPre = TRUE; + } + + if (Data->ProcessingPolicy->SaLifetime.SoftLifetime != 0) { + Print (HasPre ? L"," : L"life:["); + Print (L"%lxs", Data->ProcessingPolicy->SaLifetime.SoftLifetime); + HasPre = TRUE; + } + + if (Data->ProcessingPolicy->SaLifetime.HardLifetime != 0) { + Print (HasPre ? L"," : L"life:["); + Print (L"%lxS", Data->ProcessingPolicy->SaLifetime.HardLifetime); + HasPre = TRUE; + } + + if (HasPre) { + Print (L"]"); + } + + if (HasPre || Data->ProcessingPolicy->ExtSeqNum || + Data->ProcessingPolicy->SeqOverflow || Data->ProcessingPolicy->FragCheck) { + Print (L"\n "); + } + + String1 = MapIntegerToString (Data->ProcessingPolicy->Proto, mMapIpSecProtocol); + String2 = MapIntegerToString (Data->ProcessingPolicy->AuthAlgoId, mMapAuthAlgo); + String3 = MapIntegerToString (Data->ProcessingPolicy->EncAlgoId, mMapEncAlgo); + Print ( + L"%s Auth:%s Encrypt:%s ", + String1, + String2, + String3 + ); + + Print (L"%s ", MapIntegerToString (Data->ProcessingPolicy->Mode, mMapIpSecMode)); + if (Data->ProcessingPolicy->Mode == EfiIPsecTunnel) { + Print (L"["); + DumpIpAddress (&Data->ProcessingPolicy->TunnelOption->LocalTunnelAddress); + Print (L" -> "); + DumpIpAddress (&Data->ProcessingPolicy->TunnelOption->RemoteTunnelAddress); + Print (L" %s]", MapIntegerToString (Data->ProcessingPolicy->TunnelOption->DF, mMapDfOption)); + } + } + + Print (L"\n"); + + return EFI_SUCCESS; +} + +/** + Print EFI_IPSEC_SA_ID and EFI_IPSEC_SA_DATA2 content. + + @param[in] SaId The pointer to the EFI_IPSEC_SA_ID structure. + @param[in] Data The pointer to the EFI_IPSEC_SA_DATA2 structure. + @param[in] EntryIndex The pointer to the Index in the SAD Database. + + @retval EFI_SUCCESS Dump SAD information successfully. +**/ +EFI_STATUS +DumpSadEntry ( + IN EFI_IPSEC_SA_ID *SaId, + IN EFI_IPSEC_SA_DATA2 *Data, + IN UINTN *EntryIndex + ) +{ + BOOLEAN HasPre; + CHAR16 *AuthAlgoStr; + CHAR16 *EncAlgoStr; + + AuthAlgoStr = NULL; + EncAlgoStr = NULL; + + // + // SPI:1234 ESP Destination:xxx.xxx.xxx.xxx + // Mode:Transport SeqNum:134 AntiReplayWin:64 life:[0B,1023s,3400S] PathMTU:34 + // Auth:xxxx/password Encrypt:yyyy/password + // xxx.xxx.xxx.xxx/yy -> xxx.xxx.xxx.xx/yy proto:23 port:100~300 -> 300~400 + // + + Print (L"%d.", (*EntryIndex)++); + Print (L"0x%x %s ", (UINTN) SaId->Spi, MapIntegerToString (SaId->Proto, mMapIpSecProtocol)); + if (Data->Mode == EfiIPsecTunnel) { + Print (L"TunnelSourceAddress:"); + DumpIpAddress (&Data->TunnelSourceAddress); + Print (L"\n"); + Print (L" TunnelDestination:"); + DumpIpAddress (&Data->TunnelDestinationAddress); + Print (L"\n"); + } + + Print ( + L" Mode:%s SeqNum:%lx AntiReplayWin:%d ", + MapIntegerToString (Data->Mode, mMapIpSecMode), + Data->SNCount, + (UINTN) Data->AntiReplayWindows + ); + + HasPre = FALSE; + if (Data->SaLifetime.ByteCount != 0) { + Print (HasPre ? L"," : L"life:["); + Print (L"%lxB", Data->SaLifetime.ByteCount); + HasPre = TRUE; + } + + if (Data->SaLifetime.SoftLifetime != 0) { + Print (HasPre ? L"," : L"life:["); + Print (L"%lxs", Data->SaLifetime.SoftLifetime); + HasPre = TRUE; + } + + if (Data->SaLifetime.HardLifetime != 0) { + Print (HasPre ? L"," : L"life:["); + Print (L"%lxS", Data->SaLifetime.HardLifetime); + HasPre = TRUE; + } + + if (HasPre) { + Print (L"] "); + } + + Print (L"PathMTU:%d\n", (UINTN) Data->PathMTU); + + if (SaId->Proto == EfiIPsecAH) { + Print ( + L" Auth:%s/%s\n", + MapIntegerToString (Data->AlgoInfo.AhAlgoInfo.AuthAlgoId, mMapAuthAlgo), + Data->AlgoInfo.AhAlgoInfo.AuthKey + ); + } else { + AuthAlgoStr = MapIntegerToString (Data->AlgoInfo.EspAlgoInfo.AuthAlgoId, mMapAuthAlgo); + EncAlgoStr = MapIntegerToString (Data->AlgoInfo.EspAlgoInfo.EncAlgoId, mMapEncAlgo); + + if (Data->ManualSet) { + // + // if the SAD is set manually the key is a Ascii string in most of time. + // Print the Key in Ascii string format. + // + Print (L" Auth:%s/",AuthAlgoStr); + DumpAsciiString ( + Data->AlgoInfo.EspAlgoInfo.AuthKey, + Data->AlgoInfo.EspAlgoInfo.AuthKeyLength + ); + Print (L"\n Encrypt:%s/",EncAlgoStr); + DumpAsciiString ( + Data->AlgoInfo.EspAlgoInfo.EncKey, + Data->AlgoInfo.EspAlgoInfo.EncKeyLength + ); + } else { + // + // if the SAD is created by IKE, the key is a set of hex value in buffer. + // Print the Key in Hex format. + // + Print (L" Auth:%s/",AuthAlgoStr); + DumpBuf ((UINT8 *)(Data->AlgoInfo.EspAlgoInfo.AuthKey), Data->AlgoInfo.EspAlgoInfo.AuthKeyLength); + + Print (L"\n Encrypt:%s/",EncAlgoStr); + DumpBuf ((UINT8 *)(Data->AlgoInfo.EspAlgoInfo.EncKey), Data->AlgoInfo.EspAlgoInfo.EncKeyLength); + } + } + Print (L"\n"); + if (Data->SpdSelector != NULL) { + Print (L" "); + DumpSpdSelector (Data->SpdSelector); + Print (L"\n"); + } + + return EFI_SUCCESS; +} + +/** + Print EFI_IPSEC_PAD_ID and EFI_IPSEC_PAD_DATA content. + + @param[in] PadId The pointer to the EFI_IPSEC_PAD_ID structure. + @param[in] Data The pointer to the EFI_IPSEC_PAD_DATA structure. + @param[in] EntryIndex The pointer to the Index in the PAD Database. + + @retval EFI_SUCCESS Dump PAD information successfully. +**/ +EFI_STATUS +DumpPadEntry ( + IN EFI_IPSEC_PAD_ID *PadId, + IN EFI_IPSEC_PAD_DATA *Data, + IN UINTN *EntryIndex + ) +{ + CHAR16 *String1; + CHAR16 *String2; + + // + // ADDR:10.23.17.34/15 + // IDEv1 PreSharedSecret IKE-ID + // password + // + + Print (L"%d.", (*EntryIndex)++); + + if (PadId->PeerIdValid) { + Print (L"ID:%s", PadId->Id.PeerId); + } else { + Print (L"ADDR:"); + DumpAddressInfo (&PadId->Id.IpAddress); + } + + Print (L"\n"); + + String1 = MapIntegerToString (Data->AuthProtocol, mMapAuthProto); + String2 = MapIntegerToString (Data->AuthMethod, mMapAuthMethod); + Print ( + L" %s %s", + String1, + String2 + ); + + if (Data->IkeIdFlag) { + Print (L"IKE-ID"); + } + + Print (L"\n"); + + if (Data->AuthData != NULL) { + DumpAsciiString (Data->AuthData, Data->AuthDataSize); + Print (L"\n"); + } + + if (Data->RevocationData != NULL) { + Print (L" %s\n", Data->RevocationData); + } + + return EFI_SUCCESS; + +} + +VISIT_POLICY_ENTRY mDumpPolicyEntry[] = { + (VISIT_POLICY_ENTRY) DumpSpdEntry, + (VISIT_POLICY_ENTRY) DumpSadEntry, + (VISIT_POLICY_ENTRY) DumpPadEntry +}; + +/** + Print all entry information in the database according to datatype. + + @param[in] DataType The value of EFI_IPSEC_CONFIG_DATA_TYPE. + @param[in] ParamPackage The pointer to the ParamPackage list. + + @retval EFI_SUCCESS Dump all information successfully. + @retval Others Some mistaken case. +**/ +EFI_STATUS +ListPolicyEntry ( + IN EFI_IPSEC_CONFIG_DATA_TYPE DataType, + IN LIST_ENTRY *ParamPackage + ) +{ + UINTN EntryIndex; + + EntryIndex = 0; + return ForeachPolicyEntry (DataType, mDumpPolicyEntry[DataType], &EntryIndex); +} + diff --git a/Core/NetworkPkg/Application/IpsecConfig/Dump.h b/Core/NetworkPkg/Application/IpsecConfig/Dump.h new file mode 100644 index 0000000000..3c475dd304 --- /dev/null +++ b/Core/NetworkPkg/Application/IpsecConfig/Dump.h @@ -0,0 +1,34 @@ +/** @file + The function declaration of dump policy entry function in IpSecConfig application. + + Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _DUMP_H_ +#define _DUMP_H_ + +/** + Print all entry information in the database according to datatype. + + @param[in] DataType The value of EFI_IPSEC_CONFIG_DATA_TYPE. + @param[in] ParamPackage The pointer to the ParamPackage list. + + @retval EFI_SUCCESS Dump all information successfully. + @retval Others Some mistaken case. +**/ +EFI_STATUS +ListPolicyEntry ( + IN EFI_IPSEC_CONFIG_DATA_TYPE DataType, + IN LIST_ENTRY *ParamPackage + ); + +#endif diff --git a/Core/NetworkPkg/Application/IpsecConfig/ForEach.c b/Core/NetworkPkg/Application/IpsecConfig/ForEach.c new file mode 100644 index 0000000000..7b3b9b17a8 --- /dev/null +++ b/Core/NetworkPkg/Application/IpsecConfig/ForEach.c @@ -0,0 +1,115 @@ +/** @file + The implementation to go through each entry in IpSecConfig application. + + Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "IpSecConfig.h" +#include "ForEach.h" + + +/** + Enumerate all entries in the database to execute specified operations according to datatype. + + @param[in] DataType The value of EFI_IPSEC_CONFIG_DATA_TYPE. + @param[in] Routine The pointer to the function of a specified operation. + @param[in] Context The pointer to the context of a function. + + @retval EFI_SUCCESS Execute specified operation successfully. +**/ +EFI_STATUS +ForeachPolicyEntry ( + IN EFI_IPSEC_CONFIG_DATA_TYPE DataType, + IN VISIT_POLICY_ENTRY Routine, + IN VOID *Context + ) +{ + EFI_STATUS GetNextStatus; + EFI_STATUS GetDataStatus; + EFI_IPSEC_CONFIG_SELECTOR *Selector; + VOID *Data; + UINTN SelectorSize; + UINTN DataSize; + BOOLEAN FirstGetNext; + + FirstGetNext = TRUE; + SelectorSize = sizeof (EFI_IPSEC_CONFIG_SELECTOR); + Selector = AllocateZeroPool (SelectorSize); + + DataSize = 0; + Data = NULL; + + while (TRUE) { + GetNextStatus = mIpSecConfig->GetNextSelector ( + mIpSecConfig, + DataType, + &SelectorSize, + Selector + ); + if (GetNextStatus == EFI_BUFFER_TOO_SMALL) { + gBS->FreePool (Selector); + Selector = FirstGetNext ? AllocateZeroPool (SelectorSize) : AllocatePool (SelectorSize); + + GetNextStatus = mIpSecConfig->GetNextSelector ( + mIpSecConfig, + DataType, + &SelectorSize, + Selector + ); + } + + if (EFI_ERROR (GetNextStatus)) { + break; + } + + FirstGetNext = FALSE; + + GetDataStatus = mIpSecConfig->GetData ( + mIpSecConfig, + DataType, + Selector, + &DataSize, + Data + ); + if (GetDataStatus == EFI_BUFFER_TOO_SMALL) { + if (Data != NULL) { + gBS->FreePool (Data); + } + + Data = AllocateZeroPool (DataSize); + GetDataStatus = mIpSecConfig->GetData ( + mIpSecConfig, + DataType, + Selector, + &DataSize, + Data + ); + } + + ASSERT_EFI_ERROR (GetDataStatus); + + if (EFI_ERROR (Routine (Selector, Data, Context))) { + break; + } + } + + if (Data != NULL) { + gBS->FreePool (Data); + } + + if (Selector != NULL) { + gBS->FreePool (Selector); + } + + return EFI_SUCCESS; +} + diff --git a/Core/NetworkPkg/Application/IpsecConfig/ForEach.h b/Core/NetworkPkg/Application/IpsecConfig/ForEach.h new file mode 100644 index 0000000000..fc309300c0 --- /dev/null +++ b/Core/NetworkPkg/Application/IpsecConfig/ForEach.h @@ -0,0 +1,54 @@ +/** @file + The internal structure and function declaration of the implementation + to go through each entry in IpSecConfig application. + + Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _FOREACH_H_ +#define _FOREACH_H_ + +/** + The prototype for the DumpSpdEntry()/DumpSadEntry()/DumpPadEntry(). + Print EFI_IPSEC_CONFIG_SELECTOR and corresponding content. + + @param[in] Selector The pointer to the EFI_IPSEC_CONFIG_SELECTOR union. + @param[in] Data The pointer to the corresponding data. + @param[in] Context The pointer to the Index in SPD/SAD/PAD Database. + + @retval EFI_SUCCESS Dump SPD/SAD/PAD information successfully. +**/ +typedef +EFI_STATUS +(*VISIT_POLICY_ENTRY) ( + IN EFI_IPSEC_CONFIG_SELECTOR *Selector, + IN VOID *Data, + IN VOID *Context + ); + +/** + Enumerate all entry in the database to execute a specified operation according to datatype. + + @param[in] DataType The value of EFI_IPSEC_CONFIG_DATA_TYPE. + @param[in] Routine The pointer to function of a specified operation. + @param[in] Context The pointer to the context of a function. + + @retval EFI_SUCCESS Execute specified operation successfully. +**/ +EFI_STATUS +ForeachPolicyEntry ( + IN EFI_IPSEC_CONFIG_DATA_TYPE DataType, + IN VISIT_POLICY_ENTRY Routine, + IN VOID *Context + ); + +#endif diff --git a/Core/NetworkPkg/Application/IpsecConfig/Helper.c b/Core/NetworkPkg/Application/IpsecConfig/Helper.c new file mode 100644 index 0000000000..ae867ceee7 --- /dev/null +++ b/Core/NetworkPkg/Application/IpsecConfig/Helper.c @@ -0,0 +1,420 @@ +/** @file + The assistant function implementation for IpSecConfig application. + + Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "IpSecConfig.h" +#include "Helper.h" + +/** + Helper function called to change an input parameter in the string format to a number. + + @param[in] FlagStr The pointer to the flag string. + @param[in] Maximum Greatest value number. + @param[in, out] ValuePtr The pointer to the input parameter in string format. + @param[in] ByteCount The valid byte count + @param[in] Map The pointer to the STR2INT table. + @param[in] ParamPackage The pointer to the ParamPackage list. + @param[in] FormatMask The bit mask. + BIT 0 set indicates the value of a flag might be a number. + BIT 1 set indicates the value of a flag might be a string that needs to be looked up. + + @retval EFI_SUCCESS The operation completed successfully. + @retval EFI_NOT_FOUND The input parameter can't be found. + @retval EFI_INVALID_PARAMETER The input parameter is an invalid input. +**/ +EFI_STATUS +GetNumber ( + IN CHAR16 *FlagStr, + IN UINT64 Maximum, + IN OUT VOID *ValuePtr, + IN UINTN ByteCount, + IN STR2INT *Map, + IN LIST_ENTRY *ParamPackage, + IN UINT32 FormatMask + ) +{ + EFI_STATUS Status; + UINT64 Value64; + BOOLEAN Converted; + UINTN Index; + CONST CHAR16 *ValueStr; + + ASSERT (FormatMask & (FORMAT_NUMBER | FORMAT_STRING)); + + Converted = FALSE; + Value64 = 0; + ValueStr = ShellCommandLineGetValue (ParamPackage, FlagStr); + + if (ValueStr == NULL) { + return EFI_NOT_FOUND; + } else { + // + // Try to convert to integer directly if MaybeNumber is TRUE. + // + if ((FormatMask & FORMAT_NUMBER) != 0) { + Value64 = StrToUInteger (ValueStr, &Status); + if (!EFI_ERROR (Status)) { + // + // Convert successfully. + // + if (Value64 > Maximum) { + // + // But the result is invalid + // + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE), + mHiiHandle, + mAppName, + FlagStr, + ValueStr + ); + return EFI_INVALID_PARAMETER; + } + + Converted = TRUE; + } + } + + if (!Converted && ((FormatMask & FORMAT_STRING) != 0)) { + // + // Convert falied, so use String->Integer map. + // + ASSERT (Map != NULL); + Value64 = MapStringToInteger (ValueStr, Map); + if (Value64 == (UINT32) -1) { + // + // Cannot find the string in the map. + // + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE), + mHiiHandle, + mAppName, + FlagStr, + ValueStr + ); + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_ACCEPT_PARAMETERS), mHiiHandle); + for (Index = 0; Map[Index].String != NULL; Index++) { + Print (L" %s", Map[Index].String); + } + + Print (L"\n"); + return EFI_INVALID_PARAMETER; + } + } + + CopyMem (ValuePtr, &Value64, ByteCount); + return EFI_SUCCESS; + } +} + +/** + Helper function called to convert a string containing an Ipv4 or Ipv6 Internet Protocol address + into a proper address for the EFI_IP_ADDRESS structure. + + @param[in] Ptr The pointer to the string containing an Ipv4 or Ipv6 Internet Protocol address. + @param[out] Ip The pointer to the EFI_IP_ADDRESS structure to contain the result. + + @retval EFI_SUCCESS The operation completed successfully. + @retval EFI_INVALID_PARAMETER Invalid parameter. +**/ +EFI_STATUS +EfiInetAddr2 ( + IN CHAR16 *Ptr, + OUT EFI_IP_ADDRESS *Ip + ) +{ + EFI_STATUS Status; + + if ((Ptr == NULL) || (Ip == NULL)) { + return EFI_INVALID_PARAMETER; + } + + // + // Parse the input address as Ipv4 Address first. + // + Status = NetLibStrToIp4 (Ptr, &Ip->v4); + if (!EFI_ERROR (Status)) { + return Status; + } + + Status = NetLibStrToIp6 (Ptr, &Ip->v6); + return Status; +} + +/** + Helper function called to calculate the prefix length associated with the string + containing an Ipv4 or Ipv6 Internet Protocol address. + + @param[in] Ptr The pointer to the string containing an Ipv4 or Ipv6 Internet Protocol address. + @param[out] Addr The pointer to the EFI_IP_ADDRESS_INFO structure to contain the result. + + @retval EFI_SUCCESS The operation completed successfully. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval Others Other mistake case. +**/ +EFI_STATUS +EfiInetAddrRange ( + IN CHAR16 *Ptr, + OUT EFI_IP_ADDRESS_INFO *Addr + ) +{ + EFI_STATUS Status; + + if ((Ptr == NULL) || (Addr == NULL)) { + return EFI_INVALID_PARAMETER; + } + + Status = NetLibStrToIp4 (Ptr, &Addr->Address.v4); + if (!EFI_ERROR (Status)) { + if ((UINT32)(*Addr->Address.v4.Addr) == 0) { + Addr->PrefixLength = 0; + } else { + Addr->PrefixLength = 32; + } + return Status; + } + + Status = NetLibStrToIp6andPrefix (Ptr, &Addr->Address.v6, &Addr->PrefixLength); + if (!EFI_ERROR (Status) && (Addr->PrefixLength == 0xFF)) { + Addr->PrefixLength = 128; + } + + return Status; +} + +/** + Helper function called to calculate the port range associated with the string. + + @param[in] Ptr The pointer to the string containing a port and range. + @param[out] Port The pointer to the Port to contain the result. + @param[out] PortRange The pointer to the PortRange to contain the result. + + @retval EFI_SUCCESS The operation completed successfully. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval Others Other mistake case. +**/ +EFI_STATUS +EfiInetPortRange ( + IN CHAR16 *Ptr, + OUT UINT16 *Port, + OUT UINT16 *PortRange + ) +{ + CHAR16 *BreakPtr; + CHAR16 Ch; + EFI_STATUS Status; + + for (BreakPtr = Ptr; (*BreakPtr != L'\0') && (*BreakPtr != L':'); BreakPtr++) { + ; + } + + Ch = *BreakPtr; + *BreakPtr = L'\0'; + *Port = (UINT16) StrToUInteger (Ptr, &Status); + *BreakPtr = Ch; + if (EFI_ERROR (Status)) { + return Status; + } + + *PortRange = 0; + if (*BreakPtr == L':') { + BreakPtr++; + *PortRange = (UINT16) StrToUInteger (BreakPtr, &Status); + if (EFI_ERROR (Status)) { + return Status; + } + + if (*PortRange < *Port) { + return EFI_INVALID_PARAMETER; + } + + *PortRange = (UINT16) (*PortRange - *Port); + } + + return EFI_SUCCESS; +} + +/** + Helper function called to transfer a string to an unsigned integer. + + @param[in] Str The pointer to the string. + @param[out] Status The operation status. + + @return The integer value of converted Str. +**/ +UINT64 +StrToUInteger ( + IN CONST CHAR16 *Str, + OUT EFI_STATUS *Status + ) +{ + UINT64 Value; + UINT64 NewValue; + CHAR16 *StrTail; + CHAR16 Char; + UINTN Base; + UINTN Len; + + Base = 10; + Value = 0; + *Status = EFI_ABORTED; + + // + // Skip leading white space. + // + while ((*Str != 0) && (*Str == ' ')) { + Str++; + } + // + // For NULL Str, just return. + // + if (*Str == 0) { + return 0; + } + // + // Skip white space in tail. + // + Len = StrLen (Str); + StrTail = (CHAR16 *) (Str + Len - 1); + while (*StrTail == ' ') { + *StrTail = 0; + StrTail--; + } + + Len = StrTail - Str + 1; + + // + // Check hex prefix '0x'. + // + if ((Len >= 2) && (*Str == '0') && ((*(Str + 1) == 'x') || (*(Str + 1) == 'X'))) { + Str += 2; + Len -= 2; + Base = 16; + } + + if (Len == 0) { + return 0; + } + // + // Convert the string to value. + // + for (; Str <= StrTail; Str++) { + + Char = *Str; + + if (Base == 16) { + if (RShiftU64 (Value, 60) != 0) { + // + // Overflow here x16. + // + return 0; + } + + NewValue = LShiftU64 (Value, 4); + } else { + if (RShiftU64 (Value, 61) != 0) { + // + // Overflow here x8. + // + return 0; + } + + NewValue = LShiftU64 (Value, 3); + Value = LShiftU64 (Value, 1); + NewValue += Value; + if (NewValue < Value) { + // + // Overflow here. + // + return 0; + } + } + + Value = NewValue; + + if ((Base == 16) && (Char >= 'a') && (Char <= 'f')) { + Char = (CHAR16) (Char - 'a' + 'A'); + } + + if ((Base == 16) && (Char >= 'A') && (Char <= 'F')) { + Value += (Char - 'A') + 10; + } else if ((Char >= '0') && (Char <= '9')) { + Value += (Char - '0'); + } else { + // + // Unexpected Char encountered. + // + return 0; + } + } + + *Status = EFI_SUCCESS; + return Value; +} + +/** + Helper function called to transfer a string to an unsigned integer according to the map table. + + @param[in] Str The pointer to the string. + @param[in] Map The pointer to the map table. + + @return The integer value of converted Str. If not found, then return -1. +**/ +UINT32 +MapStringToInteger ( + IN CONST CHAR16 *Str, + IN STR2INT *Map + ) +{ + STR2INT *Item; + + for (Item = Map; Item->String != NULL; Item++) { + if (StrCmp (Item->String, Str) == 0) { + return Item->Integer; + } + } + + return (UINT32) -1; +} + +/** + Helper function called to transfer an unsigned integer to a string according to the map table. + + @param[in] Integer The pointer to the string. + @param[in] Map The pointer to the map table. + + @return The converted Str. If not found, then return NULL. +**/ +CHAR16 * +MapIntegerToString ( + IN UINT32 Integer, + IN STR2INT *Map + ) +{ + STR2INT *Item; + + for (Item = Map; Item->String != NULL; Item++) { + if (Integer == Item->Integer) { + return Item->String; + } + } + + return NULL; +} diff --git a/Core/NetworkPkg/Application/IpsecConfig/Helper.h b/Core/NetworkPkg/Application/IpsecConfig/Helper.h new file mode 100644 index 0000000000..d893145a76 --- /dev/null +++ b/Core/NetworkPkg/Application/IpsecConfig/Helper.h @@ -0,0 +1,143 @@ +/** @file + The assistant function declaration for IpSecConfig application. + + Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _HELPER_H_ +#define _HELPER_H_ + +#define FORMAT_NUMBER 0x1 +#define FORMAT_STRING 0x2 + +/** + Helper function called to change input parameter in string format to number. + + @param[in] FlagStr The pointer to the flag string. + @param[in] Maximum most value number. + @param[in, out] ValuePtr The pointer to the input parameter in string format. + @param[in] ByteCount The valid byte count + @param[in] Map The pointer to the STR2INT table. + @param[in] ParamPackage The pointer to the ParamPackage list. + @param[in] FormatMask The bit mask. + BIT 0 set indicates the value of flag might be number. + BIT 1 set indicates the value of flag might be a string that needs to be looked up. + + @retval EFI_SUCCESS The operation completed successfully. + @retval EFI_NOT_FOUND The input parameter can't be found. + @retval EFI_INVALID_PARAMETER The input parameter is an invalid input. +**/ +EFI_STATUS +GetNumber ( + IN CHAR16 *FlagStr, + IN UINT64 Maximum, + IN OUT VOID *ValuePtr, + IN UINTN ByteCount, + IN STR2INT *Map, + IN LIST_ENTRY *ParamPackage, + IN UINT32 FormatMask + ); + +/** + Helper function called to convert a string containing an (Ipv4) Internet Protocol dotted address + into a proper address for the EFI_IP_ADDRESS structure. + + @param[in] Ptr The pointer to the string containing an (Ipv4) Internet Protocol dotted address. + @param[out] Ip The pointer to the Ip address structure to contain the result. + + @retval EFI_SUCCESS The operation completed successfully. + @retval EFI_INVALID_PARAMETER Invalid parameter. +**/ +EFI_STATUS +EfiInetAddr2 ( + IN CHAR16 *Ptr, + OUT EFI_IP_ADDRESS *Ip + ); + +/** + Helper function called to calculate the prefix length associated with the string + containing an Ipv4 or Ipv6 Internet Protocol address. + + @param[in] Ptr The pointer to the string containing an Ipv4 or Ipv6 Internet Protocol address. + @param[out] Addr The pointer to the EFI_IP_ADDRESS_INFO structure to contain the result. + + @retval EFI_SUCCESS The operation completed successfully. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval Others Other mistake case. +**/ +EFI_STATUS +EfiInetAddrRange ( + IN CHAR16 *Ptr, + OUT EFI_IP_ADDRESS_INFO *Addr + ); + +/** + Helper function called to calculate the port range associated with the string. + + @param[in] Ptr The pointer to the string containing a port and range. + @param[out] Port The pointer to the Port to contain the result. + @param[out] PortRange The pointer to the PortRange to contain the result. + + @retval EFI_SUCCESS The operation completed successfully. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval Others Other mistake case. +**/ +EFI_STATUS +EfiInetPortRange ( + IN CHAR16 *Ptr, + OUT UINT16 *Port, + OUT UINT16 *PortRange + ); + +/** + Helper function called to transfer a string to an unsigned integer. + + @param[in] Str The pointer to the string. + @param[out] Status The operation status. + + @return The integer value of a converted str. +**/ +UINT64 +StrToUInteger ( + IN CONST CHAR16 *Str, + OUT EFI_STATUS *Status + ); + +/** + Helper function called to transfer a string to an unsigned integer according to the map table. + + @param[in] Str The pointer to the string. + @param[in] Map The pointer to the map table. + + @return The integer value of converted str. If not found, then return -1. +**/ +UINT32 +MapStringToInteger ( + IN CONST CHAR16 *Str, + IN STR2INT *Map + ); + +/** + Helper function called to transfer an unsigned integer to a string according to the map table. + + @param[in] Integer The pointer to the string. + @param[in] Map The pointer to the map table. + + @return The converted str. If not found, then return NULL. +**/ +CHAR16 * +MapIntegerToString ( + IN UINT32 Integer, + IN STR2INT *Map + ); + +#endif diff --git a/Core/NetworkPkg/Application/IpsecConfig/Indexer.c b/Core/NetworkPkg/Application/IpsecConfig/Indexer.c new file mode 100644 index 0000000000..353b22e06a --- /dev/null +++ b/Core/NetworkPkg/Application/IpsecConfig/Indexer.c @@ -0,0 +1,255 @@ +/** @file + The implementation of construct ENTRY_INDEXER in IpSecConfig application. + + Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "IpSecConfig.h" +#include "Indexer.h" +#include "Helper.h" + +/** + Fill in SPD_ENTRY_INDEXER through ParamPackage list. + + @param[in, out] Indexer The pointer to the SPD_ENTRY_INDEXER structure. + @param[in] ParamPackage The pointer to the ParamPackage list. + + @retval EFI_SUCCESS Filled in SPD_ENTRY_INDEXER successfully. +**/ +EFI_STATUS +ConstructSpdIndexer ( + IN OUT SPD_ENTRY_INDEXER *Indexer, + IN LIST_ENTRY *ParamPackage + ) +{ + EFI_STATUS Status; + UINT64 Value64; + CONST CHAR16 *ValueStr; + + ValueStr = NULL; + + if (ShellCommandLineGetFlag (ParamPackage, L"-i")) { + ValueStr = ShellCommandLineGetValue (ParamPackage, L"-i"); + } else if (ShellCommandLineGetFlag (ParamPackage, L"-d")) { + ValueStr = ShellCommandLineGetValue (ParamPackage, L"-d"); + } else if (ShellCommandLineGetFlag (ParamPackage, L"-e")) { + ValueStr = ShellCommandLineGetValue (ParamPackage, L"-e"); + } else { + return EFI_INVALID_PARAMETER; + } + + if (ValueStr == NULL) { + return EFI_INVALID_PARAMETER; + } + + Value64 = StrToUInteger (ValueStr, &Status); + if (!EFI_ERROR (Status)) { + Indexer->Index = (UINTN) Value64; + ZeroMem (Indexer->Name, MAX_PEERID_LEN); + } else { + UnicodeStrToAsciiStrS (ValueStr, (CHAR8 *) Indexer->Name, MAX_PEERID_LEN); + } + + return EFI_SUCCESS; +} + +/** + Fill in SAD_ENTRY_INDEXER through ParamPackage list. + + @param[in, out] Indexer The pointer to the SAD_ENTRY_INDEXER structure. + @param[in] ParamPackage The pointer to the ParamPackage list. + + @retval EFI_SUCCESS Filled in SPD_ENTRY_INDEXER successfully. + @retval EFI_INVALID_PARAMETER The mistaken user input in ParamPackage list. +**/ +EFI_STATUS +ConstructSadIndexer ( + IN OUT SAD_ENTRY_INDEXER *Indexer, + IN LIST_ENTRY *ParamPackage + ) +{ + EFI_STATUS Status; + EFI_STATUS Status1; + UINT64 Value64; + CONST CHAR16 *ValueStr; + + ValueStr = NULL; + + if (ShellCommandLineGetFlag (ParamPackage, L"-i")) { + ValueStr = ShellCommandLineGetValue (ParamPackage, L"-i"); + } else if (ShellCommandLineGetFlag (ParamPackage, L"-d")) { + ValueStr = ShellCommandLineGetValue (ParamPackage, L"-d"); + } else if (ShellCommandLineGetFlag (ParamPackage, L"-e")) { + ValueStr = ShellCommandLineGetValue (ParamPackage, L"-e"); + } else { + return EFI_INVALID_PARAMETER; + } + + if (ValueStr == NULL) { + return EFI_INVALID_PARAMETER; + } + + Value64 = StrToUInteger (ValueStr, &Status); + if (!EFI_ERROR (Status)) { + Indexer->Index = (UINTN) Value64; + ZeroMem (&Indexer->SaId, sizeof (EFI_IPSEC_SA_ID)); + } else { + if ((!ShellCommandLineGetFlag (ParamPackage, L"--lookup-spi")) || + (!ShellCommandLineGetFlag (ParamPackage, L"--lookup-ipsec-proto")) || + (!ShellCommandLineGetFlag (ParamPackage, L"--lookup-dest"))) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_ONE_OF_PARAMETERS), + mHiiHandle, + mAppName, + L"--lookup-spi --lookup-ipsec-proto --lookup-dest" + ); + return EFI_INVALID_PARAMETER; + } + + Status = GetNumber ( + L"--lookup-spi", + (UINT32) -1, + &Indexer->SaId.Spi, + sizeof (UINT32), + NULL, + ParamPackage, + FORMAT_NUMBER + ); + Status1 = GetNumber ( + L"--lookup-ipsec-proto", + 0, + &Indexer->SaId.Proto, + sizeof (EFI_IPSEC_PROTOCOL_TYPE), + mMapIpSecProtocol, + ParamPackage, + FORMAT_STRING + ); + + if (EFI_ERROR (Status) || EFI_ERROR (Status1)) { + return EFI_INVALID_PARAMETER; + } + + ValueStr = ShellCommandLineGetValue (ParamPackage, L"--lookup-dest"); + ASSERT (ValueStr != NULL); + + Status = EfiInetAddr2 ((CHAR16 *) ValueStr, &Indexer->SaId.DestAddress); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE), + mHiiHandle, + mAppName, + L"--lookup-dest", + ValueStr + ); + return EFI_INVALID_PARAMETER; + } + } + + return EFI_SUCCESS; +} + +/** + Fill in PAD_ENTRY_INDEXER through ParamPackage list. + + @param[in, out] Indexer The pointer to the PAD_ENTRY_INDEXER structure. + @param[in] ParamPackage The pointer to the ParamPackage list. + + @retval EFI_SUCCESS Filled in PAD_ENTRY_INDEXER successfully. + @retval EFI_INVALID_PARAMETER The mistaken user input in ParamPackage list. +**/ +EFI_STATUS +ConstructPadIndexer ( + IN OUT PAD_ENTRY_INDEXER *Indexer, + IN LIST_ENTRY *ParamPackage + ) +{ + EFI_STATUS Status; + UINT64 Value64; + CONST CHAR16 *ValueStr; + + ValueStr = NULL; + + if (ShellCommandLineGetFlag (ParamPackage, L"-i")) { + ValueStr = ShellCommandLineGetValue (ParamPackage, L"-i"); + } else if (ShellCommandLineGetFlag (ParamPackage, L"-d")) { + ValueStr = ShellCommandLineGetValue (ParamPackage, L"-d"); + } else if (ShellCommandLineGetFlag (ParamPackage, L"-e")) { + ValueStr = ShellCommandLineGetValue (ParamPackage, L"-e"); + } else { + return EFI_INVALID_PARAMETER; + } + + if (ValueStr == NULL) { + return EFI_INVALID_PARAMETER; + } + + Value64 = StrToUInteger (ValueStr, &Status); + + if (!EFI_ERROR (Status)) { + Indexer->Index = (UINTN) Value64; + ZeroMem (&Indexer->PadId, sizeof (EFI_IPSEC_PAD_ID)); + } else { + + if (ShellCommandLineGetFlag (ParamPackage, L"--lookup-peer-address")) { + ValueStr = ShellCommandLineGetValue (ParamPackage, L"--lookup-peer-address"); + ASSERT (ValueStr != NULL); + + Indexer->PadId.PeerIdValid = FALSE; + Status = EfiInetAddrRange ((CHAR16 *) ValueStr, &Indexer->PadId.Id.IpAddress); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE), + mHiiHandle, + mAppName, + L"--lookup-peer-address", + ValueStr + ); + return EFI_INVALID_PARAMETER; + } + } else { + ValueStr = ShellCommandLineGetValue (ParamPackage, L"--lookup-peer-id"); + if (ValueStr == NULL) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_ONE_OF_PARAMETERS), + mHiiHandle, + mAppName, + L"--lookup-peer-address --lookup-peer-id" + ); + return EFI_INVALID_PARAMETER; + } + + Indexer->PadId.PeerIdValid = TRUE; + ZeroMem (Indexer->PadId.Id.PeerId, MAX_PEERID_LEN); + StrnCpyS ((CHAR16 *) Indexer->PadId.Id.PeerId, MAX_PEERID_LEN / sizeof (CHAR16), ValueStr, MAX_PEERID_LEN / sizeof (CHAR16) - 1); + } + } + + return EFI_SUCCESS; +} + +CONSTRUCT_POLICY_ENTRY_INDEXER mConstructPolicyEntryIndexer[] = { + (CONSTRUCT_POLICY_ENTRY_INDEXER) ConstructSpdIndexer, + (CONSTRUCT_POLICY_ENTRY_INDEXER) ConstructSadIndexer, + (CONSTRUCT_POLICY_ENTRY_INDEXER) ConstructPadIndexer +}; diff --git a/Core/NetworkPkg/Application/IpsecConfig/Indexer.h b/Core/NetworkPkg/Application/IpsecConfig/Indexer.h new file mode 100644 index 0000000000..58c0689021 --- /dev/null +++ b/Core/NetworkPkg/Application/IpsecConfig/Indexer.h @@ -0,0 +1,58 @@ +/** @file + The internal structure and function declaration to construct ENTRY_INDEXER in + IpSecConfig application. + + Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _INDEXER_H_ +#define _INDEXER_H_ + +typedef struct { + UINT8 Name[MAX_PEERID_LEN]; + UINTN Index; // Used only if Name buffer is filled with zero. +} SPD_ENTRY_INDEXER; + +typedef struct { + EFI_IPSEC_SA_ID SaId; + UINTN Index; +} SAD_ENTRY_INDEXER; + +typedef struct { + EFI_IPSEC_PAD_ID PadId; + UINTN Index; +} PAD_ENTRY_INDEXER; + +typedef union { + SPD_ENTRY_INDEXER Spd; + SAD_ENTRY_INDEXER Sad; + PAD_ENTRY_INDEXER Pad; +} POLICY_ENTRY_INDEXER; + +/** + The prototype for the ConstructSpdIndexer()/ConstructSadIndexer()/ConstructPadIndexer(). + Fill in SPD_ENTRY_INDEXER/SAD_ENTRY_INDEXER/PAD_ENTRY_INDEXER through ParamPackage list. + + @param[in, out] Indexer The pointer to the POLICY_ENTRY_INDEXER union. + @param[in] ParamPackage The pointer to the ParamPackage list. + + @retval EFI_SUCCESS Filled in POLICY_ENTRY_INDEXER successfully. +**/ +typedef +EFI_STATUS +(* CONSTRUCT_POLICY_ENTRY_INDEXER) ( + IN POLICY_ENTRY_INDEXER *Indexer, + IN LIST_ENTRY *ParamPackage +); + +extern CONSTRUCT_POLICY_ENTRY_INDEXER mConstructPolicyEntryIndexer[]; +#endif diff --git a/Core/NetworkPkg/Application/IpsecConfig/IpSecConfig.c b/Core/NetworkPkg/Application/IpsecConfig/IpSecConfig.c new file mode 100644 index 0000000000..274f582b2b --- /dev/null +++ b/Core/NetworkPkg/Application/IpsecConfig/IpSecConfig.c @@ -0,0 +1,812 @@ +/** @file + The main process for IpSecConfig application. + + Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include + +#include + +#include "IpSecConfig.h" +#include "Dump.h" +#include "Indexer.h" +#include "PolicyEntryOperation.h" +#include "Delete.h" +#include "Helper.h" + +// +// String token ID of IpSecConfig command help message text. +// +GLOBAL_REMOVE_IF_UNREFERENCED EFI_STRING_ID mStringIpSecHelpTokenId = STRING_TOKEN (STR_IPSEC_CONFIG_HELP); + +// +// Used for ShellCommandLineParseEx only +// and to ensure user inputs are in valid format +// +SHELL_PARAM_ITEM mIpSecConfigParamList[] = { + { L"-p", TypeValue }, + { L"-a", TypeValue }, + { L"-i", TypeValue }, + { L"-e", TypeValue }, + { L"-d", TypeValue }, + { L"-f", TypeFlag }, + { L"-l", TypeFlag }, + { L"-enable", TypeFlag }, + { L"-disable", TypeFlag }, + { L"-status", TypeFlag }, + + // + // SPD Selector + // + { L"--local", TypeValue }, + { L"--remote", TypeValue }, + { L"--proto", TypeValue }, + { L"--local-port", TypeValue }, + { L"--remote-port", TypeValue }, + { L"--icmp-type", TypeValue }, + { L"--icmp-code", TypeValue }, + + // + // SPD Data + // + { L"--name", TypeValue }, + { L"--packet-flag", TypeValue }, + { L"--action", TypeValue }, + { L"--lifebyte", TypeValue }, + { L"--lifetime-soft", TypeValue }, + { L"--lifetime", TypeValue }, + { L"--mode", TypeValue }, + { L"--tunnel-local", TypeValue }, + { L"--tunnel-remote", TypeValue }, + { L"--dont-fragment", TypeValue }, + { L"--ipsec-proto", TypeValue }, + { L"--auth-algo", TypeValue }, + { L"--encrypt-algo", TypeValue }, + + { L"--ext-sequence", TypeFlag }, + { L"--sequence-overflow", TypeFlag }, + { L"--fragment-check", TypeFlag }, + { L"--ext-sequence-", TypeFlag }, + { L"--sequence-overflow-", TypeFlag }, + { L"--fragment-check-", TypeFlag }, + + // + // SA ID + // --ipsec-proto + // + { L"--spi", TypeValue }, + { L"--tunnel-dest", TypeValue }, + { L"--tunnel-source", TypeValue }, + { L"--lookup-spi", TypeValue }, + { L"--lookup-ipsec-proto", TypeValue }, + { L"--lookup-dest", TypeValue }, + + // + // SA DATA + // --mode + // --auth-algo + // --encrypt-algo + // + { L"--sequence-number", TypeValue }, + { L"--antireplay-window", TypeValue }, + { L"--auth-key", TypeValue }, + { L"--encrypt-key", TypeValue }, + { L"--path-mtu", TypeValue }, + + // + // PAD ID + // + { L"--peer-id", TypeValue }, + { L"--peer-address", TypeValue }, + { L"--auth-proto", TypeValue }, + { L"--auth-method", TypeValue }, + { L"--ike-id", TypeValue }, + { L"--ike-id-", TypeValue }, + { L"--auth-data", TypeValue }, + { L"--revocation-data", TypeValue }, + { L"--lookup-peer-id", TypeValue }, + { L"--lookup-peer-address", TypeValue }, + + { NULL, TypeMax }, +}; + +// +// -P +// +STR2INT mMapPolicy[] = { + { L"SPD", IPsecConfigDataTypeSpd }, + { L"SAD", IPsecConfigDataTypeSad }, + { L"PAD", IPsecConfigDataTypePad }, + { NULL, 0 }, +}; + +// +// --proto +// +STR2INT mMapIpProtocol[] = { + { L"TCP", EFI_IP4_PROTO_TCP }, + { L"UDP", EFI_IP4_PROTO_UDP }, + { L"ICMP", EFI_IP4_PROTO_ICMP }, + { NULL, 0 }, +}; + +// +// --action +// +STR2INT mMapIpSecAction[] = { + { L"Bypass", EfiIPsecActionBypass }, + { L"Discard", EfiIPsecActionDiscard }, + { L"Protect", EfiIPsecActionProtect }, + { NULL, 0 }, +}; + +// +// --mode +// +STR2INT mMapIpSecMode[] = { + { L"Transport", EfiIPsecTransport }, + { L"Tunnel", EfiIPsecTunnel }, + { NULL, 0 }, +}; + +// +// --dont-fragment +// +STR2INT mMapDfOption[] = { + { L"clear", EfiIPsecTunnelClearDf }, + { L"set", EfiIPsecTunnelSetDf }, + { L"copy", EfiIPsecTunnelCopyDf }, + { NULL, 0 }, +}; + +// +// --ipsec-proto +// +STR2INT mMapIpSecProtocol[] = { + { L"AH", EfiIPsecAH }, + { L"ESP", EfiIPsecESP }, + { NULL, 0 }, +}; + +// +// --auth-algo +// +STR2INT mMapAuthAlgo[] = { + { L"NONE", IPSEC_AALG_NONE }, + { L"MD5HMAC", IPSEC_AALG_MD5HMAC }, + { L"SHA1HMAC", IPSEC_AALG_SHA1HMAC }, + { L"SHA2-256HMAC", IPSEC_AALG_SHA2_256HMAC }, + { L"SHA2-384HMAC", IPSEC_AALG_SHA2_384HMAC }, + { L"SHA2-512HMAC", IPSEC_AALG_SHA2_512HMAC }, + { L"AES-XCBC-MAC", IPSEC_AALG_AES_XCBC_MAC }, + { L"NULL", IPSEC_AALG_NULL }, + { NULL, 0 }, +}; + +// +// --encrypt-algo +// +STR2INT mMapEncAlgo[] = { + { L"NONE", IPSEC_EALG_NONE }, + { L"DESCBC", IPSEC_EALG_DESCBC }, + { L"3DESCBC", IPSEC_EALG_3DESCBC }, + { L"CASTCBC", IPSEC_EALG_CASTCBC }, + { L"BLOWFISHCBC", IPSEC_EALG_BLOWFISHCBC }, + { L"NULL", IPSEC_EALG_NULL }, + { L"AESCBC", IPSEC_EALG_AESCBC }, + { L"AESCTR", IPSEC_EALG_AESCTR }, + { L"AES-CCM-ICV8", IPSEC_EALG_AES_CCM_ICV8 }, + { L"AES-CCM-ICV12",IPSEC_EALG_AES_CCM_ICV12 }, + { L"AES-CCM-ICV16",IPSEC_EALG_AES_CCM_ICV16 }, + { L"AES-GCM-ICV8", IPSEC_EALG_AES_GCM_ICV8 }, + { L"AES-GCM-ICV12",IPSEC_EALG_AES_GCM_ICV12 }, + { L"AES-GCM-ICV16",IPSEC_EALG_AES_GCM_ICV16 }, + { NULL, 0 }, +}; + +// +// --auth-proto +// +STR2INT mMapAuthProto[] = { + { L"IKEv1", EfiIPsecAuthProtocolIKEv1 }, + { L"IKEv2", EfiIPsecAuthProtocolIKEv2 }, + { NULL, 0 }, +}; + +// +// --auth-method +// +STR2INT mMapAuthMethod[] = { + { L"PreSharedSecret", EfiIPsecAuthMethodPreSharedSecret }, + { L"Certificates", EfiIPsecAuthMethodCertificates }, + { NULL, 0 }, +}; + +EFI_IPSEC2_PROTOCOL *mIpSec; +EFI_IPSEC_CONFIG_PROTOCOL *mIpSecConfig; +EFI_HII_HANDLE mHiiHandle; +CHAR16 mAppName[] = L"IpSecConfig"; + +// +// Used for IpSecConfigRetriveCheckListByName only to check the validation of user input +// +VAR_CHECK_ITEM mIpSecConfigVarCheckList[] = { + { L"-enable", BIT(1)|BIT(0), BIT(1), BIT(2)|BIT(1)|BIT(0), 0 }, + { L"-disable", BIT(1)|BIT(0), BIT(1), BIT(2)|BIT(1)|BIT(0), 0 }, + { L"-status", BIT(1)|BIT(0), BIT(1), BIT(2)|BIT(1)|BIT(0), 0 }, + { L"-p", BIT(1), 0, BIT(2)|BIT(1)|BIT(0), 0 }, + + { L"-a", BIT(0), 0, BIT(2)|BIT(1)|BIT(0), 0 }, + { L"-i", BIT(0), 0, BIT(2)|BIT(1)|BIT(0), 0 }, + { L"-d", BIT(0), 0, BIT(2)|BIT(1)|BIT(0), 0 }, + { L"-e", BIT(0), 0, BIT(2)|BIT(1)|BIT(0), 0 }, + { L"-l", BIT(0), 0, BIT(2)|BIT(1)|BIT(0), 0 }, + { L"-f", BIT(0), 0, BIT(2)|BIT(1)|BIT(0), 0 }, + + { L"-?", BIT(0), BIT(0), BIT(2)|BIT(1)|BIT(0), 0 }, + + // + // SPD Selector + // + { L"--local", 0, 0, BIT(2)|BIT(1), 0 }, + { L"--remote", 0, 0, BIT(2)|BIT(1), 0 }, + { L"--proto", 0, 0, BIT(2)|BIT(1), 0 }, + { L"--local-port", 0, 0, BIT(2)|BIT(1), BIT(0) }, + { L"--remote-port", 0, 0, BIT(2)|BIT(1), BIT(0) }, + { L"--icmp-type", 0, 0, BIT(2)|BIT(1), BIT(1) }, + { L"--icmp-code", 0, 0, BIT(2)|BIT(1), BIT(1) }, + + // + // SPD Data + // + { L"--name", 0, 0, BIT(2), 0 }, + { L"--packet-flag", 0, 0, BIT(2), 0 }, + { L"--action", 0, 0, BIT(2)|BIT(1), 0 }, + { L"--lifebyte", 0, 0, BIT(2)|BIT(1), 0 }, + { L"--lifetime-soft", 0, 0, BIT(2)|BIT(1), 0 }, + { L"--lifetime", 0, 0, BIT(2)|BIT(1), 0 }, + { L"--mode", 0, 0, BIT(2)|BIT(1), 0 }, + { L"--tunnel-local", 0, 0, BIT(2), 0 }, + { L"--tunnel-remote", 0, 0, BIT(2), 0 }, + { L"--dont-fragment", 0, 0, BIT(2), 0 }, + { L"--ipsec-proto", 0, 0, BIT(2)|BIT(1), 0 }, + { L"--auth-algo", 0, 0, BIT(2)|BIT(1), 0 }, + { L"--encrypt-algo", 0, 0, BIT(2)|BIT(1), 0 }, + + { L"--ext-sequence", 0, 0, BIT(2), BIT(2) }, + { L"--sequence-overflow", 0, 0, BIT(2), BIT(2) }, + { L"--fragment-check", 0, 0, BIT(2), BIT(2) }, + { L"--ext-sequence-", 0, 0, BIT(2), BIT(3) }, + { L"--sequence-overflow-", 0, 0, BIT(2), BIT(3) }, + { L"--fragment-check-", 0, 0, BIT(2), BIT(3) }, + + // + // SA ID + // --ipsec-proto + // + { L"--spi", 0, 0, BIT(1), 0 }, + { L"--tunnel-dest", 0, 0, BIT(1), 0 }, + { L"--tunnel-source", 0, 0, BIT(1), 0 }, + { L"--lookup-spi", 0, 0, BIT(1), 0 }, + { L"--lookup-ipsec-proto", 0, 0, BIT(1), 0 }, + { L"--lookup-dest", 0, 0, BIT(1), 0 }, + + // + // SA DATA + // --mode + // --auth-algo + // --encrypt-algo + // + { L"--sequence-number", 0, 0, BIT(1), 0 }, + { L"--antireplay-window", 0, 0, BIT(1), 0 }, + { L"--auth-key", 0, 0, BIT(1), 0 }, + { L"--encrypt-key", 0, 0, BIT(1), 0 }, + { L"--path-mtu", 0, 0, BIT(1), 0 }, + + // + // The example to add a PAD: + // "-A --peer-id Mike [--peer-address 10.23.2.2] --auth-proto IKE1/IKE2 + // --auth-method PreSharedSeceret/Certificate --ike-id + // --auth-data 343343 --revocation-data 2342432" + // The example to delete a PAD: + // "-D * --lookup-peer-id Mike [--lookup-peer-address 10.23.2.2]" + // "-D 1" + // The example to edit a PAD: + // "-E * --lookup-peer-id Mike --auth-method Certificate" + + // + // PAD ID + // + { L"--peer-id", 0, 0, BIT(0), BIT(4) }, + { L"--peer-address", 0, 0, BIT(0), BIT(5) }, + { L"--auth-proto", 0, 0, BIT(0), 0 }, + { L"--auth-method", 0, 0, BIT(0), 0 }, + { L"--IKE-ID", 0, 0, BIT(0), BIT(6) }, + { L"--IKE-ID-", 0, 0, BIT(0), BIT(7) }, + { L"--auth-data", 0, 0, BIT(0), 0 }, + { L"--revocation-data", 0, 0, BIT(0), 0 }, + { L"--lookup-peer-id", 0, 0, BIT(0), BIT(4) }, + { L"--lookup-peer-address",0, 0, BIT(0), BIT(5) }, + + { NULL, 0, 0, 0, 0 }, +}; + +/** + The function to allocate the proper sized buffer for various + EFI interfaces. + + @param[in, out] Status Current status. + @param[in, out] Buffer Current allocated buffer, or NULL. + @param[in] BufferSize Current buffer size needed + + @retval TRUE If the buffer was reallocated and the caller should try the API again. + @retval FALSE If the buffer was not reallocated successfully. +**/ +BOOLEAN +GrowBuffer ( + IN OUT EFI_STATUS *Status, + IN OUT VOID **Buffer, + IN UINTN BufferSize + ) +{ + BOOLEAN TryAgain; + + ASSERT (Status != NULL); + ASSERT (Buffer != NULL); + + // + // If this is an initial request, buffer will be null with a new buffer size. + // + if ((NULL == *Buffer) && (BufferSize != 0)) { + *Status = EFI_BUFFER_TOO_SMALL; + } + + // + // If the status code is "buffer too small", resize the buffer. + // + TryAgain = FALSE; + if (*Status == EFI_BUFFER_TOO_SMALL) { + + if (*Buffer != NULL) { + FreePool (*Buffer); + } + + *Buffer = AllocateZeroPool (BufferSize); + + if (*Buffer != NULL) { + TryAgain = TRUE; + } else { + *Status = EFI_OUT_OF_RESOURCES; + } + } + + // + // If there's an error, free the buffer. + // + if (!TryAgain && EFI_ERROR (*Status) && (*Buffer != NULL)) { + FreePool (*Buffer); + *Buffer = NULL; + } + + return TryAgain; +} + +/** + Function returns an array of handles that support the requested protocol + in a buffer allocated from a pool. + + @param[in] SearchType Specifies which handle(s) are to be returned. + @param[in] Protocol Provides the protocol to search by. + This parameter is only valid for SearchType ByProtocol. + + @param[in] SearchKey Supplies the search key depending on the SearchType. + @param[in, out] NoHandles The number of handles returned in Buffer. + @param[out] Buffer A pointer to the buffer to return the requested array of + handles that support Protocol. + + @retval EFI_SUCCESS The resulting array of handles was returned. + @retval Others Other mistake case. +**/ +EFI_STATUS +LocateHandle ( + IN EFI_LOCATE_SEARCH_TYPE SearchType, + IN EFI_GUID *Protocol OPTIONAL, + IN VOID *SearchKey OPTIONAL, + IN OUT UINTN *NoHandles, + OUT EFI_HANDLE **Buffer + ) +{ + EFI_STATUS Status; + UINTN BufferSize; + + ASSERT (NoHandles != NULL); + ASSERT (Buffer != NULL); + + // + // Initialize for GrowBuffer loop. + // + Status = EFI_SUCCESS; + *Buffer = NULL; + BufferSize = 50 * sizeof (EFI_HANDLE); + + // + // Call the real function. + // + while (GrowBuffer (&Status, (VOID **) Buffer, BufferSize)) { + Status = gBS->LocateHandle ( + SearchType, + Protocol, + SearchKey, + &BufferSize, + *Buffer + ); + } + + *NoHandles = BufferSize / sizeof (EFI_HANDLE); + if (EFI_ERROR (Status)) { + *NoHandles = 0; + } + + return Status; +} + +/** + Find the first instance of this protocol in the system and return its interface. + + @param[in] ProtocolGuid The guid of the protocol. + @param[out] Interface The pointer to the first instance of the protocol. + + @retval EFI_SUCCESS A protocol instance matching ProtocolGuid was found. + @retval Others A protocol instance matching ProtocolGuid was not found. +**/ +EFI_STATUS +LocateProtocol ( + IN EFI_GUID *ProtocolGuid, + OUT VOID **Interface + ) + +{ + EFI_STATUS Status; + UINTN NumberHandles; + UINTN Index; + EFI_HANDLE *Handles; + + *Interface = NULL; + Handles = NULL; + NumberHandles = 0; + + Status = LocateHandle (ByProtocol, ProtocolGuid, NULL, &NumberHandles, &Handles); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_INFO, "LibLocateProtocol: Handle not found\n")); + return Status; + } + + for (Index = 0; Index < NumberHandles; Index++) { + ASSERT (Handles != NULL); + Status = gBS->HandleProtocol ( + Handles[Index], + ProtocolGuid, + Interface + ); + + if (!EFI_ERROR (Status)) { + break; + } + } + + if (Handles != NULL) { + FreePool (Handles); + } + + return Status; +} + +/** + Helper function called to check the conflicted flags. + + @param[in] CheckList The pointer to the VAR_CHECK_ITEM table. + @param[in] ParamPackage The pointer to the ParamPackage list. + + @retval EFI_SUCCESS No conflicted flags. + @retval EFI_INVALID_PARAMETER The input parameter is erroroneous or there are some conflicted flags. +**/ +EFI_STATUS +IpSecConfigRetriveCheckListByName ( + IN VAR_CHECK_ITEM *CheckList, + IN LIST_ENTRY *ParamPackage +) +{ + + LIST_ENTRY *Node; + VAR_CHECK_ITEM *Item; + UINT32 Attribute1; + UINT32 Attribute2; + UINT32 Attribute3; + UINT32 Attribute4; + UINT32 Index; + + Attribute1 = 0; + Attribute2 = 0; + Attribute3 = 0; + Attribute4 = 0; + Index = 0; + Item = mIpSecConfigVarCheckList; + + if ((ParamPackage == NULL) || (CheckList == NULL)) { + return EFI_INVALID_PARAMETER; + } + + // + // Enumerate through the list of parameters that are input by user. + // + for (Node = GetFirstNode (ParamPackage); !IsNull (ParamPackage, Node); Node = GetNextNode (ParamPackage, Node)) { + if (((SHELL_PARAM_PACKAGE *) Node)->Name != NULL) { + // + // Enumerate the check list that defines the conflicted attributes of each flag. + // + for (; Item->VarName != NULL; Item++) { + if (StrCmp (((SHELL_PARAM_PACKAGE *) Node)->Name, Item->VarName) == 0) { + Index++; + if (Index == 1) { + Attribute1 = Item->Attribute1; + Attribute2 = Item->Attribute2; + Attribute3 = Item->Attribute3; + Attribute4 = Item->Attribute4; + } else { + Attribute1 &= Item->Attribute1; + Attribute2 |= Item->Attribute2; + Attribute3 &= Item->Attribute3; + Attribute4 |= Item->Attribute4; + if (Attribute1 != 0) { + return EFI_INVALID_PARAMETER; + } + + if (Attribute2 != 0) { + if ((Index == 2) && (StrCmp (Item->VarName, L"-p") == 0)) { + continue; + } + + return EFI_INVALID_PARAMETER; + } + + if (Attribute3 == 0) { + return EFI_INVALID_PARAMETER; + } + if (((Attribute4 & 0xFF) == 0x03) || ((Attribute4 & 0xFF) == 0x0C) || + ((Attribute4 & 0xFF) == 0x30) || ((Attribute4 & 0xFF) == 0xC0)) { + return EFI_INVALID_PARAMETER; + } + } + break; + } + } + + Item = mIpSecConfigVarCheckList; + } + } + + return EFI_SUCCESS; +} + +/** + This is the declaration of an EFI image entry point. This entry point is + the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers, including + both device drivers and bus drivers. + + The entry point for IpSecConfig application that parse the command line input and call an IpSecConfig process. + + @param[in] ImageHandle The image handle of this application. + @param[in] SystemTable The pointer to the EFI System Table. + + @retval EFI_SUCCESS The operation completed successfully. + +**/ +EFI_STATUS +EFIAPI +InitializeIpSecConfig ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_IPSEC_CONFIG_DATA_TYPE DataType; + UINT8 Value; + LIST_ENTRY *ParamPackage; + CONST CHAR16 *ValueStr; + CHAR16 *ProblemParam; + UINTN NonOptionCount; + EFI_HII_PACKAGE_LIST_HEADER *PackageList; + + // + // Retrieve HII package list from ImageHandle + // + Status = gBS->OpenProtocol ( + ImageHandle, + &gEfiHiiPackageListProtocolGuid, + (VOID **) &PackageList, + ImageHandle, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Publish HII package list to HII Database. + // + Status = gHiiDatabase->NewPackageList ( + gHiiDatabase, + PackageList, + NULL, + &mHiiHandle + ); + if (EFI_ERROR (Status)) { + return Status; + } + + ASSERT (mHiiHandle != NULL); + + Status = ShellCommandLineParseEx (mIpSecConfigParamList, &ParamPackage, &ProblemParam, TRUE, FALSE); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_UNKNOWN_OPERATION), mHiiHandle, ProblemParam); + goto Done; + } + + Status = IpSecConfigRetriveCheckListByName (mIpSecConfigVarCheckList, ParamPackage); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_MISTAKEN_OPTIONS), mHiiHandle); + goto Done; + } + + Status = LocateProtocol (&gEfiIpSecConfigProtocolGuid, (VOID **) &mIpSecConfig); + if (EFI_ERROR (Status) || mIpSecConfig == NULL) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_PROTOCOL_INEXISTENT), mHiiHandle, mAppName); + goto Done; + } + + Status = LocateProtocol (&gEfiIpSec2ProtocolGuid, (VOID **) &mIpSec); + if (EFI_ERROR (Status) || mIpSec == NULL) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_PROTOCOL_INEXISTENT), mHiiHandle, mAppName); + goto Done; + } + + // + // Enable IPsec. + // + if (ShellCommandLineGetFlag (ParamPackage, L"-enable")) { + if (!(mIpSec->DisabledFlag)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_ALREADY_ENABLE), mHiiHandle, mAppName); + } else { + // + // Set enable flag. + // + Value = IPSEC_STATUS_ENABLED; + Status = gRT->SetVariable ( + IPSECCONFIG_STATUS_NAME, + &gEfiIpSecConfigProtocolGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE, + sizeof (Value), + &Value + ); + if (!EFI_ERROR (Status)) { + mIpSec->DisabledFlag = FALSE; + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_ENABLE_SUCCESS), mHiiHandle, mAppName); + } else { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_ENABLE_FAILED), mHiiHandle, mAppName); + } + } + + goto Done; + } + + // + // Disable IPsec. + // + if (ShellCommandLineGetFlag (ParamPackage, L"-disable")) { + if (mIpSec->DisabledFlag) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_ALREADY_DISABLE), mHiiHandle, mAppName); + } else { + // + // Set disable flag; however, leave it to be disabled in the callback function of DisabledEvent. + // + gBS->SignalEvent (mIpSec->DisabledEvent); + if (mIpSec->DisabledFlag) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_DISABLE_SUCCESS), mHiiHandle, mAppName); + } else { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_DISABLE_FAILED), mHiiHandle, mAppName); + } + } + + goto Done; + } + + // + //IPsec Status. + // + if (ShellCommandLineGetFlag (ParamPackage, L"-status")) { + if (mIpSec->DisabledFlag) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_STATUS_DISABLE), mHiiHandle, mAppName); + } else { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_STATUS_ENABLE), mHiiHandle, mAppName); + } + goto Done; + } + + // + // Try to get policy database type. + // + DataType = (EFI_IPSEC_CONFIG_DATA_TYPE) - 1; + ValueStr = ShellCommandLineGetValue (ParamPackage, L"-p"); + if (ValueStr != NULL) { + DataType = (EFI_IPSEC_CONFIG_DATA_TYPE) MapStringToInteger (ValueStr, mMapPolicy); + if (DataType == -1) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_DB), mHiiHandle, mAppName, ValueStr); + goto Done; + } + } + + NonOptionCount = ShellCommandLineGetCount (ParamPackage); + if ((NonOptionCount - 1) > 0) { + ValueStr = ShellCommandLineGetRawValue (ParamPackage, (UINT32) (NonOptionCount - 1)); + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_REDUNDANCY_MANY), mHiiHandle, mAppName, ValueStr); + goto Done; + } + + if (DataType == -1) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_DB), mHiiHandle, mAppName); + goto Done; + } + + if (ShellCommandLineGetFlag (ParamPackage, L"-a")) { + Status = AddOrInsertPolicyEntry (DataType, ParamPackage); + if (EFI_ERROR (Status)) { + goto Done; + } + } else if (ShellCommandLineGetFlag (ParamPackage, L"-i")) { + Status = AddOrInsertPolicyEntry (DataType, ParamPackage); + if (EFI_ERROR (Status)) { + goto Done; + } + } else if (ShellCommandLineGetFlag (ParamPackage, L"-e")) { + Status = EditPolicyEntry (DataType, ParamPackage); + if (EFI_ERROR (Status)) { + goto Done; + } + } else if (ShellCommandLineGetFlag (ParamPackage, L"-d")) { + Status = FlushOrDeletePolicyEntry (DataType, ParamPackage); + if (EFI_ERROR (Status)) { + goto Done; + } + } else if (ShellCommandLineGetFlag (ParamPackage, L"-f")) { + Status = FlushOrDeletePolicyEntry (DataType, ParamPackage); + if (EFI_ERROR (Status)) { + goto Done; + } + } else if (ShellCommandLineGetFlag (ParamPackage, L"-l")) { + Status = ListPolicyEntry (DataType, ParamPackage); + if (EFI_ERROR (Status)) { + goto Done; + } + } else { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_UNKNOWN_OPERATION), mHiiHandle, mAppName); + goto Done; + } + +Done: + ShellCommandLineFreeVarList (ParamPackage); + HiiRemovePackages (mHiiHandle); + + return EFI_SUCCESS; +} diff --git a/Core/NetworkPkg/Application/IpsecConfig/IpSecConfig.h b/Core/NetworkPkg/Application/IpsecConfig/IpSecConfig.h new file mode 100644 index 0000000000..95bb696113 --- /dev/null +++ b/Core/NetworkPkg/Application/IpsecConfig/IpSecConfig.h @@ -0,0 +1,149 @@ +/** @file + The internal structure and function declaration in IpSecConfig application. + + Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _IPSEC_CONFIG_H_ +#define _IPSEC_CONFIG_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define IPSECCONFIG_STATUS_NAME L"IpSecStatus" + +#define BIT(x) (UINT32) (1 << (x)) + +#define IPSEC_STATUS_DISABLED 0x0 +#define IPSEC_STATUS_ENABLED 0x1 + +#define EFI_IP4_PROTO_ICMP 0x1 +#define EFI_IP4_PROTO_TCP 0x6 +#define EFI_IP4_PROTO_UDP 0x11 + +#define EFI_IPSEC_ANY_PROTOCOL 0xFFFF +#define EFI_IPSEC_ANY_PORT 0 + +/// +/// IPsec Authentication Algorithm Definition +/// The number value definition is aligned to IANA assignment +/// +#define IPSEC_AALG_NONE 0x00 +#define IPSEC_AALG_MD5HMAC 0x01 +#define IPSEC_AALG_SHA1HMAC 0x02 +#define IPSEC_AALG_SHA2_256HMAC 0x05 +#define IPSEC_AALG_SHA2_384HMAC 0x06 +#define IPSEC_AALG_SHA2_512HMAC 0x07 +#define IPSEC_AALG_AES_XCBC_MAC 0x09 +#define IPSEC_AALG_NULL 0xFB + +/// +/// IPsec Encryption Algorithm Definition +/// The number value definition is aligned to IANA assignment +/// +#define IPSEC_EALG_NONE 0x00 +#define IPSEC_EALG_DESCBC 0x02 +#define IPSEC_EALG_3DESCBC 0x03 +#define IPSEC_EALG_CASTCBC 0x06 +#define IPSEC_EALG_BLOWFISHCBC 0x07 +#define IPSEC_EALG_NULL 0x0B +#define IPSEC_EALG_AESCBC 0x0C +#define IPSEC_EALG_AESCTR 0x0D +#define IPSEC_EALG_AES_CCM_ICV8 0x0E +#define IPSEC_EALG_AES_CCM_ICV12 0x0F +#define IPSEC_EALG_AES_CCM_ICV16 0x10 +#define IPSEC_EALG_AES_GCM_ICV8 0x12 +#define IPSEC_EALG_AES_GCM_ICV12 0x13 +#define IPSEC_EALG_AES_GCM_ICV16 0x14 + +typedef struct { + CHAR16 *VarName; + UINT32 Attribute1; + UINT32 Attribute2; + UINT32 Attribute3; + UINT32 Attribute4; +} VAR_CHECK_ITEM; + +typedef struct { + LIST_ENTRY Link; + CHAR16 *Name; + SHELL_PARAM_TYPE Type; + CHAR16 *Value; + UINTN OriginalPosition; +} SHELL_PARAM_PACKAGE; + +typedef struct { + CHAR16 *String; + UINT32 Integer; +} STR2INT; + +extern EFI_IPSEC_CONFIG_PROTOCOL *mIpSecConfig; +extern EFI_HII_HANDLE mHiiHandle; +extern CHAR16 mAppName[]; + +// +// -P +// +extern STR2INT mMapPolicy[]; + +// +// --proto +// +extern STR2INT mMapIpProtocol[]; + +// +// --action +// +extern STR2INT mMapIpSecAction[]; + +// +// --mode +// +extern STR2INT mMapIpSecMode[]; + +// +// --dont-fragment +// +extern STR2INT mMapDfOption[]; + +// +// --ipsec-proto +// +extern STR2INT mMapIpSecProtocol[]; +// +// --auth-algo +// +extern STR2INT mMapAuthAlgo[]; + +// +// --encrypt-algo +// +extern STR2INT mMapEncAlgo[]; +// +// --auth-proto +// +extern STR2INT mMapAuthProto[]; + +// +// --auth-method +// +extern STR2INT mMapAuthMethod[]; + +#endif diff --git a/Core/NetworkPkg/Application/IpsecConfig/IpSecConfig.inf b/Core/NetworkPkg/Application/IpsecConfig/IpSecConfig.inf new file mode 100644 index 0000000000..02371e535d --- /dev/null +++ b/Core/NetworkPkg/Application/IpsecConfig/IpSecConfig.inf @@ -0,0 +1,76 @@ +## @file +# Shell application IpSecConfig. +# +# This application is used to set and retrieve security and policy related information +# for the EFI IPsec protocol driver. +# +# Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x00010006 + BASE_NAME = IpSecConfig + FILE_GUID = 0922E604-F5EC-42ef-980D-A35E9A2B1844 + MODULE_TYPE = UEFI_APPLICATION + VERSION_STRING = 1.0 + ENTRY_POINT = InitializeIpSecConfig + MODULE_UNI_FILE = IpSecConfig.uni + +# +# +# This flag specifies whether HII resource section is generated into PE image. +# + UEFI_HII_RESOURCE_SECTION = TRUE + +[Sources] + IpSecConfigStrings.uni + IpSecConfig.c + IpSecConfig.h + Dump.c + Dump.h + Indexer.c + Indexer.h + Match.c + Match.h + Delete.h + Delete.c + Helper.c + Helper.h + ForEach.c + ForEach.h + PolicyEntryOperation.c + PolicyEntryOperation.h + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + ShellPkg/ShellPkg.dec + +[LibraryClasses] + UefiBootServicesTableLib + UefiApplicationEntryPoint + UefiHiiServicesLib + BaseMemoryLib + ShellLib + MemoryAllocationLib + DebugLib + HiiLib + NetLib + UefiLib + +[Protocols] + gEfiIpSec2ProtocolGuid ##CONSUMES + gEfiIpSecConfigProtocolGuid ##CONSUMES + gEfiHiiPackageListProtocolGuid ##CONSUMES + +[UserExtensions.TianoCore."ExtraFiles"] + IpSecConfigExtra.uni diff --git a/Core/NetworkPkg/Application/IpsecConfig/IpSecConfig.uni b/Core/NetworkPkg/Application/IpsecConfig/IpSecConfig.uni new file mode 100644 index 0000000000..3dab958699 --- /dev/null +++ b/Core/NetworkPkg/Application/IpsecConfig/IpSecConfig.uni @@ -0,0 +1,23 @@ +// /** @file +// Shell application IpSecConfig. +// +// This application is used to set and retrieve security and policy related information +// for the EFI IPsec protocol driver. +// +// Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.
+// +// This program and the accompanying materials +// are licensed and made available under the terms and conditions of the BSD License +// which accompanies this distribution. The full text of the license may be found at +// http://opensource.org/licenses/bsd-license.php. +// +// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "Shell application IpSecConfig" + +#string STR_MODULE_DESCRIPTION #language en-US "This application is used to set and retrieve security and policy related information for the EFI IPsec protocol driver." + diff --git a/Core/NetworkPkg/Application/IpsecConfig/IpSecConfigExtra.uni b/Core/NetworkPkg/Application/IpsecConfig/IpSecConfigExtra.uni new file mode 100644 index 0000000000..53008576c0 --- /dev/null +++ b/Core/NetworkPkg/Application/IpsecConfig/IpSecConfigExtra.uni @@ -0,0 +1,20 @@ +// /** @file +// IpSecConfig Localized Strings and Content +// +// Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.
+// +// This program and the accompanying materials +// are licensed and made available under the terms and conditions of the BSD License +// which accompanies this distribution. The full text of the license may be found at +// http://opensource.org/licenses/bsd-license.php. +// +// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +// +// **/ + +#string STR_PROPERTIES_MODULE_NAME +#language en-US +"IpSec Config App" + + diff --git a/Core/NetworkPkg/Application/IpsecConfig/IpSecConfigStrings.uni b/Core/NetworkPkg/Application/IpsecConfig/IpSecConfigStrings.uni new file mode 100644 index 0000000000..bd7f546327 --- /dev/null +++ b/Core/NetworkPkg/Application/IpsecConfig/IpSecConfigStrings.uni @@ -0,0 +1,133 @@ +/** @file + String definitions for the Shell IpSecConfig application. + + Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#langdef en-US "English" + +#string STR_IPSEC_CONFIG_UNKNOWN_OPERATION #language en-US "%s: Operation not specified.\n" + +#string STR_IPSEC_CONFIG_INCORRECT_DB #language en-US "%s: Incorrect Database - %s.\n" + +#string STR_IPSEC_CONFIG_PROTOCOL_INEXISTENT #language en-US "%s: IPSEC_CONFIG protocol inexistent.\n" + +#string STR_IPSEC_CONFIG_MISSING_DB #language en-US "%s: Missing Database.\n" + +#string STR_IPSEC_CONFIG_FILE_OPEN_FAILED #language en-US "%s: Open file failed - %s.\n" + +#string STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE #language en-US "%s: Incorrect value of %s - %s.\n" + +#string STR_IPSEC_CONFIG_ACCEPT_PARAMETERS #language en-US " Values could be:" + +#string STR_IPSEC_CONFIG_MISSING_PARAMETER #language en-US "%s: Missing parameter - %s.\n" + +#string STR_IPSEC_CONFIG_MISSING_ONE_OF_PARAMETERS #language en-US "%s: Missing one of the parameters - %s.\n" + +#string STR_IPSEC_CONFIG_UNWANTED_PARAMETER #language en-US "%s: Unwanted parameter - %s.\n" + +#string STR_IPSEC_CONFIG_INSERT_FAILED #language en-US "%s: Policy entry insertion failed!\n" + +#string STR_IPSEC_CONFIG_DELETE_FAILED #language en-US "%s: Policy entry deletion failed!\n" + +#string STR_IPSEC_CONFIG_EDIT_FAILED #language en-US "%s: Policy entry edit failed!\n" + +#string STR_IPSEC_CONFIG_ALREADY_EXISTS #language en-US "%s: Policy entry already exists!\n" + +#string STR_IPSEC_CONFIG_INDEX_NOT_FOUND #language en-US "%s: Specified index not found!\n" + +#string STR_IPSEC_CONFIG_INDEX_NOT_SPECIFIED #language en-US "%s: Index should be Specified!\n" + +#string STR_IPSEC_CONFIG_INSERT_UNSUPPORT #language en-US "%s: Policy entry insertion not supported!\n" + +#string STR_IPSEC_MISTAKEN_OPTIONS #language en-US "Mistaken Input. Please refer to %H"IpSecConfig -?"%N for more help information.\n" + +#string STR_IPSEC_REDUNDANCY_MANY #language en-US "%s has one redundancy option: %H%s%N\n" + +#string STR_IPSEC_CONFIG_ALREADY_ENABLE #language en-US "IPsec has been already enabled!\n" + +#string STR_IPSEC_CONFIG_ENABLE_SUCCESS #language en-US "Enable IPsec ! \n" + +#string STR_IPSEC_CONFIG_DISABLE_SUCCESS #language en-US "Disable IPsec ! \n" + +#string STR_IPSEC_CONFIG_ALREADY_DISABLE #language en-US "IPsec has been already disabled !\n" + +#string STR_IPSEC_CONFIG_STATUS_ENABLE #language en-US "IPsec Status : Enabled ! \n" + +#string STR_IPSEC_CONFIG_STATUS_DISABLE #language en-US "IPsec Status : Disabled ! \n" + +#string STR_IPSEC_CONFIG_ENABLE_FAILED #language en-US "Error: Enable IPsec failed !\n" + +#string STR_IPSEC_CONFIG_DISABLE_FAILED #language en-US "Error: Disable IPsec failed !\n" + +#string STR_IPSEC_CONFIG_HELP #language en-US "" +".TH IpSecConfig 0 "Displays or modifies the current IPsec configuration."\r\n" +".SH NAME\r\n" +"Displays or modifies the current IPsec configuration.\r\n" +".SH SYNOPSIS\r\n" +" \r\n" +"%HIpSecConfig [-p {SPD|SAD|PAD}] [command] [options[parameters]]\r\n" +".SH OPTIONS\r\n" +" \r\n" +"%H-p (SPD|SAD|PAD)%N required.point to certain policy database.\r\n" +" \r\n" +"%Hcommand%N:\r\n" +" -a [options[parameters]] Add new policy entry.\r\n" +" -i entryid [options[parameters]] Insert new policy entry before the one\r\n" +" matched by the entryid.\r\n" +" It's only supported on SPD policy database.\r\n" +" -d entryid Delete the policy entry matched by the \r\n" +" entryid.\r\n" +" -e entryid [options[parameters]] Edit the policy entry matched by the\r\n" +" entryid.\r\n" +" -f Flush the entire policy database.\r\n" +" -l List all entries for specified database.\r\n" +" -enable Enable IPsec.\r\n" +" -disable Disable IPsec.\r\n" +" -status Show IPsec current status.\r\n" +" \r\n" +"%H[options[parameters]]%N for %HSPD%N:\r\n" +" --local localaddress optional local address\r\n" +" --remote remoteaddress required remote address\r\n" +" --proto (TCP|UDP|ICMP|...) required IP protocol\r\n" +" --local-port port optional local port for tcp/udp protocol\r\n" +" --remote-port port optional remote port for tcp/udp protocol\r\n" +" --name name optional SPD name\r\n" +" --action (Bypass|Discard|Protect) required \r\n" +" required IPsec action\r\n" +" --mode (Transport|Tunnel) optional IPsec mode, transport by default\r\n" +" --ipsec-proto (AH|ESP) optional IPsec protocol, ESP by default\r\n" +" --auth-algo (NONE|SHA1HMAC) optional authentication algorithm\r\n" +" --encrypt-algo(NONE|DESCBC|3DESCBC)optional encryption algorithm\r\n" +" --tunnel-local tunnellocaladdr optional tunnel local address(only for tunnel mode)\r\n" +" --tunnel-remote tunnelremoteaddr optional tunnel remote address(only for tunnel mode)\r\n" +" \r\n" +"%H[options[parameters]]%N for %HSAD%N:\r\n" +" --spi spi required SPI value\r\n" +" --ipsec-proto (AH|ESP) required IPsec protocol\r\n" +" --local localaddress optional local address\r\n" +" --remote remoteaddress required destination address\r\n" +" --auth-algo (NONE|SHA1HMAC) required for AH. authentication algorithm\n" +" --auth-key key required for AH. key for authentication\r\n" +" --encrypt-algo (NONE|DESCBC|3DESCBC) required for ESP. encryption algorithm\r\n" +" --encrypt-key key required for ESP. key for encryption\r\n" +" --mode (Transport|Tunnel) optional IPsec mode, transport by default\r\n" +" --tunnel-dest tunneldestaddr optional tunnel destination address(only for tunnel mode)\r\n" +" --tunnel-source tunnelsourceaddr optional tunnel source address(only for tunnel mode)\r\n" +" \r\n" +"%H[options[parameters]]%N for %HPAD%N:\r\n" +" --peer-address address required peer address\r\n" +" --auth-proto (IKEv1|IKEv2) optional IKE protocol, IKEv1 by\r\n" +" default\r\n" +" --auth-method (PreSharedSecret|Certificates) required authentication method\r\n" +" --auth-data authdata required data for authentication\r\n" +" \r\n" diff --git a/Core/NetworkPkg/Application/IpsecConfig/Match.c b/Core/NetworkPkg/Application/IpsecConfig/Match.c new file mode 100644 index 0000000000..2ee763e607 --- /dev/null +++ b/Core/NetworkPkg/Application/IpsecConfig/Match.c @@ -0,0 +1,163 @@ +/** @file + The implementation of match policy entry function in IpSecConfig application. + + Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "IpSecConfig.h" +#include "Indexer.h" +#include "Match.h" + +/** + Private function to validate a buffer that should be filled with zero. + + @param[in] Memory The pointer to the buffer. + @param[in] Size The size of the buffer. + + @retval TRUE The memory is filled with zero. + @retval FALSE The memory isn't filled with zero. +**/ +BOOLEAN +IsMemoryZero ( + IN VOID *Memory, + IN UINTN Size + ) +{ + UINTN Index; + + for (Index = 0; Index < Size; Index++) { + if (*((UINT8 *) Memory + Index) != 0) { + return FALSE; + } + } + + return TRUE; +} + +/** + Find the matching SPD with Indexer. + + @param[in] Selector The pointer to the EFI_IPSEC_SPD_SELECTOR structure. + @param[in] Data The pointer to the EFI_IPSEC_SPD_DATA structure. + @param[in] Indexer The pointer to the SPD_ENTRY_INDEXER structure. + + @retval TRUE The matched SPD is found. + @retval FALSE The matched SPD is not found. +**/ +BOOLEAN +MatchSpdEntry ( + IN EFI_IPSEC_SPD_SELECTOR *Selector, + IN EFI_IPSEC_SPD_DATA *Data, + IN SPD_ENTRY_INDEXER *Indexer + ) +{ + BOOLEAN Match; + + Match = FALSE; + if (!IsMemoryZero (Indexer->Name, MAX_PEERID_LEN)) { + if ((Data->Name != NULL) && (AsciiStrCmp ((CHAR8 *) Indexer->Name, (CHAR8 *) Data->Name) == 0)) { + Match = TRUE; + } + } else { + if (Indexer->Index == 0) { + Match = TRUE; + } + + Indexer->Index--; + } + + return Match; +} + +/** + Find the matching SAD with Indexer. + + @param[in] SaId The pointer to the EFI_IPSEC_SA_ID structure. + @param[in] Data The pointer to the EFI_IPSEC_SA_DATA2 structure. + @param[in] Indexer The pointer to the SPD_ENTRY_INDEXER structure. + + @retval TRUE The matched SAD is found. + @retval FALSE The matched SAD is not found. +**/ +BOOLEAN +MatchSadEntry ( + IN EFI_IPSEC_SA_ID *SaId, + IN EFI_IPSEC_SA_DATA2 *Data, + IN SAD_ENTRY_INDEXER *Indexer + ) +{ + BOOLEAN Match; + + Match = FALSE; + if (!IsMemoryZero (&Indexer->SaId, sizeof (EFI_IPSEC_SA_ID))) { + Match = (BOOLEAN) (CompareMem (&Indexer->SaId, SaId, sizeof (EFI_IPSEC_SA_ID)) == 0); + } else { + if (Indexer->Index == 0) { + Match = TRUE; + } + Indexer->Index--; + } + + return Match; +} + +/** + Find the matching PAD with Indexer. + + @param[in] PadId The pointer to the EFI_IPSEC_PAD_ID structure. + @param[in] Data The pointer to the EFI_IPSEC_PAD_DATA structure. + @param[in] Indexer The pointer to the SPD_ENTRY_INDEXER structure. + + @retval TRUE The matched PAD is found. + @retval FALSE The matched PAD is not found. +**/ +BOOLEAN +MatchPadEntry ( + IN EFI_IPSEC_PAD_ID *PadId, + IN EFI_IPSEC_PAD_DATA *Data, + IN PAD_ENTRY_INDEXER *Indexer + ) +{ + BOOLEAN Match; + + Match = FALSE; + if (!IsMemoryZero (&Indexer->PadId, sizeof (EFI_IPSEC_PAD_ID))) { + Match = (BOOLEAN) ((Indexer->PadId.PeerIdValid == PadId->PeerIdValid) && + ((PadId->PeerIdValid && + (StrCmp ( + (CONST CHAR16 *) Indexer->PadId.Id.PeerId, + (CONST CHAR16 *) PadId->Id.PeerId + ) == 0)) || + ((!PadId->PeerIdValid) && + (Indexer->PadId.Id.IpAddress.PrefixLength == PadId->Id.IpAddress.PrefixLength) && + (CompareMem ( + &Indexer->PadId.Id.IpAddress.Address, + &PadId->Id.IpAddress.Address, + sizeof (EFI_IP_ADDRESS) + ) == 0)))); + } else { + if (Indexer->Index == 0) { + Match = TRUE; + } + + Indexer->Index--; + } + + return Match; +} + +MATCH_POLICY_ENTRY mMatchPolicyEntry[] = { + (MATCH_POLICY_ENTRY) MatchSpdEntry, + (MATCH_POLICY_ENTRY) MatchSadEntry, + (MATCH_POLICY_ENTRY) MatchPadEntry +}; + diff --git a/Core/NetworkPkg/Application/IpsecConfig/Match.h b/Core/NetworkPkg/Application/IpsecConfig/Match.h new file mode 100644 index 0000000000..1d73c5cfbc --- /dev/null +++ b/Core/NetworkPkg/Application/IpsecConfig/Match.h @@ -0,0 +1,41 @@ +/** @file + The internal structure and function declaration of + match policy entry function in IpSecConfig application. + + Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _MATCH_H_ +#define _MATCH_H_ + +/** + The prototype for the MatchSpdEntry()/MatchSadEntry()/MatchPadEntry(). + The functionality is to find the matching SPD/SAD/PAD with Indexer. + + @param[in] Selector The pointer to the EFI_IPSEC_CONFIG_SELECTOR union. + @param[in] Data The pointer to corresponding Data. + @param[in] Indexer The pointer to the POLICY_ENTRY_INDEXER union. + + @retval TRUE The matched SPD/SAD/PAD is found. + @retval FALSE The matched SPD/SAD/PAD is not found. +**/ +typedef +BOOLEAN +(* MATCH_POLICY_ENTRY) ( + IN EFI_IPSEC_CONFIG_SELECTOR *Selector, + IN VOID *Data, + IN POLICY_ENTRY_INDEXER *Indexer + ); + +extern MATCH_POLICY_ENTRY mMatchPolicyEntry[]; + +#endif diff --git a/Core/NetworkPkg/Application/IpsecConfig/PolicyEntryOperation.c b/Core/NetworkPkg/Application/IpsecConfig/PolicyEntryOperation.c new file mode 100644 index 0000000000..06eb30c091 --- /dev/null +++ b/Core/NetworkPkg/Application/IpsecConfig/PolicyEntryOperation.c @@ -0,0 +1,2076 @@ +/** @file + The implementation of policy entry operation function in IpSecConfig application. + + Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "IpSecConfig.h" +#include "Indexer.h" +#include "Match.h" +#include "Helper.h" +#include "ForEach.h" +#include "PolicyEntryOperation.h" + +/** + Fill in EFI_IPSEC_SPD_SELECTOR through ParamPackage list. + + @param[out] Selector The pointer to the EFI_IPSEC_SPD_SELECTOR structure. + @param[in] ParamPackage The pointer to the ParamPackage list. + @param[in, out] Mask The pointer to the Mask. + + @retval EFI_SUCCESS Fill in EFI_IPSEC_SPD_SELECTOR successfully. + @retval EFI_INVALID_PARAMETER Invalid user input parameter. + +**/ +EFI_STATUS +CreateSpdSelector ( + OUT EFI_IPSEC_SPD_SELECTOR *Selector, + IN LIST_ENTRY *ParamPackage, + IN OUT UINT32 *Mask + ) +{ + EFI_STATUS Status; + EFI_STATUS ReturnStatus; + CONST CHAR16 *ValueStr; + + Status = EFI_SUCCESS; + ReturnStatus = EFI_SUCCESS; + + // + // Convert user imput from string to integer, and fill in the member in EFI_IPSEC_SPD_SELECTOR. + // + ValueStr = ShellCommandLineGetValue (ParamPackage, L"--local"); + if (ValueStr != NULL) { + Selector->LocalAddressCount = 1; + Status = EfiInetAddrRange ((CHAR16 *) ValueStr, Selector->LocalAddress); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE), + mHiiHandle, + mAppName, + L"--local", + ValueStr + ); + ReturnStatus = EFI_INVALID_PARAMETER; + } else { + *Mask |= LOCAL; + } + } + + // + // Convert user imput from string to integer, and fill in the member in EFI_IPSEC_SPD_SELECTOR. + // + ValueStr = ShellCommandLineGetValue (ParamPackage, L"--remote"); + if (ValueStr != NULL) { + Selector->RemoteAddressCount = 1; + Status = EfiInetAddrRange ((CHAR16 *) ValueStr, Selector->RemoteAddress); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE), + mHiiHandle, + mAppName, + L"--remote", + ValueStr + ); + ReturnStatus = EFI_INVALID_PARAMETER; + } else { + *Mask |= REMOTE; + } + } + + Selector->NextLayerProtocol = EFI_IPSEC_ANY_PROTOCOL; + + // + // Convert user imput from string to integer, and fill in the member in EFI_IPSEC_SPD_SELECTOR. + // + Status = GetNumber ( + L"--proto", + (UINT16) -1, + &Selector->NextLayerProtocol, + sizeof (UINT16), + mMapIpProtocol, + ParamPackage, + FORMAT_NUMBER | FORMAT_STRING + ); + if (!EFI_ERROR (Status)) { + *Mask |= PROTO; + } + + if (Status == EFI_INVALID_PARAMETER) { + ReturnStatus = EFI_INVALID_PARAMETER; + } + + Selector->LocalPort = EFI_IPSEC_ANY_PORT; + Selector->RemotePort = EFI_IPSEC_ANY_PORT; + + // + // Convert user imput from string to integer, and fill in the member in EFI_IPSEC_SPD_SELECTOR. + // + ValueStr = ShellCommandLineGetValue (ParamPackage, L"--local-port"); + if (ValueStr != NULL) { + Status = EfiInetPortRange ((CHAR16 *) ValueStr, &Selector->LocalPort, &Selector->LocalPortRange); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE), + mHiiHandle, + mAppName, + L"--local-port", + ValueStr + ); + ReturnStatus = EFI_INVALID_PARAMETER; + } else { + *Mask |= LOCAL_PORT; + } + } + + // + // Convert user imput from string to integer, and fill in the member in EFI_IPSEC_SPD_SELECTOR. + // + ValueStr = ShellCommandLineGetValue (ParamPackage, L"--remote-port"); + if (ValueStr != NULL) { + Status = EfiInetPortRange ((CHAR16 *) ValueStr, &Selector->RemotePort, &Selector->RemotePortRange); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE), + mHiiHandle, + mAppName, + L"--remote-port", + ValueStr + ); + ReturnStatus = EFI_INVALID_PARAMETER; + } else { + *Mask |= REMOTE_PORT; + } + } + + // + // Convert user imput from string to integer, and fill in the member in EFI_IPSEC_SPD_SELECTOR. + // + Status = GetNumber ( + L"--icmp-type", + (UINT8) -1, + &Selector->LocalPort, + sizeof (UINT16), + NULL, + ParamPackage, + FORMAT_NUMBER + ); + if (!EFI_ERROR (Status)) { + *Mask |= ICMP_TYPE; + } + + if (Status == EFI_INVALID_PARAMETER) { + ReturnStatus = EFI_INVALID_PARAMETER; + } + + // + // Convert user imput from string to integer, and fill in the member in EFI_IPSEC_SPD_SELECTOR. + // + Status = GetNumber ( + L"--icmp-code", + (UINT8) -1, + &Selector->RemotePort, + sizeof (UINT16), + NULL, + ParamPackage, + FORMAT_NUMBER + ); + if (!EFI_ERROR (Status)) { + *Mask |= ICMP_CODE; + } + + if (Status == EFI_INVALID_PARAMETER) { + ReturnStatus = EFI_INVALID_PARAMETER; + } + + return ReturnStatus; +} + +/** + Fill in EFI_IPSEC_SPD_SELECTOR and EFI_IPSEC_SPD_DATA through ParamPackage list. + + @param[out] Selector The pointer to the EFI_IPSEC_SPD_SELECTOR structure. + @param[out] Data The pointer to the EFI_IPSEC_SPD_DATA structure. + @param[in] ParamPackage The pointer to the ParamPackage list. + @param[out] Mask The pointer to the Mask. + @param[in] CreateNew The switch to create new. + + @retval EFI_SUCCESS Fill in EFI_IPSEC_SPD_SELECTOR and EFI_IPSEC_SPD_DATA successfully. + @retval EFI_INVALID_PARAMETER Invalid user input parameter. + +**/ +EFI_STATUS +CreateSpdEntry ( + OUT EFI_IPSEC_SPD_SELECTOR **Selector, + OUT EFI_IPSEC_SPD_DATA **Data, + IN LIST_ENTRY *ParamPackage, + OUT UINT32 *Mask, + IN BOOLEAN CreateNew + ) +{ + EFI_STATUS Status; + EFI_STATUS ReturnStatus; + CONST CHAR16 *ValueStr; + UINTN DataSize; + + Status = EFI_SUCCESS; + *Mask = 0; + + *Selector = AllocateZeroPool (sizeof (EFI_IPSEC_SPD_SELECTOR) + 2 * sizeof (EFI_IP_ADDRESS_INFO)); + ASSERT (*Selector != NULL); + + (*Selector)->LocalAddress = (EFI_IP_ADDRESS_INFO *) (*Selector + 1); + (*Selector)->RemoteAddress = (*Selector)->LocalAddress + 1; + + ReturnStatus = CreateSpdSelector (*Selector, ParamPackage, Mask); + + // + // SPD DATA + // NOTE: Allocate enough memory and add padding for different arch. + // + DataSize = ALIGN_VARIABLE (sizeof (EFI_IPSEC_SPD_DATA)); + DataSize = ALIGN_VARIABLE (DataSize + sizeof (EFI_IPSEC_PROCESS_POLICY)); + DataSize += sizeof (EFI_IPSEC_TUNNEL_OPTION); + + *Data = AllocateZeroPool (DataSize); + ASSERT (*Data != NULL); + + (*Data)->ProcessingPolicy = (EFI_IPSEC_PROCESS_POLICY *) ALIGN_POINTER ( + (*Data + 1), + sizeof (UINTN) + ); + (*Data)->ProcessingPolicy->TunnelOption = (EFI_IPSEC_TUNNEL_OPTION *) ALIGN_POINTER ( + ((*Data)->ProcessingPolicy + 1), + sizeof (UINTN) + ); + + + // + // Convert user imput from string to integer, and fill in the Name in EFI_IPSEC_SPD_DATA. + // + ValueStr = ShellCommandLineGetValue (ParamPackage, L"--name"); + if (ValueStr != NULL) { + UnicodeStrToAsciiStrS (ValueStr, (CHAR8 *) (*Data)->Name, sizeof ((*Data)->Name)); + *Mask |= NAME; + } + + // + // Convert user imput from string to integer, and fill in the PackageFlag in EFI_IPSEC_SPD_DATA. + // + Status = GetNumber ( + L"--packet-flag", + (UINT8) -1, + &(*Data)->PackageFlag, + sizeof (UINT32), + NULL, + ParamPackage, + FORMAT_NUMBER + ); + if (!EFI_ERROR (Status)) { + *Mask |= PACKET_FLAG; + } + + if (Status == EFI_INVALID_PARAMETER) { + ReturnStatus = EFI_INVALID_PARAMETER; + } + + // + // Convert user imput from string to integer, and fill in the Action in EFI_IPSEC_SPD_DATA. + // + Status = GetNumber ( + L"--action", + (UINT8) -1, + &(*Data)->Action, + sizeof (UINT32), + mMapIpSecAction, + ParamPackage, + FORMAT_STRING + ); + if (!EFI_ERROR (Status)) { + *Mask |= ACTION; + } + + if (Status == EFI_INVALID_PARAMETER) { + ReturnStatus = EFI_INVALID_PARAMETER; + } + + // + // Convert user imput from string to integer, and fill in the ExtSeqNum in EFI_IPSEC_SPD_DATA. + // + if (ShellCommandLineGetFlag (ParamPackage, L"--ext-sequence")) { + (*Data)->ProcessingPolicy->ExtSeqNum = TRUE; + *Mask |= EXT_SEQUENCE; + } else if (ShellCommandLineGetFlag (ParamPackage, L"--ext-sequence-")) { + (*Data)->ProcessingPolicy->ExtSeqNum = FALSE; + *Mask |= EXT_SEQUENCE; + } + + // + // Convert user imput from string to integer, and fill in the SeqOverflow in EFI_IPSEC_SPD_DATA. + // + if (ShellCommandLineGetFlag (ParamPackage, L"--sequence-overflow")) { + (*Data)->ProcessingPolicy->SeqOverflow = TRUE; + *Mask |= SEQUENCE_OVERFLOW; + } else if (ShellCommandLineGetFlag (ParamPackage, L"--sequence-overflow-")) { + (*Data)->ProcessingPolicy->SeqOverflow = FALSE; + *Mask |= SEQUENCE_OVERFLOW; + } + + // + // Convert user imput from string to integer, and fill in the FragCheck in EFI_IPSEC_SPD_DATA. + // + if (ShellCommandLineGetFlag (ParamPackage, L"--fragment-check")) { + (*Data)->ProcessingPolicy->FragCheck = TRUE; + *Mask |= FRAGMENT_CHECK; + } else if (ShellCommandLineGetFlag (ParamPackage, L"--fragment-check-")) { + (*Data)->ProcessingPolicy->FragCheck = FALSE; + *Mask |= FRAGMENT_CHECK; + } + + // + // Convert user imput from string to integer, and fill in the ProcessingPolicy in EFI_IPSEC_SPD_DATA. + // + Status = GetNumber ( + L"--lifebyte", + (UINT64) -1, + &(*Data)->ProcessingPolicy->SaLifetime.ByteCount, + sizeof (UINT64), + NULL, + ParamPackage, + FORMAT_NUMBER + ); + if (!EFI_ERROR (Status)) { + *Mask |= LIFEBYTE; + } + + if (Status == EFI_INVALID_PARAMETER) { + ReturnStatus = EFI_INVALID_PARAMETER; + } + + Status = GetNumber ( + L"--lifetime", + (UINT64) -1, + &(*Data)->ProcessingPolicy->SaLifetime.HardLifetime, + sizeof (UINT64), + NULL, + ParamPackage, + FORMAT_NUMBER + ); + if (!EFI_ERROR (Status)) { + *Mask |= LIFETIME; + } + if (Status == EFI_INVALID_PARAMETER) { + ReturnStatus = EFI_INVALID_PARAMETER; + } + + Status = GetNumber ( + L"--lifetime-soft", + (UINT64) -1, + &(*Data)->ProcessingPolicy->SaLifetime.SoftLifetime, + sizeof (UINT64), + NULL, + ParamPackage, + FORMAT_NUMBER + ); + if (!EFI_ERROR (Status)) { + *Mask |= LIFETIME_SOFT; + } + + if (Status == EFI_INVALID_PARAMETER) { + ReturnStatus = EFI_INVALID_PARAMETER; + } + + (*Data)->ProcessingPolicy->Mode = EfiIPsecTransport; + Status = GetNumber ( + L"--mode", + 0, + &(*Data)->ProcessingPolicy->Mode, + sizeof (UINT32), + mMapIpSecMode, + ParamPackage, + FORMAT_STRING + ); + if (!EFI_ERROR (Status)) { + *Mask |= MODE; + } + + if (Status == EFI_INVALID_PARAMETER) { + ReturnStatus = EFI_INVALID_PARAMETER; + } + + ValueStr = ShellCommandLineGetValue (ParamPackage, L"--tunnel-local"); + if (ValueStr != NULL) { + Status = EfiInetAddr2 ((CHAR16 *) ValueStr, &(*Data)->ProcessingPolicy->TunnelOption->LocalTunnelAddress); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE), + mHiiHandle, + mAppName, + L"--tunnel-local", + ValueStr + ); + ReturnStatus = EFI_INVALID_PARAMETER; + } else { + *Mask |= TUNNEL_LOCAL; + } + } + + ValueStr = ShellCommandLineGetValue (ParamPackage, L"--tunnel-remote"); + if (ValueStr != NULL) { + Status = EfiInetAddr2 ((CHAR16 *) ValueStr, &(*Data)->ProcessingPolicy->TunnelOption->RemoteTunnelAddress); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE), + mHiiHandle, + mAppName, + L"--tunnel-remote", + ValueStr + ); + ReturnStatus = EFI_INVALID_PARAMETER; + } else { + *Mask |= TUNNEL_REMOTE; + } + } + + (*Data)->ProcessingPolicy->TunnelOption->DF = EfiIPsecTunnelCopyDf; + Status = GetNumber ( + L"--dont-fragment", + 0, + &(*Data)->ProcessingPolicy->TunnelOption->DF, + sizeof (UINT32), + mMapDfOption, + ParamPackage, + FORMAT_STRING + ); + if (!EFI_ERROR (Status)) { + *Mask |= DONT_FRAGMENT; + } + + if (Status == EFI_INVALID_PARAMETER) { + ReturnStatus = EFI_INVALID_PARAMETER; + } + + (*Data)->ProcessingPolicy->Proto = EfiIPsecESP; + Status = GetNumber ( + L"--ipsec-proto", + 0, + &(*Data)->ProcessingPolicy->Proto, + sizeof (UINT32), + mMapIpSecProtocol, + ParamPackage, + FORMAT_STRING + ); + if (!EFI_ERROR (Status)) { + *Mask |= IPSEC_PROTO; + } + + if (Status == EFI_INVALID_PARAMETER) { + ReturnStatus = EFI_INVALID_PARAMETER; + } + + Status = GetNumber ( + L"--encrypt-algo", + 0, + &(*Data)->ProcessingPolicy->EncAlgoId, + sizeof (UINT8), + mMapEncAlgo, + ParamPackage, + FORMAT_STRING + ); + if (!EFI_ERROR (Status)) { + *Mask |= ENCRYPT_ALGO; + } + + if (Status == EFI_INVALID_PARAMETER) { + ReturnStatus = EFI_INVALID_PARAMETER; + } + + Status = GetNumber ( + L"--auth-algo", + 0, + &(*Data)->ProcessingPolicy->AuthAlgoId, + sizeof (UINT8), + mMapAuthAlgo, + ParamPackage, + FORMAT_STRING + ); + if (!EFI_ERROR (Status)) { + *Mask |= AUTH_ALGO; + } + + if (Status == EFI_INVALID_PARAMETER) { + ReturnStatus = EFI_INVALID_PARAMETER; + } + + // + // Cannot check Mode against EfiIPsecTunnel, because user may want to change tunnel_remote only so the Mode is not set. + // + if ((*Mask & (TUNNEL_LOCAL | TUNNEL_REMOTE | DONT_FRAGMENT)) == 0) { + (*Data)->ProcessingPolicy->TunnelOption = NULL; + } + + if ((*Mask & (EXT_SEQUENCE | SEQUENCE_OVERFLOW | FRAGMENT_CHECK | LIFEBYTE | + LIFETIME_SOFT | LIFETIME | MODE | TUNNEL_LOCAL | TUNNEL_REMOTE | + DONT_FRAGMENT | IPSEC_PROTO | AUTH_ALGO | ENCRYPT_ALGO)) == 0) { + if ((*Data)->Action != EfiIPsecActionProtect) { + // + // User may not provide additional parameter for Protect action, so we cannot simply set ProcessingPolicy to NULL. + // + (*Data)->ProcessingPolicy = NULL; + } + } + + if (CreateNew) { + if ((*Mask & (LOCAL | REMOTE | PROTO | ACTION)) != (LOCAL | REMOTE | PROTO | ACTION)) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_ONE_OF_PARAMETERS), + mHiiHandle, + mAppName, + L"--local --remote --proto --action" + ); + ReturnStatus = EFI_INVALID_PARAMETER; + } else if (((*Data)->Action == EfiIPsecActionProtect) && + ((*Data)->ProcessingPolicy->Mode == EfiIPsecTunnel) && + ((*Mask & (TUNNEL_LOCAL | TUNNEL_REMOTE)) != (TUNNEL_LOCAL | TUNNEL_REMOTE))) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_ONE_OF_PARAMETERS), + mHiiHandle, + mAppName, + L"--tunnel-local --tunnel-remote" + ); + ReturnStatus = EFI_INVALID_PARAMETER; + } + } + + return ReturnStatus; +} + +/** + Fill in EFI_IPSEC_SA_ID and EFI_IPSEC_SA_DATA2 through ParamPackage list. + + @param[out] SaId The pointer to the EFI_IPSEC_SA_ID structure. + @param[out] Data The pointer to the EFI_IPSEC_SA_DATA2 structure. + @param[in] ParamPackage The pointer to the ParamPackage list. + @param[out] Mask The pointer to the Mask. + @param[in] CreateNew The switch to create new. + + @retval EFI_SUCCESS Fill in EFI_IPSEC_SA_ID and EFI_IPSEC_SA_DATA2 successfully. + @retval EFI_INVALID_PARAMETER Invalid user input parameter. + +**/ +EFI_STATUS +CreateSadEntry ( + OUT EFI_IPSEC_SA_ID **SaId, + OUT EFI_IPSEC_SA_DATA2 **Data, + IN LIST_ENTRY *ParamPackage, + OUT UINT32 *Mask, + IN BOOLEAN CreateNew + ) +{ + EFI_STATUS Status; + EFI_STATUS ReturnStatus; + UINTN AuthKeyLength; + UINTN EncKeyLength; + CONST CHAR16 *ValueStr; + CHAR8 *AsciiStr; + UINTN DataSize; + + Status = EFI_SUCCESS; + ReturnStatus = EFI_SUCCESS; + *Mask = 0; + AuthKeyLength = 0; + EncKeyLength = 0; + + *SaId = AllocateZeroPool (sizeof (EFI_IPSEC_SA_ID)); + ASSERT (*SaId != NULL); + + // + // Convert user imput from string to integer, and fill in the Spi in EFI_IPSEC_SA_ID. + // + Status = GetNumber (L"--spi", (UINT32) -1, &(*SaId)->Spi, sizeof (UINT32), NULL, ParamPackage, FORMAT_NUMBER); + if (!EFI_ERROR (Status)) { + *Mask |= SPI; + } + + if (Status == EFI_INVALID_PARAMETER) { + ReturnStatus = EFI_INVALID_PARAMETER; + } + + // + // Convert user imput from string to integer, and fill in the Proto in EFI_IPSEC_SA_ID. + // + Status = GetNumber ( + L"--ipsec-proto", + 0, + &(*SaId)->Proto, + sizeof (EFI_IPSEC_PROTOCOL_TYPE), + mMapIpSecProtocol, + ParamPackage, + FORMAT_STRING + ); + if (!EFI_ERROR (Status)) { + *Mask |= IPSEC_PROTO; + } + + if (Status == EFI_INVALID_PARAMETER) { + ReturnStatus = EFI_INVALID_PARAMETER; + } + + // + // Convert user imput from string to integer, and fill in EFI_IPSEC_SA_DATA2. + // + ValueStr = ShellCommandLineGetValue (ParamPackage, L"--auth-key"); + if (ValueStr != NULL) { + AuthKeyLength = StrLen (ValueStr); + } + + ValueStr = ShellCommandLineGetValue (ParamPackage, L"--encrypt-key"); + if (ValueStr != NULL) { + EncKeyLength = StrLen (ValueStr); + } + + // + // EFI_IPSEC_SA_DATA2: + // +------------ + // | EFI_IPSEC_SA_DATA2 + // +----------------------- + // | AuthKey + // +------------------------- + // | EncKey + // +------------------------- + // | SpdSelector + // + // Notes: To make sure the address alignment add padding after each data if needed. + // + DataSize = ALIGN_VARIABLE (sizeof (EFI_IPSEC_SA_DATA2)); + DataSize = ALIGN_VARIABLE (DataSize + AuthKeyLength); + DataSize = ALIGN_VARIABLE (DataSize + EncKeyLength); + DataSize = ALIGN_VARIABLE (DataSize + sizeof (EFI_IPSEC_SPD_SELECTOR)); + DataSize = ALIGN_VARIABLE (DataSize + sizeof (EFI_IP_ADDRESS_INFO)); + DataSize += sizeof (EFI_IP_ADDRESS_INFO); + + + + *Data = AllocateZeroPool (DataSize); + ASSERT (*Data != NULL); + + (*Data)->ManualSet = TRUE; + (*Data)->AlgoInfo.EspAlgoInfo.AuthKey = (VOID *) ALIGN_POINTER (((*Data) + 1), sizeof (UINTN)); + (*Data)->AlgoInfo.EspAlgoInfo.EncKey = (VOID *) ALIGN_POINTER ( + ((UINT8 *) (*Data)->AlgoInfo.EspAlgoInfo.AuthKey + AuthKeyLength), + sizeof (UINTN) + ); + (*Data)->SpdSelector = (EFI_IPSEC_SPD_SELECTOR *) ALIGN_POINTER ( + ((UINT8 *) (*Data)->AlgoInfo.EspAlgoInfo.EncKey + EncKeyLength), + sizeof (UINTN) + ); + (*Data)->SpdSelector->LocalAddress = (EFI_IP_ADDRESS_INFO *) ALIGN_POINTER ( + ((UINT8 *) (*Data)->SpdSelector + sizeof (EFI_IPSEC_SPD_SELECTOR)), + sizeof (UINTN)); + (*Data)->SpdSelector->RemoteAddress = (EFI_IP_ADDRESS_INFO *) ALIGN_POINTER ( + (*Data)->SpdSelector->LocalAddress + 1, + sizeof (UINTN) + ); + + (*Data)->Mode = EfiIPsecTransport; + Status = GetNumber ( + L"--mode", + 0, + &(*Data)->Mode, + sizeof (EFI_IPSEC_MODE), + mMapIpSecMode, + ParamPackage, + FORMAT_STRING + ); + if (!EFI_ERROR (Status)) { + *Mask |= MODE; + } + + if (Status == EFI_INVALID_PARAMETER) { + ReturnStatus = EFI_INVALID_PARAMETER; + } + + // + // According to RFC 4303-3.3.3. The first packet sent using a given SA + // will contain a sequence number of 1. + // + (*Data)->SNCount = 1; + Status = GetNumber ( + L"--sequence-number", + (UINT64) -1, + &(*Data)->SNCount, + sizeof (UINT64), + NULL, + ParamPackage, + FORMAT_NUMBER + ); + if (!EFI_ERROR (Status)) { + *Mask |= SEQUENCE_NUMBER; + } + + if (Status == EFI_INVALID_PARAMETER) { + ReturnStatus = EFI_INVALID_PARAMETER; + } + + (*Data)->AntiReplayWindows = 0; + Status = GetNumber ( + L"--antireplay-window", + (UINT8) -1, + &(*Data)->AntiReplayWindows, + sizeof (UINT8), + NULL, + ParamPackage, + FORMAT_NUMBER + ); + if (!EFI_ERROR (Status)) { + *Mask |= SEQUENCE_NUMBER; + } + + if (Status == EFI_INVALID_PARAMETER) { + ReturnStatus = EFI_INVALID_PARAMETER; + } + + Status = GetNumber ( + L"--encrypt-algo", + 0, + &(*Data)->AlgoInfo.EspAlgoInfo.EncAlgoId, + sizeof (UINT8), + mMapEncAlgo, + ParamPackage, + FORMAT_STRING + ); + if (!EFI_ERROR (Status)) { + *Mask |= ENCRYPT_ALGO; + } + + if (Status == EFI_INVALID_PARAMETER) { + ReturnStatus = EFI_INVALID_PARAMETER; + } + + ValueStr = ShellCommandLineGetValue (ParamPackage, L"--encrypt-key"); + if (ValueStr != NULL ) { + (*Data)->AlgoInfo.EspAlgoInfo.EncKeyLength = EncKeyLength; + AsciiStr = AllocateZeroPool (EncKeyLength + 1); + ASSERT (AsciiStr != NULL); + UnicodeStrToAsciiStrS (ValueStr, AsciiStr, EncKeyLength + 1); + CopyMem ((*Data)->AlgoInfo.EspAlgoInfo.EncKey, AsciiStr, EncKeyLength); + FreePool (AsciiStr); + *Mask |= ENCRYPT_KEY; + } else { + (*Data)->AlgoInfo.EspAlgoInfo.EncKey = NULL; + } + + Status = GetNumber ( + L"--auth-algo", + 0, + &(*Data)->AlgoInfo.EspAlgoInfo.AuthAlgoId, + sizeof (UINT8), + mMapAuthAlgo, + ParamPackage, + FORMAT_STRING + ); + if (!EFI_ERROR (Status)) { + *Mask |= AUTH_ALGO; + } + + if (Status == EFI_INVALID_PARAMETER) { + ReturnStatus = EFI_INVALID_PARAMETER; + } + + ValueStr = ShellCommandLineGetValue (ParamPackage, L"--auth-key"); + if (ValueStr != NULL) { + (*Data)->AlgoInfo.EspAlgoInfo.AuthKeyLength = AuthKeyLength; + AsciiStr = AllocateZeroPool (AuthKeyLength + 1); + ASSERT (AsciiStr != NULL); + UnicodeStrToAsciiStrS (ValueStr, AsciiStr, AuthKeyLength + 1); + CopyMem ((*Data)->AlgoInfo.EspAlgoInfo.AuthKey, AsciiStr, AuthKeyLength); + FreePool (AsciiStr); + *Mask |= AUTH_KEY; + } else { + (*Data)->AlgoInfo.EspAlgoInfo.AuthKey = NULL; + } + + Status = GetNumber ( + L"--lifebyte", + (UINT64) -1, + &(*Data)->SaLifetime.ByteCount, + sizeof (UINT64), + NULL, + ParamPackage, + FORMAT_NUMBER + ); + if (!EFI_ERROR (Status)) { + *Mask |= LIFEBYTE; + } + + if (Status == EFI_INVALID_PARAMETER) { + ReturnStatus = EFI_INVALID_PARAMETER; + } + + Status = GetNumber ( + L"--lifetime", + (UINT64) -1, + &(*Data)->SaLifetime.HardLifetime, + sizeof (UINT64), + NULL, + ParamPackage, + FORMAT_NUMBER + ); + if (!EFI_ERROR (Status)) { + *Mask |= LIFETIME; + } + + if (Status == EFI_INVALID_PARAMETER) { + ReturnStatus = EFI_INVALID_PARAMETER; + } + + Status = GetNumber ( + L"--lifetime-soft", + (UINT64) -1, + &(*Data)->SaLifetime.SoftLifetime, + sizeof (UINT64), + NULL, + ParamPackage, + FORMAT_NUMBER + ); + if (!EFI_ERROR (Status)) { + *Mask |= LIFETIME_SOFT; + } + + if (Status == EFI_INVALID_PARAMETER) { + ReturnStatus = EFI_INVALID_PARAMETER; + } + + Status = GetNumber ( + L"--path-mtu", + (UINT32) -1, + &(*Data)->PathMTU, + sizeof (UINT32), + NULL, + ParamPackage, + FORMAT_NUMBER + ); + if (!EFI_ERROR (Status)) { + *Mask |= PATH_MTU; + } + + if (Status == EFI_INVALID_PARAMETER) { + ReturnStatus = EFI_INVALID_PARAMETER; + } + + // + // Convert user imput from string to integer, and fill in the DestAddress in EFI_IPSEC_SA_ID. + // + ValueStr = ShellCommandLineGetValue (ParamPackage, L"--tunnel-dest"); + if (ValueStr != NULL) { + Status = EfiInetAddr2 ((CHAR16 *) ValueStr, &(*Data)->TunnelDestinationAddress); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE), + mHiiHandle, + mAppName, + L"--tunnel-dest", + ValueStr + ); + ReturnStatus = EFI_INVALID_PARAMETER; + } else { + *Mask |= DEST; + } + } + + // + // Convert user input from string to integer, and fill in the DestAddress in EFI_IPSEC_SA_ID. + // + ValueStr = ShellCommandLineGetValue (ParamPackage, L"--tunnel-source"); + if (ValueStr != NULL) { + Status = EfiInetAddr2 ((CHAR16 *) ValueStr, &(*Data)->TunnelSourceAddress); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE), + mHiiHandle, + mAppName, + L"--tunnel-source", + ValueStr + ); + ReturnStatus = EFI_INVALID_PARAMETER; + } else { + *Mask |= SOURCE; + } + } + + // + // If it is TunnelMode, then check if the tunnel-source and --tunnel-dest are set + // + if ((*Data)->Mode == EfiIPsecTunnel) { + if ((*Mask & (DEST|SOURCE)) != (DEST|SOURCE)) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_ONE_OF_PARAMETERS), + mHiiHandle, + mAppName, + L"--tunnel-source --tunnel-dest" + ); + ReturnStatus = EFI_INVALID_PARAMETER; + } + } + ReturnStatus = CreateSpdSelector ((*Data)->SpdSelector, ParamPackage, Mask); + + if (CreateNew) { + if ((*Mask & (SPI|IPSEC_PROTO|LOCAL|REMOTE)) != (SPI|IPSEC_PROTO|LOCAL|REMOTE)) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_ONE_OF_PARAMETERS), + mHiiHandle, + mAppName, + L"--spi --ipsec-proto --local --remote" + ); + ReturnStatus = EFI_INVALID_PARAMETER; + } else { + if ((*SaId)->Proto == EfiIPsecAH) { + if ((*Mask & AUTH_ALGO) == 0) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_PARAMETER), + mHiiHandle, + mAppName, + L"--auth-algo" + ); + ReturnStatus = EFI_INVALID_PARAMETER; + } else if ((*Data)->AlgoInfo.EspAlgoInfo.AuthAlgoId != IPSEC_AALG_NONE && (*Mask & AUTH_KEY) == 0) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_PARAMETER), + mHiiHandle, + mAppName, + L"--auth-key" + ); + ReturnStatus = EFI_INVALID_PARAMETER; + } + } else { + if ((*Mask & (ENCRYPT_ALGO|AUTH_ALGO)) != (ENCRYPT_ALGO|AUTH_ALGO) ) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_PARAMETER), + mHiiHandle, + mAppName, + L"--encrypt-algo --auth-algo" + ); + ReturnStatus = EFI_INVALID_PARAMETER; + } else if ((*Data)->AlgoInfo.EspAlgoInfo.EncAlgoId != IPSEC_EALG_NONE && (*Mask & ENCRYPT_KEY) == 0) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_PARAMETER), + mHiiHandle, + mAppName, + L"--encrypt-key" + ); + ReturnStatus = EFI_INVALID_PARAMETER; + } else if ((*Data)->AlgoInfo.EspAlgoInfo.AuthAlgoId != IPSEC_AALG_NONE && (*Mask & AUTH_KEY) == 0) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_PARAMETER), + mHiiHandle, + mAppName, + L"--auth-key" + ); + ReturnStatus = EFI_INVALID_PARAMETER; + } + } + } + } + + return ReturnStatus; +} + +/** + Fill in EFI_IPSEC_PAD_ID and EFI_IPSEC_PAD_DATA through ParamPackage list. + + @param[out] PadId The pointer to the EFI_IPSEC_PAD_ID structure. + @param[out] Data The pointer to the EFI_IPSEC_PAD_DATA structure. + @param[in] ParamPackage The pointer to the ParamPackage list. + @param[out] Mask The pointer to the Mask. + @param[in] CreateNew The switch to create new. + + @retval EFI_SUCCESS Fill in EFI_IPSEC_PAD_ID and EFI_IPSEC_PAD_DATA successfully. + @retval EFI_INVALID_PARAMETER Invalid user input parameter. + +**/ +EFI_STATUS +CreatePadEntry ( + OUT EFI_IPSEC_PAD_ID **PadId, + OUT EFI_IPSEC_PAD_DATA **Data, + IN LIST_ENTRY *ParamPackage, + OUT UINT32 *Mask, + IN BOOLEAN CreateNew + ) +{ + EFI_STATUS Status; + EFI_STATUS ReturnStatus; + SHELL_FILE_HANDLE FileHandle; + UINT64 FileSize; + UINTN AuthDataLength; + UINTN RevocationDataLength; + UINTN DataLength; + UINTN Index; + CONST CHAR16 *ValueStr; + UINTN DataSize; + + Status = EFI_SUCCESS; + ReturnStatus = EFI_SUCCESS; + *Mask = 0; + AuthDataLength = 0; + RevocationDataLength = 0; + + *PadId = AllocateZeroPool (sizeof (EFI_IPSEC_PAD_ID)); + ASSERT (*PadId != NULL); + + // + // Convert user imput from string to integer, and fill in EFI_IPSEC_PAD_ID. + // + ValueStr = ShellCommandLineGetValue (ParamPackage, L"--peer-address"); + if (ValueStr != NULL) { + (*PadId)->PeerIdValid = FALSE; + Status = EfiInetAddrRange ((CHAR16 *) ValueStr, &(*PadId)->Id.IpAddress); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE), + mHiiHandle, + mAppName, + L"--peer-address", + ValueStr + ); + ReturnStatus = EFI_INVALID_PARAMETER; + } else { + *Mask |= PEER_ADDRESS; + } + } + + ValueStr = ShellCommandLineGetValue (ParamPackage, L"--peer-id"); + if (ValueStr != NULL) { + (*PadId)->PeerIdValid = TRUE; + StrnCpyS ((CHAR16 *) (*PadId)->Id.PeerId, MAX_PEERID_LEN / sizeof (CHAR16), ValueStr, MAX_PEERID_LEN / sizeof (CHAR16) - 1); + *Mask |= PEER_ID; + } + + ValueStr = ShellCommandLineGetValue (ParamPackage, L"--auth-data"); + if (ValueStr != NULL) { + if (ValueStr[0] == L'@') { + // + // Input is a file: --auth-data "@fs1:\My Certificates\tom.dat" + // + Status = ShellOpenFileByName (&ValueStr[1], &FileHandle, EFI_FILE_MODE_READ, 0); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_IPSEC_CONFIG_FILE_OPEN_FAILED), + mHiiHandle, + mAppName, + &ValueStr[1] + ); + ReturnStatus = EFI_INVALID_PARAMETER; + } else { + Status = ShellGetFileSize (FileHandle, &FileSize); + ShellCloseFile (&FileHandle); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_IPSEC_CONFIG_FILE_OPEN_FAILED), + mHiiHandle, + mAppName, + &ValueStr[1] + ); + ReturnStatus = EFI_INVALID_PARAMETER; + } else { + AuthDataLength = (UINTN) FileSize; + } + } + } else { + AuthDataLength = StrLen (ValueStr); + } + } + + ValueStr = ShellCommandLineGetValue (ParamPackage, L"--revocation-data"); + if (ValueStr != NULL) { + RevocationDataLength = (StrLen (ValueStr) + 1) * sizeof (CHAR16); + } + + // + // Allocate Buffer for Data. Add padding after each struct to make sure the alignment + // in different Arch. + // + DataSize = ALIGN_VARIABLE (sizeof (EFI_IPSEC_PAD_DATA)); + DataSize = ALIGN_VARIABLE (DataSize + AuthDataLength); + DataSize += RevocationDataLength; + + *Data = AllocateZeroPool (DataSize); + ASSERT (*Data != NULL); + + (*Data)->AuthData = (VOID *) ALIGN_POINTER ((*Data + 1), sizeof (UINTN)); + (*Data)->RevocationData = (VOID *) ALIGN_POINTER (((UINT8 *) (*Data + 1) + AuthDataLength), sizeof (UINTN)); + (*Data)->AuthProtocol = EfiIPsecAuthProtocolIKEv1; + + // + // Convert user imput from string to integer, and fill in EFI_IPSEC_PAD_DATA. + // + Status = GetNumber ( + L"--auth-proto", + 0, + &(*Data)->AuthProtocol, + sizeof (EFI_IPSEC_AUTH_PROTOCOL_TYPE), + mMapAuthProto, + ParamPackage, + FORMAT_STRING + ); + if (!EFI_ERROR (Status)) { + *Mask |= AUTH_PROTO; + } + + if (Status == EFI_INVALID_PARAMETER) { + ReturnStatus = EFI_INVALID_PARAMETER; + } + + Status = GetNumber ( + L"--auth-method", + 0, + &(*Data)->AuthMethod, + sizeof (EFI_IPSEC_AUTH_METHOD), + mMapAuthMethod, + ParamPackage, + FORMAT_STRING + ); + if (!EFI_ERROR (Status)) { + *Mask |= AUTH_METHOD; + } + + if (Status == EFI_INVALID_PARAMETER) { + ReturnStatus = EFI_INVALID_PARAMETER; + } + + if (ShellCommandLineGetFlag (ParamPackage, L"--ike-id")) { + (*Data)->IkeIdFlag = TRUE; + *Mask |= IKE_ID; + } + + if (ShellCommandLineGetFlag (ParamPackage, L"--ike-id-")) { + (*Data)->IkeIdFlag = FALSE; + *Mask |= IKE_ID; + } + + ValueStr = ShellCommandLineGetValue (ParamPackage, L"--auth-data"); + if (ValueStr != NULL) { + if (ValueStr[0] == L'@') { + // + // Input is a file: --auth-data "@fs1:\My Certificates\tom.dat" + // + + Status = ShellOpenFileByName (&ValueStr[1], &FileHandle, EFI_FILE_MODE_READ, 0); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_IPSEC_CONFIG_FILE_OPEN_FAILED), + mHiiHandle, + mAppName, + &ValueStr[1] + ); + ReturnStatus = EFI_INVALID_PARAMETER; + (*Data)->AuthData = NULL; + } else { + DataLength = AuthDataLength; + Status = ShellReadFile (FileHandle, &DataLength, (*Data)->AuthData); + ShellCloseFile (&FileHandle); + if (EFI_ERROR (Status)) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_IPSEC_CONFIG_FILE_OPEN_FAILED), + mHiiHandle, + mAppName, + &ValueStr[1] + ); + ReturnStatus = EFI_INVALID_PARAMETER; + (*Data)->AuthData = NULL; + } else { + ASSERT (DataLength == AuthDataLength); + *Mask |= AUTH_DATA; + } + } + } else { + for (Index = 0; Index < AuthDataLength; Index++) { + ((CHAR8 *) (*Data)->AuthData)[Index] = (CHAR8) ValueStr[Index]; + } + (*Data)->AuthDataSize = AuthDataLength; + *Mask |= AUTH_DATA; + } + } + + ValueStr = ShellCommandLineGetValue (ParamPackage, L"--revocation-data"); + if (ValueStr != NULL) { + CopyMem ((*Data)->RevocationData, ValueStr, RevocationDataLength); + (*Data)->RevocationDataSize = RevocationDataLength; + *Mask |= REVOCATION_DATA; + } else { + (*Data)->RevocationData = NULL; + } + + if (CreateNew) { + if ((*Mask & (PEER_ID | PEER_ADDRESS)) == 0) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_ONE_OF_PARAMETERS), + mHiiHandle, + mAppName, + L"--peer-id --peer-address" + ); + ReturnStatus = EFI_INVALID_PARAMETER; + } else if ((*Mask & (AUTH_METHOD | AUTH_DATA)) != (AUTH_METHOD | AUTH_DATA)) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_ONE_OF_PARAMETERS), + mHiiHandle, + mAppName, + L"--auth-method --auth-data" + ); + ReturnStatus = EFI_INVALID_PARAMETER; + } + } + + return ReturnStatus; +} + +CREATE_POLICY_ENTRY mCreatePolicyEntry[] = { + (CREATE_POLICY_ENTRY) CreateSpdEntry, + (CREATE_POLICY_ENTRY) CreateSadEntry, + (CREATE_POLICY_ENTRY) CreatePadEntry +}; + +/** + Combine old SPD entry with new SPD entry. + + @param[in, out] OldSelector The pointer to the EFI_IPSEC_SPD_SELECTOR structure. + @param[in, out] OldData The pointer to the EFI_IPSEC_SPD_DATA structure. + @param[in] NewSelector The pointer to the EFI_IPSEC_SPD_SELECTOR structure. + @param[in] NewData The pointer to the EFI_IPSEC_SPD_DATA structure. + @param[in] Mask The pointer to the Mask. + @param[out] CreateNew The switch to create new. + + @retval EFI_SUCCESS Combined successfully. + @retval EFI_INVALID_PARAMETER Invalid user input parameter. + +**/ +EFI_STATUS +CombineSpdEntry ( + IN OUT EFI_IPSEC_SPD_SELECTOR *OldSelector, + IN OUT EFI_IPSEC_SPD_DATA *OldData, + IN EFI_IPSEC_SPD_SELECTOR *NewSelector, + IN EFI_IPSEC_SPD_DATA *NewData, + IN UINT32 Mask, + OUT BOOLEAN *CreateNew + ) +{ + + // + // Process Selector + // + *CreateNew = FALSE; + if ((Mask & LOCAL) == 0) { + NewSelector->LocalAddressCount = OldSelector->LocalAddressCount; + NewSelector->LocalAddress = OldSelector->LocalAddress; + } else if ((NewSelector->LocalAddressCount != OldSelector->LocalAddressCount) || + (CompareMem (NewSelector->LocalAddress, OldSelector->LocalAddress, NewSelector->LocalAddressCount * sizeof (EFI_IP_ADDRESS_INFO)) != 0)) { + *CreateNew = TRUE; + } + + if ((Mask & REMOTE) == 0) { + NewSelector->RemoteAddressCount = OldSelector->RemoteAddressCount; + NewSelector->RemoteAddress = OldSelector->RemoteAddress; + } else if ((NewSelector->RemoteAddressCount != OldSelector->RemoteAddressCount) || + (CompareMem (NewSelector->RemoteAddress, OldSelector->RemoteAddress, NewSelector->RemoteAddressCount * sizeof (EFI_IP_ADDRESS_INFO)) != 0)) { + *CreateNew = TRUE; + } + + if ((Mask & PROTO) == 0) { + NewSelector->NextLayerProtocol = OldSelector->NextLayerProtocol; + } else if (NewSelector->NextLayerProtocol != OldSelector->NextLayerProtocol) { + *CreateNew = TRUE; + } + + switch (NewSelector->NextLayerProtocol) { + case EFI_IP4_PROTO_TCP: + case EFI_IP4_PROTO_UDP: + if ((Mask & LOCAL_PORT) == 0) { + NewSelector->LocalPort = OldSelector->LocalPort; + NewSelector->LocalPortRange = OldSelector->LocalPortRange; + } else if ((NewSelector->LocalPort != OldSelector->LocalPort) || + (NewSelector->LocalPortRange != OldSelector->LocalPortRange)) { + *CreateNew = TRUE; + } + + if ((Mask & REMOTE_PORT) == 0) { + NewSelector->RemotePort = OldSelector->RemotePort; + NewSelector->RemotePortRange = OldSelector->RemotePortRange; + } else if ((NewSelector->RemotePort != OldSelector->RemotePort) || + (NewSelector->RemotePortRange != OldSelector->RemotePortRange)) { + *CreateNew = TRUE; + } + break; + + case EFI_IP4_PROTO_ICMP: + if ((Mask & ICMP_TYPE) == 0) { + NewSelector->LocalPort = OldSelector->LocalPort; + } else if (NewSelector->LocalPort != OldSelector->LocalPort) { + *CreateNew = TRUE; + } + + if ((Mask & ICMP_CODE) == 0) { + NewSelector->RemotePort = OldSelector->RemotePort; + } else if (NewSelector->RemotePort != OldSelector->RemotePort) { + *CreateNew = TRUE; + } + break; + } + // + // Process Data + // + OldData->SaIdCount = 0; + + if ((Mask & NAME) != 0) { + AsciiStrCpyS ((CHAR8 *) OldData->Name, MAX_PEERID_LEN, (CHAR8 *) NewData->Name); + } + + if ((Mask & PACKET_FLAG) != 0) { + OldData->PackageFlag = NewData->PackageFlag; + } + + if ((Mask & ACTION) != 0) { + OldData->Action = NewData->Action; + } + + if (OldData->Action != EfiIPsecActionProtect) { + OldData->ProcessingPolicy = NULL; + } else { + // + // Protect + // + if (OldData->ProcessingPolicy == NULL) { + // + // Just point to new data if originally NULL. + // + OldData->ProcessingPolicy = NewData->ProcessingPolicy; + if (OldData->ProcessingPolicy->Mode == EfiIPsecTunnel && + (Mask & (TUNNEL_LOCAL | TUNNEL_REMOTE)) != (TUNNEL_LOCAL | TUNNEL_REMOTE) + ) { + // + // Change to Protect action and Tunnel mode, but without providing local/remote tunnel address. + // + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_ONE_OF_PARAMETERS), + mHiiHandle, + mAppName, + L"--tunnel-local --tunnel-remote" + ); + return EFI_INVALID_PARAMETER; + } + } else { + // + // Modify some of the data. + // + if ((Mask & EXT_SEQUENCE) != 0) { + OldData->ProcessingPolicy->ExtSeqNum = NewData->ProcessingPolicy->ExtSeqNum; + } + + if ((Mask & SEQUENCE_OVERFLOW) != 0) { + OldData->ProcessingPolicy->SeqOverflow = NewData->ProcessingPolicy->SeqOverflow; + } + + if ((Mask & FRAGMENT_CHECK) != 0) { + OldData->ProcessingPolicy->FragCheck = NewData->ProcessingPolicy->FragCheck; + } + + if ((Mask & LIFEBYTE) != 0) { + OldData->ProcessingPolicy->SaLifetime.ByteCount = NewData->ProcessingPolicy->SaLifetime.ByteCount; + } + + if ((Mask & LIFETIME_SOFT) != 0) { + OldData->ProcessingPolicy->SaLifetime.SoftLifetime = NewData->ProcessingPolicy->SaLifetime.SoftLifetime; + } + + if ((Mask & LIFETIME) != 0) { + OldData->ProcessingPolicy->SaLifetime.HardLifetime = NewData->ProcessingPolicy->SaLifetime.HardLifetime; + } + + if ((Mask & MODE) != 0) { + OldData->ProcessingPolicy->Mode = NewData->ProcessingPolicy->Mode; + } + + if ((Mask & IPSEC_PROTO) != 0) { + OldData->ProcessingPolicy->Proto = NewData->ProcessingPolicy->Proto; + } + + if ((Mask & AUTH_ALGO) != 0) { + OldData->ProcessingPolicy->AuthAlgoId = NewData->ProcessingPolicy->AuthAlgoId; + } + + if ((Mask & ENCRYPT_ALGO) != 0) { + OldData->ProcessingPolicy->EncAlgoId = NewData->ProcessingPolicy->EncAlgoId; + } + + if (OldData->ProcessingPolicy->Mode != EfiIPsecTunnel) { + OldData->ProcessingPolicy->TunnelOption = NULL; + } else { + if (OldData->ProcessingPolicy->TunnelOption == NULL) { + // + // Set from Transport mode to Tunnel mode, should ensure TUNNEL_LOCAL & TUNNEL_REMOTE both exists. + // + if ((Mask & (TUNNEL_LOCAL | TUNNEL_REMOTE)) != (TUNNEL_LOCAL | TUNNEL_REMOTE)) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_ONE_OF_PARAMETERS), + mHiiHandle, + mAppName, + L"--tunnel-local --tunnel-remote" + ); + return EFI_INVALID_PARAMETER; + } + + OldData->ProcessingPolicy->TunnelOption = NewData->ProcessingPolicy->TunnelOption; + } else { + if ((Mask & TUNNEL_LOCAL) != 0) { + CopyMem ( + &OldData->ProcessingPolicy->TunnelOption->LocalTunnelAddress, + &NewData->ProcessingPolicy->TunnelOption->LocalTunnelAddress, + sizeof (EFI_IP_ADDRESS) + ); + } + + if ((Mask & TUNNEL_REMOTE) != 0) { + CopyMem ( + &OldData->ProcessingPolicy->TunnelOption->RemoteTunnelAddress, + &NewData->ProcessingPolicy->TunnelOption->RemoteTunnelAddress, + sizeof (EFI_IP_ADDRESS) + ); + } + + if ((Mask & DONT_FRAGMENT) != 0) { + OldData->ProcessingPolicy->TunnelOption->DF = NewData->ProcessingPolicy->TunnelOption->DF; + } + } + } + } + } + + return EFI_SUCCESS; +} + +/** + Combine old SAD entry with new SAD entry. + + @param[in, out] OldSaId The pointer to the EFI_IPSEC_SA_ID structure. + @param[in, out] OldData The pointer to the EFI_IPSEC_SA_DATA2 structure. + @param[in] NewSaId The pointer to the EFI_IPSEC_SA_ID structure. + @param[in] NewData The pointer to the EFI_IPSEC_SA_DATA2 structure. + @param[in] Mask The pointer to the Mask. + @param[out] CreateNew The switch to create new. + + @retval EFI_SUCCESS Combined successfully. + @retval EFI_INVALID_PARAMETER Invalid user input parameter. + +**/ +EFI_STATUS +CombineSadEntry ( + IN OUT EFI_IPSEC_SA_ID *OldSaId, + IN OUT EFI_IPSEC_SA_DATA2 *OldData, + IN EFI_IPSEC_SA_ID *NewSaId, + IN EFI_IPSEC_SA_DATA2 *NewData, + IN UINT32 Mask, + OUT BOOLEAN *CreateNew + ) +{ + + *CreateNew = FALSE; + + if ((Mask & SPI) == 0) { + NewSaId->Spi = OldSaId->Spi; + } else if (NewSaId->Spi != OldSaId->Spi) { + *CreateNew = TRUE; + } + + if ((Mask & IPSEC_PROTO) == 0) { + NewSaId->Proto = OldSaId->Proto; + } else if (NewSaId->Proto != OldSaId->Proto) { + *CreateNew = TRUE; + } + + if ((Mask & DEST) == 0) { + CopyMem (&NewData->TunnelDestinationAddress, &OldData->TunnelDestinationAddress, sizeof (EFI_IP_ADDRESS)); + } else if (CompareMem (&NewData->TunnelDestinationAddress, &OldData->TunnelDestinationAddress, sizeof (EFI_IP_ADDRESS)) != 0) { + *CreateNew = TRUE; + } + + if ((Mask & SOURCE) == 0) { + CopyMem (&NewData->TunnelSourceAddress, &OldData->TunnelSourceAddress, sizeof (EFI_IP_ADDRESS)); + } else if (CompareMem (&NewData->TunnelSourceAddress, &OldData->TunnelSourceAddress, sizeof (EFI_IP_ADDRESS)) != 0) { + *CreateNew = TRUE; + } + // + // Process SA_DATA. + // + if ((Mask & MODE) != 0) { + OldData->Mode = NewData->Mode; + } + + if ((Mask & SEQUENCE_NUMBER) != 0) { + OldData->SNCount = NewData->SNCount; + } + + if ((Mask & ANTIREPLAY_WINDOW) != 0) { + OldData->AntiReplayWindows = NewData->AntiReplayWindows; + } + + if ((Mask & AUTH_ALGO) != 0) { + OldData->AlgoInfo.EspAlgoInfo.AuthAlgoId = NewData->AlgoInfo.EspAlgoInfo.AuthAlgoId; + } + + if ((Mask & AUTH_KEY) != 0) { + OldData->AlgoInfo.EspAlgoInfo.AuthKey = NewData->AlgoInfo.EspAlgoInfo.AuthKey; + OldData->AlgoInfo.EspAlgoInfo.AuthKeyLength = NewData->AlgoInfo.EspAlgoInfo.AuthKeyLength; + } + + if ((Mask & ENCRYPT_ALGO) != 0) { + OldData->AlgoInfo.EspAlgoInfo.EncAlgoId = NewData->AlgoInfo.EspAlgoInfo.EncAlgoId; + } + + if ((Mask & ENCRYPT_KEY) != 0) { + OldData->AlgoInfo.EspAlgoInfo.EncKey = NewData->AlgoInfo.EspAlgoInfo.EncKey; + OldData->AlgoInfo.EspAlgoInfo.EncKeyLength = NewData->AlgoInfo.EspAlgoInfo.EncKeyLength; + } + + if (NewSaId->Proto == EfiIPsecAH) { + if ((Mask & (ENCRYPT_ALGO | ENCRYPT_KEY)) != 0) { + // + // Should not provide encrypt_* if AH. + // + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_IPSEC_CONFIG_UNWANTED_PARAMETER), + mHiiHandle, + mAppName, + L"--encrypt-algo --encrypt-key" + ); + return EFI_INVALID_PARAMETER; + } + } + + if (NewSaId->Proto == EfiIPsecESP && OldSaId->Proto == EfiIPsecAH) { + // + // AH -> ESP + // Should provide encrypt_algo at least. + // + if ((Mask & ENCRYPT_ALGO) == 0) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_PARAMETER), + mHiiHandle, + mAppName, + L"--encrypt-algo" + ); + return EFI_INVALID_PARAMETER; + } + + // + // Encrypt_key should be provided if algorithm is not NONE. + // + if (NewData->AlgoInfo.EspAlgoInfo.EncAlgoId != IPSEC_EALG_NONE && (Mask & ENCRYPT_KEY) == 0) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_PARAMETER), + mHiiHandle, + mAppName, + L"--encrypt-algo" + ); + return EFI_INVALID_PARAMETER; + } + } + + if ((Mask & LIFEBYTE) != 0) { + OldData->SaLifetime.ByteCount = NewData->SaLifetime.ByteCount; + } + + if ((Mask & LIFETIME_SOFT) != 0) { + OldData->SaLifetime.SoftLifetime = NewData->SaLifetime.SoftLifetime; + } + + if ((Mask & LIFETIME) != 0) { + OldData->SaLifetime.HardLifetime = NewData->SaLifetime.HardLifetime; + } + + if ((Mask & PATH_MTU) != 0) { + OldData->PathMTU = NewData->PathMTU; + } + // + // Process SpdSelector. + // + if (OldData->SpdSelector == NULL) { + if ((Mask & (LOCAL | REMOTE | PROTO | LOCAL_PORT | REMOTE_PORT | ICMP_TYPE | ICMP_CODE)) != 0) { + if ((Mask & (LOCAL | REMOTE | PROTO)) != (LOCAL | REMOTE | PROTO)) { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_IPSEC_CONFIG_MISSING_ONE_OF_PARAMETERS), + mHiiHandle, + mAppName, + L"--local --remote --proto" + ); + return EFI_INVALID_PARAMETER; + } + + OldData->SpdSelector = NewData->SpdSelector; + } + } else { + if ((Mask & LOCAL) != 0) { + OldData->SpdSelector->LocalAddressCount = NewData->SpdSelector->LocalAddressCount; + OldData->SpdSelector->LocalAddress = NewData->SpdSelector->LocalAddress; + } + + if ((Mask & REMOTE) != 0) { + OldData->SpdSelector->RemoteAddressCount = NewData->SpdSelector->RemoteAddressCount; + OldData->SpdSelector->RemoteAddress = NewData->SpdSelector->RemoteAddress; + } + + if ((Mask & PROTO) != 0) { + OldData->SpdSelector->NextLayerProtocol = NewData->SpdSelector->NextLayerProtocol; + } + + if (OldData->SpdSelector != NULL) { + switch (OldData->SpdSelector->NextLayerProtocol) { + case EFI_IP4_PROTO_TCP: + case EFI_IP4_PROTO_UDP: + if ((Mask & LOCAL_PORT) != 0) { + OldData->SpdSelector->LocalPort = NewData->SpdSelector->LocalPort; + } + + if ((Mask & REMOTE_PORT) != 0) { + OldData->SpdSelector->RemotePort = NewData->SpdSelector->RemotePort; + } + break; + + case EFI_IP4_PROTO_ICMP: + if ((Mask & ICMP_TYPE) != 0) { + OldData->SpdSelector->LocalPort = (UINT8) NewData->SpdSelector->LocalPort; + } + + if ((Mask & ICMP_CODE) != 0) { + OldData->SpdSelector->RemotePort = (UINT8) NewData->SpdSelector->RemotePort; + } + break; + } + } + } + + return EFI_SUCCESS; +} + +/** + Combine old PAD entry with new PAD entry. + + @param[in, out] OldPadId The pointer to the EFI_IPSEC_PAD_ID structure. + @param[in, out] OldData The pointer to the EFI_IPSEC_PAD_DATA structure. + @param[in] NewPadId The pointer to the EFI_IPSEC_PAD_ID structure. + @param[in] NewData The pointer to the EFI_IPSEC_PAD_DATA structure. + @param[in] Mask The pointer to the Mask. + @param[out] CreateNew The switch to create new. + + @retval EFI_SUCCESS Combined successfully. + @retval EFI_INVALID_PARAMETER Invalid user input parameter. + +**/ +EFI_STATUS +CombinePadEntry ( + IN OUT EFI_IPSEC_PAD_ID *OldPadId, + IN OUT EFI_IPSEC_PAD_DATA *OldData, + IN EFI_IPSEC_PAD_ID *NewPadId, + IN EFI_IPSEC_PAD_DATA *NewData, + IN UINT32 Mask, + OUT BOOLEAN *CreateNew + ) +{ + + *CreateNew = FALSE; + + if ((Mask & (PEER_ID | PEER_ADDRESS)) == 0) { + CopyMem (NewPadId, OldPadId, sizeof (EFI_IPSEC_PAD_ID)); + } else { + if ((Mask & PEER_ID) != 0) { + if (OldPadId->PeerIdValid) { + if (StrCmp ((CONST CHAR16 *) OldPadId->Id.PeerId, (CONST CHAR16 *) NewPadId->Id.PeerId) != 0) { + *CreateNew = TRUE; + } + } else { + *CreateNew = TRUE; + } + } else { + // + // MASK & PEER_ADDRESS + // + if (OldPadId->PeerIdValid) { + *CreateNew = TRUE; + } else { + if ((CompareMem (&OldPadId->Id.IpAddress.Address, &NewPadId->Id.IpAddress.Address, sizeof (EFI_IP_ADDRESS)) != 0) || + (OldPadId->Id.IpAddress.PrefixLength != NewPadId->Id.IpAddress.PrefixLength)) { + *CreateNew = TRUE; + } + } + } + } + + if ((Mask & AUTH_PROTO) != 0) { + OldData->AuthProtocol = NewData->AuthProtocol; + } + + if ((Mask & AUTH_METHOD) != 0) { + OldData->AuthMethod = NewData->AuthMethod; + } + + if ((Mask & IKE_ID) != 0) { + OldData->IkeIdFlag = NewData->IkeIdFlag; + } + + if ((Mask & AUTH_DATA) != 0) { + OldData->AuthDataSize = NewData->AuthDataSize; + OldData->AuthData = NewData->AuthData; + } + + if ((Mask & REVOCATION_DATA) != 0) { + OldData->RevocationDataSize = NewData->RevocationDataSize; + OldData->RevocationData = NewData->RevocationData; + } + + return EFI_SUCCESS; +} + +COMBINE_POLICY_ENTRY mCombinePolicyEntry[] = { + (COMBINE_POLICY_ENTRY) CombineSpdEntry, + (COMBINE_POLICY_ENTRY) CombineSadEntry, + (COMBINE_POLICY_ENTRY) CombinePadEntry +}; + +/** + Edit entry information in the database. + + @param[in] Selector The pointer to the EFI_IPSEC_CONFIG_SELECTOR structure. + @param[in] Data The pointer to the data. + @param[in] Context The pointer to the INSERT_POLICY_ENTRY_CONTEXT structure. + + @retval EFI_SUCCESS Continue the iteration. + @retval EFI_ABORTED Abort the iteration. +**/ +EFI_STATUS +EditOperatePolicyEntry ( + IN EFI_IPSEC_CONFIG_SELECTOR *Selector, + IN VOID *Data, + IN EDIT_POLICY_ENTRY_CONTEXT *Context + ) +{ + EFI_STATUS Status; + BOOLEAN CreateNew; + + if (mMatchPolicyEntry[Context->DataType] (Selector, Data, &Context->Indexer)) { + ASSERT (Context->DataType < 3); + + Status = mCombinePolicyEntry[Context->DataType] ( + Selector, + Data, + Context->Selector, + Context->Data, + Context->Mask, + &CreateNew + ); + if (!EFI_ERROR (Status)) { + // + // If the Selector already existed, this Entry will be updated by set data. + // + Status = mIpSecConfig->SetData ( + mIpSecConfig, + Context->DataType, + Context->Selector, /// New created selector. + Data, /// Old date which has been modified, need to be set data. + Selector + ); + ASSERT_EFI_ERROR (Status); + + if (CreateNew) { + // + // Edit the entry to a new one. So, we need delete the old entry. + // + Status = mIpSecConfig->SetData ( + mIpSecConfig, + Context->DataType, + Selector, /// Old selector. + NULL, /// NULL means to delete this Entry specified by Selector. + NULL + ); + ASSERT_EFI_ERROR (Status); + } + } + + Context->Status = Status; + return EFI_ABORTED; + } + + return EFI_SUCCESS; +} + +/** + Edit entry information in database according to datatype. + + @param[in] DataType The value of EFI_IPSEC_CONFIG_DATA_TYPE. + @param[in] ParamPackage The pointer to the ParamPackage list. + + @retval EFI_SUCCESS Edit entry information successfully. + @retval EFI_NOT_FOUND Can't find the specified entry. + @retval Others Some mistaken case. +**/ +EFI_STATUS +EditPolicyEntry ( + IN EFI_IPSEC_CONFIG_DATA_TYPE DataType, + IN LIST_ENTRY *ParamPackage + ) +{ + EFI_STATUS Status; + EDIT_POLICY_ENTRY_CONTEXT Context; + CONST CHAR16 *ValueStr; + + ValueStr = ShellCommandLineGetValue (ParamPackage, L"-e"); + if (ValueStr == NULL) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_INDEX_NOT_SPECIFIED), mHiiHandle, mAppName, ValueStr); + return EFI_NOT_FOUND; + } + + Status = mConstructPolicyEntryIndexer[DataType] (&Context.Indexer, ParamPackage); + if (!EFI_ERROR (Status)) { + Context.DataType = DataType; + Context.Status = EFI_NOT_FOUND; + Status = mCreatePolicyEntry[DataType] (&Context.Selector, &Context.Data, ParamPackage, &Context.Mask, FALSE); + if (!EFI_ERROR (Status)) { + ForeachPolicyEntry (DataType, (VISIT_POLICY_ENTRY) EditOperatePolicyEntry, &Context); + Status = Context.Status; + } + + if (Context.Selector != NULL) { + gBS->FreePool (Context.Selector); + } + + if (Context.Data != NULL) { + gBS->FreePool (Context.Data); + } + } + + if (Status == EFI_NOT_FOUND) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_INDEX_NOT_FOUND), mHiiHandle, mAppName, ValueStr); + } else if (EFI_ERROR (Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_EDIT_FAILED), mHiiHandle, mAppName); + } + + return Status; + +} + +/** + Insert entry information in database. + + @param[in] Selector The pointer to the EFI_IPSEC_CONFIG_SELECTOR structure. + @param[in] Data The pointer to the data. + @param[in] Context The pointer to the INSERT_POLICY_ENTRY_CONTEXT structure. + + @retval EFI_SUCCESS Continue the iteration. + @retval EFI_ABORTED Abort the iteration. +**/ +EFI_STATUS +InsertPolicyEntry ( + IN EFI_IPSEC_CONFIG_SELECTOR *Selector, + IN VOID *Data, + IN INSERT_POLICY_ENTRY_CONTEXT *Context + ) +{ + // + // Found the entry which we want to insert before. + // + if (mMatchPolicyEntry[Context->DataType] (Selector, Data, &Context->Indexer)) { + + Context->Status = mIpSecConfig->SetData ( + mIpSecConfig, + Context->DataType, + Context->Selector, + Context->Data, + Selector + ); + // + // Abort the iteration after the insertion. + // + return EFI_ABORTED; + } + + return EFI_SUCCESS; +} + +/** + Insert or add entry information in database according to datatype. + + @param[in] DataType The value of EFI_IPSEC_CONFIG_DATA_TYPE. + @param[in] ParamPackage The pointer to the ParamPackage list. + + @retval EFI_SUCCESS Insert or add entry information successfully. + @retval EFI_NOT_FOUND Can't find the specified entry. + @retval EFI_BUFFER_TOO_SMALL The entry already existed. + @retval EFI_UNSUPPORTED The operation is not supported. + @retval Others Some mistaken case. +**/ +EFI_STATUS +AddOrInsertPolicyEntry ( + IN EFI_IPSEC_CONFIG_DATA_TYPE DataType, + IN LIST_ENTRY *ParamPackage + ) +{ + EFI_STATUS Status; + EFI_IPSEC_CONFIG_SELECTOR *Selector; + VOID *Data; + INSERT_POLICY_ENTRY_CONTEXT Context; + UINT32 Mask; + UINTN DataSize; + CONST CHAR16 *ValueStr; + + Status = mCreatePolicyEntry[DataType] (&Selector, &Data, ParamPackage, &Mask, TRUE); + if (!EFI_ERROR (Status)) { + // + // Find if the Selector to be inserted already exists. + // + DataSize = 0; + Status = mIpSecConfig->GetData ( + mIpSecConfig, + DataType, + Selector, + &DataSize, + NULL + ); + if (Status == EFI_BUFFER_TOO_SMALL) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_ALREADY_EXISTS), mHiiHandle, mAppName); + } else if (ShellCommandLineGetFlag (ParamPackage, L"-a")) { + Status = mIpSecConfig->SetData ( + mIpSecConfig, + DataType, + Selector, + Data, + NULL + ); + } else { + ValueStr = ShellCommandLineGetValue (ParamPackage, L"-i"); + if (ValueStr == NULL) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_INDEX_NOT_SPECIFIED), mHiiHandle, mAppName, ValueStr); + return EFI_NOT_FOUND; + } + + Status = mConstructPolicyEntryIndexer[DataType] (&Context.Indexer, ParamPackage); + if (!EFI_ERROR (Status)) { + Context.DataType = DataType; + Context.Status = EFI_NOT_FOUND; + Context.Selector = Selector; + Context.Data = Data; + + ForeachPolicyEntry (DataType, (VISIT_POLICY_ENTRY) InsertPolicyEntry, &Context); + Status = Context.Status; + if (Status == EFI_NOT_FOUND) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_INDEX_NOT_FOUND), mHiiHandle, mAppName, ValueStr); + } + } + } + + gBS->FreePool (Selector); + gBS->FreePool (Data); + } + + if (Status == EFI_UNSUPPORTED) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_INSERT_UNSUPPORT), mHiiHandle, mAppName); + } else if (EFI_ERROR (Status)) { + ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_INSERT_FAILED), mHiiHandle, mAppName); + } + + return Status; +} diff --git a/Core/NetworkPkg/Application/IpsecConfig/PolicyEntryOperation.h b/Core/NetworkPkg/Application/IpsecConfig/PolicyEntryOperation.h new file mode 100644 index 0000000000..4514d2f8d2 --- /dev/null +++ b/Core/NetworkPkg/Application/IpsecConfig/PolicyEntryOperation.h @@ -0,0 +1,159 @@ +/** @file + The function declaration of policy entry operation in IpSecConfig application. + + Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _POLICY_ENTRY_OPERATION_H_ +#define _POLICY_ENTRY_OPERATION_H_ + +#define LOCAL BIT(0) +#define REMOTE BIT(1) +#define PROTO BIT(2) +#define LOCAL_PORT BIT(3) +#define REMOTE_PORT BIT(4) +#define ICMP_TYPE BIT(5) +#define ICMP_CODE BIT(6) +#define NAME BIT(7) +#define PACKET_FLAG BIT(8) +#define ACTION BIT(9) +#define EXT_SEQUENCE BIT(10) +#define SEQUENCE_OVERFLOW BIT(11) +#define FRAGMENT_CHECK BIT(12) +#define LIFEBYTE BIT(13) +#define LIFETIME_SOFT BIT(14) +#define LIFETIME BIT(15) +#define MODE BIT(16) +#define TUNNEL_LOCAL BIT(17) +#define TUNNEL_REMOTE BIT(18) +#define DONT_FRAGMENT BIT(19) +#define IPSEC_PROTO BIT(20) +#define AUTH_ALGO BIT(21) +#define ENCRYPT_ALGO BIT(22) +#define SPI BIT(23) +#define DEST BIT(24) +#define SEQUENCE_NUMBER BIT(25) +#define ANTIREPLAY_WINDOW BIT(26) +#define AUTH_KEY BIT(27) +#define ENCRYPT_KEY BIT(28) +#define PATH_MTU BIT(29) +#define SOURCE BIT(30) + +#define PEER_ID BIT(0) +#define PEER_ADDRESS BIT(1) +#define AUTH_PROTO BIT(2) +#define AUTH_METHOD BIT(3) +#define IKE_ID BIT(4) +#define AUTH_DATA BIT(5) +#define REVOCATION_DATA BIT(6) + +typedef struct { + EFI_IPSEC_CONFIG_DATA_TYPE DataType; + EFI_IPSEC_CONFIG_SELECTOR *Selector; // Data to be inserted. + VOID *Data; + UINT32 Mask; + POLICY_ENTRY_INDEXER Indexer; + EFI_STATUS Status; // Indicate whether insertion succeeds. +} EDIT_POLICY_ENTRY_CONTEXT; + +typedef struct { + EFI_IPSEC_CONFIG_DATA_TYPE DataType; + EFI_IPSEC_CONFIG_SELECTOR *Selector; // Data to be inserted. + VOID *Data; + POLICY_ENTRY_INDEXER Indexer; + EFI_STATUS Status; // Indicate whether insertion succeeds. +} INSERT_POLICY_ENTRY_CONTEXT; + +/** + The prototype for the CreateSpdEntry()/CreateSadEntry()/CreatePadEntry(). + Fill in EFI_IPSEC_CONFIG_SELECTOR and corresponding data thru ParamPackage list. + + @param[out] Selector The pointer to the EFI_IPSEC_CONFIG_SELECTOR union. + @param[out] Data The pointer to corresponding data. + @param[in] ParamPackage The pointer to the ParamPackage list. + @param[out] Mask The pointer to the Mask. + @param[in] CreateNew The switch to create new. + + @retval EFI_SUCCESS Filled in EFI_IPSEC_CONFIG_SELECTOR and corresponding data successfully. + @retval EFI_INVALID_PARAMETER Invalid user input parameter. + +**/ +typedef +EFI_STATUS +(*CREATE_POLICY_ENTRY) ( + OUT EFI_IPSEC_CONFIG_SELECTOR **Selector, + OUT VOID **Data, + IN LIST_ENTRY *ParamPackage, + OUT UINT32 *Mask, + IN BOOLEAN CreateNew + ); + +/** + The prototype for the CombineSpdEntry()/CombineSadEntry()/CombinePadEntry(). + Combine old SPD/SAD/PAD entry with new SPD/SAD/PAD entry. + + @param[in, out] OldSelector The pointer to the old EFI_IPSEC_CONFIG_SELECTOR union. + @param[in, out] OldData The pointer to the corresponding old data. + @param[in] NewSelector The pointer to the new EFI_IPSEC_CONFIG_SELECTOR union. + @param[in] NewData The pointer to the corresponding new data. + @param[in] Mask The pointer to the Mask. + @param[out] CreateNew The switch to create new. + + @retval EFI_SUCCESS Combined successfully. + @retval EFI_INVALID_PARAMETER Invalid user input parameter. + +**/ +typedef +EFI_STATUS +(* COMBINE_POLICY_ENTRY) ( + IN OUT EFI_IPSEC_CONFIG_SELECTOR *OldSelector, + IN OUT VOID *OldData, + IN EFI_IPSEC_CONFIG_SELECTOR *NewSelector, + IN VOID *NewData, + IN UINT32 Mask, + OUT BOOLEAN *CreateNew + ); + +/** + Insert or add entry information in database according to datatype. + + @param[in] DataType The value of EFI_IPSEC_CONFIG_DATA_TYPE. + @param[in] ParamPackage The pointer to the ParamPackage list. + + @retval EFI_SUCCESS Insert or add entry information successfully. + @retval EFI_NOT_FOUND Can't find the specified entry. + @retval EFI_BUFFER_TOO_SMALL The entry already existed. + @retval EFI_UNSUPPORTED The operation is not supported./ + @retval Others Some mistaken case. +**/ +EFI_STATUS +AddOrInsertPolicyEntry ( + IN EFI_IPSEC_CONFIG_DATA_TYPE DataType, + IN LIST_ENTRY *ParamPackage + ); + +/** + Edit entry information in the database according to datatype. + + @param[in] DataType The value of EFI_IPSEC_CONFIG_DATA_TYPE. + @param[in] ParamPackage The pointer to the ParamPackage list. + + @retval EFI_SUCCESS Edit entry information successfully. + @retval EFI_NOT_FOUND Can't find the specified entry. + @retval Others Some mistaken case. +**/ +EFI_STATUS +EditPolicyEntry ( + IN EFI_IPSEC_CONFIG_DATA_TYPE DataType, + IN LIST_ENTRY *ParamPackage + ); +#endif -- cgit v1.2.3