diff -r 000000000000 -r 307788aac0a8 rtp/srtpstack/src/srtpaesctrcrypto.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtp/srtpstack/src/srtpaesctrcrypto.cpp Tue Feb 02 01:03:15 2010 +0200 @@ -0,0 +1,305 @@ +/* +* 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: Class for AES (in Counter Mode) encryption operations +* +*/ + + + + +#include "srtpaesctrcrypto.h" +#include +#include +#include "srtpdef.h" +#include "srtputils.h" +// --------------------------------------------------------------------------- +// CSrtpAESCTRCrypto::NewL() +// +// --------------------------------------------------------------------------- +// +EXPORT_C CSrtpAESCTRCrypto* CSrtpAESCTRCrypto::NewL() + { + CSrtpAESCTRCrypto* self=new (ELeave) CSrtpAESCTRCrypto( ); + return self; + } + +// --------------------------------------------------------------------------- +// CSrtpAESCTRCrypto::~CSrtpAESCTRCrypto() +// +// --------------------------------------------------------------------------- +// +CSrtpAESCTRCrypto::~CSrtpAESCTRCrypto() + { + } + + +// --------------------------------------------------------------------------- +// CSrtpAESCTRCrypto::CSrtpAESCTRCrypto +// +// --------------------------------------------------------------------------- +// +CSrtpAESCTRCrypto::CSrtpAESCTRCrypto( ) + { + } + + +// --------------------------------------------------------------------------- +// CSrtpAESCTRCrypto::KeystreamL +// +// --------------------------------------------------------------------------- +// +EXPORT_C HBufC8* CSrtpAESCTRCrypto::KeystreamL(TUint aBitLength, + const TDesC8& aKey, + const TDesC8& aIV ) + { + TBuf8<16> iv; //temp for IV + TBuf8<16> data; //for a 128-bit piece of a keystream + CAESEncryptor* encryptor = NULL; + TUint buffLength; //length of the result (as 8 bit descriptor) + TUint count; // how many 128-bit AES calls needed + + buffLength = aBitLength/8; + if (aBitLength%8) + { + buffLength++; + } + + count = aBitLength/128; + if (aBitLength%128) + { + count++; + } + + HBufC8* outputBuff = HBufC8::NewLC(16*count); + TPtr8 ptrOutputBuff = outputBuff->Des(); + + SRTP_DEBUG_TUINT_VALUE( "KeyStreamL, Check the length of aKey==16 and the length is", (aKey.Length()) ); + + if(aKey.Length() != 16) + { + CleanupStack::Pop(outputBuff); + delete outputBuff; + outputBuff=NULL; + User::Leave(KErrArgument); + } + + SRTP_DEBUG_TUINT_VALUE( "KeyStreamL, Check the length of aIV==16 and the length is", (TUint)aIV.Length() ); + + //if IV's length is not valid + if(aIV.Length() != 16) + { + CleanupStack::Pop(outputBuff); + delete outputBuff; + outputBuff= NULL; + User::Leave(KErrArgument); + } + + iv.Copy(aIV); + + SRTP_DEBUG_TUINT_VALUE( "KeyStreamL, Check aBitLength/128>KSRTPMaxKeyStreamBlocks and the length is", + (TUint)aBitLength/128 ); + if(aBitLength/128 > KSRTPMaxKeyStreamBlocks) + { + CleanupStack::Pop(outputBuff); + delete outputBuff; + outputBuff=NULL; + User::Leave(KErrArgument); + } + + encryptor = CAESEncryptor::NewLC(aKey); + + for(int x = 0; x < count; x++) + { + data.Copy(iv); + + encryptor->Transform(data); + + IncreaseIV(iv); + + ptrOutputBuff.Append(data); + } + + //set the size if it was changed + TInt size= ptrOutputBuff.Size(); + ptrOutputBuff.SetLength(buffLength); + + CleanupStack::PopAndDestroy(encryptor); + CleanupStack::Pop(outputBuff); + + SRTP_DEBUG_TUINT_VALUE( "CSrtpAESCTRCrypto::KeystreamL ptrOutputBuff.Size()", + (TUint)size ); + + return outputBuff; + } + + +// --------------------------------------------------------------------------- +// CSrtpAESCTRCrypto::EncryptL +// +// --------------------------------------------------------------------------- +// +EXPORT_C HBufC8* CSrtpAESCTRCrypto::EncryptL(const TDesC8& aKey, + const TDesC8& aIV, + const TDesC8& aSrc) + { + + HBufC8* outputBuff = HBufC8::NewLC(aSrc.Length()); + TPtr8 ptrOutputBuff = outputBuff->Des(); + + TBuf8<16> iv; //temp for IV + TBuf8<16> data; //for a 128-bit piece of a keystream + TBuf8<16> msg; //for a 128-bit piece of a message + TInt count=0; // how many full 128-bit pieces can be made of a source + + CAESEncryptor* encryptor = NULL; + SRTP_DEBUG_TINT_VALUE( "EncryptL, Check aBitLengh ==16 and the length is", + aKey.Length() ); + + //if key's length is not valid + if(aKey.Length() != 16) + { + CleanupStack::Pop(outputBuff); + delete outputBuff; + outputBuff= NULL; + User::Leave(KErrArgument); + } + SRTP_DEBUG_TINT_VALUE( "EncryptL, Check the length of aIV==16 and the length is", + aIV.Length() ); + + //if IV's length is not valid + if(aIV.Length() != 16) + { + CleanupStack::Pop(outputBuff); + delete outputBuff; + outputBuff= NULL; + User::Leave(KErrArgument); + } + + SRTP_DEBUG_TINT_VALUE("EncryptL, Check aSrc.Length()>KSRTPMaxTextLength and the length is", + aSrc.Length() ); + + //check that text length is less than 2^23 + if(aSrc.Length() > KSRTPMaxTextLength) + { + CleanupStack::Pop(outputBuff); + delete outputBuff; + outputBuff= NULL; + User::Leave(KErrArgument); + } + + iv.Copy(aIV); + + count = aSrc.Length()/16; + + SRTP_DEBUG_TINT_VALUE("EncryptL, count>KSRTPMaxKeyStreamBlocks and the length is", + count ); + + + if(count > KSRTPMaxKeyStreamBlocks) + { + CleanupStack::Pop(outputBuff); + delete outputBuff; + outputBuff= NULL; + User::Leave(KErrArgument); + } + + encryptor = CAESEncryptor::NewLC(aKey); + + for(int x = 0; x < count; x++) + { + msg.Copy(aSrc.Mid(x*16, 16)); + + data.Copy(iv); + + encryptor->Transform(data); + + IncreaseIV(iv); + + // XOR 128-bits of message with encrypted IV + for(int i = 0; i < 16; i++) + { + msg[i] ^= data[i]; + } + + ptrOutputBuff.Append(msg); + + } + + //if source's length isn't an exact multiple of 128-bits + if(aSrc.Length()%16) + { + TInt bytesleft; + bytesleft = aSrc.Length() - count*16; + + msg.Copy(aSrc.Mid(count*16, bytesleft)); + data.Copy(iv); + encryptor->Transform(data); + + // XOR last piece of message with encrypted IV + for(int i = 0; i < bytesleft; i++) + { + msg[i] ^= data[i]; + } + + ptrOutputBuff.Append(msg); + + } + + CleanupStack::PopAndDestroy(encryptor); + CleanupStack::Pop(outputBuff); + + return outputBuff; + } + +// --------------------------------------------------------------------------- +// CSrtpAESCTRCrypto::IncreaseIV +// +// --------------------------------------------------------------------------- +// +void CSrtpAESCTRCrypto::IncreaseIV(TDes8& iv) + { + + if(iv[15] != 0xFF) + { + iv[15] += 1; + } + else if(iv[14] != 0xFF) + { + iv[15] = 0; + iv[14] += 1; + } + else if(iv[13] != 0xFF) + { + iv[15] = 0; + iv[14] = 0; + iv[13] += 1; + } + else if (iv[12] != 0xFF) + { + iv[15] = 0; + iv[14] = 0; + iv[13] = 0; + iv[12] += 1; + } + else + { + iv[15] = 0; + iv[14] = 0; + iv[13] = 0; + iv[12] = 0; + } + + } + +