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 <ting.ye@intel.com>
Cc: Fu Siyuan <siyuan.fu@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jiaxin Wu <jiaxin.wu@intel.com>
Reviewed-by: Ye Ting <ting.ye@intel.com>
Reviewed-by: Fu Siyuan <siyuan.fu@intel.com>
This commit is contained in:
Jiaxin Wu 2016-07-20 10:53:31 +08:00
parent 8c5f78a2cc
commit 96c13c0117
3 changed files with 112 additions and 21 deletions

View File

@ -1,7 +1,7 @@
/** @file /** @file
Common operation of the IKE 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 This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD License
@ -18,10 +18,52 @@
#include "IpSecConfigImpl.h" #include "IpSecConfigImpl.h"
#include "IpSecDebug.h" #include "IpSecDebug.h"
// /**
// Initial the SPI Check whether the new generated Spi has existed.
//
UINT32 mNextSpi = IKE_SPI_BASE; @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. Call Crypto Lib to generate a random value with eight-octet length.
@ -158,19 +200,53 @@ IkePayloadFree (
/** /**
Generate an new SPI. 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 ( IkeGenerateSpi (
VOID IN IKEV2_SA_SESSION *IkeSaSession,
OUT UINT32 *SpiValue
) )
{ {
// EFI_STATUS Status;
// TODO: should generate SPI randomly to avoid security issue
// Status = EFI_SUCCESS;
return mNextSpi++;
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;
} }
/** /**

View File

@ -1,7 +1,7 @@
/** @file /** @file
Common operation of the IKE. 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 This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License 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_DEFAULT_TIMEOUT_INTERVAL 10000 // 10s
#define IKE_NONCE_SIZE 16 #define IKE_NONCE_SIZE 16
#define IKE_MAX_RETRY 4 #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_SIGNATURE SIGNATURE_32('I','K','E','P')
#define IKE_PAYLOAD_BY_PACKET(a) CR(a,IKE_PAYLOAD,ByPacket,IKE_PAYLOAD_SIGNATURE) #define IKE_PAYLOAD_BY_PACKET(a) CR(a,IKE_PAYLOAD,ByPacket,IKE_PAYLOAD_SIGNATURE)
@ -130,14 +130,20 @@ IkePayloadFree (
); );
/** /**
Generate an unused SPI 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 ( IkeGenerateSpi (
VOID IN IKEV2_SA_SESSION *IkeSaSession,
OUT UINT32 *SpiValue
); );
/** /**

View File

@ -525,7 +525,16 @@ Ikev2ChildSaSessionAlloc (
ChildSaSession->Signature = IKEV2_CHILD_SA_SESSION_SIGNATURE; ChildSaSession->Signature = IKEV2_CHILD_SA_SESSION_SIGNATURE;
ChildSaSession->IkeSaSession = IkeSaSession; ChildSaSession->IkeSaSession = IkeSaSession;
ChildSaSession->MessageId = IkeSaSession->MessageId; 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 = &ChildSaSession->SessionCommon;
ChildSaCommon->UdpService = UdpService; ChildSaCommon->UdpService = UdpService;
ChildSaCommon->Private = IkeSaSession->SessionCommon.Private; ChildSaCommon->Private = IkeSaSession->SessionCommon.Private;