os/security/cryptoplugins/cryptospiplugins/source/softwarecrypto/symmetriccipherimpl.h
First public contribution.
2 * Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
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".
9 * Initial Contributors:
10 * Nokia Corporation - initial contribution.
19 #ifndef __SYMMETRICCIPHERIMPL_H__
20 #define __SYMMETRICCIPHERIMPL_H__
30 #include <cryptospi/cryptospidef.h>
32 #include "symmetriccipherplugin.h"
34 /** The maximum block size supported (in bytes) */
35 const TUint KMaxBlockSizeSupported = 32;
38 Abstract base class for symmetric cipher plug-ins.
40 namespace SoftwareCrypto
42 using namespace CryptoSpi;
44 NONSHARABLE_CLASS(CSymmetricCipherImpl) : public CBase, public MSymmetricCipher
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.
53 virtual TBool IsValidKeyLength(TInt aKeyBytes) const = 0;
56 Helper function implemented by concrete cipher sub-class that
57 allows GetCharacteristicsL to return the correct characteristics object.
58 @return The implemention uid
60 virtual TUid ImplementationUid() const = 0;
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
67 virtual TInt GetKeyStrength() const;
70 // Override MPlugin virtual functions
72 TAny* GetExtension(TUid aExtensionId);
73 void GetCharacteristicsL(const TCharacteristics*& aPluginCharacteristics);
76 // Override MSymmetricCipherBase virtual functions
80 ~CSymmetricCipherImpl();
85 CSymmetricCipherImpl();
88 Second phase of construction. Always call ConstructL in the super-class
89 if your override this method.
91 @param aKey The key to initialise the cipher with.
93 virtual void ConstructL(const CKey& aKey);
96 Extracts the raw symmetric key from a generic key object. The buffer
97 is placed on the cleanup stack.
99 @param aKey The key object
100 @return A buffer containing the raw key value
102 HBufC8* ExtractKeyDataLC(const CKey& aKey) const;
105 Zeros a buffer before deleting it to ensure that
106 the contents will not be visible to another process if the page
108 @param aBuffer The pointer (possibly null) to the buffer to delete. This
109 is set to null after deletion.
111 void SecureDelete(HBufC8*& aBuffer);
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.
119 virtual void DoSetKeyL(const CKey& aKey);
123 /// the key, extracted from a CKey object
126 /// key size in bytes
131 NONSHARABLE_CLASS(CSymmetricStreamCipherImpl) : public CSymmetricCipherImpl
135 ~CSymmetricStreamCipherImpl();
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
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
155 CSymmetricStreamCipherImpl();
157 // Override CSymmetricCipherImpl virtual functions
158 virtual void ConstructL(const CKey& aKey);
161 Performs an encryption or decryption on supplied data.
162 @param aData On input, data to be transformed;
163 on return, transformed data.
165 virtual void DoProcess(TDes8& aData) = 0;
168 NONSHARABLE_CLASS(CSymmetricBlockCipherImpl) : public CSymmetricCipherImpl
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
179 virtual void SetKeySchedule() = 0;
181 // Override MPlugin virtual functions
182 void Reset(); // Always call reset in super-class if you override this
183 // End of MPlugin virtual functions
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);
193 TInt MaxOutputLength(TInt aInputLength) const;
194 TInt MaxFinalOutputLength(TInt aInputLength) const;
195 // End of MSymmetricCipherBase
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
203 ~CSymmetricBlockCipherImpl();
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
211 CSymmetricBlockCipherImpl(
217 // Override CSymmetricCipherImpl virtual functions
218 virtual void ConstructL(const CKey& aKey);
221 Validates and sets the crypto mode (iCryptoMode)
222 @param aCryptoMode The crypto mode
224 virtual void DoSetCryptoModeL(TUid aCryptoMode);
227 Validates and sets the operation mode (iOperationMode)
228 @param aOperationMode The operation mode
230 virtual void DoSetOperationModeL(TUid aOperationMode);
233 Validates and sets the padding mode (iPaddingMode & iPadding)
234 @param aPadding The desired padding mode
236 virtual void DoSetPaddingModeL(TUid aPadding);
238 void DoSetIvL(const TDesC8& aIv);
240 inline void ModeEncryptStart(TUint8* aBuffer);
241 inline void ModeEncryptEnd(TUint8* aBuffer);
242 inline void ModeDecryptStart(TUint8* aBuffer);
243 inline void ModeDecryptEnd(TUint8* aBuffer);
248 Encrypts a number of blocks of data
250 @param aBuffer The buffer containing exactly aNumBlocks of data to destructively encrypt
251 @param aNumBlocks The number of blocks of data to encrypt
253 virtual void TransformEncrypt(TUint8* aBuffer, TUint aNumBlocks) = 0;
256 Decrypts a number of blocks of data
258 @param aBuffer The buffer containing exactly aNumBlocks of data to destructively decrypt
259 @param aNumBlocks The number of blocks of data to decrypt
261 virtual void TransformDecrypt(TUint8* aBuffer, TUint aNumBlocks) = 0;
263 /// Pad the last block and encrypt
264 void DoProcessFinalEncryptL(const TDesC8& aInput, TDes8& aOutput);
266 /// Decrypt and unpad the last block
267 void DoProcessFinalDecryptL(const TDesC8& aInput, TDes8& aOutput);
269 inline void Transform(TUint8* aBuffer, TUint aNumBlocks);
271 void ProcessCtrL(const TDesC8& aInput, TDes8& aOutput);
275 /// block size in bytes, current largest block size is 16 bytes (AES)
277 /// encryption or decryption
279 /// The block cipher mode e.g. ECB, CBC
281 /// the current padding scheme
284 /// the initialisation vector
287 /// current padding scheme implementation
289 /// buffer to store blocks
291 /// buffer to store input / output of padding
294 /// The current block of cipher text - for CBC
295 TUint32* iCurrentCipherText;
296 /// A pointer to the current block of cipher text
297 TUint8* iCurrentCipherTextPtr;
299 /** Used in both CBC and CTR mode. In CBC mode it stores the result of the last transform. In CTR mode
300 it stores the counter.*/
302 /** A pointer to iRegister.*/
303 TUint8* iRegisterPtr;
305 /** Used in CTR mode to buffer plaintext during encryption.*/
306 HBufC8* iBufferedPlaintext;
307 /** Pointer to manipulate iBufferedPlaintext.*/
308 TPtr8 iBufferedPlaintextPtr;
310 /** CTR mode behaves like a stream cipher allowing arbitrary sized inputs to the encryption/decryption functions.
311 When handling an input whose length is not a multiple of the blocksize iCtrUnusedKeystream is used to buffer
312 the unused portions of keystream for use in the next call. Cleared in Reset().*/
313 HBufC8* iCtrUnusedKeystream;
314 /** Pointer to manipulate iCtrUnusedKeystream.*/
315 TPtr8 iCtrUnusedKeystreamPtr;
319 inline void CSymmetricBlockCipherImpl::Transform(TUint8* aBuffer, TUint aNumBlocks)
321 if (iCryptoMode.iUid == KCryptoModeEncrypt) //if in CTR mode always in crypto mode encrypt
323 TransformEncrypt(aBuffer, aNumBlocks);
325 else if (iCryptoMode.iUid == KCryptoModeDecrypt)
327 TransformDecrypt(aBuffer, aNumBlocks);
335 inline void CSymmetricBlockCipherImpl::ModeEncryptStart(TUint8* aBuffer)
337 if (iOperationMode.iUid == KOperationModeCBC)
339 for (TInt i = 0; i < iBlockBytes; ++i)
341 aBuffer[i] ^= iRegisterPtr[i];
344 else if (iOperationMode.iUid == KOperationModeCTR)
346 iBufferedPlaintextPtr.Copy(aBuffer, iBlockBytes);
347 Mem::Copy(aBuffer, iRegister, iBlockBytes);
351 inline void CSymmetricBlockCipherImpl::ModeEncryptEnd(TUint8* aBuffer)
353 if (iOperationMode.iUid == KOperationModeCBC)
355 for (TInt i = 0; i < iBlockBytes; ++i)
357 iRegisterPtr[i] = aBuffer[i];
360 else if (iOperationMode.iUid == KOperationModeCTR)
362 //XOR the plaintext with the keystream and increment counter
363 for (TInt i = 0; i < iBlockBytes; ++i)
365 aBuffer[i] ^= iBufferedPlaintextPtr[i];
367 for (TInt i = iBlockBytes - 1; i >= 0; --i)
369 if (++(iRegisterPtr[i]) != 0) break;
374 inline void CSymmetricBlockCipherImpl::ModeDecryptStart(TUint8* aBuffer)
376 __ASSERT_DEBUG((iOperationMode.iUid != KOperationModeCTR), User::Panic(_L("CSymmetricBlockCipherImpl.h"), 1));
377 if (iOperationMode.iUid == KOperationModeCBC)
379 for (TInt i = 0; i < iBlockBytes; ++i)
381 iCurrentCipherTextPtr[i] = aBuffer[i];
386 inline void CSymmetricBlockCipherImpl::ModeDecryptEnd(TUint8* aBuffer)
388 __ASSERT_DEBUG((iOperationMode.iUid != KOperationModeCTR), User::Panic(_L("CSymmetricBlockCipherImpl.h"), 2));
389 if (iOperationMode.iUid == KOperationModeCBC)
391 // xor the output with the previous cipher text
392 for (TInt i = 0; i < iBlockBytes; ++i)
394 aBuffer[i] ^= iRegisterPtr[i];
395 iRegisterPtr[i] = iCurrentCipherTextPtr[i];
401 #endif // __SYMMETRICCIPHERIMPL_H__