diff -r 000000000000 -r 2c201484c85f crypto/weakcrypto/test/trandom/t_random.cpp --- /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 +#include +#include +#include +#include + +#include + +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][0])&&(count[i][1]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); + }