Update contrib.
2 * Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
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".
9 * Initial Contributors:
10 * Nokia Corporation - initial contribution.
20 #include "destables.h"
21 #include "../common/inlines.h"
23 #include <cryptostrength.h>
25 const TInt KDESBlockBytes = 8;
26 const TInt KDESKeyBytes = 8;
28 // bit 0 is left-most in byte
29 static const TInt bytebit[] = {0200,0100,040,020,010,04,02,01};
31 void CDES::Transform(TDes8& aBlock)
33 assert(aBlock.Size() == KDESBlockBytes);
36 // Split the block into 2 word-sized big endian portions
37 GetBlockBigEndian((TUint8*)&aBlock[0], l, r);
41 CDES::DoTransform(l, r, iK1);
45 // Put the portions back into the block as little endian
46 PutBlockBigEndian((TUint8*)&aBlock[0], r, l);
49 void CDES::DoTransform(TUint32& l, TUint32& r, const TUint32* aKey)
54 TUint32 work = rotrFixed(r, 4U) ^ aKey[4*i+0];
55 l ^= DES_TABLE::sbox[6][(work) & 0x3f]
56 ^ DES_TABLE::sbox[4][(work >> 8) & 0x3f]
57 ^ DES_TABLE::sbox[2][(work >> 16) & 0x3f]
58 ^ DES_TABLE::sbox[0][(work >> 24) & 0x3f];
59 work = r ^ aKey[4*i+1];
60 l ^= DES_TABLE::sbox[7][(work) & 0x3f]
61 ^ DES_TABLE::sbox[5][(work >> 8) & 0x3f]
62 ^ DES_TABLE::sbox[3][(work >> 16) & 0x3f]
63 ^ DES_TABLE::sbox[1][(work >> 24) & 0x3f];
65 work = rotrFixed(l, 4U) ^ aKey[4*i+2];
66 r ^= DES_TABLE::sbox[6][(work) & 0x3f]
67 ^ DES_TABLE::sbox[4][(work >> 8) & 0x3f]
68 ^ DES_TABLE::sbox[2][(work >> 16) & 0x3f]
69 ^ DES_TABLE::sbox[0][(work >> 24) & 0x3f];
70 work = l ^ aKey[4*i+3];
71 r ^= DES_TABLE::sbox[7][(work) & 0x3f]
72 ^ DES_TABLE::sbox[5][(work >> 8) & 0x3f]
73 ^ DES_TABLE::sbox[3][(work >> 16) & 0x3f]
74 ^ DES_TABLE::sbox[1][(work >> 24) & 0x3f];
79 TInt CDES::BlockSize() const
81 return KDESBlockBytes;
84 TInt CDES::KeySize() const
94 void CDES::ConstructL(const TDesC8& aKey, TBool /*aCheckWeakKey*/)
96 assert(aKey.Size() == KDESKeyBytes);
106 typedef TUint8 TKeyDES[KDESKeyBytes];
107 const TInt KKnownWeakKeysCount = 16;
108 const TKeyDES weak_keys[KKnownWeakKeysCount] =
111 {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
112 {0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE},
113 {0x1E,0x1E,0x1E,0x1E,0x0E,0x0E,0x0E,0x0E},
114 {0xE0,0xE0,0xE0,0xE0,0xF0,0xF0,0xF0,0xF0},
115 {0x00,0xFE,0x00,0xFE,0x00,0xFE,0x00,0xFE},
116 {0xFE,0x00,0xFE,0x00,0xFE,0x00,0xFE,0x00},
117 {0x1E,0xE0,0x1E,0xE0,0x0E,0xF0,0x0E,0xF0},
118 {0xE0,0x1E,0xE0,0x1E,0xF0,0x0E,0xF0,0x0E},
119 {0x00,0xE0,0x00,0xE0,0x00,0xF0,0x00,0xF0},
120 {0xE0,0x00,0xE0,0x00,0xF0,0x00,0xF0,0x00},
121 {0x1E,0xFE,0x1E,0xFE,0x0E,0xFE,0x0E,0xFE},
122 {0xFE,0x1E,0xFE,0x1E,0xFE,0x0E,0xFE,0x0E},
123 {0x00,0x1E,0x00,0x1E,0x00,0x0E,0x00,0x0E},
124 {0x1E,0x00,0x1E,0x00,0x0E,0x00,0x0E,0x00},
125 {0xE0,0xFE,0xE0,0xFE,0xF0,0xFE,0xF0,0xFE},
126 {0xFE,0xE0,0xFE,0xE0,0xFE,0xF0,0xFE,0xF0}
129 void CDES::SetKey(const TDesC8& aKey, TUint32* aKeyBuffer)
131 TInt i=0, j=0, l=0, m=0;
133 // Form a byte array from aKey, taking endianess into account (little->big)
134 TUint8 key[8]; // For big endian byte array
135 Mem::Copy(&key, &aKey[0], 8);
137 TUint8 buffer[56+56+8];
138 TUint8* const pc1m = &buffer[0]; /* place to modify pc1 into */
139 TUint8* const pcr = pc1m + 56; /* place to rotate pc1 into */
140 TUint8* const ks = pcr + 56;
143 {/* convert pc1 to bits of key */
144 l = DES_TABLE::pc1[j]-1; /* integer bit location */
145 m = l & 07; /* find bit */
146 pc1m[j]=(key[l>>3] & /* find which key byte l is in */
147 bytebit[m]) /* and which bit of that byte */
148 ? (TUint8)1 : (TUint8)0; /* and store 1-bit result */
152 {/* key chunk for each iteration */
153 Mem::FillZ(ks,8); /* Clear key schedule */
155 /* rotate pc1 the right amount */
156 pcr[j] = pc1m[(l=j+DES_TABLE::totrot[i])<(j<28? 28 : 56) ? l: l-28];
158 /* rotate left and right halves independently */
161 {/* select bits individually */
162 /* check bit that goes to ks[j] */
163 if (pcr[DES_TABLE::pc2[j]-1])
164 {/* mask it in if it's there */
166 ks[j/6] |= bytebit[l] >> 2;
170 /* Now convert to odd/even interleaved form for use in F */
171 (*(aKeyBuffer+(2*i))) = ((TUint32)ks[0] << 24)
172 | ((TUint32)ks[2] << 16)
173 | ((TUint32)ks[4] << 8)
176 (*(aKeyBuffer+(2*i+1))) = ((TUint32)ks[1] << 24)
177 | ((TUint32)ks[3] << 16)
178 | ((TUint32)ks[5] << 8)
191 EXPORT_C CDESEncryptor* CDESEncryptor::NewL(const TDesC8& aKey,
194 CDESEncryptor* me = CDESEncryptor::NewLC(aKey, aCheckWeakKey);
195 CleanupStack::Pop(me);
199 EXPORT_C CDESEncryptor* CDESEncryptor::NewLC(const TDesC8& aKey,
202 CDESEncryptor* me = new (ELeave) CDESEncryptor();
203 CleanupStack::PushL(me);
204 me->ConstructL(aKey, aCheckWeakKey);
205 // DES only used 7 bits out of every key byte
206 TCrypto::IsSymmetricWeakEnoughL(BytesToBits(aKey.Size()) - aKey.Size());
210 CDESEncryptor::CDESEncryptor()
216 EXPORT_C CDESDecryptor* CDESDecryptor::NewL(const TDesC8& aKey,
219 CDESDecryptor* me = CDESDecryptor::NewLC(aKey, aCheckWeakKey);
220 CleanupStack::Pop(me);
224 EXPORT_C CDESDecryptor* CDESDecryptor::NewLC(const TDesC8& aKey,
227 CDESDecryptor* me = new (ELeave) CDESDecryptor();
228 CleanupStack::PushL(me);
229 me->ConstructL(aKey, aCheckWeakKey);
230 // DES only used 7 bits out of every key byte
231 TCrypto::IsSymmetricWeakEnoughL(BytesToBits(aKey.Size()) - aKey.Size());
236 CDESDecryptor::CDESDecryptor()
240 void CDESDecryptor::SetKey(const TDesC8& aKey, TUint32* aKeyBuffer)
242 CDES::SetKey(aKey, aKeyBuffer);
244 ReverseKeySchedule(iK1);
247 EXPORT_C TBool CDES::IsWeakKey(const TDesC8& aKey)
252 for(; index < KDESKeyBytes; index++)
254 key[index] = aKey[index] & 0xFE;
258 //Compare key with potential weak keys without parity
259 for (index=0; index < KKnownWeakKeysCount; index++)
261 if (Mem::Compare(weak_keys[index], KDESKeyBytes, &key[0], KDESKeyBytes)==0)