/** @file
  The implementation of IPSEC_CONFIG_PROTOCOL.

  Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>

  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 "IpSecConfigImpl.h"
#include "IpSecDebug.h"

LIST_ENTRY                mConfigData[IPsecConfigDataTypeMaximum];
BOOLEAN                   mSetBySelf = FALSE;

//
// Common CompareSelector routine entry for spd/sad/pad.
//
IPSEC_COMPARE_SELECTOR    mCompareSelector[] = {
  (IPSEC_COMPARE_SELECTOR) CompareSpdSelector,
  (IPSEC_COMPARE_SELECTOR) CompareSaId,
  (IPSEC_COMPARE_SELECTOR) ComparePadId
};

//
// Common IsZeroSelector routine entry for spd/sad/pad.
//
IPSEC_IS_ZERO_SELECTOR    mIsZeroSelector[] = {
  (IPSEC_IS_ZERO_SELECTOR) IsZeroSpdSelector,
  (IPSEC_IS_ZERO_SELECTOR) IsZeroSaId,
  (IPSEC_IS_ZERO_SELECTOR) IsZeroPadId
};

//
// Common DuplicateSelector routine entry for spd/sad/pad.
//
IPSEC_DUPLICATE_SELECTOR  mDuplicateSelector[] = {
  (IPSEC_DUPLICATE_SELECTOR) DuplicateSpdSelector,
  (IPSEC_DUPLICATE_SELECTOR) DuplicateSaId,
  (IPSEC_DUPLICATE_SELECTOR) DuplicatePadId
};

//
// Common FixPolicyEntry routine entry for spd/sad/pad.
//
IPSEC_FIX_POLICY_ENTRY    mFixPolicyEntry[] = {
  (IPSEC_FIX_POLICY_ENTRY) FixSpdEntry,
  (IPSEC_FIX_POLICY_ENTRY) FixSadEntry,
  (IPSEC_FIX_POLICY_ENTRY) FixPadEntry
};

//
// Common UnfixPolicyEntry routine entry for spd/sad/pad.
//
IPSEC_FIX_POLICY_ENTRY    mUnfixPolicyEntry[] = {
  (IPSEC_FIX_POLICY_ENTRY) UnfixSpdEntry,
  (IPSEC_FIX_POLICY_ENTRY) UnfixSadEntry,
  (IPSEC_FIX_POLICY_ENTRY) UnfixPadEntry
};

//
// Common SetPolicyEntry routine entry for spd/sad/pad.
//
IPSEC_SET_POLICY_ENTRY    mSetPolicyEntry[] = {
  (IPSEC_SET_POLICY_ENTRY) SetSpdEntry,
  (IPSEC_SET_POLICY_ENTRY) SetSadEntry,
  (IPSEC_SET_POLICY_ENTRY) SetPadEntry
};

//
// Common GetPolicyEntry routine entry for spd/sad/pad.
//
IPSEC_GET_POLICY_ENTRY    mGetPolicyEntry[] = {
  (IPSEC_GET_POLICY_ENTRY) GetSpdEntry,
  (IPSEC_GET_POLICY_ENTRY) GetSadEntry,
  (IPSEC_GET_POLICY_ENTRY) GetPadEntry
};

//
// Routine entry for IpSecConfig protocol.
//
EFI_IPSEC_CONFIG_PROTOCOL mIpSecConfigInstance = {
  EfiIpSecConfigSetData,
  EfiIpSecConfigGetData,
  EfiIpSecConfigGetNextSelector,
  EfiIpSecConfigRegisterNotify,
  EfiIpSecConfigUnregisterNotify
};

/**
  Get the all IPSec configuration variables and store those variables
  to the internal data structure.

  This founction is called by IpSecConfigInitialize() that is to intialize the
  IPsecConfiguration Protocol.

  @param[in]  Private            Point to IPSEC_PRIVATE_DATA.

  @retval EFI_OUT_OF_RESOURCES   The required system resource could not be allocated.
  @retval EFI_SUCCESS            Restore the IPsec Configuration successfully.
  @retval  others                Other errors is found during the variable getting.

**/
EFI_STATUS
IpSecConfigRestore (
  IN IPSEC_PRIVATE_DATA               *Private
  );

/**
  Check if the specified EFI_IP_ADDRESS_INFO is in EFI_IP_ADDRESS_INFO list.

  @param[in]   AddressInfo         Pointer of IP_ADDRESS_INFO to be search in AddressInfo list.
  @param[in]   AddressInfoList     A list that contains IP_ADDRESS_INFOs.
  @param[in]   AddressCount        Point out how many IP_ADDRESS_INFO in the list.

  @retval  TRUE    The specified AddressInfo is in the AddressInfoList.
  @retval  FALSE   The specified AddressInfo is not in the AddressInfoList.

**/
BOOLEAN
IsInAddressInfoList(
  IN EFI_IP_ADDRESS_INFO              *AddressInfo,
  IN EFI_IP_ADDRESS_INFO              *AddressInfoList,
  IN UINT32                           AddressCount
  )
{
  UINT8  Index;

  for (Index = 0; Index < AddressCount ; Index++) {
    if (CompareMem (
          AddressInfo,
          &AddressInfoList[Index].Address,
          sizeof (EFI_IP_ADDRESS)
          ) == 0 &&
          AddressInfo->PrefixLength == AddressInfoList[Index].PrefixLength
          ) {
       return TRUE;
     }
  }
  return FALSE;
}

/**
  Compare two SPD Selectors.

  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    This two Selector have the same value in above fields.
  @retval  FALSE   Not all above fields have the same value in these two Selectors.

**/
BOOLEAN
CompareSpdSelector (
  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->LocalAddressCount != SpdSel2->RemoteAddressCount) ||
      (SpdSel1->RemoteAddressCount != SpdSel2->RemoteAddressCount &&
       SpdSel1->RemoteAddressCount != SpdSel2->LocalAddressCount) ||
       SpdSel1->NextLayerProtocol != SpdSel2->NextLayerProtocol ||
       SpdSel1->LocalPort != SpdSel2->LocalPort ||
       SpdSel1->LocalPortRange != SpdSel2->LocalPortRange ||
       SpdSel1->RemotePort != SpdSel2->RemotePort ||
       SpdSel1->RemotePortRange != SpdSel2->RemotePortRange
       ) {
    IsMatch = FALSE;
    return IsMatch;
  }

  //
  // Compare the all LocalAddress fields in the two Spdselectors.
  // First, SpdSel1->LocalAddress to SpdSel2->LocalAddress && Compare
  // SpdSel1->RemoteAddress to SpdSel2->RemoteAddress. If all match, return
  // TRUE.
  //
  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 < SpdSel2->LocalAddressCount; Index++) {
      if (!IsInAddressInfoList (
            &SpdSel2->LocalAddress[Index],
            SpdSel1->LocalAddress,
            SpdSel1->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) {
    for (Index = 0; Index < SpdSel2->RemoteAddressCount; Index++) {
      if (!IsInAddressInfoList (
            &SpdSel2->RemoteAddress[Index],
            SpdSel1->RemoteAddress,
            SpdSel1->RemoteAddressCount
            )) {
        IsMatch = FALSE;
        break;
      }
    }
  }
  //
  // Finish the one direction compare. If it is matched, return; otherwise,
  // compare the other direction.
  //
  if (IsMatch) {
    return IsMatch;
  }
  //
  // Secondly, the SpdSel1->LocalAddress doesn't equal to  SpdSel2->LocalAddress and
  // SpdSel1->RemoteAddress doesn't equal to SpdSel2->RemoteAddress. Try to compare
  // the RemoteAddress to LocalAddress.
  //
  IsMatch = TRUE;
  for (Index = 0; Index < SpdSel1->RemoteAddressCount; Index++) {
    if (!IsInAddressInfoList (
          &SpdSel1->RemoteAddress[Index],
          SpdSel2->LocalAddress,
          SpdSel2->LocalAddressCount
          )) {
      IsMatch = FALSE;
      break;
    }
  }
  if (IsMatch) {
    for (Index = 0; Index < SpdSel2->RemoteAddressCount; Index++) {
      if (!IsInAddressInfoList (
            &SpdSel2->RemoteAddress[Index],
            SpdSel1->LocalAddress,
            SpdSel1->LocalAddressCount
            )) {
        IsMatch = FALSE;
        break;
      }
    }
  }
  if (IsMatch) {
    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 < SpdSel2->LocalAddressCount; Index++) {
      if (!IsInAddressInfoList (
            &SpdSel2->LocalAddress[Index],
            SpdSel1->RemoteAddress,
            SpdSel1->RemoteAddressCount
            )) {
        IsMatch = FALSE;
        break;
      }
    }
  }
  return IsMatch;
}

/**
  Compare two SA IDs.

  @param[in]   Selector1           Pointer of first SA ID.
  @param[in]   Selector2           Pointer of second SA ID.

  @retval  TRUE    This two Selectors have the same SA ID.
  @retval  FALSE   This two Selecotrs don't have the same SA ID.

**/
BOOLEAN
CompareSaId (
  IN EFI_IPSEC_CONFIG_SELECTOR        *Selector1,
  IN EFI_IPSEC_CONFIG_SELECTOR        *Selector2
  )
{
  EFI_IPSEC_SA_ID *SaId1;
  EFI_IPSEC_SA_ID *SaId2;
  BOOLEAN         IsMatch;

  SaId1   = &Selector1->SaId;
  SaId2   = &Selector2->SaId;
  IsMatch = TRUE;

  if (CompareMem (SaId1, SaId2, sizeof (EFI_IPSEC_SA_ID)) != 0) {
    IsMatch = FALSE;
  }

  return IsMatch;
}

/**
  Compare two PAD IDs.

  @param[in]   Selector1           Pointer of first PAD ID.
  @param[in]   Selector2           Pointer of second PAD ID.

  @retval  TRUE    This two Selectors have the same PAD ID.
  @retval  FALSE   This two Selecotrs don't have the same PAD ID.

**/
BOOLEAN
ComparePadId (
  IN EFI_IPSEC_CONFIG_SELECTOR        *Selector1,
  IN EFI_IPSEC_CONFIG_SELECTOR        *Selector2
  )
{
  EFI_IPSEC_PAD_ID  *PadId1;
  EFI_IPSEC_PAD_ID  *PadId2;
  BOOLEAN           IsMatch;

  PadId1  = &Selector1->PadId;
  PadId2  = &Selector2->PadId;
  IsMatch = TRUE;

  //
  // Compare the PeerIdValid fields in PadId.
  //
  if (PadId1->PeerIdValid != PadId2->PeerIdValid) {
    IsMatch = FALSE;
  }
  //
  // Compare the PeerId fields in PadId if PeerIdValid is true.
  //
  if (IsMatch &&
      PadId1->PeerIdValid &&
      AsciiStriCmp ((CONST CHAR8 *) PadId1->Id.PeerId, (CONST CHAR8 *) PadId2->Id.PeerId) != 0
      ) {
    IsMatch = FALSE;
  }
  //
  // Compare the IpAddress fields in PadId if PeerIdValid is false.
  //
  if (IsMatch &&
      !PadId1->PeerIdValid &&
      (PadId1->Id.IpAddress.PrefixLength != PadId2->Id.IpAddress.PrefixLength ||
       CompareMem (&PadId1->Id.IpAddress.Address, &PadId2->Id.IpAddress.Address, sizeof (EFI_IP_ADDRESS)) != 0)
      ) {
    IsMatch = FALSE;
  }

  return IsMatch;
}

/**
  Check if the SPD Selector is Zero by its LocalAddressCount and RemoteAddressCount
  fields.

  @param[in]  Selector      Pointer of the SPD Selector.

  @retval     TRUE          If the SPD Selector is Zero.
  @retval     FALSE         If the SPD Selector is not Zero.

**/
BOOLEAN
IsZeroSpdSelector (
  IN EFI_IPSEC_CONFIG_SELECTOR        *Selector
  )
{
  EFI_IPSEC_SPD_SELECTOR  *SpdSel;
  BOOLEAN                 IsZero;

  SpdSel  = &Selector->SpdSelector;
  IsZero  = FALSE;

  if (SpdSel->LocalAddressCount == 0 && SpdSel->RemoteAddressCount == 0) {
    IsZero = TRUE;
  }

  return IsZero;
}

