Annotation of 43BSDReno/domestic/src/des/des.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1989 The Regents of the University of California.
        !             3:  * All rights reserved.
        !             4:  *
        !             5:  * This code is derived from software contributed to Berkeley by
        !             6:  * Phil Karn, derived from original work by Jim Gillogly and
        !             7:  * Richard Outerbridge.
        !             8:  *
        !             9:  * Redistribution and use in source and binary forms are permitted
        !            10:  * provided that: (1) source distributions retain this entire copyright
        !            11:  * notice and comment, and (2) distributions including binaries display
        !            12:  * the following acknowledgement:  ``This product includes software
        !            13:  * developed by the University of California, Berkeley and its contributors''
        !            14:  * in the documentation or other materials provided with the distribution
        !            15:  * and in all advertising materials mentioning features or use of this
        !            16:  * software. Neither the name of the University nor the names of its
        !            17:  * contributors may be used to endorse or promote products derived
        !            18:  * from this software without specific prior written permission.
        !            19:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
        !            20:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
        !            21:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
        !            22:  */
        !            23: 
        !            24: #ifndef lint
        !            25: static char sccsid[] = "@(#)des.c      5.3 (Berkeley) 6/1/90";
        !            26: #endif /* not lint */
        !            27: 
        !            28: /* Sofware DES functions
        !            29:  * written 12 Dec 1986 by Phil Karn, KA9Q; large sections adapted from
        !            30:  * the 1977 public-domain program by Jim Gillogly
        !            31:  */
        !            32: 
        !            33: #include <machine/endian.h>
        !            34: #include <stdio.h>
        !            35: 
        !            36: #if BYTE_ORDER == LITTLE_ENDIAN
        !            37: static long byteswap();
        !            38: #endif
        !            39: static void permute(),perminit(),spinit();
        !            40: static long f();
        !            41: 
        !            42: /* Tables defined in the Data Encryption Standard documents */
        !            43: 
        !            44: /* initial permutation IP */
        !            45: static char ip[] = {
        !            46:        58, 50, 42, 34, 26, 18, 10,  2,
        !            47:        60, 52, 44, 36, 28, 20, 12,  4,
        !            48:        62, 54, 46, 38, 30, 22, 14,  6,
        !            49:        64, 56, 48, 40, 32, 24, 16,  8,
        !            50:        57, 49, 41, 33, 25, 17,  9,  1,
        !            51:        59, 51, 43, 35, 27, 19, 11,  3,
        !            52:        61, 53, 45, 37, 29, 21, 13,  5,
        !            53:        63, 55, 47, 39, 31, 23, 15,  7
        !            54: };
        !            55: 
        !            56: /* final permutation IP^-1 */
        !            57: static char fp[] = {
        !            58:        40,  8, 48, 16, 56, 24, 64, 32,
        !            59:        39,  7, 47, 15, 55, 23, 63, 31,
        !            60:        38,  6, 46, 14, 54, 22, 62, 30,
        !            61:        37,  5, 45, 13, 53, 21, 61, 29,
        !            62:        36,  4, 44, 12, 52, 20, 60, 28,
        !            63:        35,  3, 43, 11, 51, 19, 59, 27,
        !            64:        34,  2, 42, 10, 50, 18, 58, 26,
        !            65:        33,  1, 41,  9, 49, 17, 57, 25
        !            66: };
        !            67: 
        !            68: /* expansion operation matrix
        !            69:  * This is for reference only; it is unused in the code
        !            70:  * as the f() function performs it implicitly for speed
        !            71:  */
        !            72: #ifdef notdef
        !            73: static char ei[] = {
        !            74:        32,  1,  2,  3,  4,  5,
        !            75:         4,  5,  6,  7,  8,  9,
        !            76:         8,  9, 10, 11, 12, 13,
        !            77:        12, 13, 14, 15, 16, 17,
        !            78:        16, 17, 18, 19, 20, 21,
        !            79:        20, 21, 22, 23, 24, 25,
        !            80:        24, 25, 26, 27, 28, 29,
        !            81:        28, 29, 30, 31, 32,  1 
        !            82: };
        !            83: #endif
        !            84: 
        !            85: /* permuted choice table (key) */
        !            86: static char pc1[] = {
        !            87:        57, 49, 41, 33, 25, 17,  9,
        !            88:         1, 58, 50, 42, 34, 26, 18,
        !            89:        10,  2, 59, 51, 43, 35, 27,
        !            90:        19, 11,  3, 60, 52, 44, 36,
        !            91: 
        !            92:        63, 55, 47, 39, 31, 23, 15,
        !            93:         7, 62, 54, 46, 38, 30, 22,
        !            94:        14,  6, 61, 53, 45, 37, 29,
        !            95:        21, 13,  5, 28, 20, 12,  4
        !            96: };
        !            97: 
        !            98: /* number left rotations of pc1 */
        !            99: static char totrot[] = {
        !           100:        1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28
        !           101: };
        !           102: 
        !           103: /* permuted choice key (table) */
        !           104: static char pc2[] = {
        !           105:        14, 17, 11, 24,  1,  5,
        !           106:         3, 28, 15,  6, 21, 10,
        !           107:        23, 19, 12,  4, 26,  8,
        !           108:        16,  7, 27, 20, 13,  2,
        !           109:        41, 52, 31, 37, 47, 55,
        !           110:        30, 40, 51, 45, 33, 48,
        !           111:        44, 49, 39, 56, 34, 53,
        !           112:        46, 42, 50, 36, 29, 32
        !           113: };
        !           114: 
        !           115: /* The (in)famous S-boxes */
        !           116: static char si[8][64] = {
        !           117:        /* S1 */
        !           118:        14,  4, 13,  1,  2, 15, 11,  8,  3, 10,  6, 12,  5,  9,  0,  7,
        !           119:         0, 15,  7,  4, 14,  2, 13,  1, 10,  6, 12, 11,  9,  5,  3,  8,
        !           120:         4,  1, 14,  8, 13,  6,  2, 11, 15, 12,  9,  7,  3, 10,  5,  0,
        !           121:        15, 12,  8,  2,  4,  9,  1,  7,  5, 11,  3, 14, 10,  0,  6, 13,
        !           122: 
        !           123:        /* S2 */
        !           124:        15,  1,  8, 14,  6, 11,  3,  4,  9,  7,  2, 13, 12,  0,  5, 10,
        !           125:         3, 13,  4,  7, 15,  2,  8, 14, 12,  0,  1, 10,  6,  9, 11,  5,
        !           126:         0, 14,  7, 11, 10,  4, 13,  1,  5,  8, 12,  6,  9,  3,  2, 15,
        !           127:        13,  8, 10,  1,  3, 15,  4,  2, 11,  6,  7, 12,  0,  5, 14,  9,
        !           128: 
        !           129:        /* S3 */
        !           130:        10,  0,  9, 14,  6,  3, 15,  5,  1, 13, 12,  7, 11,  4,  2,  8,
        !           131:        13,  7,  0,  9,  3,  4,  6, 10,  2,  8,  5, 14, 12, 11, 15,  1,
        !           132:        13,  6,  4,  9,  8, 15,  3,  0, 11,  1,  2, 12,  5, 10, 14,  7,
        !           133:         1, 10, 13,  0,  6,  9,  8,  7,  4, 15, 14,  3, 11,  5,  2, 12,
        !           134: 
        !           135:        /* S4 */
        !           136:         7, 13, 14,  3,  0,  6,  9, 10,  1,  2,  8,  5, 11, 12,  4, 15,
        !           137:        13,  8, 11,  5,  6, 15,  0,  3,  4,  7,  2, 12,  1, 10, 14,  9,
        !           138:        10,  6,  9,  0, 12, 11,  7, 13, 15,  1,  3, 14,  5,  2,  8,  4,
        !           139:         3, 15,  0,  6, 10,  1, 13,  8,  9,  4,  5, 11, 12,  7,  2, 14,
        !           140: 
        !           141:        /* S5 */
        !           142:         2, 12,  4,  1,  7, 10, 11,  6,  8,  5,  3, 15, 13,  0, 14,  9,
        !           143:        14, 11,  2, 12,  4,  7, 13,  1,  5,  0, 15, 10,  3,  9,  8,  6,
        !           144:         4,  2,  1, 11, 10, 13,  7,  8, 15,  9, 12,  5,  6,  3,  0, 14,
        !           145:        11,  8, 12,  7,  1, 14,  2, 13,  6, 15,  0,  9, 10,  4,  5,  3,
        !           146: 
        !           147:        /* S6 */
        !           148:        12,  1, 10, 15,  9,  2,  6,  8,  0, 13,  3,  4, 14,  7,  5, 11,
        !           149:        10, 15,  4,  2,  7, 12,  9,  5,  6,  1, 13, 14,  0, 11,  3,  8,
        !           150:         9, 14, 15,  5,  2,  8, 12,  3,  7,  0,  4, 10,  1, 13, 11,  6,
        !           151:         4,  3,  2, 12,  9,  5, 15, 10, 11, 14,  1,  7,  6,  0,  8, 13,
        !           152: 
        !           153:        /* S7 */
        !           154:         4, 11,  2, 14, 15,  0,  8, 13,  3, 12,  9,  7,  5, 10,  6,  1,
        !           155:        13,  0, 11,  7,  4,  9,  1, 10, 14,  3,  5, 12,  2, 15,  8,  6,
        !           156:         1,  4, 11, 13, 12,  3,  7, 14, 10, 15,  6,  8,  0,  5,  9,  2,
        !           157:         6, 11, 13,  8,  1,  4, 10,  7,  9,  5,  0, 15, 14,  2,  3, 12,
        !           158: 
        !           159:        /* S8 */
        !           160:        13,  2,  8,  4,  6, 15, 11,  1, 10,  9,  3, 14,  5,  0, 12,  7,
        !           161:         1, 15, 13,  8, 10,  3,  7,  4, 12,  5,  6, 11,  0, 14,  9,  2,
        !           162:         7, 11,  4,  1,  9, 12, 14,  2,  0,  6, 10, 13, 15,  3,  5,  8,
        !           163:         2,  1, 14,  7,  4, 10,  8, 13, 15, 12,  9,  0,  3,  5,  6, 11
        !           164: };
        !           165: 
        !           166: /* 32-bit permutation function P used on the output of the S-boxes */
        !           167: static char p32i[] = { 
        !           168:        16,  7, 20, 21,
        !           169:        29, 12, 28, 17,
        !           170:         1, 15, 23, 26,
        !           171:         5, 18, 31, 10,
        !           172:         2,  8, 24, 14,
        !           173:        32, 27,  3,  9,
        !           174:        19, 13, 30,  6,
        !           175:        22, 11,  4, 25
        !           176: };
        !           177: /* End of DES-defined tables */
        !           178: 
        !           179: /* Lookup tables initialized once only at startup by desinit() */
        !           180: static long (*sp)[64];         /* Combined S and P boxes */
        !           181: 
        !           182: static char (*iperm)[16][8];   /* Initial and final permutations */
        !           183: static char (*fperm)[16][8];
        !           184: 
        !           185: /* 8 6-bit subkeys for each of 16 rounds, initialized by setkey() */
        !           186: static char (*kn)[8];
        !           187: 
        !           188: /* bit 0 is left-most in byte */
        !           189: static int bytebit[] = {
        !           190:        0200,0100,040,020,010,04,02,01
        !           191: };
        !           192: 
        !           193: static int nibblebit[] = {
        !           194:         010,04,02,01
        !           195: };
        !           196: static int desmode;
        !           197: 
        !           198: /* Allocate space and initialize DES lookup arrays
        !           199:  * mode == 0: standard Data Encryption Algorithm
        !           200:  * mode == 1: DEA without initial and final permutations for speed
        !           201:  * mode == 2: DEA without permutations and with 128-byte key (completely
        !           202:  *            independent subkeys for each round)
        !           203:  */
        !           204: int
        !           205: desinit(mode)
        !           206: int mode;
        !           207: {
        !           208:        char *malloc();
        !           209: 
        !           210:        if(sp != NULL){
        !           211:                /* Already initialized */
        !           212:                return 0;
        !           213:        }
        !           214:        desmode = mode;
        !           215:        
        !           216:        if((sp = (long (*)[64])malloc(sizeof(long) * 8 * 64)) == NULL){
        !           217:                return -1;
        !           218:        }
        !           219:        spinit();
        !           220:        kn = (char (*)[8])malloc(sizeof(char) * 8 * 16);
        !           221:        if(kn == NULL){
        !           222:                free((char *)sp);
        !           223:                return -1;
        !           224:        }
        !           225:        if(mode == 1 || mode == 2)      /* No permutations */
        !           226:                return 0;
        !           227: 
        !           228:        iperm = (char (*)[16][8])malloc(sizeof(char) * 16 * 16 * 8);
        !           229:        if(iperm == NULL){
        !           230:                free((char *)sp);
        !           231:                free((char *)kn);
        !           232:                return -1;
        !           233:        }
        !           234:        perminit(iperm,ip);
        !           235: 
        !           236:        fperm = (char (*)[16][8])malloc(sizeof(char) * 16 * 16 * 8);
        !           237:        if(fperm == NULL){
        !           238:                free((char *)sp);
        !           239:                free((char *)kn);
        !           240:                free((char *)iperm);
        !           241:                return -1;
        !           242:        }
        !           243:        perminit(fperm,fp);
        !           244:        
        !           245:        return 0;
        !           246: }
        !           247: /* Free up storage used by DES */
        !           248: void
        !           249: desdone()
        !           250: {
        !           251:        if(sp == NULL)
        !           252:                return; /* Already done */
        !           253: 
        !           254:        free((char *)sp);
        !           255:        free((char *)kn);
        !           256:        if(iperm != NULL)
        !           257:                free((char *)iperm);
        !           258:        if(fperm != NULL)
        !           259:                free((char *)fperm);
        !           260: 
        !           261:        sp = NULL;
        !           262:        iperm = NULL;
        !           263:        fperm = NULL;
        !           264:        kn = NULL;
        !           265: }
        !           266: /* Set key (initialize key schedule array) */
        !           267: void
        !           268: setkey(key)
        !           269: char *key;                     /* 64 bits (will use only 56) */
        !           270: {
        !           271:        char pc1m[56];          /* place to modify pc1 into */
        !           272:        char pcr[56];           /* place to rotate pc1 into */
        !           273:        register int i,j,l;
        !           274:        int m;
        !           275: 
        !           276:        /* In mode 2, the 128 bytes of subkey are set directly from the
        !           277:         * user's key, allowing him to use completely independent
        !           278:         * subkeys for each round. Note that the user MUST specify a
        !           279:         * full 128 bytes.
        !           280:         *
        !           281:         * I would like to think that this technique gives the NSA a real
        !           282:         * headache, but I'm not THAT naive.
        !           283:         */
        !           284:        if(desmode == 2){
        !           285:                for(i=0;i<16;i++)
        !           286:                        for(j=0;j<8;j++)
        !           287:                                kn[i][j] = *key++;
        !           288:                return;
        !           289:        }
        !           290:        /* Clear key schedule */
        !           291:        memset((char *)kn,0,16*8);
        !           292: 
        !           293:        for (j=0; j<56; j++) {          /* convert pc1 to bits of key */
        !           294:                l=pc1[j]-1;             /* integer bit location  */
        !           295:                m = l & 07;             /* find bit              */
        !           296:                pc1m[j]=(key[l>>3] &    /* find which key byte l is in */
        !           297:                        bytebit[m])     /* and which bit of that byte */
        !           298:                        ? 1 : 0;        /* and store 1-bit result */
        !           299:        }
        !           300:        for (i=0; i<16; i++) {          /* key chunk for each iteration */
        !           301:                for (j=0; j<56; j++)    /* rotate pc1 the right amount */
        !           302:                        pcr[j] = pc1m[(l=j+totrot[i])<(j<28? 28 : 56) ? l: l-28];
        !           303:                        /* rotate left and right halves independently */
        !           304:                for (j=0; j<48; j++){   /* select bits individually */
        !           305:                        /* check bit that goes to kn[j] */
        !           306:                        if (pcr[pc2[j]-1]){
        !           307:                                /* mask it in if it's there */
        !           308:                                l= j % 6;
        !           309:                                kn[i][j/6] |= bytebit[l] >> 2;
        !           310:                        }
        !           311:                }
        !           312:        }
        !           313: }
        !           314: /* In-place encryption of 64-bit block */
        !           315: void
        !           316: endes(block)
        !           317: char *block;
        !           318: {
        !           319:        register long left,right;
        !           320:        register char *knp;
        !           321:        long work[2];           /* Working data storage */
        !           322: 
        !           323:        permute(block,iperm,(char *)work);      /* Initial Permutation */
        !           324: #if BYTE_ORDER == LITTLE_ENDIAN
        !           325:        left = byteswap(work[0]);
        !           326:        right = byteswap(work[1]);
        !           327: #else
        !           328:        left = work[0];
        !           329:        right = work[1];
        !           330: #endif
        !           331: 
        !           332:        /* Do the 16 rounds.
        !           333:         * The rounds are numbered from 0 to 15. On even rounds
        !           334:         * the right half is fed to f() and the result exclusive-ORs
        !           335:         * the left half; on odd rounds the reverse is done.
        !           336:         */
        !           337:        knp = &kn[0][0];
        !           338:        left ^= f(right,knp);
        !           339:        knp += 8;
        !           340:        right ^= f(left,knp);
        !           341:        knp += 8;
        !           342:        left ^= f(right,knp);
        !           343:        knp += 8;
        !           344:        right ^= f(left,knp);
        !           345:        knp += 8;
        !           346:        left ^= f(right,knp);
        !           347:        knp += 8;
        !           348:        right ^= f(left,knp);
        !           349:        knp += 8;
        !           350:        left ^= f(right,knp);
        !           351:        knp += 8;
        !           352:        right ^= f(left,knp);
        !           353:        knp += 8;
        !           354:        left ^= f(right,knp);
        !           355:        knp += 8;
        !           356:        right ^= f(left,knp);
        !           357:        knp += 8;
        !           358:        left ^= f(right,knp);
        !           359:        knp += 8;
        !           360:        right ^= f(left,knp);
        !           361:        knp += 8;
        !           362:        left ^= f(right,knp);
        !           363:        knp += 8;
        !           364:        right ^= f(left,knp);
        !           365:        knp += 8;
        !           366:        left ^= f(right,knp);
        !           367:        knp += 8;
        !           368:        right ^= f(left,knp);
        !           369: 
        !           370:        /* Left/right half swap, plus byte swap if little-endian */
        !           371: #if BYTE_ORDER == LITTLE_ENDIAN
        !           372:        work[1] = byteswap(left);
        !           373:        work[0] = byteswap(right);
        !           374: #else
        !           375:        work[0] = right;
        !           376:        work[1] = left;
        !           377: #endif
        !           378:        permute((char *)work,fperm,block);      /* Inverse initial permutation */
        !           379: }
        !           380: /* In-place decryption of 64-bit block. This function is the mirror
        !           381:  * image of encryption; exactly the same steps are taken, but in
        !           382:  * reverse order
        !           383:  */
        !           384: void
        !           385: dedes(block)
        !           386: char *block;
        !           387: {
        !           388:        register long left,right;
        !           389:        register char *knp;
        !           390:        long work[2];   /* Working data storage */
        !           391: 
        !           392:        permute(block,iperm,(char *)work);      /* Initial permutation */
        !           393: 
        !           394:        /* Left/right half swap, plus byte swap if little-endian */
        !           395: #if BYTE_ORDER == LITTLE_ENDIAN
        !           396:        right = byteswap(work[0]);
        !           397:        left = byteswap(work[1]);
        !           398: #else
        !           399:        right = work[0];
        !           400:        left = work[1];
        !           401: #endif
        !           402:        /* Do the 16 rounds in reverse order.
        !           403:         * The rounds are numbered from 15 to 0. On even rounds
        !           404:         * the right half is fed to f() and the result exclusive-ORs
        !           405:         * the left half; on odd rounds the reverse is done.
        !           406:         */
        !           407:        knp = &kn[15][0];
        !           408:        right ^= f(left,knp);
        !           409:        knp -= 8;
        !           410:        left ^= f(right,knp);
        !           411:        knp -= 8;
        !           412:        right ^= f(left,knp);
        !           413:        knp -= 8;
        !           414:        left ^= f(right,knp);
        !           415:        knp -= 8;
        !           416:        right ^= f(left,knp);
        !           417:        knp -= 8;
        !           418:        left ^= f(right,knp);
        !           419:        knp -= 8;
        !           420:        right ^= f(left,knp);
        !           421:        knp -= 8;
        !           422:        left ^= f(right,knp);
        !           423:        knp -= 8;
        !           424:        right ^= f(left,knp);
        !           425:        knp -= 8;
        !           426:        left ^= f(right,knp);
        !           427:        knp -= 8;
        !           428:        right ^= f(left,knp);
        !           429:        knp -= 8;
        !           430:        left ^= f(right,knp);
        !           431:        knp -= 8;
        !           432:        right ^= f(left,knp);
        !           433:        knp -= 8;
        !           434:        left ^= f(right,knp);
        !           435:        knp -= 8;
        !           436:        right ^= f(left,knp);
        !           437:        knp -= 8;
        !           438:        left ^= f(right,knp);
        !           439: 
        !           440: #if BYTE_ORDER == LITTLE_ENDIAN
        !           441:        work[0] = byteswap(left);
        !           442:        work[1] = byteswap(right);
        !           443: #else
        !           444:        work[0] = left;
        !           445:        work[1] = right;
        !           446: #endif
        !           447:        permute((char *)work,fperm,block);      /* Inverse initial permutation */
        !           448: }
        !           449: 
        !           450: /* Permute inblock with perm */
        !           451: static void
        !           452: permute(inblock,perm,outblock)
        !           453: char *inblock, *outblock;              /* result into outblock,64 bits */
        !           454: char perm[16][16][8];                  /* 2K bytes defining perm. */
        !           455: {
        !           456:        register char *ib, *ob;         /* ptr to input or output block */
        !           457:        register char *p, *q;
        !           458:        register int j;
        !           459: 
        !           460:        if(perm == NULL){
        !           461:                /* No permutation, just copy */
        !           462:                memcpy(outblock,inblock,8);
        !           463:                return;
        !           464:        }
        !           465:        /* Clear output block */
        !           466:        memset(outblock,'\0',8);
        !           467: 
        !           468:        ib = inblock;
        !           469:        for (j = 0; j < 16; j += 2, ib++) { /* for each input nibble */
        !           470:                ob = outblock;
        !           471:                p = perm[j][(*ib >> 4) & 0xf];
        !           472:                q = perm[j + 1][*ib & 0xf];
        !           473:                /* and each output byte, OR the masks together */
        !           474:                *ob++ |= *p++ | *q++;
        !           475:                *ob++ |= *p++ | *q++;
        !           476:                *ob++ |= *p++ | *q++;
        !           477:                *ob++ |= *p++ | *q++;
        !           478:                *ob++ |= *p++ | *q++;
        !           479:                *ob++ |= *p++ | *q++;
        !           480:                *ob++ |= *p++ | *q++;
        !           481:                *ob++ |= *p++ | *q++;
        !           482:        }
        !           483: }
        !           484: 
        !           485: /* The nonlinear function f(r,k), the heart of DES */
        !           486: static long
        !           487: f(r,subkey)
        !           488: register long r;       /* 32 bits */
        !           489: register char *subkey; /* 48-bit key for this round */
        !           490: {
        !           491:        register long *spp;
        !           492:        register long rval,rt;
        !           493:        register int er;
        !           494: 
        !           495: #ifdef TRACE
        !           496:        printf("f(%08lx, %02x %02x %02x %02x %02x %02x %02x %02x) = ",
        !           497:                r,
        !           498:                subkey[0], subkey[1], subkey[2],
        !           499:                subkey[3], subkey[4], subkey[5],
        !           500:                subkey[6], subkey[7]);
        !           501: #endif
        !           502:        /* Run E(R) ^ K through the combined S & P boxes.
        !           503:         * This code takes advantage of a convenient regularity in
        !           504:         * E, namely that each group of 6 bits in E(R) feeding
        !           505:         * a single S-box is a contiguous segment of R.
        !           506:         */
        !           507:        subkey += 7;
        !           508: 
        !           509:        /* Compute E(R) for each block of 6 bits, and run thru boxes */
        !           510:        er = ((int)r << 1) | ((r & 0x80000000) ? 1 : 0);
        !           511:        spp = &sp[7][0];
        !           512:        rval = spp[(er ^ *subkey--) & 0x3f];
        !           513:        spp -= 64;
        !           514:        rt = (unsigned long)r >> 3;
        !           515:        rval |= spp[((int)rt ^ *subkey--) & 0x3f];
        !           516:        spp -= 64;
        !           517:        rt >>= 4;
        !           518:        rval |= spp[((int)rt ^ *subkey--) & 0x3f];
        !           519:        spp -= 64;
        !           520:        rt >>= 4;
        !           521:        rval |= spp[((int)rt ^ *subkey--) & 0x3f];
        !           522:        spp -= 64;
        !           523:        rt >>= 4;
        !           524:        rval |= spp[((int)rt ^ *subkey--) & 0x3f];
        !           525:        spp -= 64;
        !           526:        rt >>= 4;
        !           527:        rval |= spp[((int)rt ^ *subkey--) & 0x3f];
        !           528:        spp -= 64;
        !           529:        rt >>= 4;
        !           530:        rval |= spp[((int)rt ^ *subkey--) & 0x3f];
        !           531:        spp -= 64;
        !           532:        rt >>= 4;
        !           533:        rt |= (r & 1) << 5;
        !           534:        rval |= spp[((int)rt ^ *subkey) & 0x3f];
        !           535: #ifdef TRACE
        !           536:        printf(" %08lx\n",rval);
        !           537: #endif
        !           538:        return rval;
        !           539: }
        !           540: /* initialize a perm array */
        !           541: static void
        !           542: perminit(perm,p)
        !           543: char perm[16][16][8];                  /* 64-bit, either init or final */
        !           544: char p[64];
        !           545: {
        !           546:        register int l, j, k;
        !           547:        int i,m;
        !           548: 
        !           549:        /* Clear the permutation array */
        !           550:        memset((char *)perm,0,16*16*8);
        !           551: 
        !           552:        for (i=0; i<16; i++)            /* each input nibble position */
        !           553:                for (j = 0; j < 16; j++)/* each possible input nibble */
        !           554:                for (k = 0; k < 64; k++)/* each output bit position */
        !           555:                {   l = p[k] - 1;       /* where does this bit come from*/
        !           556:                        if ((l >> 2) != i)  /* does it come from input posn?*/
        !           557:                        continue;       /* if not, bit k is 0    */
        !           558:                        if (!(j & nibblebit[l & 3]))
        !           559:                        continue;       /* any such bit in input? */
        !           560:                        m = k & 07;     /* which bit is this in the byte*/
        !           561:                        perm[i][j][k>>3] |= bytebit[m];
        !           562:                }
        !           563: }
        !           564: 
        !           565: /* Initialize the lookup table for the combined S and P boxes */
        !           566: static void
        !           567: spinit()
        !           568: {
        !           569:        char pbox[32];
        !           570:        int p,i,s,j,rowcol;
        !           571:        long val;
        !           572: 
        !           573:        /* Compute pbox, the inverse of p32i.
        !           574:         * This is easier to work with
        !           575:         */
        !           576:        for(p=0;p<32;p++){
        !           577:                for(i=0;i<32;i++){
        !           578:                        if(p32i[i]-1 == p){
        !           579:                                pbox[p] = i;
        !           580:                                break;
        !           581:                        }
        !           582:                }
        !           583:        }
        !           584:        for(s = 0; s < 8; s++){                 /* For each S-box */
        !           585:                for(i=0; i<64; i++){            /* For each possible input */
        !           586:                        val = 0;
        !           587:                        /* The row number is formed from the first and last
        !           588:                         * bits; the column number is from the middle 4
        !           589:                         */
        !           590:                        rowcol = (i & 32) | ((i & 1) ? 16 : 0) | ((i >> 1) & 0xf);
        !           591:                        for(j=0;j<4;j++){       /* For each output bit */
        !           592:                                if(si[s][rowcol] & (8 >> j)){
        !           593:                                 val |= 1L << (31 - pbox[4*s + j]);
        !           594:                                }
        !           595:                        }
        !           596:                        sp[s][i] = val;
        !           597: 
        !           598: #ifdef DEBUG
        !           599:                        printf("sp[%d][%2d] = %08lx\n",s,i,sp[s][i]);
        !           600: #endif
        !           601:                }
        !           602:        }
        !           603: }
        !           604: 
        !           605: #if BYTE_ORDER == LITTLE_ENDIAN
        !           606: /* Byte swap a long */
        !           607: static long
        !           608: byteswap(x)
        !           609: unsigned long x;
        !           610: {
        !           611:        register char *cp,tmp;
        !           612: 
        !           613:        cp = (char *)&x;
        !           614:        tmp = cp[3];
        !           615:        cp[3] = cp[0];
        !           616:        cp[0] = tmp;
        !           617: 
        !           618:        tmp = cp[2];
        !           619:        cp[2] = cp[1];
        !           620:        cp[1] = tmp;
        !           621: 
        !           622:        return x;
        !           623: }
        !           624: #endif

unix.superglobalmegacorp.com

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