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; } //