summaryrefslogtreecommitdiff
path: root/NetworkPkg
diff options
context:
space:
mode:
Diffstat (limited to 'NetworkPkg')
-rw-r--r--NetworkPkg/IpSecDxe/IkeCommon.c102
-rw-r--r--NetworkPkg/IpSecDxe/IkeCommon.h20
-rw-r--r--NetworkPkg/IpSecDxe/Ikev2/Utility.c11
3 files changed, 112 insertions, 21 deletions
diff --git a/NetworkPkg/IpSecDxe/IkeCommon.c b/NetworkPkg/IpSecDxe/IkeCommon.c
index 6fc7c06353..b1e4321142 100644
--- a/NetworkPkg/IpSecDxe/IkeCommon.c
+++ b/NetworkPkg/IpSecDxe/IkeCommon.c
@@ -1,7 +1,7 @@
/** @file
Common operation of the IKE
- Copyright (c) 2010 - 2015, 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
@@ -18,10 +18,52 @@
#include "IpSecConfigImpl.h"
#include "IpSecDebug.h"
-//
-// Initial the SPI
-//
-UINT32 mNextSpi = IKE_SPI_BASE;
+/**
+ Check whether the new generated Spi has existed.
+
+ @param[in] IkeSaSession Pointer to the Child SA Session.
+ @param[in] SpiValue SPI Value.
+
+ @retval TRUE This SpiValue has existed in the Child SA Session
+ @retval FALSE This SpiValue doesn't exist in the Child SA Session.
+
+**/
+BOOLEAN
+IkeSpiValueExisted (
+ IN IKEV2_SA_SESSION *IkeSaSession,
+ IN UINT32 SpiValue
+ )
+{
+ LIST_ENTRY *Entry;
+ LIST_ENTRY *Next;
+ IKEV2_CHILD_SA_SESSION *SaSession;
+
+ Entry = NULL;
+ Next = NULL;
+ SaSession = NULL;
+
+ //
+ // Check whether the SPI value has existed in ChildSaEstablishSessionList.
+ //
+ NET_LIST_FOR_EACH_SAFE (Entry, Next, &IkeSaSession->ChildSaEstablishSessionList) {
+ SaSession= IKEV2_CHILD_SA_SESSION_BY_IKE_SA (Entry);
+ if (SaSession->LocalPeerSpi == SpiValue) {
+ return TRUE;
+ }
+ }
+
+ //
+ // Check whether the SPI value has existed in ChildSaSessionList.
+ //
+ NET_LIST_FOR_EACH_SAFE (Entry, Next, &IkeSaSession->ChildSaSessionList) {
+ SaSession= IKEV2_CHILD_SA_SESSION_BY_IKE_SA (Entry);
+ if (SaSession->LocalPeerSpi == SpiValue) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
/**
Call Crypto Lib to generate a random value with eight-octet length.
@@ -158,19 +200,53 @@ IkePayloadFree (
/**
Generate an new SPI.
-
- @return a SPI in 4 bytes.
+
+ @param[in] IkeSaSession Pointer to IKEV2_SA_SESSION related to this Child SA
+ Session.
+ @param[in out] SpiValue Pointer to the new generated SPI value.
+
+ @retval EFI_SUCCESS The operation performs successfully.
+ @retval Otherwise The operation is failed.
**/
-UINT32
+EFI_STATUS
IkeGenerateSpi (
- VOID
+ IN IKEV2_SA_SESSION *IkeSaSession,
+ OUT UINT32 *SpiValue
)
{
- //
- // TODO: should generate SPI randomly to avoid security issue
- //
- return mNextSpi++;
+ EFI_STATUS Status;
+
+ Status = EFI_SUCCESS;
+
+ while (TRUE) {
+ //
+ // Generate SPI randomly
+ //
+ Status = IpSecCryptoIoGenerateRandomBytes ((UINT8 *)SpiValue, sizeof (UINT32));
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+
+ //
+ // The set of SPI values in the range 1 through 255 are reserved by the
+ // Internet Assigned Numbers Authority (IANA) for future use; a reserved
+ // SPI value will not normally be assigned by IANA unless the use of the
+ // assigned SPI value is specified in an RFC.
+ //
+ if (*SpiValue < IKE_SPI_BASE) {
+ *SpiValue += IKE_SPI_BASE;
+ }
+
+ //
+ // Check whether the new generated SPI has existed.
+ //
+ if (!IkeSpiValueExisted (IkeSaSession, *SpiValue)) {
+ break;
+ }
+ }
+
+ return Status;
}
/**
diff --git a/NetworkPkg/IpSecDxe/IkeCommon.h b/NetworkPkg/IpSecDxe/IkeCommon.h
index 714ecaa8e3..7f7fd4d5b0 100644
--- a/NetworkPkg/IpSecDxe/IkeCommon.h
+++ b/NetworkPkg/IpSecDxe/IkeCommon.h
@@ -1,7 +1,7 @@
/** @file
Common operation of the IKE.
- Copyright (c) 2010 - 2015, 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
@@ -39,7 +39,7 @@
#define IKE_DEFAULT_TIMEOUT_INTERVAL 10000 // 10s
#define IKE_NONCE_SIZE 16
#define IKE_MAX_RETRY 4
-#define IKE_SPI_BASE 0x10000
+#define IKE_SPI_BASE 0x100
#define IKE_PAYLOAD_SIGNATURE SIGNATURE_32('I','K','E','P')
#define IKE_PAYLOAD_BY_PACKET(a) CR(a,IKE_PAYLOAD,ByPacket,IKE_PAYLOAD_SIGNATURE)
@@ -130,14 +130,20 @@ IkePayloadFree (
);
/**
- Generate an unused SPI
-
- @return a SPI in 4 bytes.
+ Generate an new SPI.
+
+ @param[in] IkeSaSession Pointer to IKEV2_SA_SESSION related to this Child SA
+ Session.
+ @param[in out] SpiValue Pointer to the new generated SPI value.
+
+ @retval EFI_SUCCESS The operation performs successfully.
+ @retval Otherwise The operation is failed.
**/
-UINT32
+EFI_STATUS
IkeGenerateSpi (
- VOID
+ IN IKEV2_SA_SESSION *IkeSaSession,
+ OUT UINT32 *SpiValue
);
/**
diff --git a/NetworkPkg/IpSecDxe/Ikev2/Utility.c b/NetworkPkg/IpSecDxe/Ikev2/Utility.c
index 5b26ba1d02..c3655328c4 100644
--- a/NetworkPkg/IpSecDxe/Ikev2/Utility.c
+++ b/NetworkPkg/IpSecDxe/Ikev2/Utility.c
@@ -525,7 +525,16 @@ Ikev2ChildSaSessionAlloc (
ChildSaSession->Signature = IKEV2_CHILD_SA_SESSION_SIGNATURE;
ChildSaSession->IkeSaSession = IkeSaSession;
ChildSaSession->MessageId = IkeSaSession->MessageId;
- ChildSaSession->LocalPeerSpi = IkeGenerateSpi ();
+
+ //
+ // Generate an new SPI.
+ //
+ Status = IkeGenerateSpi (IkeSaSession, &(ChildSaSession->LocalPeerSpi));
+ if (EFI_ERROR (Status)) {
+ FreePool (ChildSaSession);
+ return NULL;
+ }
+
ChildSaCommon = &ChildSaSession->SessionCommon;
ChildSaCommon->UdpService = UdpService;
ChildSaCommon->Private = IkeSaSession->SessionCommon.Private;