1 /*
2  * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 package com.sun.crypto.provider;
27 
28 import java.security.InvalidKeyException;
29 
30 /**
31  * This is the internal DES class responsible for encryption and
32  * decryption of a byte array of size <code>DES_BLOCK_SIZE</code>.
33  *
34  * @author Gigi Ankeny
35  * @author Jan Luehe
36  *
37  *
38  * @see DESConstants
39  * @see DESCipher
40  */
41 
42 class DESCrypt extends SymmetricCipher implements DESConstants {
43     private static final int s0p[] = {
44         0x00410100, 0x00010000, 0x40400000, 0x40410100, 0x00400000,
45         0x40010100, 0x40010000, 0x40400000, 0x40010100, 0x00410100,
46         0x00410000, 0x40000100, 0x40400100, 0x00400000, 0x00000000,
47         0x40010000, 0x00010000, 0x40000000, 0x00400100, 0x00010100,
48         0x40410100, 0x00410000, 0x40000100, 0x00400100, 0x40000000,
49         0x00000100, 0x00010100, 0x40410000, 0x00000100, 0x40400100,
50         0x40410000, 0x00000000, 0x00000000, 0x40410100, 0x00400100,
51         0x40010000, 0x00410100, 0x00010000, 0x40000100, 0x00400100,
52         0x40410000, 0x00000100, 0x00010100, 0x40400000, 0x40010100,
53         0x40000000, 0x40400000, 0x00410000, 0x40410100, 0x00010100,
54         0x00410000, 0x40400100, 0x00400000, 0x40000100, 0x40010000,
55         0x00000000, 0x00010000, 0x00400000, 0x40400100, 0x00410100,
56         0x40000000, 0x40410000, 0x00000100, 0x40010100,
57     };
58 
59     private static final int s1p[] = {
60         0x08021002, 0x00000000, 0x00021000, 0x08020000, 0x08000002,
61         0x00001002, 0x08001000, 0x00021000, 0x00001000, 0x08020002,
62         0x00000002, 0x08001000, 0x00020002, 0x08021000, 0x08020000,
63         0x00000002, 0x00020000, 0x08001002, 0x08020002, 0x00001000,
64         0x00021002, 0x08000000, 0x00000000, 0x00020002, 0x08001002,
65         0x00021002, 0x08021000, 0x08000002, 0x08000000, 0x00020000,
66         0x00001002, 0x08021002, 0x00020002, 0x08021000, 0x08001000,
67         0x00021002, 0x08021002, 0x00020002, 0x08000002, 0x00000000,
68         0x08000000, 0x00001002, 0x00020000, 0x08020002, 0x00001000,
69         0x08000000, 0x00021002, 0x08001002, 0x08021000, 0x00001000,
70         0x00000000, 0x08000002, 0x00000002, 0x08021002, 0x00021000,
71         0x08020000, 0x08020002, 0x00020000, 0x00001002, 0x08001000,
72         0x08001002, 0x00000002, 0x08020000, 0x00021000,
73     };
74 
75     private static final int s2p[] = {
76         0x20800000, 0x00808020, 0x00000020, 0x20800020, 0x20008000,
77         0x00800000, 0x20800020, 0x00008020, 0x00800020, 0x00008000,
78         0x00808000, 0x20000000, 0x20808020, 0x20000020, 0x20000000,
79         0x20808000, 0x00000000, 0x20008000, 0x00808020, 0x00000020,
80         0x20000020, 0x20808020, 0x00008000, 0x20800000, 0x20808000,
81         0x00800020, 0x20008020, 0x00808000, 0x00008020, 0x00000000,
82         0x00800000, 0x20008020, 0x00808020, 0x00000020, 0x20000000,
83         0x00008000, 0x20000020, 0x20008000, 0x00808000, 0x20800020,
84         0x00000000, 0x00808020, 0x00008020, 0x20808000, 0x20008000,
85         0x00800000, 0x20808020, 0x20000000, 0x20008020, 0x20800000,
86         0x00800000, 0x20808020, 0x00008000, 0x00800020, 0x20800020,
87         0x00008020, 0x00800020, 0x00000000, 0x20808000, 0x20000020,
88         0x20800000, 0x20008020, 0x00000020, 0x00808000,
89     };
90 
91     private static final int s3p[] = {
92         0x00080201, 0x02000200, 0x00000001, 0x02080201, 0x00000000,
93         0x02080000, 0x02000201, 0x00080001, 0x02080200, 0x02000001,
94         0x02000000, 0x00000201, 0x02000001, 0x00080201, 0x00080000,
95         0x02000000, 0x02080001, 0x00080200, 0x00000200, 0x00000001,
96         0x00080200, 0x02000201, 0x02080000, 0x00000200, 0x00000201,
97         0x00000000, 0x00080001, 0x02080200, 0x02000200, 0x02080001,
98         0x02080201, 0x00080000, 0x02080001, 0x00000201, 0x00080000,
99         0x02000001, 0x00080200, 0x02000200, 0x00000001, 0x02080000,
100         0x02000201, 0x00000000, 0x00000200, 0x00080001, 0x00000000,
101         0x02080001, 0x02080200, 0x00000200, 0x02000000, 0x02080201,
102         0x00080201, 0x00080000, 0x02080201, 0x00000001, 0x02000200,
103         0x00080201, 0x00080001, 0x00080200, 0x02080000, 0x02000201,
104         0x00000201, 0x02000000, 0x02000001, 0x02080200,
105     };
106 
107     private static final int s4p[] = {
108         0x01000000, 0x00002000, 0x00000080, 0x01002084, 0x01002004,
109         0x01000080, 0x00002084, 0x01002000, 0x00002000, 0x00000004,
110         0x01000004, 0x00002080, 0x01000084, 0x01002004, 0x01002080,
111         0x00000000, 0x00002080, 0x01000000, 0x00002004, 0x00000084,
112         0x01000080, 0x00002084, 0x00000000, 0x01000004, 0x00000004,
113         0x01000084, 0x01002084, 0x00002004, 0x01002000, 0x00000080,
114         0x00000084, 0x01002080, 0x01002080, 0x01000084, 0x00002004,
115         0x01002000, 0x00002000, 0x00000004, 0x01000004, 0x01000080,
116         0x01000000, 0x00002080, 0x01002084, 0x00000000, 0x00002084,
117         0x01000000, 0x00000080, 0x00002004, 0x01000084, 0x00000080,
118         0x00000000, 0x01002084, 0x01002004, 0x01002080, 0x00000084,
119         0x00002000, 0x00002080, 0x01002004, 0x01000080, 0x00000084,
120         0x00000004, 0x00002084, 0x01002000, 0x01000004,
121     };
122 
123     private static final int s5p[] = {
124         0x10000008, 0x00040008, 0x00000000, 0x10040400, 0x00040008,
125         0x00000400, 0x10000408, 0x00040000, 0x00000408, 0x10040408,
126         0x00040400, 0x10000000, 0x10000400, 0x10000008, 0x10040000,
127         0x00040408, 0x00040000, 0x10000408, 0x10040008, 0x00000000,
128         0x00000400, 0x00000008, 0x10040400, 0x10040008, 0x10040408,
129         0x10040000, 0x10000000, 0x00000408, 0x00000008, 0x00040400,
130         0x00040408, 0x10000400, 0x00000408, 0x10000000, 0x10000400,
131         0x00040408, 0x10040400, 0x00040008, 0x00000000, 0x10000400,
132         0x10000000, 0x00000400, 0x10040008, 0x00040000, 0x00040008,
133         0x10040408, 0x00040400, 0x00000008, 0x10040408, 0x00040400,
134         0x00040000, 0x10000408, 0x10000008, 0x10040000, 0x00040408,
135         0x00000000, 0x00000400, 0x10000008, 0x10000408, 0x10040400,
136         0x10040000, 0x00000408, 0x00000008, 0x10040008,
137     };
138 
139     private static final int s6p[] = {
140         0x00000800, 0x00000040, 0x00200040, 0x80200000, 0x80200840,
141         0x80000800, 0x00000840, 0x00000000, 0x00200000, 0x80200040,
142         0x80000040, 0x00200800, 0x80000000, 0x00200840, 0x00200800,
143         0x80000040, 0x80200040, 0x00000800, 0x80000800, 0x80200840,
144         0x00000000, 0x00200040, 0x80200000, 0x00000840, 0x80200800,
145         0x80000840, 0x00200840, 0x80000000, 0x80000840, 0x80200800,
146         0x00000040, 0x00200000, 0x80000840, 0x00200800, 0x80200800,
147         0x80000040, 0x00000800, 0x00000040, 0x00200000, 0x80200800,
148         0x80200040, 0x80000840, 0x00000840, 0x00000000, 0x00000040,
149         0x80200000, 0x80000000, 0x00200040, 0x00000000, 0x80200040,
150         0x00200040, 0x00000840, 0x80000040, 0x00000800, 0x80200840,
151         0x00200000, 0x00200840, 0x80000000, 0x80000800, 0x80200840,
152         0x80200000, 0x00200840, 0x00200800, 0x80000800,
153     };
154 
155     private static final int s7p[] = {
156         0x04100010, 0x04104000, 0x00004010, 0x00000000, 0x04004000,
157         0x00100010, 0x04100000, 0x04104010, 0x00000010, 0x04000000,
158         0x00104000, 0x00004010, 0x00104010, 0x04004010, 0x04000010,
159         0x04100000, 0x00004000, 0x00104010, 0x00100010, 0x04004000,
160         0x04104010, 0x04000010, 0x00000000, 0x00104000, 0x04000000,
161         0x00100000, 0x04004010, 0x04100010, 0x00100000, 0x00004000,
162         0x04104000, 0x00000010, 0x00100000, 0x00004000, 0x04000010,
163         0x04104010, 0x00004010, 0x04000000, 0x00000000, 0x00104000,
164         0x04100010, 0x04004010, 0x04004000, 0x00100010, 0x04104000,
165         0x00000010, 0x00100010, 0x04004000, 0x04104010, 0x00100000,
166         0x04100000, 0x04000010, 0x00104000, 0x00004010, 0x04004010,
167         0x04100000, 0x00000010, 0x04104000, 0x00104010, 0x00000000,
168         0x04000000, 0x04100010, 0x00004000, 0x00104010,
169     };
170 
171     private static final int permRight0[] = {
172         0x00000000, 0x40000000, 0x00400000, 0x40400000, 0x00004000,
173         0x40004000, 0x00404000, 0x40404000, 0x00000040, 0x40000040,
174         0x00400040, 0x40400040, 0x00004040, 0x40004040, 0x00404040,
175         0x40404040,
176     };
177 
178     private static final int permLeft1[] = {
179         0x00000000, 0x40000000, 0x00400000, 0x40400000, 0x00004000,
180         0x40004000, 0x00404000, 0x40404000, 0x00000040, 0x40000040,
181         0x00400040, 0x40400040, 0x00004040, 0x40004040, 0x00404040,
182         0x40404040,
183     };
184 
185     private static final int permRight2[] = {
186         0x00000000, 0x10000000, 0x00100000, 0x10100000, 0x00001000,
187         0x10001000, 0x00101000, 0x10101000, 0x00000010, 0x10000010,
188         0x00100010, 0x10100010, 0x00001010, 0x10001010, 0x00101010,
189         0x10101010,
190     };
191 
192     private static final int permLeft3[] = {
193         0x00000000, 0x10000000, 0x00100000, 0x10100000, 0x00001000,
194         0x10001000, 0x00101000, 0x10101000, 0x00000010, 0x10000010,
195         0x00100010, 0x10100010, 0x00001010, 0x10001010, 0x00101010,
196         0x10101010,
197     };
198 
199     private static final int permRight4[] = {
200         0x00000000, 0x04000000, 0x00040000, 0x04040000, 0x00000400,
201         0x04000400, 0x00040400, 0x04040400, 0x00000004, 0x04000004,
202         0x00040004, 0x04040004, 0x00000404, 0x04000404, 0x00040404,
203         0x04040404,
204     };
205 
206     private static final int permLeft5[] = {
207         0x00000000, 0x04000000, 0x00040000, 0x04040000, 0x00000400,
208         0x04000400, 0x00040400, 0x04040400, 0x00000004, 0x04000004,
209         0x00040004, 0x04040004, 0x00000404, 0x04000404, 0x00040404,
210         0x04040404,
211     };
212 
213     private static final int permRight6[] = {
214         0x00000000, 0x01000000, 0x00010000, 0x01010000, 0x00000100,
215         0x01000100, 0x00010100, 0x01010100, 0x00000001, 0x01000001,
216         0x00010001, 0x01010001, 0x00000101, 0x01000101, 0x00010101,
217         0x01010101,
218     };
219 
220     private static final int permLeft7[] = {
221         0x00000000, 0x01000000, 0x00010000, 0x01010000, 0x00000100,
222         0x01000100, 0x00010100, 0x01010100, 0x00000001, 0x01000001,
223         0x00010001, 0x01010001, 0x00000101, 0x01000101, 0x00010101,
224         0x01010101,
225     };
226 
227     private static final int permRight8[] = {
228         0x00000000, 0x80000000, 0x00800000, 0x80800000, 0x00008000,
229         0x80008000, 0x00808000, 0x80808000, 0x00000080, 0x80000080,
230         0x00800080, 0x80800080, 0x00008080, 0x80008080, 0x00808080,
231         0x80808080,
232     };
233 
234     private static final int permLeft9[] = {
235         0x00000000, 0x80000000, 0x00800000, 0x80800000, 0x00008000,
236         0x80008000, 0x00808000, 0x80808000, 0x00000080, 0x80000080,
237         0x00800080, 0x80800080, 0x00008080, 0x80008080, 0x00808080,
238         0x80808080,
239     };
240 
241     private static final int permRightA[] = {
242         0x00000000, 0x20000000, 0x00200000, 0x20200000, 0x00002000,
243         0x20002000, 0x00202000, 0x20202000, 0x00000020, 0x20000020,
244         0x00200020, 0x20200020, 0x00002020, 0x20002020, 0x00202020,
245         0x20202020,
246     };
247 
248     private static final int permLeftB[] = {
249         0x00000000, 0x20000000, 0x00200000, 0x20200000, 0x00002000,
250         0x20002000, 0x00202000, 0x20202000, 0x00000020, 0x20000020,
251         0x00200020, 0x20200020, 0x00002020, 0x20002020, 0x00202020,
252         0x20202020,
253     };
254 
255     private static final int permRightC[] = {
256         0x00000000, 0x08000000, 0x00080000, 0x08080000, 0x00000800,
257         0x08000800, 0x00080800, 0x08080800, 0x00000008, 0x08000008,
258         0x00080008, 0x08080008, 0x00000808, 0x08000808, 0x00080808,
259         0x08080808,
260     };
261 
262     private static final int permLeftD[] = {
263         0x00000000, 0x08000000, 0x00080000, 0x08080000, 0x00000800,
264         0x08000800, 0x00080800, 0x08080800, 0x00000008, 0x08000008,
265         0x00080008, 0x08080008, 0x00000808, 0x08000808, 0x00080808,
266         0x08080808,
267     };
268 
269     private static final int permRightE[] = {
270         0x00000000, 0x02000000, 0x00020000, 0x02020000, 0x00000200,
271         0x02000200, 0x00020200, 0x02020200, 0x00000002, 0x02000002,
272         0x00020002, 0x02020002, 0x00000202, 0x02000202, 0x00020202,
273         0x02020202,
274     };
275 
276     private static final int permLeftF[] = {
277         0x00000000, 0x02000000, 0x00020000, 0x02020000, 0x00000200,
278         0x02000200, 0x00020200, 0x02020200, 0x00000002, 0x02000002,
279         0x00020002, 0x02020002, 0x00000202, 0x02000202, 0x00020202,
280         0x02020202,
281     };
282 
283     /*
284      *        Initial Permutation
285      */
286     private static final int initPermLeft0[] = {
287        0x00000000, 0x00008000, 0x00000000, 0x00008000, 0x00000080,
288        0x00008080, 0x00000080, 0x00008080, 0x00000000, 0x00008000,
289        0x00000000, 0x00008000, 0x00000080, 0x00008080, 0x00000080,
290        0x00008080,
291     };
292 
293     private static final int initPermRight0[] = {
294        0x00000000, 0x00000000, 0x00008000, 0x00008000, 0x00000000,
295        0x00000000, 0x00008000, 0x00008000, 0x00000080, 0x00000080,
296        0x00008080, 0x00008080, 0x00000080, 0x00000080, 0x00008080,
297        0x00008080,
298     };
299 
300     private static final int initPermLeft1[] = {
301        0x00000000, 0x80000000, 0x00000000, 0x80000000, 0x00800000,
302        0x80800000, 0x00800000, 0x80800000, 0x00000000, 0x80000000,
303        0x00000000, 0x80000000, 0x00800000, 0x80800000, 0x00800000,
304        0x80800000,
305     };
306 
307     private static final int initPermRight1[] = {
308        0x00000000, 0x00000000, 0x80000000, 0x80000000, 0x00000000,
309        0x00000000, 0x80000000, 0x80000000, 0x00800000, 0x00800000,
310        0x80800000, 0x80800000, 0x00800000, 0x00800000, 0x80800000,
311        0x80800000,
312     };
313 
314     private static final int initPermLeft2[] = {
315        0x00000000, 0x00004000, 0x00000000, 0x00004000, 0x00000040,
316        0x00004040, 0x00000040, 0x00004040, 0x00000000, 0x00004000,
317        0x00000000, 0x00004000, 0x00000040, 0x00004040, 0x00000040,
318        0x00004040,
319     };
320 
321     private static final int initPermRight2[] = {
322        0x00000000, 0x00000000, 0x00004000, 0x00004000, 0x00000000,
323        0x00000000, 0x00004000, 0x00004000, 0x00000040, 0x00000040,
324        0x00004040, 0x00004040, 0x00000040, 0x00000040, 0x00004040,
325        0x00004040,
326     };
327 
328     private static final int initPermLeft3[] = {
329        0x00000000, 0x40000000, 0x00000000, 0x40000000, 0x00400000,
330        0x40400000, 0x00400000, 0x40400000, 0x00000000, 0x40000000,
331        0x00000000, 0x40000000, 0x00400000, 0x40400000, 0x00400000,
332        0x40400000,
333     };
334 
335     private static final int initPermRight3[] = {
336        0x00000000, 0x00000000, 0x40000000, 0x40000000, 0x00000000,
337        0x00000000, 0x40000000, 0x40000000, 0x00400000, 0x00400000,
338        0x40400000, 0x40400000, 0x00400000, 0x00400000, 0x40400000,
339        0x40400000,
340     };
341 
342     private static final int initPermLeft4[] = {
343        0x00000000, 0x00002000, 0x00000000, 0x00002000, 0x00000020,
344        0x00002020, 0x00000020, 0x00002020, 0x00000000, 0x00002000,
345        0x00000000, 0x00002000, 0x00000020, 0x00002020, 0x00000020,
346        0x00002020,
347     };
348 
349     private static final int initPermRight4[] = {
350        0x00000000, 0x00000000, 0x00002000, 0x00002000, 0x00000000,
351        0x00000000, 0x00002000, 0x00002000, 0x00000020, 0x00000020,
352        0x00002020, 0x00002020, 0x00000020, 0x00000020, 0x00002020,
353        0x00002020,
354     };
355 
356     private static final int initPermLeft5[] = {
357        0x00000000, 0x20000000, 0x00000000, 0x20000000, 0x00200000,
358        0x20200000, 0x00200000, 0x20200000, 0x00000000, 0x20000000,
359        0x00000000, 0x20000000, 0x00200000, 0x20200000, 0x00200000,
360        0x20200000,
361     };
362 
363     private static final int initPermRight5[] = {
364        0x00000000, 0x00000000, 0x20000000, 0x20000000, 0x00000000,
365        0x00000000, 0x20000000, 0x20000000, 0x00200000, 0x00200000,
366        0x20200000, 0x20200000, 0x00200000, 0x00200000, 0x20200000,
367        0x20200000,
368     };
369 
370     private static final int initPermLeft6[] = {
371        0x00000000, 0x00001000, 0x00000000, 0x00001000, 0x00000010,
372        0x00001010, 0x00000010, 0x00001010, 0x00000000, 0x00001000,
373        0x00000000, 0x00001000, 0x00000010, 0x00001010, 0x00000010,
374        0x00001010,
375     };
376 
377     private static final int initPermRight6[] = {
378        0x00000000, 0x00000000, 0x00001000, 0x00001000, 0x00000000,
379        0x00000000, 0x00001000, 0x00001000, 0x00000010, 0x00000010,
380        0x00001010, 0x00001010, 0x00000010, 0x00000010, 0x00001010,
381        0x00001010,
382     };
383 
384     private static final int initPermLeft7[] = {
385        0x00000000, 0x10000000, 0x00000000, 0x10000000, 0x00100000,
386        0x10100000, 0x00100000, 0x10100000, 0x00000000, 0x10000000,
387        0x00000000, 0x10000000, 0x00100000, 0x10100000, 0x00100000,
388        0x10100000,
389     };
390 
391     private static final int initPermRight7[] = {
392        0x00000000, 0x00000000, 0x10000000, 0x10000000, 0x00000000,
393        0x00000000, 0x10000000, 0x10000000, 0x00100000, 0x00100000,
394        0x10100000, 0x10100000, 0x00100000, 0x00100000, 0x10100000,
395        0x10100000,
396     };
397 
398     private static final int initPermLeft8[] = {
399        0x00000000, 0x00000800, 0x00000000, 0x00000800, 0x00000008,
400        0x00000808, 0x00000008, 0x00000808, 0x00000000, 0x00000800,
401        0x00000000, 0x00000800, 0x00000008, 0x00000808, 0x00000008,
402        0x00000808,
403     };
404 
405     private static final int initPermRight8[] = {
406        0x00000000, 0x00000000, 0x00000800, 0x00000800, 0x00000000,
407        0x00000000, 0x00000800, 0x00000800, 0x00000008, 0x00000008,
408        0x00000808, 0x00000808, 0x00000008, 0x00000008, 0x00000808,
409        0x00000808,
410     };
411 
412     private static final int initPermLeft9[] = {
413        0x00000000, 0x08000000, 0x00000000, 0x08000000, 0x00080000,
414        0x08080000, 0x00080000, 0x08080000, 0x00000000, 0x08000000,
415        0x00000000, 0x08000000, 0x00080000, 0x08080000, 0x00080000,
416        0x08080000,
417     };
418 
419     private static final int initPermRight9[] = {
420        0x00000000, 0x00000000, 0x08000000, 0x08000000, 0x00000000,
421        0x00000000, 0x08000000, 0x08000000, 0x00080000, 0x00080000,
422        0x08080000, 0x08080000, 0x00080000, 0x00080000, 0x08080000,
423        0x08080000,
424     };
425 
426     private static final int initPermLeftA[] = {
427        0x00000000, 0x00000400, 0x00000000, 0x00000400, 0x00000004,
428        0x00000404, 0x00000004, 0x00000404, 0x00000000, 0x00000400,
429        0x00000000, 0x00000400, 0x00000004, 0x00000404, 0x00000004,
430        0x00000404,
431     };
432 
433     private static final int initPermRightA[] = {
434        0x00000000, 0x00000000, 0x00000400, 0x00000400, 0x00000000,
435        0x00000000, 0x00000400, 0x00000400, 0x00000004, 0x00000004,
436        0x00000404, 0x00000404, 0x00000004, 0x00000004, 0x00000404,
437        0x00000404,
438     };
439 
440     private static final int initPermLeftB[] = {
441        0x00000000, 0x04000000, 0x00000000, 0x04000000, 0x00040000,
442        0x04040000, 0x00040000, 0x04040000, 0x00000000, 0x04000000,
443        0x00000000, 0x04000000, 0x00040000, 0x04040000, 0x00040000,
444        0x04040000,
445     };
446 
447     private static final int initPermRightB[] = {
448        0x00000000, 0x00000000, 0x04000000, 0x04000000, 0x00000000,
449        0x00000000, 0x04000000, 0x04000000, 0x00040000, 0x00040000,
450        0x04040000, 0x04040000, 0x00040000, 0x00040000, 0x04040000,
451        0x04040000,
452     };
453 
454     private static final int initPermLeftC[] = {
455        0x00000000, 0x00000200, 0x00000000, 0x00000200, 0x00000002,
456        0x00000202, 0x00000002, 0x00000202, 0x00000000, 0x00000200,
457        0x00000000, 0x00000200, 0x00000002, 0x00000202, 0x00000002,
458        0x00000202,
459     };
460 
461     private static final int initPermRightC[] = {
462        0x00000000, 0x00000000, 0x00000200, 0x00000200, 0x00000000,
463        0x00000000, 0x00000200, 0x00000200, 0x00000002, 0x00000002,
464        0x00000202, 0x00000202, 0x00000002, 0x00000002, 0x00000202,
465        0x00000202,
466     };
467 
468     private static final int initPermLeftD[] = {
469        0x00000000, 0x02000000, 0x00000000, 0x02000000, 0x00020000,
470        0x02020000, 0x00020000, 0x02020000, 0x00000000, 0x02000000,
471        0x00000000, 0x02000000, 0x00020000, 0x02020000, 0x00020000,
472        0x02020000,
473     };
474 
475     private static final int initPermRightD[] = {
476        0x00000000, 0x00000000, 0x02000000, 0x02000000, 0x00000000,
477        0x00000000, 0x02000000, 0x02000000, 0x00020000, 0x00020000,
478        0x02020000, 0x02020000, 0x00020000, 0x00020000, 0x02020000,
479        0x02020000,
480     };
481 
482     private static final int initPermLeftE[] = {
483        0x00000000, 0x00000100, 0x00000000, 0x00000100, 0x00000001,
484        0x00000101, 0x00000001, 0x00000101, 0x00000000, 0x00000100,
485        0x00000000, 0x00000100, 0x00000001, 0x00000101, 0x00000001,
486        0x00000101,
487     };
488 
489     private static final int initPermRightE[] = {
490        0x00000000, 0x00000000, 0x00000100, 0x00000100, 0x00000000,
491        0x00000000, 0x00000100, 0x00000100, 0x00000001, 0x00000001,
492        0x00000101, 0x00000101, 0x00000001, 0x00000001, 0x00000101,
493        0x00000101,
494     };
495 
496     private static final int initPermLeftF[] = {
497        0x00000000, 0x01000000, 0x00000000, 0x01000000, 0x00010000,
498        0x01010000, 0x00010000, 0x01010000, 0x00000000, 0x01000000,
499        0x00000000, 0x01000000, 0x00010000, 0x01010000, 0x00010000,
500        0x01010000,
501     };
502 
503     private static final int initPermRightF[] = {
504        0x00000000, 0x00000000, 0x01000000, 0x01000000, 0x00000000,
505        0x00000000, 0x01000000, 0x01000000, 0x00010000, 0x00010000,
506        0x01010000, 0x01010000, 0x00010000, 0x00010000, 0x01010000,
507        0x01010000,
508     };
509 
510     /*
511      * the encryption key array after expansion and permutation
512      */
513     byte[] expandedKey = null;
514 
515     /*
516      * Are we encrypting or decrypting?
517      */
518     boolean decrypting = false;
519 
520     /**
521      * Returns this cipher's block size.
522      *
523      * @return this cipher's block size
524      */
getBlockSize()525     int getBlockSize() {
526         return DES_BLOCK_SIZE;
527     }
528 
init(boolean decrypting, String algorithm, byte[] rawKey)529     void init(boolean decrypting, String algorithm, byte[] rawKey)
530             throws InvalidKeyException {
531         this.decrypting = decrypting;
532         if (!algorithm.equalsIgnoreCase("DES")) {
533             throw new InvalidKeyException("Wrong algorithm: DES required");
534         }
535         if (rawKey.length != DES_BLOCK_SIZE) {
536             throw new InvalidKeyException("Wrong key size");
537         }
538         expandKey(rawKey);
539     }
540 
541     /**
542      * Performs encryption operation.
543      *
544      * <p>The input plain text <code>plain</code>, starting at
545      * <code>plainOffset</code> and ending at
546      * <code>(plainOffset + len - 1)</code>, is encrypted.
547      * The result is stored in <code>cipher</code>, starting at
548      * <code>cipherOffset</code>.
549      *
550      * <p>The subclass that implements Cipher should ensure that
551      * <code>init</code> has been called before this method is called.
552      *
553      * @param plain the buffer with the input data to be encrypted
554      * @param plainOffset the offset in <code>plain</code>
555      * @param cipher the buffer for the result
556      * @param cipherOffset the offset in <code>cipher</code>
557      */
encryptBlock(byte[] plain, int plainOffset, byte[] cipher, int cipherOffset)558     void encryptBlock(byte[] plain, int plainOffset,
559                  byte[] cipher, int cipherOffset)
560     {
561         cipherBlock(plain, plainOffset, cipher, cipherOffset);
562     }
563 
564     /**
565      * Performs decryption operation.
566      *
567      * <p>The input cipher text <code>cipher</code>, starting at
568      * <code>cipherOffset</code> and ending at
569      * <code>(cipherOffset + len - 1)</code>, is decrypted.
570      * The result is stored in <code>plain</code>, starting at
571      * <code>plainOffset</code>.
572      *
573      * <p>The subclass that implements Cipher should ensure that
574      * <code>init</code> has been called before this method is called.
575      *
576      * @param cipher the buffer with the input data to be decrypted
577      * @param cipherOffset the offset in <code>cipherOffset</code>
578      * @param plain the buffer for the result
579      * @param plainOffset the offset in <code>plain</code>
580      */
decryptBlock(byte[] cipher, int cipherOffset, byte[] plain, int plainOffset)581     void decryptBlock(byte[] cipher, int cipherOffset,
582                  byte[] plain, int plainOffset)
583     {
584         cipherBlock(cipher, cipherOffset, plain, plainOffset);
585     }
586 
587 
cipherBlock(byte[] in, int inOffset, byte[] out, int outOffset)588     void cipherBlock(byte[] in, int inOffset, byte[] out, int outOffset) {
589         byte key[];
590         int temp;
591         int i, j;
592         int offset;
593         int left, right;
594 
595         left = initialPermutationLeft(in, inOffset);
596         right = initialPermutationRight(in, inOffset);
597 
598         key = expandedKey;
599 
600         if (decrypting) {
601             offset = 16 - DES_BLOCK_SIZE;
602             j = 128 - DES_BLOCK_SIZE;
603 
604         } else {
605             offset = 0 - DES_BLOCK_SIZE;
606             j = 0;
607         }
608 
609         for (i = 0; i < 16; i++) {
610             // make the first and last bit adjacent
611             // move the first bit to the last
612             temp = (right << 1) | ((right >> 31) & 1);
613 
614             // mangler function:
615             // every 6 bit is fed into the sbox, which
616             // produces 4-bit output
617             left ^= s0p[(temp & 0x3f) ^ key[j+0]]
618                 ^ s1p[((temp >>  4) & 0x3f) ^ key[j+1]]
619                 ^ s2p[((temp >>  8) & 0x3f) ^ key[j+2]]
620                 ^ s3p[((temp >> 12) & 0x3f) ^ key[j+3]]
621                 ^ s4p[((temp >> 16) & 0x3f) ^ key[j+4]]
622                 ^ s5p[((temp >> 20) & 0x3f) ^ key[j+5]]
623                 ^ s6p[((temp >> 24) & 0x3f) ^ key[j+6]];
624 
625             // make the last sbox input the last bit from right[0]
626             temp = ((right & 1) << 5) | ((right >> 27) & 0x1f);
627             left ^= s7p[temp ^ key[j+7]];
628             temp = left;
629             left = right;
630             right = temp;
631             j -= offset;
632         }
633 
634         temp = left;
635         left = right;
636         right = temp;
637         perm(left, right, out, outOffset);
638     }
639 
perm(int left, int right, byte out[], int offset)640     private static void perm(int left, int right,
641                              byte out[], int offset) {
642         int low, high, temp;
643 
644         temp = left;
645         high = permRight0[temp & 0x0000000f];
646         temp >>= 4;
647         low  = permLeft1[temp & 0x0000000f];
648         temp >>= 4;
649         high |= permRight2[temp & 0x0000000f];
650         temp >>= 4;
651         low  |= permLeft3[temp & 0x0000000f];
652         temp >>= 4;
653         high |= permRight4[temp & 0x0000000f];
654         temp >>= 4;
655         low  |= permLeft5[temp & 0x0000000f];
656         temp >>= 4;
657         high |= permRight6[temp & 0x0000000f];
658         temp >>= 4;
659         low  |= permLeft7[temp & 0x0000000f];
660 
661         temp = right;
662         high |= permRight8[temp & 0x0000000f];
663         temp >>= 4;
664         low  |= permLeft9[temp & 0x0000000f];
665         temp >>= 4;
666         high |= permRightA[temp & 0x0000000f];
667         temp >>= 4;
668         low  |= permLeftB[temp & 0x0000000f];
669         temp >>= 4;
670         high |= permRightC[temp & 0x0000000f];
671         temp >>= 4;
672         low  |= permLeftD[temp & 0x0000000f];
673         temp >>= 4;
674         high |= permRightE[temp & 0x0000000f];
675         temp >>= 4;
676         low  |= permLeftF[temp & 0x0000000f];
677 
678 
679         out[offset + 0] = (byte)low;
680         out[offset + 1] = (byte)(low >> 8);
681         out[offset + 2] = (byte)(low >> 16);
682         out[offset + 3] = (byte)(low >> 24);
683         out[offset + 4] = (byte)high;
684         out[offset + 5] = (byte)(high >> 8);
685         out[offset + 6] = (byte)(high >> 16);
686         out[offset + 7] = (byte)(high >> 24);
687 
688     }
689 
initialPermutationLeft(byte block[], int offset)690     private static int initialPermutationLeft(byte block[], int offset) {
691         int l;
692 
693         l  = initPermLeft1[block[offset] & 0xf];
694         l |= initPermLeft0[(block[offset] >> 4) & 0xf];
695         l |= initPermLeft3[block[offset + 1] & 0xf];
696         l |= initPermLeft2[(block[offset + 1] >> 4) & 0xf];
697         l |= initPermLeft5[block[offset + 2] & 0xf];
698         l |= initPermLeft4[(block[offset + 2] >> 4) & 0xf];
699         l |= initPermLeft7[block[offset + 3] & 0xf];
700         l |= initPermLeft6[(block[offset + 3] >> 4) & 0xf];
701         l |= initPermLeft9[block[offset + 4] & 0xf];
702         l |= initPermLeft8[(block[offset + 4] >> 4) & 0xf];
703         l |= initPermLeftB[block[offset + 5] & 0xf];
704         l |= initPermLeftA[(block[offset + 5] >> 4) & 0xf];
705         l |= initPermLeftD[block[offset + 6] & 0xf];
706         l |= initPermLeftC[(block[offset + 6] >> 4) & 0xf];
707         l |= initPermLeftF[block[offset + 7] & 0xf];
708         l |= initPermLeftE[(block[offset + 7] >> 4) & 0xf];
709         return l;
710     }
711 
initialPermutationRight(byte block[], int offset)712     private static int initialPermutationRight(byte block[], int offset) {
713         int l;
714 
715         l  = initPermRight1[block[offset] & 0xf];
716         l |= initPermRight0[(block[offset] >> 4) & 0xf];
717         l |= initPermRight3[block[offset + 1] & 0xf];
718         l |= initPermRight2[(block[offset + 1] >> 4) & 0xf];
719         l |= initPermRight5[block[offset + 2] & 0xf];
720         l |= initPermRight4[(block[offset + 2] >> 4) & 0xf];
721         l |= initPermRight7[block[offset + 3] & 0xf];
722         l |= initPermRight6[(block[offset + 3] >> 4) & 0xf];
723         l |= initPermRight9[block[offset + 4] & 0xf];
724         l |= initPermRight8[(block[offset + 4] >> 4) & 0xf];
725         l |= initPermRightB[block[offset + 5] & 0xf];
726         l |= initPermRightA[(block[offset + 5] >> 4) & 0xf];
727         l |= initPermRightD[block[offset + 6] & 0xf];
728         l |= initPermRightC[(block[offset + 6] >> 4) & 0xf];
729         l |= initPermRightF[block[offset + 7] & 0xf];
730         l |= initPermRightE[(block[offset + 7] >> 4) & 0xf];
731         return l;
732     }
733 
expandKey(byte key[])734     void expandKey(byte key[]) {
735         int octet;
736         byte ek[] = new byte[128];
737 
738         octet = key[0];
739         if ((octet & 0x80) != 0) {
740             ek[  3] |=  2; ek[  9] |=  8; ek[ 18] |=  8;
741             ek[ 27] |= 32; ek[ 33] |=  2; ek[ 42] |= 16;
742             ek[ 48] |=  8; ek[ 65] |= 16; ek[ 74] |=  2;
743             ek[ 80] |=  2; ek[ 89] |=  4; ek[ 99] |= 16;
744             ek[104] |=  4; ek[122] |= 32;
745         }
746         if ((octet & 0x40) != 0) {
747             ek[  1] |=  4; ek[  8] |=  1; ek[ 18] |=  4;
748             ek[ 25] |= 32; ek[ 34] |= 32; ek[ 41] |=  8;
749             ek[ 50] |=  8; ek[ 59] |= 32; ek[ 64] |= 16;
750             ek[ 75] |=  4; ek[ 90] |=  1; ek[ 97] |= 16;
751             ek[106] |=  2; ek[112] |=  2; ek[123] |=  1;
752         }
753         if ((octet & 0x20) != 0) {
754             ek[  2] |=  1; ek[ 19] |=  8; ek[ 35] |=  1;
755             ek[ 40] |=  1; ek[ 50] |=  4; ek[ 57] |= 32;
756             ek[ 75] |=  2; ek[ 80] |= 32; ek[ 89] |=  1;
757             ek[ 96] |= 16; ek[107] |=  4; ek[120] |=  8;
758         }
759         if ((octet & 0x10) != 0) {
760             ek[  4] |= 32; ek[ 20] |=  2; ek[ 31] |=  4;
761             ek[ 37] |= 32; ek[ 47] |=  1; ek[ 54] |=  1;
762             ek[ 63] |=  2; ek[ 68] |=  1; ek[ 78] |=  4;
763             ek[ 84] |=  8; ek[101] |= 16; ek[108] |=  4;
764             ek[119] |= 16; ek[126] |=  8;
765         }
766         if ((octet & 0x8) != 0) {
767             ek[  5] |=  4; ek[ 15] |=  4; ek[ 21] |= 32;
768             ek[ 31] |=  1; ek[ 38] |=  1; ek[ 47] |=  2;
769             ek[ 53] |=  2; ek[ 68] |=  8; ek[ 85] |= 16;
770             ek[ 92] |=  4; ek[103] |= 16; ek[108] |= 32;
771             ek[118] |= 32; ek[124] |=  2;
772         }
773         if ((octet & 0x4) != 0) {
774             ek[ 15] |=  2; ek[ 21] |=  2; ek[ 39] |=  8;
775             ek[ 46] |= 16; ek[ 55] |= 32; ek[ 61] |=  1;
776             ek[ 71] |= 16; ek[ 76] |= 32; ek[ 86] |= 32;
777             ek[ 93] |=  4; ek[102] |=  2; ek[108] |= 16;
778             ek[117] |=  8; ek[126] |=  1;
779         }
780         if ((octet & 0x2) != 0) {
781             ek[ 14] |= 16; ek[ 23] |= 32; ek[ 29] |=  1;
782             ek[ 38] |=  8; ek[ 52] |=  2; ek[ 63] |=  4;
783             ek[ 70] |=  2; ek[ 76] |= 16; ek[ 85] |=  8;
784             ek[100] |=  1; ek[110] |=  4; ek[116] |=  8;
785             ek[127] |=  8;
786         }
787         octet = key[1];
788         if ((octet & 0x80) != 0) {
789             ek[  1] |=  8; ek[  8] |= 32; ek[ 17] |=  1;
790             ek[ 24] |= 16; ek[ 35] |=  4; ek[ 50] |=  1;
791             ek[ 57] |= 16; ek[ 67] |=  8; ek[ 83] |=  1;
792             ek[ 88] |=  1; ek[ 98] |=  4; ek[105] |= 32;
793             ek[114] |= 32; ek[123] |=  2;
794         }
795         if ((octet & 0x40) != 0) {
796             ek[  0] |=  1; ek[ 11] |= 16; ek[ 16] |=  4;
797             ek[ 35] |=  2; ek[ 40] |= 32; ek[ 49] |=  1;
798             ek[ 56] |= 16; ek[ 65] |=  2; ek[ 74] |= 16;
799             ek[ 80] |=  8; ek[ 99] |=  8; ek[115] |=  1;
800             ek[121] |=  4;
801         }
802         if ((octet & 0x20) != 0) {
803             ek[  9] |= 16; ek[ 18] |=  2; ek[ 24] |=  2;
804             ek[ 33] |=  4; ek[ 43] |= 16; ek[ 48] |=  4;
805             ek[ 66] |= 32; ek[ 73] |=  8; ek[ 82] |=  8;
806             ek[ 91] |= 32; ek[ 97] |=  2; ek[106] |= 16;
807             ek[112] |=  8; ek[122] |=  1;
808         }
809         if ((octet & 0x10) != 0) {
810             ek[ 14] |= 32; ek[ 21] |=  4; ek[ 30] |=  2;
811             ek[ 36] |= 16; ek[ 45] |=  8; ek[ 60] |=  1;
812             ek[ 69] |=  2; ek[ 87] |=  8; ek[ 94] |= 16;
813             ek[103] |= 32; ek[109] |=  1; ek[118] |=  8;
814             ek[124] |= 32;
815         }
816         if ((octet & 0x8) != 0) {
817             ek[  7] |=  4; ek[ 14] |=  2; ek[ 20] |= 16;
818             ek[ 29] |=  8; ek[ 44] |=  1; ek[ 54] |=  4;
819             ek[ 60] |=  8; ek[ 71] |=  8; ek[ 78] |= 16;
820             ek[ 87] |= 32; ek[ 93] |=  1; ek[102] |=  8;
821             ek[116] |=  2; ek[125] |=  4;
822         }
823         if ((octet & 0x4) != 0) {
824             ek[  7] |=  2; ek[ 12] |=  1; ek[ 22] |=  4;
825             ek[ 28] |=  8; ek[ 45] |= 16; ek[ 52] |=  4;
826             ek[ 63] |= 16; ek[ 70] |=  8; ek[ 84] |=  2;
827             ek[ 95] |=  4; ek[101] |= 32; ek[111] |=  1;
828             ek[118] |=  1;
829         }
830         if ((octet & 0x2) != 0) {
831             ek[  6] |= 16; ek[ 13] |= 16; ek[ 20] |=  4;
832             ek[ 31] |= 16; ek[ 36] |= 32; ek[ 46] |= 32;
833             ek[ 53] |=  4; ek[ 62] |=  2; ek[ 69] |= 32;
834             ek[ 79] |=  1; ek[ 86] |=  1; ek[ 95] |=  2;
835             ek[101] |=  2; ek[119] |=  8;
836         }
837         octet = key[2];
838         if ((octet & 0x80) != 0) {
839             ek[  0] |= 32; ek[ 10] |=  8; ek[ 19] |= 32;
840             ek[ 25] |=  2; ek[ 34] |= 16; ek[ 40] |=  8;
841             ek[ 59] |=  8; ek[ 66] |=  2; ek[ 72] |=  2;
842             ek[ 81] |=  4; ek[ 91] |= 16; ek[ 96] |=  4;
843             ek[115] |=  2; ek[121] |=  8;
844         }
845         if ((octet & 0x40) != 0) {
846             ek[  3] |= 16; ek[ 10] |=  4; ek[ 17] |= 32;
847             ek[ 26] |= 32; ek[ 33] |=  8; ek[ 42] |=  8;
848             ek[ 51] |= 32; ek[ 57] |=  2; ek[ 67] |=  4;
849             ek[ 82] |=  1; ek[ 89] |= 16; ek[ 98] |=  2;
850             ek[104] |=  2; ek[113] |=  4; ek[120] |=  1;
851         }
852         if ((octet & 0x20) != 0) {
853             ek[  1] |= 16; ek[ 11] |=  8; ek[ 27] |=  1;
854             ek[ 32] |=  1; ek[ 42] |=  4; ek[ 49] |= 32;
855             ek[ 58] |= 32; ek[ 67] |=  2; ek[ 72] |= 32;
856             ek[ 81] |=  1; ek[ 88] |= 16; ek[ 99] |=  4;
857             ek[114] |=  1;
858         }
859         if ((octet & 0x10) != 0) {
860             ek[  6] |= 32; ek[ 12] |=  2; ek[ 23] |=  4;
861             ek[ 29] |= 32; ek[ 39] |=  1; ek[ 46] |=  1;
862             ek[ 55] |=  2; ek[ 61] |=  2; ek[ 70] |=  4;
863             ek[ 76] |=  8; ek[ 93] |= 16; ek[100] |=  4;
864             ek[111] |= 16; ek[116] |= 32;
865         }
866         if ((octet & 0x8) != 0) {
867             ek[  6] |=  2; ek[ 13] |= 32; ek[ 23] |=  1;
868             ek[ 30] |=  1; ek[ 39] |=  2; ek[ 45] |=  2;
869             ek[ 63] |=  8; ek[ 77] |= 16; ek[ 84] |=  4;
870             ek[ 95] |= 16; ek[100] |= 32; ek[110] |= 32;
871             ek[117] |=  4; ek[127] |=  4;
872         }
873         if ((octet & 0x4) != 0) {
874             ek[  4] |=  1; ek[ 13] |=  2; ek[ 31] |=  8;
875             ek[ 38] |= 16; ek[ 47] |= 32; ek[ 53] |=  1;
876             ek[ 62] |=  8; ek[ 68] |= 32; ek[ 78] |= 32;
877             ek[ 85] |=  4; ek[ 94] |=  2; ek[100] |= 16;
878             ek[109] |=  8; ek[127] |=  2;
879         }
880         if ((octet & 0x2) != 0) {
881             ek[  5] |= 16; ek[ 15] |= 32; ek[ 21] |=  1;
882             ek[ 30] |=  8; ek[ 44] |=  2; ek[ 55] |=  4;
883             ek[ 61] |= 32; ek[ 68] |= 16; ek[ 77] |=  8;
884             ek[ 92] |=  1; ek[102] |=  4; ek[108] |=  8;
885             ek[126] |= 16;
886         }
887         octet = key[3];
888         if ((octet & 0x80) != 0) {
889             ek[  2] |=  8; ek[  9] |=  1; ek[ 16] |= 16;
890             ek[ 27] |=  4; ek[ 42] |=  1; ek[ 49] |= 16;
891             ek[ 58] |=  2; ek[ 75] |=  1; ek[ 80] |=  1;
892             ek[ 90] |=  4; ek[ 97] |= 32; ek[106] |= 32;
893             ek[113] |=  8; ek[120] |= 32;
894         }
895         if ((octet & 0x40) != 0) {
896             ek[  2] |=  4; ek[  8] |=  4; ek[ 27] |=  2;
897             ek[ 32] |= 32; ek[ 41] |=  1; ek[ 48] |= 16;
898             ek[ 59] |=  4; ek[ 66] |= 16; ek[ 72] |=  8;
899             ek[ 91] |=  8; ek[107] |=  1; ek[112] |=  1;
900             ek[123] |= 16;
901         }
902         if ((octet & 0x20) != 0) {
903             ek[  3] |=  8; ek[ 10] |=  2; ek[ 16] |=  2;
904             ek[ 25] |=  4; ek[ 35] |= 16; ek[ 40] |=  4;
905             ek[ 59] |=  2; ek[ 65] |=  8; ek[ 74] |=  8;
906             ek[ 83] |= 32; ek[ 89] |=  2; ek[ 98] |= 16;
907             ek[104] |=  8; ek[121] |= 16;
908         }
909         if ((octet & 0x10) != 0) {
910             ek[  4] |=  2; ek[ 13] |=  4; ek[ 22] |=  2;
911             ek[ 28] |= 16; ek[ 37] |=  8; ek[ 52] |=  1;
912             ek[ 62] |=  4; ek[ 79] |=  8; ek[ 86] |= 16;
913             ek[ 95] |= 32; ek[101] |=  1; ek[110] |=  8;
914             ek[126] |= 32;
915         }
916         if ((octet & 0x8) != 0) {
917             ek[  5] |= 32; ek[ 12] |= 16; ek[ 21] |=  8;
918             ek[ 36] |=  1; ek[ 46] |=  4; ek[ 52] |=  8;
919             ek[ 70] |= 16; ek[ 79] |= 32; ek[ 85] |=  1;
920             ek[ 94] |=  8; ek[108] |=  2; ek[119] |=  4;
921             ek[126] |=  2;
922         }
923         if ((octet & 0x4) != 0) {
924             ek[  5] |=  2; ek[ 14] |=  4; ek[ 20] |=  8;
925             ek[ 37] |= 16; ek[ 44] |=  4; ek[ 55] |= 16;
926             ek[ 60] |= 32; ek[ 76] |=  2; ek[ 87] |=  4;
927             ek[ 93] |= 32; ek[103] |=  1; ek[110] |=  1;
928             ek[119] |=  2; ek[124] |=  1;
929         }
930         if ((octet & 0x2) != 0) {
931             ek[  7] |= 32; ek[ 12] |=  4; ek[ 23] |= 16;
932             ek[ 28] |= 32; ek[ 38] |= 32; ek[ 45] |=  4;
933             ek[ 54] |=  2; ek[ 60] |= 16; ek[ 71] |=  1;
934             ek[ 78] |=  1; ek[ 87] |=  2; ek[ 93] |=  2;
935             ek[111] |=  8; ek[118] |= 16; ek[125] |= 16;
936         }
937         octet = key[4];
938         if ((octet & 0x80) != 0) {
939             ek[  1] |=  1; ek[ 11] |= 32; ek[ 17] |=  2;
940             ek[ 26] |= 16; ek[ 32] |=  8; ek[ 51] |=  8;
941             ek[ 64] |=  2; ek[ 73] |=  4; ek[ 83] |= 16;
942             ek[ 88] |=  4; ek[107] |=  2; ek[112] |= 32;
943             ek[122] |=  8;
944         }
945         if ((octet & 0x40) != 0) {
946             ek[  0] |=  4; ek[  9] |= 32; ek[ 18] |= 32;
947             ek[ 25] |=  8; ek[ 34] |=  8; ek[ 43] |= 32;
948             ek[ 49] |=  2; ek[ 58] |= 16; ek[ 74] |=  1;
949             ek[ 81] |= 16; ek[ 90] |=  2; ek[ 96] |=  2;
950             ek[105] |=  4; ek[115] |= 16; ek[122] |=  4;
951         }
952         if ((octet & 0x20) != 0) {
953             ek[  2] |=  2; ek[ 19] |=  1; ek[ 24] |=  1;
954             ek[ 34] |=  4; ek[ 41] |= 32; ek[ 50] |= 32;
955             ek[ 57] |=  8; ek[ 64] |= 32; ek[ 73] |=  1;
956             ek[ 80] |= 16; ek[ 91] |=  4; ek[106] |=  1;
957             ek[113] |= 16; ek[123] |=  8;
958         }
959         if ((octet & 0x10) != 0) {
960             ek[  3] |=  4; ek[ 10] |= 16; ek[ 16] |=  8;
961             ek[ 35] |=  8; ek[ 51] |=  1; ek[ 56] |=  1;
962             ek[ 67] |= 16; ek[ 72] |=  4; ek[ 91] |=  2;
963             ek[ 96] |= 32; ek[105] |=  1; ek[112] |= 16;
964             ek[121] |=  2;
965         }
966         if ((octet & 0x8) != 0) {
967             ek[  4] |= 16; ek[ 15] |=  1; ek[ 22] |=  1;
968             ek[ 31] |=  2; ek[ 37] |=  2; ek[ 55] |=  8;
969             ek[ 62] |= 16; ek[ 69] |= 16; ek[ 76] |=  4;
970             ek[ 87] |= 16; ek[ 92] |= 32; ek[102] |= 32;
971             ek[109] |=  4; ek[118] |=  2; ek[125] |= 32;
972         }
973         if ((octet & 0x4) != 0) {
974             ek[  6] |=  4; ek[ 23] |=  8; ek[ 30] |= 16;
975             ek[ 39] |= 32; ek[ 45] |=  1; ek[ 54] |=  8;
976             ek[ 70] |= 32; ek[ 77] |=  4; ek[ 86] |=  2;
977             ek[ 92] |= 16; ek[101] |=  8; ek[116] |=  1;
978             ek[125] |=  2;
979         }
980         if ((octet & 0x2) != 0) {
981             ek[  4] |=  4; ek[ 13] |=  1; ek[ 22] |=  8;
982             ek[ 36] |=  2; ek[ 47] |=  4; ek[ 53] |= 32;
983             ek[ 63] |=  1; ek[ 69] |=  8; ek[ 84] |=  1;
984             ek[ 94] |=  4; ek[100] |=  8; ek[117] |= 16;
985             ek[127] |= 32;
986         }
987         octet = key[5];
988         if ((octet & 0x80) != 0) {
989             ek[  3] |= 32; ek[  8] |= 16; ek[ 19] |=  4;
990             ek[ 34] |=  1; ek[ 41] |= 16; ek[ 50] |=  2;
991             ek[ 56] |=  2; ek[ 67] |=  1; ek[ 72] |=  1;
992             ek[ 82] |=  4; ek[ 89] |= 32; ek[ 98] |= 32;
993             ek[105] |=  8; ek[114] |=  8; ek[121] |=  1;
994         }
995         if ((octet & 0x40) != 0) {
996             ek[  1] |= 32; ek[ 19] |=  2; ek[ 24] |= 32;
997             ek[ 33] |=  1; ek[ 40] |= 16; ek[ 51] |=  4;
998             ek[ 64] |=  8; ek[ 83] |=  8; ek[ 99] |=  1;
999             ek[104] |=  1; ek[114] |=  4; ek[120] |=  4;
1000         }
1001         if ((octet & 0x20) != 0) {
1002             ek[  8] |=  2; ek[ 17] |=  4; ek[ 27] |= 16;
1003             ek[ 32] |=  4; ek[ 51] |=  2; ek[ 56] |= 32;
1004             ek[ 66] |=  8; ek[ 75] |= 32; ek[ 81] |=  2;
1005             ek[ 90] |= 16; ek[ 96] |=  8; ek[115] |=  8;
1006             ek[122] |=  2;
1007         }
1008         if ((octet & 0x10) != 0) {
1009             ek[  2] |= 16; ek[ 18] |=  1; ek[ 25] |= 16;
1010             ek[ 34] |=  2; ek[ 40] |=  2; ek[ 49] |=  4;
1011             ek[ 59] |= 16; ek[ 66] |=  4; ek[ 73] |= 32;
1012             ek[ 82] |= 32; ek[ 89] |=  8; ek[ 98] |=  8;
1013             ek[107] |= 32; ek[113] |=  2; ek[123] |=  4;
1014         }
1015         if ((octet & 0x8) != 0) {
1016             ek[  7] |=  1; ek[ 13] |=  8; ek[ 28] |=  1;
1017             ek[ 38] |=  4; ek[ 44] |=  8; ek[ 61] |= 16;
1018             ek[ 71] |= 32; ek[ 77] |=  1; ek[ 86] |=  8;
1019             ek[100] |=  2; ek[111] |=  4; ek[117] |= 32;
1020             ek[124] |= 16;
1021         }
1022         if ((octet & 0x4) != 0) {
1023             ek[ 12] |=  8; ek[ 29] |= 16; ek[ 36] |=  4;
1024             ek[ 47] |= 16; ek[ 52] |= 32; ek[ 62] |= 32;
1025             ek[ 68] |=  2; ek[ 79] |=  4; ek[ 85] |= 32;
1026             ek[ 95] |=  1; ek[102] |=  1; ek[111] |=  2;
1027             ek[117] |=  2; ek[126] |=  4;
1028         }
1029         if ((octet & 0x2) != 0) {
1030             ek[  5] |=  1; ek[ 15] |= 16; ek[ 20] |= 32;
1031             ek[ 30] |= 32; ek[ 37] |=  4; ek[ 46] |=  2;
1032             ek[ 52] |= 16; ek[ 61] |=  8; ek[ 70] |=  1;
1033             ek[ 79] |=  2; ek[ 85] |=  2; ek[103] |=  8;
1034             ek[110] |= 16; ek[119] |= 32; ek[124] |=  4;
1035         }
1036         octet = key[6];
1037         if ((octet & 0x80) != 0) {
1038             ek[  0] |= 16; ek[  9] |=  2; ek[ 18] |= 16;
1039             ek[ 24] |=  8; ek[ 43] |=  8; ek[ 59] |=  1;
1040             ek[ 65] |=  4; ek[ 75] |= 16; ek[ 80] |=  4;
1041             ek[ 99] |=  2; ek[104] |= 32; ek[113] |=  1;
1042             ek[123] |= 32;
1043         }
1044         if ((octet & 0x40) != 0) {
1045             ek[ 10] |= 32; ek[ 17] |=  8; ek[ 26] |=  8;
1046             ek[ 35] |= 32; ek[ 41] |=  2; ek[ 50] |= 16;
1047             ek[ 56] |=  8; ek[ 66] |=  1; ek[ 73] |= 16;
1048             ek[ 82] |=  2; ek[ 88] |=  2; ek[ 97] |=  4;
1049             ek[107] |= 16; ek[112] |=  4; ek[121] |= 32;
1050         }
1051         if ((octet & 0x20) != 0) {
1052             ek[  0] |=  2; ek[ 11] |=  1; ek[ 16] |=  1;
1053             ek[ 26] |=  4; ek[ 33] |= 32; ek[ 42] |= 32;
1054             ek[ 49] |=  8; ek[ 58] |=  8; ek[ 65] |=  1;
1055             ek[ 72] |= 16; ek[ 83] |=  4; ek[ 98] |=  1;
1056             ek[105] |= 16; ek[114] |=  2;
1057         }
1058         if ((octet & 0x10) != 0) {
1059             ek[  8] |=  8; ek[ 27] |=  8; ek[ 43] |=  1;
1060             ek[ 48] |=  1; ek[ 58] |=  4; ek[ 64] |=  4;
1061             ek[ 83] |=  2; ek[ 88] |= 32; ek[ 97] |=  1;
1062             ek[104] |= 16; ek[115] |=  4; ek[122] |= 16;
1063         }
1064         if ((octet & 0x8) != 0) {
1065             ek[  5] |=  8; ek[ 14] |=  1; ek[ 23] |=  2;
1066             ek[ 29] |=  2; ek[ 47] |=  8; ek[ 54] |= 16;
1067             ek[ 63] |= 32; ek[ 68] |=  4; ek[ 79] |= 16;
1068             ek[ 84] |= 32; ek[ 94] |= 32; ek[101] |=  4;
1069             ek[110] |=  2; ek[116] |= 16; ek[127] |=  1;
1070         }
1071         if ((octet & 0x4) != 0) {
1072             ek[  4] |=  8; ek[ 15] |=  8; ek[ 22] |= 16;
1073             ek[ 31] |= 32; ek[ 37] |=  1; ek[ 46] |=  8;
1074             ek[ 60] |=  2; ek[ 69] |=  4; ek[ 78] |=  2;
1075             ek[ 84] |= 16; ek[ 93] |=  8; ek[108] |=  1;
1076             ek[118] |=  4;
1077         }
1078         if ((octet & 0x2) != 0) {
1079             ek[  7] |= 16; ek[ 14] |=  8; ek[ 28] |=  2;
1080             ek[ 39] |=  4; ek[ 45] |= 32; ek[ 55] |=  1;
1081             ek[ 62] |=  1; ek[ 76] |=  1; ek[ 86] |=  4;
1082             ek[ 92] |=  8; ek[109] |= 16; ek[116] |=  4;
1083             ek[125] |=  1;
1084         }
1085         octet = key[7];
1086         if ((octet & 0x80) != 0) {
1087             ek[  1] |=  2; ek[ 11] |=  4; ek[ 26] |=  1;
1088             ek[ 33] |= 16; ek[ 42] |=  2; ek[ 48] |=  2;
1089             ek[ 57] |=  4; ek[ 64] |=  1; ek[ 74] |=  4;
1090             ek[ 81] |= 32; ek[ 90] |= 32; ek[ 97] |=  8;
1091             ek[106] |=  8; ek[115] |= 32; ek[120] |= 16;
1092         }
1093         if ((octet & 0x40) != 0) {
1094             ek[  2] |= 32; ek[ 11] |=  2; ek[ 16] |= 32;
1095             ek[ 25] |=  1; ek[ 32] |= 16; ek[ 43] |=  4;
1096             ek[ 58] |=  1; ek[ 75] |=  8; ek[ 91] |=  1;
1097             ek[ 96] |=  1; ek[106] |=  4; ek[113] |= 32;
1098         }
1099         if ((octet & 0x20) != 0) {
1100             ek[  3] |=  1; ek[  9] |=  4; ek[ 19] |= 16;
1101             ek[ 24] |=  4; ek[ 43] |=  2; ek[ 48] |= 32;
1102             ek[ 57] |=  1; ek[ 67] |= 32; ek[ 73] |=  2;
1103             ek[ 82] |= 16; ek[ 88] |=  8; ek[107] |=  8;
1104             ek[120] |=  2;
1105         }
1106         if ((octet & 0x10) != 0) {
1107             ek[  0] |=  8; ek[ 10] |=  1; ek[ 17] |= 16;
1108             ek[ 26] |=  2; ek[ 32] |=  2; ek[ 41] |=  4;
1109             ek[ 51] |= 16; ek[ 56] |=  4; ek[ 65] |= 32;
1110             ek[ 74] |= 32; ek[ 81] |=  8; ek[ 90] |=  8;
1111             ek[ 99] |= 32; ek[105] |=  2; ek[114] |= 16;
1112         }
1113         if ((octet & 0x8) != 0) {
1114             ek[  6] |=  1; ek[ 20] |=  1; ek[ 30] |=  4;
1115             ek[ 36] |=  8; ek[ 53] |= 16; ek[ 60] |=  4;
1116             ek[ 69] |=  1; ek[ 78] |=  8; ek[ 92] |=  2;
1117             ek[103] |=  4; ek[109] |= 32; ek[119] |=  1;
1118             ek[125] |=  8;
1119         }
1120         if ((octet & 0x4) != 0) {
1121             ek[  7] |=  8; ek[ 21] |= 16; ek[ 28] |=  4;
1122             ek[ 39] |= 16; ek[ 44] |= 32; ek[ 54] |= 32;
1123             ek[ 61] |=  4; ek[ 71] |=  4; ek[ 77] |= 32;
1124             ek[ 87] |=  1; ek[ 94] |=  1; ek[103] |=  2;
1125             ek[109] |=  2; ek[124] |=  8;
1126         }
1127         if ((octet & 0x2) != 0) {
1128             ek[  6] |=  8; ek[ 12] |= 32; ek[ 22] |= 32;
1129             ek[ 29] |=  4; ek[ 38] |=  2; ek[ 44] |= 16;
1130             ek[ 53] |=  8; ek[ 71] |=  2; ek[ 77] |=  2;
1131             ek[ 95] |=  8; ek[102] |= 16; ek[111] |= 32;
1132             ek[117] |=  1; ek[127] |= 16;
1133         }
1134 
1135         expandedKey = ek;
1136     }
1137 }
1138