rtp/srtpstack/src/srtputils.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Mon, 15 Mar 2010 12:42:05 +0200
branchRCL_3
changeset 3 dc4cddf5f2f8
parent 0 307788aac0a8
permissions -rw-r--r--
Revision: 201009 Kit: 201010

/*
* Copyright (c) 2005 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:    Contains SRTP utility functions.
*
*/




// INCLUDES
#include "srtputils.h"
#include <e32math.h>
#define DES_AS_8_BIT(str) (TPtrC8((TText8*)((str).Ptr()), (str).Size()))




// ---------------------------------------------------------------------------
// TSRTPUtils::CountIV()
// ---------------------------------------------------------------------------
//
TInt TSRTPUtils::CountIV(TDes8& aRes, 
                        const TDesC8& aSalt,
                        TUint aSSRC,
                        TUint64 aIndex)
    { 
    SRTP_DEBUG_DETAIL( "TSRTPUtils::CountIV ENNTRY");
            
    TBuf8<32> firstIVTerm;    
    TBuf8<32> secondIVTerm;    
    TBuf8<32> thirdIVTerm;    
            
    GetIVFirstTerm(firstIVTerm, aSalt);
    
    GetIVSecondTerm(secondIVTerm, aSSRC);
            
    GetIVThirdTerm(thirdIVTerm, aIndex);
	
	
     
    if (aRes.Length() != 16)
        {
        SRTP_DEBUG_TINT_VALUE( "the length is", aRes.Length() );
        return KErrArgument;        
        }
           
    //first XOR 1st (=padded session salt) and 2nd (= padded SSRC) terms
    for (TInt i=0; i<16; i++)
        {
        aRes[i] = firstIVTerm[i] ^ secondIVTerm[i];        
        }      

    //next XOR result with 1st term
    for (TInt i=0; i<16; i++)
        {
        aRes[i] = thirdIVTerm[i] ^ aRes[i];        
        }      
    SRTP_DEBUG_DETAIL( "TSRTPUtils::CountIV EXIT");
    return KErrNone;
    }

// ---------------------------------------------------------------------------
// TSRTPUtils::GetIVFirstTerm()
// ---------------------------------------------------------------------------
//
void TSRTPUtils::GetIVFirstTerm(TDes8& aRes, const TDesC8& aSalt)
    {
    TInt count = 16 - aSalt.Length();
    aRes.Copy(aSalt);
    for (TInt i = 0; i<count; i++ )
        {
        aRes.Append(0x00);        
        }            
    }


// ---------------------------------------------------------------------------
// TSRTPUtils::GetIVSecondTerm()
// ---------------------------------------------------------------------------
//
void TSRTPUtils::GetIVSecondTerm(TDes8& aRes, TUint aSSRC)
    {
    TBuf8<32> ssrc;    
    TBuf8<32> temp;    
    
    ssrc.AppendNumUC(aSSRC, EHex); 
    TSRTPUtils::DeHex(ssrc, aRes); 
    
    for (TInt i=0; i<8; i++)
        {
        aRes.Append(0x00);        
        }

    TInt count = 16 - aRes.Length();
    for (TInt i = 0; i<count; i++ )
        {
        temp.Append(0x00);        
        }                    
        
    aRes.Insert(0, temp);        
    }


// ---------------------------------------------------------------------------
// TSRTPUtils::GetIVThirdTerm()
// ---------------------------------------------------------------------------
//
void TSRTPUtils::GetIVThirdTerm(TDes8& aRes, TUint64 aIndex)
    {
    TBuf8<32> temp;
    TBuf8<32> index;    
            
    index.AppendNumUC(aIndex, EHex); 
    TSRTPUtils::DeHex(index, aRes); 
    
    aRes.Append(0x00);        
    aRes.Append(0x00);        
            
    TInt count = 16 - aRes.Length();
    for (TInt i = 0; i<count; i++ )
        {
        temp.Append(0x00);        
        }                    
        
    aRes.Insert(0, temp);        
    }



// ---------------------------------------------------------------------------
// TSRTPUtils::Cnt_r()
// ---------------------------------------------------------------------------
//
TUint64 TSRTPUtils::Cnt_r(const TUint64 aIndex, 
                         const TUint32 aDerivRate)
    {   
    return SrtpDIV(aIndex, aDerivRate);
    }
    
