os/security/crypto/weakcrypto/source/random/random.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 /*
     2 * Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
     3 * All rights reserved.
     4 * This component and the accompanying materials are made available
     5 * under the terms of the License "Eclipse Public License v1.0"
     6 * which accompanies this distribution, and is available
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
     8 *
     9 * Initial Contributors:
    10 * Nokia Corporation - initial contribution.
    11 *
    12 * Contributors:
    13 *
    14 * Description: 
    15 * (c) 1999-2003 Symbian Ltd
    16 *
    17 */
    18 
    19 
    20 /**
    21  @file
    22 */
    23 
    24 #include <e32std.h>
    25 #include <random.h>
    26 #include <hash.h>
    27 #include <e32math.h>
    28 #include "randsvr.h"
    29 #include "randcliserv.h"
    30 
    31 _LIT(KRandomServerImg,"z:\\system\\libs\\randsvr.exe");		// DLL/EXE name
    32 _LIT(KRandomServerConnect, "Randsvr connect");
    33 _LIT(KRandomServerGet, "Randsvr get");
    34 
    35 const TUid KServerUid3={0x100066dc};
    36 
    37 extern "C" {
    38 EXPORT_C void RAND_bytes(unsigned char* buf,int bytes)
    39 	{
    40 	TPtr8 ptr(buf,bytes,bytes);
    41 	buf[0]++;
    42 	TRandom::Random(ptr);
    43 	}
    44 }
    45 
    46 EXPORT_C CRandom::CRandom(void)
    47 	{
    48 	}
    49 
    50 EXPORT_C CSystemRandom* CSystemRandom::NewL(void)
    51 	{
    52 	CSystemRandom* self = new(ELeave)CSystemRandom();
    53 	return self;
    54 	}
    55 
    56 EXPORT_C CSystemRandom* CSystemRandom::NewLC(void)
    57 	{
    58 	CSystemRandom* self = NewL();
    59 	CleanupStack::PushL(self);
    60 	return self;
    61 	}
    62 
    63 void CSystemRandom::GenerateBytesL(TDes8& aDest)
    64 	{
    65 	TRandom::RandomL(aDest);
    66 	}
    67 
    68 CSystemRandom::CSystemRandom(void)
    69 	{
    70 	}
    71 
    72 EXPORT_C void TRandom::Random(TDes8& aDestination)
    73 	{
    74 	RRandomSession rs;
    75 	TRAPD(ret,rs.ConnectL());
    76 	if (ret)
    77 		{
    78 		User::Panic(KRandomServerConnect, ret);
    79 		}
    80 	TInt err=rs.GetRandom(aDestination);
    81 	if (err)
    82 		{
    83 		User::Panic(KRandomServerGet, err);
    84 		}
    85 	rs.Close();
    86 	}
    87 
    88 EXPORT_C void TRandom::RandomL(TDes8& aDestination)
    89 	{
    90 	RRandomSession rs;
    91 	TRAPD(ret,rs.ConnectL());
    92 	User::LeaveIfError(ret);
    93 	CleanupClosePushL(rs);
    94 
    95 	TInt err=rs.GetRandom(aDestination);
    96 	User::LeaveIfError(err);
    97 
    98 	CleanupStack::PopAndDestroy(); // rs
    99 	}
   100 
   101 EXPORT_C RRandomSession::RRandomSession(void)
   102 	{
   103 	}
   104 
   105 static TInt StartServer()
   106 // Borrowed from AndrewT's server startup code.
   107 // Start the server process/thread which lives in an EPOCEXE object
   108 //
   109 	{
   110 	
   111 	const TUidType serverUid(KNullUid,KNullUid,KServerUid3);
   112 
   113 	//
   114 	// EPOC and EKA2 is easy, we just create a new server process. Simultaneous
   115 	// launching of two such processes should be detected when the second one
   116 	// attempts to create the server object, failing with KErrAlreadyExists.
   117 	//
   118 	RProcess server;
   119 	TInt r=server.Create(KRandomServerImg, KNullDesC, serverUid);
   120 
   121 	if (r!=KErrNone)
   122 		return r;
   123 	TRequestStatus stat;
   124 	server.Rendezvous(stat);
   125 	if (stat!=KRequestPending)
   126 		server.Kill(0);		// abort startup
   127 	else
   128 		server.Resume();	// logon OK - start the server
   129 	User::WaitForRequest(stat);		// wait for start or death
   130 	// we can't use the 'exit reason' if the server panicked as this
   131 	// is the panic 'reason' and may be '0' which cannot be distinguished
   132 	// from KErrNone
   133 	r=(server.ExitType()==EExitPanic) ? KErrGeneral : stat.Int();
   134 	server.Close();
   135 	return r;
   136 
   137 	}
   138 
   139 EXPORT_C void RRandomSession::ConnectL(void)
   140 	{
   141 	TInt retry=2;
   142 	for (;;)
   143 		{
   144 		TInt r=CreateSession(KRandomServerName,TVersion(0,0,0),1);
   145 		if (r!=KErrNotFound && r!=KErrServerTerminated)
   146 			   User::Leave(r);
   147 		if (--retry==0)
   148 			User::Leave(r);
   149 		r=StartServer();
   150 		if (r!=KErrNone && r!=KErrAlreadyExists)
   151 			User::Leave(r);
   152 		}
   153 	}
   154 
   155 EXPORT_C TInt RRandomSession::GetRandom(TDes8& aDestination)
   156 	{
   157 	if (aDestination.Length()<KRandomBlockSize)
   158 		{
   159 		return SendReceive(CRandomSession::KRandomRequest,
   160 		                   TIpcArgs(&aDestination, aDestination.Length()));
   161 		}
   162 	else
   163 		{
   164 		TInt i;
   165 		TInt err=KErrNone;
   166 		TInt length=aDestination.Length();
   167 		for (i=0;(i+KRandomBlockSize)<length;i+=KRandomBlockSize)
   168 			{
   169 			TPtr8 buffer(&aDestination[i],KRandomBlockSize,KRandomBlockSize);
   170 			err=SendReceive(CRandomSession::KRandomRequest,
   171 			 				TIpcArgs(&buffer, KRandomBlockSize));
   172 			if (err)
   173 				{
   174 				return err;
   175 				}
   176 			}
   177 		TPtr8 buffer(&aDestination[i],length%KRandomBlockSize,KRandomBlockSize);
   178 		err=SendReceive(CRandomSession::KRandomRequest,
   179 						TIpcArgs(&buffer, length-i));
   180 		return err;
   181 		}
   182 	}
   183