/** @file
  The implementation of IPsec.

  (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
  Copyright (c) 2009 - 2018, 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 "IpSecImpl.h"
#include "IkeService.h"
#include "IpSecDebug.h"
#include "IpSecCryptIo.h"
#include "IpSecConfigImpl.h"

/**
  Check if the specified Address is the Valid Address Range.

  This function checks if the bytes after prefixed length are all Zero in this
  Address. This Address is supposed to point to a range address. That means it
  should gives the correct prefixed address and the bytes outside the prefixed are
  zero.

  @param[in]  IpVersion         The IP version.
  @param[in]  Address           Points to EFI_IP_ADDRESS to be checked.
  @param[in]  PrefixLength      The PrefixeLength of this address.

  @retval     TRUE      The address is a vaild address range.
  @retval     FALSE     The address is not a vaild address range.

**/
BOOLEAN
IpSecValidAddressRange (
  IN UINT8                     IpVersion,
  IN EFI_IP_ADDRESS            *Address,
  IN UINT8                     PrefixLength
  )
{
  UINT8           Div;
  UINT8           Mod;
  UINT8           Mask;
  UINT8           AddrLen;
  UINT8           *Addr;
  EFI_IP_ADDRESS  ZeroAddr;

  if (PrefixLength == 0) {
    return TRUE;
  }

  AddrLen = (UINT8) ((IpVersion == IP_VERSION_4) ? 32 : 128);

  if (AddrLen <= PrefixLength) {
    return FALSE;
  }

  Div   = (UINT8) (PrefixLength / 8);
  Mod   = (UINT8) (PrefixLength % 8);
  Addr  = (UINT8 *) Address;
  ZeroMem (&ZeroAddr, sizeof (EFI_IP_ADDRESS));

  //
  // Check whether the mod part of host scope is zero or not.
  //
  if (Mod > 0) {
    Mask = (UINT8) (0xFF << (8 - Mod));

    if ((Addr[Div] | Mask) != Mask) {
      return FALSE;
    }

    Div++;
  }
  //
  // Check whether the div part of host scope is zero or not.
  //
  if (CompareMem (
        &Addr[Div],
        &ZeroAddr,
        sizeof (EFI_IP_ADDRESS) - Div
        ) != 0) {
    return FALSE;
  }

  return TRUE;
}

/**
  Extrct the Address Range from a Address.

  This function keep the prefix address and zero other part address.

  @param[in]  Address           Point to a specified address.
  @param[in]  PrefixLength      The prefix length.
  @param[out] Range             Contain the return Address Range.

**/
VOID
IpSecExtractAddressRange (
  IN EFI_IP_ADDRESS            *Address,
  IN UINT8                     PrefixLength,
  OUT EFI_IP_ADDRESS           *Range
  )
{
  UINT8 Div;
  UINT8 Mod;
  UINT8 Mask;
  UINT8 *Addr;

  if (PrefixLength == 0) {
    return ;
  }

  Div   = (UINT8) (PrefixLength / 8);
  Mod   = (UINT8) (PrefixLength % 8);
  Addr  = (UINT8 *) Range;

  CopyMem (Range, Address, sizeof (EFI_IP_ADDRESS));

  //
  // Zero the mod part of host scope.
  //
  if (Mod > 0) {
    Mask      = (UINT8) (0xFF << (8 - Mod));
    Addr[Div] = (UINT8) (Addr[Div] & Mask);
    Div++;
  }
  //
  // Zero the div part of host scope.
  //
  ZeroMem (&Addr[Div], sizeof (EFI_IP_ADDRESS) - Div);

}

/**
  Checks if the IP Address in the address range of AddressInfos specified.

  @param[in]  IpVersion         The IP version.
  @param[in]  IpAddr            Point to EFI_IP_ADDRESS to be check.
  @param[in]  AddressInfo       A list of EFI_IP_ADDRESS_INFO that is used to check
                                the IP Address is matched.
  @param[in]  AddressCount      The total numbers of the AddressInfo.

  @retval   TRUE    If the Specified IP Address is in the range of the AddressInfos specified.
  @retval   FALSE   If the Specified IP Address is not in the range of the AddressInfos specified.

**/
BOOLEAN
IpSecMatchIpAddress (
  IN UINT8                     IpVersion,
  IN EFI_IP_ADDRESS            *IpAddr,
  IN EFI_IP_ADDRESS_INFO       *AddressInfo,
  IN UINT32                    AddressCount
  )
{
  EFI_IP_ADDRESS  Range;
  UINT32          Index;
  BOOLEAN         IsMatch;

  IsMatch = FALSE;

  for (Index = 0; Index < AddressCount; Index++) {
    //
    // Check whether the target address is in the address range
    // if it's a valid range of address.
    //
    if (IpSecValidAddressRange (
          IpVersion,
          &AddressInfo[Index].Address,
          AddressInfo[Index].PrefixLength
          )) {
      //
      // Get the range of the target address belongs to.
      //
      ZeroMem (&Range, sizeof (EFI_IP_ADDRESS));
      IpSecExtractAddressRange (
        IpAddr,
        AddressInfo[Index].PrefixLength,
        &Range
        );

      if (CompareMem (
            &Range,
            &AddressInfo[Index].Address,
            sizeof (EFI_IP_ADDRESS)
            ) == 0) {
        //
        // The target address is in the address range.
        //
        IsMatch = TRUE;
        break;
      }
    }

    if (CompareMem (
          IpAddr,
          &AddressInfo[Index].Address,
          sizeof (EFI_IP_ADDRESS)
          ) == 0) {
      //
      // The target address is exact same as the address.
      //
      IsMatch = TRUE;
      break;
    }
  }
  return IsMatch;
}

/**
  Check if the specified Protocol and Prot is supported by the specified SPD Entry.

  This function is the subfunction of IPsecLookUpSpdEntry() that is used to
  check if the sent/received IKE packet has the related SPD entry support.

  @param[in]  Protocol          The Protocol to be checked.
  @param[in]  IpPayload         Point to IP Payload to be check.
  @param[in]  SpdProtocol       The Protocol supported by SPD.
  @param[in]  SpdLocalPort      The Local Port in SPD.
  @param[in]  SpdRemotePort     The Remote Port in SPD.
  @param[in]  IsOutbound        Flag to indicate the is for IKE Packet sending or recieving.

  @retval     TRUE      The Protocol and Port are supported by the SPD Entry.
  @retval     FALSE     The Protocol and Port are not supported by the SPD Entry.

**/
BOOLEAN
IpSecMatchNextLayerProtocol (
  IN UINT8                     Protocol,
  IN UINT8                     *IpPayload,
  IN UINT16                    SpdProtocol,
  IN UINT16                    SpdLocalPort,
  IN UINT16                    SpdRemotePort,
  IN BOOLEAN                   IsOutbound
  )
{
  BOOLEAN IsMatch;

  if (SpdProtocol == EFI_IPSEC_ANY_PROTOCOL) {
    return TRUE;
  }

  IsMatch = FALSE;

  if (SpdProtocol == Protocol) {
    switch (Protocol) {
    case EFI_IP_PROTO_UDP:
    case EFI_IP_PROTO_TCP:
      //
      // For udp and tcp, (0, 0) means no need to check local and remote
      // port. The payload is passed from upper level, which means it should
      // be in network order.
      //
      IsMatch = (BOOLEAN) (SpdLocalPort == 0 && SpdRemotePort == 0);
      IsMatch = (BOOLEAN) (IsMatch ||
                           (IsOutbound &&
                           (BOOLEAN)(
                              NTOHS (((EFI_UDP_HEADER *) IpPayload)->SrcPort) == SpdLocalPort &&
                              NTOHS (((EFI_UDP_HEADER *) IpPayload)->DstPort) == SpdRemotePort
                              )
                            ));

      IsMatch = (BOOLEAN) (IsMatch ||
                           (!IsOutbound &&
                           (BOOLEAN)(
                              NTOHS (((EFI_UDP_HEADER *) IpPayload)->DstPort) == SpdLocalPort &&
                              NTOHS (((EFI_UDP_HEADER *) IpPayload)->SrcPort) == SpdRemotePort
                              )
                           ));
      break;

    case EFI_IP_PROTO_ICMP:
      //
      // For icmpv4, type code is replaced with local port and remote port,
      // and (0, 0) means no need to check.
      //
      IsMatch = (BOOLEAN) (SpdLocalPort == 0 && SpdRemotePort == 0);
      IsMatch = (BOOLEAN) (IsMatch ||
                           (BOOLEAN) (((IP4_ICMP_HEAD *) IpPayload)->Type == SpdLocalPort &&
                                      ((IP4_ICMP_HEAD *) IpPayload)->Code == SpdRemotePort
                                      )
                           );
      break;

    case IP6_ICMP:
      //
      // For icmpv6, type code is replaced with local port and remote port,
      // and (0, 0) means no need to check.
      //
      IsMatch = (BOOLEAN) (SpdLocalPort == 0 && SpdRemotePort == 0);

      IsMatch = (BOOLEAN) (IsMatch ||
                           (BOOLEAN) (((IP6_ICMP_HEAD *) IpPayload)->Type == SpdLocalPort &&
                                      ((IP6_ICMP_HEAD *) IpPayload)->Code == SpdRemotePort
                                      )
                          );
      break;

    default:
      IsMatch = TRUE;
      break;
    }
  }

  return IsMatch;
}

