NetworkPkg/IpSecDxe: Fix wrong IKE header "FLAG" update

*v2: update the commit log and refine the code comments.

There are three kinds of IKE Exchange process:
#1. Initial Exchange
#2. CREATE_CHILD_SA_Exchange
#3. Information Exchange

The IKE header "FLAG" update is incorrect in #2 and #3 exchange,
which may cause the continue session failure. This patch is used
to correct the updates of IKE header "FLAG" according the RFC4306
section 3.1.

Cc: Ye Ting <ting.ye@intel.com>
Cc: Fu Siyuan <siyuan.fu@intel.com>
Cc: Zhang Lubo <lubo.zhang@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jiaxin Wu <jiaxin.wu@intel.com>
Reviewed-by: Ye Ting <ting.ye@intel.com>
diff --git a/NetworkPkg/IpSecDxe/Ikev2/ChildSa.c b/NetworkPkg/IpSecDxe/Ikev2/ChildSa.c
index 1f0199b..eaccad2 100644
--- a/NetworkPkg/IpSecDxe/Ikev2/ChildSa.c
+++ b/NetworkPkg/IpSecDxe/Ikev2/ChildSa.c
@@ -76,9 +76,7 @@
     }    

     

     if (ChildSaSession->SessionCommon.IsInitiator) {

-      IkePacket->Header->Flags = IKE_HEADER_FLAGS_CHILD_INIT;

-    } else {

-      IkePacket->Header->Flags = IKE_HEADER_FLAGS_RESPOND;

+      IkePacket->Header->Flags = IKE_HEADER_FLAGS_INIT;

     }

       

   } else {

@@ -96,11 +94,13 @@
     }    

     

     if (IkeSaSession->SessionCommon.IsInitiator) {

-      IkePacket->Header->Flags = IKE_HEADER_FLAGS_CHILD_INIT;

-    } else {

-      IkePacket->Header->Flags = IKE_HEADER_FLAGS_RESPOND;

+      IkePacket->Header->Flags = IKE_HEADER_FLAGS_INIT;

     }

-  } 

+  }

+

+  if (MessageId != NULL) {

+    IkePacket->Header->Flags |= IKE_HEADER_FLAGS_RESPOND;

+  }

    

   //

   // According to RFC4306, Chapter 4.

diff --git a/NetworkPkg/IpSecDxe/Ikev2/Exchange.c b/NetworkPkg/IpSecDxe/Ikev2/Exchange.c
index 1eddbfb..5609964 100644
--- a/NetworkPkg/IpSecDxe/Ikev2/Exchange.c
+++ b/NetworkPkg/IpSecDxe/Ikev2/Exchange.c
@@ -705,7 +705,7 @@
   //

   // Generate the reply packet if needed and send it out.

   //

-  if (IkePacket->Header->Flags != IKE_HEADER_FLAGS_RESPOND) {

+  if (!(IkePacket->Header->Flags & IKE_HEADER_FLAGS_RESPOND)) {

     Reply = mIkev2CreateChild.Generator ((UINT8 *) IkeSaSession, &IkePacket->Header->MessageId);

     if (Reply != NULL) {

       Status = Ikev2SendIkePacket (UdpService, (UINT8 *) &(IkeSaSession->SessionCommon), Reply, 0);

diff --git a/NetworkPkg/IpSecDxe/Ikev2/Info.c b/NetworkPkg/IpSecDxe/Ikev2/Info.c
index 23e47ce..0d2b290 100644
--- a/NetworkPkg/IpSecDxe/Ikev2/Info.c
+++ b/NetworkPkg/IpSecDxe/Ikev2/Info.c
@@ -128,7 +128,11 @@
       // The input parameter is not correct.

       //

       goto ERROR_EXIT;

-    } 

+    }

+

+    if (IkeSaSession->SessionCommon.IsInitiator) {

+      IkePacket->Header->Flags = IKE_HEADER_FLAGS_INIT ;

+    }  

   } else {

     //

     // Delete the Child SA Information Exchagne

@@ -180,13 +184,16 @@
     // Change the IsOnDeleting Flag

     //

     ChildSaSession->SessionCommon.IsOnDeleting = TRUE;

+

+    if (ChildSaSession->SessionCommon.IsInitiator) {

+      IkePacket->Header->Flags = IKE_HEADER_FLAGS_INIT ;

+    }

   }

 

-  if (InfoContext == NULL) {

-    IkePacket->Header->Flags = IKE_HEADER_FLAGS_INIT;

-  } else {

-    IkePacket->Header->Flags = IKE_HEADER_FLAGS_RESPOND;

+  if (InfoContext != NULL) {

+    IkePacket->Header->Flags |= IKE_HEADER_FLAGS_RESPOND;

   }

+  

   return IkePacket;

 

 ERROR_EXIT:

diff --git a/NetworkPkg/IpSecDxe/Ikev2/Payload.h b/NetworkPkg/IpSecDxe/Ikev2/Payload.h
index 6096a3b..7a85792 100644
--- a/NetworkPkg/IpSecDxe/Ikev2/Payload.h
+++ b/NetworkPkg/IpSecDxe/Ikev2/Payload.h
@@ -1,7 +1,7 @@
 /** @file

   The Definitions related to IKEv2 payload.

 

-  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>

+  Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.<BR>

 

   This program and the accompanying materials

   are licensed and made available under the terms and conditions of the BSD License

@@ -37,11 +37,16 @@
 #define IKEV2_PAYLOAD_TYPE_EAP      48

 

 //

-// IKE header Flag for IKEv2

+// IKE header Flag (1 octet) for IKEv2, defined in RFC 4306 section 3.1 

+//

+// I(nitiator) (bit 3 of Flags, 0x08) - This bit MUST be set in messages sent by the 

+//                                      original initiator of the IKE_SA

+//

+// R(esponse) (bit 5 of Flags, 0x20)  - This bit indicates that this message is a response to 

+//                                      a message containing the same message ID.

 //

 #define IKE_HEADER_FLAGS_INIT       0x08

 #define IKE_HEADER_FLAGS_RESPOND    0x20

-#define IKE_HEADER_FLAGS_CHILD_INIT 0

 

 //

 // IKE Header Exchange Type for IKEv2