/** @file
  The implementation of IPSEC_CONFIG_PROTOCOL.

  Copyright (c) 2009 - 2017, 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;
  EFI_IP_ADDRESS  ZeroAddress;

  ZeroMem(&ZeroAddress, sizeof (EFI_IP_ADDRESS));

  //
  // Zero Address means any address is matched.
  //
  if (AddressCount == 1) {
    if (CompareMem (
          &AddressInfoList[0].Address,
          &ZeroAddress,
          sizeof (EFI_IP_ADDRESS)
          ) == 0) {
      return TRUE;
    }
  }
  for (Index = 0; Index < AddressCount ; Index++) {
    if (CompareMem (
          AddressInfo,
          &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 and RemoteAddress 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;
}

/**
  Find if the two SPD Selectors has subordinative.

  Compare two SPD Selector by the fields of LocalAddressCount/RemoteAddressCount/
  NextLayerProtocol/LocalPort/LocalPortRange/RemotePort/RemotePortRange and the 
  Local Addresses and remote Addresses.

  @param[in]   Selector1           Pointer of first SPD Selector.
  @param[in]   Selector2           Pointer of second SPD Selector.

  @retval  TRUE    The first SPD Selector is subordinate Selector of second SPD Selector.
  @retval  FALSE   The first SPD Selector is not subordinate Selector of second 
                   SPD Selector.
  
**/
BOOLEAN
IsSubSpdSelector (
  IN EFI_IPSEC_CONFIG_SELECTOR        *Selector1,
  IN EFI_IPSEC_CONFIG_SELECTOR        *Selector2
  )
{
  EFI_IPSEC_SPD_SELECTOR  *SpdSel1;
  EFI_IPSEC_SPD_SELECTOR  *SpdSel2;
  BOOLEAN                 IsMatch;
  UINTN                   Index;

  SpdSel1 = &Selector1->SpdSelector;
  SpdSel2 = &Selector2->SpdSelector;
  IsMatch = TRUE;

  //
  // Compare the LocalAddressCount/RemoteAddressCount/NextLayerProtocol/
  // LocalPort/LocalPortRange/RemotePort/RemotePortRange fields in the
  // two Spdselectors. Since the SPD supports two directions, it needs to 
  // compare two directions.
  //
  if (SpdSel1->LocalAddressCount > SpdSel2->LocalAddressCount ||
      SpdSel1->RemoteAddressCount > SpdSel2->RemoteAddressCount ||
      (SpdSel1->NextLayerProtocol != SpdSel2->NextLayerProtocol && SpdSel2->NextLayerProtocol != 0xffff) ||
      (SpdSel1->LocalPort > SpdSel2->LocalPort && SpdSel2->LocalPort != 0)||
      (SpdSel1->LocalPortRange > SpdSel2->LocalPortRange && SpdSel1->LocalPort != 0)||
      (SpdSel1->RemotePort > SpdSel2->RemotePort && SpdSel2->RemotePort != 0) ||
      (SpdSel1->RemotePortRange > SpdSel2->RemotePortRange && SpdSel2->RemotePort != 0)
      ) {
    IsMatch = FALSE;
  }
  
  //
  // Compare the all LocalAddress and RemoteAddress fields in the two Spdselectors.
  // First, SpdSel1->LocalAddress to SpdSel2->LocalAddress && Compare 
  // SpdSel1->RemoteAddress to SpdSel2->RemoteAddress. If all match, return
  // TRUE.
  //
  if (IsMatch) {
    for (Index = 0; Index < SpdSel1->LocalAddressCount; Index++) {
      if (!IsInAddressInfoList (
            &SpdSel1->LocalAddress[Index],
            SpdSel2->LocalAddress,
            SpdSel2->LocalAddressCount
            )) {
        IsMatch = FALSE;
        break;
      }
    }

    if (IsMatch) {
      for (Index = 0; Index < SpdSel1->RemoteAddressCount; Index++) {
        if (!IsInAddressInfoList (
              &SpdSel1->RemoteAddress[Index],
              SpdSel2->RemoteAddress,
              SpdSel2->RemoteAddressCount
              )) {
          IsMatch = FALSE;
          break;
        }
      }
    }
  }
  if (IsMatch) {
    return IsMatch;
  }
  
  //
  //
  // The SPD selector in SPD entry is two way.
  //
  // Compare the LocalAddressCount/RemoteAddressCount/NextLayerProtocol/
  // LocalPort/LocalPortRange/RemotePort/RemotePortRange fields in the
  // two Spdselectors. Since the SPD supports two directions, it needs to 
  // compare two directions.
  //
  IsMatch = TRUE;
  if (SpdSel1->LocalAddressCount > SpdSel2->RemoteAddressCount ||
      SpdSel1->RemoteAddressCount > SpdSel2->LocalAddressCount ||
      (SpdSel1->NextLayerProtocol != SpdSel2->NextLayerProtocol && SpdSel2->NextLayerProtocol != 0xffff) ||
      (SpdSel1->LocalPort > SpdSel2->RemotePort && SpdSel2->RemotePort != 0)||
      (SpdSel1->LocalPortRange > SpdSel2->RemotePortRange && SpdSel1->RemotePort != 0)||
      (SpdSel1->RemotePort > SpdSel2->LocalPort && SpdSel2->LocalPort != 0) ||
      (SpdSel1->RemotePortRange > SpdSel2->LocalPortRange && SpdSel2->LocalPort != 0)
      ) {
    IsMatch = FALSE;
    return IsMatch;
  }
  
  //
  // Compare the all LocalAddress and RemoteAddress fields in the two Spdselectors.
  // First, SpdSel1->LocalAddress to SpdSel2->RemoteAddress && Compare 
  // SpdSel1->RemoteAddress to SpdSel2->LocalAddress. If all match, return
  // TRUE.
  //
  for (Index = 0; Index < SpdSel1->LocalAddressCount; Index++) {
    if (!IsInAddressInfoList (
          &SpdSel1->LocalAddress[Index],
          SpdSel2->RemoteAddress,
          SpdSel2->RemoteAddressCount
          )) {
      IsMatch = FALSE;
      break;
    }
  }

  if (IsMatch) {
    for (Index = 0; Index < SpdSel1->RemoteAddressCount; Index++) {
      if (!IsInAddressInfoList (
            &SpdSel1->RemoteAddress[Index],
            SpdSel2->LocalAddress,
            SpdSel2->LocalAddressCount
            )) {
        IsMatch = FALSE;
        break;
      }
    }
  }
  return IsMatch;
  
}

