--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/crypto/weakcryptospi/source/symmetric/bufferedtransformation.cpp Fri Nov 13 10:07:38 2009 +0530
@@ -0,0 +1,260 @@
+/*
+* 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 "bufferedtransformation.h"
+
+#include <cryptospi/cryptospidef.h>
+#include <cryptopanic.h>
+#include <e32cmn.h>
+#include "symmetriccipherplugin.h"
+
+#include "blocktransformation.h"
+#include "bufferedtransformationshim.h"
+#include "padding.h"
+#include "../common/inlines.h"
+
+EXPORT_C CBufferedTransformation::~CBufferedTransformation()
+ {
+ delete iBT;
+ delete iPadding;
+ delete iInputStoreBuf;
+ }
+
+void CBufferedTransformation::Process(const TDesC8& aInput, TDes8& aOutput)
+ {
+ __ASSERT_DEBUG(aOutput.MaxLength() >= MaxOutputLength(aInput.Length()), User::Panic(KCryptoPanic, ECryptoPanicOutputDescriptorOverflow));
+
+ TInt blockSize = iBT->BlockSize();
+
+ if ( (aInput.Size() + iInputStore.Size()) < blockSize )
+ {
+ iInputStore.Append(aInput);
+ }
+ else
+ {
+ TInt outputIndex = aOutput.Size();
+ aOutput.Append(iInputStore);
+
+ TInt inputIndex = blockSize - iInputStore.Size();
+ aOutput.Append(aInput.Mid(0, inputIndex));
+
+ TPtr8 transformBuf((TUint8*)(aOutput.Ptr()) + outputIndex, blockSize,
+ blockSize);
+ //This should read:
+ //TPtr8 transformBuf(aOutput.Mid(outputIndex, blockSize));
+ //but in the wonderful world of descriptors, Mid returns a TPtrC8 even
+ //when called on a TPtr8. Fantastic eh?
+ iBT->Transform(transformBuf);
+
+ outputIndex += blockSize;
+
+ TInt len = aInput.Size() - blockSize;
+
+ for (; inputIndex<=len; inputIndex+=blockSize)
+ {
+ aOutput.Append(aInput.Mid(inputIndex, blockSize));
+ transformBuf.Set((TUint8*)(aOutput.Ptr()) + outputIndex, blockSize,
+ blockSize);
+ iBT->Transform(transformBuf);
+ outputIndex += blockSize;
+ }
+
+ iInputStore.Zero();
+ if (inputIndex < aInput.Size())
+ iInputStore.Append(aInput.Mid(inputIndex));
+ }
+ }
+
+TInt CBufferedTransformation::MaxOutputLength(TInt aInputLength) const
+ {
+ TInt rem = (aInputLength + iInputStore.Size()) % (iBT->BlockSize());
+ return ((aInputLength + iInputStore.Size()) - rem);
+ }
+
+void CBufferedTransformation::Reset()
+ {
+ iBT->Reset();
+ iInputStore.Zero();
+ }
+
+TInt CBufferedTransformation::BlockSize() const
+ {
+ return (iBT->BlockSize());
+ }
+
+TInt CBufferedTransformation::KeySize() const
+ {
+ return (iBT->KeySize());
+ }
+
+EXPORT_C CBlockTransformation* CBufferedTransformation::BlockTransformer() const
+{
+ return (iBT);
+}
+
+CBufferedTransformation::CBufferedTransformation()
+ : iInputStore(0,0,0)
+ {
+ }
+
+void CBufferedTransformation::ConstructL(CBlockTransformation* aBT, CPadding* aPadding)
+ {
+ iInputStoreBuf = HBufC8::NewL(aBT->BlockSize());
+ iInputStore.Set(iInputStoreBuf->Des());
+
+ // Take ownership last - doesn't take ownership if we leave
+ iBT = aBT;
+ iPadding = aPadding;
+ }
+
+
+// CBufferedEncryptor
+
+EXPORT_C CBufferedEncryptor* CBufferedEncryptor::NewL(
+ CBlockTransformation* aBT, CPadding* aPadding)
+ {
+ CBufferedEncryptor* self = CBufferedEncryptorShim::NewL(aBT, aPadding);
+ if (! self)
+ {
+ // not able to use CryptoSpi, possibly due to an exterally
+ // derived legacy class so fallback to old implementation.
+ self = NewLC(aBT,aPadding);
+ CleanupStack::Pop(self);
+ }
+ return self;
+ }
+
+EXPORT_C CBufferedEncryptor* CBufferedEncryptor::NewLC(
+ CBlockTransformation* aBT, CPadding* aPadding)
+ {
+ CBufferedEncryptor* self = new (ELeave) CBufferedEncryptor();
+ CleanupStack::PushL(self);
+ self->ConstructL(aBT, aPadding);
+ return self;
+ }
+
+void CBufferedEncryptor::ConstructL(CBlockTransformation* aBT, CPadding* aPadding)
+ {
+ CBufferedTransformation::ConstructL(aBT, aPadding);
+ }
+
+CBufferedEncryptor::CBufferedEncryptor()
+ {
+ }
+
+void CBufferedEncryptor::ProcessFinalL(const TDesC8& aInput, TDes8& aOutput)
+ {
+ __ASSERT_DEBUG(aOutput.MaxLength() >= MaxFinalOutputLength(aInput.Length()), User::Panic(KCryptoPanic, ECryptoPanicOutputDescriptorOverflow));
+ Process(aInput, aOutput);
+
+ TInt outputIndex = aOutput.Size();
+ iPadding->PadL(iInputStore, aOutput);
+ assert(aOutput.Size() % iBT->BlockSize() == 0);
+
+ TUint blockSize = iBT->BlockSize();
+ TInt len = aOutput.Size() - outputIndex;
+
+ for(TInt i=len; i>0; i-=blockSize)
+ {
+ TPtr8 transformBuf((TUint8*)(aOutput.Ptr()) + outputIndex, blockSize,
+ blockSize);
+ iBT->Transform(transformBuf);
+ outputIndex+=blockSize;
+ }
+
+ iInputStore.Zero();
+ }
+
+TInt CBufferedEncryptor::MaxFinalOutputLength(TInt aInputLength) const
+ {
+ return iPadding->MaxPaddedLength(iInputStore.Size() + aInputLength);
+ }
+
+// CBufferedDecryptor
+
+EXPORT_C CBufferedDecryptor* CBufferedDecryptor::NewL(
+ CBlockTransformation* aBT, CPadding* aPadding)
+ {
+ CBufferedDecryptor* self = CBufferedDecryptorShim::NewL(aBT, aPadding);
+ if (! self)
+ {
+ // not able to use CryptoSpi, possibly due to an exterally
+ // derived legacy class so fallback to old implementation.
+ self = NewLC(aBT,aPadding);
+ CleanupStack::Pop(self);
+ }
+ return self;
+ }
+
+EXPORT_C CBufferedDecryptor* CBufferedDecryptor::NewLC(
+ CBlockTransformation* aBT, CPadding* aPadding)
+ {
+ CBufferedDecryptor* self = new (ELeave) CBufferedDecryptor();
+ CleanupStack::PushL(self);
+ self->ConstructL(aBT, aPadding);
+ return self;
+ }
+
+CBufferedDecryptor::CBufferedDecryptor()
+ {
+ }
+
+void CBufferedDecryptor::ProcessFinalL(const TDesC8& aInput, TDes8& aOutput)
+ {
+ __ASSERT_DEBUG(aOutput.MaxLength() >= MaxFinalOutputLength(aInput.Length()), User::Panic(KCryptoPanic, ECryptoPanicOutputDescriptorOverflow));
+
+ assert((aInput.Size() + iInputStore.Size()) % iPadding->BlockSize()==0);
+ assert(aInput.Size() + iInputStore.Size() !=0 );
+ assert(iPadding->BlockSize() % BlockSize() == 0);
+ //1) Decrypt into aOutput up till the last full _padding_ blocksize
+ //If this panics with descriptor problems, you've probably called
+ //ProcessFinalL with a non-_padding_ blocksized aligned amount of data.
+ TInt lenToDecrypt = aInput.Size() - iPadding->BlockSize();
+ if(lenToDecrypt > 0)
+ {
+ Process(aInput.Left(lenToDecrypt), aOutput);
+ assert(iInputStore.Size()==0);
+ }
+ else
+ {
+ lenToDecrypt = 0;
+ }
+
+ //2) Decrypt the last _padding_ blocksize into a new buffer
+ HBufC8* padBuf = HBufC8::NewLC(iPadding->BlockSize());
+ TPtr8 padPtr = padBuf->Des();
+ Process(aInput.Mid(lenToDecrypt), padPtr);
+ assert(iInputStore.Size()==0);
+
+ //3) Unpad that last _padding_ blocksize into aOutput
+ // Note that padding systems must always, like everything else in crypto,
+ // _append_ data.
+ iPadding->UnPadL(padPtr, aOutput);
+
+ CleanupStack::PopAndDestroy(padBuf);
+ }
+
+TInt CBufferedDecryptor::MaxFinalOutputLength(TInt aInputLength) const
+ {
+ return iPadding->MaxUnPaddedLength(aInputLength + iInputStore.Size());
+ }
+
+void CBufferedDecryptor::ConstructL(CBlockTransformation* aBT, CPadding* aPadding)
+ {
+ CBufferedTransformation::ConstructL(aBT, aPadding);
+ }