/**
  Find the SAD through a specified SPD's SAD list.

  @param[in]  SadList           SAD list related to a specified SPD entry.
  @param[in]  DestAddress       The destination address used to find the SAD entry.
  @param[in]  IpVersion         The IP version. Ip4 or Ip6.

  @return  The pointer to a certain SAD entry.

**/
IPSEC_SAD_ENTRY *
IpSecLookupSadBySpd (
  IN LIST_ENTRY                 *SadList,
  IN EFI_IP_ADDRESS             *DestAddress,
  IN UINT8                      IpVersion
  )
{
  LIST_ENTRY      *Entry;
  IPSEC_SAD_ENTRY *SadEntry;

  NET_LIST_FOR_EACH (Entry, SadList) {

    SadEntry = IPSEC_SAD_ENTRY_FROM_SPD (Entry);
    //
    // Find the right SAD entry which contains the appointed dest address.
    //
    if (IpSecMatchIpAddress (
          IpVersion,
          DestAddress,
          SadEntry->Data->SpdSelector->RemoteAddress,
          SadEntry->Data->SpdSelector->RemoteAddressCount
          )){
      return SadEntry;
    }
  }

  return NULL;
}

/**
  Find the SAD through whole SAD list.

  @param[in]  Spi               The SPI used to search the SAD entry.
  @param[in]  DestAddress       The destination used to search the SAD entry.
  @param[in]  IpVersion         The IP version. Ip4 or Ip6.

  @return  the pointer to a certain SAD entry.

**/
IPSEC_SAD_ENTRY *
IpSecLookupSadBySpi (
  IN UINT32                   Spi,
  IN EFI_IP_ADDRESS           *DestAddress,
  IN UINT8                    IpVersion
  )
{
  LIST_ENTRY      *Entry;
  LIST_ENTRY      *SadList;
  IPSEC_SAD_ENTRY *SadEntry;

  SadList = &mConfigData[IPsecConfigDataTypeSad];

  NET_LIST_FOR_EACH (Entry, SadList) {

    SadEntry = IPSEC_SAD_ENTRY_FROM_LIST (Entry);

    //
    // Find the right SAD entry which contain the appointed spi and dest addr.
    //
    if (SadEntry->Id->Spi == Spi) {
      if (SadEntry->Data->Mode == EfiIPsecTunnel) {
        if (CompareMem (
              &DestAddress,
              &SadEntry->Data->TunnelDestAddress,
              sizeof (EFI_IP_ADDRESS)
              )) {
          return SadEntry;
        }
      } else {
        if (SadEntry->Data->SpdSelector != NULL &&
            IpSecMatchIpAddress (
              IpVersion,
              DestAddress,
              SadEntry->Data->SpdSelector->RemoteAddress,
              SadEntry->Data->SpdSelector->RemoteAddressCount
              )
            ) {
          return SadEntry;
        }
      }
    }
  }
  return NULL;
}

/**
  Look up if there is existing SAD entry for specified IP packet sending.

  This function is called by the IPsecProcess when there is some IP packet needed to
  send out. This function checks if there is an existing SAD entry that can be serviced
  to this IP packet sending. If no existing SAD entry could be used, this
  function will invoke an IPsec Key Exchange Negotiation.

  @param[in]  Private           Points to private data.
  @param[in]  NicHandle         Points to a NIC handle.
  @param[in]  IpVersion         The version of IP.
  @param[in]  IpHead            The IP Header of packet to be sent out.
  @param[in]  IpPayload         The IP Payload to be sent out.
  @param[in]  OldLastHead       The Last protocol of the IP packet.
  @param[in]  SpdEntry          Points to a related SPD entry.
  @param[out] SadEntry          Contains the Point of a related SAD entry.

  @retval EFI_DEVICE_ERROR  One of following conditions is TRUE:
                            - If don't find related UDP service.
                            - Sequence Number is used up.
                            - Extension Sequence Number is used up.
  @retval EFI_NOT_READY     No existing SAD entry could be used.
  @retval EFI_SUCCESS       Find the related SAD entry.

**/
EFI_STATUS
IpSecLookupSadEntry (
  IN IPSEC_PRIVATE_DATA      *Private,
  IN EFI_HANDLE              NicHandle,
  IN UINT8                   IpVersion,
  IN VOID                    *IpHead,
  IN UINT8                   *IpPayload,
  IN UINT8                   OldLastHead,
  IN IPSEC_SPD_ENTRY         *SpdEntry,
  OUT IPSEC_SAD_ENTRY        **SadEntry
  )
{
  IKE_UDP_SERVICE *UdpService;
  IPSEC_SAD_ENTRY *Entry;
  IPSEC_SAD_DATA  *Data;
  EFI_IP_ADDRESS  DestIp;
  UINT32          SeqNum32;

  *SadEntry   = NULL;
  UdpService  = IkeLookupUdp (Private, NicHandle, IpVersion);

  if (UdpService == NULL) {
    return EFI_DEVICE_ERROR;
  }
  //
  // Parse the destination address from ip header.
  //
  ZeroMem (&DestIp, sizeof (EFI_IP_ADDRESS));
  if (IpVersion == IP_VERSION_4) {
    CopyMem (
      &DestIp,
      &((IP4_HEAD *) IpHead)->Dst,
      sizeof (IP4_ADDR)
      );
  } else {
    CopyMem (
      &DestIp,
      &((EFI_IP6_HEADER *) IpHead)->DestinationAddress,
      sizeof (EFI_IP_ADDRESS)
      );
  }

  //
  // Find the SAD entry in the spd.sas list according to the dest address.
  //
  Entry = IpSecLookupSadBySpd (&SpdEntry->Data->Sas, &DestIp, IpVersion);

  if (Entry == NULL) {
    if (OldLastHead != IP6_ICMP ||
        (OldLastHead == IP6_ICMP && *IpPayload == ICMP_V6_ECHO_REQUEST)
        ) {
      //
      // Start ike negotiation process except the request packet of ping.
      //
      if (SpdEntry->Data->ProcessingPolicy->Mode == EfiIPsecTunnel) {
        IkeNegotiate (
          UdpService,
          SpdEntry,
          &SpdEntry->Data->ProcessingPolicy->TunnelOption->RemoteTunnelAddress
          );
      } else {
        IkeNegotiate (
          UdpService,
          SpdEntry,
          &DestIp
        );
      }

    }

    return EFI_NOT_READY;
  }

  Data = Entry->Data;

  if (!Data->ManualSet) {
    if (Data->ESNEnabled) {
      //
      // Validate the 64bit sn number if 64bit sn enabled.
      //
      if ((UINT64) (Data->SequenceNumber + 1) == 0) {
        //
        // TODO: Re-negotiate SA
        //
        return EFI_DEVICE_ERROR;
      }
    } else {
      //
      // Validate the 32bit sn number if 64bit sn disabled.
      //
      SeqNum32 = (UINT32) Data->SequenceNumber;
      if ((UINT32) (SeqNum32 + 1) == 0) {
        //
        // TODO: Re-negotiate SA
        //
        return EFI_DEVICE_ERROR;
      }
    }
  }

  *SadEntry = Entry;

  return EFI_SUCCESS;
}

/**
  Find a PAD entry according to a remote IP address.

  @param[in]  IpVersion         The version of IP.
  @param[in]  IpAddr            Points to remote IP address.

  @return the pointer of related PAD entry.

**/
IPSEC_PAD_ENTRY *
IpSecLookupPadEntry (
  IN UINT8                   IpVersion,
  IN EFI_IP_ADDRESS          *IpAddr
  )
{
  LIST_ENTRY          *PadList;
  LIST_ENTRY          *Entry;
  EFI_IP_ADDRESS_INFO *IpAddrInfo;
  IPSEC_PAD_ENTRY     *PadEntry;

  PadList = &mConfigData[IPsecConfigDataTypePad];

  for (Entry = PadList->ForwardLink; Entry != PadList; Entry = Entry->ForwardLink) {

    PadEntry    = IPSEC_PAD_ENTRY_FROM_LIST (Entry);
    IpAddrInfo  = &PadEntry->Id->Id.IpAddress;
    //
    // Find the right pad entry which contain the appointed dest addr.
    //
    if (IpSecMatchIpAddress (IpVersion, IpAddr, IpAddrInfo, 1)) {
      return PadEntry;
    }
  }

  return NULL;
}

