diff -r da2ae96f639b -r cd501b96611d crypto/weakcryptospi/source/random/randsvr.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/crypto/weakcryptospi/source/random/randsvr.cpp Fri Nov 06 13:21:00 2009 +0200 @@ -0,0 +1,255 @@ +/* +* 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: +* +*/ + + +/** + @file +*/ + +#include "randsvr.h" +#include "randcliserv.h" +#include "sha1shim.h" +#include +#include "randsvrimpl.h" + +//const TInt KFastTickTimer=1000000; // These are testing numbers! +//const TInt KSlowTickTimer=30000000; +const TInt KThreshold=1024; + +const TInt KFastTickTimer=30000000; // These are the real numbers! +const TInt KSlowTickTimer=0x7fffffff; + +using namespace CryptoSpi; + +void SignalClient() +// +// Signal the owning thread that the server has started successfully +// This may itself fail +// + { + RProcess::Rendezvous(KErrNone); + } + + +TInt RunRandomServer(TAny* /*aUnused*/) + { + + __UHEAP_MARK; + + CTrapCleanup* cleanup=CTrapCleanup::New(); + if (!cleanup) + { + return KErrNoMemory; + } + + TInt ret = User::RenameThread(KRandomServerName); + + __ASSERT_ALWAYS(ret==KErrNone,User::Panic(KRandomServerName,KErrServerTerminated)); + + if (CRandomScheduler::New()) + return KErrNoMemory; + CRandomServer* random(0); + TRAP(ret, random = CRandomServer::NewL()); + if (ret != KErrNone) + return ret; + random->Start(KRandomServerName); + // Initialisation complete, now signal the client + SignalClient(); + + CRandomScheduler::Start(); + delete random; + delete cleanup; + + __UHEAP_MARKEND; + return KErrNone; + } + +TBool CRandomScheduler::New(void) + { + CRandomScheduler* rs; + rs=new CRandomScheduler; + CRandomScheduler::Install(rs); + return (rs == NULL); + } + +void CRandomScheduler::Error(TInt /*aError*/) const + { + User::Panic(KRandomServerName, 3); + } + +CRandomServer::CRandomServer(void) : CServer2(EPriorityLow) + { + } + +CRandomServer::~CRandomServer(void) + { + // This should never happen....but in case it does: + delete iHash; + delete iTicker; + delete iPool; + } + +CRandomServer* CRandomServer::NewL(void) + { + CRandomServer* self = new (ELeave) CRandomServer; + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +void CRandomServer::ConstructL(void) + { + iPool=new (ELeave) TUint8[KRandomPoolSize]; + iHash=CSHA1Shim::NewL(); + iPoolIn=0; + iPoolOut=0; + iTicker=CPeriodic::NewL(EPriorityLow); + TCallBack callback(Tick,this); + iTicker->Start(KFastTickTimer,KFastTickTimer,callback); // **** these figures might need tweaking! + iQuality=0; + iFast=ETrue; + } + +TInt CRandomServer::Tick(TAny* aServer) + { + CRandomServer* svr=(CRandomServer*)aServer; + svr->Stir(); + svr->iQuality+=30; + if (svr->iFast) + { + if (svr->iQuality>KThreshold) + { + TCallBack callback(Tick,svr); + svr->iTicker->Cancel(); + svr->iTicker->Start(KSlowTickTimer,KSlowTickTimer,callback); // **** these figures might need tweaking! + svr->iFast=EFalse; + } + } + if (svr->iQuality>(KRandomPoolSize<<3)) + { + svr->iQuality=(KRandomPoolSize<<3); + } + return ETrue; + } + +CSession2* CRandomServer::NewSessionL(const TVersion& /*aVersion*/, const RMessage2& /*aMessage*/) const + { + return CRandomSession::NewL(const_cast(this)); + //CRandomSession::NewL(CONST_CAST(CRandomServer*,this),Message().Client()); + } + +TPtrC8 CRandomServer::GetRandom(void) + { + TPtr8 res(&iPool[iPoolOut],iHash->HashSize(),iHash->HashSize()); + iPoolOut+=iHash->HashSize(); + if ((iPoolOut+iHash->HashSize())>KRandomPoolSize) + { + iPoolOut=0; + } + return iHash->Hash(res); + } + +CMessageDigest* CRandomServer::Hash(void) const + { + return iHash; + } + +void CRandomServer::Stir(void) + { + TInt rnd; + rnd=Math::Random(); + TPtrC8 r((TUint8*)&rnd,sizeof(TInt)); + iHash->Hash(r); + TPtr8 dest(&iPool[iPoolIn],iHash->HashSize()); + dest.Copy(iHash->Hash(dest)); + iPoolIn+=iHash->HashSize(); + if ((iPoolIn+iHash->HashSize())>KRandomPoolSize) + { + iPoolIn=0; + } + } + +CRandomSession* CRandomSession::NewL(CRandomServer* aServer) + { + CRandomSession* self; + self=new (ELeave) CRandomSession(aServer); + return self; + } + +CRandomSession::CRandomSession(CRandomServer* aServer) : CSession2(), iServer(aServer) + { + } + +CRandomSession::~CRandomSession(void) + { + } + +void CRandomSession::ServiceL(const RMessage2& aMessage) + { + switch (aMessage.Function()) + { + case KRandomRequest: + { + TInt ret = FillBuffer(aMessage); + aMessage.Complete(ret); + break; + } + default: + aMessage.Complete(KErrNotSupported); + break; + }; + } + +TInt CRandomSession::FillBuffer(const RMessage2& aMessage) + { + TInt length = aMessage.Int1(); + iServer->iQuality -= length; + if (iServer->iQuality<0) + { + iServer->iQuality=0; + } + if (!iServer->iFast) + { + if (iServer->iQualityiTicker->Cancel(); + iServer->iTicker->Start(KFastTickTimer,KFastTickTimer,callback); // **** these figures might need tweaking! + iServer->iFast=ETrue; + } + } + TBuf8 buf(0); + iServer->Stir(); + TInt i; + TInt hashsize=iServer->Hash()->HashSize(); + for (i=0; i+hashsize < length; i+=hashsize) + { + buf.Append(iServer->GetRandom()); + iServer->Stir(); + } + TPtrC8 ptr(iServer->GetRandom().Ptr(), length-i); + buf.Append(ptr); + + TRAPD(ret, aMessage.WriteL(0, buf)); + return ret; + } + +GLDEF_C TInt E32Main(void) + { + return RunRandomServer(NULL); + }