// ---------------------------------------------------------------------------
// TSRTPUtils::Cnt_key_id()
// ---------------------------------------------------------------------------
//
TUint64 TSRTPUtils::Cnt_key_id(const TUint8 aLabel,
                              const TUint64 a_R,
                              const TUint64 aIndexLength)
    {   
    return (aLabel * aIndexLength + a_R);
    }    

// ---------------------------------------------------------------------------
// TUint16 TSRTPUtils::Read16()
// ---------------------------------------------------------------------------
//
TUint16 TSRTPUtils::Read16( const TUint8* const aPointer )
    {
    return static_cast<TUint16>( aPointer[1] + ( aPointer[0] << 8 ) );
    }    

// ---------------------------------------------------------------------------
// TSRTPUtils::Write16()
// ---------------------------------------------------------------------------
//
void TSRTPUtils::Write16( TUint8* const aPointer, TUint16 aValue )
    {
    // check value range (16 bits)
    aPointer[0] = static_cast<TUint8>( ( aValue & 0xFF00 ) >> 8 );
    aPointer[1] = static_cast<TUint8>( aValue & 0x00FF );
    }
    
// ---------------------------------------------------------------------------
// TSRTPUtils::Write32()
// Write a 32-bit aValue as 4 consecutive bytes in MSB order
// Memory (at least 4 bytes) must have been allocated to aPointer
// before the function is called.
// ---------------------------------------------------------------------------
void TSRTPUtils::Write32( TUint8* const aPointer, TUint32 aValue )
    {
    aPointer[0] = static_cast<TUint8>( ( aValue & 0xFF000000 ) >> 24 );
    aPointer[1] = static_cast<TUint8>( ( aValue & 0x00FF0000 ) >> 16 );
    aPointer[2] = static_cast<TUint8>( ( aValue & 0x0000FF00 ) >> 8 );
    aPointer[3] = static_cast<TUint8>( aValue & 0x000000FF );
    }

// ---------------------------------------------------------------------------
// TUint32 TSRTPUtils::Read32()
// Read a 32-bit aValue given as 4 consecutive bytes in MSB order
// Memory (at least 4 bytes) must have been allocated to aPointer
// before the function is called.
// ---------------------------------------------------------------------------
TUint32 TSRTPUtils::Read32( const TUint8* const aPointer )
    {
    return ( aPointer[3] +
             ( static_cast<TUint32>( aPointer[2] ) << 8 ) +
             ( static_cast<TUint32>( aPointer[1] ) << 16 ) +
             ( static_cast<TUint32>( aPointer[0] ) << 24 ) );
    }
                             
// ---------------------------------------------------------------------------
// TSRTPUtils::Cnt_x()
// ---------------------------------------------------------------------------
//
void TSRTPUtils::Cnt_x(const TUint64 a_key_id, TDes8& aRes, const TDesC8& aSalt)
    {  
                    
    TBuf8<32> key_id;    
    TBuf8<16> key_id_dehexed;    
            
    key_id.AppendNumUC(a_key_id, EHex); 
    TSRTPUtils::DeHex(key_id, key_id_dehexed); 
        
    aRes.Copy(aSalt);
    
    TUint key_length = key_id_dehexed.Length();
    TUint salt_length = aRes.Length();
    TInt i,j;
    
    for (i=key_length-1, j=salt_length-1; i>=0; i--, j--)
        {
        aRes[j] = key_id_dehexed[i] ^ aRes[j];        
        }      
    }



// ---------------------------------------------------------------------------
// TSRTPUtils::SrtpDIV()
// ---------------------------------------------------------------------------
//
TUint64 TSRTPUtils::SrtpDIV(const TUint64 aA ,const TUint64 aB)
    {   
    if (aB == 0)
        {
        return 0;        
        }
    else
        {
        return (aA / aB);
        }
    }


// ---------------------------------------------------------------------------
// TSRTPUtils::HexVal()
// ---------------------------------------------------------------------------
//
TUint8 TSRTPUtils::HexVal(TUint8 c)
	{
	if (c >= 'a' && c <= 'f')
		return (TUint8)(c - 'a' + 10);
	else if (c >= 'A' && c <= 'F')
		return (TUint8)(c - 'A' + 10);
	else if (c >= '0' && c <= '9')
		return (TUint8)(c - '0');
	else
		return 0;
	}

