/** @file
  The implementation of IPSEC_CONFIG_PROTOCOL.

  Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>

  This program and the accompanying materials
  are licensed and made available under the terms and conditions of the BSD License
  which accompanies this distribution.  The full text of the license may be found at
  http://opensource.org/licenses/bsd-license.php.

  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include "IpSecConfigImpl.h"
#include "IpSecDebug.h"

LIST_ENTRY                mConfigData[IPsecConfigDataTypeMaximum];
BOOLEAN                   mSetBySelf = FALSE;

//
// Common CompareSelector routine entry for SPD/SAD/PAD.
//
IPSEC_COMPARE_SELECTOR    mCompareSelector[] = {
  (IPSEC_COMPARE_SELECTOR) CompareSpdSelector,
  (IPSEC_COMPARE_SELECTOR) CompareSaId,
  (IPSEC_COMPARE_SELECTOR) ComparePadId
};

//
// Common IsZeroSelector routine entry for SPD/SAD/PAD.
//
IPSEC_IS_ZERO_SELECTOR    mIsZeroSelector[] = {
  (IPSEC_IS_ZERO_SELECTOR) IsZeroSpdSelector,
  (IPSEC_IS_ZERO_SELECTOR) IsZeroSaId,
  (IPSEC_IS_ZERO_SELECTOR) IsZeroPadId
};

//
// Common DuplicateSelector routine entry for SPD/SAD/PAD.
//
IPSEC_DUPLICATE_SELECTOR  mDuplicateSelector[] = {
  (IPSEC_DUPLICATE_SELECTOR) DuplicateSpdSelector,
  (IPSEC_DUPLICATE_SELECTOR) DuplicateSaId,
  (IPSEC_DUPLICATE_SELECTOR) DuplicatePadId
};

//
// Common FixPolicyEntry routine entry for SPD/SAD/PAD.
//
IPSEC_FIX_POLICY_ENTRY    mFixPolicyEntry[] = {
  (IPSEC_FIX_POLICY_ENTRY) FixSpdEntry,
  (IPSEC_FIX_POLICY_ENTRY) FixSadEntry,
  (IPSEC_FIX_POLICY_ENTRY) FixPadEntry
};

//
// Common UnfixPolicyEntry routine entry for SPD/SAD/PAD.
//
IPSEC_FIX_POLICY_ENTRY    mUnfixPolicyEntry[] = {
  (IPSEC_FIX_POLICY_ENTRY) UnfixSpdEntry,
  (IPSEC_FIX_POLICY_ENTRY) UnfixSadEntry,
  (IPSEC_FIX_POLICY_ENTRY) UnfixPadEntry
};

//
// Common SetPolicyEntry routine entry for SPD/SAD/PAD.
//
IPSEC_SET_POLICY_ENTRY    mSetPolicyEntry[] = {
  (IPSEC_SET_POLICY_ENTRY) SetSpdEntry,
  (IPSEC_SET_POLICY_ENTRY) SetSadEntry,
  (IPSEC_SET_POLICY_ENTRY) SetPadEntry
};

//
// Common GetPolicyEntry routine entry for SPD/SAD/PAD.
//
IPSEC_GET_POLICY_ENTRY    mGetPolicyEntry[] = {
  (IPSEC_GET_POLICY_ENTRY) GetSpdEntry,
  (IPSEC_GET_POLICY_ENTRY) GetSadEntry,
  (IPSEC_GET_POLICY_ENTRY) GetPadEntry
};

//
// Routine entry for IpSecConfig protocol.
//
EFI_IPSEC_CONFIG_PROTOCOL mIpSecConfigInstance = {
  EfiIpSecConfigSetData,
  EfiIpSecConfigGetData,
  EfiIpSecConfigGetNextSelector,
  EfiIpSecConfigRegisterNotify,
  EfiIpSecConfigUnregisterNotify
};

/**
  Get the all IPSec configuration variables and store those variables
  to the internal data structure.

  This founction is called by IpSecConfigInitialize() that is to intialize the 
  IPsecConfiguration Protocol.

  @param[in]  Private            Point to IPSEC_PRIVATE_DATA.

  @retval EFI_OUT_OF_RESOURCES   The required system resource could not be allocated.
  @retval EFI_SUCCESS            Restore the IPsec Configuration successfully.
  @retval  others                Other errors is found during the variable getting.

**/
EFI_STATUS
IpSecConfigRestore (
  IN IPSEC_PRIVATE_DATA               *Private
  );

