]> git.proxmox.com Git - mirror_edk2.git/blobdiff - NetworkPkg/IpSecDxe/IpSecImpl.c
NetworkPkg: Clean up source files
[mirror_edk2.git] / NetworkPkg / IpSecDxe / IpSecImpl.c
index 7ccbfa25eea5f8bdc71c2601588e7e6df87506ac..da981842083b9fca8409ecbe988ffe6e6cc53d4f 100644 (file)
@@ -1,7 +1,8 @@
 /** @file\r
   The implementation of IPsec.\r
 \r
-  Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>\r
+  (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>\r
+  Copyright (c) 2009 - 2018, 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
@@ -23,7 +24,7 @@
   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
@@ -329,7 +330,7 @@ IpSecLookupSadBySpd (
 {\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
@@ -341,7 +342,7 @@ IpSecLookupSadBySpd (
           DestAddress,\r
           SadEntry->Data->SpdSelector->RemoteAddress,\r
           SadEntry->Data->SpdSelector->RemoteAddressCount\r
-          )){    \r
+          )){\r
       return SadEntry;\r
     }\r
   }\r
@@ -382,7 +383,7 @@ IpSecLookupSadBySpi (
     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
@@ -391,14 +392,14 @@ IpSecLookupSadBySpi (
       } 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
@@ -471,14 +472,13 @@ IpSecLookupSadEntry (
       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
@@ -498,7 +498,7 @@ IpSecLookupSadEntry (
           &DestIp\r
         );\r
       }\r
-      \r
+\r
     }\r
 \r
     return EFI_NOT_READY;\r
@@ -595,7 +595,7 @@ IpSecLookupSpdEntry (
   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
@@ -733,7 +733,7 @@ IpSecRecycleCallback (
 }\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
@@ -783,7 +783,7 @@ IpSecEspAuthVerifyPayload (
   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
@@ -794,15 +794,14 @@ IpSecEspAuthVerifyPayload (
   //\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
@@ -810,16 +809,16 @@ IpSecEspAuthVerifyPayload (
              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
@@ -833,10 +832,10 @@ IpSecEspAuthVerifyPayload (
   @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
@@ -844,10 +843,10 @@ IpSecFoundSadFromInboundPacket (
    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
@@ -865,10 +864,10 @@ IpSecFoundSadFromInboundPacket (
       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
@@ -900,7 +899,6 @@ IpSecIsIp6ExtsValid (
   UINT32                     Pointer;\r
   UINT8                      *Option;\r
   UINT8                      OptionLen;\r
-  BOOLEAN                    Flag;\r
   UINT8                      CountD;\r
   UINT8                      CountF;\r
   UINT8                      CountA;\r
@@ -920,7 +918,6 @@ IpSecIsIp6ExtsValid (
   }\r
 \r
   Pointer = 0;\r
-  Flag    = FALSE;\r
   CountD  = 0;\r
   CountF  = 0;\r
   CountA  = 0;\r
@@ -933,8 +930,6 @@ IpSecIsIp6ExtsValid (
         return FALSE;\r
       }\r
 \r
-      Flag = TRUE;\r
-\r
     //\r
     // Fall through\r
     //\r
@@ -995,7 +990,7 @@ IpSecIsIp6ExtsValid (
        }\r
 \r
        return TRUE;\r
-    }   \r
+    }\r
   }\r
 \r
   *LastHeader = NextHeader;\r
@@ -1008,14 +1003,14 @@ IpSecIsIp6ExtsValid (
 }\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
@@ -1043,10 +1038,10 @@ IpSecTunnelInboundPacket (
   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
@@ -1058,20 +1053,20 @@ IpSecTunnelInboundPacket (
       &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
@@ -1092,7 +1087,7 @@ IpSecTunnelInboundPacket (
       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
@@ -1101,14 +1096,14 @@ IpSecTunnelInboundPacket (
                        ((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
@@ -1120,7 +1115,7 @@ IpSecTunnelInboundPacket (
         &SadData->TunnelDestAddress.v6,\r
         sizeof (EFI_IPv6_ADDRESS)\r
         );\r
-      \r
+\r
       //\r
       // Get the Extension Header and Header length.\r
       //\r
@@ -1131,7 +1126,7 @@ IpSecTunnelInboundPacket (
         &LastHead,\r
         &OptionLen\r
         );\r
-      \r
+\r
       //\r
       // Recalcualte PseudoChecksum\r
       //\r
@@ -1155,7 +1150,7 @@ IpSecTunnelInboundPacket (
         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
@@ -1164,7 +1159,7 @@ IpSecTunnelInboundPacket (
                          *LastHead,\r
                          0\r
                          );\r
-    \r
+\r
     if (Checksum != NULL) {\r
       *Checksum = NetAddChecksum (PacketChecksum, PseudoChecksum);\r
       *Checksum = (UINT16) ~(NetAddChecksum (\r
@@ -1172,32 +1167,29 @@ IpSecTunnelInboundPacket (
                                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]      OptionsBuffer      Pointer to the options buffer. It is optional.\r
-  @param[in]      OptionsLength      Length of the options buffer. It is optional.\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
                                      IPsec on input, and with IPsec protected\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
@@ -1222,10 +1214,13 @@ IpSecTunnelOutboundPacket (
   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
@@ -1238,6 +1233,10 @@ IpSecTunnelOutboundPacket (
       );\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
@@ -1256,7 +1255,7 @@ IpSecTunnelOutboundPacket (
       *OptionsLength = 0;\r
     }\r
   }\r
-  \r
+\r
   //\r
   // 2. Reassamlbe Fragment into Packet\r
   //\r
@@ -1268,7 +1267,11 @@ IpSecTunnelOutboundPacket (
              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
@@ -1294,13 +1297,13 @@ IpSecTunnelOutboundPacket (
     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
@@ -1318,7 +1321,7 @@ IpSecTunnelOutboundPacket (
                        *LastHead,\r
                        0\r
                        );\r
-    \r
+\r
    } else {\r
      //\r
      // Replace the source address of Inner Header.\r
@@ -1335,7 +1338,7 @@ IpSecTunnelOutboundPacket (
                       *LastHead,\r
                       0\r
                       );\r
-   \r
+\r
    }\r
    if (Checksum != NULL) {\r
      *Checksum = NetAddChecksum (PacketChecksum, PseudoChecksum);\r
@@ -1351,17 +1354,17 @@ IpSecTunnelOutboundPacket (
 /**\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
-  @param[in, out] OptionsBuffer      Pointer to the options buffer. It is optional.\r
-  @param[in, out] OptionsLength      Length of the options buffer. It is optional.\r
+  @param[in, out] OptionsBuffer      Pointer to the options buffer.\r
+  @param[in, out] OptionsLength      Length of the options buffer.\r
   @param[in, out] FragmentTable      Pointer to a list of fragments in the form of IPsec\r
                                      protected on input, and without IPsec protected\r
                                      on return.\r
@@ -1371,7 +1374,7 @@ IpSecTunnelOutboundPacket (
 \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
@@ -1382,8 +1385,8 @@ IpSecEspInboundPacket (
   IN     UINT8                       IpVersion,\r
   IN OUT VOID                        *IpHead,\r
      OUT UINT8                       *LastHead,\r
-  IN OUT VOID                        **OptionsBuffer, OPTIONAL\r
-  IN OUT UINT32                      *OptionsLength,  OPTIONAL\r
+  IN OUT VOID                        **OptionsBuffer,\r
+  IN OUT UINT32                      *OptionsLength,\r
   IN OUT EFI_IPSEC_FRAGMENT_DATA     **FragmentTable,\r
   IN OUT UINT32                      *FragmentCount,\r
      OUT EFI_IPSEC_SPD_SELECTOR      **SpdSelector,\r
@@ -1394,6 +1397,8 @@ IpSecEspInboundPacket (
   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
@@ -1415,7 +1420,7 @@ IpSecEspInboundPacket (
   *RecycleEvent     = NULL;\r
   PlainPayloadSize  = 0;\r
   NextHeader        = 0;\r
-  \r
+\r
   //\r
   // Build netbuf from fragment table first.\r
   //\r
@@ -1431,27 +1436,27 @@ IpSecEspInboundPacket (
     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
@@ -1473,7 +1478,7 @@ IpSecEspInboundPacket (
     // TODO: Check SA lifetime and sequence number\r
     //\r
   }\r
-    \r
+\r
   //\r
   // Allocate buffer for decryption and authentication.\r
   //\r
@@ -1486,15 +1491,36 @@ IpSecEspInboundPacket (
   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
@@ -1503,7 +1529,6 @@ IpSecEspInboundPacket (
   //\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
@@ -1518,15 +1543,20 @@ IpSecEspInboundPacket (
       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
@@ -1550,7 +1580,7 @@ IpSecEspInboundPacket (
   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
@@ -1562,7 +1592,7 @@ IpSecEspInboundPacket (
 \r
   RecycleContext->PayloadBuffer       = ProcessBuffer;\r
   RecycleContext->FragmentTable       = *FragmentTable;\r
-  \r
+\r
   //\r
   // If Tunnel, recalculate upper-layyer PesudoCheckSum and trim the out\r
   //\r
@@ -1575,28 +1605,28 @@ IpSecEspInboundPacket (
       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
@@ -1606,7 +1636,7 @@ IpSecEspInboundPacket (
     //\r
     *LastHead = NextHeader;\r
   }\r
-  \r
+\r
 \r
   //\r
   // Update the SPD association of the SAD entry.\r
@@ -1647,8 +1677,8 @@ ON_EXIT:
                                      to be processed on input, and inserted ESP header\r
                                      on return.\r
   @param[in, out] LastHead           The Last Header in IP header.\r
-  @param[in, out] OptionsBuffer      Pointer to the options buffer. It is optional.\r
-  @param[in, out] OptionsLength      Length of the options buffer. It is optional.\r
+  @param[in, out] OptionsBuffer      Pointer to the options buffer.\r
+  @param[in, out] OptionsLength      Length of the options buffer.\r
   @param[in, out] FragmentTable      Pointer to a list of fragments to be protected by\r
                                      IPsec on input, and with IPsec protected\r
                                      on return.\r
@@ -1665,8 +1695,8 @@ IpSecEspOutboundPacket (
   IN UINT8                           IpVersion,\r
   IN OUT VOID                        *IpHead,\r
   IN OUT UINT8                       *LastHead,\r
-  IN OUT VOID                        **OptionsBuffer, OPTIONAL\r
-  IN OUT UINT32                      *OptionsLength,  OPTIONAL\r
+  IN OUT VOID                        **OptionsBuffer,\r
+  IN OUT UINT32                      *OptionsLength,\r
   IN OUT EFI_IPSEC_FRAGMENT_DATA     **FragmentTable,\r
   IN OUT UINT32                      *FragmentCount,\r
   IN     IPSEC_SAD_ENTRY             *SadEntry,\r
@@ -1694,7 +1724,7 @@ IpSecEspOutboundPacket (
   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
@@ -1727,7 +1757,7 @@ IpSecEspOutboundPacket (
                   FragmentTable,\r
                   FragmentCount\r
                   );\r
-    \r
+\r
     if (InnerHead == NULL) {\r
       return EFI_INVALID_PARAMETER;\r
     }\r
@@ -1748,7 +1778,7 @@ IpSecEspOutboundPacket (
   }\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
@@ -1767,7 +1797,7 @@ IpSecEspOutboundPacket (
     //\r
     // OPtions should be encryption into it\r
     //\r
-    PlainPayloadSize += *OptionsLength;    \r
+    PlainPayloadSize += *OptionsLength;\r
   }\r
 \r
 \r
@@ -1825,7 +1855,7 @@ IpSecEspOutboundPacket (
       // 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
@@ -1877,7 +1907,7 @@ IpSecEspOutboundPacket (
       EspTail->NextHeader = 4;\r
     } else {\r
       EspTail->NextHeader = 41;\r
-    }    \r
+    }\r
   }\r
 \r
   //\r
@@ -1887,8 +1917,8 @@ IpSecEspOutboundPacket (
              (UINT8 *) (EspHeader + 1),\r
              IvSize\r
              );\r
-  \r
-  \r
+\r
+\r
   if (EFI_ERROR (Status)) {\r
     goto ON_EXIT;\r
   }\r
@@ -1984,10 +2014,10 @@ IpSecEspOutboundPacket (
   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
@@ -2038,16 +2068,16 @@ ON_EXIT:
 /**\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
-  @param[in, out] OptionsBuffer      Pointer to the options buffer. It is optional.\r
-  @param[in, out] OptionsLength      Length of the options buffer. It is optional.\r
+  @param[in, out] OptionsBuffer      Pointer to the options buffer.\r
+  @param[in, out] OptionsLength      Length of the options buffer.\r
   @param[in, out] FragmentTable      Pointer to a list of fragments in form of IPsec\r
                                      protected on input, and without IPsec protected\r
                                      on return.\r
@@ -2064,8 +2094,8 @@ IpSecProtectInboundPacket (
   IN     UINT8                       IpVersion,\r
   IN OUT VOID                        *IpHead,\r
   IN OUT UINT8                       *LastHead,\r
-  IN OUT VOID                        **OptionsBuffer, OPTIONAL\r
-  IN OUT UINT32                      *OptionsLength,  OPTIONAL\r
+  IN OUT VOID                        **OptionsBuffer,\r
+  IN OUT UINT32                      *OptionsLength,\r
   IN OUT EFI_IPSEC_FRAGMENT_DATA     **FragmentTable,\r
   IN OUT UINT32                      *FragmentCount,\r
      OUT EFI_IPSEC_SPD_SELECTOR      **SpdEntry,\r
@@ -2105,8 +2135,8 @@ IpSecProtectInboundPacket (
                                      to be processed on input, and inserted ESP/AH header\r
                                      on return.\r
   @param[in, out] LastHead           The Last Header in IP header.\r
-  @param[in, out] OptionsBuffer      Pointer to the options buffer. It is optional.\r
-  @param[in, out] OptionsLength      Length of the options buffer. It is optional.\r
+  @param[in, out] OptionsBuffer      Pointer to the options buffer.\r
+  @param[in, out] OptionsLength      Length of the options buffer.\r
   @param[in, out] FragmentTable      Pointer to a list of fragments to be protected by\r
                                      IPsec on input, and with IPsec protected\r
                                      on return.\r
@@ -2123,8 +2153,8 @@ IpSecProtectOutboundPacket (
   IN     UINT8                       IpVersion,\r
   IN OUT VOID                        *IpHead,\r
   IN OUT UINT8                       *LastHead,\r
-  IN OUT VOID                        **OptionsBuffer, OPTIONAL\r
-  IN OUT UINT32                      *OptionsLength,  OPTIONAL\r
+  IN OUT VOID                        **OptionsBuffer,\r
+  IN OUT UINT32                      *OptionsLength,\r
   IN OUT EFI_IPSEC_FRAGMENT_DATA     **FragmentTable,\r
   IN OUT UINT32                      *FragmentCount,\r
   IN     IPSEC_SAD_ENTRY             *SadEntry,\r