OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [gnu/] [javax/] [crypto/] [cipher/] [DES.java] - Blame information for rev 769

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 769 jeremybenn
/* DES.java --
2
   Copyright (C) 2002, 2003, 2006 Free Software Foundation, Inc.
3
 
4
This file is a part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2 of the License, or (at
9
your option) any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; if not, write to the Free Software
18
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
19
USA
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version.  */
37
 
38
 
39
package gnu.javax.crypto.cipher;
40
 
41
import gnu.java.security.Registry;
42
import gnu.java.security.Properties;
43
import gnu.java.security.util.Util;
44
 
45
import java.security.InvalidKeyException;
46
import java.util.Arrays;
47
import java.util.Collections;
48
import java.util.Iterator;
49
 
50
/**
51
 * The Data Encryption Standard. DES is a 64-bit block cipher with a 56-bit
52
 * key, developed by IBM in the 1970's for the standardization process begun by
53
 * the National Bureau of Standards (now NIST).
54
 * <p>
55
 * New applications should not use DES except for compatibility.
56
 * <p>
57
 * This version is based upon the description and sample implementation in
58
 * [1].
59
 * <p>
60
 * References:
61
 * <ol>
62
 *    <li>Bruce Schneier, <i>Applied Cryptography: Protocols, Algorithms, and
63
 *    Source Code in C, Second Edition</i>. (1996 John Wiley and Sons) ISBN
64
 *    0-471-11709-9. Pages 265--301, 623--632.</li>
65
 * </ol>
66
 */
67
public class DES
68
    extends BaseCipher
