1 package org.apache.turbine.services.crypto.impl;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.util.Random;
23
24 /***
25 * Unix crypt (3) algorithm implementation. The java
26 * implementation was taken from the JetSpeed Portal project
27 * (see org.apache.jetspeed.services.security.ldap.UnixCrypt).
28 *
29 * @author Siegfried Goeschl
30 */
31 public class UnixCrypt
32 {
33 private static final char saltChars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./".toCharArray();
34 private static final int ITERATIONS = 16;
35 private static final int con_salt[] = {
36 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
37 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
38 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
39 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
40 0, 0, 0, 0, 0, 0, 0, 1, 2, 3,
41 4, 5, 6, 7, 8, 9, 10, 11, 5, 6,
42 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
43 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
44 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
45 37, 32, 33, 34, 35, 36, 37, 38, 39, 40,
46 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
47 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
48 61, 62, 63, 0, 0, 0, 0, 0
49 };
50 private static final boolean shifts2[] = {
51 false, false, true, true, true, true, true, true, false, true,
52 true, true, true, true, true, false
53 };
54 private static final int skb[][] = {
55 {
56 0, 16, 0x20000000, 0x20000010, 0x10000, 0x10010, 0x20010000, 0x20010010, 2048, 2064,
57 0x20000800, 0x20000810, 0x10800, 0x10810, 0x20010800, 0x20010810, 32, 48, 0x20000020, 0x20000030,
58 0x10020, 0x10030, 0x20010020, 0x20010030, 2080, 2096, 0x20000820, 0x20000830, 0x10820, 0x10830,
59 0x20010820, 0x20010830, 0x80000, 0x80010, 0x20080000, 0x20080010, 0x90000, 0x90010, 0x20090000, 0x20090010,
60 0x80800, 0x80810, 0x20080800, 0x20080810, 0x90800, 0x90810, 0x20090800, 0x20090810, 0x80020, 0x80030,
61 0x20080020, 0x20080030, 0x90020, 0x90030, 0x20090020, 0x20090030, 0x80820, 0x80830, 0x20080820, 0x20080830,
62 0x90820, 0x90830, 0x20090820, 0x20090830
63 }, {
64 0, 0x2000000, 8192, 0x2002000, 0x200000, 0x2200000, 0x202000, 0x2202000, 4, 0x2000004,
65 8196, 0x2002004, 0x200004, 0x2200004, 0x202004, 0x2202004, 1024, 0x2000400, 9216, 0x2002400,
66 0x200400, 0x2200400, 0x202400, 0x2202400, 1028, 0x2000404, 9220, 0x2002404, 0x200404, 0x2200404,
67 0x202404, 0x2202404, 0x10000000, 0x12000000, 0x10002000, 0x12002000, 0x10200000, 0x12200000, 0x10202000, 0x12202000,
68 0x10000004, 0x12000004, 0x10002004, 0x12002004, 0x10200004, 0x12200004, 0x10202004, 0x12202004, 0x10000400, 0x12000400,
69 0x10002400, 0x12002400, 0x10200400, 0x12200400, 0x10202400, 0x12202400, 0x10000404, 0x12000404, 0x10002404, 0x12002404,
70 0x10200404, 0x12200404, 0x10202404, 0x12202404
71 }, {
72 0, 1, 0x40000, 0x40001, 0x1000000, 0x1000001, 0x1040000, 0x1040001, 2, 3,
73 0x40002, 0x40003, 0x1000002, 0x1000003, 0x1040002, 0x1040003, 512, 513, 0x40200, 0x40201,
74 0x1000200, 0x1000201, 0x1040200, 0x1040201, 514, 515, 0x40202, 0x40203, 0x1000202, 0x1000203,
75 0x1040202, 0x1040203, 0x8000000, 0x8000001, 0x8040000, 0x8040001, 0x9000000, 0x9000001, 0x9040000, 0x9040001,
76 0x8000002, 0x8000003, 0x8040002, 0x8040003, 0x9000002, 0x9000003, 0x9040002, 0x9040003, 0x8000200, 0x8000201,
77 0x8040200, 0x8040201, 0x9000200, 0x9000201, 0x9040200, 0x9040201, 0x8000202, 0x8000203, 0x8040202, 0x8040203,
78 0x9000202, 0x9000203, 0x9040202, 0x9040203
79 }, {
80 0, 0x100000, 256, 0x100100, 8, 0x100008, 264, 0x100108, 4096, 0x101000,
81 4352, 0x101100, 4104, 0x101008, 4360, 0x101108, 0x4000000, 0x4100000, 0x4000100, 0x4100100,
82 0x4000008, 0x4100008, 0x4000108, 0x4100108, 0x4001000, 0x4101000, 0x4001100, 0x4101100, 0x4001008, 0x4101008,
83 0x4001108, 0x4101108, 0x20000, 0x120000, 0x20100, 0x120100, 0x20008, 0x120008, 0x20108, 0x120108,
84 0x21000, 0x121000, 0x21100, 0x121100, 0x21008, 0x121008, 0x21108, 0x121108, 0x4020000, 0x4120000,
85 0x4020100, 0x4120100, 0x4020008, 0x4120008, 0x4020108, 0x4120108, 0x4021000, 0x4121000, 0x4021100, 0x4121100,
86 0x4021008, 0x4121008, 0x4021108, 0x4121108
87 }, {
88 0, 0x10000000, 0x10000, 0x10010000, 4, 0x10000004, 0x10004, 0x10010004, 0x20000000, 0x30000000,
89 0x20010000, 0x30010000, 0x20000004, 0x30000004, 0x20010004, 0x30010004, 0x100000, 0x10100000, 0x110000, 0x10110000,
90 0x100004, 0x10100004, 0x110004, 0x10110004, 0x20100000, 0x30100000, 0x20110000, 0x30110000, 0x20100004, 0x30100004,
91 0x20110004, 0x30110004, 4096, 0x10001000, 0x11000, 0x10011000, 4100, 0x10001004, 0x11004, 0x10011004,
92 0x20001000, 0x30001000, 0x20011000, 0x30011000, 0x20001004, 0x30001004, 0x20011004, 0x30011004, 0x101000, 0x10101000,
93 0x111000, 0x10111000, 0x101004, 0x10101004, 0x111004, 0x10111004, 0x20101000, 0x30101000, 0x20111000, 0x30111000,
94 0x20101004, 0x30101004, 0x20111004, 0x30111004
95 }, {
96 0, 0x8000000, 8, 0x8000008, 1024, 0x8000400, 1032, 0x8000408, 0x20000, 0x8020000,
97 0x20008, 0x8020008, 0x20400, 0x8020400, 0x20408, 0x8020408, 1, 0x8000001, 9, 0x8000009,
98 1025, 0x8000401, 1033, 0x8000409, 0x20001, 0x8020001, 0x20009, 0x8020009, 0x20401, 0x8020401,
99 0x20409, 0x8020409, 0x2000000, 0xa000000, 0x2000008, 0xa000008, 0x2000400, 0xa000400, 0x2000408, 0xa000408,
100 0x2020000, 0xa020000, 0x2020008, 0xa020008, 0x2020400, 0xa020400, 0x2020408, 0xa020408, 0x2000001, 0xa000001,
101 0x2000009, 0xa000009, 0x2000401, 0xa000401, 0x2000409, 0xa000409, 0x2020001, 0xa020001, 0x2020009, 0xa020009,
102 0x2020401, 0xa020401, 0x2020409, 0xa020409
103 }, {
104 0, 256, 0x80000, 0x80100, 0x1000000, 0x1000100, 0x1080000, 0x1080100, 16, 272,
105 0x80010, 0x80110, 0x1000010, 0x1000110, 0x1080010, 0x1080110, 0x200000, 0x200100, 0x280000, 0x280100,
106 0x1200000, 0x1200100, 0x1280000, 0x1280100, 0x200010, 0x200110, 0x280010, 0x280110, 0x1200010, 0x1200110,
107 0x1280010, 0x1280110, 512, 768, 0x80200, 0x80300, 0x1000200, 0x1000300, 0x1080200, 0x1080300,
108 528, 784, 0x80210, 0x80310, 0x1000210, 0x1000310, 0x1080210, 0x1080310, 0x200200, 0x200300,
109 0x280200, 0x280300, 0x1200200, 0x1200300, 0x1280200, 0x1280300, 0x200210, 0x200310, 0x280210, 0x280310,
110 0x1200210, 0x1200310, 0x1280210, 0x1280310
111 }, {
112 0, 0x4000000, 0x40000, 0x4040000, 2, 0x4000002, 0x40002, 0x4040002, 8192, 0x4002000,
113 0x42000, 0x4042000, 8194, 0x4002002, 0x42002, 0x4042002, 32, 0x4000020, 0x40020, 0x4040020,
114 34, 0x4000022, 0x40022, 0x4040022, 8224, 0x4002020, 0x42020, 0x4042020, 8226, 0x4002022,
115 0x42022, 0x4042022, 2048, 0x4000800, 0x40800, 0x4040800, 2050, 0x4000802, 0x40802, 0x4040802,
116 10240, 0x4002800, 0x42800, 0x4042800, 10242, 0x4002802, 0x42802, 0x4042802, 2080, 0x4000820,
117 0x40820, 0x4040820, 2082, 0x4000822, 0x40822, 0x4040822, 10272, 0x4002820, 0x42820, 0x4042820,
118 10274, 0x4002822, 0x42822, 0x4042822
119 }
120 };
121 private static final int SPtrans[][] = {
122 {
123 0x820200, 0x20000, 0x80800000, 0x80820200, 0x800000, 0x80020200, 0x80020000, 0x80800000, 0x80020200, 0x820200,
124 0x820000, 0x80000200, 0x80800200, 0x800000, 0, 0x80020000, 0x20000, 0x80000000, 0x800200, 0x20200,
125 0x80820200, 0x820000, 0x80000200, 0x800200, 0x80000000, 512, 0x20200, 0x80820000, 512, 0x80800200,
126 0x80820000, 0, 0, 0x80820200, 0x800200, 0x80020000, 0x820200, 0x20000, 0x80000200, 0x800200,
127 0x80820000, 512, 0x20200, 0x80800000, 0x80020200, 0x80000000, 0x80800000, 0x820000, 0x80820200, 0x20200,
128 0x820000, 0x80800200, 0x800000, 0x80000200, 0x80020000, 0, 0x20000, 0x800000, 0x80800200, 0x820200,
129 0x80000000, 0x80820000, 512, 0x80020200
130 }, {
131 0x10042004, 0, 0x42000, 0x10040000, 0x10000004, 8196, 0x10002000, 0x42000, 8192, 0x10040004,
132 4, 0x10002000, 0x40004, 0x10042000, 0x10040000, 4, 0x40000, 0x10002004, 0x10040004, 8192,
133 0x42004, 0x10000000, 0, 0x40004, 0x10002004, 0x42004, 0x10042000, 0x10000004, 0x10000000, 0x40000,
134 8196, 0x10042004, 0x40004, 0x10042000, 0x10002000, 0x42004, 0x10042004, 0x40004, 0x10000004, 0,
135 0x10000000, 8196, 0x40000, 0x10040004, 8192, 0x10000000, 0x42004, 0x10002004, 0x10042000, 8192,
136 0, 0x10000004, 4, 0x10042004, 0x42000, 0x10040000, 0x10040004, 0x40000, 8196, 0x10002000,
137 0x10002004, 4, 0x10040000, 0x42000
138 }, {
139 0x41000000, 0x1010040, 64, 0x41000040, 0x40010000, 0x1000000, 0x41000040, 0x10040, 0x1000040, 0x10000,
140 0x1010000, 0x40000000, 0x41010040, 0x40000040, 0x40000000, 0x41010000, 0, 0x40010000, 0x1010040, 64,
141 0x40000040, 0x41010040, 0x10000, 0x41000000, 0x41010000, 0x1000040, 0x40010040, 0x1010000, 0x10040, 0,
142 0x1000000, 0x40010040, 0x1010040, 64, 0x40000000, 0x10000, 0x40000040, 0x40010000, 0x1010000, 0x41000040,
143 0, 0x1010040, 0x10040, 0x41010000, 0x40010000, 0x1000000, 0x41010040, 0x40000000, 0x40010040, 0x41000000,
144 0x1000000, 0x41010040, 0x10000, 0x1000040, 0x41000040, 0x10040, 0x1000040, 0, 0x41010000, 0x40000040,
145 0x41000000, 0x40010040, 64, 0x1010000
146 }, {
147 0x100402, 0x4000400, 2, 0x4100402, 0, 0x4100000, 0x4000402, 0x100002, 0x4100400, 0x4000002,
148 0x4000000, 1026, 0x4000002, 0x100402, 0x100000, 0x4000000, 0x4100002, 0x100400, 1024, 2,
149 0x100400, 0x4000402, 0x4100000, 1024, 1026, 0, 0x100002, 0x4100400, 0x4000400, 0x4100002,
150 0x4100402, 0x100000, 0x4100002, 1026, 0x100000, 0x4000002, 0x100400, 0x4000400, 2, 0x4100000,
151 0x4000402, 0, 1024, 0x100002, 0, 0x4100002, 0x4100400, 1024, 0x4000000, 0x4100402,
152 0x100402, 0x100000, 0x4100402, 2, 0x4000400, 0x100402, 0x100002, 0x100400, 0x4100000, 0x4000402,
153 1026, 0x4000000, 0x4000002, 0x4100400
154 }, {
155 0x2000000, 16384, 256, 0x2004108, 0x2004008, 0x2000100, 16648, 0x2004000, 16384, 8,
156 0x2000008, 16640, 0x2000108, 0x2004008, 0x2004100, 0, 16640, 0x2000000, 16392, 264,
157 0x2000100, 16648, 0, 0x2000008, 8, 0x2000108, 0x2004108, 16392, 0x2004000, 256,
158 264, 0x2004100, 0x2004100, 0x2000108, 16392, 0x2004000, 16384, 8, 0x2000008, 0x2000100,
159 0x2000000, 16640, 0x2004108, 0, 16648, 0x2000000, 256, 16392, 0x2000108, 256,
160 0, 0x2004108, 0x2004008, 0x2004100, 264, 16384, 16640, 0x2004008, 0x2000100, 264,
161 8, 16648, 0x2004000, 0x2000008
162 }, {
163 0x20000010, 0x80010, 0, 0x20080800, 0x80010, 2048, 0x20000810, 0x80000, 2064, 0x20080810,
164 0x80800, 0x20000000, 0x20000800, 0x20000010, 0x20080000, 0x80810, 0x80000, 0x20000810, 0x20080010, 0,
165 2048, 16, 0x20080800, 0x20080010, 0x20080810, 0x20080000, 0x20000000, 2064, 16, 0x80800,
166 0x80810, 0x20000800, 2064, 0x20000000, 0x20000800, 0x80810, 0x20080800, 0x80010, 0, 0x20000800,
167 0x20000000, 2048, 0x20080010, 0x80000, 0x80010, 0x20080810, 0x80800, 16, 0x20080810, 0x80800,
168 0x80000, 0x20000810, 0x20000010, 0x20080000, 0x80810, 0, 2048, 0x20000010, 0x20000810, 0x20080800,
169 0x20080000, 2064, 16, 0x20080010
170 }, {
171 4096, 128, 0x400080, 0x400001, 0x401081, 4097, 4224, 0, 0x400000, 0x400081,
172 129, 0x401000, 1, 0x401080, 0x401000, 129, 0x400081, 4096, 4097, 0x401081,
173 0, 0x400080, 0x400001, 4224, 0x401001, 4225, 0x401080, 1, 4225, 0x401001,
174 128, 0x400000, 4225, 0x401000, 0x401001, 129, 4096, 128, 0x400000, 0x401001,
175 0x400081, 4225, 4224, 0, 128, 0x400001, 1, 0x400080, 0, 0x400081,
176 0x400080, 4224, 129, 4096, 0x401081, 0x400000, 0x401080, 1, 4097, 0x401081,
177 0x400001, 0x401080, 0x401000, 4097
178 }, {
179 0x8200020, 0x8208000, 32800, 0, 0x8008000, 0x200020, 0x8200000, 0x8208020, 32, 0x8000000,
180 0x208000, 32800, 0x208020, 0x8008020, 0x8000020, 0x8200000, 32768, 0x208020, 0x200020, 0x8008000,
181 0x8208020, 0x8000020, 0, 0x208000, 0x8000000, 0x200000, 0x8008020, 0x8200020, 0x200000, 32768,
182 0x8208000, 32, 0x200000, 32768, 0x8000020, 0x8208020, 32800, 0x8000000, 0, 0x208000,
183 0x8200020, 0x8008020, 0x8008000, 0x200020, 0x8208000, 32, 0x200020, 0x8008000, 0x8208020, 0x200000,
184 0x8200000, 0x8000020, 0x208000, 32800, 0x8008020, 0x8200000, 32, 0x8208000, 0x208020, 0,
185 0x8000000, 0x8200020, 32768, 0x208020
186 }
187 };
188 private static final int cov_2char[] = {
189 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
190 56, 57, 65, 66, 67, 68, 69, 70, 71, 72,
191 73, 74, 75, 76, 77, 78, 79, 80, 81, 82,
192 83, 84, 85, 86, 87, 88, 89, 90, 97, 98,
193 99, 100, 101, 102, 103, 104, 105, 106, 107, 108,
194 109, 110, 111, 112, 113, 114, 115, 116, 117, 118,
195 119, 120, 121, 122
196 };
197
198 private UnixCrypt() {}
199
200 private static final int D_ENCRYPT(int L, int R, int S, int E0, int E1, int s[])
201 {
202 int v = R ^ R >>> 16;
203 int u = v & E0;
204 v &= E1;
205 u = u ^ u << 16 ^ R ^ s[S];
206 int t = v ^ v << 16 ^ R ^ s[S + 1];
207 t = t >>> 4 | t << 28;
208 L ^= SPtrans[1][t & 0x3f] | SPtrans[3][t >>> 8 & 0x3f] | SPtrans[5][t >>> 16 & 0x3f] | SPtrans[7][t >>> 24 & 0x3f] | SPtrans[0][u & 0x3f] | SPtrans[2][u >>> 8 & 0x3f] | SPtrans[4][u >>> 16 & 0x3f] | SPtrans[6][u >>> 24 & 0x3f];
209 return L;
210 }
211
212 private static final int HPERM_OP(int a, int n, int m)
213 {
214 int t = (a << 16 - n ^ a) & m;
215 a = a ^ t ^ t >>> 16 - n;
216 return a;
217 }
218
219 private static final void PERM_OP(int a, int b, int n, int m, int results[])
220 {
221 int t = (a >>> n ^ b) & m;
222 a ^= t << n;
223 b ^= t;
224 results[0] = a;
225 results[1] = b;
226 }
227
228 private static final int[] body(int schedule[], int Eswap0, int Eswap1)
229 {
230 int left = 0;
231 int right = 0;
232 int t = 0;
233 for(int j = 0; j < 25; j++)
234 {
235 for(int i = 0; i < 32; i += 4)
236 {
237 left = D_ENCRYPT(left, right, i, Eswap0, Eswap1, schedule);
238 right = D_ENCRYPT(right, left, i + 2, Eswap0, Eswap1, schedule);
239 }
240
241 t = left;
242 left = right;
243 right = t;
244 }
245
246 t = right;
247 right = left >>> 1 | left << 31;
248 left = t >>> 1 | t << 31;
249 left &= 0xffffffff;
250 right &= 0xffffffff;
251 int results[] = new int[2];
252 PERM_OP(right, left, 1, 0x55555555, results);
253 right = results[0];
254 left = results[1];
255 PERM_OP(left, right, 8, 0xff00ff, results);
256 left = results[0];
257 right = results[1];
258 PERM_OP(right, left, 2, 0x33333333, results);
259 right = results[0];
260 left = results[1];
261 PERM_OP(left, right, 16, 65535, results);
262 left = results[0];
263 right = results[1];
264 PERM_OP(right, left, 4, 0xf0f0f0f, results);
265 right = results[0];
266 left = results[1];
267 int out[] = new int[2];
268 out[0] = left;
269 out[1] = right;
270 return out;
271 }
272
273 private static final int byteToUnsigned(byte b)
274 {
275 int value = b;
276 return value < 0 ? value + 256 : value;
277 }
278
279 public static final String crypt(String original)
280 {
281 Random randomGenerator = new Random();
282 int numSaltChars = saltChars.length;
283 String salt = "" + saltChars[Math.abs(randomGenerator.nextInt()) % numSaltChars] + saltChars[Math.abs(randomGenerator.nextInt()) % numSaltChars];
284 return crypt(salt, original);
285 }
286
287 public static final String crypt(String salt, String original)
288 {
289 for(; salt.length() < 2; salt = salt + "A");
290 StringBuffer buffer = new StringBuffer(" ");
291 char charZero = salt.charAt(0);
292 char charOne = salt.charAt(1);
293 buffer.setCharAt(0, charZero);
294 buffer.setCharAt(1, charOne);
295 int Eswap0 = con_salt[charZero];
296 int Eswap1 = con_salt[charOne] << 4;
297 byte key[] = new byte[8];
298 for(int i = 0; i < key.length; i++)
299 key[i] = 0;
300
301 for(int i = 0; i < key.length && i < original.length(); i++)
302 {
303 int iChar = original.charAt(i);
304 key[i] = (byte)(iChar << 1);
305 }
306
307 int schedule[] = des_set_key(key);
308 int out[] = body(schedule, Eswap0, Eswap1);
309 byte b[] = new byte[9];
310 intToFourBytes(out[0], b, 0);
311 intToFourBytes(out[1], b, 4);
312 b[8] = 0;
313 int i = 2;
314 int y = 0;
315 int u = 128;
316 for(; i < 13; i++)
317 {
318 int j = 0;
319 int c = 0;
320 for(; j < 6; j++)
321 {
322 c <<= 1;
323 if((b[y] & u) != 0)
324 c |= 0x1;
325 u >>>= 1;
326 if(u == 0)
327 {
328 y++;
329 u = 128;
330 }
331 buffer.setCharAt(i, (char) cov_2char[c]);
332 }
333
334 }
335
336 return buffer.toString();
337 }
338
339 private static int[] des_set_key(byte key[])
340 {
341 int schedule[] = new int[32];
342 int c = fourBytesToInt(key, 0);
343 int d = fourBytesToInt(key, 4);
344 int results[] = new int[2];
345 PERM_OP(d, c, 4, 0xf0f0f0f, results);
346 d = results[0];
347 c = results[1];
348 c = HPERM_OP(c, -2, 0xcccc0000);
349 d = HPERM_OP(d, -2, 0xcccc0000);
350 PERM_OP(d, c, 1, 0x55555555, results);
351 d = results[0];
352 c = results[1];
353 PERM_OP(c, d, 8, 0xff00ff, results);
354 c = results[0];
355 d = results[1];
356 PERM_OP(d, c, 1, 0x55555555, results);
357 d = results[0];
358 c = results[1];
359 d = (d & 0xff) << 16 | d & 0xff00 | (d & 0xff0000) >>> 16 | (c & 0xf0000000) >>> 4;
360 c &= 0xfffffff;
361 int j = 0;
362 for(int i = 0; i < 16; i++)
363 {
364 if(shifts2[i])
365 {
366 c = c >>> 2 | c << 26;
367 d = d >>> 2 | d << 26;
368 } else
369 {
370 c = c >>> 1 | c << 27;
371 d = d >>> 1 | d << 27;
372 }
373 c &= 0xfffffff;
374 d &= 0xfffffff;
375 int s = skb[0][c & 0x3f] | skb[1][c >>> 6 & 0x3 | c >>> 7 & 0x3c] | skb[2][c >>> 13 & 0xf | c >>> 14 & 0x30] | skb[3][c >>> 20 & 0x1 | c >>> 21 & 0x6 | c >>> 22 & 0x38];
376 int t = skb[4][d & 0x3f] | skb[5][d >>> 7 & 0x3 | d >>> 8 & 0x3c] | skb[6][d >>> 15 & 0x3f] | skb[7][d >>> 21 & 0xf | d >>> 22 & 0x30];
377 schedule[j++] = (t << 16 | s & 0xffff) & 0xffffffff;
378 s = s >>> 16 | t & 0xffff0000;
379 s = s << 4 | s >>> 28;
380 schedule[j++] = s & 0xffffffff;
381 }
382
383 return schedule;
384 }
385
386 private static int fourBytesToInt(byte b[], int offset)
387 {
388 int value = byteToUnsigned(b[offset++]);
389 value |= byteToUnsigned(b[offset++]) << 8;
390 value |= byteToUnsigned(b[offset++]) << 16;
391 value |= byteToUnsigned(b[offset++]) << 24;
392 return value;
393 }
394
395 private static final void intToFourBytes(int iValue, byte b[], int offset)
396 {
397 b[offset++] = (byte)(iValue & 0xff);
398 b[offset++] = (byte)(iValue >>> 8 & 0xff);
399 b[offset++] = (byte)(iValue >>> 16 & 0xff);
400 b[offset++] = (byte)(iValue >>> 24 & 0xff);
401 }
402
403 public static final boolean matches(String encryptedPassword, String enteredPassword)
404 {
405 String salt = encryptedPassword.substring(0, 3);
406 String newCrypt = crypt(salt, enteredPassword);
407 return newCrypt.equals(encryptedPassword);
408 }
409
410 }