os/security/crypto/weakcryptospi/test/tplugins/inc/symmetriccipherimpl.h
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 /*
     2 * Copyright (c) 2006-2010 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 <cryptospi/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__