cryptoplugins/cryptospiplugins/source/softwarecrypto/3desimpl.cpp
changeset 19 cd501b96611d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cryptoplugins/cryptospiplugins/source/softwarecrypto/3desimpl.cpp	Fri Nov 06 13:21:00 2009 +0200
@@ -0,0 +1,190 @@
+/*
+* Copyright (c) 2006-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 "3desimpl.h"
+
+#include "destables.h"
+#include "common/inlines.h"
+#include "des.inl"
+#include "pluginconfig.h"
+#include "symmetriccipherimpl.h"
+#include <cryptostrength.h>
+
+using namespace SoftwareCrypto;
+
+/* C3DesImpl */
+C3DesImpl::C3DesImpl(
+	TUid aCryptoMode,
+	TUid aOperationMode,
+	TUid aPadding) :
+	CDesImpl(KDesBlockBytes, aCryptoMode, aOperationMode, aPadding)
+	{
+	}
+
+C3DesImpl* C3DesImpl::NewL(const CKey& aKey, TUid aCryptoMode, TUid aOperationMode, TUid aPadding)
+	{
+	C3DesImpl* self = C3DesImpl::NewLC(aKey, aCryptoMode, aOperationMode, aPadding);
+	CleanupStack::Pop(self);
+	return self;
+	}
+	
+C3DesImpl* C3DesImpl::NewLC(const CKey& aKey, TUid aCryptoMode, TUid aOperationMode, TUid aPadding)
+	{
+	C3DesImpl* self = new(ELeave) C3DesImpl(aCryptoMode, aOperationMode, aPadding);
+	CleanupStack::PushL(self);
+	self->ConstructL(aKey);
+
+	const TDesC8& keyContent = aKey.GetTDesC8L(KSymmetricKeyParameterUid);
+	TCrypto::IsSymmetricWeakEnoughL(BytesToBits(keyContent.Size()) - keyContent.Size());
+	return self;
+	}
+		
+C3DesImpl::~C3DesImpl()
+	{
+	// make sure key information isn't visible to other processes if the
+	// page is reused.
+	Mem::FillZ(&iK1, sizeof(iK1));
+	Mem::FillZ(&iK2, sizeof(iK2));
+	Mem::FillZ(&iK3, sizeof(iK3));
+	}
+	
+void C3DesImpl::ConstructL(const CKey& aKey)
+	{
+	CDesImpl::ConstructL(aKey);
+	SetKeySchedule();
+	}	
+	
+CExtendedCharacteristics* C3DesImpl::CreateExtendedCharacteristicsL()
+	{
+	// All Symbian software plug-ins have unlimited concurrency, cannot be reserved
+	// for exclusive use and are not CERTIFIED to be standards compliant.
+	return CExtendedCharacteristics::NewL(KMaxTInt, EFalse);
+	}
+	
+const CExtendedCharacteristics* C3DesImpl::GetExtendedCharacteristicsL()
+	{
+	return C3DesImpl::CreateExtendedCharacteristicsL();
+	}
+
+TUid C3DesImpl::ImplementationUid() const
+	{
+	return KCryptoPlugin3DesUid;
+	}
+	
+TBool C3DesImpl::IsValidKeyLength(TInt aKeyBytes) const
+	{
+	return (aKeyBytes == K3DesKeyBytes);
+	}
+	
+TInt C3DesImpl::GetKeyStrength() const
+	{
+	// Exclude parity bits from each subkey
+	return BytesToBits(K3DesKeyBytes - (3 * 8));
+	}	
+	
+void C3DesImpl::TransformEncrypt(
+	TUint8* aBuffer,
+	TUint aNumBlocks)
+	{			
+	for (TInt i = 0; i < aNumBlocks; ++i)
+		{		
+		ModeEncryptStart(aBuffer);
+
+		TUint32 l, r;
+		// Split the block into 2 word-sized big endian portions
+		GetBlockBigEndian(aBuffer, l, r);
+
+		IPerm(l,r);
+		// The mode is applied to the entire operation and NOT 
+		// for each DES transform
+		TUid opMode = iOperationMode;
+		iOperationMode = KOperationModeECBUid;
+		DoTransform(l, r, iK1);
+		DoTransform(r, l, iK2);
+		DoTransform(l, r, iK3);
+		iOperationMode = opMode;
+		FPerm(l,r);
+
+		// Put the portions back into the block as little endian
+		PutBlockBigEndian(aBuffer, r, l);
+		ModeEncryptEnd(aBuffer);
+		aBuffer += KDesBlockBytes;
+		}
+	}
+	
+void C3DesImpl::TransformDecrypt(
+	TUint8* aBuffer,
+	const TUint aNumBlocks)
+	{	
+	for (TInt i = 0; i < aNumBlocks; ++i)
+		{		
+		ModeDecryptStart(aBuffer);
+			
+		TUint32 l, r;
+		// Split the block into 2 word-sized big endian portions
+		GetBlockBigEndian(aBuffer, l, r);
+
+		IPerm(l,r);
+		
+		// The mode is applied to the entire operation and NOT 
+		// for each DES transform
+		TUid opMode = iOperationMode;
+		iOperationMode = KOperationModeECBUid;
+		DoTransform(l, r, iK1);
+		DoTransform(r, l, iK2);
+		DoTransform(l, r, iK3);
+		iOperationMode = opMode;
+		FPerm(l,r);
+
+		// Put the portions back into the block as little endian
+		PutBlockBigEndian(aBuffer, r, l);	
+		ModeDecryptEnd(aBuffer);
+		aBuffer += K3DesBlockBytes;
+		}
+	}	
+
+void C3DesImpl::SetKeySchedule()
+	{
+	if (iCryptoMode.iUid == KCryptoModeEncrypt)
+		{
+		// Encrypt -> Decrypt -> Encrypt
+		// Encryptor key	
+		SetEncryptKeySchedule(iKey->Mid(0, KDesKeyBytes), iK1);
+		
+		// Decryptor key
+		SetDecryptKeySchedule(iKey->Mid(KDesKeyBytes, 2 * KDesKeyBytes), iK2);
+		
+		// Encryptor key
+		SetEncryptKeySchedule(iKey->Mid(2 * KDesKeyBytes), iK3);
+		}
+	else 
+		{
+		// Decrypt -> Encrypt -> Decrypt
+		// Key order is reversed !
+		
+		ASSERT(iCryptoMode.iUid == KCryptoModeDecrypt);
+		// Decryptor key	
+		SetDecryptKeySchedule(iKey->Mid(0, KDesKeyBytes), iK3);
+		
+		// Encryptor key
+		SetEncryptKeySchedule(iKey->Mid(KDesKeyBytes, 2 * KDesKeyBytes), iK2);
+		
+		// Decryptor key
+		SetDecryptKeySchedule(iKey->Mid(2 * KDesKeyBytes), iK1);
+		}	
+	}