/**
  Compare two SA IDs.

  @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
  )
{
  BOOLEAN                   IsZero;
  EFI_IPSEC_CONFIG_SELECTOR ZeroSelector;
  
  IsZero    = FALSE;

  ZeroMem (&ZeroSelector, sizeof (EFI_IPSEC_CONFIG_SELECTOR));

  if (CompareMem (&ZeroSelector, Selector, sizeof (EFI_IPSEC_CONFIG_SELECTOR)) == 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_DATA2                *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_DATA2                   *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.
                                   - SadEntry requied to be set into new SpdEntry's Sas has 
                                     been found but it is invalid.
  @retval EFI_OUT_OF_RESOURCED  The required system resource could not be allocated.
  @retval EFI_SUCCESS           The specified configuration data was obtained successfully.

**/
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              *Entry2;
  LIST_ENTRY              *NextEntry;
  LIST_ENTRY              *NextEntry2;
  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;
      
      //
      // Remove the related SAs from Sas(SadEntry->BySpd). If the SA entry is established by 
      // IKE, remove from mConfigData list(SadEntry->List) and then free it directly since its 
      // SpdEntry will be freed later.
      //
      NET_LIST_FOR_EACH_SAFE (Entry2, NextEntry2, SpdSas) {
        SadEntry = IPSEC_SAD_ENTRY_FROM_SPD (Entry2);
        
        if (SadEntry->Data->SpdEntry != NULL) {
          RemoveEntryList (&SadEntry->BySpd);
          SadEntry->Data->SpdEntry = NULL;
        }
        
        if (!(SadEntry->Data->ManualSet)) {
          RemoveEntryList (&SadEntry->List);
          FreePool (SadEntry);
        }
      }
      
      //
      // Free the existed SPD entry
      //
      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 + 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->TrafficDirection = SpdData->TrafficDirection;
  SpdEntry->Data->Action           = SpdData->Action;
  
  //
  // Fix the address of ProcessingPolicy and copy it if need, which is continous
  // memory and close to the base structure of SAD data.
  //
  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
              )) {
          //
          // Check whether the found SadEntry is vaild.
          //
          if (IsSubSpdSelector (
                (EFI_IPSEC_CONFIG_SELECTOR *) SadEntry->Data->SpdSelector,
                (EFI_IPSEC_CONFIG_SELECTOR *) SpdEntry->Selector
                )) {
            if (SadEntry->Data->SpdEntry != NULL) {
              RemoveEntryList (&SadEntry->BySpd);
            }
            InsertTailList (&SpdEntry->Data->Sas, &SadEntry->BySpd);
            SadEntry->Data->SpdEntry = SpdEntry;
          } else {
            return EFI_INVALID_PARAMETER;
          }
        }
      }      
  }
  
  //
  // Insert the new SPD entry.
  //
  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_DATA2 *SaData;
  EFI_IPSEC_SA_ID   *InsertBefore;
  LIST_ENTRY        *EntryInsertBefore;
  UINTN             SadEntrySize;
  
  SaId          = (Selector == NULL) ? NULL : &Selector->SaId;
  SaData        = (Data == NULL) ? NULL : (EFI_IPSEC_SA_DATA2 *) 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_ID));
  SadEntrySize  = ALIGN_VARIABLE (SadEntrySize + sizeof (IPSEC_SAD_DATA));
  
  if (SaId->Proto == EfiIPsecAH) {
    SadEntrySize += SaData->AlgoInfo.AhAlgoInfo.AuthKeyLength;
  } else {
    SadEntrySize  = ALIGN_VARIABLE (SadEntrySize + SaData->AlgoInfo.EspAlgoInfo.AuthKeyLength);
    SadEntrySize += ALIGN_VARIABLE (SaData->AlgoInfo.EspAlgoInfo.EncKeyLength);
  }

  if (SaData->SpdSelector != NULL) {
    SadEntrySize += SadEntrySize + SIZE_OF_SPD_SELECTOR (SaData->SpdSelector);
  }
  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->SpdSelector = NULL;
  SadEntry->Data->ESNEnabled  = FALSE;
  SadEntry->Data->ManualSet   = SaData->ManualSet;

  //
  // Copy Tunnel Source/Destination Address
  //
  if (SaData->Mode == EfiIPsecTunnel) {
    CopyMem (
      &SadEntry->Data->TunnelDestAddress,
      &SaData->TunnelDestinationAddress,
      sizeof (EFI_IP_ADDRESS)
      );
    CopyMem (
      &SadEntry->Data->TunnelSourceAddress,
      &SaData->TunnelSourceAddress,
      sizeof (EFI_IP_ADDRESS)
      );
  }
  //
  // Update the spd.sas list of the spd entry specified by SAD selector
  //
  SpdList = &mConfigData[IPsecConfigDataTypeSpd];

  for (Entry = SpdList->ForwardLink; Entry != SpdList && SaData->SpdSelector != NULL; Entry = Entry->ForwardLink) {

    SpdEntry = IPSEC_SPD_ENTRY_FROM_LIST (Entry);
    if (IsSubSpdSelector (
          (EFI_IPSEC_CONFIG_SELECTOR *) SaData->SpdSelector,
          (EFI_IPSEC_CONFIG_SELECTOR *) SpdEntry->Selector
          ) && SpdEntry->Data->Action == EfiIPsecActionProtect) {
      SadEntry->Data->SpdEntry = SpdEntry;
      SadEntry->Data->SpdSelector = (EFI_IPSEC_SPD_SELECTOR *)((UINT8 *)SadEntry +
                                                                SadEntrySize -
                                                                SIZE_OF_SPD_SELECTOR (SaData->SpdSelector)
                                                                );
      DuplicateSpdSelector (
       (EFI_IPSEC_CONFIG_SELECTOR *) SadEntry->Data->SpdSelector,
       (EFI_IPSEC_CONFIG_SELECTOR *) SaData->SpdSelector,
       NULL
       );
      InsertTailList (&SpdEntry->Data->Sas, &SadEntry->BySpd);
    }
  }
  //
  // Insert the new SAD entry.
  //
  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->TrafficDirection = SpdEntry->Data->TrafficDirection;
      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_DATA2 *SaData;
  UINTN             RequiredSize;

  SaId    = &Selector->SaId;
  SaData  = (EFI_IPSEC_SA_DATA2 *) Data;
  SadList = &mConfigData[IPsecConfigDataTypeSad];

  NET_LIST_FOR_EACH (Entry, SadList) {
    SadEntry = IPSEC_SAD_ENTRY_FROM_LIST (Entry);

    //
    // Find the required SAD entry.
    //
    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_DATA2));

      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->SpdSelector != NULL) {
        RequiredSize += SIZE_OF_SPD_SELECTOR (SadEntry->Data->SpdSelector);
      }
      
      if (*DataSize < RequiredSize) {
        *DataSize = RequiredSize;
        return EFI_BUFFER_TOO_SMALL;
      }
      
      //
      // Fill the data fields of SAD entry.
      //
      *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 Tunnel Address if it is Tunnel Mode
      //
      if (SadEntry->Data->Mode == EfiIPsecTunnel) {
        CopyMem (
          &SaData->TunnelDestinationAddress,
          &SadEntry->Data->TunnelDestAddress,
          sizeof (EFI_IP_ADDRESS)
          );
        CopyMem (
          &SaData->TunnelSourceAddress,
          &SadEntry->Data->TunnelSourceAddress,
          sizeof (EFI_IP_ADDRESS)
          );
      }
      //
      // Fill the spd selector field of SAD data
      //
      if (SadEntry->Data->SpdSelector != NULL) {

        SaData->SpdSelector = (EFI_IPSEC_SPD_SELECTOR *) (
                                (UINT8 *)SaData +
                                RequiredSize -
                                SIZE_OF_SPD_SELECTOR (SadEntry->Data->SpdSelector)
                                );
       
        DuplicateSpdSelector (
          (EFI_IPSEC_CONFIG_SELECTOR *) SaData->SpdSelector,
          (EFI_IPSEC_CONFIG_SELECTOR *) SadEntry->Data->SpdSelector,
          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);
  if (VariableNameI == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_EXIT;
  }
  
  //
  // 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 || (BOOLEAN)(mIsZeroSelector[DataType](Selector))) {
      //
      // If found the appointed entry, then duplicate the next one and return,
      // or if the appointed entry is zero, then return the first one directly.
      //
      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_DATA2 *) 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
                );
}