/**
  Check if the specified IP packet can be serviced by this SPD entry.

  @param[in]  SpdEntry          Point to SPD entry.
  @param[in]  IpVersion         Version of IP.
  @param[in]  IpHead            Point to IP header.
  @param[in]  IpPayload         Point to IP payload.
  @param[in]  Protocol          The Last protocol of IP packet.
  @param[in]  IsOutbound        Traffic direction.
  @param[out] Action            The support action of SPD entry.

  @retval EFI_SUCCESS       Find the related SPD.
  @retval EFI_NOT_FOUND     Not find the related SPD entry;

**/
EFI_STATUS
IpSecLookupSpdEntry (
  IN     IPSEC_SPD_ENTRY         *SpdEntry,
  IN     UINT8                   IpVersion,
  IN     VOID                    *IpHead,
  IN     UINT8                   *IpPayload,
  IN     UINT8                   Protocol,
  IN     BOOLEAN                 IsOutbound,
     OUT EFI_IPSEC_ACTION        *Action
  )
{
  EFI_IPSEC_SPD_SELECTOR  *SpdSel;
  IP4_HEAD                *Ip4;
  EFI_IP6_HEADER          *Ip6;
  EFI_IP_ADDRESS          SrcAddr;
  EFI_IP_ADDRESS          DstAddr;
  BOOLEAN                 SpdMatch;

  ASSERT (SpdEntry != NULL);
  SpdSel  = SpdEntry->Selector;
  Ip4     = (IP4_HEAD *) IpHead;
  Ip6     = (EFI_IP6_HEADER *) IpHead;

  ZeroMem (&SrcAddr, sizeof (EFI_IP_ADDRESS));
  ZeroMem (&DstAddr, sizeof (EFI_IP_ADDRESS));

  //
  // Parse the source and destination address from ip header.
  //
  if (IpVersion == IP_VERSION_4) {
    CopyMem (&SrcAddr, &Ip4->Src, sizeof (IP4_ADDR));
    CopyMem (&DstAddr, &Ip4->Dst, sizeof (IP4_ADDR));
  } else {
    CopyMem (&SrcAddr, &Ip6->SourceAddress, sizeof (EFI_IPv6_ADDRESS));
    CopyMem (&DstAddr, &Ip6->DestinationAddress, sizeof (EFI_IPv6_ADDRESS));
  }
  //
  // Check the local and remote addresses for outbound traffic
  //
  SpdMatch = (BOOLEAN)(IsOutbound &&
                       IpSecMatchIpAddress (
                         IpVersion,
                         &SrcAddr,
                         SpdSel->LocalAddress,
                         SpdSel->LocalAddressCount
                         ) &&
                       IpSecMatchIpAddress (
                         IpVersion,
                         &DstAddr,
                         SpdSel->RemoteAddress,
                         SpdSel->RemoteAddressCount
                         )
                       );

  //
  // Check the local and remote addresses for inbound traffic
  //
  SpdMatch = (BOOLEAN) (SpdMatch ||
                        (!IsOutbound &&
                        IpSecMatchIpAddress (
                          IpVersion,
                          &DstAddr,
                          SpdSel->LocalAddress,
                          SpdSel->LocalAddressCount
                          ) &&
                        IpSecMatchIpAddress (
                          IpVersion,
                          &SrcAddr,
                          SpdSel->RemoteAddress,
                          SpdSel->RemoteAddressCount
                          )
                        ));

  //
  // Check the next layer protocol and local and remote ports.
  //
  SpdMatch = (BOOLEAN) (SpdMatch &&
                        IpSecMatchNextLayerProtocol (
                          Protocol,
                          IpPayload,
                          SpdSel->NextLayerProtocol,
                          SpdSel->LocalPort,
                          SpdSel->RemotePort,
                          IsOutbound
                          )
                        );

  if (SpdMatch) {
    //
    // Find the right SPD entry if match the 5 key elements.
    //
    *Action = SpdEntry->Data->Action;
    return EFI_SUCCESS;
  }

  return EFI_NOT_FOUND;
}

/**
  The call back function of NetbufFromExt.

  @param[in]  Arg            The argument passed from the caller.

**/
VOID
EFIAPI
IpSecOnRecyclePacket (
  IN VOID                            *Arg
  )
{
}

/**
  This is a Notification function. It is called when the related IP6_TXTOKEN_WRAP
  is released.

  @param[in]  Event              The related event.
  @param[in]  Context            The data passed by the caller.

**/
VOID
EFIAPI
IpSecRecycleCallback (
  IN EFI_EVENT                       Event,
  IN VOID                            *Context
  )
{
  IPSEC_RECYCLE_CONTEXT *RecycleContext;

  RecycleContext = (IPSEC_RECYCLE_CONTEXT *) Context;

  if (RecycleContext->FragmentTable != NULL) {
    FreePool (RecycleContext->FragmentTable);
  }

  if (RecycleContext->PayloadBuffer != NULL) {
    FreePool (RecycleContext->PayloadBuffer);
  }

  FreePool (RecycleContext);
  gBS->CloseEvent (Event);

}

/**
  Calculate the extension hader of IP. The return length only doesn't contain
  the fixed IP header length.

  @param[in]  IpHead             Points to an IP head to be calculated.
  @param[in]  LastHead           Points to the last header of the IP header.

  @return The length of the extension header.

**/
UINT16
IpSecGetPlainExtHeadSize (
  IN VOID                             *IpHead,
  IN UINT8                            *LastHead
  )
{
  UINT16  Size;

  Size = (UINT16) (LastHead - (UINT8 *) IpHead);

  if (Size > sizeof (EFI_IP6_HEADER)) {
    //
    // * (LastHead+1) point the last header's length but not include the first
    // 8 octers, so this formluation add 8 at the end.
    //
    Size = (UINT16) (Size - sizeof (EFI_IP6_HEADER) + *(LastHead + 1) + 8);
  } else {
    Size = 0;
  }

  return Size;
}

