sl@0: /* sl@0: * Copyright (c) 2006-2010 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 "cbcmodeshim.h" sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include "../common/inlines.h" sl@0: sl@0: // CModeCBCEncryptorShim sl@0: CModeCBCEncryptorShim::CModeCBCEncryptorShim(CryptoSpi::CSymmetricCipher* aSymmetricCipherImpl) : sl@0: iSymmetricCipherImpl(aSymmetricCipherImpl) sl@0: { sl@0: } sl@0: sl@0: CModeCBCEncryptorShim* CModeCBCEncryptorShim::NewL(CBlockTransformation* aBT, const TDesC8& aIv) sl@0: { sl@0: CModeCBCEncryptorShim* self(0); sl@0: sl@0: // Check whether the block transform contains an SPI plug-in sl@0: TAny* implPtr(0); sl@0: TInt err = aBT->GetExtension(CryptoSpi::KSymmetricCipherInterface, implPtr, NULL); sl@0: if (err == KErrNone && implPtr) sl@0: { sl@0: CryptoSpi::CSymmetricCipher* impl(static_cast(implPtr)); sl@0: sl@0: const CryptoSpi::TCharacteristics* c(0); sl@0: impl->GetCharacteristicsL(c); sl@0: sl@0: const CryptoSpi::TSymmetricCipherCharacteristics* cipherCharacteristics( sl@0: static_cast(c)); sl@0: sl@0: // Verify that the plug-in supports CBC mode sl@0: if (err == KErrNone && sl@0: cipherCharacteristics->IsOperationModeSupported(CryptoSpi::KOperationModeCBCUid)) sl@0: { sl@0: // Set block transform to encrypt-cbc sl@0: impl->SetCryptoModeL(CryptoSpi::KCryptoModeEncryptUid); sl@0: impl->SetOperationModeL(CryptoSpi::KOperationModeCBCUid); sl@0: impl->SetIvL(aIv); sl@0: self = new(ELeave) CModeCBCEncryptorShim(impl); sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(aBT, aIv); sl@0: CleanupStack::Pop(self); sl@0: } sl@0: } sl@0: return self; sl@0: } sl@0: sl@0: void CModeCBCEncryptorShim::ConstructL(CBlockTransformation* aBT, const TDesC8& aIv) sl@0: { sl@0: CModeCBCEncryptor::ConstructL(aBT, aIv); sl@0: } sl@0: sl@0: void CModeCBCEncryptorShim::Reset() sl@0: { sl@0: iSymmetricCipherImpl->Reset(); sl@0: } sl@0: sl@0: TInt CModeCBCEncryptorShim::BlockSize() const sl@0: { sl@0: return BitsToBytes(iSymmetricCipherImpl->BlockSize()); sl@0: } sl@0: sl@0: TInt CModeCBCEncryptorShim::KeySize() const sl@0: { sl@0: return iSymmetricCipherImpl->KeySize(); sl@0: } sl@0: sl@0: void CModeCBCEncryptorShim::Transform(TDes8& aBlock) sl@0: { sl@0: // This function will never get called if a buffered sl@0: // encryptor is used because Process and ProcessFinalL call sl@0: // iSymmetricCipherImpl directly sl@0: iBT->Transform(aBlock); sl@0: } sl@0: sl@0: void CModeCBCEncryptorShim::SetIV(const TDesC8& aIv) sl@0: { sl@0: TRAPD(err, iSymmetricCipherImpl->SetIvL(aIv)); sl@0: if (err == KErrOverflow) sl@0: { sl@0: User::Panic(KCryptoPanic, ECryptoPanicInputTooLarge); sl@0: } sl@0: else if (err != KErrNone) sl@0: { sl@0: // SetIvL should only leave if the aIv is incorrect sl@0: User::Panic(KCryptoPanic, KErrArgument); sl@0: } sl@0: } sl@0: sl@0: TInt CModeCBCEncryptorShim::Extension_(TUint aExtensionId, TAny*& a0, TAny* /*a1*/) sl@0: { sl@0: TInt ret(KErrExtensionNotSupported); sl@0: sl@0: if (CryptoSpi::KSymmetricCipherInterface == aExtensionId) sl@0: { sl@0: a0=iSymmetricCipherImpl; sl@0: ret=KErrNone; sl@0: } sl@0: return ret; sl@0: } sl@0: sl@0: // CModeCBCDecryptorShim sl@0: CModeCBCDecryptorShim::CModeCBCDecryptorShim(CryptoSpi::CSymmetricCipher* aSymmetricCipherImpl) : sl@0: iSymmetricCipherImpl(aSymmetricCipherImpl) sl@0: { sl@0: } sl@0: sl@0: CModeCBCDecryptorShim* CModeCBCDecryptorShim::NewL(CBlockTransformation* aBT, const TDesC8& aIv) sl@0: { sl@0: CModeCBCDecryptorShim* self(0); sl@0: sl@0: // Check whether the block transform contains an SPI plug-in sl@0: TAny* implPtr(0); sl@0: TInt err = aBT->GetExtension(CryptoSpi::KSymmetricCipherInterface, implPtr, NULL); sl@0: if (err == KErrNone && implPtr) sl@0: { sl@0: CryptoSpi::CSymmetricCipher* impl(static_cast(implPtr)); sl@0: sl@0: const CryptoSpi::TCharacteristics* c(0); sl@0: impl->GetCharacteristicsL(c); sl@0: sl@0: const CryptoSpi::TSymmetricCipherCharacteristics* cipherCharacteristics( sl@0: static_cast(c)); sl@0: sl@0: // Verify that the plug-in supports CBC mode sl@0: if (err == KErrNone && sl@0: cipherCharacteristics->IsOperationModeSupported(CryptoSpi::KOperationModeCBCUid)) sl@0: { sl@0: // Set block transform to encrypt-cbc sl@0: impl->SetCryptoModeL(CryptoSpi::KCryptoModeDecryptUid); sl@0: impl->SetOperationModeL(CryptoSpi::KOperationModeCBCUid); sl@0: impl->SetIvL(aIv); sl@0: self = new(ELeave) CModeCBCDecryptorShim(impl); sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(aBT, aIv); sl@0: CleanupStack::Pop(self); sl@0: } sl@0: } sl@0: return self; sl@0: } sl@0: sl@0: void CModeCBCDecryptorShim::ConstructL(CBlockTransformation* aBT, const TDesC8& aIv) sl@0: { sl@0: CModeCBCDecryptor::ConstructL(aBT, aIv); sl@0: } sl@0: sl@0: void CModeCBCDecryptorShim::Reset() sl@0: { sl@0: iSymmetricCipherImpl->Reset(); sl@0: } sl@0: sl@0: TInt CModeCBCDecryptorShim::BlockSize() const sl@0: { sl@0: return BitsToBytes(iSymmetricCipherImpl->BlockSize()); sl@0: } sl@0: sl@0: TInt CModeCBCDecryptorShim::KeySize() const sl@0: { sl@0: return iSymmetricCipherImpl->KeySize(); sl@0: } sl@0: sl@0: void CModeCBCDecryptorShim::Transform(TDes8& aBlock) sl@0: { sl@0: // This function will never get called if a buffered sl@0: // encryptor is used because Process and ProcessFinalL call sl@0: // iSymmetricCipherImpl directly sl@0: iBT->Transform(aBlock); sl@0: } sl@0: sl@0: void CModeCBCDecryptorShim::SetIV(const TDesC8& aIv) sl@0: { sl@0: TRAPD(err, iSymmetricCipherImpl->SetIvL(aIv)); sl@0: if (err == KErrOverflow) sl@0: { sl@0: User::Panic(KCryptoPanic, ECryptoPanicInputTooLarge); sl@0: } sl@0: else if (err != KErrNone) sl@0: { sl@0: // SetIvL should only leave if the aIv is incorrect sl@0: User::Panic(KCryptoPanic, KErrArgument); sl@0: } sl@0: } sl@0: sl@0: TInt CModeCBCDecryptorShim::Extension_(TUint aExtensionId, TAny*& a0, TAny* /*a1*/) sl@0: { sl@0: TInt ret(KErrExtensionNotSupported); sl@0: sl@0: if (CryptoSpi::KSymmetricCipherInterface == aExtensionId) sl@0: { sl@0: a0=iSymmetricCipherImpl; sl@0: ret=KErrNone; sl@0: } sl@0: return ret; sl@0: }