]> 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
-  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
 #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
@@ -159,19 +200,53 @@ IkePayloadFree (
 \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
-UINT32\r
+EFI_STATUS\r
 IkeGenerateSpi (\r
-  VOID\r
+  IN     IKEV2_SA_SESSION         *IkeSaSession,\r
+  IN OUT UINT32                   *SpiValue\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
@@ -194,42 +269,42 @@ IkeGenerateIv (
 }\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
-
+\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
-  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
-    //
-    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