Home | History | Annotate | Download | only in cipher
      1 package ch.ethz.ssh2.crypto.cipher;
      2 
      3 /*
      4  This file is based on the 3DES implementation from the Bouncy Castle Crypto package.
      5  Their licence file states the following:
      6 
      7  Copyright (c) 2000 - 2004 The Legion Of The Bouncy Castle
      8  (http://www.bouncycastle.org)
      9 
     10  Permission is hereby granted, free of charge, to any person obtaining a copy
     11  of this software and associated documentation files (the "Software"), to deal
     12  in the Software without restriction, including without limitation the rights
     13  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     14  copies of the Software, and to permit persons to whom the Software is
     15  furnished to do so, subject to the following conditions:
     16 
     17  The above copyright notice and this permission notice shall be included in
     18  all copies or substantial portions of the Software.
     19 
     20  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     21  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     22  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     23  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     24  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     25  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     26  THE SOFTWARE.
     27  */
     28 
     29 /**
     30  * DES.
     31  *
     32  * @author See comments in the source file
     33  * @version 2.50, 03/15/10
     34  *
     35  */
     36 public class DES implements BlockCipher
     37 {
     38 	private int[] workingKey = null;
     39 
     40 	/**
     41 	 * standard constructor.
     42 	 */
     43 	public DES()
     44 	{
     45 	}
     46 
     47 	/**
     48 	 * initialise a DES cipher.
     49 	 *
     50 	 * @param encrypting
     51 	 *            whether or not we are for encryption.
     52 	 * @param key
     53 	 *            the parameters required to set up the cipher.
     54 	 * @exception IllegalArgumentException
     55 	 *                if the params argument is inappropriate.
     56 	 */
     57 	public void init(boolean encrypting, byte[] key)
     58 	{
     59 		this.workingKey = generateWorkingKey(encrypting, key, 0);
     60 	}
     61 
     62 	public String getAlgorithmName()
     63 	{
     64 		return "DES";
     65 	}
     66 
     67 	public int getBlockSize()
     68 	{
     69 		return 8;
     70 	}
     71 
     72 	public void transformBlock(byte[] in, int inOff, byte[] out, int outOff)
     73 	{
     74 		if (workingKey == null)
     75 		{
     76 			throw new IllegalStateException("DES engine not initialised!");
     77 		}
     78 
     79 		desFunc(workingKey, in, inOff, out, outOff);
     80 	}
     81 
     82 	public void reset()
     83 	{
     84 	}
     85 
     86 	/**
     87 	 * what follows is mainly taken from "Applied Cryptography", by Bruce
     88 	 * Schneier, however it also bears great resemblance to Richard
     89 	 * Outerbridge's D3DES...
     90 	 */
     91 
     92 	static short[] Df_Key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32,
     93 			0x10, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67 };
     94 
     95 	static short[] bytebit = { 0200, 0100, 040, 020, 010, 04, 02, 01 };
     96 
     97 	static int[] bigbyte = { 0x800000, 0x400000, 0x200000, 0x100000, 0x80000, 0x40000, 0x20000, 0x10000, 0x8000,
     98 			0x4000, 0x2000, 0x1000, 0x800, 0x400, 0x200, 0x100, 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1 };
     99 
    100 	/*
    101 	 * Use the key schedule specified in the Standard (ANSI X3.92-1981).
    102 	 */
    103 
    104 	static byte[] pc1 = { 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2,
    105 			59, 51, 43, 35, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 60, 52, 44, 36, 28, 20, 12,
    106 			4, 27, 19, 11, 3 };
    107 
    108 	static byte[] totrot = { 1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28 };
    109 
    110 	static byte[] pc2 = { 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9, 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1, 40,
    111 			51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 };
    112 
    113 	static int[] SP1 = { 0x01010400, 0x00000000, 0x00010000, 0x01010404, 0x01010004, 0x00010404, 0x00000004,
    114 			0x00010000, 0x00000400, 0x01010400, 0x01010404, 0x00000400, 0x01000404, 0x01010004, 0x01000000, 0x00000004,
    115 			0x00000404, 0x01000400, 0x01000400, 0x00010400, 0x00010400, 0x01010000, 0x01010000, 0x01000404, 0x00010004,
    116 			0x01000004, 0x01000004, 0x00010004, 0x00000000, 0x00000404, 0x00010404, 0x01000000, 0x00010000, 0x01010404,
    117 			0x00000004, 0x01010000, 0x01010400, 0x01000000, 0x01000000, 0x00000400, 0x01010004, 0x00010000, 0x00010400,
    118 			0x01000004, 0x00000400, 0x00000004, 0x01000404, 0x00010404, 0x01010404, 0x00010004, 0x01010000, 0x01000404,
    119 			0x01000004, 0x00000404, 0x00010404, 0x01010400, 0x00000404, 0x01000400, 0x01000400, 0x00000000, 0x00010004,
    120 			0x00010400, 0x00000000, 0x01010004 };
    121 
    122 	static int[] SP2 = { 0x80108020, 0x80008000, 0x00008000, 0x00108020, 0x00100000, 0x00000020, 0x80100020,
    123 			0x80008020, 0x80000020, 0x80108020, 0x80108000, 0x80000000, 0x80008000, 0x00100000, 0x00000020, 0x80100020,
    124 			0x00108000, 0x00100020, 0x80008020, 0x00000000, 0x80000000, 0x00008000, 0x00108020, 0x80100000, 0x00100020,
    125 			0x80000020, 0x00000000, 0x00108000, 0x00008020, 0x80108000, 0x80100000, 0x00008020, 0x00000000, 0x00108020,
    126 			0x80100020, 0x00100000, 0x80008020, 0x80100000, 0x80108000, 0x00008000, 0x80100000, 0x80008000, 0x00000020,
    127 			0x80108020, 0x00108020, 0x00000020, 0x00008000, 0x80000000, 0x00008020, 0x80108000, 0x00100000, 0x80000020,
    128 			0x00100020, 0x80008020, 0x80000020, 0x00100020, 0x00108000, 0x00000000, 0x80008000, 0x00008020, 0x80000000,
    129 			0x80100020, 0x80108020, 0x00108000 };
    130 
    131 	static int[] SP3 = { 0x00000208, 0x08020200, 0x00000000, 0x08020008, 0x08000200, 0x00000000, 0x00020208,
    132 			0x08000200, 0x00020008, 0x08000008, 0x08000008, 0x00020000, 0x08020208, 0x00020008, 0x08020000, 0x00000208,
    133 			0x08000000, 0x00000008, 0x08020200, 0x00000200, 0x00020200, 0x08020000, 0x08020008, 0x00020208, 0x08000208,
    134 			0x00020200, 0x00020000, 0x08000208, 0x00000008, 0x08020208, 0x00000200, 0x08000000, 0x08020200, 0x08000000,
    135 			0x00020008, 0x00000208, 0x00020000, 0x08020200, 0x08000200, 0x00000000, 0x00000200, 0x00020008, 0x08020208,
    136 			0x08000200, 0x08000008, 0x00000200, 0x00000000, 0x08020008, 0x08000208, 0x00020000, 0x08000000, 0x08020208,
    137 			0x00000008, 0x00020208, 0x00020200, 0x08000008, 0x08020000, 0x08000208, 0x00000208, 0x08020000, 0x00020208,
    138 			0x00000008, 0x08020008, 0x00020200 };
    139 
    140 	static int[] SP4 = { 0x00802001, 0x00002081, 0x00002081, 0x00000080, 0x00802080, 0x00800081, 0x00800001,
    141 			0x00002001, 0x00000000, 0x00802000, 0x00802000, 0x00802081, 0x00000081, 0x00000000, 0x00800080, 0x00800001,
    142 			0x00000001, 0x00002000, 0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002001, 0x00002080, 0x00800081,
    143 			0x00000001, 0x00002080, 0x00800080, 0x00002000, 0x00802080, 0x00802081, 0x00000081, 0x00800080, 0x00800001,
    144 			0x00802000, 0x00802081, 0x00000081, 0x00000000, 0x00000000, 0x00802000, 0x00002080, 0x00800080, 0x00800081,
    145 			0x00000001, 0x00802001, 0x00002081, 0x00002081, 0x00000080, 0x00802081, 0x00000081, 0x00000001, 0x00002000,
    146 			0x00800001, 0x00002001, 0x00802080, 0x00800081, 0x00002001, 0x00002080, 0x00800000, 0x00802001, 0x00000080,
    147 			0x00800000, 0x00002000, 0x00802080 };
    148 
    149 	static int[] SP5 = { 0x00000100, 0x02080100, 0x02080000, 0x42000100, 0x00080000, 0x00000100, 0x40000000,
    150 			0x02080000, 0x40080100, 0x00080000, 0x02000100, 0x40080100, 0x42000100, 0x42080000, 0x00080100, 0x40000000,
    151 			0x02000000, 0x40080000, 0x40080000, 0x00000000, 0x40000100, 0x42080100, 0x42080100, 0x02000100, 0x42080000,
    152 			0x40000100, 0x00000000, 0x42000000, 0x02080100, 0x02000000, 0x42000000, 0x00080100, 0x00080000, 0x42000100,
    153 			0x00000100, 0x02000000, 0x40000000, 0x02080000, 0x42000100, 0x40080100, 0x02000100, 0x40000000, 0x42080000,
    154 			0x02080100, 0x40080100, 0x00000100, 0x02000000, 0x42080000, 0x42080100, 0x00080100, 0x42000000, 0x42080100,
    155 			0x02080000, 0x00000000, 0x40080000, 0x42000000, 0x00080100, 0x02000100, 0x40000100, 0x00080000, 0x00000000,
    156 			0x40080000, 0x02080100, 0x40000100 };
    157 
    158 	static int[] SP6 = { 0x20000010, 0x20400000, 0x00004000, 0x20404010, 0x20400000, 0x00000010, 0x20404010,
    159 			0x00400000, 0x20004000, 0x00404010, 0x00400000, 0x20000010, 0x00400010, 0x20004000, 0x20000000, 0x00004010,
    160 			0x00000000, 0x00400010, 0x20004010, 0x00004000, 0x00404000, 0x20004010, 0x00000010, 0x20400010, 0x20400010,
    161 			0x00000000, 0x00404010, 0x20404000, 0x00004010, 0x00404000, 0x20404000, 0x20000000, 0x20004000, 0x00000010,
    162 			0x20400010, 0x00404000, 0x20404010, 0x00400000, 0x00004010, 0x20000010, 0x00400000, 0x20004000, 0x20000000,
    163 			0x00004010, 0x20000010, 0x20404010, 0x00404000, 0x20400000, 0x00404010, 0x20404000, 0x00000000, 0x20400010,
    164 			0x00000010, 0x00004000, 0x20400000, 0x00404010, 0x00004000, 0x00400010, 0x20004010, 0x00000000, 0x20404000,
    165 			0x20000000, 0x00400010, 0x20004010 };
    166 
    167 	static int[] SP7 = { 0x00200000, 0x04200002, 0x04000802, 0x00000000, 0x00000800, 0x04000802, 0x00200802,
    168 			0x04200800, 0x04200802, 0x00200000, 0x00000000, 0x04000002, 0x00000002, 0x04000000, 0x04200002, 0x00000802,
    169 			0x04000800, 0x00200802, 0x00200002, 0x04000800, 0x04000002, 0x04200000, 0x04200800, 0x00200002, 0x04200000,
    170 			0x00000800, 0x00000802, 0x04200802, 0x00200800, 0x00000002, 0x04000000, 0x00200800, 0x04000000, 0x00200800,
    171 			0x00200000, 0x04000802, 0x04000802, 0x04200002, 0x04200002, 0x00000002, 0x00200002, 0x04000000, 0x04000800,
    172 			0x00200000, 0x04200800, 0x00000802, 0x00200802, 0x04200800, 0x00000802, 0x04000002, 0x04200802, 0x04200000,
    173 			0x00200800, 0x00000000, 0x00000002, 0x04200802, 0x00000000, 0x00200802, 0x04200000, 0x00000800, 0x04000002,
    174 			0x04000800, 0x00000800, 0x00200002 };
    175 
    176 	static int[] SP8 = { 0x10001040, 0x00001000, 0x00040000, 0x10041040, 0x10000000, 0x10001040, 0x00000040,
    177 			0x10000000, 0x00040040, 0x10040000, 0x10041040, 0x00041000, 0x10041000, 0x00041040, 0x00001000, 0x00000040,
    178 			0x10040000, 0x10000040, 0x10001000, 0x00001040, 0x00041000, 0x00040040, 0x10040040, 0x10041000, 0x00001040,
    179 			0x00000000, 0x00000000, 0x10040040, 0x10000040, 0x10001000, 0x00041040, 0x00040000, 0x00041040, 0x00040000,
    180 			0x10041000, 0x00001000, 0x00000040, 0x10040040, 0x00001000, 0x00041040, 0x10001000, 0x00000040, 0x10000040,
    181 			0x10040000, 0x10040040, 0x10000000, 0x00040000, 0x10001040, 0x00000000, 0x10041040, 0x00040040, 0x10000040,
    182 			0x10040000, 0x10001000, 0x10001040, 0x00000000, 0x10041040, 0x00041000, 0x00041000, 0x00001040, 0x00001040,
    183 			0x00040040, 0x10000000, 0x10041000 };
    184 
    185 	/**
    186 	 * generate an integer based working key based on our secret key and what we
    187 	 * processing we are planning to do.
    188 	 *
    189 	 * Acknowledgements for this routine go to James Gillogly & Phil Karn.
    190 	 * (whoever, and wherever they are!).
    191 	 */
    192 	protected int[] generateWorkingKey(boolean encrypting, byte[] key, int off)
    193 	{
    194 		int[] newKey = new int[32];
    195 		boolean[] pc1m = new boolean[56], pcr = new boolean[56];
    196 
    197 		for (int j = 0; j < 56; j++)
    198 		{
    199 			int l = pc1[j];
    200 
    201 			pc1m[j] = ((key[off + (l >>> 3)] & bytebit[l & 07]) != 0);
    202 		}
    203 
    204 		for (int i = 0; i < 16; i++)
    205 		{
    206 			int l, m, n;
    207 
    208 			if (encrypting)
    209 			{
    210 				m = i << 1;
    211 			}
    212 			else
    213 			{
    214 				m = (15 - i) << 1;
    215 			}
    216 
    217 			n = m + 1;
    218 			newKey[m] = newKey[n] = 0;
    219 
    220 			for (int j = 0; j < 28; j++)
    221 			{
    222 				l = j + totrot[i];
    223 				if (l < 28)
    224 				{
    225 					pcr[j] = pc1m[l];
    226 				}
    227 				else
    228 				{
    229 					pcr[j] = pc1m[l - 28];
    230 				}
    231 			}
    232 
    233 			for (int j = 28; j < 56; j++)
    234 			{
    235 				l = j + totrot[i];
    236 				if (l < 56)
    237 				{
    238 					pcr[j] = pc1m[l];
    239 				}
    240 				else
    241 				{
    242 					pcr[j] = pc1m[l - 28];
    243 				}
    244 			}
    245 
    246 			for (int j = 0; j < 24; j++)
    247 			{
    248 				if (pcr[pc2[j]])
    249 				{
    250 					newKey[m] |= bigbyte[j];
    251 				}
    252 
    253 				if (pcr[pc2[j + 24]])
    254 				{
    255 					newKey[n] |= bigbyte[j];
    256 				}
    257 			}
    258 		}
    259 
    260 		//
    261 		// store the processed key
    262 		//
    263 		for (int i = 0; i != 32; i += 2)
    264 		{
    265 			int i1, i2;
    266 
    267 			i1 = newKey[i];
    268 			i2 = newKey[i + 1];
    269 
    270 			newKey[i] = ((i1 & 0x00fc0000) << 6) | ((i1 & 0x00000fc0) << 10) | ((i2 & 0x00fc0000) >>> 10)
    271 					| ((i2 & 0x00000fc0) >>> 6);
    272 
    273 			newKey[i + 1] = ((i1 & 0x0003f000) << 12) | ((i1 & 0x0000003f) << 16) | ((i2 & 0x0003f000) >>> 4)
    274 					| (i2 & 0x0000003f);
    275 		}
    276 
    277 		return newKey;
    278 	}
    279 
    280 	/**
    281 	 * the DES engine.
    282 	 */
    283 	protected void desFunc(int[] wKey, byte[] in, int inOff, byte[] out, int outOff)
    284 	{
    285 		int work, right, left;
    286 
    287 		left = (in[inOff + 0] & 0xff) << 24;
    288 		left |= (in[inOff + 1] & 0xff) << 16;
    289 		left |= (in[inOff + 2] & 0xff) << 8;
    290 		left |= (in[inOff + 3] & 0xff);
    291 
    292 		right = (in[inOff + 4] & 0xff) << 24;
    293 		right |= (in[inOff + 5] & 0xff) << 16;
    294 		right |= (in[inOff + 6] & 0xff) << 8;
    295 		right |= (in[inOff + 7] & 0xff);
    296 
    297 		work = ((left >>> 4) ^ right) & 0x0f0f0f0f;
    298 		right ^= work;
    299 		left ^= (work << 4);
    300 		work = ((left >>> 16) ^ right) & 0x0000ffff;
    301 		right ^= work;
    302 		left ^= (work << 16);
    303 		work = ((right >>> 2) ^ left) & 0x33333333;
    304 		left ^= work;
    305 		right ^= (work << 2);
    306 		work = ((right >>> 8) ^ left) & 0x00ff00ff;
    307 		left ^= work;
    308 		right ^= (work << 8);
    309 		right = ((right << 1) | ((right >>> 31) & 1)) & 0xffffffff;
    310 		work = (left ^ right) & 0xaaaaaaaa;
    311 		left ^= work;
    312 		right ^= work;
    313 		left = ((left << 1) | ((left >>> 31) & 1)) & 0xffffffff;
    314 
    315 		for (int round = 0; round < 8; round++)
    316 		{
    317 			int fval;
    318 
    319 			work = (right << 28) | (right >>> 4);
    320 			work ^= wKey[round * 4 + 0];
    321 			fval = SP7[work & 0x3f];
    322 			fval |= SP5[(work >>> 8) & 0x3f];
    323 			fval |= SP3[(work >>> 16) & 0x3f];
    324 			fval |= SP1[(work >>> 24) & 0x3f];
    325 			work = right ^ wKey[round * 4 + 1];
    326 			fval |= SP8[work & 0x3f];
    327 			fval |= SP6[(work >>> 8) & 0x3f];
    328 			fval |= SP4[(work >>> 16) & 0x3f];
    329 			fval |= SP2[(work >>> 24) & 0x3f];
    330 			left ^= fval;
    331 			work = (left << 28) | (left >>> 4);
    332 			work ^= wKey[round * 4 + 2];
    333 			fval = SP7[work & 0x3f];
    334 			fval |= SP5[(work >>> 8) & 0x3f];
    335 			fval |= SP3[(work >>> 16) & 0x3f];
    336 			fval |= SP1[(work >>> 24) & 0x3f];
    337 			work = left ^ wKey[round * 4 + 3];
    338 			fval |= SP8[work & 0x3f];
    339 			fval |= SP6[(work >>> 8) & 0x3f];
    340 			fval |= SP4[(work >>> 16) & 0x3f];
    341 			fval |= SP2[(work >>> 24) & 0x3f];
    342 			right ^= fval;
    343 		}
    344 
    345 		right = (right << 31) | (right >>> 1);
    346 		work = (left ^ right) & 0xaaaaaaaa;
    347 		left ^= work;
    348 		right ^= work;
    349 		left = (left << 31) | (left >>> 1);
    350 		work = ((left >>> 8) ^ right) & 0x00ff00ff;
    351 		right ^= work;
    352 		left ^= (work << 8);
    353 		work = ((left >>> 2) ^ right) & 0x33333333;
    354 		right ^= work;
    355 		left ^= (work << 2);
    356 		work = ((right >>> 16) ^ left) & 0x0000ffff;
    357 		left ^= work;
    358 		right ^= (work << 16);
    359 		work = ((right >>> 4) ^ left) & 0x0f0f0f0f;
    360 		left ^= work;
    361 		right ^= (work << 4);
    362 
    363 		out[outOff + 0] = (byte) ((right >>> 24) & 0xff);
    364 		out[outOff + 1] = (byte) ((right >>> 16) & 0xff);
    365 		out[outOff + 2] = (byte) ((right >>> 8) & 0xff);
    366 		out[outOff + 3] = (byte) (right & 0xff);
    367 		out[outOff + 4] = (byte) ((left >>> 24) & 0xff);
    368 		out[outOff + 5] = (byte) ((left >>> 16) & 0xff);
    369 		out[outOff + 6] = (byte) ((left >>> 8) & 0xff);
    370 		out[outOff + 7] = (byte) (left & 0xff);
    371 	}
    372 }
    373