Annotation of 43BSDReno/kerberosIV/des/des.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * $Source: /mit/kerberos/src/lib/des/RCS/des.c,v $
                      3:  * $Author: jtkohl $
                      4:  *
                      5:  * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
                      6:  * of Technology.
                      7:  *
                      8:  * For copying and distribution information, please see the file
                      9:  * <mit-copyright.h>.
                     10:  *
                     11:  * These routines perform encryption and decryption using the DES
                     12:  * private key algorithm, or else a subset of it-- fewer inner loops.
                     13:  * (AUTH_DES_ITER defaults to 16, may be less.)
                     14:  *
                     15:  * Under U.S. law, this software may not be exported outside the US
                     16:  * without license from the U.S. Commerce department.
                     17:  *
                     18:  * The key schedule is passed as an arg, as well as the cleartext or
                     19:  * ciphertext.
                     20:  *
                     21:  * All registers labeled imply Vax using the Ultrix or 4.2bsd
                     22:  * compiler.
                     23:  *
                     24:  *
                     25:  *     NOTE:  bit and byte numbering:
                     26:  *                     DES algorithm is defined in terms of bits of L
                     27:  *                     followed by bits of R.
                     28:  *             bit 0  ==> lsb of L
                     29:  *             bit 63 ==> msb of R
                     30:  *
                     31:  * Always work in register pairs, FROM L1,R1 TO L2,R2 to make
                     32:  * bookkeeping easier.
                     33:  *
                     34:  * originally written by Steve Miller, MIT Project Athena
                     35:  */
                     36: 
                     37: #ifndef        lint
                     38: static char rcsid_des_c[] =
                     39: "$Header: des.c,v 4.13 89/01/21 16:49:55 jtkohl Exp $";
                     40: #endif lint
                     41: 
                     42: #include <mit-copyright.h>
                     43: 
                     44: #include <stdio.h>
                     45: #include <des.h>
                     46: #include "des_internal.h"
                     47: #include "s_table.h"
                     48: #ifdef BIG
                     49: #include "p_table.h"
                     50: #endif
                     51: 
                     52: #ifdef DEBUG
                     53: #define DBG_PRINT(s) if (des_debug & 2) \
                     54:     des_debug_print(s,i,L1&0xffff,(L1>>16)&0xffff, \
                     55:                R1&0xffff,(R1>>16)&0xffff)
                     56: #else
                     57: #define DBG_PRINT(s)
                     58: #endif
                     59: 
                     60: extern int des_debug;
                     61: extern des_cblock_print_file ();
                     62: extern des_debug_print ();
                     63: 
                     64: int
                     65: des_ecb_encrypt(clear, cipher, schedule, encrypt)
                     66:     unsigned long *clear;
                     67:     unsigned long *cipher;
                     68:     int encrypt;               /* 0 ==> decrypt, else encrypt */
                     69:     register des_key_schedule schedule; /* r11 */
                     70: {
                     71: 
                     72:     /* better pass 8 bytes, length not checked here */
                     73: 
                     74:     register unsigned long R1, L1; /* R1 = r10, L1 = r9 */
                     75:     register unsigned long R2, L2; /* R2 = r8, L2 = r7 */
                     76:     long i;
                     77:     /* one more registers left on VAX, see below P_temp_p */
                     78: #ifdef BITS16
                     79:     sbox_in_16_a S_in_16_a;
                     80:     sbox_in_16_b S_in_16_b;
                     81:     sbox_in_16_c S_in_16_c;
                     82:     unsigned int *S_in_a_16_p = (unsigned int *) &S_in_16_a;
                     83:     unsigned int *S_in_b_16_p = (unsigned int *) &S_in_16_b;
                     84:     unsigned int *S_in_c_16_p = (unsigned int *) &S_in_16_c;
                     85: #endif
                     86: #ifndef BITS32
                     87: #ifndef BITS16
                     88:     dunno how to do this machine type, you lose;
                     89: #endif
                     90: #endif
                     91:     unsigned long P_temp;
                     92:     register unsigned char *P_temp_p = (unsigned char *) & P_temp;
                     93: #ifdef BITS16
                     94:     sbox_out S_out;
                     95:     unsigned long *S_out_p = (unsigned long *) &S_out;
                     96: #endif
                     97:     unsigned long R_save, L_save;
                     98: #ifdef DEBUG
                     99:     unsigned long dbg_tmp[2];
                    100: #endif
                    101: 
                    102:     /*
                    103:      * Use L1,R1 and L2,R2 as two sets of "64-bit" registers always
                    104:      * work from L1,R1 input to L2,R2 output; initialize the cleartext
                    105:      * into registers.
                    106:      */
                    107: #ifdef MUSTALIGN
                    108: #ifdef DEBUG
                    109:     /*
                    110:      * If the alignment is wrong, the programmer really screwed up --
                    111:      * we aren't even getting the right data type.  His problem.  Keep
                    112:      * this code for debugging.
                    113:      */
                    114:     /* Make sure schedule is ok */
                    115:     if ((long) schedule & 3) {
                    116:        fprintf(stderr,"des.c schedule arg pointer not aligned\n");
                    117:        abort();
                    118:     }
                    119: #endif
                    120:     if ((long) clear & 3) {
                    121:        bcopy((char *)clear++,(char *)&L_save,sizeof(L_save));
                    122:        bcopy((char *)clear,(char *)&R_save,sizeof(R_save));
                    123:        L1 = L_save;
                    124:        R1 = R_save;
                    125:     }
                    126:     else
                    127: #endif
                    128:     {
                    129:        if (clear) L1 = *clear++;
                    130:        else L1 = NULL;
                    131:        if (clear) R1 = *clear;
                    132:        else R1 = NULL;
                    133:     }
                    134: 
                    135: #ifdef DEBUG
                    136:     if (des_debug & 2) {
                    137:        printf("All values printed from low byte (bit 0)");
                    138:        printf(" --> high byte (bit 63)\n");
                    139:        i = 0;
                    140:        dbg_tmp[0] = L1;
                    141:        dbg_tmp[1] = R1;
                    142:        printf("iter = %2d  before IP\n\t\tL1 R1 = ",i);
                    143:        des_cblock_print_file (dbg_tmp, stdout);
                    144:     }
                    145: 
                    146:     DBG_PRINT("before IP");
                    147: #endif
                    148: 
                    149: /*   IP_start:*/
                    150: 
                    151:     /* all the Initial Permutation code is in the include file */
                    152: #include "ip.c"
                    153:     /* reset input to L1,R1 */
                    154:     L1 = L2;
                    155:     R1 = R2;
                    156: 
                    157:     /* iterate through the inner loop */
                    158:     for (i = 0; i <= (AUTH_DES_ITER-1); i++) {
                    159: 
                    160: #ifdef DEBUG
                    161:        if (des_debug & 2) {
                    162:            dbg_tmp[0] = L1;
                    163:            dbg_tmp[1] = R1;
                    164:            printf("iter = %2d  start loop\n\t\tL1 R1 = ",i);
                    165:            des_cblock_print_file (dbg_tmp, stdout);
                    166:            DBG_PRINT("start loop");
                    167:        }
                    168: 
                    169: #endif
                    170: 
                    171:        R_save = R1;
                    172:        L_save = L1;
                    173: 
                    174: /*   E_start:*/
                    175:        /* apply the E permutation from R1 to L2, R2 */
                    176: #ifndef VAXASM
                    177: #ifdef SLOW_E
                    178: #include "e.c"
                    179: #else /* Bill's fast E */
                    180:        L2 = (R1 << 1);
                    181:        if (R1 & (1<<31))
                    182:            L2 |= 1<<0;
                    183:        L2 &= 077;
                    184:        L2 |= (R1 <<3) & 07700;
                    185:        L2 |= (R1 <<5) & 0770000;
                    186:        L2 |= (R1 <<7) & 077000000;
                    187:        L2 |= (R1 <<9) & 07700000000;
                    188:        L2 |= (R1 <<11) & 030000000000;
                    189: 
                    190:        /* now from right to right */
                    191: 
                    192:        R2 = ((R1 >> 17) & 0176000);
                    193:        if (R1 & (1<<0)) R2 |= 1<<15;
                    194: 
                    195:        R2 |= ((R1 >> 21) & 017);
                    196:        R2 |= ((R1 >> 19) & 01760);
                    197: #endif /* SLOW_E */
                    198: #else /* VAXASM */
                    199:        /* E operations */
                    200:        /* right to left */
                    201:        asm("   rotl    $1,r10,r7");
                    202:        L2 &= 077;
                    203:        L2 |= (R1 <<3) & 07700;
                    204:        L2 |= (R1 <<5) & 0770000;
                    205:        L2 |= (R1 <<7) & 077000000;
                    206:        L2 |= (R1 <<9) & 07700000000;
                    207:        L2 |= (R1 <<11) & 030000000000;
                    208: 
                    209:        asm("   rotl    $-17,r10,r8");
                    210:        R2 &= 0176000;
                    211:        asm("   rotl    $-21,r10,r0");
                    212:        asm("   bicl2   $-16,r0");
                    213:        asm("  bisl2    r0,r8");
                    214:        asm("   rotl    $-19,r10,r0");
                    215:        asm("   bicl2   $-1009,r0");
                    216:        asm("  bisl2    r0,r8");
                    217: 
                    218: #endif
                    219: 
                    220:        /* reset input to L1,R1 */
                    221:        L1 = L2;
                    222:        R1 = R2;
                    223: 
                    224: #ifdef DEBUG
                    225:        if (des_debug & 2) {
                    226:            dbg_tmp[0] = L1;
                    227:            dbg_tmp[1] = R1;
                    228:            DBG_PRINT("after e");
                    229:            printf("iter = %2d  after e\n\t\tL1 R1 = ",i);
                    230:            des_cblock_print_file (dbg_tmp, stdout);
                    231:        }
                    232: #endif
                    233: 
                    234: /*   XOR_start:*/
                    235:        /*
                    236:         * XOR with the key schedule, "schedule"
                    237:         *
                    238:         * If this is an encryption operation, use schedule[i],
                    239:         * otherwise use schedule [AUTH_DES_ITER-i-1]
                    240:         *
                    241:         * First XOR left half.
                    242:         */
                    243:        if (encrypt) {
                    244:            L1 ^= *(((unsigned long *) &schedule[i] )+0);
                    245:            /* now right half */
                    246:            R1 ^= *(((unsigned long *) &schedule[i] )+1);
                    247:        }
                    248:        else {
                    249:            L1 ^= *(((unsigned long *) &schedule[AUTH_DES_ITER-i-1] )+0);
                    250:            /* now right half */
                    251:            R1 ^= *(((unsigned long *) &schedule[AUTH_DES_ITER-i-1] )+1);
                    252:        }
                    253: 
                    254:        /* dont have to reset input to L1, R1 */
                    255: 
                    256: #ifdef DEBUG
                    257:        if (des_debug & 2) {
                    258:            dbg_tmp[0] = L1;
                    259:            dbg_tmp[1] = R1;
                    260:            DBG_PRINT("after xor");
                    261:            printf("iter = %2d  after xor\n\t\tL1 R1 =",i);
                    262:            des_cblock_print_file (dbg_tmp, stdout);
                    263:        }
                    264: #endif
                    265: 
                    266: /*   S_start:*/
                    267:        /* apply the S selection from L1, R1 to R2 */
                    268: 
                    269: #ifdef notdef
                    270: #include "s.c"
                    271: #endif
                    272: 
                    273:        /* S operations , cant use registers for bit field stuff */
                    274:        /* from S_in to S_out */
                    275: 
                    276: #ifdef BITS16
                    277:        *S_in_a_16_p = L1&0xffff;
                    278:        *S_in_b_16_p = (L1>>16)&0xffff;
                    279:        *S_in_c_16_p = R1&0xffff;
                    280:        (*(unsigned long *) &S_out) =
                    281:            (unsigned) S_adj[0][S_in_16_a.b0];
                    282:        S_out.b1 = (unsigned) S_adj[1][S_in_16_a.b1];
                    283:        /* b2 spans two words */
                    284:        S_out.b2 = (unsigned)
                    285:            S_adj[2][(unsigned) S_in_16_a.b2
                    286:                     + (((unsigned) S_in_16_b.b2) << 4)];
                    287:        S_out.b3 = (unsigned) S_adj[3][S_in_16_b.b3];
                    288:        S_out.b4 = (unsigned) S_adj[4][S_in_16_b.b4];
                    289:        /* b5 spans both parts */
                    290:        S_out.b5 = (unsigned)
                    291:            S_adj[5][(unsigned) S_in_16_b.b5
                    292:                     + (((unsigned) S_in_16_c.b5) << 2)];
                    293:        S_out.b6 = (unsigned) S_adj[6][S_in_16_c.b6];
                    294:        S_out.b7 = (unsigned) S_adj[7][S_in_16_c.b7];
                    295:        R1 = *S_out_p;
                    296: #else
                    297:        /* is a 32 bit sys */
                    298: #ifndef VAXASM
                    299:        R2 =  (unsigned) S_adj[0][L1 & 077];
                    300:        L2 = (unsigned) S_adj[1][(L1 >> 6) & 077];
                    301:        R2 |= (L2 <<4 );
                    302:        L2 = (unsigned) S_adj[2][(L1 >> 12) & 077];
                    303:        R2 |= (L2 <<8);
                    304:        L2 = (unsigned) S_adj[3][(L1 >> 18) & 077];
                    305:        R2 |= (L2 <<12);
                    306:        L2 = (unsigned) S_adj[4][(L1 >> 24) & 077];
                    307:        R2 |= (L2 <<16);
                    308:        /* b5 spans both parts */
                    309:        L2 = (unsigned)
                    310:            S_adj[5][(unsigned) ((L1 >>30) & 03) + ((R1 & 017) << 2)];
                    311:        R2 |= (L2 << 20);
                    312:        L2 = (unsigned) S_adj[6][(R1 >> 4) & 077];
                    313:        R2 |= (L2 <<24);
                    314:        L2 = (unsigned) S_adj[7][(R1 >> 10) & 077];
                    315:        R1 = R2 | (L2 <<28);
                    316:        /* reset input to L1, R1 */
                    317: #else /* vaxasm */
                    318:        /*
                    319:         * this is the c code produced above, with
                    320:         * extzv replaced by rotl
                    321:         */
                    322:        asm("bicl3      $-64,r9,r0");
                    323:        asm("movzbl     _S_adj[r0],r8");
                    324:        asm("rotl       $-6,r9,r0");
                    325:        asm("bicl2      $-64,r0");
                    326:        asm("movzbl     _S_adj+64[r0],r7");
                    327:        asm("ashl       $4,r7,r0");
                    328:        asm("bisl2      r0,r8");
                    329:        asm("rotl       $-12,r9,r0");
                    330:        asm("bicl2      $-64,r0");
                    331:        asm("movzbl     _S_adj+128[r0],r7");
                    332:        asm("ashl       $8,r7,r0");
                    333:        asm("bisl2      r0,r8");
                    334:        asm("rotl       $-18,r9,r0");
                    335:        asm("bicl2      $-64,r0");
                    336:        asm("movzbl     _S_adj+192[r0],r7");
                    337:        asm("ashl       $12,r7,r0");
                    338:        asm("bisl2      r0,r8");
                    339:        asm("rotl       $-24,r9,r0");
                    340:        asm("bicl2      $-64,r0");
                    341:        asm("movzbl     _S_adj+256[r0],r7");
                    342:        asm("ashl       $16,r7,r0");
                    343:        asm("bisl2      r0,r8");
                    344:        asm("rotl       $-30,r9,r0");
                    345:        asm("bicl2      $-4,r0");
                    346:        asm("bicl3      $-16,r10,r1");
                    347:        asm("ashl       $2,r1,r1");
                    348:        asm("addl2      r1,r0");
                    349:        asm("movzbl     _S_adj+320[r0],r7");
                    350:        asm("ashl       $20,r7,r0");
                    351:        asm("bisl2      r0,r8");
                    352:        asm("rotl       $-4,r10,r0");
                    353:        asm("bicl2      $-64,r0");
                    354:        asm("movzbl     _S_adj+384[r0],r7");
                    355:        asm("ashl       $24,r7,r0");
                    356:        asm("bisl2      r0,r8");
                    357:        asm("rotl       $-10,r10,r0");
                    358:        asm("bicl2      $-64,r0");
                    359:        asm("movzbl     _S_adj+448[r0],r7");
                    360:        asm("ashl       $28,r7,r0");
                    361:        asm("bisl2      r8,r0");
                    362:        asm("movl       r0,r10");
                    363: 
                    364: #endif /* vaxasm */
                    365: #endif
                    366: 
                    367: #ifdef DEBUG
                    368:        if (des_debug & 2) {
                    369:            dbg_tmp[0] = L1;
                    370:            dbg_tmp[1] = R1;
                    371:            DBG_PRINT("after s");
                    372:            printf("iter = %2d  after s\n\t\tL1 R1 = ",i);
                    373:            des_cblock_print_file (dbg_tmp, stdout);
                    374:        }
                    375: #endif
                    376: 
                    377: /*   P_start:*/
                    378:        /* and then the p permutation from R1 into R2 */
                    379: #include "p.c"
                    380:        /* reset the input to L1, R1 */
                    381:        R1 = R2;
                    382: 
                    383: #ifdef DEBUG
                    384:        if (des_debug & 2) {
                    385:            dbg_tmp[0] = L1;
                    386:            dbg_tmp[1] = R1;
                    387:            DBG_PRINT("after p");
                    388:            printf("iter = %2d  after p\n\t\tL1 R1 = ",i);
                    389:            des_cblock_print_file (dbg_tmp, stdout);
                    390:        }
                    391: #endif
                    392: 
                    393:        /* R1 is the output value from the f() */
                    394:        /* move R[iter] to L[iter+1] */
                    395: /*   XOR_2_start:*/
                    396:        L1 = R_save;
                    397:        /* xor with left */
                    398:        R1 = L_save ^ R1;
                    399:        /* reset the input */
                    400:     }
                    401: 
                    402:     /* flip left and right before final permutation */
                    403:     L2 = R1;                   /* flip */
                    404:     R2 = L1;
                    405:     /* reset the input */
                    406:     L1 = L2;
                    407:     R1 = R2;
                    408: 
                    409: #ifdef DEBUG
                    410:     if (des_debug & 2) {
                    411:        dbg_tmp[0] = L1;
                    412:        dbg_tmp[1] = R1;
                    413:        DBG_PRINT("before FP");
                    414:        printf("iter = %2d  before FP\n\t\tL1 R1 = ",i);
                    415:        des_cblock_print_file (dbg_tmp, stdout);
                    416:     }
                    417: 
                    418: #endif
                    419: 
                    420: /*FP_start:*/
                    421:     /* do the final permutation from L1R1 to L2R2 */
                    422:     /* all the fp code is in the include file */
                    423: #include "fp.c"
                    424: 
                    425:     /* copy the output to the ciphertext string;
                    426:      * can be same as cleartext
                    427:      */
                    428: 
                    429: #ifdef MUSTALIGN
                    430:     if ((long) cipher & 3) {
                    431:        L_save = L2;    /* cant bcopy a reg */
                    432:        R_save = R2;
                    433:        bcopy((char *)&L_save,(char *)cipher++,sizeof(L_save));
                    434:        bcopy((char *)&R_save,(char *)cipher,sizeof(R_save));
                    435:     }
                    436:     else
                    437: #endif
                    438:     {
                    439:        *cipher++ = L2;
                    440:        *cipher = R2;
                    441:     }
                    442: 
                    443: #ifdef DEBUG
                    444:     if (des_debug & 2) {
                    445:        L1 = L2;
                    446:        R1 = R2;
                    447:        dbg_tmp[0] = L1;
                    448:        dbg_tmp[1] = R1;
                    449:        DBG_PRINT("done");
                    450:        printf("iter = %2d  done\n\t\tL1 R1 = ",i);
                    451:        des_cblock_print_file (dbg_tmp, stdout);
                    452:     }
                    453: #endif
                    454: 
                    455:     /* that's it, no errors can be returned */
                    456:     return 0;
                    457: }
                    458: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.