]> granicus.if.org Git - postgresql/blob - src/interfaces/jdbc/org/postgresql/util/UnixCrypt.java
Cleanup and reorganization.
[postgresql] / src / interfaces / jdbc / org / postgresql / util / UnixCrypt.java
1 /*-------------------------------------------------------------------------
2  *
3  * UnixCrypt.java
4  *     Contains static methods to encrypt and compare
5  *     passwords with Unix encrypted passwords.
6  *
7  * Copyright (c) 2003, PostgreSQL Global Development Group
8  *
9  * IDENTIFICATION
10  *        $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/util/Attic/UnixCrypt.java,v 1.4 2003/03/07 18:39:46 barry Exp $
11  *
12  *-------------------------------------------------------------------------
13  */
14 package org.postgresql.util;
15
16 /*
17  * <P>See <A HREF="http://www.zeh.com/local/jfd/crypt.html">
18  * John Dumas's Java Crypt page</A> for the original source.</P>
19  *
20  * @author jdumas@zgs.com (John Dumas)
21  */
22 public class UnixCrypt extends Object
23 {
24         //
25         // Null constructor - can't instantiate class
26         private UnixCrypt()
27         {}
28
29         private static final char[] saltChars =
30                 ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./".toCharArray());
31
32         private static final int ITERATIONS = 16;
33
34         private static final int con_salt[] =
35                 {
36                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
37                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
38                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
39                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
40                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
41                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
42                         0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
43                         0x0A, 0x0B, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A,
44                         0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12,
45                         0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A,
46                         0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22,
47                         0x23, 0x24, 0x25, 0x20, 0x21, 0x22, 0x23, 0x24,
48                         0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C,
49                         0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34,
50                         0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C,
51                         0x3D, 0x3E, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00,
52                 };
53
54         private static final boolean shifts2[] =
55                 {
56                         false, false, true, true, true, true, true, true,
57                         false, true, true, true, true, true, true, false
58                 };
59
60         private static final int skb[][] =
61                 {
62                         {
63                                 /* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
64                                 0x00000000, 0x00000010, 0x20000000, 0x20000010,
65                                 0x00010000, 0x00010010, 0x20010000, 0x20010010,
66                                 0x00000800, 0x00000810, 0x20000800, 0x20000810,
67                                 0x00010800, 0x00010810, 0x20010800, 0x20010810,
68                                 0x00000020, 0x00000030, 0x20000020, 0x20000030,
69                                 0x00010020, 0x00010030, 0x20010020, 0x20010030,
70                                 0x00000820, 0x00000830, 0x20000820, 0x20000830,
71                                 0x00010820, 0x00010830, 0x20010820, 0x20010830,
72                                 0x00080000, 0x00080010, 0x20080000, 0x20080010,
73                                 0x00090000, 0x00090010, 0x20090000, 0x20090010,
74                                 0x00080800, 0x00080810, 0x20080800, 0x20080810,
75                                 0x00090800, 0x00090810, 0x20090800, 0x20090810,
76                                 0x00080020, 0x00080030, 0x20080020, 0x20080030,
77                                 0x00090020, 0x00090030, 0x20090020, 0x20090030,
78                                 0x00080820, 0x00080830, 0x20080820, 0x20080830,
79                                 0x00090820, 0x00090830, 0x20090820, 0x20090830,
80                         },
81                         {
82                                 /* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */
83                                 0x00000000, 0x02000000, 0x00002000, 0x02002000,
84                                 0x00200000, 0x02200000, 0x00202000, 0x02202000,
85                                 0x00000004, 0x02000004, 0x00002004, 0x02002004,
86                                 0x00200004, 0x02200004, 0x00202004, 0x02202004,
87                                 0x00000400, 0x02000400, 0x00002400, 0x02002400,
88                                 0x00200400, 0x02200400, 0x00202400, 0x02202400,
89                                 0x00000404, 0x02000404, 0x00002404, 0x02002404,
90                                 0x00200404, 0x02200404, 0x00202404, 0x02202404,
91                                 0x10000000, 0x12000000, 0x10002000, 0x12002000,
92                                 0x10200000, 0x12200000, 0x10202000, 0x12202000,
93                                 0x10000004, 0x12000004, 0x10002004, 0x12002004,
94                                 0x10200004, 0x12200004, 0x10202004, 0x12202004,
95                                 0x10000400, 0x12000400, 0x10002400, 0x12002400,
96                                 0x10200400, 0x12200400, 0x10202400, 0x12202400,
97                                 0x10000404, 0x12000404, 0x10002404, 0x12002404,
98                                 0x10200404, 0x12200404, 0x10202404, 0x12202404,
99                         },
100                         {
101                                 /* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */
102                                 0x00000000, 0x00000001, 0x00040000, 0x00040001,
103                                 0x01000000, 0x01000001, 0x01040000, 0x01040001,
104                                 0x00000002, 0x00000003, 0x00040002, 0x00040003,
105                                 0x01000002, 0x01000003, 0x01040002, 0x01040003,
106                                 0x00000200, 0x00000201, 0x00040200, 0x00040201,
107                                 0x01000200, 0x01000201, 0x01040200, 0x01040201,
108                                 0x00000202, 0x00000203, 0x00040202, 0x00040203,
109                                 0x01000202, 0x01000203, 0x01040202, 0x01040203,
110                                 0x08000000, 0x08000001, 0x08040000, 0x08040001,
111                                 0x09000000, 0x09000001, 0x09040000, 0x09040001,
112                                 0x08000002, 0x08000003, 0x08040002, 0x08040003,
113                                 0x09000002, 0x09000003, 0x09040002, 0x09040003,
114                                 0x08000200, 0x08000201, 0x08040200, 0x08040201,
115                                 0x09000200, 0x09000201, 0x09040200, 0x09040201,
116                                 0x08000202, 0x08000203, 0x08040202, 0x08040203,
117                                 0x09000202, 0x09000203, 0x09040202, 0x09040203,
118                         },
119                         {
120                                 /* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */
121                                 0x00000000, 0x00100000, 0x00000100, 0x00100100,
122                                 0x00000008, 0x00100008, 0x00000108, 0x00100108,
123                                 0x00001000, 0x00101000, 0x00001100, 0x00101100,
124                                 0x00001008, 0x00101008, 0x00001108, 0x00101108,
125                                 0x04000000, 0x04100000, 0x04000100, 0x04100100,
126                                 0x04000008, 0x04100008, 0x04000108, 0x04100108,
127                                 0x04001000, 0x04101000, 0x04001100, 0x04101100,
128                                 0x04001008, 0x04101008, 0x04001108, 0x04101108,
129                                 0x00020000, 0x00120000, 0x00020100, 0x00120100,
130                                 0x00020008, 0x00120008, 0x00020108, 0x00120108,
131                                 0x00021000, 0x00121000, 0x00021100, 0x00121100,
132                                 0x00021008, 0x00121008, 0x00021108, 0x00121108,
133                                 0x04020000, 0x04120000, 0x04020100, 0x04120100,
134                                 0x04020008, 0x04120008, 0x04020108, 0x04120108,
135                                 0x04021000, 0x04121000, 0x04021100, 0x04121100,
136                                 0x04021008, 0x04121008, 0x04021108, 0x04121108,
137                         },
138                         {
139                                 /* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
140                                 0x00000000, 0x10000000, 0x00010000, 0x10010000,
141                                 0x00000004, 0x10000004, 0x00010004, 0x10010004,
142                                 0x20000000, 0x30000000, 0x20010000, 0x30010000,
143                                 0x20000004, 0x30000004, 0x20010004, 0x30010004,
144                                 0x00100000, 0x10100000, 0x00110000, 0x10110000,
145                                 0x00100004, 0x10100004, 0x00110004, 0x10110004,
146                                 0x20100000, 0x30100000, 0x20110000, 0x30110000,
147                                 0x20100004, 0x30100004, 0x20110004, 0x30110004,
148                                 0x00001000, 0x10001000, 0x00011000, 0x10011000,
149                                 0x00001004, 0x10001004, 0x00011004, 0x10011004,
150                                 0x20001000, 0x30001000, 0x20011000, 0x30011000,
151                                 0x20001004, 0x30001004, 0x20011004, 0x30011004,
152                                 0x00101000, 0x10101000, 0x00111000, 0x10111000,
153                                 0x00101004, 0x10101004, 0x00111004, 0x10111004,
154                                 0x20101000, 0x30101000, 0x20111000, 0x30111000,
155                                 0x20101004, 0x30101004, 0x20111004, 0x30111004,
156                         },
157                         {
158                                 /* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */
159                                 0x00000000, 0x08000000, 0x00000008, 0x08000008,
160                                 0x00000400, 0x08000400, 0x00000408, 0x08000408,
161                                 0x00020000, 0x08020000, 0x00020008, 0x08020008,
162                                 0x00020400, 0x08020400, 0x00020408, 0x08020408,
163                                 0x00000001, 0x08000001, 0x00000009, 0x08000009,
164                                 0x00000401, 0x08000401, 0x00000409, 0x08000409,
165                                 0x00020001, 0x08020001, 0x00020009, 0x08020009,
166                                 0x00020401, 0x08020401, 0x00020409, 0x08020409,
167                                 0x02000000, 0x0A000000, 0x02000008, 0x0A000008,
168                                 0x02000400, 0x0A000400, 0x02000408, 0x0A000408,
169                                 0x02020000, 0x0A020000, 0x02020008, 0x0A020008,
170                                 0x02020400, 0x0A020400, 0x02020408, 0x0A020408,
171                                 0x02000001, 0x0A000001, 0x02000009, 0x0A000009,
172                                 0x02000401, 0x0A000401, 0x02000409, 0x0A000409,
173                                 0x02020001, 0x0A020001, 0x02020009, 0x0A020009,
174                                 0x02020401, 0x0A020401, 0x02020409, 0x0A020409,
175                         },
176                         {
177                                 /* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */
178                                 0x00000000, 0x00000100, 0x00080000, 0x00080100,
179                                 0x01000000, 0x01000100, 0x01080000, 0x01080100,
180                                 0x00000010, 0x00000110, 0x00080010, 0x00080110,
181                                 0x01000010, 0x01000110, 0x01080010, 0x01080110,
182                                 0x00200000, 0x00200100, 0x00280000, 0x00280100,
183                                 0x01200000, 0x01200100, 0x01280000, 0x01280100,
184                                 0x00200010, 0x00200110, 0x00280010, 0x00280110,
185                                 0x01200010, 0x01200110, 0x01280010, 0x01280110,
186                                 0x00000200, 0x00000300, 0x00080200, 0x00080300,
187                                 0x01000200, 0x01000300, 0x01080200, 0x01080300,
188                                 0x00000210, 0x00000310, 0x00080210, 0x00080310,
189                                 0x01000210, 0x01000310, 0x01080210, 0x01080310,
190                                 0x00200200, 0x00200300, 0x00280200, 0x00280300,
191                                 0x01200200, 0x01200300, 0x01280200, 0x01280300,
192                                 0x00200210, 0x00200310, 0x00280210, 0x00280310,
193                                 0x01200210, 0x01200310, 0x01280210, 0x01280310,
194                         },
195                         {
196                                 /* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */
197                                 0x00000000, 0x04000000, 0x00040000, 0x04040000,
198                                 0x00000002, 0x04000002, 0x00040002, 0x04040002,
199                                 0x00002000, 0x04002000, 0x00042000, 0x04042000,
200                                 0x00002002, 0x04002002, 0x00042002, 0x04042002,
201                                 0x00000020, 0x04000020, 0x00040020, 0x04040020,
202                                 0x00000022, 0x04000022, 0x00040022, 0x04040022,
203                                 0x00002020, 0x04002020, 0x00042020, 0x04042020,
204                                 0x00002022, 0x04002022, 0x00042022, 0x04042022,
205                                 0x00000800, 0x04000800, 0x00040800, 0x04040800,
206                                 0x00000802, 0x04000802, 0x00040802, 0x04040802,
207                                 0x00002800, 0x04002800, 0x00042800, 0x04042800,
208                                 0x00002802, 0x04002802, 0x00042802, 0x04042802,
209                                 0x00000820, 0x04000820, 0x00040820, 0x04040820,
210                                 0x00000822, 0x04000822, 0x00040822, 0x04040822,
211                                 0x00002820, 0x04002820, 0x00042820, 0x04042820,
212                                 0x00002822, 0x04002822, 0x00042822, 0x04042822,
213                         },
214                 };
215
216         private static final int SPtrans[][] =
217                 {
218                         {
219                                 /* nibble 0 */
220                                 0x00820200, 0x00020000, 0x80800000, 0x80820200,
221                                 0x00800000, 0x80020200, 0x80020000, 0x80800000,
222                                 0x80020200, 0x00820200, 0x00820000, 0x80000200,
223                                 0x80800200, 0x00800000, 0x00000000, 0x80020000,
224                                 0x00020000, 0x80000000, 0x00800200, 0x00020200,
225                                 0x80820200, 0x00820000, 0x80000200, 0x00800200,
226                                 0x80000000, 0x00000200, 0x00020200, 0x80820000,
227                                 0x00000200, 0x80800200, 0x80820000, 0x00000000,
228                                 0x00000000, 0x80820200, 0x00800200, 0x80020000,
229                                 0x00820200, 0x00020000, 0x80000200, 0x00800200,
230                                 0x80820000, 0x00000200, 0x00020200, 0x80800000,
231                                 0x80020200, 0x80000000, 0x80800000, 0x00820000,
232                                 0x80820200, 0x00020200, 0x00820000, 0x80800200,
233                                 0x00800000, 0x80000200, 0x80020000, 0x00000000,
234                                 0x00020000, 0x00800000, 0x80800200, 0x00820200,
235                                 0x80000000, 0x80820000, 0x00000200, 0x80020200,
236                         },
237                         {
238                                 /* nibble 1 */
239                                 0x10042004, 0x00000000, 0x00042000, 0x10040000,
240                                 0x10000004, 0x00002004, 0x10002000, 0x00042000,
241                                 0x00002000, 0x10040004, 0x00000004, 0x10002000,
242                                 0x00040004, 0x10042000, 0x10040000, 0x00000004,
243                                 0x00040000, 0x10002004, 0x10040004, 0x00002000,
244                                 0x00042004, 0x10000000, 0x00000000, 0x00040004,
245                                 0x10002004, 0x00042004, 0x10042000, 0x10000004,
246                                 0x10000000, 0x00040000, 0x00002004, 0x10042004,
247                                 0x00040004, 0x10042000, 0x10002000, 0x00042004,
248                                 0x10042004, 0x00040004, 0x10000004, 0x00000000,
249                                 0x10000000, 0x00002004, 0x00040000, 0x10040004,
250                                 0x00002000, 0x10000000, 0x00042004, 0x10002004,
251                                 0x10042000, 0x00002000, 0x00000000, 0x10000004,
252                                 0x00000004, 0x10042004, 0x00042000, 0x10040000,
253                                 0x10040004, 0x00040000, 0x00002004, 0x10002000,
254                                 0x10002004, 0x00000004, 0x10040000, 0x00042000,
255                         },
256                         {
257                                 /* nibble 2 */
258                                 0x41000000, 0x01010040, 0x00000040, 0x41000040,
259                                 0x40010000, 0x01000000, 0x41000040, 0x00010040,
260                                 0x01000040, 0x00010000, 0x01010000, 0x40000000,
261                                 0x41010040, 0x40000040, 0x40000000, 0x41010000,
262                                 0x00000000, 0x40010000, 0x01010040, 0x00000040,
263                                 0x40000040, 0x41010040, 0x00010000, 0x41000000,
264                                 0x41010000, 0x01000040, 0x40010040, 0x01010000,
265                                 0x00010040, 0x00000000, 0x01000000, 0x40010040,
266                                 0x01010040, 0x00000040, 0x40000000, 0x00010000,
267                                 0x40000040, 0x40010000, 0x01010000, 0x41000040,
268                                 0x00000000, 0x01010040, 0x00010040, 0x41010000,
269                                 0x40010000, 0x01000000, 0x41010040, 0x40000000,
270                                 0x40010040, 0x41000000, 0x01000000, 0x41010040,
271                                 0x00010000, 0x01000040, 0x41000040, 0x00010040,
272                                 0x01000040, 0x00000000, 0x41010000, 0x40000040,
273                                 0x41000000, 0x40010040, 0x00000040, 0x01010000,
274                         },
275                         {
276                                 /* nibble 3 */
277                                 0x00100402, 0x04000400, 0x00000002, 0x04100402,
278                                 0x00000000, 0x04100000, 0x04000402, 0x00100002,
279                                 0x04100400, 0x04000002, 0x04000000, 0x00000402,
280                                 0x04000002, 0x00100402, 0x00100000, 0x04000000,
281                                 0x04100002, 0x00100400, 0x00000400, 0x00000002,
282                                 0x00100400, 0x04000402, 0x04100000, 0x00000400,
283                                 0x00000402, 0x00000000, 0x00100002, 0x04100400,
284                                 0x04000400, 0x04100002, 0x04100402, 0x00100000,
285                                 0x04100002, 0x00000402, 0x00100000, 0x04000002,
286                                 0x00100400, 0x04000400, 0x00000002, 0x04100000,
287                                 0x04000402, 0x00000000, 0x00000400, 0x00100002,
288                                 0x00000000, 0x04100002, 0x04100400, 0x00000400,
289                                 0x04000000, 0x04100402, 0x00100402, 0x00100000,
290                                 0x04100402, 0x00000002, 0x04000400, 0x00100402,
291                                 0x00100002, 0x00100400, 0x04100000, 0x04000402,
292                                 0x00000402, 0x04000000, 0x04000002, 0x04100400,
293                         },
294                         {
295                                 /* nibble 4 */
296                                 0x02000000, 0x00004000, 0x00000100, 0x02004108,
297                                 0x02004008, 0x02000100, 0x00004108, 0x02004000,
298                                 0x00004000, 0x00000008, 0x02000008, 0x00004100,
299                                 0x02000108, 0x02004008, 0x02004100, 0x00000000,
300                                 0x00004100, 0x02000000, 0x00004008, 0x00000108,
301                                 0x02000100, 0x00004108, 0x00000000, 0x02000008,
302                                 0x00000008, 0x02000108, 0x02004108, 0x00004008,
303                                 0x02004000, 0x00000100, 0x00000108, 0x02004100,
304                                 0x02004100, 0x02000108, 0x00004008, 0x02004000,
305                                 0x00004000, 0x00000008, 0x02000008, 0x02000100,
306                                 0x02000000, 0x00004100, 0x02004108, 0x00000000,
307                                 0x00004108, 0x02000000, 0x00000100, 0x00004008,
308                                 0x02000108, 0x00000100, 0x00000000, 0x02004108,
309                                 0x02004008, 0x02004100, 0x00000108, 0x00004000,
310                                 0x00004100, 0x02004008, 0x02000100, 0x00000108,
311                                 0x00000008, 0x00004108, 0x02004000, 0x02000008,
312                         },
313                         {
314                                 /* nibble 5 */
315                                 0x20000010, 0x00080010, 0x00000000, 0x20080800,
316                                 0x00080010, 0x00000800, 0x20000810, 0x00080000,
317                                 0x00000810, 0x20080810, 0x00080800, 0x20000000,
318                                 0x20000800, 0x20000010, 0x20080000, 0x00080810,
319                                 0x00080000, 0x20000810, 0x20080010, 0x00000000,
320                                 0x00000800, 0x00000010, 0x20080800, 0x20080010,
321                                 0x20080810, 0x20080000, 0x20000000, 0x00000810,
322                                 0x00000010, 0x00080800, 0x00080810, 0x20000800,
323                                 0x00000810, 0x20000000, 0x20000800, 0x00080810,
324                                 0x20080800, 0x00080010, 0x00000000, 0x20000800,
325                                 0x20000000, 0x00000800, 0x20080010, 0x00080000,
326                                 0x00080010, 0x20080810, 0x00080800, 0x00000010,
327                                 0x20080810, 0x00080800, 0x00080000, 0x20000810,
328                                 0x20000010, 0x20080000, 0x00080810, 0x00000000,
329                                 0x00000800, 0x20000010, 0x20000810, 0x20080800,
330                                 0x20080000, 0x00000810, 0x00000010, 0x20080010,
331                         },
332                         {
333                                 /* nibble 6 */
334                                 0x00001000, 0x00000080, 0x00400080, 0x00400001,
335                                 0x00401081, 0x00001001, 0x00001080, 0x00000000,
336                                 0x00400000, 0x00400081, 0x00000081, 0x00401000,
337                                 0x00000001, 0x00401080, 0x00401000, 0x00000081,
338                                 0x00400081, 0x00001000, 0x00001001, 0x00401081,
339                                 0x00000000, 0x00400080, 0x00400001, 0x00001080,
340                                 0x00401001, 0x00001081, 0x00401080, 0x00000001,
341                                 0x00001081, 0x00401001, 0x00000080, 0x00400000,
342                                 0x00001081, 0x00401000, 0x00401001, 0x00000081,
343                                 0x00001000, 0x00000080, 0x00400000, 0x00401001,
344                                 0x00400081, 0x00001081, 0x00001080, 0x00000000,
345                                 0x00000080, 0x00400001, 0x00000001, 0x00400080,
346                                 0x00000000, 0x00400081, 0x00400080, 0x00001080,
347                                 0x00000081, 0x00001000, 0x00401081, 0x00400000,
348                                 0x00401080, 0x00000001, 0x00001001, 0x00401081,
349                                 0x00400001, 0x00401080, 0x00401000, 0x00001001,
350                         },
351                         {
352                                 /* nibble 7 */
353                                 0x08200020, 0x08208000, 0x00008020, 0x00000000,
354                                 0x08008000, 0x00200020, 0x08200000, 0x08208020,
355                                 0x00000020, 0x08000000, 0x00208000, 0x00008020,
356                                 0x00208020, 0x08008020, 0x08000020, 0x08200000,
357                                 0x00008000, 0x00208020, 0x00200020, 0x08008000,
358                                 0x08208020, 0x08000020, 0x00000000, 0x00208000,
359                                 0x08000000, 0x00200000, 0x08008020, 0x08200020,
360                                 0x00200000, 0x00008000, 0x08208000, 0x00000020,
361                                 0x00200000, 0x00008000, 0x08000020, 0x08208020,
362                                 0x00008020, 0x08000000, 0x00000000, 0x00208000,
363                                 0x08200020, 0x08008020, 0x08008000, 0x00200020,
364                                 0x08208000, 0x00000020, 0x00200020, 0x08008000,
365                                 0x08208020, 0x00200000, 0x08200000, 0x08000020,
366                                 0x00208000, 0x00008020, 0x08008020, 0x08200000,
367                                 0x00000020, 0x08208000, 0x00208020, 0x00000000,
368                                 0x08000000, 0x08200020, 0x00008000, 0x00208020
369                         }
370                 };
371
372         private static final int cov_2char[] =
373                 {
374                         0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
375                         0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44,
376                         0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C,
377                         0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54,
378                         0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61, 0x62,
379                         0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A,
380                         0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72,
381                         0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A
382                 };
383
384         private static final int byteToUnsigned(byte b)
385         {
386                 int value = (int)b;
387
388                 return (value >= 0 ? value : value + 256);
389         }
390
391         private static int fourBytesToInt(byte b[], int offset)
392         {
393                 int value;
394
395                 value = byteToUnsigned(b[offset++]);
396                 value |= (byteToUnsigned(b[offset++]) << 8);
397                 value |= (byteToUnsigned(b[offset++]) << 16);
398                 value |= (byteToUnsigned(b[offset++]) << 24);
399
400                 return (value);
401         }
402
403         private static final void intToFourBytes(int iValue, byte b[], int offset)
404         {
405                 b[offset++] = (byte)((iValue) & 0xff);
406                 b[offset++] = (byte)((iValue >>> 8 ) & 0xff);
407                 b[offset++] = (byte)((iValue >>> 16) & 0xff);
408                 b[offset++] = (byte)((iValue >>> 24) & 0xff);
409         }
410
411         private static final void PERM_OP(int a, int b, int n, int m, int results[])
412         {
413                 int t;
414
415                 t = ((a >>> n) ^ b) & m;
416                 a ^= t << n;
417                 b ^= t;
418
419                 results[0] = a;
420                 results[1] = b;
421         }
422
423         private static final int HPERM_OP(int a, int n, int m)
424         {
425                 int t;
426
427                 t = ((a << (16 - n)) ^ a) & m;
428                 a = a ^ t ^ (t >>> (16 - n));
429
430                 return (a);
431         }
432
433         private static int [] des_set_key(byte key[])
434         {
435                 int schedule[] = new int[ITERATIONS * 2];
436
437                 int c = fourBytesToInt(key, 0);
438                 int d = fourBytesToInt(key, 4);
439
440                 int results[] = new int[2];
441
442                 PERM_OP(d, c, 4, 0x0f0f0f0f, results);
443                 d = results[0];
444                 c = results[1];
445
446                 c = HPERM_OP(c, -2, 0xcccc0000);
447                 d = HPERM_OP(d, -2, 0xcccc0000);
448
449                 PERM_OP(d, c, 1, 0x55555555, results);
450                 d = results[0];
451                 c = results[1];
452
453                 PERM_OP(c, d, 8, 0x00ff00ff, results);
454                 c = results[0];
455                 d = results[1];
456
457                 PERM_OP(d, c, 1, 0x55555555, results);
458                 d = results[0];
459                 c = results[1];
460
461                 d = (((d & 0x000000ff) << 16) | (d & 0x0000ff00) |
462                          ((d & 0x00ff0000) >>> 16) | ((c & 0xf0000000) >>> 4));
463                 c &= 0x0fffffff;
464
465                 int s, t;
466                 int j = 0;
467
468                 for (int i = 0; i < ITERATIONS; i ++)
469                 {
470                         if (shifts2[i])
471                         {
472                                 c = (c >>> 2) | (c << 26);
473                                 d = (d >>> 2) | (d << 26);
474                         }
475                         else
476                         {
477                                 c = (c >>> 1) | (c << 27);
478                                 d = (d >>> 1) | (d << 27);
479                         }
480
481                         c &= 0x0fffffff;
482                         d &= 0x0fffffff;
483
484                         s = skb[0][ (c ) & 0x3f ] |
485                                 skb[1][((c >>> 6) & 0x03) | ((c >>> 7) & 0x3c)] |
486                                 skb[2][((c >>> 13) & 0x0f) | ((c >>> 14) & 0x30)] |
487                                 skb[3][((c >>> 20) & 0x01) | ((c >>> 21) & 0x06) |
488                                            ((c >>> 22) & 0x38)];
489
490                         t = skb[4][ (d ) & 0x3f ] |
491                                 skb[5][((d >>> 7) & 0x03) | ((d >>> 8) & 0x3c)] |
492                                 skb[6][ (d >>> 15) & 0x3f ] |
493                                 skb[7][((d >>> 21) & 0x0f) | ((d >>> 22) & 0x30)];
494
495                         schedule[j++] = ((t << 16) | (s & 0x0000ffff)) & 0xffffffff;
496                         s = ((s >>> 16) | (t & 0xffff0000));
497
498                         s = (s << 4) | (s >>> 28);
499                         schedule[j++] = s & 0xffffffff;
500                 }
501                 return (schedule);
502         }
503
504         private static final int D_ENCRYPT
505         (
506                 int L, int R, int S, int E0, int E1, int s[]
507         )
508         {
509                 int t, u, v;
510
511                 v = R ^ (R >>> 16);
512                 u = v & E0;
513                 v = v & E1;
514                 u = (u ^ (u << 16)) ^ R ^ s[S];
515                 t = (v ^ (v << 16)) ^ R ^ s[S + 1];
516                 t = (t >>> 4) | (t << 28);
517
518                 L ^= SPtrans[1][(t ) & 0x3f] |
519                          SPtrans[3][(t >>> 8) & 0x3f] |
520                          SPtrans[5][(t >>> 16) & 0x3f] |
521                          SPtrans[7][(t >>> 24) & 0x3f] |
522                          SPtrans[0][(u ) & 0x3f] |
523                          SPtrans[2][(u >>> 8) & 0x3f] |
524                          SPtrans[4][(u >>> 16) & 0x3f] |
525                          SPtrans[6][(u >>> 24) & 0x3f];
526
527                 return (L);
528         }
529
530         private static final int [] body(int schedule[], int Eswap0, int Eswap1)
531         {
532                 int left = 0;
533                 int right = 0;
534                 int t = 0;
535
536                 for (int j = 0; j < 25; j ++)
537                 {
538                         for (int i = 0; i < ITERATIONS * 2; i += 4)
539                         {
540                                 left = D_ENCRYPT(left, right, i, Eswap0, Eswap1, schedule);
541                                 right = D_ENCRYPT(right, left, i + 2, Eswap0, Eswap1, schedule);
542                         }
543                         t = left;
544                         left = right;
545                         right = t;
546                 }
547
548                 t = right;
549
550                 right = (left >>> 1) | (left << 31);
551                 left = (t >>> 1) | (t << 31);
552
553                 left &= 0xffffffff;
554                 right &= 0xffffffff;
555
556                 int results[] = new int[2];
557
558                 PERM_OP(right, left, 1, 0x55555555, results);
559                 right = results[0];
560                 left = results[1];
561
562                 PERM_OP(left, right, 8, 0x00ff00ff, results);
563                 left = results[0];
564                 right = results[1];
565
566                 PERM_OP(right, left, 2, 0x33333333, results);
567                 right = results[0];
568                 left = results[1];
569
570                 PERM_OP(left, right, 16, 0x0000ffff, results);
571                 left = results[0];
572                 right = results[1];
573
574                 PERM_OP(right, left, 4, 0x0f0f0f0f, results);
575                 right = results[0];
576                 left = results[1];
577
578                 int out[] = new int[2];
579
580                 out[0] = left;
581                 out[1] = right;
582
583                 return (out);
584         }
585
586         /*
587          * <P>Encrypt a password given the cleartext password and a "salt".</P>
588          * @param salt A two-character string representing the salt used to
589          * iterate the encryption engine in lots of different ways. If you
590          * are generating a new encryption then this value should be
591          * randomised.
592          * @param original The password to be encrypted.
593          * @return A string consisting of the 2-character salt followed by the
594          * encrypted password.
595          */
596         public static final String crypt(String salt, String original)
597         {
598                 while (salt.length() < 2)
599                         salt += "A";
600
601                 StringBuffer buffer = new StringBuffer("             ");
602
603                 char charZero = salt.charAt(0);
604                 char charOne = salt.charAt(1);
605
606                 buffer.setCharAt(0, charZero);
607                 buffer.setCharAt(1, charOne);
608
609                 int Eswap0 = con_salt[(int)charZero];
610                 int Eswap1 = con_salt[(int)charOne] << 4;
611
612                 byte key[] = new byte[8];
613
614                 for (int i = 0; i < key.length; i ++)
615                         key[i] = (byte)0;
616
617                 for (int i = 0; i < key.length && i < original.length(); i ++)
618                 {
619                         int iChar = (int)original.charAt(i);
620
621                         key[i] = (byte)(iChar << 1);
622                 }
623
624                 int schedule[] = des_set_key(key);
625                 int out[] = body(schedule, Eswap0, Eswap1);
626
627                 byte b[] = new byte[9];
628
629                 intToFourBytes(out[0], b, 0);
630                 intToFourBytes(out[1], b, 4);
631                 b[8] = 0;
632
633                 for (int i = 2, y = 0, u = 0x80; i < 13; i ++)
634                 {
635                         for (int j = 0, c = 0; j < 6; j ++)
636                         {
637                                 c <<= 1;
638
639                                 if (((int)b[y] & u) != 0)
640                                         c |= 1;
641
642                                 u >>>= 1;
643
644                                 if (u == 0)
645                                 {
646                                         y++;
647                                         u = 0x80;
648                                 }
649                                 buffer.setCharAt(i, (char)cov_2char[c]);
650                         }
651                 }
652                 return (buffer.toString());
653         }
654
655         /*
656          * <P>Encrypt a password given the cleartext password. This method
657          * generates a random salt using the 'java.util.Random' class.</P>
658          * @param original The password to be encrypted.
659          * @return A string consisting of the 2-character salt followed by the
660          * encrypted password.
661          */
662         public static final String crypt(String original)
663         {
664                 java.util.Random randomGenerator = new java.util.Random();
665                 int numSaltChars = saltChars.length;
666                 String salt;
667
668                 salt = (new StringBuffer()).append(saltChars[Math.abs(randomGenerator.nextInt()) % numSaltChars]).append(saltChars[Math.abs(randomGenerator.nextInt()) % numSaltChars]).toString();
669
670                 return crypt(salt, original);
671         }
672
673         /*
674          * <P>Check that <I>enteredPassword</I> encrypts to
675          * <I>encryptedPassword</I>.</P>
676          * @param encryptedPassword The <I>encryptedPassword</I>. The first
677          * two characters are assumed to be the salt. This string would
678          * be the same as one found in a Unix <U>/etc/passwd</U> file.
679          * @param enteredPassword The password as entered by the user (or
680          * otherwise aquired).
681          * @return <B>true</B> if the password should be considered correct.
682          */
683         public final static boolean matches(String encryptedPassword, String enteredPassword)
684         {
685                 String salt = encryptedPassword.substring(0, 3);
686                 String newCrypt = crypt(salt, enteredPassword);
687
688                 return newCrypt.equals(encryptedPassword);
689         }
690 }
691