/**
  Check if the specified EFI_IP_ADDRESS_INFO is in EFI_IP_ADDRESS_INFO list.

  @param[in]   AddressInfo         Pointer of IP_ADDRESS_INFO to be search in AddressInfo list.
  @param[in]   AddressInfoList     A list that contains IP_ADDRESS_INFOs.
  @param[in]   AddressCount        Point out how many IP_ADDRESS_INFO in the list.

  @retval  TRUE    The specified AddressInfo is in the AddressInfoList.
  @retval  FALSE   The specified AddressInfo is not in the AddressInfoList.
  
**/
BOOLEAN
IsInAddressInfoList(
  IN EFI_IP_ADDRESS_INFO              *AddressInfo,
  IN EFI_IP_ADDRESS_INFO              *AddressInfoList,
  IN UINT32                           AddressCount
  )
{
  UINT8           Index;
  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 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 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 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->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.
  @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;
  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;
      
      //
      // TODO: Deleted the related SAs.
      //
      NET_LIST_FOR_EACH (Entry2, SpdSas) {
        SadEntry                  = IPSEC_SAD_ENTRY_FROM_SPD (Entry2);
        SadEntry->Data->SpdEntry  = NULL;
      }
      
      //
      // Free the existed SPD entry
      //
      FreePool (SpdEntry);
    }
  }
  //
  // Return success here if only want to remove the SPD entry.
  //
  if (SpdData == NULL || SpdSel == NULL) {
    return EFI_SUCCESS;
  }
  //
  // Search the appointed entry position if InsertBefore is not NULL.
  //
  if (InsertBefore != NULL) {

    NET_LIST_FOR_EACH (Entry, SpdList) {
      SpdEntry = IPSEC_SPD_ENTRY_FROM_LIST (Entry);

      if (CompareSpdSelector (
            (EFI_IPSEC_CONFIG_SELECTOR *) SpdEntry->Selector,
            (EFI_IPSEC_CONFIG_SELECTOR *) InsertBefore
            )) {
        EntryInsertBefore = Entry;
        break;
      }
    }
  }

  //
  // Do Padding for the different Arch.
  //
  SpdEntrySize  = ALIGN_VARIABLE (sizeof (IPSEC_SPD_ENTRY));
  SpdEntrySize  = ALIGN_VARIABLE (SpdEntrySize + (UINTN)SIZE_OF_SPD_SELECTOR (SpdSel));
  SpdEntrySize += IpSecGetSizeOfEfiSpdData (SpdData);

  SpdEntry = AllocateZeroPool (SpdEntrySize);

  if (SpdEntry == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }
  //
  // Fix the address of Selector and Data buffer and copy them, which is
  // continous memory and close to the base structure of SPD entry.
  //
  SpdEntry->Selector  = (EFI_IPSEC_SPD_SELECTOR *) ALIGN_POINTER ((SpdEntry + 1), sizeof (UINTN));
  SpdEntry->Data      = (IPSEC_SPD_DATA *) ALIGN_POINTER (
                                            ((UINT8 *) SpdEntry->Selector + SIZE_OF_SPD_SELECTOR (SpdSel)),
                                            sizeof (UINTN)
                                            );

  DuplicateSpdSelector (
    (EFI_IPSEC_CONFIG_SELECTOR *) SpdEntry->Selector,
    (EFI_IPSEC_CONFIG_SELECTOR *) SpdSel,
    NULL
    );

  CopyMem (
    SpdEntry->Data->Name,
    SpdData->Name,
    sizeof (SpdData->Name)
    );
  SpdEntry->Data->PackageFlag = SpdData->PackageFlag;
  SpdEntry->Data->Action      = SpdData->Action;

  //
  // Fix the address of ProcessingPolicy and copy it if need, which is continous
  // memory and close to the base structure of SAD data.
  //
  if (SpdData->Action != EfiIPsecActionProtect) {
    SpdEntry->Data->ProcessingPolicy = NULL;
  } else {
    SpdEntry->Data->ProcessingPolicy = (EFI_IPSEC_PROCESS_POLICY *) ALIGN_POINTER (
                                                                      SpdEntry->Data + 1,
                                                                      sizeof (UINTN)
                                                                      );
    IpSecDuplicateProcessPolicy (SpdEntry->Data->ProcessingPolicy, SpdData->ProcessingPolicy);
  }
  //
  // Update the sas list of the new SPD entry.
  //
  InitializeListHead (&SpdEntry->Data->Sas);

  SadList = &mConfigData[IPsecConfigDataTypeSad];

  NET_LIST_FOR_EACH (Entry, SadList) {
    SadEntry = IPSEC_SAD_ENTRY_FROM_LIST (Entry);

    for (Index = 0; Index < SpdData->SaIdCount; Index++) {

      if (CompareSaId (
            (EFI_IPSEC_CONFIG_SELECTOR *) &SpdData->SaId[Index],
            (EFI_IPSEC_CONFIG_SELECTOR *) SadEntry->Id
            )) {
        InsertTailList (&SpdEntry->Data->Sas, &SadEntry->BySpd);
        SadEntry->Data->SpdEntry = SpdEntry;
        DuplicateSpdSelector (
          (EFI_IPSEC_CONFIG_SELECTOR *)SadEntry->Data->SpdSelector,
          (EFI_IPSEC_CONFIG_SELECTOR *)SpdEntry->Selector,
          NULL
          );             
      }
    }
  }
  //
  // 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 + (UINTN)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 -
                                                                (UINTN)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->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);
  ASSERT (VariableNameI != NULL);
  
  //
  // Construct the varible name of ipsecconfig meta data.
  //
  UnicodeSPrint (VariableNameI, VariableNameISize, L"%s%s", VariableName, L"Info");

  DataSizeI = sizeof (IpSecVariableInfo);

  Status = gRT->GetVariable (
                  VariableNameI,
                  VendorGuid,
                  Attributes,
                  &DataSizeI,
                  &IpSecVariableInfo
                  );
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  if (*DataSize < IpSecVariableInfo.VariableSize) {
    *DataSize = IpSecVariableInfo.VariableSize;
    Status    = EFI_BUFFER_TOO_SMALL;
    goto ON_EXIT;
  }

  VariableCount     = IpSecVariableInfo.VariableCount;
  VariableNameI[0]  = L'\0';

  while (VariableCount != 0) {
    //
    // Get the variable name one by one in the variable database.
    //
    VariableNameISizeNew = VariableNameISize;
    Status = gRT->GetNextVariableName (
                    &VariableNameISizeNew,
                    VariableNameI,
                    &VendorGuidI
                    );
    if (Status == EFI_BUFFER_TOO_SMALL) {
      VariableNameI = ReallocatePool (
                        VariableNameISize,
                        VariableNameISizeNew,
                        VariableNameI
                        );
      if (VariableNameI == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        break;
      }
      VariableNameISize = VariableNameISizeNew;

      Status = gRT->GetNextVariableName (
                      &VariableNameISizeNew,
                      VariableNameI,
                      &VendorGuidI
                      );
    }

    if (EFI_ERROR (Status)) {
      break;
    }
    //
    // Check whether the current variable is the required "ipsecconfig".
    //
    if (StrnCmp (VariableNameI, VariableName, VariableNameLength) == 0 ||
        CompareGuid (VendorGuid, &VendorGuidI)
        ) {
      //
      // Parse the variable count of the current ipsecconfig data.
      //
      VariableIndex = StrDecimalToUintn (VariableNameI + VariableNameLength);
      if (VariableIndex!= 0 && VariableIndex <= IpSecVariableInfo.VariableCount) {
        //
        // Get the variable size of the current ipsecconfig data.
        //
        DataSizeI = 0;
        Status = gRT->GetVariable (
                        VariableNameI,
                        VendorGuid,
                        Attributes,
                        &DataSizeI,
                        NULL
                        );
        ASSERT (Status == EFI_BUFFER_TOO_SMALL);
        //
        // Validate the variable count and variable size.
        //
        if (VariableIndex != IpSecVariableInfo.VariableCount) {
          //
          // If the varaibe is not the last one, its size should be the max
          // size of the single variable.
          //
          if (DataSizeI != IpSecVariableInfo.SingleVariableSize) {
            return EFI_ABORTED;
          }
        } else {
          if (DataSizeI != IpSecVariableInfo.VariableSize % IpSecVariableInfo.SingleVariableSize) {
            return EFI_ABORTED;
          }
        }
        //
        // Get the variable data of the current ipsecconfig data and
        // store it into user buffer continously.
        //
        Status = gRT->GetVariable (
                        VariableNameI,
                        VendorGuid,
                        Attributes,
                        &DataSizeI,
                        (UINT8 *) Data + (VariableIndex - 1) * IpSecVariableInfo.SingleVariableSize
                        );
        ASSERT_EFI_ERROR (Status);
        VariableCount--;
      }
    }
  }
  //
  // The VariableCount in "VariableNameInfo" varaible should have the correct
  // numbers of variables which name starts with VariableName.
  //
  if (VariableCount != 0) {
    Status = EFI_ABORTED;
  }

