rtp/srtpstack/src/srtpaesctrcrypto.cpp
changeset 0 307788aac0a8
child 9 1e1cc61f56c3
equal deleted inserted replaced
-1:000000000000 0:307788aac0a8
       
     1 /*
       
     2 * Copyright (c) 2005 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:    Class for AES (in Counter Mode) encryption operations
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 
       
    21 #include "srtpaesctrcrypto.h"
       
    22 #include <e32uid.h>
       
    23 #include <symmetric.h>
       
    24 #include "srtpdef.h"
       
    25 #include "srtputils.h"
       
    26 // ---------------------------------------------------------------------------
       
    27 // CSrtpAESCTRCrypto::NewL()
       
    28 // 
       
    29 // ---------------------------------------------------------------------------
       
    30 //
       
    31 EXPORT_C CSrtpAESCTRCrypto* CSrtpAESCTRCrypto::NewL()
       
    32 	{
       
    33 	CSrtpAESCTRCrypto* self=new (ELeave) CSrtpAESCTRCrypto( );
       
    34 	return self;
       
    35 	}
       
    36 
       
    37 // ---------------------------------------------------------------------------
       
    38 // CSrtpAESCTRCrypto::~CSrtpAESCTRCrypto()
       
    39 // 
       
    40 // ---------------------------------------------------------------------------
       
    41 //
       
    42 CSrtpAESCTRCrypto::~CSrtpAESCTRCrypto()
       
    43 	{
       
    44 	}
       
    45 
       
    46 
       
    47 // ---------------------------------------------------------------------------
       
    48 // CSrtpAESCTRCrypto::CSrtpAESCTRCrypto
       
    49 // 
       
    50 // ---------------------------------------------------------------------------
       
    51 //
       
    52 CSrtpAESCTRCrypto::CSrtpAESCTRCrypto( ) 
       
    53 	{
       
    54 	}
       
    55 
       
    56 
       
    57 // ---------------------------------------------------------------------------
       
    58 // CSrtpAESCTRCrypto::KeystreamL
       
    59 // 
       
    60 // ---------------------------------------------------------------------------
       
    61 //
       
    62 EXPORT_C HBufC8* CSrtpAESCTRCrypto::KeystreamL(TUint aBitLength, 
       
    63                                                 const TDesC8& aKey, 
       
    64                                                 const TDesC8& aIV )
       
    65 	{
       
    66     TBuf8<16> iv;           //temp for IV    
       
    67     TBuf8<16> data;         //for a 128-bit piece of a keystream    
       
    68     CAESEncryptor*  encryptor = NULL;
       
    69     TUint buffLength;       //length of the result (as 8 bit descriptor)
       
    70     TUint count;          // how many 128-bit AES calls needed 
       
    71     
       
    72     buffLength = aBitLength/8;  
       
    73     if (aBitLength%8)
       
    74         {
       
    75         buffLength++;            
       
    76         }
       
    77 
       
    78     count = aBitLength/128;    
       
    79     if (aBitLength%128)
       
    80         {
       
    81         count++;            
       
    82         }
       
    83     
       
    84 	HBufC8* outputBuff = HBufC8::NewLC(16*count);
       
    85 	TPtr8 ptrOutputBuff = outputBuff->Des();	
       
    86     
       
    87     SRTP_DEBUG_TUINT_VALUE( "KeyStreamL, Check the length of aKey==16 and the length is", (aKey.Length()) );
       
    88     
       
    89     if(aKey.Length() != 16)
       
    90     	{
       
    91 	    CleanupStack::Pop(outputBuff);
       
    92         delete outputBuff;    
       
    93         outputBuff=NULL;    
       
    94     	User::Leave(KErrArgument);
       
    95     	}
       
    96     
       
    97     SRTP_DEBUG_TUINT_VALUE( "KeyStreamL, Check the length of aIV==16 and the length is", (TUint)aIV.Length() );
       
    98     
       
    99     //if IV's length is not valid
       
   100     if(aIV.Length() != 16)
       
   101     	{
       
   102 	    CleanupStack::Pop(outputBuff);
       
   103         delete outputBuff;    
       
   104         outputBuff= NULL; 
       
   105     	User::Leave(KErrArgument);
       
   106     	}    
       
   107             
       
   108     iv.Copy(aIV);
       
   109     
       
   110     SRTP_DEBUG_TUINT_VALUE( "KeyStreamL, Check aBitLength/128>KSRTPMaxKeyStreamBlocks and the length is", 
       
   111                 (TUint)aBitLength/128  );
       
   112     if(aBitLength/128 > KSRTPMaxKeyStreamBlocks)
       
   113     	{
       
   114 	    CleanupStack::Pop(outputBuff);
       
   115         delete outputBuff;    
       
   116         outputBuff=NULL;   
       
   117     	User::Leave(KErrArgument);
       
   118     	}
       
   119 
       
   120     encryptor = CAESEncryptor::NewLC(aKey);
       
   121                    
       
   122     for(int x = 0; x < count; x++)
       
   123     	{    	    	   	
       
   124     	data.Copy(iv);
       
   125     
       
   126     	encryptor->Transform(data);
       
   127 
       
   128     	IncreaseIV(iv);
       
   129     	    			
       
   130 		ptrOutputBuff.Append(data);		    	
       
   131     	}
       
   132     
       
   133     //set the size if it was changed
       
   134     TInt size= ptrOutputBuff.Size();
       
   135     ptrOutputBuff.SetLength(buffLength);
       
   136     	
       
   137 	CleanupStack::PopAndDestroy(encryptor);
       
   138     CleanupStack::Pop(outputBuff); 
       
   139        	    
       
   140     SRTP_DEBUG_TUINT_VALUE( "CSrtpAESCTRCrypto::KeystreamL ptrOutputBuff.Size()", 
       
   141     			(TUint)size );
       
   142     
       
   143     return outputBuff;	
       
   144 	}
       
   145 
       
   146 
       
   147 // ---------------------------------------------------------------------------
       
   148 // CSrtpAESCTRCrypto::EncryptL
       
   149 // 
       
   150 // ---------------------------------------------------------------------------
       
   151 //
       
   152 EXPORT_C HBufC8* CSrtpAESCTRCrypto::EncryptL(const TDesC8& aKey, 
       
   153                                             const TDesC8& aIV, 
       
   154                                             const TDesC8& aSrc)
       
   155 	{
       
   156 		
       
   157 		HBufC8* outputBuff = HBufC8::NewLC(aSrc.Length());
       
   158 		TPtr8 ptrOutputBuff = outputBuff->Des();
       
   159 			
       
   160 	    TBuf8<16> iv; //temp for IV
       
   161 	    TBuf8<16> data; //for a 128-bit piece of a keystream
       
   162 	    TBuf8<16> msg; //for a 128-bit piece of a message
       
   163 	    TInt count=0; // how many full 128-bit pieces can be made of a source
       
   164 	    
       
   165 	    CAESEncryptor* encryptor = NULL;
       
   166 	    SRTP_DEBUG_TINT_VALUE( "EncryptL, Check aBitLengh ==16 and the length is", 
       
   167 	                aKey.Length()  );
       
   168 	      
       
   169 	    //if key's length is not valid
       
   170 	    if(aKey.Length() != 16)
       
   171 	    	{
       
   172 		    CleanupStack::Pop(outputBuff);
       
   173 	        delete outputBuff;    
       
   174 	        outputBuff= NULL;
       
   175 	    	User::Leave(KErrArgument);
       
   176 	    	}
       
   177 	    SRTP_DEBUG_TINT_VALUE( "EncryptL, Check the length of aIV==16 and the length is", 
       
   178 	                aIV.Length() );
       
   179 	               
       
   180 	    //if IV's length is not valid
       
   181 	    if(aIV.Length() != 16)
       
   182 	    	{
       
   183 		    CleanupStack::Pop(outputBuff);
       
   184 	        delete outputBuff;    
       
   185 	        outputBuff= NULL;  
       
   186 	    	User::Leave(KErrArgument);
       
   187 	    	}    
       
   188 		
       
   189 		SRTP_DEBUG_TINT_VALUE("EncryptL, Check aSrc.Length()>KSRTPMaxTextLength and the length is", 
       
   190 	                aSrc.Length()  );
       
   191 	          
       
   192 	    //check that text length is less than 2^23
       
   193 	    if(aSrc.Length() > KSRTPMaxTextLength)
       
   194 	    	{
       
   195 		    CleanupStack::Pop(outputBuff);
       
   196 	        delete outputBuff;    
       
   197 	        outputBuff= NULL;    
       
   198 	    	User::Leave(KErrArgument);
       
   199 	    	}
       
   200 	            
       
   201 	    iv.Copy(aIV);
       
   202 	        
       
   203 	    count = aSrc.Length()/16;
       
   204 		
       
   205 		SRTP_DEBUG_TINT_VALUE("EncryptL, count>KSRTPMaxKeyStreamBlocks and the length is", 
       
   206 	                count  );
       
   207 	         
       
   208 
       
   209 	    if(count > KSRTPMaxKeyStreamBlocks)
       
   210 	    	{
       
   211 		    CleanupStack::Pop(outputBuff);
       
   212 	        delete outputBuff;    
       
   213 	        outputBuff= NULL;  
       
   214 	    	User::Leave(KErrArgument);
       
   215 	    	}
       
   216 
       
   217 	    encryptor = CAESEncryptor::NewLC(aKey);
       
   218 	                   
       
   219 	    for(int x = 0; x < count; x++)
       
   220 	    	{
       
   221 	    	msg.Copy(aSrc.Mid(x*16, 16));
       
   222 	    	
       
   223 	    	data.Copy(iv);
       
   224 	    	   	
       
   225 	    	encryptor->Transform(data);
       
   226 
       
   227 	    	IncreaseIV(iv);
       
   228 	    	    	
       
   229 		    // XOR 128-bits of message with encrypted IV
       
   230 		    for(int i = 0; i < 16; i++)
       
   231 				{
       
   232 				msg[i] ^= data[i];
       
   233 				}
       
   234 			
       
   235 			ptrOutputBuff.Append(msg);
       
   236 			    	
       
   237 	    	}
       
   238 	    
       
   239 	    //if source's length isn't an exact multiple of 128-bits
       
   240 	    if(aSrc.Length()%16)
       
   241 	    	{
       
   242 	    	TInt bytesleft;
       
   243 	    	bytesleft = aSrc.Length() - count*16;
       
   244 	    	
       
   245 	    	msg.Copy(aSrc.Mid(count*16, bytesleft));
       
   246 	    	data.Copy(iv);
       
   247 	    	encryptor->Transform(data);
       
   248 	    		
       
   249 		    // XOR last piece of message with encrypted IV
       
   250 		    for(int i = 0; i < bytesleft; i++)
       
   251 			{
       
   252 					msg[i] ^= data[i];
       
   253 			}
       
   254 			
       
   255 			ptrOutputBuff.Append(msg);
       
   256 			    		
       
   257 	    	}
       
   258 		
       
   259 		CleanupStack::PopAndDestroy(encryptor);
       
   260 	    CleanupStack::Pop(outputBuff);    	    
       
   261 	    
       
   262 	    return outputBuff;
       
   263 	}
       
   264 
       
   265 // ---------------------------------------------------------------------------
       
   266 // CSrtpAESCTRCrypto::IncreaseIV
       
   267 // 
       
   268 // ---------------------------------------------------------------------------
       
   269 //
       
   270 void CSrtpAESCTRCrypto::IncreaseIV(TDes8& iv)
       
   271 	{
       
   272 	
       
   273 	if(iv[15] != 0xFF)
       
   274 		{
       
   275 		iv[15] += 1;	
       
   276 		}
       
   277 	else if(iv[14] != 0xFF)
       
   278 		{
       
   279 		iv[15] = 0;
       
   280 		iv[14] += 1;
       
   281 		}
       
   282 	else if(iv[13] != 0xFF)
       
   283 		{
       
   284 		iv[15] = 0;
       
   285 		iv[14] = 0;
       
   286 		iv[13] += 1;
       
   287 		}	
       
   288 	else if (iv[12] != 0xFF)
       
   289 		{
       
   290 		iv[15] = 0;
       
   291 		iv[14] = 0;
       
   292 		iv[13] = 0;
       
   293 		iv[12] += 1;
       
   294 		}		
       
   295 	else
       
   296 		{
       
   297 		iv[15] = 0;
       
   298 		iv[14] = 0;
       
   299 		iv[13] = 0;
       
   300 		iv[12] = 0;
       
   301 		}
       
   302 
       
   303 	} 
       
   304 
       
   305