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