/**
  Check if the SA ID is Zero by its DestAddress.

  @param[in]  Selector      Pointer of the SA ID.

  @retval     TRUE          If the SA ID is Zero.
  @retval     FALSE         If the SA ID is not Zero.

**/
BOOLEAN
IsZeroSaId (
  IN EFI_IPSEC_CONFIG_SELECTOR        *Selector
  )
{
  EFI_IP_ADDRESS  *DestAddr;
  EFI_IP_ADDRESS  ZeroAddr;
  BOOLEAN         IsZero;

  DestAddr  = &Selector->SaId.DestAddress;
  IsZero    = FALSE;

  ZeroMem (&ZeroAddr, sizeof (EFI_IP_ADDRESS));

  if (CompareMem (DestAddr, &ZeroAddr, sizeof (EFI_IP_ADDRESS)) == 0) {
    IsZero = TRUE;
  }

  return IsZero;
}

/**
  Check if the PAD ID is Zero.

  @param[in]  Selector      Pointer of the PAD ID.

  @retval     TRUE          If the PAD ID is Zero.
  @retval     FALSE         If the PAD ID is not Zero.

**/
BOOLEAN
IsZeroPadId (
  IN EFI_IPSEC_CONFIG_SELECTOR        *Selector
  )
{
  EFI_IPSEC_PAD_ID  *PadId;
  EFI_IPSEC_PAD_ID  ZeroId;
  BOOLEAN           IsZero;

  PadId   = &Selector->PadId;
  IsZero  = FALSE;

  ZeroMem (&ZeroId, sizeof (EFI_IPSEC_PAD_ID));

  if (CompareMem (PadId, &ZeroId, sizeof (EFI_IPSEC_PAD_ID)) == 0) {
    IsZero = TRUE;
  }

  return IsZero;
}

/**
  Copy Source SPD Selector to the Destination SPD Selector.

  @param[in, out] DstSel             Pointer of Destination SPD Selector.
  @param[in]      SrcSel             Pointer of Source SPD Selector.
  @param[in, out] Size               The size of the Destination SPD Selector. If it
                                     not NULL and its value less than the size of
                                     Source SPD Selector, the value of Source SPD
                                     Selector's size will be passed to caller by this
                                     parameter.

  @retval EFI_INVALID_PARAMETER  If the Destination or Source SPD Selector is NULL
  @retval EFI_BUFFER_TOO_SMALL   If the input Size is less than size of the Source SPD Selector.
  @retval EFI_SUCCESS            Copy Source SPD Selector to the Destination SPD
                                 Selector successfully.

**/
EFI_STATUS
DuplicateSpdSelector (
  IN OUT EFI_IPSEC_CONFIG_SELECTOR    *DstSel,
  IN     EFI_IPSEC_CONFIG_SELECTOR    *SrcSel,
  IN OUT UINTN                        *Size
  )
{
  EFI_IPSEC_SPD_SELECTOR  *Dst;
  EFI_IPSEC_SPD_SELECTOR  *Src;

  Dst = &DstSel->SpdSelector;
  Src = &SrcSel->SpdSelector;

  if (Dst == NULL || Src == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (Size != NULL && (*Size) < SIZE_OF_SPD_SELECTOR (Src)) {
    *Size = SIZE_OF_SPD_SELECTOR (Src);
    return EFI_BUFFER_TOO_SMALL;
  }
  //
  // Copy the base structure of spd selector.
  //
  CopyMem (Dst, Src, sizeof (EFI_IPSEC_SPD_SELECTOR));

  //
  // Copy the local address array of spd selector.
  //
  Dst->LocalAddress = (EFI_IP_ADDRESS_INFO *) (Dst + 1);
  CopyMem (
    Dst->LocalAddress,
    Src->LocalAddress,
    sizeof (EFI_IP_ADDRESS_INFO) * Dst->LocalAddressCount
    );

  //
  // Copy the remote address array of spd selector.
  //
  Dst->RemoteAddress = Dst->LocalAddress + Dst->LocalAddressCount;
  CopyMem (
    Dst->RemoteAddress,
    Src->RemoteAddress,
    sizeof (EFI_IP_ADDRESS_INFO) * Dst->RemoteAddressCount
    );

  return EFI_SUCCESS;
}

/**
  Copy Source SA ID to the Destination SA ID.

  @param[in, out] DstSel             Pointer of Destination SA ID.
  @param[in]      SrcSel             Pointer of Source SA ID.
  @param[in, out] Size               The size of the Destination SA ID. If it
                                     not NULL and its value less than the size of
                                     Source SA ID, the value of Source SA ID's size
                                     will be passed to caller by this parameter.

  @retval EFI_INVALID_PARAMETER  If the Destination or Source SA ID is NULL.
  @retval EFI_BUFFER_TOO_SMALL   If the input Size less than size of source SA ID.
  @retval EFI_SUCCESS            Copy Source SA ID  to the Destination SA ID successfully.

**/
EFI_STATUS
DuplicateSaId (
  IN OUT EFI_IPSEC_CONFIG_SELECTOR    *DstSel,
  IN     EFI_IPSEC_CONFIG_SELECTOR    *SrcSel,
  IN OUT UINTN                        *Size
  )
{
  EFI_IPSEC_SA_ID *Dst;
  EFI_IPSEC_SA_ID *Src;

  Dst = &DstSel->SaId;
  Src = &SrcSel->SaId;

  if (Dst == NULL || Src == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (Size != NULL && *Size < sizeof (EFI_IPSEC_SA_ID)) {
    *Size = sizeof (EFI_IPSEC_SA_ID);
    return EFI_BUFFER_TOO_SMALL;
  }

  CopyMem (Dst, Src, sizeof (EFI_IPSEC_SA_ID));

  return EFI_SUCCESS;
}

/**
  Copy Source PAD ID to the Destination PAD ID.

  @param[in, out] DstSel             Pointer of Destination PAD ID.
  @param[in]      SrcSel             Pointer of Source PAD ID.
  @param[in, out] Size               The size of the Destination PAD ID. If it
                                     not NULL and its value less than the size of
                                     Source PAD ID, the value of Source PAD ID's size
                                     will be passed to caller by this parameter.

  @retval EFI_INVALID_PARAMETER  If the Destination or Source PAD ID is NULL.
  @retval EFI_BUFFER_TOO_SMALL   If the input Size less than size of source PAD ID .
  @retval EFI_SUCCESS            Copy Source PAD ID  to the Destination PAD ID successfully.

**/
EFI_STATUS
DuplicatePadId (
  IN OUT EFI_IPSEC_CONFIG_SELECTOR    *DstSel,
  IN     EFI_IPSEC_CONFIG_SELECTOR    *SrcSel,
  IN OUT UINTN                        *Size
  )
{
  EFI_IPSEC_PAD_ID  *Dst;
  EFI_IPSEC_PAD_ID  *Src;

  Dst = &DstSel->PadId;
  Src = &SrcSel->PadId;

  if (Dst == NULL || Src == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (Size != NULL && *Size < sizeof (EFI_IPSEC_PAD_ID)) {
    *Size = sizeof (EFI_IPSEC_PAD_ID);
    return EFI_BUFFER_TOO_SMALL;
  }

  CopyMem (Dst, Src, sizeof (EFI_IPSEC_PAD_ID));

  return EFI_SUCCESS;
}

/**
  Fix the value of some members of SPD Selector.

  This function is called by IpSecCopyPolicyEntry()which copy the Policy
  Entry into the Variable. Since some members in SPD Selector are pointers,
  a physical address to relative address convertion is required before copying
  this SPD entry into the variable.

  @param[in]       Selector              Pointer of SPD Selector.
  @param[in, out]  Data                  Pointer of SPD Data.

**/
VOID
FixSpdEntry (
  IN     EFI_IPSEC_SPD_SELECTOR            *Selector,
  IN OUT EFI_IPSEC_SPD_DATA                *Data
  )
{
  //
  // 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);
  FIX_REF_BUF_ADDR (Selector->RemoteAddress, Selector);

  if (Data->ProcessingPolicy != NULL) {
    if (Data->ProcessingPolicy->TunnelOption != NULL) {
      FIX_REF_BUF_ADDR (Data->ProcessingPolicy->TunnelOption, Data);
    }

    FIX_REF_BUF_ADDR (Data->ProcessingPolicy, Data);
  }

}

/**
  Fix the value of some members of SA ID.

  This function is called by IpSecCopyPolicyEntry()which copy the Policy
  Entry into the Variable. Since some members in SA ID are pointers,
  a physical address to relative address conversion is required before copying
  this SAD into the variable.

  @param[in]       SaId                  Pointer of SA ID
  @param[in, out]  Data                  Pointer of SA Data.

**/
VOID
FixSadEntry (
  IN     EFI_IPSEC_SA_ID                  *SaId,
  IN OUT EFI_IPSEC_SA_DATA                *Data
  )
{
  //
  // 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) {
    FIX_REF_BUF_ADDR (Data->AlgoInfo.EspAlgoInfo.AuthKey, Data);
  }

  if (SaId->Proto == EfiIPsecESP && Data->AlgoInfo.EspAlgoInfo.EncKey != NULL) {
    FIX_REF_BUF_ADDR (Data->AlgoInfo.EspAlgoInfo.EncKey, Data);
  }

  if (Data->SpdSelector != NULL) {
    if (Data->SpdSelector->LocalAddress != NULL) {
      FIX_REF_BUF_ADDR (Data->SpdSelector->LocalAddress, Data);
    }

    FIX_REF_BUF_ADDR (Data->SpdSelector->RemoteAddress, Data);
    FIX_REF_BUF_ADDR (Data->SpdSelector, Data);
  }

}

/**
  Fix the value of some members of PAD ID.

  This function is called by IpSecCopyPolicyEntry()which copy the Policy
  Entry into the Variable. Since some members in PAD ID are pointers,
  a physical address to relative address conversion is required before copying
  this PAD into the variable.

  @param[in]       PadId              Pointer of PAD ID.
  @param[in, out]  Data               Pointer of PAD Data.

**/
VOID
FixPadEntry (
  IN     EFI_IPSEC_PAD_ID                  *PadId,
  IN OUT EFI_IPSEC_PAD_DATA                *Data
  )
{
  //
  // It assumes that all ref buffers in pad selector and data are
  // stored in the continous memory and close to the base structure.
  //
  if (Data->AuthData != NULL) {
    FIX_REF_BUF_ADDR (Data->AuthData, Data);
  }

  if (Data->RevocationData != NULL) {
    FIX_REF_BUF_ADDR (Data->RevocationData, Data);
  }

}

/**
  Recover the value of some members of SPD Selector.

  This function is corresponding to FixSpdEntry(). It recovers the value of members
  of SPD Selector that are fixed by FixSpdEntry().

  @param[in, out]  Selector              Pointer of SPD Selector.
  @param[in, out]  Data                  Pointer of SPD Data.

**/
VOID
UnfixSpdEntry (
  IN OUT EFI_IPSEC_SPD_SELECTOR           *Selector,
  IN OUT EFI_IPSEC_SPD_DATA               *Data
  )
{
  //
  // 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);
  UNFIX_REF_BUF_ADDR (Selector->RemoteAddress, Selector);

  if (Data->ProcessingPolicy != NULL) {
    UNFIX_REF_BUF_ADDR (Data->ProcessingPolicy, Data);
    if (Data->ProcessingPolicy->TunnelOption != NULL) {
      UNFIX_REF_BUF_ADDR (Data->ProcessingPolicy->TunnelOption, Data);
    }
  }

}

/**
  Recover the value of some members of SA ID.

  This function is corresponding to FixSadEntry(). It recovers the value of members
  of SAD ID that are fixed by FixSadEntry().

  @param[in, out]  SaId              Pointer of SAD ID.
  @param[in, out]  Data              Pointer of SAD Data.

**/
VOID
UnfixSadEntry (
  IN OUT EFI_IPSEC_SA_ID                     *SaId,
  IN OUT EFI_IPSEC_SA_DATA                   *Data
  )
{
  //
  // 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) {
    UNFIX_REF_BUF_ADDR (Data->AlgoInfo.EspAlgoInfo.AuthKey, Data);
  }

  if (SaId->Proto == EfiIPsecESP && Data->AlgoInfo.EspAlgoInfo.EncKey != NULL) {
    UNFIX_REF_BUF_ADDR (Data->AlgoInfo.EspAlgoInfo.EncKey, Data);
  }

  if (Data->SpdSelector != NULL) {
    UNFIX_REF_BUF_ADDR (Data->SpdSelector, Data);
    if (Data->SpdSelector->LocalAddress != NULL) {
      UNFIX_REF_BUF_ADDR (Data->SpdSelector->LocalAddress, Data);
    }

    UNFIX_REF_BUF_ADDR (Data->SpdSelector->RemoteAddress, Data);
  }

}

/**
  Recover the value of some members of PAD ID.

  This function is corresponding to FixPadEntry(). It recovers the value of members
  of PAD ID that are fixed by FixPadEntry().

  @param[in]       PadId              Pointer of PAD ID.
  @param[in, out]  Data               Pointer of PAD Data.

**/
VOID
UnfixPadEntry (
  IN     EFI_IPSEC_PAD_ID                 *PadId,
  IN OUT EFI_IPSEC_PAD_DATA               *Data
  )
{
  //
  // It assumes that all ref buffers in pad selector and data are
  // stored in the continous memory and close to the base structure.
  //
  if (Data->AuthData != NULL) {
    UNFIX_REF_BUF_ADDR (Data->AuthData, Data);
  }

  if (Data->RevocationData != NULL) {
    UNFIX_REF_BUF_ADDR (Data->RevocationData, Data);
  }

}

/**
  Set the security policy information for the EFI IPsec driver.

  The IPsec configuration data has a unique selector/identifier separately to
  identify a data entry.

  @param[in]  Selector           Pointer to an entry selector on operated
                                 configuration data specified by DataType.
                                 A NULL Selector causes the entire specified-type
                                 configuration information to be flushed.
  @param[in]  Data               The data buffer to be set. The structure
                                 of the data buffer should be EFI_IPSEC_SPD_DATA.
  @param[in]  Context            Pointer to one entry selector that describes
                                 the expected position the new data entry will
                                 be added. If Context is NULL, the new entry will
                                 be appended the end of database.

  @retval EFI_INVALID_PARAMETER  One or more of the following are TRUE:
                                   - Selector is not NULL and its LocalAddress
                                     is NULL or its RemoteAddress is NULL.
                                   - Data is not NULL and its Action is Protected
                                     and its plolicy is NULL.
                                   - Data is not NULL, its Action is not protected,
                                     and its policy is not NULL.
                                   - The Action of Data is Protected, its policy
                                     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.
  @retval EFI_OUT_OF_RESOURCED  The required system resource could not be allocated.
  @retval EFI_SUCCESS           The specified configuration data was obtained successfully.

**/
EFI_STATUS
SetSpdEntry (
  IN EFI_IPSEC_CONFIG_SELECTOR       *Selector,
  IN VOID                            *Data,
  IN VOID                            *Context OPTIONAL
  )
{
  EFI_IPSEC_SPD_SELECTOR  *SpdSel;
  EFI_IPSEC_SPD_DATA      *SpdData;
  EFI_IPSEC_SPD_SELECTOR  *InsertBefore;
  LIST_ENTRY              *SpdList;
  LIST_ENTRY              *SadList;
  LIST_ENTRY              *SpdSas;
  LIST_ENTRY              *EntryInsertBefore;
  LIST_ENTRY              *Entry;
  LIST_ENTRY              *NextEntry;
  LIST_ENTRY              *Entry2;
  IPSEC_SPD_ENTRY         *SpdEntry;
  IPSEC_SAD_ENTRY         *SadEntry;
  UINTN                   SpdEntrySize;
  UINTN                   Index;

  SpdSel        = (Selector == NULL) ? NULL : &Selector->SpdSelector;
  SpdData       = (Data == NULL) ? NULL : (EFI_IPSEC_SPD_DATA *) Data;
  InsertBefore  = (Context == NULL) ? NULL : &((EFI_IPSEC_CONFIG_SELECTOR *) Context)->SpdSelector;
  SpdList       = &mConfigData[IPsecConfigDataTypeSpd];

  if (SpdSel != NULL) {
    if (SpdSel->LocalAddress == NULL || SpdSel->RemoteAddress == NULL) {
      return EFI_INVALID_PARAMETER;
    }
  }

  if (SpdData != NULL) {
    if ((SpdData->Action == EfiIPsecActionProtect && SpdData->ProcessingPolicy == NULL) ||
        (SpdData->Action != EfiIPsecActionProtect && SpdData->ProcessingPolicy != NULL)
        ) {
      return EFI_INVALID_PARAMETER;
    }

    if (SpdData->Action == EfiIPsecActionProtect) {
      if ((SpdData->ProcessingPolicy->Mode == EfiIPsecTunnel && SpdData->ProcessingPolicy->TunnelOption == NULL) ||
          (SpdData->ProcessingPolicy->Mode != EfiIPsecTunnel && SpdData->ProcessingPolicy->TunnelOption != NULL)
          ) {
        return EFI_INVALID_PARAMETER;
      }
    }
  }
  //
  // The default behavior is to insert the node ahead of the header.
  //
  EntryInsertBefore = SpdList;

  //
  // Remove the existed spd entry.
  //
  NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, SpdList) {

    SpdEntry = IPSEC_SPD_ENTRY_FROM_LIST (Entry);

    if (SpdSel == NULL ||
        CompareSpdSelector ((EFI_IPSEC_CONFIG_SELECTOR *) SpdEntry->Selector, (EFI_IPSEC_CONFIG_SELECTOR *) SpdSel)
        ) {
      //
      // Record the existed entry position to keep the original order.
      //
      EntryInsertBefore = SpdEntry->List.ForwardLink;
      RemoveEntryList (&SpdEntry->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;
      }
      //
      // Free the existed spd entry
      //
      FreePool (SpdEntry);
    }
  }
  //
  // Return success here if only want to remove the spd entry.
  //
  if (SpdData == NULL || SpdSel == NULL) {
    return EFI_SUCCESS;
  }
  //
  // Search the appointed entry position if InsertBefore is not NULL.
  //
  if (InsertBefore != NULL) {

    NET_LIST_FOR_EACH (Entry, SpdList) {
      SpdEntry = IPSEC_SPD_ENTRY_FROM_LIST (Entry);

      if (CompareSpdSelector (
            (EFI_IPSEC_CONFIG_SELECTOR *) SpdEntry->Selector,
            (EFI_IPSEC_CONFIG_SELECTOR *) InsertBefore
            )) {
        EntryInsertBefore = Entry;
        break;
      }
    }
  }

  //
  // Do Padding for the different Arch.
  //
  SpdEntrySize  = ALIGN_VARIABLE (sizeof (IPSEC_SPD_ENTRY));
  SpdEntrySize  = ALIGN_VARIABLE (SpdEntrySize + (UINTN)SIZE_OF_SPD_SELECTOR (SpdSel));
  SpdEntrySize += IpSecGetSizeOfEfiSpdData (SpdData);

  SpdEntry = AllocateZeroPool (SpdEntrySize);

  if (SpdEntry == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }
  //
  // Fix the address of Selector and Data buffer and copy them, which is
  // 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 (
                                            ((UINT8 *) SpdEntry->Selector + SIZE_OF_SPD_SELECTOR (SpdSel)),
                                            sizeof (UINTN)
                                            );

  DuplicateSpdSelector (
    (EFI_IPSEC_CONFIG_SELECTOR *) SpdEntry->Selector,
    (EFI_IPSEC_CONFIG_SELECTOR *) SpdSel,
    NULL
    );

  CopyMem (
    SpdEntry->Data->Name,
    SpdData->Name,
    sizeof (SpdData->Name)
    );
  SpdEntry->Data->PackageFlag = SpdData->PackageFlag;
  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.
  //
  if (SpdData->Action != EfiIPsecActionProtect) {
    SpdEntry->Data->ProcessingPolicy = NULL;
  } else {
    SpdEntry->Data->ProcessingPolicy = (EFI_IPSEC_PROCESS_POLICY *) ALIGN_POINTER (
                                                                      SpdEntry->Data + 1,
                                                                      sizeof (UINTN)
                                                                      );
    IpSecDuplicateProcessPolicy (SpdEntry->Data->ProcessingPolicy, SpdData->ProcessingPolicy);
  }
  //
  // Update the sas list of the new spd entry.
  //
  InitializeListHead (&SpdEntry->Data->Sas);

  SadList = &mConfigData[IPsecConfigDataTypeSad];

  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;
      }
    }
  }
  //
  // Insert the new spd entry.
  //
  InsertTailList (EntryInsertBefore, &SpdEntry->List);

  return EFI_SUCCESS;
}

