crypto/weakcryptospi/source/pbe/pbesymmetricfactory.cpp
changeset 19 cd501b96611d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/crypto/weakcryptospi/source/pbe/pbesymmetricfactory.cpp	Fri Nov 06 13:21:00 2009 +0200
@@ -0,0 +1,245 @@
+/*
+* Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: 
+*
+*/
+
+
+#include <symmetric.h>
+#include "pbesymmetricfactory.h"
+
+#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
+
+/** OpenSSL PKCS8 Effective Key Length Compatibility.*/
+const TUint KPkcs8CompatibilityBits = 128;
+
+/** PKCS12 PBE Effective Key Length Compatibility.*/
+const TUint KPkcs12CompatibilityBits = 40;
+
+#endif
+
+TUint PBE::GetBlockBytes(TPBECipher aCipher)
+	{
+	switch(aCipher)
+		{
+		case ECipherAES_CBC_128:
+		case ECipherAES_CBC_192:
+		case ECipherAES_CBC_256:
+			return KAESBlockBytes;
+		case ECipherDES_CBC:
+		case ECipher3DES_CBC:
+
+		case ECipher2Key3DES_CBC: 
+
+			return KDESBlockBytes;
+		case ECipherRC2_CBC_128_16:
+		case ECipherRC2_CBC_40_16:
+		case ECipherRC2_CBC_128:
+		case ECipherRC2_CBC_40:
+
+		case ECipherRC2_CBC_40_5:
+
+			return KRC2BlockBytes;
+
+		case ECipherARC4_128:
+		case ECipherARC4_40:
+			return 1; // 1 byte block for stream cipher
+
+		default:
+			User::Panic(_L("Invalid PBE cipher"), 1);
+		}
+	return (KErrNone); //	For the compiler
+	}
+
+TUint PBE::GetKeyBytes(TPBECipher aCipher)
+	{
+	switch(aCipher)
+		{
+		case ECipherAES_CBC_128:
+			return KAESKeyBytes128;
+		case ECipherAES_CBC_192:
+			return KAESKeyBytes192;
+		case ECipherAES_CBC_256:
+			return KAESKeyBytes256;
+		case ECipherDES_CBC:
+			return KDESKeyBytes;
+		case ECipher3DES_CBC:
+			return K3DESKeyBytes;
+
+		case ECipher2Key3DES_CBC:
+			return K2Key3DESKeyBytes;
+
+ 		case ECipherRC2_CBC_128:
+ 		case ECipherRC2_CBC_128_16:
+			return KRC2KeyBytes128;
+		case ECipherRC2_CBC_40:
+		case ECipherRC2_CBC_40_16:
+
+		case ECipherRC2_CBC_40_5:
+
+			return KRC2KeyBytes40;
+
+		case ECipherARC4_128:
+			return KRC4KeyBytes128;
+		case ECipherARC4_40:	
+			return KRC4KeyBytes40;
+
+		default:
+			User::Panic(_L("Invalid PBE cipher"), 1);
+		}
+	return (KErrNone);	//	For the compiler
+	}
+
+CSymmetricCipher* PBE::MakeEncryptorL(TPBECipher aCipher, const TDesC8& aKey, 
+	const TDesC8& aIV)
+	{
+	CSymmetricCipher* cipher = 0;	
+	CBlockTransformation* block = 0;
+	switch(aCipher)
+		{
+
+		// stream cipher
+		case ECipherARC4_40:
+		case ECipherARC4_128:
+			cipher = CARC4::NewL(aKey, 0);
+			break;	
+
+		// block cipher	
+		case ECipherAES_CBC_128:
+		case ECipherAES_CBC_192:
+		case ECipherAES_CBC_256:
+			block = CAESEncryptor::NewLC(aKey);
+			break;
+
+		case ECipherDES_CBC:
+			block = CDESEncryptor::NewLC(aKey);
+			break;
+			
+		case ECipher3DES_CBC:		
+			block = C3DESEncryptor::NewLC(aKey);
+			break;
+	
+		case ECipher2Key3DES_CBC:
+			{
+			// Construct 3key from 2 key ( copy first key to 3rd key ) each key 8 bytes
+			TBuf8<K3DESKeyBytes>  encryptKey(aKey);			
+			encryptKey.Append(aKey.Ptr(),KDESKeyBytes);
+			block = C3DESEncryptor::NewLC(encryptKey);			
+			break;
+			}
+
+		case ECipherRC2_CBC_40:
+		case ECipherRC2_CBC_128:		
+			block = CRC2Encryptor::NewLC(aKey);
+			break;
+
+		case ECipherRC2_CBC_40_16:
+		case ECipherRC2_CBC_128_16:
+			block = CRC2Encryptor::NewLC(aKey, KPkcs8CompatibilityBits);
+			break;
+
+		case ECipherRC2_CBC_40_5:
+			block = CRC2Encryptor::NewLC(aKey, KPkcs12CompatibilityBits);
+			break;	
+
+		default:
+			User::Panic(_L("Invalid PBE encryptor"), 1);
+		}
+
+	// if aCipher is not stream cipher, create block cipher object
+	if(aCipher != ECipherARC4_40 && aCipher != ECipherARC4_128)
+		{			
+		block = CModeCBCEncryptor::NewL(block, aIV);
+		CleanupStack::Pop(); //1st block owned by 2nd
+		CleanupStack::PushL(block);//2nd block
+		CPadding* padding = CPaddingSSLv3::NewLC(GetBlockBytes(aCipher));
+		cipher = CBufferedEncryptor::NewL(block, padding);
+		CleanupStack::Pop(padding); //owned by cipher
+		CleanupStack::Pop(block); //owned by cipher
+		}
+
+	return cipher;
+	}
+
+
+CSymmetricCipher* PBE::MakeDecryptorL(TPBECipher aCipher, const TDesC8& aKey, 
+	const TDesC8& aIV)
+	{
+	CSymmetricCipher* cipher = 0;
+	CBlockTransformation* block = 0;
+	switch(aCipher)
+		{
+		// stream cipher
+		case ECipherARC4_40:
+		case ECipherARC4_128:
+			cipher = CARC4::NewL(aKey, 0);
+			break;	
+
+		// block cipher	
+		case ECipherAES_CBC_128:
+		case ECipherAES_CBC_192:
+		case ECipherAES_CBC_256:
+			block = CAESDecryptor::NewLC(aKey);
+			break;
+
+		case ECipherDES_CBC:
+			block = CDESDecryptor::NewLC(aKey);
+			break;
+			
+		case ECipher3DES_CBC:		
+			block = C3DESDecryptor::NewLC(aKey);
+			break;
+
+		case ECipher2Key3DES_CBC:
+			{
+			// Construct 3key from 2 key ( copy first key to 3rd key ) each key 8 bytes
+			TBuf8<K3DESKeyBytes>  encryptKey(aKey);			
+			encryptKey.Append(aKey.Ptr(),KDESKeyBytes);
+			block = C3DESDecryptor::NewLC(encryptKey);			
+			break;
+			}
+
+		case ECipherRC2_CBC_40:
+		case ECipherRC2_CBC_128:
+		  	block = CRC2Decryptor::NewLC(aKey);
+			break;
+			
+		case ECipherRC2_CBC_40_16:
+		case ECipherRC2_CBC_128_16:
+		  	block = CRC2Decryptor::NewLC(aKey, KPkcs8CompatibilityBits);
+			break;
+
+		case ECipherRC2_CBC_40_5:
+			block = CRC2Decryptor::NewLC(aKey, KPkcs12CompatibilityBits);
+			break;	
+
+		default:
+			User::Panic(_L("Invalid PBE decryptor"), 1);
+		}
+
+	// if aCipher is not stream cipher, create block cipher object
+	if(aCipher != ECipherARC4_40 && aCipher != ECipherARC4_128)
+		{	
+		block = CModeCBCDecryptor::NewL(block, aIV);
+		CleanupStack::Pop(); //1st block owned by 2nd
+		CleanupStack::PushL(block);//2nd block
+
+		CPadding* padding = CPaddingSSLv3::NewLC(GetBlockBytes(aCipher));
+		cipher = CBufferedDecryptor::NewL(block, padding);
+		CleanupStack::Pop(padding); //owned by cipher
+		CleanupStack::Pop(block); //owned by cipher
+		}
+
+	return cipher;
+	}