1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/security/crypto/weakcryptospi/test/trandom/t_random.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,389 @@
1.4 +/*
1.5 +* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
1.6 +* All rights reserved.
1.7 +* This component and the accompanying materials are made available
1.8 +* under the terms of the License "Eclipse Public License v1.0"
1.9 +* which accompanies this distribution, and is available
1.10 +* at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.11 +*
1.12 +* Initial Contributors:
1.13 +* Nokia Corporation - initial contribution.
1.14 +*
1.15 +* Contributors:
1.16 +*
1.17 +* Description:
1.18 +* (c) 1999 Symbian Ltd
1.19 +*
1.20 +*/
1.21 +
1.22 +
1.23 +/**
1.24 + @file
1.25 +*/
1.26 +
1.27 +#include <e32base.h>
1.28 +#include <e32std.h>
1.29 +#include <e32test.h>
1.30 +#include <random.h>
1.31 +#include <f32file.h>
1.32 +
1.33 +RTest test(_L("Random Number Generator"));
1.34 +
1.35 +TInt gTestPassCount = 0;
1.36 +TInt gTestRequestCount = 10;
1.37 +TInt gNumberOfRandomNumbers=10000;
1.38 +
1.39 +/** Wraps a console and logs output to a file. */
1.40 +class CTestConsole:public CConsoleBase
1.41 + {
1.42 + public:
1.43 + static CTestConsole* NewL(CConsoleBase* aCon, const TDesC& aFilename);
1.44 + TInt Create(const TDesC16& aTitle,TSize aSize) {return iCon->Create(aTitle,aSize);};
1.45 + void Read(TRequestStatus& aStatus) {iCon->Read(aStatus);};
1.46 + void ReadCancel(void) {iCon->ReadCancel();};
1.47 + void Write(const TDesC16& aString);
1.48 + TPoint CursorPos(void) const {return iCon->CursorPos();};
1.49 + void SetCursorPosAbs(const TPoint& aPos) {iCon->SetCursorPosAbs(aPos);};
1.50 + void SetCursorPosRel(const TPoint& aPos) {iCon->SetCursorPosRel(aPos);};
1.51 + void SetCursorHeight(TInt aHeight) {iCon->SetCursorHeight(aHeight);};
1.52 + void SetTitle(const TDesC16& aTitle) {iCon->SetTitle(aTitle);};
1.53 + void ClearScreen(void) {iCon->ClearScreen();};
1.54 + void ClearToEndOfLine(void) {iCon->ClearToEndOfLine();};
1.55 + TSize ScreenSize(void) const {return iCon->ScreenSize();};
1.56 + TKeyCode KeyCode(void) const {return iCon->KeyCode();};
1.57 + TUint KeyModifiers(void) const {return iCon->KeyModifiers();};
1.58 + ~CTestConsole(void);
1.59 + private:
1.60 + CTestConsole(CConsoleBase* aCon);
1.61 + void ConstructL(const TDesC& aFilename);
1.62 + CConsoleBase* iCon; ///< Pointer to wrapped console, we don't own this
1.63 + RFs iFs;
1.64 + RFile iFile; ///< Log file
1.65 + };
1.66 +
1.67 +CTestConsole* CTestConsole::NewL(CConsoleBase* aCon, const TDesC& aFilename)
1.68 +
1.69 + {
1.70 + CTestConsole* self;
1.71 + self=new (ELeave) CTestConsole(aCon);
1.72 + CleanupStack::PushL(self);
1.73 + self->ConstructL(aFilename);
1.74 + CleanupStack::Pop(self);
1.75 + return self;
1.76 + }
1.77 +
1.78 +CTestConsole::CTestConsole(CConsoleBase* aCon) :
1.79 + CConsoleBase(), iCon(aCon)
1.80 +
1.81 + {
1.82 + }
1.83 +
1.84 +void CTestConsole::ConstructL(const TDesC& aFilename)
1.85 +
1.86 + {
1.87 + User::LeaveIfError(iFs.Connect());
1.88 + User::LeaveIfError(iFile.Replace(iFs,aFilename,EFileShareAny|EFileWrite));
1.89 + }
1.90 +
1.91 +CTestConsole::~CTestConsole(void)
1.92 +
1.93 + {
1.94 + iFile.Close();
1.95 + iFs.Close();
1.96 + }
1.97 +
1.98 +void CTestConsole::Write(const TDesC16& aString)
1.99 +
1.100 + {
1.101 + iCon->Write(aString);
1.102 + TUint8 space[200];
1.103 + TPtr8 ptr(space,200);
1.104 + ptr.Copy(aString);
1.105 + iFile.Write(ptr);
1.106 + }
1.107 +
1.108 +void Monobit(const TUint8* aData)
1.109 +
1.110 + {
1.111 + const TInt bitcount[256]=
1.112 + { 0,1,1,2,1,2,2,3, // 00-07
1.113 + 1,2,2,3,2,3,3,4, // 08-0f
1.114 + 1,2,2,3,2,3,3,4, // 10-17
1.115 + 2,3,3,4,3,4,4,5, // 18-1f
1.116 + 1,2,2,3,2,3,3,4, // 20-27
1.117 + 2,3,3,4,3,4,4,5, // 28-2f
1.118 + 2,3,3,4,3,4,4,5, // 30-37
1.119 + 3,4,4,5,4,5,5,6, // 38-3f
1.120 +
1.121 + 1,2,2,3,2,3,3,4, // 40-47
1.122 + 2,3,3,4,3,4,4,5, // 48-4f
1.123 + 2,3,3,4,3,4,4,5, // 50-57
1.124 + 3,4,4,5,4,5,5,6, // 58-5f
1.125 + 2,3,3,4,3,4,4,5, // 60-67
1.126 + 3,4,4,5,4,5,5,6, // 68-6f
1.127 + 3,4,4,5,4,5,5,6, // 70-77
1.128 + 4,5,5,6,5,6,6,7, // 78-7f
1.129 +
1.130 + 1,2,2,3,2,3,3,4, // 80-87
1.131 + 2,3,3,4,3,4,4,5, // 88-8f
1.132 + 2,3,3,4,3,4,4,5, // 90-97
1.133 + 3,4,4,5,4,5,5,6, // 98-9f
1.134 + 2,3,3,4,3,4,4,5, // a0-a7
1.135 + 3,4,4,5,4,5,5,6, // a8-af
1.136 + 3,4,4,5,4,5,5,6, // b0-b7
1.137 + 4,5,5,6,5,6,6,7, // b8-bf
1.138 +
1.139 + 2,3,3,4,3,4,4,5, // c0-c7
1.140 + 3,4,4,5,4,5,5,6, // c8-cf
1.141 + 3,4,4,5,4,5,5,6, // d0-d7
1.142 + 4,5,5,6,5,6,6,7, // d8-df
1.143 + 3,4,4,5,4,5,5,6, // e0-e7
1.144 + 4,5,5,6,5,6,6,7, // e8-ef
1.145 + 4,5,5,6,5,6,6,7, // f0-f7
1.146 + 5,6,6,7,6,7,7,8 // f8-ff
1.147 + };
1.148 + TInt total=0;
1.149 + TInt i;
1.150 + for (i=0;i<2500;i++)
1.151 + {
1.152 + total+=bitcount[aData[i]];
1.153 + }
1.154 + test.Printf(_L(" Total bitcount %d\r\n"),total);
1.155 + if ((total>9654)&&(total<10346))
1.156 + {
1.157 + test.Printf(_L(" Passed Monobit\r\n"));
1.158 + }
1.159 + else
1.160 + {
1.161 + test.Printf(_L(" ***FAILED!\r\n"));
1.162 + User::Panic(_L("t_random.exe"), KErrGeneral);
1.163 + }
1.164 + }
1.165 +
1.166 +void Poker(const TUint8* aData)
1.167 +
1.168 + {
1.169 + TInt f[16]= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
1.170 + TInt i;
1.171 + for (i=0;i<2500;i++)
1.172 + {
1.173 + f[(aData[i]&0x0f)]++;
1.174 + f[((aData[i]&0xf0)>>4)]++;
1.175 + }
1.176 + TReal x=0;
1.177 + for (i=0;i<16;i++)
1.178 + {
1.179 + x+=f[i]*f[i];
1.180 + }
1.181 + x*=16;
1.182 + x/=5000;
1.183 + x-=5000;
1.184 + if ((x>1.03)&&(x<57.4))
1.185 + {
1.186 + test.Printf(_L(" Passed poker test\r\n"));
1.187 + }
1.188 + else
1.189 + {
1.190 + test.Printf(_L(" ***FAILED poker test\r\n"));
1.191 + User::Panic(_L("t_random.exe"), KErrGeneral);
1.192 + }
1.193 + }
1.194 +
1.195 +void Runs(const TUint8* aData)
1.196 +
1.197 + {
1.198 + TInt i;
1.199 + TInt lastbit=0;
1.200 + TInt count[7][2]={
1.201 + { 0,0 },
1.202 + { 0,0 },
1.203 + { 0,0 },
1.204 + { 0,0 },
1.205 + { 0,0 },
1.206 + { 0,0 },
1.207 + { 0,0 }
1.208 + };
1.209 + TInt thisrun=0;
1.210 + TInt longrun=0;
1.211 + for (i=0;i<2500;i++)
1.212 + {
1.213 + TInt bit;
1.214 + for (bit=0;bit<8;bit++)
1.215 + {
1.216 + if (((aData[i]>>bit)&1)==lastbit)
1.217 + {
1.218 + thisrun++;
1.219 + }
1.220 + else
1.221 + {
1.222 + if (thisrun<5)
1.223 + {
1.224 + count[thisrun][lastbit]++;
1.225 + }
1.226 + else
1.227 + {
1.228 + count[5][lastbit]++;
1.229 + }
1.230 + lastbit^=1;
1.231 + if (thisrun>longrun)
1.232 + {
1.233 + longrun=thisrun;
1.234 + }
1.235 + thisrun=0;
1.236 + }
1.237 + }
1.238 + }
1.239 + TInt bound[6][2]=
1.240 + {
1.241 + {2267,2733},
1.242 + {1079,1421},
1.243 + { 502, 748},
1.244 + { 223, 402},
1.245 + { 90, 223},
1.246 + { 90, 223}
1.247 + };
1.248 + TBool failed=EFalse;
1.249 + for (i=0;i<6;i++)
1.250 + {
1.251 + if (!((count[i][0]>bound[i][0])&&(count[i][0]<bound[i][1])))
1.252 + {
1.253 + test.Printf(_L(" ***FAILED runs test\r\n"));
1.254 + failed=ETrue;
1.255 + }
1.256 + if (!((count[i][1]>bound[i][0])&&(count[i][1]<bound[i][1])))
1.257 + {
1.258 + test.Printf(_L(" ***FAILED runs test\r\n"));
1.259 + failed=ETrue;
1.260 + }
1.261 + }
1.262 + if (!failed)
1.263 + {
1.264 + test.Printf(_L(" Passed runs test\r\n"));
1.265 + }
1.266 + if ( (longrun>34) || (failed) )
1.267 + {
1.268 + test.Printf(_L(" ***FAILED longrun test\r\n"));
1.269 + User::Panic(_L("t_random.exe"), KErrGeneral);
1.270 + }
1.271 + }
1.272 +
1.273 +void FIPSTest(const TUint8* aData)
1.274 +// Run some basic tests to check it's returned some numbers
1.275 +// These will panic if a failure is detected
1.276 + {
1.277 + Monobit(aData);
1.278 + Poker(aData);
1.279 + Runs(aData);
1.280 + }
1.281 +
1.282 +void WriteFile(const TUint8* aData,const TDesC& aFileName)
1.283 +
1.284 + {
1.285 + RFs fs;
1.286 + fs.Connect();
1.287 + RFile file;
1.288 + TInt err;
1.289 + err=file.Open(fs,aFileName,EFileShareAny|EFileWrite);
1.290 + if (err)
1.291 + {
1.292 + if (file.Create(fs,aFileName,EFileShareAny|EFileWrite))
1.293 + {
1.294 + return;
1.295 + }
1.296 + }
1.297 + TPtrC8 ptr(aData,gNumberOfRandomNumbers);
1.298 + TInt size;
1.299 + file.Size(size);
1.300 + file.Write(size,ptr);
1.301 + file.Close();
1.302 + fs.Close();
1.303 + FIPSTest(aData);
1.304 + }
1.305 +
1.306 +void DoTestsL(void)
1.307 +
1.308 + {
1.309 + test.Printf(_L("Run random tests with normal salting\r\n"));
1.310 + TInt i;
1.311 + TBuf8<16> buf2;
1.312 + for (i=0;i<16;i++)
1.313 + {
1.314 + buf2.SetLength(i);
1.315 + TRandom::RandomL(buf2);
1.316 + }
1.317 +
1.318 + HBufC8* buf=HBufC8::NewMaxL(gNumberOfRandomNumbers);
1.319 + CleanupStack::PushL(buf);
1.320 + TPtr8 buffer=buf->Des();
1.321 + test.Printf(_L("\nRequesting for random numbers.\n"));
1.322 + for (i=0;i<gTestRequestCount;i++)
1.323 + {
1.324 + TPtr8 thePtr(buf->Des());
1.325 + // Generate the random data
1.326 + TRandom::RandomL(buffer);
1.327 + if (buf->Length()!=gNumberOfRandomNumbers)
1.328 + {
1.329 + User::Leave(KErrGeneral);
1.330 + }
1.331 + ++gTestPassCount;
1.332 + test.Printf(_L("."));
1.333 + }
1.334 +
1.335 + // Request for Secure Random numbers.
1.336 + test.Printf(_L("\nRequesting for cryptographically secure random numbers.\n"));
1.337 + for (i=0;i<gTestRequestCount;i++)
1.338 + {
1.339 + TPtr8 thePtr(buf->Des());
1.340 + // Generate the random data
1.341 + TRAP_IGNORE(TRandom::SecureRandomL(buffer));
1.342 + if (buf->Length() != gNumberOfRandomNumbers)
1.343 + {
1.344 + User::Leave(KErrGeneral);
1.345 + }
1.346 + ++gTestPassCount;
1.347 + test.Printf(_L("."));
1.348 + }
1.349 + CleanupStack::PopAndDestroy(buf);
1.350 + }
1.351 +
1.352 +void TestsL(void)
1.353 + {
1.354 + TDriveUnit sysDrive (RFs::GetSystemDrive());
1.355 + TBuf<64> logFile (sysDrive.Name());
1.356 + logFile.Append(_L("\\t_random.log"));
1.357 + CTestConsole* con = CTestConsole::NewL(test.Console(), logFile);
1.358 + test.SetConsole(con);
1.359 +
1.360 + DoTestsL();
1.361 + }
1.362 +
1.363 +GLDEF_C TInt E32Main(void)
1.364 +
1.365 + {
1.366 + CTrapCleanup* cleanup;
1.367 + cleanup=CTrapCleanup::New();
1.368 +
1.369 + __UHEAP_MARK;
1.370 +
1.371 + test.Start(_L(" @SYMTestCaseID:SEC-CRYPTOSPI-RANDOM-0001 Starting random number generator tests\r\n"));
1.372 + CConsoleBase* originalConsole = test.Console();
1.373 +
1.374 + TRAPD(ret,TestsL());
1.375 + // Infor the user about the test cases' status.
1.376 + test.Printf(_L("\n%d tests failed out of %d\r\n"), ((2*gTestRequestCount) - gTestPassCount), 2*gTestRequestCount);
1.377 +
1.378 + test (ret == KErrNone);
1.379 + test.End();
1.380 +
1.381 + if (test.Console() != originalConsole)
1.382 + {
1.383 + delete test.Console();
1.384 + test.SetConsole(originalConsole);
1.385 + }
1.386 + test.Close();
1.387 +
1.388 + __UHEAP_MARKEND;
1.389 +
1.390 + delete cleanup;
1.391 + return(KErrNone);
1.392 + }