os/security/cryptoplugins/cryptospiplugins/test/h4drv/crypto_h4/cryptoh4.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 /*
     2 * Copyright (c) 2007-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 *
    16 */
    17 
    18 
    19 /**
    20  @file
    21  @internalComponent
    22  @released
    23 */
    24 #include <kernel/kern_priv.h>
    25 #include "cryptodriver.h"
    26 #ifdef __MARM__
    27 #include <omap_hrp/assp/shared/omap_reg.h>
    28 #include <omap_hrp/assp/shared/omap_interrupt.h>
    29 #endif
    30 #include "cryptoh4.h"
    31 #include "cryptoh4rng.h"
    32 #include "cryptoh4aes.h"
    33 
    34 DECLARE_STANDARD_PDD()
    35     {
    36     return new DCryptoPddFactory;
    37     }
    38 
    39 // Name for PDD, must match LDD name with a '.' and distinguishing name appended
    40 _LIT(KCryptoH4PddName,"crypto.h4");
    41 
    42 DCryptoPddFactory::DCryptoPddFactory()
    43 	// : iDfcQueInitialised(EFalse)
    44     {
    45 	TRACE_FUNCTION("DCryptoPddFactory");
    46 	// Set version number for this device
    47 	//
    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();
    52     }
    53 
    54 void DCryptoPddFactory::DeleteDfcQFunc(TAny *p)
    55 	{
    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);
    60 	delete q;
    61 	// Delete our thread
    62 	Kern::Exit(KErrNone);
    63 	}
    64 
    65 TDfc deleteDfcQDfc(0, 0, 0); // Dummy create, will be overwritten later
    66 
    67 DCryptoPddFactory::~DCryptoPddFactory()
    68 	{
    69 	TRACE_FUNCTION("~DCryptoPddFactory");
    70 	if(iDfcQueInitialised)
    71 		{
    72 		// Need to shutdown our DFC queue.
    73 		// 
    74 		// In theory the DFC could run after we have returned and the
    75 		// framework has deleting everything...
    76 		// 
    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....
    80 		//
    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;
    86 		}
    87 	}
    88 
    89 
    90 
    91 
    92 // Missing h/w registers & masks
    93 const TUint KHtRngSysResetStatus = KBit0;
    94 
    95 /**
    96   Second stage constructor for DPhysicalDevice derived objects.
    97   This must at least set a name for the driver object.
    98 
    99   @return KErrNone or standard error code.
   100 */
   101 _LIT(KCryptoHwQueueName, "CryptoHwDfcQue");
   102 TInt DCryptoPddFactory::Install()
   103     {
   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);
   108 	if(r != KErrNone)
   109 		{
   110 		return r;
   111 		}
   112 	iDfcQueInitialised = ETrue;
   113 
   114 	// Reset h/w
   115 	Kern::Printf("DCryptoPddFactory::Install - Reseting h/w");
   116 #ifdef __MARM__
   117 	// RNG
   118 	// The RNG has no state worth reseting - a reset would delay the
   119 	// availabilty of a new random number (and maybe reduce its
   120 	// quality).
   121 	//	TOmap::SetRegister32(KHwBaseRngReg + KHoRng_Mask, KHtRngMaskSoftReset);
   122 
   123 	// DES/3DES
   124 	TOmap::SetRegister32(KHwBaseDes3DesReg + KHoDES_MASK, KHtDesMaskSoftReset);
   125 
   126 	// SHA1/MD5
   127 	TOmap::SetRegister32(KHwBaseSha1Md5Reg + KHoSHA_MASK, KHtShaMaskSoftReset);
   128 
   129 	// AES
   130 	TOmap::SetRegister32(KHwBaseAesReg + KHoAES_MASK, KHtAesMaskSoftReset);
   131 
   132 	// PKA
   133 	TOmap::SetRegister32(KHwBasePkaReg + KHoPKA_MASK, KHtPkaMaskSoftReset);
   134 	
   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))
   141 		{
   142 		Kern::Printf("DCryptoPddFactory::Install - waiting for h/w");
   143 		}
   144 
   145 #endif
   146 	//	Kern::Printf("DCryptoPddFactory::Install - h/w reset complete");
   147 
   148     return SetName(&KCryptoH4PddName);
   149     }
   150 
   151 
   152 
   153 
   154 /**
   155    Returns the drivers capabilities.
   156 
   157    This is required by the Symbian OS device driver framework.
   158    
   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)....
   161 
   162    NOT USED IN THIS DRIVER.
   163    
   164    @param aDes Descriptor to write capabilities information into
   165 */
   166 void DCryptoPddFactory::GetCaps(TDes8& /* aDes */) const
   167 	{
   168 	TRACE_FUNCTION("GetCaps");
   169 	}
   170 
   171 
   172 /**
   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.
   177 
   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 
   182 
   183   @return KErrNone or standard error code.
   184 */
   185 TInt DCryptoPddFactory::Create(DBase*& aChannel, TInt aUnit, const TDesC8* aInfo, const TVersion& aVer)
   186     {
   187 	TRACE_FUNCTION("Create");
   188     // Ignore the parameters we aren't interested in...
   189     (void)aUnit;
   190     (void)aInfo;
   191     (void)aVer;
   192 
   193     // Create a new physical channel
   194 DCryptoH4Chan* device=new DCryptoH4Chan(*this);
   195     aChannel=device;
   196     if (!device)
   197         return KErrNoMemory;
   198     return device->DoCreate();
   199     }
   200 
   201 /**
   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.
   206 
   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 
   210 
   211   @return KErrNone or standard error code.
   212 */
   213 TInt DCryptoPddFactory::Validate(TInt aUnit, const TDesC8* aInfo, const TVersion& aVer)
   214     {
   215 	TRACE_FUNCTION("Validate");
   216     // Check version numbers
   217     if ((!Kern::QueryVersionSupported(iVersion,aVer)) || (!Kern::QueryVersionSupported(aVer,TVersion(EMinimumLddMajorVersion,EMinimumLddMinorVersion,EMinimumLddBuild))))
   218         return KErrNotSupported;
   219 
   220     // We don't support units
   221     if (aUnit != -1)
   222         return KErrNotSupported;
   223 
   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()
   227     (void)aInfo;
   228 
   229     // OK
   230     return KErrNone;
   231     }
   232 
   233 
   234 TDfcQue *DCryptoPddFactory::DfcQue()
   235 	{
   236 	TRACE_FUNCTION("DfcQue");
   237 	return iDfcQue;
   238 	}
   239 
   240 
   241 
   242 //
   243 // DCryptoH4Chan
   244 //
   245 
   246 DCryptoH4Chan::DCryptoH4Chan(DCryptoPddFactory &iCryptoPddFactory)
   247     : iCryptoPddFactory(iCryptoPddFactory),
   248 	  iFakeDriverSetting(100000)
   249     {
   250 	TRACE_FUNCTION("DCryptoH4Chan");
   251     }
   252 
   253 DCryptoH4Chan::~DCryptoH4Chan()
   254     {
   255 	TRACE_FUNCTION("~DCryptoH4Chan");
   256 	if(iCryptoJobRandom)
   257 		{
   258 		// Make sure we are not queued on a job scheduler.
   259 		iCryptoJobRandom->DeScheduleJob();
   260 		delete iCryptoJobRandom;
   261 		}
   262 	if(iCryptoJobAes)
   263 		{
   264 		// Make sure we are not queued on a job scheduler.
   265 		iCryptoJobAes->DeScheduleJob();
   266 		delete iCryptoJobAes;
   267 		}
   268     }
   269 
   270 
   271 TInt DCryptoH4Chan::DoCreate()
   272     {
   273 	TRACE_FUNCTION("DoCreate");
   274 
   275 
   276     return KErrNone;
   277     }
   278 
   279 TDfcQue* DCryptoH4Chan::DfcQue()
   280     {
   281 	TRACE_FUNCTION("DfcQue");
   282     return iCryptoPddFactory.DfcQue();
   283     }
   284 
   285 void DCryptoH4Chan::GetHwVersions(RCryptoDriver::THwVersions &aHwVersions) const
   286 	{
   287 	TRACE_FUNCTION("THwVersions");
   288 #ifdef __MARM__
   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);
   296 #else
   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;
   303 #endif
   304     }
   305 
   306 TInt DCryptoH4Chan::FakeDriverSetting() const
   307     {
   308 	TRACE_FUNCTION("FakeDriverSetting");
   309     return iFakeDriverSetting;
   310     }
   311 
   312 TInt DCryptoH4Chan::SetFakeDriverSetting(TInt aFakeDriverSetting)
   313     {
   314 	TRACE_FUNCTION("SetFakeDriverSetting");
   315     if(aFakeDriverSetting<=0)
   316         return KErrArgument;
   317     iFakeDriverSetting = aFakeDriverSetting;
   318     return KErrNone;
   319     }
   320 
   321 CryptoJobRandom *DCryptoH4Chan::GetJobRandom(TBool aAutoCreate)
   322 	{
   323 	TRACE_FUNCTION("GetJobRandom");
   324 	if(aAutoCreate && iCryptoJobRandom == 0)
   325 		{
   326 		iCryptoJobRandom = new CryptoH4JobRandom(iCryptoLddChannel->iLddChanRandom);
   327 		iCryptoJobRandom->SetDfcQ(DfcQue());
   328 		}
   329 	return iCryptoJobRandom;
   330 	}
   331 
   332 CryptoJobAes *DCryptoH4Chan::GetJobAes(TBool aAutoCreate)
   333 	{
   334 	TRACE_FUNCTION("GetJobAes");
   335 	if(aAutoCreate && iCryptoJobAes == 0)
   336 		{
   337 		iCryptoJobAes = new CryptoH4JobAes(iCryptoLddChannel->iLddChanAes);
   338 		iCryptoJobAes->SetDfcQ(DfcQue());
   339 		}
   340 	return iCryptoJobAes;
   341 	}
   342 
   343 
   344 // End of file