/** @file\r
The implementation of IPSEC_CONFIG_PROTOCOL.\r
\r
- Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>\r
\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
BOOLEAN mSetBySelf = FALSE;\r
\r
//\r
-// Common CompareSelector routine entry for spd/sad/pad.\r
+// Common CompareSelector routine entry for SPD/SAD/PAD.\r
//\r
IPSEC_COMPARE_SELECTOR mCompareSelector[] = {\r
(IPSEC_COMPARE_SELECTOR) CompareSpdSelector,\r
};\r
\r
//\r
-// Common IsZeroSelector routine entry for spd/sad/pad.\r
+// Common IsZeroSelector routine entry for SPD/SAD/PAD.\r
//\r
IPSEC_IS_ZERO_SELECTOR mIsZeroSelector[] = {\r
(IPSEC_IS_ZERO_SELECTOR) IsZeroSpdSelector,\r
};\r
\r
//\r
-// Common DuplicateSelector routine entry for spd/sad/pad.\r
+// Common DuplicateSelector routine entry for SPD/SAD/PAD.\r
//\r
IPSEC_DUPLICATE_SELECTOR mDuplicateSelector[] = {\r
(IPSEC_DUPLICATE_SELECTOR) DuplicateSpdSelector,\r
};\r
\r
//\r
-// Common FixPolicyEntry routine entry for spd/sad/pad.\r
+// Common FixPolicyEntry routine entry for SPD/SAD/PAD.\r
//\r
IPSEC_FIX_POLICY_ENTRY mFixPolicyEntry[] = {\r
(IPSEC_FIX_POLICY_ENTRY) FixSpdEntry,\r
};\r
\r
//\r
-// Common UnfixPolicyEntry routine entry for spd/sad/pad.\r
+// Common UnfixPolicyEntry routine entry for SPD/SAD/PAD.\r
//\r
IPSEC_FIX_POLICY_ENTRY mUnfixPolicyEntry[] = {\r
(IPSEC_FIX_POLICY_ENTRY) UnfixSpdEntry,\r
};\r
\r
//\r
-// Common SetPolicyEntry routine entry for spd/sad/pad.\r
+// Common SetPolicyEntry routine entry for SPD/SAD/PAD.\r
//\r
IPSEC_SET_POLICY_ENTRY mSetPolicyEntry[] = {\r
(IPSEC_SET_POLICY_ENTRY) SetSpdEntry,\r
};\r
\r
//\r
-// Common GetPolicyEntry routine entry for spd/sad/pad.\r
+// Common GetPolicyEntry routine entry for SPD/SAD/PAD.\r
//\r
IPSEC_GET_POLICY_ENTRY mGetPolicyEntry[] = {\r
(IPSEC_GET_POLICY_ENTRY) GetSpdEntry,\r
IN UINT32 AddressCount\r
)\r
{\r
- UINT8 Index;\r
+ UINT8 Index;\r
+ EFI_IP_ADDRESS ZeroAddress;\r
\r
+ ZeroMem(&ZeroAddress, sizeof (EFI_IP_ADDRESS));\r
+\r
+ //\r
+ // Zero Address means any address is matched.\r
+ //\r
+ if (AddressCount == 1) {\r
+ if (CompareMem (\r
+ &AddressInfoList[0].Address,\r
+ &ZeroAddress,\r
+ sizeof (EFI_IP_ADDRESS)\r
+ ) == 0) {\r
+ return TRUE;\r
+ }\r
+ }\r
for (Index = 0; Index < AddressCount ; Index++) {\r
if (CompareMem (\r
AddressInfo,\r
}\r
\r
//\r
- // Compare the all LocalAddress fields in the two Spdselectors.\r
+ // Compare the all LocalAddress and RemoteAddress fields in the two Spdselectors.\r
// First, SpdSel1->LocalAddress to SpdSel2->LocalAddress && Compare\r
// SpdSel1->RemoteAddress to SpdSel2->RemoteAddress. If all match, return\r
// TRUE.\r
return IsMatch;\r
}\r
\r
+/**\r
+ Find if the two SPD Selectors has subordinative.\r
+\r
+ Compare two SPD Selector by the fields of LocalAddressCount/RemoteAddressCount/\r
+ NextLayerProtocol/LocalPort/LocalPortRange/RemotePort/RemotePortRange and the\r
+ Local Addresses and remote Addresses.\r
+\r
+ @param[in] Selector1 Pointer of first SPD Selector.\r
+ @param[in] Selector2 Pointer of second SPD Selector.\r
+\r
+ @retval TRUE The first SPD Selector is subordinate Selector of second SPD Selector.\r
+ @retval FALSE The first SPD Selector is not subordinate Selector of second\r
+ SPD Selector.\r
+\r
+**/\r
+BOOLEAN\r
+IsSubSpdSelector (\r
+ IN EFI_IPSEC_CONFIG_SELECTOR *Selector1,\r
+ IN EFI_IPSEC_CONFIG_SELECTOR *Selector2\r
+ )\r
+{\r
+ EFI_IPSEC_SPD_SELECTOR *SpdSel1;\r
+ EFI_IPSEC_SPD_SELECTOR *SpdSel2;\r
+ BOOLEAN IsMatch;\r
+ UINTN Index;\r
+\r
+ SpdSel1 = &Selector1->SpdSelector;\r
+ SpdSel2 = &Selector2->SpdSelector;\r
+ IsMatch = TRUE;\r
+\r
+ //\r
+ // Compare the LocalAddressCount/RemoteAddressCount/NextLayerProtocol/\r
+ // LocalPort/LocalPortRange/RemotePort/RemotePortRange fields in the\r
+ // two Spdselectors. Since the SPD supports two directions, it needs to\r
+ // compare two directions.\r
+ //\r
+ if (SpdSel1->LocalAddressCount > SpdSel2->LocalAddressCount ||\r
+ SpdSel1->RemoteAddressCount > SpdSel2->RemoteAddressCount ||\r
+ (SpdSel1->NextLayerProtocol != SpdSel2->NextLayerProtocol && SpdSel2->NextLayerProtocol != 0xffff) ||\r
+ (SpdSel1->LocalPort > SpdSel2->LocalPort && SpdSel2->LocalPort != 0)||\r
+ (SpdSel1->LocalPortRange > SpdSel2->LocalPortRange && SpdSel1->LocalPort != 0)||\r
+ (SpdSel1->RemotePort > SpdSel2->RemotePort && SpdSel2->RemotePort != 0) ||\r
+ (SpdSel1->RemotePortRange > SpdSel2->RemotePortRange && SpdSel2->RemotePort != 0)\r
+ ) {\r
+ IsMatch = FALSE;\r
+ }\r
+\r
+ //\r
+ // Compare the all LocalAddress and RemoteAddress fields in the two Spdselectors.\r
+ // First, SpdSel1->LocalAddress to SpdSel2->LocalAddress && Compare\r
+ // SpdSel1->RemoteAddress to SpdSel2->RemoteAddress. If all match, return\r
+ // TRUE.\r
+ //\r
+ if (IsMatch) {\r
+ for (Index = 0; Index < SpdSel1->LocalAddressCount; Index++) {\r
+ if (!IsInAddressInfoList (\r
+ &SpdSel1->LocalAddress[Index],\r
+ SpdSel2->LocalAddress,\r
+ SpdSel2->LocalAddressCount\r
+ )) {\r
+ IsMatch = FALSE;\r
+ break;\r
+ }\r
+ }\r
+\r
+ if (IsMatch) {\r
+ for (Index = 0; Index < SpdSel1->RemoteAddressCount; Index++) {\r
+ if (!IsInAddressInfoList (\r
+ &SpdSel1->RemoteAddress[Index],\r
+ SpdSel2->RemoteAddress,\r
+ SpdSel2->RemoteAddressCount\r
+ )) {\r
+ IsMatch = FALSE;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ if (IsMatch) {\r
+ return IsMatch;\r
+ }\r
+\r
+ //\r
+ //\r
+ // The SPD selector in SPD entry is two way.\r
+ //\r
+ // Compare the LocalAddressCount/RemoteAddressCount/NextLayerProtocol/\r
+ // LocalPort/LocalPortRange/RemotePort/RemotePortRange fields in the\r
+ // two Spdselectors. Since the SPD supports two directions, it needs to\r
+ // compare two directions.\r
+ //\r
+ IsMatch = TRUE;\r
+ if (SpdSel1->LocalAddressCount > SpdSel2->RemoteAddressCount ||\r
+ SpdSel1->RemoteAddressCount > SpdSel2->LocalAddressCount ||\r
+ (SpdSel1->NextLayerProtocol != SpdSel2->NextLayerProtocol && SpdSel2->NextLayerProtocol != 0xffff) ||\r
+ (SpdSel1->LocalPort > SpdSel2->RemotePort && SpdSel2->RemotePort != 0)||\r
+ (SpdSel1->LocalPortRange > SpdSel2->RemotePortRange && SpdSel1->RemotePort != 0)||\r
+ (SpdSel1->RemotePort > SpdSel2->LocalPort && SpdSel2->LocalPort != 0) ||\r
+ (SpdSel1->RemotePortRange > SpdSel2->LocalPortRange && SpdSel2->LocalPort != 0)\r
+ ) {\r
+ IsMatch = FALSE;\r
+ return IsMatch;\r
+ }\r
+\r
+ //\r
+ // Compare the all LocalAddress and RemoteAddress fields in the two Spdselectors.\r
+ // First, SpdSel1->LocalAddress to SpdSel2->RemoteAddress && Compare\r
+ // SpdSel1->RemoteAddress to SpdSel2->LocalAddress. If all match, return\r
+ // TRUE.\r
+ //\r
+ for (Index = 0; Index < SpdSel1->LocalAddressCount; Index++) {\r
+ if (!IsInAddressInfoList (\r
+ &SpdSel1->LocalAddress[Index],\r
+ SpdSel2->RemoteAddress,\r
+ SpdSel2->RemoteAddressCount\r
+ )) {\r
+ IsMatch = FALSE;\r
+ break;\r
+ }\r
+ }\r
+\r
+ if (IsMatch) {\r
+ for (Index = 0; Index < SpdSel1->RemoteAddressCount; Index++) {\r
+ if (!IsInAddressInfoList (\r
+ &SpdSel1->RemoteAddress[Index],\r
+ SpdSel2->LocalAddress,\r
+ SpdSel2->LocalAddressCount\r
+ )) {\r
+ IsMatch = FALSE;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ return IsMatch;\r
+\r
+}\r
+\r
/**\r
Compare two SA IDs.\r
\r
IN EFI_IPSEC_CONFIG_SELECTOR *Selector\r
)\r
{\r
- EFI_IP_ADDRESS *DestAddr;\r
- EFI_IP_ADDRESS ZeroAddr;\r
- BOOLEAN IsZero;\r
+ BOOLEAN IsZero;\r
+ EFI_IPSEC_CONFIG_SELECTOR ZeroSelector;\r
\r
- DestAddr = &Selector->SaId.DestAddress;\r
IsZero = FALSE;\r
\r
- ZeroMem (&ZeroAddr, sizeof (EFI_IP_ADDRESS));\r
+ ZeroMem (&ZeroSelector, sizeof (EFI_IPSEC_CONFIG_SELECTOR));\r
\r
- if (CompareMem (DestAddr, &ZeroAddr, sizeof (EFI_IP_ADDRESS)) == 0) {\r
+ if (CompareMem (&ZeroSelector, Selector, sizeof (EFI_IPSEC_CONFIG_SELECTOR)) == 0) {\r
IsZero = TRUE;\r
}\r
\r
return EFI_BUFFER_TOO_SMALL;\r
}\r
//\r
- // Copy the base structure of spd selector.\r
+ // Copy the base structure of SPD selector.\r
//\r
CopyMem (Dst, Src, sizeof (EFI_IPSEC_SPD_SELECTOR));\r
\r
//\r
- // Copy the local address array of spd selector.\r
+ // Copy the local address array of SPD selector.\r
//\r
Dst->LocalAddress = (EFI_IP_ADDRESS_INFO *) (Dst + 1);\r
CopyMem (\r
);\r
\r
//\r
- // Copy the remote address array of spd selector.\r
+ // Copy the remote address array of SPD selector.\r
//\r
Dst->RemoteAddress = Dst->LocalAddress + Dst->LocalAddressCount;\r
CopyMem (\r
)\r
{\r
//\r
- // It assumes that all ref buffers in spd selector and data are\r
+ // It assumes that all ref buffers in SPD selector and data are\r
// stored in the continous memory and close to the base structure.\r
//\r
FIX_REF_BUF_ADDR (Selector->LocalAddress, Selector);\r
VOID\r
FixSadEntry (\r
IN EFI_IPSEC_SA_ID *SaId,\r
- IN OUT EFI_IPSEC_SA_DATA *Data\r
+ IN OUT EFI_IPSEC_SA_DATA2 *Data\r
)\r
{\r
//\r
- // It assumes that all ref buffers in sad selector and data are\r
+ // It assumes that all ref buffers in SAD selector and data are\r
// stored in the continous memory and close to the base structure.\r
//\r
if (Data->AlgoInfo.EspAlgoInfo.AuthKey != NULL) {\r
)\r
{\r
//\r
- // It assumes that all ref buffers in spd selector and data are\r
+ // It assumes that all ref buffers in SPD selector and data are\r
// stored in the continous memory and close to the base structure.\r
//\r
UNFIX_REF_BUF_ADDR (Selector->LocalAddress, Selector);\r
VOID\r
UnfixSadEntry (\r
IN OUT EFI_IPSEC_SA_ID *SaId,\r
- IN OUT EFI_IPSEC_SA_DATA *Data\r
+ IN OUT EFI_IPSEC_SA_DATA2 *Data\r
)\r
{\r
//\r
- // It assumes that all ref buffers in sad selector and data are\r
+ // It assumes that all ref buffers in SAD selector and data are\r
// stored in the continous memory and close to the base structure.\r
//\r
if (Data->AlgoInfo.EspAlgoInfo.AuthKey != NULL) {\r
mode is Tunnel, and its tunnel option is NULL.\r
- The Action of Data is protected and its policy\r
mode is not Tunnel and it tunnel option is not NULL.\r
+ - SadEntry requied to be set into new SpdEntry's Sas has\r
+ been found but it is invalid.\r
@retval EFI_OUT_OF_RESOURCED The required system resource could not be allocated.\r
@retval EFI_SUCCESS The specified configuration data was obtained successfully.\r
\r
LIST_ENTRY *SpdSas;\r
LIST_ENTRY *EntryInsertBefore;\r
LIST_ENTRY *Entry;\r
- LIST_ENTRY *NextEntry;\r
LIST_ENTRY *Entry2;\r
+ LIST_ENTRY *NextEntry;\r
+ LIST_ENTRY *NextEntry2;\r
IPSEC_SPD_ENTRY *SpdEntry;\r
IPSEC_SAD_ENTRY *SadEntry;\r
UINTN SpdEntrySize;\r
EntryInsertBefore = SpdList;\r
\r
//\r
- // Remove the existed spd entry.\r
+ // Remove the existed SPD entry.\r
//\r
NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, SpdList) {\r
\r
RemoveEntryList (&SpdEntry->List);\r
\r
//\r
- // Update the reverse ref of sad entry in the spd.sas list.\r
+ // Update the reverse ref of SAD entry in the SPD.sas list.\r
//\r
SpdSas = &SpdEntry->Data->Sas;\r
- NET_LIST_FOR_EACH (Entry2, SpdSas) {\r
- SadEntry = IPSEC_SAD_ENTRY_FROM_SPD (Entry2);\r
- SadEntry->Data->SpdEntry = NULL;\r
+\r
+ //\r
+ // Remove the related SAs from Sas(SadEntry->BySpd). If the SA entry is established by\r
+ // IKE, remove from mConfigData list(SadEntry->List) and then free it directly since its\r
+ // SpdEntry will be freed later.\r
+ //\r
+ NET_LIST_FOR_EACH_SAFE (Entry2, NextEntry2, SpdSas) {\r
+ SadEntry = IPSEC_SAD_ENTRY_FROM_SPD (Entry2);\r
+\r
+ if (SadEntry->Data->SpdEntry != NULL) {\r
+ RemoveEntryList (&SadEntry->BySpd);\r
+ SadEntry->Data->SpdEntry = NULL;\r
+ }\r
+\r
+ if (!(SadEntry->Data->ManualSet)) {\r
+ RemoveEntryList (&SadEntry->List);\r
+ FreePool (SadEntry);\r
+ }\r
}\r
+\r
//\r
- // Free the existed spd entry\r
+ // Free the existed SPD entry\r
//\r
FreePool (SpdEntry);\r
}\r
}\r
//\r
- // Return success here if only want to remove the spd entry.\r
+ // Return success here if only want to remove the SPD entry.\r
//\r
if (SpdData == NULL || SpdSel == NULL) {\r
return EFI_SUCCESS;\r
// Do Padding for the different Arch.\r
//\r
SpdEntrySize = ALIGN_VARIABLE (sizeof (IPSEC_SPD_ENTRY));\r
- SpdEntrySize = ALIGN_VARIABLE (SpdEntrySize + (UINTN)SIZE_OF_SPD_SELECTOR (SpdSel));\r
+ SpdEntrySize = ALIGN_VARIABLE (SpdEntrySize + SIZE_OF_SPD_SELECTOR (SpdSel));\r
SpdEntrySize += IpSecGetSizeOfEfiSpdData (SpdData);\r
\r
SpdEntry = AllocateZeroPool (SpdEntrySize);\r
}\r
//\r
// Fix the address of Selector and Data buffer and copy them, which is\r
- // continous memory and close to the base structure of spd entry.\r
+ // continous memory and close to the base structure of SPD entry.\r
//\r
SpdEntry->Selector = (EFI_IPSEC_SPD_SELECTOR *) ALIGN_POINTER ((SpdEntry + 1), sizeof (UINTN));\r
SpdEntry->Data = (IPSEC_SPD_DATA *) ALIGN_POINTER (\r
SpdData->Name,\r
sizeof (SpdData->Name)\r
);\r
- SpdEntry->Data->PackageFlag = SpdData->PackageFlag;\r
- SpdEntry->Data->Action = SpdData->Action;\r
+ SpdEntry->Data->PackageFlag = SpdData->PackageFlag;\r
+ SpdEntry->Data->TrafficDirection = SpdData->TrafficDirection;\r
+ SpdEntry->Data->Action = SpdData->Action;\r
\r
//\r
// Fix the address of ProcessingPolicy and copy it if need, which is continous\r
- // memory and close to the base structure of sad data.\r
+ // memory and close to the base structure of SAD data.\r
//\r
if (SpdData->Action != EfiIPsecActionProtect) {\r
SpdEntry->Data->ProcessingPolicy = NULL;\r
IpSecDuplicateProcessPolicy (SpdEntry->Data->ProcessingPolicy, SpdData->ProcessingPolicy);\r
}\r
//\r
- // Update the sas list of the new spd entry.\r
+ // Update the sas list of the new SPD entry.\r
//\r
InitializeListHead (&SpdEntry->Data->Sas);\r
\r
NET_LIST_FOR_EACH (Entry, SadList) {\r
SadEntry = IPSEC_SAD_ENTRY_FROM_LIST (Entry);\r
\r
- for (Index = 0; Index < SpdData->SaIdCount; Index++) {\r
-\r
- if (CompareSaId (\r
- (EFI_IPSEC_CONFIG_SELECTOR *) &SpdData->SaId[Index],\r
- (EFI_IPSEC_CONFIG_SELECTOR *) SadEntry->Id\r
- )) {\r
- InsertTailList (&SpdEntry->Data->Sas, &SadEntry->BySpd);\r
- SadEntry->Data->SpdEntry = SpdEntry;\r
+ for (Index = 0; Index < SpdData->SaIdCount; Index++) {\r
+ if (CompareSaId (\r
+ (EFI_IPSEC_CONFIG_SELECTOR *) &SpdData->SaId[Index],\r
+ (EFI_IPSEC_CONFIG_SELECTOR *) SadEntry->Id\r
+ )) {\r
+ //\r
+ // Check whether the found SadEntry is vaild.\r
+ //\r
+ if (IsSubSpdSelector (\r
+ (EFI_IPSEC_CONFIG_SELECTOR *) SadEntry->Data->SpdSelector,\r
+ (EFI_IPSEC_CONFIG_SELECTOR *) SpdEntry->Selector\r
+ )) {\r
+ if (SadEntry->Data->SpdEntry != NULL) {\r
+ RemoveEntryList (&SadEntry->BySpd);\r
+ }\r
+ InsertTailList (&SpdEntry->Data->Sas, &SadEntry->BySpd);\r
+ SadEntry->Data->SpdEntry = SpdEntry;\r
+ } else {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ }\r
}\r
- }\r
}\r
+\r
//\r
- // Insert the new spd entry.\r
+ // Insert the new SPD entry.\r
//\r
InsertTailList (EntryInsertBefore, &SpdEntry->List);\r
\r
LIST_ENTRY *SadList;\r
LIST_ENTRY *SpdList;\r
EFI_IPSEC_SA_ID *SaId;\r
- EFI_IPSEC_SA_DATA *SaData;\r
+ EFI_IPSEC_SA_DATA2 *SaData;\r
EFI_IPSEC_SA_ID *InsertBefore;\r
LIST_ENTRY *EntryInsertBefore;\r
UINTN SadEntrySize;\r
\r
SaId = (Selector == NULL) ? NULL : &Selector->SaId;\r
- SaData = (Data == NULL) ? NULL : (EFI_IPSEC_SA_DATA *) Data;\r
+ SaData = (Data == NULL) ? NULL : (EFI_IPSEC_SA_DATA2 *) Data;\r
InsertBefore = (Context == NULL) ? NULL : &((EFI_IPSEC_CONFIG_SELECTOR *) Context)->SaId;\r
SadList = &mConfigData[IPsecConfigDataTypeSad];\r
\r
EntryInsertBefore = SadList;\r
\r
//\r
- // Remove the existed sad entry.\r
+ // Remove the existed SAD entry.\r
//\r
NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, SadList) {\r
\r
EntryInsertBefore = SadEntry->List.ForwardLink;\r
\r
//\r
- // Update the related sad.byspd field.\r
+ // Update the related SAD.byspd field.\r
//\r
if (SadEntry->Data->SpdEntry != NULL) {\r
RemoveEntryList (&SadEntry->BySpd);\r
}\r
}\r
//\r
- // Return success here if only want to remove the sad entry\r
+ // Return success here if only want to remove the SAD entry\r
//\r
if (SaData == NULL || SaId == NULL) {\r
return EFI_SUCCESS;\r
// Do Padding for different Arch.\r
//\r
SadEntrySize = ALIGN_VARIABLE (sizeof (IPSEC_SAD_ENTRY));\r
- SadEntrySize = ALIGN_VARIABLE (SadEntrySize + sizeof (EFI_IPSEC_SA_DATA));\r
+ SadEntrySize = ALIGN_VARIABLE (SadEntrySize + sizeof (EFI_IPSEC_SA_ID));\r
SadEntrySize = ALIGN_VARIABLE (SadEntrySize + sizeof (IPSEC_SAD_DATA));\r
\r
if (SaId->Proto == EfiIPsecAH) {\r
SadEntrySize += SaData->AlgoInfo.AhAlgoInfo.AuthKeyLength;\r
} else {\r
SadEntrySize = ALIGN_VARIABLE (SadEntrySize + SaData->AlgoInfo.EspAlgoInfo.AuthKeyLength);\r
- SadEntrySize += SaData->AlgoInfo.EspAlgoInfo.EncKeyLength;\r
+ SadEntrySize += ALIGN_VARIABLE (SaData->AlgoInfo.EspAlgoInfo.EncKeyLength);\r
}\r
\r
+ if (SaData->SpdSelector != NULL) {\r
+ SadEntrySize += SadEntrySize + SIZE_OF_SPD_SELECTOR (SaData->SpdSelector);\r
+ }\r
SadEntry = AllocateZeroPool (SadEntrySize);\r
\r
if (SadEntry == NULL) {\r
}\r
//\r
// Fix the address of Id and Data buffer and copy them, which is\r
- // continous memory and close to the base structure of sad entry.\r
+ // continous memory and close to the base structure of SAD entry.\r
//\r
SadEntry->Id = (EFI_IPSEC_SA_ID *) ALIGN_POINTER ((SadEntry + 1), sizeof (UINTN));\r
SadEntry->Data = (IPSEC_SAD_DATA *) ALIGN_POINTER ((SadEntry->Id + 1), sizeof (UINTN));\r
);\r
\r
SadEntry->Data->PathMTU = SaData->PathMTU;\r
- SadEntry->Data->SpdEntry = NULL;\r
+ SadEntry->Data->SpdSelector = NULL;\r
SadEntry->Data->ESNEnabled = FALSE;\r
SadEntry->Data->ManualSet = SaData->ManualSet;\r
\r
//\r
- // Update the spd.sas list of the spd entry specified by sad.selector\r
+ // Copy Tunnel Source/Destination Address\r
+ //\r
+ if (SaData->Mode == EfiIPsecTunnel) {\r
+ CopyMem (\r
+ &SadEntry->Data->TunnelDestAddress,\r
+ &SaData->TunnelDestinationAddress,\r
+ sizeof (EFI_IP_ADDRESS)\r
+ );\r
+ CopyMem (\r
+ &SadEntry->Data->TunnelSourceAddress,\r
+ &SaData->TunnelSourceAddress,\r
+ sizeof (EFI_IP_ADDRESS)\r
+ );\r
+ }\r
+ //\r
+ // Update the spd.sas list of the spd entry specified by SAD selector\r
//\r
SpdList = &mConfigData[IPsecConfigDataTypeSpd];\r
\r
for (Entry = SpdList->ForwardLink; Entry != SpdList && SaData->SpdSelector != NULL; Entry = Entry->ForwardLink) {\r
\r
SpdEntry = IPSEC_SPD_ENTRY_FROM_LIST (Entry);\r
- if (CompareSpdSelector (\r
- (EFI_IPSEC_CONFIG_SELECTOR *) SpdEntry->Selector,\r
- (EFI_IPSEC_CONFIG_SELECTOR *) SaData->SpdSelector\r
+ if (IsSubSpdSelector (\r
+ (EFI_IPSEC_CONFIG_SELECTOR *) SaData->SpdSelector,\r
+ (EFI_IPSEC_CONFIG_SELECTOR *) SpdEntry->Selector\r
) && SpdEntry->Data->Action == EfiIPsecActionProtect) {\r
SadEntry->Data->SpdEntry = SpdEntry;\r
+ SadEntry->Data->SpdSelector = (EFI_IPSEC_SPD_SELECTOR *)((UINT8 *)SadEntry +\r
+ SadEntrySize -\r
+ SIZE_OF_SPD_SELECTOR (SaData->SpdSelector)\r
+ );\r
+ DuplicateSpdSelector (\r
+ (EFI_IPSEC_CONFIG_SELECTOR *) SadEntry->Data->SpdSelector,\r
+ (EFI_IPSEC_CONFIG_SELECTOR *) SaData->SpdSelector,\r
+ NULL\r
+ );\r
InsertTailList (&SpdEntry->Data->Sas, &SadEntry->BySpd);\r
}\r
}\r
//\r
- // Insert the new sad entry.\r
+ // Insert the new SAD entry.\r
//\r
InsertTailList (EntryInsertBefore, &SadEntry->List);\r
\r
SpdEntry = IPSEC_SPD_ENTRY_FROM_LIST (Entry);\r
\r
//\r
- // Find the required spd entry\r
+ // Find the required SPD entry\r
//\r
if (CompareSpdSelector (\r
(EFI_IPSEC_CONFIG_SELECTOR *) SpdSel,\r
*DataSize = RequiredSize;\r
\r
//\r
- // Extract and fill all SaId array from the spd.sas list\r
+ // Extract and fill all SaId array from the SPD.sas list\r
//\r
SpdSas = &SpdEntry->Data->Sas;\r
SpdData->SaIdCount = 0;\r
);\r
}\r
//\r
- // Fill the other fields in spd data.\r
+ // Fill the other fields in SPD data.\r
//\r
CopyMem (SpdData->Name, SpdEntry->Data->Name, sizeof (SpdData->Name));\r
\r
- SpdData->PackageFlag = SpdEntry->Data->PackageFlag;\r
- SpdData->Action = SpdEntry->Data->Action;\r
+ SpdData->PackageFlag = SpdEntry->Data->PackageFlag;\r
+ SpdData->TrafficDirection = SpdEntry->Data->TrafficDirection;\r
+ SpdData->Action = SpdEntry->Data->Action;\r
\r
if (SpdData->Action != EfiIPsecActionProtect) {\r
SpdData->ProcessingPolicy = NULL;\r
LIST_ENTRY *Entry;\r
LIST_ENTRY *SadList;\r
EFI_IPSEC_SA_ID *SaId;\r
- EFI_IPSEC_SA_DATA *SaData;\r
+ EFI_IPSEC_SA_DATA2 *SaData;\r
UINTN RequiredSize;\r
\r
SaId = &Selector->SaId;\r
- SaData = (EFI_IPSEC_SA_DATA *) Data;\r
+ SaData = (EFI_IPSEC_SA_DATA2 *) Data;\r
SadList = &mConfigData[IPsecConfigDataTypeSad];\r
\r
NET_LIST_FOR_EACH (Entry, SadList) {\r
SadEntry = IPSEC_SAD_ENTRY_FROM_LIST (Entry);\r
\r
//\r
- // Find the required sad entry.\r
+ // Find the required SAD entry.\r
//\r
if (CompareSaId (\r
(EFI_IPSEC_CONFIG_SELECTOR *) SaId,\r
(EFI_IPSEC_CONFIG_SELECTOR *) SadEntry->Id\r
)) {\r
//\r
- // Calculate the required size of the sad entry.\r
+ // Calculate the required size of the SAD entry.\r
// Data Layout is follows:\r
// |EFI_IPSEC_SA_DATA\r
// |AuthKey\r
// |EncryptKey (Optional)\r
// |SpdSelector (Optional)\r
//\r
- RequiredSize = ALIGN_VARIABLE (sizeof (EFI_IPSEC_SA_DATA));\r
+ RequiredSize = ALIGN_VARIABLE (sizeof (EFI_IPSEC_SA_DATA2));\r
\r
if (SaId->Proto == EfiIPsecAH) {\r
RequiredSize = ALIGN_VARIABLE (RequiredSize + SadEntry->Data->AlgoInfo.AhAlgoInfo.AuthKeyLength);\r
RequiredSize = ALIGN_VARIABLE (RequiredSize + SadEntry->Data->AlgoInfo.EspAlgoInfo.EncKeyLength);\r
}\r
\r
- if (SadEntry->Data->SpdEntry != NULL) {\r
- RequiredSize += SIZE_OF_SPD_SELECTOR (SadEntry->Data->SpdEntry->Selector);\r
+ if (SadEntry->Data->SpdSelector != NULL) {\r
+ RequiredSize += SIZE_OF_SPD_SELECTOR (SadEntry->Data->SpdSelector);\r
}\r
\r
-\r
-\r
if (*DataSize < RequiredSize) {\r
*DataSize = RequiredSize;\r
return EFI_BUFFER_TOO_SMALL;\r
}\r
+\r
//\r
- // Fill the data fields of sad entry.\r
+ // Fill the data fields of SAD entry.\r
//\r
*DataSize = RequiredSize;\r
SaData->Mode = SadEntry->Data->Mode;\r
SaData->PathMTU = SadEntry->Data->PathMTU;\r
\r
//\r
- // Fill the spd selector field of sad data\r
+ // Fill Tunnel Address if it is Tunnel Mode\r
//\r
- if (SadEntry->Data->SpdEntry != NULL) {\r
+ if (SadEntry->Data->Mode == EfiIPsecTunnel) {\r
+ CopyMem (\r
+ &SaData->TunnelDestinationAddress,\r
+ &SadEntry->Data->TunnelDestAddress,\r
+ sizeof (EFI_IP_ADDRESS)\r
+ );\r
+ CopyMem (\r
+ &SaData->TunnelSourceAddress,\r
+ &SadEntry->Data->TunnelSourceAddress,\r
+ sizeof (EFI_IP_ADDRESS)\r
+ );\r
+ }\r
+ //\r
+ // Fill the spd selector field of SAD data\r
+ //\r
+ if (SadEntry->Data->SpdSelector != NULL) {\r
\r
SaData->SpdSelector = (EFI_IPSEC_SPD_SELECTOR *) (\r
(UINT8 *)SaData +\r
RequiredSize -\r
- SIZE_OF_SPD_SELECTOR (SadEntry->Data->SpdEntry->Selector)\r
+ SIZE_OF_SPD_SELECTOR (SadEntry->Data->SpdSelector)\r
);\r
\r
DuplicateSpdSelector (\r
(EFI_IPSEC_CONFIG_SELECTOR *) SaData->SpdSelector,\r
- (EFI_IPSEC_CONFIG_SELECTOR *) SadEntry->Data->SpdEntry->Selector,\r
+ (EFI_IPSEC_CONFIG_SELECTOR *) SadEntry->Data->SpdSelector,\r
NULL\r
);\r
\r
VariableNameLength = StrLen (VariableName);\r
VariableNameISize = (VariableNameLength + 5) * sizeof (CHAR16);\r
VariableNameI = AllocateZeroPool (VariableNameISize);\r
- ASSERT (VariableNameI != NULL);\r
+ if (VariableNameI == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto ON_EXIT;\r
+ }\r
\r
//\r
// Construct the varible name of ipsecconfig meta data.\r
VariableNameISizeNew,\r
VariableNameI\r
);\r
+ if (VariableNameI == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ break;\r
+ }\r
VariableNameISize = VariableNameISizeNew;\r
\r
Status = gRT->GetNextVariableName (\r
}\r
\r
ON_EXIT:\r
- FreePool (VariableNameI);\r
+ if (VariableNameI != NULL) {\r
+ FreePool (VariableNameI);\r
+ }\r
return Status;\r
}\r
\r
NET_LIST_FOR_EACH (Link, &mConfigData[DataType]) {\r
CommonEntry = BASE_CR (Link, IPSEC_COMMON_POLICY_ENTRY, List);\r
\r
- if (IsFound || mIsZeroSelector[DataType](Selector)) {\r
+ if (IsFound || (BOOLEAN)(mIsZeroSelector[DataType](Selector))) {\r
//\r
// If found the appointed entry, then duplicate the next one and return,\r
// or if the appointed entry is zero, then return the first one directly.\r
\r
if (Type == IPsecConfigDataTypeSad) {\r
//\r
- // Don't save automatically-generated sa entry into variable.\r
+ // Don't save automatically-generated SA entry into variable.\r
//\r
- if (((EFI_IPSEC_SA_DATA *) Data)->ManualSet == FALSE) {\r
+ if (((EFI_IPSEC_SA_DATA2 *) Data)->ManualSet == FALSE) {\r
return EFI_SUCCESS;\r
}\r
}\r
Buffer->Capacity += EntrySize;\r
TempPoint = AllocatePool (Buffer->Capacity);\r
\r
- if (Buffer->Ptr == NULL) {\r
+ if (TempPoint == NULL) {\r
return EFI_OUT_OF_RESOURCES;\r
}\r
//\r