--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/crypto/weakcrypto/test/trandom/t_random.cpp Wed Jul 08 11:25:26 2009 +0100
@@ -0,0 +1,412 @@
+/*
+* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+* (c) 1999 Symbian Ltd
+*
+*/
+
+
+
+
+/**
+ @file
+*/
+
+#include <e32base.h>
+#include <e32std.h>
+#include <e32test.h>
+#include <random.h>
+#include <f32file.h>
+
+#include <randsvr.h>
+
+RTest test(_L("Random Number Generator Tests"));
+
+TInt gNumberOfRandomNumbers=10000;
+
+/** Wraps a console and logs output to a file. */
+class CTestConsole:public CConsoleBase
+ {
+ public:
+ static CTestConsole* NewL(CConsoleBase* aCon, const TDesC& aFilename);
+ TInt Create(const TDesC16& aTitle,TSize aSize) {return iCon->Create(aTitle,aSize);};
+ void Read(TRequestStatus& aStatus) {iCon->Read(aStatus);};
+ void ReadCancel(void) {iCon->ReadCancel();};
+ void Write(const TDesC16& aString);
+ TPoint CursorPos(void) const {return iCon->CursorPos();};
+ void SetCursorPosAbs(const TPoint& aPos) {iCon->SetCursorPosAbs(aPos);};
+ void SetCursorPosRel(const TPoint& aPos) {iCon->SetCursorPosRel(aPos);};
+ void SetCursorHeight(TInt aHeight) {iCon->SetCursorHeight(aHeight);};
+ void SetTitle(const TDesC16& aTitle) {iCon->SetTitle(aTitle);};
+ void ClearScreen(void) {iCon->ClearScreen();};
+ void ClearToEndOfLine(void) {iCon->ClearToEndOfLine();};
+ TSize ScreenSize(void) const {return iCon->ScreenSize();};
+ TKeyCode KeyCode(void) const {return iCon->KeyCode();};
+ TUint KeyModifiers(void) const {return iCon->KeyModifiers();};
+ ~CTestConsole(void);
+ private:
+ CTestConsole(CConsoleBase* aCon);
+ void ConstructL(const TDesC& aFilename);
+ CConsoleBase* iCon; ///< Pointer to wrapped console, we don't own this
+ RFs iFs;
+ RFile iFile; ///< Log file
+ };
+
+CTestConsole* CTestConsole::NewL(CConsoleBase* aCon, const TDesC& aFilename)
+
+ {
+ CTestConsole* self;
+ self=new (ELeave) CTestConsole(aCon);
+ CleanupStack::PushL(self);
+ self->ConstructL(aFilename);
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+CTestConsole::CTestConsole(CConsoleBase* aCon) :
+ CConsoleBase(), iCon(aCon)
+
+ {
+ }
+
+void CTestConsole::ConstructL(const TDesC& aFilename)
+
+ {
+ User::LeaveIfError(iFs.Connect());
+ User::LeaveIfError(iFile.Replace(iFs,aFilename,EFileShareAny|EFileWrite));
+ }
+
+CTestConsole::~CTestConsole(void)
+
+ {
+ iFile.Close();
+ iFs.Close();
+ }
+
+void CTestConsole::Write(const TDesC16& aString)
+
+ {
+ iCon->Write(aString);
+ TUint8 space[200];
+ TPtr8 ptr(space,200);
+ ptr.Copy(aString);
+ iFile.Write(ptr);
+ }
+
+void Monobit(const TUint8* aData)
+
+ {
+ const TInt bitcount[256]=
+ { 0,1,1,2,1,2,2,3, // 00-07
+ 1,2,2,3,2,3,3,4, // 08-0f
+ 1,2,2,3,2,3,3,4, // 10-17
+ 2,3,3,4,3,4,4,5, // 18-1f
+ 1,2,2,3,2,3,3,4, // 20-27
+ 2,3,3,4,3,4,4,5, // 28-2f
+ 2,3,3,4,3,4,4,5, // 30-37
+ 3,4,4,5,4,5,5,6, // 38-3f
+
+ 1,2,2,3,2,3,3,4, // 40-47
+ 2,3,3,4,3,4,4,5, // 48-4f
+ 2,3,3,4,3,4,4,5, // 50-57
+ 3,4,4,5,4,5,5,6, // 58-5f
+ 2,3,3,4,3,4,4,5, // 60-67
+ 3,4,4,5,4,5,5,6, // 68-6f
+ 3,4,4,5,4,5,5,6, // 70-77
+ 4,5,5,6,5,6,6,7, // 78-7f
+
+ 1,2,2,3,2,3,3,4, // 80-87
+ 2,3,3,4,3,4,4,5, // 88-8f
+ 2,3,3,4,3,4,4,5, // 90-97
+ 3,4,4,5,4,5,5,6, // 98-9f
+ 2,3,3,4,3,4,4,5, // a0-a7
+ 3,4,4,5,4,5,5,6, // a8-af
+ 3,4,4,5,4,5,5,6, // b0-b7
+ 4,5,5,6,5,6,6,7, // b8-bf
+
+ 2,3,3,4,3,4,4,5, // c0-c7
+ 3,4,4,5,4,5,5,6, // c8-cf
+ 3,4,4,5,4,5,5,6, // d0-d7
+ 4,5,5,6,5,6,6,7, // d8-df
+ 3,4,4,5,4,5,5,6, // e0-e7
+ 4,5,5,6,5,6,6,7, // e8-ef
+ 4,5,5,6,5,6,6,7, // f0-f7
+ 5,6,6,7,6,7,7,8 // f8-ff
+ };
+ TInt total=0;
+ TInt i;
+ for (i=0;i<2500;i++)
+ {
+ total+=bitcount[aData[i]];
+ }
+ test.Printf(_L(" Total bitcount %d\r\n"),total);
+ if ((total>9654)&&(total<10346))
+ {
+ test.Printf(_L(" Passed Monobit\r\n"));
+ }
+ else
+ {
+ test.Printf(_L(" ***FAILED!\r\n"));
+ User::Panic(_L("t_random.exe"), KErrGeneral);
+ }
+ }
+
+void Poker(const TUint8* aData)
+
+ {
+ TInt f[16]= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+ TInt i;
+ for (i=0;i<2500;i++)
+ {
+ f[(aData[i]&0x0f)]++;
+ f[((aData[i]&0xf0)>>4)]++;
+ }
+ TReal x=0;
+ for (i=0;i<16;i++)
+ {
+ x+=f[i]*f[i];
+ }
+ x*=16;
+ x/=5000;
+ x-=5000;
+ if ((x>1.03)&&(x<57.4))
+ {
+ test.Printf(_L(" Passed poker test\r\n"));
+ }
+ else
+ {
+ test.Printf(_L(" ***FAILED poker test\r\n"));
+ User::Panic(_L("t_random.exe"), KErrGeneral);
+ }
+ }
+
+void Runs(const TUint8* aData)
+
+ {
+ TInt i;
+ TInt lastbit=0;
+ TInt count[7][2]={
+ { 0,0 },
+ { 0,0 },
+ { 0,0 },
+ { 0,0 },
+ { 0,0 },
+ { 0,0 },
+ { 0,0 }
+ };
+ TInt thisrun=0;
+ TInt longrun=0;
+ for (i=0;i<2500;i++)
+ {
+ TInt bit;
+ for (bit=0;bit<8;bit++)
+ {
+ if (((aData[i]>>bit)&1)==lastbit)
+ {
+ thisrun++;
+ }
+ else
+ {
+ if (thisrun<5)
+ {
+ count[thisrun][lastbit]++;
+ }
+ else
+ {
+ count[5][lastbit]++;
+ }
+ lastbit^=1;
+ if (thisrun>longrun)
+ {
+ longrun=thisrun;
+ }
+ thisrun=0;
+ }
+ }
+ }
+ TInt bound[6][2]=
+ {
+ {2267,2733},
+ {1079,1421},
+ { 502, 748},
+ { 223, 402},
+ { 90, 223},
+ { 90, 223}
+ };
+ TBool failed=EFalse;
+ for (i=0;i<6;i++)
+ {
+ if (!((count[i][0]>bound[i][0])&&(count[i][0]<bound[i][1])))
+ {
+ test.Printf(_L(" ***FAILED runs test\r\n"));
+ failed=ETrue;
+ }
+ if (!((count[i][1]>bound[i][0])&&(count[i][1]<bound[i][1])))
+ {
+ test.Printf(_L(" ***FAILED runs test\r\n"));
+ failed=ETrue;
+ }
+ }
+ if (!failed)
+ {
+ test.Printf(_L(" Passed runs test\r\n"));
+ }
+ if ( (longrun>34) || (failed) )
+ {
+ test.Printf(_L(" ***FAILED longrun test\r\n"));
+ User::Panic(_L("t_random.exe"), KErrGeneral);
+ }
+ }
+
+void FIPSTest(const TUint8* aData)
+// Run some basic tests to check it's returned some numbers
+// These will panic if a failure is detected
+ {
+ Monobit(aData);
+ Poker(aData);
+ Runs(aData);
+ }
+
+void WriteFile(const TUint8* aData,const TDesC& aFileName)
+
+ {
+ RFs fs;
+ fs.Connect();
+ RFile file;
+ TInt err;
+ err=file.Open(fs,aFileName,EFileShareAny|EFileWrite);
+ if (err)
+ {
+ if (file.Create(fs,aFileName,EFileShareAny|EFileWrite))
+ {
+ return;
+ }
+ }
+ TPtrC8 ptr(aData,gNumberOfRandomNumbers);
+ TInt size;
+ file.Size(size);
+ file.Write(size,ptr);
+ file.Close();
+ fs.Close();
+ FIPSTest(aData);
+ }
+
+class RTestRandomSession : public RRandomSession
+ {
+ public:
+ void SendMalformedInputL()
+ {
+ test.Printf(_L("Test malformed input with negative buffer size\r\n"));
+ TBuf8<1024> buffer;
+ TInt err = SendReceive(CRandomSession::KRandomRequest, TIpcArgs(&buffer, -1));
+ if (err != KErrArgument)
+ {
+ test.Printf(_L("%d should have been returned on negative buffer size test, but %d was returned!\r\n"), KErrArgument, err);
+ User::Leave(KErrGeneral);
+ }
+ }
+ };
+
+// Checks that RandomServer handles malformed length correctly - see INC113902
+void TestMalformedInputL()
+ {
+ RTestRandomSession rs;
+ TRAPD(err, rs.ConnectL());
+ User::LeaveIfError(err); // The connect method leaves with zero even if it succeeds, so we have to trap the error
+ CleanupClosePushL(rs);
+ rs.SendMalformedInputL();
+ CleanupStack::PopAndDestroy(&rs);
+ }
+
+void DoTestsL()
+
+ {
+ TestMalformedInputL();
+
+ test.Printf(_L(" Run random tests with normal salting\r\n"));
+
+ TInt i;
+ TBuf8<16> buf2;
+ for (i=0;i<16;i++)
+ {
+ buf2.SetLength(i);
+ TRandom::RandomL(buf2);
+ }
+ HBufC8* buf=HBufC8::NewMaxL(gNumberOfRandomNumbers);
+ TPtr8 buffer=buf->Des();
+ for (i=0;i<11;i++)
+ {
+ User::After(10000000);
+ TPtr8 thePtr(buf->Des());
+ thePtr.FillZ();
+ // Generate the random data
+ TRandom::RandomL(buffer);
+ if (buf->Length()!=gNumberOfRandomNumbers)
+ User::Leave(KErrGeneral);
+
+
+ WriteFile(buffer.Ptr(),_L("User.rnd"));
+ test.Printf(_L("."));
+ }
+ delete buf;
+ }
+
+void TestsL(void)
+ {
+ TDriveUnit sysDrive (RFs::GetSystemDrive());
+ TDriveName driveName(sysDrive.Name());
+ TBuf<64> logFile (driveName);
+ logFile.Append(_L("\\t_random.log"));
+ CTestConsole* con = CTestConsole::NewL(test.Console(), logFile);
+ test.SetConsole(con);
+
+ DoTestsL();
+
+ // If test reached here, no tests failed, otherwise it would have panicked
+ // and terminated prematurely. Print this out for tester's reference.
+ test.Printf(_L("\n0 tests failed out of 12\r\n"));
+ }
+
+GLDEF_C TInt E32Main(void)
+
+ {
+ CTrapCleanup* cleanup;
+ cleanup=CTrapCleanup::New();
+
+ __UHEAP_MARK;
+
+ test.Start(_L("Starting random number generator tests\r\n"));
+ CConsoleBase* originalConsole = test.Console();
+
+ TRAPD(ret,TestsL());
+ if (ret)
+ {
+ test.Printf(_L("Unexpected leave\r\n"));
+ // Print something to let the build system know we failed
+ test.Printf(_L("\n1 tests failed out of 11\r\n"));
+ }
+ test.End();
+
+ if (test.Console() != originalConsole)
+ {
+ delete test.Console();
+ test.SetConsole(originalConsole);
+ }
+ test.Close();
+
+ __UHEAP_MARKEND;
+
+ delete cleanup;
+ return(KErrNone);
+ }