]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Update IPsec.h file to follow approved ECR which will be collected into future UEFI...
authorqianouyang <qianouyang@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 15 Oct 2010 05:40:41 +0000 (05:40 +0000)
committerqianouyang <qianouyang@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 15 Oct 2010 05:40:41 +0000 (05:40 +0000)
  1. Add EFI_IPSEC2_PROTOCOL
  2. Remove IPsec Authentication Algorithm Definition and IPsec Encryption Algorithm
     Definition.
  3. Add EFI_IPSEC_SA_DATA2 data structure.
And also update IPv4 driver to call EFI_IPSEC2_PROTOCOL.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10941 6f19259b-4bc3-4df7-8a09-765794883524

MdeModulePkg/Include/Library/NetLib.h
MdeModulePkg/Library/DxeNetLib/NetBuffer.c
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.c
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.h
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Output.c
MdePkg/Include/Protocol/IpSec.h
MdePkg/Include/Protocol/IpSecConfig.h

index 0a9d03c6e8d92ad29d0b9d1755d9035a3bf863d3..fe59cc3e443c95bdf1f2b03a7c13bc14f687d193 100644 (file)
@@ -2003,4 +2003,20 @@ NetIp6PseudoHeadChecksum (
   IN UINT8                  NextHeader,\r
   IN UINT32                 Len\r
   );\r
+\r
+/**\r
+  The function frees the net buffer which allocated by the IP protocol. It releases \r
+  only the net buffer and doesn't call the external free function. \r
+\r
+  This function should be called after finishing the process of mIpSec->ProcessExt() \r
+  for outbound traffic. The (EFI_IPSEC2_PROTOCOL)->ProcessExt() allocates a new \r
+  buffer for the ESP, so there needs a function to free the old net buffer.\r
+\r
+  @param[in]  Nbuf       The network buffer to be freed.\r
+\r
+**/\r
+VOID\r
+NetIpSecNetbufFree (\r
+  NET_BUF   *Nbuf\r
+  );\r
 #endif\r
index 43bcae6600bc74baa1753a17acc3fddd7d476fd1..bbbdbc048aedc45acacc1b462f57e20d1beb69e1 100644 (file)
@@ -1842,3 +1842,51 @@ NetIp6PseudoHeadChecksum (
   return NetblockChecksum ((UINT8 *) &Hdr, sizeof (Hdr));\r
 }\r
 \r
+/**\r
+  The function frees the net buffer which allocated by the IP protocol. It releases \r
+  only the net buffer and doesn't call the external free function. \r
+\r
+  This function should be called after finishing the process of mIpSec->ProcessExt() \r
+  for outbound traffic. The (EFI_IPSEC2_PROTOCOL)->ProcessExt() allocates a new \r
+  buffer for the ESP, so there needs a function to free the old net buffer.\r
+\r
+  @param[in]  Nbuf       The network buffer to be freed.\r
+\r
+**/\r
+VOID\r
+NetIpSecNetbufFree (\r
+  NET_BUF   *Nbuf\r
+  )\r
+{\r
+  NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);\r
+  ASSERT (Nbuf->RefCnt > 0);\r
+\r
+  Nbuf->RefCnt--;\r
+\r
+  if (Nbuf->RefCnt == 0) {\r
+    \r
+    //\r
+    // Update Vector only when NBuf is to be released. That is,\r
+    // all the sharing of Nbuf increse Vector's RefCnt by one\r
+    //\r
+    NET_CHECK_SIGNATURE (Nbuf->Vector, NET_VECTOR_SIGNATURE);\r
+    ASSERT (Nbuf->Vector->RefCnt > 0);\r
+\r
+    Nbuf->Vector->RefCnt--;\r
+\r
+    if (Nbuf->Vector->RefCnt > 0) {\r
+      return;\r
+    }\r
+\r
+    //\r
+    // If NET_VECTOR_OWN_FIRST is set, release the first block since it is \r
+    // allocated by us\r
+    //\r
+    if ((Nbuf->Vector->Flag & NET_VECTOR_OWN_FIRST) != 0) {\r
+      FreePool (Nbuf->Vector->Block[0].Bulk);\r
+    }\r
+    FreePool (Nbuf->Vector);\r
+    FreePool (Nbuf); \r
+  } \r
+}\r
+\r
index 8974f5a5b7679916668488efaaf4e14ec4cab924..2cad1f3bb97e03b03d1c60e37e41421f0bd29dde 100644 (file)
@@ -13,7 +13,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 #include "Ip4Impl.h"\r
 \r
