multimediacommsengine/mmcesrv/mmcemediamanager/src/mcesecuredesstream.cpp
changeset 0 1bce908db942
child 3 513a8b745b2f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/multimediacommsengine/mmcesrv/mmcemediamanager/src/mcesecuredesstream.cpp	Tue Feb 02 01:04:58 2010 +0200
@@ -0,0 +1,1901 @@
+/*
+* Copyright (c) 2002-2007 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:    Provides services for SDP Security Descriptions.
+*
+*/
+
+
+
+
+// INCLUDE FILES
+#include    "mcesecuredesstream.h"
+#include	"mcemmlogs.h"
+#include    <tconvbase64.h> // TImCodecB64
+#include    <random.h> 
+#include    <e32math.h>
+#include 	<sdpdocument.h>
+#include    <sdpcodecstringconstants.h>
+#include    <sdpcodecstringpool.h>
+#include    <sdpmediafield.h>
+#include    <sdpfmtattributefield.h>
+#include    <sdpattributefield.h>
+#include    <mmccsrtpmasterkey.h>
+#include    <mmccsrtpmastersalt.h>
+#include 	<mmccsecureinterface.h>
+#include 	"mcesecuresession.h"
+#include 	"mcecomsession.h"
+#include 	"mcecommediastream.h"
+#include 	"mcesip.h"
+#define MSG_IGNORE_RETURN( )\
+    if( iGnoreSdpMsg ){ iSecureSession.RemoveSecureCrypto(); return; }
+        
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CMceSecureDesStream::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CMceSecureDesStream::ConstructL(CSdpMediaField& aMediaField)
+    {
+   	iCryptoOuts = new ( ELeave ) CArrayFixFlat< TMceSecureCryptoInfo >( KCryptoGranularity );
+    iCryptoIns = new ( ELeave ) CArrayFixFlat< TMceSecureCryptoInfo >( KCryptoGranularity );
+
+    iMediaField=aMediaField.CloneL();
+    }
+
+// -----------------------------------------------------------------------------
+// CMceSecureDesStream::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CMceSecureDesStream* CMceSecureDesStream::NewL( CMceSecureMediaSession& aSecureSession,
+												CSdpMediaField& aMediaField,
+											CMccSecureInterface& aSecureInterface,
+											CMceComMediaStream& aMediaStream)
+    {
+    CMceSecureDesStream* self = new (ELeave) CMceSecureDesStream(aSecureSession,
+    															aSecureInterface,
+    															aMediaStream);
+    CleanupStack::PushL( self );
+    self->ConstructL(aMediaField);
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CMceSecureDesStream::CMceSecureDesStream
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CMceSecureDesStream::CMceSecureDesStream(	CMceSecureMediaSession& aSecureSession,
+											CMccSecureInterface& aSecureInterface,
+        									CMceComMediaStream& aMediaStream
+        									):
+	
+	iSecureSession(aSecureSession),
+	iSecInf(aSecureInterface),
+	iMediaStream(aMediaStream),
+	iIsSAVP(ETrue),
+	iWaitingBinding(EFalse),
+	iCryptoContextOutId(0),
+	iCryptoContextInId(0),
+	iOldLocalMediaPort(0)
+	{
+	
+    }
+
+// -----------------------------------------------------------------------------
+// CMceSecureDesStream::CMceSecureDesStream
+// Destructor
+// -----------------------------------------------------------------------------
+//
+CMceSecureDesStream::~CMceSecureDesStream()
+    {
+    if(iCryptoOuts!=NULL)
+        {
+    	if ( iCryptoOuts->Count() )
+    		{
+    		iCryptoOuts->Reset();
+    		}
+        }
+    if(iCryptoIns!=NULL)
+        {
+	    if ( iCryptoIns->Count() )
+    		{
+    		iCryptoIns->Reset();
+    		}
+        }
+    delete iCryptoOuts;
+    delete iCryptoIns;
+    iCryptoOut.iMasterKeys.Close();
+    iCryptoIn.iMasterKeys.Close();
+    iCryptoOut.iSaltKeys.Close();
+    iCryptoIn.iSaltKeys.Close();
+    iCryptoOut.iEncodedKeys.Close();
+    iCryptoIn.iEncodedKeys.Close();
+   	iCryptoOut.CryptoDestruct();
+   	iCryptoIn.CryptoDestruct();
+   	delete iMediaField;
+   	delete iMKIBuf;
+    }
+    
+
+// -----------------------------------------------------------------------------
+// CMceSecureDesStream::GenerateRandomKeys
+// Generates security keys
+// -----------------------------------------------------------------------------
+//
+void CMceSecureDesStream::GenerateRandomKeys( TMceSecureCryptoInfo& aCrypto )
+    {
+    MCEMM_DEBUG("CMceSecureDesStream::GenerateRandomKeys, Entry ")
+    
+    MCEMM_DEBUG("Generate Keys")
+	TBuf8< KMasterKeyAndSaltLength > random;
+	RandomString( random );
+
+	// Encode random string
+	TBuf8< KEncodedStringLength > encoded;
+	Base64Encode( random, encoded );
+	aCrypto.ResetKeys();
+	aCrypto.iEncodedKey = encoded;
+	//added generated masterkey
+	aCrypto.iSetMasterKey = random.Mid( 0, KMasterKeyLength );
+
+	//added generated salt key
+	aCrypto.iSetSaltKey = random.Mid( KMasterKeyLength );
+	aCrypto.iKeysCreated = ETrue;
+	random.Zero();
+	
+    MCEMM_DEBUG("CMceSecureDesStream::GenerateRandomKeys, Exit ")   
+    }
+    
+// -----------------------------------------------------------------------------
+// CMceSecureDesStream::EncodeSecureSdpL()
+// Generates security key to SDP offer/Answer.
+// -----------------------------------------------------------------------------
+//
+void CMceSecureDesStream::EncodeSecureSdpL( 
+    CSdpMediaField& aMediaField,
+    TBool aIsAnswer )
+    {
+   	MCEMM_DEBUG("CMceSecureDesStream::EncodeSecureSdpL(), Entry ")
+    
+    iGnoreSdpMsg = EFalse;
+    
+    const TUint8 KCryptoTag = 1;
+    
+   	TInt authCount = ClientCrytoCount();
+   	authCount = authCount ? authCount : KAuthTagLengthTypeCount;
+   	MCEMM_DEBUG_DVALUE("iKeyNeedUpdated", iSecureSession.iKeyNeedUpdated )
+  	TBuf8< KCryptoLineMaxLength > cryptoLine;
+  	
+    if ( aIsAnswer ) 
+    	{
+    	MCEMM_DEBUG("Encode Secure Answer")
+		if ( iSecureSession.iCryptoContextUpdate )
+		    {
+		    iCryptoOuts->Reset();
+		    iSecureSession.iCryptoContextUpdate = EFalse;	
+		    }
+
+    	iCryptoOut.iTag = KCryptoTag;
+       	GenerateCryptoLineL( cryptoLine, iCryptoOut.iTag, aIsAnswer );
+
+    	if ( !iGnoreSdpMsg && 
+    	     KCryptoAttributeValueMinLength <= cryptoLine.Length() &&
+             iCryptoOut.iEncodedKey.Length() > 0 )
+            {
+    		AppendCryptoAttributeL(	cryptoLine, aMediaField );    
+    		}
+        cryptoLine.Zero();                        
+    	}
+    else if ( iSecureSession.iKeyNeedUpdated && 
+              iSecureSession.iCryptoContextUpdate )
+    	{
+    	MCEMM_DEBUG("Encode Secure Offer; Crypto Update Required")		
+    	iSecureSession.iCryptoContextUpdate = EFalse;
+    	TInt tagIndex = 0;
+    	TInt tag;
+    	iCryptoOuts->Reset();
+   		for ( tagIndex = 0; tagIndex < authCount; tagIndex++ )
+			{
+			tag = tagIndex+1;
+			GenerateCryptoLineL( cryptoLine, tag, aIsAnswer );	
+
+		    if ( !iGnoreSdpMsg && 
+		         KCryptoAttributeValueMinLength <= cryptoLine.Length() )
+		        {
+		        AppendCryptoAttributeL(	cryptoLine, aMediaField );  
+		        }
+			cryptoLine.Zero();
+			}
+    	}     	
+   	else 
+   		{ 
+   		MCEMM_DEBUG("Encode Updated Offer; No Crypto Update Required")	
+   		iCryptoOut.iTag = KCryptoTag;
+       	GenerateCryptoLineL( cryptoLine, iCryptoOut.iTag, aIsAnswer );	
+	
+		if ( !iGnoreSdpMsg && 
+		      KCryptoAttributeValueMinLength <= cryptoLine.Length() &&
+              iCryptoOut.iEncodedKey.Length() > 0 )
+            {
+		    AppendCryptoAttributeL(	cryptoLine, aMediaField );    
+		    }	
+       	cryptoLine.Zero();                        
+   		}       	    
+    	
+    if ( !iGnoreSdpMsg )
+    	{
+    	SetSecureProtocolL( aMediaField );
+    	iCryptoUpdateNeeded = 
+    	    iCryptoUpdateNeeded ? EFalse : iCryptoUpdateNeeded;
+    	MCEMM_DEBUG("Encode Secure Crypto Succeeded")
+    	}
+   	
+   	if ( !aMediaField.IsValid() )
+   	    {
+   	    User::Leave( KErrCorrupt );
+   	    }
+    
+    MCEMM_DEBUG("CMceSecureDesStream::EncodeSecureSdpL(), Exit")	
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMceSecureDesStream::StoreKeys()
+// Store security keys
+// -----------------------------------------------------------------------------
+//
+void CMceSecureDesStream::StoreKeys( TDesC8& aData )
+    {
+    //DecodeAnswer or Offer
+    //multiple tag
+    	/*a=crypto:1 AES_CM_128_HMAC_SHA1_80
+       inline:WVNfX19zZW1jdGwgKCkgewkyMjA7fQp9CnVubGVz|2^20|1:4
+       FEC_ORDER=FEC_SRTP
+      a=crypto:2 F8_128_HMAC_SHA1_80
+       inline:MTIzNDU2Nzg5QUJDREUwMTIzNDU2Nzg5QUJjZGVm|2^20|1:4;
+       inline:QUJjZGVmMTIzNDU2Nzg5QUJDREUwMTIzNDU2Nzg5|2^20|2:4
+       FEC_ORDER=FEC_SRTP
+	*/
+    
+    TBuf8 < KMasterKeyAndSaltLength > masterKeyAndSalt;
+    Base64Decode( aData, masterKeyAndSalt );
+    
+	//it should be validate already so it is our prefered key
+	iCryptoIn.iEncodedKey = aData;
+	iCryptoIn.iSetMasterKey = masterKeyAndSalt.Mid( 0, KMasterKeyLength );
+	iCryptoIn.iSetSaltKey = masterKeyAndSalt.Mid( KMasterKeyLength );
+	iCryptoIn.iKeysCreated = ETrue;
+    }
+        
+
+// -----------------------------------------------------------------------------
+// CMceSecureDesStream::DecodeSecureSdpL()
+// Decode Secure Sdp Offer / Update
+// -----------------------------------------------------------------------------
+//
+void CMceSecureDesStream::DecodeSecureSdpL( CSdpMediaField& aMediaField )
+    {
+    MCEMM_DEBUG("CMceSecureDesStream::DecodeSecureSdpL(), Entry")
+    MCEMM_DEBUG_DVALUE("iKeyNeedUpdated", iSecureSession.iKeyNeedUpdated )
+    iGnoreSdpMsg = EFalse;
+    CSdpAttributeField* attributeField = NULL;    
+    
+	RPointerArray< CSdpAttributeField > attrList =  
+                aMediaField.AttributeFields();
+    TInt attrCount = attrList.Count();
+    TInt cryptoAttrCount =
+        iSecureSession.SdpCryptoAttributeCount( aMediaField );
+    iCryptoIns->Reset();
+    RemoveClientCrypto();
+
+    for (TInt j = 0; j < attrCount; j++ )
+        {
+       	attributeField = attrList[ j ];
+
+        RStringF attribute = attributeField->Attribute();
+
+        // check if attribute is 'crypto'
+        if ( attribute.DesC().Match(KCrypto)!= KErrNotFound )
+            {
+           	--cryptoAttrCount;
+           	//check how many inline
+           	ValidateOfferByAnswerL( attributeField->Value() );
+           	if ( !cryptoAttrCount && iGnoreSdpMsg && !iCryptoIns->Count() )
+           		{
+           		//Last attribute ignored and no valid attributes found
+           		User::Leave ( KErrArgument );
+           		}
+		    if ( !cryptoAttrCount )
+		        {
+		        break;
+		        }
+		    }
+        }
+	if ( iCryptoIns->Count() )
+	    {
+	    //acceptable crypto suite found, not to be ignored
+	    iGnoreSdpMsg = EFalse;
+	    }
+    if ( !iGnoreSdpMsg && SetMediaProfile ( aMediaField ) == KErrNone )
+    	{
+    	SetMultipleClientCryptoL( *iCryptoIns );
+    	MCEMM_DEBUG(" Set Multiple Client Cryptoto")
+    	User::LeaveIfError ( CountCryptoInOffer( aMediaField ) );
+    	Session().iIsSecureSession =  !iGnoreSdpMsg ? ETrue : EFalse;
+    	}
+    MCEMM_DEBUG("CMceSecureDesStream::DecodeSecureSdpL(), Exit")      
+    MSG_IGNORE_RETURN()
+    }
+
+// -----------------------------------------------------------------------------
+// CMceSecureDesStream::DecodeSecureSdpAnswerL()
+// Decode Secure Sdp Offer/Answer
+// -----------------------------------------------------------------------------
+//
+void CMceSecureDesStream::DecodeSecureSdpAnswerL( CSdpMediaField& aMediaField)
+    {
+    MCEMM_DEBUG("CMceSecureDesStream::DecodeSecureSdpAnswerL(), Entry")  
+    MCEMM_DEBUG_DVALUE("iKeyNeedUpdated", iSecureSession.iKeyNeedUpdated)
+    TInt cryptoCount = iSecureSession.SdpCryptoAttributeCount(aMediaField);
+    
+    if ( cryptoCount != KCryptoAnswerCount )
+    	{
+    	User::Leave( KErrArgument );
+    	}
+	
+	CSdpAttributeField* attr = MediaFieldAttrMatch( aMediaField, KCrypto);    
+    
+    // check if attribute is 'crypto' 
+    if ( attr )
+        {
+        ValidateAnswerByOfferL( attr->Value() );
+        
+    	if ( !iGnoreSdpMsg  && SetMediaProfile ( aMediaField ) == KErrNone )
+			{
+			if ( iSecureSession.iKeyNeedUpdated )
+				{
+				Session().iIsSecureSession = ETrue;
+				
+				Session().iClientCryptoSuites.Reset();
+				
+				SetClientCryptoL( iCryptoIn );
+				}
+			if ( iSecureSession.iLSReadyToBind )
+				{
+				SetCryptoContextL();
+				}
+			MSG_IGNORE_RETURN()
+			if ( !iCryptoIn.iCryptoSuite.Length() )
+				{
+				User::Leave( KErrArgument );
+				}
+			MCEMM_DEBUG("Set Crypto Context succeed")  	
+			
+			}
+	
+		else
+			{
+			MCEMM_DEBUG("No suitable crypto or malformate crypto session reject")      
+    
+			User::Leave( KErrArgument );
+			}
+		}
+    MCEMM_DEBUG("CMceSecureDesStream::DecodeSecureSdpAnswerL(), Exit")    
+  	MSG_IGNORE_RETURN()
+    }
+
+// -----------------------------------------------------------------------------
+// CMceSecureDesStream::RemvoeSecureSdpL
+// Remove Secure Sdp Offer/Answer
+// -----------------------------------------------------------------------------
+//
+void CMceSecureDesStream::RemvoeSecureSdp(CSdpMediaField& aMediaField)
+	{
+	MCEMM_DEBUG("CMceSecureDesStream::RemvoeSecureSdpL(), Entry") 
+    
+    RStringF mediaType = aMediaField.Media();
+    
+    RPointerArray< CSdpAttributeField> attrList =  
+                    aMediaField.AttributeFields();
+	
+	TInt attrCount = attrList.Count();
+    
+    for (TInt index = attrCount; index >0 ; index-- )
+        {
+        CSdpAttributeField* attributeField = attrList[index-1];
+        RStringF attribute = attributeField->Attribute();
+                 // check if attribute is 'crypto' 
+        if ( KErrNotFound != attribute.DesC().Find( KCrypto ) )
+            {   
+            TInt removing =aMediaField.AttributeFields().Find(attributeField);
+            aMediaField.AttributeFields().Remove(removing);
+            delete attributeField;
+            attributeField=NULL;
+            }
+        }
+	mediaType.Close();
+	MCEMM_DEBUG("CMceSecureDesStream::RemvoeSecureSdpL(), Exit")     
+    
+	}
+
+// -----------------------------------------------------------------------------
+// CMceSecureDesStream::SetCryptoContext( )
+// Sets crypto context to MCC
+// -----------------------------------------------------------------------------
+//
+void CMceSecureDesStream::SetCryptoContextL( )
+    {
+    MCEMM_DEBUG("SetCryptoContext(), Entry")   
+    TBool storedIgnoreSdpMsg = EFalse;
+    //Check state first if the crypto has been set
+    if ( !iCryptoIn.iIfCryptoContextIdSet && 
+    	!iCryptoOut.iIfCryptoContextIdSet &&
+    	iCryptoIn.iSetMasterKey.Length() && 
+    	iCryptoIn.iSetSaltKey.Length() &&
+    	iCryptoOut.iSetMasterKey.Length() &&
+    	iCryptoOut.iSetSaltKey.Length() )
+    	{
+    	MCEMM_DEBUG("First Time Bind")
+    	CreateCryptoContextL( iCryptoIn );
+    	CreateCryptoContextL( iCryptoOut ); 
+    	MCEMM_DEBUG_DVALUE( "iCryptoContextOutId", iCryptoIn.iCryptoContextId )
+		MCEMM_DEBUG_DVALUE( "iCryptoContextInId", iCryptoOut.iCryptoContextId )
+
+    	iCryptoOuts->Reset();
+    	
+    
+    	}
+    else if ( iCryptoIn.iSetMasterKey.Length() && 
+    		iCryptoIn.iSetSaltKey.Length() &&
+    	  	iCryptoOut.iSetMasterKey.Length() &&
+    	 	iCryptoOut.iSetSaltKey.Length() )
+		{
+		MCEMM_DEBUG("Bind has done before so this is for updated")  
+		if ( iCryptoContextInId != 0  && iCryptoContextOutId != 0 )
+			{
+			iCryptoIn.iCryptoContextId = iCryptoContextInId;
+			iCryptoOut.iCryptoContextId =  iCryptoContextOutId;
+			}
+		MCEMM_DEBUG_DVALUE( "Updated iCryptoContextOutId", iCryptoIn.iCryptoContextId )
+		MCEMM_DEBUG_DVALUE( "Updated iCryptoContextInId", iCryptoOut.iCryptoContextId )
+    	if ( iSecureSession.iKeyNeedUpdated )
+    		{
+    		UpdateCryptoContextL( iCryptoIn ); 
+    		storedIgnoreSdpMsg = iGnoreSdpMsg;
+    		UpdateCryptoContextL( iCryptoOut ); 
+    		iGnoreSdpMsg = iGnoreSdpMsg && storedIgnoreSdpMsg;
+    		}
+    	else
+    		{
+    		iWaitingBinding = ETrue;	
+    		}
+    	iCryptoOuts->Reset(); 
+    	}
+    iGnoreSdpMsg = (iCryptoIn.iIfCryptoContextIdSet && 
+    				iCryptoOut.iIfCryptoContextIdSet ) &&
+    				!iGnoreSdpMsg ? EFalse : ETrue;		
+    if ( iWaitingBinding )
+    	{
+    	iSecureSession.BindStreamCrypto();
+    	}
+    	
+    MCEMM_DEBUG("SetCryptoContext(), Exit")
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMceSecureDesStream::CreateCryptoContextL()
+// 
+// -----------------------------------------------------------------------------
+//     
+void CMceSecureDesStream::CreateCryptoContextL( TMceSecureCryptoInfo& aCrypto )
+    {
+    MCEMM_DEBUG("CMceSecureDesStream::CreateCryptoContextL Entry")
+    // if  ESrtpNullAlg == iEncAlgms Fallback to RTP, set NULL policy
+    // Create phony master and salt from local values 
+    // since remote keys not available
+    iWaitingBinding = EFalse;
+    TInt err(KErrNone);
+    FormMKIL(aCrypto);
+    TBuf8<KMKILength> mki;
+    mki.Copy( KNullDesC8 );
+   	TMccSrtpMasterKey masterKey(aCrypto.iSetMasterKey, mki); 
+   
+    if (aCrypto.iMKIUsed && iMKIBuf)
+    	{
+    	masterKey.iMKI.Copy(iMKIBuf->Des()); 
+    	masterKey.iMKI.SetLength(aCrypto.iMKILength);
+    	}
+    TMccSrtpMasterSalt saltKey( aCrypto.iSetSaltKey);
+	TMccSrtpCryptoParams params;
+    
+    params.iSrtpEncAlg = aCrypto.iEncAlgms; 
+    params.iSrtcpEncAlg = aCrypto.iEncAlgms; 
+    params.iSrtpAuthAlg = aCrypto.iAuthAlgms; 
+    params.iSrtcpAuthAlg = aCrypto.iAuthAlgms; 
+    params.iSrtpAuthTagLen = aCrypto.iTagLen;
+    params.iSrtcpAuthTagLen = aCrypto.iTagLen;
+    if ( aCrypto.iMKLifeTime )
+    	{
+    	params.iMasterKeysLifeTime = aCrypto.iMKLifeTime;
+    	}
+    
+    
+    TMccSrtpMasterKeyPckg masterKeyPckg(masterKey); 
+    const TDesC8& masterKeyDes = masterKeyPckg;
+    
+    TMccSrtpMasterSaltPckg masterSaltPckg( saltKey );  
+    const TDesC8& saltKeyDes = masterSaltPckg;                      
+   	
+   	TMccSrtpCryptoParamsPckg cryptoParamsPckg ( params );
+   	const TDesC8& cryptoParamsDes = cryptoParamsPckg;   
+   	//remember to handle and pass the keys
+   	err = iSecInf.CreateContext(masterKeyDes, saltKeyDes,
+	                                 aCrypto.iCryptoContextId, cryptoParamsDes );  
+	if ( err == KErrNone )
+		{
+		MCEMM_DEBUG("Create Crypto Succeed")
+		aCrypto.iIfCryptoContextIdSet = ETrue;
+		iWaitingBinding = ETrue;
+		}
+	
+	MCEMM_DEBUG_DVALUE( "createContext error", err )		
+	MCEMM_DEBUG("CMceSecureDesStream::CreateCryptoContextL Exit")
+    }
+
+// -----------------------------------------------------------------------------
+// CMceSecureDesStream::UpdateCryptoContext()
+// 
+// -----------------------------------------------------------------------------
+//     
+void CMceSecureDesStream::UpdateCryptoContextL( TMceSecureCryptoInfo& aCrypto )
+    {
+    MCEMM_DEBUG("CMceSecureDesStream::UpdateCryptoContextL Entry")	
+    TInt err(KErrNone);
+    iWaitingBinding = EFalse;
+   
+    aCrypto.iIfBinded = EFalse;
+    FormMKIL(aCrypto);
+    TBuf8<KMKILength> mki;
+    mki.Copy( KNullDesC8 );
+   	TMccSrtpMasterKey masterKey( aCrypto.iSetMasterKey, mki ); 
+   
+    if ( aCrypto.iMKIUsed && iMKIBuf )
+    	{
+    	masterKey.iMKI.Copy(iMKIBuf->Des()); 
+    	}
+    TMccSrtpMasterSalt saltKey( aCrypto.iSetSaltKey);
+	TMccSrtpCryptoParams params;
+    
+    params.iSrtpEncAlg = aCrypto.iEncAlgms; 
+    params.iSrtcpEncAlg = aCrypto.iEncAlgms; 
+    params.iSrtpAuthAlg = aCrypto.iAuthAlgms; 
+    params.iSrtcpAuthAlg = aCrypto.iAuthAlgms; 
+    params.iSrtpAuthTagLen = aCrypto.iTagLen;
+    params.iSrtcpAuthTagLen = aCrypto.iTagLen;
+    if ( aCrypto.iMKLifeTime )
+    	{
+    	params.iMasterKeysLifeTime = aCrypto.iMKLifeTime;
+    	}
+    
+    
+    TMccSrtpMasterKeyPckg masterKeyPckg(masterKey); 
+    const TDesC8& masterKeyDes = masterKeyPckg;
+    
+    TMccSrtpMasterSaltPckg masterSaltPckg( saltKey );  
+    const TDesC8& saltKeyDes = masterSaltPckg;                      
+   	
+   	TMccSrtpCryptoParamsPckg cryptoParamsPckg ( params );
+   	const TDesC8& cryptoParamsDes = cryptoParamsPckg;  
+
+	err = iSecInf.UpdateContext( masterKeyDes, saltKeyDes,
+                             aCrypto.iCryptoContextId, cryptoParamsDes );
+
+	if ( err==KErrNone)
+		{
+		MCEMM_DEBUG("Updated Crypto Succeed")
+		aCrypto.iIfCryptoContextIdSet = ETrue;
+		iWaitingBinding = ETrue;
+		}
+	//This is to check if the crypto Id after update can be found
+	// if not found, context Id maybe wrong	
+	iGnoreSdpMsg = err == KErrNotFound ? ETrue : EFalse;	
+	MCEMM_DEBUG_DVALUE( "UpdateContext error", err )
+	MCEMM_DEBUG("CMceSecureDesStream::UpdateCryptoContextL Exit")	
+	}
+
+// -----------------------------------------------------------------------------
+// CMceSecureDesStream::FormMKIL()
+// 
+// -----------------------------------------------------------------------------
+//     
+void CMceSecureDesStream::FormMKIL( TMceSecureCryptoInfo& aCrypto )
+    {
+    delete iMKIBuf;
+    iMKIBuf=NULL;
+    if ( aCrypto.iMKILength > 0 && 
+         aCrypto.iMKILength%4 == 0 &&
+         aCrypto.iMKIUsed )
+    	{
+    	__ASSERT_ALWAYS( aCrypto.iMKILength <= KMKIMaxLength,
+    	                 User::Leave( KErrOverflow ) );
+    	
+    	iMKIBuf = HBufC8::NewL( aCrypto.iMKILength );
+    	TUint8* mkiData = const_cast<TUint8*>( iMKIBuf->Des().Ptr() );
+    	Mem::FillZ( mkiData, aCrypto.iMKILength );
+    	if (aCrypto.iMKILength > KMKILength)
+    		{
+    		mkiData+= ( aCrypto.iMKILength - KMKILength );
+    		}
+		TUint32 mkiValue=aCrypto.iMKIValue;
+		BigEndian::Put32(mkiData, mkiValue);
+    	mkiData += KMKILength;
+    	iMKIBuf->Des().SetLength( aCrypto.iMKILength );
+    	}
+    
+    }
+// -----------------------------------------------------------------------------
+// CMceSecureDesStream::BindCrypto( )
+// -----------------------------------------------------------------------------
+//
+
+TInt CMceSecureDesStream::BindCrypto( CMceSrvStream& aStream )
+    					
+	{
+	MCEMM_DEBUG("CMceSecureDesStream::BindCrypto(), Entry")				
+	
+	MCEMM_DEBUG_DVALUE("	BindStreamId", aStream.Id() )	
+	MCEMM_DEBUG_DVALUE("	BindLinkId", aStream.LinkId() )	
+	MCEMM_DEBUG_DVALUE("	iCryptoIn.iIfBinded", iCryptoIn.iIfBinded )
+	MCEMM_DEBUG_DVALUE("	iCryptoOut.iIfBinded", iCryptoOut.iIfBinded )
+	
+	TInt err(KErrNotFound);
+	if (iCryptoIn.iEncodedKey.Length() && 
+		iCryptoIn.iIfCryptoContextIdSet &&
+		IS_RECEIVESTREAM(&aStream.Data()) )
+		{
+		MCEMM_DEBUG_DVALUE("	BindContext In Id", iCryptoIn.iCryptoContextId )	
+		MCEMM_DEBUG_DVALUE("	BindSourceId", aStream.Source().Id() )
+	
+		err = iSecInf.Bind( aStream.SessionId(), 
+								aStream.LinkId(),
+								aStream.Id(), 
+								aStream.Source().Id(), 
+								iCryptoIn.iCryptoContextId );	
+		
+		MCEMM_DEBUG_DVALUE("	BindSource result=", err)
+		
+		if ( err == KErrNone )
+			{
+			iCryptoIn.iIfBinded = ETrue;
+			MCEMM_DEBUG("Bind Downlink Source Successful")
+			}
+					
+		}
+
+
+	if (iCryptoOut.iEncodedKey.Length() && 
+		iCryptoOut.iIfCryptoContextIdSet &&
+		IS_SENDSTREAM(&aStream.Data())  )
+		{
+	
+		MCEMM_DEBUG_DVALUE("	BindContext Out Id", iCryptoOut.iCryptoContextId )	
+	    MCEMM_DEBUG_DVALUE("	BindSinkId", aStream.Sink().Id() )
+	
+		err =iSecInf.Bind( aStream.SessionId(), 
+								aStream.LinkId(),
+								aStream.Id(), 
+								aStream.Sink().Id(), 
+								iCryptoOut.iCryptoContextId );	
+		
+		MCEMM_DEBUG_DVALUE("	BindSink result=", err)				
+
+		if (err == KErrNone)
+			{
+			iCryptoOut.iIfBinded=ETrue;
+			MCEMM_DEBUG("	Bind Uplink Sink Successful")
+			}
+		
+		}							
+
+	if (iCryptoIn.iIfBinded && iCryptoOut.iIfBinded)
+		{
+		MCEMM_DEBUG("	Bind Successful for Downlink and Uplink")
+		iWaitingBinding=EFalse;	
+		}
+	err = iWaitingBinding? KErrNotFound : KErrNone;
+		
+	MCEMM_DEBUG("CMceSecureDesStream::BindCrypto(), Exit")			
+	
+	return err;	
+   }
+			
+
+// -----------------------------------------------------------------------------
+// CMceSecureDesStream::Base64Encode
+// Base64 encoding.
+// -----------------------------------------------------------------------------
+//
+void CMceSecureDesStream::Base64Encode( const TDesC8& aData, TDes8& aEncoded )
+    {
+    TBase64 encode;
+    encode.Encode( aData, aEncoded );
+    }
+
+// -----------------------------------------------------------------------------
+// CMceSecureDesStream::Base64Decode
+// Base64 decode.
+// -----------------------------------------------------------------------------
+//
+void CMceSecureDesStream::Base64Decode( const TDesC8& aData, TDes8& aDecoded )
+    {
+    TBase64 decode;
+    decode.Decode( aData, aDecoded );
+    }
+
+// -----------------------------------------------------------------------------
+// CMceSecureDesStream::ValidateSecurityDescriptions
+// Check if security description is valid
+// -----------------------------------------------------------------------------
+//    
+TBool CMceSecureDesStream::ValidateSecurityDescriptions( TDesC8& aData )
+    {
+    TBool valid( ETrue );
+    
+    TBuf8< KCryptoLineMaxLength > masterKeyAndSalt;
+    Base64Decode( aData, masterKeyAndSalt );
+    TInt countChar=0;
+    // Check that encoded string is right sized
+    // Validate length of master key and salt 
+    if ( KEncodedStringLength != aData.Length() || 
+         KMasterKeyAndSaltLength != masterKeyAndSalt.Length() )
+        {
+        return !valid ;
+        }
+          
+    // Validate Base64 Encoding characters
+    TBool charFound( EFalse );
+    for ( TInt i = 0; i < aData.Length(); i++ )
+        {
+        
+        for (TInt j = 0; j < KRandomStringCount; j++ )
+            {
+            if ( aData[i] == KBase64Chars[j] )
+                {
+                charFound = ETrue;
+                countChar++;
+                }
+            }
+        
+        if ( !charFound )
+            {
+            // invalid character has been found
+            valid = EFalse;
+            }
+            
+        charFound = EFalse;
+        }
+    if (countChar!=aData.Length())
+    	{
+    	valid=EFalse; 
+    	}
+    return valid;
+    }
+
+// -----------------------------------------------------------------------------
+// CMceSecureDesStream::RandomString
+// Generates random string
+// -----------------------------------------------------------------------------
+//    
+void CMceSecureDesStream::RandomString( TDes8& aRandom )
+    {
+    TTime time;
+    time.UniversalTime();
+    TInt64 seed = time.Int64();
+    TUint32 random= Math::Random();
+    seed += random;
+    TInt randomNumber(0);
+        
+    for( TInt i = 0; i < aRandom.MaxSize(); i++ )
+        {
+        randomNumber = Math::Rand( seed ) % KRandomStringCount;
+        aRandom.Append( KRandomChars[ randomNumber ] );
+        }
+
+    }
+
+// -----------------------------------------------------------------------------
+// CMceSecureDesStream::GenerateCryptoLineL()
+// Cryptoline creation
+// -----------------------------------------------------------------------------
+//    
+void CMceSecureDesStream::GenerateCryptoLineL( 
+    TDes8& aResult,
+    TInt aCryptoCount,
+    TBool aAnswer )
+    {
+    MCEMM_DEBUG("CMceSecureDesStream::GenerateCryptoLineL Entry")
+    SetClientCryptoL( aCryptoCount );
+    if ( aAnswer ) 
+        {
+        //Compare with crypto In and create cryptoOut
+        MCEMM_DEBUG("GenerateCryptoLineL for Answer")
+        if ( iSecureSession.iKeyNeedUpdated )
+        	{
+       		User::LeaveIfError ( CompareCryptosForAnswer() );
+        	GenerateRandomKeys( iCryptoOut );
+        	MCEMM_DEBUG("GenerateRandomKeys Key is updated")
+        	iOldLocalMediaPort = iMediaStream.iLocalMediaPort;
+        	}
+        else
+        	{
+        	if(iOldLocalMediaPort != iMediaStream.iLocalMediaPort)
+        		{
+        	    GenerateRandomKeys( iCryptoOut );
+        	    MCEMM_DEBUG("GenerateRandomKeys Key is updated when oldport is different from newport")
+        	    iOldLocalMediaPort = iMediaStream.iLocalMediaPort;
+        	    }
+        	}
+        aResult.AppendNum( iCryptoOut.iTag );
+		aResult.Append( KSpace );
+        GenerateCryptoSuiteLineL( aResult, iCryptoOut );
+        MSG_IGNORE_RETURN()
+      	if ( iSecureSession.iLSReadyToBind )
+      		{
+      		SetCryptoContextL();
+      		}
+        MSG_IGNORE_RETURN()
+        }
+	 else
+    	{
+    	MCEMM_DEBUG("GenerateCryptoLineL for Offer")
+    	
+    	if ( iSecureSession.iKeyNeedUpdated )
+    		{
+    		iGnoreSdpMsg = !iCryptoOuts->Count() ? ETrue : EFalse;
+    		iGnoreSdpMsg = aCryptoCount - 1 >= iCryptoOuts->Count() ? ETrue : EFalse;
+    		MSG_IGNORE_RETURN()
+    		TMceSecureCryptoInfo crypto = iCryptoOuts->At( aCryptoCount-1 );
+    		GenerateRandomKeys( crypto );
+    		crypto.iTag = aCryptoCount;
+    		aResult.AppendNum( aCryptoCount );
+			aResult.Append( KSpace );
+			GenerateCryptoSuiteLineL( aResult, crypto );
+			MSG_IGNORE_RETURN()
+			iCryptoOuts->At( aCryptoCount-1 ).Copy( crypto );
+            iOldLocalMediaPort = iMediaStream.iLocalMediaPort;			
+    		}
+		else
+			{
+		    aResult.AppendNum( iCryptoOut.iTag );
+			aResult.Append( KSpace );
+        	GenerateCryptoSuiteLineL( aResult, iCryptoOut );
+			}    		
+    	
+		}
+	MCEMM_DEBUG("CMceSecureDesStream::GenerateCryptoLineL Exit")	
+   	MSG_IGNORE_RETURN()	
+    }
+
+// -----------------------------------------------------------------------------
+// CMceSecureDesStream::GenerateCryptoSuiteLine
+// Cryptoline creation
+// -----------------------------------------------------------------------------
+//    
+void CMceSecureDesStream::GenerateCryptoSuiteLineL( TDes8& aResult, 
+										TMceSecureCryptoInfo& aCrypto )
+    {
+    switch ( aCrypto.iEncAlgms )
+        {
+        case ESrtpEncAES_CM:
+            {
+            if ( aCrypto.iTagLen == KAuthTagLength32 )
+                {
+                aResult.Append( KAES_SHA1_32 );
+                }
+            else
+                {
+                aResult.Append( KAES_SHA1_80 );
+                }
+            break;
+            }
+        default:
+            {
+            iGnoreSdpMsg = ETrue;
+            break;
+            }
+        }
+   
+    MSG_IGNORE_RETURN()
+    aResult.Append( KSpace );
+    aResult.Append( KInline );
+    if (aCrypto.iEncodedKey.Length() > 0)
+    	{
+    	aResult.Append( aCrypto.iEncodedKey );
+    // Append MKI and lifetime if needed, MKI as default
+    	if ( aCrypto.iMKIUsed && aCrypto.iMKI.Length() > 0 )
+        	{
+        	aResult.Append( KSeparator );
+       	 	aResult.Append( aCrypto.iMKI );
+        	}
+        //set default masterkeyLT
+        aCrypto.iMKLifeTime = KDefalutMaterKeysLifeTime;
+    	}
+    else
+    	{
+    	User::Leave( KErrArgument ); 	
+    	}
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMceSecureDesStream::MediaField()
+// Return this MediaField
+// -----------------------------------------------------------------------------
+//	
+CSdpMediaField& CMceSecureDesStream::MediaField()
+	{
+	return *iMediaField;
+	}
+
+// -----------------------------------------------------------------------------
+// CMceSecureDesStream::Codec()
+// Return this related codec
+// -----------------------------------------------------------------------------
+//
+CMceComMediaStream& CMceSecureDesStream::MediaStream() const
+    {
+    return iMediaStream;
+    }
+    
+
+// -----------------------------------------------------------------------------
+// CMceSecureDesStream::CompareContextId
+// Return TBool
+// -----------------------------------------------------------------------------
+//    
+TBool CMceSecureDesStream::CompareContextId( TUint32 aContextId )
+	{
+	TBool equal = EFalse;
+	if (aContextId == iCryptoIn.iCryptoContextId ||
+			aContextId == iCryptoOut.iCryptoContextId)
+		{
+		equal = ETrue;
+		}
+	return equal;	
+	}	
+	
+// -----------------------------------------------------------------------------
+// CMceSecureDesStream::DecodeMKLifeTime
+// 
+// -----------------------------------------------------------------------------
+//    
+void CMceSecureDesStream::DecodeMKLifeTimeL(const TDesC8& aSecDec,
+											TMceSecureCryptoInfo& aCrypto )
+	{
+	/*
+	RFC 4568 6.1         
+	*/
+	// aSecDec is CSdpAttributeField value
+	//By Type we know it is offer or answer so we know crypto In/Out should be
+	// assign
+	//Note that no matter how many inline the MKI will be same in the one cryptosute
+	_LIT8( KMatchMKLTPowerTwo,"*|*^*|*:*" );
+	_LIT8( KMatchMKLTDigit,"*|*|*:*" );
+    _LIT8 ( KMatchMKLT, "*|2^*");
+    _LIT8 ( KOnlyMKI, "*|*:*");
+   
+    TChar separator = '|';
+    const TUint8 KMatchMKLToffset = 3;
+    const TReal mkiPowerBase = 2;
+    TBool found=EFalse;
+	TInt totalLen = aSecDec.Length();
+	TUint32 unitMKLT = 0;
+	TPtrC8 mkLT( NULL,0 );
+	TPtrC8 sec( NULL,0 );
+	TReal powerResult = 0;
+	TInt posSemi= aSecDec.Find( KSemiColon );
+	sec.Set( aSecDec.Ptr(), aSecDec.Length() );
+	if ( posSemi != KErrNotFound )
+		{
+		sec.Set(aSecDec.Left(posSemi).Ptr(), posSemi);
+		}
+	//sec is now only before semicolon
+	// make sure if there is MKLT
+	if ( sec.Match ( KMatchMKLTPowerTwo ) != KErrNotFound ) 
+    	{
+        
+        TInt firstSep = SearchChar( sec, separator, 0 );
+        TInt sndSep = SearchChar( sec, separator, firstSep );
+    	mkLT.Set( sec.Mid( firstSep + 1, sndSep - firstSep -1 ) );
+    	TInt posInvol = mkLT.Find( KInvolute );
+		TLex8 lexMKL( mkLT.Mid( posInvol+1 ) );
+		User::LeaveIfError( lexMKL.Val(unitMKLT, EDecimal ));
+		Math::Pow( powerResult, mkiPowerBase, (TReal)unitMKLT );
+		unitMKLT = (TUint32)powerResult;
+
+		found = ETrue;	
+        }
+    else if (sec.Match ( KMatchMKLTDigit ) != KErrNotFound )
+    	{
+    	found= ETrue;
+		//only Decimal case
+		TInt first = sec.Find( KSeparator );
+		TInt second = sec.LocateReverse( separator );
+		mkLT.Set( aSecDec.Mid( first+1, second - first - 1  ));
+		TLex8 lexMKL(mkLT);
+		
+		User::LeaveIfError( lexMKL.Val(unitMKLT, EDecimal ));
+    	}
+	else if( sec.Match( KMatchMKLT ) != KErrNotFound )	
+		{
+		found = ETrue;
+		//onlyMKLT with power 2 no MasterKeyIdentifier
+		TInt posSeparator = sec.Match( KMatchMKLT );
+		TInt remainLen = sec.Length() - ( posSeparator + KMatchMKLToffset );
+		//only number after power
+		mkLT.Set( sec.Mid( posSeparator + KMatchMKLToffset, remainLen ) );
+	
+		TLex8 lexMKL( mkLT );
+		
+		User::LeaveIfError( lexMKL.Val(unitMKLT, EDecimal ));
+		Math::Pow( powerResult, mkiPowerBase, (TReal)unitMKLT );
+		mkLT.Set( sec.Mid( posSeparator + 1 ));// ex 2^32
+		
+		unitMKLT = (TUint32)powerResult;
+		}
+     else if ( sec.Match(KOnlyMKI) == KErrNotFound  && totalLen > 0
+			&& sec.Find(KSeparator) != KErrNotFound )
+		{
+		found= ETrue;
+		//only Decimal case
+		TInt posfirst = sec.Find( KSeparator );
+		TInt mkltpos = posfirst +1;
+		TInt remainLen = totalLen - ( mkltpos );
+		mkLT.Set( aSecDec.Mid( mkltpos, remainLen ));
+		TLex8 lexMKL(mkLT);
+		User::LeaveIfError( lexMKL.Val(unitMKLT, EDecimal ));
+		}  
+    
+	if (found )
+		{
+		//It is decode so only for cryptoIn
+		aCrypto.iMKLifeTime = unitMKLT;
+		}
+    }
+
+// -----------------------------------------------------------------------------
+// CMceSecureDesStream::DecodeMKIValue
+// 
+// -----------------------------------------------------------------------------
+//    
+void CMceSecureDesStream::DecodeMKIValueL( 	const TDesC8& aSecDec,
+											TBool aIsAnswer,
+    										TMceSecureCryptoInfo& aCrypto )
+	{
+	/*RFC 4568 6.1
+	*/
+	// aSecDec is CSdpAttributeField value
+	const TInt KMKIMaxLen = 3;
+    const TInt KMKIColonLen = 1;
+    const TInt KMKIMaxBytes = 128;
+    _LIT8 (KOnlyMKI, "*|*:*");
+
+	TPtrC8 sec(NULL,0);
+	TChar separator='|';
+	TChar colon=':';
+	TChar space = ' ';
+	TInt mkifound = aSecDec.Match( KOnlyMKI );
+	TInt posSemi= aSecDec.Find( KSemiColon );
+	sec.Set( aSecDec.Ptr(),aSecDec.Length() );
+	if ( posSemi != KErrNotFound )
+		{
+		//with secon inline
+		sec.Set( aSecDec.Left(posSemi).Ptr(), posSemi );
+		}
+		
+	if ( aIsAnswer )
+		{
+		//compare with cryptoOut
+		if ( !iCryptoOut.iMKIUsed && mkifound != KErrNotFound )
+			{
+			//should not have MKI field , reject this 
+			User::Leave ( KErrArgument );
+			}
+		}
+	if ( mkifound != KErrNotFound )
+		{
+		//there is MKI
+		/*If the MKI length is not given or
+   		its value exceeds 128 (bytes), then the entire crypto attribute MUST
+   		be considered invalid.*/
+		TInt separator2ndPos = sec.LocateReverse( separator );
+		TInt mkiPos = separator2ndPos+1;
+		TInt colonPos = sec.LocateReverse( colon );
+		TInt mKIoffset = colonPos - mkiPos;
+		//mki value
+		if ( mKIoffset < 0 )
+			{
+			//malformate MKI
+			User::Leave( KErrArgument );
+			}
+	
+		TPtrC8 mkiValue = sec.Mid(mkiPos, mKIoffset);
+		TLex8 lexMKI(mkiValue);
+		User::LeaveIfError(lexMKI.Val(aCrypto.iMKIValue, EDecimal) );
+		
+		//mki length
+		TInt mkilenPos = colonPos+1;
+		TInt mkilenOffset = sec.Length() - mkilenPos;
+		if ( mkilenOffset> KMKIMaxLen )
+			{
+			//there is extra session parameter behind
+			//looking for white space
+			TInt spacePos = sec.LocateReverse( space );
+			mkilenOffset = spacePos-mkilenPos;
+			}
+		TPtrC8 mkilen = sec.Mid( mkilenPos, mkilenOffset );
+		TLex8 lexMkiLen(mkilen);
+		User::LeaveIfError(lexMkiLen.Val(aCrypto.iMKILength, EDecimal, KMKIMaxBytes));
+    	__ASSERT_ALWAYS( aCrypto.iMKILength <= KMKIMaxLength,
+    	                 User::Leave( KErrOverflow ) );		
+		
+		//get whole MKI ( value + length)-> This is for adding SDP only
+		TInt total = mKIoffset +  mkilenOffset + KMKIColonLen;
+		aCrypto.iMKI = sec.Mid( mkiPos, total ) ;		
+		aCrypto.iMKIUsed = ETrue;
+		}
+	
+	return;	
+	}
+
+// -----------------------------------------------------------------------------
+// CMceSecureDesStream::ValidateAnswerByOffer
+// Validate and Set cryptoIn information
+// -----------------------------------------------------------------------------
+//    
+void CMceSecureDesStream::ValidateAnswerByOfferL(const TDesC8& aSecDec )
+	{
+	/*
+	Vaidata the incoming answer by the original offer
+	7.1.3.  Processing of the Initial Answer - Unicast Streams
+	*/
+	//remember to check how many inlinle later
+	MCEMM_DEBUG("CMceSecureDesStream::ValidateAnswerByOfferL, Entry")
+    if (aSecDec.Length() < KCryptoAttributeValueMinLength)
+ 		{
+ 		User::Leave( KErrArgument );
+ 		}
+    // Check SRTP crypto-suites
+    if ( iSecureSession.iKeyNeedUpdated )
+    	{
+    	IfMatchLocalCryptoL(aSecDec);
+    	}
+    MSG_IGNORE_RETURN()
+   	//check key param
+   
+	TInt foundInline = aSecDec.Find( KInline );
+ 	TInt foundSeparator = aSecDec.Find( KSeparator);
+ 	TInt foundColon = aSecDec.Find(KColon);
+ 	if ( KErrNotFound != foundInline)
+ 		{
+    //check key info
+	    TInt keyInfoPos = foundColon+1;
+	    TInt keyInfoLen = 0;
+	    if (foundSeparator != KErrNotFound)
+	        	{
+	        	keyInfoLen = foundSeparator-keyInfoPos;
+	        	}
+	        else
+	        	{
+	        	keyInfoLen = aSecDec.Length()-keyInfoPos;
+	        	}
+    
+	    TPtrC8 keyInfo = aSecDec.Mid(keyInfoPos, keyInfoLen);
+	    if ( iSecureSession.iKeyNeedUpdated )
+	    	{
+	    	
+		    TBool valid = ValidateSecurityDescriptions( keyInfo );
+	   		if ( valid )
+	   			{
+	   			
+		    	// check keyInfo 
+			    if (iCryptoOut.iEncodedKey.Compare( keyInfo ) == 0)
+			    	{
+			    	User::Leave( KErrArgument );
+			    	}
+		    	//check keyinfo mki 
+				DecodeMKIValueL(aSecDec, ETrue, iCryptoIn );     
+				MSG_IGNORE_RETURN()
+				DecodeMKLifeTimeL( aSecDec, iCryptoIn );		
+					//check sessionparam later
+				iCryptoIn.iEncodedKey = keyInfo;
+				StoreKeys(iCryptoIn.iEncodedKey);
+	   			}
+	   		else
+	   			{
+	   			User::Leave( KErrArgument );
+	   			}
+	    	}
+	   	}
+ 	else
+ 		{
+ 		User::Leave( KErrArgument );
+ 		}
+    MCEMM_DEBUG("CMceSecureDesStream::ValidateAnswerByOfferL, Exit")
+    }
+	
+// -----------------------------------------------------------------------------
+// CMceSecureDesStream::ValidateOfferByAnswer
+// aSecDec is one attribute
+// -----------------------------------------------------------------------------
+//    
+void CMceSecureDesStream::ValidateOfferByAnswerL( const TDesC8& aSecDec )
+	{
+	/*
+	RFC 4568               SDP Security Descriptions               
+	7.1.2.  Generating the Initial Answer - Unicast Streams
+	*/
+	//check client abilities and same time set the Answer crypto but not keys
+	MCEMM_DEBUG("CMceSecureDesStream::ValidateOfferByAnswerL, Entry")
+
+ 	if ( aSecDec.Length() < KCryptoAttributeValueMinLength )
+ 		{
+ 		User::Leave ( KErrArgument);
+ 		}
+ 	SetPreferedCryptoL();
+ 	TMceSecureCryptoInfo crypto;
+    StoreCryptoInFromOfferL(aSecDec, crypto);
+    MSG_IGNORE_RETURN()
+	//SetClientCryptoL(crypto);	        
+	   //check key param
+     
+    TInt foundInline = aSecDec.Find( KInline );
+    TInt foundSeparator = aSecDec.Find( KSeparator);
+    TInt foundColon = aSecDec.Find(KColon);
+    if ( KErrNotFound != foundInline)
+     	{
+        //check key info
+        TInt keyInfoPos=foundColon+1;
+        TInt keyInfoLen=0;
+        if (foundSeparator!= KErrNotFound)
+        	{
+        	keyInfoLen= foundSeparator-keyInfoPos;
+        	}
+        else
+        	{
+        	keyInfoLen = aSecDec.Length()-keyInfoPos;
+        	}
+        TPtrC8 keyInfo = aSecDec.Mid(keyInfoPos, keyInfoLen);
+        TBool valid = ValidateSecurityDescriptions( keyInfo );
+        
+        if ( valid )
+        	{
+        	
+            //check keyinfo mki 
+		     DecodeMKIValueL( aSecDec, EFalse, crypto );   
+		     MSG_IGNORE_RETURN()
+		     //set MKI value for our local crypto because all MKI in one crypto suite
+		     // should be the same
+	     
+	     	DecodeMKLifeTimeL( aSecDec, crypto );
+	     	//StorKey
+	     	crypto.iEncodedKey = keyInfo;
+	     	TBuf8 < KMasterKeyAndSaltLength > masterKeyAndSalt;
+			Base64Decode( crypto.iEncodedKey, masterKeyAndSalt );
+
+			//it should be validate already so it is our prefered key
+		
+			crypto.iSetMasterKey = masterKeyAndSalt.Mid( 0, KMasterKeyLength );
+			crypto.iSetSaltKey = masterKeyAndSalt.Mid( KMasterKeyLength );
+			crypto.iKeysCreated = ETrue;
+			iCryptoIns->AppendL( crypto );
+	     	//check sessionparam later	
+	     		
+        	}
+        else
+        	{
+        	User::Leave( KErrArgument);
+        	}
+     	}
+   	else
+   		{
+ 		User::Leave( KErrArgument);
+ 		}
+
+    MCEMM_DEBUG("CMceSecureDesStream::ValidateOfferByAnswerL, Exit")
+ 	}
+	
+// -----------------------------------------------------------------------------
+// CMceSecureDesStream::SetSecureProtocol()
+// 
+// -----------------------------------------------------------------------------
+//    
+void CMceSecureDesStream::SetSecureProtocolL(CSdpMediaField& aMediaField)
+	{
+	MCEMM_DEBUG("CMceSecureDesStream::SetSecureProtocol(), Entry")   
+	TPtrC8 protocolName( KProtocolSAVP );
+	
+	if ( Session().Modifier( KMceSecureSession ) == KMceSecurePlainAVP )
+		{
+		protocolName.Set ( KProtocolAVP );
+		}
+	if ( !iIsSAVP )
+		{
+		protocolName.Set( KProtocolSAVPF );
+		Session().Modifier( KMceSecureSession ) = KMceSecureNormal;
+		}
+		
+	RStringF protocol = SdpCodecStringPool::StringPoolL().OpenFStringL( protocolName);		
+	CleanupClosePushL( protocol );                            
+    
+	aMediaField.SetProtocolL( protocol );	
+	CleanupStack::PopAndDestroy( &protocol );
+
+	MCEMM_DEBUG("CMceSecureDesStream::SetSecureProtocol(), Exit")  
+	}
+	
+
+//-----------------------------------------------------------------------------
+// CMceSecureDesStream::SetPreferedCrypto()
+// 
+// -----------------------------------------------------------------------------
+//    
+void CMceSecureDesStream::SetPreferedCryptoL()
+	{
+	MCEMM_DEBUG( "CMceSecureDesStream::SetPreferedCryptoL, entry" )	
+	RArray <TMceCryptoContext> clientCryptoSuite = 
+					Session().iClientCryptoSuites;
+	TInt clientCryptoCount = clientCryptoSuite.Count();
+	if ( !iCryptoOuts->Count() )
+		{
+		AppendEmptyCryptoL( *iCryptoOuts, KTotalCryptoAnswerCount );
+		}
+	if (!clientCryptoCount )
+		{
+		MCEMM_DEBUG( "Client has no preference on crypto" )	
+		iCryptoOuts->Reset();
+		// tag 80 prefered
+		SetDefaultCryptoL( *iCryptoOuts );
+		}
+	else
+		{
+		iCryptoOuts->Reset();
+		SetCryptoByClientL( *iCryptoOuts );
+		}
+	MCEMM_DEBUG( "CMceSecureDesStream::SetPreferedCryptoL, exit" )		
+	}
+
+//-----------------------------------------------------------------------------
+// CMceSecureDesStream::SetClientCrypto()
+// 
+// -----------------------------------------------------------------------------
+//    
+void CMceSecureDesStream::SetClientCryptoL( TInt aCryptoCount )
+	{
+	MCEMM_DEBUG( "CMceSecureDesStream::SetClientCryptoL, entry" )	
+	RArray< TMceCryptoContext > clientCryptoSuite = 
+	    Session().iClientCryptoSuites;
+	TInt clientCryptoSuiteCount = clientCryptoSuite.Count();
+	
+	if ( iCryptoOuts->Count() == 0 )
+		{
+		AppendEmptyCryptoL( *iCryptoOuts, KTotalCryptoAnswerCount );
+		}
+		
+	if ( clientCryptoSuiteCount > 0 )
+		{	
+		for ( TInt index = 0; index < clientCryptoSuiteCount; index++ )
+			{
+			if ( aCryptoCount-1 == index )
+				{
+				MCEMM_DEBUG_DVALUE(" index = ", index )
+				MCEMM_DEBUG_DVALUE(" iCryptoOuts->Count() ", iCryptoOuts->Count() )	
+				iGnoreSdpMsg = index >= iCryptoOuts->Count() ? ETrue : EFalse;
+				MSG_IGNORE_RETURN()
+				TMceSecureCryptoInfo cryptoOut = iCryptoOuts->At( index );
+				
+				if ( clientCryptoSuite[index]== EAES_CM_128_HMAC_SHA1_80 )
+					{
+					SetSHA180( cryptoOut, aCryptoCount );
+					}
+				if ( clientCryptoSuite[ index ] == EAES_CM_128_HMAC_SHA1_32 )
+					{
+					//iCrytoOuts has been created in GenerateKey
+					SetSHA132( cryptoOut, aCryptoCount );
+					}	
+				iCryptoOuts->At( index ).Copy( cryptoOut );	
+				}
+			}
+		}
+	MCEMM_DEBUG( "CMceSecureDesStream::SetClientCryptoL, exit" )
+	}	
+
+
+//-----------------------------------------------------------------------------
+// CMceSecureDesStream::ClientCrytoCount()
+// 
+// -----------------------------------------------------------------------------
+//    
+TInt CMceSecureDesStream::ClientCrytoCount()
+	{
+	TInt count = Session().iClientCryptoSuites.Count();
+	return count;
+	}		
+
+
+//-----------------------------------------------------------------------------
+// CMceSecureDesStream::IfMatchLocalCryptoL()
+// 
+// -----------------------------------------------------------------------------
+//
+void CMceSecureDesStream::IfMatchLocalCryptoL( const TDesC8& aSecDec )
+	{
+	MCEMM_DEBUG( "CMceSecureDesStream::IfMatchLocalCryptoL, entry" )
+	TMceSecureCryptoInfo crypto;
+	TInt foundAes80 = aSecDec.Find( KAES_SHA1_80 );
+	TInt foundAes32 = aSecDec.Find( KAES_SHA1_32 );
+	if (foundAes80 != KErrNotFound )
+		{
+		TPtrC8 tagValue = aSecDec.Mid( foundAes80-2, 1);
+		TLex8 lexTag(tagValue);
+		TUint tag=0;
+		User::LeaveIfError( lexTag.Val( tag, EDecimal));
+		SetSHA180( crypto, tag );
+		}
+	else if (foundAes32!= KErrNotFound )
+		{
+		TPtrC8 tagValue = aSecDec.Mid( foundAes32-2, 1 );
+		TLex8 lexTag( tagValue );
+		TUint tag = 0;
+		User::LeaveIfError( lexTag.Val( tag, EDecimal ));
+		SetSHA132( crypto, tag );
+		}	
+	TInt find = SearchAndSetCrypto( crypto );
+	iGnoreSdpMsg = find == KErrNone ? EFalse : ETrue;
+	MCEMM_DEBUG( "CMceSecureDesStream::IfMatchLocalCryptoL, exit" )
+	return ;
+	}
+
+//-----------------------------------------------------------------------------
+// CMceSecureDesStream::SearchAndSetCrypto()
+// 
+// -----------------------------------------------------------------------------
+//
+TInt CMceSecureDesStream::SearchAndSetCrypto(TMceSecureCryptoInfo& aCrypto)
+	{
+	MCEMM_DEBUG( "CMceSecureDesStream::SearchAndSetCrypto, entry" )
+	for ( TInt i=0; i < iCryptoOuts->Count(); i++ )
+		{
+		MCEMM_DEBUG_DVALUE(" iCryptoOuts->Count() ", iCryptoOuts->Count() )	
+				
+		TMceSecureCryptoInfo cryptoOut = iCryptoOuts->At( i );
+		if ( cryptoOut.iTagLen == aCrypto.iTagLen &&
+			 cryptoOut.iEncAlgms == aCrypto.iEncAlgms &&
+			 cryptoOut.iAuthAlgms == aCrypto.iAuthAlgms &&
+			 cryptoOut.iCryptoSuite.Compare(aCrypto.iCryptoSuite) == 0)
+			{
+			//SEtCrypto
+			iCryptoOut.Copy( cryptoOut );
+			iCryptoIn.iTag = cryptoOut.iTag;
+			iCryptoIn.iEncAlgms = cryptoOut.iEncAlgms;
+			iCryptoIn.iAuthAlgms = cryptoOut.iAuthAlgms;
+			iCryptoIn.iTagLen = cryptoOut.iTagLen;
+			iCryptoIn.iCryptoSuite = cryptoOut.iCryptoSuite ;
+        	return KErrNone;
+			}
+		}
+	MCEMM_DEBUG( "SearchAndSetCrypto NotFound" )	
+	MCEMM_DEBUG( "CMceSecureDesStream::SearchAndSetCrypto, exit" )	
+	return KErrNotFound;	
+	}	
+	
+	
+//-----------------------------------------------------------------------------
+// CMceSecureDesStream::StoreCryptoInFromOffer()
+// 
+// -----------------------------------------------------------------------------
+//
+void CMceSecureDesStream::StoreCryptoInFromOfferL( const TDesC8& aSecDec, 
+                                                   TMceSecureCryptoInfo& aCrypto)
+	{
+	MCEMM_DEBUG( "CMceSecureDesStream::StoreCryptoInFromOfferL entry" )
+	TInt foundAes80 = aSecDec.Find( KAES_SHA1_80 );
+	TInt foundAes32 = aSecDec.Find( KAES_SHA1_32 );
+	if ( foundAes80 != KErrNotFound )
+		{
+		TPtrC8 tagValue = aSecDec.Mid( foundAes80-2, 1 );
+		TLex8 lexTag( tagValue );
+		TUint tag = 0;
+		User::LeaveIfError( lexTag.Val( tag, EDecimal ));
+		SetSHA180( aCrypto, tag );
+		}
+	else if (foundAes32!= KErrNotFound )
+		{
+		TPtrC8 tagValue = aSecDec.Mid( foundAes32-2, 1 );
+		TLex8 lexTag( tagValue );
+		TUint tag = 0;
+		User::LeaveIfError( lexTag.Val( tag, EDecimal ));
+		SetSHA132( aCrypto, tag );
+		}
+			
+	if (foundAes32 == KErrNotFound && foundAes80 == KErrNotFound)
+		{
+		iGnoreSdpMsg = ETrue;
+		MCEMM_DEBUG( " Not Found any acceptible Crypto Value in SecureDes" )
+		return;
+		} 
+	
+	for ( TInt i=0; i < iCryptoOuts->Count(); i++ )
+		{
+		MCEMM_DEBUG_DVALUE(" iCryptoOuts->Count() ", iCryptoOuts->Count() )	
+				
+		TMceSecureCryptoInfo cryptoOut = iCryptoOuts->At( i );
+		if ( cryptoOut.iTagLen == aCrypto.iTagLen &&
+			 cryptoOut.iEncAlgms == aCrypto.iEncAlgms &&
+			 cryptoOut.iAuthAlgms == aCrypto.iAuthAlgms &&
+			 cryptoOut.iCryptoSuite.Compare(aCrypto.iCryptoSuite) == 0 )
+			{
+			MCEMM_DEBUG( " Compare with own crypto OK" )
+			return;
+			}
+		}
+	iGnoreSdpMsg = ETrue;
+	MCEMM_DEBUG( "CMceSecureDesStream::StoreCryptoInFromOfferL exit" )	
+	}	
+
+	
+//-----------------------------------------------------------------------------
+// CMceSecureDesStream::StoreCryptoInFromOffer()
+// 
+// -----------------------------------------------------------------------------
+//
+TInt CMceSecureDesStream::CompareCryptosForAnswer()
+	{
+	//check how client wants
+	MCEMM_DEBUG( "CMceSecureDesStream::CompareCryptosForAnswer entry" )
+	if (iCryptoOuts->Count())
+		{
+		MCEMM_DEBUG_DVALUE(" iCryptoOuts->Count() ", iCryptoOuts->Count() )	
+				
+		TInt count = iCryptoOuts->Count();
+		for ( TInt i = 0; i< count; i++ )
+			{
+			for ( TInt j = 0; j < iCryptoIns->Count(); j++ )
+				{	
+				MCEMM_DEBUG_DVALUE(" iCryptoIns->Count() ", iCryptoIns->Count() )
+				if (iCryptoOuts->At( i ).iTagLen == iCryptoIns->At( j ).iTagLen &&
+					iCryptoOuts->At( i ).iEncAlgms == iCryptoIns->At( j ).iEncAlgms &&
+					iCryptoOuts->At( i ).iAuthAlgms == iCryptoIns->At( j ).iAuthAlgms &&
+					iCryptoOuts->At( i ).iCryptoSuite.Compare( iCryptoIns->At( j ).iCryptoSuite) == 0 )
+					{
+					iCryptoIn.Copy( iCryptoIns->At( j ) );
+					//So can set the MKI and MKT
+					iCryptoOut.Copy( iCryptoIns->At( j ) );
+					MCEMM_DEBUG( "CMceSecureDesStream::CompareCryptosForAnswer exit" )
+					return KErrNone;
+					}
+				}
+			}
+		}
+	MCEMM_DEBUG( "No CryptoOuts Set" )
+	MCEMM_DEBUG( "CMceSecureDesStream::CompareCryptosForAnswer exit" )
+	return KErrArgument;	
+	}
+	
+//-----------------------------------------------------------------------------
+// CMceSecureDesStream::RemoveClientCrypto()
+// 
+// -----------------------------------------------------------------------------
+//
+void CMceSecureDesStream::RemoveClientCrypto()
+	{
+	TInt count = ClientCrytoCount();
+    for (TInt i = count; i > 0; i--)
+    	{
+    	Session().iClientCryptoSuites.Remove( i-1 );	
+   		}	
+	}
+
+//-----------------------------------------------------------------------------
+// CMceSecureDesStream::SetClientCrypto()
+// 
+// -----------------------------------------------------------------------------
+//
+void CMceSecureDesStream::SetClientCryptoL( TMceSecureCryptoInfo& aCrypto )
+	{
+    if ( !aCrypto.iCryptoSuite.Compare( KAES_SHA1_32 ))
+    	{
+    	User::LeaveIfError( 
+    		Session().iClientCryptoSuites.Append( EAES_CM_128_HMAC_SHA1_32 ));		
+    	}
+    if ( !aCrypto.iCryptoSuite.Compare(KAES_SHA1_80) )
+    	{
+    	User::LeaveIfError( 
+    	    Session().iClientCryptoSuites.Append( EAES_CM_128_HMAC_SHA1_80 ));		
+    	}
+	}
+
+//-----------------------------------------------------------------------------
+// CMceSecureDesStream::SetMultipleClientCrypto()
+// 
+// -----------------------------------------------------------------------------
+//
+void CMceSecureDesStream::SetMultipleClientCryptoL( 
+    CArrayFixFlat< TMceSecureCryptoInfo>& aArray )
+	{
+	TInt index =0;
+	TInt count = aArray.Count();
+	for ( index = 0; index < count; index ++ )
+		{
+		SetClientCryptoL( aArray[index] );
+		}
+    
+	}
+//-----------------------------------------------------------------------------
+// CMceSecureDesStream::CountCrypto()
+// 
+// -----------------------------------------------------------------------------
+//
+TInt CMceSecureDesStream::CountCryptoInOffer( CSdpMediaField& aMediaField )
+	{
+	
+    if ( !iCryptoIns->Count() && !ClientCrytoCount()  && 
+    		iSecureSession.SdpCryptoAttributeCount(aMediaField) )
+    	{
+    	return KErrArgument;
+    	}
+    return KErrNone;	
+    }				
+
+//-----------------------------------------------------------------------------
+// CMceSecureDesStream::Copy()
+// 
+// -----------------------------------------------------------------------------
+//
+void CMceSecureDesStream::CopyStreamCryptoL( CMceSecureDesStream& aCopyFrom ) 
+	{
+	MCEMM_DEBUG( "CMceSecureDesStream::CopyStreamCryptoL Entry" )
+	iCryptoUpdateNeeded = ETrue;
+    iCryptoOut.Copy(aCopyFrom.iCryptoOut);
+    MCEMM_DEBUG_DVALUE( "iCryptoContextOutId", aCopyFrom.iCryptoOut.iCryptoContextId )
+    iCryptoContextOutId = aCopyFrom.iCryptoOut.iCryptoContextId;
+    iCryptoIn.Copy(aCopyFrom.iCryptoIn);
+    iCryptoContextInId = aCopyFrom.iCryptoIn.iCryptoContextId;
+    MCEMM_DEBUG_DVALUE( "iCryptoContextInId", aCopyFrom.iCryptoIn.iCryptoContextId )
+
+	for (TInt i = 0; i < aCopyFrom.iCryptoOuts->Count(); i++)
+		{
+		iCryptoOuts->AppendL( aCopyFrom.iCryptoOuts->At( i ) );
+		}
+		iOldLocalMediaPort = aCopyFrom.iOldLocalMediaPort;
+ 	MCEMM_DEBUG( "CMceSecureDesStream::CopyStreamCryptoL Exit" )
+	}
+
+//-----------------------------------------------------------------------------
+// CMceSecureDesStream::Session()
+// 
+// -----------------------------------------------------------------------------
+//
+CMceComSession& CMceSecureDesStream::Session()
+	{
+	return iSecureSession.iSession;
+	}
+
+//-----------------------------------------------------------------------------
+// CMceSecureDesStream::MediaFieldAttrMatch()
+// 
+// -----------------------------------------------------------------------------
+//
+CSdpAttributeField* CMceSecureDesStream::MediaFieldAttrMatch( 	CSdpMediaField& aMediaField,
+																const TDesC8& aMatchString )
+	{
+	RPointerArray< CSdpAttributeField > attrList =  
+                aMediaField.AttributeFields();
+    
+    TInt attrCount = attrList.Count();
+    
+    for (TInt j = 0; j < attrCount; j++ )
+        {
+        RStringF attribute = attrList[ j ]->Attribute();
+     
+     	 if ( attribute.DesC().Match( aMatchString )!= KErrNotFound )
+        	{
+        	return attrList[ j ];
+        	}
+        }
+    return NULL;    
+	}
+	
+//-----------------------------------------------------------------------------
+// CMceSecureDesStream::SetMediaProfile ()
+// 
+// -----------------------------------------------------------------------------
+//
+TInt CMceSecureDesStream::SetMediaProfile( CSdpMediaField& aMediaField )
+	{
+	//answer or offer/update or refresh
+	TInt findSAVP = aMediaField.Protocol().DesC().Find( KProtocolSAVP );
+	TInt findSAVPF = aMediaField.Protocol().DesC().Find( KProtocolSAVPF );	
+    TInt findAVP = aMediaField.Protocol().DesC().Find( KProtocolAVP );	
+    
+    if ( findSAVP == KErrNotFound && findSAVPF == KErrNotFound &&
+		findAVP == KErrNotFound)
+		{
+		return KErrArgument;
+		}
+	if ( findAVP != KErrNotFound )
+		{
+        Session().Modifier( KMceSecureSession ) = KMceSecurePlainAVP;
+		}
+	if ( findSAVP != KErrNotFound || findSAVPF != KErrNotFound )
+		{
+		Session().Modifier( KMceSecureSession ) = KMceSecureNormal;
+		iIsSAVP = findSAVPF != KErrNotFound ? !iIsSAVP : iIsSAVP;	
+		}
+	
+	
+	return KErrNone;
+	}
+
+
+//-----------------------------------------------------------------------------
+// CMceSecureDesStream::AppendCryptoAttributeL ()
+// 
+// -----------------------------------------------------------------------------
+//
+void CMceSecureDesStream::AppendCryptoAttributeL( 	TDesC8& aCryptoLine,
+													CSdpMediaField& aMediaField )
+	{
+	RStringF crypto = SdpCodecStringPool::StringPoolL().OpenFStringL( KCrypto );
+    CleanupClosePushL( crypto );               
+	CSdpAttributeField* attribute = NULL;
+	attribute = CSdpAttributeField::NewLC( crypto, aCryptoLine );
+   	User::LeaveIfError ( aMediaField.AttributeFields().Append( attribute ) );
+    CleanupStack::Pop(attribute);	   
+    CleanupStack::PopAndDestroy( &crypto ); 
+	}
+
+//-----------------------------------------------------------------------------
+// CMceSecureDesStream::AppendCryptoAttributeL ()
+// 
+// -----------------------------------------------------------------------------
+//
+TInt CMceSecureDesStream::SearchChar( 	TDesC8& aSearchLine, 
+										TChar& aChar, 
+										TInt aSearchFrom )
+	{
+	TInt len = aSearchLine.Length();
+	TLex8 search( aSearchLine );
+
+	for ( TInt offset = 0; offset < len; offset++ )
+		{
+		if ( search.Peek() == aChar )
+			{
+			if ( !aSearchFrom )
+				return offset;
+			if (aSearchFrom && offset > aSearchFrom)
+				return offset;
+			}
+		search.Inc();	
+		}
+	return KErrNone;
+	}	
+
+//-----------------------------------------------------------------------------
+// CMceSecureDesStream::AppendEmptyCryptoL ()
+// 
+// -----------------------------------------------------------------------------
+//
+void CMceSecureDesStream::AppendEmptyCryptoL( 
+							CArrayFixFlat<TMceSecureCryptoInfo>& aCryptos,
+							TInt aCount )
+	{
+	for ( TInt i = 0; i < aCount; i++)
+		{
+		TMceSecureCryptoInfo crypto;
+		aCryptos.AppendL( crypto );
+		}
+	}
+
+//-----------------------------------------------------------------------------
+// CMceSecureDesStream::SetSHA132 ()
+// 
+// -----------------------------------------------------------------------------
+//
+void CMceSecureDesStream::SetSHA132( TMceSecureCryptoInfo& aCrypto, TInt aTag )
+	{
+	aCrypto.iTag = aTag;
+	aCrypto.iEncAlgms = ESrtpEncAES_CM;
+    aCrypto.iTagLen = KAuthTagLength32;
+    aCrypto.iAuthAlgms = ESrtpAuthHMAC_SHA1;
+	aCrypto.iCryptoSuite = KAES_SHA1_32;
+	}	
+
+//-----------------------------------------------------------------------------
+// CMceSecureDesStream::SetSHA180 ()
+// 
+// -----------------------------------------------------------------------------
+//
+void CMceSecureDesStream::SetSHA180( TMceSecureCryptoInfo& aCrypto, TInt aTag )
+	{
+	aCrypto.iTag = aTag;
+	aCrypto.iEncAlgms = ESrtpEncAES_CM;
+    aCrypto.iTagLen = KAuthTagLength80;
+    aCrypto.iAuthAlgms = ESrtpAuthHMAC_SHA1;
+	aCrypto.iCryptoSuite = KAES_SHA1_80;
+   	}
+   	
+//-----------------------------------------------------------------------------
+// CMceSecureDesStream::SetDefaultCryptoL ()
+// 
+// -----------------------------------------------------------------------------
+//
+void CMceSecureDesStream::SetDefaultCryptoL( 
+							CArrayFixFlat<TMceSecureCryptoInfo>& aCryptos )
+	{
+	MCEMM_DEBUG( "CMceSecureDesStream::SetDefaultCryptoL, entry " )
+	const TInt tag1 = 1;
+	const TInt tag2 = 2;
+	const TUint index1 = 0;
+	const TInt index2 = 1;
+	
+	AppendEmptyCryptoL( aCryptos, KTotalCryptoAnswerCount );
+	
+	MCEMM_DEBUG_DVALUE(" CryptoCount = ", aCryptos.Count() )
+	iGnoreSdpMsg = !aCryptos.Count() ? ETrue : EFalse;
+	MSG_IGNORE_RETURN()
+    SetSHA180( aCryptos.At( index1 ), tag1 );
+    
+    iGnoreSdpMsg = index2 >= iCryptoOuts->Count() ? ETrue : EFalse;
+    MSG_IGNORE_RETURN()
+    SetSHA132( aCryptos.At( index2 ), tag2 );
+    
+	MCEMM_DEBUG( "CMceSecureDesStream::SetDefaultCryptoL, exit " )
+	}   
+	
+//-----------------------------------------------------------------------------
+// CMceSecureDesStream::SetCryptoByClientL ()
+// 
+// -----------------------------------------------------------------------------
+//
+void CMceSecureDesStream::SetCryptoByClientL( 
+							CArrayFixFlat<TMceSecureCryptoInfo>& aCryptos )
+	{
+	MCEMM_DEBUG( "CMceSecureDesStream::SetCryptoByClientL, entry " )
+	RArray <TMceCryptoContext> clientCryptoSuite =  
+											Session().iClientCryptoSuites;
+	TInt clientCryptoCount = clientCryptoSuite.Count();
+	MCEMM_DEBUG_DVALUE(" ClientCryptoCount = ", aCryptos.Count() )											
+	for ( TInt i = 0; i < clientCryptoCount; i++ )
+			{
+			TMceSecureCryptoInfo crypto;
+			
+			if ( clientCryptoSuite[i] == EAES_CM_128_HMAC_SHA1_32 )
+				{
+				SetSHA132( crypto, i+1 );
+				}
+			if ( clientCryptoSuite[i] == EAES_CM_128_HMAC_SHA1_80 )
+				{
+				SetSHA180( crypto, i+1 );
+				}
+			aCryptos.AppendL( crypto );		
+			}
+	MCEMM_DEBUG( "CMceSecureDesStream::SetCryptoByClientL, exit " )
+	}   							
+//  End of File