001/*
002 *  Licensed to the Apache Software Foundation (ASF) under one
003 *  or more contributor license agreements.  See the NOTICE file
004 *  distributed with this work for additional information
005 *  regarding copyright ownership.  The ASF licenses this file
006 *  to you under the Apache License, Version 2.0 (the
007 *  "License"); you may not use this file except in compliance
008 *  with the License.  You may obtain a copy of the License at
009 *  
010 *    http://www.apache.org/licenses/LICENSE-2.0
011 *  
012 *  Unless required by applicable law or agreed to in writing,
013 *  software distributed under the License is distributed on an
014 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 *  KIND, either express or implied.  See the License for the
016 *  specific language governing permissions and limitations
017 *  under the License. 
018 *  
019 */
020
021/*
022 * @(#)UnixCrypt.java    0.9 96/11/25
023 *
024 * Copyright (c) 1996 Aki Yoshida. All rights reserved.
025 *
026 * Permission to use, copy, modify and distribute this software
027 * for non-commercial or commercial purposes and without fee is
028 * hereby granted provided that this copyright notice appears in
029 * all copies.
030 */
031
032/**
033 * Unix crypt(3C) utility
034 *
035 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
036 *
037 * modified April 2001
038 * by Iris Van den Broeke, Daniel Deville
039 */
040
041package org.apache.directory.api.util;
042
043
044import org.apache.directory.api.i18n.I18n;
045
046
047/*
048 * @(#)UnixCrypt.java   0.9 96/11/25
049 *
050 * Copyright (c) 1996 Aki Yoshida. All rights reserved.
051 *
052 * Permission to use, copy, modify and distribute this software
053 * for non-commercial or commercial purposes and without fee is
054 * hereby granted provided that this copyright notice appears in
055 * all copies.
056*/
057
058/**
059 * Unix crypt(3C) utility
060 *
061   * @author  Aki Yoshida
062 * 2001
063 * by Iris Van den Broeke, Daniel Deville
064 */
065
066/* ------------------------------------------------------------ */
067/** Unix Crypt.
068 * Implements the one way cryptography used by Unix systems for
069 * simple password protection.
070   * @author Greg Wilkins (gregw)
071 */
072public class UnixCrypt extends Object
073{
074
075    /* (mostly) Standard DES Tables from Tom Truscott */
076    private static final byte[] IP =
077        { 
078            /* initial permutation */
079            58, 50, 42, 34, 26, 18, 10, 2,
080            60, 52, 44, 36, 28, 20, 12, 4,
081            62, 54, 46, 38, 30, 22, 14, 6,
082            64, 56, 48, 40, 32, 24, 16, 8,
083            57, 49, 41, 33, 25, 17, 9, 1,
084            59, 51, 43, 35, 27, 19, 11, 3,
085            61, 53, 45, 37, 29, 21, 13, 5,
086            63, 55, 47, 39, 31, 23, 15, 7 };
087
088    /* The final permutation is the inverse of IP - no table is necessary */
089    private static final byte[] ExpandTr =
090        { 
091            /* expansion operation */
092            32, 1, 2, 3, 4, 5,
093            4, 5, 6, 7, 8, 9,
094            8, 9, 10, 11, 12, 13,
095            12, 13, 14, 15, 16, 17,
096            16, 17, 18, 19, 20, 21,
097            20, 21, 22, 23, 24, 25,
098            24, 25, 26, 27, 28, 29,
099            28, 29, 30, 31, 32, 1 };
100
101    private static final byte[] PC1 =
102        { 
103            /* permuted choice table 1 */
104            57, 49, 41, 33, 25, 17, 9,
105            1, 58, 50, 42, 34, 26, 18,
106            10, 2, 59, 51, 43, 35, 27,
107            19, 11, 3, 60, 52, 44, 36,
108
109            63, 55, 47, 39, 31, 23, 15,
110            7, 62, 54, 46, 38, 30, 22,
111            14, 6, 61, 53, 45, 37, 29,
112            21, 13, 5, 28, 20, 12, 4 };
113
114    private static final byte[] Rotates =
115        { 
116            /* PC1 rotation schedule */
117            1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 };
118
119    private static final byte[] PC2 =
120        { 
121            /* permuted choice table 2 */
122            9, 18, 14, 17, 11, 24, 1, 5,
123            22, 25, 3, 28, 15, 6, 21, 10,
124            35, 38, 23, 19, 12, 4, 26, 8,
125            43, 54, 16, 7, 27, 20, 13, 2,
126
127            0, 0, 41, 52, 31, 37, 47, 55,
128            0, 0, 30, 40, 51, 45, 33, 48,
129            0, 0, 44, 49, 39, 56, 34, 53,
130            0, 0, 46, 42, 50, 36, 29, 32 };
131
132    private static final byte[][] S =
133        { 
134            /* 48->32 bit substitution tables */
135            /* S[1]         */
136            { 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
137                0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
138                4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
139                15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 },
140            /* S[2]         */
141            { 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
142                3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
143                0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
144                13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 },
145            /* S[3]         */
146            { 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
147                13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
148                13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
149                1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 },
150            /* S[4]         */
151            { 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
152                13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
153                10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
154                3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 },
155            /* S[5]         */
156            { 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
157                14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
158                4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
159                11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 },
160            /* S[6]         */
161            { 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
162                10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
163                9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
164                4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 },
165            /* S[7]         */
166            { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
167                13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
168                1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
169                6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 },
170            /* S[8]         */
171            { 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
172                1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
173                7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
174                2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 } };
175
176    private static final byte[] P32Tr =
177        { 
178            /* 32-bit permutation function */
179            16, 7, 20, 21,
180            29, 12, 28, 17,
181            1, 15, 23, 26,
182            5, 18, 31, 10,
183            2, 8, 24, 14,
184            32, 27, 3, 9,
185            19, 13, 30, 6,
186            22, 11, 4, 25 };
187
188    private static final byte[] CIFP =
189        { 
190            /* compressed/interleaved permutation */
191            1, 2, 3, 4, 17, 18, 19, 20,
192            5, 6, 7, 8, 21, 22, 23, 24,
193            9, 10, 11, 12, 25, 26, 27, 28,
194            13, 14, 15, 16, 29, 30, 31, 32,
195
196            33, 34, 35, 36, 49, 50, 51, 52,
197            37, 38, 39, 40, 53, 54, 55, 56,
198            41, 42, 43, 44, 57, 58, 59, 60,
199            45, 46, 47, 48, 61, 62, 63, 64 };
200
201    private static final byte[] ITOA64 =
202        { 
203            /* 0..63 => ascii-64 */
204            ( byte ) '.',
205            ( byte ) '/',
206            ( byte ) '0',
207            ( byte ) '1',
208            ( byte ) '2',
209            ( byte ) '3',
210            ( byte ) '4',
211            ( byte ) '5',
212            ( byte ) '6',
213            ( byte ) '7',
214            ( byte ) '8',
215            ( byte ) '9',
216            ( byte ) 'A',
217            ( byte ) 'B',
218            ( byte ) 'C',
219            ( byte ) 'D',
220            ( byte ) 'E',
221            ( byte ) 'F',
222            ( byte ) 'G',
223            ( byte ) 'H',
224            ( byte ) 'I',
225            ( byte ) 'J',
226            ( byte ) 'K',
227            ( byte ) 'L',
228            ( byte ) 'M',
229            ( byte ) 'N',
230            ( byte ) 'O',
231            ( byte ) 'P',
232            ( byte ) 'Q',
233            ( byte ) 'R',
234            ( byte ) 'S',
235            ( byte ) 'T',
236            ( byte ) 'U',
237            ( byte ) 'V',
238            ( byte ) 'W',
239            ( byte ) 'X',
240            ( byte ) 'Y',
241            ( byte ) 'Z',
242            ( byte ) 'a',
243            ( byte ) 'b',
244            ( byte ) 'c',
245            ( byte ) 'd',
246            ( byte ) 'e',
247            ( byte ) 'f',
248            ( byte ) 'g',
249            ( byte ) 'h',
250            ( byte ) 'i',
251            ( byte ) 'j',
252            ( byte ) 'k',
253            ( byte ) 'l',
254            ( byte ) 'm',
255            ( byte ) 'n',
256            ( byte ) 'o',
257            ( byte ) 'p',
258            ( byte ) 'q',
259            ( byte ) 'r',
260            ( byte ) 's',
261            ( byte ) 't',
262            ( byte ) 'u',
263            ( byte ) 'v',
264            ( byte ) 'w',
265            ( byte ) 'x',
266            ( byte ) 'y',
267            ( byte ) 'z' };
268
269    /* =====  Tables that are initialized at run time  ==================== */
270
271    private static byte[] A64TOI = new byte[128]; /* ascii-64 => 0..63 */
272
273    /* Initial key schedule permutation */
274    private static long[][] PC1ROT = new long[16][16];
275
276    /* Subsequent key schedule rotation permutations */
277    private static long[][][] PC2ROT = new long[2][16][16];
278
279    /* Initial permutation/expansion table */
280    private static long[][] IE3264 = new long[8][16];
281
282    /* Table that combines the S, P, and E operations.  */
283    private static long[][] SPE = new long[8][64];
284
285    /* compressed/interleaved => final permutation table */
286    private static long[][] CF6464 = new long[16][16];
287
288    /* ==================================== */
289
290    static
291    {
292        byte[] perm = new byte[64];
293        byte[] temp = new byte[64];
294
295        // inverse table.
296        for ( int i = 0; i < 64; i++ )
297        {
298            A64TOI[ITOA64[i]] = ( byte ) i;
299        }
300
301        // PC1ROT - bit reverse, then PC1, then Rotate, then PC2
302        for ( int i = 0; i < 64; i++ )
303        {
304            perm[i] = ( byte ) 0;
305        }
306        
307        for ( int i = 0; i < 64; i++ )
308        {
309            int k;
310            
311            if ( ( k = PC2[i] ) == 0 )
312            {
313                continue;
314            }
315            
316            k += Rotates[0] - 1;
317            
318            if ( ( k % 28 ) < Rotates[0] )
319            {
320                k -= 28;
321            }
322            
323            k = PC1[k];
324            
325            if ( k > 0 )
326            {
327                k--;
328                k = ( k | 0x07 ) - ( k & 0x07 );
329                k++;
330            }
331            
332            perm[i] = ( byte ) k;
333        }
334        
335        init_perm( PC1ROT, perm, 8 );
336
337        // PC2ROT - PC2 inverse, then Rotate, then PC2
338        for ( int j = 0; j < 2; j++ )
339        {
340            int k;
341            
342            for ( int i = 0; i < 64; i++ )
343            {
344                perm[i] = temp[i] = 0;
345            }
346            
347            for ( int i = 0; i < 64; i++ )
348            {
349                if ( ( k = PC2[i] ) == 0 )
350                {
351                    continue;
352                }
353                
354                temp[k - 1] = ( byte ) ( i + 1 );
355            }
356            
357            for ( int i = 0; i < 64; i++ )
358            {
359                if ( ( k = PC2[i] ) == 0 )
360                {
361                    continue;
362                }
363                
364                k += j;
365                
366                if ( ( k % 28 ) <= j )
367                {
368                    k -= 28;
369                }
370                
371                perm[i] = temp[k];
372            }
373
374            init_perm( PC2ROT[j], perm, 8 );
375        }
376
377        // Bit reverse, intial permupation, expantion
378        for ( int i = 0; i < 8; i++ )
379        {
380            for ( int j = 0; j < 8; j++ )
381            {
382                int k = ( j < 2 ) ? 0 : IP[ExpandTr[i * 6 + j - 2] - 1];
383                
384                if ( k > 32 )
385                {
386                    k -= 32;
387                }
388                else if ( k > 0 )
389                {
390                    k--;
391                }
392                
393                if ( k > 0 )
394                {
395                    k--;
396                    k = ( k | 0x07 ) - ( k & 0x07 );
397                    k++;
398                }
399                
400                perm[i * 8 + j] = ( byte ) k;
401            }
402        }
403
404        init_perm( IE3264, perm, 8 );
405
406        // Compression, final permutation, bit reverse
407        for ( int i = 0; i < 64; i++ )
408        {
409            int k = IP[CIFP[i] - 1];
410            
411            if ( k > 0 )
412            {
413                k--;
414                k = ( k | 0x07 ) - ( k & 0x07 );
415                k++;
416            }
417            
418            perm[k - 1] = ( byte ) ( i + 1 );
419        }
420
421        init_perm( CF6464, perm, 8 );
422
423        // SPE table
424        for ( int i = 0; i < 48; i++ )
425        {
426            perm[i] = P32Tr[ExpandTr[i] - 1];
427        }
428        
429        for ( int t = 0; t < 8; t++ )
430        {
431            for ( int j = 0; j < 64; j++ )
432            {
433                int k = ( ( ( j >> 0 ) & 0x01 ) << 5 ) | ( ( ( j >> 1 ) & 0x01 ) << 3 ) |
434                    ( ( ( j >> 2 ) & 0x01 ) << 2 ) | ( ( ( j >> 3 ) & 0x01 ) << 1 ) |
435                    ( ( ( j >> 4 ) & 0x01 ) << 0 ) | ( ( ( j >> 5 ) & 0x01 ) << 4 );
436                k = S[t][k];
437                k = ( ( ( k >> 3 ) & 0x01 ) << 0 ) | ( ( ( k >> 2 ) & 0x01 ) << 1 ) |
438                    ( ( ( k >> 1 ) & 0x01 ) << 2 ) | ( ( ( k >> 0 ) & 0x01 ) << 3 );
439                
440                for ( int i = 0; i < 32; i++ )
441                {
442                    temp[i] = 0;
443                }
444                
445                for ( int i = 0; i < 4; i++ )
446                {
447                    temp[4 * t + i] = ( byte ) ( ( k >> i ) & 0x01 );
448                }
449                
450                long kk = 0;
451                
452                for ( int i = 24; --i >= 0; )
453                {
454                    kk = ( ( kk << 1 ) |
455                        ( ( long ) temp[perm[i] - 1] ) << 32 |
456                        ( temp[perm[i + 24] - 1] ) );
457                }
458
459                SPE[t][j] = to_six_bit( kk );
460            }
461        }
462    }
463
464
465    /**
466     * You can't call the constructer.
467     */
468    private UnixCrypt()
469    {
470    }
471
472
473    /**
474     * Returns the transposed and split code of a 24-bit code
475     * into a 4-byte code, each having 6 bits.
476     */
477    private static int to_six_bit( int num )
478    {
479        return ( ( ( num << 26 ) & 0xfc000000 ) | ( ( num << 12 ) & 0xfc0000 ) |
480            ( ( num >> 2 ) & 0xfc00 ) | ( ( num >> 16 ) & 0xfc ) );
481    }
482
483
484    /**
485     * Returns the transposed and split code of two 24-bit code 
486     * into two 4-byte code, each having 6 bits.
487     */
488    private static long to_six_bit( long num )
489    {
490        return ( ( ( num << 26 ) & 0xfc000000fc000000L ) | ( ( num << 12 ) & 0xfc000000fc0000L ) |
491            ( ( num >> 2 ) & 0xfc000000fc00L ) | ( ( num >> 16 ) & 0xfc000000fcL ) );
492    }
493
494
495    /**
496     * Returns the permutation of the given 64-bit code with
497     * the specified permutataion table.
498     */
499    private static long perm6464( long c, long[][] p )
500    {
501        long out = 0L;
502        
503        for ( int i = 8; --i >= 0; )
504        {
505            int t = ( int ) ( 0x00ff & c );
506            c >>= 8;
507            long tp = p[i << 1][t & 0x0f];
508            out |= tp;
509            tp = p[( i << 1 ) + 1][t >> 4];
510            out |= tp;
511        }
512        
513        return out;
514    }
515
516
517    /**
518     * Returns the permutation of the given 32-bit code with
519     * the specified permutataion table.
520     */
521    private static long perm3264( int c, long[][] p )
522    {
523        long out = 0L;
524        
525        for ( int i = 4; --i >= 0; )
526        {
527            int t = ( 0x00ff & c );
528            c >>= 8;
529            long tp = p[i << 1][t & 0x0f];
530            out |= tp;
531            tp = p[( i << 1 ) + 1][t >> 4];
532            out |= tp;
533        }
534        
535        return out;
536    }
537
538
539    /**
540     * Returns the key schedule for the given key.
541     */
542    private static long[] des_setkey( long keyword )
543    {
544        long K = perm6464( keyword, PC1ROT );
545        long[] KS = new long[16];
546        KS[0] = K & ~0x0303030300000000L;
547
548        for ( int i = 1; i < 16; i++ )
549        {
550            KS[i] = K;
551            K = perm6464( K, PC2ROT[Rotates[i] - 1] );
552
553            KS[i] = K & ~0x0303030300000000L;
554        }
555        return KS;
556    }
557
558
559    /**
560     * Returns the DES encrypted code of the given word with the specified 
561     * environment.
562     */
563    private static long des_cipher( long in, int salt, int num_iter, long[] KS )
564    {
565        salt = to_six_bit( salt );
566        long L = in;
567        long R = L;
568        L &= 0x5555555555555555L;
569        R = ( R & 0xaaaaaaaa00000000L ) | ( ( R >> 1 ) & 0x0000000055555555L );
570        L = ( ( ( ( L << 1 ) | ( L << 32 ) ) & 0xffffffff00000000L ) |
571            ( ( R | ( R >> 32 ) ) & 0x00000000ffffffffL ) );
572
573        L = perm3264( ( int ) ( L >> 32 ), IE3264 );
574        R = perm3264( ( int ) ( L & 0xffffffff ), IE3264 );
575
576        while ( --num_iter >= 0 )
577        {
578            for ( int loop_count = 0; loop_count < 8; loop_count++ )
579            {
580                long kp;
581                long B;
582                long k;
583
584                kp = KS[( loop_count << 1 )];
585                k = ( ( R >> 32 ) ^ R ) & salt & 0xffffffffL;
586                k |= ( k << 32 );
587                B = ( k ^ R ^ kp );
588
589                L ^= ( SPE[0][( int ) ( ( B >> 58 ) & 0x3f )] ^ SPE[1][( int ) ( ( B >> 50 ) & 0x3f )] ^
590                    SPE[2][( int ) ( ( B >> 42 ) & 0x3f )] ^ SPE[3][( int ) ( ( B >> 34 ) & 0x3f )] ^
591                    SPE[4][( int ) ( ( B >> 26 ) & 0x3f )] ^ SPE[5][( int ) ( ( B >> 18 ) & 0x3f )] ^
592                    SPE[6][( int ) ( ( B >> 10 ) & 0x3f )] ^ SPE[7][( int ) ( ( B >> 2 ) & 0x3f )] );
593
594                kp = KS[( loop_count << 1 ) + 1];
595                k = ( ( L >> 32 ) ^ L ) & salt & 0xffffffffL;
596                k |= ( k << 32 );
597                B = ( k ^ L ^ kp );
598
599                R ^= ( SPE[0][( int ) ( ( B >> 58 ) & 0x3f )] ^ SPE[1][( int ) ( ( B >> 50 ) & 0x3f )] ^
600                    SPE[2][( int ) ( ( B >> 42 ) & 0x3f )] ^ SPE[3][( int ) ( ( B >> 34 ) & 0x3f )] ^
601                    SPE[4][( int ) ( ( B >> 26 ) & 0x3f )] ^ SPE[5][( int ) ( ( B >> 18 ) & 0x3f )] ^
602                    SPE[6][( int ) ( ( B >> 10 ) & 0x3f )] ^ SPE[7][( int ) ( ( B >> 2 ) & 0x3f )] );
603            }
604            // swap L and R
605            L ^= R;
606            R ^= L;
607            L ^= R;
608        }
609        L = ( ( ( ( L >> 35 ) & 0x0f0f0f0fL ) | ( ( ( L & 0xffffffff ) << 1 ) & 0xf0f0f0f0L ) ) << 32 |
610            ( ( ( R >> 35 ) & 0x0f0f0f0fL ) | ( ( ( R & 0xffffffff ) << 1 ) & 0xf0f0f0f0L ) ) );
611
612        L = perm6464( L, CF6464 );
613
614        return L;
615    }
616
617
618    /**
619     * Initializes the given permutation table with the mapping table.
620     */
621    private static void init_perm( long[][] perm, byte[] p, int chars_out )
622    {
623        for ( int k = 0; k < chars_out * 8; k++ )
624        {
625
626            int l = p[k] - 1;
627            
628            if ( l < 0 )
629            {
630                continue;
631            }
632            
633            int i = l >> 2;
634            l = 1 << ( l & 0x03 );
635            
636            for ( int j = 0; j < 16; j++ )
637            {
638                int s = ( ( k & 0x07 ) + ( ( 7 - ( k >> 3 ) ) << 3 ) );
639                
640                if ( ( j & l ) != 0x00 )
641                {
642                    perm[i][j] |= ( 1L << s );
643                }
644            }
645        }
646    }
647
648
649    /**
650     * Encrypts String into crypt (Unix) code.
651     * @param key the key to be encrypted
652     * @param setting the salt to be used
653     * @return the encrypted String
654     */
655    @SuppressWarnings("deprecation")
656    public static String crypt( String key, String setting )
657    {
658        /* encryption constant */
659        long constdatablock = 0L; 
660        /* encrypted result */
661        byte[] cryptresult = new byte[13]; 
662        long keyword = 0L;
663        
664        /* invalid parameters! */
665        if ( key == null || setting == null )
666        {
667         // will NOT match under ANY circumstances!
668            return "*"; 
669        } 
670
671        int keylen = key.length();
672
673        for ( int i = 0; i < 8; i++ )
674        {
675            keyword = ( keyword << 8 ) | ( ( i < keylen ) ? 2 * key.charAt( i ) : 0 );
676        }
677
678        long[] KS = des_setkey( keyword );
679
680        int salt = 0;
681        
682        for ( int i = 2; --i >= 0; )
683        {
684            char c = ( i < setting.length() ) ? setting.charAt( i ) : '.';
685            cryptresult[i] = ( byte ) c;
686            salt = ( salt << 6 ) | ( 0x00ff & A64TOI[c] );
687        }
688
689        long rsltblock = des_cipher( constdatablock, salt, 25, KS );
690
691        cryptresult[12] = ITOA64[( ( ( int ) rsltblock ) << 2 ) & 0x3f];
692        rsltblock >>= 4;
693        
694        for ( int i = 12; --i >= 2; )
695        {
696            cryptresult[i] = ITOA64[( ( int ) rsltblock ) & 0x3f];
697            rsltblock >>= 6;
698        }
699
700        return new String( cryptresult, 0x00, 0, 13 );
701    }
702
703
704    public static void main( String[] arg )
705    {
706        if ( arg.length != 2 )
707        {
708            System.err.println( I18n.err( I18n.ERR_04439 ) );
709            System.exit( 1 );
710        }
711
712        System.err.println( I18n.err( I18n.ERR_04440, crypt( arg[0], arg[1] ) ) );
713    }
714}