-EFI_IPSEC_PROTOCOL    *mIpSec = NULL;\r
+EFI_IPSEC2_PROTOCOL    *mIpSec = NULL;\r
 \r
 /**\r
   Gets the current operational settings for this instance of the EFI IPv4 Protocol driver.\r
index b43f6073207bc8bce45c24d395ec3a1c74e89815..86e6385ecf5fc642ade37a2f2440e4f1600268a1 100644 (file)
@@ -379,6 +379,6 @@ Ip4FreeTxToken (
   IN VOID                   *Context\r
   );\r
 \r
-extern EFI_IPSEC_PROTOCOL   *mIpSec;\r
+extern EFI_IPSEC2_PROTOCOL   *mIpSec;\r
 \r
 #endif\r
index 75333b82efa6c521e5e8d93bb4cac4eba70ac525..0734e091bf7c8ec32af23e9d6891862d60552195 100644 (file)
@@ -463,14 +463,14 @@ Ip4IpSecFree (
   outbound IP packets. The process routine handls the packet with following\r
   actions: bypass the packet, discard the packet, or protect the packet.       \r
 \r
-  @param[in]       IpSb          The IP4 service instance\r
-  @param[in]       Head          The The caller supplied IP4 header.\r
-  @param[in, out]  Netbuf        The IP4 packet to be processed by IPsec\r
-  @param[in]       Options       The caller supplied options\r
-  @param[in]       OptionsLen    The length of the option\r
+  @param[in]       IpSb          The IP4 service instance.\r
+  @param[in, out]  Head          The The caller supplied IP4 header.\r
+  @param[in, out]  Netbuf        The IP4 packet to be processed by IPsec.\r
+  @param[in, out]  Options       The caller supplied options.\r
+  @param[in, out]  OptionsLen    The length of the option.\r
   @param[in]       Direction     The directionality in an SPD entry, \r
-                                 EfiIPsecInBound or EfiIPsecOutBound\r
-  @param[in]       Context       The token's wrap\r
+                                 EfiIPsecInBound or EfiIPsecOutBound.\r
+  @param[in]       Context       The token's wrap.\r
 \r
   @retval EFI_SUCCESS            The IPsec protocol is not available or disabled.\r
   @retval EFI_SUCCESS            The packet was bypassed and all buffers remain the same.\r
@@ -483,22 +483,25 @@ Ip4IpSecFree (
 **/\r
 EFI_STATUS\r
 Ip4IpSecProcessPacket (\r
-  IN IP4_SERVICE            *IpSb,\r
-  IN IP4_HEAD               *Head,\r
-  IN OUT NET_BUF            **Netbuf,\r
-  IN UINT8                  *Options,\r
-  IN UINT32                 OptionsLen,\r
-  IN EFI_IPSEC_TRAFFIC_DIR  Direction,\r
-  IN VOID                   *Context\r
+  IN     IP4_SERVICE            *IpSb,\r
+  IN OUT IP4_HEAD               **Head,\r
+  IN OUT NET_BUF                **Netbuf,\r
+  IN OUT UINT8                  **Options,\r
+  IN OUT UINT32                 *OptionsLen,\r
+  IN     EFI_IPSEC_TRAFFIC_DIR  Direction,\r
+  IN     VOID                   *Context\r
   )\r
 {\r
   NET_FRAGMENT              *FragmentTable;\r
+  NET_FRAGMENT              *OriginalFragmentTable;\r
   UINT32                    FragmentCount;\r
+  UINT32                    OriginalFragmentCount;\r
   EFI_EVENT                 RecycleEvent;\r
   NET_BUF                   *Packet;\r
   IP4_TXTOKEN_WRAP          *TxWrap;\r
   IP4_IPSEC_WRAP            *IpSecWrap;\r
   EFI_STATUS                Status;\r
+  IP4_HEAD                  ZeroHead;\r
 \r
   Status        = EFI_SUCCESS;\r
   Packet        = *Netbuf;\r
@@ -507,6 +510,8 @@ Ip4IpSecProcessPacket (
   FragmentTable = NULL;\r
   TxWrap        = (IP4_TXTOKEN_WRAP *) Context; \r
   FragmentCount = Packet->BlockOpNum;\r
+\r
+  ZeroMem (&ZeroHead, sizeof (IP4_HEAD));\r
   \r
   if (mIpSec == NULL) {\r
     gBS->LocateProtocol (&gEfiIpSecProtocolGuid, NULL, (VOID **) &mIpSec);\r
@@ -542,6 +547,12 @@ Ip4IpSecProcessPacket (
   }\r
  \r
   Status = NetbufBuildExt (Packet, FragmentTable, &FragmentCount);\r
+  \r
+  //\r
+  // Record the original FragmentTable and count.\r
+  //\r
+  OriginalFragmentTable = FragmentTable;\r
+  OriginalFragmentCount = FragmentCount;\r
 \r
   if (EFI_ERROR (Status)) {\r
     FreePool (FragmentTable);\r
@@ -551,16 +562,16 @@ Ip4IpSecProcessPacket (
   //\r
   // Convert host byte order to network byte order\r
   //\r
-  Ip4NtohHead (Head);\r
+  Ip4NtohHead (*Head);\r
   \r
-  Status = mIpSec->Process (\r
+  Status = mIpSec->ProcessExt (\r
                      mIpSec,\r
                      IpSb->Controller,\r
                      IP_VERSION_4,\r
-                     (VOID *) Head,\r
-                     &Head->Protocol,\r
-                     NULL,\r
-                     0,\r
+                     (VOID *) (*Head),\r
+                     &(*Head)->Protocol,\r
+                     Options,\r
+                     OptionsLen,\r
                      (EFI_IPSEC_FRAGMENT_DATA **) (&FragmentTable),\r
                      &FragmentCount,\r
                      Direction,\r
@@ -569,12 +580,16 @@ Ip4IpSecProcessPacket (
   //\r
   // Convert back to host byte order\r
   //\r
-  Ip4NtohHead (Head);\r
+  Ip4NtohHead (*Head);\r
   \r
   if (EFI_ERROR (Status)) {\r
     goto ON_EXIT;\r
   }\r
 \r
+  if (OriginalFragmentTable == FragmentTable && OriginalFragmentCount == FragmentCount) {\r
+    goto ON_EXIT;\r
+  }\r
+\r
   if (Direction == EfiIPsecOutBound && TxWrap != NULL) {\r
   \r
     TxWrap->IpSecRecycleSignal = RecycleEvent;\r
@@ -591,6 +606,10 @@ Ip4IpSecProcessPacket (
       goto ON_EXIT;\r
     }\r
 \r
+    //\r
+    // Free orginal Netbuf.\r
+    //\r
+    NetIpSecNetbufFree (*Netbuf);\r
     *Netbuf = TxWrap->Packet;\r
     \r
   } else {\r
@@ -617,10 +636,10 @@ Ip4IpSecProcessPacket (
       goto ON_EXIT;\r
     }\r
 \r
-    if (Direction == EfiIPsecInBound) {\r
-      Ip4PrependHead (Packet, Head, Options, OptionsLen);\r
+    if (Direction == EfiIPsecInBound && 0 != CompareMem (*Head, &ZeroHead, sizeof (IP4_HEAD))) {\r
+      Ip4PrependHead (Packet, *Head, *Options, *OptionsLen);\r
       Ip4NtohHead (Packet->Ip.Ip4);\r
-      NetbufTrim (Packet, (Head->HeadLen << 2), TRUE);\r
+      NetbufTrim (Packet, ((*Head)->HeadLen << 2), TRUE);\r
 \r
       CopyMem (\r
         IP4_GET_CLIP_INFO (Packet),\r
@@ -628,7 +647,6 @@ Ip4IpSecProcessPacket (
         sizeof (IP4_CLIP_INFO)\r
         );\r
     }\r
-\r
     *Netbuf = Packet;\r
   }\r
 \r
@@ -637,63 +655,56 @@ ON_EXIT:
 }\r
 \r
 /**\r
-  The IP4 input routine. It is called by the IP4_INTERFACE when a\r
-  IP4 fragment is received from MNP.\r
+  Pre-process the IPv4 packet. First validates the IPv4 packet, and\r
+  then reassembles packet if it is necessary.\r
+  \r
+  @param[in]       IpSb            Pointer to IP4_SERVICE.\r
+  @param[in, out]  Packet          Pointer to the Packet to be processed.\r
+  @param[in]       Head            Pointer to the IP4_HEAD.\r
+  @param[in]       Option          Pointer to a buffer which contains the IPv4 option.\r
+  @param[in]       OptionLen       The length of Option in bytes.\r
+  @param[in]       Flag            The link layer flag for the packet received, such\r
+                                   as multicast.\r
 \r
-  @param[in]  Ip4Instance        The IP4 child that request the receive, most like\r
-                                 it is NULL.\r
-  @param[in]  Packet             The IP4 packet received.\r
-  @param[in]  IoStatus           The return status of receive request.\r
-  @param[in]  Flag               The link layer flag for the packet received, such\r
-                                 as multicast.\r
-  @param[in]  Context            The IP4 service instance that own the MNP.\r
+  @retval     EFI_SEUCCESS               The recieved packet is in well form.\r
+  @retval     EFI_INVAILD_PARAMETER      The recieved packet is malformed.  \r
 \r
 **/\r
-VOID\r
-Ip4AccpetFrame (\r
-  IN IP4_PROTOCOL           *Ip4Instance,\r
-  IN NET_BUF                *Packet,\r
-  IN EFI_STATUS             IoStatus,\r
-  IN UINT32                 Flag,\r
-  IN VOID                   *Context\r
-  )\r
+EFI_STATUS\r
+Ip4PreProcessPacket (\r
+  IN     IP4_SERVICE    *IpSb,\r
+  IN OUT NET_BUF        **Packet,\r
+  IN     IP4_HEAD       *Head,\r
+  IN     UINT8          *Option,\r
+  IN     UINT32         OptionLen, \r
+  IN     UINT32         Flag\r
+  ) \r
 {\r
-  IP4_SERVICE               *IpSb;\r
   IP4_CLIP_INFO             *Info;\r
-  IP4_HEAD                  *Head;\r
   UINT32                    HeadLen;\r
-  UINT32                    OptionLen;\r
   UINT32                    TotalLen;\r
   UINT16                    Checksum;\r
-  EFI_STATUS                Status;\r
-\r
-  IpSb = (IP4_SERVICE *) Context;\r
-\r
-  if (EFI_ERROR (IoStatus) || (IpSb->State == IP4_SERVICE_DESTORY)) {\r
-    goto DROP;\r
-  }\r
 \r
   //\r
   // Check that the IP4 header is correctly formatted\r
   //\r
-  if (Packet->TotalSize < IP4_MIN_HEADLEN) {\r
-    goto RESTART;\r
+  if ((*Packet)->TotalSize < IP4_MIN_HEADLEN) {\r
+    return EFI_INVALID_PARAMETER;\r
   }\r
-\r
-  Head     = (IP4_HEAD *) NetbufGetByte (Packet, 0, NULL);\r
+  \r
   HeadLen  = (Head->HeadLen << 2);\r
   TotalLen = NTOHS (Head->TotalLen);\r
 \r
   //\r
   // Mnp may deliver frame trailer sequence up, trim it off.\r
   //\r
-  if (TotalLen < Packet->TotalSize) {\r
-    NetbufTrim (Packet, Packet->TotalSize - TotalLen, FALSE);\r
+  if (TotalLen < (*Packet)->TotalSize) {\r
+    NetbufTrim (*Packet, (*Packet)->TotalSize - TotalLen, FALSE);\r
   }\r
 \r
   if ((Head->Ver != 4) || (HeadLen < IP4_MIN_HEADLEN) ||\r
-      (TotalLen < HeadLen) || (TotalLen != Packet->TotalSize)) {\r
-    goto RESTART;\r
+      (TotalLen < HeadLen) || (TotalLen != (*Packet)->TotalSize)) {\r
+    return EFI_INVALID_PARAMETER;\r
   }\r
 \r
   //\r
@@ -702,15 +713,15 @@ Ip4AccpetFrame (
   Checksum = (UINT16) (~NetblockChecksum ((UINT8 *) Head, HeadLen));\r
 \r
   if ((Head->Checksum != 0) && (Checksum != 0)) {\r
-    goto RESTART;\r
+    return EFI_INVALID_PARAMETER;\r
   }\r
 \r
   //\r
   // Convert the IP header to host byte order, then get the per packet info.\r
   //\r
-  Packet->Ip.Ip4  = Ip4NtohHead (Head);\r
+  (*Packet)->Ip.Ip4  = Ip4NtohHead (Head);\r
 \r
-  Info            = IP4_GET_CLIP_INFO (Packet);\r
+  Info            = IP4_GET_CLIP_INFO (*Packet);\r
   Info->LinkFlag  = Flag;\r
   Info->CastType  = Ip4GetHostCast (IpSb, Head->Dst, Head->Src);\r
   Info->Start     = (Head->Fragment & IP4_HEAD_OFFSET_MASK) << 3;\r
@@ -722,24 +733,23 @@ Ip4AccpetFrame (
   // The packet is destinated to us if the CastType is non-zero.\r
   //\r
   if ((Info->CastType == 0) || (Info->End > IP4_MAX_PACKET_SIZE)) {\r
-    goto RESTART;\r
+    return EFI_INVALID_PARAMETER;\r
   }\r
 \r
   //\r
   // Validate the options. Don't call the Ip4OptionIsValid if\r
   // there is no option to save some CPU process.\r
   //\r
-  OptionLen = HeadLen - IP4_MIN_HEADLEN;\r
-\r
-  if ((OptionLen > 0) && !Ip4OptionIsValid ((UINT8 *) (Head + 1), OptionLen, TRUE)) {\r
-    goto RESTART;\r
+  \r
+  if ((OptionLen > 0) && !Ip4OptionIsValid (Option, OptionLen, TRUE)) {\r
+    return EFI_INVALID_PARAMETER;\r
   }\r
 \r
   //\r
   // Trim the head off, after this point, the packet is headless.\r
   // and Packet->TotalLen == Info->Length.\r
   //\r
-  NetbufTrim (Packet, HeadLen, TRUE);\r
+  NetbufTrim (*Packet, HeadLen, TRUE);\r
 \r
   //\r
   // Reassemble the packet if this is a fragment. The packet is a\r
@@ -752,25 +762,86 @@ Ip4AccpetFrame (
     // need to send a type 4 destination unreache ICMP message here.\r
     //\r
     if ((Head->Fragment & IP4_HEAD_DF_MASK) != 0) {\r
-      goto RESTART;\r
+      return EFI_INVALID_PARAMETER;\r
     }\r
 \r
     //\r
     // The length of all but the last fragments is in the unit of 8 bytes.\r
     //\r
     if (((Head->Fragment & IP4_HEAD_MF_MASK) != 0) && (Info->Length % 8 != 0)) {\r
-      goto RESTART;\r
+      return EFI_INVALID_PARAMETER;\r
     }\r
 \r
-    Packet = Ip4Reassemble (&IpSb->Assemble, Packet);\r
+    *Packet = Ip4Reassemble (&IpSb->Assemble, *Packet);\r
 \r
     //\r
     // Packet assembly isn't complete, start receive more packet.\r
     //\r
-    if (Packet == NULL) {\r
-      goto RESTART;\r
+    if (*Packet == NULL) {\r
+      return EFI_INVALID_PARAMETER;\r
     }\r
   }\r
+  \r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  The IP4 input routine. It is called by the IP4_INTERFACE when a\r
+  IP4 fragment is received from MNP.\r
+\r
+  @param[in]  Ip4Instance        The IP4 child that request the receive, most like\r
+                                 it is NULL.\r
+  @param[in]  Packet             The IP4 packet received.\r
+  @param[in]  IoStatus           The return status of receive request.\r
+  @param[in]  Flag               The link layer flag for the packet received, such\r
+                                 as multicast.\r
+  @param[in]  Context            The IP4 service instance that own the MNP.\r
+\r
+**/\r
+VOID\r
+Ip4AccpetFrame (\r
+  IN IP4_PROTOCOL           *Ip4Instance,\r
+  IN NET_BUF                *Packet,\r
+  IN EFI_STATUS             IoStatus,\r
+  IN UINT32                 Flag,\r
+  IN VOID                   *Context\r
+  )\r
+{\r
+  IP4_SERVICE               *IpSb;\r
+  IP4_HEAD                  *Head;\r
+  EFI_STATUS                Status;\r
+  IP4_HEAD                  ZeroHead;\r
+  UINT8                     *Option;\r
+  UINT32                    OptionLen;\r
+  \r
+  IpSb   = (IP4_SERVICE *) Context;\r
+  Option = NULL;\r
+\r
+  if (EFI_ERROR (IoStatus) || (IpSb->State == IP4_SERVICE_DESTORY)) {\r
+    goto DROP;\r
+  }\r
+\r
+  Head      = (IP4_HEAD *) NetbufGetByte (Packet, 0, NULL); \r
+  OptionLen = (Head->HeadLen << 2) - IP4_MIN_HEADLEN;\r
+  if (OptionLen > 0) {\r
+    Option = (UINT8 *) (Head + 1);\r
+  }\r
+\r
+  //\r
+  // Validate packet format and reassemble packet if it is necessary.\r
+  //\r
+  Status = Ip4PreProcessPacket (\r
+             IpSb, \r
+             &Packet, \r
+             Head, \r
+             Option,\r
+             OptionLen,  \r
+             Flag\r
+             );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    goto RESTART;\r
+  }\r
 \r
   //\r
   // After trim off, the packet is a esp/ah/udp/tcp/icmp6 net buffer,\r
@@ -778,21 +849,40 @@ Ip4AccpetFrame (
   //\r
   Status = Ip4IpSecProcessPacket (\r
              IpSb, \r
-             Head, \r
+             &Head, \r
              &Packet, \r
-             NULL,\r
-             0\r
+             &Option,\r
+             &OptionLen\r
              EfiIPsecInBound,\r
              NULL\r
              );\r
 \r
-  if (EFI_ERROR(Status)) {\r
+  if (EFI_ERROR (Status)) {\r
     goto RESTART;\r
   }\r
+  \r
+  //\r
+  // If the packet is protected by tunnel mode, parse the inner Ip Packet.\r
+  //\r
+  ZeroMem (&ZeroHead, sizeof (IP4_HEAD));\r
+  if (0 == CompareMem (Head, &ZeroHead, sizeof (IP4_HEAD))) {\r
   // Packet may have been changed. Head, HeadLen, TotalLen, and\r
   // info must be reloaded bofore use. The ownership of the packet\r
   // is transfered to the packet process logic.\r
   //\r
+    Head = (IP4_HEAD *) NetbufGetByte (Packet, 0, NULL);\r
+    Status = Ip4PreProcessPacket (\r
+               IpSb, \r
+               &Packet, \r
+               Head, \r
+               Option,\r
+               OptionLen,  \r
+               Flag\r
+               );\r
+    if (EFI_ERROR (Status)) {\r
+      goto RESTART;\r
+    }\r
+  }\r
   Head  = Packet->Ip.Ip4;\r
   IP4_GET_CLIP_INFO (Packet)->Status = EFI_SUCCESS;\r
 \r
index bb167266245382627e6d653b202b0e07c131ddf0..fda4d18c9ca8a428b46722c68d1168107e90438f 100644 (file)
@@ -212,14 +212,14 @@ Ip4PacketTimerTicking (
   outbound IP packets. The process routine handls the packet with following\r
   actions: bypass the packet, discard the packet, or protect the packet.       \r
 \r
-  @param[in]       IpSb          The IP4 service instance\r
-  @param[in]       Head          The The caller supplied IP4 header.\r
-  @param[in, out]  Netbuf        The IP4 packet to be processed by IPsec\r
-  @param[in]       Options       The caller supplied options\r
-  @param[in]       OptionsLen    The length of the option\r
+  @param[in]       IpSb          The IP4 service instance.\r
+  @param[in, out]  Head          The The caller supplied IP4 header.\r
+  @param[in, out]  Netbuf        The IP4 packet to be processed by IPsec.\r
+  @param[in, out]  Options       The caller supplied options.\r
+  @param[in, out]  OptionsLen    The length of the option.\r
   @param[in]       Direction     The directionality in an SPD entry, \r
-                                 EfiIPsecInBound or EfiIPsecOutBound\r
-  @param[in]       Context       The token's wrap\r
+                                 EfiIPsecInBound or EfiIPsecOutBound.\r
+  @param[in]       Context       The token's wrap.\r
 \r
   @retval EFI_SUCCESS            The IPsec protocol is not available or disabled.\r
   @retval EFI_SUCCESS            The packet was bypassed and all buffers remain the same.\r
@@ -232,13 +232,13 @@ Ip4PacketTimerTicking (
 **/\r
 EFI_STATUS\r
 Ip4IpSecProcessPacket (\r
-  IN IP4_SERVICE            *IpSb,\r
-  IN IP4_HEAD               *Head,\r
-  IN OUT NET_BUF            **Netbuf,\r
-  IN UINT8                  *Options,\r
-  IN UINT32                 OptionsLen,\r
-  IN EFI_IPSEC_TRAFFIC_DIR  Direction,\r
-  IN VOID                   *Context\r
+  IN     IP4_SERVICE            *IpSb,\r
+  IN OUT IP4_HEAD               **Head,\r
+  IN OUT NET_BUF                **Netbuf,\r
+  IN OUT UINT8                  **Options,\r
+  IN OUT UINT32                 *OptionsLen,\r
+  IN     EFI_IPSEC_TRAFFIC_DIR  Direction,\r
+  IN     VOID                   *Context\r
   );\r
 \r
 #endif\r
index 863ca2a46451ec84903f8073a6bbebb754e64dda..93cc52eb57f1687863fc1c4cd3412b8701bc38ba 100644 (file)
@@ -250,6 +250,31 @@ Ip4Output (
     Head->Src = IpIf->Ip;\r
   }\r
 \r
+  //\r
+  // Before IPsec process, prepared the IP head.\r
+  //\r
+  HeadLen        = sizeof (IP4_HEAD) + ((OptLen + 3) & (~0x03));\r
+  Head->HeadLen  = (UINT8) HeadLen >> 2;\r
+  Head->Id       = mIp4Id++;\r
+  Head->Ver      = 4;\r
+  \r
+  //\r
+  // Call IPsec process.\r
+  //\r
+  Status = Ip4IpSecProcessPacket (\r
+             IpSb, \r
+             &Head, \r
+             &Packet, \r
+             &Option, \r
+             &OptLen, \r
+             EfiIPsecOutBound,\r
+             Context\r
+             );\r
+\r
+  if (EFI_ERROR(Status)) {\r
+    return Status;\r
+  }\r
+\r
   //\r
   // Route the packet unless overrided, that is, GateWay isn't zero.\r
   //\r
@@ -291,30 +316,11 @@ Ip4Output (
     }\r
   }\r
 \r
-  //\r
-  // TODO: currently Option/OptLen are not included into encryption scope.\r
-  //\r
-  Status = Ip4IpSecProcessPacket (\r
-             IpSb, \r
-             Head, \r
-             &Packet, \r
-             Option, \r
-             OptLen, \r
-             EfiIPsecOutBound,\r
-             Context\r
-             );\r
-\r
-  if (EFI_ERROR(Status)) {\r
-    return Status;\r
-  }\r
-\r
   //\r
   // OK, selected the source and route, fragment the packet then send\r
   // them. Tag each fragment other than the first one as spawn from it.\r
   //\r
-  Mtu            = IpSb->MaxPacketSize + sizeof (IP4_HEAD);\r
-  HeadLen        = sizeof (IP4_HEAD) + ((OptLen + 3) & (~0x03));\r
-  Head->Id       = mIp4Id++;\r
+  Mtu = IpSb->MaxPacketSize + sizeof (IP4_HEAD);  \r
 \r
   if (Packet->TotalSize + HeadLen > Mtu) {\r
     //\r
index 626c87003b181cbeaee0de3c09c425e2d34095f1..f5571db645dbc925cd249b4921f21919ebbe16e3 100644 (file)
@@ -1,7 +1,14 @@
 /** @file\r
   EFI IPSEC Protocol Definition\r
   The EFI_IPSEC_PROTOCOL is used to abstract the ability to deal with the individual\r
-  packets sent and received by the host and provide packet-level security for IP datagram.\r
+  packets sent and received by the host and provide packet-level security for IP \r
+  datagram.\r
+  The EFI_IPSEC2_PROTOCOL is used to abstract the ability to deal with the individual\r
+  packets sent and received by the host and provide packet-level security for IP \r
+  datagram. In addition, it supports the Option (extension header) processing in \r
+  IPsec which doesn't support in EFI_IPSEC_PROTOCOL. It is also recommended to \r
+  use EFI_IPSEC2_PROTOCOL instead of EFI_IPSEC_PROTOCOL especially for IPsec Tunnel \r
+  Mode.\r
 \r
   Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>\r
   This program and the accompanying materials\r
     0xdfb386f7, 0xe100, 0x43ad, {0x9c, 0x9a, 0xed, 0x90, 0xd0, 0x8a, 0x5e, 0x12 } \\r
   }\r
 \r
+#define EFI_IPSEC2_PROTOCOL_GUID \\r
+  { \\r
+    0xa3979e64, 0xace8, 0x4ddc, {0xbc, 0x7, 0x4d, 0x66, 0xb8, 0xfd, 0x9, 0x77 } \\r
+  }\r
+\r
 typedef struct _EFI_IPSEC_PROTOCOL  EFI_IPSEC_PROTOCOL;\r
+typedef struct _EFI_IPSEC2_PROTOCOL EFI_IPSEC2_PROTOCOL;\r
 \r
 ///\r
 /// EFI_IPSEC_FRAGMENT_DATA \r
@@ -93,6 +106,119 @@ struct _EFI_IPSEC_PROTOCOL {
   BOOLEAN                DisabledFlag;      ///< State of the interface.\r
 };\r
 \r
-extern EFI_GUID gEfiIpSecProtocolGuid;\r
+/**\r
+  Handles IPsec processing for both inbound and outbound IP packets. Compare with \r
+  Process() in EFI_IPSEC_PROTOCOL, this interface has the capability to process \r
+  Option(Extension Header). \r
+\r
+  The EFI_IPSEC2_PROCESS process routine handles each inbound or outbound packet.\r
+  The behavior is that it can perform one of the following actions: \r
+  bypass the packet, discard the packet, or protect the packet.  \r
+\r
+  @param[in]       This               Pointer to the EFI_IPSEC2_PROTOCOL instance.\r
+  @param[in]       NicHandle          Instance of the network interface. \r
+  @param[in]       IpVer              IP version.IPv4 or IPv6.\r
+  @param[in, out]  IpHead             Pointer to the IP Header it is either \r
+                                      the EFI_IP4_HEADER or EFI_IP6_HEADER.\r
+                                      On input, it contains the IP header. \r
+                                      On output, 1) in tunnel mode and the \r
+                                      traffic direction is inbound, the buffer \r
+                                      will be reset to zero by IPsec; 2) in \r
+                                      tunnel mode and the traffic direction \r
+                                      is outbound, the buffer will reset to \r
+                                      be the tunnel IP header.3) in transport \r
+                                      mode, the related fielders (like payload \r
+                                      length, Next header) in IP header will \r
+                                      be modified according to the condition.\r
+  @param[in, out]  LastHead           For IP4, it is the next protocol in IP\r
+                                      header. For IP6 it is the Next Header \r
+                                      of the last extension header.\r
+  @param[in, out]  OptionsBuffer      On input, it contains the options \r
+                                      (extensions header) to be processed by \r
+                                      IPsec. On output, 1) in tunnel mode and\r
+                                      the traffic direction is outbound, it \r
+                                      will be set to NULL, and that means this \r
+                                      contents was wrapped after inner header \r
+                                      and should not be concatenated after \r
+                                      tunnel header again; 2) in transport \r
+                                      mode and the traffic direction is inbound, \r
+                                      if there are IP options (extension headers) \r
+                                      protected by IPsec, IPsec will concatenate \r
+                                      the those options after the input options \r
+                                      (extension headers); 3) on other situations, \r
+                                      the output of contents of OptionsBuffer \r
+                                      might be same with input's. The caller \r
+                                      should take the responsibility to free \r
+                                      the buffer both on input and on output.\r
+  @param[in, out]  OptionsLength      On input, the input length of the options \r
+                                      buffer. On output, the output length of \r
+                                      the options buffer.\r
+  @param[in, out]  FragmentTable      Pointer to a list of fragments. On input, \r
+                                      these fragments contain the IP payload. \r
+                                      On output, 1) in tunnel mode and the traffic \r
+                                      direction is inbound, the fragments contain \r
+                                      the whole IP payload which is from the \r
+                                      IP inner header to the last byte of the \r
+                                      packet; 2) in tunnel mode and the traffic \r
+                                      direction is the outbound, the fragments \r
+                                      contains the whole encapsulated payload \r
+                                      which encapsulates the whole IP payload \r
+                                      between the encapsulated header and \r
+                                      encapsulated trailer fields. 3) in transport \r
+                                      mode and the traffic direction is inbound, \r
+                                      the fragments contains the IP payload \r
+                                      which is from the next layer protocol to \r
+                                      the last byte of the packet; 4) in transport \r
+                                      mode and the traffic direction is outbound, \r
+                                      the fragments contains the whole encapsulated \r
+                                      payload which encapsulates the next layer \r
+                                      protocol information between the encapsulated \r
+                                      header and encapsulated trailer fields.\r
+  @param[in, out]  FragmentCount      Number of fragments.\r
+  @param[in]       TrafficDirection   Traffic direction.\r
+  @param[out]      RecycleSignal      Event for recycling of resources.\r
+\r
+  @retval      EFI_SUCCESS           The packet was processed by IPsec successfully.\r
+  @retval      EFI_ACCESS_DENIED     The packet was discarded.\r
+  @retval      EFI_NOT_READY         The IKE negotiation is invoked and the packet \r
+                                     was discarded.\r
+  @retval      EFI_INVALID_PARAMETER One or more of following are TRUE:\r
+                                     If OptionsBuffer is NULL;\r
+                                     If OptionsLength is NULL;\r
+                                     If FragmentTable is NULL;\r
+                                     If FragmentCount is NULL.\r
+\r
+**/\r
+typedef \r
+EFI_STATUS\r
+(EFIAPI *EFI_IPSEC_PROCESSEXT) ( \r
+  IN EFI_IPSEC2_PROTOCOL         *This, \r
+  IN EFI_HANDLE                  NicHandle, \r
+  IN UINT8                       IpVer, \r
+  IN OUT VOID                    *IpHead, \r
+  IN OUT UINT8                   *LastHead, \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 EFI_IPSEC_TRAFFIC_DIR       TrafficDirection, \r
+     OUT EFI_EVENT               *RecycleSignal\r
+  );\r
 \r
+/// \r
+/// EFI_IPSEC2_PROTOCOL\r
+/// supports the Option (extension header) processing in IPsec which doesn't support\r
+/// in EFI_IPSEC_PROTOCOL. It is also recommended to use EFI_IPSEC2_PROTOCOL instead\r
+/// of EFI_IPSEC_PROTOCOL especially for IPsec Tunnel Mode.\r
+/// provides the ability for securing IP communications by authenticating and/or\r
+/// encrypting each IP packet in a data stream.\r
+///\r
+struct _EFI_IPSEC2_PROTOCOL { \r
+EFI_IPSEC_PROCESSEXT ProcessExt;\r
+EFI_EVENT            DisabledEvent; \r
+BOOLEAN              DisabledFlag; \r
+};\r
+\r
+extern EFI_GUID gEfiIpSecProtocolGuid;\r
+extern EFI_GUID gEfiIpSec2ProtocolGuid;\r
 #endif\r
index 4c4dad0403287b143d1a61542ca8d7ae313ff398..e305381f7ecfa3b5a5da5249bbfecfec73b6662c 100644 (file)
@@ -302,38 +302,6 @@ typedef struct _EFI_IPSEC_PROCESS_POLICY {
   UINT8                   EncAlgoId;\r
 } EFI_IPSEC_PROCESS_POLICY;\r
 \r
-///\r
-/// IPsec Authentication Algorithm Definition\r
-///   The number value definition is aligned to IANA assignment\r
-///\r
-#define EFI_IPSEC_AALG_NONE                0x00\r
-#define EFI_IPSEC_AALG_MD5HMAC             0x02\r
-#define EFI_IPSEC_AALG_SHA1HMAC            0x03\r
-#define EFI_IPSEC_AALG_SHA2_256HMAC        0x05\r
-#define EFI_IPSEC_AALG_SHA2_384HMAC        0x06\r
-#define EFI_IPSEC_AALG_SHA2_512HMAC        0x07\r
-#define EFI_IPSEC_AALG_AES_XCBC_MAC        0x09\r
-#define EFI_IPSEC_AALG_NULL                0xFB\r
-\r
-///\r
-/// IPsec Encryption Algorithm Definition\r
-///   The number value definition is aligned to IANA assignment\r
-///\r
-#define EFI_IPSEC_EALG_NONE                0x00\r
-#define EFI_IPSEC_EALG_DESCBC              0x02\r
-#define EFI_IPSEC_EALG_3DESCBC             0x03\r
-#define EFI_IPSEC_EALG_CASTCBC             0x06\r
-#define EFI_IPSEC_EALG_BLOWFISHCBC         0x07\r
-#define EFI_IPSEC_EALG_NULL                0x0B\r
-#define EFI_IPSEC_EALG_AESCBC              0x0C\r
-#define EFI_IPSEC_EALG_AESCTR              0x0D\r
-#define EFI_IPSEC_EALG_AES_CCM_ICV8        0x0E\r
-#define EFI_IPSEC_EALG_AES_CCM_ICV12       0x0F\r
-#define EFI_IPSEC_EALG_AES_CCM_ICV16       0x10\r
-#define EFI_IPSEC_EALG_AES_GCM_ICV8        0x12\r
-#define EFI_IPSEC_EALG_AES_GCM_ICV12       0x13\r
-#define EFI_IPSEC_EALG_AES_GCM_ICV16       0x14\r
-\r
 ///\r
 /// EFI_IPSEC_SA_ID\r
 /// A triplet to identify an SA, consisting of the following members.\r
@@ -486,6 +454,58 @@ typedef struct _EFI_IPSEC_SA_DATA {
   BOOLEAN                         ManualSet;\r
 } EFI_IPSEC_SA_DATA;\r
 \r
+///\r
+/// EFI_IPSEC_SA_DATA2\r
+///\r
+typedef struct _EFI_IPSEC_SA_DATA2 { \r
+  ///\r
+  /// IPsec mode: tunnel or transport\r
+  ///\r
+  EFI_IPSEC_MODE             Mode; \r
+  ///\r
+  /// Sequence Number Counter. A 64-bit counter used to generate the sequence \r
+  /// number field in AH or ESP headers. \r
+  ///\r
+  UINT64                     SNCount; \r
+  ///\r
+  /// Anti-Replay Window. A 64-bit counter and a bit-map used to determine \r
+  /// whether an inbound AH or ESP packet is a replay.\r
+  ///\r
+  UINT8                      AntiReplayWindows; \r
+  ///\r
+  /// AH/ESP cryptographic algorithm, key and parameters.\r
+  ///\r
+  EFI_IPSEC_ALGO_INFO        AlgoInfo; \r
+  ///\r
+  /// Lifetime of this SA.\r
+  ///\r
+  EFI_IPSEC_SA_LIFETIME      SaLifetime; \r
+  ///\r
+  /// Any observed path MTU and aging variables. The Path MTU processing is \r
+  /// defined in section 8 of RFC 4301.\r
+  ///\r
+  UINT32                     PathMTU; \r
+  ///\r
+  /// Link to one SPD entry\r
+  ///\r
+  EFI_IPSEC_SPD_SELECTOR     *SpdSelector; \r
+  ///\r
+  /// Indication of whether it's manually set or negotiated automatically. \r
+  /// If ManualSet is FALSE, the corresponding SA entry is inserted through IKE \r
+  /// protocol negotiation\r
+  ///\r
+  BOOLEAN                    ManualSet;\r
+  ///\r
+  /// The tunnel header IP source address.\r
+  ///\r
+  EFI_IP_ADDRESS             TunnelSourceAddress;\r
+  ///\r
+  /// The tunnel header IP destination address.\r
+  ///\r
+  EFI_IP_ADDRESS             TunnelDestinationAddress;\r
+} EFI_IPSEC_SA_DATA2; \r
+\r
+\r
 ///\r
 /// EFI_IPSEC_PAD_ID\r
 /// specifies the identifier for PAD entry, which is also used for SPD lookup.\r