crypto/weakcryptospi/test/tplugins/inc/symmetriccipherimpl.h
changeset 8 35751d3474b7
child 43 2f10d260163b
equal deleted inserted replaced
2:675a964f4eb5 8:35751d3474b7
       
     1 /*
       
     2 * Copyright (c) 2006-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 #ifndef	__SYMMETRICCIPHERIMPL_H__
       
    20 #define	__SYMMETRICCIPHERIMPL_H__
       
    21 
       
    22 /**
       
    23 @file 
       
    24 @internalComponent
       
    25 @released
       
    26 */
       
    27 
       
    28 #include <e32base.h>
       
    29 #include <e32cmn.h>
       
    30 #include <cryptospi/cryptospidef.h>
       
    31 #include <padding.h>
       
    32 #include "symmetriccipherplugin.h"
       
    33 
       
    34 /** The maximum block size supported (in bytes) */
       
    35 const TUint KMaxBlockSizeSupported = 32;
       
    36 
       
    37 /**
       
    38 Abstract base class for symmetric cipher plug-ins.
       
    39 */
       
    40 namespace SoftwareCrypto
       
    41 	{
       
    42 	using namespace CryptoSpi;
       
    43 		
       
    44 	NONSHARABLE_CLASS(CSymmetricCipherImpl) : public CBase, public MSymmetricCipher
       
    45 		{
       
    46 	public:
       
    47 		/**
       
    48 		Implemented by each cipher subclass to determine whether the
       
    49 		specified key length is valid for that cipher.
       
    50 		This is called by ConstructL and SetKeyL
       
    51 		@param aKeyLength The key length in bytes to verify.
       
    52 		*/
       
    53 		virtual TBool IsValidKeyLength(TInt aKeyBytes) const = 0;
       
    54 		
       
    55 		/**
       
    56 		Helper function implemented by concrete cipher sub-class that 
       
    57 		allows GetCharacteristicsL to return the correct characteristics object.
       
    58 		@return The implemention uid
       
    59 		*/
       
    60 		virtual TUid ImplementationUid() const = 0;
       
    61 		
       
    62 		/**
       
    63 		Gets the strength of the current key, needed to check whether the cipher
       
    64 		may operate if strong cryptography is not enabled.
       
    65 		@return The strength of the current key
       
    66 		*/
       
    67 		virtual TInt GetKeyStrength() const;
       
    68 		
       
    69 				
       
    70 		// Override MPlugin virtual functions
       
    71 		void Close();
       
    72 		TAny* GetExtension(TUid aExtensionId);
       
    73 		void GetCharacteristicsL(const TCharacteristics*& aPluginCharacteristics);	
       
    74 		// End of MPlugin
       
    75 		
       
    76 		// Override MSymmetricCipherBase virtual functions 
       
    77 		TInt KeySize() const;
       
    78 						
       
    79 		/// Destructor
       
    80 		~CSymmetricCipherImpl();
       
    81 
       
    82 	protected:
       
    83 		
       
    84 		//Constructor
       
    85 		CSymmetricCipherImpl();
       
    86 		
       
    87 		/**
       
    88 		Second phase of construction. Always call ConstructL in the super-class
       
    89 		if your override this method.
       
    90 		
       
    91 		@param aKey The key to initialise the cipher with.
       
    92 		*/
       
    93 		virtual void ConstructL(const CKey& aKey);			
       
    94 		
       
    95 		/**
       
    96 		Extracts the raw symmetric key from a generic key object. The buffer
       
    97 		is placed on the cleanup stack.
       
    98 		
       
    99 		@param aKey The key object
       
   100 		@return A buffer containing the raw key value
       
   101 		*/
       
   102 		HBufC8* ExtractKeyDataLC(const CKey& aKey) const;	
       
   103 	
       
   104 		/**
       
   105 		Zeros a buffer before deleting it to ensure that
       
   106 		the contents will not be visible to another process if the page
       
   107 		is re-used.
       
   108 		@param aBuffer The pointer (possibly null) to the buffer to delete. This
       
   109 		is set to null after deletion.
       
   110 		*/
       
   111 		void SecureDelete(HBufC8*& aBuffer);		
       
   112 					
       
   113 		/**
       
   114 		Extracts the raw key from aKey and sets iKey and iKeyBytes
       
   115 		The key length is also checked to meet export restrictions and
       
   116 		to ensure that it is appropriate for the cipher.
       
   117 		@param aKey The key
       
   118 		*/
       
   119 		virtual void DoSetKeyL(const CKey& aKey);
       
   120 		
       
   121 			
       
   122 	protected:
       
   123 		/// the key, extracted from a CKey object
       
   124 		HBufC8* iKey;
       
   125 		
       
   126 		/// key size in bytes
       
   127 		TUint iKeyBytes;
       
   128 		
       
   129 		};
       
   130 
       
   131 	NONSHARABLE_CLASS(CSymmetricStreamCipherImpl) : public CSymmetricCipherImpl
       
   132 		{
       
   133 	public:
       
   134 		// Destructor
       
   135 		~CSymmetricStreamCipherImpl();
       
   136 		
       
   137 		// Override MSymmetricCipherBase virtual functions 
       
   138 		TInt BlockSize() const;
       
   139 		void SetKeyL(const CKey& aKey);		// override DoSetKeyL instead
       
   140 		void SetCryptoModeL(TUid aCryptoMode);
       
   141 		void SetOperationModeL(TUid aOperationMode);
       
   142 		void SetPaddingModeL(TUid aPaddingMode);
       
   143 		void SetIvL(const TDesC8& aIv);
       
   144 		TInt MaxOutputLength(TInt aInputLength) const;
       
   145 		TInt MaxFinalOutputLength(TInt aInputLength) const;
       
   146 		// End of MSymmetricCipherBase
       
   147 		
       
   148 		// Override MSymmetricCipher virtual functions
       
   149 		void ProcessL(const TDesC8& aInput, TDes8& aOutput);
       
   150 		void ProcessFinalL(const TDesC8& aInput, TDes8& aOutput);						
       
   151 		// End of MSymmetricCipher 
       
   152 	
       
   153 	protected:
       
   154 		// Constructor
       
   155 		CSymmetricStreamCipherImpl();
       
   156 		
       
   157 		// Override CSymmetricCipherImpl virtual functions
       
   158 		virtual void ConstructL(const CKey& aKey);
       
   159 
       
   160 		/**	
       
   161 		Performs an encryption or decryption on supplied data.
       
   162 		@param aData	On input, data to be transformed; 
       
   163 						on return, transformed data.
       
   164 		*/
       
   165 		virtual void DoProcess(TDes8& aData) = 0;
       
   166 		};
       
   167 
       
   168 	NONSHARABLE_CLASS(CSymmetricBlockCipherImpl) : public CSymmetricCipherImpl
       
   169 		{
       
   170 	public:	
       
   171 
       
   172 
       
   173 		/**
       
   174 		This function is invoked by SetKey and SetCryptoMode
       
   175 		allowing the cipher sub-class to rebuild it's key schedule. 
       
   176 		N.B. It is assumed that the key schedule is NOT modified
       
   177 		by TransformEncrypt or TransformDecrypt
       
   178 		*/
       
   179 		virtual void SetKeySchedule() = 0;
       
   180 		
       
   181 		// Override MPlugin virtual functions		
       
   182 		void Reset(); // Always call reset in super-class if you override this
       
   183 		// End of MPlugin virtual functions
       
   184 
       
   185 		// Override MSymmetricCipherBase virtual functions 
       
   186 		TInt BlockSize() const;
       
   187 		void SetKeyL(const CKey& aKey);  				// override DoSetKeyL instead
       
   188 		void SetCryptoModeL(TUid aCryptoMode);			// override DoSetCryptoModeL instead
       
   189 		void SetOperationModeL(TUid aOperationMode);	// override DoSetOperationMode instead		
       
   190 		void SetPaddingModeL(TUid aPaddingMode);		// override DoSetPaddingModeL instead
       
   191 		void SetIvL(const TDesC8& aIv);
       
   192 		
       
   193 		TInt MaxOutputLength(TInt aInputLength) const;
       
   194 		TInt MaxFinalOutputLength(TInt aInputLength) const;
       
   195 		// End of MSymmetricCipherBase
       
   196 
       
   197 		// Override MSymmetricCipher virtual functions
       
   198 		void ProcessL(const TDesC8& aInput, TDes8& aOutput);
       
   199 		void ProcessFinalL(const TDesC8& aInput, TDes8& aOutput);						
       
   200 		// End of MSymmetricCipher
       
   201 
       
   202 		/// Destructor
       
   203 		~CSymmetricBlockCipherImpl();		
       
   204 	protected:	
       
   205 		/**
       
   206 		Constructor
       
   207 		@param aBlockBytes The block size in bytes
       
   208 		@param aOperationMode The mode of operation e.g. CBC
       
   209 		@param aCryptoMode Whether to encrypt or decrypt
       
   210 		*/
       
   211 		CSymmetricBlockCipherImpl(
       
   212 			TUint8 aBlockBytes,
       
   213 			TUid aOperationMode,
       
   214 			TUid aCryptoMode,
       
   215 			TUid aPaddingMode);
       
   216 			
       
   217 		// Override CSymmetricCipherImpl virtual functions
       
   218 		virtual void ConstructL(const CKey& aKey);
       
   219 
       
   220 		/**
       
   221 		Validates and sets the crypto mode (iCryptoMode)
       
   222 		@param aCryptoMode The crypto mode
       
   223 		*/	
       
   224 		virtual void DoSetCryptoModeL(TUid aCryptoMode);
       
   225 		
       
   226 		/**
       
   227 		Validates and sets the operation mode (iOperationMode)
       
   228 		@param aOperationMode The operation mode
       
   229 		*/
       
   230 		virtual void DoSetOperationModeL(TUid aOperationMode);
       
   231 		
       
   232 		/**
       
   233 		Validates and sets the padding mode (iPaddingMode & iPadding)
       
   234 		@param aPadding The desired padding mode
       
   235 		*/
       
   236 		virtual void DoSetPaddingModeL(TUid aPadding);
       
   237 		
       
   238 		void DoSetIvL(const TDesC8& aIv);
       
   239 
       
   240 		inline void ModeEncryptStart(TUint8* aBuffer);
       
   241 		inline void ModeEncryptEnd(TUint8* aBuffer);
       
   242 		inline void ModeDecryptStart(TUint8* aBuffer);
       
   243 		inline void ModeDecryptEnd(TUint8* aBuffer);
       
   244 
       
   245 	private:
       
   246 	
       
   247 		/**
       
   248 		Encrypts a number of blocks of data
       
   249 		
       
   250 		@param aBuffer The buffer containing exactly aNumBlocks of data to destructively encrypt
       
   251 		@param aNumBlocks The number of blocks of data to encrypt
       
   252 		*/
       
   253 		virtual void TransformEncrypt(TUint8* aBuffer, TUint aNumBlocks) = 0;
       
   254 		
       
   255 		/**
       
   256 		Decrypts a number of blocks of data
       
   257 				
       
   258 		@param aBuffer The buffer containing exactly aNumBlocks of data to destructively decrypt
       
   259 		@param aNumBlocks The number of blocks of data to decrypt
       
   260 		*/
       
   261 		virtual void TransformDecrypt(TUint8* aBuffer, TUint aNumBlocks) = 0;		
       
   262 			
       
   263 		/// Pad the last block and encrypt
       
   264 		void DoProcessFinalEncryptL(const TDesC8& aInput, TDes8& aOutput);
       
   265 		
       
   266 		/// Decrypt and unpad the last block
       
   267 		void DoProcessFinalDecryptL(const TDesC8& aInput, TDes8& aOutput);		
       
   268 		
       
   269 		inline void Transform(TUint8* aBuffer, TUint aNumBlocks);
       
   270 		
       
   271 	protected:
       
   272 	
       
   273 		/// block size in bytes, current largest block size is 16 bytes (AES)
       
   274 		TUint8 iBlockBytes;	
       
   275 		/// encryption or decryption
       
   276 		TUid iCryptoMode;		
       
   277 		/// The block cipher mode e.g. ECB, CBC
       
   278 		TUid iOperationMode;
       
   279 		/// the current padding scheme
       
   280 		TUid iPaddingMode;
       
   281 		
       
   282 		/// the initialisation vector
       
   283 		RBuf8 iIv;
       
   284 		
       
   285 		/// current padding scheme implementation
       
   286 		CPadding* iPadding;
       
   287 		/// buffer to store blocks
       
   288 		RBuf8 iInputStore;
       
   289 		/// buffer to store input / output of padding
       
   290 		RBuf8 iPaddingBlock;
       
   291 
       
   292 		/// The current block of cipher text - for CBC 
       
   293 		TUint32* iCurrentCipherText;	
       
   294 		/// A pointer to the current block of cipher text
       
   295 		TUint8* iCurrentCipherTextPtr;		
       
   296 		
       
   297 		/// The result of the transform
       
   298 		TUint32* iCbcRegister;	
       
   299 		/// A pointer to the result of the transform
       
   300 		TUint8* iCbcRegisterPtr;			
       
   301 		};
       
   302 
       
   303 
       
   304 	inline void CSymmetricBlockCipherImpl::Transform(TUint8* aBuffer, TUint aNumBlocks)
       
   305 		{				
       
   306 		if (iCryptoMode.iUid == KCryptoModeEncrypt)
       
   307 			{				
       
   308 			TransformEncrypt(aBuffer, aNumBlocks);
       
   309 			}
       
   310 		else if (iCryptoMode.iUid == KCryptoModeDecrypt)
       
   311 			{				
       
   312 			TransformDecrypt(aBuffer, aNumBlocks);
       
   313 			}
       
   314 		else 
       
   315 			{
       
   316 			ASSERT(EFalse);
       
   317 			}
       
   318 		}
       
   319 			
       
   320 	inline void CSymmetricBlockCipherImpl::ModeEncryptStart(TUint8* aBuffer)
       
   321 		{
       
   322 		if (iOperationMode.iUid == KOperationModeCBC)
       
   323 			{			
       
   324 			for (TInt i = 0; i < iBlockBytes; ++i)
       
   325 				{
       
   326 				aBuffer[i] ^= iCbcRegisterPtr[i];
       
   327 				}					
       
   328 			}
       
   329 		}		
       
   330 	
       
   331 	inline void CSymmetricBlockCipherImpl::ModeEncryptEnd(TUint8* aBuffer)
       
   332 		{				
       
   333 		if (iOperationMode.iUid == KOperationModeCBC)
       
   334 			{
       
   335 			for (TInt i = 0; i < iBlockBytes; ++i)
       
   336 				{
       
   337 				iCbcRegisterPtr[i] = aBuffer[i]; 
       
   338 				}													
       
   339 			}									
       
   340 		}		
       
   341 
       
   342 	inline void CSymmetricBlockCipherImpl::ModeDecryptStart(TUint8* aBuffer)
       
   343 		{
       
   344 		if (iOperationMode.iUid == KOperationModeCBC)
       
   345 			{			
       
   346 			for (TInt i = 0; i < iBlockBytes; ++i)
       
   347 				{
       
   348 				iCurrentCipherTextPtr[i] = aBuffer[i];
       
   349 				}
       
   350 			}
       
   351 		}
       
   352 
       
   353 	inline void CSymmetricBlockCipherImpl::ModeDecryptEnd(TUint8* aBuffer)
       
   354 		{		
       
   355 		if (iOperationMode.iUid == KOperationModeCBC)
       
   356 			{			
       
   357 			// xor the output with the previous cipher text
       
   358 			for (TInt i = 0; i < iBlockBytes; ++i)
       
   359 				{
       
   360 				aBuffer[i] ^= iCbcRegisterPtr[i];
       
   361 				iCbcRegisterPtr[i] = iCurrentCipherTextPtr[i];
       
   362 				}
       
   363 			}	
       
   364 		}		
       
   365 	}						
       
   366 
       
   367 #endif	//	__SYMMETRICCIPHERIMPL_H__