rtp/srtpstack/src/srtpcryptohandler.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 02 Feb 2010 01:03:15 +0200
changeset 0 307788aac0a8
permissions -rw-r--r--
Revision: 201003 Kit: 201005

/*
* 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 "srtpcryptocontext.h"
#include "srtputils.h"
#include "srtpstream.h"
#include "srtpaesctrcrypto.h"
#include "srtpkeyderivation_aescm128.h"
#include "srtpcipher_aescm128.h"
#include "srtpcipher_null.h"
#include "srtpauthentication_hmac_sha1.h"
#include "srtpauthentication_null.h"
#include "srtpauthentication_rcc.h"
#include "srtppacket.h"
#include "srtpmasterkey.h"
#include "srtpmastersalt.h"

// CONSTANTS
const TInt CSRTPCryptoHandler::iHandlerOffset = _FOFF( CSRTPCryptoHandler, iHandlerLink );

// ---------------------------------------------------------------------------
// CSRTPCryptoHandler::CSrtpCryptoHandler
// ---------------------------------------------------------------------------
//
CSRTPCryptoHandler::CSRTPCryptoHandler( CSRTPStream& aStream ) :
        iStream(aStream),
        iCurrentPacket(NULL),
        iKeyDeriver(NULL),
        iAuthenticator(NULL),
        iCipher(NULL),
        iMasterDataUpdated(EFalse),
        iSessionEncrKey(NULL),
        iSessionAuthKey(NULL),
        iSessionSaltKey(NULL),
        iReKey(EFalse),
        iBitmap(NULL),
        iNumPackets(NULL)
    {
        
    }

// ---------------------------------------------------------------------------
// CSRTPCryptoHandler::~CSrtpCryptoHandler
// ---------------------------------------------------------------------------
//
CSRTPCryptoHandler::~CSRTPCryptoHandler( )
    { 
    if (&Context())
    	{
    	Context().RemoveCryptoChangeObserver(this);	
    	}
    
    delete iCurrentPacket; iCurrentPacket=NULL;
    delete iKeyDeriver; iKeyDeriver=NULL;
    delete iCipher; iCipher=NULL;
    delete iAuthenticator; iAuthenticator=NULL;        
    
    DeleteSessionKeys();
    }

// ---------------------------------------------------------------------------
// void CSRTPCryptoHandler::SRTPMasterKeyChanged()
// ---------------------------------------------------------------------------
//
void CSRTPCryptoHandler::SRTPMasterKeyChanged()
    {
     iMasterDataUpdated = ETrue;
    //RFC 3711 8.1
     iReKey= EFalse;
    }
        
// ---------------------------------------------------------------------------
// void CSRTPCryptoHandler::SRTPMasterSaltChanged()
// ---------------------------------------------------------------------------
//
void CSRTPCryptoHandler::SRTPMasterSaltChanged()
    {
     iMasterDataUpdated = ETrue;   
         
    }
    

// ---------------------------------------------------------------------------
// CSRTPCryptoHandler::ConstructL
// ---------------------------------------------------------------------------
//
void CSRTPCryptoHandler::ConstructL( )
    {  
    if (!Context().Valid())
    	{
    	User::Leave(KErrArgument);
    	}
    Context().AddCryptoChangeObserver(this);	
    
    iKeyDeriver = CSRTPKeyDerivation_AESCM128::NewL();
    }

// ---------------------------------------------------------------------------
// CSRTPCryptoHandler::SetEncAndAlg ();
// ---------------------------------------------------------------------------
//
void CSRTPCryptoHandler::SetEncAndAuthL (TSRTPEncAlg aEngAlg, 
										TSRTPAuthAlg aAuthAlg)
	{
	delete iCipher; iCipher=NULL;
    delete iAuthenticator; iAuthenticator=NULL;  
	switch (aEngAlg)
	    {
	    case EEncAES_CM:
	        {
	        iCipher = CSRTPCipherAESCM128::NewL();        
	        break;                
	        }      
	    case ENullAlg:
	        {
	        iCipher = CSRTPCipherNULL::NewL();        
	        break;                
	        }      
	    default:          
	        {
	        User::Leave(KErrNotSupported);
	        }
	    }  

	switch (aAuthAlg)
	    {
	    case EAuthHMAC_SHA1:
	   
	        {
	        iAuthenticator = CSRTPAuthentication_HMAC_SHA1::NewL();        
	        break;                
	        }     
	    case EAuthNull:  
	    case EAuthRCCm3:
	    	{
	        iAuthenticator = CSRTPAuthentication_NULL::NewL();        
	        break;                
	        } 
	    case EAuthRCCm1: 
	    case EAuthRCCm2: 	                 
	       	{
	        iAuthenticator = CSrtpAuthentication_RCC::NewL();        
	        break;                
	        } 

	    default:          
	        {
	        User::Leave(KErrNotSupported);
	        }
	    }  
	}
	
// ---------------------------------------------------------------------------
// CSRTPCryptoHandler::Context()
// ---------------------------------------------------------------------------
//
CSRTPCryptoContext& CSRTPCryptoHandler::Context()
    {
    return iStream.GetCryptoContext();
    }

// ---------------------------------------------------------------------------
// CSRTPCryptoHandler::CryptoParams()
// ---------------------------------------------------------------------------
//
const TSrtpCryptoParams& CSRTPCryptoHandler::CryptoParams()
    {
    return Context().CryptoParams();
    }

// ---------------------------------------------------------------------------
// CSRTPCryptoHandler::DeleteSessionKeys()
// ---------------------------------------------------------------------------
//
void CSRTPCryptoHandler::DeleteSessionKeys()
    {
     delete iSessionEncrKey;
     delete iSessionAuthKey;
     delete iSessionSaltKey;  
     iSessionEncrKey = NULL;
     iSessionAuthKey = NULL;
     iSessionSaltKey = NULL;
    }

// ---------------------------------------------------------------------------
// CSRTPCryptoHandler::Count_X()
// ---------------------------------------------------------------------------
//
void CSRTPCryptoHandler::Count_X(TUint64 a_R,
                                TInt8 aLabel, 
                                const TUint64 aIndexLength, 
                                TDes8 &aRes)
    {
        
    TUint64 key_id = TSRTPUtils::Cnt_key_id(aLabel, a_R, aIndexLength);
    
    TSRTPUtils::Cnt_x(key_id, aRes, Context().MasterSalt().MasterSalt());
    
    } 



// ---------------------------------------------------------------------------
// CSRTPCryptoHandler::SetROC()
// 
// ---------------------------------------------------------------------------
//

void CSRTPCryptoHandler::SetROC(  TUint32 aROC )
    {
    iStream.SetROC(aROC);
    }

// ---------------------------------------------------------------------------
// CSRTPCryptoHandler::ROC
// 
// ---------------------------------------------------------------------------
//
TUint32 CSRTPCryptoHandler::ROC() const
    {
    return iStream.ROC();
    }


// ---------------------------------------------------------------------------
// CSRTPCryptoHandler::SSRC
// 
// ---------------------------------------------------------------------------
//
TUint CSRTPCryptoHandler::SSRC() const
    {
    return iStream.SSRC();
    }



// ---------------------------------------------------------------------------
// TInt CSRTPCryptoHandler::ReplayCheck()
// ---------------------------------------------------------------------------
//
TInt CSRTPCryptoHandler::ReplayCheck(TInt aDelta) 
	{
	TInt replayWSH= KReplayWindowSize;
	if (CryptoParams().iReplayWindowSizeHint!=replayWSH)
		{
		replayWSH= CryptoParams().iReplayWindowSizeHint;
		}
	//Remember to initial bitmask at the first time
  	//if aDelta ==0 it might be just re-sent	
	if (aDelta > 0) 
		{                
		/* new larger sequence number */
        
        if (aDelta < replayWSH) 
        	{  /* In window */
            iBitmap <<= aDelta;
            iBitmap |= 1;  /* set bit for this packet */
        	} else iBitmap = 1; /* This packet has a "way larger" */
        
        return KErrNone;   /* larger is good */
    	}
    TInt diff= -(aDelta);
    if (diff >= replayWSH) return KErrArgument; /* too old or wrapped */

    if (iBitmap & ((TUint64)1 << diff)) return KErrArgument; /* already seen */
    //if none of above then will mark as seen in the AddReplayIndex() function             
    return KErrNone;  /* out of order but good */

	}