69
{
70
  /** DES operates on 64 bit blocks. */
71
  public static final int BLOCK_SIZE = 8;
72
  /** DES uses 56 bits of a 64 bit parity-adjusted key. */
73
  public static final int KEY_SIZE = 8;
74
  // S-Boxes 1 through 8.
75
  private static final int[] SP1 = new int[] {
76
      0x01010400, 0x00000000, 0x00010000, 0x01010404, 0x01010004, 0x00010404,
77
      0x00000004, 0x00010000, 0x00000400, 0x01010400, 0x01010404, 0x00000400,
78
      0x01000404, 0x01010004, 0x01000000, 0x00000004, 0x00000404, 0x01000400,
79
      0x01000400, 0x00010400, 0x00010400, 0x01010000, 0x01010000, 0x01000404,
80
      0x00010004, 0x01000004, 0x01000004, 0x00010004, 0x00000000, 0x00000404,
81
      0x00010404, 0x01000000, 0x00010000, 0x01010404, 0x00000004, 0x01010000,
82
      0x01010400, 0x01000000, 0x01000000, 0x00000400, 0x01010004, 0x00010000,
83
      0x00010400, 0x01000004, 0x00000400, 0x00000004, 0x01000404, 0x00010404,
84
      0x01010404, 0x00010004, 0x01010000, 0x01000404, 0x01000004, 0x00000404,
85
      0x00010404, 0x01010400, 0x00000404, 0x01000400, 0x01000400, 0x00000000,
86
      0x00010004, 0x00010400, 0x00000000, 0x01010004 };
87
  private static final int[] SP2 = new int[] {
88
      0x80108020, 0x80008000, 0x00008000, 0x00108020, 0x00100000, 0x00000020,
89
      0x80100020, 0x80008020, 0x80000020, 0x80108020, 0x80108000, 0x80000000,
90
      0x80008000, 0x00100000, 0x00000020, 0x80100020, 0x00108000, 0x00100020,
91
      0x80008020, 0x00000000, 0x80000000, 0x00008000, 0x00108020, 0x80100000,
92
      0x00100020, 0x80000020, 0x00000000, 0x00108000, 0x00008020, 0x80108000,
93
      0x80100000, 0x00008020, 0x00000000, 0x00108020, 0x80100020, 0x00100000,
94
      0x80008020, 0x80100000, 0x80108000, 0x00008000, 0x80100000, 0x80008000,
95
      0x00000020, 0x80108020, 0x00108020, 0x00000020, 0x00008000, 0x80000000,
96
      0x00008020, 0x80108000, 0x00100000, 0x80000020, 0x00100020, 0x80008020,
97
      0x80000020, 0x00100020, 0x00108000, 0x00000000, 0x80008000, 0x00008020,
98
      0x80000000, 0x80100020, 0x80108020, 0x00108000 };
99
  private static final int[] SP3 = new int[] {
100
      0x00000208, 0x08020200, 0x00000000, 0x08020008, 0x08000200, 0x00000000,
101
      0x00020208, 0x08000200, 0x00020008, 0x08000008, 0x08000008, 0x00020000,
102
      0x08020208, 0x00020008, 0x08020000, 0x00000208, 0x08000000, 0x00000008,
103
      0x08020200, 0x00000200, 0x00020200, 0x08020000, 0x08020008, 0x00020208,
104
      0x08000208, 0x00020200, 0x00020000, 0x08000208, 0x00000008, 0x08020208,
105
      0x00000200, 0x08000000, 0x08020200, 0x08000000, 0x00020008, 0x00000208,
106
      0x00020000, 0x08020200, 0x08000200, 0x00000000, 0x00000200, 0x00020008,
107
      0x08020208, 0x08000200, 0x08000008, 0x00000200, 0x00000000, 0x08020008,
108
      0x08000208, 0x00020000, 0x08000000, 0x08020208, 0x00000008, 0x00020208,
109
      0x00020200, 0x08000008, 0x08020000, 0x08000208, 0x00000208, 0x08020000,
110
      0x00020208, 0x00000008, 0x08020008, 0x00020200 };
111
  private static final int[] SP4 = new int[] {
112
      0x00802001, 0x00002081, 0x00002081, 0x00000080, 0x00802080, 0x00800081,
113
      0x00800001, 0x00002001, 0x00000000, 0x00802000, 0x00802000, 0x00802081,
114
      0x00000081, 0x00000000, 0x00800080, 0x00800001, 0x00000001, 0x00002000,
115
      0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002001, 0x00002080,
116
      0x00800081, 0x00000001, 0x00002080, 0x00800080, 0x00002000, 0x00802080,
117
      0x00802081, 0x00000081, 0x00800080, 0x00800001, 0x00802000, 0x00802081,
118
      0x00000081, 0x00000000, 0x00000000, 0x00802000, 0x00002080, 0x00800080,
119
      0x00800081, 0x00000001, 0x00802001, 0x00002081, 0x00002081, 0x00000080,
120
      0x00802081, 0x00000081, 0x00000001, 0x00002000, 0x00800001, 0x00002001,
121
      0x00802080, 0x00800081, 0x00002001, 0x00002080, 0x00800000, 0x00802001,
122
      0x00000080, 0x00800000, 0x00002000, 0x00802080 };
123
  private static final int[] SP5 = new int[] {
124
      0x00000100, 0x02080100, 0x02080000, 0x42000100, 0x00080000, 0x00000100,
125
      0x40000000, 0x02080000, 0x40080100, 0x00080000, 0x02000100, 0x40080100,
126
      0x42000100, 0x42080000, 0x00080100, 0x40000000, 0x02000000, 0x40080000,
127
      0x40080000, 0x00000000, 0x40000100, 0x42080100, 0x42080100, 0x02000100,
128
      0x42080000, 0x40000100, 0x00000000, 0x42000000, 0x02080100, 0x02000000,
129
      0x42000000, 0x00080100, 0x00080000, 0x42000100, 0x00000100, 0x02000000,
130
      0x40000000, 0x02080000, 0x42000100, 0x40080100, 0x02000100, 0x40000000,
131
      0x42080000, 0x02080100, 0x40080100, 0x00000100, 0x02000000, 0x42080000,
132
      0x42080100, 0x00080100, 0x42000000, 0x42080100, 0x02080000, 0x00000000,
133
      0x40080000, 0x42000000, 0x00080100, 0x02000100, 0x40000100, 0x00080000,
134
      0x00000000, 0x40080000, 0x02080100, 0x40000100 };
135
  private static final int[] SP6 = new int[] {
136
      0x20000010, 0x20400000, 0x00004000, 0x20404010, 0x20400000, 0x00000010,
137
      0x20404010, 0x00400000, 0x20004000, 0x00404010, 0x00400000, 0x20000010,
138
      0x00400010, 0x20004000, 0x20000000, 0x00004010, 0x00000000, 0x00400010,
139
      0x20004010, 0x00004000, 0x00404000, 0x20004010, 0x00000010, 0x20400010,
140
      0x20400010, 0x00000000, 0x00404010, 0x20404000, 0x00004010, 0x00404000,
141
      0x20404000, 0x20000000, 0x20004000, 0x00000010, 0x20400010, 0x00404000,
142
      0x20404010, 0x00400000, 0x00004010, 0x20000010, 0x00400000, 0x20004000,
143
      0x20000000, 0x00004010, 0x20000010, 0x20404010, 0x00404000, 0x20400000,
144
      0x00404010, 0x20404000, 0x00000000, 0x20400010, 0x00000010, 0x00004000,
145
      0x20400000, 0x00404010, 0x00004000, 0x00400010, 0x20004010, 0x00000000,
146
      0x20404000, 0x20000000, 0x00400010, 0x20004010 };
147
  private static final int[] SP7 = new int[] {
148
      0x00200000, 0x04200002, 0x04000802, 0x00000000, 0x00000800, 0x04000802,
149
      0x00200802, 0x04200800, 0x04200802, 0x00200000, 0x00000000, 0x04000002,
150
      0x00000002, 0x04000000, 0x04200002, 0x00000802, 0x04000800, 0x00200802,
151
      0x00200002, 0x04000800, 0x04000002, 0x04200000, 0x04200800, 0x00200002,
152
      0x04200000, 0x00000800, 0x00000802, 0x04200802, 0x00200800, 0x00000002,
153
      0x04000000, 0x00200800, 0x04000000, 0x00200800, 0x00200000, 0x04000802,
154
      0x04000802, 0x04200002, 0x04200002, 0x00000002, 0x00200002, 0x04000000,
155
      0x04000800, 0x00200000, 0x04200800, 0x00000802, 0x00200802, 0x04200800,
156
      0x00000802, 0x04000002, 0x04200802, 0x04200000, 0x00200800, 0x00000000,
157
      0x00000002, 0x04200802, 0x00000000, 0x00200802, 0x04200000, 0x00000800,
158
      0x04000002, 0x04000800, 0x00000800, 0x00200002 };
159
  private static final int[] SP8 = new int[] {
160
      0x10001040, 0x00001000, 0x00040000, 0x10041040, 0x10000000, 0x10001040,
161
      0x00000040, 0x10000000, 0x00040040, 0x10040000, 0x10041040, 0x00041000,
162
      0x10041000, 0x00041040, 0x00001000, 0x00000040, 0x10040000, 0x10000040,
163
      0x10001000, 0x00001040, 0x00041000, 0x00040040, 0x10040040, 0x10041000,
164
      0x00001040, 0x00000000, 0x00000000, 0x10040040, 0x10000040, 0x10001000,
165
      0x00041040, 0x00040000, 0x00041040, 0x00040000, 0x10041000, 0x00001000,
166
      0x00000040, 0x10040040, 0x00001000, 0x00041040, 0x10001000, 0x00000040,
167
      0x10000040, 0x10040000, 0x10040040, 0x10000000, 0x00040000, 0x10001040,
168
      0x00000000, 0x10041040, 0x00040040, 0x10000040, 0x10040000, 0x10001000,
169
      0x10001040, 0x00000000, 0x10041040, 0x00041000, 0x00041000, 0x00001040,
170
      0x00001040, 0x00040040, 0x10000000, 0x10041000 };
171
  /**
172
   * Constants that help in determining whether or not a byte array is parity
173
   * adjusted.
174
   */
175
  private static final byte[] PARITY = {
176
      8, 1, 0, 8, 0, 8, 8, 0, 0, 8, 8, 0, 8, 0, 2, 8,
177
      0, 8, 8, 0, 8, 0, 0, 8, 8, 0, 0, 8, 0, 8, 8, 3,
178
      0, 8, 8, 0, 8, 0, 0, 8, 8, 0, 0, 8, 0, 8, 8, 0,
179
      8, 0, 0, 8, 0, 8, 8, 0, 0, 8, 8, 0, 8, 0, 0, 8,
180
      0, 8, 8, 0, 8, 0, 0, 8, 8, 0, 0, 8, 0, 8, 8, 0,
181
      8, 0, 0, 8, 0, 8, 8, 0, 0, 8, 8, 0, 8, 0, 0, 8,
182
      8, 0, 0, 8, 0, 8, 8, 0, 0, 8, 8, 0, 8, 0, 0, 8,
183
      0, 8, 8, 0, 8, 0, 0, 8, 8, 0, 0, 8, 0, 8, 8, 0,
184
      0, 8, 8, 0, 8, 0, 0, 8, 8, 0, 0, 8, 0, 8, 8, 0,
185
      8, 0, 0, 8, 0, 8, 8, 0, 0, 8, 8, 0, 8, 0, 0, 8,
186
      8, 0, 0, 8, 0, 8, 8, 0, 0, 8, 8, 0, 8, 0, 0, 8,
187
      0, 8, 8, 0, 8, 0, 0, 8, 8, 0, 0, 8, 0, 8, 8, 0,
188
      8, 0, 0, 8, 0, 8, 8, 0, 0, 8, 8, 0, 8, 0, 0, 8,
189
      0, 8, 8, 0, 8, 0, 0, 8, 8, 0, 0, 8, 0, 8, 8, 0,
190
      4, 8, 8, 0, 8, 0, 0, 8, 8, 0, 0, 8, 0, 8, 8, 0,
191
      8, 5, 0, 8, 0, 8, 8, 0, 0, 8, 8, 0, 8, 0, 6, 8 };
192
  // Key schedule constants.
193
  private static final byte[] ROTARS = {
194
      1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28 };
195
  private static final byte[] PC1 = {
196
      56, 48, 40, 32, 24, 16,  8,  0, 57, 49, 41, 33, 25, 17,  9,  1,
197
      58, 50, 42, 34, 26, 18, 10,  2, 59, 51, 43, 35, 62, 54, 46, 38,
198
      30, 22, 14,  6, 61, 53, 45, 37, 29, 21, 13,  5, 60, 52, 44, 36,
199
      28, 20, 12,  4, 27, 19, 11,  3 };
200
  private static final byte[] PC2 = {
201
      13, 16, 10, 23,  0,  4,  2, 27, 14,  5, 20,  9, 22, 18, 11,  3,
202
      25,  7, 15,  6, 26, 19, 12,  1, 40, 51, 30, 36, 46, 54, 29, 39,
203
      50, 44, 32, 47, 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 };
204
  /**
205
   * Weak keys (parity adjusted): If all the bits in each half are either 0
206
   * or 1, then the key used for any cycle of the algorithm is the same as
207
   * all other cycles.
208
   */
209
  public static final byte[][] WEAK_KEYS = {
210
      Util.toBytesFromString("0101010101010101"),
211
      Util.toBytesFromString("01010101FEFEFEFE"),
212
      Util.toBytesFromString("FEFEFEFE01010101"),
213
      Util.toBytesFromString("FEFEFEFEFEFEFEFE") };
214
  /**
215
   * Semi-weak keys (parity adjusted):  Some pairs of keys encrypt plain text
216
   * to identical cipher text. In other words, one key in the pair can decrypt
217
   * messages that were encrypted with the other key. These keys are called
218
   * semi-weak keys. This occurs because instead of 16 different sub-keys being
219
   * generated, these semi-weak keys produce only two different sub-keys.
220
   */
221
  public static final byte[][] SEMIWEAK_KEYS = {
222
      Util.toBytesFromString("01FE01FE01FE01FE"),
223
      Util.toBytesFromString("FE01FE01FE01FE01"),
224
      Util.toBytesFromString("1FE01FE00EF10EF1"),
225
      Util.toBytesFromString("E01FE01FF10EF10E"),
226
      Util.toBytesFromString("01E001E001F101F1"),
227
      Util.toBytesFromString("E001E001F101F101"),
228
      Util.toBytesFromString("1FFE1FFE0EFE0EFE"),
229
      Util.toBytesFromString("FE1FFE1FFE0EFE0E"),
230
      Util.toBytesFromString("011F011F010E010E"),
231
      Util.toBytesFromString("1F011F010E010E01"),
232
      Util.toBytesFromString("E0FEE0FEF1FEF1FE"),
233
      Util.toBytesFromString("FEE0FEE0FEF1FEF1") };
234
  /** Possible weak keys (parity adjusted) --produce 4 instead of 16 subkeys. */
235
  public static final byte[][] POSSIBLE_WEAK_KEYS = {
236
      Util.toBytesFromString("1F1F01010E0E0101"),
237
      Util.toBytesFromString("011F1F01010E0E01"),
238
      Util.toBytesFromString("1F01011F0E01010E"),
239
      Util.toBytesFromString("01011F1F01010E0E"),
240
      Util.toBytesFromString("E0E00101F1F10101"),
241
      Util.toBytesFromString("FEFE0101FEFE0101"),
242
      Util.toBytesFromString("FEE01F01FEF10E01"),
243
      Util.toBytesFromString("E0FE1F01F1FE0E01"),
244
      Util.toBytesFromString("FEE0011FFEF1010E"),
245
      Util.toBytesFromString("E0FE011FF1FE010E"),
246
      Util.toBytesFromString("E0E01F1FF1F10E0E"),
247
      Util.toBytesFromString("FEFE1F1FFEFE0E0E"),
248
      Util.toBytesFromString("1F1F01010E0E0101"),
249
      Util.toBytesFromString("011F1F01010E0E01"),
250
      Util.toBytesFromString("1F01011F0E01010E"),
251
      Util.toBytesFromString("01011F1F01010E0E"),
252
      Util.toBytesFromString("01E0E00101F1F101"),
253
      Util.toBytesFromString("1FFEE0010EFEF001"),
254
      Util.toBytesFromString("1FE0FE010EF1FE01"),
255
      Util.toBytesFromString("01FEFE0101FEFE01"),
256
      Util.toBytesFromString("1FE0E01F0EF1F10E"),
257
      Util.toBytesFromString("01FEE01F01FEF10E"),
258
      Util.toBytesFromString("01E0FE1F01F1FE0E"),
259
      Util.toBytesFromString("1FFEFE1F0EFEFE0E"),
260
 
261
      Util.toBytesFromString("E00101E0F10101F1"),
262
      Util.toBytesFromString("FE1F01E0FE0E0EF1"),
263
      Util.toBytesFromString("FE011FE0FE010EF1"),
264
      Util.toBytesFromString("E01F1FE0F10E0EF1"),
265
      Util.toBytesFromString("FE0101FEFE0101FE"),
266
      Util.toBytesFromString("E01F01FEF10E01FE"),
267
      Util.toBytesFromString("E0011FFEF1010EFE"),
268
      Util.toBytesFromString("FE1F1FFEFE0E0EFE"),
269
      Util.toBytesFromString("1FFE01E00EFE01F1"),
270
      Util.toBytesFromString("01FE1FE001FE0EF1"),
271
      Util.toBytesFromString("1FE001FE0EF101FE"),
272
      Util.toBytesFromString("01E01FFE01F10EFE"),
273
      Util.toBytesFromString("0101E0E00101F1F1"),
274
      Util.toBytesFromString("1F1FE0E00E0EF1F1"),
275
      Util.toBytesFromString("1F01FEE00E01FEF1"),
276
      Util.toBytesFromString("011FFEE0010EFEF1"),
277
      Util.toBytesFromString("1F01E0FE0E01F1FE"),
278
      Util.toBytesFromString("011FE0FE010EF1FE"),
279
      Util.toBytesFromString("0101FEFE0001FEFE"),
280
      Util.toBytesFromString("1F1FFEFE0E0EFEFE"),
281
      Util.toBytesFromString("FEFEE0E0FEFEF1F1"),
282
      Util.toBytesFromString("E0FEFEE0F1FEFEF1"),
283
      Util.toBytesFromString("FEE0E0FEFEF1F1FE"),
284
      Util.toBytesFromString("E0E0FEFEF1F1FEFE") };
285
 
286
  /** Default 0-argument constructor. */
287
  public DES()
288
  {
289
    super(Registry.DES_CIPHER, BLOCK_SIZE, KEY_SIZE);
290
  }
291
 
292
  /**
293
   * Adjust the parity for a raw key array. This essentially means that each
294
   * byte in the array will have an odd number of '1' bits (the last bit in
295
   * each byte is unused.
296
   *
297
   * @param kb The key array, to be parity-adjusted.
298
   * @param offset The starting index into the key bytes.
299
   */
300
  public static void adjustParity(byte[] kb, int offset)
301
  {
302
    for (int i = offset; i < offset + KEY_SIZE; i++)
303
      kb[i] ^= (PARITY[kb[i] & 0xff] == 8) ? 1 : 0;
304
  }
305
 
306
  /**
307
   * Test if a byte array, which must be at least 8 bytes long, is parity
308
   * adjusted.
309
   *
310
   * @param kb The key bytes.
311
   * @param offset The starting index into the key bytes.
312
   * @return <code>true</code> if the first 8 bytes of <i>kb</i> have been
313
   * parity adjusted. <code>false</code> otherwise.
314
   */
315
  public static boolean isParityAdjusted(byte[] kb, int offset)
316
  {
317
    int w = 0x88888888;
318
    int n = PARITY[kb[offset + 0] & 0xff];
319
    n <<= 4;
320
    n |= PARITY[kb[offset + 1] & 0xff];
321
    n <<= 4;
322
    n |= PARITY[kb[offset + 2] & 0xff];
323
    n <<= 4;
324
    n |= PARITY[kb[offset + 3] & 0xff];
325
    n <<= 4;
326
    n |= PARITY[kb[offset + 4] & 0xff];
327
    n <<= 4;
328
    n |= PARITY[kb[offset + 5] & 0xff];
329
    n <<= 4;
330
    n |= PARITY[kb[offset + 6] & 0xff];
331
    n <<= 4;
332
    n |= PARITY[kb[offset + 7] & 0xff];
333
    return (n & w) == 0;
334
  }
335
 
336
  /**
337
   * Test if a key is a weak key.
338
   *
339
   * @param kb The key to test.
340
   * @return <code>true</code> if the key is weak.
341
   */
342
  public static boolean isWeak(byte[] kb)
343
  {
344
    for (int i = 0; i < WEAK_KEYS.length; i++)
345
      if (Arrays.equals(WEAK_KEYS[i], kb))
346
        return true;
347
    return false;
348
  }
349
 
350
  /**
351
   * Test if a key is a semi-weak key.
352
   *
353
   * @param kb The key to test.
354
   * @return <code>true</code> if this key is semi-weak.
355
   */
356
  public static boolean isSemiWeak(byte[] kb)
357
  {
358
    for (int i = 0; i < SEMIWEAK_KEYS.length; i++)
359
      if (Arrays.equals(SEMIWEAK_KEYS[i], kb))
360
        return true;
361
    return false;
362
  }
363
 
364
  /**
365
   * Test if the designated byte array represents a possibly weak key.
366
   *
367
   * @param kb the byte array to test.
368
   * @return <code>true</code> if <code>kb</code>represents a possibly weak key.
369
   * Returns <code>false</code> otherwise.
370
   */
371
  public static boolean isPossibleWeak(byte[] kb)
372
  {
373
    for (int i = 0; i < POSSIBLE_WEAK_KEYS.length; i++)
374
      if (Arrays.equals(POSSIBLE_WEAK_KEYS[i], kb))
375
        return true;
376
    return false;
377
  }
378
 
379
  /**
380
   * The core DES function. This is used for both encryption and decryption,
381
   * the only difference being the key.
382
   *
383
   * @param in The input bytes.
384
   * @param i The starting offset into the input bytes.
385
   * @param out The output bytes.
386
   * @param o The starting offset into the output bytes.
387
   * @param key The working key.
388
   */
389
  private static void desFunc(byte[] in, int i, byte[] out, int o, int[] key)
390
  {
391
    int right, left, work;
392
    // Load.
393
    left =  (in[i++] & 0xff) << 24
394
          | (in[i++] & 0xff) << 16
395
          | (in[i++] & 0xff) << 8
396
          |  in[i++] & 0xff;
397
    right = (in[i++] & 0xff) << 24
398
          | (in[i++] & 0xff) << 16
399
          | (in[i++] & 0xff) << 8
400
          |  in[i  ] & 0xff;
401
    // Initial permutation.
402
    work = ((left >>> 4) ^ right) & 0x0F0F0F0F;
403
    left ^= work << 4;
404
    right ^= work;
405
 
406
    work = ((left >>> 16) ^ right) & 0x0000FFFF;
407
    left ^= work << 16;
408
    right ^= work;
409
 
410
    work = ((right >>> 2) ^ left) & 0x33333333;
411
    right ^= work << 2;
412
    left ^= work;
413
 
414
    work = ((right >>> 8) ^ left) & 0x00FF00FF;
415
    right ^= work << 8;
416
    left ^= work;
417
 
418
    right = ((right << 1) | ((right >>> 31) & 1)) & 0xFFFFFFFF;
419
    work = (left ^ right) & 0xAAAAAAAA;
420
    left ^= work;
421
    right ^= work;
422
    left = ((left << 1) | ((left >>> 31) & 1)) & 0xFFFFFFFF;
423
 
424
    int k = 0, t;
425
    for (int round = 0; round < 8; round++)
426
      {
427
        work = right >>> 4 | right << 28;
428
        work ^= key[k++];
429
        t = SP7[work & 0x3F];
430
        work >>>= 8;
431
        t |= SP5[work & 0x3F];
432
        work >>>= 8;
433
        t |= SP3[work & 0x3F];
434
        work >>>= 8;
435
        t |= SP1[work & 0x3F];
436
        work = right ^ key[k++];
437
        t |= SP8[work & 0x3F];
438
        work >>>= 8;
439
        t |= SP6[work & 0x3F];
440
        work >>>= 8;
441
        t |= SP4[work & 0x3F];
442
        work >>>= 8;
443
        t |= SP2[work & 0x3F];
444
        left ^= t;
445
 
446
        work = left >>> 4 | left << 28;
447
        work ^= key[k++];
448
        t = SP7[work & 0x3F];
449
        work >>>= 8;
450
        t |= SP5[work & 0x3F];
451
        work >>>= 8;
452
        t |= SP3[work & 0x3F];
453
        work >>>= 8;
454
        t |= SP1[work & 0x3F];
455
        work = left ^ key[k++];
456
        t |= SP8[work & 0x3F];
457
        work >>>= 8;
458
        t |= SP6[work & 0x3F];
459
        work >>>= 8;
460
        t |= SP4[work & 0x3F];
461
        work >>>= 8;
462
        t |= SP2[work & 0x3F];
463
        right ^= t;
464
      }
465
    // The final permutation.
466
    right = (right << 31) | (right >>> 1);
467
    work = (left ^ right) & 0xAAAAAAAA;
468
    left ^= work;
469
    right ^= work;
470
    left = (left << 31) | (left >>> 1);
471
 
472
    work = ((left >>> 8) ^ right) & 0x00FF00FF;
473
    left ^= work << 8;
474
    right ^= work;
475
 
476
    work = ((left >>> 2) ^ right) & 0x33333333;
477
    left ^= work << 2;
478
    right ^= work;
479
 
480
    work = ((right >>> 16) ^ left) & 0x0000FFFF;
481
    right ^= work << 16;
482
    left ^= work;
483
 
484
    work = ((right >>> 4) ^ left) & 0x0F0F0F0F;
485
    right ^= work << 4;
486
    left ^= work;
487
 
488
    out[o++] = (byte)(right >>> 24);
489
    out[o++] = (byte)(right >>> 16);
490
    out[o++] = (byte)(right >>> 8);
491
    out[o++] = (byte) right;
492
    out[o++] = (byte)(left >>> 24);
493
    out[o++] = (byte)(left >>> 16);
494
    out[o++] = (byte)(left >>> 8);
495
    out[o  ] = (byte) left;
496
  }
497
 
498
  public Object clone()
499
  {
500
    return new DES();
501
  }
502
 
503
  public Iterator blockSizes()
504
  {
505
    return Collections.singleton(Integer.valueOf(BLOCK_SIZE)).iterator();
506
  }
507
 
508
  public Iterator keySizes()
509
  {
510
    return Collections.singleton(Integer.valueOf(KEY_SIZE)).iterator();
511
  }
512
 
513
  public Object makeKey(byte[] kb, int bs) throws InvalidKeyException
514
  {
515
    if (kb == null || kb.length != KEY_SIZE)
516
      throw new InvalidKeyException("DES keys must be 8 bytes long");
517
 
518
    if (Properties.checkForWeakKeys()
519
        && (isWeak(kb) || isSemiWeak(kb) || isPossibleWeak(kb)))
520
      throw new WeakKeyException();
521
 
522
    int i, j, l, m, n;
523
    long pc1m = 0, pcr = 0;
524
 
525
    for (i = 0; i < 56; i++)
526
      {
527
        l = PC1[i];
528
        pc1m |= ((kb[l >>> 3] & (0x80 >>> (l & 7))) != 0) ? (1L << (55 - i))
529
                                                          : 0;
530
      }
531
    Context ctx = new Context();
532
    // Encryption key first.
533
    for (i = 0; i < 16; i++)
534
      {
535
        pcr = 0;
536
        m = i << 1;
537
        n = m + 1;
538
        for (j = 0; j < 28; j++)
539
          {
540
            l = j + ROTARS[i];
541
            if (l < 28)
542
              pcr |= ((pc1m & 1L << (55 - l)) != 0) ? (1L << (55 - j)) : 0;
543
            else
544
              pcr |= ((pc1m & 1L << (55 - (l - 28))) != 0) ? (1L << (55 - j))
545
                                                           : 0;
546
          }
547
        for (j = 28; j < 56; j++)
548
          {
549
            l = j + ROTARS[i];
550
            if (l < 56)
551
              pcr |= ((pc1m & 1L << (55 - l)) != 0) ? (1L << (55 - j)) : 0;
552
            else
553
              pcr |= ((pc1m & 1L << (55 - (l - 28))) != 0) ? (1L << (55 - j))
554
                                                           : 0;
555
          }
556
        for (j = 0; j < 24; j++)
557
          {
558
            if ((pcr & 1L << (55 - PC2[j])) != 0)
559
              ctx.ek[m] |= 1 << (23 - j);
560
            if ((pcr & 1L << (55 - PC2[j + 24])) != 0)
561
              ctx.ek[n] |= 1 << (23 - j);
562
          }
563
      }
564
    // The decryption key is the same, but in reversed order.
565
    for (i = 0; i < Context.EXPANDED_KEY_SIZE; i += 2)
566
      {
567
        ctx.dk[30 - i] = ctx.ek[i];
568
        ctx.dk[31 - i] = ctx.ek[i + 1];
569
      }
570
    // "Cook" the keys.
571
    for (i = 0; i < 32; i += 2)
572
      {
573
        int x, y;
574
        x = ctx.ek[i];
575
        y = ctx.ek[i + 1];
576
        ctx.ek[i    ] = ((x & 0x00FC0000)  <<  6)
577
                      | ((x & 0x00000FC0)  << 10)
578
                      | ((y & 0x00FC0000) >>> 10)
579
                      | ((y & 0x00000FC0) >>>  6);
580
        ctx.ek[i + 1] = ((x & 0x0003F000)  << 12)
581
                      | ((x & 0x0000003F)  << 16)
582
                      | ((y & 0x0003F000) >>>  4)
583
                      |  (y & 0x0000003F);
584
        x = ctx.dk[i];
585
        y = ctx.dk[i + 1];
586
        ctx.dk[i    ] = ((x & 0x00FC0000)  <<  6)
587
                      | ((x & 0x00000FC0)  << 10)
588
                      | ((y & 0x00FC0000) >>> 10)
589
                      | ((y & 0x00000FC0) >>>  6);
590
        ctx.dk[i + 1] = ((x & 0x0003F000)  << 12)
591
                      | ((x & 0x0000003F)  << 16)
592
                      | ((y & 0x0003F000) >>>  4)
593
                      |  (y & 0x0000003F);
594
      }
595
    return ctx;
596
  }
597
 
598
  public void encrypt(byte[] in, int i, byte[] out, int o, Object K, int bs)
599
  {
600
    desFunc(in, i, out, o, ((Context) K).ek);
601
  }
602
 
603
  public void decrypt(byte[] in, int i, byte[] out, int o, Object K, int bs)
604
  {
605
    desFunc(in, i, out, o, ((Context) K).dk);
606
  }
607
 
608
  /**
609
   * Simple wrapper class around the session keys. Package-private so TripleDES
610
   * can see it.
611
   */
612
  final class Context
613
  {
614
    private static final int EXPANDED_KEY_SIZE = 32;
615
 
616
    /** The encryption key. */
617
    int[] ek;
618
 
619
    /** The decryption key. */
620
    int[] dk;
621
 
622
    /** Default 0-arguments constructor. */
623
    Context()
624
    {
625
      ek = new int[EXPANDED_KEY_SIZE];
626
      dk = new int[EXPANDED_KEY_SIZE];
627
    }
628
 
629
    byte[] getEncryptionKeyBytes()
630
    {
631
      return toByteArray(ek);
632
    }
633
 
634
    byte[] getDecryptionKeyBytes()
635
    {
636
      return toByteArray(dk);
637
    }
638
 
639
    byte[] toByteArray(int[] k)
640
    {
641
      byte[] result = new byte[4 * k.length];
642
      for (int i = 0, j = 0; i < k.length; i++)
643
        {
644
          result[j++] = (byte)(k[i] >>> 24);
645
          result[j++] = (byte)(k[i] >>> 16);
646
          result[j++] = (byte)(k[i] >>> 8);
647
          result[j++] = (byte) k[i];
648
        }
649
      return result;
650
    }
651
  }
652
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.