/**
  Verify if the Authentication payload is correct.

  @param[in]  EspBuffer          Points to the ESP wrapped buffer.
  @param[in]  EspSize            The size of the ESP wrapped buffer.
  @param[in]  SadEntry           The related SAD entry to store the authentication
                                 algorithm key.
  @param[in]  IcvSize            The length of ICV.

  @retval EFI_SUCCESS        The authentication data is correct.
  @retval EFI_ACCESS_DENIED  The authentication data is not correct.

**/
EFI_STATUS
IpSecEspAuthVerifyPayload (
  IN UINT8                           *EspBuffer,
  IN UINTN                           EspSize,
  IN IPSEC_SAD_ENTRY                 *SadEntry,
  IN UINTN                           IcvSize
  )
{
  EFI_STATUS           Status;
  UINTN                AuthSize;
  UINT8                IcvBuffer[12];
  HASH_DATA_FRAGMENT   HashFragment[1];

  //
  // Calculate the size of authentication payload.
  //
  AuthSize  = EspSize - IcvSize;

  //
  // Calculate the icv buffer and size of the payload.
  //
  HashFragment[0].Data     = EspBuffer;
  HashFragment[0].DataSize = AuthSize;

  Status = IpSecCryptoIoHmac (
             SadEntry->Data->AlgoInfo.EspAlgoInfo.AuthAlgoId,
             SadEntry->Data->AlgoInfo.EspAlgoInfo.AuthKey,
             SadEntry->Data->AlgoInfo.EspAlgoInfo.AuthKeyLength,
             HashFragment,
             1,
             IcvBuffer,
             IcvSize
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Compare the calculated icv and the appended original icv.
  //
  if (CompareMem (EspBuffer + AuthSize, IcvBuffer, IcvSize) == 0) {
    return EFI_SUCCESS;
  }

  DEBUG ((DEBUG_ERROR, "Error auth verify payload\n"));
  return EFI_ACCESS_DENIED;
}

/**
  Search the related SAD entry by the input .

  @param[in]  IpHead       The pointer to IP header.
  @param[in]  IpVersion    The version of IP (IP4 or IP6).
  @param[in]  Spi          The SPI used to search the related SAD entry.


  @retval     NULL             Not find the related SAD entry.
  @retval     IPSEC_SAD_ENTRY  Return the related SAD entry.

**/
IPSEC_SAD_ENTRY *
IpSecFoundSadFromInboundPacket (
   UINT8   *IpHead,
   UINT8   IpVersion,
   UINT32  Spi
   )
{
  EFI_IP_ADDRESS   DestIp;

  //
  // Parse destination address from ip header.
  //
  ZeroMem (&DestIp, sizeof (EFI_IP_ADDRESS));
  if (IpVersion == IP_VERSION_4) {
    CopyMem (
      &DestIp,
      &((IP4_HEAD *) IpHead)->Dst,
      sizeof (IP4_ADDR)
      );
  } else {
    CopyMem (
      &DestIp,
      &((EFI_IP6_HEADER *) IpHead)->DestinationAddress,
      sizeof (EFI_IPv6_ADDRESS)
      );
  }

  //
  // Lookup SAD entry according to the spi and dest address.
  //
  return IpSecLookupSadBySpi (Spi, &DestIp, IpVersion);
}

/**
  Validate the IP6 extension header format for both the packets we received
  and that we will transmit.

  @param[in]  NextHeader    The next header field in IPv6 basic header.
  @param[in]  ExtHdrs       The first bye of the option.
  @param[in]  ExtHdrsLen    The length of the whole option.
  @param[out] LastHeader    The pointer of NextHeader of the last extension
                            header processed by IP6.
  @param[out] RealExtsLen   The length of extension headers processed by IP6 layer.
                            This is an optional parameter that may be NULL.

  @retval     TRUE          The option is properly formated.
  @retval     FALSE         The option is malformated.

**/
BOOLEAN
IpSecIsIp6ExtsValid (
  IN UINT8                  *NextHeader,
  IN UINT8                  *ExtHdrs,
  IN UINT32                 ExtHdrsLen,
  OUT UINT8                 **LastHeader,
  OUT UINT32                *RealExtsLen    OPTIONAL
  )
{
  UINT32                     Pointer;
  UINT8                      *Option;
  UINT8                      OptionLen;
  UINT8                      CountD;
  UINT8                      CountF;
  UINT8                      CountA;

  if (RealExtsLen != NULL) {
    *RealExtsLen = 0;
  }

  *LastHeader = NextHeader;

  if (ExtHdrs == NULL && ExtHdrsLen == 0) {
    return TRUE;
  }

  if ((ExtHdrs == NULL && ExtHdrsLen != 0) || (ExtHdrs != NULL && ExtHdrsLen == 0)) {
    return FALSE;
  }

  Pointer = 0;
  CountD  = 0;
  CountF  = 0;
  CountA  = 0;

  while (Pointer <= ExtHdrsLen) {

    switch (*NextHeader) {
    case IP6_HOP_BY_HOP:
      if (Pointer != 0) {
        return FALSE;
      }

    //
    // Fall through
    //
    case IP6_DESTINATION:
      if (*NextHeader == IP6_DESTINATION) {
        CountD++;
      }

      if (CountD > 2) {
        return FALSE;
      }

      NextHeader = ExtHdrs + Pointer;

      Pointer++;
      Option     = ExtHdrs + Pointer;
      OptionLen  = (UINT8) ((*Option + 1) * 8 - 2);
      Option++;
      Pointer++;

      Pointer = Pointer + OptionLen;
      break;

    case IP6_FRAGMENT:
      if (++CountF > 1) {
        return FALSE;
      }
      //
      // RFC2402, AH header should after fragment header.
      //
      if (CountA > 1) {
        return FALSE;
      }

      NextHeader = ExtHdrs + Pointer;
      Pointer    = Pointer + 8;
      break;

    case IP6_AH:
      if (++CountA > 1) {
        return FALSE;
      }

      Option     = ExtHdrs + Pointer;
      NextHeader = Option;
      Option++;
      //
      // RFC2402, Payload length is specified in 32-bit words, minus "2".
      //
      OptionLen  = (UINT8) ((*Option + 2) * 4);
      Pointer    = Pointer + OptionLen;
      break;

    default:
      *LastHeader = NextHeader;
       if (RealExtsLen != NULL) {
         *RealExtsLen = Pointer;
       }

       return TRUE;
    }
  }

  *LastHeader = NextHeader;

  if (RealExtsLen != NULL) {
    *RealExtsLen = Pointer;
  }

  return TRUE;
}

/**
  The actual entry to process the tunnel header and inner header for tunnel mode
  outbound traffic.

  This function is the subfunction of IpSecEspInboundPacket(). It change the destination
  Ip address to the station address and recalculate the uplayyer's checksum.


  @param[in, out] IpHead             Points to the IP header containing the ESP header
                                     to be trimed on input, and without ESP header
                                     on return.
  @param[in]      IpPayload          The decrypted Ip payload. It start from the inner
                                     header.
  @param[in]      IpVersion          The version of IP.
  @param[in]      SadData            Pointer of the relevant SAD.
  @param[in, out] LastHead           The Last Header in IP header on return.

**/
VOID
IpSecTunnelInboundPacket (
  IN OUT UINT8           *IpHead,
  IN     UINT8           *IpPayload,
  IN     UINT8           IpVersion,
  IN     IPSEC_SAD_DATA  *SadData,
  IN OUT UINT8           *LastHead
  )
{
  EFI_UDP_HEADER   *UdpHeader;
  TCP_HEAD         *TcpHeader;
  UINT16            *Checksum;
  UINT16           PseudoChecksum;
  UINT16           PacketChecksum;
  UINT32           OptionLen;
  IP6_ICMP_HEAD    *Icmp6Head;

  Checksum = NULL;

  if (IpVersion == IP_VERSION_4) {
    //
    // Zero OutIP header use this to indicate the input packet is under
    // IPsec Tunnel protected.
    //
    ZeroMem (
      (IP4_HEAD *)IpHead,
      sizeof (IP4_HEAD)
      );
    CopyMem (
      &((IP4_HEAD *)IpPayload)->Dst,
      &SadData->TunnelDestAddress.v4,
      sizeof (EFI_IPv4_ADDRESS)
      );

    //
    // Recalculate IpHeader Checksum
    //
    if (((IP4_HEAD *)(IpPayload))->Checksum != 0 ) {
      ((IP4_HEAD *)(IpPayload))->Checksum = 0;
      ((IP4_HEAD *)(IpPayload))->Checksum = (UINT16) (~NetblockChecksum (
                                                        (UINT8 *)IpPayload,
                                                        ((IP4_HEAD *)IpPayload)->HeadLen << 2
                                                        ));


    }

    //
    // Recalcualte PseudoChecksum
    //
    switch (((IP4_HEAD *)IpPayload)->Protocol) {
    case EFI_IP_PROTO_UDP :
      UdpHeader = (EFI_UDP_HEADER *)((UINT8 *)IpPayload + (((IP4_HEAD *)IpPayload)->HeadLen << 2));
      Checksum  = & UdpHeader->Checksum;
      *Checksum = 0;
      break;

    case EFI_IP_PROTO_TCP:
      TcpHeader = (TCP_HEAD *) ((UINT8 *)IpPayload + (((IP4_HEAD *)IpPayload)->HeadLen << 2));
      Checksum  = &TcpHeader->Checksum;
      *Checksum = 0;
      break;

    default:
      break;
      }
    PacketChecksum = NetblockChecksum (
                       (UINT8 *)IpPayload + (((IP4_HEAD *)IpPayload)->HeadLen << 2),
                       NTOHS (((IP4_HEAD *)IpPayload)->TotalLen) - (((IP4_HEAD *)IpPayload)->HeadLen << 2)
                       );
    PseudoChecksum = NetPseudoHeadChecksum (
                       ((IP4_HEAD *)IpPayload)->Src,
                       ((IP4_HEAD *)IpPayload)->Dst,
                       ((IP4_HEAD *)IpPayload)->Protocol,
                       0
                       );

      if (Checksum != NULL) {
        *Checksum = NetAddChecksum (PacketChecksum, PseudoChecksum);
        *Checksum = (UINT16) ~(NetAddChecksum (*Checksum, HTONS((UINT16)(NTOHS (((IP4_HEAD *)IpPayload)->TotalLen) - (((IP4_HEAD *)IpPayload)->HeadLen << 2)))));
      }
    }else {
      //
      //  Zero OutIP header use this to indicate the input packet is under
      //  IPsec Tunnel protected.
      //
      ZeroMem (
        IpHead,
        sizeof (EFI_IP6_HEADER)
        );
      CopyMem (
        &((EFI_IP6_HEADER*)IpPayload)->DestinationAddress,
        &SadData->TunnelDestAddress.v6,
        sizeof (EFI_IPv6_ADDRESS)
        );

      //
      // Get the Extension Header and Header length.
      //
      IpSecIsIp6ExtsValid (
        &((EFI_IP6_HEADER *)IpPayload)->NextHeader,
        IpPayload + sizeof (EFI_IP6_HEADER),
        ((EFI_IP6_HEADER *)IpPayload)->PayloadLength,
        &LastHead,
        &OptionLen
        );

      //
      // Recalcualte PseudoChecksum
      //
      switch (*LastHead) {
      case EFI_IP_PROTO_UDP:
        UdpHeader = (EFI_UDP_HEADER *)((UINT8 *)IpPayload + sizeof (EFI_IP6_HEADER) + OptionLen);
        Checksum  = &UdpHeader->Checksum;
        *Checksum = 0;
        break;

      case EFI_IP_PROTO_TCP:
        TcpHeader = (TCP_HEAD *)(IpPayload + sizeof (EFI_IP6_HEADER) + OptionLen);
        Checksum  = &TcpHeader->Checksum;
        *Checksum = 0;
        break;

      case IP6_ICMP:
        Icmp6Head  = (IP6_ICMP_HEAD *) (IpPayload + sizeof (EFI_IP6_HEADER) + OptionLen);
        Checksum   = &Icmp6Head->Checksum;
        *Checksum  = 0;
        break;
      }
      PacketChecksum = NetblockChecksum (
                         IpPayload + sizeof (EFI_IP6_HEADER) + OptionLen,
                         NTOHS(((EFI_IP6_HEADER *)IpPayload)->PayloadLength) - OptionLen
                         );
      PseudoChecksum = NetIp6PseudoHeadChecksum (
                         &((EFI_IP6_HEADER *)IpPayload)->SourceAddress,
                         &((EFI_IP6_HEADER *)IpPayload)->DestinationAddress,
                         *LastHead,
                         0
                         );

    if (Checksum != NULL) {
      *Checksum = NetAddChecksum (PacketChecksum, PseudoChecksum);
      *Checksum = (UINT16) ~(NetAddChecksum (
                               *Checksum,
                               HTONS ((UINT16)((NTOHS (((EFI_IP6_HEADER *)(IpPayload))->PayloadLength)) - OptionLen))
                               ));
    }
  }
}

/**
  The actual entry to create inner header for tunnel mode inbound traffic.

  This function is the subfunction of IpSecEspOutboundPacket(). It create
  the sending packet by encrypting its payload and inserting ESP header in the orginal
  IP header, then return the IpHeader and IPsec protected Fragmentable.

  @param[in, out] IpHead             Points to IP header containing the orginal IP header
                                     to be processed on input, and inserted ESP header
                                     on return.
  @param[in]      IpVersion          The version of IP.
  @param[in]      SadData            The related SAD data.
  @param[in, out] LastHead           The Last Header in IP header.
  @param[in]      OptionsBuffer      Pointer to the options buffer.
  @param[in]      OptionsLength      Length of the options buffer.
  @param[in, out] FragmentTable      Pointer to a list of fragments to be protected by
                                     IPsec on input, and with IPsec protected
                                     on return.
  @param[in]      FragmentCount      The number of fragments.

**/
UINT8 *
IpSecTunnelOutboundPacket (
  IN OUT UINT8                   *IpHead,
  IN     UINT8                   IpVersion,
  IN     IPSEC_SAD_DATA          *SadData,
  IN OUT UINT8                   *LastHead,
  IN     VOID                    **OptionsBuffer,
  IN     UINT32                  *OptionsLength,
  IN OUT EFI_IPSEC_FRAGMENT_DATA **FragmentTable,
  IN     UINT32                  *FragmentCount
  )
{
  UINT8         *InnerHead;
  NET_BUF       *Packet;
  UINT16        PacketChecksum;
  UINT16        *Checksum;
  UINT16        PseudoChecksum;
  IP6_ICMP_HEAD *IcmpHead;

  Checksum = NULL;
  if (OptionsLength == NULL) {
    return NULL;
  }

  if (IpVersion == IP_VERSION_4) {
    InnerHead = AllocateZeroPool (sizeof (IP4_HEAD) + *OptionsLength);
    if (InnerHead == NULL) {
      return NULL;
    }

    CopyMem (
      InnerHead,
      IpHead,
      sizeof (IP4_HEAD)
      );
    CopyMem (
      InnerHead + sizeof (IP4_HEAD),
      *OptionsBuffer,
      *OptionsLength
      );
  } else {
    InnerHead = AllocateZeroPool (sizeof (EFI_IP6_HEADER) + *OptionsLength);
    if (InnerHead == NULL) {
      return NULL;
    }

    CopyMem (
      InnerHead,
      IpHead,
      sizeof (EFI_IP6_HEADER)
      );
    CopyMem (
      InnerHead + sizeof (EFI_IP6_HEADER),
      *OptionsBuffer,
      *OptionsLength
      );
  }
  if (OptionsBuffer != NULL) {
    if (*OptionsLength != 0) {

      *OptionsBuffer = NULL;
      *OptionsLength = 0;
    }
  }

  //
  // 2. Reassamlbe Fragment into Packet
  //
  Packet = NetbufFromExt (
             (NET_FRAGMENT *)(*FragmentTable),
             *FragmentCount,
             0,
             0,
             IpSecOnRecyclePacket,
             NULL
             );
  if (Packet == NULL) {
    FreePool (InnerHead);
    return NULL;
  }

  //
  // 3. Check the Last Header, if it is TCP, UDP or ICMP recalcualate its pesudo
  //    CheckSum.
  //
  switch (*LastHead) {
  case EFI_IP_PROTO_UDP:
    Packet->Udp = (EFI_UDP_HEADER *) NetbufGetByte (Packet, 0, 0);
    ASSERT (Packet->Udp != NULL);
    Checksum = &Packet->Udp->Checksum;
    *Checksum = 0;
    break;

  case EFI_IP_PROTO_TCP:
    Packet->Tcp = (TCP_HEAD *) NetbufGetByte (Packet, 0, 0);
    ASSERT (Packet->Tcp != NULL);
    Checksum = &Packet->Tcp->Checksum;
    *Checksum = 0;
    break;

  case IP6_ICMP:
    IcmpHead = (IP6_ICMP_HEAD *) NetbufGetByte (Packet, 0, NULL);
    ASSERT (IcmpHead != NULL);
    Checksum = &IcmpHead->Checksum;
    *Checksum = 0;
    break;

  default:
    break;
  }

  PacketChecksum = NetbufChecksum (Packet);

  if (IpVersion == IP_VERSION_4) {
    //
    // Replace the source address of Inner Header.
    //
    CopyMem (
      &((IP4_HEAD *)InnerHead)->Src,
      &SadData->SpdSelector->LocalAddress[0].Address.v4,
      sizeof (EFI_IPv4_ADDRESS)
      );

    PacketChecksum = NetbufChecksum (Packet);
    PseudoChecksum = NetPseudoHeadChecksum (
                       ((IP4_HEAD *)InnerHead)->Src,
                       ((IP4_HEAD *)InnerHead)->Dst,
                       *LastHead,
                       0
                       );

   } else {
     //
     // Replace the source address of Inner Header.
     //
     CopyMem (
       &((EFI_IP6_HEADER *)InnerHead)->SourceAddress,
       &(SadData->SpdSelector->LocalAddress[0].Address.v6),
       sizeof (EFI_IPv6_ADDRESS)
       );
     PacketChecksum = NetbufChecksum (Packet);
     PseudoChecksum = NetIp6PseudoHeadChecksum (
                      &((EFI_IP6_HEADER *)InnerHead)->SourceAddress,
                      &((EFI_IP6_HEADER *)InnerHead)->DestinationAddress,
                      *LastHead,
                      0
                      );

   }
   if (Checksum != NULL) {
     *Checksum = NetAddChecksum (PacketChecksum, PseudoChecksum);
     *Checksum = (UINT16) ~(NetAddChecksum ((UINT16)*Checksum, HTONS ((UINT16) Packet->TotalSize)));
   }

  if (Packet != NULL) {
    NetbufFree (Packet);
  }
  return InnerHead;
}

/**
  The actual entry to relative function processes the inbound traffic of ESP header.

  This function is the subfunction of IpSecProtectInboundPacket(). It checks the
  received packet security property and trim the ESP header and then returns without
  an IPsec protected IP Header and FramgmentTable.

  @param[in]      IpVersion          The version of IP.
  @param[in, out] IpHead             Points to the IP header containing the ESP header
                                     to be trimed on input, and without ESP header
                                     on return.
  @param[out]     LastHead           The Last Header in IP header on return.
  @param[in, out] OptionsBuffer      Pointer to the options buffer.
  @param[in, out] OptionsLength      Length of the options buffer.
  @param[in, out] FragmentTable      Pointer to a list of fragments in the form of IPsec
                                     protected on input, and without IPsec protected
                                     on return.
  @param[in, out] FragmentCount      The number of fragments.
  @param[out]     SpdSelector        Pointer to contain the address of SPD selector on return.
  @param[out]     RecycleEvent       The event for recycling of resources.

  @retval EFI_SUCCESS              The operation was successful.
  @retval EFI_ACCESS_DENIED        One or more following conditions is TRUE:
                                   - ESP header was not found or mal-format.
                                   - The related SAD entry was not found.
                                   - The related SAD entry does not support the ESP protocol.
  @retval EFI_OUT_OF_RESOURCES     The required system resource can't be allocated.

**/
EFI_STATUS
IpSecEspInboundPacket (
  IN     UINT8                       IpVersion,
  IN OUT VOID                        *IpHead,
     OUT UINT8                       *LastHead,
  IN OUT VOID                        **OptionsBuffer,
  IN OUT UINT32                      *OptionsLength,
  IN OUT EFI_IPSEC_FRAGMENT_DATA     **FragmentTable,
  IN OUT UINT32                      *FragmentCount,
     OUT EFI_IPSEC_SPD_SELECTOR      **SpdSelector,
     OUT EFI_EVENT                   *RecycleEvent
  )
{
  EFI_STATUS            Status;
  NET_BUF               *Payload;
  UINTN                 EspSize;
  UINTN                 IvSize;
  UINTN                 BlockSize;
  UINTN                 MiscSize;
  UINTN                 PlainPayloadSize;
  UINTN                 PaddingSize;
  UINTN                 IcvSize;
  UINT8                 *ProcessBuffer;
  EFI_ESP_HEADER        *EspHeader;
  EFI_ESP_TAIL          *EspTail;
  EFI_IPSEC_SA_ID       *SaId;
  IPSEC_SAD_DATA        *SadData;
  IPSEC_SAD_ENTRY       *SadEntry;
  IPSEC_RECYCLE_CONTEXT *RecycleContext;
  UINT8                 NextHeader;
  UINT16                IpSecHeadSize;
  UINT8                 *InnerHead;

  Status            = EFI_SUCCESS;
  Payload           = NULL;
  ProcessBuffer     = NULL;
  RecycleContext    = NULL;
  *RecycleEvent     = NULL;
  PlainPayloadSize  = 0;
  NextHeader        = 0;

  //
  // Build netbuf from fragment table first.
  //
  Payload = NetbufFromExt (
              (NET_FRAGMENT *) *FragmentTable,
              *FragmentCount,
              0,
              sizeof (EFI_ESP_HEADER),
              IpSecOnRecyclePacket,
              NULL
              );
  if (Payload == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_EXIT;
  }

  //
  // Get the esp size and esp header from netbuf.
  //
  EspSize   = Payload->TotalSize;
  EspHeader = (EFI_ESP_HEADER *) NetbufGetByte (Payload, 0, NULL);

  if (EspHeader == NULL) {
    Status = EFI_ACCESS_DENIED;
    goto ON_EXIT;
  }

  //
  // Parse destination address from ip header and found the related SAD Entry.
  //
  SadEntry = IpSecFoundSadFromInboundPacket (
               IpHead,
               IpVersion,
               NTOHL (EspHeader->Spi)
               );

  if (SadEntry == NULL) {
    Status = EFI_ACCESS_DENIED;
    goto ON_EXIT;
  }

  SaId    = SadEntry->Id;
  SadData = SadEntry->Data;

  //
  // Only support esp protocol currently.
  //
  if (SaId->Proto != EfiIPsecESP) {
    Status = EFI_ACCESS_DENIED;
    goto ON_EXIT;
  }

  if (!SadData->ManualSet) {
    //
    // TODO: Check SA lifetime and sequence number
    //
  }

  //
  // Allocate buffer for decryption and authentication.
  //
  ProcessBuffer = AllocateZeroPool (EspSize);
  if (ProcessBuffer == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_EXIT;
  }

  NetbufCopy (Payload, 0, (UINT32) EspSize, ProcessBuffer);

  //
  // Get the IcvSize for authentication and BlockSize/IvSize for Decryption.
  //
  IcvSize   = IpSecGetIcvLength (SadEntry->Data->AlgoInfo.EspAlgoInfo.AuthAlgoId);
  IvSize    = IpSecGetEncryptIvLength (SadEntry->Data->AlgoInfo.EspAlgoInfo.EncAlgoId);
  BlockSize = IpSecGetEncryptBlockSize (SadEntry->Data->AlgoInfo.EspAlgoInfo.EncAlgoId);

  //
  // Make sure the ESP packet is not mal-formt.
  // 1. Check whether the Espsize is larger than ESP header + IvSize + EspTail + IcvSize.
  // 2. Check whether the left payload size is multiple of IvSize.
  //
  MiscSize = sizeof (EFI_ESP_HEADER) + IvSize + IcvSize;
  if (EspSize <= (MiscSize + sizeof (EFI_ESP_TAIL))) {
    Status = EFI_ACCESS_DENIED;
    goto ON_EXIT;
  }
  if ((EspSize - MiscSize) % BlockSize != 0) {
    Status = EFI_ACCESS_DENIED;
    goto ON_EXIT;
  }

  //
  // Authenticate the ESP packet.
  //
  if (SadData->AlgoInfo.EspAlgoInfo.AuthKey != NULL) {
    Status = IpSecEspAuthVerifyPayload (
               ProcessBuffer,
               EspSize,
               SadEntry,
               IcvSize
               );
    if (EFI_ERROR (Status)) {
      goto ON_EXIT;
    }
  }
  //
  // Decrypt the payload by the SAD entry if it has decrypt key.
  //
  if (SadData->AlgoInfo.EspAlgoInfo.EncKey != NULL) {
    Status = IpSecCryptoIoDecrypt (
               SadEntry->Data->AlgoInfo.EspAlgoInfo.EncAlgoId,
               SadEntry->Data->AlgoInfo.EspAlgoInfo.EncKey,
               SadEntry->Data->AlgoInfo.EspAlgoInfo.EncKeyLength << 3,
               ProcessBuffer + sizeof (EFI_ESP_HEADER),
               ProcessBuffer + sizeof (EFI_ESP_HEADER) + IvSize,
               EspSize - sizeof (EFI_ESP_HEADER) - IvSize - IcvSize,
               ProcessBuffer + sizeof (EFI_ESP_HEADER) + IvSize
               );
    if (EFI_ERROR (Status)) {
      goto ON_EXIT;
    }
  }

  //
  // Parse EspTail and compute the plain payload size.
  //
  EspTail           = (EFI_ESP_TAIL *) (ProcessBuffer + EspSize - IcvSize - sizeof (EFI_ESP_TAIL));
  PaddingSize       = EspTail->PaddingLength;
  NextHeader        = EspTail->NextHeader;

  if (EspSize <= (MiscSize + sizeof (EFI_ESP_TAIL) + PaddingSize)) {
    Status = EFI_ACCESS_DENIED;
    goto ON_EXIT;
  }
  PlainPayloadSize  = EspSize - MiscSize - sizeof (EFI_ESP_TAIL) - PaddingSize;

  //
  // TODO: handle anti-replay window
  //
  //
  // Decryption and authentication with esp has been done, so it's time to
  // reload the new packet, create recycle event and fixup ip header.
  //
  RecycleContext = AllocateZeroPool (sizeof (IPSEC_RECYCLE_CONTEXT));
  if (RecycleContext == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_EXIT;
  }

  Status = gBS->CreateEvent (
                  EVT_NOTIFY_SIGNAL,
                  TPL_NOTIFY,
                  IpSecRecycleCallback,
                  RecycleContext,
                  RecycleEvent
                  );
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  //
  // The caller will take responsible to handle the original fragment table
  //
  *FragmentTable = AllocateZeroPool (sizeof (EFI_IPSEC_FRAGMENT_DATA));
  if (*FragmentTable == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_EXIT;
  }

  RecycleContext->PayloadBuffer       = ProcessBuffer;
  RecycleContext->FragmentTable       = *FragmentTable;

  //
  // If Tunnel, recalculate upper-layyer PesudoCheckSum and trim the out
  //
  if (SadData->Mode == EfiIPsecTunnel) {
    InnerHead = ProcessBuffer + sizeof (EFI_ESP_HEADER) + IvSize;
    IpSecTunnelInboundPacket (
      IpHead,
      InnerHead,
      IpVersion,
      SadData,
      LastHead
      );

    if (IpVersion == IP_VERSION_4) {
      (*FragmentTable)[0].FragmentBuffer  = InnerHead ;
      (*FragmentTable)[0].FragmentLength  = (UINT32) PlainPayloadSize;

    }else {
      (*FragmentTable)[0].FragmentBuffer  = InnerHead;
      (*FragmentTable)[0].FragmentLength  = (UINT32) PlainPayloadSize;
    }
  } else {
    (*FragmentTable)[0].FragmentBuffer  = ProcessBuffer + sizeof (EFI_ESP_HEADER) + IvSize;
    (*FragmentTable)[0].FragmentLength  = (UINT32) PlainPayloadSize;
  }

  *FragmentCount                      = 1;

  //
  // Update the total length field in ip header since processed by esp.
  //
  if (SadData->Mode != EfiIPsecTunnel) {
    if (IpVersion == IP_VERSION_4) {
      ((IP4_HEAD *) IpHead)->TotalLen = HTONS ((UINT16) ((((IP4_HEAD *) IpHead)->HeadLen << 2) + PlainPayloadSize));
    } else {
      IpSecHeadSize                              = IpSecGetPlainExtHeadSize (IpHead, LastHead);
      ((EFI_IP6_HEADER *) IpHead)->PayloadLength = HTONS ((UINT16)(IpSecHeadSize + PlainPayloadSize));
    }
    //
    // Update the next layer field in ip header since esp header inserted.
    //
    *LastHead = NextHeader;
  }


  //
  // Update the SPD association of the SAD entry.
  //
  *SpdSelector = SadData->SpdSelector;

ON_EXIT:
  if (Payload != NULL) {
    NetbufFree (Payload);
  }

  if (EFI_ERROR (Status)) {
    if (ProcessBuffer != NULL) {
      FreePool (ProcessBuffer);
    }

    if (RecycleContext != NULL) {
      FreePool (RecycleContext);
    }

    if (*RecycleEvent != NULL) {
      gBS->CloseEvent (*RecycleEvent);
    }
  }

  return Status;
}

/**
  The actual entry to the relative function processes the output traffic using the ESP protocol.

  This function is the subfunction of IpSecProtectOutboundPacket(). It protected
  the sending packet by encrypting its payload and inserting ESP header in the orginal
  IP header, then return the IpHeader and IPsec protected Fragmentable.

  @param[in]      IpVersion          The version of IP.
  @param[in, out] IpHead             Points to IP header containing the orginal IP header
                                     to be processed on input, and inserted ESP header
                                     on return.
  @param[in, out] LastHead           The Last Header in IP header.
  @param[in, out] OptionsBuffer      Pointer to the options buffer.
  @param[in, out] OptionsLength      Length of the options buffer.
  @param[in, out] FragmentTable      Pointer to a list of fragments to be protected by
                                     IPsec on input, and with IPsec protected
                                     on return.
  @param[in, out] FragmentCount      The number of fragments.
  @param[in]      SadEntry           The related SAD entry.
  @param[out]     RecycleEvent       The event for recycling of resources.

  @retval EFI_SUCCESS              The operation was successful.
  @retval EFI_OUT_OF_RESOURCES     The required system resources can't be allocated.

**/
EFI_STATUS
IpSecEspOutboundPacket (
  IN UINT8                           IpVersion,
  IN OUT VOID                        *IpHead,
  IN OUT UINT8                       *LastHead,
  IN OUT VOID                        **OptionsBuffer,
  IN OUT UINT32                      *OptionsLength,
  IN OUT EFI_IPSEC_FRAGMENT_DATA     **FragmentTable,
  IN OUT UINT32                      *FragmentCount,
  IN     IPSEC_SAD_ENTRY             *SadEntry,
     OUT EFI_EVENT                   *RecycleEvent
  )
{
  EFI_STATUS            Status;
  UINTN                 Index;
  EFI_IPSEC_SA_ID       *SaId;
  IPSEC_SAD_DATA        *SadData;
  IPSEC_RECYCLE_CONTEXT *RecycleContext;
  UINT8                 *ProcessBuffer;
  UINTN                 BytesCopied;
  INTN                  EncryptBlockSize;// Size of encryption block, 4 bytes aligned and >= 4
  UINTN                 EspSize;         // Total size of esp wrapped ip payload
  UINTN                 IvSize;          // Size of IV, optional, might be 0
  UINTN                 PlainPayloadSize;// Original IP payload size
  UINTN                 PaddingSize;     // Size of padding
  UINTN                 EncryptSize;     // Size of data to be encrypted, start after IV and
                                         // stop before ICV
  UINTN                 IcvSize;         // Size of ICV, optional, might be 0
  UINT8                 *RestOfPayload;  // Start of Payload after IV
  UINT8                 *Padding;        // Start address of padding
  EFI_ESP_HEADER        *EspHeader;      // Start address of ESP frame
  EFI_ESP_TAIL          *EspTail;        // Address behind padding
  UINT8                 *InnerHead;
  HASH_DATA_FRAGMENT    HashFragment[1];

  Status          = EFI_ACCESS_DENIED;
  SaId            = SadEntry->Id;
  SadData         = SadEntry->Data;
  ProcessBuffer   = NULL;
  RecycleContext  = NULL;
  *RecycleEvent   = NULL;
  InnerHead       = NULL;

  if (!SadData->ManualSet &&
      SadData->AlgoInfo.EspAlgoInfo.EncKey == NULL &&
      SadData->AlgoInfo.EspAlgoInfo.AuthKey == NULL
      ) {
    //
    // Invalid manual SAD entry configuration.
    //
    goto ON_EXIT;
  }

  //
  // Create OutHeader according to Inner Header
  //
  if (SadData->Mode == EfiIPsecTunnel) {
    InnerHead = IpSecTunnelOutboundPacket (
                  IpHead,
                  IpVersion,
                  SadData,
                  LastHead,
                  OptionsBuffer,
                  OptionsLength,
                  FragmentTable,
                  FragmentCount
                  );

    if (InnerHead == NULL) {
      return EFI_INVALID_PARAMETER;
    }

  }

  //
  // Calculate enctrypt block size, need iv by default and 4 bytes alignment.
  //
  EncryptBlockSize  = 4;

  if (SadData->AlgoInfo.EspAlgoInfo.EncKey != NULL) {
    EncryptBlockSize  = IpSecGetEncryptBlockSize (SadEntry->Data->AlgoInfo.EspAlgoInfo.EncAlgoId);

    if (EncryptBlockSize < 0 || (EncryptBlockSize != 1 && EncryptBlockSize % 4 != 0)) {
      goto ON_EXIT;
    }
  }

  //
  // Calculate the plain payload size according to the fragment table.
  //
  PlainPayloadSize = 0;
  for (Index = 0; Index < *FragmentCount; Index++) {
    PlainPayloadSize += (*FragmentTable)[Index].FragmentLength;
  }

  //
  // Add IPHeader size for Tunnel Mode
  //
  if (SadData->Mode == EfiIPsecTunnel) {
    if (IpVersion == IP_VERSION_4) {
      PlainPayloadSize += sizeof (IP4_HEAD);
    } else {
      PlainPayloadSize += sizeof (EFI_IP6_HEADER);
    }
    //
    // OPtions should be encryption into it
    //
    PlainPayloadSize += *OptionsLength;
  }


  //
  // Calculate icv size, optional by default and 4 bytes alignment.
  //
  IcvSize = 0;
  if (SadData->AlgoInfo.EspAlgoInfo.AuthKey != NULL) {
    IcvSize = IpSecGetIcvLength (SadEntry->Data->AlgoInfo.EspAlgoInfo.AuthAlgoId);
    if (IcvSize % 4 != 0) {
      goto ON_EXIT;
    }
  }

  //
  // Calcuate the total size of esp wrapped ip payload.
  //
  IvSize        = IpSecGetEncryptIvLength (SadEntry->Data->AlgoInfo.EspAlgoInfo.EncAlgoId);
  EncryptSize   = (PlainPayloadSize + sizeof (EFI_ESP_TAIL) + EncryptBlockSize - 1) / EncryptBlockSize * EncryptBlockSize;
  PaddingSize   = EncryptSize - PlainPayloadSize - sizeof (EFI_ESP_TAIL);
  EspSize       = sizeof (EFI_ESP_HEADER) + IvSize + EncryptSize + IcvSize;

  ProcessBuffer = AllocateZeroPool (EspSize);
  if (ProcessBuffer == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_EXIT;
  }

  //
  // Calculate esp header and esp tail including header, payload and padding.
  //
  EspHeader     = (EFI_ESP_HEADER *) ProcessBuffer;
  RestOfPayload = (UINT8 *) (EspHeader + 1) + IvSize;
  Padding       = RestOfPayload + PlainPayloadSize;
  EspTail       = (EFI_ESP_TAIL *) (Padding + PaddingSize);

  //
  // Fill the sn and spi fields in esp header.
  //
  EspHeader->SequenceNumber = HTONL ((UINT32) SadData->SequenceNumber + 1);
  //EspHeader->SequenceNumber = HTONL ((UINT32) SadData->SequenceNumber);
  EspHeader->Spi            = HTONL (SaId->Spi);

  //
  // Copy the rest of payload (after iv) from the original fragment buffer.
  //
  BytesCopied = 0;

  //
  // For Tunnel Mode
  //
  if (SadData->Mode == EfiIPsecTunnel) {
    if (IpVersion == IP_VERSION_4) {
      //
      // HeadLen, Total Length
      //
      ((IP4_HEAD *)InnerHead)->HeadLen  = (UINT8) ((sizeof (IP4_HEAD) + *OptionsLength) >> 2);
      ((IP4_HEAD *)InnerHead)->TotalLen = HTONS ((UINT16) PlainPayloadSize);
      ((IP4_HEAD *)InnerHead)->Checksum = 0;
      ((IP4_HEAD *)InnerHead)->Checksum = (UINT16) (~NetblockChecksum (
                                                  (UINT8 *)InnerHead,
                                                  sizeof(IP4_HEAD)
                                                  ));
      CopyMem (
        RestOfPayload + BytesCopied,
        InnerHead,
        sizeof (IP4_HEAD) + *OptionsLength
        );
      BytesCopied += sizeof (IP4_HEAD) + *OptionsLength;

    } else {
    ((EFI_IP6_HEADER *)InnerHead)->PayloadLength = HTONS ((UINT16) (PlainPayloadSize - sizeof (EFI_IP6_HEADER)));
      CopyMem (
        RestOfPayload + BytesCopied,
        InnerHead,
        sizeof (EFI_IP6_HEADER) + *OptionsLength
        );
      BytesCopied += sizeof (EFI_IP6_HEADER) + *OptionsLength;
    }
  }

  for (Index = 0; Index < *FragmentCount; Index++) {
    CopyMem (
      (RestOfPayload + BytesCopied),
      (*FragmentTable)[Index].FragmentBuffer,
      (*FragmentTable)[Index].FragmentLength
      );
    BytesCopied += (*FragmentTable)[Index].FragmentLength;
  }
  //
  // Fill the padding buffer by natural number sequence.
  //
  for (Index = 0; Index < PaddingSize; Index++) {
    Padding[Index] = (UINT8) (Index + 1);
  }
  //
  // Fill the padding length and next header fields in esp tail.
  //
  EspTail->PaddingLength  = (UINT8) PaddingSize;
  EspTail->NextHeader     = *LastHead;

  //
  // Fill the next header for Tunnel mode.
  //
  if (SadData->Mode == EfiIPsecTunnel) {
    if (IpVersion == IP_VERSION_4) {
      EspTail->NextHeader = 4;
    } else {
      EspTail->NextHeader = 41;
    }
  }

  //
  // Generate iv at random by crypt library.
  //
  Status = IpSecGenerateIv (
             (UINT8 *) (EspHeader + 1),
             IvSize
             );


  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  //
  // Encryption the payload (after iv) by the SAD entry if has encrypt key.
  //
  if (SadData->AlgoInfo.EspAlgoInfo.EncKey != NULL) {
    Status = IpSecCryptoIoEncrypt (
               SadEntry->Data->AlgoInfo.EspAlgoInfo.EncAlgoId,
               SadEntry->Data->AlgoInfo.EspAlgoInfo.EncKey,
               SadEntry->Data->AlgoInfo.EspAlgoInfo.EncKeyLength << 3,
               (UINT8 *)(EspHeader + 1),
               RestOfPayload,
               EncryptSize,
               RestOfPayload
               );

    if (EFI_ERROR (Status)) {
      goto ON_EXIT;
    }
  }

  //
  // Authenticate the esp wrapped buffer by the SAD entry if it has auth key.
  //
  if (SadData->AlgoInfo.EspAlgoInfo.AuthKey != NULL) {

    HashFragment[0].Data     = ProcessBuffer;
    HashFragment[0].DataSize = EspSize - IcvSize;
    Status = IpSecCryptoIoHmac (
               SadEntry->Data->AlgoInfo.EspAlgoInfo.AuthAlgoId,
               SadEntry->Data->AlgoInfo.EspAlgoInfo.AuthKey,
               SadEntry->Data->AlgoInfo.EspAlgoInfo.AuthKeyLength,
               HashFragment,
               1,
               ProcessBuffer + EspSize - IcvSize,
               IcvSize
               );
    if (EFI_ERROR (Status)) {
      goto ON_EXIT;
    }
  }

  //
  // Encryption and authentication with esp has been done, so it's time to
  // reload the new packet, create recycle event and fixup ip header.
  //
  RecycleContext = AllocateZeroPool (sizeof (IPSEC_RECYCLE_CONTEXT));
  if (RecycleContext == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_EXIT;
  }

  Status = gBS->CreateEvent (
                  EVT_NOTIFY_SIGNAL,
                  TPL_NOTIFY,
                  IpSecRecycleCallback,
                  RecycleContext,
                  RecycleEvent
                  );
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }
  //
  // Caller take responsible to handle the original fragment table.
  //
  *FragmentTable = AllocateZeroPool (sizeof (EFI_IPSEC_FRAGMENT_DATA));
  if (*FragmentTable == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_EXIT;
  }

  RecycleContext->FragmentTable       = *FragmentTable;
  RecycleContext->PayloadBuffer       = ProcessBuffer;
  (*FragmentTable)[0].FragmentBuffer  = ProcessBuffer;
  (*FragmentTable)[0].FragmentLength  = (UINT32) EspSize;
  *FragmentCount                      = 1;

  //
  // Update the total length field in ip header since processed by esp.
  //
  if (IpVersion == IP_VERSION_4) {
    ((IP4_HEAD *) IpHead)->TotalLen = HTONS ((UINT16) ((((IP4_HEAD *) IpHead)->HeadLen << 2) + EspSize));
  } else {
    ((EFI_IP6_HEADER *) IpHead)->PayloadLength = (UINT16) (IpSecGetPlainExtHeadSize (IpHead, LastHead) + EspSize);
  }

  //
  // If tunnel mode, it should change the outer Ip header with tunnel source address
  // and destination tunnel address.
  //
  if (SadData->Mode == EfiIPsecTunnel) {
    if (IpVersion == IP_VERSION_4) {
      CopyMem (
        &((IP4_HEAD *) IpHead)->Src,
        &SadData->TunnelSourceAddress.v4,
        sizeof (EFI_IPv4_ADDRESS)
        );
      CopyMem (
        &((IP4_HEAD *) IpHead)->Dst,
        &SadData->TunnelDestAddress.v4,
        sizeof (EFI_IPv4_ADDRESS)
        );
    } else {
      CopyMem (
        &((EFI_IP6_HEADER *) IpHead)->SourceAddress,
        &SadData->TunnelSourceAddress.v6,
        sizeof (EFI_IPv6_ADDRESS)
        );
      CopyMem (
        &((EFI_IP6_HEADER *) IpHead)->DestinationAddress,
        &SadData->TunnelDestAddress.v6,
        sizeof (EFI_IPv6_ADDRESS)
        );
    }
  }

  //
  // Update the next layer field in ip header since esp header inserted.
  //
  *LastHead = IPSEC_ESP_PROTOCOL;

  //
  // Increase the sn number in SAD entry according to rfc4303.
  //
  SadData->SequenceNumber++;

ON_EXIT:
  if (EFI_ERROR (Status)) {
    if (ProcessBuffer != NULL) {
      FreePool (ProcessBuffer);
    }

    if (RecycleContext != NULL) {
      FreePool (RecycleContext);
    }

    if (*RecycleEvent != NULL) {
      gBS->CloseEvent (*RecycleEvent);
    }
  }

  return Status;
}

