From 96c13c011766a950247c743887705cc035a15497 Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Wed, 20 Jul 2016 10:53:31 +0800 Subject: [PATCH] NetworkPkg/IpSecDxe: Generate SPI randomly and correct IKE_SPI_BASE value This path made the following update: * Generate SPI randomly. * Correct IKE_SPI_BASE value according RFC 4302/4303. Cc: Ye Ting Cc: Fu Siyuan Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jiaxin Wu Reviewed-by: Ye Ting Reviewed-by: Fu Siyuan --- NetworkPkg/IpSecDxe/IkeCommon.c | 102 ++++++++++++++++++++++++---- NetworkPkg/IpSecDxe/IkeCommon.h | 20 ++++-- NetworkPkg/IpSecDxe/Ikev2/Utility.c | 11 ++- 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.
+ Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.
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.
+ Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.
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; -- 2.39.2