diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/src/ikev2sadata.cpp --- /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; +}