/**
  This function processes the inbound traffic with IPsec.

  It checks the received packet security property, trims the ESP/AH header, and then
  returns without an IPsec protected IP Header and FragmentTable.

  @param[in]      IpVersion          The version of IP.
  @param[in, out] IpHead             Points to IP header containing the ESP/AH header
                                     to be trimed on input, and without ESP/AH header
                                     on return.
  @param[in, out] LastHead           The Last Header in IP header on return.
  @param[in, out] OptionsBuffer      Pointer to the options buffer.
  @param[in, out] OptionsLength      Length of the options buffer.
  @param[in, out] FragmentTable      Pointer to a list of fragments in form of IPsec
                                     protected on input, and without IPsec protected
                                     on return.
  @param[in, out] FragmentCount      The number of fragments.
  @param[out]     SpdEntry           Pointer to contain the address of SPD entry on return.
  @param[out]     RecycleEvent       The event for recycling of resources.

  @retval EFI_SUCCESS              The operation was successful.
  @retval EFI_UNSUPPORTED          The IPSEC protocol is not supported.

**/
EFI_STATUS
IpSecProtectInboundPacket (
  IN     UINT8                       IpVersion,
  IN OUT VOID                        *IpHead,
  IN OUT UINT8                       *LastHead,
  IN OUT VOID                        **OptionsBuffer,
  IN OUT UINT32                      *OptionsLength,
  IN OUT EFI_IPSEC_FRAGMENT_DATA     **FragmentTable,
  IN OUT UINT32                      *FragmentCount,
     OUT EFI_IPSEC_SPD_SELECTOR      **SpdEntry,
     OUT EFI_EVENT                   *RecycleEvent
  )
{
  if (*LastHead == IPSEC_ESP_PROTOCOL) {
    //
    // Process the esp ipsec header of the inbound traffic.
    //
    return IpSecEspInboundPacket (
             IpVersion,
             IpHead,
             LastHead,
             OptionsBuffer,
             OptionsLength,
             FragmentTable,
             FragmentCount,
             SpdEntry,
             RecycleEvent
             );
  }
  //
  // The other protocols are not supported.
  //
  return EFI_UNSUPPORTED;
}