// ---------------------------------------------------------------------------
// TSRTPUtils::HexString()
// ---------------------------------------------------------------------------
//
void TSRTPUtils::HexString(HBufC8& aString)
    {
    TPtr8 ptr=aString.Des();
    if (aString.Length()%2)
        {
        ptr.SetLength(0);
        return;
        }
    TInt i;
    for (i=0;i<aString.Length();i+=2)
        {
        TUint8 tmp;
        tmp=(TUint8)(aString[i]-(aString[i]>'9'?('A'-10):'0'));
        tmp*=16;
        tmp|=(TUint8)(aString[i+1]-(aString[i+1]>'9'?('A'-10):'0'));
        ptr[i/2]=tmp;
        }
    ptr.SetLength(aString.Length()/2);
    }	

	
// ---------------------------------------------------------------------------
// TSRTPUtils::DeHex()
// ---------------------------------------------------------------------------
//
void TSRTPUtils::DeHex(const TDesC8 &aSrc, TDes8 &aDest)
	{
	const TUint8 *s = aSrc.Ptr();
	int i = aSrc.Length();
	TUint8 d1, d2;

    TReal remainder;
    Math::Mod(remainder,i,2);
    if (remainder>0)
        {
		d1 = TSRTPUtils::HexVal(*s++);        
		aDest.Append((TUint8)(d1));	
		i--;	    		    
        }	
	    while (i > 0)
		    {
		    d1 = TSRTPUtils::HexVal(*s++);
		    d2 = TSRTPUtils::HexVal(*s++);		    
		    aDest.Append((TUint8)(d1 * 16 + d2));		    
		    i -= 2;
		    }        
	}

#ifdef _SRTP_FILE

// ---------------------------------------------------------------------------
// TInt TSRTPUtils::Print()
// 
// ---------------------------------------------------------------------------
//

void  TSRTPUtils::Print( const TDesC& aName, const TDesC& aP )
    {
    HBufC* msg = NULL;
    TRAPD( msgError, msg = HBufC::NewL( aP.Length() + 20 ) );
    if ( msgError != KErrNone )
       	{
    	delete msg; msg = NULL;
    	return;
    	}
    	
    TPtr16 b( msg->Des() );

    b.Append( KSRTPString );
   
    b.AppendFormat( _L( "%u - " ), ( TUint * ) ( TSRTPUtils::GtGetTime() ) );

    b.Append( aP );
    b.Append( _L( "\n" ) );

    TFileUtil::LogMessage( aName, b );

    delete msg;
    
    }

// ---------------------------------------------------------------------------
// TInt TSRTPUtils::Print()
// 
// ---------------------------------------------------------------------------
//
void TSRTPUtils::Print( const TDesC& aName, const TDesC& aP, TInt aValue )
    {
    HBufC* msg = NULL;
    TRAPD( msgError, msg = HBufC::NewL( aP.Length() + 106 ) );
    if ( msgError != KErrNone )
        {
    	delete msg; msg = NULL;
    	return;
    	}

    TPtr16 b( msg->Des() );
    b.Append( KSRTPString );

    //apend current time
    b.AppendFormat( _L( "%u - " ), ( TUint * ) ( TSRTPUtils::GtGetTime() ) );
    b.Append( aP );
    b.AppendFormat( _L( "<%d> " ), aValue );
    b.Append( _L( "\n" ) );

    TFileUtil::LogMessage( aName, b );

    delete msg;
    }

// ---------------------------------------------------------------------------
// TInt TFileUtil::LogMessage()
// 
// ---------------------------------------------------------------------------
//
TInt TFileUtil::LogMessage( const TFileName& name, const TDesC& mess )
    {
    RFs fs;
    RFile file;
    TFileName nameWithPath;

    nameWithPath = KDefaultPath;
    nameWithPath.Append( name );
    nameWithPath.ZeroTerminate();
    TInt err = fs.Connect();

    if ( err != KErrNone )
        return err;

    err = file.Open( fs, nameWithPath, EFileStream | EFileWrite | EFileShareExclusive );
    if ( err == KErrNotFound )
        err = file.Create( fs, nameWithPath, EFileStream | EFileWrite | EFileShareExclusive );
    if ( err != KErrNone )
        return err;

    TInt off( 0 );
    err = file.Seek( ESeekEnd, off );
    if ( err != KErrNone )
        return err;
  
    file.Write( DES_AS_8_BIT (mess) );
    file.Flush();
    file.Close();
    fs.Close();

    return KErrNone;
    }

