crypto/weakcrypto/source/symmetric/des.cpp
changeset 0 2c201484c85f
equal deleted inserted replaced
-1:000000000000 0:2c201484c85f
       
     1 /*
       
     2 * Copyright (c) 2002-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 "des.h"
       
    20 #include "destables.h"
       
    21 #include "../common/inlines.h"
       
    22 #include "des.inl"
       
    23 #include <cryptostrength.h>
       
    24 
       
    25 const TInt KDESBlockBytes = 8;
       
    26 const TInt KDESKeyBytes = 8;
       
    27 
       
    28 //	bit 0 is left-most in byte
       
    29 static const TInt bytebit[] = {0200,0100,040,020,010,04,02,01};
       
    30 
       
    31 void CDES::Transform(TDes8& aBlock)
       
    32 	{
       
    33 	assert(aBlock.Size() == KDESBlockBytes);
       
    34 
       
    35 	TUint32 l, r;
       
    36 	// Split the block into 2 word-sized big endian portions
       
    37 	GetBlockBigEndian((TUint8*)&aBlock[0], l, r);
       
    38 
       
    39 	IPerm(l,r);
       
    40 
       
    41 	CDES::DoTransform(l, r, iK1);
       
    42 		
       
    43 	FPerm(l,r);
       
    44 
       
    45 	// Put the portions back into the block as little endian
       
    46 	PutBlockBigEndian((TUint8*)&aBlock[0], r, l);
       
    47 	}
       
    48 
       
    49 void CDES::DoTransform(TUint32& l, TUint32& r, const TUint32* aKey)
       
    50 	{
       
    51 	TInt i = 0;
       
    52 	for (; i<8; i++)
       
    53 		{
       
    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];
       
    64 
       
    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];
       
    75 		}
       
    76 	}
       
    77 
       
    78 
       
    79 TInt CDES::BlockSize() const
       
    80 	{
       
    81 	return KDESBlockBytes;
       
    82 	}
       
    83 
       
    84 TInt CDES::KeySize() const
       
    85 	{
       
    86 	return KDESKeyBytes;
       
    87 	}
       
    88 
       
    89 CDES::~CDES()
       
    90 	{
       
    91 	delete iKey;
       
    92 	}
       
    93 
       
    94 void CDES::ConstructL(const TDesC8& aKey, TBool /*aCheckWeakKey*/)
       
    95 	{
       
    96 	assert(aKey.Size() == KDESKeyBytes);
       
    97 
       
    98 	iKey = aKey.AllocL();
       
    99 	SetKey(aKey, iK1);
       
   100 	}
       
   101 
       
   102 CDES::CDES()
       
   103 	{
       
   104 	}
       
   105 
       
   106 typedef TUint8 TKeyDES[KDESKeyBytes];
       
   107 const TInt KKnownWeakKeysCount = 16;
       
   108 const TKeyDES weak_keys[KKnownWeakKeysCount] =
       
   109 	{
       
   110 	/* weak keys */
       
   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}
       
   127 	};
       
   128 
       
   129 void CDES::SetKey(const TDesC8& aKey, TUint32* aKeyBuffer)
       
   130 	{
       
   131 	TInt i=0, j=0, l=0, m=0;
       
   132 
       
   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);
       
   136 
       
   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;
       
   141 
       
   142 	for (j=0; j<56; j++) 
       
   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 */
       
   149 		}
       
   150 
       
   151 	for (i=0; i<16; i++) 
       
   152 		{/* key chunk for each iteration */
       
   153 		Mem::FillZ(ks,8);							/* Clear key schedule */
       
   154 		for (j=0; j<56; j++)
       
   155 		/*	rotate pc1 the right amount */
       
   156 			pcr[j] = pc1m[(l=j+DES_TABLE::totrot[i])<(j<28? 28 : 56) ? l: l-28];
       
   157 		
       
   158 		/* rotate left and right halves independently */
       
   159 		
       
   160 		for (j=0; j<48; j++)
       
   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 */
       
   165 				l= j % 6;
       
   166 				ks[j/6] |= bytebit[l] >> 2;
       
   167 				}
       
   168 			}
       
   169 
       
   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)
       
   174 			| ((TUint32)ks[6]);
       
   175 		
       
   176 		(*(aKeyBuffer+(2*i+1))) = ((TUint32)ks[1] << 24)
       
   177 			| ((TUint32)ks[3] << 16)
       
   178 			| ((TUint32)ks[5] << 8)
       
   179 			| ((TUint32)ks[7]);
       
   180 		}
       
   181 	}
       
   182 
       
   183 void CDES::Reset()
       
   184 	{
       
   185 	SetKey(*iKey, iK1);
       
   186 	}
       
   187 
       
   188 
       
   189 /* CDESEncryptor */
       
   190 
       
   191 EXPORT_C CDESEncryptor* CDESEncryptor::NewL(const TDesC8& aKey, 
       
   192 	TBool aCheckWeakKey)
       
   193 	{
       
   194 	CDESEncryptor* me = CDESEncryptor::NewLC(aKey, aCheckWeakKey);
       
   195 	CleanupStack::Pop(me);
       
   196 	return (me);
       
   197 	}
       
   198 
       
   199 EXPORT_C CDESEncryptor* CDESEncryptor::NewLC(const TDesC8& aKey, 
       
   200 	TBool aCheckWeakKey)
       
   201 	{
       
   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());
       
   207 	return (me);
       
   208 	}
       
   209 
       
   210 CDESEncryptor::CDESEncryptor()
       
   211 	{
       
   212 	}
       
   213 
       
   214 /* CDESDecryptor */
       
   215 
       
   216 EXPORT_C CDESDecryptor* CDESDecryptor::NewL(const TDesC8& aKey, 
       
   217 	TBool aCheckWeakKey)
       
   218 	{
       
   219 	CDESDecryptor* me = CDESDecryptor::NewLC(aKey, aCheckWeakKey);
       
   220 	CleanupStack::Pop(me);
       
   221 	return (me);
       
   222 	}
       
   223 
       
   224 EXPORT_C CDESDecryptor* CDESDecryptor::NewLC(const TDesC8& aKey, 
       
   225 	TBool aCheckWeakKey)
       
   226 	{
       
   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());
       
   232 	return (me);
       
   233 	}
       
   234 
       
   235 
       
   236 CDESDecryptor::CDESDecryptor()
       
   237 	{
       
   238 	}
       
   239 
       
   240 void CDESDecryptor::SetKey(const TDesC8& aKey, TUint32* aKeyBuffer)
       
   241 	{
       
   242 	CDES::SetKey(aKey, aKeyBuffer);
       
   243 
       
   244 	ReverseKeySchedule(iK1);
       
   245 	}
       
   246 
       
   247 EXPORT_C TBool CDES::IsWeakKey(const TDesC8& aKey)
       
   248 	{
       
   249 	TKeyDES key;
       
   250 	TInt index = 0;
       
   251 	//Reset parity bits
       
   252 	for(; index < KDESKeyBytes; index++)
       
   253 		{
       
   254 		key[index] = aKey[index] & 0xFE;
       
   255 		}
       
   256 		
       
   257 	TBool weak = EFalse;	
       
   258 	//Compare key with potential weak keys without parity	
       
   259 	for (index=0; index < KKnownWeakKeysCount; index++)
       
   260 		{
       
   261 		if (Mem::Compare(weak_keys[index], KDESKeyBytes, &key[0], KDESKeyBytes)==0)
       
   262 			{
       
   263 			weak = ETrue;
       
   264 			break;
       
   265 			}
       
   266 		}
       
   267 	return weak;
       
   268 	}