stdlibs/libcrypt/test/src/tcrypt.cpp
changeset 50 79045913e4e9
equal deleted inserted replaced
49:e5d77a29bdca 50:79045913e4e9
       
     1 /*
       
     2 * Copyright (c) 2010 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:
       
    15 *
       
    16 */
       
    17 
       
    18 // INCLUDE FILES
       
    19 #include <e32svr.h>
       
    20 #include "tcrypt.h"
       
    21 
       
    22 // EXTERNAL FUNCTION PROTOTYPES  
       
    23 extern "C" {
       
    24 IMPORT_C char *crypt(const char *key, const char *salt);
       
    25 IMPORT_C void setkey(const char *key);
       
    26 IMPORT_C void encrypt(char block[], int edflag);
       
    27 }
       
    28 
       
    29 // LOCAL FUNCTION PROTOTYPES
       
    30 LOCAL_C void GetBitVector(char data[], char* buffer);
       
    31 LOCAL_C char *TrimWhiteSpaces(char *string);
       
    32 
       
    33 // ============================= LOCAL FUNCTIONS ===============================
       
    34 
       
    35 // -----------------------------------------------------------------------------
       
    36 // TrimWhiteSpaces
       
    37 // To to trim whitespaces in the input string
       
    38 // -----------------------------------------------------------------------------
       
    39 //
       
    40 LOCAL_C char *TrimWhiteSpaces(char *string)
       
    41 {
       
    42 	char *pTemp = string;
       
    43 	for(;*string != '\0'; string++)
       
    44 	{
       
    45 		if((*string == ' ') || (*string == '\t'))
       
    46 		{
       
    47 			pTemp++;
       
    48 		}
       
    49 	}
       
    50 	
       
    51 	return pTemp;
       
    52 }
       
    53 
       
    54 // -----------------------------------------------------------------------------
       
    55 // GetBitVector
       
    56 // This function unpacks the byte to obtain the corresponding bit vector
       
    57 // -----------------------------------------------------------------------------
       
    58 //
       
    59 LOCAL_C void GetBitVector(char data[], char* buffer)
       
    60 {
       
    61 	int temp;
       
    62 	if(buffer != NULL )
       
    63 	{
       
    64 		temp = strlen(buffer);
       
    65 		for(int i = 0 ; i<temp ; ++i, ++buffer)
       
    66 		{
       
    67 			data[i] = *buffer - '0';
       
    68 		}
       
    69 	}
       
    70 }
       
    71 
       
    72 
       
    73 CTestCrypt::~CTestCrypt() 
       
    74 	{ 
       
    75 	
       
    76 	}  
       
    77 
       
    78 CTestCrypt::CTestCrypt(const TDesC& aStepName)
       
    79 	{
       
    80 	// MANDATORY Call to base class method to set up the human readable name for logging.
       
    81 	SetTestStepName(aStepName);		
       
    82 	}
       
    83 
       
    84 TVerdict CTestCrypt::doTestStepPreambleL()
       
    85 	{
       
    86 	__UHEAP_MARK;	
       
    87 	
       
    88 	SetTestStepResult(EPass);
       
    89 	iTestDataFile = fopen("C:\\tcrypt\\test_data.dat", "r");	
       
    90 	if(iTestDataFile == NULL)
       
    91 		{
       
    92 		SetTestStepResult(EFail);	
       
    93 		}
       
    94 
       
    95 	return TestStepResult();
       
    96 	}
       
    97 
       
    98 TVerdict CTestCrypt::doTestStepPostambleL()
       
    99 	{
       
   100 	fclose(iTestDataFile);
       
   101 	__UHEAP_MARKEND;	
       
   102 	return TestStepResult();
       
   103 	}
       
   104 
       
   105 TVerdict CTestCrypt::doTestStepL()
       
   106 	{
       
   107 	int err;
       
   108 		
       
   109 	if(TestStepName() == KEncrypt)
       
   110 		{
       
   111    		INFO_PRINTF1(_L("Encrypt():"));
       
   112    		err = Encrypt();
       
   113    		SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass);
       
   114    		}
       
   115 	else if(TestStepName() == KCrypt)
       
   116 		{
       
   117    		INFO_PRINTF1(_L("Crypt():"));
       
   118    		err = Crypt();
       
   119    		SetTestStepResult(err ? static_cast<TVerdict>(err) : EPass);
       
   120    		}
       
   121   		
       
   122    	return TestStepResult(); 
       
   123 	}
       
   124 
       
   125 
       
   126 // -----------------------------------------------------------------------------
       
   127 // CTestCrypt::Encrypt
       
   128 // Encrypt function
       
   129 // -----------------------------------------------------------------------------
       
   130 //
       
   131 TInt CTestCrypt::Encrypt()
       
   132 {
       
   133 	static int tId = 0;
       
   134 	char pTemp[30];
       
   135 	memset(pTemp, 0, 30);
       
   136 	sprintf(pTemp, "ENCRYPT_TEST_DATA_%d", ++tId);
       
   137     INFO_PRINTF2(_L("Begin: ENCRYPT_TEST_DATA_%d\n"), tId);
       
   138  
       
   139     // locate "test_data_id" from within the file
       
   140     if(!RepositionFilePointer(pTemp))
       
   141     {
       
   142     	// String not found...invalid test data ID
       
   143     	INFO_PRINTF1(_L("Requested test data ID could not be found\n"));
       
   144     	return KErrNotFound;
       
   145     }
       
   146 
       
   147 	// Get the key, data block, operation to be performed and the 
       
   148 	// expected output for the current test data ID
       
   149 	char key[64] = 
       
   150 	{
       
   151 		 0
       
   152 	};
       
   153 	char block[64] = 
       
   154 	{
       
   155 		0
       
   156 	};
       
   157 	char output[64] = 
       
   158 	{
       
   159 		0
       
   160 	};
       
   161 	int edflag = -1;
       
   162 	if(GetEncryptTestData(key, block, &edflag, output) != KErrNone)
       
   163 	{
       
   164 		// Test data not found or is not present in the expected 
       
   165 		// format
       
   166 		INFO_PRINTF1(_L("Test data not found or is not present in the expected format\n"));
       
   167 		return KErrNotFound;
       
   168 	}
       
   169 	
       
   170 	// Perform encryption/decryption
       
   171 	
       
   172 	// Invoke setkey from the libcrypt library
       
   173 	setkey(key);
       
   174 	
       
   175 	// Call the encrypt function
       
   176 	encrypt(block,edflag);
       
   177 	
       
   178 	// Verify if the final output is same as the expected output
       
   179 
       
   180 	if(!strcmp(block,block))
       
   181 	{
       
   182 		INFO_PRINTF2(_L("End: ENCRYPT_TEST_DATA_%d\n"), tId);
       
   183 		// Test case passed
       
   184 		return KErrNone;
       
   185 	}
       
   186 	INFO_PRINTF1(_L("Output from the encrypt() function does not match the \"expected output\""));
       
   187 	INFO_PRINTF2(_L("End: ENCRYPT_TEST_DATA_%d\n"), tId);
       
   188 	return KErrNotFound;
       
   189 }
       
   190 
       
   191 // -----------------------------------------------------------------------------
       
   192 // CTestCrypt::RepositionFilePointer
       
   193 // This function positions the file pointer to the line immediately following
       
   194 // the string aString
       
   195 // -----------------------------------------------------------------------------
       
   196 //
       
   197 
       
   198 TInt CTestCrypt::RepositionFilePointer(const char *aString)
       
   199 {
       
   200     char buffer[256];
       
   201    	char * ptr = NULL;
       
   202     while(fgets((char*)buffer, 256, iTestDataFile) != NULL)
       
   203     {
       
   204     	 ptr = NULL;
       
   205     
       
   206     	if((ptr=strchr(buffer,'\r')) || (ptr=strchr(buffer,'\n'))) //check for both
       
   207 		*ptr='\0';
       
   208     	if(!strcmp(buffer, aString))
       
   209     	{
       
   210     		return 1;
       
   211     	}
       
   212     	memset(buffer, 0, 256);
       
   213     }
       
   214     return 0;
       
   215 }
       
   216 
       
   217 // -----------------------------------------------------------------------------
       
   218 // CTestCrypt::GetEncryptTestData
       
   219 // This function reads the test data for encrypt() API
       
   220 // -----------------------------------------------------------------------------
       
   221 //
       
   222 TInt CTestCrypt::GetEncryptTestData(char key[], char block[], int *edflag, char output[])
       
   223 {
       
   224 	char buffer[256];
       
   225 	char *p = NULL;
       
   226 	bool bKey = false,		// will be set to true upon reading 'key'
       
   227 	     bBlock = false,    // will be set to true upon reading 'data block'
       
   228 	     bEdflag = false,   // will be set to true upon reading 'edflag'
       
   229 	     bOutput = false;   // will be set to true upon reading 'expected output'
       
   230 	     
       
   231 	char *pTemp = NULL;
       
   232    	char * ptr = NULL;
       
   233 
       
   234 	while((p = fgets(buffer, 256, iTestDataFile)) != NULL)
       
   235 	{
       
   236 
       
   237 		ptr = NULL;
       
   238     
       
   239     	if((ptr=strchr(buffer,'\r')) || (ptr=strchr(buffer,'\n'))) //check for both
       
   240 			*ptr='\0';
       
   241 		if(strstr(buffer, "//") != NULL)
       
   242 		{
       
   243 			continue;
       
   244 		}
       
   245 		if(!strcmp(buffer, "END_TEST_DATA"))
       
   246 		{
       
   247 			if(bKey && bBlock && bEdflag && bOutput)
       
   248 			{
       
   249 				return KErrNone;
       
   250 			}
       
   251 			return KErrNotFound;
       
   252 		}
       
   253 		if(strstr(buffer, "KEY") != NULL)
       
   254 		{
       
   255 			// Read the key
       
   256 			
       
   257 			// Get bytes...
       
   258 			pTemp = strstr(buffer, ":");
       
   259 			if(pTemp != NULL)
       
   260 			{
       
   261 				pTemp++;
       
   262 			    pTemp = TrimWhiteSpaces(pTemp);
       
   263 				GetBitVector(key, pTemp);
       
   264 			}
       
   265 			bKey = true;
       
   266 			continue;
       
   267 		}
       
   268 		if(strstr(buffer, "DATA_BLOCK") != NULL)
       
   269 		{
       
   270 			// Read the data block
       
   271 			
       
   272 			pTemp = strstr(buffer, ":");
       
   273 			if(pTemp != NULL)
       
   274 			{
       
   275 				pTemp++;
       
   276 				pTemp = TrimWhiteSpaces(pTemp);
       
   277 				GetBitVector(block, pTemp);
       
   278 			}
       
   279 			bBlock = true;
       
   280 			continue;
       
   281 		}
       
   282 		if(strstr(buffer, "ED_FLAG") != NULL)
       
   283 		{
       
   284 			// Read the ed_flag parameter
       
   285 			
       
   286 			pTemp = strstr(buffer, ":");
       
   287 			if(pTemp != NULL)
       
   288 			{
       
   289 				pTemp++;
       
   290 				pTemp = TrimWhiteSpaces(pTemp);
       
   291 				*edflag = (*pTemp) - '0';
       
   292 			}
       
   293 			bEdflag = true;
       
   294 			continue;
       
   295 		}
       
   296 		if(strstr(buffer, "EXPECTED_OUTPUT") != NULL)
       
   297 		{
       
   298 			// Read the bit vector for the expected output
       
   299 			
       
   300 			pTemp = strstr(buffer, ":");
       
   301 			if(pTemp != NULL)
       
   302 			{
       
   303 				pTemp++;
       
   304 				pTemp = TrimWhiteSpaces(pTemp);
       
   305 				GetBitVector(output, pTemp);
       
   306 			}
       
   307 			bOutput = true;
       
   308 			continue;
       
   309 		}
       
   310 	}
       
   311 	
       
   312 	return KErrNotFound;
       
   313 }
       
   314 
       
   315 // -----------------------------------------------------------------------------
       
   316 // CTestCrypt::Crypt
       
   317 // Test function to perform crypt() on the input data
       
   318 // -----------------------------------------------------------------------------
       
   319 //
       
   320 TInt CTestCrypt::Crypt()
       
   321 {
       
   322 	static int tId = 0;
       
   323 	char pTemp[30];
       
   324 	memset(pTemp, 0, 30);
       
   325 	sprintf(pTemp, "CRYPT_TEST_DATA_%d", ++tId);
       
   326     INFO_PRINTF2(_L("Begin CRYPT_TEST_DATA_%d\n"), tId);
       
   327     
       
   328     // locate "test_data_id" from within the file
       
   329     if(!RepositionFilePointer(pTemp))
       
   330     {
       
   331     	// String not found...invalid test data ID
       
   332     	INFO_PRINTF1(_L("Requested test data ID could not be found\n"));
       
   333     	return KErrNotFound;
       
   334     }
       
   335     
       
   336     char password[34] = 
       
   337     {
       
   338     	'\0'
       
   339     };
       
   340     char salt[30] = 
       
   341     {
       
   342     	'\0'
       
   343     };
       
   344     char output[35] = 
       
   345     {
       
   346     	'\0'
       
   347     };
       
   348     
       
   349     if(GetCryptTestData(password, salt, output) != KErrNone)
       
   350     {
       
   351     	// Data not in the expected format or is invalid
       
   352     	INFO_PRINTF1(_L("Test data not found or is not present in the expected format\n"));
       
   353     	return KErrNotFound;
       
   354     }
       
   355     
       
   356     char *crypt_output = NULL;
       
   357     // Invoke crypt()
       
   358     crypt_output = crypt(password,salt);
       
   359 	if(!strcmp(output,""))
       
   360 	{
       
   361 		// Since salt is NULL, the expected output is ignored...
       
   362 		return KErrNone;
       
   363 	}
       
   364     if(!strcmp(salt, ""))
       
   365     {
       
   366 		// salt is NULL, so skip the first byte from the crypt output
       
   367 		if(crypt_output != NULL)
       
   368 		{
       
   369 			crypt_output++;
       
   370 			if(!strcmp(crypt_output, &output[0]))
       
   371 			{
       
   372 				INFO_PRINTF2(_L("End: CRYPT_TEST_DATA_%d\n"), tId);
       
   373 				return KErrNone;
       
   374 			}
       
   375 			INFO_PRINTF1(_L("Output from the crypt() function does not match the \"expected output\""));
       
   376 			return KErrNotFound;
       
   377 		}
       
   378     }
       
   379     else
       
   380     {
       
   381     	// salt is not NULL
       
   382     	if(!strcmp(crypt_output, output))
       
   383     	{
       
   384     		INFO_PRINTF2(_L("End: CRYPT_TEST_DATA_%d\n"), tId);
       
   385     		return KErrNone;
       
   386     	}
       
   387     	INFO_PRINTF1(_L("Output from the crypt() function does not match the \"expected output\""));
       
   388     	return KErrNotFound;
       
   389     }
       
   390     return KErrNotFound;
       
   391 }
       
   392 
       
   393 // -----------------------------------------------------------------------------
       
   394 // CTestCrypt::GetCryptTestData
       
   395 // To retrieve the test data for crypt() API
       
   396 // -----------------------------------------------------------------------------
       
   397 //
       
   398 TInt CTestCrypt::GetCryptTestData(char password[], char salt[], char output[])
       
   399 {
       
   400 	char buffer[256];
       
   401 	char *p = NULL;
       
   402 	char *pTemp = NULL;
       
   403 	int nLength = 0;
       
   404 	bool bPassword = false,
       
   405 	     bSalt = false,
       
   406 	     bOutput = false;
       
   407    	char * ptr = NULL;
       
   408 
       
   409 	while((p = fgets(buffer, 256, iTestDataFile)) != NULL)
       
   410 	{
       
   411     	ptr = NULL;
       
   412     
       
   413     	if((ptr=strchr(buffer,'\r')) || (ptr=strchr(buffer,'\n'))) //check for both
       
   414 			*ptr='\0';
       
   415 		if(strstr(buffer, "//") != NULL)	// skip the comments
       
   416 		{
       
   417 			// "//" could appear within password or salt, so further
       
   418 			// check is required
       
   419 			
       
   420 			// Since judicious use of whitespaces is allowed only from within
       
   421 			// the comment lines, the comment line will always start with
       
   422 			// "//"
       
   423 			if(buffer[0] == '/' && buffer[1] == '/')
       
   424 			{
       
   425 				continue;
       
   426 			}
       
   427 		}
       
   428 		if(!strcmp(buffer, "END_TEST_DATA"))
       
   429 		{
       
   430 			if(bPassword && bSalt && bOutput)
       
   431 			{
       
   432 				return KErrNone;
       
   433 			}
       
   434 			return KErrNotFound;
       
   435 		}
       
   436 
       
   437 		// Verify if the input buffer has "data". Data is followed by ":"
       
   438 		pTemp = strstr(buffer, ":");
       
   439 		if(pTemp != NULL)
       
   440 		{
       
   441 			pTemp++;
       
   442 			pTemp = TrimWhiteSpaces(pTemp);
       
   443 			nLength = strlen(pTemp);
       
   444 			if(strstr(buffer, "PASSWORD") != NULL)
       
   445 			{
       
   446 				strncpy(password,pTemp,nLength);
       
   447 				bPassword = true;
       
   448 				continue;
       
   449 			}
       
   450 			else if(strstr(buffer, "SALT") != NULL)
       
   451 			{
       
   452 				strncpy(salt,pTemp,nLength);
       
   453 				bSalt = true;
       
   454 				continue;
       
   455 			}
       
   456 			else if(strstr(buffer, "EXPECTED_OUTPUT") != NULL)
       
   457 			{
       
   458 				strncpy(output,pTemp,nLength);
       
   459 				bOutput = true;
       
   460 				continue;
       
   461 			}
       
   462 			else
       
   463 			{
       
   464 				// Unexpected output
       
   465 				return KErrNotFound;
       
   466 			}
       
   467 		}
       
   468 	}
       
   469 	return KErrNotFound;
       
   470 }
       
   471 
       
   472 //  End of File
       
   473