diff -r 000000000000 -r d0791faffa3f backupandrestore/backupengine/src/sbecompressionandencryption.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/backupandrestore/backupengine/src/sbecompressionandencryption.cpp Tue Feb 02 01:11:40 2010 +0200 @@ -0,0 +1,770 @@ +// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "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: +// Implementation of compression and encryption +// +// + +/** + @file +*/ +#include "sbencrypt.h" +#include "sbecompressionandencryption.h" +#include "sblog.h" +#include "sbtypes.h" + +#include +#include +#include + +// Uncomment the next line if you want to turn off compression & encryption, ignore the warnings. +//#define TURN_OFF_COMPRESSION_AND_ENCRYPTION + +namespace conn + { +#ifndef TURN_OFF_COMPRESSION_AND_ENCRYPTION + const TInt KJavaVirtualMachineSecureId = 0x102033e6; + const TInt KMaxHeapSize = KMaxTInt / 2; +#endif + /** Compression block size + */ + const TInt KCompressionBlockSize = 1024 * 64; // 64K + /** Compression growth size + + This is calculated as the size of the block we want to compress * 1.01. As defined by the ZLib library. + */ + const TInt CSBECompressAndEncrypt::iCompressionGrowthSize = static_cast(KCompressionBlockSize * 0.01) + 12 + sizeof(TCompressionHeader); + + + template void ReadL(T& aT, TPtr8& aBuffer, TInt aStartAt = 0, TInt aToCopy = sizeof(T)) + /** Reads data from any given type into aBuffer + + @param aT type to put in buffer + @param aBuffer the buffer + @param aStartAt offset of the data + @param aToCopy the amount of data to copy + */ + { + TUint8* inData = const_cast(aBuffer.Ptr()); + TUint8* outData = (reinterpret_cast(&aT)) + aStartAt; + for (TInt x = 0; x < aToCopy; x++) + { + *(outData++) = *(inData++); + } // for + } + + + template void WriteL(T& aT, TPtr8& aBuffer, TInt aStartAt = 0, TInt aToCopy = sizeof(T)) + /** Writes data from aBuffer into any given type + + @param aT type to read in from buffer + @param aBuffer the buffer + @param aStartAt offset of the data + @param aToCopy the amount of data to copy + */ + { + TUint8* inData = reinterpret_cast(&aT); + TUint8* outData = (const_cast(aBuffer.Ptr())) + aStartAt; + for (TInt x = 0; x < aToCopy; x++) + { + *(outData++) = *(inData++); + } // for + + aBuffer.SetLength(aBuffer.Length() + sizeof(T)); + } + + CSBECompressAndEncrypt* CSBECompressAndEncrypt::NewLC(CSBGenericTransferType*& apTransferType, TPtr8& aInputData) + /** Standard Symbian constructor + + @param apTransferType transfer type of data. + @param aInputData data block to be used. Start point will be changed to allow for compression. + */ + { + CSBECompressAndEncrypt* self = new(ELeave) CSBECompressAndEncrypt(); + CleanupStack::PushL(self); + self->ConstructL(apTransferType, aInputData); + + return self; + } + + CSBECompressAndEncrypt::CSBECompressAndEncrypt() : + iActualStart(NULL, 0), iCipher(NULL), iIsFreed(EFalse) + /** Standard C++ Constructor + */ + { + } + + CSBECompressAndEncrypt::~CSBECompressAndEncrypt() + /** Standard C++ Destructor + */ + { +#ifndef TURN_OFF_COMPRESSION_AND_ENCRYPTION + + if( ! iIsFreed ) + iOffsetStart->Set(iActualStart); // free reserved space when leave occurs. +#endif + delete iCipher; + } + + void CSBECompressAndEncrypt::ConstructL(CSBGenericTransferType*& apTransferType, TPtr8& aOutputData) + /** + Standard Symbian second phase constructor + + @param apTransferType transfer type of data. + @param aInputData data block to be used. Start point will be changed to allow for compression. + */ + { + __LOG2("CSBECompressAndEncrypt::ConstructL() - START - aOutputData: 0x%08x (%d)", aOutputData.Ptr(), aOutputData.Length()); + +#ifndef TURN_OFF_COMPRESSION_AND_ENCRYPTION + // Do we need a key source and cipher? + TSBDerivedType derivedType = apTransferType->DerivedTypeL(); + TInt extraToReserve = 0; + if ((derivedType == ESIDTransferDerivedType) || (derivedType == EJavaTransferDerivedType)) + { + TSecureId secureId; + TDriveNumber driveNumber; + if (derivedType == ESIDTransferDerivedType) + { + // Need the Sid transfertype + CSBSIDTransferType* pSIDTransferType = CSBSIDTransferType::NewL(apTransferType); + CleanupStack::PushL(pSIDTransferType); + + secureId = pSIDTransferType->SecureIdL(); + driveNumber = pSIDTransferType->DriveNumberL(); + + CleanupStack::PopAndDestroy(pSIDTransferType); + } // if + else + { + // Java + secureId.iId = KJavaVirtualMachineSecureId; + driveNumber = apTransferType->DriveNumberL(); + } // else + + // We will be doing encryption. Get the key + CSecureBUREncryptKeySource* keySource = CSecureBUREncryptKeySource::NewL(); + CleanupStack::PushL(keySource); + + // Get the key and the buffer? + keySource->GetBackupKeyL(driveNumber, secureId, + iDoEncrypt, iKey, iGotBuffer, iBuffer); + if (!iGotBuffer) + { + // See if there is a default buffer + keySource->GetDefaultBufferForBackupL(driveNumber, iGotBuffer, iBuffer); + } // if + + CleanupStack::PopAndDestroy(keySource); + + // Create the cipher, if needed. + if (iDoEncrypt) + { + __LOG1("Key length: %d", iKey.Length() * 4); + iCipher = CARC4::NewL(iKey); + } // if + + extraToReserve = sizeof(TEncryptionHeader) + iBuffer.Size(); + } // if + + // Reserve the space required + TInt numberBlocks = (aOutputData.MaxSize() / KCompressionBlockSize) + (((aOutputData.MaxSize() % KCompressionBlockSize) == 0) ? 0 : 1); + TInt reservedSpace = (numberBlocks * iCompressionGrowthSize) + extraToReserve; + __LOG2("CSBECompressAndEncrypt::ConstructL() - numberBlocks: %d, reservedSpace: %d", numberBlocks, reservedSpace); + + // Keep a copy of the acutual data block + iActualStart.Set(const_cast(aOutputData.Ptr()), 0, aOutputData.MaxSize()); + + // Reserve the space in the input data + if (reservedSpace > aOutputData.MaxSize()) + { + User::Leave(KErrOverflow); + } + aOutputData.Set((const_cast(aOutputData.Ptr()) + reservedSpace), 0, aOutputData.MaxSize() - reservedSpace); + iOffsetStart = &aOutputData; +#endif + __LOG2("CSBECompressAndEncrypt::ConstructL() - END - aOutputData: 0x%08x (%d)", aOutputData.Ptr(), aOutputData.Length()); + } + + void CSBECompressAndEncrypt::PackL(TPtr8& aOutputData) + /** Performs the compression and encryption + + @param aOutputData the compressed data + */ + { + __LOG4("CSBECompressAndEncrypt::PackL() - START - aOutputData: 0x%08x (%d), iActualStart: 0x%08x (%d)", aOutputData.Ptr(), aOutputData.Length(), iActualStart.Ptr(), iActualStart.Length()); +#ifndef TURN_OFF_COMPRESSION_AND_ENCRYPTION + // Add the encryption header + TEncryptionHeader encryptionHeader; + encryptionHeader.iEncrypted = iDoEncrypt; + encryptionHeader.iBufferSize = iBuffer.Size(); + encryptionHeader.iTotalSize = sizeof(TEncryptionHeader) + encryptionHeader.iBufferSize; + + __LOG1("CSBECompressAndEncrypt::PackL() - Encryption Header: Encryption supported %d", encryptionHeader.iEncrypted); + __LOG1("CSBECompressAndEncrypt::PackL() - Encryption Header: BufferSize %d", encryptionHeader.iBufferSize); + __LOG1("CSBECompressAndEncrypt::PackL() - Encryption Header: Total Size %d",encryptionHeader.iTotalSize); + + // Move along + TPtr8 encryptionOffset(const_cast(iActualStart.Ptr()), 0, sizeof(TEncryptionHeader)); + iActualStart.SetLength(sizeof(TEncryptionHeader)); + + // Add the encryption buffer + if (encryptionHeader.iBufferSize > 0) + { + iActualStart.Append(reinterpret_cast(const_cast(iBuffer.Ptr())), iBuffer.Size()); + } // if + + // Temp buffers used for compression & encryption + HBufC8* compressionBuffer = HBufC8::NewLC(KCompressionBlockSize + iCompressionGrowthSize); + HBufC8* encryptionBuffer = NULL; + if (iDoEncrypt) + { + encryptionBuffer = HBufC8::NewLC(KCompressionBlockSize + iCompressionGrowthSize); + } // if + + // Do compression and encryption + TInt location = 0; + while (location < iOffsetStart->Size()) + { + // Size of data to compress + TInt toCompressSize = KCompressionBlockSize; + if ((iOffsetStart->Size() - location) < KCompressionBlockSize) + { + toCompressSize = iOffsetStart->Size() - location; + } + + // Compress the data + TPtr8 toCompress((const_cast(iOffsetStart->Ptr()) + location), toCompressSize, toCompressSize); + TPtr8 compress = compressionBuffer->Des(); + CEZCompressor::CompressL(compress, toCompress, Z_BEST_COMPRESSION); + + // Add the header information + TCompressionHeader compressionHeader; + compressionHeader.iCompressedSize = compressionBuffer->Size(); + compressionHeader.iUncompressedSize = toCompressSize; + + __LOG1("CSBECompressAndEncrypt::PackL() - Compression Header: Compressed %d", compressionHeader.iCompressedSize); + __LOG1("CSBECompressAndEncrypt::PackL() - Compression Header: UnCompressed %d", compressionHeader.iUncompressedSize); + + if (iDoEncrypt) + { + encryptionBuffer->Des().Append(reinterpret_cast(&compressionHeader), sizeof(TCompressionHeader)); + encryptionBuffer->Des().Append(compressionBuffer->Des()); + + iCipher->Process(encryptionBuffer->Des(), iActualStart); + } // if + else + { + iActualStart.Append(reinterpret_cast(&compressionHeader), sizeof(TCompressionHeader)); + iActualStart.Append(compressionBuffer->Des()); + } // else + + if (encryptionBuffer) + { + encryptionBuffer->Des().SetLength(0); + } + compressionBuffer->Des().SetLength(0); + location += toCompressSize; + encryptionHeader.iTotalSize += sizeof(TCompressionHeader) + compressionHeader.iCompressedSize; + } // while + + // Add the encryption buffer + WriteL(encryptionHeader, encryptionOffset, 0, sizeof(TEncryptionHeader)); + + // Cleanup + if (encryptionBuffer) + { + CleanupStack::PopAndDestroy(encryptionBuffer); + } // if + CleanupStack::PopAndDestroy(compressionBuffer); + + aOutputData.Set(iActualStart); + iIsFreed = ETrue; +#endif + __LOG("CSBECompressAndEncrypt::PackL() - END"); + } + void CSBECompressAndEncrypt::FreeReservedSpace(TPtr8& aOutputData) + /* + Free space researved in ConstructL if no data to be compressed. + @param aOutputData the compressed data + */ + { + __LOG("CSBECompressAndEncrypt::FreeReservedSpace() - START"); + +#ifndef TURN_OFF_COMPRESSION_AND_ENCRYPTION + + __LOG1("CSBECompressAndEncrypt::FreeReservedSpace() aOutputData.Length(): %d", aOutputData.Length()); + + aOutputData.Set(iActualStart); + iIsFreed = ETrue; +#endif + + __LOG("CSBECompressAndEncrypt::FreeReservedSpace() - END"); + } + + CSBEDecompressAndEncrypt* CSBEDecompressAndEncrypt::NewL() + /** Standard Symbian constructor + */ + { + CSBEDecompressAndEncrypt* self = CSBEDecompressAndEncrypt::NewLC(); + CleanupStack::Pop(self); + + return self; + } + + CSBEDecompressAndEncrypt* CSBEDecompressAndEncrypt::NewLC() + /** Standard Symbian constructor + */ + { + CSBEDecompressAndEncrypt* self = new(ELeave) CSBEDecompressAndEncrypt(); + CleanupStack::PushL(self); + + return self; + } + + CSBEDecompressAndEncrypt::CSBEDecompressAndEncrypt() : + iType(ENotSet), iCurrentPtr(NULL, 0), iCount(0), iJavaHash(NULL), iCipher(NULL) + /** Stanard C++ Constructor + */ + { + Reset(); + } + + CSBEDecompressAndEncrypt::~CSBEDecompressAndEncrypt() + /** Standard C++ Destructor + */ + { + delete iCipher; + delete iJavaHash; + delete iBuffer; + } + + void CSBEDecompressAndEncrypt::SetBuffer(TDesC8& aOutputData) + { + iCurrentPtr.Set(const_cast(aOutputData.Ptr()), aOutputData.Size(), aOutputData.Size()); + } + + void CSBEDecompressAndEncrypt::SetGenericTransferTypeL(CSBGenericTransferType*& apTransferType) + { + __LOG("CSBEDecompressAndEncrypt::SetGenericTransferTypeL() - START"); +#ifndef TURN_OFF_COMPRESSION_AND_ENCRYPTION + TSBDerivedType derivedType = apTransferType->DerivedTypeL(); + if (derivedType == ESIDTransferDerivedType) + { + // Need the Sid transfertype + CSBSIDTransferType* pSIDTransferType = CSBSIDTransferType::NewL(apTransferType); + CleanupStack::PushL(pSIDTransferType); + + // Do we need to perform a reset + if ((iType != ESid) || + (iDriveNumber != pSIDTransferType->DriveNumberL()) || + (iSecureId != pSIDTransferType->SecureIdL())) + { + Reset(); + + iDriveNumber = pSIDTransferType->DriveNumberL(); + iSecureId = pSIDTransferType->SecureIdL(); + __LOG1("CSBEDecompressAndEncrypt::SetGenericTransferTypeL() - SecureId ID 0x%08x", iSecureId.iId); + iType = ESid; + } // if + CleanupStack::PopAndDestroy(pSIDTransferType); + } // if + else if (derivedType == EJavaTransferDerivedType) + { + // Java + CSBJavaTransferType* pJavaTransferType = CSBJavaTransferType::NewL(apTransferType); + CleanupStack::PushL(pJavaTransferType); + + // Do we need to perform a reset + const TDesC& javahash = pJavaTransferType->SuiteHashL(); + __LOG1("CSBEDecompressAndEncrypt::SetGenericTransferTypeL() - JavaHash %S", &javahash); + if ((iType != EJava) || + (iDriveNumber != pJavaTransferType->DriveNumberL()) || + (iJavaHash->Des() != javahash)) + { + Reset(); + + // Store java hash + delete iJavaHash; + iJavaHash = NULL; + iJavaHash = HBufC::NewL(javahash.Size()); + iJavaHash->Des().Append(javahash); + + iSecureId.iId = KJavaVirtualMachineSecureId; + iDriveNumber = apTransferType->DriveNumberL(); + iType = EJava; + } + + CleanupStack::PopAndDestroy(pJavaTransferType); + } // else if + else if (derivedType == EPackageTransferDerivedType) + { + // Package + CSBPackageTransferType* pPackageTransferType = CSBPackageTransferType::NewL(apTransferType); + CleanupStack::PushL(pPackageTransferType); + + // Do we need to perform a reset + if ((iType != EPackage) || + (iPackageId != pPackageTransferType->PackageIdL())) + { + Reset(); + iPackageId = pPackageTransferType->PackageIdL(); + __LOG1("CSBEDecompressAndEncrypt::SetGenericTransferTypeL() - Package ID 0x%08x", iPackageId.iUid); + iType = EPackage; + } + + CleanupStack::PopAndDestroy(pPackageTransferType); + } // else if + else + { + __LOG("CSBEDecompressAndEncrypt::SetGenericTransferTypeL() - DerivedType not supported"); + User::Leave(KErrNotSupported); + } // else +#endif + __LOG("CSBEDecompressAndEncrypt::SetGenericTransferTypeL() - END"); + } + + void CSBEDecompressAndEncrypt::Reset() + /** Resets the data + */ + { + __LOG("CSBEDecompressAndEncrypt::Reset()"); + iCount = 0; + iType = ENotSet; + iDoDecrypt = EFalse; + iCurrentPtr.Set(NULL, 0, 0); + iGotCompressionHeader = EFalse; + iCompressionSizeRead = 0; + iEncryptionSizeRead = 0; + iDoneDecompression = EFalse; + iGotCipher = EFalse; + delete iBuffer; + iBuffer = NULL; + } + + void CSBEDecompressAndEncrypt::MoveAlongL(TPtr8& aPtr, TInt aAmount) + /** Move a pointer along a given amount + + @param aPtr pointer to move + @param aAmount amount to move + */ + { + TInt newSize = aPtr.Size() - aAmount; + // Check + if (newSize < 0) + { + __LOG("CSBEDecompressAndEncrypt::MoveAlong() - Overflow"); + User::Leave(KErrOverflow); + } + + aPtr.Set(const_cast(aPtr.Ptr()) + aAmount, newSize, newSize); + } + + TBool CSBEDecompressAndEncrypt::NextLC(HBufC8*& apOutput, TBool& aMoreData) + /** Decompress a block of the data + + @param apOutput on return the next block of uncompressed data. This must be deleted by the caller. + @param aMoreData is there more data left in the compressed block. + */ + { + __LOG("CSBEDecompressAndEncrypt::NextLC() - START"); +#ifndef TURN_OFF_COMPRESSION_AND_ENCRYPTION + if (!iGotCipher) + { + iGotCipher = CreateCipherL(); + if (!iGotCipher) + { + return EFalse; + } // if + } + + if (!iGotCompressionHeader) + { + __LOG("CSBEDecompressAndEncrypt::NextLC - No Header read yet"); + + // Determine how much data we need to read to complete the header + TInt dataAvail = iCurrentPtr.Size(); + if (iCompressionSizeRead + dataAvail > sizeof(TCompressionHeader)) + { + dataAvail = sizeof(TCompressionHeader) - iCompressionSizeRead; + } + + // Read data into header + ReadL(iCompressionHeader, iCurrentPtr, iCompressionSizeRead, dataAvail); + MoveAlongL(iCurrentPtr, dataAvail); + iCompressionSizeRead += dataAvail; + iCount += dataAvail; + + if (iCompressionSizeRead < sizeof(TCompressionHeader)) + { + __LOG1("CSBEDecompressAndEncrypt::NextLC - Got partial compression header (%d bytes)",iCompressionSizeRead ); + return EFalse; + } + + __LOG2("CSBEDecompressAndEncrypt::NextLC - Got compression header (compressed size=%d, uncompressed=%d)", + iCompressionHeader.iCompressedSize, iCompressionHeader.iUncompressedSize); + + // Was the header encrypted? + if (iEncryptionHeader.iEncrypted) + { + __LOG("CSBEDecompressAndEncrypt::NextLC - Header Encrypted!"); + TCompressionHeader compressionHeader; + TPtr8 inData(reinterpret_cast(&iCompressionHeader), sizeof(TCompressionHeader), sizeof(TCompressionHeader)); + TPtr8 outData(reinterpret_cast(&compressionHeader), 0, sizeof(TCompressionHeader)); + + iCipher->Process(inData, outData); + iCompressionHeader = compressionHeader; + __LOG2("CSBEDecompressAndEncrypt::NextLC - unencrypted header, compressed size %d, uncompressed %d", iCompressionHeader.iCompressedSize, iCompressionHeader.iUncompressedSize); + } + + iCompressionSizeRead = 0; + iGotCompressionHeader = ETrue; + } // if + + // Check the compression header is sensible + if ((iCompressionHeader.iCompressedSize < 0) || + (iCompressionHeader.iUncompressedSize < 0) || + (iCompressionHeader.iCompressedSize >= KMaxHeapSize) || + (iCompressionHeader.iUncompressedSize >= KMaxHeapSize)) + { + __LOG("CSBEDecompressAndEncrypt::NextLC() - Compression header is corrupt"); + User::Leave(KErrCorrupt); + } + + if (!iDoneDecompression) + { + // Do we have enough data to decompress? + TInt dataSize = iCurrentPtr.Size(); + __LOG1("CSBEDecompressAndEncrypt::NextLC() - Doing Decompression - data size %d", dataSize); + if (iBuffer != NULL) + { + dataSize += iBuffer->Size(); + __LOG1("CSBEDecompressAndEncrypt::NextLC() - iBuffer not NULL new data size %d", dataSize) + } + if (dataSize < iCompressionHeader.iCompressedSize) + { + __LOG("CSBEDecompressAndEncrypt::NextLC() - data size < compressed size"); + // Need to buffer the buffer + if (iBuffer == NULL) + { + __LOG1("CSBEDecompressAndEncrypt::NextLC() - Creating internal buffer of size %d",iCompressionHeader.iCompressedSize); + iBuffer = HBufC8::NewL(iCompressionHeader.iCompressedSize); + } + + iBuffer->Des().Append(const_cast(iCurrentPtr.Ptr()), iCurrentPtr.Size()); + __LOG("CSBEDecompressAndEncrypt::NextLC() - Appending data to internal buffer"); + return EFalse; + } // if + + // Do we have a buffer? + TPtr8 inData(NULL, 0); + TInt toAppend = 0; + if (iBuffer != NULL) + { + __LOG("CSBEDecompressAndEncrypt::NextLC() - Preparing inData from internal buffer"); + toAppend = iCompressionHeader.iCompressedSize - iBuffer->Des().Size(); + iBuffer->Des().Append(const_cast(iCurrentPtr.Ptr()), toAppend); + + inData.Set(const_cast(iBuffer->Des().Ptr()), iBuffer->Des().Size(), iBuffer->Des().Size()); + } // if + else + { + __LOG("CSBEDecompressAndEncrypt::NextLC() - Preparing inData"); + inData.Set(const_cast(iCurrentPtr.Ptr()), iCompressionHeader.iCompressedSize, iCompressionHeader.iCompressedSize); + } // else + + // Uncompress + Decrypt the buffer + apOutput = HBufC8::NewLC(iCompressionHeader.iUncompressedSize); + __LOG1("CSBEDecompressAndEncrypt::NextLC() - Allocated Output data for uncompressed data of size %d", iCompressionHeader.iUncompressedSize); + if (iEncryptionHeader.iEncrypted) + { + __LOG("CSBEDecompressAndEncrypt::NextLC() Encrypted data, trying to allocate temp"); + // Need another temp buffer + HBufC8* temp = HBufC8::NewLC(iCompressionHeader.iCompressedSize); + + // Decrypt + TPtr8 ptrTemp = temp->Des(); + iCipher->Process(inData, ptrTemp); + // Decompress + TPtr8 ptrOutput = apOutput->Des(); + CEZDecompressor::DecompressL(ptrOutput, ptrTemp); + + // Cleanup + CleanupStack::PopAndDestroy(temp); + __LOG("CSBEDecompressAndEncrypt::NextLC() Decryption and decompresson done"); + } // if + else + { + // Decompress + TPtr8 ptrOutput = apOutput->Des(); + CEZDecompressor::DecompressL(ptrOutput, inData); + __LOG("CSBEDecompressAndEncrypt::NextLC() decompresson done"); + } // else + + iCount += iCompressionHeader.iCompressedSize; + if (toAppend != 0) + { + MoveAlongL(iCurrentPtr, toAppend); + } + else + { + MoveAlongL(iCurrentPtr, iCompressionHeader.iCompressedSize); + } + + delete iBuffer; + iBuffer = NULL; + + iDoneDecompression = ETrue; + } // if + + __LOG2("CSBEDecompressAndEncrypt::NextLC() - encryption buffer done %d of %d", iCount, iEncryptionHeader.iTotalSize); + + // If the entire encrypted block has been read, prepare to read the next one + if (iCount >= iEncryptionHeader.iTotalSize) + { + iGotCipher = EFalse; + iEncryptionSizeRead = 0; + iCount = 0; + } + + // Is there more data available? + if (iCurrentPtr.Size() == 0) + { + Reset(); + aMoreData = EFalse; + } + else + { + aMoreData = ETrue; + } + + // Prepare to read the next compressed block + iGotCompressionHeader = EFalse; + iCompressionSizeRead = 0; + iDoneDecompression = EFalse; + +#else + TInt size = g_CompressionBlockSize; + if (size > iCurrentPtr.Size()) + { + size = iCurrentPtr.Size(); + } // if + + apOutput = HBufC8::NewLC(size); + apOutput->Des().Append(iCurrentPtr.Ptr(), size); + MoveAlong(iCurrentPtr, size); + + // Is there more data available? + if (iCurrentPtr.Size() == 0) + { + aMoreData = EFalse; + } + else + { + aMoreData = ETrue; + } +#endif + __LOG("CSBEDecompressAndEncrypt::NextLC() - END"); + return ETrue; + } + + TBool CSBEDecompressAndEncrypt::CreateCipherL() + /** + Creates the cipher to to use in decryption. + + @return ETrue if cipher created, otherwise EFalse. + */ + { + __LOG("CSBEDecompressAndEncrypt::CreateCipherL() - START"); + + TInt dataAvail = iCurrentPtr.Size(); + if (iEncryptionSizeRead + dataAvail > sizeof(TEncryptionHeader)) + { + dataAvail = sizeof(TEncryptionHeader) - iEncryptionSizeRead; + } + + // Read data into header + ReadL(iEncryptionHeader, iCurrentPtr, iEncryptionSizeRead, dataAvail); + MoveAlongL(iCurrentPtr, dataAvail); + iEncryptionSizeRead += dataAvail; + iCount += dataAvail; + + if (iEncryptionSizeRead < sizeof(TEncryptionHeader)) + { + __LOG1("CSBEDecompressAndEncrypt::CreateCipherL - Got partial encryption header (%d bytes)",iEncryptionSizeRead); + return EFalse; + } + + __LOG3("CSBEDecompressAndEncrypt::CreateCipherL - Got encryption header (encrypted=%d, buffer size=%d, total size=%d)", + iEncryptionHeader.iEncrypted, iEncryptionHeader.iBufferSize, iEncryptionHeader.iTotalSize); + + // Check we have a sensible encryption header + if ((iEncryptionHeader.iBufferSize < 0) || + (iEncryptionHeader.iTotalSize < 0)) + { + __LOG("CSBEDecompressAndEncrypt::CreateCipherL() - Corrupt data"); + User::Leave(KErrCorrupt); + } + if (iEncryptionHeader.iEncrypted) + { + // Get the decryption key + CSecureBUREncryptKeySource* keySource = CSecureBUREncryptKeySource::NewL(); + CleanupStack::PushL(keySource); + + HBufC* alignedBuffer = HBufC::NewLC(iEncryptionHeader.iBufferSize); + TBool gotBuffer = (iEncryptionHeader.iBufferSize > 0); + if (gotBuffer) + { + TUint8* in = reinterpret_cast(const_cast(alignedBuffer->Des().Ptr())); + TUint8* out = const_cast(iCurrentPtr.Ptr()); + + for (TInt x = 0; x < iEncryptionHeader.iBufferSize; x++) + { + in[x] = out[x]; + } // for x + alignedBuffer->Des().SetLength(iEncryptionHeader.iBufferSize / KCharWidthInBytes); + } + + TBuf8 key; + TBool gotKey = EFalse; + TPtr16 ptrAlignedBuffer(alignedBuffer->Des()); + keySource->GetRestoreKeyL(iDriveNumber, iSecureId, gotBuffer, ptrAlignedBuffer, gotKey, key); + if (!gotKey) + { + User::Leave(KErrCorrupt); + } + + // Create the cipher + if (iCipher) + { + delete iCipher; + iCipher = NULL; + } + iCipher = CARC4::NewL(key); + + // Cleanup + CleanupStack::PopAndDestroy(alignedBuffer); + CleanupStack::PopAndDestroy(keySource); + } // if + + // Set iCount + iCount += iEncryptionHeader.iBufferSize; + // Move current pointer along + MoveAlongL(iCurrentPtr, iEncryptionHeader.iBufferSize); + __LOG("CSBEDecompressAndEncrypt::CreateCipherL() - END"); + return ETrue; + } + + } + +