Update contrib.
2 * Copyright (c) 2002-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 #include "bufferedtransformation.h"
20 #include "blocktransformation.h"
22 #include "../common/inlines.h"
23 #include <cryptopanic.h>
25 EXPORT_C CBufferedTransformation::~CBufferedTransformation()
29 delete iInputStoreBuf;
32 void CBufferedTransformation::Process(const TDesC8& aInput, TDes8& aOutput)
34 __ASSERT_DEBUG(aOutput.MaxLength() >= MaxOutputLength(aInput.Length()), User::Panic(KCryptoPanic, ECryptoPanicOutputDescriptorOverflow));
36 TInt blockSize = iBT->BlockSize();
38 if ( (aInput.Size() + iInputStore.Size()) < blockSize )
40 iInputStore.Append(aInput);
44 TInt outputIndex = aOutput.Size();
45 aOutput.Append(iInputStore);
47 TInt inputIndex = blockSize - iInputStore.Size();
48 aOutput.Append(aInput.Mid(0, inputIndex));
50 TPtr8 transformBuf((TUint8*)(aOutput.Ptr()) + outputIndex, blockSize,
53 //TPtr8 transformBuf(aOutput.Mid(outputIndex, blockSize));
54 //but in the wonderful world of descriptors, Mid returns a TPtrC8 even
55 //when called on a TPtr8. Fantastic eh?
56 iBT->Transform(transformBuf);
58 outputIndex += blockSize;
60 TInt len = aInput.Size() - blockSize;
62 for (; inputIndex<=len; inputIndex+=blockSize)
64 aOutput.Append(aInput.Mid(inputIndex, blockSize));
65 transformBuf.Set((TUint8*)(aOutput.Ptr()) + outputIndex, blockSize,
67 iBT->Transform(transformBuf);
68 outputIndex += blockSize;
72 if (inputIndex < aInput.Size())
73 iInputStore.Append(aInput.Mid(inputIndex));
77 TInt CBufferedTransformation::MaxOutputLength(TInt aInputLength) const
79 TInt rem = (aInputLength + iInputStore.Size()) % (iBT->BlockSize());
80 return ((aInputLength + iInputStore.Size()) - rem);
83 void CBufferedTransformation::Reset()
89 TInt CBufferedTransformation::BlockSize() const
91 return (iBT->BlockSize());
94 TInt CBufferedTransformation::KeySize() const
96 return (iBT->KeySize());
99 EXPORT_C CBlockTransformation* CBufferedTransformation::BlockTransformer() const
104 CBufferedTransformation::CBufferedTransformation()
109 void CBufferedTransformation::ConstructL(CBlockTransformation* aBT, CPadding* aPadding)
111 iInputStoreBuf = HBufC8::NewL(aBT->BlockSize());
112 iInputStore.Set(iInputStoreBuf->Des());
114 // Take ownership last - doesn't take ownership if we leave
120 // CBufferedEncryptor
122 EXPORT_C CBufferedEncryptor* CBufferedEncryptor::NewL(
123 CBlockTransformation* aBT, CPadding* aPadding)
125 CBufferedEncryptor* self = NewLC(aBT,aPadding);
126 CleanupStack::Pop(self);
130 EXPORT_C CBufferedEncryptor* CBufferedEncryptor::NewLC(
131 CBlockTransformation* aBT, CPadding* aPadding)
133 CBufferedEncryptor* self = new (ELeave) CBufferedEncryptor();
134 CleanupStack::PushL(self);
135 self->ConstructL(aBT, aPadding);
139 CBufferedEncryptor::CBufferedEncryptor()
143 void CBufferedEncryptor::ProcessFinalL(const TDesC8& aInput, TDes8& aOutput)
145 __ASSERT_DEBUG(aOutput.MaxLength() >= MaxFinalOutputLength(aInput.Length()), User::Panic(KCryptoPanic, ECryptoPanicOutputDescriptorOverflow));
146 Process(aInput, aOutput);
148 TInt outputIndex = aOutput.Size();
149 iPadding->PadL(iInputStore, aOutput);
150 assert(aOutput.Size() % iBT->BlockSize() == 0);
152 TUint blockSize = iBT->BlockSize();
153 TInt len = aOutput.Size() - outputIndex;
155 for(TInt i=len; i>0; i-=blockSize)
157 TPtr8 transformBuf((TUint8*)(aOutput.Ptr()) + outputIndex, blockSize,
159 iBT->Transform(transformBuf);
160 outputIndex+=blockSize;
166 TInt CBufferedEncryptor::MaxFinalOutputLength(TInt aInputLength) const
168 return iPadding->MaxPaddedLength(iInputStore.Size() + aInputLength);
171 // CBufferedDecryptor
173 EXPORT_C CBufferedDecryptor* CBufferedDecryptor::NewL(
174 CBlockTransformation* aBT, CPadding* aPadding)
176 CBufferedDecryptor* self = NewLC(aBT,aPadding);
177 CleanupStack::Pop(self);
181 EXPORT_C CBufferedDecryptor* CBufferedDecryptor::NewLC(
182 CBlockTransformation* aBT, CPadding* aPadding)
184 CBufferedDecryptor* self = new (ELeave) CBufferedDecryptor();
185 CleanupStack::PushL(self);
186 self->ConstructL(aBT, aPadding);
190 CBufferedDecryptor::CBufferedDecryptor()
194 void CBufferedDecryptor::ProcessFinalL(const TDesC8& aInput, TDes8& aOutput)
196 __ASSERT_DEBUG(aOutput.MaxLength() >= MaxFinalOutputLength(aInput.Length()), User::Panic(KCryptoPanic, ECryptoPanicOutputDescriptorOverflow));
198 assert((aInput.Size() + iInputStore.Size()) % iPadding->BlockSize()==0);
199 assert(aInput.Size() + iInputStore.Size() !=0 );
200 assert(iPadding->BlockSize() % BlockSize() == 0);
201 //1) Decrypt into aOutput up till the last full _padding_ blocksize
202 //If this panics with descriptor problems, you've probably called
203 //ProcessFinalL with a non-_padding_ blocksized aligned amount of data.
204 TInt lenToDecrypt = aInput.Size() - iPadding->BlockSize();
207 Process(aInput.Left(lenToDecrypt), aOutput);
208 assert(iInputStore.Size()==0);
215 //2) Decrypt the last _padding_ blocksize into a new buffer
216 HBufC8* padBuf = HBufC8::NewLC(iPadding->BlockSize());
217 TPtr8 padPtr = padBuf->Des();
218 Process(aInput.Mid(lenToDecrypt), padPtr);
219 assert(iInputStore.Size()==0);
221 //3) Unpad that last _padding_ blocksize into aOutput
222 // Note that padding systems must always, like everything else in crypto,
224 iPadding->UnPadL(padPtr, aOutput);
226 CleanupStack::PopAndDestroy(padBuf);
229 TInt CBufferedDecryptor::MaxFinalOutputLength(TInt aInputLength) const
231 return iPadding->MaxUnPaddedLength(aInputLength + iInputStore.Size());