1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/security/cryptoplugins/cryptospiplugins/source/softwarecrypto/rc2impl.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,213 @@
1.4 +/*
1.5 +* Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
1.6 +* All rights reserved.
1.7 +* This component and the accompanying materials are made available
1.8 +* under the terms of the License "Eclipse Public License v1.0"
1.9 +* which accompanies this distribution, and is available
1.10 +* at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.11 +*
1.12 +* Initial Contributors:
1.13 +* Nokia Corporation - initial contribution.
1.14 +*
1.15 +* Contributors:
1.16 +*
1.17 +* Description:
1.18 +*
1.19 +*/
1.20 +
1.21 +
1.22 +#include "rc2impl.h"
1.23 +#include "keys.h"
1.24 +
1.25 +#include "rc2table.h"
1.26 +#include "common/inlines.h"
1.27 +#include "pluginconfig.h"
1.28 +#include "symmetriccipherimpl.h"
1.29 +#include <cryptostrength.h>
1.30 +
1.31 +using namespace SoftwareCrypto;
1.32 +
1.33 +CRc2Impl::CRc2Impl(
1.34 + TUid aCryptoMode,
1.35 + TUid aOperationMode,
1.36 + TUid aPadding) :
1.37 + CSymmetricBlockCipherImpl(KRc2BlockBytes, aCryptoMode, aOperationMode, aPadding)
1.38 + {
1.39 + }
1.40 +
1.41 +CRc2Impl* CRc2Impl::NewL(
1.42 + const CKey& aKey,
1.43 + TUid aCryptoMode,
1.44 + TUid aOperationMode,
1.45 + TUid aPadding,
1.46 + TInt aEffectiveKeyLenBits)
1.47 + {
1.48 + CRc2Impl* self = CRc2Impl::NewLC(aKey, aCryptoMode, aOperationMode, aPadding, aEffectiveKeyLenBits);
1.49 + CleanupStack::Pop(self);
1.50 + return self;
1.51 + }
1.52 +
1.53 +CRc2Impl* CRc2Impl::NewLC(
1.54 + const CKey& aKey,
1.55 + TUid aCryptoMode,
1.56 + TUid aOperationMode,
1.57 + TUid aPadding,
1.58 + TInt aEffectiveKeyLenBits)
1.59 + {
1.60 + CRc2Impl* self = new(ELeave) CRc2Impl(aCryptoMode, aOperationMode, aPadding);
1.61 + CleanupStack::PushL(self);
1.62 + self->ConstructL(aKey, aEffectiveKeyLenBits);
1.63 +
1.64 + const TDesC8& keyContent = aKey.GetTDesC8L(KSymmetricKeyParameterUid);
1.65 + TCrypto::IsSymmetricWeakEnoughL(BytesToBits(keyContent.Size()) - keyContent.Size());
1.66 + return self;
1.67 + }
1.68 +
1.69 +CRc2Impl::~CRc2Impl()
1.70 + {
1.71 + Mem::FillZ(&iK, sizeof(iK));
1.72 + }
1.73 +
1.74 +void CRc2Impl::ConstructL(const CKey& aKey, TInt aEffectiveKeyLenBits)
1.75 + {
1.76 + iEffectiveKeyLenBits = aEffectiveKeyLenBits;
1.77 + CSymmetricBlockCipherImpl::ConstructL(aKey);
1.78 + SetKeySchedule();
1.79 + }
1.80 +
1.81 +CExtendedCharacteristics* CRc2Impl::CreateExtendedCharacteristicsL()
1.82 + {
1.83 + // All Symbian software plug-ins have unlimited concurrency, cannot be reserved
1.84 + // for exclusive use and are not CERTIFIED to be standards compliant.
1.85 + return CExtendedCharacteristics::NewL(KMaxTInt, EFalse);
1.86 + }
1.87 +
1.88 +const CExtendedCharacteristics* CRc2Impl::GetExtendedCharacteristicsL()
1.89 + {
1.90 + return CRc2Impl::CreateExtendedCharacteristicsL();
1.91 + }
1.92 +
1.93 +TUid CRc2Impl::ImplementationUid() const
1.94 + {
1.95 + return KCryptoPluginRc2Uid;
1.96 + }
1.97 +
1.98 +TBool CRc2Impl::IsValidKeyLength(TInt aKeyBytes) const
1.99 + {
1.100 + return ((aKeyBytes > 0 && aKeyBytes <= KRc2MaxKeySizeBytes) ? ETrue : EFalse);
1.101 + }
1.102 +
1.103 +TInt CRc2Impl::GetKeyStrength() const
1.104 + {
1.105 + return Min(iEffectiveKeyLenBits, BytesToBits(iKeyBytes));
1.106 + }
1.107 +
1.108 +void CRc2Impl::SetKeySchedule()
1.109 + {
1.110 + TUint keyLen = iKey->Length();
1.111 +
1.112 + TUint8 L[KRc2MaxKeySizeBytes];
1.113 + Mem::Copy((TUint8*)&L[0], (TUint8*)&(*iKey)[0], keyLen);
1.114 +
1.115 + TInt i = keyLen;
1.116 + for (; i < KRc2MaxKeySizeBytes; i++)
1.117 + {
1.118 + L[i] = RC2_TABLE::PITABLE[(L[i-1] + L[i-keyLen]) & 255];
1.119 + }
1.120 +
1.121 + TUint T8 = (iEffectiveKeyLenBits+7) / 8;
1.122 + TUint8 TM = (TUint8)(255 >> ((8-(iEffectiveKeyLenBits%8))%8));
1.123 + L[128-T8] = RC2_TABLE::PITABLE[L[128-T8] & TM];
1.124 +
1.125 + for (i=127-T8; i>=0; i--)
1.126 + L[i] = RC2_TABLE::PITABLE[L[i+1] ^ L[i+T8]];
1.127 +
1.128 + for (i=0; i < KRc2ExpandedKeyLen; i++)
1.129 + iK[i] = (TUint16)(L[2*i] + (L[2*i+1] << 8));
1.130 + }
1.131 +
1.132 +#pragma warning (disable : 4244) // conversion from 'int' to 'unsigned short', possible loss of data
1.133 +void CRc2Impl::TransformEncrypt(
1.134 + TUint8* aBuffer,
1.135 + TUint aNumBlocks)
1.136 + {
1.137 + for (TInt blockNum = 0; blockNum < aNumBlocks; ++blockNum)
1.138 + {
1.139 + ModeEncryptStart(aBuffer);
1.140 +
1.141 + TUint16 R0, R1, R2, R3;
1.142 + GetBlockLittleEndian(aBuffer, R0, R1, R2, R3);
1.143 +
1.144 + TInt i = 0;
1.145 + for (; i < 16; i++)
1.146 + {
1.147 + R0 += (R1 & ~R3) + (R2 & R3) + iK[4*i+0];
1.148 + R0 = rotlFixed(R0, 1);
1.149 +
1.150 + R1 += (R2 & ~R0) + (R3 & R0) + iK[4*i+1];
1.151 + R1 = rotlFixed(R1, 2);
1.152 +
1.153 + R2 += (R3 & ~R1) + (R0 & R1) + iK[4*i+2];
1.154 + R2 = rotlFixed(R2, 3);
1.155 +
1.156 + R3 += (R0 & ~R2) + (R1 & R2) + iK[4*i+3];
1.157 + R3 = rotlFixed(R3, 5);
1.158 +
1.159 + if (i == 4 || i == 10)
1.160 + {
1.161 + R0 += iK[R3 & 63];
1.162 + R1 += iK[R0 & 63];
1.163 + R2 += iK[R1 & 63];
1.164 + R3 += iK[R2 & 63];
1.165 + }
1.166 + }
1.167 + PutBlockLittleEndian(aBuffer, R0, R1, R2, R3);
1.168 + ModeEncryptEnd(aBuffer);
1.169 + aBuffer += KRc2BlockBytes;
1.170 + }
1.171 + }
1.172 +#pragma warning (default : 4244) // conversion from 'int' to 'unsigned short', possible loss of data
1.173 +
1.174 +
1.175 +#pragma warning (disable : 4244) // conversion from 'int' to 'unsigned short', possible loss of data
1.176 +void CRc2Impl::TransformDecrypt(
1.177 + TUint8* aBuffer,
1.178 + TUint aNumBlocks)
1.179 + {
1.180 + for (TInt blockNum = 0; blockNum < aNumBlocks; ++blockNum)
1.181 + {
1.182 + ModeDecryptStart(aBuffer);
1.183 +
1.184 + TUint16 R0, R1, R2, R3;
1.185 + GetBlockLittleEndian(aBuffer, R0, R1, R2, R3);
1.186 +
1.187 + TInt i = 15;
1.188 + for (; i >= 0; i--)
1.189 + {
1.190 + if (i == 4 || i == 10)
1.191 + {
1.192 + R3 -= iK[R2 & 63];
1.193 + R2 -= iK[R1 & 63];
1.194 + R1 -= iK[R0 & 63];
1.195 + R0 -= iK[R3 & 63];
1.196 + }
1.197 +
1.198 + R3 = rotrFixed(R3, 5);
1.199 + R3 -= (R0 & ~R2) + (R1 & R2) + iK[4*i+3];
1.200 +
1.201 + R2 = rotrFixed(R2, 3);
1.202 + R2 -= (R3 & ~R1) + (R0 & R1) + iK[4*i+2];
1.203 +
1.204 + R1 = rotrFixed(R1, 2);
1.205 + R1 -= (R2 & ~R0) + (R3 & R0) + iK[4*i+1];
1.206 +
1.207 + R0 = rotrFixed(R0, 1);
1.208 + R0 -= (R1 & ~R3) + (R2 & R3) + iK[4*i+0];
1.209 + }
1.210 +
1.211 + PutBlockLittleEndian(aBuffer, R0, R1, R2, R3);
1.212 + ModeDecryptEnd(aBuffer);
1.213 + aBuffer += KRc2BlockBytes;
1.214 + }
1.215 + }
1.216 +#pragma warning (default : 4244) // conversion from 'int' to 'unsigned short', possible loss of data