1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/security/crypto/weakcrypto/source/symmetric/des.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,269 @@
1.4 +/*
1.5 +* Copyright (c) 2002-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 "des.h"
1.23 +#include "destables.h"
1.24 +#include "../common/inlines.h"
1.25 +#include "des.inl"
1.26 +#include <cryptostrength.h>
1.27 +
1.28 +const TInt KDESBlockBytes = 8;
1.29 +const TInt KDESKeyBytes = 8;
1.30 +
1.31 +// bit 0 is left-most in byte
1.32 +static const TInt bytebit[] = {0200,0100,040,020,010,04,02,01};
1.33 +
1.34 +void CDES::Transform(TDes8& aBlock)
1.35 + {
1.36 + assert(aBlock.Size() == KDESBlockBytes);
1.37 +
1.38 + TUint32 l, r;
1.39 + // Split the block into 2 word-sized big endian portions
1.40 + GetBlockBigEndian((TUint8*)&aBlock[0], l, r);
1.41 +
1.42 + IPerm(l,r);
1.43 +
1.44 + CDES::DoTransform(l, r, iK1);
1.45 +
1.46 + FPerm(l,r);
1.47 +
1.48 + // Put the portions back into the block as little endian
1.49 + PutBlockBigEndian((TUint8*)&aBlock[0], r, l);
1.50 + }
1.51 +
1.52 +void CDES::DoTransform(TUint32& l, TUint32& r, const TUint32* aKey)
1.53 + {
1.54 + TInt i = 0;
1.55 + for (; i<8; i++)
1.56 + {
1.57 + TUint32 work = rotrFixed(r, 4U) ^ aKey[4*i+0];
1.58 + l ^= DES_TABLE::sbox[6][(work) & 0x3f]
1.59 + ^ DES_TABLE::sbox[4][(work >> 8) & 0x3f]
1.60 + ^ DES_TABLE::sbox[2][(work >> 16) & 0x3f]
1.61 + ^ DES_TABLE::sbox[0][(work >> 24) & 0x3f];
1.62 + work = r ^ aKey[4*i+1];
1.63 + l ^= DES_TABLE::sbox[7][(work) & 0x3f]
1.64 + ^ DES_TABLE::sbox[5][(work >> 8) & 0x3f]
1.65 + ^ DES_TABLE::sbox[3][(work >> 16) & 0x3f]
1.66 + ^ DES_TABLE::sbox[1][(work >> 24) & 0x3f];
1.67 +
1.68 + work = rotrFixed(l, 4U) ^ aKey[4*i+2];
1.69 + r ^= DES_TABLE::sbox[6][(work) & 0x3f]
1.70 + ^ DES_TABLE::sbox[4][(work >> 8) & 0x3f]
1.71 + ^ DES_TABLE::sbox[2][(work >> 16) & 0x3f]
1.72 + ^ DES_TABLE::sbox[0][(work >> 24) & 0x3f];
1.73 + work = l ^ aKey[4*i+3];
1.74 + r ^= DES_TABLE::sbox[7][(work) & 0x3f]
1.75 + ^ DES_TABLE::sbox[5][(work >> 8) & 0x3f]
1.76 + ^ DES_TABLE::sbox[3][(work >> 16) & 0x3f]
1.77 + ^ DES_TABLE::sbox[1][(work >> 24) & 0x3f];
1.78 + }
1.79 + }
1.80 +
1.81 +
1.82 +TInt CDES::BlockSize() const
1.83 + {
1.84 + return KDESBlockBytes;
1.85 + }
1.86 +
1.87 +TInt CDES::KeySize() const
1.88 + {
1.89 + return KDESKeyBytes;
1.90 + }
1.91 +
1.92 +CDES::~CDES()
1.93 + {
1.94 + delete iKey;
1.95 + }
1.96 +
1.97 +void CDES::ConstructL(const TDesC8& aKey, TBool /*aCheckWeakKey*/)
1.98 + {
1.99 + assert(aKey.Size() == KDESKeyBytes);
1.100 +
1.101 + iKey = aKey.AllocL();
1.102 + SetKey(aKey, iK1);
1.103 + }
1.104 +
1.105 +CDES::CDES()
1.106 + {
1.107 + }
1.108 +
1.109 +typedef TUint8 TKeyDES[KDESKeyBytes];
1.110 +const TInt KKnownWeakKeysCount = 16;
1.111 +const TKeyDES weak_keys[KKnownWeakKeysCount] =
1.112 + {
1.113 + /* weak keys */
1.114 + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
1.115 + {0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE},
1.116 + {0x1E,0x1E,0x1E,0x1E,0x0E,0x0E,0x0E,0x0E},
1.117 + {0xE0,0xE0,0xE0,0xE0,0xF0,0xF0,0xF0,0xF0},
1.118 + {0x00,0xFE,0x00,0xFE,0x00,0xFE,0x00,0xFE},
1.119 + {0xFE,0x00,0xFE,0x00,0xFE,0x00,0xFE,0x00},
1.120 + {0x1E,0xE0,0x1E,0xE0,0x0E,0xF0,0x0E,0xF0},
1.121 + {0xE0,0x1E,0xE0,0x1E,0xF0,0x0E,0xF0,0x0E},
1.122 + {0x00,0xE0,0x00,0xE0,0x00,0xF0,0x00,0xF0},
1.123 + {0xE0,0x00,0xE0,0x00,0xF0,0x00,0xF0,0x00},
1.124 + {0x1E,0xFE,0x1E,0xFE,0x0E,0xFE,0x0E,0xFE},
1.125 + {0xFE,0x1E,0xFE,0x1E,0xFE,0x0E,0xFE,0x0E},
1.126 + {0x00,0x1E,0x00,0x1E,0x00,0x0E,0x00,0x0E},
1.127 + {0x1E,0x00,0x1E,0x00,0x0E,0x00,0x0E,0x00},
1.128 + {0xE0,0xFE,0xE0,0xFE,0xF0,0xFE,0xF0,0xFE},
1.129 + {0xFE,0xE0,0xFE,0xE0,0xFE,0xF0,0xFE,0xF0}
1.130 + };
1.131 +
1.132 +void CDES::SetKey(const TDesC8& aKey, TUint32* aKeyBuffer)
1.133 + {
1.134 + TInt i=0, j=0, l=0, m=0;
1.135 +
1.136 +// Form a byte array from aKey, taking endianess into account (little->big)
1.137 + TUint8 key[8]; // For big endian byte array
1.138 + Mem::Copy(&key, &aKey[0], 8);
1.139 +
1.140 + TUint8 buffer[56+56+8];
1.141 + TUint8* const pc1m = &buffer[0]; /* place to modify pc1 into */
1.142 + TUint8* const pcr = pc1m + 56; /* place to rotate pc1 into */
1.143 + TUint8* const ks = pcr + 56;
1.144 +
1.145 + for (j=0; j<56; j++)
1.146 + {/* convert pc1 to bits of key */
1.147 + l = DES_TABLE::pc1[j]-1; /* integer bit location */
1.148 + m = l & 07; /* find bit */
1.149 + pc1m[j]=(key[l>>3] & /* find which key byte l is in */
1.150 + bytebit[m]) /* and which bit of that byte */
1.151 + ? (TUint8)1 : (TUint8)0; /* and store 1-bit result */
1.152 + }
1.153 +
1.154 + for (i=0; i<16; i++)
1.155 + {/* key chunk for each iteration */
1.156 + Mem::FillZ(ks,8); /* Clear key schedule */
1.157 + for (j=0; j<56; j++)
1.158 + /* rotate pc1 the right amount */
1.159 + pcr[j] = pc1m[(l=j+DES_TABLE::totrot[i])<(j<28? 28 : 56) ? l: l-28];
1.160 +
1.161 + /* rotate left and right halves independently */
1.162 +
1.163 + for (j=0; j<48; j++)
1.164 + {/* select bits individually */
1.165 + /* check bit that goes to ks[j] */
1.166 + if (pcr[DES_TABLE::pc2[j]-1])
1.167 + {/* mask it in if it's there */
1.168 + l= j % 6;
1.169 + ks[j/6] |= bytebit[l] >> 2;
1.170 + }
1.171 + }
1.172 +
1.173 + /* Now convert to odd/even interleaved form for use in F */
1.174 + (*(aKeyBuffer+(2*i))) = ((TUint32)ks[0] << 24)
1.175 + | ((TUint32)ks[2] << 16)
1.176 + | ((TUint32)ks[4] << 8)
1.177 + | ((TUint32)ks[6]);
1.178 +
1.179 + (*(aKeyBuffer+(2*i+1))) = ((TUint32)ks[1] << 24)
1.180 + | ((TUint32)ks[3] << 16)
1.181 + | ((TUint32)ks[5] << 8)
1.182 + | ((TUint32)ks[7]);
1.183 + }
1.184 + }
1.185 +
1.186 +void CDES::Reset()
1.187 + {
1.188 + SetKey(*iKey, iK1);
1.189 + }
1.190 +
1.191 +
1.192 +/* CDESEncryptor */
1.193 +
1.194 +EXPORT_C CDESEncryptor* CDESEncryptor::NewL(const TDesC8& aKey,
1.195 + TBool aCheckWeakKey)
1.196 + {
1.197 + CDESEncryptor* me = CDESEncryptor::NewLC(aKey, aCheckWeakKey);
1.198 + CleanupStack::Pop(me);
1.199 + return (me);
1.200 + }
1.201 +
1.202 +EXPORT_C CDESEncryptor* CDESEncryptor::NewLC(const TDesC8& aKey,
1.203 + TBool aCheckWeakKey)
1.204 + {
1.205 + CDESEncryptor* me = new (ELeave) CDESEncryptor();
1.206 + CleanupStack::PushL(me);
1.207 + me->ConstructL(aKey, aCheckWeakKey);
1.208 + // DES only used 7 bits out of every key byte
1.209 + TCrypto::IsSymmetricWeakEnoughL(BytesToBits(aKey.Size()) - aKey.Size());
1.210 + return (me);
1.211 + }
1.212 +
1.213 +CDESEncryptor::CDESEncryptor()
1.214 + {
1.215 + }
1.216 +
1.217 +/* CDESDecryptor */
1.218 +
1.219 +EXPORT_C CDESDecryptor* CDESDecryptor::NewL(const TDesC8& aKey,
1.220 + TBool aCheckWeakKey)
1.221 + {
1.222 + CDESDecryptor* me = CDESDecryptor::NewLC(aKey, aCheckWeakKey);
1.223 + CleanupStack::Pop(me);
1.224 + return (me);
1.225 + }
1.226 +
1.227 +EXPORT_C CDESDecryptor* CDESDecryptor::NewLC(const TDesC8& aKey,
1.228 + TBool aCheckWeakKey)
1.229 + {
1.230 + CDESDecryptor* me = new (ELeave) CDESDecryptor();
1.231 + CleanupStack::PushL(me);
1.232 + me->ConstructL(aKey, aCheckWeakKey);
1.233 + // DES only used 7 bits out of every key byte
1.234 + TCrypto::IsSymmetricWeakEnoughL(BytesToBits(aKey.Size()) - aKey.Size());
1.235 + return (me);
1.236 + }
1.237 +
1.238 +
1.239 +CDESDecryptor::CDESDecryptor()
1.240 + {
1.241 + }
1.242 +
1.243 +void CDESDecryptor::SetKey(const TDesC8& aKey, TUint32* aKeyBuffer)
1.244 + {
1.245 + CDES::SetKey(aKey, aKeyBuffer);
1.246 +
1.247 + ReverseKeySchedule(iK1);
1.248 + }
1.249 +
1.250 +EXPORT_C TBool CDES::IsWeakKey(const TDesC8& aKey)
1.251 + {
1.252 + TKeyDES key;
1.253 + TInt index = 0;
1.254 + //Reset parity bits
1.255 + for(; index < KDESKeyBytes; index++)
1.256 + {
1.257 + key[index] = aKey[index] & 0xFE;
1.258 + }
1.259 +
1.260 + TBool weak = EFalse;
1.261 + //Compare key with potential weak keys without parity
1.262 + for (index=0; index < KKnownWeakKeysCount; index++)
1.263 + {
1.264 + if (Mem::Compare(weak_keys[index], KDESKeyBytes, &key[0], KDESKeyBytes)==0)
1.265 + {
1.266 + weak = ETrue;
1.267 + break;
1.268 + }
1.269 + }
1.270 + return weak;
1.271 + }
1.272 +