/**
  Set the security association information for the EFI IPsec driver.

  The IPsec configuration data has a unique selector/identifier separately to
  identify a data entry.

  @param[in]  Selector           Pointer to an entry selector on operated
                                 configuration data specified by DataType.
                                 A NULL Selector causes the entire specified-type
                                 configuration information to be flushed.
  @param[in]  Data               The data buffer to be set. The structure
                                 of the data buffer should be EFI_IPSEC_SA_DATA.
  @param[in]  Context            Pointer to one entry selector which describes
                                 the expected position the new data entry will
                                 be added. If Context is NULL,the new entry will
                                 be appended the end of database.

  @retval EFI_OUT_OF_RESOURCED  The required system resource could not be allocated.
  @retval EFI_SUCCESS           The specified configuration data was obtained successfully.

**/
EFI_STATUS
SetSadEntry (
  IN EFI_IPSEC_CONFIG_SELECTOR       *Selector,
  IN VOID                            *Data,
  IN VOID                            *Context OPTIONAL
  )
{
  IPSEC_SAD_ENTRY   *SadEntry;
  IPSEC_SPD_ENTRY   *SpdEntry;
  LIST_ENTRY        *Entry;
  LIST_ENTRY        *NextEntry;
  LIST_ENTRY        *SadList;
  LIST_ENTRY        *SpdList;
  EFI_IPSEC_SA_ID   *SaId;
  EFI_IPSEC_SA_DATA *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;
  InsertBefore  = (Context == NULL) ? NULL : &((EFI_IPSEC_CONFIG_SELECTOR *) Context)->SaId;
  SadList       = &mConfigData[IPsecConfigDataTypeSad];

  //
  // The default behavior is to insert the node ahead of the header.
  //
  EntryInsertBefore = SadList;

  //
  // Remove the existed sad entry.
  //
  NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, SadList) {

    SadEntry = IPSEC_SAD_ENTRY_FROM_LIST (Entry);

    if (SaId == NULL ||
        CompareSaId (
          (EFI_IPSEC_CONFIG_SELECTOR *) SadEntry->Id,
          (EFI_IPSEC_CONFIG_SELECTOR *) SaId
          )) {
      //
      // Record the existed entry position to keep the original order.
      //
      EntryInsertBefore = SadEntry->List.ForwardLink;

      //
      // Update the related sad.byspd field.
      //
      if (SadEntry->Data->SpdEntry != NULL) {
        RemoveEntryList (&SadEntry->BySpd);
      }

      RemoveEntryList (&SadEntry->List);
      FreePool (SadEntry);
    }
  }
  //
  // Return success here if only want to remove the sad entry
  //
  if (SaData == NULL || SaId == NULL) {
    return EFI_SUCCESS;
  }
  //
  // Search the appointed entry position if InsertBefore is not NULL.
  //
  if (InsertBefore != NULL) {

    NET_LIST_FOR_EACH (Entry, SadList) {
      SadEntry = IPSEC_SAD_ENTRY_FROM_LIST (Entry);

      if (CompareSaId (
           (EFI_IPSEC_CONFIG_SELECTOR *) SadEntry->Id,
           (EFI_IPSEC_CONFIG_SELECTOR *) InsertBefore
           )) {
        EntryInsertBefore = Entry;
        break;
      }
    }
  }

  //
  // 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 (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;
  }

  SadEntry      = AllocateZeroPool (SadEntrySize);

  if (SadEntry == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }
  //
  // Fix the address of Id and Data buffer and copy them, which is
  // 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));

  CopyMem (SadEntry->Id, SaId, sizeof (EFI_IPSEC_SA_ID));

  SadEntry->Data->Mode                  = SaData->Mode;
  SadEntry->Data->SequenceNumber        = SaData->SNCount;
  SadEntry->Data->AntiReplayWindowSize  = SaData->AntiReplayWindows;

  ZeroMem (
    &SadEntry->Data->AntiReplayBitmap,
    sizeof (SadEntry->Data->AntiReplayBitmap)
    );

  ZeroMem (
    &SadEntry->Data->AlgoInfo,
    sizeof (EFI_IPSEC_ALGO_INFO)
    );

  SadEntry->Data->AlgoInfo.EspAlgoInfo.AuthAlgoId     = SaData->AlgoInfo.EspAlgoInfo.AuthAlgoId;
  SadEntry->Data->AlgoInfo.EspAlgoInfo.AuthKeyLength  = SaData->AlgoInfo.EspAlgoInfo.AuthKeyLength;

  if (SadEntry->Data->AlgoInfo.EspAlgoInfo.AuthKeyLength != 0) {
    SadEntry->Data->AlgoInfo.EspAlgoInfo.AuthKey = (VOID *) ALIGN_POINTER ((SadEntry->Data + 1), sizeof (UINTN));
    CopyMem (
      SadEntry->Data->AlgoInfo.EspAlgoInfo.AuthKey,
      SaData->AlgoInfo.EspAlgoInfo.AuthKey,
      SadEntry->Data->AlgoInfo.EspAlgoInfo.AuthKeyLength
      );
  }

  if (SaId->Proto == EfiIPsecESP) {
    SadEntry->Data->AlgoInfo.EspAlgoInfo.EncAlgoId    = SaData->AlgoInfo.EspAlgoInfo.EncAlgoId;
    SadEntry->Data->AlgoInfo.EspAlgoInfo.EncKeyLength = SaData->AlgoInfo.EspAlgoInfo.EncKeyLength;

    if (SadEntry->Data->AlgoInfo.EspAlgoInfo.EncKeyLength != 0) {
      SadEntry->Data->AlgoInfo.EspAlgoInfo.EncKey = (VOID *) ALIGN_POINTER (
                                                               ((UINT8 *) (SadEntry->Data + 1) +
                                                                 SadEntry->Data->AlgoInfo.EspAlgoInfo.AuthKeyLength),
                                                                 sizeof (UINTN)
                                                                 );
      CopyMem (
        SadEntry->Data->AlgoInfo.EspAlgoInfo.EncKey,
        SaData->AlgoInfo.EspAlgoInfo.EncKey,
        SadEntry->Data->AlgoInfo.EspAlgoInfo.EncKeyLength
        );
    }
  }

  CopyMem (
    &SadEntry->Data->SaLifetime,
    &SaData->SaLifetime,
    sizeof (EFI_IPSEC_SA_LIFETIME)
    );

  SadEntry->Data->PathMTU     = SaData->PathMTU;
  SadEntry->Data->SpdEntry    = NULL;
  SadEntry->Data->ESNEnabled  = FALSE;
  SadEntry->Data->ManualSet   = SaData->ManualSet;

  //
  // 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
          ) && SpdEntry->Data->Action == EfiIPsecActionProtect) {
      SadEntry->Data->SpdEntry = SpdEntry;
      InsertTailList (&SpdEntry->Data->Sas, &SadEntry->BySpd);
    }
  }
  //
  // Insert the new sad entry.
  //
  InsertTailList (EntryInsertBefore, &SadEntry->List);

  return EFI_SUCCESS;
}

