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