1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/security/crypto/weakcryptospi/test/tplugins/src/desimpl.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,252 @@
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 "desimpl.h"
1.23 +
1.24 +#include "destables.h"
1.25 +#include "../../../source/common/inlines.h"
1.26 +#include "des.inl"
1.27 +#include "pluginconfig.h"
1.28 +#include "symmetriccipherimpl.h"
1.29 +#include <cryptostrength.h>
1.30 +
1.31 +
1.32 +// bit 0 is left-most in byte
1.33 +static const TInt bytebit[] = {0200,0100,040,020,010,04,02,01};
1.34 +
1.35 +using namespace SoftwareCrypto;
1.36 +
1.37 +/* CDesImpl */
1.38 +CDesImpl::CDesImpl(
1.39 + TUid aImplementationUid,
1.40 + TUint8 aBlockBytes,
1.41 + TUid aCryptoMode,
1.42 + TUid aOperationMode,
1.43 + TUid aPadding) :
1.44 + CSymmetricBlockCipherImpl(aBlockBytes, aCryptoMode, aOperationMode, aPadding),
1.45 + iImplementationUid(aImplementationUid)
1.46 + {
1.47 + }
1.48 +
1.49 +CDesImpl* CDesImpl::NewL(TUid aImplementationUid, const CKey& aKey, TUid aCryptoMode, TUid aOperationMode, TUid aPadding)
1.50 + {
1.51 + CDesImpl* self = CDesImpl::NewLC(aImplementationUid, aKey, aCryptoMode, aOperationMode, aPadding);
1.52 + CleanupStack::Pop(self);
1.53 + return self;
1.54 + }
1.55 +
1.56 +CDesImpl* CDesImpl::NewLC(TUid aImplementationUid, const CKey& aKey, TUid aCryptoMode, TUid aOperationMode, TUid aPadding)
1.57 + {
1.58 + CDesImpl* self = new(ELeave) CDesImpl(aImplementationUid, KDesBlockBytes, aCryptoMode, aOperationMode, aPadding);
1.59 + CleanupStack::PushL(self);
1.60 + self->ConstructL(aKey);
1.61 +
1.62 + const TDesC8& keyContent = aKey.GetTDesC8L(KSymmetricKeyParameterUid);
1.63 + TCrypto::IsSymmetricWeakEnoughL(BytesToBits(keyContent.Size()) - keyContent.Size());
1.64 + return self;
1.65 + }
1.66 +
1.67 +CDesImpl::~CDesImpl()
1.68 + {
1.69 + // make sure key information isn't visible to other processes if the
1.70 + // page is reused.
1.71 + Mem::FillZ(&iK, sizeof(iK));
1.72 + }
1.73 +
1.74 +void CDesImpl::ConstructL(const CKey& aKey)
1.75 + {
1.76 + CSymmetricBlockCipherImpl::ConstructL(aKey);
1.77 + SetKeySchedule();
1.78 + }
1.79 +
1.80 +CExtendedCharacteristics* CDesImpl::CreateExtendedCharacteristicsL()
1.81 + {
1.82 + // All Symbian software plug-ins have unlimited concurrency, cannot be reserved
1.83 + // for exclusive use and are not CERTIFIED to be standards compliant.
1.84 +
1.85 + return CExtendedCharacteristics::NewL(KMaxTInt, EFalse);
1.86 + }
1.87 +
1.88 +const CExtendedCharacteristics* CDesImpl::GetExtendedCharacteristicsL()
1.89 + {
1.90 + return CDesImpl::CreateExtendedCharacteristicsL();
1.91 + }
1.92 +
1.93 +TUid CDesImpl::ImplementationUid() const
1.94 + {
1.95 + return iImplementationUid;
1.96 + }
1.97 +
1.98 +TBool CDesImpl::IsValidKeyLength(TInt aKeyBytes) const
1.99 + {
1.100 + return (aKeyBytes == KDesKeyBytes);
1.101 + }
1.102 +
1.103 +TInt CDesImpl::GetKeyStrength() const
1.104 + {
1.105 + // parity bits are excluded
1.106 + return BytesToBits(KDesKeyBytes - 8);
1.107 + }
1.108 +
1.109 +void CDesImpl::TransformEncrypt(
1.110 + TUint8* aBuffer,
1.111 + TUint aNumBlocks)
1.112 + {
1.113 + for (TInt i = 0; i < aNumBlocks; ++i)
1.114 + {
1.115 + ModeEncryptStart(aBuffer);
1.116 + TUint32 l, r;
1.117 + // Split the block into 2 word-sized big endian portions
1.118 + GetBlockBigEndian(aBuffer, l, r);
1.119 + IPerm(l,r);
1.120 + DoTransform(l, r, iK);
1.121 + FPerm(l,r);
1.122 +
1.123 + // Put the portions back into the block as little endian
1.124 + PutBlockBigEndian(aBuffer, r, l);
1.125 +
1.126 + ModeEncryptEnd(aBuffer);
1.127 + aBuffer += KDesBlockBytes;
1.128 + }
1.129 + }
1.130 +
1.131 +void CDesImpl::TransformDecrypt(
1.132 + TUint8* aBuffer,
1.133 + TUint aNumBlocks)
1.134 + {
1.135 + for (TInt i = 0; i < aNumBlocks; ++i)
1.136 + {
1.137 + ModeDecryptStart(aBuffer);
1.138 +
1.139 + TUint32 l, r;
1.140 + // Split the block into 2 word-sized big endian portions
1.141 + GetBlockBigEndian(aBuffer, l, r);
1.142 +
1.143 + IPerm(l,r);
1.144 + DoTransform(l, r, iK);
1.145 + FPerm(l,r);
1.146 +
1.147 + // Put the portions back into the block as little endian
1.148 + PutBlockBigEndian(aBuffer, r, l);
1.149 +
1.150 + ModeDecryptEnd(aBuffer);
1.151 + aBuffer += KDesBlockBytes;
1.152 + }
1.153 + }
1.154 +
1.155 +void CDesImpl::SetKeySchedule()
1.156 + {
1.157 + if (iCryptoMode.iUid == KCryptoModeEncrypt)
1.158 + {
1.159 + SetEncryptKeySchedule(*iKey, iK);
1.160 + }
1.161 + else
1.162 + {
1.163 + ASSERT(iCryptoMode.iUid == KCryptoModeDecrypt);
1.164 + SetDecryptKeySchedule(*iKey, iK);
1.165 + }
1.166 + }
1.167 +
1.168 +void CDesImpl::DoTransform(TUint32& l, TUint32& r, const TUint32* aKeySchedule)
1.169 + {
1.170 + TInt i = 0;
1.171 + for (; i<8; i++)
1.172 + {
1.173 + TUint32 work = rotrFixed(r, 4U) ^ aKeySchedule[4*i+0];
1.174 + l ^= DES_TABLE::sbox[6][(work) & 0x3f]
1.175 + ^ DES_TABLE::sbox[4][(work >> 8) & 0x3f]
1.176 + ^ DES_TABLE::sbox[2][(work >> 16) & 0x3f]
1.177 + ^ DES_TABLE::sbox[0][(work >> 24) & 0x3f];
1.178 + work = r ^ aKeySchedule[4*i+1];
1.179 + l ^= DES_TABLE::sbox[7][(work) & 0x3f]
1.180 + ^ DES_TABLE::sbox[5][(work >> 8) & 0x3f]
1.181 + ^ DES_TABLE::sbox[3][(work >> 16) & 0x3f]
1.182 + ^ DES_TABLE::sbox[1][(work >> 24) & 0x3f];
1.183 +
1.184 + work = rotrFixed(l, 4U) ^ aKeySchedule[4*i+2];
1.185 + r ^= DES_TABLE::sbox[6][(work) & 0x3f]
1.186 + ^ DES_TABLE::sbox[4][(work >> 8) & 0x3f]
1.187 + ^ DES_TABLE::sbox[2][(work >> 16) & 0x3f]
1.188 + ^ DES_TABLE::sbox[0][(work >> 24) & 0x3f];
1.189 + work = l ^ aKeySchedule[4*i+3];
1.190 + r ^= DES_TABLE::sbox[7][(work) & 0x3f]
1.191 + ^ DES_TABLE::sbox[5][(work >> 8) & 0x3f]
1.192 + ^ DES_TABLE::sbox[3][(work >> 16) & 0x3f]
1.193 + ^ DES_TABLE::sbox[1][(work >> 24) & 0x3f];
1.194 + }
1.195 + }
1.196 +
1.197 +void CDesImpl::SetEncryptKeySchedule(const TDesC8& aKey, TUint32* aKeySchedule)
1.198 + {
1.199 + TInt i=0, j=0, l=0, m=0;
1.200 +
1.201 +// Form a byte array from aKey, taking endianess into account (little->big)
1.202 + TUint8 key[8]; // For big endian byte array
1.203 + Mem::Copy(&key, &aKey[0], 8);
1.204 +
1.205 + TUint8 buffer[56+56+8];
1.206 + TUint8* const pc1m = &buffer[0]; /* place to modify pc1 into */
1.207 + TUint8* const pcr = pc1m + 56; /* place to rotate pc1 into */
1.208 + TUint8* const ks = pcr + 56;
1.209 +
1.210 + for (j=0; j<56; j++)
1.211 + {/* convert pc1 to bits of key */
1.212 + l = DES_TABLE::pc1[j]-1; /* integer bit location */
1.213 + m = l & 07; /* find bit */
1.214 + pc1m[j]=(key[l>>3] & /* find which key byte l is in */
1.215 + bytebit[m]) /* and which bit of that byte */
1.216 + ? (TUint8)1 : (TUint8)0; /* and store 1-bit result */
1.217 + }
1.218 +
1.219 + for (i=0; i<16; i++)
1.220 + {/* key chunk for each iteration */
1.221 + Mem::FillZ(ks,8); /* Clear key schedule */
1.222 + for (j=0; j<56; j++)
1.223 + /* rotate pc1 the right amount */
1.224 + pcr[j] = pc1m[(l=j+DES_TABLE::totrot[i])<(j<28? 28 : 56) ? l: l-28];
1.225 +
1.226 + /* rotate left and right halves independently */
1.227 +
1.228 + for (j=0; j<48; j++)
1.229 + {/* select bits individually */
1.230 + /* check bit that goes to ks[j] */
1.231 + if (pcr[DES_TABLE::pc2[j]-1])
1.232 + {/* mask it in if it's there */
1.233 + l= j % 6;
1.234 + ks[j/6] |= bytebit[l] >> 2;
1.235 + }
1.236 + }
1.237 +
1.238 + /* Now convert to odd/even interleaved form for use in F */
1.239 + (*(aKeySchedule+(2*i))) = ((TUint32)ks[0] << 24)
1.240 + | ((TUint32)ks[2] << 16)
1.241 + | ((TUint32)ks[4] << 8)
1.242 + | ((TUint32)ks[6]);
1.243 +
1.244 + (*(aKeySchedule+(2*i+1))) = ((TUint32)ks[1] << 24)
1.245 + | ((TUint32)ks[3] << 16)
1.246 + | ((TUint32)ks[5] << 8)
1.247 + | ((TUint32)ks[7]);
1.248 + }
1.249 + }
1.250 +
1.251 +void CDesImpl::SetDecryptKeySchedule(const TDesC8& aKey, TUint32* aKeySchedule)
1.252 + {
1.253 + SetEncryptKeySchedule(aKey, aKeySchedule);
1.254 + ReverseKeySchedule(aKeySchedule);
1.255 + }