ON_EXIT:
  if (VariableNameI != NULL) {
    FreePool (VariableNameI);
  }
  return Status;
}

/**
  Set the IPsec variables.

  Set all IPsec variables which start with the specified variable name. Those variables
  are set one by one.

  @param[in]  VariableName  The name of the vendor's variable. It is a
                            Null-Terminated Unicode String.
  @param[in]  VendorGuid    Unify identifier for vendor.
  @param[in]  Attributes    Point to memory location to return the attributes of 
                            variable. If the point is NULL, the parameter would be ignored.
  @param[in]  DataSize      The size in bytes of Data-Buffer.
  @param[in]  Data          Points to the content of the variable.

  @retval  EFI_SUCCESS      The firmware successfully stored the variable and its data, as
                            defined by the Attributes.
  @retval  others           Storing the variables failed.      

**/
EFI_STATUS
IpSecSetVariable (
  IN CHAR16                           *VariableName,
  IN EFI_GUID                         *VendorGuid,
  IN UINT32                           Attributes,
  IN UINTN                            DataSize,
  IN VOID                             *Data
  )
{
  EFI_STATUS            Status;
  CHAR16                *VariableNameI;
  UINTN                 VariableNameSize;
  UINTN                 VariableIndex;
  IP_SEC_VARIABLE_INFO  IpSecVariableInfo;
  UINT64                MaximumVariableStorageSize;
  UINT64                RemainingVariableStorageSize;
  UINT64                MaximumVariableSize;

  Status = gRT->QueryVariableInfo (
                  Attributes,
                  &MaximumVariableStorageSize,
                  &RemainingVariableStorageSize,
                  &MaximumVariableSize
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }
  
  //
  // "VariableName + Info/0001/0002/... + NULL"
  //
  VariableNameSize  = (StrLen (VariableName) + 5) * sizeof (CHAR16);
  VariableNameI     = AllocateZeroPool (VariableNameSize);

  if (VariableNameI == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_EXIT;
  }
  //
  // Construct the variable of ipsecconfig general information. Like the total
  // numbers of the Ipsecconfig variables, the total size of all ipsecconfig variables.
  //
  UnicodeSPrint (VariableNameI, VariableNameSize, L"%s%s", VariableName, L"Info");
  MaximumVariableSize -= VariableNameSize;
  
  IpSecVariableInfo.VariableCount       = (UINT32) ((DataSize + (UINTN) MaximumVariableSize - 1) / (UINTN) MaximumVariableSize);
  IpSecVariableInfo.VariableSize        = (UINT32) DataSize;
  IpSecVariableInfo.SingleVariableSize  = (UINT32) MaximumVariableSize;

  //
  // Set the variable of ipsecconfig general information.
  //
  Status = gRT->SetVariable (
                  VariableNameI,
                  VendorGuid,
                  Attributes,
                  sizeof (IpSecVariableInfo),
                  &IpSecVariableInfo
                  );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "Error set ipsecconfig meta data with %r\n", Status));
    goto ON_EXIT;
  }

  for (VariableIndex = 0; VariableIndex < IpSecVariableInfo.VariableCount; VariableIndex++) {
    //
    // Construct and set the variable of ipsecconfig data one by one.
    // The index of variable name begin from 0001, and the varaible name
    // likes "VariableName0001", "VaraiableName0002"....
    // 
    UnicodeSPrint (VariableNameI, VariableNameSize, L"%s%04d", VariableName, VariableIndex + 1);
    Status = gRT->SetVariable (
                    VariableNameI,
                    VendorGuid,
                    Attributes,
                    (VariableIndex == IpSecVariableInfo.VariableCount - 1) ?
                    (DataSize % (UINTN) MaximumVariableSize) :
                    (UINTN) MaximumVariableSize,
                    (UINT8 *) Data + VariableIndex * (UINTN) MaximumVariableSize
                    );

    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "Error set ipsecconfig variable data with %r\n", Status));
      goto ON_EXIT;
    }
  }

