• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package org.bouncycastle.crypto.engines;
2 
3 import org.bouncycastle.crypto.BlockCipher;
4 import org.bouncycastle.crypto.CipherParameters;
5 import org.bouncycastle.crypto.DataLengthException;
6 import org.bouncycastle.crypto.OutputLengthException;
7 import org.bouncycastle.crypto.params.KeyParameter;
8 
9 /**
10  * A class that provides Twofish encryption operations.
11  *
12  * This Java implementation is based on the Java reference
13  * implementation provided by Bruce Schneier and developed
14  * by Raif S. Naffah.
15  */
16 public final class TwofishEngine
17     implements BlockCipher
18 {
19     private static final byte[][] P =  {
20     {  // p0
21         (byte) 0xA9, (byte) 0x67, (byte) 0xB3, (byte) 0xE8,
22         (byte) 0x04, (byte) 0xFD, (byte) 0xA3, (byte) 0x76,
23         (byte) 0x9A, (byte) 0x92, (byte) 0x80, (byte) 0x78,
24         (byte) 0xE4, (byte) 0xDD, (byte) 0xD1, (byte) 0x38,
25         (byte) 0x0D, (byte) 0xC6, (byte) 0x35, (byte) 0x98,
26         (byte) 0x18, (byte) 0xF7, (byte) 0xEC, (byte) 0x6C,
27         (byte) 0x43, (byte) 0x75, (byte) 0x37, (byte) 0x26,
28         (byte) 0xFA, (byte) 0x13, (byte) 0x94, (byte) 0x48,
29         (byte) 0xF2, (byte) 0xD0, (byte) 0x8B, (byte) 0x30,
30         (byte) 0x84, (byte) 0x54, (byte) 0xDF, (byte) 0x23,
31         (byte) 0x19, (byte) 0x5B, (byte) 0x3D, (byte) 0x59,
32         (byte) 0xF3, (byte) 0xAE, (byte) 0xA2, (byte) 0x82,
33         (byte) 0x63, (byte) 0x01, (byte) 0x83, (byte) 0x2E,
34         (byte) 0xD9, (byte) 0x51, (byte) 0x9B, (byte) 0x7C,
35         (byte) 0xA6, (byte) 0xEB, (byte) 0xA5, (byte) 0xBE,
36         (byte) 0x16, (byte) 0x0C, (byte) 0xE3, (byte) 0x61,
37         (byte) 0xC0, (byte) 0x8C, (byte) 0x3A, (byte) 0xF5,
38         (byte) 0x73, (byte) 0x2C, (byte) 0x25, (byte) 0x0B,
39         (byte) 0xBB, (byte) 0x4E, (byte) 0x89, (byte) 0x6B,
40         (byte) 0x53, (byte) 0x6A, (byte) 0xB4, (byte) 0xF1,
41         (byte) 0xE1, (byte) 0xE6, (byte) 0xBD, (byte) 0x45,
42         (byte) 0xE2, (byte) 0xF4, (byte) 0xB6, (byte) 0x66,
43         (byte) 0xCC, (byte) 0x95, (byte) 0x03, (byte) 0x56,
44         (byte) 0xD4, (byte) 0x1C, (byte) 0x1E, (byte) 0xD7,
45         (byte) 0xFB, (byte) 0xC3, (byte) 0x8E, (byte) 0xB5,
46         (byte) 0xE9, (byte) 0xCF, (byte) 0xBF, (byte) 0xBA,
47         (byte) 0xEA, (byte) 0x77, (byte) 0x39, (byte) 0xAF,
48         (byte) 0x33, (byte) 0xC9, (byte) 0x62, (byte) 0x71,
49         (byte) 0x81, (byte) 0x79, (byte) 0x09, (byte) 0xAD,
50         (byte) 0x24, (byte) 0xCD, (byte) 0xF9, (byte) 0xD8,
51         (byte) 0xE5, (byte) 0xC5, (byte) 0xB9, (byte) 0x4D,
52         (byte) 0x44, (byte) 0x08, (byte) 0x86, (byte) 0xE7,
53         (byte) 0xA1, (byte) 0x1D, (byte) 0xAA, (byte) 0xED,
54         (byte) 0x06, (byte) 0x70, (byte) 0xB2, (byte) 0xD2,
55         (byte) 0x41, (byte) 0x7B, (byte) 0xA0, (byte) 0x11,
56         (byte) 0x31, (byte) 0xC2, (byte) 0x27, (byte) 0x90,
57         (byte) 0x20, (byte) 0xF6, (byte) 0x60, (byte) 0xFF,
58         (byte) 0x96, (byte) 0x5C, (byte) 0xB1, (byte) 0xAB,
59         (byte) 0x9E, (byte) 0x9C, (byte) 0x52, (byte) 0x1B,
60         (byte) 0x5F, (byte) 0x93, (byte) 0x0A, (byte) 0xEF,
61         (byte) 0x91, (byte) 0x85, (byte) 0x49, (byte) 0xEE,
62         (byte) 0x2D, (byte) 0x4F, (byte) 0x8F, (byte) 0x3B,
63         (byte) 0x47, (byte) 0x87, (byte) 0x6D, (byte) 0x46,
64         (byte) 0xD6, (byte) 0x3E, (byte) 0x69, (byte) 0x64,
65         (byte) 0x2A, (byte) 0xCE, (byte) 0xCB, (byte) 0x2F,
66         (byte) 0xFC, (byte) 0x97, (byte) 0x05, (byte) 0x7A,
67         (byte) 0xAC, (byte) 0x7F, (byte) 0xD5, (byte) 0x1A,
68         (byte) 0x4B, (byte) 0x0E, (byte) 0xA7, (byte) 0x5A,
69         (byte) 0x28, (byte) 0x14, (byte) 0x3F, (byte) 0x29,
70         (byte) 0x88, (byte) 0x3C, (byte) 0x4C, (byte) 0x02,
71         (byte) 0xB8, (byte) 0xDA, (byte) 0xB0, (byte) 0x17,
72         (byte) 0x55, (byte) 0x1F, (byte) 0x8A, (byte) 0x7D,
73         (byte) 0x57, (byte) 0xC7, (byte) 0x8D, (byte) 0x74,
74         (byte) 0xB7, (byte) 0xC4, (byte) 0x9F, (byte) 0x72,
75         (byte) 0x7E, (byte) 0x15, (byte) 0x22, (byte) 0x12,
76         (byte) 0x58, (byte) 0x07, (byte) 0x99, (byte) 0x34,
77         (byte) 0x6E, (byte) 0x50, (byte) 0xDE, (byte) 0x68,
78         (byte) 0x65, (byte) 0xBC, (byte) 0xDB, (byte) 0xF8,
79         (byte) 0xC8, (byte) 0xA8, (byte) 0x2B, (byte) 0x40,
80         (byte) 0xDC, (byte) 0xFE, (byte) 0x32, (byte) 0xA4,
81         (byte) 0xCA, (byte) 0x10, (byte) 0x21, (byte) 0xF0,
82         (byte) 0xD3, (byte) 0x5D, (byte) 0x0F, (byte) 0x00,
83         (byte) 0x6F, (byte) 0x9D, (byte) 0x36, (byte) 0x42,
84         (byte) 0x4A, (byte) 0x5E, (byte) 0xC1, (byte) 0xE0 },
85     {  // p1
86         (byte) 0x75, (byte) 0xF3, (byte) 0xC6, (byte) 0xF4,
87         (byte) 0xDB, (byte) 0x7B, (byte) 0xFB, (byte) 0xC8,
88         (byte) 0x4A, (byte) 0xD3, (byte) 0xE6, (byte) 0x6B,
89         (byte) 0x45, (byte) 0x7D, (byte) 0xE8, (byte) 0x4B,
90         (byte) 0xD6, (byte) 0x32, (byte) 0xD8, (byte) 0xFD,
91         (byte) 0x37, (byte) 0x71, (byte) 0xF1, (byte) 0xE1,
92         (byte) 0x30, (byte) 0x0F, (byte) 0xF8, (byte) 0x1B,
93         (byte) 0x87, (byte) 0xFA, (byte) 0x06, (byte) 0x3F,
94         (byte) 0x5E, (byte) 0xBA, (byte) 0xAE, (byte) 0x5B,
95         (byte) 0x8A, (byte) 0x00, (byte) 0xBC, (byte) 0x9D,
96         (byte) 0x6D, (byte) 0xC1, (byte) 0xB1, (byte) 0x0E,
97         (byte) 0x80, (byte) 0x5D, (byte) 0xD2, (byte) 0xD5,
98         (byte) 0xA0, (byte) 0x84, (byte) 0x07, (byte) 0x14,
99         (byte) 0xB5, (byte) 0x90, (byte) 0x2C, (byte) 0xA3,
100         (byte) 0xB2, (byte) 0x73, (byte) 0x4C, (byte) 0x54,
101         (byte) 0x92, (byte) 0x74, (byte) 0x36, (byte) 0x51,
102         (byte) 0x38, (byte) 0xB0, (byte) 0xBD, (byte) 0x5A,
103         (byte) 0xFC, (byte) 0x60, (byte) 0x62, (byte) 0x96,
104         (byte) 0x6C, (byte) 0x42, (byte) 0xF7, (byte) 0x10,
105         (byte) 0x7C, (byte) 0x28, (byte) 0x27, (byte) 0x8C,
106         (byte) 0x13, (byte) 0x95, (byte) 0x9C, (byte) 0xC7,
107         (byte) 0x24, (byte) 0x46, (byte) 0x3B, (byte) 0x70,
108         (byte) 0xCA, (byte) 0xE3, (byte) 0x85, (byte) 0xCB,
109         (byte) 0x11, (byte) 0xD0, (byte) 0x93, (byte) 0xB8,
110         (byte) 0xA6, (byte) 0x83, (byte) 0x20, (byte) 0xFF,
111         (byte) 0x9F, (byte) 0x77, (byte) 0xC3, (byte) 0xCC,
112         (byte) 0x03, (byte) 0x6F, (byte) 0x08, (byte) 0xBF,
113         (byte) 0x40, (byte) 0xE7, (byte) 0x2B, (byte) 0xE2,
114         (byte) 0x79, (byte) 0x0C, (byte) 0xAA, (byte) 0x82,
115         (byte) 0x41, (byte) 0x3A, (byte) 0xEA, (byte) 0xB9,
116         (byte) 0xE4, (byte) 0x9A, (byte) 0xA4, (byte) 0x97,
117         (byte) 0x7E, (byte) 0xDA, (byte) 0x7A, (byte) 0x17,
118         (byte) 0x66, (byte) 0x94, (byte) 0xA1, (byte) 0x1D,
119         (byte) 0x3D, (byte) 0xF0, (byte) 0xDE, (byte) 0xB3,
120         (byte) 0x0B, (byte) 0x72, (byte) 0xA7, (byte) 0x1C,
121         (byte) 0xEF, (byte) 0xD1, (byte) 0x53, (byte) 0x3E,
122         (byte) 0x8F, (byte) 0x33, (byte) 0x26, (byte) 0x5F,
123         (byte) 0xEC, (byte) 0x76, (byte) 0x2A, (byte) 0x49,
124         (byte) 0x81, (byte) 0x88, (byte) 0xEE, (byte) 0x21,
125         (byte) 0xC4, (byte) 0x1A, (byte) 0xEB, (byte) 0xD9,
126         (byte) 0xC5, (byte) 0x39, (byte) 0x99, (byte) 0xCD,
127         (byte) 0xAD, (byte) 0x31, (byte) 0x8B, (byte) 0x01,
128         (byte) 0x18, (byte) 0x23, (byte) 0xDD, (byte) 0x1F,
129         (byte) 0x4E, (byte) 0x2D, (byte) 0xF9, (byte) 0x48,
130         (byte) 0x4F, (byte) 0xF2, (byte) 0x65, (byte) 0x8E,
131         (byte) 0x78, (byte) 0x5C, (byte) 0x58, (byte) 0x19,
132         (byte) 0x8D, (byte) 0xE5, (byte) 0x98, (byte) 0x57,
133         (byte) 0x67, (byte) 0x7F, (byte) 0x05, (byte) 0x64,
134         (byte) 0xAF, (byte) 0x63, (byte) 0xB6, (byte) 0xFE,
135         (byte) 0xF5, (byte) 0xB7, (byte) 0x3C, (byte) 0xA5,
136         (byte) 0xCE, (byte) 0xE9, (byte) 0x68, (byte) 0x44,
137         (byte) 0xE0, (byte) 0x4D, (byte) 0x43, (byte) 0x69,
138         (byte) 0x29, (byte) 0x2E, (byte) 0xAC, (byte) 0x15,
139         (byte) 0x59, (byte) 0xA8, (byte) 0x0A, (byte) 0x9E,
140         (byte) 0x6E, (byte) 0x47, (byte) 0xDF, (byte) 0x34,
141         (byte) 0x35, (byte) 0x6A, (byte) 0xCF, (byte) 0xDC,
142         (byte) 0x22, (byte) 0xC9, (byte) 0xC0, (byte) 0x9B,
143         (byte) 0x89, (byte) 0xD4, (byte) 0xED, (byte) 0xAB,
144         (byte) 0x12, (byte) 0xA2, (byte) 0x0D, (byte) 0x52,
145         (byte) 0xBB, (byte) 0x02, (byte) 0x2F, (byte) 0xA9,
146         (byte) 0xD7, (byte) 0x61, (byte) 0x1E, (byte) 0xB4,
147         (byte) 0x50, (byte) 0x04, (byte) 0xF6, (byte) 0xC2,
148         (byte) 0x16, (byte) 0x25, (byte) 0x86, (byte) 0x56,
149         (byte) 0x55, (byte) 0x09, (byte) 0xBE, (byte) 0x91  }
150     };
151 
152     /**
153     * Define the fixed p0/p1 permutations used in keyed S-box lookup.
154     * By changing the following constant definitions, the S-boxes will
155     * automatically get changed in the Twofish engine.
156     */
157     private static final int P_00 = 1;
158     private static final int P_01 = 0;
159     private static final int P_02 = 0;
160     private static final int P_03 = P_01 ^ 1;
161     private static final int P_04 = 1;
162 
163     private static final int P_10 = 0;
164     private static final int P_11 = 0;
165     private static final int P_12 = 1;
166     private static final int P_13 = P_11 ^ 1;
167     private static final int P_14 = 0;
168 
169     private static final int P_20 = 1;
170     private static final int P_21 = 1;
171     private static final int P_22 = 0;
172     private static final int P_23 = P_21 ^ 1;
173     private static final int P_24 = 0;
174 
175     private static final int P_30 = 0;
176     private static final int P_31 = 1;
177     private static final int P_32 = 1;
178     private static final int P_33 = P_31 ^ 1;
179     private static final int P_34 = 1;
180 
181     /* Primitive polynomial for GF(256) */
182     private static final int GF256_FDBK =   0x169;
183     private static final int GF256_FDBK_2 = GF256_FDBK / 2;
184     private static final int GF256_FDBK_4 = GF256_FDBK / 4;
185 
186     private static final int RS_GF_FDBK = 0x14D; // field generator
187 
188     //====================================
189     // Useful constants
190     //====================================
191 
192     private static final int    ROUNDS = 16;
193     private static final int    MAX_ROUNDS = 16;  // bytes = 128 bits
194     private static final int    BLOCK_SIZE = 16;  // bytes = 128 bits
195     private static final int    MAX_KEY_BITS = 256;
196 
197     private static final int    INPUT_WHITEN=0;
198     private static final int    OUTPUT_WHITEN=INPUT_WHITEN+BLOCK_SIZE/4; // 4
199     private static final int    ROUND_SUBKEYS=OUTPUT_WHITEN+BLOCK_SIZE/4;// 8
200 
201     private static final int    TOTAL_SUBKEYS=ROUND_SUBKEYS+2*MAX_ROUNDS;// 40
202 
203     private static final int    SK_STEP = 0x02020202;
204     private static final int    SK_BUMP = 0x01010101;
205     private static final int    SK_ROTL = 9;
206 
207     private boolean encrypting = false;
208 
209     private int[] gMDS0 = new int[MAX_KEY_BITS];
210     private int[] gMDS1 = new int[MAX_KEY_BITS];
211     private int[] gMDS2 = new int[MAX_KEY_BITS];
212     private int[] gMDS3 = new int[MAX_KEY_BITS];
213 
214     /**
215      * gSubKeys[] and gSBox[] are eventually used in the
216      * encryption and decryption methods.
217      */
218     private int[] gSubKeys;
219     private int[] gSBox;
220 
221     private int k64Cnt = 0;
222 
223     private byte[] workingKey = null;
224 
TwofishEngine()225     public TwofishEngine()
226     {
227         // calculate the MDS matrix
228         int[] m1 = new int[2];
229         int[] mX = new int[2];
230         int[] mY = new int[2];
231         int j;
232 
233         for (int i=0; i< MAX_KEY_BITS ; i++)
234         {
235             j = P[0][i] & 0xff;
236             m1[0] = j;
237             mX[0] = Mx_X(j) & 0xff;
238             mY[0] = Mx_Y(j) & 0xff;
239 
240             j = P[1][i] & 0xff;
241             m1[1] = j;
242             mX[1] = Mx_X(j) & 0xff;
243             mY[1] = Mx_Y(j) & 0xff;
244 
245             gMDS0[i] = m1[P_00]       | mX[P_00] <<  8 |
246                          mY[P_00] << 16 | mY[P_00] << 24;
247 
248             gMDS1[i] = mY[P_10]       | mY[P_10] <<  8 |
249                          mX[P_10] << 16 | m1[P_10] << 24;
250 
251             gMDS2[i] = mX[P_20]       | mY[P_20] <<  8 |
252                          m1[P_20] << 16 | mY[P_20] << 24;
253 
254             gMDS3[i] = mX[P_30]       | m1[P_30] <<  8 |
255                          mY[P_30] << 16 | mX[P_30] << 24;
256         }
257     }
258 
259     /**
260      * initialise a Twofish cipher.
261      *
262      * @param encrypting whether or not we are for encryption.
263      * @param params the parameters required to set up the cipher.
264      * @exception IllegalArgumentException if the params argument is
265      * inappropriate.
266      */
init( boolean encrypting, CipherParameters params)267     public void init(
268         boolean             encrypting,
269         CipherParameters    params)
270     {
271         if (params instanceof KeyParameter)
272         {
273             this.encrypting = encrypting;
274             this.workingKey = ((KeyParameter)params).getKey();
275             this.k64Cnt = (this.workingKey.length / 8); // pre-padded ?
276             setKey(this.workingKey);
277 
278             return;
279         }
280 
281         throw new IllegalArgumentException("invalid parameter passed to Twofish init - " + params.getClass().getName());
282     }
283 
getAlgorithmName()284     public String getAlgorithmName()
285     {
286         return "Twofish";
287     }
288 
processBlock( byte[] in, int inOff, byte[] out, int outOff)289     public int processBlock(
290         byte[] in,
291         int inOff,
292         byte[] out,
293         int outOff)
294     {
295         if (workingKey == null)
296         {
297             throw new IllegalStateException("Twofish not initialised");
298         }
299 
300         if ((inOff + BLOCK_SIZE) > in.length)
301         {
302             throw new DataLengthException("input buffer too short");
303         }
304 
305         if ((outOff + BLOCK_SIZE) > out.length)
306         {
307             throw new OutputLengthException("output buffer too short");
308         }
309 
310         if (encrypting)
311         {
312             encryptBlock(in, inOff, out, outOff);
313         }
314         else
315         {
316             decryptBlock(in, inOff, out, outOff);
317         }
318 
319         return BLOCK_SIZE;
320     }
321 
reset()322     public void reset()
323     {
324         if (this.workingKey != null)
325         {
326             setKey(this.workingKey);
327         }
328     }
329 
getBlockSize()330     public int getBlockSize()
331     {
332         return BLOCK_SIZE;
333     }
334 
335     //==================================
336     // Private Implementation
337     //==================================
338 
setKey(byte[] key)339     private void setKey(byte[] key)
340     {
341         int[] k32e = new int[MAX_KEY_BITS/64]; // 4
342         int[] k32o = new int[MAX_KEY_BITS/64]; // 4
343 
344         int[] sBoxKeys = new int[MAX_KEY_BITS/64]; // 4
345         gSubKeys = new int[TOTAL_SUBKEYS];
346 
347         if (k64Cnt < 1)
348         {
349             throw new IllegalArgumentException("Key size less than 64 bits");
350         }
351 
352         if (k64Cnt > 4)
353         {
354             throw new IllegalArgumentException("Key size larger than 256 bits");
355         }
356 
357         /*
358          * k64Cnt is the number of 8 byte blocks (64 chunks)
359          * that are in the input key.  The input key is a
360          * maximum of 32 bytes (256 bits), so the range
361          * for k64Cnt is 1..4
362          */
363         for (int i=0; i<k64Cnt ; i++)
364         {
365             int p = i* 8;
366 
367             k32e[i] = BytesTo32Bits(key, p);
368             k32o[i] = BytesTo32Bits(key, p+4);
369 
370             sBoxKeys[k64Cnt-1-i] = RS_MDS_Encode(k32e[i], k32o[i]);
371         }
372 
373         int q,A,B;
374         for (int i=0; i < TOTAL_SUBKEYS / 2 ; i++)
375         {
376             q = i*SK_STEP;
377             A = F32(q,         k32e);
378             B = F32(q+SK_BUMP, k32o);
379             B = B << 8 | B >>> 24;
380             A += B;
381             gSubKeys[i*2] = A;
382             A += B;
383             gSubKeys[i*2 + 1] = A << SK_ROTL | A >>> (32-SK_ROTL);
384         }
385 
386         /*
387          * fully expand the table for speed
388          */
389         int k0 = sBoxKeys[0];
390         int k1 = sBoxKeys[1];
391         int k2 = sBoxKeys[2];
392         int k3 = sBoxKeys[3];
393         int b0, b1, b2, b3;
394         gSBox = new int[4*MAX_KEY_BITS];
395         for (int i=0; i<MAX_KEY_BITS; i++)
396         {
397             b0 = b1 = b2 = b3 = i;
398             switch (k64Cnt & 3)
399             {
400                 case 1:
401                     gSBox[i*2]       = gMDS0[(P[P_01][b0] & 0xff) ^ b0(k0)];
402                     gSBox[i*2+1]     = gMDS1[(P[P_11][b1] & 0xff) ^ b1(k0)];
403                     gSBox[i*2+0x200] = gMDS2[(P[P_21][b2] & 0xff) ^ b2(k0)];
404                     gSBox[i*2+0x201] = gMDS3[(P[P_31][b3] & 0xff) ^ b3(k0)];
405                 break;
406                 case 0: // 256 bits of key
407                     b0 = (P[P_04][b0] & 0xff) ^ b0(k3);
408                     b1 = (P[P_14][b1] & 0xff) ^ b1(k3);
409                     b2 = (P[P_24][b2] & 0xff) ^ b2(k3);
410                     b3 = (P[P_34][b3] & 0xff) ^ b3(k3);
411                     // fall through, having pre-processed b[0]..b[3] with k32[3]
412                 case 3: // 192 bits of key
413                     b0 = (P[P_03][b0] & 0xff) ^ b0(k2);
414                     b1 = (P[P_13][b1] & 0xff) ^ b1(k2);
415                     b2 = (P[P_23][b2] & 0xff) ^ b2(k2);
416                     b3 = (P[P_33][b3] & 0xff) ^ b3(k2);
417                     // fall through, having pre-processed b[0]..b[3] with k32[2]
418                 case 2: // 128 bits of key
419                     gSBox[i*2]   = gMDS0[(P[P_01]
420                         [(P[P_02][b0] & 0xff) ^ b0(k1)] & 0xff) ^ b0(k0)];
421                     gSBox[i*2+1] = gMDS1[(P[P_11]
422                         [(P[P_12][b1] & 0xff) ^ b1(k1)] & 0xff) ^ b1(k0)];
423                     gSBox[i*2+0x200] = gMDS2[(P[P_21]
424                         [(P[P_22][b2] & 0xff) ^ b2(k1)] & 0xff) ^ b2(k0)];
425                     gSBox[i*2+0x201] = gMDS3[(P[P_31]
426                         [(P[P_32][b3] & 0xff) ^ b3(k1)] & 0xff) ^ b3(k0)];
427                 break;
428             }
429         }
430 
431         /*
432          * the function exits having setup the gSBox with the
433          * input key material.
434          */
435     }
436 
437     /**
438      * Encrypt the given input starting at the given offset and place
439      * the result in the provided buffer starting at the given offset.
440      * The input will be an exact multiple of our blocksize.
441      *
442      * encryptBlock uses the pre-calculated gSBox[] and subKey[]
443      * arrays.
444      */
encryptBlock( byte[] src, int srcIndex, byte[] dst, int dstIndex)445     private void encryptBlock(
446         byte[] src,
447         int srcIndex,
448         byte[] dst,
449         int dstIndex)
450     {
451         int x0 = BytesTo32Bits(src, srcIndex) ^ gSubKeys[INPUT_WHITEN];
452         int x1 = BytesTo32Bits(src, srcIndex + 4) ^ gSubKeys[INPUT_WHITEN + 1];
453         int x2 = BytesTo32Bits(src, srcIndex + 8) ^ gSubKeys[INPUT_WHITEN + 2];
454         int x3 = BytesTo32Bits(src, srcIndex + 12) ^ gSubKeys[INPUT_WHITEN + 3];
455 
456         int k = ROUND_SUBKEYS;
457         int t0, t1;
458         for (int r = 0; r < ROUNDS; r +=2)
459         {
460             t0 = Fe32_0(x0);
461             t1 = Fe32_3(x1);
462             x2 ^= t0 + t1 + gSubKeys[k++];
463             x2 = x2 >>>1 | x2 << 31;
464             x3 = (x3 << 1 | x3 >>> 31) ^ (t0 + 2*t1 + gSubKeys[k++]);
465 
466             t0 = Fe32_0(x2);
467             t1 = Fe32_3(x3);
468             x0 ^= t0 + t1 + gSubKeys[k++];
469             x0 = x0 >>>1 | x0 << 31;
470             x1 = (x1 << 1 | x1 >>> 31) ^ (t0 + 2*t1 + gSubKeys[k++]);
471         }
472 
473         Bits32ToBytes(x2 ^ gSubKeys[OUTPUT_WHITEN], dst, dstIndex);
474         Bits32ToBytes(x3 ^ gSubKeys[OUTPUT_WHITEN + 1], dst, dstIndex + 4);
475         Bits32ToBytes(x0 ^ gSubKeys[OUTPUT_WHITEN + 2], dst, dstIndex + 8);
476         Bits32ToBytes(x1 ^ gSubKeys[OUTPUT_WHITEN + 3], dst, dstIndex + 12);
477     }
478 
479     /**
480      * Decrypt the given input starting at the given offset and place
481      * the result in the provided buffer starting at the given offset.
482      * The input will be an exact multiple of our blocksize.
483      */
decryptBlock( byte[] src, int srcIndex, byte[] dst, int dstIndex)484     private void decryptBlock(
485         byte[] src,
486         int srcIndex,
487         byte[] dst,
488         int dstIndex)
489     {
490         int x2 = BytesTo32Bits(src, srcIndex) ^ gSubKeys[OUTPUT_WHITEN];
491         int x3 = BytesTo32Bits(src, srcIndex+4) ^ gSubKeys[OUTPUT_WHITEN + 1];
492         int x0 = BytesTo32Bits(src, srcIndex+8) ^ gSubKeys[OUTPUT_WHITEN + 2];
493         int x1 = BytesTo32Bits(src, srcIndex+12) ^ gSubKeys[OUTPUT_WHITEN + 3];
494 
495         int k = ROUND_SUBKEYS + 2 * ROUNDS -1 ;
496         int t0, t1;
497         for (int r = 0; r< ROUNDS ; r +=2)
498         {
499             t0 = Fe32_0(x2);
500             t1 = Fe32_3(x3);
501             x1 ^= t0 + 2*t1 + gSubKeys[k--];
502             x0 = (x0 << 1 | x0 >>> 31) ^ (t0 + t1 + gSubKeys[k--]);
503             x1 = x1 >>>1 | x1 << 31;
504 
505             t0 = Fe32_0(x0);
506             t1 = Fe32_3(x1);
507             x3 ^= t0 + 2*t1 + gSubKeys[k--];
508             x2 = (x2 << 1 | x2 >>> 31) ^ (t0 + t1 + gSubKeys[k--]);
509             x3 = x3 >>>1 | x3 << 31;
510         }
511 
512         Bits32ToBytes(x0 ^ gSubKeys[INPUT_WHITEN], dst, dstIndex);
513         Bits32ToBytes(x1 ^ gSubKeys[INPUT_WHITEN + 1], dst, dstIndex + 4);
514         Bits32ToBytes(x2 ^ gSubKeys[INPUT_WHITEN + 2], dst, dstIndex + 8);
515         Bits32ToBytes(x3 ^ gSubKeys[INPUT_WHITEN + 3], dst, dstIndex + 12);
516     }
517 
518     /*
519      * TODO:  This can be optimised and made cleaner by combining
520      * the functionality in this function and applying it appropriately
521      * to the creation of the subkeys during key setup.
522      */
F32(int x, int[] k32)523     private int F32(int x, int[] k32)
524     {
525         int b0 = b0(x);
526         int b1 = b1(x);
527         int b2 = b2(x);
528         int b3 = b3(x);
529         int k0 = k32[0];
530         int k1 = k32[1];
531         int k2 = k32[2];
532         int k3 = k32[3];
533 
534         int result = 0;
535         switch (k64Cnt & 3)
536         {
537             case 1:
538                 result = gMDS0[(P[P_01][b0] & 0xff) ^ b0(k0)] ^
539                          gMDS1[(P[P_11][b1] & 0xff) ^ b1(k0)] ^
540                          gMDS2[(P[P_21][b2] & 0xff) ^ b2(k0)] ^
541                          gMDS3[(P[P_31][b3] & 0xff) ^ b3(k0)];
542                 break;
543             case 0: /* 256 bits of key */
544                 b0 = (P[P_04][b0] & 0xff) ^ b0(k3);
545                 b1 = (P[P_14][b1] & 0xff) ^ b1(k3);
546                 b2 = (P[P_24][b2] & 0xff) ^ b2(k3);
547                 b3 = (P[P_34][b3] & 0xff) ^ b3(k3);
548             case 3:
549                 b0 = (P[P_03][b0] & 0xff) ^ b0(k2);
550                 b1 = (P[P_13][b1] & 0xff) ^ b1(k2);
551                 b2 = (P[P_23][b2] & 0xff) ^ b2(k2);
552                 b3 = (P[P_33][b3] & 0xff) ^ b3(k2);
553             case 2:
554                 result =
555                 gMDS0[(P[P_01][(P[P_02][b0]&0xff)^b0(k1)]&0xff)^b0(k0)] ^
556                 gMDS1[(P[P_11][(P[P_12][b1]&0xff)^b1(k1)]&0xff)^b1(k0)] ^
557                 gMDS2[(P[P_21][(P[P_22][b2]&0xff)^b2(k1)]&0xff)^b2(k0)] ^
558                 gMDS3[(P[P_31][(P[P_32][b3]&0xff)^b3(k1)]&0xff)^b3(k0)];
559             break;
560         }
561         return result;
562     }
563 
564     /**
565      * Use (12, 8) Reed-Solomon code over GF(256) to produce
566      * a key S-box 32-bit entity from 2 key material 32-bit
567      * entities.
568      *
569      * @param    k0 first 32-bit entity
570      * @param    k1 second 32-bit entity
571      * @return     Remainder polynomial generated using RS code
572      */
RS_MDS_Encode(int k0, int k1)573     private int RS_MDS_Encode(int k0, int k1)
574     {
575         int r = k1;
576         for (int i = 0 ; i < 4 ; i++) // shift 1 byte at a time
577         {
578             r = RS_rem(r);
579         }
580         r ^= k0;
581         for (int i=0 ; i < 4 ; i++)
582         {
583             r = RS_rem(r);
584         }
585 
586         return r;
587     }
588 
589     /**
590      * Reed-Solomon code parameters: (12,8) reversible code:<p>
591      * <pre>
592      * g(x) = x^4 + (a+1/a)x^3 + ax^2 + (a+1/a)x + 1
593      * </pre>
594      * where a = primitive root of field generator 0x14D
595      */
RS_rem(int x)596     private int RS_rem(int x)
597     {
598         int b = (x >>> 24) & 0xff;
599         int g2 = ((b << 1) ^
600                  ((b & 0x80) != 0 ? RS_GF_FDBK : 0)) & 0xff;
601         int g3 = ((b >>> 1) ^
602                  ((b & 0x01) != 0 ? (RS_GF_FDBK >>> 1) : 0)) ^ g2 ;
603         return ((x << 8) ^ (g3 << 24) ^ (g2 << 16) ^ (g3 << 8) ^ b);
604     }
605 
LFSR1(int x)606     private int LFSR1(int x)
607     {
608         return (x >> 1) ^
609                 (((x & 0x01) != 0) ? GF256_FDBK_2 : 0);
610     }
611 
LFSR2(int x)612     private int LFSR2(int x)
613     {
614         return (x >> 2) ^
615                 (((x & 0x02) != 0) ? GF256_FDBK_2 : 0) ^
616                 (((x & 0x01) != 0) ? GF256_FDBK_4 : 0);
617     }
618 
Mx_X(int x)619     private int Mx_X(int x)
620     {
621         return x ^ LFSR2(x);
622     } // 5B
623 
Mx_Y(int x)624     private int Mx_Y(int x)
625     {
626         return x ^ LFSR1(x) ^ LFSR2(x);
627     } // EF
628 
b0(int x)629     private int b0(int x)
630     {
631         return x & 0xff;
632     }
633 
b1(int x)634     private int b1(int x)
635     {
636         return (x >>> 8) & 0xff;
637     }
638 
b2(int x)639     private int b2(int x)
640     {
641         return (x >>> 16) & 0xff;
642     }
643 
b3(int x)644     private int b3(int x)
645     {
646         return (x >>> 24) & 0xff;
647     }
648 
Fe32_0(int x)649     private int Fe32_0(int x)
650     {
651         return gSBox[ 0x000 + 2*(x & 0xff) ] ^
652                gSBox[ 0x001 + 2*((x >>> 8) & 0xff) ] ^
653                gSBox[ 0x200 + 2*((x >>> 16) & 0xff) ] ^
654                gSBox[ 0x201 + 2*((x >>> 24) & 0xff) ];
655     }
656 
Fe32_3(int x)657     private int Fe32_3(int x)
658     {
659         return gSBox[ 0x000 + 2*((x >>> 24) & 0xff) ] ^
660                gSBox[ 0x001 + 2*(x & 0xff) ] ^
661                gSBox[ 0x200 + 2*((x >>> 8) & 0xff) ] ^
662                gSBox[ 0x201 + 2*((x >>> 16) & 0xff) ];
663     }
664 
BytesTo32Bits(byte[] b, int p)665     private int BytesTo32Bits(byte[] b, int p)
666     {
667         return ((b[p] & 0xff)) |
668              ((b[p+1] & 0xff) << 8) |
669              ((b[p+2] & 0xff) << 16) |
670              ((b[p+3] & 0xff) << 24);
671     }
672 
Bits32ToBytes(int in, byte[] b, int offset)673     private void Bits32ToBytes(int in,  byte[] b, int offset)
674     {
675         b[offset] = (byte)in;
676         b[offset + 1] = (byte)(in >> 8);
677         b[offset + 2] = (byte)(in >> 16);
678         b[offset + 3] = (byte)(in >> 24);
679     }
680 }
681