/**
  Set the peer authorization configuration information for the EFI IPsec driver.

  The IPsec configuration data has a unique selector/identifier separately to
  identify a data entry.

  @param[in]  Selector           Pointer to an entry selector on operated
                                 configuration data specified by DataType.
                                 A NULL Selector causes the entire specified-type
                                 configuration information to be flushed.
  @param[in]  Data               The data buffer to be set. The structure
                                 of the data buffer should be EFI_IPSEC_PAD_DATA.
  @param[in]  Context            Pointer to one entry selector that describes
                                 the expected position the new data entry will
                                 be added. If Context is NULL, the new entry will
                                 be appended the end of database.

  @retval EFI_OUT_OF_RESOURCES  The required system resources could not be allocated.
  @retval EFI_SUCCESS           The specified configuration data was obtained successfully.

**/
EFI_STATUS
SetPadEntry (
  IN EFI_IPSEC_CONFIG_SELECTOR       *Selector,
  IN VOID                            *Data,
  IN VOID                            *Context OPTIONAL
  )
{
  IPSEC_PAD_ENTRY     *PadEntry;
  EFI_IPSEC_PAD_ID    *PadId;
  EFI_IPSEC_PAD_DATA  *PadData;
  LIST_ENTRY          *PadList;
  LIST_ENTRY          *Entry;
  LIST_ENTRY          *NextEntry;
  EFI_IPSEC_PAD_ID    *InsertBefore;
  LIST_ENTRY          *EntryInsertBefore;
  UINTN               PadEntrySize;

  PadId         = (Selector == NULL) ? NULL : &Selector->PadId;
  PadData       = (Data == NULL) ? NULL : (EFI_IPSEC_PAD_DATA *) Data;
  InsertBefore  = (Context == NULL) ? NULL : &((EFI_IPSEC_CONFIG_SELECTOR *) Context)->PadId;
  PadList       = &mConfigData[IPsecConfigDataTypePad];

  //
  // The default behavior is to insert the node ahead of the header.
  //
  EntryInsertBefore = PadList;

  //
  // Remove the existed pad entry.
  //
  NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, PadList) {

    PadEntry = IPSEC_PAD_ENTRY_FROM_LIST (Entry);

    if (PadId == NULL ||
        ComparePadId ((EFI_IPSEC_CONFIG_SELECTOR *) PadEntry->Id, (EFI_IPSEC_CONFIG_SELECTOR *) PadId)
        ) {
      //
      // Record the existed entry position to keep the original order.
      //
      EntryInsertBefore = PadEntry->List.ForwardLink;
      RemoveEntryList (&PadEntry->List);

      FreePool (PadEntry);
    }
  }
  //
  // Return success here if only want to remove the pad entry
  //
  if (PadData == NULL || PadId == NULL) {
    return EFI_SUCCESS;
  }
  //
  // Search the appointed entry position if InsertBefore is not NULL.
  //
  if (InsertBefore != NULL) {

    NET_LIST_FOR_EACH (Entry, PadList) {
      PadEntry = IPSEC_PAD_ENTRY_FROM_LIST (Entry);

      if (ComparePadId (
            (EFI_IPSEC_CONFIG_SELECTOR *) PadEntry->Id,
            (EFI_IPSEC_CONFIG_SELECTOR *) InsertBefore
            )) {
        EntryInsertBefore = Entry;
        break;
      }
    }
  }

  //
  // Do PADDING for different arch.
  //
  PadEntrySize  = ALIGN_VARIABLE (sizeof (IPSEC_PAD_ENTRY));
  PadEntrySize  = ALIGN_VARIABLE (PadEntrySize + sizeof (EFI_IPSEC_PAD_ID));
  PadEntrySize  = ALIGN_VARIABLE (PadEntrySize + sizeof (EFI_IPSEC_PAD_DATA));
  PadEntrySize  = ALIGN_VARIABLE (PadEntrySize + (PadData->AuthData != NULL ? PadData->AuthDataSize : 0));
  PadEntrySize += PadData->RevocationData != NULL ? PadData->RevocationDataSize : 0;

  PadEntry      = AllocateZeroPool (PadEntrySize);

  if (PadEntry == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }
  //
  // Fix the address of Id and Data buffer and copy them, which is
  // continous memory and close to the base structure of pad entry.
  //
  PadEntry->Id    = (EFI_IPSEC_PAD_ID *) ALIGN_POINTER ((PadEntry + 1), sizeof (UINTN));
  PadEntry->Data  = (EFI_IPSEC_PAD_DATA *) ALIGN_POINTER ((PadEntry->Id + 1), sizeof (UINTN));

  CopyMem (PadEntry->Id, PadId, sizeof (EFI_IPSEC_PAD_ID));

  PadEntry->Data->AuthProtocol  = PadData->AuthProtocol;
  PadEntry->Data->AuthMethod    = PadData->AuthMethod;
  PadEntry->Data->IkeIdFlag     = PadData->IkeIdFlag;

  if (PadData->AuthData != NULL) {
    PadEntry->Data->AuthDataSize  = PadData->AuthDataSize;
    PadEntry->Data->AuthData      = (VOID *) ALIGN_POINTER (PadEntry->Data + 1, sizeof (UINTN));
    CopyMem (
      PadEntry->Data->AuthData,
      PadData->AuthData,
      PadData->AuthDataSize
      );
  } else {
    PadEntry->Data->AuthDataSize  = 0;
    PadEntry->Data->AuthData      = NULL;
  }

  if (PadData->RevocationData != NULL) {
    PadEntry->Data->RevocationDataSize  = PadData->RevocationDataSize;
    PadEntry->Data->RevocationData      = (VOID *) ALIGN_POINTER (
                                                    ((UINT8 *) (PadEntry->Data + 1) + PadData->AuthDataSize),
                                                    sizeof (UINTN)
                                                    );
    CopyMem (
      PadEntry->Data->RevocationData,
      PadData->RevocationData,
      PadData->RevocationDataSize
      );
  } else {
    PadEntry->Data->RevocationDataSize  = 0;
    PadEntry->Data->RevocationData      = NULL;
  }
  //
  // Insert the new pad entry.
  //
  InsertTailList (EntryInsertBefore, &PadEntry->List);

  return EFI_SUCCESS;
}

/**
  This function lookup the data entry from IPsec SPD. Return the configuration
  value of the specified SPD Entry.

  @param[in]      Selector      Pointer to an entry selector which is an identifier
                                of the SPD entry.
  @param[in, out] DataSize      On output the size of data returned in Data.
  @param[out]     Data          The buffer to return the contents of the IPsec
                                configuration data. The type of the data buffer
                                is associated with the DataType.

  @retval EFI_SUCCESS           The specified configuration data was obtained successfully.
  @retval EFI_INVALID_PARAMETER Data is NULL and *DataSize is not zero.
  @retval EFI_NOT_FOUND         The configuration data specified by Selector is not found.
  @retval EFI_BUFFER_TOO_SMALL  The DataSize is too small for the result. DataSize has been
                                updated with the size needed to complete the request.

**/
EFI_STATUS
GetSpdEntry (
  IN     EFI_IPSEC_CONFIG_SELECTOR       *Selector,
  IN OUT UINTN                           *DataSize,
     OUT VOID                            *Data
  )
{
  IPSEC_SPD_ENTRY         *SpdEntry;
  IPSEC_SAD_ENTRY         *SadEntry;
  EFI_IPSEC_SPD_SELECTOR  *SpdSel;
  EFI_IPSEC_SPD_DATA      *SpdData;
  LIST_ENTRY              *SpdList;
  LIST_ENTRY              *SpdSas;
  LIST_ENTRY              *Entry;
  UINTN                   RequiredSize;

  SpdSel  = &Selector->SpdSelector;
  SpdData = (EFI_IPSEC_SPD_DATA *) Data;
  SpdList = &mConfigData[IPsecConfigDataTypeSpd];

  NET_LIST_FOR_EACH (Entry, SpdList) {
    SpdEntry = IPSEC_SPD_ENTRY_FROM_LIST (Entry);

    //
    // Find the required spd entry
    //
    if (CompareSpdSelector (
          (EFI_IPSEC_CONFIG_SELECTOR *) SpdSel,
          (EFI_IPSEC_CONFIG_SELECTOR *) SpdEntry->Selector
          )) {

      RequiredSize = IpSecGetSizeOfSpdData (SpdEntry->Data);
      if (*DataSize < RequiredSize) {
        *DataSize = RequiredSize;
        return EFI_BUFFER_TOO_SMALL;
      }

      if (SpdData == NULL) {
        return EFI_INVALID_PARAMETER;
      }

      *DataSize = RequiredSize;

      //
      // Extract and fill all SaId array from the spd.sas list
      //
      SpdSas              = &SpdEntry->Data->Sas;
      SpdData->SaIdCount  = 0;

      NET_LIST_FOR_EACH (Entry, SpdSas) {
        SadEntry = IPSEC_SAD_ENTRY_FROM_SPD (Entry);
        CopyMem (
          &SpdData->SaId[SpdData->SaIdCount++],
          SadEntry->Id,
          sizeof (EFI_IPSEC_SA_ID)
          );
      }
      //
      // 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;

      if (SpdData->Action != EfiIPsecActionProtect) {
        SpdData->ProcessingPolicy = NULL;
      } else {
        SpdData->ProcessingPolicy = (EFI_IPSEC_PROCESS_POLICY *) ((UINT8 *) SpdData + sizeof (EFI_IPSEC_SPD_DATA) + (SpdData->SaIdCount - 1) * sizeof (EFI_IPSEC_SA_ID));

        IpSecDuplicateProcessPolicy (
          SpdData->ProcessingPolicy,
          SpdEntry->Data->ProcessingPolicy
          );
      }

      return EFI_SUCCESS;
    }
  }

  return EFI_NOT_FOUND;
}