// ---------------------------------------------------------------------------
// TInt TFileUtil::InitLogFile()
// 
// ---------------------------------------------------------------------------
//
TInt TFileUtil::InitLogFile( const TFileName& name )
    {
    RFs fs;
    RFile file;
    TFileName nameWithPath;

    nameWithPath = KDefaultPath;
    nameWithPath.Append( name );
    nameWithPath.ZeroTerminate();
    TInt err = fs.Connect();

    if ( err != KErrNone )
        return err;

    err = file.Replace( fs, nameWithPath, EFileStream | EFileWrite | EFileShareExclusive );
    if ( err != KErrNone )
        return err;

    file.Close();
    fs.Close();

    return KErrNone;
    }

// ---------------------------------------------------------------------------
// void SrtpPrint()
// Utility function for logging a string
// ---------------------------------------------------------------------------
//
void TSRTPUtils::SrtpPrintToFile( TPtrC8 aString )
    {
	TSRTPUtils::OctetToHexString( aString, aString.Length(), KLogFile );      	
    }

// ---------------------------------------------------------------------------
// void TSRTPUtils::OctetToHexString()
// Write the Hex Character to the files
// ---------------------------------------------------------------------------
//
void
TSRTPUtils::OctetToHexString(TPtrC8 aString, int length, const TDesC& aName) 
	{
  
	  TBuf<256> test;
	  int i;
	  
	  /* double length, since one octet takes two hex characters */
	  TInt len= length *2;
	  if (len<256)
	  	{
	  	
	    for (i=0;i<length;i++)
	        {
	        TUint8 di;
	        di= (TUint8)((aString[i]>>4)&0xF);
	        test.AppendNumUC(di, EHex);
	        di=(TUint8)(aString[i]&0xF);
	        test.AppendNumUC(di, EHex);
	        }
	    test.Append( _L( "\n" ));
			
	   	TFileUtil::LogMessage( aName, test );
	  	}
	}
	
#endif

#ifdef _DEBUG
	    
// ---------------------------------------------------------------------------
// TInt TSRTPUtils::Print()
// 
// ---------------------------------------------------------------------------
//

void TSRTPUtils::Print( const TDesC& aP )
    {
    HBufC* msg = NULL;
    TRAPD( msgError, msg = HBufC::NewL( aP.Length() + 20 ) );
    if ( msgError != KErrNone )
    	{
    	delete msg; msg = NULL;
    	return;
    	}
        
    TPtr16 b( msg->Des() );

    b.Append( KSRTPString );
   
    //apend current time
    b.AppendFormat( _L( "%u - " ), ( TUint * ) ( TSRTPUtils::GtGetTime() ) );

    b.Append( aP );
    b.Append( _L( "\n" ) );

    TBuf<128> buf;
    buf.Copy( b );
    RDebug::Print( buf );

    delete msg;
    }



// ---------------------------------------------------------------------------
// TInt TSRTPUtils::Print()
// 
// ---------------------------------------------------------------------------
//
void TSRTPUtils::Print( const TDesC& aP, TInt aValue )
    {
    HBufC* msg = NULL;
    TRAPD( msgError, msg = HBufC::NewL( aP.Length() + 106 ) );
    if ( msgError != KErrNone )
       	{
    	delete msg; msg = NULL;
    	return;
    	}
    	
    TPtr16 b( msg->Des() );
    b.Append( KSRTPString );

    //apend current time
    b.AppendFormat( _L( "%u - " ), ( TUint * ) ( TSRTPUtils::GtGetTime() ) );
    b.Append( aP );
    b.AppendFormat( _L( "<%d> " ), aValue );
    b.Append( _L( "\n" ) );

    TBuf<128> buf;
    buf.Copy( b );
    RDebug::Print( buf );

    delete msg;
    }


// ---------------------------------------------------------------------------
// TUint TSRTPUtils::GtGetTime()
// Return time elapse from 01/01/1970 in tenth of millsecond
// ---------------------------------------------------------------------------
//
TUint TSRTPUtils::GtGetTime()
    {
    TTimeIntervalMicroSeconds32 uspertick;     // scale factor: number of microseconds per system tick
    UserHal::TickPeriod( uspertick );
    return static_cast<TUint>( uspertick.Int() // number of '1us periods' per system tick 
            * User::TickCount()                // number of system ticks
            / 100 );                           // in tenths of ms, note still wraps after 5 days.
    }


#endif