--- /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 <e32uid.h>
+#include <symmetric.h>
+#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;
+ }
+
+ }
+
+