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