/** @file\r
The implementation of IPsec.\r
\r
- Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>\r
+ (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>\r
+ Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>\r
\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
Check if the specified Address is the Valid Address Range.\r
\r
This function checks if the bytes after prefixed length are all Zero in this\r
- Address. This Address is supposed to point to a range address. That means it \r
+ Address. This Address is supposed to point to a range address. That means it\r
should gives the correct prefixed address and the bytes outside the prefixed are\r
zero.\r
\r
{\r
LIST_ENTRY *Entry;\r
IPSEC_SAD_ENTRY *SadEntry;\r
- \r
+\r
NET_LIST_FOR_EACH (Entry, SadList) {\r
\r
SadEntry = IPSEC_SAD_ENTRY_FROM_SPD (Entry);\r
DestAddress,\r
SadEntry->Data->SpdSelector->RemoteAddress,\r
SadEntry->Data->SpdSelector->RemoteAddressCount\r
- )){ \r
+ )){\r
return SadEntry;\r
}\r
}\r
if (SadEntry->Id->Spi == Spi) {\r
if (SadEntry->Data->Mode == EfiIPsecTunnel) {\r
if (CompareMem (\r
- &DestAddress, \r
+ &DestAddress,\r
&SadEntry->Data->TunnelDestAddress,\r
sizeof (EFI_IP_ADDRESS)\r
)) {\r
} else {\r
if (SadEntry->Data->SpdSelector != NULL &&\r
IpSecMatchIpAddress (\r
- IpVersion, \r
- DestAddress, \r
+ IpVersion,\r
+ DestAddress,\r
SadEntry->Data->SpdSelector->RemoteAddress,\r
SadEntry->Data->SpdSelector->RemoteAddressCount\r
)\r
) {\r
return SadEntry;\r
- } \r
+ }\r
}\r
}\r
}\r
sizeof (EFI_IP_ADDRESS)\r
);\r
}\r
- \r
+\r
//\r
// Find the SAD entry in the spd.sas list according to the dest address.\r
//\r
Entry = IpSecLookupSadBySpd (&SpdEntry->Data->Sas, &DestIp, IpVersion);\r
\r
if (Entry == NULL) {\r
-\r
if (OldLastHead != IP6_ICMP ||\r
(OldLastHead == IP6_ICMP && *IpPayload == ICMP_V6_ECHO_REQUEST)\r
) {\r
&DestIp\r
);\r
}\r
- \r
+\r
}\r
\r
return EFI_NOT_READY;\r
IN VOID *IpHead,\r
IN UINT8 *IpPayload,\r
IN UINT8 Protocol,\r
- IN BOOLEAN IsOutbound, \r
+ IN BOOLEAN IsOutbound,\r
OUT EFI_IPSEC_ACTION *Action\r
)\r
{\r
}\r
\r
/**\r
- Calculate the extension hader of IP. The return length only doesn't contain \r
+ Calculate the extension hader of IP. The return length only doesn't contain\r
the fixed IP header length.\r
\r
@param[in] IpHead Points to an IP head to be calculated.\r
IN UINT8 *EspBuffer,\r
IN UINTN EspSize,\r
IN IPSEC_SAD_ENTRY *SadEntry,\r
- IN UINTN *IcvSize\r
+ IN UINTN IcvSize\r
)\r
{\r
EFI_STATUS Status;\r
//\r
// Calculate the size of authentication payload.\r
//\r
- *IcvSize = IpSecGetIcvLength (SadEntry->Data->AlgoInfo.EspAlgoInfo.AuthAlgoId);\r
- AuthSize = EspSize - *IcvSize;\r
+ AuthSize = EspSize - IcvSize;\r
\r
//\r
// Calculate the icv buffer and size of the payload.\r
//\r
HashFragment[0].Data = EspBuffer;\r
HashFragment[0].DataSize = AuthSize;\r
- \r
+\r
Status = IpSecCryptoIoHmac (\r
SadEntry->Data->AlgoInfo.EspAlgoInfo.AuthAlgoId,\r
SadEntry->Data->AlgoInfo.EspAlgoInfo.AuthKey,\r
HashFragment,\r
1,\r
IcvBuffer,\r
- *IcvSize\r
+ IcvSize\r
);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
- \r
+\r
//\r
// Compare the calculated icv and the appended original icv.\r
//\r
- if (CompareMem (EspBuffer + AuthSize, IcvBuffer, *IcvSize) == 0) {\r
+ if (CompareMem (EspBuffer + AuthSize, IcvBuffer, IcvSize) == 0) {\r
return EFI_SUCCESS;\r
}\r
\r
@param[in] IpHead The pointer to IP header.\r
@param[in] IpVersion The version of IP (IP4 or IP6).\r
@param[in] Spi The SPI used to search the related SAD entry.\r
- \r
+\r
\r
@retval NULL Not find the related SAD entry.\r
- @retval IPSEC_SAD_ENTRY Return the related SAD entry. \r
+ @retval IPSEC_SAD_ENTRY Return the related SAD entry.\r
\r
**/\r
IPSEC_SAD_ENTRY *\r
UINT8 *IpHead,\r
UINT8 IpVersion,\r
UINT32 Spi\r
- ) \r
+ )\r
{\r
EFI_IP_ADDRESS DestIp;\r
- \r
+\r
//\r
// Parse destination address from ip header.\r
//\r
sizeof (EFI_IPv6_ADDRESS)\r
);\r
}\r
- \r
+\r
//\r
// Lookup SAD entry according to the spi and dest address.\r
- // \r
+ //\r
return IpSecLookupSadBySpi (Spi, &DestIp, IpVersion);\r
}\r
\r
UINT32 Pointer;\r
UINT8 *Option;\r
UINT8 OptionLen;\r
- BOOLEAN Flag;\r
UINT8 CountD;\r
UINT8 CountF;\r
UINT8 CountA;\r
}\r
\r
Pointer = 0;\r
- Flag = FALSE;\r
CountD = 0;\r
CountF = 0;\r
CountA = 0;\r
return FALSE;\r
}\r
\r
- Flag = TRUE;\r
-\r
//\r
// Fall through\r
//\r
}\r
\r
return TRUE;\r
- } \r
+ }\r
}\r
\r
*LastHeader = NextHeader;\r
}\r
\r
/**\r
- The actual entry to process the tunnel header and inner header for tunnel mode \r
+ The actual entry to process the tunnel header and inner header for tunnel mode\r
outbound traffic.\r
\r
- This function is the subfunction of IpSecEspInboundPacket(). It change the destination \r
+ This function is the subfunction of IpSecEspInboundPacket(). It change the destination\r
Ip address to the station address and recalculate the uplayyer's checksum.\r
- \r
\r
- @param[in, out] IpHead Points to the IP header containing the ESP header \r
+\r
+ @param[in, out] IpHead Points to the IP header containing the ESP header\r
to be trimed on input, and without ESP header\r
on return.\r
@param[in] IpPayload The decrypted Ip payload. It start from the inner\r
IP6_ICMP_HEAD *Icmp6Head;\r
\r
Checksum = NULL;\r
- \r
+\r
if (IpVersion == IP_VERSION_4) {\r
//\r
- // Zero OutIP header use this to indicate the input packet is under \r
+ // Zero OutIP header use this to indicate the input packet is under\r
// IPsec Tunnel protected.\r
//\r
ZeroMem (\r
&SadData->TunnelDestAddress.v4,\r
sizeof (EFI_IPv4_ADDRESS)\r
);\r
- \r
+\r
//\r
// Recalculate IpHeader Checksum\r
//\r
if (((IP4_HEAD *)(IpPayload))->Checksum != 0 ) {\r
((IP4_HEAD *)(IpPayload))->Checksum = 0;\r
((IP4_HEAD *)(IpPayload))->Checksum = (UINT16) (~NetblockChecksum (\r
- (UINT8 *)IpPayload, \r
+ (UINT8 *)IpPayload,\r
((IP4_HEAD *)IpPayload)->HeadLen << 2\r
));\r
\r
\r
}\r
- \r
+\r
//\r
// Recalcualte PseudoChecksum\r
//\r
break;\r
}\r
PacketChecksum = NetblockChecksum (\r
- (UINT8 *)IpPayload + (((IP4_HEAD *)IpPayload)->HeadLen << 2), \r
+ (UINT8 *)IpPayload + (((IP4_HEAD *)IpPayload)->HeadLen << 2),\r
NTOHS (((IP4_HEAD *)IpPayload)->TotalLen) - (((IP4_HEAD *)IpPayload)->HeadLen << 2)\r
);\r
PseudoChecksum = NetPseudoHeadChecksum (\r
((IP4_HEAD *)IpPayload)->Protocol,\r
0\r
);\r
- \r
+\r
if (Checksum != NULL) {\r
*Checksum = NetAddChecksum (PacketChecksum, PseudoChecksum);\r
*Checksum = (UINT16) ~(NetAddChecksum (*Checksum, HTONS((UINT16)(NTOHS (((IP4_HEAD *)IpPayload)->TotalLen) - (((IP4_HEAD *)IpPayload)->HeadLen << 2)))));\r
}\r
}else {\r
//\r
- // Zero OutIP header use this to indicate the input packet is under \r
+ // Zero OutIP header use this to indicate the input packet is under\r
// IPsec Tunnel protected.\r
//\r
ZeroMem (\r
&SadData->TunnelDestAddress.v6,\r
sizeof (EFI_IPv6_ADDRESS)\r
);\r
- \r
+\r
//\r
// Get the Extension Header and Header length.\r
//\r
&LastHead,\r
&OptionLen\r
);\r
- \r
+\r
//\r
// Recalcualte PseudoChecksum\r
//\r
break;\r
}\r
PacketChecksum = NetblockChecksum (\r
- IpPayload + sizeof (EFI_IP6_HEADER) + OptionLen, \r
+ IpPayload + sizeof (EFI_IP6_HEADER) + OptionLen,\r
NTOHS(((EFI_IP6_HEADER *)IpPayload)->PayloadLength) - OptionLen\r
);\r
PseudoChecksum = NetIp6PseudoHeadChecksum (\r
*LastHead,\r
0\r
);\r
- \r
+\r
if (Checksum != NULL) {\r
*Checksum = NetAddChecksum (PacketChecksum, PseudoChecksum);\r
*Checksum = (UINT16) ~(NetAddChecksum (\r
HTONS ((UINT16)((NTOHS (((EFI_IP6_HEADER *)(IpPayload))->PayloadLength)) - OptionLen))\r
));\r
}\r
- } \r
+ }\r
}\r
\r
/**\r
The actual entry to create inner header for tunnel mode inbound traffic.\r
\r
- This function is the subfunction of IpSecEspOutboundPacket(). It create \r
- the sending packet by encrypting its payload and inserting ESP header in the orginal \r
+ This function is the subfunction of IpSecEspOutboundPacket(). It create\r
+ the sending packet by encrypting its payload and inserting ESP header in the orginal\r
IP header, then return the IpHeader and IPsec protected Fragmentable.\r
- \r
- @param[in, out] IpHead Points to IP header containing the orginal IP header \r
+\r
+ @param[in, out] IpHead Points to IP header containing the orginal IP header\r
to be processed on input, and inserted ESP header\r
on return.\r
@param[in] IpVersion The version of IP.\r
@param[in] SadData The related SAD data.\r
- @param[in, out] LastHead The Last Header in IP header. \r
+ @param[in, out] LastHead The Last Header in IP header.\r
@param[in] OptionsBuffer Pointer to the options buffer.\r
@param[in] OptionsLength Length of the options buffer.\r
@param[in, out] FragmentTable Pointer to a list of fragments to be protected by\r
on return.\r
@param[in] FragmentCount The number of fragments.\r
\r
- @retval EFI_SUCCESS The operation was successful.\r
- @retval EFI_OUT_OF_RESOURCES The required system resources can't be allocated.\r
-\r
**/\r
UINT8 *\r
IpSecTunnelOutboundPacket (\r
if (OptionsLength == NULL) {\r
return NULL;\r
}\r
- \r
+\r
if (IpVersion == IP_VERSION_4) {\r
InnerHead = AllocateZeroPool (sizeof (IP4_HEAD) + *OptionsLength);\r
- ASSERT (InnerHead != NULL);\r
+ if (InnerHead == NULL) {\r
+ return NULL;\r
+ }\r
+ \r
CopyMem (\r
InnerHead,\r
IpHead,\r
);\r
} else {\r
InnerHead = AllocateZeroPool (sizeof (EFI_IP6_HEADER) + *OptionsLength);\r
+ if (InnerHead == NULL) {\r
+ return NULL;\r
+ }\r
+ \r
CopyMem (\r
InnerHead,\r
IpHead,\r
*OptionsLength = 0;\r
}\r
}\r
- \r
+\r
//\r
// 2. Reassamlbe Fragment into Packet\r
//\r
IpSecOnRecyclePacket,\r
NULL\r
);\r
- ASSERT (Packet != NULL);\r
+ if (Packet == NULL) {\r
+ FreePool (InnerHead);\r
+ return NULL;\r
+ }\r
+ \r
//\r
// 3. Check the Last Header, if it is TCP, UDP or ICMP recalcualate its pesudo\r
// CheckSum.\r
Checksum = &IcmpHead->Checksum;\r
*Checksum = 0;\r
break;\r
- \r
- default: \r
+\r
+ default:\r
break;\r
}\r
\r
PacketChecksum = NetbufChecksum (Packet);\r
- \r
+\r
if (IpVersion == IP_VERSION_4) {\r
//\r
// Replace the source address of Inner Header.\r
*LastHead,\r
0\r
);\r
- \r
+\r
} else {\r
//\r
// Replace the source address of Inner Header.\r
*LastHead,\r
0\r
);\r
- \r
+\r
}\r
if (Checksum != NULL) {\r
*Checksum = NetAddChecksum (PacketChecksum, PseudoChecksum);\r
/**\r
The actual entry to relative function processes the inbound traffic of ESP header.\r
\r
- This function is the subfunction of IpSecProtectInboundPacket(). It checks the \r
+ This function is the subfunction of IpSecProtectInboundPacket(). It checks the\r
received packet security property and trim the ESP header and then returns without\r
an IPsec protected IP Header and FramgmentTable.\r
- \r
+\r
@param[in] IpVersion The version of IP.\r
- @param[in, out] IpHead Points to the IP header containing the ESP header \r
+ @param[in, out] IpHead Points to the IP header containing the ESP header\r
to be trimed on input, and without ESP header\r
on return.\r
@param[out] LastHead The Last Header in IP header on return.\r
\r
@retval EFI_SUCCESS The operation was successful.\r
@retval EFI_ACCESS_DENIED One or more following conditions is TRUE:\r
- - ESP header was not found.\r
+ - ESP header was not found or mal-format.\r
- The related SAD entry was not found.\r
- The related SAD entry does not support the ESP protocol.\r
@retval EFI_OUT_OF_RESOURCES The required system resource can't be allocated.\r
NET_BUF *Payload;\r
UINTN EspSize;\r
UINTN IvSize;\r
+ UINTN BlockSize;\r
+ UINTN MiscSize;\r
UINTN PlainPayloadSize;\r
UINTN PaddingSize;\r
UINTN IcvSize;\r
*RecycleEvent = NULL;\r
PlainPayloadSize = 0;\r
NextHeader = 0;\r
- \r
+\r
//\r
// Build netbuf from fragment table first.\r
//\r
Status = EFI_OUT_OF_RESOURCES;\r
goto ON_EXIT;\r
}\r
- \r
+\r
//\r
// Get the esp size and esp header from netbuf.\r
//\r
EspSize = Payload->TotalSize;\r
EspHeader = (EFI_ESP_HEADER *) NetbufGetByte (Payload, 0, NULL);\r
- \r
+\r
if (EspHeader == NULL) {\r
Status = EFI_ACCESS_DENIED;\r
goto ON_EXIT;\r
}\r
- \r
+\r
//\r
// Parse destination address from ip header and found the related SAD Entry.\r
//\r
SadEntry = IpSecFoundSadFromInboundPacket (\r
- IpHead, \r
+ IpHead,\r
IpVersion,\r
NTOHL (EspHeader->Spi)\r
);\r
- \r
+\r
if (SadEntry == NULL) {\r
Status = EFI_ACCESS_DENIED;\r
goto ON_EXIT;\r
// TODO: Check SA lifetime and sequence number\r
//\r
}\r
- \r
+\r
//\r
// Allocate buffer for decryption and authentication.\r
//\r
NetbufCopy (Payload, 0, (UINT32) EspSize, ProcessBuffer);\r
\r
//\r
- // Authenticate the esp wrapped buffer by the auth keys which is from SAD entry.\r
+ // Get the IcvSize for authentication and BlockSize/IvSize for Decryption.\r
+ //\r
+ IcvSize = IpSecGetIcvLength (SadEntry->Data->AlgoInfo.EspAlgoInfo.AuthAlgoId);\r
+ IvSize = IpSecGetEncryptIvLength (SadEntry->Data->AlgoInfo.EspAlgoInfo.EncAlgoId);\r
+ BlockSize = IpSecGetEncryptBlockSize (SadEntry->Data->AlgoInfo.EspAlgoInfo.EncAlgoId);\r
+\r
+ //\r
+ // Make sure the ESP packet is not mal-formt.\r
+ // 1. Check whether the Espsize is larger than ESP header + IvSize + EspTail + IcvSize.\r
+ // 2. Check whether the left payload size is multiple of IvSize.\r
+ //\r
+ MiscSize = sizeof (EFI_ESP_HEADER) + IvSize + IcvSize;\r
+ if (EspSize <= (MiscSize + sizeof (EFI_ESP_TAIL))) {\r
+ Status = EFI_ACCESS_DENIED;\r
+ goto ON_EXIT;\r
+ }\r
+ if ((EspSize - MiscSize) % BlockSize != 0) {\r
+ Status = EFI_ACCESS_DENIED;\r
+ goto ON_EXIT;\r
+ }\r
+\r
+ //\r
+ // Authenticate the ESP packet.\r
//\r
- IcvSize = 0;\r
if (SadData->AlgoInfo.EspAlgoInfo.AuthKey != NULL) {\r
Status = IpSecEspAuthVerifyPayload (\r
ProcessBuffer,\r
EspSize,\r
SadEntry,\r
- &IcvSize\r
+ IcvSize\r
);\r
if (EFI_ERROR (Status)) {\r
goto ON_EXIT;\r
//\r
// Decrypt the payload by the SAD entry if it has decrypt key.\r
//\r
- IvSize = IpSecGetEncryptIvLength (SadEntry->Data->AlgoInfo.EspAlgoInfo.EncAlgoId);\r
if (SadData->AlgoInfo.EspAlgoInfo.EncKey != NULL) {\r
Status = IpSecCryptoIoDecrypt (\r
SadEntry->Data->AlgoInfo.EspAlgoInfo.EncAlgoId,\r
goto ON_EXIT;\r
}\r
}\r
- \r
+\r
//\r
// Parse EspTail and compute the plain payload size.\r
//\r
EspTail = (EFI_ESP_TAIL *) (ProcessBuffer + EspSize - IcvSize - sizeof (EFI_ESP_TAIL));\r
PaddingSize = EspTail->PaddingLength;\r
NextHeader = EspTail->NextHeader;\r
- PlainPayloadSize = EspSize - sizeof (EFI_ESP_HEADER) - IvSize - IcvSize - sizeof (EFI_ESP_TAIL) - PaddingSize;\r
- \r
+\r
+ if (EspSize <= (MiscSize + sizeof (EFI_ESP_TAIL) + PaddingSize)) {\r
+ Status = EFI_ACCESS_DENIED;\r
+ goto ON_EXIT;\r
+ }\r
+ PlainPayloadSize = EspSize - MiscSize - sizeof (EFI_ESP_TAIL) - PaddingSize;\r
+\r
//\r
// TODO: handle anti-replay window\r
//\r
if (EFI_ERROR (Status)) {\r
goto ON_EXIT;\r
}\r
- \r
+\r
//\r
// The caller will take responsible to handle the original fragment table\r
//\r
\r
RecycleContext->PayloadBuffer = ProcessBuffer;\r
RecycleContext->FragmentTable = *FragmentTable;\r
- \r
+\r
//\r
// If Tunnel, recalculate upper-layyer PesudoCheckSum and trim the out\r
//\r
SadData,\r
LastHead\r
);\r
- \r
+\r
if (IpVersion == IP_VERSION_4) {\r
(*FragmentTable)[0].FragmentBuffer = InnerHead ;\r
(*FragmentTable)[0].FragmentLength = (UINT32) PlainPayloadSize;\r
- \r
- }else { \r
+\r
+ }else {\r
(*FragmentTable)[0].FragmentBuffer = InnerHead;\r
(*FragmentTable)[0].FragmentLength = (UINT32) PlainPayloadSize;\r
- } \r
+ }\r
} else {\r
(*FragmentTable)[0].FragmentBuffer = ProcessBuffer + sizeof (EFI_ESP_HEADER) + IvSize;\r
(*FragmentTable)[0].FragmentLength = (UINT32) PlainPayloadSize;\r
}\r
- \r
+\r
*FragmentCount = 1;\r
\r
//\r
// Update the total length field in ip header since processed by esp.\r
//\r
- if (!SadData->Mode == EfiIPsecTunnel) {\r
+ if (SadData->Mode != EfiIPsecTunnel) {\r
if (IpVersion == IP_VERSION_4) {\r
- ((IP4_HEAD *) IpHead)->TotalLen = HTONS ((UINT16) (((IP4_HEAD *) IpHead)->HeadLen + PlainPayloadSize));\r
+ ((IP4_HEAD *) IpHead)->TotalLen = HTONS ((UINT16) ((((IP4_HEAD *) IpHead)->HeadLen << 2) + PlainPayloadSize));\r
} else {\r
IpSecHeadSize = IpSecGetPlainExtHeadSize (IpHead, LastHead);\r
((EFI_IP6_HEADER *) IpHead)->PayloadLength = HTONS ((UINT16)(IpSecHeadSize + PlainPayloadSize));\r
//\r
*LastHead = NextHeader;\r
}\r
- \r
+\r
\r
//\r
// Update the SPD association of the SAD entry.\r
EFI_ESP_TAIL *EspTail; // Address behind padding\r
UINT8 *InnerHead;\r
HASH_DATA_FRAGMENT HashFragment[1];\r
- \r
+\r
Status = EFI_ACCESS_DENIED;\r
SaId = SadEntry->Id;\r
SadData = SadEntry->Data;\r
FragmentTable,\r
FragmentCount\r
);\r
- \r
+\r
if (InnerHead == NULL) {\r
return EFI_INVALID_PARAMETER;\r
}\r
}\r
\r
//\r
- // Calculate the plain payload size accroding to the fragment table.\r
+ // Calculate the plain payload size according to the fragment table.\r
//\r
PlainPayloadSize = 0;\r
for (Index = 0; Index < *FragmentCount; Index++) {\r
//\r
// OPtions should be encryption into it\r
//\r
- PlainPayloadSize += *OptionsLength; \r
+ PlainPayloadSize += *OptionsLength;\r
}\r
\r
\r
// HeadLen, Total Length\r
//\r
((IP4_HEAD *)InnerHead)->HeadLen = (UINT8) ((sizeof (IP4_HEAD) + *OptionsLength) >> 2);\r
- ((IP4_HEAD *)InnerHead)->TotalLen = HTONS ((UINT16) PlainPayloadSize); \r
+ ((IP4_HEAD *)InnerHead)->TotalLen = HTONS ((UINT16) PlainPayloadSize);\r
((IP4_HEAD *)InnerHead)->Checksum = 0;\r
((IP4_HEAD *)InnerHead)->Checksum = (UINT16) (~NetblockChecksum (\r
(UINT8 *)InnerHead,\r
EspTail->NextHeader = 4;\r
} else {\r
EspTail->NextHeader = 41;\r
- } \r
+ }\r
}\r
\r
//\r
(UINT8 *) (EspHeader + 1),\r
IvSize\r
);\r
- \r
- \r
+\r
+\r
if (EFI_ERROR (Status)) {\r
goto ON_EXIT;\r
}\r
if (SadData->Mode == EfiIPsecTunnel) {\r
if (IpVersion == IP_VERSION_4) {\r
CopyMem (\r
- &((IP4_HEAD *) IpHead)->Src, \r
+ &((IP4_HEAD *) IpHead)->Src,\r
&SadData->TunnelSourceAddress.v4,\r
sizeof (EFI_IPv4_ADDRESS)\r
- ); \r
+ );\r
CopyMem (\r
&((IP4_HEAD *) IpHead)->Dst,\r
&SadData->TunnelDestAddress.v4,\r
/**\r
This function processes the inbound traffic with IPsec.\r
\r
- It checks the received packet security property, trims the ESP/AH header, and then \r
+ It checks the received packet security property, trims the ESP/AH header, and then\r
returns without an IPsec protected IP Header and FragmentTable.\r
- \r
+\r
@param[in] IpVersion The version of IP.\r
- @param[in, out] IpHead Points to IP header containing the ESP/AH header \r
+ @param[in, out] IpHead Points to IP header containing the ESP/AH header\r
to be trimed on input, and without ESP/AH header\r
on return.\r
@param[in, out] LastHead The Last Header in IP header on return.\r