1 /*
2  * Copyright (c) 2000, 2003, 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 /*      Copyright (c) 1988 AT&T */
27 /*        All Rights Reserved   */
28 
29 /**
30  * Implements the UNIX crypt(3) function, based on a direct port of the
31  * libc crypt function.
32  *
33  * <p>
34  * From the crypt man page:
35  * <p>
36  * crypt() is the password encryption routine, based on the NBS
37  * Data  Encryption  Standard,  with variations intended (among
38  * other things) to frustrate use of  hardware  implementations
39  * of the DES for key search.
40  * <p>
41  * The first argument to crypt() is  normally  a  user's  typed
42  * password.   The  second  is a 2-character string chosen from
43  * the set [a-zA-Z0-9./].  the  salt string is used to perturb
44  * the DES algorithm in one
45  * of 4096 different ways, after which the password is used  as
46  * the  key  to  encrypt  repeatedly  a  constant  string.  The
47  * returned value points to the encrypted password, in the same
48  * alphabet as the salt.  The first two characters are the salt
49  * itself.
50  *
51  * @author Roland Schemers
52  */
53 
54 package com.sun.security.auth.module;
55 
56 class Crypt {
57 
58 /* EXPORT DELETE START */
59 
60     private static final byte[] IP = {
61         58, 50, 42, 34, 26, 18, 10, 2,
62         60, 52, 44, 36, 28, 20, 12, 4,
63         62, 54, 46, 38, 30, 22, 14, 6,
64         64, 56, 48, 40, 32, 24, 16, 8,
65         57, 49, 41, 33, 25, 17, 9, 1,
66         59, 51, 43, 35, 27, 19, 11, 3,
67         61, 53, 45, 37, 29, 21, 13, 5,
68         63, 55, 47, 39, 31, 23, 15, 7,
69     };
70 
71     private static final byte[] FP = {
72         40, 8, 48, 16, 56, 24, 64, 32,
73         39, 7, 47, 15,  55, 23, 63, 31,
74         38, 6, 46, 14, 54, 22, 62, 30,
75         37, 5, 45, 13, 53, 21, 61, 29,
76         36, 4, 44, 12, 52, 20, 60, 28,
77         35, 3, 43, 11, 51, 19, 59, 27,
78         34, 2, 42, 10, 50, 18, 58, 26,
79         33, 1, 41, 9, 49, 17, 57, 25,
80     };
81 
82     private static final byte[] PC1_C = {
83         57, 49, 41, 33, 25, 17, 9,
84         1, 58, 50, 42, 34, 26, 18,
85         10, 2, 59, 51, 43, 35, 27,
86         19, 11, 3, 60, 52, 44, 36,
87     };
88 
89     private static final byte[] PC1_D = {
90         63, 55, 47, 39, 31, 23, 15,
91         7, 62, 54, 46, 38, 30, 22,
92         14, 6, 61, 53, 45, 37, 29,
93         21, 13, 5, 28, 20, 12, 4,
94     };
95 
96     private static final byte[] shifts = { 1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1, };
97 
98     private static final byte[] PC2_C = {
99         14, 17, 11, 24, 1, 5,
100         3, 28, 15, 6, 21, 10,
101         23, 19, 12, 4, 26, 8,
102         16, 7, 27, 20, 13, 2,
103     };
104 
105     private static final byte[] PC2_D = {
106         41,52,31,37,47,55,
107         30,40,51,45,33,48,
108         44,49,39,56,34,53,
109         46,42,50,36,29,32,
110     };
111 
112     private byte[] C = new byte[28];
113     private byte[] D = new byte[28];
114 
115     private byte[] KS;
116 
117     private byte[] E = new byte[48];
118 
119     private static final byte[] e2 = {
120         32, 1, 2, 3, 4, 5,
121         4, 5, 6, 7, 8, 9,
122         8, 9,10,11,12,13,
123         12,13,14,15,16,17,
124         16,17,18,19,20,21,
125         20,21,22,23,24,25,
126         24,25,26,27,28,29,
127         28,29,30,31,32, 1,
128     };
129 
setkey(byte[] key)130     private void setkey(byte[] key) {
131         int i, j, k;
132         byte t;
133 
134         if (KS == null) {
135             KS = new byte[16*48];
136         }
137 
138         for (i = 0; i < 28; i++) {
139                 C[i] = key[PC1_C[i]-1];
140                 D[i] = key[PC1_D[i]-1];
141         }
142         for (i = 0; i < 16; i++) {
143                 for (k = 0; k < shifts[i]; k++) {
144                         t = C[0];
145                         for (j = 0; j < 28-1; j++)
146                                 C[j] = C[j+1];
147                         C[27] = t;
148                         t = D[0];
149                         for (j = 0; j < 28-1; j++)
150                                 D[j] = D[j+1];
151                         D[27] = t;
152                 }
153                 for (j = 0; j < 24; j++) {
154                         int index = i * 48;
155 
156                         KS[index+j] = C[PC2_C[j]-1];
157                         KS[index+j+24] = D[PC2_D[j]-28-1];
158                 }
159         }
160         for (i = 0; i < 48; i++)
161                 E[i] = e2[i];
162     }
163 
164 
165     private static final byte[][] S = {
166         {14, 4,13, 1, 2,15,11, 8, 3,10, 6,12, 5, 9, 0, 7,
167         0,15, 7, 4,14, 2,13, 1,10, 6,12,11, 9, 5, 3, 8,
168         4, 1,14, 8,13, 6, 2,11,15,12, 9, 7, 3,10, 5, 0,
169         15,12, 8, 2, 4, 9, 1, 7, 5,11, 3,14,10, 0, 6,13},
170 
171         {15, 1, 8,14, 6,11, 3, 4, 9, 7, 2,13,12, 0, 5,10,
172         3,13, 4, 7,15, 2, 8,14,12, 0, 1,10, 6, 9,11, 5,
173         0,14, 7,11,10, 4,13, 1, 5, 8,12, 6, 9, 3, 2,15,
174         13, 8,10, 1, 3,15, 4, 2,11, 6, 7,12, 0, 5,14, 9},
175 
176         {10, 0, 9,14, 6, 3,15, 5, 1,13,12, 7,11, 4, 2, 8,
177         13, 7, 0, 9, 3, 4, 6,10, 2, 8, 5,14,12,11,15, 1,
178         13, 6, 4, 9, 8,15, 3, 0,11, 1, 2,12, 5,10,14, 7,
179          1,10,13, 0, 6, 9, 8, 7, 4,15,14, 3,11, 5, 2,12},
180 
181         {7,13,14, 3, 0, 6, 9,10, 1, 2, 8, 5,11,12, 4,15,
182         13, 8,11, 5, 6,15, 0, 3, 4, 7, 2,12, 1,10,14, 9,
183         10, 6, 9, 0,12,11, 7,13,15, 1, 3,14, 5, 2, 8, 4,
184          3,15, 0, 6,10, 1,13, 8, 9, 4, 5,11,12, 7, 2,14},
185 
186         {2,12, 4, 1, 7,10,11, 6, 8, 5, 3,15,13, 0,14, 9,
187         14,11, 2,12, 4, 7,13, 1, 5, 0,15,10, 3, 9, 8, 6,
188          4, 2, 1,11,10,13, 7, 8,15, 9,12, 5, 6, 3, 0,14,
189         11, 8,12, 7, 1,14, 2,13, 6,15, 0, 9,10, 4, 5, 3},
190 
191         {12, 1,10,15, 9, 2, 6, 8, 0,13, 3, 4,14, 7, 5,11,
192         10,15, 4, 2, 7,12, 9, 5, 6, 1,13,14, 0,11, 3, 8,
193          9,14,15, 5, 2, 8,12, 3, 7, 0, 4,10, 1,13,11, 6,
194          4, 3, 2,12, 9, 5,15,10,11,14, 1, 7, 6, 0, 8,13},
195 
196         {4,11, 2,14,15, 0, 8,13, 3,12, 9, 7, 5,10, 6, 1,
197         13, 0,11, 7, 4, 9, 1,10,14, 3, 5,12, 2,15, 8, 6,
198          1, 4,11,13,12, 3, 7,14,10,15, 6, 8, 0, 5, 9, 2,
199          6,11,13, 8, 1, 4,10, 7, 9, 5, 0,15,14, 2, 3,12},
200 
201         {13, 2, 8, 4, 6,15,11, 1,10, 9, 3,14, 5, 0,12, 7,
202          1,15,13, 8,10, 3, 7, 4,12, 5, 6,11, 0,14, 9, 2,
203          7,11, 4, 1, 9,12,14, 2, 0, 6,10,13,15, 3, 5, 8,
204          2, 1,14, 7, 4,10, 8,13,15,12, 9, 0, 3, 5, 6,11},
205     };
206 
207 
208     private static final byte[] P = {
209         16, 7,20,21,
210         29,12,28,17,
211          1,15,23,26,
212          5,18,31,10,
213          2, 8,24,14,
214         32,27, 3, 9,
215         19,13,30, 6,
216         22,11, 4,25,
217     };
218 
219     private byte[]  L = new byte[64];
220     private byte[] tempL = new byte[32];
221     private byte[] f = new byte[32];
222     private byte[] preS = new byte[48];
223 
224 
encrypt(byte[] block,int fake)225     private void encrypt(byte[] block,int fake) {
226         int     i;
227         int t, j, k;
228         int R = 32; // &L[32]
229 
230         if (KS == null) {
231             KS = new byte[16*48];
232         }
233 
234         for(j=0; j < 64; j++) {
235             L[j] = block[IP[j]-1];
236         }
237         for(i=0; i < 16; i++) {
238             int index = i * 48;
239 
240             for(j=0; j < 32; j++) {
241                 tempL[j] = L[R+j];
242             }
243             for(j=0; j < 48; j++) {
244                 preS[j] = (byte) (L[R+E[j]-1] ^ KS[index+j]);
245             }
246             for(j=0; j < 8; j++) {
247                 t = 6*j;
248                 k = S[j][(preS[t+0]<<5)+
249                          (preS[t+1]<<3)+
250                          (preS[t+2]<<2)+
251                          (preS[t+3]<<1)+
252                          (preS[t+4]<<0)+
253                          (preS[t+5]<<4)];
254                 t = 4*j;
255                 f[t+0] = (byte) ((k>>3)&01);
256                 f[t+1] = (byte) ((k>>2)&01);
257                 f[t+2] = (byte) ((k>>1)&01);
258                 f[t+3] = (byte) ((k>>0)&01);
259             }
260             for(j=0; j < 32; j++) {
261                         L[R+j] = (byte) (L[j] ^ f[P[j]-1]);
262             }
263             for(j=0; j < 32; j++) {
264                         L[j] = tempL[j];
265             }
266         }
267         for(j=0; j < 32; j++) {
268             t = L[j];
269             L[j] = L[R+j];
270             L[R+j] = (byte)t;
271         }
272         for(j=0; j < 64; j++) {
273                 block[j] = L[FP[j]-1];
274         }
275     }
276 /* EXPORT DELETE END */
277 
278     /**
279      * Creates a new Crypt object for use with the crypt method.
280      *
281      */
282 
Crypt()283     public Crypt()
284     {
285         // does nothing at this time
286         super();
287     }
288 
289     /**
290      * Implements the libc crypt(3) function.
291      *
292      * @param pw the password to "encrypt".
293      *
294      * @param salt the salt to use.
295      *
296      * @return A new byte[13] array that contains the encrypted
297      * password. The first two characters are the salt.
298      *
299      */
300 
crypt(byte[] pw, byte[] salt)301     public synchronized byte[] crypt(byte[] pw, byte[] salt) {
302         int c, i, j, pwi;
303         byte temp;
304         byte[] block = new byte[66];
305         byte[] iobuf = new byte[13];
306 
307 /* EXPORT DELETE START */
308 
309         pwi = 0;
310 
311         for(i=0; pwi < pw.length && i < 64; pwi++) {
312             c = pw[pwi];
313             for(j=0; j < 7; j++, i++) {
314                 block[i] = (byte) ((c>>(6-j)) & 01);
315             }
316             i++;
317         }
318 
319         setkey(block);
320 
321         for(i=0; i < 66; i++) {
322             block[i] = 0;
323         }
324 
325         for(i=0; i < 2; i++) {
326             c = salt[i];
327             iobuf[i] = (byte)c;
328             if(c > 'Z')
329                 c -= 6;
330             if(c > '9')
331                 c -= 7;
332             c -= '.';
333             for(j=0; j < 6; j++) {
334                 if( ((c>>j) & 01) != 0) {
335                     temp = E[6*i+j];
336                     E[6*i+j] = E[6*i+j+24];
337                     E[6*i+j+24] = temp;
338                 }
339             }
340         }
341 
342         for(i=0; i < 25; i++) {
343                 encrypt(block,0);
344         }
345 
346         for(i=0; i < 11; i++) {
347             c = 0;
348             for(j=0; j < 6; j++) {
349                 c <<= 1;
350                 c |= block[6*i+j];
351             }
352             c += '.';
353             if(c > '9') {
354                 c += 7;
355             }
356             if(c > 'Z') {
357                 c += 6;
358             }
359             iobuf[i+2] = (byte)c;
360         }
361         //iobuf[i+2] = 0;
362         if(iobuf[1] == 0) {
363             iobuf[1] = iobuf[0];
364         }
365 /* EXPORT DELETE END */
366         return(iobuf);
367     }
368 
369     /**
370      * program to test the crypt routine.
371      *
372      * The first parameter is the cleartext password, the second is
373      * the salt to use. The salt should be two characters from the
374      * set [a-zA-Z0-9./]. Outputs the crypt result.
375      *
376      * @param arg command line arguments.
377      *
378      */
379 
main(String[] arg)380     public static void main(String[] arg) {
381 
382         if (arg.length!=2) {
383             System.err.println("usage: Crypt password salt");
384             System.exit(1);
385         }
386 
387         Crypt c = new Crypt();
388         try {
389             byte[] result = c.crypt
390                 (arg[0].getBytes("ISO-8859-1"), arg[1].getBytes("ISO-8859-1"));
391             for (int i=0; i<result.length; i++) {
392                 System.out.println(" "+i+" "+(char)result[i]);
393             }
394         } catch (java.io.UnsupportedEncodingException uee) {
395             // cannot happen
396         }
397     }
398 }
399