--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/rtp/srtpstack/src/srtpcryptohandlersrtp.cpp Tue Feb 02 01:03:15 2010 +0200
@@ -0,0 +1,863 @@
+/*
+* Copyright (c) 2004 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: .
+*
+*/
+
+
+
+
+// INCLUDES
+#include <e32std.h>
+#include "srtpcryptohandler.h"
+#include "srtpcryptohandlersrtp.h"
+#include "msrtpcryptohandlercontext.h"
+#include "srtputils.h"
+#include <e32math.h>
+#include "srtpstream.h"
+#include "srtpmasterkey.h"
+#include "srtpmastersalt.h"
+#include "msrtpkeyderivation.h"
+#include "msrtpauthentication.h"
+#include "msrtpcipher.h"
+#include "srtppacketrtp.h"
+#include "srtppacketsrtp.h"
+#include "srtpcryptoparams.h"
+#include "srtpcipher_aescm128.h"
+#include "srtpcipher_null.h"
+#include "srtpauthentication_hmac_sha1.h"
+#include "srtpauthentication_null.h"
+#include "srtpauthentication_rcc.h"
+
+// ---------------------------------------------------------------------------
+// CSRTPCryptoHandlerSRTP::CSRTPCryptoHandlerSRTP
+// ---------------------------------------------------------------------------
+//
+CSRTPCryptoHandlerSRTP::CSRTPCryptoHandlerSRTP( CSRTPStream& aStream):
+ CSRTPCryptoHandler(aStream)
+ {}
+
+// ---------------------------------------------------------------------------
+// CSRTPCryptoHandlerSRTP::~CSRTPCryptoHandlerSRTP
+// ---------------------------------------------------------------------------
+//
+CSRTPCryptoHandlerSRTP::~CSRTPCryptoHandlerSRTP( )
+ {
+
+ }
+
+
+// ---------------------------------------------------------------------------
+// Two-phased constructor.
+//
+// ---------------------------------------------------------------------------
+//
+CSRTPCryptoHandlerSRTP* CSRTPCryptoHandlerSRTP::NewL(CSRTPStream& aStream)
+ {
+ CSRTPCryptoHandlerSRTP* self = CSRTPCryptoHandlerSRTP::NewLC( aStream);
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CSRTPCryptoHandlerSRTP::NewLC
+// -----------------------------------------------------------------------------
+//
+CSRTPCryptoHandlerSRTP* CSRTPCryptoHandlerSRTP::NewLC(CSRTPStream& aStream)
+ {
+ CSRTPCryptoHandlerSRTP* self = new( ELeave )CSRTPCryptoHandlerSRTP( aStream);
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ return self;
+ }
+
+
+
+// -----------------------------------------------------------------------------
+// CSRTPCryptoHandlerSRTP::SetReceiver_s_l
+// -----------------------------------------------------------------------------
+//
+void CSRTPCryptoHandlerSRTP::SetReceiver_s_l()
+ {
+ // initialize s_l value for the first packet
+ iS_L=iCurrentPacket->SequenceNumber();
+ }
+
+
+// ---------------------------------------------------------------------------
+// CSRTPCryptoHandlerSRTP::ConstructL()
+// ---------------------------------------------------------------------------
+//
+void CSRTPCryptoHandlerSRTP::ConstructL()
+ {
+ //construct the upper class
+ CSRTPCryptoHandler::ConstructL();
+ SetEncAndAuthL( CryptoParams().iSrtpEncAlg,
+ CryptoParams().iSrtpAuthAlg );
+ //when the session starts set ROC to zero
+ iROC =0; //only using when RCC mode as sender Roc
+ SetROC(0);
+ iPktIndex=0;//Replay Index
+ iReplayIndexDelta=0;
+ iSRTPMasterKeyLifeTime = CryptoParams().iMasterKeysLifeTime;
+ if ( !iSRTPMasterKeyLifeTime ||
+ iSRTPMasterKeyLifeTime > KSRTPMasterKeysLifeTime )
+ {
+ iSRTPMasterKeyLifeTime = KSRTPMasterKeysLifeTime;
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// void CSRTPCryptoHandlerSRTP::MasterKeysUpdated()
+// ---------------------------------------------------------------------------
+//
+TBool CSRTPCryptoHandlerSRTP::MasterKeysUpdated()
+ {
+ return iMasterDataUpdated;
+ }
+
+
+// ---------------------------------------------------------------------------
+// void CSRTPCryptoHandlerSRTP::InitializePlainPacketL()
+// ---------------------------------------------------------------------------
+//
+void CSRTPCryptoHandlerSRTP::InitializePlainPacketL(const TDesC8& aPacket)
+ {
+ if(iCurrentPacket)
+ delete iCurrentPacket; iCurrentPacket=NULL;
+ iCurrentPacket = CSRTPPacketRTP::NewL(aPacket, *this);
+ }
+
+// ---------------------------------------------------------------------------
+// void CSRTPCryptoHandlerSRTP::InitializeEncryptedPacketL()
+// ---------------------------------------------------------------------------
+//
+void CSRTPCryptoHandlerSRTP::InitializeEncryptedPacketL(const TDesC8& aPacket)
+ {
+ if(iCurrentPacket)
+ delete iCurrentPacket;iCurrentPacket=NULL;
+ iCurrentPacket = CSRTPPacketSRTP::NewL(aPacket, *this);
+
+ }
+
+// ---------------------------------------------------------------------------
+// CSRTPCryptoHandlerSRTP::DecryptL()
+// ---------------------------------------------------------------------------
+//
+HBufC8* CSRTPCryptoHandlerSRTP::DecryptL()
+ {
+ // Step 6, decryption (in RFC 3711, section 3.3):
+ SRTP_DEBUG_DETAIL( "CSRTPCryptoHandlerSRTP::DecryptL() Entry" );
+
+ HBufC8* decryptedPayload = CountIV_And_TransformL();
+ CleanupStack::PushL(decryptedPayload);
+
+ TUint8* decryptedPayloadPtr = const_cast<TUint8*>(decryptedPayload->Des().Ptr());
+ HBufC8* rtpPacket = iCurrentPacket->CreateDecryptedPacketL(decryptedPayloadPtr);
+ TUint8* rtpPacketPtr = const_cast<TUint8*>(rtpPacket->Des().Ptr());
+
+ SRTP_DEBUG_DETAIL( "SRTP Decrypt Payload" );
+ SRTP_DEBUG_PACKET( *decryptedPayload );
+
+ CleanupStack::PopAndDestroy( decryptedPayload );
+
+ SRTP_DEBUG_DETAIL( "CSRTPCryptoHandlerSRTP::DecryptL() Exit" );
+
+ return rtpPacket;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CSRTPCryptoHandlerSRTP::AuthenticateL()
+// ---------------------------------------------------------------------------
+//
+void CSRTPCryptoHandlerSRTP::AuthenticateL()
+ {
+ SRTP_DEBUG_DETAIL( "CSRTPCryptoHandlerSRTP::AuthenticateL() ENTRY" );
+
+ //Note that RCCm1 only to integrity check when carrying ROC
+ if ( iCurrentPacket->AuthenticationTag().Length() > 0 &&
+ ( CryptoParams().iSrtpAuthAlg == EAuthHMAC_SHA1 ||
+ CryptoParams().iSrtpAuthAlg == EAuthRCCm2||
+ ( CryptoParams().iSrtpAuthAlg == EAuthRCCm1&& CarryROC() ) ))
+ {
+ // calculate auth tag from the authenticated area..
+ HBufC8* calculatedAuthTag = CalculateAuthTagL();
+ if (!calculatedAuthTag)
+ {
+ User::Leave(KErrNotFound);
+ }
+ CleanupStack::PushL(calculatedAuthTag);
+
+ // finally, compare the two auth tags..
+ if (iCurrentPacket->AuthenticationTag().Compare(
+ *calculatedAuthTag) != 0)
+ {
+ SRTP_DEBUG_DETAIL( "SRTP HMAC caculated Authentication tag and the compared is wrong" );
+ SRTP_DEBUG_PACKET( *calculatedAuthTag );
+
+ // authentication failed, since tags dont match
+ User::Leave(KErrNotFound);
+ }
+
+ // then, lose the auth tag we just calculated
+ CleanupStack::PopAndDestroy(calculatedAuthTag);
+
+ }
+ //authentication successful then set localROC to sender ROC need to be implemented
+ SRTP_DEBUG_DETAIL( "CSRTPCryptoHandlerSRTP::AuthenticateL() EXIT" );
+
+ }
+
+// ---------------------------------------------------------------------------
+// CSRTPCryptoHandlerSRTP::CalculateAuthTagL()
+// only using in SRTP
+// ---------------------------------------------------------------------------
+//
+HBufC8* CSRTPCryptoHandlerSRTP::CalculateAuthTagL()
+ {
+ // M denotes the authenticated area, that is header + payload..
+ // ..but for RTP we need to add the ROC,
+ // that is, M = header + payload || ROC
+
+ TBuf8<16> roc;
+ TBuf8<8> roc_hexed;
+ //using iV instead of ROC because ROC is not updated yet until decryption sucessfull
+ roc.AppendNumUC(iV, EHex);
+
+ TSRTPUtils::DeHex(roc, roc_hexed);
+ TUint size = roc.Size();
+
+ for (TInt i=0; i<(4-size); i++)
+ {
+ roc_hexed.Append(0x00);
+ }
+ TInt len = iCurrentPacket->HeaderLength() + iCurrentPacket->PayloadLength();
+ HBufC8* authPortion = iCurrentPacket->Get_Concatenated_MDataL(EFalse);
+ CleanupStack::PushL(authPortion);
+ authPortion->Des().SetLength(len);
+
+ HBufC8* calculatedAuthTag = DoAuthenticationL(*authPortion, roc_hexed);
+
+ CleanupStack::PopAndDestroy(authPortion);
+
+ roc.Zero();
+ roc_hexed.Zero();
+ return calculatedAuthTag;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CSRTPCryptoHandlerSRTP::CountReceiverPacketIndexL()
+// ---------------------------------------------------------------------------
+//
+void CSRTPCryptoHandlerSRTP::CountReceiverPacketIndexL()
+ {
+ if (iReKey)
+ {
+ User::Leave(KErrTooBig);
+ }
+ TReal result;
+
+ TReal twoexp32= 4294967296;
+ //TReal twoexp16= 65536;
+ TReal ROCnumber= ROC()-1;
+
+ if (iS_L < 32768)
+ {
+ if (iCurrentPacket->SequenceNumber() - iS_L > 32768)
+ {
+ User::LeaveIfError(Math::Mod(result, ROCnumber /*ROC() - 1*/, twoexp32));
+ User::LeaveIfError(Math::Int(iV, result));
+ }
+ else
+ {
+ iV = ROC();
+ }
+ }
+ else
+ {
+ if (iS_L - 32768 > iCurrentPacket->SequenceNumber())
+ {
+ User::LeaveIfError(Math::Mod(result, ROC() + 1, twoexp32));
+ User::LeaveIfError(Math::Int(iV, result));
+ }
+ else
+ {
+ iV = ROC();
+ }
+ }
+
+ ReKeyCheck();
+
+ //Set for current Packet index
+ //check if authAlg is RCCmode and if carry ROC
+ if (CarryROC())
+ {
+ iCurrentPacket->SetPacketIndex(CountSndIndxbySndROC());
+ iROC = iCurrentPacket->GetSenderROC();
+ }
+ else
+ {
+ iCurrentPacket->SetPacketIndex(iCurrentPacket->SequenceNumber() + iV * 65536/*K2EXP16*/);
+ }
+
+ }
+
+
+// ---------------------------------------------------------------------------
+// void CSRTPCryptoHandlerSRTP::CheckMasterKeyIdentifierL()
+// ---------------------------------------------------------------------------
+//
+void CSRTPCryptoHandlerSRTP::CheckMasterKeyIdentifierL()
+ {
+ // Step 3 (in RFC 3711, section 3.3):
+ // verify that this packet uses the same MKI
+ // than we have in CryptoContext
+ if(Context().MasterKey().MKI()!= KNullDesC8)
+ {
+ if (Context().MasterKey().MKI().Length() > 0)
+ {
+ TPtrC8 mki = iCurrentPacket->MasterKeyIdentifier();
+ if (Context().MasterKey().MKI().Compare(mki) != 0)
+ {
+ // we can not process this packet, since MKI does not match
+ User::Leave(KErrNotFound);
+ }
+ }
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CSRTPCryptoHandlerSRTP::Update_s_l_and_RocL()
+// ---------------------------------------------------------------------------
+//
+void CSRTPCryptoHandlerSRTP::Update_s_l_and_RocL()
+ {
+
+ TReal result;
+ TInt32 intResult;
+ TReal modulus(0x100000000);
+
+ // count (ROC - 1) mod 2^32
+
+ TInt res = Math::Mod(result, ROC() - 1, modulus);
+ if (res!=KErrNone)
+ {
+ User::Leave(res);
+ }
+
+ intResult = (TUint)result;
+
+ // if v == (ROC - 1) mod 2^32
+ if (iV == intResult)
+ {
+ // no update
+ return;
+ }
+
+ // if v == ROC
+ if (iV == ROC())
+ {
+ // if SEQ > s_l
+ if (iCurrentPacket->SequenceNumber() > iS_L)
+ {
+ //set s_l = SEQ
+ iS_L = iCurrentPacket->SequenceNumber();
+ }
+ }
+ else
+ {
+ // count (ROC + 1) mod 2^32
+ TReal temp= 4294967296;
+ res = Math::Mod(result, ROC() + 1, temp/*K2EXP32*/);
+ if (res!=KErrNone)
+ {
+ User::Leave(res);
+ }
+ res = Math::Int(intResult, result);
+ if (res!=KErrNone)
+ {
+ User::Leave(res);
+ }
+
+ // if v == (ROC + 1) mod 2^32
+ if (iV == intResult)
+ {
+ // set s_l to SEQ, and
+ // ROC to v
+ iS_L = iCurrentPacket->SequenceNumber();
+ SetROC(iV);
+ }
+ }
+ //RCCm1 and RCCm2 authentication successful then set localROC to sender ROC
+ //no authentication needed for RCCm3
+ if ((iCurrentPacket->AuthenticationTag().Length()>0 && CarryROC())||
+ (CryptoParams().iSrtpAuthAlg == EAuthRCCm3 &&
+ CarryROC() && !CryptoParams().iIsRCCm3Sync))
+ {
+ SetROC(iROC);
+ }
+
+ }
+
+
+// ---------------------------------------------------------------------------
+// CSRTPCryptoHandlerSRTP::CountSenderPacketIndex()
+// ---------------------------------------------------------------------------
+//
+void CSRTPCryptoHandlerSRTP::CountSenderPacketIndexL()
+ {
+ if (iReKey)
+ {
+ User::Leave(KErrTooBig);
+ }
+ //iReKey should be false
+ iCurrentPacket->CountSenderPacketIndex();
+ /*For Re-Key,
+ RFC 3711 3.2.1 and 9.2
+ i= 2^16*roc + seq
+ */
+
+ ReKeyCheck();
+ }
+
+// ---------------------------------------------------------------------------
+// CSRTPCryptoHandlerSRTP::ReKeyCheck()
+// ---------------------------------------------------------------------------
+//
+void CSRTPCryptoHandlerSRTP::ReKeyCheck()
+ {
+ TReal remainder;
+ Math::Mod(remainder, iCurrentPacket->SequenceNumber(), 0x10000-1);
+
+ // update ROC when SEQ wraps 2^16,
+ // with following exception:
+ // when SEQ is 0, MOD result is also 0,
+ // but we want remainder to be 0
+ // only when SEQ == 65535
+ if (remainder == 0.0 && iCurrentPacket->SequenceNumber() != 0)
+ {
+ if (ROC()+1 >= (0x100000000-1))
+ {
+ //RFC3711 3.2.1, i=2^16(1+ROC) , i can not more than 2^48
+ //Hex 0x100000000 is 2^32
+ // CRITICAL error
+ // we have sent more than 2^48 packets,
+ // can not send any more, should do reKey
+ //Should consider sending and receiving case
+ //Re-Key is needed, can send bye packet or event should be logged
+ //Sendbye should be at application level
+ iReKey = ETrue;
+ iStream.KeyExpired();
+ iStream.ReKeyNeeded();
+ }
+ }
+ TUint64 reKeyNumPacket = iNumPackets + KLeftNumOfPacketBeforeReKey;
+ //Re-Key is only called once when the number is equal
+ if ( ( reKeyNumPacket ) == iSRTPMasterKeyLifeTime )
+ {
+ //Call for Rekey before expired
+ iStream.ReKeyNeeded();
+ }
+ //when packets is really gets there, key expired
+ if ( iNumPackets >= iSRTPMasterKeyLifeTime )
+ {
+ iReKey = ETrue;
+ iStream.KeyExpired();
+ }
+ }
+// ---------------------------------------------------------------------------
+// CSRTPCryptoHandlerSRTP::CountIV_And_TransformL()
+// ---------------------------------------------------------------------------
+//
+HBufC8* CSRTPCryptoHandlerSRTP::CountIV_And_TransformL()
+ {
+ /*
+ This step is the same in RTP encryption and decryption,
+ RTCP case is different.
+ */
+ //IV is 128 bit value
+ TBuf8<16> iv;
+ // set IV to be 128 bit, 16 octets
+ iv.SetLength(16);
+
+ // count the IV for decryption
+
+ TInt ret = TSRTPUtils::CountIV(iv, *iSessionSaltKey, SSRC(), iCurrentPacket->PacketIndex());
+
+ if (ret!=KErrNone)
+ {
+ User::Leave(ret);
+ }
+
+ // Step 5, encryption (in RFC 3711, section 3.3):
+ return iCipher->TransformL( *iSessionEncrKey,
+ iv, iCurrentPacket->Payload() );
+ }
+
+// ---------------------------------------------------------------------------
+// CSRTPCryptoHandlerSRTP::EncryptL()
+// ---------------------------------------------------------------------------
+//
+HBufC8* CSRTPCryptoHandlerSRTP::EncryptL()
+ {
+ // Step 5, encryption (in RFC 3711, section 3.3):
+ SRTP_DEBUG_DETAIL( "CSRTPCryptoHandlerSRTP::EncryptL() ENTRY" );
+
+ SRTP_DEBUG_DETAIL( "CountIV_And_TransformL" );
+ HBufC8* encryptedPayload = CountIV_And_TransformL();
+ CleanupStack::PushL(encryptedPayload);
+
+ TUint8* encryptedPayloadPtr = const_cast<TUint8*>(encryptedPayload->Des().Ptr());
+
+ HBufC8* srtpPacket = iCurrentPacket->CreateEncryptedPacketL(encryptedPayloadPtr);
+ CleanupStack::PushL(srtpPacket);
+
+ TUint8* srtpPacketPtr = const_cast<TUint8*>(srtpPacket->Des().Ptr());
+
+ //Step 6, Add MKI (in RFC 3711, section 3.3):
+ AddMKIToPacket(srtpPacketPtr);
+
+ SRTP_DEBUG_DETAIL( "AddAuthTag" );
+
+ //Step 7, Add authentication tag (in RFC 3711, section 3.3):
+ if(IfAddAuthTag())
+ {
+ AddAuthTagToPacketL(srtpPacketPtr);
+ }
+
+ CleanupStack::Pop(srtpPacket);
+
+ SRTP_DEBUG_DETAIL( "Encrypted Payload" );
+ SRTP_DEBUG_PACKET( *encryptedPayload );
+
+ CleanupStack::PopAndDestroy(encryptedPayload);
+
+ SRTP_DEBUG_DETAIL( "CSRTPCryptoHandlerSRTP::EncryptL() EXIT" );
+
+ return srtpPacket;
+ }
+
+// ---------------------------------------------------------------------------
+// CSRTPCryptoHandler::AddMKIToPacket
+//
+// ---------------------------------------------------------------------------
+//
+void CSRTPCryptoHandlerSRTP::AddMKIToPacket(TUint8* aSrtpPacketPtr)
+ {
+ TUint8* ptr = aSrtpPacketPtr;
+ if(Context().MasterKey().MKI()!= KNullDesC8)
+ {
+ //Step 6, Add MKI (in RFC 3711, section 3.3):
+ if (Context().MasterKey().MKI().Length()>0)
+ {
+ ptr += iCurrentPacket->HeaderLength();
+ ptr += iCurrentPacket->PayloadLength();
+ TUint8* mkiPtr = const_cast<TUint8*>(Context().MasterKey().MKI().Ptr());
+ Mem::Copy( ptr, mkiPtr, Context().MasterKey().MKI().Length());
+ }
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// CSRTPCryptoHandlerSRTP::AddAuthTagToPacketL
+//
+// ---------------------------------------------------------------------------
+//
+void CSRTPCryptoHandlerSRTP::AddAuthTagToPacketL(TUint8* aSrtpPacketPtr)
+ {
+ TUint8* ptr = aSrtpPacketPtr;
+
+ //Step 7, Add authentication tag (in RFC 3711, section 3.3):
+ if (CryptoParams().iSrtpAuthTagLen>0)
+ {
+ ptr += iCurrentPacket->HeaderLength();
+ ptr += iCurrentPacket->PayloadLength();
+ if(Context().MasterKey().MKI()!= KNullDesC8)
+ {
+ ptr += Context().MasterKey().MKI().Length();
+ }
+ TBuf8<16> roc;
+ TBuf8<8> roc_hexed;
+
+ if (!CarryROC())
+ {
+ roc.AppendNumUC(ROC(), EHex);
+ }
+ else
+ {
+ roc.AppendNumUC(iROC, EHex);
+ }
+
+
+ TSRTPUtils::DeHex(roc, roc_hexed);
+ TUint size = roc.Size();
+
+ for (TInt i=0; i<(4-size); i++)
+ {
+ roc_hexed.Append(0x00);
+ }
+ //Copy the authenticatin portion only not with MKI key part
+ TInt len= iCurrentPacket->HeaderLength() + iCurrentPacket->PayloadLength();
+ HBufC8* authPortion = HBufC8::NewMaxLC(len);
+ TUint8* authptr = const_cast<TUint8*>(authPortion->Des().Ptr());
+ Mem::Copy( authptr, aSrtpPacketPtr, len);
+ authPortion->Des().SetLength(len);
+
+ HBufC8* authTag = DoAuthenticationL(*authPortion, roc_hexed);
+ CleanupStack::PopAndDestroy( authPortion );
+ authPortion=NULL;
+
+ if (CarryROC())
+ {
+ TSRTPUtils::Write32( ptr,ROC());
+ ptr+= KSRTPROCLength4;
+ }
+ if (authTag)
+ {
+ Mem::Copy( ptr, authTag->Ptr(), authTag->Length());
+ }
+ delete authTag;
+ authTag=NULL;
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CSRTPCryptoHandlerSRTP::DoAuthenticationL
+//
+// ---------------------------------------------------------------------------
+//
+HBufC8* CSRTPCryptoHandlerSRTP::DoAuthenticationL(const TDesC8& aAuthenticatedArea,
+ const TDesC8& aRoc)
+ {
+ // calculate auth tag from the authenticated area..
+ TUint authtaglen= CryptoParams().iSrtpAuthTagLen;
+ // Note that RCCm3 work as Auth Null so taglen does not matter to RTP/RTCP
+ if (aRoc.Length() &&
+ (CryptoParams().iSrtpAuthAlg ==EAuthRCCm1 ||
+ CryptoParams().iSrtpAuthAlg == EAuthRCCm2 ))
+ {
+ authtaglen-= KSRTPAuthTagLength32 ;
+ }
+ if ((!aRoc.Length()) &&
+ ( CryptoParams().iSrtpAuthAlg != EAuthNull &&
+ CryptoParams().iSrtpAuthAlg != EAuthHMAC_SHA1))
+ {
+ //This is for RTCP if using RCC mode because currently handler sharing
+ //the same context
+ authtaglen=KSRTPAuthTagDefaultLength;
+ }
+ return iAuthenticator->AuthenticateL(authtaglen,
+ *iSessionAuthKey,
+ aAuthenticatedArea,
+ aRoc);
+ }
+
+// ---------------------------------------------------------------------------
+// CSRTPCryptoHandlerSRTP::UpdateROC()
+// ---------------------------------------------------------------------------
+//
+void CSRTPCryptoHandlerSRTP::UpdateROC()
+ {
+ // conditional update of ROC at sender's side
+
+ TReal remainder;
+ Math::Mod(remainder, iCurrentPacket->SequenceNumber(), 0x10000-1);
+
+ // update ROC when SEQ wraps 2^16,
+ // with following exception:
+ // when SEQ is 0, MOD result is also 0,
+ // but we want remainder to be 0
+ // only when SEQ == 65535
+ if (remainder == 0.0 && iCurrentPacket->SequenceNumber() != 0)
+ {
+ SetROC(ROC()+1);
+ }
+ //Add number of packets sending
+ iNumPackets++;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CSRTPCryptoHandlerSRTP::DeriveSessionKeysL()
+// ---------------------------------------------------------------------------
+//
+void CSRTPCryptoHandlerSRTP::DeriveSessionKeysL()
+ {
+ SRTP_DEBUG_DETAIL( "CSRTPCryptoHandlerSRTP::DeriveSessionKeysL() Entry " );
+
+ TBuf8<100> sessionKey_X;
+
+ DeleteSessionKeys();
+
+ TUint64 r = TSRTPUtils::Cnt_r(iCurrentPacket->PacketIndex(),
+ CryptoParams().iSrtpKeyDervRate);
+
+ sessionKey_X.SetLength(100);
+
+ // session encryption key derivation :
+ sessionKey_X.FillZ();
+ // first count X value for the session encryption key
+ // note that the output length is determined by master salt
+ Count_X(r, KSRTPEncryptionLabel, KSRTPIndexLength, sessionKey_X);
+ // then add possible padding bits,
+ // and call the current PRF_n function (AESCM)
+ iSessionEncrKey = iKeyDeriver->PRF_128BitL(Context().MasterKey().EncrKeyLength(),
+ Context().MasterKey().MasterKey(),
+ sessionKey_X);
+
+ SRTP_DEBUG_DETAIL( "iSessionEncrKey as CipherKey" );
+
+ SRTP_DEBUG_PACKET( *iSessionEncrKey );
+
+ // note that the result is already truncated to the user defined size by PRF function
+
+ // session authentication key derivation :
+ sessionKey_X.FillZ();
+ // first count X value for the session authentication key
+ // note that the output length is determined by master salt
+ Count_X(r, KSRTPAuthenticationLabel, KSRTPIndexLength, sessionKey_X);
+ // then add possible padding bits,
+ // and call the current PRF_n function (AESCM)
+ iSessionAuthKey = iKeyDeriver->PRF_128BitL(Context().MasterKey().AuthKeyLength(),
+ Context().MasterKey().MasterKey(),
+ sessionKey_X);
+ //iSessionAuthKey->Des().SetLength(Context()->MasterKey().AuthKeyLength());
+
+ SRTP_DEBUG_DETAIL( "iSessionAuthKey" );
+ SRTP_DEBUG_PACKET( *iSessionAuthKey );
+ // note that the result is already truncated to the user defined size by PRF function
+
+ // session salting key derivation :
+ sessionKey_X.FillZ();
+ // first count X value for the session salting key
+ // note that the output length is determined by master salt
+ Count_X(r, KSRTPSaltingLabel, KSRTPIndexLength, sessionKey_X);
+ // then add possible padding bits,
+ // and call the current PRF_n function (AESCM)
+ iSessionSaltKey = iKeyDeriver->PRF_128BitL(Context().MasterSalt().SaltLength(),
+ Context().MasterKey().MasterKey(),
+ sessionKey_X);
+ SRTP_DEBUG_DETAIL( "iSessionSaltKey" );
+ SRTP_DEBUG_PACKET( *iSessionSaltKey );
+
+ // note that the result is already truncated to the user defined size by PRF function
+
+ iMasterDataUpdated = EFalse;
+ }
+
+
+// ---------------------------------------------------------------------------
+// void CSRTPCryptoHandlerSRTP::ReplayProtectionL()
+// ---------------------------------------------------------------------------
+//
+void CSRTPCryptoHandlerSRTP::ReplayProtectionL()
+ {
+ //Index estamation
+ if ( CryptoParams().iSrtpReplayProtection )
+ {
+ TInt delta =0;
+ delta= (iCurrentPacket->PacketIndex()) - iPktIndex; //set as 0
+
+ //Index check
+ User::LeaveIfError (ReplayCheck(delta));
+ //if the index is inside the replay window and index does not appear in rdb
+ //then Index add after authentication passed
+ iReplayIndexDelta= delta;
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// TInt CSRTPCryptoHandlerSRTP::AddReplayIndex()
+// ---------------------------------------------------------------------------
+//
+void
+CSRTPCryptoHandlerSRTP::AddReplayIndex()
+ {
+ if ( CryptoParams().iSrtpReplayProtection )
+ {
+
+ if (iReplayIndexDelta > 0)
+ {
+ /* shift forward by delta */
+ //iPktIndex += iReplayIndexDelta;
+ iPktIndex = iCurrentPacket->PacketIndex();
+ }
+ else
+ {
+ /* delta is in window, so flip bit in bitmap */
+ /* mark as seen */
+ TInt diff= -(iReplayIndexDelta);
+ iBitmap |= ((TUint64)1 << diff);
+ }
+ }
+ /* note that we need not consider the case that delta == 0 */
+ iNumPackets++;
+ }
+
+// ---------------------------------------------------------------------------
+// TBool CSRTPCryptoHandlerSRTP::CarryROC
+// ---------------------------------------------------------------------------
+//
+TBool CSRTPCryptoHandlerSRTP::CarryROC()
+ {
+ if ( CryptoParams().iSrtpAuthAlg == EAuthRCCm1 ||
+ CryptoParams().iSrtpAuthAlg == EAuthRCCm2 ||
+ CryptoParams().iSrtpAuthAlg == EAuthRCCm3 )
+ {
+ TReal remainder;
+ // SEQ%R
+ Math::Mod( remainder, iCurrentPacket->SequenceNumber(),
+ CryptoParams().iROCTransRate);
+ //SEQ%R=0
+ if ( !remainder )
+ return ETrue;
+ //SEQ%R!=0
+ return EFalse;
+ }
+ return EFalse;
+ }
+
+// ---------------------------------------------------------------------------
+// TInt64 CSRTPCryptoHandlerSRTP::CountSndIndxbySndROC
+// ---------------------------------------------------------------------------
+//
+TInt64 CSRTPCryptoHandlerSRTP::CountSndIndxbySndROC()
+ {
+ //This is called when receiving
+ //i = 2^16 * ROC + SEQ.
+
+ TInt64 indx = 65535 * ( iCurrentPacket->GetSenderROC() ) +
+ iCurrentPacket->SequenceNumber();
+
+ return indx;
+ }
+
+// ---------------------------------------------------------------------------
+// TBool CSRTPCryptoHandlerSRTP::IfAddAuthTag()
+// ---------------------------------------------------------------------------
+//
+TBool CSRTPCryptoHandlerSRTP::IfAddAuthTag()
+ {
+ if (( CryptoParams().iSrtpAuthAlg== EAuthRCCm1 &&
+ !CarryROC() ) || CryptoParams().iSrtpAuthAlg == EAuthNull
+ )
+ {
+ return EFalse;
+ }
+ return ETrue;
+ }
+