]> git.proxmox.com Git - mirror_edk2.git/blobdiff - NetworkPkg/IpSecDxe/IkeCommon.c
NetworkPkg/IScsiDxe: Fix the incorrect error handling in DriverEntryPoint
[mirror_edk2.git] / NetworkPkg / IpSecDxe / IkeCommon.c
index 7f563653e6c7d3ee460498b270961c092de96918..c5fbfab6a955a74322d8415638c5738790658035 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Common operation of the IKE\r
   \r
 /** @file\r
   Common operation of the IKE\r
   \r
-  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2010 - 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
 \r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
 #include "IpSecConfigImpl.h"\r
 #include "IpSecDebug.h"\r
 \r
 #include "IpSecConfigImpl.h"\r
 #include "IpSecDebug.h"\r
 \r
-//\r
-// Initial the SPI\r
-//\r
-UINT32            mNextSpi  = IKE_SPI_BASE;\r
-EFI_GUID          mZeroGuid = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };\r
+/**\r
+  Check whether the new generated Spi has existed.\r
+\r
+  @param[in]   IkeSaSession   Pointer to the Child SA Session.\r
+  @param[in]   SpiValue       SPI Value.\r
+\r
+  @retval  TRUE    This SpiValue has existed in the Child SA Session\r
+  @retval  FALSE   This SpiValue doesn't exist in the Child SA Session.\r
+  \r
+**/\r
+BOOLEAN\r
+IkeSpiValueExisted (\r
+  IN IKEV2_SA_SESSION      *IkeSaSession,\r
+  IN UINT32                SpiValue\r
+  )\r
+{\r
+  LIST_ENTRY              *Entry;\r
+  LIST_ENTRY              *Next;\r
+  IKEV2_CHILD_SA_SESSION  *SaSession;\r
+\r
+  Entry     = NULL;\r
+  Next      = NULL;\r
+  SaSession = NULL; \r
+    \r
+  //\r
+  // Check whether the SPI value has existed in ChildSaEstablishSessionList.\r
+  //\r
+  NET_LIST_FOR_EACH_SAFE (Entry, Next, &IkeSaSession->ChildSaEstablishSessionList) {\r
+    SaSession= IKEV2_CHILD_SA_SESSION_BY_IKE_SA (Entry);\r
+    if (SaSession->LocalPeerSpi == SpiValue) {\r
+      return TRUE;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Check whether the SPI value has existed in ChildSaSessionList.\r
+  //\r
+  NET_LIST_FOR_EACH_SAFE (Entry, Next, &IkeSaSession->ChildSaSessionList) {\r
+    SaSession= IKEV2_CHILD_SA_SESSION_BY_IKE_SA (Entry);\r
+    if (SaSession->LocalPeerSpi == SpiValue) {\r
+      return TRUE;\r
+    }\r
+  }\r
+\r
+  return FALSE;\r
+}\r
 \r
 /**\r
   Call Crypto Lib to generate a random value with eight-octet length.\r
 \r
 /**\r
   Call Crypto Lib to generate a random value with eight-octet length.\r
@@ -159,19 +200,53 @@ IkePayloadFree (
 \r
 /**\r
   Generate an new SPI.\r
 \r
 /**\r
   Generate an new SPI.\r
-\r
-  @return a SPI in 4 bytes.\r
+  \r
+  @param[in]       IkeSaSession   Pointer to IKEV2_SA_SESSION related to this Child SA \r
+                                  Session.\r
+  @param[in, out]  SpiValue       Pointer to the new generated SPI value. \r
+                              \r
+  @retval EFI_SUCCESS         The operation performs successfully.\r
+  @retval Otherwise           The operation is failed.\r
 \r
 **/\r
 \r
 **/\r
-UINT32\r
+EFI_STATUS\r
 IkeGenerateSpi (\r
 IkeGenerateSpi (\r
-  VOID\r
+  IN     IKEV2_SA_SESSION         *IkeSaSession,\r
+  IN OUT UINT32                   *SpiValue\r
   )\r
 {\r
   )\r
 {\r
-  //\r
-  // TODO: should generate SPI randomly to avoid security issue\r
-  //\r
-  return mNextSpi++;\r
+  EFI_STATUS   Status;\r
+\r
+  Status = EFI_SUCCESS;\r
\r
+  while (TRUE) {\r
+    //\r
+    // Generate SPI randomly\r
+    //\r
+    Status = IpSecCryptoIoGenerateRandomBytes ((UINT8 *)SpiValue, sizeof (UINT32));\r
+    if (EFI_ERROR (Status)) {\r
+      break;\r
+    }\r
+\r
+    //\r
+    // The set of SPI values in the range 1 through 255 are reserved by the \r
+    // Internet Assigned Numbers Authority (IANA) for future use; a reserved \r
+    // SPI value will not normally be assigned by IANA unless the use of the \r
+    // assigned SPI value is specified in an RFC.\r
+    //\r
+    if (*SpiValue < IKE_SPI_BASE) {\r
+      *SpiValue += IKE_SPI_BASE; \r
+    }\r
+\r
+    //\r
+    // Check whether the new generated SPI has existed.\r
+    //\r
+    if (!IkeSpiValueExisted (IkeSaSession, *SpiValue)) {\r
+      break;\r
+    }\r
+  }\r
+  \r
+  return Status;\r
 }\r
 \r
 /**\r
 }\r
 \r
 /**\r
@@ -194,42 +269,42 @@ IkeGenerateIv (
 }\r
 \r
 \r
 }\r
 \r
 \r
-/**
-  Find SPD entry by a specified SPD selector.
-
+/**\r
+  Find SPD entry by a specified SPD selector.\r
+\r
   @param[in] SpdSel       Point to SPD Selector to be searched for.\r
   @param[in] SpdSel       Point to SPD Selector to be searched for.\r
-
+\r
   @retval Point to SPD Entry if the SPD entry found.\r
   @retval Point to SPD Entry if the SPD entry found.\r
-  @retval NULL if not found.
-
-**/
-IPSEC_SPD_ENTRY *
+  @retval NULL if not found.\r
+\r
+**/\r
+IPSEC_SPD_ENTRY *\r
 IkeSearchSpdEntry (\r
 IkeSearchSpdEntry (\r
-  IN EFI_IPSEC_SPD_SELECTOR             *SpdSel
-  )
-{
-  IPSEC_SPD_ENTRY *SpdEntry;
-  LIST_ENTRY      *SpdList;
-  LIST_ENTRY      *Entry;
-
-  SpdList = &mConfigData[IPsecConfigDataTypeSpd];
-
-  NET_LIST_FOR_EACH (Entry, SpdList) {
-    SpdEntry = IPSEC_SPD_ENTRY_FROM_LIST (Entry);
-
-    //
+  IN EFI_IPSEC_SPD_SELECTOR             *SpdSel\r
+  )\r
+{\r
+  IPSEC_SPD_ENTRY *SpdEntry;\r
+  LIST_ENTRY      *SpdList;\r
+  LIST_ENTRY      *Entry;\r
+\r
+  SpdList = &mConfigData[IPsecConfigDataTypeSpd];\r
+\r
+  NET_LIST_FOR_EACH (Entry, SpdList) {\r
+    SpdEntry = IPSEC_SPD_ENTRY_FROM_LIST (Entry);\r
+\r
+    //\r
     // Find the required SPD entry\r
     // Find the required SPD entry\r
-    //
-    if (CompareSpdSelector (
-          (EFI_IPSEC_CONFIG_SELECTOR *) SpdSel,
-          (EFI_IPSEC_CONFIG_SELECTOR *) SpdEntry->Selector
-          )) {
-      return SpdEntry;
-    }
-
-  }
-
-  return NULL;
+    //\r
+    if (CompareSpdSelector (\r
+          (EFI_IPSEC_CONFIG_SELECTOR *) SpdSel,\r
+          (EFI_IPSEC_CONFIG_SELECTOR *) SpdEntry->Selector\r
+          )) {\r
+      return SpdEntry;\r
+    }\r
+\r
+  }\r
+\r
+  return NULL;\r
 }\r
 \r
 /**\r
 }\r
 \r
 /**\r