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