/**
  This fucntion processes the output traffic with IPsec.

  It protected the sending packet by encrypting it payload and inserting ESP/AH header
  in the orginal IP header, then return the IpHeader and IPsec protected Fragmentable.

  @param[in]      IpVersion          The version of IP.
  @param[in, out] IpHead             Point to IP header containing the orginal IP header
                                     to be processed on input, and inserted ESP/AH header
                                     on return.
  @param[in, out] LastHead           The Last Header in IP header.
  @param[in, out] OptionsBuffer      Pointer to the options buffer.
  @param[in, out] OptionsLength      Length of the options buffer.
  @param[in, out] FragmentTable      Pointer to a list of fragments to be protected by
                                     IPsec on input, and with IPsec protected
                                     on return.
  @param[in, out] FragmentCount      Number of fragments.
  @param[in]      SadEntry           Related SAD entry.
  @param[out]     RecycleEvent       Event for recycling of resources.

  @retval EFI_SUCCESS              The operation is successful.
  @retval EFI_UNSUPPORTED          If the IPSEC protocol is not supported.

**/
EFI_STATUS
IpSecProtectOutboundPacket (
  IN     UINT8                       IpVersion,
  IN OUT VOID                        *IpHead,
  IN OUT UINT8                       *LastHead,
  IN OUT VOID                        **OptionsBuffer,
  IN OUT UINT32                      *OptionsLength,
  IN OUT EFI_IPSEC_FRAGMENT_DATA     **FragmentTable,
  IN OUT UINT32                      *FragmentCount,
  IN     IPSEC_SAD_ENTRY             *SadEntry,
     OUT EFI_EVENT                   *RecycleEvent
  )
{
  if (SadEntry->Id->Proto == EfiIPsecESP) {
    //
    // Process the esp ipsec header of the outbound traffic.
    //
    return IpSecEspOutboundPacket (
             IpVersion,
             IpHead,
             LastHead,
             OptionsBuffer,
             OptionsLength,
             FragmentTable,
             FragmentCount,
             SadEntry,
             RecycleEvent
             );
  }
  //
  // The other protocols are not supported.
  //
  return EFI_UNSUPPORTED;
}
