cryptoplugins/cryptospiplugins/source/softwarecrypto/randomimpl.cpp
changeset 19 cd501b96611d
child 41 9b5a3a9fddf8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cryptoplugins/cryptospiplugins/source/softwarecrypto/randomimpl.cpp	Fri Nov 06 13:21:00 2009 +0200
@@ -0,0 +1,212 @@
+/*
+* 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 <e32std.h>
+#include <e32debug.h>
+
+#include "randomimpl.h"
+#include "pluginentry.h"
+#include "pluginconfig.h"
+
+#include "randsvr.h"
+#include "randcliserv.h"
+#include "randsvrimpl.h"
+
+_LIT(KRandomServerImg,"z:\\sys\\bin\\randsvr.exe");		// DLL/EXE name
+_LIT(KRandomServerConnect, "Randsvr connect");
+_LIT(KRandomServerGet, "Randsvr get");
+
+const TUid KServerUid3={0x100066dc};
+
+
+using namespace SoftwareCrypto;
+
+
+CRandomImpl* CRandomImpl::NewL(void)
+	{
+	CRandomImpl* self = new(ELeave)CRandomImpl();
+	return self;
+	}
+
+CRandomImpl* CRandomImpl::NewLC(void)
+	{
+	CRandomImpl* self = NewL();
+	CleanupStack::PushL(self);
+	return self;
+	}
+
+void CRandomImpl::GenerateRandomBytesL(TDes8& aDest)
+	{
+	TRandomImpl::Random(aDest);
+	}
+
+CRandomImpl::CRandomImpl(void)
+	{
+	}
+
+void TRandomImpl::Random(TDes8& aDestination)
+	{
+	RRandomSessionImpl rs;
+	TRAPD(ret,rs.ConnectL());
+	if (ret != KErrNone)
+		{
+		User::Panic(KRandomServerConnect, ret);
+		}
+	TInt err=rs.GetRandom(aDestination);
+	if (err != KErrNone)
+		{
+		User::Panic(KRandomServerGet, err);
+		}
+	rs.Close();
+	}
+
+void CRandomImpl::GetCharacteristicsL(const TCharacteristics*& aPluginCharacteristics)
+	{
+	TInt randomNum = sizeof(KRandomCharacteristics)/sizeof(TRandomCharacteristics*);
+	for (TInt i = 0; i < randomNum; i++)
+		{
+		if (KRandomCharacteristics[i]->cmn.iImplementationUID == ImplementationUid().iUid)
+			{
+			aPluginCharacteristics = KRandomCharacteristics[i];
+			break;
+			}
+		}
+	}
+
+CExtendedCharacteristics* CRandomImpl::CreateExtendedCharacteristicsL()
+	{
+	// All Symbian software plug-ins have unlimited concurrency, cannot be reserved
+	// for exclusive use and are not CERTIFIED to be standards compliant.
+	return CExtendedCharacteristics::NewL(KMaxTInt, EFalse);
+	}
+
+const CExtendedCharacteristics* CRandomImpl::GetExtendedCharacteristicsL()
+	{
+	return CRandomImpl::CreateExtendedCharacteristicsL();
+	}
+
+TUid CRandomImpl::ImplementationUid() const
+	{
+	return KCryptoPluginRandomUid;
+	}
+
+CRandomImpl::~CRandomImpl()
+	{
+	}
+
+void CRandomImpl::Close()
+	{
+	delete this;
+	}
+
+// All crypto plugins must implement this, to reset
+// hardware if required. Do nothing in this version
+void CRandomImpl::Reset()
+	{
+	}
+
+RRandomSessionImpl::RRandomSessionImpl(void)
+	{
+	}
+
+static TInt StartServer()
+// Borrowed from AndrewT's server startup code.
+// Start the server process/thread which lives in an EPOCEXE object
+//
+	{
+	
+	const TUidType serverUid(KNullUid,KNullUid,KServerUid3);
+
+	//
+	// EPOC and EKA2 is easy, we just create a new server process. Simultaneous
+	// launching of two such processes should be detected when the second one
+	// attempts to create the server object, failing with KErrAlreadyExists.
+	//
+	RProcess server;
+	TInt r=server.Create(KRandomServerImg, KNullDesC, serverUid);
+
+	if (r!=KErrNone)
+		return r;
+	TRequestStatus stat;
+	server.Rendezvous(stat);
+	if (stat!=KRequestPending)
+		server.Kill(0);		// abort startup
+	else
+		server.Resume();	// logon OK - start the server
+	User::WaitForRequest(stat);		// wait for start or death
+	// we can't use the 'exit reason' if the server panicked as this
+	// is the panic 'reason' and may be '0' which cannot be distinguished
+	// from KErrNone
+	r=(server.ExitType()==EExitPanic) ? KErrGeneral : stat.Int();
+	server.Close();
+	return r;
+
+	}
+
+void RRandomSessionImpl::ConnectL(void)
+	{
+	TInt retry=2;
+	for (;;)
+		{
+		// Magic number 1 below is the number of asynchronous message slots
+		TInt r = CreateSession(KRandomServerName,TVersion(0,0,0), 1);
+		if (r == KErrNone) return;
+		// We used to leave with KErrNone, but this is inefficient and
+		// provokes an emulator problem in User::Leave which causes tpbe to crash
+		// if (r == KErrNone) User::Leave(r);   // Connected okay
+		if (r != KErrNotFound && r != KErrServerTerminated)
+			   User::Leave(r);   // Something else happened
+		if (--retry == 0)
+			User::Leave(r);      // Give up after a while
+		r = StartServer();       // Try starting again
+		if (r != KErrNone && r != KErrAlreadyExists)
+			User::Leave(r);
+		}
+	}
+
+TInt RRandomSessionImpl::GetRandom(TDes8& aDestination)
+	{
+	TInt desclength = aDestination.Length();
+	for ( TInt i = 0; i < desclength; i += KRandomBlockSize)
+		{
+		TInt getlen = Min(KRandomBlockSize, desclength - i);
+		TPtr8 buffer(&aDestination[i], KRandomBlockSize, KRandomBlockSize);
+		TInt err = SendReceive(CRandomSession::KRandomRequest, TIpcArgs(&buffer, getlen));
+		if (err != KErrNone)
+			{
+			return err;
+			}
+		}
+	return KErrNone;
+	}
+
+// Methods which are not supported can be excluded from the coverage.
+#ifdef _BullseyeCoverage
+#pragma suppress_warnings on
+#pragma BullseyeCoverage off
+#pragma suppress_warnings off
+#endif
+
+TAny* CRandomImpl::GetExtension(TUid /*aExtensionId*/)
+	{
+	return NULL;
+	}