--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/vpnengine/ikev2lib/src/ikev2sadata.cpp Thu Dec 17 09:14:51 2009 +0200
@@ -0,0 +1,259 @@
+/*
+* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: IKEv2 SA data definition
+* Class TIkev2SAData is the IKEv2 SA parameter definition which
+* is used to pass SA information between IKE server and IKEv2
+* plug-in.
+*
+*/
+
+#include "ikev2SAdata.h"
+#include "ikecrypto.h"
+#include "ikev2const.h"
+
+TIkev2SAData::TIkev2SAData()
+://iSAId(0),
+ iSPI_I(),
+ iSPI_R(),
+ iSAState(0),
+ iInitiator(EFalse),
+ iIkeData(NULL),
+ iVpnIapId(0),
+ iLocalAddr(),
+ iVirtualAddr(),
+ iRemoteAddr(),
+ iDestinAddr(),
+ iNATFlags(0),
+ iFloatedPort(EFalse),
+ iWindowSize(0),
+ iRespRetryCount(0),
+ iEncrAlg(0),
+ iPRFAlg(0),
+ iIntegAlg(0),
+ iDHGroup(0),
+ iEAPType(0),
+ iAuthMethod(0),
+ iLifetime(0),
+ iCipherKeyLth(0),
+ iCipherBlkLth(0),
+ iIntChkSumLth(0),
+ iMobikeUsed(EFalse)
+ {
+ iSPI_I.SetLength(iSPI_I.MaxLength());
+ iSPI_I.FillZ();
+
+ iSPI_R.SetLength(iSPI_R.MaxLength());
+ iSPI_R.FillZ();
+ }
+
+
+void TIkev2SAData::CleanUp()
+ {
+ FreeRespMsg();
+ FreeRequestMsg();
+ }
+
+
+void TIkev2SAData::FreeRespMsg()
+ {
+ delete iLastResponse;
+ iLastResponse = NULL;
+ }
+
+
+void TIkev2SAData::FreeRequestMsg()
+ {
+ delete iLastRequest;
+ iLastRequest = NULL;
+ }
+
+
+void TIkev2SAData::StoreVirtualIp(const TInetAddr& aVirtualAddr)
+ {
+ iVirtualAddr = aVirtualAddr;
+ }
+
+
+void TIkev2SAData::SaveRespMsg(CIkeV2Message* aRespMsg)
+ {
+ FreeRespMsg();
+ iLastResponse = aRespMsg;
+ }
+
+
+void TIkev2SAData::SaveRequestMsg(CIkeV2Message* aRequestMsg)
+ {
+ FreeRequestMsg();
+ iLastRequest = aRequestMsg;
+ }
+
+
+void TIkev2SAData::Copy(TIkev2SAData& aSrc)
+ {
+ TInetAddr savedVirtualAddr = iVirtualAddr;
+ CIkeV2Message* savedLastResponse = iLastResponse;
+ CIkeV2Message* savedLastRequest = iLastRequest;
+
+ Mem::Copy((TUint8*)&iSAId, (TUint8*)&aSrc.iSAId, sizeof(TIkev2SAData));
+
+ if (iLastResponse != NULL)
+ {
+ delete savedLastResponse;
+ aSrc.iLastResponse = NULL;
+ }
+ else
+ {
+ iLastResponse = savedLastResponse;
+ }
+
+ if (iLastRequest != NULL)
+ {
+ delete savedLastRequest;
+ aSrc.iLastRequest = NULL;
+ }
+ else
+ {
+ iLastRequest = savedLastRequest;
+ }
+
+ if ( iVirtualAddr.IsUnspecified() )
+ iVirtualAddr = savedVirtualAddr;
+ }
+
+
+TUint32 TIkev2SAData::SaId() const
+ {
+ return iSAId;
+ }
+
+
+void TIkev2SAData::SetSaId(TUint32 aSaId)
+ {
+ iSAId = aSaId;
+ }
+
+
+TIkeSPI& TIkev2SAData::SpiI()
+ {
+ return iSPI_I;
+ }
+
+
+void TIkev2SAData::SetSpiI(const TIkeSPI& aSpiI)
+ {
+ iSPI_I = aSpiI;
+ }
+
+
+TIkeSPI& TIkev2SAData::SpiR()
+ {
+ return iSPI_R;
+ }
+
+
+void TIkev2SAData::SetSpiR(const TIkeSPI& aSpiR)
+{
+ iSPI_R = aSpiR;
+}
+
+void TIkev2SAData::GenerateIkeKeyDerivatesL(const TDesC8& aSKEYSEED,TUint16 aPrfAlg,
+ const TDesC8& aNonceI, const TDesC8& aNonceR)
+{
+ //
+ // Generate IKE keying information from SKEYDSEED (its
+ // derivates).
+ // SK_d | SK_ai | SK_ar | SK_ei | SK_er | SK_pi | SK_pr
+ // = prf+ (SKEYSEED, Ni | Nr | SPIi | SPIr )
+ // Since the amount of keying material needed may be greater than
+ // the size of the output of the prf algorithm prf+ is used as
+ // follows prf+ (SKEYSEED,S) = T1 | T2 | T3 | T4 | ...
+ // where: T1 = prf (SKEYSEED, S | 0x01)
+ // T2 = prf (SKEYSEED, T1 | S | 0x02) ..
+ // TN = prf (SKEYSEED, TN-1 | S | 0xN ) ;[ N < 256 ]
+ // Calculate first required key material length:
+ // Length of SK_d = Length of PRF algorithm output
+ // Length of SK_ai and SK_ar = Length of integrity algorithm key
+ // Length of SK_ei and SK_er = Length of cipher algorithm key
+ // Length of SK_pi and SK_pr = Length of PRF output
+ //
+ TInt EncKeyLth = IkeCrypto::AlgorithmInfo(IKEV2_ENCR, iEncrAlg, &iCipherBlkLth);
+ if ( iCipherKeyLth == 0 )
+ iCipherKeyLth = EncKeyLth;
+ TInt IntKeyLth = IkeCrypto::AlgorithmInfo(IKEV2_INTEG, iIntegAlg, &iIntChkSumLth);
+ TInt PrfKeyLth = IkeCrypto::AlgorithmInfo(IKEV2_PRF, iPRFAlg, NULL);
+ TInt KeyMatLth = 2*iCipherKeyLth + 2*IntKeyLth + 3*PrfKeyLth;
+ HBufC8* S = HBufC8::NewL(aNonceI.Length() + aNonceR.Length() + 2*IKEV2_SPI_SIZE);
+ CleanupStack::PushL(S);
+ //
+ // Copy value S = (Ni | Nr | SPIi | SPIr) into work buffer S
+ //
+ S->Des().Copy(aNonceI);
+ S->Des().Append(aNonceR);
+ S->Des().Append(SpiI());
+ S->Des().Append(SpiR());
+
+ HBufC8* KeyMat = IkeCrypto::GenerateKeyingMaterialL(aSKEYSEED, S->Des(), KeyMatLth, aPrfAlg);
+ //
+ // Store derived key material into negotiation object in the
+ // following order: Key material =
+ // SK_d | SK_ai | SK_ar | SK_ei | SK_er | SK_pi | SK_pr
+ //
+ TUint8* KeyMatBfr = (TUint8*)KeyMat->Ptr(); // Keymaterial buffer start
+ iSK_d.Copy(KeyMatBfr, PrfKeyLth);
+ KeyMatBfr += PrfKeyLth;
+ iSK_ai.Copy(KeyMatBfr,IntKeyLth );
+ KeyMatBfr += IntKeyLth;
+ iSK_ar.Copy(KeyMatBfr, IntKeyLth);
+ KeyMatBfr += IntKeyLth;
+ iSK_ei.Copy(KeyMatBfr, iCipherKeyLth);
+ KeyMatBfr += iCipherKeyLth;
+ iSK_er.Copy(KeyMatBfr, iCipherKeyLth);
+ KeyMatBfr += iCipherKeyLth;
+ iSK_pi.Copy(KeyMatBfr,PrfKeyLth );
+ KeyMatBfr += PrfKeyLth;
+ iSK_pr.Copy(KeyMatBfr, PrfKeyLth);
+
+ KeyMat->Des().FillZ(); // Wipe out key material (T1 | T2 | ...) data from buffer
+ delete KeyMat;
+
+ CleanupStack::PopAndDestroy(); //S
+}
+
+
+TUint32 TIkev2SAData::NextRequestId() const
+{
+ TUint32 msgId = 0;
+ if(iLastRequest != NULL)
+ {
+ msgId = iLastRequest->MessageId() + 1;
+ }
+ return msgId;
+}
+
+
+TUint32 TIkev2SAData::ExpectedResponseId() const
+{
+ __ASSERT_DEBUG(iLastRequest != NULL, User::Invariant());
+ return iLastRequest->MessageId();
+}
+
+TUint32 TIkev2SAData::ExpectedRequestId() const
+{
+ TUint32 msgId = 0;
+ if(iLastResponse != NULL)
+ {
+ msgId = iLastResponse->MessageId() + 1;
+ }
+ return msgId;
+}