ON_EXIT:
  if (VariableNameI != NULL) {
    FreePool (VariableNameI);
  }

  return Status;
}

/**
  Return the configuration value for the EFI IPsec driver. 

  This function lookup the data entry from IPsec database or IKEv2 configuration
  information. The expected data type and unique identification are described in
  DataType and Selector parameters.        

  @param[in]      This          Pointer to the EFI_IPSEC_CONFIG_PROTOCOL instance.
  @param[in]      DataType      The type of data to retrieve.
  @param[in]      Selector      Pointer to an entry selector that is an identifier of the IPsec 
                                configuration data entry.
  @param[in, out] DataSize      On output the size of data returned in Data.
  @param[out]     Data          The buffer to return the contents of the IPsec configuration data. 
                                The type of the data buffer associated with the DataType. 
 
  @retval EFI_SUCCESS           The specified configuration data was obtained successfully.
  @retval EFI_INVALID_PARAMETER One or more of the followings are TRUE:
                                - This is NULL.
                                - Selector is NULL.
                                - DataSize is NULL.
                                - Data is NULL and *DataSize is not zero
  @retval EFI_NOT_FOUND         The configuration data specified by Selector is not found.
  @retval EFI_UNSUPPORTED       The specified DataType is not supported.
  @retval EFI_BUFFER_TOO_SMALL  The DataSize is too small for the result. DataSize has been
                                updated with the size needed to complete the request.

**/
EFI_STATUS
EFIAPI
EfiIpSecConfigGetData (
  IN     EFI_IPSEC_CONFIG_PROTOCOL    *This,
  IN     EFI_IPSEC_CONFIG_DATA_TYPE   DataType,
  IN     EFI_IPSEC_CONFIG_SELECTOR    *Selector,
  IN OUT UINTN                        *DataSize,
     OUT VOID                         *Data
  )
{
  if (This == NULL || Selector == NULL || DataSize == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (*DataSize != 0 && Data == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (DataType >= IPsecConfigDataTypeMaximum) {
    return EFI_UNSUPPORTED;
  }

  return mGetPolicyEntry[DataType](Selector, DataSize, Data);
}

/**
  Set the security association, security policy and peer authorization configuration
  information for the EFI IPsec driver. 

  This function is used to set the IPsec configuration information of type DataType for
  the EFI IPsec driver.
  The IPsec configuration data has a unique selector/identifier separately to identify
  a data entry. The selector structure depends on DataType's definition.
  Using SetData() with a Data of NULL causes the IPsec configuration data entry identified
  by DataType and Selector to be deleted.        

  @param[in] This               Pointer to the EFI_IPSEC_CONFIG_PROTOCOL instance.
  @param[in] DataType           The type of data to be set.
  @param[in] Selector           Pointer to an entry selector on operated configuration data 
                                specified by DataType. A NULL Selector causes the entire 
                                specified-type configuration information to be flushed.
  @param[in] Data               The data buffer to be set. The structure of the data buffer is 
                                associated with the DataType.
  @param[in] InsertBefore       Pointer to one entry selector which describes the expected
                                position the new data entry will be added. If InsertBefore is NULL,
                                the new entry will be appended to the end of the database.
 
  @retval EFI_SUCCESS           The specified configuration entry data was set successfully.
  @retval EFI_INVALID_PARAMETER One or more of the following are TRUE:
                                - This is NULL.
  @retval EFI_UNSUPPORTED       The specified DataType is not supported.
  @retval EFI_OUT_OF_RESOURCED  The required system resource could not be allocated.

**/
EFI_STATUS
EFIAPI
EfiIpSecConfigSetData (
  IN EFI_IPSEC_CONFIG_PROTOCOL        *This,
  IN EFI_IPSEC_CONFIG_DATA_TYPE       DataType,
  IN EFI_IPSEC_CONFIG_SELECTOR        *Selector,
  IN VOID                             *Data,
  IN EFI_IPSEC_CONFIG_SELECTOR        *InsertBefore OPTIONAL
  )
{
  EFI_STATUS  Status;

  if (This == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (DataType >= IPsecConfigDataTypeMaximum) {
    return EFI_UNSUPPORTED;
  }
  
  Status = mSetPolicyEntry[DataType](Selector, Data, InsertBefore);

  if (!EFI_ERROR (Status) && !mSetBySelf) {
    //
    // Save the updated config data into variable.
    //
    IpSecConfigSave ();
  }

  return Status;
}

/**
  Enumerates the current selector for IPsec configuration data entry. 

  This function is called multiple times to retrieve the entry Selector in IPsec
  configuration database. On each call to GetNextSelector(), the next entry 
  Selector are retrieved into the output interface.
 
  If the entire IPsec configuration database has been iterated, the error 
  EFI_NOT_FOUND is returned.
  If the Selector buffer is too small for the next Selector copy, an 
  EFI_BUFFER_TOO_SMALL error is returned, and SelectorSize is updated to reflect 
  the size of buffer needed.

  On the initial call to GetNextSelector() to start the IPsec configuration database
  search, a pointer to the buffer with all zero value is passed in Selector. Calls 
  to SetData() between calls to GetNextSelector may produce unpredictable results.         

  @param[in]      This          Pointer to the EFI_IPSEC_CONFIG_PROTOCOL instance.
  @param[in]      DataType      The type of IPsec configuration data to retrieve.
  @param[in, out] SelectorSize  The size of the Selector buffer.
  @param[in, out] Selector      On input, supplies the pointer to last Selector that was 
                                returned by GetNextSelector().
                                On output, returns one copy of the current entry Selector
                                of a given DataType. 
 
  @retval EFI_SUCCESS           The specified configuration data was obtained successfully.
  @retval EFI_INVALID_PARAMETER One or more of the followings are TRUE:
                                - This is NULL.
                                - SelectorSize is NULL.
                                - Selector is NULL.
  @retval EFI_NOT_FOUND         The next configuration data entry was not found.
  @retval EFI_UNSUPPORTED       The specified DataType is not supported.
  @retval EFI_BUFFER_TOO_SMALL  The SelectorSize is too small for the result. This parameter
                                has been updated with the size needed to complete the search 
                                request.

**/
EFI_STATUS
EFIAPI
EfiIpSecConfigGetNextSelector (
  IN     EFI_IPSEC_CONFIG_PROTOCOL    *This,
  IN     EFI_IPSEC_CONFIG_DATA_TYPE   DataType,
  IN OUT UINTN                        *SelectorSize,
  IN OUT EFI_IPSEC_CONFIG_SELECTOR    *Selector
  )
{
  LIST_ENTRY                *Link;
  IPSEC_COMMON_POLICY_ENTRY *CommonEntry;
  BOOLEAN                   IsFound;

  if (This == NULL || Selector == NULL || SelectorSize == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (DataType >= IPsecConfigDataTypeMaximum) {
    return EFI_UNSUPPORTED;
  }

  IsFound = FALSE;

  NET_LIST_FOR_EACH (Link, &mConfigData[DataType]) {
    CommonEntry = BASE_CR (Link, IPSEC_COMMON_POLICY_ENTRY, List);

    if (IsFound || (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
                );
}