/**
  This function lookup the data entry from IPsec SAD. Return the configuration
  value of the specified SAD Entry.

  @param[in]      Selector      Pointer to an entry selector which is an identifier
                                of the SAD entry.
  @param[in, out] DataSize      On output, the size of data returned in Data.
  @param[out]     Data          The buffer to return the contents of the IPsec
                                configuration data. The type of the data buffer
                                is associated with the DataType.

  @retval EFI_SUCCESS           The specified configuration data was obtained successfully.
  @retval EFI_NOT_FOUND         The configuration data specified by Selector is not found.
  @retval EFI_BUFFER_TOO_SMALL  The DataSize is too small for the result. DataSize has been
                                updated with the size needed to complete the request.

**/
EFI_STATUS
GetSadEntry (
  IN     EFI_IPSEC_CONFIG_SELECTOR     *Selector,
  IN OUT UINTN                         *DataSize,
     OUT VOID                          *Data
  )
{
  IPSEC_SAD_ENTRY   *SadEntry;
  LIST_ENTRY        *Entry;
  LIST_ENTRY        *SadList;
  EFI_IPSEC_SA_ID   *SaId;
  EFI_IPSEC_SA_DATA *SaData;
  UINTN             RequiredSize;

  SaId    = &Selector->SaId;
  SaData  = (EFI_IPSEC_SA_DATA *) Data;
  SadList = &mConfigData[IPsecConfigDataTypeSad];

  NET_LIST_FOR_EACH (Entry, SadList) {
    SadEntry = IPSEC_SAD_ENTRY_FROM_LIST (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.
      // Data Layout is follows:
      // |EFI_IPSEC_SA_DATA
      // |AuthKey
      // |EncryptKey  (Optional)
      // |SpdSelector (Optional)
      //
      RequiredSize  = ALIGN_VARIABLE (sizeof (EFI_IPSEC_SA_DATA));

      if (SaId->Proto == EfiIPsecAH) {
        RequiredSize  = ALIGN_VARIABLE (RequiredSize + SadEntry->Data->AlgoInfo.AhAlgoInfo.AuthKeyLength);
      } else {
        RequiredSize  = ALIGN_VARIABLE (RequiredSize + SadEntry->Data->AlgoInfo.EspAlgoInfo.AuthKeyLength);
        RequiredSize  = ALIGN_VARIABLE (RequiredSize + SadEntry->Data->AlgoInfo.EspAlgoInfo.EncKeyLength);
      }

      if (SadEntry->Data->SpdEntry != NULL) {
        RequiredSize += SIZE_OF_SPD_SELECTOR (SadEntry->Data->SpdEntry->Selector);
      }



      if (*DataSize < RequiredSize) {
        *DataSize = RequiredSize;
        return EFI_BUFFER_TOO_SMALL;
      }
      //
      // Fill the data fields of sad entry.
      //
      *DataSize                 = RequiredSize;
      SaData->Mode              = SadEntry->Data->Mode;
      SaData->SNCount           = SadEntry->Data->SequenceNumber;
      SaData->AntiReplayWindows = SadEntry->Data->AntiReplayWindowSize;

      CopyMem (
        &SaData->SaLifetime,
        &SadEntry->Data->SaLifetime,
        sizeof (EFI_IPSEC_SA_LIFETIME)
        );

      ZeroMem (
        &SaData->AlgoInfo,
        sizeof (EFI_IPSEC_ALGO_INFO)
        );

      if (SaId->Proto == EfiIPsecAH) {
        //
        // Copy AH alogrithm INFO to SaData
        //
        SaData->AlgoInfo.AhAlgoInfo.AuthAlgoId    = SadEntry->Data->AlgoInfo.AhAlgoInfo.AuthAlgoId;
        SaData->AlgoInfo.AhAlgoInfo.AuthKeyLength = SadEntry->Data->AlgoInfo.AhAlgoInfo.AuthKeyLength;
        if (SaData->AlgoInfo.AhAlgoInfo.AuthKeyLength != 0) {
          SaData->AlgoInfo.AhAlgoInfo.AuthKey = (VOID *) ALIGN_POINTER ((SaData + 1), sizeof (UINTN));
          CopyMem (
            SaData->AlgoInfo.AhAlgoInfo.AuthKey,
            SadEntry->Data->AlgoInfo.AhAlgoInfo.AuthKey,
            SaData->AlgoInfo.AhAlgoInfo.AuthKeyLength
            );
        }
      } else if (SaId->Proto == EfiIPsecESP) {
        //
        // Copy ESP alogrithem INFO to SaData
        //
        SaData->AlgoInfo.EspAlgoInfo.AuthAlgoId     = SadEntry->Data->AlgoInfo.EspAlgoInfo.AuthAlgoId;
        SaData->AlgoInfo.EspAlgoInfo.AuthKeyLength  = SadEntry->Data->AlgoInfo.EspAlgoInfo.AuthKeyLength;
        if (SaData->AlgoInfo.EspAlgoInfo.AuthKeyLength != 0) {
          SaData->AlgoInfo.EspAlgoInfo.AuthKey = (VOID *) ALIGN_POINTER ((SaData + 1), sizeof (UINTN));
          CopyMem (
            SaData->AlgoInfo.EspAlgoInfo.AuthKey,
            SadEntry->Data->AlgoInfo.EspAlgoInfo.AuthKey,
            SaData->AlgoInfo.EspAlgoInfo.AuthKeyLength
            );
        }

        SaData->AlgoInfo.EspAlgoInfo.EncAlgoId    = SadEntry->Data->AlgoInfo.EspAlgoInfo.EncAlgoId;
        SaData->AlgoInfo.EspAlgoInfo.EncKeyLength = SadEntry->Data->AlgoInfo.EspAlgoInfo.EncKeyLength;

        if (SaData->AlgoInfo.EspAlgoInfo.EncKeyLength != 0) {
          SaData->AlgoInfo.EspAlgoInfo.EncKey = (VOID *) ALIGN_POINTER (
                                                          ((UINT8 *) (SaData + 1) +
                                                            SaData->AlgoInfo.EspAlgoInfo.AuthKeyLength),
                                                            sizeof (UINTN)
                                                            );
          CopyMem (
            SaData->AlgoInfo.EspAlgoInfo.EncKey,
            SadEntry->Data->AlgoInfo.EspAlgoInfo.EncKey,
            SaData->AlgoInfo.EspAlgoInfo.EncKeyLength
            );
        }
      }

      SaData->PathMTU = SadEntry->Data->PathMTU;

      //
      // Fill the spd selector field of sad data
      //
      if (SadEntry->Data->SpdEntry != NULL) {

        SaData->SpdSelector = (EFI_IPSEC_SPD_SELECTOR *) (
                                (UINT8 *)SaData +
                                RequiredSize -
                                SIZE_OF_SPD_SELECTOR (SadEntry->Data->SpdEntry->Selector)
                                );

        DuplicateSpdSelector (
          (EFI_IPSEC_CONFIG_SELECTOR *) SaData->SpdSelector,
          (EFI_IPSEC_CONFIG_SELECTOR *) SadEntry->Data->SpdEntry->Selector,
          NULL
          );

      } else {

        SaData->SpdSelector = NULL;
      }

      SaData->ManualSet = SadEntry->Data->ManualSet;

      return EFI_SUCCESS;
    }
  }

  return EFI_NOT_FOUND;
}

/**
  This function lookup the data entry from IPsec PAD. Return the configuration
  value of the specified PAD Entry.

  @param[in]      Selector      Pointer to an entry selector which is an identifier
                                of the PAD entry.
  @param[in, out] DataSize      On output the size of data returned in Data.
  @param[out]     Data          The buffer to return the contents of the IPsec
                                configuration data. The type of the data buffer
                                is associated with the DataType.

  @retval EFI_SUCCESS           The specified configuration data was obtained successfully.
  @retval EFI_NOT_FOUND         The configuration data specified by Selector is not found.
  @retval EFI_BUFFER_TOO_SMALL  The DataSize is too small for the result. DataSize has been
                                updated with the size needed to complete the request.

**/
EFI_STATUS
GetPadEntry (
  IN     EFI_IPSEC_CONFIG_SELECTOR   *Selector,
  IN OUT UINTN                       *DataSize,
     OUT VOID                        *Data
  )
{
  IPSEC_PAD_ENTRY     *PadEntry;
  LIST_ENTRY          *PadList;
  LIST_ENTRY          *Entry;
  EFI_IPSEC_PAD_ID    *PadId;
  EFI_IPSEC_PAD_DATA  *PadData;
  UINTN               RequiredSize;

  PadId   = &Selector->PadId;
  PadData = (EFI_IPSEC_PAD_DATA *) Data;
  PadList = &mConfigData[IPsecConfigDataTypePad];

  NET_LIST_FOR_EACH (Entry, PadList) {
    PadEntry = IPSEC_PAD_ENTRY_FROM_LIST (Entry);

    //
    // Find the required pad entry.
    //
    if (ComparePadId (
          (EFI_IPSEC_CONFIG_SELECTOR *) PadId,
          (EFI_IPSEC_CONFIG_SELECTOR *) PadEntry->Id
          )) {
      //
      // Calculate the required size of the pad entry.
      //
      RequiredSize  = ALIGN_VARIABLE (sizeof (EFI_IPSEC_PAD_DATA));
      RequiredSize  = ALIGN_VARIABLE (RequiredSize + PadEntry->Data->AuthDataSize);
      RequiredSize += PadEntry->Data->RevocationDataSize;

      if (*DataSize < RequiredSize) {
        *DataSize = RequiredSize;
        return EFI_BUFFER_TOO_SMALL;
      }
      //
      // Fill the data fields of pad entry
      //
      *DataSize             = RequiredSize;
      PadData->AuthProtocol = PadEntry->Data->AuthProtocol;
      PadData->AuthMethod   = PadEntry->Data->AuthMethod;
      PadData->IkeIdFlag    = PadEntry->Data->IkeIdFlag;

      //
      // Copy Authentication data.
      //
      if (PadEntry->Data->AuthData != NULL) {

        PadData->AuthDataSize = PadEntry->Data->AuthDataSize;
        PadData->AuthData     = (VOID *) ALIGN_POINTER ((PadData + 1), sizeof (UINTN));
        CopyMem (
          PadData->AuthData,
          PadEntry->Data->AuthData,
          PadData->AuthDataSize
          );
      } else {

        PadData->AuthDataSize = 0;
        PadData->AuthData     = NULL;
      }
      //
      // Copy Revocation Data.
      //
      if (PadEntry->Data->RevocationData != NULL) {

        PadData->RevocationDataSize = PadEntry->Data->RevocationDataSize;
        PadData->RevocationData     = (VOID *) ALIGN_POINTER (
                                                 ((UINT8 *) (PadData + 1) + PadData->AuthDataSize),
                                                  sizeof (UINTN)
                                                  );
        CopyMem (
          PadData->RevocationData,
          PadEntry->Data->RevocationData,
          PadData->RevocationDataSize
          );
      } else {

        PadData->RevocationDataSize = 0;
        PadData->RevocationData     = NULL;
      }

      return EFI_SUCCESS;
    }
  }

  return EFI_NOT_FOUND;
}

/**
  Copy Source Process Policy to the Destination Process Policy.

  @param[in]  Dst                  Pointer to the Source Process Policy.
  @param[in]  Src                  Pointer to the Destination Process Policy.

**/
VOID
IpSecDuplicateProcessPolicy (
  IN EFI_IPSEC_PROCESS_POLICY            *Dst,
  IN EFI_IPSEC_PROCESS_POLICY            *Src
  )
{
  //
  // Firstly copy the structure content itself.
  //
  CopyMem (Dst, Src, sizeof (EFI_IPSEC_PROCESS_POLICY));

  //
  // Recursively copy the tunnel option if needed.
  //
  if (Dst->Mode != EfiIPsecTunnel) {
    ASSERT (Dst->TunnelOption == NULL);
  } else {
    Dst->TunnelOption = (EFI_IPSEC_TUNNEL_OPTION *) ALIGN_POINTER ((Dst + 1), sizeof (UINTN));
    CopyMem (
      Dst->TunnelOption,
      Src->TunnelOption,
      sizeof (EFI_IPSEC_TUNNEL_OPTION)
      );
  }
}

