os/security/cryptoplugins/cryptospiplugins/test/h4drv/crypto_h4/cryptoh4.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/security/cryptoplugins/cryptospiplugins/test/h4drv/crypto_h4/cryptoh4.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,344 @@
     1.4 +/*
     1.5 +* Copyright (c) 2007-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 + @internalComponent
    1.25 + @released
    1.26 +*/
    1.27 +#include <kernel/kern_priv.h>
    1.28 +#include "cryptodriver.h"
    1.29 +#ifdef __MARM__
    1.30 +#include <omap_hrp/assp/shared/omap_reg.h>
    1.31 +#include <omap_hrp/assp/shared/omap_interrupt.h>
    1.32 +#endif
    1.33 +#include "cryptoh4.h"
    1.34 +#include "cryptoh4rng.h"
    1.35 +#include "cryptoh4aes.h"
    1.36 +
    1.37 +DECLARE_STANDARD_PDD()
    1.38 +    {
    1.39 +    return new DCryptoPddFactory;
    1.40 +    }
    1.41 +
    1.42 +// Name for PDD, must match LDD name with a '.' and distinguishing name appended
    1.43 +_LIT(KCryptoH4PddName,"crypto.h4");
    1.44 +
    1.45 +DCryptoPddFactory::DCryptoPddFactory()
    1.46 +	// : iDfcQueInitialised(EFalse)
    1.47 +    {
    1.48 +	TRACE_FUNCTION("DCryptoPddFactory");
    1.49 +	// Set version number for this device
    1.50 +	//
    1.51 +	// We re-use the version number of the LDD which effectively
    1.52 +	// specifies the version of both the external RCryptoDriver
    1.53 +	// interface to the LDD and the internal LDD to PDD interface.
    1.54 +    iVersion=RCryptoDriver::VersionRequired();
    1.55 +    }
    1.56 +
    1.57 +void DCryptoPddFactory::DeleteDfcQFunc(TAny *p)
    1.58 +	{
    1.59 +	TRACE_FUNCTION("DeleteDfcQFunc");
    1.60 +	// We do not need to delete the TDfc because it is a static
    1.61 +	// Delete the DFC queue.
    1.62 +	TDfcQue *q = reinterpret_cast<TDfcQue *>(p);
    1.63 +	delete q;
    1.64 +	// Delete our thread
    1.65 +	Kern::Exit(KErrNone);
    1.66 +	}
    1.67 +
    1.68 +TDfc deleteDfcQDfc(0, 0, 0); // Dummy create, will be overwritten later
    1.69 +
    1.70 +DCryptoPddFactory::~DCryptoPddFactory()
    1.71 +	{
    1.72 +	TRACE_FUNCTION("~DCryptoPddFactory");
    1.73 +	if(iDfcQueInitialised)
    1.74 +		{
    1.75 +		// Need to shutdown our DFC queue.
    1.76 +		// 
    1.77 +		// In theory the DFC could run after we have returned and the
    1.78 +		// framework has deleting everything...
    1.79 +		// 
    1.80 +		// But the DLL will NOT be unloaded until the next time the
    1.81 +		// IDLE task runs, so we know the DFC will reach completion
    1.82 +		// before then (but it most not use any of our members....
    1.83 +		//
    1.84 +		// For the same reason we should use a TDfc which is not
    1.85 +		// inside this object.
    1.86 +		deleteDfcQDfc = TDfc(DeleteDfcQFunc, iDfcQue, iDfcQue, 0);
    1.87 +		deleteDfcQDfc.Enque();
    1.88 +		iDfcQueInitialised = EFalse;
    1.89 +		}
    1.90 +	}
    1.91 +
    1.92 +
    1.93 +
    1.94 +
    1.95 +// Missing h/w registers & masks
    1.96 +const TUint KHtRngSysResetStatus = KBit0;
    1.97 +
    1.98 +/**
    1.99 +  Second stage constructor for DPhysicalDevice derived objects.
   1.100 +  This must at least set a name for the driver object.
   1.101 +
   1.102 +  @return KErrNone or standard error code.
   1.103 +*/
   1.104 +_LIT(KCryptoHwQueueName, "CryptoHwDfcQue");
   1.105 +TInt DCryptoPddFactory::Install()
   1.106 +    {
   1.107 +	TRACE_FUNCTION("Install");
   1.108 +	// 28 is the recommended setting for a low priority kernel driver
   1.109 +	// (I can't find an enum for this).
   1.110 +	TInt r = Kern::DfcQCreate(iDfcQue, 28, &KCryptoHwQueueName);
   1.111 +	if(r != KErrNone)
   1.112 +		{
   1.113 +		return r;
   1.114 +		}
   1.115 +	iDfcQueInitialised = ETrue;
   1.116 +
   1.117 +	// Reset h/w
   1.118 +	Kern::Printf("DCryptoPddFactory::Install - Reseting h/w");
   1.119 +#ifdef __MARM__
   1.120 +	// RNG
   1.121 +	// The RNG has no state worth reseting - a reset would delay the
   1.122 +	// availabilty of a new random number (and maybe reduce its
   1.123 +	// quality).
   1.124 +	//	TOmap::SetRegister32(KHwBaseRngReg + KHoRng_Mask, KHtRngMaskSoftReset);
   1.125 +
   1.126 +	// DES/3DES
   1.127 +	TOmap::SetRegister32(KHwBaseDes3DesReg + KHoDES_MASK, KHtDesMaskSoftReset);
   1.128 +
   1.129 +	// SHA1/MD5
   1.130 +	TOmap::SetRegister32(KHwBaseSha1Md5Reg + KHoSHA_MASK, KHtShaMaskSoftReset);
   1.131 +
   1.132 +	// AES
   1.133 +	TOmap::SetRegister32(KHwBaseAesReg + KHoAES_MASK, KHtAesMaskSoftReset);
   1.134 +
   1.135 +	// PKA
   1.136 +	TOmap::SetRegister32(KHwBasePkaReg + KHoPKA_MASK, KHtPkaMaskSoftReset);
   1.137 +	
   1.138 +	// Make sure all cypto h/w (rng/des/sha1/aes/pka) is out of reset
   1.139 +	while(((TOmap::Register32(KHwBaseRngReg + KHoRng_SysStatus) & KHtRngSysResetStatus) == 0) ||
   1.140 +		  ((TOmap::Register32(KHwBaseDes3DesReg + KHoDES_SYSSTATUS) & KHtDesSysResetStatus) == 0) ||
   1.141 +		  ((TOmap::Register32(KHwBaseSha1Md5Reg + KHoSHA_SYSSTATUS) & KHtShaSysResetStatus) == 0) ||
   1.142 +		  ((TOmap::Register32(KHwBaseAesReg + KHoAES_SYSSTATUS) & KHtAesSysResetStatus) == 0) ||
   1.143 +		  ((TOmap::Register32(KHwBasePkaReg + KHoPKA_SYSSTATUS) & KHtPkaSysResetStatus) == 0))
   1.144 +		{
   1.145 +		Kern::Printf("DCryptoPddFactory::Install - waiting for h/w");
   1.146 +		}
   1.147 +
   1.148 +#endif
   1.149 +	//	Kern::Printf("DCryptoPddFactory::Install - h/w reset complete");
   1.150 +
   1.151 +    return SetName(&KCryptoH4PddName);
   1.152 +    }
   1.153 +
   1.154 +
   1.155 +
   1.156 +
   1.157 +/**
   1.158 +   Returns the drivers capabilities.
   1.159 +
   1.160 +   This is required by the Symbian OS device driver framework.
   1.161 +   
   1.162 +   It can NOT be used by the LDD factory GetCaps function because that
   1.163 +   class does not contain a link tous (and we might not be loaded)....
   1.164 +
   1.165 +   NOT USED IN THIS DRIVER.
   1.166 +   
   1.167 +   @param aDes Descriptor to write capabilities information into
   1.168 +*/
   1.169 +void DCryptoPddFactory::GetCaps(TDes8& /* aDes */) const
   1.170 +	{
   1.171 +	TRACE_FUNCTION("GetCaps");
   1.172 +	}
   1.173 +
   1.174 +
   1.175 +/**
   1.176 +  Called by the kernel's device driver framework to create a Physical Channel.
   1.177 +  This is called in the context of the user thread (client) which requested the creation of a Logical Channel
   1.178 +  (E.g. through a call to RBusLogicalChannel::DoCreate)
   1.179 +  The thread is in a critical section.
   1.180 +
   1.181 +  @param aChannel Set to point to the created Physical Channel
   1.182 +  @param aUnit The unit argument supplied by the client to RBusLogicalChannel::DoCreate
   1.183 +  @param aInfo The info argument supplied by the client to RBusLogicalChannel::DoCreate
   1.184 +  @param aVer The version number of the Logical Channel which will use this Physical Channel 
   1.185 +
   1.186 +  @return KErrNone or standard error code.
   1.187 +*/
   1.188 +TInt DCryptoPddFactory::Create(DBase*& aChannel, TInt aUnit, const TDesC8* aInfo, const TVersion& aVer)
   1.189 +    {
   1.190 +	TRACE_FUNCTION("Create");
   1.191 +    // Ignore the parameters we aren't interested in...
   1.192 +    (void)aUnit;
   1.193 +    (void)aInfo;
   1.194 +    (void)aVer;
   1.195 +
   1.196 +    // Create a new physical channel
   1.197 +DCryptoH4Chan* device=new DCryptoH4Chan(*this);
   1.198 +    aChannel=device;
   1.199 +    if (!device)
   1.200 +        return KErrNoMemory;
   1.201 +    return device->DoCreate();
   1.202 +    }
   1.203 +
   1.204 +/**
   1.205 +  Called by the kernel's device driver framework to check if this PDD is suitable for use with a Logical Channel.
   1.206 +  This is called in the context of the user thread (client) which requested the creation of a Logical Channel
   1.207 +  (E.g. through a call to RBusLogicalChannel::DoCreate)
   1.208 +  The thread is in a critical section.
   1.209 +
   1.210 +  @param aUnit The unit argument supplied by the client to RBusLogicalChannel::DoCreate
   1.211 +  @param aInfo The info argument supplied by the client to RBusLogicalChannel::DoCreate
   1.212 +  @param aVer The version number of the Logical Channel which will use this Physical Channel 
   1.213 +
   1.214 +  @return KErrNone or standard error code.
   1.215 +*/
   1.216 +TInt DCryptoPddFactory::Validate(TInt aUnit, const TDesC8* aInfo, const TVersion& aVer)
   1.217 +    {
   1.218 +	TRACE_FUNCTION("Validate");
   1.219 +    // Check version numbers
   1.220 +    if ((!Kern::QueryVersionSupported(iVersion,aVer)) || (!Kern::QueryVersionSupported(aVer,TVersion(EMinimumLddMajorVersion,EMinimumLddMinorVersion,EMinimumLddBuild))))
   1.221 +        return KErrNotSupported;
   1.222 +
   1.223 +    // We don't support units
   1.224 +    if (aUnit != -1)
   1.225 +        return KErrNotSupported;
   1.226 +
   1.227 +    // Ignore extra info, (this could be used for validation purposes)
   1.228 +    // Note, aInfo is a pointer to a descriptor in user memory, therefore safe methods should
   1.229 +    // be used for reading its contents. E.g. using Kern::KUDesGet()
   1.230 +    (void)aInfo;
   1.231 +
   1.232 +    // OK
   1.233 +    return KErrNone;
   1.234 +    }
   1.235 +
   1.236 +
   1.237 +TDfcQue *DCryptoPddFactory::DfcQue()
   1.238 +	{
   1.239 +	TRACE_FUNCTION("DfcQue");
   1.240 +	return iDfcQue;
   1.241 +	}
   1.242 +
   1.243 +
   1.244 +
   1.245 +//
   1.246 +// DCryptoH4Chan
   1.247 +//
   1.248 +
   1.249 +DCryptoH4Chan::DCryptoH4Chan(DCryptoPddFactory &iCryptoPddFactory)
   1.250 +    : iCryptoPddFactory(iCryptoPddFactory),
   1.251 +	  iFakeDriverSetting(100000)
   1.252 +    {
   1.253 +	TRACE_FUNCTION("DCryptoH4Chan");
   1.254 +    }
   1.255 +
   1.256 +DCryptoH4Chan::~DCryptoH4Chan()
   1.257 +    {
   1.258 +	TRACE_FUNCTION("~DCryptoH4Chan");
   1.259 +	if(iCryptoJobRandom)
   1.260 +		{
   1.261 +		// Make sure we are not queued on a job scheduler.
   1.262 +		iCryptoJobRandom->DeScheduleJob();
   1.263 +		delete iCryptoJobRandom;
   1.264 +		}
   1.265 +	if(iCryptoJobAes)
   1.266 +		{
   1.267 +		// Make sure we are not queued on a job scheduler.
   1.268 +		iCryptoJobAes->DeScheduleJob();
   1.269 +		delete iCryptoJobAes;
   1.270 +		}
   1.271 +    }
   1.272 +
   1.273 +
   1.274 +TInt DCryptoH4Chan::DoCreate()
   1.275 +    {
   1.276 +	TRACE_FUNCTION("DoCreate");
   1.277 +
   1.278 +
   1.279 +    return KErrNone;
   1.280 +    }
   1.281 +
   1.282 +TDfcQue* DCryptoH4Chan::DfcQue()
   1.283 +    {
   1.284 +	TRACE_FUNCTION("DfcQue");
   1.285 +    return iCryptoPddFactory.DfcQue();
   1.286 +    }
   1.287 +
   1.288 +void DCryptoH4Chan::GetHwVersions(RCryptoDriver::THwVersions &aHwVersions) const
   1.289 +	{
   1.290 +	TRACE_FUNCTION("THwVersions");
   1.291 +#ifdef __MARM__
   1.292 +	aHwVersions.iRngHwVersion = TOmap::Register32(KHwBaseRngReg + KHoRng_Rev);
   1.293 +	aHwVersions.iDes3DesHwVersion = TOmap::Register32(KHwBaseDes3DesReg + KHoDES_REV);
   1.294 +	aHwVersions.iSha1Md5HwVersion = TOmap::Register32(KHwBaseSha1Md5Reg + KHoSHA_REV);
   1.295 +	aHwVersions.iAesHwVersion = TOmap::Register32(KHwBaseAesReg + KHoAES_REV);
   1.296 +	aHwVersions.iPkaHwVersion = TOmap::Register32(KHwBasePkaReg + KHoPKA_REV);
   1.297 +	TOmap::SetRegister32(KHwBasePkaReg + KHoPKA_REV,42);
   1.298 +	aHwVersions.iPkaHwVersion = TOmap::Register32(KHwBasePkaReg + KHoPKA_REV);
   1.299 +#else
   1.300 +	// Return fake hardware versions for testing
   1.301 +	aHwVersions.iRngHwVersion = 42;
   1.302 +	aHwVersions.iDes3DesHwVersion = 43;
   1.303 +	aHwVersions.iSha1Md5HwVersion = 44;
   1.304 +	aHwVersions.iAesHwVersion = 45;
   1.305 +	aHwVersions.iPkaHwVersion = 46;
   1.306 +#endif
   1.307 +    }
   1.308 +
   1.309 +TInt DCryptoH4Chan::FakeDriverSetting() const
   1.310 +    {
   1.311 +	TRACE_FUNCTION("FakeDriverSetting");
   1.312 +    return iFakeDriverSetting;
   1.313 +    }
   1.314 +
   1.315 +TInt DCryptoH4Chan::SetFakeDriverSetting(TInt aFakeDriverSetting)
   1.316 +    {
   1.317 +	TRACE_FUNCTION("SetFakeDriverSetting");
   1.318 +    if(aFakeDriverSetting<=0)
   1.319 +        return KErrArgument;
   1.320 +    iFakeDriverSetting = aFakeDriverSetting;
   1.321 +    return KErrNone;
   1.322 +    }
   1.323 +
   1.324 +CryptoJobRandom *DCryptoH4Chan::GetJobRandom(TBool aAutoCreate)
   1.325 +	{
   1.326 +	TRACE_FUNCTION("GetJobRandom");
   1.327 +	if(aAutoCreate && iCryptoJobRandom == 0)
   1.328 +		{
   1.329 +		iCryptoJobRandom = new CryptoH4JobRandom(iCryptoLddChannel->iLddChanRandom);
   1.330 +		iCryptoJobRandom->SetDfcQ(DfcQue());
   1.331 +		}
   1.332 +	return iCryptoJobRandom;
   1.333 +	}
   1.334 +
   1.335 +CryptoJobAes *DCryptoH4Chan::GetJobAes(TBool aAutoCreate)
   1.336 +	{
   1.337 +	TRACE_FUNCTION("GetJobAes");
   1.338 +	if(aAutoCreate && iCryptoJobAes == 0)
   1.339 +		{
   1.340 +		iCryptoJobAes = new CryptoH4JobAes(iCryptoLddChannel->iLddChanAes);
   1.341 +		iCryptoJobAes->SetDfcQ(DfcQue());
   1.342 +		}
   1.343 +	return iCryptoJobAes;
   1.344 +	}
   1.345 +
   1.346 +
   1.347 +// End of file