os/security/crypto/weakcryptospi/test/trandom/t_random.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 /*
     2 * Copyright (c) 2005-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 * (c) 1999 Symbian Ltd
    16 *
    17 */
    18 
    19 
    20 /**
    21  @file
    22 */
    23 
    24 #include <e32base.h>
    25 #include <e32std.h>
    26 #include <e32test.h>
    27 #include <random.h>
    28 #include <f32file.h>
    29 
    30 RTest test(_L("Random Number Generator"));
    31 
    32 TInt gTestPassCount = 0;
    33 TInt gTestRequestCount = 10;
    34 TInt gNumberOfRandomNumbers=10000;
    35 
    36 /** Wraps a console and logs output to a file. */
    37 class CTestConsole:public CConsoleBase
    38 	{
    39 	public:
    40 		static CTestConsole* NewL(CConsoleBase* aCon, const TDesC& aFilename);
    41 		TInt Create(const TDesC16& aTitle,TSize aSize) {return iCon->Create(aTitle,aSize);};
    42 		void Read(TRequestStatus& aStatus) {iCon->Read(aStatus);};
    43 		void ReadCancel(void) {iCon->ReadCancel();};
    44 		void Write(const TDesC16& aString);
    45 		TPoint CursorPos(void) const {return iCon->CursorPos();};
    46 		void SetCursorPosAbs(const TPoint& aPos) {iCon->SetCursorPosAbs(aPos);};
    47 		void SetCursorPosRel(const TPoint& aPos) {iCon->SetCursorPosRel(aPos);};
    48 		void SetCursorHeight(TInt aHeight) {iCon->SetCursorHeight(aHeight);};
    49 		void SetTitle(const TDesC16& aTitle) {iCon->SetTitle(aTitle);};
    50 		void ClearScreen(void) {iCon->ClearScreen();};
    51 		void ClearToEndOfLine(void) {iCon->ClearToEndOfLine();};
    52 		TSize ScreenSize(void) const {return iCon->ScreenSize();};
    53 		TKeyCode KeyCode(void) const {return iCon->KeyCode();};
    54 		TUint KeyModifiers(void) const {return iCon->KeyModifiers();};
    55 		~CTestConsole(void);
    56 	private:
    57 		CTestConsole(CConsoleBase* aCon);
    58 	    void ConstructL(const TDesC& aFilename);
    59 	    CConsoleBase* iCon;  ///< Pointer to wrapped console, we don't own this
    60 	    RFs iFs;
    61 	    RFile iFile;		 ///< Log file
    62 	};
    63 
    64 CTestConsole* CTestConsole::NewL(CConsoleBase* aCon, const TDesC& aFilename)
    65 
    66 	{
    67 	CTestConsole* self;
    68 	self=new (ELeave) CTestConsole(aCon);
    69 	CleanupStack::PushL(self);
    70 	self->ConstructL(aFilename);
    71 	CleanupStack::Pop(self);
    72 	return self;
    73 	}
    74 
    75 CTestConsole::CTestConsole(CConsoleBase* aCon) :
    76 	CConsoleBase(), iCon(aCon)
    77 
    78 	{
    79 	}
    80 
    81 void CTestConsole::ConstructL(const TDesC& aFilename)
    82 	
    83 	{
    84 	User::LeaveIfError(iFs.Connect());
    85 	User::LeaveIfError(iFile.Replace(iFs,aFilename,EFileShareAny|EFileWrite));
    86 	}
    87 
    88 CTestConsole::~CTestConsole(void)
    89 
    90 	{
    91 	iFile.Close();
    92 	iFs.Close();
    93 	}
    94 
    95 void CTestConsole::Write(const TDesC16& aString)
    96 
    97 	{
    98 	iCon->Write(aString);
    99 	TUint8 space[200];
   100 	TPtr8 ptr(space,200);
   101 	ptr.Copy(aString);
   102 	iFile.Write(ptr);
   103 	}
   104 
   105 void Monobit(const TUint8* aData)
   106 
   107 	{
   108 	const TInt bitcount[256]=
   109 		{ 0,1,1,2,1,2,2,3,		// 00-07
   110 		  1,2,2,3,2,3,3,4,		// 08-0f
   111 		  1,2,2,3,2,3,3,4,		// 10-17
   112 		  2,3,3,4,3,4,4,5,		// 18-1f
   113 		  1,2,2,3,2,3,3,4,		// 20-27
   114 		  2,3,3,4,3,4,4,5,		// 28-2f
   115 		  2,3,3,4,3,4,4,5,		// 30-37
   116 		  3,4,4,5,4,5,5,6,		// 38-3f
   117 
   118 		  1,2,2,3,2,3,3,4,		// 40-47
   119 		  2,3,3,4,3,4,4,5,		// 48-4f
   120 		  2,3,3,4,3,4,4,5,		// 50-57
   121 		  3,4,4,5,4,5,5,6,		// 58-5f
   122 		  2,3,3,4,3,4,4,5,		// 60-67
   123 		  3,4,4,5,4,5,5,6,		// 68-6f
   124 		  3,4,4,5,4,5,5,6,		// 70-77
   125 		  4,5,5,6,5,6,6,7,		// 78-7f
   126 
   127 		  1,2,2,3,2,3,3,4,		// 80-87
   128 		  2,3,3,4,3,4,4,5,		// 88-8f
   129 		  2,3,3,4,3,4,4,5,		// 90-97
   130 		  3,4,4,5,4,5,5,6,		// 98-9f
   131 		  2,3,3,4,3,4,4,5,		// a0-a7
   132 		  3,4,4,5,4,5,5,6,		// a8-af
   133 		  3,4,4,5,4,5,5,6,		// b0-b7
   134 		  4,5,5,6,5,6,6,7,		// b8-bf
   135 
   136 		  2,3,3,4,3,4,4,5,		// c0-c7
   137 		  3,4,4,5,4,5,5,6,		// c8-cf
   138 		  3,4,4,5,4,5,5,6,		// d0-d7
   139 		  4,5,5,6,5,6,6,7,		// d8-df
   140 		  3,4,4,5,4,5,5,6,		// e0-e7
   141 		  4,5,5,6,5,6,6,7,		// e8-ef
   142 		  4,5,5,6,5,6,6,7,		// f0-f7
   143 		  5,6,6,7,6,7,7,8		// f8-ff
   144 		};
   145 	TInt total=0;
   146 	TInt i;
   147 	for (i=0;i<2500;i++)
   148 		{
   149 		total+=bitcount[aData[i]];
   150 		}
   151 	test.Printf(_L("    Total bitcount %d\r\n"),total);
   152 	if ((total>9654)&&(total<10346))
   153 		{
   154 		test.Printf(_L("    Passed Monobit\r\n"));
   155 		}
   156 	else
   157 		{
   158 		test.Printf(_L("    ***FAILED!\r\n"));
   159 		User::Panic(_L("t_random.exe"), KErrGeneral);
   160 		}
   161 	}
   162 
   163 void Poker(const TUint8* aData)
   164 	
   165 	{
   166 	TInt f[16]= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
   167 	TInt i;
   168 	for (i=0;i<2500;i++)
   169 		{
   170 		f[(aData[i]&0x0f)]++;
   171 		f[((aData[i]&0xf0)>>4)]++;
   172 		}
   173 	TReal x=0;
   174 	for (i=0;i<16;i++)
   175 		{
   176 		x+=f[i]*f[i];
   177 		}
   178 	x*=16;
   179 	x/=5000;
   180 	x-=5000;
   181 	if ((x>1.03)&&(x<57.4))
   182 		{
   183 		test.Printf(_L("    Passed poker test\r\n"));
   184 		}
   185 	else
   186 		{
   187 		test.Printf(_L("    ***FAILED poker test\r\n"));
   188 		User::Panic(_L("t_random.exe"), KErrGeneral);
   189 		}
   190 	}
   191 
   192 void Runs(const TUint8* aData)
   193 
   194 	{
   195 	TInt i;
   196 	TInt lastbit=0;
   197 	TInt count[7][2]={
   198 		{ 0,0 },
   199 		{ 0,0 },
   200 		{ 0,0 },
   201 		{ 0,0 },
   202 		{ 0,0 },
   203 		{ 0,0 },
   204 		{ 0,0 }
   205 		};
   206 	TInt thisrun=0;
   207 	TInt longrun=0;
   208 	for (i=0;i<2500;i++)
   209 		{
   210 		TInt bit;
   211 		for (bit=0;bit<8;bit++)
   212 			{
   213 			if (((aData[i]>>bit)&1)==lastbit)
   214 				{
   215 				thisrun++;
   216 				}
   217 			else
   218 				{
   219 				if (thisrun<5)
   220 					{
   221 					count[thisrun][lastbit]++;
   222 					}
   223 				else
   224 					{
   225 					count[5][lastbit]++;
   226 					}
   227 				lastbit^=1;
   228 				if (thisrun>longrun)
   229 					{
   230 					longrun=thisrun;
   231 					}
   232 				thisrun=0;
   233 				}
   234 			}
   235 		}
   236 	TInt bound[6][2]=
   237 		{
   238 			{2267,2733},
   239 			{1079,1421},
   240 			{ 502, 748},
   241 			{ 223, 402},
   242 			{  90, 223},
   243 			{  90, 223}
   244 		};
   245 	TBool failed=EFalse;
   246 	for (i=0;i<6;i++)
   247 		{
   248 		if (!((count[i][0]>bound[i][0])&&(count[i][0]<bound[i][1])))
   249 			{
   250 			test.Printf(_L("    ***FAILED runs test\r\n"));
   251 			failed=ETrue;
   252 			}
   253 		if (!((count[i][1]>bound[i][0])&&(count[i][1]<bound[i][1])))
   254 			{
   255 			test.Printf(_L("    ***FAILED runs test\r\n"));
   256 			failed=ETrue;
   257 			}
   258 		}
   259 	if (!failed)
   260 		{
   261 		test.Printf(_L("    Passed runs test\r\n"));
   262 		}
   263 	if ( (longrun>34) || (failed) )
   264 		{
   265 		test.Printf(_L("    ***FAILED longrun test\r\n"));
   266 		User::Panic(_L("t_random.exe"), KErrGeneral);
   267 		}
   268 	}
   269 
   270 void FIPSTest(const TUint8* aData)
   271 //	Run some basic tests to check it's returned some numbers
   272 //	These will panic if a failure is detected
   273 	{
   274 	Monobit(aData);
   275 	Poker(aData);
   276 	Runs(aData);
   277 	}
   278 
   279 void WriteFile(const TUint8* aData,const TDesC& aFileName)
   280 
   281 	{
   282 	RFs fs;
   283 	fs.Connect();
   284 	RFile file;
   285 	TInt err;
   286 	err=file.Open(fs,aFileName,EFileShareAny|EFileWrite);
   287 	if (err)
   288 		{
   289 		if (file.Create(fs,aFileName,EFileShareAny|EFileWrite))
   290 			{
   291 			return;
   292 			}
   293 		}
   294 	TPtrC8 ptr(aData,gNumberOfRandomNumbers);
   295 	TInt size;
   296 	file.Size(size);
   297 	file.Write(size,ptr);
   298 	file.Close();
   299 	fs.Close();
   300 	FIPSTest(aData);
   301 	}
   302 
   303 void DoTestsL(void)
   304 
   305 	{
   306 	test.Printf(_L("Run random tests with normal salting\r\n"));    
   307 	TInt i;
   308 	TBuf8<16> buf2;
   309 	for (i=0;i<16;i++)
   310 		{
   311 		buf2.SetLength(i);
   312 		TRandom::RandomL(buf2);
   313 		}
   314 	
   315 	HBufC8* buf=HBufC8::NewMaxL(gNumberOfRandomNumbers);
   316 	CleanupStack::PushL(buf);
   317 	TPtr8 buffer=buf->Des();
   318 	test.Printf(_L("\nRequesting for random numbers.\n"));
   319 	for (i=0;i<gTestRequestCount;i++)
   320 		{
   321 		TPtr8 thePtr(buf->Des());		
   322 		//	Generate the random data	
   323 		TRandom::RandomL(buffer);
   324 		if (buf->Length()!=gNumberOfRandomNumbers)
   325 		    {
   326 			User::Leave(KErrGeneral);
   327 		    }
   328 		++gTestPassCount;
   329 	    test.Printf(_L("."));
   330 		}	
   331 	
   332 	// Request for Secure Random numbers.
   333 	test.Printf(_L("\nRequesting for cryptographically secure random numbers.\n"));
   334     for (i=0;i<gTestRequestCount;i++)
   335         {
   336         TPtr8 thePtr(buf->Des());        
   337 		// Generate the random data    
   338         TRAP_IGNORE(TRandom::SecureRandomL(buffer));
   339         if (buf->Length() != gNumberOfRandomNumbers)
   340             {
   341             User::Leave(KErrGeneral);
   342             }
   343         ++gTestPassCount;
   344         test.Printf(_L("."));
   345         }
   346 	CleanupStack::PopAndDestroy(buf);
   347 	}
   348 
   349 void TestsL(void)
   350 	{
   351 	TDriveUnit sysDrive (RFs::GetSystemDrive());
   352 	TBuf<64> logFile (sysDrive.Name());
   353 	logFile.Append(_L("\\t_random.log"));
   354 	CTestConsole* con = CTestConsole::NewL(test.Console(), logFile);
   355 	test.SetConsole(con);
   356 	
   357 	DoTestsL();
   358 	}
   359 
   360 GLDEF_C TInt E32Main(void)
   361 
   362 	{
   363 	CTrapCleanup* cleanup;
   364 	cleanup=CTrapCleanup::New();
   365 	
   366 	__UHEAP_MARK;
   367 	
   368 	test.Start(_L(" @SYMTestCaseID:SEC-CRYPTOSPI-RANDOM-0001 Starting random number generator tests\r\n"));
   369 	CConsoleBase* originalConsole = test.Console();
   370 
   371 	TRAPD(ret,TestsL());   
   372     // Infor the user about the test cases' status.
   373     test.Printf(_L("\n%d tests failed out of %d\r\n"), ((2*gTestRequestCount) - gTestPassCount), 2*gTestRequestCount);
   374     
   375     test (ret == KErrNone);
   376 	test.End();
   377 
   378 	if (test.Console() != originalConsole)
   379 		{
   380 		delete test.Console();
   381 		test.SetConsole(originalConsole);
   382 		}	
   383 	test.Close();
   384 	
   385 	__UHEAP_MARKEND;
   386 	
   387 	delete cleanup;
   388 	return(KErrNone);
   389 	}