/**
  Calculate the a whole size of EFI_IPSEC_SPD_DATA, which includes the buffer size pointed
  to by the pointer members.

  @param[in]  SpdData             Pointer to a specified EFI_IPSEC_SPD_DATA.

  @return the whole size the specified EFI_IPSEC_SPD_DATA.

**/
UINTN
IpSecGetSizeOfEfiSpdData (
  IN EFI_IPSEC_SPD_DATA               *SpdData
  )
{
  UINTN Size;

  Size = ALIGN_VARIABLE (sizeof (IPSEC_SPD_DATA));

  if (SpdData->Action == EfiIPsecActionProtect) {
    Size = ALIGN_VARIABLE (Size + sizeof (EFI_IPSEC_PROCESS_POLICY));

    if (SpdData->ProcessingPolicy->Mode == EfiIPsecTunnel) {
      Size = ALIGN_VARIABLE (Size + sizeof (EFI_IPSEC_TUNNEL_OPTION));
    }
  }

  return Size;
}

/**
  Calculate the a whole size of IPSEC_SPD_DATA which includes the buffer size pointed
  to by the pointer members and the buffer size used by the Sa List.

  @param[in]  SpdData       Pointer to the specified IPSEC_SPD_DATA.

  @return the whole size of IPSEC_SPD_DATA.

**/
UINTN
IpSecGetSizeOfSpdData (
  IN IPSEC_SPD_DATA                   *SpdData
  )
{
  UINTN       Size;
  LIST_ENTRY  *Link;

  Size = sizeof (EFI_IPSEC_SPD_DATA) - sizeof (EFI_IPSEC_SA_ID);

  if (SpdData->Action == EfiIPsecActionProtect) {
    Size += sizeof (EFI_IPSEC_PROCESS_POLICY);

    if (SpdData->ProcessingPolicy->Mode == EfiIPsecTunnel) {
      Size += sizeof (EFI_IPSEC_TUNNEL_OPTION);
    }
  }

  NET_LIST_FOR_EACH (Link, &SpdData->Sas) {
    Size += sizeof (EFI_IPSEC_SA_ID);
  }

  return Size;
}

/**
  Get the IPsec Variable.

  Get the all variables which start with the string contained in VaraiableName.
  Since all IPsec related variable store in continual space, those kinds of
  variable can be searched by the EfiGetNextVariableName. Those variables also are
  returned in a continual buffer.

  @param[in]      VariableName          Pointer to a specified Variable Name.
  @param[in]      VendorGuid            Pointer to a specified Vendor Guid.
  @param[in]      Attributes            Point to memory location to return the attributes
                                        of variable. If the point is NULL, the parameter
                                        would be ignored.
  @param[in, out] DataSize              As input, point to the maximum size of return
                                        Data-Buffer. As output, point to the actual
                                        size of the returned Data-Buffer.
  @param[in]      Data                  Point to return Data-Buffer.

  @retval  EFI_ABORTED           If the Variable size which contained in the variable
                                 structure doesn't match the variable size obtained
                                 from the EFIGetVariable.
  @retval  EFI_BUFFER_TOO_SMALL  The DataSize is too small for the result. DataSize has
                                 been updated with the size needed to complete the request.
  @retval  EFI_SUCCESS           The function completed successfully.
  @retval  others                Other errors found during the variable getting.
**/
EFI_STATUS
IpSecGetVariable (
  IN     CHAR16                       *VariableName,
  IN     EFI_GUID                     *VendorGuid,
  IN     UINT32                       *Attributes, OPTIONAL
  IN OUT UINTN                        *DataSize,
  IN     VOID                         *Data
  )
{
  EFI_STATUS            Status;
  EFI_GUID              VendorGuidI;
  UINTN                 VariableNameLength;
  CHAR16                *VariableNameI;
  UINTN                 VariableNameISize;
  UINTN                 VariableNameISizeNew;
  UINTN                 VariableIndex;
  UINTN                 VariableCount;
  IP_SEC_VARIABLE_INFO  IpSecVariableInfo;
  UINTN                 DataSizeI;

  //
  // The variable name constructor is "VariableName + Info/0001/0002/... + NULL".
  // So the varialbe name is like "VariableNameInfo", "VariableName0001", ...
  // "VariableNameNULL".
  //
  VariableNameLength  = StrLen (VariableName);
  VariableNameISize   = (VariableNameLength + 5) * sizeof (CHAR16);
  VariableNameI       = AllocateZeroPool (VariableNameISize);
  ASSERT (VariableNameI != NULL);

  //
  // Construct the varible name of ipsecconfig meta data.
  //
  UnicodeSPrint (VariableNameI, VariableNameISize, L"%s%s", VariableName, L"Info");

  DataSizeI = sizeof (IpSecVariableInfo);

  Status = gRT->GetVariable (
                  VariableNameI,
                  VendorGuid,
                  Attributes,
                  &DataSizeI,
                  &IpSecVariableInfo
                  );
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  if (*DataSize < IpSecVariableInfo.VariableSize) {
    *DataSize = IpSecVariableInfo.VariableSize;
    Status    = EFI_BUFFER_TOO_SMALL;
    goto ON_EXIT;
  }

  VariableCount     = IpSecVariableInfo.VariableCount;
  VariableNameI[0]  = L'\0';

  while (VariableCount != 0) {
    //
    // Get the variable name one by one in the variable database.
    //
    VariableNameISizeNew = VariableNameISize;
    Status = gRT->GetNextVariableName (
                    &VariableNameISizeNew,
                    VariableNameI,
                    &VendorGuidI
                    );
    if (Status == EFI_BUFFER_TOO_SMALL) {
      VariableNameI = ReallocatePool (
                        VariableNameISize,
                        VariableNameISizeNew,
                        VariableNameI
                        );
      if (VariableNameI == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        break;
      }
      VariableNameISize = VariableNameISizeNew;

      Status = gRT->GetNextVariableName (
                      &VariableNameISizeNew,
                      VariableNameI,
                      &VendorGuidI
                      );
    }

    if (EFI_ERROR (Status)) {
      break;
    }
    //
    // Check whether the current variable is the required "ipsecconfig".
    //
    if (StrnCmp (VariableNameI, VariableName, VariableNameLength) == 0 ||
        CompareGuid (VendorGuid, &VendorGuidI)
        ) {
      //
      // Parse the variable count of the current ipsecconfig data.
      //
      VariableIndex = StrDecimalToUintn (VariableNameI + VariableNameLength);
      if (VariableIndex!= 0 && VariableIndex <= IpSecVariableInfo.VariableCount) {
        //
        // Get the variable size of the current ipsecconfig data.
        //
        DataSizeI = 0;
        Status = gRT->GetVariable (
                        VariableNameI,
                        VendorGuid,
                        Attributes,
                        &DataSizeI,
                        NULL
                        );
        ASSERT (Status == EFI_BUFFER_TOO_SMALL);
        //
        // Validate the variable count and variable size.
        //
        if (VariableIndex != IpSecVariableInfo.VariableCount) {
          //
          // If the varaibe is not the last one, its size should be the max
          // size of the single variable.
          //
          if (DataSizeI != IpSecVariableInfo.SingleVariableSize) {
            return EFI_ABORTED;
          }
        } else {
          if (DataSizeI != IpSecVariableInfo.VariableSize % IpSecVariableInfo.SingleVariableSize) {
            return EFI_ABORTED;
          }
        }
        //
        // Get the variable data of the current ipsecconfig data and
        // store it into user buffer continously.
        //
        Status = gRT->GetVariable (
                        VariableNameI,
                        VendorGuid,
                        Attributes,
                        &DataSizeI,
                        (UINT8 *) Data + (VariableIndex - 1) * IpSecVariableInfo.SingleVariableSize
                        );
        ASSERT_EFI_ERROR (Status);
        VariableCount--;
      }
    }
  }
  //
  // The VariableCount in "VariableNameInfo" varaible should have the correct
  // numbers of variables which name starts with VariableName.
  //
  if (VariableCount != 0) {
    Status = EFI_ABORTED;
  }

ON_EXIT:
  if (VariableNameI != NULL) {
    FreePool (VariableNameI);
  }
  return Status;
}

/**
  Set the IPsec variables.

  Set all IPsec variables which start with the specified variable name. Those variables
  are set one by one.

  @param[in]  VariableName  The name of the vendor's variable. It is a
                            Null-Terminated Unicode String.
  @param[in]  VendorGuid    Unify identifier for vendor.
  @param[in]  Attributes    Point to memory location to return the attributes of
                            variable. If the point is NULL, the parameter would be ignored.
  @param[in]  DataSize      The size in bytes of Data-Buffer.
  @param[in]  Data          Points to the content of the variable.

  @retval  EFI_SUCCESS      The firmware successfully stored the variable and its data, as
                            defined by the Attributes.
  @retval  others           Storing the variables failed.

**/
EFI_STATUS
IpSecSetVariable (
  IN CHAR16                           *VariableName,
  IN EFI_GUID                         *VendorGuid,
  IN UINT32                           Attributes,
  IN UINTN                            DataSize,
  IN VOID                             *Data
  )
{
  EFI_STATUS            Status;
  CHAR16                *VariableNameI;
  UINTN                 VariableNameSize;
  UINTN                 VariableIndex;
  IP_SEC_VARIABLE_INFO  IpSecVariableInfo;
  UINT64                MaximumVariableStorageSize;
  UINT64                RemainingVariableStorageSize;
  UINT64                MaximumVariableSize;

  Status = gRT->QueryVariableInfo (
                  Attributes,
                  &MaximumVariableStorageSize,
                  &RemainingVariableStorageSize,
                  &MaximumVariableSize
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // "VariableName + Info/0001/0002/... + NULL"
  //
  VariableNameSize  = (StrLen (VariableName) + 5) * sizeof (CHAR16);
  VariableNameI     = AllocateZeroPool (VariableNameSize);

  if (VariableNameI == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_EXIT;
  }
  //
  // Construct the variable of ipsecconfig general information. Like the total
  // numbers of the Ipsecconfig variables, the total size of all ipsecconfig variables.
  //
  UnicodeSPrint (VariableNameI, VariableNameSize, L"%s%s", VariableName, L"Info");
  MaximumVariableSize -= VariableNameSize;

  IpSecVariableInfo.VariableCount       = (UINT32) ((DataSize + (UINTN) MaximumVariableSize - 1) / (UINTN) MaximumVariableSize);
  IpSecVariableInfo.VariableSize        = (UINT32) DataSize;
  IpSecVariableInfo.SingleVariableSize  = (UINT32) MaximumVariableSize;

  //
  // Set the variable of ipsecconfig general information.
  //
  Status = gRT->SetVariable (
                  VariableNameI,
                  VendorGuid,
                  Attributes,
                  sizeof (IpSecVariableInfo),
                  &IpSecVariableInfo
                  );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "Error set ipsecconfig meta data with %r\n", Status));
    goto ON_EXIT;
  }

  for (VariableIndex = 0; VariableIndex < IpSecVariableInfo.VariableCount; VariableIndex++) {
    //
    // Construct and set the variable of ipsecconfig data one by one.
    // The index of variable name begin from 0001, and the varaible name
    // likes "VariableName0001", "VaraiableName0002"....
    //
    UnicodeSPrint (VariableNameI, VariableNameSize, L"%s%04d", VariableName, VariableIndex + 1);
    Status = gRT->SetVariable (
                    VariableNameI,
                    VendorGuid,
                    Attributes,
                    (VariableIndex == IpSecVariableInfo.VariableCount - 1) ?
                    (DataSize % (UINTN) MaximumVariableSize) :
                    (UINTN) MaximumVariableSize,
                    (UINT8 *) Data + VariableIndex * (UINTN) MaximumVariableSize
                    );

    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "Error set ipsecconfig variable data with %r\n", Status));
      goto ON_EXIT;
    }
  }

