sl@0: /* sl@0: * Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: * All rights reserved. sl@0: * This component and the accompanying materials are made available sl@0: * under the terms of the License "Eclipse Public License v1.0" sl@0: * which accompanies this distribution, and is available sl@0: * at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: * sl@0: * Initial Contributors: sl@0: * Nokia Corporation - initial contribution. sl@0: * sl@0: * Contributors: sl@0: * sl@0: * Description: sl@0: * sl@0: */ sl@0: sl@0: sl@0: /** sl@0: @file sl@0: @internalComponent sl@0: @released sl@0: */ sl@0: #ifndef __CRYPTOJOBS__ sl@0: #define __CRYPTOJOBS__ sl@0: #include sl@0: #include sl@0: #include sl@0: #include "cryptodriver.h" sl@0: sl@0: #define TRACE_FUNCTION(funcName) do{ static TraceFunction tf( __FILE__ , funcName ); tf.Inc(); }while(0) sl@0: sl@0: class TraceFunction sl@0: { sl@0: public: sl@0: TraceFunction(const char *aFileName, const char *aFunctionName) sl@0: : iFileName(aFileName), sl@0: iFunctionName(aFunctionName), sl@0: iHitCount(0), sl@0: iNext(HeadRef()) sl@0: { sl@0: HeadRef() = this; sl@0: } sl@0: sl@0: void Inc() sl@0: { sl@0: ++iHitCount; sl@0: } sl@0: sl@0: static void DumpCounts() sl@0: { sl@0: Kern::Printf("TraceFunction::DumpCounts\n"); sl@0: TraceFunction *p = HeadRef(); sl@0: while(p) sl@0: { sl@0: Kern::Printf("%d\t%s:%s\n", p->iHitCount, p->iFileName, p->iFunctionName); sl@0: p->iHitCount = 0; sl@0: p = p->iNext; sl@0: } sl@0: } sl@0: sl@0: IMPORT_C static TraceFunction *&HeadRef(); sl@0: sl@0: private: sl@0: const char *iFileName; sl@0: const char *iFunctionName; sl@0: TUint32 iHitCount; sl@0: sl@0: TraceFunction *iNext; sl@0: }; sl@0: sl@0: sl@0: class CryptoJob; sl@0: class MCryptoJobCallbacks; sl@0: class DCryptoJobScheduler : public DBase sl@0: { sl@0: public: sl@0: IMPORT_C DCryptoJobScheduler(); sl@0: IMPORT_C ~DCryptoJobScheduler(); sl@0: sl@0: /** sl@0: ScheduleJob sl@0: sl@0: If job is already queued, and is the current job, and is not sl@0: already running, attempt to schedule it and return. Otherwise, sl@0: if already in the queue, just return. sl@0: sl@0: If the job is not in the queue, then add it - If the queue is sl@0: empty it is added at the front and we attempt to run it, sl@0: otherwise we add it second in the queue for later scheduling. sl@0: */ sl@0: IMPORT_C void ScheduleJob(CryptoJob *aJob); sl@0: sl@0: /** sl@0: Abort the job synchronously sl@0: sl@0: In the EReady state call DoReleaseHw derived function which sl@0: should, before returning, abort the job. sl@0: sl@0: Changes the state to Idle. sl@0: sl@0: Removes from the scheduler. sl@0: sl@0: The caller is expected to complete any outstanding user request. sl@0: */ sl@0: IMPORT_C void DeScheduleJob(CryptoJob *aJob); sl@0: sl@0: /** sl@0: SliceComplete sl@0: sl@0: Called by a job when the current slice is complete. The job sl@0: should update its internal state before calling us. sl@0: sl@0: The specified job MUST be the current job. sl@0: */ sl@0: IMPORT_C void SliceComplete(CryptoJob *aJob, TInt aStatus); sl@0: sl@0: /** sl@0: JobComplete sl@0: sl@0: Called by a job when the final slice is complete. sl@0: sl@0: The specified job MUST be the current job. sl@0: */ sl@0: IMPORT_C void JobComplete(CryptoJob *aJob, TInt aStatus); sl@0: private: sl@0: /** sl@0: Schedule sl@0: sl@0: If current job is not running make it run sl@0: */ sl@0: void Schedule(TBool aReschedule); sl@0: sl@0: CryptoJob *iJobList; sl@0: }; sl@0: sl@0: sl@0: class DCryptoLddChannel; sl@0: class CryptoJob sl@0: { sl@0: public: sl@0: IMPORT_C CryptoJob(); sl@0: IMPORT_C virtual ~CryptoJob(); sl@0: virtual void SetDfcQ(TDfcQue *aDfcQue) = 0; sl@0: sl@0: IMPORT_C void Stalled(); // This job MUST be the current job sl@0: IMPORT_C void Resume(); sl@0: IMPORT_C void DeScheduleJob(); sl@0: IMPORT_C void SetRunning(TBool aRunning); sl@0: sl@0: virtual void GetToPddBuffer(TUint8 * &aBuf, TUint32 &aBufLen, TBool &aMore) = 0; sl@0: virtual void BytesWrittenToPdd(TUint32 aBytes) = 0; sl@0: sl@0: virtual void GetFromPddBuffer(TUint8 * &aBuf, TUint32 &aBufLen, TBool &aMore) = 0; sl@0: virtual void BytesReadFromPdd(TUint32 aBytes) = 0; sl@0: sl@0: enum CryptoJobState sl@0: { sl@0: ECreated, // Not registered with LDD factory sl@0: EReadyForFirstRun, // Not running, but could run next for the first time sl@0: ERunning, // H/w is currently working on this job sl@0: EReady, // Is the current job (h/w is setup), but h/w is idle sl@0: EReadyNoSavedState, // Ready to run sl@0: EReadySavedState, // Ready to run, but requires state restore sl@0: // EStalled sl@0: // sl@0: // Three cases:- sl@0: // sl@0: // 1) Already got enough data but LDD hasn't read it yet. sl@0: // 2) No space for more h/w output sl@0: // 3) No more data to feed to h/w sl@0: // sl@0: // Ultimately recoverd by the LDD reading/writing data and/or sl@0: // deleting the job. sl@0: EStalled sl@0: }; sl@0: sl@0: IMPORT_C CryptoJobState State() const; sl@0: sl@0: private: sl@0: friend class DCryptoJobScheduler; sl@0: /** sl@0: sl@0: */ sl@0: virtual void DoSlice(TBool aFirstSlice) = 0; sl@0: sl@0: /** sl@0: DoSaveState sl@0: sl@0: Save the current job h/w state so that the job can be later sl@0: restored when we are re-scheduled. sl@0: sl@0: If there is state to save it should return ETrue (in which case sl@0: DoRestoreState will be called before our DoSlice function is sl@0: next called). sl@0: sl@0: If the h/w state does not require saving/restore it should sl@0: return EFalse. sl@0: */ sl@0: virtual TBool DoSaveState() = 0; sl@0: sl@0: /** sl@0: DoRestoreState sl@0: sl@0: Restore the h/w state. The caller will almost certainly call sl@0: DoSlice just after this to continue the job. sl@0: */ sl@0: virtual void DoRestoreState() = 0; sl@0: sl@0: /** sl@0: DoReleaseHw sl@0: sl@0: Only called in state EReady or ERunning sl@0: sl@0: Should abort the operation and release h/w (unhook ISRs etc) sl@0: before returning. sl@0: sl@0: Later the caller will probably complete the user request... sl@0: */ sl@0: virtual void DoReleaseHw() = 0; sl@0: sl@0: CryptoJobState iState; sl@0: sl@0: protected: sl@0: DCryptoJobScheduler *iJobScheduler; sl@0: MCryptoJobCallbacks *iCallbacks; sl@0: private: sl@0: sl@0: CryptoJob *iNext; sl@0: TBool iInJobList; sl@0: }; sl@0: sl@0: class MCryptoJobCallbacks sl@0: { sl@0: public: sl@0: /** sl@0: DataRequired sl@0: sl@0: PDD is requesting more data to process. sl@0: sl@0: Normally the LDD will write one or more bytes into the supplied sl@0: buffer and return the number of bytes written. It is also legal sl@0: for the LDD to not write any bytes and return 0. sl@0: sl@0: If not enough bytes are supplied, the PDD will underrun and sl@0: stall (this function might not be re-called). sl@0: sl@0: The LDD should provide more data to the h/w via the sl@0: GetToPddBuffer/BytesWrittenToPdd functions. sl@0: sl@0: @return KErrNone or error code sl@0: */ sl@0: virtual TInt DataRequired() = 0; sl@0: sl@0: /** sl@0: DataAvailable sl@0: sl@0: PDD has output data available for copying to the user. sl@0: sl@0: This function will be called when the PDD is running low out sl@0: space for storing output data of if all input data has been sl@0: processed. sl@0: sl@0: Normally the LDD would copy all the supplied data to the user. sl@0: sl@0: It is legal for the LDD to copy less bytes, but this may cause sl@0: and the PDD to overrun and stall (this function might not be sl@0: re-called). sl@0: sl@0: The LDD should use the GetFromPddBuffer/BytesReadFromPdd sl@0: functions to read data from the PDD. sl@0: sl@0: @return KErrNone or error code sl@0: sl@0: */ sl@0: virtual TInt DataAvailable() = 0; sl@0: sl@0: /** sl@0: JobComplete sl@0: sl@0: The job scheduler has declared this job complete (maybe with an sl@0: error), and calls this function to tell the LDD to complete the sl@0: user request. sl@0: */ sl@0: virtual void JobComplete(TInt aResult) = 0; sl@0: }; sl@0: sl@0: sl@0: class CryptoJobRandom : public CryptoJob sl@0: { sl@0: public: sl@0: /** sl@0: SetDetails sl@0: sl@0: Setup and start job. Results later available via ResultsBuffer() sl@0: sl@0: @param Ptr to the DCryptoJobScheduler for this type of job sl@0: @param Ptr to the LDD object for MCryptoJobCallbacks sl@0: @param aNumOfBytes Total number of random numbers the user requires sl@0: */ sl@0: virtual void SetDetails(DCryptoJobScheduler *aJobScheduler, sl@0: MCryptoJobCallbacks *aCallbacks, sl@0: TUint32 aNumOfBytes) = 0; sl@0: }; sl@0: sl@0: class CryptoJobAes : public CryptoJob sl@0: { sl@0: public: sl@0: /** sl@0: GetKeyBuffer sl@0: sl@0: Get ptr to KEY buffer to copy user data into. Max key length is sl@0: 32 bytes (256 bits) sl@0: sl@0: @param Pointer to key buffer sl@0: */ sl@0: virtual TUint8 *GetKeyBuffer() = 0; sl@0: sl@0: /** sl@0: GetIVBuffer sl@0: sl@0: Get ptr to IV buffer to copy user IV data into. 16 bytes long. sl@0: sl@0: @param Pointer to IV buffer sl@0: */ sl@0: virtual TUint8 *GetIVBuffer() = 0; sl@0: sl@0: /** sl@0: MaxBytes sl@0: sl@0: @param Length of buffer returned by Buffer(). sl@0: */ sl@0: virtual TUint32 MaxBytes() const = 0; sl@0: sl@0: /** sl@0: Buffer sl@0: sl@0: Get ptr to PDD buffer to copy user data into and results from sl@0: Buffer length <= MaxBytes(). sl@0: sl@0: @param Pointer to key buffer sl@0: */ sl@0: virtual TUint8 *GetIOBuffer() = 0; sl@0: sl@0: /** sl@0: SetDetails sl@0: sl@0: @param Ptr to the DCryptoJobScheduler for this type of job sl@0: @param Ptr to the LDD object for MCryptoJobCallbacks sl@0: @param aEncrypt True requests encryption, false decryption sl@0: @param aKeyLength Length of key in bytes sl@0: @param aMode See RCryptoDriver::TChainingMode sl@0: @return KErrNone or error code sl@0: */ sl@0: virtual TInt SetDetails(DCryptoJobScheduler *aJobScheduler, sl@0: MCryptoJobCallbacks *aCallbacks, sl@0: TBool aEncrypt, sl@0: TInt aKeyLengthBytes, sl@0: RCryptoDriver::TChainingMode aMode) = 0; sl@0: sl@0: virtual void NotifyReadRequestLength(TUint32 aReadRequestLength) = 0; sl@0: virtual void HwPerfCheck() = 0; sl@0: }; sl@0: sl@0: #endif