First public contribution.
2 * Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
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".
9 * Initial Contributors:
10 * Nokia Corporation - initial contribution.
24 #include <kernel/kern_priv.h>
25 #include "cryptodriver.h"
27 #include <omap_hrp/assp/shared/omap_reg.h>
28 #include <omap_hrp/assp/shared/omap_interrupt.h>
31 #include "cryptoh4rng.h"
32 #include "cryptoh4aes.h"
34 DECLARE_STANDARD_PDD()
36 return new DCryptoPddFactory;
39 // Name for PDD, must match LDD name with a '.' and distinguishing name appended
40 _LIT(KCryptoH4PddName,"crypto.h4");
42 DCryptoPddFactory::DCryptoPddFactory()
43 // : iDfcQueInitialised(EFalse)
45 TRACE_FUNCTION("DCryptoPddFactory");
46 // Set version number for this device
48 // We re-use the version number of the LDD which effectively
49 // specifies the version of both the external RCryptoDriver
50 // interface to the LDD and the internal LDD to PDD interface.
51 iVersion=RCryptoDriver::VersionRequired();
54 void DCryptoPddFactory::DeleteDfcQFunc(TAny *p)
56 TRACE_FUNCTION("DeleteDfcQFunc");
57 // We do not need to delete the TDfc because it is a static
58 // Delete the DFC queue.
59 TDfcQue *q = reinterpret_cast<TDfcQue *>(p);
65 TDfc deleteDfcQDfc(0, 0, 0); // Dummy create, will be overwritten later
67 DCryptoPddFactory::~DCryptoPddFactory()
69 TRACE_FUNCTION("~DCryptoPddFactory");
70 if(iDfcQueInitialised)
72 // Need to shutdown our DFC queue.
74 // In theory the DFC could run after we have returned and the
75 // framework has deleting everything...
77 // But the DLL will NOT be unloaded until the next time the
78 // IDLE task runs, so we know the DFC will reach completion
79 // before then (but it most not use any of our members....
81 // For the same reason we should use a TDfc which is not
82 // inside this object.
83 deleteDfcQDfc = TDfc(DeleteDfcQFunc, iDfcQue, iDfcQue, 0);
84 deleteDfcQDfc.Enque();
85 iDfcQueInitialised = EFalse;
92 // Missing h/w registers & masks
93 const TUint KHtRngSysResetStatus = KBit0;
96 Second stage constructor for DPhysicalDevice derived objects.
97 This must at least set a name for the driver object.
99 @return KErrNone or standard error code.
101 _LIT(KCryptoHwQueueName, "CryptoHwDfcQue");
102 TInt DCryptoPddFactory::Install()
104 TRACE_FUNCTION("Install");
105 // 28 is the recommended setting for a low priority kernel driver
106 // (I can't find an enum for this).
107 TInt r = Kern::DfcQCreate(iDfcQue, 28, &KCryptoHwQueueName);
112 iDfcQueInitialised = ETrue;
115 Kern::Printf("DCryptoPddFactory::Install - Reseting h/w");
118 // The RNG has no state worth reseting - a reset would delay the
119 // availabilty of a new random number (and maybe reduce its
121 // TOmap::SetRegister32(KHwBaseRngReg + KHoRng_Mask, KHtRngMaskSoftReset);
124 TOmap::SetRegister32(KHwBaseDes3DesReg + KHoDES_MASK, KHtDesMaskSoftReset);
127 TOmap::SetRegister32(KHwBaseSha1Md5Reg + KHoSHA_MASK, KHtShaMaskSoftReset);
130 TOmap::SetRegister32(KHwBaseAesReg + KHoAES_MASK, KHtAesMaskSoftReset);
133 TOmap::SetRegister32(KHwBasePkaReg + KHoPKA_MASK, KHtPkaMaskSoftReset);
135 // Make sure all cypto h/w (rng/des/sha1/aes/pka) is out of reset
136 while(((TOmap::Register32(KHwBaseRngReg + KHoRng_SysStatus) & KHtRngSysResetStatus) == 0) ||
137 ((TOmap::Register32(KHwBaseDes3DesReg + KHoDES_SYSSTATUS) & KHtDesSysResetStatus) == 0) ||
138 ((TOmap::Register32(KHwBaseSha1Md5Reg + KHoSHA_SYSSTATUS) & KHtShaSysResetStatus) == 0) ||
139 ((TOmap::Register32(KHwBaseAesReg + KHoAES_SYSSTATUS) & KHtAesSysResetStatus) == 0) ||
140 ((TOmap::Register32(KHwBasePkaReg + KHoPKA_SYSSTATUS) & KHtPkaSysResetStatus) == 0))
142 Kern::Printf("DCryptoPddFactory::Install - waiting for h/w");
146 // Kern::Printf("DCryptoPddFactory::Install - h/w reset complete");
148 return SetName(&KCryptoH4PddName);
155 Returns the drivers capabilities.
157 This is required by the Symbian OS device driver framework.
159 It can NOT be used by the LDD factory GetCaps function because that
160 class does not contain a link tous (and we might not be loaded)....
162 NOT USED IN THIS DRIVER.
164 @param aDes Descriptor to write capabilities information into
166 void DCryptoPddFactory::GetCaps(TDes8& /* aDes */) const
168 TRACE_FUNCTION("GetCaps");
173 Called by the kernel's device driver framework to create a Physical Channel.
174 This is called in the context of the user thread (client) which requested the creation of a Logical Channel
175 (E.g. through a call to RBusLogicalChannel::DoCreate)
176 The thread is in a critical section.
178 @param aChannel Set to point to the created Physical Channel
179 @param aUnit The unit argument supplied by the client to RBusLogicalChannel::DoCreate
180 @param aInfo The info argument supplied by the client to RBusLogicalChannel::DoCreate
181 @param aVer The version number of the Logical Channel which will use this Physical Channel
183 @return KErrNone or standard error code.
185 TInt DCryptoPddFactory::Create(DBase*& aChannel, TInt aUnit, const TDesC8* aInfo, const TVersion& aVer)
187 TRACE_FUNCTION("Create");
188 // Ignore the parameters we aren't interested in...
193 // Create a new physical channel
194 DCryptoH4Chan* device=new DCryptoH4Chan(*this);
198 return device->DoCreate();
202 Called by the kernel's device driver framework to check if this PDD is suitable for use with a Logical Channel.
203 This is called in the context of the user thread (client) which requested the creation of a Logical Channel
204 (E.g. through a call to RBusLogicalChannel::DoCreate)
205 The thread is in a critical section.
207 @param aUnit The unit argument supplied by the client to RBusLogicalChannel::DoCreate
208 @param aInfo The info argument supplied by the client to RBusLogicalChannel::DoCreate
209 @param aVer The version number of the Logical Channel which will use this Physical Channel
211 @return KErrNone or standard error code.
213 TInt DCryptoPddFactory::Validate(TInt aUnit, const TDesC8* aInfo, const TVersion& aVer)
215 TRACE_FUNCTION("Validate");
216 // Check version numbers
217 if ((!Kern::QueryVersionSupported(iVersion,aVer)) || (!Kern::QueryVersionSupported(aVer,TVersion(EMinimumLddMajorVersion,EMinimumLddMinorVersion,EMinimumLddBuild))))
218 return KErrNotSupported;
220 // We don't support units
222 return KErrNotSupported;
224 // Ignore extra info, (this could be used for validation purposes)
225 // Note, aInfo is a pointer to a descriptor in user memory, therefore safe methods should
226 // be used for reading its contents. E.g. using Kern::KUDesGet()
234 TDfcQue *DCryptoPddFactory::DfcQue()
236 TRACE_FUNCTION("DfcQue");
246 DCryptoH4Chan::DCryptoH4Chan(DCryptoPddFactory &iCryptoPddFactory)
247 : iCryptoPddFactory(iCryptoPddFactory),
248 iFakeDriverSetting(100000)
250 TRACE_FUNCTION("DCryptoH4Chan");
253 DCryptoH4Chan::~DCryptoH4Chan()
255 TRACE_FUNCTION("~DCryptoH4Chan");
258 // Make sure we are not queued on a job scheduler.
259 iCryptoJobRandom->DeScheduleJob();
260 delete iCryptoJobRandom;
264 // Make sure we are not queued on a job scheduler.
265 iCryptoJobAes->DeScheduleJob();
266 delete iCryptoJobAes;
271 TInt DCryptoH4Chan::DoCreate()
273 TRACE_FUNCTION("DoCreate");
279 TDfcQue* DCryptoH4Chan::DfcQue()
281 TRACE_FUNCTION("DfcQue");
282 return iCryptoPddFactory.DfcQue();
285 void DCryptoH4Chan::GetHwVersions(RCryptoDriver::THwVersions &aHwVersions) const
287 TRACE_FUNCTION("THwVersions");
289 aHwVersions.iRngHwVersion = TOmap::Register32(KHwBaseRngReg + KHoRng_Rev);
290 aHwVersions.iDes3DesHwVersion = TOmap::Register32(KHwBaseDes3DesReg + KHoDES_REV);
291 aHwVersions.iSha1Md5HwVersion = TOmap::Register32(KHwBaseSha1Md5Reg + KHoSHA_REV);
292 aHwVersions.iAesHwVersion = TOmap::Register32(KHwBaseAesReg + KHoAES_REV);
293 aHwVersions.iPkaHwVersion = TOmap::Register32(KHwBasePkaReg + KHoPKA_REV);
294 TOmap::SetRegister32(KHwBasePkaReg + KHoPKA_REV,42);
295 aHwVersions.iPkaHwVersion = TOmap::Register32(KHwBasePkaReg + KHoPKA_REV);
297 // Return fake hardware versions for testing
298 aHwVersions.iRngHwVersion = 42;
299 aHwVersions.iDes3DesHwVersion = 43;
300 aHwVersions.iSha1Md5HwVersion = 44;
301 aHwVersions.iAesHwVersion = 45;
302 aHwVersions.iPkaHwVersion = 46;
306 TInt DCryptoH4Chan::FakeDriverSetting() const
308 TRACE_FUNCTION("FakeDriverSetting");
309 return iFakeDriverSetting;
312 TInt DCryptoH4Chan::SetFakeDriverSetting(TInt aFakeDriverSetting)
314 TRACE_FUNCTION("SetFakeDriverSetting");
315 if(aFakeDriverSetting<=0)
317 iFakeDriverSetting = aFakeDriverSetting;
321 CryptoJobRandom *DCryptoH4Chan::GetJobRandom(TBool aAutoCreate)
323 TRACE_FUNCTION("GetJobRandom");
324 if(aAutoCreate && iCryptoJobRandom == 0)
326 iCryptoJobRandom = new CryptoH4JobRandom(iCryptoLddChannel->iLddChanRandom);
327 iCryptoJobRandom->SetDfcQ(DfcQue());
329 return iCryptoJobRandom;
332 CryptoJobAes *DCryptoH4Chan::GetJobAes(TBool aAutoCreate)
334 TRACE_FUNCTION("GetJobAes");
335 if(aAutoCreate && iCryptoJobAes == 0)
337 iCryptoJobAes = new CryptoH4JobAes(iCryptoLddChannel->iLddChanAes);
338 iCryptoJobAes->SetDfcQ(DfcQue());
340 return iCryptoJobAes;