1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/security/crypto/weakcrypto/source/random/randsvr.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,256 @@
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 +*
1.19 +*/
1.20 +
1.21 +
1.22 +/**
1.23 + @file
1.24 +*/
1.25 +
1.26 +#include "randsvr.h"
1.27 +#include "randcliserv.h"
1.28 +#include <e32math.h>
1.29 +#include "randsvrimpl.h"
1.30 +
1.31 +
1.32 +//const TInt KFastTickTimer=1000000; // These are testing numbers!
1.33 +//const TInt KSlowTickTimer=30000000;
1.34 +const TInt KThreshold=1024;
1.35 +
1.36 +const TInt KFastTickTimer=30000000; // These are the real numbers!
1.37 +const TInt KSlowTickTimer=0x7fffffff;
1.38 +
1.39 +
1.40 +void SignalClient()
1.41 +//
1.42 +// Signal the owning thread that the server has started successfully
1.43 +// This may itself fail
1.44 +//
1.45 + {
1.46 + RProcess::Rendezvous(KErrNone);
1.47 + }
1.48 +
1.49 +
1.50 +EXPORT_C TInt RunRandomServer(TAny* /*aUnused*/)
1.51 + {
1.52 + CTrapCleanup* cleanup=CTrapCleanup::New();
1.53 + if (!cleanup)
1.54 + {
1.55 + return KErrNoMemory;
1.56 + }
1.57 +
1.58 + TInt ret = User::RenameThread(KRandomServerName);
1.59 +
1.60 + __ASSERT_ALWAYS(ret==KErrNone,User::Panic(KRandomServerName,KErrServerTerminated));
1.61 +
1.62 + if (CRandomScheduler::New())
1.63 + return KErrNoMemory;
1.64 + ret = CRandomServer::New();
1.65 + if (ret != KErrNone )
1.66 + return ret;
1.67 + // Initialisation complete, now signal the client
1.68 + SignalClient();
1.69 +
1.70 + CRandomScheduler::Start();
1.71 + delete cleanup;
1.72 + return KErrNone;
1.73 + }
1.74 +
1.75 +TBool CRandomScheduler::New(void)
1.76 + {
1.77 + CRandomScheduler* rs;
1.78 + rs=new CRandomScheduler;
1.79 + CRandomScheduler::Install(rs);
1.80 + return (rs == NULL);
1.81 + }
1.82 +
1.83 +void CRandomScheduler::Error(TInt /*aError*/) const
1.84 + {
1.85 + User::Panic(KRandomServerName, 3);
1.86 + }
1.87 +
1.88 +CRandomServer::CRandomServer(void) : CServer2(EPriorityLow)
1.89 + {
1.90 + }
1.91 +
1.92 +CRandomServer::~CRandomServer(void)
1.93 + {
1.94 + // This should never happen....but in case it does:
1.95 + delete iHash;
1.96 + delete iTicker;
1.97 + delete iPool;
1.98 + }
1.99 +
1.100 +TInt CRandomServer::New(void)
1.101 + {
1.102 + CRandomServer* self;
1.103 + self=new CRandomServer;
1.104 + if (!self)
1.105 + {
1.106 + return KErrNoMemory;
1.107 + }
1.108 + TRAPD(ret,self->ConstructL());
1.109 + if (ret)
1.110 + {
1.111 + return ret;
1.112 + }
1.113 +
1.114 + return self->Start(KRandomServerName);
1.115 + }
1.116 +
1.117 +void CRandomServer::ConstructL(void)
1.118 + {
1.119 + iPool=new (ELeave) TUint8[KRandomPoolSize];
1.120 + iHash=CSHA1::NewL();
1.121 + iPoolIn=0;
1.122 + iPoolOut=0;
1.123 + iTicker=CPeriodic::NewL(EPriorityLow);
1.124 + TCallBack callback(Tick,this);
1.125 + iTicker->Start(KFastTickTimer,KFastTickTimer,callback); // **** these figures might need tweaking!
1.126 + iQuality=0;
1.127 + iFast=ETrue;
1.128 + }
1.129 +
1.130 +TInt CRandomServer::Tick(TAny* aServer)
1.131 + {
1.132 + CRandomServer* svr=(CRandomServer*)aServer;
1.133 + svr->Stir();
1.134 + svr->iQuality+=30;
1.135 + if (svr->iFast)
1.136 + {
1.137 + if (svr->iQuality>KThreshold)
1.138 + {
1.139 + TCallBack callback(Tick,svr);
1.140 + svr->iTicker->Cancel();
1.141 + svr->iTicker->Start(KSlowTickTimer,KSlowTickTimer,callback); // **** these figures might need tweaking!
1.142 + svr->iFast=EFalse;
1.143 + }
1.144 + }
1.145 + if (svr->iQuality>(KRandomPoolSize<<3))
1.146 + {
1.147 + svr->iQuality=(KRandomPoolSize<<3);
1.148 + }
1.149 + return ETrue;
1.150 + }
1.151 +
1.152 +CSession2* CRandomServer::NewSessionL(const TVersion& /*aVersion*/, const RMessage2& /*aMessage*/) const
1.153 + {
1.154 + return CRandomSession::NewL(const_cast<CRandomServer*>(this));
1.155 + //CRandomSession::NewL(CONST_CAST(CRandomServer*,this),Message().Client());
1.156 + }
1.157 +
1.158 +TPtrC8 CRandomServer::GetRandom(void)
1.159 + {
1.160 + TPtr8 res(&iPool[iPoolOut],iHash->HashSize(),iHash->HashSize());
1.161 + iPoolOut+=iHash->HashSize();
1.162 + if ((iPoolOut+iHash->HashSize())>KRandomPoolSize)
1.163 + {
1.164 + iPoolOut=0;
1.165 + }
1.166 + return iHash->Hash(res);
1.167 + }
1.168 +
1.169 +CMessageDigest* CRandomServer::Hash(void) const
1.170 + {
1.171 + return iHash;
1.172 + }
1.173 +
1.174 +void CRandomServer::Stir(void)
1.175 + {
1.176 + TInt rnd;
1.177 + rnd=Math::Random();
1.178 + TPtrC8 r((TUint8*)&rnd,sizeof(TInt));
1.179 + iHash->Hash(r);
1.180 + TPtr8 dest(&iPool[iPoolIn],iHash->HashSize());
1.181 + dest.Copy(iHash->Hash(dest));
1.182 + iPoolIn+=iHash->HashSize();
1.183 + if ((iPoolIn+iHash->HashSize())>KRandomPoolSize)
1.184 + {
1.185 + iPoolIn=0;
1.186 + }
1.187 + }
1.188 +
1.189 +CRandomSession* CRandomSession::NewL(CRandomServer* aServer)
1.190 + {
1.191 + CRandomSession* self;
1.192 + self=new (ELeave) CRandomSession(aServer);
1.193 + return self;
1.194 + }
1.195 +
1.196 +CRandomSession::CRandomSession(CRandomServer* aServer) : CSession2(), iServer(aServer)
1.197 + {
1.198 + }
1.199 +
1.200 +CRandomSession::~CRandomSession(void)
1.201 + {
1.202 + }
1.203 +
1.204 +void CRandomSession::ServiceL(const RMessage2& aMessage)
1.205 + {
1.206 + switch (aMessage.Function())
1.207 + {
1.208 + case KRandomRequest:
1.209 + {
1.210 + TInt ret = FillBuffer(aMessage);
1.211 + aMessage.Complete(ret);
1.212 + break;
1.213 + }
1.214 + default:
1.215 + aMessage.Complete(KErrNotSupported);
1.216 + break;
1.217 + };
1.218 + }
1.219 +
1.220 +TInt CRandomSession::FillBuffer(const RMessage2& aMessage)
1.221 + {
1.222 + TInt length = aMessage.Int1();
1.223 + if (length < 0 || length > KRandomBlockSize)
1.224 + return KErrArgument;
1.225 + iServer->iQuality -= length;
1.226 + if (iServer->iQuality<0)
1.227 + {
1.228 + iServer->iQuality=0;
1.229 + }
1.230 + if (!iServer->iFast)
1.231 + {
1.232 + if (iServer->iQuality<KThreshold)
1.233 + {
1.234 + TCallBack callback(CRandomServer::Tick,iServer);
1.235 + iServer->iTicker->Cancel();
1.236 + iServer->iTicker->Start(KFastTickTimer,KFastTickTimer,callback); // **** these figures might need tweaking!
1.237 + iServer->iFast=ETrue;
1.238 + }
1.239 + }
1.240 + TBuf8<KRandomBlockSize> buf(0);
1.241 + iServer->Stir();
1.242 + TInt i;
1.243 + TInt hashsize=iServer->Hash()->HashSize();
1.244 + for (i=0; i+hashsize < length; i+=hashsize)
1.245 + {
1.246 + buf.Append(iServer->GetRandom());
1.247 + iServer->Stir();
1.248 + }
1.249 + TPtrC8 ptr(iServer->GetRandom().Ptr(), length-i);
1.250 + buf.Append(ptr);
1.251 +
1.252 + TRAPD(ret, aMessage.WriteL(0, buf));
1.253 + return ret;
1.254 + }
1.255 +
1.256 +GLDEF_C TInt E32Main(void)
1.257 + {
1.258 + return RunRandomServer(NULL);
1.259 + }