1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/security/crypto/weakcryptospi/test/tplugins/inc/symmetriccipherimpl.h Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,367 @@
1.4 +/*
1.5 +* Copyright (c) 2006-2010 Nokia Corporation and/or its subsidiary(-ies).
1.6 +* All rights reserved.
1.7 +* This component and the accompanying materials are made available
1.8 +* under the terms of the License "Eclipse Public License v1.0"
1.9 +* which accompanies this distribution, and is available
1.10 +* at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.11 +*
1.12 +* Initial Contributors:
1.13 +* Nokia Corporation - initial contribution.
1.14 +*
1.15 +* Contributors:
1.16 +*
1.17 +* Description:
1.18 +*
1.19 +*/
1.20 +
1.21 +
1.22 +#ifndef __SYMMETRICCIPHERIMPL_H__
1.23 +#define __SYMMETRICCIPHERIMPL_H__
1.24 +
1.25 +/**
1.26 +@file
1.27 +@internalComponent
1.28 +@released
1.29 +*/
1.30 +
1.31 +#include <e32base.h>
1.32 +#include <e32cmn.h>
1.33 +#include <cryptospi/cryptospidef.h>
1.34 +#include <padding.h>
1.35 +#include <cryptospi/symmetriccipherplugin.h>
1.36 +
1.37 +/** The maximum block size supported (in bytes) */
1.38 +const TUint KMaxBlockSizeSupported = 32;
1.39 +
1.40 +/**
1.41 +Abstract base class for symmetric cipher plug-ins.
1.42 +*/
1.43 +namespace SoftwareCrypto
1.44 + {
1.45 + using namespace CryptoSpi;
1.46 +
1.47 + NONSHARABLE_CLASS(CSymmetricCipherImpl) : public CBase, public MSymmetricCipher
1.48 + {
1.49 + public:
1.50 + /**
1.51 + Implemented by each cipher subclass to determine whether the
1.52 + specified key length is valid for that cipher.
1.53 + This is called by ConstructL and SetKeyL
1.54 + @param aKeyLength The key length in bytes to verify.
1.55 + */
1.56 + virtual TBool IsValidKeyLength(TInt aKeyBytes) const = 0;
1.57 +
1.58 + /**
1.59 + Helper function implemented by concrete cipher sub-class that
1.60 + allows GetCharacteristicsL to return the correct characteristics object.
1.61 + @return The implemention uid
1.62 + */
1.63 + virtual TUid ImplementationUid() const = 0;
1.64 +
1.65 + /**
1.66 + Gets the strength of the current key, needed to check whether the cipher
1.67 + may operate if strong cryptography is not enabled.
1.68 + @return The strength of the current key
1.69 + */
1.70 + virtual TInt GetKeyStrength() const;
1.71 +
1.72 +
1.73 + // Override MPlugin virtual functions
1.74 + void Close();
1.75 + TAny* GetExtension(TUid aExtensionId);
1.76 + void GetCharacteristicsL(const TCharacteristics*& aPluginCharacteristics);
1.77 + // End of MPlugin
1.78 +
1.79 + // Override MSymmetricCipherBase virtual functions
1.80 + TInt KeySize() const;
1.81 +
1.82 + /// Destructor
1.83 + ~CSymmetricCipherImpl();
1.84 +
1.85 + protected:
1.86 +
1.87 + //Constructor
1.88 + CSymmetricCipherImpl();
1.89 +
1.90 + /**
1.91 + Second phase of construction. Always call ConstructL in the super-class
1.92 + if your override this method.
1.93 +
1.94 + @param aKey The key to initialise the cipher with.
1.95 + */
1.96 + virtual void ConstructL(const CKey& aKey);
1.97 +
1.98 + /**
1.99 + Extracts the raw symmetric key from a generic key object. The buffer
1.100 + is placed on the cleanup stack.
1.101 +
1.102 + @param aKey The key object
1.103 + @return A buffer containing the raw key value
1.104 + */
1.105 + HBufC8* ExtractKeyDataLC(const CKey& aKey) const;
1.106 +
1.107 + /**
1.108 + Zeros a buffer before deleting it to ensure that
1.109 + the contents will not be visible to another process if the page
1.110 + is re-used.
1.111 + @param aBuffer The pointer (possibly null) to the buffer to delete. This
1.112 + is set to null after deletion.
1.113 + */
1.114 + void SecureDelete(HBufC8*& aBuffer);
1.115 +
1.116 + /**
1.117 + Extracts the raw key from aKey and sets iKey and iKeyBytes
1.118 + The key length is also checked to meet export restrictions and
1.119 + to ensure that it is appropriate for the cipher.
1.120 + @param aKey The key
1.121 + */
1.122 + virtual void DoSetKeyL(const CKey& aKey);
1.123 +
1.124 +
1.125 + protected:
1.126 + /// the key, extracted from a CKey object
1.127 + HBufC8* iKey;
1.128 +
1.129 + /// key size in bytes
1.130 + TUint iKeyBytes;
1.131 +
1.132 + };
1.133 +
1.134 + NONSHARABLE_CLASS(CSymmetricStreamCipherImpl) : public CSymmetricCipherImpl
1.135 + {
1.136 + public:
1.137 + // Destructor
1.138 + ~CSymmetricStreamCipherImpl();
1.139 +
1.140 + // Override MSymmetricCipherBase virtual functions
1.141 + TInt BlockSize() const;
1.142 + void SetKeyL(const CKey& aKey); // override DoSetKeyL instead
1.143 + void SetCryptoModeL(TUid aCryptoMode);
1.144 + void SetOperationModeL(TUid aOperationMode);
1.145 + void SetPaddingModeL(TUid aPaddingMode);
1.146 + void SetIvL(const TDesC8& aIv);
1.147 + TInt MaxOutputLength(TInt aInputLength) const;
1.148 + TInt MaxFinalOutputLength(TInt aInputLength) const;
1.149 + // End of MSymmetricCipherBase
1.150 +
1.151 + // Override MSymmetricCipher virtual functions
1.152 + void ProcessL(const TDesC8& aInput, TDes8& aOutput);
1.153 + void ProcessFinalL(const TDesC8& aInput, TDes8& aOutput);
1.154 + // End of MSymmetricCipher
1.155 +
1.156 + protected:
1.157 + // Constructor
1.158 + CSymmetricStreamCipherImpl();
1.159 +
1.160 + // Override CSymmetricCipherImpl virtual functions
1.161 + virtual void ConstructL(const CKey& aKey);
1.162 +
1.163 + /**
1.164 + Performs an encryption or decryption on supplied data.
1.165 + @param aData On input, data to be transformed;
1.166 + on return, transformed data.
1.167 + */
1.168 + virtual void DoProcess(TDes8& aData) = 0;
1.169 + };
1.170 +
1.171 + NONSHARABLE_CLASS(CSymmetricBlockCipherImpl) : public CSymmetricCipherImpl
1.172 + {
1.173 + public:
1.174 +
1.175 +
1.176 + /**
1.177 + This function is invoked by SetKey and SetCryptoMode
1.178 + allowing the cipher sub-class to rebuild it's key schedule.
1.179 + N.B. It is assumed that the key schedule is NOT modified
1.180 + by TransformEncrypt or TransformDecrypt
1.181 + */
1.182 + virtual void SetKeySchedule() = 0;
1.183 +
1.184 + // Override MPlugin virtual functions
1.185 + void Reset(); // Always call reset in super-class if you override this
1.186 + // End of MPlugin virtual functions
1.187 +
1.188 + // Override MSymmetricCipherBase virtual functions
1.189 + TInt BlockSize() const;
1.190 + void SetKeyL(const CKey& aKey); // override DoSetKeyL instead
1.191 + void SetCryptoModeL(TUid aCryptoMode); // override DoSetCryptoModeL instead
1.192 + void SetOperationModeL(TUid aOperationMode); // override DoSetOperationMode instead
1.193 + void SetPaddingModeL(TUid aPaddingMode); // override DoSetPaddingModeL instead
1.194 + void SetIvL(const TDesC8& aIv);
1.195 +
1.196 + TInt MaxOutputLength(TInt aInputLength) const;
1.197 + TInt MaxFinalOutputLength(TInt aInputLength) const;
1.198 + // End of MSymmetricCipherBase
1.199 +
1.200 + // Override MSymmetricCipher virtual functions
1.201 + void ProcessL(const TDesC8& aInput, TDes8& aOutput);
1.202 + void ProcessFinalL(const TDesC8& aInput, TDes8& aOutput);
1.203 + // End of MSymmetricCipher
1.204 +
1.205 + /// Destructor
1.206 + ~CSymmetricBlockCipherImpl();
1.207 + protected:
1.208 + /**
1.209 + Constructor
1.210 + @param aBlockBytes The block size in bytes
1.211 + @param aOperationMode The mode of operation e.g. CBC
1.212 + @param aCryptoMode Whether to encrypt or decrypt
1.213 + */
1.214 + CSymmetricBlockCipherImpl(
1.215 + TUint8 aBlockBytes,
1.216 + TUid aOperationMode,
1.217 + TUid aCryptoMode,
1.218 + TUid aPaddingMode);
1.219 +
1.220 + // Override CSymmetricCipherImpl virtual functions
1.221 + virtual void ConstructL(const CKey& aKey);
1.222 +
1.223 + /**
1.224 + Validates and sets the crypto mode (iCryptoMode)
1.225 + @param aCryptoMode The crypto mode
1.226 + */
1.227 + virtual void DoSetCryptoModeL(TUid aCryptoMode);
1.228 +
1.229 + /**
1.230 + Validates and sets the operation mode (iOperationMode)
1.231 + @param aOperationMode The operation mode
1.232 + */
1.233 + virtual void DoSetOperationModeL(TUid aOperationMode);
1.234 +
1.235 + /**
1.236 + Validates and sets the padding mode (iPaddingMode & iPadding)
1.237 + @param aPadding The desired padding mode
1.238 + */
1.239 + virtual void DoSetPaddingModeL(TUid aPadding);
1.240 +
1.241 + void DoSetIvL(const TDesC8& aIv);
1.242 +
1.243 + inline void ModeEncryptStart(TUint8* aBuffer);
1.244 + inline void ModeEncryptEnd(TUint8* aBuffer);
1.245 + inline void ModeDecryptStart(TUint8* aBuffer);
1.246 + inline void ModeDecryptEnd(TUint8* aBuffer);
1.247 +
1.248 + private:
1.249 +
1.250 + /**
1.251 + Encrypts a number of blocks of data
1.252 +
1.253 + @param aBuffer The buffer containing exactly aNumBlocks of data to destructively encrypt
1.254 + @param aNumBlocks The number of blocks of data to encrypt
1.255 + */
1.256 + virtual void TransformEncrypt(TUint8* aBuffer, TUint aNumBlocks) = 0;
1.257 +
1.258 + /**
1.259 + Decrypts a number of blocks of data
1.260 +
1.261 + @param aBuffer The buffer containing exactly aNumBlocks of data to destructively decrypt
1.262 + @param aNumBlocks The number of blocks of data to decrypt
1.263 + */
1.264 + virtual void TransformDecrypt(TUint8* aBuffer, TUint aNumBlocks) = 0;
1.265 +
1.266 + /// Pad the last block and encrypt
1.267 + void DoProcessFinalEncryptL(const TDesC8& aInput, TDes8& aOutput);
1.268 +
1.269 + /// Decrypt and unpad the last block
1.270 + void DoProcessFinalDecryptL(const TDesC8& aInput, TDes8& aOutput);
1.271 +
1.272 + inline void Transform(TUint8* aBuffer, TUint aNumBlocks);
1.273 +
1.274 + protected:
1.275 +
1.276 + /// block size in bytes, current largest block size is 16 bytes (AES)
1.277 + TUint8 iBlockBytes;
1.278 + /// encryption or decryption
1.279 + TUid iCryptoMode;
1.280 + /// The block cipher mode e.g. ECB, CBC
1.281 + TUid iOperationMode;
1.282 + /// the current padding scheme
1.283 + TUid iPaddingMode;
1.284 +
1.285 + /// the initialisation vector
1.286 + RBuf8 iIv;
1.287 +
1.288 + /// current padding scheme implementation
1.289 + CPadding* iPadding;
1.290 + /// buffer to store blocks
1.291 + RBuf8 iInputStore;
1.292 + /// buffer to store input / output of padding
1.293 + RBuf8 iPaddingBlock;
1.294 +
1.295 + /// The current block of cipher text - for CBC
1.296 + TUint32* iCurrentCipherText;
1.297 + /// A pointer to the current block of cipher text
1.298 + TUint8* iCurrentCipherTextPtr;
1.299 +
1.300 + /// The result of the transform
1.301 + TUint32* iCbcRegister;
1.302 + /// A pointer to the result of the transform
1.303 + TUint8* iCbcRegisterPtr;
1.304 + };
1.305 +
1.306 +
1.307 + inline void CSymmetricBlockCipherImpl::Transform(TUint8* aBuffer, TUint aNumBlocks)
1.308 + {
1.309 + if (iCryptoMode.iUid == KCryptoModeEncrypt)
1.310 + {
1.311 + TransformEncrypt(aBuffer, aNumBlocks);
1.312 + }
1.313 + else if (iCryptoMode.iUid == KCryptoModeDecrypt)
1.314 + {
1.315 + TransformDecrypt(aBuffer, aNumBlocks);
1.316 + }
1.317 + else
1.318 + {
1.319 + ASSERT(EFalse);
1.320 + }
1.321 + }
1.322 +
1.323 + inline void CSymmetricBlockCipherImpl::ModeEncryptStart(TUint8* aBuffer)
1.324 + {
1.325 + if (iOperationMode.iUid == KOperationModeCBC)
1.326 + {
1.327 + for (TInt i = 0; i < iBlockBytes; ++i)
1.328 + {
1.329 + aBuffer[i] ^= iCbcRegisterPtr[i];
1.330 + }
1.331 + }
1.332 + }
1.333 +
1.334 + inline void CSymmetricBlockCipherImpl::ModeEncryptEnd(TUint8* aBuffer)
1.335 + {
1.336 + if (iOperationMode.iUid == KOperationModeCBC)
1.337 + {
1.338 + for (TInt i = 0; i < iBlockBytes; ++i)
1.339 + {
1.340 + iCbcRegisterPtr[i] = aBuffer[i];
1.341 + }
1.342 + }
1.343 + }
1.344 +
1.345 + inline void CSymmetricBlockCipherImpl::ModeDecryptStart(TUint8* aBuffer)
1.346 + {
1.347 + if (iOperationMode.iUid == KOperationModeCBC)
1.348 + {
1.349 + for (TInt i = 0; i < iBlockBytes; ++i)
1.350 + {
1.351 + iCurrentCipherTextPtr[i] = aBuffer[i];
1.352 + }
1.353 + }
1.354 + }
1.355 +
1.356 + inline void CSymmetricBlockCipherImpl::ModeDecryptEnd(TUint8* aBuffer)
1.357 + {
1.358 + if (iOperationMode.iUid == KOperationModeCBC)
1.359 + {
1.360 + // xor the output with the previous cipher text
1.361 + for (TInt i = 0; i < iBlockBytes; ++i)
1.362 + {
1.363 + aBuffer[i] ^= iCbcRegisterPtr[i];
1.364 + iCbcRegisterPtr[i] = iCurrentCipherTextPtr[i];
1.365 + }
1.366 + }
1.367 + }
1.368 + }
1.369 +
1.370 +#endif // __SYMMETRICCIPHERIMPL_H__