X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=NetworkPkg%2FIpSecDxe%2FIpSecConfigImpl.c;h=8893d49a9fe37a2d53eff453a5afc83025d4355d;hb=d3b05936d961fa9530ae7a5ca6363abd45864b83;hp=e671e42e27af1230f804c4eb625d87047c846d9d;hpb=a3bcde70e6dc69000f85cc5deee98101d2ae200a;p=mirror_edk2.git
diff --git a/NetworkPkg/IpSecDxe/IpSecConfigImpl.c b/NetworkPkg/IpSecDxe/IpSecConfigImpl.c
index e671e42e27..8893d49a9f 100644
--- a/NetworkPkg/IpSecDxe/IpSecConfigImpl.c
+++ b/NetworkPkg/IpSecDxe/IpSecConfigImpl.c
@@ -1,7 +1,7 @@
/** @file
The implementation of IPSEC_CONFIG_PROTOCOL.
- Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
+ Copyright (c) 2009 - 2018, 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
@@ -20,7 +20,7 @@ LIST_ENTRY mConfigData[IPsecConfigDataTypeMaximum];
BOOLEAN mSetBySelf = FALSE;
//
-// Common CompareSelector routine entry for spd/sad/pad.
+// Common CompareSelector routine entry for SPD/SAD/PAD.
//
IPSEC_COMPARE_SELECTOR mCompareSelector[] = {
(IPSEC_COMPARE_SELECTOR) CompareSpdSelector,
@@ -29,7 +29,7 @@ IPSEC_COMPARE_SELECTOR mCompareSelector[] = {
};
//
-// Common IsZeroSelector routine entry for spd/sad/pad.
+// Common IsZeroSelector routine entry for SPD/SAD/PAD.
//
IPSEC_IS_ZERO_SELECTOR mIsZeroSelector[] = {
(IPSEC_IS_ZERO_SELECTOR) IsZeroSpdSelector,
@@ -38,7 +38,7 @@ IPSEC_IS_ZERO_SELECTOR mIsZeroSelector[] = {
};
//
-// Common DuplicateSelector routine entry for spd/sad/pad.
+// Common DuplicateSelector routine entry for SPD/SAD/PAD.
//
IPSEC_DUPLICATE_SELECTOR mDuplicateSelector[] = {
(IPSEC_DUPLICATE_SELECTOR) DuplicateSpdSelector,
@@ -47,7 +47,7 @@ IPSEC_DUPLICATE_SELECTOR mDuplicateSelector[] = {
};
//
-// Common FixPolicyEntry routine entry for spd/sad/pad.
+// Common FixPolicyEntry routine entry for SPD/SAD/PAD.
//
IPSEC_FIX_POLICY_ENTRY mFixPolicyEntry[] = {
(IPSEC_FIX_POLICY_ENTRY) FixSpdEntry,
@@ -56,7 +56,7 @@ IPSEC_FIX_POLICY_ENTRY mFixPolicyEntry[] = {
};
//
-// Common UnfixPolicyEntry routine entry for spd/sad/pad.
+// Common UnfixPolicyEntry routine entry for SPD/SAD/PAD.
//
IPSEC_FIX_POLICY_ENTRY mUnfixPolicyEntry[] = {
(IPSEC_FIX_POLICY_ENTRY) UnfixSpdEntry,
@@ -65,7 +65,7 @@ IPSEC_FIX_POLICY_ENTRY mUnfixPolicyEntry[] = {
};
//
-// Common SetPolicyEntry routine entry for spd/sad/pad.
+// Common SetPolicyEntry routine entry for SPD/SAD/PAD.
//
IPSEC_SET_POLICY_ENTRY mSetPolicyEntry[] = {
(IPSEC_SET_POLICY_ENTRY) SetSpdEntry,
@@ -74,7 +74,7 @@ IPSEC_SET_POLICY_ENTRY mSetPolicyEntry[] = {
};
//
-// Common GetPolicyEntry routine entry for spd/sad/pad.
+// Common GetPolicyEntry routine entry for SPD/SAD/PAD.
//
IPSEC_GET_POLICY_ENTRY mGetPolicyEntry[] = {
(IPSEC_GET_POLICY_ENTRY) GetSpdEntry,
@@ -130,8 +130,23 @@ IsInAddressInfoList(
IN UINT32 AddressCount
)
{
- UINT8 Index;
+ UINT8 Index;
+ EFI_IP_ADDRESS ZeroAddress;
+ ZeroMem(&ZeroAddress, sizeof (EFI_IP_ADDRESS));
+
+ //
+ // Zero Address means any address is matched.
+ //
+ if (AddressCount == 1) {
+ if (CompareMem (
+ &AddressInfoList[0].Address,
+ &ZeroAddress,
+ sizeof (EFI_IP_ADDRESS)
+ ) == 0) {
+ return TRUE;
+ }
+ }
for (Index = 0; Index < AddressCount ; Index++) {
if (CompareMem (
AddressInfo,
@@ -196,7 +211,7 @@ CompareSpdSelector (
}
//
- // Compare the all LocalAddress fields in the two Spdselectors.
+ // Compare the all LocalAddress and RemoteAddress fields in the two Spdselectors.
// First, SpdSel1->LocalAddress to SpdSel2->LocalAddress && Compare
// SpdSel1->RemoteAddress to SpdSel2->RemoteAddress. If all match, return
// TRUE.
@@ -309,6 +324,143 @@ CompareSpdSelector (
return IsMatch;
}
+/**
+ Find if the two SPD Selectors has subordinative.
+
+ Compare two SPD Selector by the fields of LocalAddressCount/RemoteAddressCount/
+ NextLayerProtocol/LocalPort/LocalPortRange/RemotePort/RemotePortRange and the
+ Local Addresses and remote Addresses.
+
+ @param[in] Selector1 Pointer of first SPD Selector.
+ @param[in] Selector2 Pointer of second SPD Selector.
+
+ @retval TRUE The first SPD Selector is subordinate Selector of second SPD Selector.
+ @retval FALSE The first SPD Selector is not subordinate Selector of second
+ SPD Selector.
+
+**/
+BOOLEAN
+IsSubSpdSelector (
+ IN EFI_IPSEC_CONFIG_SELECTOR *Selector1,
+ IN EFI_IPSEC_CONFIG_SELECTOR *Selector2
+ )
+{
+ EFI_IPSEC_SPD_SELECTOR *SpdSel1;
+ EFI_IPSEC_SPD_SELECTOR *SpdSel2;
+ BOOLEAN IsMatch;
+ UINTN Index;
+
+ SpdSel1 = &Selector1->SpdSelector;
+ SpdSel2 = &Selector2->SpdSelector;
+ IsMatch = TRUE;
+
+ //
+ // Compare the LocalAddressCount/RemoteAddressCount/NextLayerProtocol/
+ // LocalPort/LocalPortRange/RemotePort/RemotePortRange fields in the
+ // two Spdselectors. Since the SPD supports two directions, it needs to
+ // compare two directions.
+ //
+ if (SpdSel1->LocalAddressCount > SpdSel2->LocalAddressCount ||
+ SpdSel1->RemoteAddressCount > SpdSel2->RemoteAddressCount ||
+ (SpdSel1->NextLayerProtocol != SpdSel2->NextLayerProtocol && SpdSel2->NextLayerProtocol != 0xffff) ||
+ (SpdSel1->LocalPort > SpdSel2->LocalPort && SpdSel2->LocalPort != 0)||
+ (SpdSel1->LocalPortRange > SpdSel2->LocalPortRange && SpdSel1->LocalPort != 0)||
+ (SpdSel1->RemotePort > SpdSel2->RemotePort && SpdSel2->RemotePort != 0) ||
+ (SpdSel1->RemotePortRange > SpdSel2->RemotePortRange && SpdSel2->RemotePort != 0)
+ ) {
+ IsMatch = FALSE;
+ }
+
+ //
+ // Compare the all LocalAddress and RemoteAddress fields in the two Spdselectors.
+ // First, SpdSel1->LocalAddress to SpdSel2->LocalAddress && Compare
+ // SpdSel1->RemoteAddress to SpdSel2->RemoteAddress. If all match, return
+ // TRUE.
+ //
+ if (IsMatch) {
+ for (Index = 0; Index < SpdSel1->LocalAddressCount; Index++) {
+ if (!IsInAddressInfoList (
+ &SpdSel1->LocalAddress[Index],
+ SpdSel2->LocalAddress,
+ SpdSel2->LocalAddressCount
+ )) {
+ IsMatch = FALSE;
+ break;
+ }
+ }
+
+ if (IsMatch) {
+ for (Index = 0; Index < SpdSel1->RemoteAddressCount; Index++) {
+ if (!IsInAddressInfoList (
+ &SpdSel1->RemoteAddress[Index],
+ SpdSel2->RemoteAddress,
+ SpdSel2->RemoteAddressCount
+ )) {
+ IsMatch = FALSE;
+ break;
+ }
+ }
+ }
+ }
+ if (IsMatch) {
+ return IsMatch;
+ }
+
+ //
+ //
+ // The SPD selector in SPD entry is two way.
+ //
+ // Compare the LocalAddressCount/RemoteAddressCount/NextLayerProtocol/
+ // LocalPort/LocalPortRange/RemotePort/RemotePortRange fields in the
+ // two Spdselectors. Since the SPD supports two directions, it needs to
+ // compare two directions.
+ //
+ IsMatch = TRUE;
+ if (SpdSel1->LocalAddressCount > SpdSel2->RemoteAddressCount ||
+ SpdSel1->RemoteAddressCount > SpdSel2->LocalAddressCount ||
+ (SpdSel1->NextLayerProtocol != SpdSel2->NextLayerProtocol && SpdSel2->NextLayerProtocol != 0xffff) ||
+ (SpdSel1->LocalPort > SpdSel2->RemotePort && SpdSel2->RemotePort != 0)||
+ (SpdSel1->LocalPortRange > SpdSel2->RemotePortRange && SpdSel1->RemotePort != 0)||
+ (SpdSel1->RemotePort > SpdSel2->LocalPort && SpdSel2->LocalPort != 0) ||
+ (SpdSel1->RemotePortRange > SpdSel2->LocalPortRange && SpdSel2->LocalPort != 0)
+ ) {
+ IsMatch = FALSE;
+ return IsMatch;
+ }
+
+ //
+ // Compare the all LocalAddress and RemoteAddress fields in the two Spdselectors.
+ // First, SpdSel1->LocalAddress to SpdSel2->RemoteAddress && Compare
+ // SpdSel1->RemoteAddress to SpdSel2->LocalAddress. If all match, return
+ // TRUE.
+ //
+ for (Index = 0; Index < SpdSel1->LocalAddressCount; Index++) {
+ if (!IsInAddressInfoList (
+ &SpdSel1->LocalAddress[Index],
+ SpdSel2->RemoteAddress,
+ SpdSel2->RemoteAddressCount
+ )) {
+ IsMatch = FALSE;
+ break;
+ }
+ }
+
+ if (IsMatch) {
+ for (Index = 0; Index < SpdSel1->RemoteAddressCount; Index++) {
+ if (!IsInAddressInfoList (
+ &SpdSel1->RemoteAddress[Index],
+ SpdSel2->LocalAddress,
+ SpdSel2->LocalAddressCount
+ )) {
+ IsMatch = FALSE;
+ break;
+ }
+ }
+ }
+ return IsMatch;
+
+}
+
/**
Compare two SA IDs.
@@ -435,16 +587,14 @@ IsZeroSaId (
IN EFI_IPSEC_CONFIG_SELECTOR *Selector
)
{
- EFI_IP_ADDRESS *DestAddr;
- EFI_IP_ADDRESS ZeroAddr;
- BOOLEAN IsZero;
+ BOOLEAN IsZero;
+ EFI_IPSEC_CONFIG_SELECTOR ZeroSelector;
- DestAddr = &Selector->SaId.DestAddress;
IsZero = FALSE;
- ZeroMem (&ZeroAddr, sizeof (EFI_IP_ADDRESS));
+ ZeroMem (&ZeroSelector, sizeof (EFI_IPSEC_CONFIG_SELECTOR));
- if (CompareMem (DestAddr, &ZeroAddr, sizeof (EFI_IP_ADDRESS)) == 0) {
+ if (CompareMem (&ZeroSelector, Selector, sizeof (EFI_IPSEC_CONFIG_SELECTOR)) == 0) {
IsZero = TRUE;
}
@@ -520,12 +670,12 @@ DuplicateSpdSelector (
return EFI_BUFFER_TOO_SMALL;
}
//
- // Copy the base structure of spd selector.
+ // Copy the base structure of SPD selector.
//
CopyMem (Dst, Src, sizeof (EFI_IPSEC_SPD_SELECTOR));
//
- // Copy the local address array of spd selector.
+ // Copy the local address array of SPD selector.
//
Dst->LocalAddress = (EFI_IP_ADDRESS_INFO *) (Dst + 1);
CopyMem (
@@ -535,7 +685,7 @@ DuplicateSpdSelector (
);
//
- // Copy the remote address array of spd selector.
+ // Copy the remote address array of SPD selector.
//
Dst->RemoteAddress = Dst->LocalAddress + Dst->LocalAddressCount;
CopyMem (
@@ -650,7 +800,7 @@ FixSpdEntry (
)
{
//
- // It assumes that all ref buffers in spd selector and data are
+ // It assumes that all ref buffers in SPD selector and data are
// stored in the continous memory and close to the base structure.
//
FIX_REF_BUF_ADDR (Selector->LocalAddress, Selector);
@@ -681,11 +831,11 @@ FixSpdEntry (
VOID
FixSadEntry (
IN EFI_IPSEC_SA_ID *SaId,
- IN OUT EFI_IPSEC_SA_DATA *Data
+ IN OUT EFI_IPSEC_SA_DATA2 *Data
)
{
//
- // It assumes that all ref buffers in sad selector and data are
+ // It assumes that all ref buffers in SAD selector and data are
// stored in the continous memory and close to the base structure.
//
if (Data->AlgoInfo.EspAlgoInfo.AuthKey != NULL) {
@@ -756,7 +906,7 @@ UnfixSpdEntry (
)
{
//
- // It assumes that all ref buffers in spd selector and data are
+ // It assumes that all ref buffers in SPD selector and data are
// stored in the continous memory and close to the base structure.
//
UNFIX_REF_BUF_ADDR (Selector->LocalAddress, Selector);
@@ -784,11 +934,11 @@ UnfixSpdEntry (
VOID
UnfixSadEntry (
IN OUT EFI_IPSEC_SA_ID *SaId,
- IN OUT EFI_IPSEC_SA_DATA *Data
+ IN OUT EFI_IPSEC_SA_DATA2 *Data
)
{
//
- // It assumes that all ref buffers in sad selector and data are
+ // It assumes that all ref buffers in SAD selector and data are
// stored in the continous memory and close to the base structure.
//
if (Data->AlgoInfo.EspAlgoInfo.AuthKey != NULL) {
@@ -868,6 +1018,8 @@ UnfixPadEntry (
mode is Tunnel, and its tunnel option is NULL.
- The Action of Data is protected and its policy
mode is not Tunnel and it tunnel option is not NULL.
+ - SadEntry requied to be set into new SpdEntry's Sas has
+ been found but it is invalid.
@retval EFI_OUT_OF_RESOURCED The required system resource could not be allocated.
@retval EFI_SUCCESS The specified configuration data was obtained successfully.
@@ -887,8 +1039,9 @@ SetSpdEntry (
LIST_ENTRY *SpdSas;
LIST_ENTRY *EntryInsertBefore;
LIST_ENTRY *Entry;
- LIST_ENTRY *NextEntry;
LIST_ENTRY *Entry2;
+ LIST_ENTRY *NextEntry;
+ LIST_ENTRY *NextEntry2;
IPSEC_SPD_ENTRY *SpdEntry;
IPSEC_SAD_ENTRY *SadEntry;
UINTN SpdEntrySize;
@@ -926,7 +1079,7 @@ SetSpdEntry (
EntryInsertBefore = SpdList;
//
- // Remove the existed spd entry.
+ // Remove the existed SPD entry.
//
NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, SpdList) {
@@ -942,21 +1095,37 @@ SetSpdEntry (
RemoveEntryList (&SpdEntry->List);
//
- // Update the reverse ref of sad entry in the spd.sas list.
+ // Update the reverse ref of SAD entry in the SPD.sas list.
//
SpdSas = &SpdEntry->Data->Sas;
- NET_LIST_FOR_EACH (Entry2, SpdSas) {
- SadEntry = IPSEC_SAD_ENTRY_FROM_SPD (Entry2);
- SadEntry->Data->SpdEntry = NULL;
+
+ //
+ // Remove the related SAs from Sas(SadEntry->BySpd). If the SA entry is established by
+ // IKE, remove from mConfigData list(SadEntry->List) and then free it directly since its
+ // SpdEntry will be freed later.
+ //
+ NET_LIST_FOR_EACH_SAFE (Entry2, NextEntry2, SpdSas) {
+ SadEntry = IPSEC_SAD_ENTRY_FROM_SPD (Entry2);
+
+ if (SadEntry->Data->SpdEntry != NULL) {
+ RemoveEntryList (&SadEntry->BySpd);
+ SadEntry->Data->SpdEntry = NULL;
+ }
+
+ if (!(SadEntry->Data->ManualSet)) {
+ RemoveEntryList (&SadEntry->List);
+ FreePool (SadEntry);
+ }
}
+
//
- // Free the existed spd entry
+ // Free the existed SPD entry
//
FreePool (SpdEntry);
}
}
//
- // Return success here if only want to remove the spd entry.
+ // Return success here if only want to remove the SPD entry.
//
if (SpdData == NULL || SpdSel == NULL) {
return EFI_SUCCESS;
@@ -983,7 +1152,7 @@ SetSpdEntry (
// Do Padding for the different Arch.
//
SpdEntrySize = ALIGN_VARIABLE (sizeof (IPSEC_SPD_ENTRY));
- SpdEntrySize = ALIGN_VARIABLE (SpdEntrySize + (UINTN)SIZE_OF_SPD_SELECTOR (SpdSel));
+ SpdEntrySize = ALIGN_VARIABLE (SpdEntrySize + SIZE_OF_SPD_SELECTOR (SpdSel));
SpdEntrySize += IpSecGetSizeOfEfiSpdData (SpdData);
SpdEntry = AllocateZeroPool (SpdEntrySize);
@@ -993,7 +1162,7 @@ SetSpdEntry (
}
//
// Fix the address of Selector and Data buffer and copy them, which is
- // continous memory and close to the base structure of spd entry.
+ // continous memory and close to the base structure of SPD entry.
//
SpdEntry->Selector = (EFI_IPSEC_SPD_SELECTOR *) ALIGN_POINTER ((SpdEntry + 1), sizeof (UINTN));
SpdEntry->Data = (IPSEC_SPD_DATA *) ALIGN_POINTER (
@@ -1012,12 +1181,13 @@ SetSpdEntry (
SpdData->Name,
sizeof (SpdData->Name)
);
- SpdEntry->Data->PackageFlag = SpdData->PackageFlag;
- SpdEntry->Data->Action = SpdData->Action;
+ SpdEntry->Data->PackageFlag = SpdData->PackageFlag;
+ SpdEntry->Data->TrafficDirection = SpdData->TrafficDirection;
+ SpdEntry->Data->Action = SpdData->Action;
//
// Fix the address of ProcessingPolicy and copy it if need, which is continous
- // memory and close to the base structure of sad data.
+ // memory and close to the base structure of SAD data.
//
if (SpdData->Action != EfiIPsecActionProtect) {
SpdEntry->Data->ProcessingPolicy = NULL;
@@ -1029,7 +1199,7 @@ SetSpdEntry (
IpSecDuplicateProcessPolicy (SpdEntry->Data->ProcessingPolicy, SpdData->ProcessingPolicy);
}
//
- // Update the sas list of the new spd entry.
+ // Update the sas list of the new SPD entry.
//
InitializeListHead (&SpdEntry->Data->Sas);
@@ -1038,19 +1208,32 @@ SetSpdEntry (
NET_LIST_FOR_EACH (Entry, SadList) {
SadEntry = IPSEC_SAD_ENTRY_FROM_LIST (Entry);
- for (Index = 0; Index < SpdData->SaIdCount; Index++) {
-
- if (CompareSaId (
- (EFI_IPSEC_CONFIG_SELECTOR *) &SpdData->SaId[Index],
- (EFI_IPSEC_CONFIG_SELECTOR *) SadEntry->Id
- )) {
- InsertTailList (&SpdEntry->Data->Sas, &SadEntry->BySpd);
- SadEntry->Data->SpdEntry = SpdEntry;
+ for (Index = 0; Index < SpdData->SaIdCount; Index++) {
+ if (CompareSaId (
+ (EFI_IPSEC_CONFIG_SELECTOR *) &SpdData->SaId[Index],
+ (EFI_IPSEC_CONFIG_SELECTOR *) SadEntry->Id
+ )) {
+ //
+ // Check whether the found SadEntry is vaild.
+ //
+ if (IsSubSpdSelector (
+ (EFI_IPSEC_CONFIG_SELECTOR *) SadEntry->Data->SpdSelector,
+ (EFI_IPSEC_CONFIG_SELECTOR *) SpdEntry->Selector
+ )) {
+ if (SadEntry->Data->SpdEntry != NULL) {
+ RemoveEntryList (&SadEntry->BySpd);
+ }
+ InsertTailList (&SpdEntry->Data->Sas, &SadEntry->BySpd);
+ SadEntry->Data->SpdEntry = SpdEntry;
+ } else {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
}
- }
}
+
//
- // Insert the new spd entry.
+ // Insert the new SPD entry.
//
InsertTailList (EntryInsertBefore, &SpdEntry->List);
@@ -1092,13 +1275,13 @@ SetSadEntry (
LIST_ENTRY *SadList;
LIST_ENTRY *SpdList;
EFI_IPSEC_SA_ID *SaId;
- EFI_IPSEC_SA_DATA *SaData;
+ EFI_IPSEC_SA_DATA2 *SaData;
EFI_IPSEC_SA_ID *InsertBefore;
LIST_ENTRY *EntryInsertBefore;
UINTN SadEntrySize;
SaId = (Selector == NULL) ? NULL : &Selector->SaId;
- SaData = (Data == NULL) ? NULL : (EFI_IPSEC_SA_DATA *) Data;
+ SaData = (Data == NULL) ? NULL : (EFI_IPSEC_SA_DATA2 *) Data;
InsertBefore = (Context == NULL) ? NULL : &((EFI_IPSEC_CONFIG_SELECTOR *) Context)->SaId;
SadList = &mConfigData[IPsecConfigDataTypeSad];
@@ -1108,7 +1291,7 @@ SetSadEntry (
EntryInsertBefore = SadList;
//
- // Remove the existed sad entry.
+ // Remove the existed SAD entry.
//
NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, SadList) {
@@ -1125,7 +1308,7 @@ SetSadEntry (
EntryInsertBefore = SadEntry->List.ForwardLink;
//
- // Update the related sad.byspd field.
+ // Update the related SAD.byspd field.
//
if (SadEntry->Data->SpdEntry != NULL) {
RemoveEntryList (&SadEntry->BySpd);
@@ -1136,7 +1319,7 @@ SetSadEntry (
}
}
//
- // Return success here if only want to remove the sad entry
+ // Return success here if only want to remove the SAD entry
//
if (SaData == NULL || SaId == NULL) {
return EFI_SUCCESS;
@@ -1163,16 +1346,19 @@ SetSadEntry (
// Do Padding for different Arch.
//
SadEntrySize = ALIGN_VARIABLE (sizeof (IPSEC_SAD_ENTRY));
- SadEntrySize = ALIGN_VARIABLE (SadEntrySize + sizeof (EFI_IPSEC_SA_DATA));
+ SadEntrySize = ALIGN_VARIABLE (SadEntrySize + sizeof (EFI_IPSEC_SA_ID));
SadEntrySize = ALIGN_VARIABLE (SadEntrySize + sizeof (IPSEC_SAD_DATA));
if (SaId->Proto == EfiIPsecAH) {
SadEntrySize += SaData->AlgoInfo.AhAlgoInfo.AuthKeyLength;
} else {
SadEntrySize = ALIGN_VARIABLE (SadEntrySize + SaData->AlgoInfo.EspAlgoInfo.AuthKeyLength);
- SadEntrySize += SaData->AlgoInfo.EspAlgoInfo.EncKeyLength;
+ SadEntrySize += ALIGN_VARIABLE (SaData->AlgoInfo.EspAlgoInfo.EncKeyLength);
}
+ if (SaData->SpdSelector != NULL) {
+ SadEntrySize += SadEntrySize + SIZE_OF_SPD_SELECTOR (SaData->SpdSelector);
+ }
SadEntry = AllocateZeroPool (SadEntrySize);
if (SadEntry == NULL) {
@@ -1180,7 +1366,7 @@ SetSadEntry (
}
//
// Fix the address of Id and Data buffer and copy them, which is
- // continous memory and close to the base structure of sad entry.
+ // continous memory and close to the base structure of SAD entry.
//
SadEntry->Id = (EFI_IPSEC_SA_ID *) ALIGN_POINTER ((SadEntry + 1), sizeof (UINTN));
SadEntry->Data = (IPSEC_SAD_DATA *) ALIGN_POINTER ((SadEntry->Id + 1), sizeof (UINTN));
@@ -1238,28 +1424,52 @@ SetSadEntry (
);
SadEntry->Data->PathMTU = SaData->PathMTU;
- SadEntry->Data->SpdEntry = NULL;
+ SadEntry->Data->SpdSelector = NULL;
SadEntry->Data->ESNEnabled = FALSE;
SadEntry->Data->ManualSet = SaData->ManualSet;
//
- // Update the spd.sas list of the spd entry specified by sad.selector
+ // Copy Tunnel Source/Destination Address
+ //
+ if (SaData->Mode == EfiIPsecTunnel) {
+ CopyMem (
+ &SadEntry->Data->TunnelDestAddress,
+ &SaData->TunnelDestinationAddress,
+ sizeof (EFI_IP_ADDRESS)
+ );
+ CopyMem (
+ &SadEntry->Data->TunnelSourceAddress,
+ &SaData->TunnelSourceAddress,
+ sizeof (EFI_IP_ADDRESS)
+ );
+ }
+ //
+ // Update the spd.sas list of the spd entry specified by SAD selector
//
SpdList = &mConfigData[IPsecConfigDataTypeSpd];
for (Entry = SpdList->ForwardLink; Entry != SpdList && SaData->SpdSelector != NULL; Entry = Entry->ForwardLink) {
SpdEntry = IPSEC_SPD_ENTRY_FROM_LIST (Entry);
- if (CompareSpdSelector (
- (EFI_IPSEC_CONFIG_SELECTOR *) SpdEntry->Selector,
- (EFI_IPSEC_CONFIG_SELECTOR *) SaData->SpdSelector
+ if (IsSubSpdSelector (
+ (EFI_IPSEC_CONFIG_SELECTOR *) SaData->SpdSelector,
+ (EFI_IPSEC_CONFIG_SELECTOR *) SpdEntry->Selector
) && SpdEntry->Data->Action == EfiIPsecActionProtect) {
SadEntry->Data->SpdEntry = SpdEntry;
+ SadEntry->Data->SpdSelector = (EFI_IPSEC_SPD_SELECTOR *)((UINT8 *)SadEntry +
+ SadEntrySize -
+ SIZE_OF_SPD_SELECTOR (SaData->SpdSelector)
+ );
+ DuplicateSpdSelector (
+ (EFI_IPSEC_CONFIG_SELECTOR *) SadEntry->Data->SpdSelector,
+ (EFI_IPSEC_CONFIG_SELECTOR *) SaData->SpdSelector,
+ NULL
+ );
InsertTailList (&SpdEntry->Data->Sas, &SadEntry->BySpd);
}
}
//
- // Insert the new sad entry.
+ // Insert the new SAD entry.
//
InsertTailList (EntryInsertBefore, &SadEntry->List);
@@ -1462,7 +1672,7 @@ GetSpdEntry (
SpdEntry = IPSEC_SPD_ENTRY_FROM_LIST (Entry);
//
- // Find the required spd entry
+ // Find the required SPD entry
//
if (CompareSpdSelector (
(EFI_IPSEC_CONFIG_SELECTOR *) SpdSel,
@@ -1482,7 +1692,7 @@ GetSpdEntry (
*DataSize = RequiredSize;
//
- // Extract and fill all SaId array from the spd.sas list
+ // Extract and fill all SaId array from the SPD.sas list
//
SpdSas = &SpdEntry->Data->Sas;
SpdData->SaIdCount = 0;
@@ -1496,12 +1706,13 @@ GetSpdEntry (
);
}
//
- // Fill the other fields in spd data.
+ // Fill the other fields in SPD data.
//
CopyMem (SpdData->Name, SpdEntry->Data->Name, sizeof (SpdData->Name));
- SpdData->PackageFlag = SpdEntry->Data->PackageFlag;
- SpdData->Action = SpdEntry->Data->Action;
+ SpdData->PackageFlag = SpdEntry->Data->PackageFlag;
+ SpdData->TrafficDirection = SpdEntry->Data->TrafficDirection;
+ SpdData->Action = SpdEntry->Data->Action;
if (SpdData->Action != EfiIPsecActionProtect) {
SpdData->ProcessingPolicy = NULL;
@@ -1549,32 +1760,32 @@ GetSadEntry (
LIST_ENTRY *Entry;
LIST_ENTRY *SadList;
EFI_IPSEC_SA_ID *SaId;
- EFI_IPSEC_SA_DATA *SaData;
+ EFI_IPSEC_SA_DATA2 *SaData;
UINTN RequiredSize;
SaId = &Selector->SaId;
- SaData = (EFI_IPSEC_SA_DATA *) Data;
+ SaData = (EFI_IPSEC_SA_DATA2 *) Data;
SadList = &mConfigData[IPsecConfigDataTypeSad];
NET_LIST_FOR_EACH (Entry, SadList) {
SadEntry = IPSEC_SAD_ENTRY_FROM_LIST (Entry);
//
- // Find the required sad entry.
+ // Find the required SAD entry.
//
if (CompareSaId (
(EFI_IPSEC_CONFIG_SELECTOR *) SaId,
(EFI_IPSEC_CONFIG_SELECTOR *) SadEntry->Id
)) {
//
- // Calculate the required size of the sad entry.
+ // Calculate the required size of the SAD entry.
// Data Layout is follows:
// |EFI_IPSEC_SA_DATA
// |AuthKey
// |EncryptKey (Optional)
// |SpdSelector (Optional)
//
- RequiredSize = ALIGN_VARIABLE (sizeof (EFI_IPSEC_SA_DATA));
+ RequiredSize = ALIGN_VARIABLE (sizeof (EFI_IPSEC_SA_DATA2));
if (SaId->Proto == EfiIPsecAH) {
RequiredSize = ALIGN_VARIABLE (RequiredSize + SadEntry->Data->AlgoInfo.AhAlgoInfo.AuthKeyLength);
@@ -1583,18 +1794,17 @@ GetSadEntry (
RequiredSize = ALIGN_VARIABLE (RequiredSize + SadEntry->Data->AlgoInfo.EspAlgoInfo.EncKeyLength);
}
- if (SadEntry->Data->SpdEntry != NULL) {
- RequiredSize += SIZE_OF_SPD_SELECTOR (SadEntry->Data->SpdEntry->Selector);
+ if (SadEntry->Data->SpdSelector != NULL) {
+ RequiredSize += SIZE_OF_SPD_SELECTOR (SadEntry->Data->SpdSelector);
}
-
-
if (*DataSize < RequiredSize) {
*DataSize = RequiredSize;
return EFI_BUFFER_TOO_SMALL;
}
+
//
- // Fill the data fields of sad entry.
+ // Fill the data fields of SAD entry.
//
*DataSize = RequiredSize;
SaData->Mode = SadEntry->Data->Mode;
@@ -1661,19 +1871,34 @@ GetSadEntry (
SaData->PathMTU = SadEntry->Data->PathMTU;
//
- // Fill the spd selector field of sad data
+ // Fill Tunnel Address if it is Tunnel Mode
//
- if (SadEntry->Data->SpdEntry != NULL) {
+ if (SadEntry->Data->Mode == EfiIPsecTunnel) {
+ CopyMem (
+ &SaData->TunnelDestinationAddress,
+ &SadEntry->Data->TunnelDestAddress,
+ sizeof (EFI_IP_ADDRESS)
+ );
+ CopyMem (
+ &SaData->TunnelSourceAddress,
+ &SadEntry->Data->TunnelSourceAddress,
+ sizeof (EFI_IP_ADDRESS)
+ );
+ }
+ //
+ // Fill the spd selector field of SAD data
+ //
+ if (SadEntry->Data->SpdSelector != NULL) {
SaData->SpdSelector = (EFI_IPSEC_SPD_SELECTOR *) (
(UINT8 *)SaData +
RequiredSize -
- SIZE_OF_SPD_SELECTOR (SadEntry->Data->SpdEntry->Selector)
+ SIZE_OF_SPD_SELECTOR (SadEntry->Data->SpdSelector)
);
DuplicateSpdSelector (
(EFI_IPSEC_CONFIG_SELECTOR *) SaData->SpdSelector,
- (EFI_IPSEC_CONFIG_SELECTOR *) SadEntry->Data->SpdEntry->Selector,
+ (EFI_IPSEC_CONFIG_SELECTOR *) SadEntry->Data->SpdSelector,
NULL
);
@@ -1950,7 +2175,10 @@ IpSecGetVariable (
VariableNameLength = StrLen (VariableName);
VariableNameISize = (VariableNameLength + 5) * sizeof (CHAR16);
VariableNameI = AllocateZeroPool (VariableNameISize);
- ASSERT (VariableNameI != NULL);
+ if (VariableNameI == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
//
// Construct the varible name of ipsecconfig meta data.
@@ -1995,6 +2223,10 @@ IpSecGetVariable (
VariableNameISizeNew,
VariableNameI
);
+ if (VariableNameI == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ break;
+ }
VariableNameISize = VariableNameISizeNew;
Status = gRT->GetNextVariableName (
@@ -2071,7 +2303,9 @@ IpSecGetVariable (
}
ON_EXIT:
- FreePool (VariableNameI);
+ if (VariableNameI != NULL) {
+ FreePool (VariableNameI);
+ }
return Status;
}
@@ -2365,7 +2599,7 @@ EfiIpSecConfigGetNextSelector (
NET_LIST_FOR_EACH (Link, &mConfigData[DataType]) {
CommonEntry = BASE_CR (Link, IPSEC_COMMON_POLICY_ENTRY, List);
- if (IsFound || mIsZeroSelector[DataType](Selector)) {
+ if (IsFound || (BOOLEAN)(mIsZeroSelector[DataType](Selector))) {
//
// If found the appointed entry, then duplicate the next one and return,
// or if the appointed entry is zero, then return the first one directly.
@@ -2477,9 +2711,9 @@ IpSecCopyPolicyEntry (
if (Type == IPsecConfigDataTypeSad) {
//
- // Don't save automatically-generated sa entry into variable.
+ // Don't save automatically-generated SA entry into variable.
//
- if (((EFI_IPSEC_SA_DATA *) Data)->ManualSet == FALSE) {
+ if (((EFI_IPSEC_SA_DATA2 *) Data)->ManualSet == FALSE) {
return EFI_SUCCESS;
}
}
@@ -2499,7 +2733,7 @@ IpSecCopyPolicyEntry (
Buffer->Capacity += EntrySize;
TempPoint = AllocatePool (Buffer->Capacity);
- if (Buffer->Ptr == NULL) {
+ if (TempPoint == NULL) {
return EFI_OUT_OF_RESOURCES;
}
//