ON_EXIT:
  if (VariableNameI != NULL) {
    FreePool (VariableNameI);
  }

  return Status;
}

/**
  Return the configuration value for the EFI IPsec driver.

  This function lookup the data entry from IPsec database or IKEv2 configuration
  information. The expected data type and unique identification are described in
  DataType and Selector parameters.

  @param[in]      This          Pointer to the EFI_IPSEC_CONFIG_PROTOCOL instance.
  @param[in]      DataType      The type of data to retrieve.
  @param[in]      Selector      Pointer to an entry selector that is an identifier of the IPsec
                                configuration data entry.
  @param[in, out] DataSize      On output the size of data returned in Data.
  @param[out]     Data          The buffer to return the contents of the IPsec configuration data.
                                The type of the data buffer associated with the DataType.

  @retval EFI_SUCCESS           The specified configuration data was obtained successfully.
  @retval EFI_INVALID_PARAMETER One or more of the followings are TRUE:
                                - This is NULL.
                                - Selector is NULL.
                                - DataSize is NULL.
                                - Data is NULL and *DataSize is not zero
  @retval EFI_NOT_FOUND         The configuration data specified by Selector is not found.
  @retval EFI_UNSUPPORTED       The specified DataType is not supported.
  @retval EFI_BUFFER_TOO_SMALL  The DataSize is too small for the result. DataSize has been
                                updated with the size needed to complete the request.

**/
EFI_STATUS
EFIAPI
EfiIpSecConfigGetData (
  IN     EFI_IPSEC_CONFIG_PROTOCOL    *This,
  IN     EFI_IPSEC_CONFIG_DATA_TYPE   DataType,
  IN     EFI_IPSEC_CONFIG_SELECTOR    *Selector,
  IN OUT UINTN                        *DataSize,
     OUT VOID                         *Data
  )
{
  if (This == NULL || Selector == NULL || DataSize == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (*DataSize != 0 && Data == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (DataType >= IPsecConfigDataTypeMaximum) {
    return EFI_UNSUPPORTED;
  }

  return mGetPolicyEntry[DataType](Selector, DataSize, Data);
}

/**
  Set the security association, security policy and peer authorization configuration
  information for the EFI IPsec driver.

  This function is used to set the IPsec configuration information of type DataType for
  the EFI IPsec driver.
  The IPsec configuration data has a unique selector/identifier separately to identify
  a data entry. The selector structure depends on DataType's definition.
  Using SetData() with a Data of NULL causes the IPsec configuration data entry identified
  by DataType and Selector to be deleted.

  @param[in] This               Pointer to the EFI_IPSEC_CONFIG_PROTOCOL instance.
  @param[in] DataType           The type of data to be set.
  @param[in] Selector           Pointer to an entry selector on operated configuration data
                                specified by DataType. A NULL Selector causes the entire
                                specified-type configuration information to be flushed.
  @param[in] Data               The data buffer to be set. The structure of the data buffer is
                                associated with the DataType.
  @param[in] InsertBefore       Pointer to one entry selector which describes the expected
                                position the new data entry will be added. If InsertBefore is NULL,
                                the new entry will be appended to the end of the database.

  @retval EFI_SUCCESS           The specified configuration entry data was set successfully.
  @retval EFI_INVALID_PARAMETER One or more of the following are TRUE:
                                - This is NULL.
  @retval EFI_UNSUPPORTED       The specified DataType is not supported.
  @retval EFI_OUT_OF_RESOURCED  The required system resource could not be allocated.

**/
EFI_STATUS
EFIAPI
EfiIpSecConfigSetData (
  IN EFI_IPSEC_CONFIG_PROTOCOL        *This,
  IN EFI_IPSEC_CONFIG_DATA_TYPE       DataType,
  IN EFI_IPSEC_CONFIG_SELECTOR        *Selector,
  IN VOID                             *Data,
  IN EFI_IPSEC_CONFIG_SELECTOR        *InsertBefore OPTIONAL
  )
{
  EFI_STATUS  Status;

  if (This == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (DataType >= IPsecConfigDataTypeMaximum) {
    return EFI_UNSUPPORTED;
  }

  Status = mSetPolicyEntry[DataType](Selector, Data, InsertBefore);

  if (!EFI_ERROR (Status) && !mSetBySelf) {
    //
    // Save the updated config data into variable.
    //
    IpSecConfigSave ();
  }

  return Status;
}

/**
  Enumerates the current selector for IPsec configuration data entry.

  This function is called multiple times to retrieve the entry Selector in IPsec
  configuration database. On each call to GetNextSelector(), the next entry
  Selector are retrieved into the output interface.

  If the entire IPsec configuration database has been iterated, the error
  EFI_NOT_FOUND is returned.
  If the Selector buffer is too small for the next Selector copy, an
  EFI_BUFFER_TOO_SMALL error is returned, and SelectorSize is updated to reflect
  the size of buffer needed.

  On the initial call to GetNextSelector() to start the IPsec configuration database
  search, a pointer to the buffer with all zero value is passed in Selector. Calls
  to SetData() between calls to GetNextSelector may produce unpredictable results.

  @param[in]      This          Pointer to the EFI_IPSEC_CONFIG_PROTOCOL instance.
  @param[in]      DataType      The type of IPsec configuration data to retrieve.
  @param[in, out] SelectorSize  The size of the Selector buffer.
  @param[in, out] Selector      On input, supplies the pointer to last Selector that was
                                returned by GetNextSelector().
                                On output, returns one copy of the current entry Selector
                                of a given DataType.

  @retval EFI_SUCCESS           The specified configuration data was obtained successfully.
  @retval EFI_INVALID_PARAMETER One or more of the followings are TRUE:
                                - This is NULL.
                                - SelectorSize is NULL.
                                - Selector is NULL.
  @retval EFI_NOT_FOUND         The next configuration data entry was not found.
  @retval EFI_UNSUPPORTED       The specified DataType is not supported.
  @retval EFI_BUFFER_TOO_SMALL  The SelectorSize is too small for the result. This parameter
                                has been updated with the size needed to complete the search
                                request.

**/
EFI_STATUS
EFIAPI
EfiIpSecConfigGetNextSelector (
  IN     EFI_IPSEC_CONFIG_PROTOCOL    *This,
  IN     EFI_IPSEC_CONFIG_DATA_TYPE   DataType,
  IN OUT UINTN                        *SelectorSize,
  IN OUT EFI_IPSEC_CONFIG_SELECTOR    *Selector
  )
{
  LIST_ENTRY                *Link;
  IPSEC_COMMON_POLICY_ENTRY *CommonEntry;
  BOOLEAN                   IsFound;

  if (This == NULL || Selector == NULL || SelectorSize == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (DataType >= IPsecConfigDataTypeMaximum) {
    return EFI_UNSUPPORTED;
  }

  IsFound = FALSE;

  NET_LIST_FOR_EACH (Link, &mConfigData[DataType]) {
    CommonEntry = BASE_CR (Link, IPSEC_COMMON_POLICY_ENTRY, List);

    if (IsFound || 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.
      //
      return mDuplicateSelector[DataType](Selector, CommonEntry->Selector, SelectorSize);
    } else {
      //
      // Set the flag if find the appointed entry.
      //
      IsFound = mCompareSelector[DataType](Selector, CommonEntry->Selector);
    }
  }

  return EFI_NOT_FOUND;
}

/**
  Register an event that is to be signaled whenever a configuration process on the
  specified IPsec configuration information is done.

  The register function is not surpport now and always returns EFI_UNSUPPORTED.

  @param[in] This               Pointer to the EFI_IPSEC_CONFIG_PROTOCOL instance.
  @param[in] DataType           The type of data to be registered the event for.
  @param[in] Event              The event to be registered.

  @retval EFI_SUCCESS           The event is registered successfully.
  @retval EFI_INVALID_PARAMETER This is NULL or Event is NULL.
  @retval EFI_ACCESS_DENIED     The Event is already registered for the DataType.
  @retval EFI_UNSUPPORTED       The notify registration is unsupported, or the specified
                                DataType is not supported.

**/
EFI_STATUS
EFIAPI
EfiIpSecConfigRegisterNotify (
  IN EFI_IPSEC_CONFIG_PROTOCOL        *This,
  IN EFI_IPSEC_CONFIG_DATA_TYPE       DataType,
  IN EFI_EVENT                        Event
  )
{
  return EFI_UNSUPPORTED;
}

/**
  Remove the specified event that was previously registered on the specified IPsec
  configuration data.

  This function is not support now and alwasy return EFI_UNSUPPORTED.

  @param[in] This               Pointer to the EFI_IPSEC_CONFIG_PROTOCOL instance.
  @param[in] DataType           The configuration data type to remove the registered event for.
  @param[in] Event              The event to be unregistered.

  @retval EFI_SUCCESS           The event was removed successfully.
  @retval EFI_NOT_FOUND         The Event specified by DataType could not be found in the
                                database.
  @retval EFI_INVALID_PARAMETER This is NULL or Event is NULL.
  @retval EFI_UNSUPPORTED       The notify registration is unsupported, or the specified
                                DataType is not supported.

**/
EFI_STATUS
EFIAPI
EfiIpSecConfigUnregisterNotify (
  IN EFI_IPSEC_CONFIG_PROTOCOL        *This,
  IN EFI_IPSEC_CONFIG_DATA_TYPE       DataType,
  IN EFI_EVENT                        Event
  )
{
  return EFI_UNSUPPORTED;
}

/**
  Copy whole data in specified EFI_SIPEC_CONFIG_SELECTOR and the Data to a buffer.

  This function is a caller defined function, and it is called by the IpSecVisitConfigData().
  The orignal caller is IpSecConfigSave(), which calls the IpsecVisitConfigData() to
  copy all types of IPsec Config datas into one buffer and store this buffer into firmware in
  the form of several variables.

  @param[in]      Type              A specified IPSEC_CONFIG_DATA_TYPE.
  @param[in]      Selector          Points to a EFI_IPSEC_CONFIG_SELECTOR to be copied
                                    to the buffer.
  @param[in]      Data              Points to data to be copied to the buffer. The
                                    Data type is related to the Type.
  @param[in]      SelectorSize      The size of the Selector.
  @param[in]      DataSize          The size of the Data.
  @param[in, out] Buffer            The buffer to store the Selector and Data.

  @retval EFI_SUCCESS            Copy the Selector and Data to a buffer successfully.
  @retval EFI_OUT_OF_RESOURCES   The required system resource could not be allocated.

**/
EFI_STATUS
IpSecCopyPolicyEntry (
  IN     EFI_IPSEC_CONFIG_DATA_TYPE   Type,
  IN     EFI_IPSEC_CONFIG_SELECTOR    *Selector,
  IN     VOID                         *Data,
  IN     UINTN                        SelectorSize,
  IN     UINTN                        DataSize,
  IN OUT IPSEC_VARIABLE_BUFFER        *Buffer
  )
{
  IPSEC_VAR_ITEM_HEADER SelectorHeader;
  IPSEC_VAR_ITEM_HEADER DataHeader;
  UINTN                 EntrySize;
  UINT8                 *TempPoint;

  if (Type == IPsecConfigDataTypeSad) {
    //
    // Don't save automatically-generated sa entry into variable.
    //
    if (((EFI_IPSEC_SA_DATA *) Data)->ManualSet == FALSE) {
      return EFI_SUCCESS;
    }
  }
  //
  // Increase the capacity size of the buffer if needed.
  //
  EntrySize  = ALIGN_VARIABLE (sizeof (SelectorHeader));
  EntrySize  = ALIGN_VARIABLE (EntrySize + SelectorSize);
  EntrySize  = ALIGN_VARIABLE (EntrySize + sizeof (SelectorHeader));
  EntrySize  = ALIGN_VARIABLE (EntrySize + DataSize);

  //EntrySize = SelectorSize + DataSize + 2 * sizeof (SelectorHeader);
  if (Buffer->Capacity - Buffer->Size < EntrySize) {
    //
    // Calculate the required buffer
    //
    Buffer->Capacity += EntrySize;
    TempPoint         = AllocatePool (Buffer->Capacity);
    
    if (TempPoint == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }
    //
    // Copy the old Buffer to new buffer and free the old one.
    //
    CopyMem (TempPoint, Buffer->Ptr, Buffer->Size);
    FreePool (Buffer->Ptr);

    Buffer->Ptr       =  TempPoint;
  }

  mFixPolicyEntry[Type](Selector, Data);

  //
  // Fill the selector header and copy it into buffer.
  //
  SelectorHeader.Type = (UINT8) (Type | IPSEC_VAR_ITEM_HEADER_LOGO_BIT);
  SelectorHeader.Size = (UINT16) SelectorSize;

  CopyMem (
    Buffer->Ptr + Buffer->Size,
    &SelectorHeader,
    sizeof (SelectorHeader)
    );
  Buffer->Size  = ALIGN_VARIABLE (Buffer->Size + sizeof (SelectorHeader));

  //
  // Copy the selector into buffer.
  //
  CopyMem (
    Buffer->Ptr + Buffer->Size,
    Selector,
    SelectorSize
    );
  Buffer->Size  = ALIGN_VARIABLE (Buffer->Size + SelectorSize);

  //
  // Fill the data header and copy it into buffer.
  //
  DataHeader.Type = (UINT8) Type;
  DataHeader.Size = (UINT16) DataSize;

  CopyMem (
    Buffer->Ptr + Buffer->Size,
    &DataHeader,
    sizeof (DataHeader)
    );
  Buffer->Size  = ALIGN_VARIABLE (Buffer->Size + sizeof (DataHeader));
  //
  // Copy the data into buffer.
  //
  CopyMem (
    Buffer->Ptr + Buffer->Size,
    Data,
    DataSize
    );
  Buffer->Size  = ALIGN_VARIABLE (Buffer->Size + DataSize);

  mUnfixPolicyEntry[Type](Selector, Data);

  return EFI_SUCCESS;
}

/**
  Visit all IPsec Configurations of specified Type and call the caller defined
  interface.

  @param[in]  DataType          The specified IPsec Config Data Type.
  @param[in]  Routine           The function defined by the caller.
  @param[in]  Context           The data passed to the Routine.

  @retval EFI_OUT_OF_RESOURCES   The required system resource could not be allocated
  @retval EFI_SUCCESS            This function completed successfully.

**/
EFI_STATUS
IpSecVisitConfigData (
  IN EFI_IPSEC_CONFIG_DATA_TYPE DataType,
  IN IPSEC_COPY_POLICY_ENTRY    Routine,
  IN VOID                       *Context
  )
{
  EFI_STATUS                GetNextStatus;
  EFI_STATUS                GetDataStatus;
  EFI_STATUS                RoutineStatus;
  EFI_IPSEC_CONFIG_SELECTOR *Selector;
  VOID                      *Data;
  UINTN                     SelectorSize;
  UINTN                     DataSize;
  UINTN                     SelectorBufferSize;
  UINTN                     DataBufferSize;
  BOOLEAN                   FirstGetNext;

  FirstGetNext        = TRUE;
  DataBufferSize      = 0;
  Data                = NULL;
  SelectorBufferSize  = sizeof (EFI_IPSEC_CONFIG_SELECTOR);
  Selector            = AllocateZeroPool (SelectorBufferSize);

  if (Selector == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  while (TRUE) {
    //
    // Get the real size of the selector.
    //
    SelectorSize = SelectorBufferSize;
    GetNextStatus = EfiIpSecConfigGetNextSelector (
                      &mIpSecConfigInstance,
                      DataType,
                      &SelectorSize,
                      Selector
                      );
    if (GetNextStatus == EFI_BUFFER_TOO_SMALL) {
      FreePool (Selector);
      SelectorBufferSize = SelectorSize;
      //
      // Allocate zero pool for the first selector, while store the last
      // selector content for the other selectors.
      //
      if (FirstGetNext) {
        Selector = AllocateZeroPool (SelectorBufferSize);
      } else {
        Selector = AllocateCopyPool (SelectorBufferSize, Selector);
      }

      if (Selector == NULL) {
        return EFI_OUT_OF_RESOURCES;
      }
      //
      // Get the content of the selector.
      //
      GetNextStatus = EfiIpSecConfigGetNextSelector (
                        &mIpSecConfigInstance,
                        DataType,
                        &SelectorSize,
                        Selector
                        );
    }

    if (EFI_ERROR (GetNextStatus)) {
      break;
    }

    FirstGetNext = FALSE;

    //
    // Get the real size of the policy entry according to the selector.
    //
    DataSize = DataBufferSize;
    GetDataStatus = EfiIpSecConfigGetData (
                      &mIpSecConfigInstance,
                      DataType,
                      Selector,
                      &DataSize,
                      Data
                      );
    if (GetDataStatus == EFI_BUFFER_TOO_SMALL) {
      if (Data != NULL) {
        FreePool (Data);
      }

      DataBufferSize  = DataSize;
      Data            = AllocateZeroPool (DataBufferSize);

      if (Data == NULL) {
        return EFI_OUT_OF_RESOURCES;
      }
      //
      // Get the content of the policy entry according to the selector.
      //
      GetDataStatus = EfiIpSecConfigGetData (
                        &mIpSecConfigInstance,
                        DataType,
                        Selector,
                        &DataSize,
                        Data
                        );
    }

    if (EFI_ERROR (GetDataStatus)) {
      break;
    }
    //
    // Prepare the buffer of updated policy entry, which is stored in
    // the continous memory, and then save into variable later.
    //
    RoutineStatus = Routine (
                      DataType,
                      Selector,
                      Data,
                      SelectorSize,
                      DataSize,
                      Context
                      );
    if (EFI_ERROR (RoutineStatus)) {
      break;
    }
  }

  if (Data != NULL) {
    FreePool (Data);
  }

  if (Selector != NULL) {
    FreePool (Selector);
  }

  return EFI_SUCCESS;
}

/**
  This function is the subfunction of  EFIIpSecConfigSetData.

  This function call IpSecSetVaraible to set the IPsec Configuration into the firmware.

  @retval EFI_OUT_OF_RESOURCES   The required system resource could not be allocated.
  @retval EFI_SUCCESS            Saved the configration successfully.
  @retval Others                 Other errors were found while obtaining the variable.

**/
EFI_STATUS
IpSecConfigSave (
  VOID
  )
{
  IPSEC_VARIABLE_BUFFER       Buffer;
  EFI_STATUS                  Status;
  EFI_IPSEC_CONFIG_DATA_TYPE  Type;

  Buffer.Size     = 0;
  Buffer.Capacity = IPSEC_DEFAULT_VARIABLE_SIZE;
  Buffer.Ptr      = AllocateZeroPool (Buffer.Capacity);

  if (Buffer.Ptr == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }
  //
  // For each policy database, prepare the contious buffer to save into variable.
  //
  for (Type = IPsecConfigDataTypeSpd; Type < IPsecConfigDataTypeMaximum; Type++) {
    IpSecVisitConfigData (
      Type,
      (IPSEC_COPY_POLICY_ENTRY) IpSecCopyPolicyEntry,
      &Buffer
      );
  }
  //
  // Save the updated policy database into variable.
  //
  Status = IpSecSetVariable (
             IPSECCONFIG_VARIABLE_NAME,
             &gEfiIpSecConfigProtocolGuid,
             EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
             Buffer.Size,
             Buffer.Ptr
             );

  FreePool (Buffer.Ptr);

  return Status;
}

/**
  Get the all IPSec configuration variables and store those variables
  to the internal data structure.

  This founction is called by IpSecConfigInitialize() which is to intialize the
  IPsecConfiguration Protocol.

  @param[in]  Private            Point to IPSEC_PRIVATE_DATA.

  @retval EFI_OUT_OF_RESOURCES   The required system resource could not be allocated
  @retval EFI_SUCCESS            Restore the IPsec Configuration successfully.
  @retval  others                Other errors is found while obtaining the variable.

**/
EFI_STATUS
IpSecConfigRestore (
  IN IPSEC_PRIVATE_DATA           *Private
  )
{
  EFI_STATUS                  Status;
  UINTN                       BufferSize;
  UINT8                       *Buffer;
  IPSEC_VAR_ITEM_HEADER       *Header;
  UINT8                       *Ptr;
  EFI_IPSEC_CONFIG_SELECTOR   *Selector;
  EFI_IPSEC_CONFIG_DATA_TYPE  Type;
  VOID                        *Data;
  UINT8                       Value;
  UINTN                       Size;

  Value       = 0;
  Size        = sizeof (Value);
  BufferSize  = 0;
  Buffer      = NULL;

  Status = gRT->GetVariable (
                  IPSECCONFIG_STATUS_NAME,
                  &gEfiIpSecConfigProtocolGuid,
                  NULL,
                  &Size,
                  &Value
             );

  if (!EFI_ERROR (Status) && Value == IPSEC_STATUS_ENABLED) {
    Private->IpSec.DisabledFlag = FALSE;
  }
  //
  // Get the real size of policy database in variable.
  //
  Status = IpSecGetVariable (
             IPSECCONFIG_VARIABLE_NAME,
             &gEfiIpSecConfigProtocolGuid,
             NULL,
             &BufferSize,
             Buffer
             );
  if (Status == EFI_BUFFER_TOO_SMALL) {

    Buffer = AllocateZeroPool (BufferSize);
    if (Buffer == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }
    //
    // Get the content of policy database in variable.
    //
    Status = IpSecGetVariable (
               IPSECCONFIG_VARIABLE_NAME,
               &gEfiIpSecConfigProtocolGuid,
               NULL,
               &BufferSize,
               Buffer
               );
    if (EFI_ERROR (Status)) {
      FreePool (Buffer);
      return Status;
    }

    for (Ptr = Buffer; Ptr < Buffer + BufferSize;) {

      Header  = (IPSEC_VAR_ITEM_HEADER *) Ptr;
      Type    = (EFI_IPSEC_CONFIG_DATA_TYPE) (Header->Type & IPSEC_VAR_ITEM_HEADER_CONTENT_BIT);
      ASSERT (((Header->Type & 0x80) == IPSEC_VAR_ITEM_HEADER_LOGO_BIT) && (Type < IPsecConfigDataTypeMaximum));

      Selector  = (EFI_IPSEC_CONFIG_SELECTOR *) ALIGN_POINTER (Header + 1, sizeof (UINTN));
      Header    = (IPSEC_VAR_ITEM_HEADER *) ALIGN_POINTER (
                                              (UINT8 *) Selector + Header->Size,
                                              sizeof (UINTN)
                                              );
      ASSERT (Header->Type == Type);

      Data = ALIGN_POINTER (Header + 1, sizeof (UINTN));

      mUnfixPolicyEntry[Type](Selector, Data);

      //
      // Update each policy entry according to the content in variable.
      //
      mSetBySelf = TRUE;
      Status = EfiIpSecConfigSetData (
                 &Private->IpSecConfig,
                 Type,
                 Selector,
                 Data,
                 NULL
                 );
      mSetBySelf = FALSE;

      if (EFI_ERROR (Status)) {
        FreePool (Buffer);
        return Status;
      }

      Ptr =  ALIGN_POINTER ((UINT8 *) Data + Header->Size, sizeof (UINTN));
    }

    FreePool (Buffer);
  }

  return EFI_SUCCESS;
}

/**
  Install and Initialize IPsecConfig protocol

  @param[in, out]  Private   Pointer to IPSEC_PRIVATE_DATA. After this function finish,
                             the pointer of IPsecConfig Protocol implementation will copy
                             into its IPsecConfig member.

  @retval     EFI_SUCCESS    Initialized the IPsecConfig Protocol successfully.
  @retval     Others         Initializing the IPsecConfig Protocol failed.
**/
EFI_STATUS
IpSecConfigInitialize (
  IN OUT IPSEC_PRIVATE_DATA        *Private
  )
{
  EFI_IPSEC_CONFIG_DATA_TYPE  Type;

  CopyMem (
    &Private->IpSecConfig,
    &mIpSecConfigInstance,
    sizeof (EFI_IPSEC_CONFIG_PROTOCOL)
    );

  //
  // Initialize the list head of policy database.
  //
  for (Type = IPsecConfigDataTypeSpd; Type < IPsecConfigDataTypeMaximum; Type++) {
    InitializeListHead (&mConfigData[Type]);
  }
  //
  // Restore the content of policy database according to the variable.
  //
  IpSecConfigRestore (Private);

  return gBS->InstallMultipleProtocolInterfaces (
                &Private->Handle,
                &gEfiIpSecConfigProtocolGuid,
                &Private->IpSecConfig,
                NULL
                );
}
