os/security/crypto/weakcryptospi/test/tcryptospi/src/symmetriccipherobjectreusestep.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 /*
     2 * Copyright (c) 2007-2009 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 the License "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: 
    15 * Example CTestStep derived implementation
    16 *
    17 */
    18 
    19 
    20 /**
    21  @file
    22  @internalTechnology
    23 */
    24 #include "symmetriccipherobjectreusestep.h"
    25 
    26 #include "filewriter.h"
    27 #include "filecompare.h"
    28 
    29 using namespace CryptoSpi;
    30 
    31 
    32 CSymmetricCipherObjectReuseStep::CSymmetricCipherObjectReuseStep(TInt aOffset) : iOffset(aOffset)
    33 	{
    34 	}
    35 
    36 
    37 CSymmetricCipherObjectReuseStep::~CSymmetricCipherObjectReuseStep()
    38 	{
    39 	}
    40 
    41 
    42 TVerdict CSymmetricCipherObjectReuseStep::doTestStepPreambleL()
    43 	{
    44 	SetTestStepResult(EPass);
    45 	return TestStepResult();
    46 	}
    47 
    48 
    49 TVerdict CSymmetricCipherObjectReuseStep::doTestStepL()
    50 	{
    51 	INFO_PRINTF1(_L("*** Symmetric Cipher - Object Reuse ***"));
    52 	INFO_PRINTF2(_L("HEAP CELLS: %d"), User::CountAllocCells());
    53   	if (TestStepResult()==EPass)
    54 		{
    55 		
    56 		//Assume failure, unless all is successful
    57 		SetTestStepResult(EFail);
    58 		
    59 		TPtrC keyPath;
    60 		TPtrC srcPath;
    61 		TVariantPtrC algorithm;
    62 		TVariantPtrC operationMode;
    63 		TVariantPtrC paddingMode;
    64 		
    65 		if(	!GetStringFromConfig(ConfigSection(),KConfigEncryptKey, keyPath) ||
    66 			!GetStringFromConfig(ConfigSection(),KConfigSourcePath, srcPath) || 
    67 			!GetStringFromConfig(ConfigSection(),KConfigAlgorithmUid, algorithm) || 
    68 			!GetStringFromConfig(ConfigSection(),KConfigOperationMode, operationMode) ||
    69 			!GetStringFromConfig(ConfigSection(),KConfigPaddingMode, paddingMode ))
    70 			{
    71 			User::Leave(KErrNotFound);
    72 			}
    73 		else
    74 			{
    75 			
    76 			//Create an instance of TKeyProperty
    77 			TKeyProperty keyProperty;
    78 			
    79 			//Load the key data using the
    80 			CFileReader* keyData = CFileReader::NewLC(keyPath);
    81 			
    82 			CCryptoParams* params = CCryptoParams::NewLC(); 
    83 			params->AddL( *keyData, KSymmetricKeyParameterUid); 
    84 			
    85 			CKey* key=CKey::NewL(keyProperty, *params);
    86 			CleanupStack::PushL(key);
    87 			
    88 			CCryptoParams* xparams = NULL;
    89 			
    90 			if (TUid(algorithm) == KArc4Uid)
    91 				{
    92 				//Set the RC4 DiscardBytes to 0
    93 				xparams = CCryptoParams::NewL();
    94 				xparams->AddL(NULL, KARC4DiscardBytes);
    95 				CleanupStack::PushL(xparams);
    96 				}
    97 
    98 			if (TUid(algorithm) == KRc2Uid)
    99 				{
   100 				TInt keylen = TPtrC8(*keyData).Length() * 8;
   101 				xparams = CCryptoParams::NewLC();
   102 				
   103 				//Set the RC2 EffectiveKeyLen according to the input key size
   104 				xparams->AddL( keylen, KRC2EffectiveKeyLenBits);
   105 				}
   106 			
   107 			INFO_PRINTF1(_L("Creating Symmetric Cipher Object..."));
   108 
   109 			// Create a Symmetric Cipher with the values from the ini config file	
   110 			CryptoSpi::CSymmetricCipher * impl = NULL;	
   111 			TRAPD(err,CSymmetricCipherFactory::CreateSymmetricCipherL
   112 										(
   113 										impl,
   114 										algorithm,
   115 										*key,
   116 										KCryptoModeEncryptUid,
   117 										operationMode,
   118 										paddingMode,
   119 										xparams));
   120 	
   121 			if(impl && (err == KErrNone))
   122 				{
   123 				CleanupStack::PushL(impl);
   124 				
   125 				const TInt KObjectReuseItterations = 5; // 5 iterations should be enough to check the object reuse feature
   126 														// the no of iteration is reduced, to reduce the time taken for execution
   127 				
   128 				//Boolean to denote the state				
   129 				TBool testPass = ETrue;
   130 				
   131 				/*************** Encrypt/Decrypt Reuse Loop ****************/
   132 				for(TInt index = 0; index < KObjectReuseItterations; index++)
   133 					{
   134 					INFO_PRINTF3(_L("i=%d : START HEAP CELLS: %d"),index, User::CountAllocCells());
   135 					
   136 					//-----RESET IMPLEMENTATION OBJECT (NORMAL LOGGING)----------
   137 					
   138 					impl->Reset();
   139 					
   140 					TRAP(err,impl->SetKeyL(*key));
   141 					
   142 					if(err != KErrNone)
   143 						{
   144 						ERR_PRINTF3(_L("*** ERROR:%d - SetKeyL() i=%d ***"),err,index);
   145 						User::Leave(err);	
   146 						}
   147 						
   148 					TRAP(err,impl->SetCryptoModeL(KCryptoModeEncryptUid));
   149 					
   150 					if(err != KErrNone)
   151 						{
   152 						ERR_PRINTF3(_L("*** ERROR:%d - SetCryptoModeL() i=%d ***"),err,index);
   153 						User::Leave(err);	
   154 						}
   155 						
   156 					if(TUid(algorithm) != KArc4Uid)
   157 						{
   158 						
   159 						impl->SetOperationModeL(operationMode);
   160 					
   161 						if(err != KErrNone)
   162 							{
   163 							ERR_PRINTF3(_L("*** ERROR:%d - SetOperationModeL() i=%d ***"),err,index);
   164 							User::Leave(err);	
   165 							}
   166 							
   167 						TRAP(err,impl->SetPaddingModeL(paddingMode));
   168 						
   169 						if(err != KErrNone)
   170 							{
   171 							ERR_PRINTF3(_L("*** ERROR:%d - SetPaddingModeL() i=%d ***"),err,index);
   172 							User::Leave(err);	
   173 							}
   174 								
   175 						}
   176 
   177 					//------------------------------------------------------
   178 					
   179 					//find out the block size for this algorithm
   180 					TInt blockSize(0);
   181 					
   182 					if (TUid(operationMode) == KOperationModeCTRUid)
   183 						{
   184 						blockSize = CtrModeCalcBlockSizeL(*impl);
   185 						}
   186 					else
   187 						{
   188 						blockSize = impl->BlockSize();	
   189 						}
   190 					
   191 					HBufC8* iv = NULL;
   192 					
   193 					if ((TUid(operationMode) == KOperationModeCBCUid) || (TUid(operationMode) == KOperationModeCTRUid))
   194 						{
   195 						// block size is in bits so to allocate the correct number of bytes divide by 8
   196 						// iv is left on the cleanup stack for the duration of the test and deleted in a conditional at the end of the outer block.
   197 						// If this conditional block changes, take care to update the condition for deleting this allocated IV, near the end of this function.
   198 						iv = HBufC8::NewLC(blockSize/8);	
   199 						
   200 						// blocksize is in bits so to allocate the correct number of 8 byte chunks divide by 64
   201 						for(TInt i = 0 ; i <blockSize/64 ; i++)
   202 						{
   203 							iv->Des().Append(_L8("12345678"));
   204 						}
   205 		
   206 						TRAP_LOG(err,impl->SetIvL(iv->Des())); 
   207 						}
   208 					
   209 					// convert to bytesize
   210 					blockSize/=8;
   211 					blockSize += iOffset;
   212 					
   213 					//read from src file
   214 					CFileReader* srcData = CFileReader::NewLC(srcPath,blockSize);
   215 					
   216 					// first step is to read from the src file one block
   217 					// at a time, encrypt that block and then write
   218 					// the encrypted block out to a temporary file.
   219 					CFileWriter* encryptedDataWriter = CFileWriter::NewLC(TPtrC(KTempEncryptedFilePath));
   220 					
   221 					TInt numBlocks = srcData->NumBlocks();
   222 					
   223 					INFO_PRINTF1(_L("Starting Incremental Encryption..."));
   224 					
   225 					for(TInt i = 1 ; i <= numBlocks ; i++)
   226 						{
   227 						TRAP_LOG(err,srcData->ReadBlockL());
   228 					
   229 						//Create buffer for encrypted data
   230 						TInt maxOutputLength = impl->MaxFinalOutputLength(TPtrC8(*srcData).Length());
   231 						HBufC8* encrypted =	HBufC8::NewLC(maxOutputLength);
   232 						TPtr8 encryptedPtr = encrypted->Des();
   233 					
   234 						if(i == numBlocks)
   235 							{
   236 							TRAP(err,impl->ProcessFinalL(*srcData, encryptedPtr));
   237 							
   238 							if(err != KErrNone)
   239 								{
   240 								ERR_PRINTF3(_L("*** ERROR:%d - ProcessFinalL() Block=%d ***"),err,i);
   241 								User::Leave(err);	
   242 								}
   243 							}
   244 						else
   245 							{
   246 							TRAP(err,impl->ProcessL(*srcData, encryptedPtr));
   247 							
   248 							if(err != KErrNone)
   249 								{
   250 								ERR_PRINTF3(_L("*** ERROR:%d - ProcessL() Block=%d ***"),err,i);
   251 								User::Leave(err);	
   252 								}
   253 							}	
   254 						
   255 						TRAP_LOG(err,encryptedDataWriter->WriteBlockL(encryptedPtr));
   256 					
   257 						CleanupStack::PopAndDestroy(encrypted); 
   258 						}
   259 						
   260 					CleanupStack::PopAndDestroy(encryptedDataWriter); 
   261 						
   262 					//Switch to Decrypt Crypto Mode
   263 					TRAP(err,impl->SetCryptoModeL(KCryptoModeDecryptUid));
   264 					
   265 					if(err != KErrNone)
   266 						{
   267 						ERR_PRINTF3(_L("*** ERROR:%d - SetCryptoModeL() i=%d ***"),err,index);
   268 						User::Leave(err);	
   269 						}
   270 
   271 					//If in CTR mode need to reset the keystream to the start of the sequence used for encryption.
   272 					if(TUid(operationMode) == KOperationModeCTRUid)
   273 						{
   274 						impl->SetIvL(iv->Des());
   275 						}
   276 
   277 					
   278 					// the next step is to read the previously encrypted data
   279 					// from the temporary file decrypting this one block
   280 					// at a time and outputing this to a temporary file.
   281 					CFileReader* encryptedDataReader = CFileReader::NewLC(TPtrC(KTempEncryptedFilePath),blockSize);
   282 					CFileWriter* decryptedDataWriter = CFileWriter::NewLC(TPtrC(KTempDecryptedFilePath));
   283 					
   284 					numBlocks = encryptedDataReader->NumBlocks();
   285 					
   286 					INFO_PRINTF1(_L("Starting Incremental Decryption..."));
   287 					
   288 					for(TInt i = 1 ; i <= numBlocks ; i++)
   289 						{
   290 						encryptedDataReader->ReadBlockL();
   291 						//Create buffer for encrypted data
   292 						TInt maxOutputLength = impl->MaxFinalOutputLength(TPtrC8(*encryptedDataReader).Length());
   293 						HBufC8* decrypted =	HBufC8::NewLC(maxOutputLength);
   294 						TPtr8 decryptedPtr = decrypted->Des();
   295 
   296 						//Perform the decryption operation
   297 						if(i == numBlocks)
   298 							{
   299 							TRAP(err,impl->ProcessFinalL(*encryptedDataReader, decryptedPtr));
   300 							
   301 							if(err != KErrNone)
   302 								{
   303 								ERR_PRINTF3(_L("*** ERROR:%d - ProcessFinalL() Block=%d ***"),err,i);
   304 								User::Leave(err);	
   305 								}
   306 							}
   307 						else
   308 							{
   309 							TRAP(err,impl->ProcessL(*encryptedDataReader, decryptedPtr));
   310 							
   311 							if(err != KErrNone)
   312 								{
   313 								ERR_PRINTF3(_L("*** ERROR:%d - ProcessL() Block=%d ***"),err,i);
   314 								User::Leave(err);	
   315 								}
   316 							}
   317 							
   318 						TRAP_LOG(err,decryptedDataWriter->WriteBlockL(decryptedPtr));
   319 					
   320 						CleanupStack::PopAndDestroy(decrypted); 
   321 						}
   322 						
   323 					CleanupStack::PopAndDestroy(decryptedDataWriter); 
   324 					CleanupStack::PopAndDestroy(encryptedDataReader); 
   325 					CleanupStack::PopAndDestroy(srcData);
   326 					
   327 					if((TUid(operationMode) == KOperationModeCBCUid) || (TUid(operationMode) == KOperationModeCTRUid))
   328 						{
   329 						// Iv is left on the cleanupstack at creation.  
   330 						// If it becomes possible for operationMode to be modified during
   331 						// the test this needs to be re-engineered.
   332 						CleanupStack::PopAndDestroy(iv);
   333 						}
   334 					
   335 					
   336 					// compare the src with the file thats been
   337 					// encrypted then decrypted
   338 					// Note: Returning 0 means that the files match
   339 					if(!TFileCompare::CompareL(srcPath,TPtrC(KTempDecryptedFilePath)))
   340 						{
   341 						INFO_PRINTF2(_L("*** PASS = Source File and Decrypted Data Match - i=%d ***"),index);
   342 						}
   343 					else
   344 						{
   345 						testPass = EFalse;
   346 						ERR_PRINTF2(_L("*** ERROR: Source File and Decrypted Data Mismatch - i=%d ***"),index);
   347 						}
   348 						
   349 					RFs rFs;
   350 					rFs.Connect();
   351 					rFs.Delete(	KTempDecryptedFilePath );
   352 					rFs.Delete(	KTempEncryptedFilePath );
   353 					rFs.Close();
   354 										
   355 					INFO_PRINTF3(_L("*** i=%d : END HEAP CELLS: %d ***"),index, User::CountAllocCells());
   356 					}
   357 					
   358 				/*************** END OF LOOP ****************/
   359 					
   360 				CleanupStack::PopAndDestroy(impl);
   361 				
   362 				if(testPass == EFalse)
   363 					{
   364 					ERR_PRINTF1(_L("*** TEST FAIL : Symmetric Cipher - Object Reuse ***"));
   365 					}
   366 				else
   367 					{
   368 					INFO_PRINTF1(_L("*** TEST PASS : Symmetric Cipher - Object Reuse ***"));
   369 					SetTestStepResult(EPass);	
   370 					}
   371 				
   372 				}
   373 			else
   374 				{
   375 				ERR_PRINTF2(_L("*** FAIL: Failed to Create Symmetric Object - %d ***"), err);
   376 				User::Leave(err);	
   377 				}
   378 								
   379 			if (TUid(algorithm) == KArc4Uid || TUid(algorithm) == KRc2Uid)
   380 				{
   381 				CleanupStack::PopAndDestroy(xparams);				
   382 				}
   383 				
   384 			CleanupStack::PopAndDestroy(key);
   385 			CleanupStack::PopAndDestroy(params);
   386 			CleanupStack::PopAndDestroy(keyData);
   387 			}
   388 		}
   389 	INFO_PRINTF2(_L("HEAP CELLS: %d"), User::CountAllocCells());
   390 
   391 	return TestStepResult();
   392 
   393 	}
   394 
   395 
   396 TVerdict CSymmetricCipherObjectReuseStep::doTestStepPostambleL()
   397 	{
   398 	return TestStepResult();
   399 	}