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