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