]> git.proxmox.com Git - mirror_edk2.git/blobdiff - NetworkPkg/IpSecDxe/IkeCommon.c
NetworkPkg/IpSecDxe: Generate SPI randomly and correct IKE_SPI_BASE value
[mirror_edk2.git] / NetworkPkg / IpSecDxe / IkeCommon.c
index 6fc7c063538da76cdb0416a79b7f3398057d54c2..b1e432114226e1720f5720b2ac6a3dd43c684039 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Common operation of the IKE\r
   \r
-  Copyright (c) 2010 - 2015, 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
+/**\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
@@ -158,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
+  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