cryptoplugins/cryptospiplugins/source/softwarecrypto/rc2impl.cpp
changeset 19 cd501b96611d
equal deleted inserted replaced
15:da2ae96f639b 19:cd501b96611d
       
     1 /*
       
     2 * Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     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".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "rc2impl.h"
       
    20 #include "keys.h"
       
    21 
       
    22 #include "rc2table.h"
       
    23 #include "common/inlines.h"
       
    24 #include "pluginconfig.h"
       
    25 #include "symmetriccipherimpl.h"
       
    26 #include <cryptostrength.h>
       
    27 
       
    28 using namespace SoftwareCrypto;
       
    29 
       
    30 CRc2Impl::CRc2Impl(
       
    31 	TUid aCryptoMode,
       
    32 	TUid aOperationMode,
       
    33 	TUid aPadding) :
       
    34 	CSymmetricBlockCipherImpl(KRc2BlockBytes, aCryptoMode, aOperationMode, aPadding)
       
    35 	{
       
    36 	}
       
    37 
       
    38 CRc2Impl* CRc2Impl::NewL(
       
    39 	const CKey& aKey,
       
    40 	TUid aCryptoMode,
       
    41 	TUid aOperationMode,
       
    42 	TUid aPadding,
       
    43 	TInt aEffectiveKeyLenBits)	
       
    44 	{
       
    45 	CRc2Impl* self = CRc2Impl::NewLC(aKey, aCryptoMode, aOperationMode, aPadding, aEffectiveKeyLenBits);
       
    46 	CleanupStack::Pop(self);
       
    47 	return self;
       
    48 	}
       
    49 	
       
    50 CRc2Impl* CRc2Impl::NewLC(
       
    51 	const CKey& aKey,
       
    52 	TUid aCryptoMode,
       
    53 	TUid aOperationMode,
       
    54 	TUid aPadding,
       
    55 	TInt aEffectiveKeyLenBits)
       
    56 	{
       
    57 	CRc2Impl* self = new(ELeave) CRc2Impl(aCryptoMode, aOperationMode, aPadding);
       
    58 	CleanupStack::PushL(self);
       
    59 	self->ConstructL(aKey, aEffectiveKeyLenBits);
       
    60 	
       
    61 	const TDesC8& keyContent = aKey.GetTDesC8L(KSymmetricKeyParameterUid);
       
    62 	TCrypto::IsSymmetricWeakEnoughL(BytesToBits(keyContent.Size()) - keyContent.Size());
       
    63 	return self;
       
    64 	}
       
    65 		
       
    66 CRc2Impl::~CRc2Impl()
       
    67 	{
       
    68 	Mem::FillZ(&iK, sizeof(iK));
       
    69 	}
       
    70 	
       
    71 void CRc2Impl::ConstructL(const CKey& aKey, TInt aEffectiveKeyLenBits)	
       
    72 	{
       
    73 	iEffectiveKeyLenBits = aEffectiveKeyLenBits;	
       
    74 	CSymmetricBlockCipherImpl::ConstructL(aKey);
       
    75 	SetKeySchedule();
       
    76 	}
       
    77 	
       
    78 CExtendedCharacteristics* CRc2Impl::CreateExtendedCharacteristicsL()
       
    79 	{
       
    80 	// All Symbian software plug-ins have unlimited concurrency, cannot be reserved
       
    81 	// for exclusive use and are not CERTIFIED to be standards compliant.
       
    82 	return CExtendedCharacteristics::NewL(KMaxTInt, EFalse);
       
    83 	}
       
    84 
       
    85 const CExtendedCharacteristics* CRc2Impl::GetExtendedCharacteristicsL()
       
    86 	{
       
    87 	return CRc2Impl::CreateExtendedCharacteristicsL();
       
    88 	}
       
    89 
       
    90 TUid CRc2Impl::ImplementationUid() const
       
    91 	{
       
    92 	return KCryptoPluginRc2Uid;
       
    93 	}
       
    94 
       
    95 TBool CRc2Impl::IsValidKeyLength(TInt aKeyBytes) const
       
    96 	{
       
    97 	return ((aKeyBytes > 0 && aKeyBytes <= KRc2MaxKeySizeBytes) ? ETrue : EFalse);
       
    98 	}	
       
    99 	
       
   100 TInt CRc2Impl::GetKeyStrength() const
       
   101 	{
       
   102 	return Min(iEffectiveKeyLenBits, BytesToBits(iKeyBytes));
       
   103 	}
       
   104 
       
   105 void CRc2Impl::SetKeySchedule()
       
   106 	{				
       
   107 	TUint keyLen = iKey->Length();
       
   108 	
       
   109 	TUint8 L[KRc2MaxKeySizeBytes];	
       
   110 	Mem::Copy((TUint8*)&L[0], (TUint8*)&(*iKey)[0], keyLen);
       
   111 
       
   112 	TInt i = keyLen;
       
   113 	for (; i < KRc2MaxKeySizeBytes; i++)
       
   114 		{
       
   115 		L[i] = RC2_TABLE::PITABLE[(L[i-1] + L[i-keyLen]) & 255];
       
   116 		}
       
   117 
       
   118 	TUint T8 = (iEffectiveKeyLenBits+7) / 8;
       
   119 	TUint8 TM = (TUint8)(255 >> ((8-(iEffectiveKeyLenBits%8))%8));
       
   120 	L[128-T8] = RC2_TABLE::PITABLE[L[128-T8] & TM];
       
   121 
       
   122 	for (i=127-T8; i>=0; i--)
       
   123 		L[i] = RC2_TABLE::PITABLE[L[i+1] ^ L[i+T8]];
       
   124 
       
   125 	for (i=0; i < KRc2ExpandedKeyLen; i++)
       
   126 		iK[i] = (TUint16)(L[2*i] + (L[2*i+1] << 8));
       
   127 	}
       
   128 
       
   129 #pragma warning (disable : 4244)	//	conversion from 'int' to 'unsigned short', possible loss of data
       
   130 void CRc2Impl::TransformEncrypt(
       
   131 	TUint8* aBuffer,
       
   132 	TUint aNumBlocks)
       
   133 	{
       
   134 	for (TInt blockNum = 0; blockNum < aNumBlocks; ++blockNum)
       
   135 		{		
       
   136 		ModeEncryptStart(aBuffer);
       
   137 		
       
   138 		TUint16 R0, R1, R2, R3;
       
   139 		GetBlockLittleEndian(aBuffer, R0, R1, R2, R3);
       
   140 		
       
   141 		TInt i = 0;
       
   142 		for (; i < 16; i++)
       
   143 			{
       
   144 			R0 += (R1 & ~R3) + (R2 & R3) + iK[4*i+0];
       
   145 			R0 = rotlFixed(R0, 1);
       
   146 
       
   147 			R1 += (R2 & ~R0) + (R3 & R0) + iK[4*i+1];
       
   148 			R1 = rotlFixed(R1, 2);
       
   149 
       
   150 			R2 += (R3 & ~R1) + (R0 & R1) + iK[4*i+2];
       
   151 			R2 = rotlFixed(R2, 3);
       
   152 
       
   153 			R3 += (R0 & ~R2) + (R1 & R2) + iK[4*i+3];
       
   154 			R3 = rotlFixed(R3, 5);
       
   155 
       
   156 			if (i == 4 || i == 10)
       
   157 				{
       
   158 				R0 += iK[R3 & 63];
       
   159 				R1 += iK[R0 & 63];
       
   160 				R2 += iK[R1 & 63];
       
   161 				R3 += iK[R2 & 63];
       
   162 				}
       
   163 			}
       
   164 		PutBlockLittleEndian(aBuffer, R0, R1, R2, R3);	
       
   165 		ModeEncryptEnd(aBuffer);
       
   166 		aBuffer += KRc2BlockBytes;
       
   167 		}
       
   168 	}
       
   169 #pragma warning (default : 4244)	//	conversion from 'int' to 'unsigned short', possible loss of data
       
   170 
       
   171 
       
   172 #pragma warning (disable : 4244)	//	conversion from 'int' to 'unsigned short', possible loss of data
       
   173 void CRc2Impl::TransformDecrypt(
       
   174 	TUint8* aBuffer,
       
   175 	TUint aNumBlocks)
       
   176 	{
       
   177 	for (TInt blockNum = 0; blockNum < aNumBlocks; ++blockNum)
       
   178 		{		
       
   179 		ModeDecryptStart(aBuffer);
       
   180 
       
   181 		TUint16 R0, R1, R2, R3;
       
   182 		GetBlockLittleEndian(aBuffer, R0, R1, R2, R3);
       
   183 
       
   184 		TInt i = 15;
       
   185 		for (; i >= 0; i--)
       
   186 			{
       
   187 			if (i == 4 || i == 10)
       
   188 				{
       
   189 				R3 -= iK[R2 & 63];
       
   190 				R2 -= iK[R1 & 63];
       
   191 				R1 -= iK[R0 & 63];
       
   192 				R0 -= iK[R3 & 63];
       
   193 				}
       
   194 
       
   195 			R3 = rotrFixed(R3, 5);
       
   196 			R3 -= (R0 & ~R2) + (R1 & R2) + iK[4*i+3];
       
   197 
       
   198 			R2 = rotrFixed(R2, 3);
       
   199 			R2 -= (R3 & ~R1) + (R0 & R1) + iK[4*i+2];
       
   200 
       
   201 			R1 = rotrFixed(R1, 2);
       
   202 			R1 -= (R2 & ~R0) + (R3 & R0) + iK[4*i+1];
       
   203 
       
   204 			R0 = rotrFixed(R0, 1);
       
   205 			R0 -= (R1 & ~R3) + (R2 & R3) + iK[4*i+0];
       
   206 			}
       
   207 
       
   208 		PutBlockLittleEndian(aBuffer, R0, R1, R2, R3);
       
   209 		ModeDecryptEnd(aBuffer);
       
   210 		aBuffer += KRc2BlockBytes;
       
   211 		}
       
   212 	}
       
   213 #pragma warning (default : 4244)	//	conversion from 'int' to 'unsigned short', possible loss of data