os/security/cryptoplugins/cryptospiplugins/source/softwarecrypto/rc2impl.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     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