Annotation of embedaddon/strongswan/src/libstrongswan/plugins/des/des_crypter.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * Copyright (C) 2009 Tobias Brunner
        !             3:  * Copyright (C) 2006 Martin Willi
        !             4:  * HSR Hochschule fuer Technik Rapperswil
        !             5:  *
        !             6:  * Derived from Plutos DES library by Eric Young.
        !             7:  *
        !             8:  * Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
        !             9:  * All rights reserved.
        !            10:  *
        !            11:  * This package is an SSL implementation written
        !            12:  * by Eric Young (eay@cryptsoft.com).
        !            13:  * The implementation was written so as to conform with Netscapes SSL.
        !            14:  *
        !            15:  * This library is free for commercial and non-commercial use as long as
        !            16:  * the following conditions are adhered to.
        !            17:  *
        !            18:  * Copyright remains Eric Young's, and as such any Copyright notices in
        !            19:  * the code are not to be removed.
        !            20:  * If this package is used in a product, Eric Young should be given attribution
        !            21:  * as the author of the parts of the library used.
        !            22:  * This can be in the form of a textual message at program startup or
        !            23:  * in documentation (online or textual) provided with the package.
        !            24:  *
        !            25:  * Redistribution and use in source and binary forms, with or without
        !            26:  * modification, are permitted provided that the following conditions
        !            27:  * are met:
        !            28:  * 1. Redistributions of source code must retain the copyright
        !            29:  *    notice, this list of conditions and the following disclaimer.
        !            30:  * 2. Redistributions in binary form must reproduce the above copyright
        !            31:  *    notice, this list of conditions and the following disclaimer in the
        !            32:  *    documentation and/or other materials provided with the distribution.
        !            33:  * 3. All advertising materials mentioning features or use of this software
        !            34:  *    must display the following acknowledgement:
        !            35:  *    "This product includes cryptographic software written by
        !            36:  *     Eric Young (eay@cryptsoft.com)"
        !            37:  *    The word 'cryptographic' can be left out if the routines from the library
        !            38:  *    being used are not cryptographic related :-).
        !            39:  * 4. If you include any Windows specific code (or a derivative thereof) from
        !            40:  *    the apps directory (application code) you must include an acknowledgement:
        !            41:  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
        !            42:  *
        !            43:  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
        !            44:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            45:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            46:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        !            47:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            48:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            49:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            50:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            51:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            52:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            53:  * SUCH DAMAGE.
        !            54:  *
        !            55:  * The licence and distribution terms for any publicly available version or
        !            56:  * derivative of this code cannot be changed.  i.e. this code cannot simply be
        !            57:  * copied and put under another distribution licence
        !            58:  * [including the GNU Public Licence.]
        !            59:  */
        !            60: 
        !            61: #include "des_crypter.h"
        !            62: 
        !            63: typedef u_char des_cblock[DES_BLOCK_SIZE];
        !            64: 
        !            65: typedef struct des_ks_struct {
        !            66:        des_cblock _;
        !            67: } des_key_schedule[16];
        !            68: 
        !            69: 
        !            70: typedef struct private_des_crypter_t private_des_crypter_t;
        !            71: 
        !            72: /**
        !            73:  * Private data for des_crypter_t
        !            74:  */
        !            75: struct private_des_crypter_t {
        !            76: 
        !            77:        /**
        !            78:         * Public part of this class.
        !            79:         */
        !            80:        des_crypter_t public;
        !            81: 
        !            82:        /**
        !            83:         * Key size, depends on algorithm...
        !            84:         */
        !            85:        size_t key_size;
        !            86: 
        !            87:        union {
        !            88:                /** key schedule for single des */
        !            89:                des_key_schedule ks;
        !            90:                /** key schedule for 3des */
        !            91:                des_key_schedule ks3[3];
        !            92:        };
        !            93: };
        !            94: 
        !            95: 
        !            96: #define DES_ENCRYPT 1
        !            97: #define DES_DECRYPT 0
        !            98: 
        !            99: #define DES_LONG uint32_t
        !           100: 
        !           101: #if defined(WIN32) || defined(WIN16)
        !           102: #ifndef MSDOS
        !           103: #define MSDOS
        !           104: #endif
        !           105: #endif
        !           106: 
        !           107: #ifndef DES_DEFAULT_OPTIONS
        !           108: /* the following is tweaked from a config script, that is why it is a
        !           109:  * protected undef/define */
        !           110: #ifndef DES_PTR
        !           111: #define DES_PTR
        !           112: #endif
        !           113: 
        !           114: /* This helps C compiler generate the correct code for multiple functional
        !           115:  * units.  It reduces register dependencies at the expense of 2 more
        !           116:  * registers */
        !           117: #ifndef DES_RISC1
        !           118: #define DES_RISC1
        !           119: #endif
        !           120: 
        !           121: #ifndef DES_RISC2
        !           122: #undef DES_RISC2
        !           123: #endif
        !           124: 
        !           125: #if defined(DES_RISC1) && defined(DES_RISC2)
        !           126: YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!!
        !           127: #endif
        !           128: 
        !           129: /* Unroll the inner loop, this sometimes helps, sometimes hinders.
        !           130:  * Very much CPU dependent */
        !           131: #ifndef DES_UNROLL
        !           132: #define DES_UNROLL
        !           133: #endif
        !           134: 
        !           135: /* These default values were supplied by
        !           136:  * Peter Gutman <pgut001@cs.auckland.ac.nz>
        !           137:  * They are only used if nothing else has been defined */
        !           138: #if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL)
        !           139: /* Special defines which change the way the code is built depending on the
        !           140:    CPU and OS.  For SGI machines you can use _MIPS_SZLONG (32 or 64) to find
        !           141:    even newer MIPS CPU's, but at the moment one size fits all for
        !           142:    optimization options.  Older Sparc's work better with only UNROLL, but
        !           143:    there's no way to tell at compile time what it is you're running on */
        !           144: 
        !           145: #if defined( sun )             /* Newer Sparc's */
        !           146: #define DES_PTR
        !           147: #define DES_RISC1
        !           148: #define DES_UNROLL
        !           149: #elif defined( __ultrix )      /* Older MIPS */
        !           150: #define DES_PTR
        !           151: #define DES_RISC2
        !           152: #define DES_UNROLL
        !           153: #elif defined( __osf1__ )      /* Alpha */
        !           154: #define DES_PTR
        !           155: #define DES_RISC2
        !           156: #elif defined ( _AIX )         /* RS6000 */
        !           157:   /* Unknown */
        !           158: #elif defined( __hpux )                /* HP-PA */
        !           159:   /* Unknown */
        !           160: #elif defined( __aux )         /* 68K */
        !           161:   /* Unknown */
        !           162: #elif defined( __dgux )                /* 88K (but P6 in latest boxes) */
        !           163: #define DES_UNROLL
        !           164: #elif defined( __sgi )         /* Newer MIPS */
        !           165: #define DES_PTR
        !           166: #define DES_RISC2
        !           167: #define DES_UNROLL
        !           168: #elif defined( i386 )          /* x86 boxes, should be gcc */
        !           169: #define DES_PTR
        !           170: #define DES_RISC1
        !           171: #define DES_UNROLL
        !           172: #endif /* Systems-specific speed defines */
        !           173: #endif
        !           174: 
        !           175: #endif /* DES_DEFAULT_OPTIONS */
        !           176: 
        !           177: #ifdef MSDOS           /* Visual C++ 2.1 (Windows NT/95) */
        !           178: #include <stdlib.h>
        !           179: #include <errno.h>
        !           180: #include <time.h>
        !           181: #include <io.h>
        !           182: #ifndef RAND
        !           183: #define RAND
        !           184: #endif
        !           185: #undef NOPROTO
        !           186: #endif
        !           187: 
        !           188: #if defined(__STDC__) || defined(VMS) || defined(M_XENIX) || defined(MSDOS)
        !           189: #ifndef __KERNEL__
        !           190: #include <string.h>
        !           191: #else
        !           192: #include <linux/string.h>
        !           193: #endif
        !           194: #endif
        !           195: 
        !           196: #ifndef RAND
        !           197: #define RAND
        !           198: #endif
        !           199: 
        !           200: #ifdef linux
        !           201: #undef RAND
        !           202: #endif
        !           203: 
        !           204: #ifdef MSDOS
        !           205: #define getpid() 2
        !           206: #define RAND
        !           207: #undef NOPROTO
        !           208: #endif
        !           209: 
        !           210: #if defined(NOCONST)
        !           211: #define const
        !           212: #endif
        !           213: 
        !           214: #ifdef __STDC__
        !           215: #undef NOPROTO
        !           216: #endif
        !           217: 
        !           218: #ifdef RAND
        !           219: #define srandom(s) srand(s)
        !           220: #define random rand
        !           221: #endif
        !           222: 
        !           223: #define ITERATIONS 16
        !           224: #define HALF_ITERATIONS 8
        !           225: 
        !           226: /* used in des_read and des_write */
        !           227: #define MAXWRITE       (1024*16)
        !           228: #define BSIZE          (MAXWRITE+4)
        !           229: 
        !           230: #define c2l(c,l)       (l =((DES_LONG)(*((c)++)))    , \
        !           231:                         l|=((DES_LONG)(*((c)++)))<< 8L, \
        !           232:                         l|=((DES_LONG)(*((c)++)))<<16L, \
        !           233:                         l|=((DES_LONG)(*((c)++)))<<24L)
        !           234: 
        !           235: /* NOTE - c is not incremented as per c2l */
        !           236: #define c2ln(c,l1,l2,n)        { \
        !           237:                        c+=n; \
        !           238:                        l1=l2=0; \
        !           239:                        switch (n) { \
        !           240:                        case 8: l2 =((DES_LONG)(*(--(c))))<<24L; \
        !           241:                        case 7: l2|=((DES_LONG)(*(--(c))))<<16L; \
        !           242:                        case 6: l2|=((DES_LONG)(*(--(c))))<< 8L; \
        !           243:                        case 5: l2|=((DES_LONG)(*(--(c))));     \
        !           244:                        case 4: l1 =((DES_LONG)(*(--(c))))<<24L; \
        !           245:                        case 3: l1|=((DES_LONG)(*(--(c))))<<16L; \
        !           246:                        case 2: l1|=((DES_LONG)(*(--(c))))<< 8L; \
        !           247:                        case 1: l1|=((DES_LONG)(*(--(c))));     \
        !           248: } \
        !           249: }
        !           250: 
        !           251: #define l2c(l,c)       (*((c)++)=(unsigned char)(((l)     )&0xff), \
        !           252:                         *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
        !           253:                         *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
        !           254:                         *((c)++)=(unsigned char)(((l)>>24L)&0xff))
        !           255: 
        !           256: /* replacements for htonl and ntohl since I have no idea what to do
        !           257:  * when faced with machines with 8 byte longs. */
        !           258: #define HDRSIZE 4
        !           259: 
        !           260: #define n2l(c,l)       (l =((DES_LONG)(*((c)++)))<<24L, \
        !           261:                         l|=((DES_LONG)(*((c)++)))<<16L, \
        !           262:                         l|=((DES_LONG)(*((c)++)))<< 8L, \
        !           263:                         l|=((DES_LONG)(*((c)++))))
        !           264: 
        !           265: #define l2n(l,c)       (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
        !           266:                         *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
        !           267:                         *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
        !           268:                         *((c)++)=(unsigned char)(((l)     )&0xff))
        !           269: 
        !           270: /* NOTE - c is not incremented as per l2c */
        !           271: #define l2cn(l1,l2,c,n)        { \
        !           272:                        c+=n; \
        !           273:                        switch (n) { \
        !           274:                        case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \
        !           275:                        case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \
        !           276:                        case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \
        !           277:                        case 5: *(--(c))=(unsigned char)(((l2)     )&0xff); \
        !           278:                        case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \
        !           279:                        case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \
        !           280:                        case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \
        !           281:                        case 1: *(--(c))=(unsigned char)(((l1)     )&0xff); \
        !           282: } \
        !           283: }
        !           284: 
        !           285: #if defined(WIN32)
        !           286: #define        ROTATE(a,n)     (_lrotr(a,n))
        !           287: #else
        !           288: #define        ROTATE(a,n)     (((a)>>(n))+((a)<<(32-(n))))
        !           289: #endif
        !           290: 
        !           291: /* Don't worry about the LOAD_DATA() stuff, that is used by
        !           292:  * fcrypt() to add it's little bit to the front */
        !           293: 
        !           294: #ifdef DES_FCRYPT
        !           295: 
        !           296: #define LOAD_DATA_tmp(R,S,u,t,E0,E1) \
        !           297: { DES_LONG tmp; LOAD_DATA(R,S,u,t,E0,E1,tmp); }
        !           298: 
        !           299: #define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
        !           300:        t=R^(R>>16L); \
        !           301:        u=t&E0; t&=E1; \
        !           302:        tmp=(u<<16); u^=R^s[S  ]; u^=tmp; \
        !           303:        tmp=(t<<16); t^=R^s[S+1]; t^=tmp
        !           304: #else
        !           305: #define LOAD_DATA_tmp(a,b,c,d,e,f) LOAD_DATA(a,b,c,d,e,f,g)
        !           306: #define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
        !           307:        u=R^s[S  ]; \
        !           308:        t=R^s[S+1]
        !           309: #endif
        !           310: 
        !           311: /* The changes to this macro may help or hinder, depending on the
        !           312:  * compiler and the architecture.  gcc2 always seems to do well :-).
        !           313:  * Inspired by Dana How <how@isl.stanford.edu>
        !           314:  * DO NOT use the alternative version on machines with 8 byte longs.
        !           315:  * It does not seem to work on the Alpha, even when DES_LONG is 4
        !           316:  * bytes, probably an issue of accessing non-word aligned objects :-( */
        !           317: #ifdef DES_PTR
        !           318: 
        !           319: /* It recently occurred to me that 0^0^0^0^0^0^0 == 0, so there
        !           320:  * is no reason to not xor all the sub items together.  This potentially
        !           321:  * saves a register since things can be xored directly into L */
        !           322: 
        !           323: #if defined(DES_RISC1) || defined(DES_RISC2)
        !           324: #ifdef DES_RISC1
        !           325: #define D_ENCRYPT(LL,R,S) { \
        !           326:        unsigned int u1,u2,u3; \
        !           327:        LOAD_DATA(R,S,u,t,E0,E1,u1); \
        !           328:        u2=(int)u>>8L; \
        !           329:        u1=(int)u&0xfc; \
        !           330:        u2&=0xfc; \
        !           331:        t=ROTATE(t,4); \
        !           332:        u>>=16L; \
        !           333:        LL^= *(DES_LONG *)((unsigned char *)des_SP      +u1); \
        !           334:        LL^= *(DES_LONG *)((unsigned char *)des_SP+0x200+u2); \
        !           335:        u3=(int)(u>>8L); \
        !           336:        u1=(int)u&0xfc; \
        !           337:        u3&=0xfc; \
        !           338:        LL^= *(DES_LONG *)((unsigned char *)des_SP+0x400+u1); \
        !           339:        LL^= *(DES_LONG *)((unsigned char *)des_SP+0x600+u3); \
        !           340:        u2=(int)t>>8L; \
        !           341:        u1=(int)t&0xfc; \
        !           342:        u2&=0xfc; \
        !           343:        t>>=16L; \
        !           344:        LL^= *(DES_LONG *)((unsigned char *)des_SP+0x100+u1); \
        !           345:        LL^= *(DES_LONG *)((unsigned char *)des_SP+0x300+u2); \
        !           346:        u3=(int)t>>8L; \
        !           347:        u1=(int)t&0xfc; \
        !           348:        u3&=0xfc; \
        !           349:        LL^= *(DES_LONG *)((unsigned char *)des_SP+0x500+u1); \
        !           350:        LL^= *(DES_LONG *)((unsigned char *)des_SP+0x700+u3); }
        !           351: #endif
        !           352: #ifdef DES_RISC2
        !           353: #define D_ENCRYPT(LL,R,S) { \
        !           354:        unsigned int u1,u2,s1,s2; \
        !           355:        LOAD_DATA(R,S,u,t,E0,E1,u1); \
        !           356:        u2=(int)u>>8L; \
        !           357:        u1=(int)u&0xfc; \
        !           358:        u2&=0xfc; \
        !           359:        t=ROTATE(t,4); \
        !           360:        LL^= *(DES_LONG *)((unsigned char *)des_SP      +u1); \
        !           361:        LL^= *(DES_LONG *)((unsigned char *)des_SP+0x200+u2); \
        !           362:        s1=(int)(u>>16L); \
        !           363:        s2=(int)(u>>24L); \
        !           364:        s1&=0xfc; \
        !           365:        s2&=0xfc; \
        !           366:        LL^= *(DES_LONG *)((unsigned char *)des_SP+0x400+s1); \
        !           367:        LL^= *(DES_LONG *)((unsigned char *)des_SP+0x600+s2); \
        !           368:        u2=(int)t>>8L; \
        !           369:        u1=(int)t&0xfc; \
        !           370:        u2&=0xfc; \
        !           371:        LL^= *(DES_LONG *)((unsigned char *)des_SP+0x100+u1); \
        !           372:        LL^= *(DES_LONG *)((unsigned char *)des_SP+0x300+u2); \
        !           373:        s1=(int)(t>>16L); \
        !           374:        s2=(int)(t>>24L); \
        !           375:        s1&=0xfc; \
        !           376:        s2&=0xfc; \
        !           377:        LL^= *(DES_LONG *)((unsigned char *)des_SP+0x500+s1); \
        !           378:        LL^= *(DES_LONG *)((unsigned char *)des_SP+0x700+s2); }
        !           379: #endif
        !           380: #else
        !           381: #define D_ENCRYPT(LL,R,S) { \
        !           382:        LOAD_DATA_tmp(R,S,u,t,E0,E1); \
        !           383:        t=ROTATE(t,4); \
        !           384:        LL^= \
        !           385:        *(DES_LONG *)((unsigned char *)des_SP      +((u     )&0xfc))^ \
        !           386:        *(DES_LONG *)((unsigned char *)des_SP+0x200+((u>> 8L)&0xfc))^ \
        !           387:        *(DES_LONG *)((unsigned char *)des_SP+0x400+((u>>16L)&0xfc))^ \
        !           388:        *(DES_LONG *)((unsigned char *)des_SP+0x600+((u>>24L)&0xfc))^ \
        !           389:        *(DES_LONG *)((unsigned char *)des_SP+0x100+((t     )&0xfc))^ \
        !           390:        *(DES_LONG *)((unsigned char *)des_SP+0x300+((t>> 8L)&0xfc))^ \
        !           391:        *(DES_LONG *)((unsigned char *)des_SP+0x500+((t>>16L)&0xfc))^ \
        !           392:        *(DES_LONG *)((unsigned char *)des_SP+0x700+((t>>24L)&0xfc)); }
        !           393: #endif
        !           394: 
        !           395: #else /* original version */
        !           396: 
        !           397: #if defined(DES_RISC1) || defined(DES_RISC2)
        !           398: #ifdef DES_RISC1
        !           399: #define D_ENCRYPT(LL,R,S) {\
        !           400:        unsigned int u1,u2,u3; \
        !           401:        LOAD_DATA(R,S,u,t,E0,E1,u1); \
        !           402:        u>>=2L; \
        !           403:        t=ROTATE(t,6); \
        !           404:        u2=(int)u>>8L; \
        !           405:        u1=(int)u&0x3f; \
        !           406:        u2&=0x3f; \
        !           407:        u>>=16L; \
        !           408:        LL^=des_SPtrans[0][u1]; \
        !           409:        LL^=des_SPtrans[2][u2]; \
        !           410:        u3=(int)u>>8L; \
        !           411:        u1=(int)u&0x3f; \
        !           412:        u3&=0x3f; \
        !           413:        LL^=des_SPtrans[4][u1]; \
        !           414:        LL^=des_SPtrans[6][u3]; \
        !           415:        u2=(int)t>>8L; \
        !           416:        u1=(int)t&0x3f; \
        !           417:        u2&=0x3f; \
        !           418:        t>>=16L; \
        !           419:        LL^=des_SPtrans[1][u1]; \
        !           420:        LL^=des_SPtrans[3][u2]; \
        !           421:        u3=(int)t>>8L; \
        !           422:        u1=(int)t&0x3f; \
        !           423:        u3&=0x3f; \
        !           424:        LL^=des_SPtrans[5][u1]; \
        !           425:        LL^=des_SPtrans[7][u3]; }
        !           426: #endif
        !           427: #ifdef DES_RISC2
        !           428: #define D_ENCRYPT(LL,R,S) {\
        !           429:        unsigned int u1,u2,s1,s2; \
        !           430:        LOAD_DATA(R,S,u,t,E0,E1,u1); \
        !           431:        u>>=2L; \
        !           432:        t=ROTATE(t,6); \
        !           433:        u2=(int)u>>8L; \
        !           434:        u1=(int)u&0x3f; \
        !           435:        u2&=0x3f; \
        !           436:        LL^=des_SPtrans[0][u1]; \
        !           437:        LL^=des_SPtrans[2][u2]; \
        !           438:        s1=(int)u>>16L; \
        !           439:        s2=(int)u>>24L; \
        !           440:        s1&=0x3f; \
        !           441:        s2&=0x3f; \
        !           442:        LL^=des_SPtrans[4][s1]; \
        !           443:        LL^=des_SPtrans[6][s2]; \
        !           444:        u2=(int)t>>8L; \
        !           445:        u1=(int)t&0x3f; \
        !           446:        u2&=0x3f; \
        !           447:        LL^=des_SPtrans[1][u1]; \
        !           448:        LL^=des_SPtrans[3][u2]; \
        !           449:        s1=(int)t>>16; \
        !           450:        s2=(int)t>>24L; \
        !           451:        s1&=0x3f; \
        !           452:        s2&=0x3f; \
        !           453:        LL^=des_SPtrans[5][s1]; \
        !           454:        LL^=des_SPtrans[7][s2]; }
        !           455: #endif
        !           456: 
        !           457: #else
        !           458: 
        !           459: #define D_ENCRYPT(LL,R,S) {\
        !           460:        LOAD_DATA_tmp(R,S,u,t,E0,E1); \
        !           461:        t=ROTATE(t,4); \
        !           462:        LL^=\
        !           463:                des_SPtrans[0][(u>> 2L)&0x3f]^ \
        !           464:                des_SPtrans[2][(u>>10L)&0x3f]^ \
        !           465:                des_SPtrans[4][(u>>18L)&0x3f]^ \
        !           466:                des_SPtrans[6][(u>>26L)&0x3f]^ \
        !           467:                des_SPtrans[1][(t>> 2L)&0x3f]^ \
        !           468:                des_SPtrans[3][(t>>10L)&0x3f]^ \
        !           469:                des_SPtrans[5][(t>>18L)&0x3f]^ \
        !           470:                des_SPtrans[7][(t>>26L)&0x3f]; }
        !           471: #endif
        !           472: #endif
        !           473: 
        !           474:        /* IP and FP
        !           475:         * The problem is more of a geometric problem that random bit fiddling.
        !           476:         0  1  2  3  4  5  6  7      62 54 46 38 30 22 14  6
        !           477:         8  9 10 11 12 13 14 15      60 52 44 36 28 20 12  4
        !           478:        16 17 18 19 20 21 22 23      58 50 42 34 26 18 10  2
        !           479:        24 25 26 27 28 29 30 31  to  56 48 40 32 24 16  8  0
        !           480: 
        !           481:        32 33 34 35 36 37 38 39      63 55 47 39 31 23 15  7
        !           482:        40 41 42 43 44 45 46 47      61 53 45 37 29 21 13  5
        !           483:        48 49 50 51 52 53 54 55      59 51 43 35 27 19 11  3
        !           484:        56 57 58 59 60 61 62 63      57 49 41 33 25 17  9  1
        !           485: 
        !           486:        The output has been subject to swaps of the form
        !           487:        0 1 -> 3 1 but the odd and even bits have been put into
        !           488:        2 3    2 0
        !           489:        different words.  The main trick is to remember that
        !           490:        t=((l>>size)^r)&(mask);
        !           491:        r^=t;
        !           492:        l^=(t<<size);
        !           493:        can be used to swap and move bits between words.
        !           494: 
        !           495:        So l =  0  1  2  3  r = 16 17 18 19
        !           496:                4  5  6  7      20 21 22 23
        !           497:                8  9 10 11      24 25 26 27
        !           498:               12 13 14 15      28 29 30 31
        !           499:        becomes (for size == 2 and mask == 0x3333)
        !           500:           t =   2^16  3^17 -- --   l =  0  1 16 17  r =  2  3 18 19
        !           501:                 6^20  7^21 -- --        4  5 20 21       6  7 22 23
        !           502:                10^24 11^25 -- --        8  9 24 25      10 11 24 25
        !           503:                14^28 15^29 -- --       12 13 28 29      14 15 28 29
        !           504: 
        !           505:        Thanks for hints from Richard Outerbridge - he told me IP&FP
        !           506:        could be done in 15 xor, 10 shifts and 5 ands.
        !           507:        When I finally started to think of the problem in 2D
        !           508:        I first got ~42 operations without xors.  When I remembered
        !           509:        how to use xors :-) I got it to its final state.
        !           510:        */
        !           511: #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
        !           512:        (b)^=(t),\
        !           513:        (a)^=((t)<<(n)))
        !           514: 
        !           515: #define IP(l,r) \
        !           516: { \
        !           517:        register DES_LONG tt; \
        !           518:        PERM_OP(r,l,tt, 4,0x0f0f0f0fL); \
        !           519:        PERM_OP(l,r,tt,16,0x0000ffffL); \
        !           520:        PERM_OP(r,l,tt, 2,0x33333333L); \
        !           521:        PERM_OP(l,r,tt, 8,0x00ff00ffL); \
        !           522:        PERM_OP(r,l,tt, 1,0x55555555L); \
        !           523: }
        !           524: 
        !           525: #define FP(l,r) \
        !           526: { \
        !           527:        register DES_LONG tt; \
        !           528:        PERM_OP(l,r,tt, 1,0x55555555L); \
        !           529:        PERM_OP(r,l,tt, 8,0x00ff00ffL); \
        !           530:        PERM_OP(l,r,tt, 2,0x33333333L); \
        !           531:        PERM_OP(r,l,tt,16,0x0000ffffL); \
        !           532:        PERM_OP(l,r,tt, 4,0x0f0f0f0fL); \
        !           533: }
        !           534: 
        !           535: #ifndef NOPROTO
        !           536: void fcrypt_body(DES_LONG *out,des_key_schedule ks,
        !           537:                                 DES_LONG Eswap0, DES_LONG Eswap1);
        !           538: #else
        !           539: void fcrypt_body();
        !           540: #endif
        !           541: 
        !           542: static const DES_LONG des_skb[8][64]={
        !           543:        {       /* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
        !           544:                0x00000000L,0x00000010L,0x20000000L,0x20000010L,
        !           545:                0x00010000L,0x00010010L,0x20010000L,0x20010010L,
        !           546:                0x00000800L,0x00000810L,0x20000800L,0x20000810L,
        !           547:                0x00010800L,0x00010810L,0x20010800L,0x20010810L,
        !           548:                0x00000020L,0x00000030L,0x20000020L,0x20000030L,
        !           549:                0x00010020L,0x00010030L,0x20010020L,0x20010030L,
        !           550:                0x00000820L,0x00000830L,0x20000820L,0x20000830L,
        !           551:                0x00010820L,0x00010830L,0x20010820L,0x20010830L,
        !           552:                0x00080000L,0x00080010L,0x20080000L,0x20080010L,
        !           553:                0x00090000L,0x00090010L,0x20090000L,0x20090010L,
        !           554:                0x00080800L,0x00080810L,0x20080800L,0x20080810L,
        !           555:                0x00090800L,0x00090810L,0x20090800L,0x20090810L,
        !           556:                0x00080020L,0x00080030L,0x20080020L,0x20080030L,
        !           557:                0x00090020L,0x00090030L,0x20090020L,0x20090030L,
        !           558:                0x00080820L,0x00080830L,0x20080820L,0x20080830L,
        !           559:                0x00090820L,0x00090830L,0x20090820L,0x20090830L,
        !           560:        },
        !           561:        {       /* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */
        !           562:                0x00000000L,0x02000000L,0x00002000L,0x02002000L,
        !           563:                0x00200000L,0x02200000L,0x00202000L,0x02202000L,
        !           564:                0x00000004L,0x02000004L,0x00002004L,0x02002004L,
        !           565:                0x00200004L,0x02200004L,0x00202004L,0x02202004L,
        !           566:                0x00000400L,0x02000400L,0x00002400L,0x02002400L,
        !           567:                0x00200400L,0x02200400L,0x00202400L,0x02202400L,
        !           568:                0x00000404L,0x02000404L,0x00002404L,0x02002404L,
        !           569:                0x00200404L,0x02200404L,0x00202404L,0x02202404L,
        !           570:                0x10000000L,0x12000000L,0x10002000L,0x12002000L,
        !           571:                0x10200000L,0x12200000L,0x10202000L,0x12202000L,
        !           572:                0x10000004L,0x12000004L,0x10002004L,0x12002004L,
        !           573:                0x10200004L,0x12200004L,0x10202004L,0x12202004L,
        !           574:                0x10000400L,0x12000400L,0x10002400L,0x12002400L,
        !           575:                0x10200400L,0x12200400L,0x10202400L,0x12202400L,
        !           576:                0x10000404L,0x12000404L,0x10002404L,0x12002404L,
        !           577:                0x10200404L,0x12200404L,0x10202404L,0x12202404L,
        !           578:        },
        !           579:        {       /* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */
        !           580:                0x00000000L,0x00000001L,0x00040000L,0x00040001L,
        !           581:                0x01000000L,0x01000001L,0x01040000L,0x01040001L,
        !           582:                0x00000002L,0x00000003L,0x00040002L,0x00040003L,
        !           583:                0x01000002L,0x01000003L,0x01040002L,0x01040003L,
        !           584:                0x00000200L,0x00000201L,0x00040200L,0x00040201L,
        !           585:                0x01000200L,0x01000201L,0x01040200L,0x01040201L,
        !           586:                0x00000202L,0x00000203L,0x00040202L,0x00040203L,
        !           587:                0x01000202L,0x01000203L,0x01040202L,0x01040203L,
        !           588:                0x08000000L,0x08000001L,0x08040000L,0x08040001L,
        !           589:                0x09000000L,0x09000001L,0x09040000L,0x09040001L,
        !           590:                0x08000002L,0x08000003L,0x08040002L,0x08040003L,
        !           591:                0x09000002L,0x09000003L,0x09040002L,0x09040003L,
        !           592:                0x08000200L,0x08000201L,0x08040200L,0x08040201L,
        !           593:                0x09000200L,0x09000201L,0x09040200L,0x09040201L,
        !           594:                0x08000202L,0x08000203L,0x08040202L,0x08040203L,
        !           595:                0x09000202L,0x09000203L,0x09040202L,0x09040203L,
        !           596:        },
        !           597:        {       /* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */
        !           598:                0x00000000L,0x00100000L,0x00000100L,0x00100100L,
        !           599:                0x00000008L,0x00100008L,0x00000108L,0x00100108L,
        !           600:                0x00001000L,0x00101000L,0x00001100L,0x00101100L,
        !           601:                0x00001008L,0x00101008L,0x00001108L,0x00101108L,
        !           602:                0x04000000L,0x04100000L,0x04000100L,0x04100100L,
        !           603:                0x04000008L,0x04100008L,0x04000108L,0x04100108L,
        !           604:                0x04001000L,0x04101000L,0x04001100L,0x04101100L,
        !           605:                0x04001008L,0x04101008L,0x04001108L,0x04101108L,
        !           606:                0x00020000L,0x00120000L,0x00020100L,0x00120100L,
        !           607:                0x00020008L,0x00120008L,0x00020108L,0x00120108L,
        !           608:                0x00021000L,0x00121000L,0x00021100L,0x00121100L,
        !           609:                0x00021008L,0x00121008L,0x00021108L,0x00121108L,
        !           610:                0x04020000L,0x04120000L,0x04020100L,0x04120100L,
        !           611:                0x04020008L,0x04120008L,0x04020108L,0x04120108L,
        !           612:                0x04021000L,0x04121000L,0x04021100L,0x04121100L,
        !           613:                0x04021008L,0x04121008L,0x04021108L,0x04121108L,
        !           614:        },
        !           615:        {       /* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
        !           616:                0x00000000L,0x10000000L,0x00010000L,0x10010000L,
        !           617:                0x00000004L,0x10000004L,0x00010004L,0x10010004L,
        !           618:                0x20000000L,0x30000000L,0x20010000L,0x30010000L,
        !           619:                0x20000004L,0x30000004L,0x20010004L,0x30010004L,
        !           620:                0x00100000L,0x10100000L,0x00110000L,0x10110000L,
        !           621:                0x00100004L,0x10100004L,0x00110004L,0x10110004L,
        !           622:                0x20100000L,0x30100000L,0x20110000L,0x30110000L,
        !           623:                0x20100004L,0x30100004L,0x20110004L,0x30110004L,
        !           624:                0x00001000L,0x10001000L,0x00011000L,0x10011000L,
        !           625:                0x00001004L,0x10001004L,0x00011004L,0x10011004L,
        !           626:                0x20001000L,0x30001000L,0x20011000L,0x30011000L,
        !           627:                0x20001004L,0x30001004L,0x20011004L,0x30011004L,
        !           628:                0x00101000L,0x10101000L,0x00111000L,0x10111000L,
        !           629:                0x00101004L,0x10101004L,0x00111004L,0x10111004L,
        !           630:                0x20101000L,0x30101000L,0x20111000L,0x30111000L,
        !           631:                0x20101004L,0x30101004L,0x20111004L,0x30111004L,
        !           632:        },
        !           633:        {       /* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */
        !           634:                0x00000000L,0x08000000L,0x00000008L,0x08000008L,
        !           635:                0x00000400L,0x08000400L,0x00000408L,0x08000408L,
        !           636:                0x00020000L,0x08020000L,0x00020008L,0x08020008L,
        !           637:                0x00020400L,0x08020400L,0x00020408L,0x08020408L,
        !           638:                0x00000001L,0x08000001L,0x00000009L,0x08000009L,
        !           639:                0x00000401L,0x08000401L,0x00000409L,0x08000409L,
        !           640:                0x00020001L,0x08020001L,0x00020009L,0x08020009L,
        !           641:                0x00020401L,0x08020401L,0x00020409L,0x08020409L,
        !           642:                0x02000000L,0x0A000000L,0x02000008L,0x0A000008L,
        !           643:                0x02000400L,0x0A000400L,0x02000408L,0x0A000408L,
        !           644:                0x02020000L,0x0A020000L,0x02020008L,0x0A020008L,
        !           645:                0x02020400L,0x0A020400L,0x02020408L,0x0A020408L,
        !           646:                0x02000001L,0x0A000001L,0x02000009L,0x0A000009L,
        !           647:                0x02000401L,0x0A000401L,0x02000409L,0x0A000409L,
        !           648:                0x02020001L,0x0A020001L,0x02020009L,0x0A020009L,
        !           649:                0x02020401L,0x0A020401L,0x02020409L,0x0A020409L,
        !           650:        },
        !           651:        {       /* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */
        !           652:                0x00000000L,0x00000100L,0x00080000L,0x00080100L,
        !           653:                0x01000000L,0x01000100L,0x01080000L,0x01080100L,
        !           654:                0x00000010L,0x00000110L,0x00080010L,0x00080110L,
        !           655:                0x01000010L,0x01000110L,0x01080010L,0x01080110L,
        !           656:                0x00200000L,0x00200100L,0x00280000L,0x00280100L,
        !           657:                0x01200000L,0x01200100L,0x01280000L,0x01280100L,
        !           658:                0x00200010L,0x00200110L,0x00280010L,0x00280110L,
        !           659:                0x01200010L,0x01200110L,0x01280010L,0x01280110L,
        !           660:                0x00000200L,0x00000300L,0x00080200L,0x00080300L,
        !           661:                0x01000200L,0x01000300L,0x01080200L,0x01080300L,
        !           662:                0x00000210L,0x00000310L,0x00080210L,0x00080310L,
        !           663:                0x01000210L,0x01000310L,0x01080210L,0x01080310L,
        !           664:                0x00200200L,0x00200300L,0x00280200L,0x00280300L,
        !           665:                0x01200200L,0x01200300L,0x01280200L,0x01280300L,
        !           666:                0x00200210L,0x00200310L,0x00280210L,0x00280310L,
        !           667:                0x01200210L,0x01200310L,0x01280210L,0x01280310L,
        !           668:        },
        !           669:        {       /* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */
        !           670:                0x00000000L,0x04000000L,0x00040000L,0x04040000L,
        !           671:                0x00000002L,0x04000002L,0x00040002L,0x04040002L,
        !           672:                0x00002000L,0x04002000L,0x00042000L,0x04042000L,
        !           673:                0x00002002L,0x04002002L,0x00042002L,0x04042002L,
        !           674:                0x00000020L,0x04000020L,0x00040020L,0x04040020L,
        !           675:                0x00000022L,0x04000022L,0x00040022L,0x04040022L,
        !           676:                0x00002020L,0x04002020L,0x00042020L,0x04042020L,
        !           677:                0x00002022L,0x04002022L,0x00042022L,0x04042022L,
        !           678:                0x00000800L,0x04000800L,0x00040800L,0x04040800L,
        !           679:                0x00000802L,0x04000802L,0x00040802L,0x04040802L,
        !           680:                0x00002800L,0x04002800L,0x00042800L,0x04042800L,
        !           681:                0x00002802L,0x04002802L,0x00042802L,0x04042802L,
        !           682:                0x00000820L,0x04000820L,0x00040820L,0x04040820L,
        !           683:                0x00000822L,0x04000822L,0x00040822L,0x04040822L,
        !           684:                0x00002820L,0x04002820L,0x00042820L,0x04042820L,
        !           685:                0x00002822L,0x04002822L,0x00042822L,0x04042822L,
        !           686:        }
        !           687: };
        !           688: 
        !           689: const DES_LONG des_SPtrans[8][64]={
        !           690:        {
        !           691:                /* nibble 0 */
        !           692:                0x02080800L, 0x00080000L, 0x02000002L, 0x02080802L,
        !           693:                0x02000000L, 0x00080802L, 0x00080002L, 0x02000002L,
        !           694:                0x00080802L, 0x02080800L, 0x02080000L, 0x00000802L,
        !           695:                0x02000802L, 0x02000000L, 0x00000000L, 0x00080002L,
        !           696:                0x00080000L, 0x00000002L, 0x02000800L, 0x00080800L,
        !           697:                0x02080802L, 0x02080000L, 0x00000802L, 0x02000800L,
        !           698:                0x00000002L, 0x00000800L, 0x00080800L, 0x02080002L,
        !           699:                0x00000800L, 0x02000802L, 0x02080002L, 0x00000000L,
        !           700:                0x00000000L, 0x02080802L, 0x02000800L, 0x00080002L,
        !           701:                0x02080800L, 0x00080000L, 0x00000802L, 0x02000800L,
        !           702:                0x02080002L, 0x00000800L, 0x00080800L, 0x02000002L,
        !           703:                0x00080802L, 0x00000002L, 0x02000002L, 0x02080000L,
        !           704:                0x02080802L, 0x00080800L, 0x02080000L, 0x02000802L,
        !           705:                0x02000000L, 0x00000802L, 0x00080002L, 0x00000000L,
        !           706:                0x00080000L, 0x02000000L, 0x02000802L, 0x02080800L,
        !           707:                0x00000002L, 0x02080002L, 0x00000800L, 0x00080802L,
        !           708:        },
        !           709:        {       /* nibble 1 */
        !           710:                0x40108010L, 0x00000000L, 0x00108000L, 0x40100000L,
        !           711:                0x40000010L, 0x00008010L, 0x40008000L, 0x00108000L,
        !           712:                0x00008000L, 0x40100010L, 0x00000010L, 0x40008000L,
        !           713:                0x00100010L, 0x40108000L, 0x40100000L, 0x00000010L,
        !           714:                0x00100000L, 0x40008010L, 0x40100010L, 0x00008000L,
        !           715:                0x00108010L, 0x40000000L, 0x00000000L, 0x00100010L,
        !           716:                0x40008010L, 0x00108010L, 0x40108000L, 0x40000010L,
        !           717:                0x40000000L, 0x00100000L, 0x00008010L, 0x40108010L,
        !           718:                0x00100010L, 0x40108000L, 0x40008000L, 0x00108010L,
        !           719:                0x40108010L, 0x00100010L, 0x40000010L, 0x00000000L,
        !           720:                0x40000000L, 0x00008010L, 0x00100000L, 0x40100010L,
        !           721:                0x00008000L, 0x40000000L, 0x00108010L, 0x40008010L,
        !           722:                0x40108000L, 0x00008000L, 0x00000000L, 0x40000010L,
        !           723:                0x00000010L, 0x40108010L, 0x00108000L, 0x40100000L,
        !           724:                0x40100010L, 0x00100000L, 0x00008010L, 0x40008000L,
        !           725:                0x40008010L, 0x00000010L, 0x40100000L, 0x00108000L,
        !           726:        },
        !           727:        {       /* nibble 2 */
        !           728:                0x04000001L, 0x04040100L, 0x00000100L, 0x04000101L,
        !           729:                0x00040001L, 0x04000000L, 0x04000101L, 0x00040100L,
        !           730:                0x04000100L, 0x00040000L, 0x04040000L, 0x00000001L,
        !           731:                0x04040101L, 0x00000101L, 0x00000001L, 0x04040001L,
        !           732:                0x00000000L, 0x00040001L, 0x04040100L, 0x00000100L,
        !           733:                0x00000101L, 0x04040101L, 0x00040000L, 0x04000001L,
        !           734:                0x04040001L, 0x04000100L, 0x00040101L, 0x04040000L,
        !           735:                0x00040100L, 0x00000000L, 0x04000000L, 0x00040101L,
        !           736:                0x04040100L, 0x00000100L, 0x00000001L, 0x00040000L,
        !           737:                0x00000101L, 0x00040001L, 0x04040000L, 0x04000101L,
        !           738:                0x00000000L, 0x04040100L, 0x00040100L, 0x04040001L,
        !           739:                0x00040001L, 0x04000000L, 0x04040101L, 0x00000001L,
        !           740:                0x00040101L, 0x04000001L, 0x04000000L, 0x04040101L,
        !           741:                0x00040000L, 0x04000100L, 0x04000101L, 0x00040100L,
        !           742:                0x04000100L, 0x00000000L, 0x04040001L, 0x00000101L,
        !           743:                0x04000001L, 0x00040101L, 0x00000100L, 0x04040000L,
        !           744:        },
        !           745:        {       /* nibble 3 */
        !           746:                0x00401008L, 0x10001000L, 0x00000008L, 0x10401008L,
        !           747:                0x00000000L, 0x10400000L, 0x10001008L, 0x00400008L,
        !           748:                0x10401000L, 0x10000008L, 0x10000000L, 0x00001008L,
        !           749:                0x10000008L, 0x00401008L, 0x00400000L, 0x10000000L,
        !           750:                0x10400008L, 0x00401000L, 0x00001000L, 0x00000008L,
        !           751:                0x00401000L, 0x10001008L, 0x10400000L, 0x00001000L,
        !           752:                0x00001008L, 0x00000000L, 0x00400008L, 0x10401000L,
        !           753:                0x10001000L, 0x10400008L, 0x10401008L, 0x00400000L,
        !           754:                0x10400008L, 0x00001008L, 0x00400000L, 0x10000008L,
        !           755:                0x00401000L, 0x10001000L, 0x00000008L, 0x10400000L,
        !           756:                0x10001008L, 0x00000000L, 0x00001000L, 0x00400008L,
        !           757:                0x00000000L, 0x10400008L, 0x10401000L, 0x00001000L,
        !           758:                0x10000000L, 0x10401008L, 0x00401008L, 0x00400000L,
        !           759:                0x10401008L, 0x00000008L, 0x10001000L, 0x00401008L,
        !           760:                0x00400008L, 0x00401000L, 0x10400000L, 0x10001008L,
        !           761:                0x00001008L, 0x10000000L, 0x10000008L, 0x10401000L,
        !           762:        },
        !           763:        {       /* nibble 4 */
        !           764:                0x08000000L, 0x00010000L, 0x00000400L, 0x08010420L,
        !           765:                0x08010020L, 0x08000400L, 0x00010420L, 0x08010000L,
        !           766:                0x00010000L, 0x00000020L, 0x08000020L, 0x00010400L,
        !           767:                0x08000420L, 0x08010020L, 0x08010400L, 0x00000000L,
        !           768:                0x00010400L, 0x08000000L, 0x00010020L, 0x00000420L,
        !           769:                0x08000400L, 0x00010420L, 0x00000000L, 0x08000020L,
        !           770:                0x00000020L, 0x08000420L, 0x08010420L, 0x00010020L,
        !           771:                0x08010000L, 0x00000400L, 0x00000420L, 0x08010400L,
        !           772:                0x08010400L, 0x08000420L, 0x00010020L, 0x08010000L,
        !           773:                0x00010000L, 0x00000020L, 0x08000020L, 0x08000400L,
        !           774:                0x08000000L, 0x00010400L, 0x08010420L, 0x00000000L,
        !           775:                0x00010420L, 0x08000000L, 0x00000400L, 0x00010020L,
        !           776:                0x08000420L, 0x00000400L, 0x00000000L, 0x08010420L,
        !           777:                0x08010020L, 0x08010400L, 0x00000420L, 0x00010000L,
        !           778:                0x00010400L, 0x08010020L, 0x08000400L, 0x00000420L,
        !           779:                0x00000020L, 0x00010420L, 0x08010000L, 0x08000020L,
        !           780:        },
        !           781:        {       /* nibble 5 */
        !           782:                0x80000040L, 0x00200040L, 0x00000000L, 0x80202000L,
        !           783:                0x00200040L, 0x00002000L, 0x80002040L, 0x00200000L,
        !           784:                0x00002040L, 0x80202040L, 0x00202000L, 0x80000000L,
        !           785:                0x80002000L, 0x80000040L, 0x80200000L, 0x00202040L,
        !           786:                0x00200000L, 0x80002040L, 0x80200040L, 0x00000000L,
        !           787:                0x00002000L, 0x00000040L, 0x80202000L, 0x80200040L,
        !           788:                0x80202040L, 0x80200000L, 0x80000000L, 0x00002040L,
        !           789:                0x00000040L, 0x00202000L, 0x00202040L, 0x80002000L,
        !           790:                0x00002040L, 0x80000000L, 0x80002000L, 0x00202040L,
        !           791:                0x80202000L, 0x00200040L, 0x00000000L, 0x80002000L,
        !           792:                0x80000000L, 0x00002000L, 0x80200040L, 0x00200000L,
        !           793:                0x00200040L, 0x80202040L, 0x00202000L, 0x00000040L,
        !           794:                0x80202040L, 0x00202000L, 0x00200000L, 0x80002040L,
        !           795:                0x80000040L, 0x80200000L, 0x00202040L, 0x00000000L,
        !           796:                0x00002000L, 0x80000040L, 0x80002040L, 0x80202000L,
        !           797:                0x80200000L, 0x00002040L, 0x00000040L, 0x80200040L,
        !           798:        },
        !           799:        {       /* nibble 6 */
        !           800:                0x00004000L, 0x00000200L, 0x01000200L, 0x01000004L,
        !           801:                0x01004204L, 0x00004004L, 0x00004200L, 0x00000000L,
        !           802:                0x01000000L, 0x01000204L, 0x00000204L, 0x01004000L,
        !           803:                0x00000004L, 0x01004200L, 0x01004000L, 0x00000204L,
        !           804:                0x01000204L, 0x00004000L, 0x00004004L, 0x01004204L,
        !           805:                0x00000000L, 0x01000200L, 0x01000004L, 0x00004200L,
        !           806:                0x01004004L, 0x00004204L, 0x01004200L, 0x00000004L,
        !           807:                0x00004204L, 0x01004004L, 0x00000200L, 0x01000000L,
        !           808:                0x00004204L, 0x01004000L, 0x01004004L, 0x00000204L,
        !           809:                0x00004000L, 0x00000200L, 0x01000000L, 0x01004004L,
        !           810:                0x01000204L, 0x00004204L, 0x00004200L, 0x00000000L,
        !           811:                0x00000200L, 0x01000004L, 0x00000004L, 0x01000200L,
        !           812:                0x00000000L, 0x01000204L, 0x01000200L, 0x00004200L,
        !           813:                0x00000204L, 0x00004000L, 0x01004204L, 0x01000000L,
        !           814:                0x01004200L, 0x00000004L, 0x00004004L, 0x01004204L,
        !           815:                0x01000004L, 0x01004200L, 0x01004000L, 0x00004004L,
        !           816:        },
        !           817:        {       /* nibble 7 */
        !           818:                0x20800080L, 0x20820000L, 0x00020080L, 0x00000000L,
        !           819:                0x20020000L, 0x00800080L, 0x20800000L, 0x20820080L,
        !           820:                0x00000080L, 0x20000000L, 0x00820000L, 0x00020080L,
        !           821:                0x00820080L, 0x20020080L, 0x20000080L, 0x20800000L,
        !           822:                0x00020000L, 0x00820080L, 0x00800080L, 0x20020000L,
        !           823:                0x20820080L, 0x20000080L, 0x00000000L, 0x00820000L,
        !           824:                0x20000000L, 0x00800000L, 0x20020080L, 0x20800080L,
        !           825:                0x00800000L, 0x00020000L, 0x20820000L, 0x00000080L,
        !           826:                0x00800000L, 0x00020000L, 0x20000080L, 0x20820080L,
        !           827:                0x00020080L, 0x20000000L, 0x00000000L, 0x00820000L,
        !           828:                0x20800080L, 0x20020080L, 0x20020000L, 0x00800080L,
        !           829:                0x20820000L, 0x00000080L, 0x00800080L, 0x20020000L,
        !           830:                0x20820080L, 0x00800000L, 0x20800000L, 0x20000080L,
        !           831:                0x00820000L, 0x00020080L, 0x20020080L, 0x20800000L,
        !           832:                0x00000080L, 0x20820000L, 0x00820080L, 0x00000000L,
        !           833:                0x20000000L, 0x20800080L, 0x00020000L, 0x00820080L,
        !           834:        }
        !           835: };
        !           836: 
        !           837: #define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
        !           838:        (a)=(a)^(t)^(t>>(16-(n))))
        !           839: 
        !           840: static const unsigned char odd_parity[256]={
        !           841:        1,  1,  2,  2,  4,  4,  7,  7,  8,  8, 11, 11, 13, 13, 14, 14,
        !           842:        16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31,
        !           843:        32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47,
        !           844:        49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62,
        !           845:        64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79,
        !           846:        81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94,
        !           847:        97, 97, 98, 98,100,100,103,103,104,104,107,107,109,109,110,110,
        !           848:        112,112,115,115,117,117,118,118,121,121,122,122,124,124,127,127,
        !           849:        128,128,131,131,133,133,134,134,137,137,138,138,140,140,143,143,
        !           850:        145,145,146,146,148,148,151,151,152,152,155,155,157,157,158,158,
        !           851:        161,161,162,162,164,164,167,167,168,168,171,171,173,173,174,174,
        !           852:        176,176,179,179,181,181,182,182,185,185,186,186,188,188,191,191,
        !           853:        193,193,194,194,196,196,199,199,200,200,203,203,205,205,206,206,
        !           854:        208,208,211,211,213,213,214,214,217,217,218,218,220,220,223,223,
        !           855:        224,224,227,227,229,229,230,230,233,233,234,234,236,236,239,239,
        !           856:        241,241,242,242,244,244,247,247,248,248,251,251,253,253,254,254
        !           857: };
        !           858: 
        !           859: /**
        !           860:  * Create key schedule for a single DES 64Bit key
        !           861:  */
        !           862: static int des_set_key(des_cblock *key, des_key_schedule *schedule)
        !           863: {
        !           864:        static int shifts2[16] = {0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0};
        !           865:        register DES_LONG c,d,t,s,t2;
        !           866:        register unsigned char *in;
        !           867:        register DES_LONG *k;
        !           868:        register int i;
        !           869:        des_cblock odd;
        !           870: 
        !           871:        for (i = 0; i < sizeof(des_cblock); i++)
        !           872:        {
        !           873:                odd[i] = odd_parity[(*key)[i]];
        !           874:        }
        !           875: 
        !           876:        k=(DES_LONG *)schedule;
        !           877:        in=(unsigned char *)&odd;
        !           878: 
        !           879:        c2l(in,c);
        !           880:        c2l(in,d);
        !           881: 
        !           882:        /* do PC1 in 60 simple operations */
        !           883: /*     PERM_OP(d,c,t,4,0x0f0f0f0fL);
        !           884:        HPERM_OP(c,t,-2, 0xcccc0000L);
        !           885:        HPERM_OP(c,t,-1, 0xaaaa0000L);
        !           886:        HPERM_OP(c,t, 8, 0x00ff0000L);
        !           887:        HPERM_OP(c,t,-1, 0xaaaa0000L);
        !           888:        HPERM_OP(d,t,-8, 0xff000000L);
        !           889:        HPERM_OP(d,t, 8, 0x00ff0000L);
        !           890:        HPERM_OP(d,t, 2, 0x33330000L);
        !           891:        d=((d&0x00aa00aaL)<<7L)|((d&0x55005500L)>>7L)|(d&0xaa55aa55L);
        !           892:        d=(d>>8)|((c&0xf0000000L)>>4);
        !           893:        c&=0x0fffffffL; */
        !           894: 
        !           895:        /* I now do it in 47 simple operations :-)
        !           896:        * Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
        !           897:        * for the inspiration. :-) */
        !           898:        PERM_OP (d,c,t,4,0x0f0f0f0fL);
        !           899:        HPERM_OP(c,t,-2,0xcccc0000L);
        !           900:        HPERM_OP(d,t,-2,0xcccc0000L);
        !           901:        PERM_OP (d,c,t,1,0x55555555L);
        !           902:        PERM_OP (c,d,t,8,0x00ff00ffL);
        !           903:        PERM_OP (d,c,t,1,0x55555555L);
        !           904:        d=      (((d&0x000000ffL)<<16L)| (d&0x0000ff00L)     |
        !           905:                        ((d&0x00ff0000L)>>16L)|((c&0xf0000000L)>>4L));
        !           906:        c&=0x0fffffffL;
        !           907: 
        !           908:        for (i=0; i<ITERATIONS; i++)
        !           909:        {
        !           910:                if (shifts2[i])
        !           911:                { c=((c>>2L)|(c<<26L)); d=((d>>2L)|(d<<26L)); }
        !           912:                else
        !           913:                { c=((c>>1L)|(c<<27L)); d=((d>>1L)|(d<<27L)); }
        !           914:                c&=0x0fffffffL;
        !           915:                d&=0x0fffffffL;
        !           916:                /* could be a few less shifts but I am to lazy at this
        !           917:                * point in time to investigate */
        !           918:                s=      des_skb[0][ (c    )&0x3f                ]|
        !           919:                                des_skb[1][((c>> 6)&0x03)|((c>> 7L)&0x3c)]|
        !           920:                                des_skb[2][((c>>13)&0x0f)|((c>>14L)&0x30)]|
        !           921:                                des_skb[3][((c>>20)&0x01)|((c>>21L)&0x06) |
        !           922:                                ((c>>22L)&0x38)];
        !           923:                t=      des_skb[4][ (d    )&0x3f                ]|
        !           924:                                des_skb[5][((d>> 7L)&0x03)|((d>> 8L)&0x3c)]|
        !           925:                                des_skb[6][ (d>>15L)&0x3f                ]|
        !           926:                                des_skb[7][((d>>21L)&0x0f)|((d>>22L)&0x30)];
        !           927: 
        !           928:                /* table contained 0213 4657 */
        !           929:                t2=((t<<16L)|(s&0x0000ffffL))&0xffffffffL;
        !           930:                *(k++)=ROTATE(t2,30)&0xffffffffL;
        !           931: 
        !           932:                t2=((s>>16L)|(t&0xffff0000L));
        !           933:                *(k++)=ROTATE(t2,26)&0xffffffffL;
        !           934:        }
        !           935:        return(0);
        !           936: }
        !           937: 
        !           938: 
        !           939: static void des_encrypt(DES_LONG *data, des_key_schedule ks, int enc)
        !           940: {
        !           941:        register DES_LONG l,r,t,u;
        !           942: #ifdef DES_PTR
        !           943:        register unsigned char *des_SP=(unsigned char *)des_SPtrans;
        !           944: #endif
        !           945: #ifndef DES_UNROLL
        !           946:        register int i;
        !           947: #endif
        !           948:        register DES_LONG *s;
        !           949: 
        !           950:        r=data[0];
        !           951:        l=data[1];
        !           952: 
        !           953:        IP(r,l);
        !           954:        /* Things have been modified so that the initial rotate is
        !           955:        * done outside the loop.  This required the
        !           956:        * des_SPtrans values in sp.h to be rotated 1 bit to the right.
        !           957:        * One perl script later and things have a 5% speed up on a sparc2.
        !           958:        * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
        !           959:        * for pointing this out. */
        !           960:        /* clear the top bits on machines with 8byte longs */
        !           961:        /* shift left by 2 */
        !           962:        r=ROTATE(r,29)&0xffffffffL;
        !           963:        l=ROTATE(l,29)&0xffffffffL;
        !           964: 
        !           965:        s=(DES_LONG *)ks;
        !           966:        /* I don't know if it is worth the effort of loop unrolling the
        !           967:        * inner loop */
        !           968:        if (enc)
        !           969:        {
        !           970: #ifdef DES_UNROLL
        !           971:                D_ENCRYPT(l,r, 0); /*  1 */
        !           972:                D_ENCRYPT(r,l, 2); /*  2 */
        !           973:                D_ENCRYPT(l,r, 4); /*  3 */
        !           974:                D_ENCRYPT(r,l, 6); /*  4 */
        !           975:                D_ENCRYPT(l,r, 8); /*  5 */
        !           976:                D_ENCRYPT(r,l,10); /*  6 */
        !           977:                D_ENCRYPT(l,r,12); /*  7 */
        !           978:                D_ENCRYPT(r,l,14); /*  8 */
        !           979:                D_ENCRYPT(l,r,16); /*  9 */
        !           980:                D_ENCRYPT(r,l,18); /*  10 */
        !           981:                D_ENCRYPT(l,r,20); /*  11 */
        !           982:                D_ENCRYPT(r,l,22); /*  12 */
        !           983:                D_ENCRYPT(l,r,24); /*  13 */
        !           984:                D_ENCRYPT(r,l,26); /*  14 */
        !           985:                D_ENCRYPT(l,r,28); /*  15 */
        !           986:                D_ENCRYPT(r,l,30); /*  16 */
        !           987: #else
        !           988:                for (i=0; i<32; i+=8)
        !           989: {
        !           990:        D_ENCRYPT(l,r,i+0); /*  1 */
        !           991:        D_ENCRYPT(r,l,i+2); /*  2 */
        !           992:        D_ENCRYPT(l,r,i+4); /*  3 */
        !           993:        D_ENCRYPT(r,l,i+6); /*  4 */
        !           994: }
        !           995: #endif
        !           996:        }
        !           997:        else
        !           998: {
        !           999: #ifdef DES_UNROLL
        !          1000:                D_ENCRYPT(l,r,30); /* 16 */
        !          1001:                D_ENCRYPT(r,l,28); /* 15 */
        !          1002:                D_ENCRYPT(l,r,26); /* 14 */
        !          1003:                D_ENCRYPT(r,l,24); /* 13 */
        !          1004:                D_ENCRYPT(l,r,22); /* 12 */
        !          1005:                D_ENCRYPT(r,l,20); /* 11 */
        !          1006:                D_ENCRYPT(l,r,18); /* 10 */
        !          1007:                D_ENCRYPT(r,l,16); /*  9 */
        !          1008:                D_ENCRYPT(l,r,14); /*  8 */
        !          1009:                D_ENCRYPT(r,l,12); /*  7 */
        !          1010:                D_ENCRYPT(l,r,10); /*  6 */
        !          1011:                D_ENCRYPT(r,l, 8); /*  5 */
        !          1012:                D_ENCRYPT(l,r, 6); /*  4 */
        !          1013:                D_ENCRYPT(r,l, 4); /*  3 */
        !          1014:                D_ENCRYPT(l,r, 2); /*  2 */
        !          1015:                D_ENCRYPT(r,l, 0); /*  1 */
        !          1016: #else
        !          1017:                for (i=30; i>0; i-=8)
        !          1018: {
        !          1019:        D_ENCRYPT(l,r,i-0); /* 16 */
        !          1020:        D_ENCRYPT(r,l,i-2); /* 15 */
        !          1021:        D_ENCRYPT(l,r,i-4); /* 14 */
        !          1022:        D_ENCRYPT(r,l,i-6); /* 13 */
        !          1023: }
        !          1024: #endif
        !          1025: }
        !          1026: 
        !          1027:        /* rotate and clear the top bits on machines with 8byte longs */
        !          1028:        l=ROTATE(l,3)&0xffffffffL;
        !          1029:        r=ROTATE(r,3)&0xffffffffL;
        !          1030: 
        !          1031:        FP(r,l);
        !          1032:        data[0]=l;
        !          1033:        data[1]=r;
        !          1034:        l=r=t=u=0;
        !          1035: }
        !          1036: 
        !          1037: /**
        !          1038:  * DES CBC encrypt decrypt routine
        !          1039:  */
        !          1040: static void des_cbc_encrypt(des_cblock *input, des_cblock *output, long length,
        !          1041:                                                    des_key_schedule schedule, des_cblock *ivec, int enc)
        !          1042: {
        !          1043:        register DES_LONG tin0,tin1;
        !          1044:        register DES_LONG tout0,tout1,xor0,xor1;
        !          1045:        register unsigned char *in,*out;
        !          1046:        register long l=length;
        !          1047:        DES_LONG tin[2];
        !          1048:        unsigned char *iv;
        !          1049: 
        !          1050:        in=(unsigned char *)input;
        !          1051:        out=(unsigned char *)output;
        !          1052:        iv=(unsigned char *)ivec;
        !          1053: 
        !          1054:        if (enc)
        !          1055:        {
        !          1056:                c2l(iv,tout0);
        !          1057:                c2l(iv,tout1);
        !          1058:                for (l-=8; l>=0; l-=8)
        !          1059:                {
        !          1060:                        c2l(in,tin0);
        !          1061:                        c2l(in,tin1);
        !          1062:                        tin0^=tout0; tin[0]=tin0;
        !          1063:                        tin1^=tout1; tin[1]=tin1;
        !          1064:                        des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
        !          1065:                        tout0=tin[0]; l2c(tout0,out);
        !          1066:                        tout1=tin[1]; l2c(tout1,out);
        !          1067:                }
        !          1068:                if (l != -8)
        !          1069:                {
        !          1070:                        c2ln(in,tin0,tin1,l+8);
        !          1071:                        tin0^=tout0; tin[0]=tin0;
        !          1072:                        tin1^=tout1; tin[1]=tin1;
        !          1073:                        des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
        !          1074:                        tout0=tin[0]; l2c(tout0,out);
        !          1075:                        tout1=tin[1]; l2c(tout1,out);
        !          1076:                }
        !          1077:        }
        !          1078:        else
        !          1079:        {
        !          1080:                c2l(iv,xor0);
        !          1081:                c2l(iv,xor1);
        !          1082:                for (l-=8; l>=0; l-=8)
        !          1083:                {
        !          1084:                        c2l(in,tin0); tin[0]=tin0;
        !          1085:                        c2l(in,tin1); tin[1]=tin1;
        !          1086:                        des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
        !          1087:                        tout0=tin[0]^xor0;
        !          1088:                        tout1=tin[1]^xor1;
        !          1089:                        l2c(tout0,out);
        !          1090:                        l2c(tout1,out);
        !          1091:                        xor0=tin0;
        !          1092:                        xor1=tin1;
        !          1093:                }
        !          1094:                if (l != -8)
        !          1095:                {
        !          1096:                        c2l(in,tin0); tin[0]=tin0;
        !          1097:                        c2l(in,tin1); tin[1]=tin1;
        !          1098:                        des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
        !          1099:                        tout0=tin[0]^xor0;
        !          1100:                        tout1=tin[1]^xor1;
        !          1101:                        l2cn(tout0,tout1,out,l+8);
        !          1102:                /*      xor0=tin0;
        !          1103:                        xor1=tin1; */
        !          1104:                }
        !          1105:        }
        !          1106:        tin0=tin1=tout0=tout1=xor0=xor1=0;
        !          1107:        tin[0]=tin[1]=0;
        !          1108: }
        !          1109: 
        !          1110: /**
        !          1111:  * DES ECB encrypt decrypt routine
        !          1112:  */
        !          1113: static void des_ecb_encrypt(des_cblock *input, des_cblock *output, long length,
        !          1114:                                                    des_key_schedule schedule, int enc)
        !          1115: {
        !          1116:        register DES_LONG tin0,tin1;
        !          1117:        register DES_LONG tout0,tout1;
        !          1118:        register unsigned char *in,*out;
        !          1119:        register long l=length;
        !          1120:        DES_LONG tin[2];
        !          1121: 
        !          1122:        in=(unsigned char *)input;
        !          1123:        out=(unsigned char *)output;
        !          1124: 
        !          1125:        if (enc)
        !          1126:        {
        !          1127:                for (l-=8; l>=0; l-=8)
        !          1128:                {
        !          1129:                        c2l(in,tin0); tin[0]=tin0;
        !          1130:                        c2l(in,tin1); tin[1]=tin1;
        !          1131:                        des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
        !          1132:                        tout0=tin[0]; l2c(tout0,out);
        !          1133:                        tout1=tin[1]; l2c(tout1,out);
        !          1134:                }
        !          1135:                if (l != -8)
        !          1136:                {
        !          1137:                        c2ln(in,tin0,tin1,l+8);
        !          1138:                        tin[0]=tin0;
        !          1139:                        tin[1]=tin1;
        !          1140:                        des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
        !          1141:                        tout0=tin[0]; l2c(tout0,out);
        !          1142:                        tout1=tin[1]; l2c(tout1,out);
        !          1143:                }
        !          1144:        }
        !          1145:        else
        !          1146:        {
        !          1147:                for (l-=8; l>=0; l-=8)
        !          1148:                {
        !          1149:                        c2l(in,tin0); tin[0]=tin0;
        !          1150:                        c2l(in,tin1); tin[1]=tin1;
        !          1151:                        des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
        !          1152:                        tout0=tin[0]; l2c(tout0,out);
        !          1153:                        tout1=tin[1]; l2c(tout1,out);
        !          1154:                }
        !          1155:                if (l != -8)
        !          1156:                {
        !          1157:                        c2l(in,tin0); tin[0]=tin0;
        !          1158:                        c2l(in,tin1); tin[1]=tin1;
        !          1159:                        des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
        !          1160:                        tout0=tin[0];
        !          1161:                        tout1=tin[1];
        !          1162:                        l2cn(tout0,tout1,out,l+8);
        !          1163:                }
        !          1164:        }
        !          1165:        tin0=tin1=tout0=tout1=0;
        !          1166:        tin[0]=tin[1]=0;
        !          1167: }
        !          1168: 
        !          1169: static void des_encrypt2(DES_LONG *data, des_key_schedule ks, int enc)
        !          1170: {
        !          1171:        register DES_LONG l,r,t,u;
        !          1172: #ifdef DES_PTR
        !          1173:        register unsigned char *des_SP=(unsigned char *)des_SPtrans;
        !          1174: #endif
        !          1175: #ifndef DES_UNROLL
        !          1176:        register int i;
        !          1177: #endif
        !          1178:        register DES_LONG *s;
        !          1179: 
        !          1180:        r=data[0];
        !          1181:        l=data[1];
        !          1182: 
        !          1183:        /* Things have been modified so that the initial rotate is
        !          1184:         * done outside the loop.  This required the
        !          1185:         * des_SPtrans values in sp.h to be rotated 1 bit to the right.
        !          1186:         * One perl script later and things have a 5% speed up on a sparc2.
        !          1187:         * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
        !          1188:         * for pointing this out.
        !          1189:         * clear the top bits on machines with 8byte longs */
        !          1190:        r=ROTATE(r,29)&0xffffffffL;
        !          1191:        l=ROTATE(l,29)&0xffffffffL;
        !          1192: 
        !          1193:        s=(DES_LONG *)ks;
        !          1194:        /* I don't know if it is worth the effort of loop unrolling the
        !          1195:        * inner loop */
        !          1196:        if (enc)
        !          1197:        {
        !          1198: #ifdef DES_UNROLL
        !          1199:                D_ENCRYPT(l,r, 0); /*  1 */
        !          1200:                D_ENCRYPT(r,l, 2); /*  2 */
        !          1201:                D_ENCRYPT(l,r, 4); /*  3 */
        !          1202:                D_ENCRYPT(r,l, 6); /*  4 */
        !          1203:                D_ENCRYPT(l,r, 8); /*  5 */
        !          1204:                D_ENCRYPT(r,l,10); /*  6 */
        !          1205:                D_ENCRYPT(l,r,12); /*  7 */
        !          1206:                D_ENCRYPT(r,l,14); /*  8 */
        !          1207:                D_ENCRYPT(l,r,16); /*  9 */
        !          1208:                D_ENCRYPT(r,l,18); /*  10 */
        !          1209:                D_ENCRYPT(l,r,20); /*  11 */
        !          1210:                D_ENCRYPT(r,l,22); /*  12 */
        !          1211:                D_ENCRYPT(l,r,24); /*  13 */
        !          1212:                D_ENCRYPT(r,l,26); /*  14 */
        !          1213:                D_ENCRYPT(l,r,28); /*  15 */
        !          1214:                D_ENCRYPT(r,l,30); /*  16 */
        !          1215: #else
        !          1216:                for (i=0; i<32; i+=8)
        !          1217: {
        !          1218:        D_ENCRYPT(l,r,i+0); /*  1 */
        !          1219:        D_ENCRYPT(r,l,i+2); /*  2 */
        !          1220:        D_ENCRYPT(l,r,i+4); /*  3 */
        !          1221:        D_ENCRYPT(r,l,i+6); /*  4 */
        !          1222: }
        !          1223: #endif
        !          1224:        }
        !          1225:        else
        !          1226: {
        !          1227: #ifdef DES_UNROLL
        !          1228:                D_ENCRYPT(l,r,30); /* 16 */
        !          1229:                D_ENCRYPT(r,l,28); /* 15 */
        !          1230:                D_ENCRYPT(l,r,26); /* 14 */
        !          1231:                D_ENCRYPT(r,l,24); /* 13 */
        !          1232:                D_ENCRYPT(l,r,22); /* 12 */
        !          1233:                D_ENCRYPT(r,l,20); /* 11 */
        !          1234:                D_ENCRYPT(l,r,18); /* 10 */
        !          1235:                D_ENCRYPT(r,l,16); /*  9 */
        !          1236:                D_ENCRYPT(l,r,14); /*  8 */
        !          1237:                D_ENCRYPT(r,l,12); /*  7 */
        !          1238:                D_ENCRYPT(l,r,10); /*  6 */
        !          1239:                D_ENCRYPT(r,l, 8); /*  5 */
        !          1240:                D_ENCRYPT(l,r, 6); /*  4 */
        !          1241:                D_ENCRYPT(r,l, 4); /*  3 */
        !          1242:                D_ENCRYPT(l,r, 2); /*  2 */
        !          1243:                D_ENCRYPT(r,l, 0); /*  1 */
        !          1244: #else
        !          1245:                for (i=30; i>0; i-=8)
        !          1246: {
        !          1247:        D_ENCRYPT(l,r,i-0); /* 16 */
        !          1248:        D_ENCRYPT(r,l,i-2); /* 15 */
        !          1249:        D_ENCRYPT(l,r,i-4); /* 14 */
        !          1250:        D_ENCRYPT(r,l,i-6); /* 13 */
        !          1251: }
        !          1252: #endif
        !          1253: }
        !          1254:        /* rotate and clear the top bits on machines with 8byte longs */
        !          1255:        data[0]=ROTATE(l,3)&0xffffffffL;
        !          1256:        data[1]=ROTATE(r,3)&0xffffffffL;
        !          1257:        l=r=t=u=0;
        !          1258: }
        !          1259: 
        !          1260: /**
        !          1261:  * Single block 3DES EDE encrypt routine
        !          1262:  */
        !          1263: static void des_encrypt3(DES_LONG *data, des_key_schedule ks1,
        !          1264:                                                 des_key_schedule ks2, des_key_schedule ks3)
        !          1265: {
        !          1266:        register DES_LONG l,r;
        !          1267: 
        !          1268:        l=data[0];
        !          1269:        r=data[1];
        !          1270:        IP(l,r);
        !          1271:        data[0]=l;
        !          1272:        data[1]=r;
        !          1273:        des_encrypt2((DES_LONG *)data,ks1,DES_ENCRYPT);
        !          1274:        des_encrypt2((DES_LONG *)data,ks2,DES_DECRYPT);
        !          1275:        des_encrypt2((DES_LONG *)data,ks3,DES_ENCRYPT);
        !          1276:        l=data[0];
        !          1277:        r=data[1];
        !          1278:        FP(r,l);
        !          1279:        data[0]=l;
        !          1280:        data[1]=r;
        !          1281: }
        !          1282: 
        !          1283: /**
        !          1284:  * Single block 3DES EDE decrypt routine
        !          1285:  */
        !          1286: static void des_decrypt3(DES_LONG *data, des_key_schedule ks1,
        !          1287:                                                 des_key_schedule ks2, des_key_schedule ks3)
        !          1288: {
        !          1289:        register DES_LONG l,r;
        !          1290: 
        !          1291:        l=data[0];
        !          1292:        r=data[1];
        !          1293:        IP(l,r);
        !          1294:        data[0]=l;
        !          1295:        data[1]=r;
        !          1296:        des_encrypt2((DES_LONG *)data,ks3,DES_DECRYPT);
        !          1297:        des_encrypt2((DES_LONG *)data,ks2,DES_ENCRYPT);
        !          1298:        des_encrypt2((DES_LONG *)data,ks1,DES_DECRYPT);
        !          1299:        l=data[0];
        !          1300:        r=data[1];
        !          1301:        FP(r,l);
        !          1302:        data[0]=l;
        !          1303:        data[1]=r;
        !          1304: }
        !          1305: 
        !          1306: /**
        !          1307:  * 3DES EDE CBC encrypt/decrypt routine
        !          1308:  */
        !          1309: static void des_ede3_cbc_encrypt(des_cblock *input, des_cblock *output, long length,
        !          1310:                                                                 des_key_schedule ks1, des_key_schedule ks2,
        !          1311:                                                                 des_key_schedule ks3, des_cblock *ivec, int enc)
        !          1312: {
        !          1313:        register DES_LONG tin0,tin1;
        !          1314:        register DES_LONG tout0,tout1,xor0,xor1;
        !          1315:        register unsigned char *in,*out;
        !          1316:        register long l=length;
        !          1317:        DES_LONG tin[2];
        !          1318:        unsigned char *iv;
        !          1319: 
        !          1320:        in=(unsigned char *)input;
        !          1321:        out=(unsigned char *)output;
        !          1322:        iv=(unsigned char *)ivec;
        !          1323: 
        !          1324:        if (enc)
        !          1325:        {
        !          1326:                c2l(iv,tout0);
        !          1327:                c2l(iv,tout1);
        !          1328:                for (l-=8; l>=0; l-=8)
        !          1329:                {
        !          1330:                        c2l(in,tin0);
        !          1331:                        c2l(in,tin1);
        !          1332:                        tin0^=tout0;
        !          1333:                        tin1^=tout1;
        !          1334: 
        !          1335:                        tin[0]=tin0;
        !          1336:                        tin[1]=tin1;
        !          1337:                        des_encrypt3((DES_LONG *)tin,ks1,ks2,ks3);
        !          1338:                        tout0=tin[0];
        !          1339:                        tout1=tin[1];
        !          1340: 
        !          1341:                        l2c(tout0,out);
        !          1342:                        l2c(tout1,out);
        !          1343:                }
        !          1344:                if (l != -8)
        !          1345:                {
        !          1346:                        c2ln(in,tin0,tin1,l+8);
        !          1347:                        tin0^=tout0;
        !          1348:                        tin1^=tout1;
        !          1349: 
        !          1350:                        tin[0]=tin0;
        !          1351:                        tin[1]=tin1;
        !          1352:                        des_encrypt3((DES_LONG *)tin,ks1,ks2,ks3);
        !          1353:                        tout0=tin[0];
        !          1354:                        tout1=tin[1];
        !          1355: 
        !          1356:                        l2c(tout0,out);
        !          1357:                        l2c(tout1,out);
        !          1358:                }
        !          1359:                iv=(unsigned char *)ivec;
        !          1360:                l2c(tout0,iv);
        !          1361:                l2c(tout1,iv);
        !          1362:        }
        !          1363:        else
        !          1364:        {
        !          1365:                register DES_LONG t0,t1;
        !          1366: 
        !          1367:                c2l(iv,xor0);
        !          1368:                c2l(iv,xor1);
        !          1369:                for (l-=8; l>=0; l-=8)
        !          1370:                {
        !          1371:                        c2l(in,tin0);
        !          1372:                        c2l(in,tin1);
        !          1373: 
        !          1374:                        t0=tin0;
        !          1375:                        t1=tin1;
        !          1376: 
        !          1377:                        tin[0]=tin0;
        !          1378:                        tin[1]=tin1;
        !          1379:                        des_decrypt3((DES_LONG *)tin,ks1,ks2,ks3);
        !          1380:                        tout0=tin[0];
        !          1381:                        tout1=tin[1];
        !          1382: 
        !          1383:                        tout0^=xor0;
        !          1384:                        tout1^=xor1;
        !          1385:                        l2c(tout0,out);
        !          1386:                        l2c(tout1,out);
        !          1387:                        xor0=t0;
        !          1388:                        xor1=t1;
        !          1389:                }
        !          1390:                if (l != -8)
        !          1391:                {
        !          1392:                        c2l(in,tin0);
        !          1393:                        c2l(in,tin1);
        !          1394: 
        !          1395:                        t0=tin0;
        !          1396:                        t1=tin1;
        !          1397: 
        !          1398:                        tin[0]=tin0;
        !          1399:                        tin[1]=tin1;
        !          1400:                        des_decrypt3((DES_LONG *)tin,ks1,ks2,ks3);
        !          1401:                        tout0=tin[0];
        !          1402:                        tout1=tin[1];
        !          1403: 
        !          1404:                        tout0^=xor0;
        !          1405:                        tout1^=xor1;
        !          1406:                        l2cn(tout0,tout1,out,l+8);
        !          1407:                        xor0=t0;
        !          1408:                        xor1=t1;
        !          1409:                }
        !          1410: 
        !          1411:                iv=(unsigned char *)ivec;
        !          1412:                l2c(xor0,iv);
        !          1413:                l2c(xor1,iv);
        !          1414:        }
        !          1415:        tin0=tin1=tout0=tout1=xor0=xor1=0;
        !          1416:        tin[0]=tin[1]=0;
        !          1417: }
        !          1418: 
        !          1419: METHOD(crypter_t, decrypt, bool,
        !          1420:        private_des_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *decrypted)
        !          1421: {
        !          1422:        des_cblock ivb;
        !          1423:        uint8_t *out;
        !          1424: 
        !          1425:        out = data.ptr;
        !          1426:        if (decrypted)
        !          1427:        {
        !          1428:                *decrypted = chunk_alloc(data.len);
        !          1429:                out = decrypted->ptr;
        !          1430:        }
        !          1431:        memcpy(&ivb, iv.ptr, sizeof(des_cblock));
        !          1432:        des_cbc_encrypt((des_cblock*)(data.ptr), (des_cblock*)out,
        !          1433:                                         data.len, this->ks, &ivb, DES_DECRYPT);
        !          1434:        return TRUE;
        !          1435: }
        !          1436: 
        !          1437: 
        !          1438: METHOD(crypter_t, encrypt, bool,
        !          1439:        private_des_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *encrypted)
        !          1440: {
        !          1441:        des_cblock ivb;
        !          1442:        uint8_t *out;
        !          1443: 
        !          1444:        out = data.ptr;
        !          1445:        if (encrypted)
        !          1446:        {
        !          1447:                *encrypted = chunk_alloc(data.len);
        !          1448:                out = encrypted->ptr;
        !          1449:        }
        !          1450:        memcpy(&ivb, iv.ptr, sizeof(des_cblock));
        !          1451:        des_cbc_encrypt((des_cblock*)(data.ptr), (des_cblock*)out,
        !          1452:                                         data.len, this->ks, &ivb, DES_ENCRYPT);
        !          1453:        return TRUE;
        !          1454: }
        !          1455: 
        !          1456: METHOD(crypter_t, decrypt_ecb, bool,
        !          1457:        private_des_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *decrypted)
        !          1458: {
        !          1459:        uint8_t *out;
        !          1460: 
        !          1461:        out = data.ptr;
        !          1462:        if (decrypted)
        !          1463:        {
        !          1464:                *decrypted = chunk_alloc(data.len);
        !          1465:                out = decrypted->ptr;
        !          1466:        }
        !          1467:        des_ecb_encrypt((des_cblock*)(data.ptr), (des_cblock*)out,
        !          1468:                                         data.len, this->ks, DES_DECRYPT);
        !          1469:        return TRUE;
        !          1470: }
        !          1471: 
        !          1472: METHOD(crypter_t, encrypt_ecb, bool,
        !          1473:        private_des_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *encrypted)
        !          1474: {
        !          1475:        uint8_t *out;
        !          1476: 
        !          1477:        out = data.ptr;
        !          1478:        if (encrypted)
        !          1479:        {
        !          1480:                *encrypted = chunk_alloc(data.len);
        !          1481:                out = encrypted->ptr;
        !          1482:        }
        !          1483:        des_ecb_encrypt((des_cblock*)(data.ptr), (des_cblock*)out,
        !          1484:                                         data.len, this->ks, DES_ENCRYPT);
        !          1485:        return TRUE;
        !          1486: }
        !          1487: 
        !          1488: METHOD(crypter_t, decrypt3, bool,
        !          1489:        private_des_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *decrypted)
        !          1490: {
        !          1491:        des_cblock ivb;
        !          1492:        uint8_t *out;
        !          1493: 
        !          1494:        out = data.ptr;
        !          1495:        if (decrypted)
        !          1496:        {
        !          1497:                *decrypted = chunk_alloc(data.len);
        !          1498:                out = decrypted->ptr;
        !          1499:        }
        !          1500:        memcpy(&ivb, iv.ptr, sizeof(des_cblock));
        !          1501:        des_ede3_cbc_encrypt((des_cblock*)(data.ptr), (des_cblock*)out,
        !          1502:                                                 data.len, this->ks3[0], this->ks3[1], this->ks3[2],
        !          1503:                                                 &ivb, DES_DECRYPT);
        !          1504:        return TRUE;
        !          1505: }
        !          1506: 
        !          1507: METHOD(crypter_t, encrypt3, bool,
        !          1508:        private_des_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *encrypted)
        !          1509: {
        !          1510:        des_cblock ivb;
        !          1511:        uint8_t *out;
        !          1512: 
        !          1513:        out = data.ptr;
        !          1514:        if (encrypted)
        !          1515:        {
        !          1516:                *encrypted = chunk_alloc(data.len);
        !          1517:                out = encrypted->ptr;
        !          1518:        }
        !          1519:        memcpy(&ivb, iv.ptr, sizeof(des_cblock));
        !          1520:        des_ede3_cbc_encrypt((des_cblock*)(data.ptr), (des_cblock*)out,
        !          1521:                                                  data.len, this->ks3[0], this->ks3[1], this->ks3[2],
        !          1522:                                                  &ivb, DES_ENCRYPT);
        !          1523:        return TRUE;
        !          1524: }
        !          1525: 
        !          1526: METHOD(crypter_t, get_block_size, size_t,
        !          1527:        private_des_crypter_t *this)
        !          1528: {
        !          1529:        return sizeof(des_cblock);
        !          1530: }
        !          1531: 
        !          1532: METHOD(crypter_t, get_iv_size, size_t,
        !          1533:        private_des_crypter_t *this)
        !          1534: {
        !          1535:        return sizeof(des_cblock);
        !          1536: }
        !          1537: 
        !          1538: METHOD(crypter_t, get_key_size, size_t,
        !          1539:        private_des_crypter_t *this)
        !          1540: {
        !          1541:        return this->key_size;
        !          1542: }
        !          1543: 
        !          1544: METHOD(crypter_t, set_key, bool,
        !          1545:        private_des_crypter_t *this, chunk_t key)
        !          1546: {
        !          1547:        des_set_key((des_cblock*)(key.ptr), &this->ks);
        !          1548:        return TRUE;
        !          1549: }
        !          1550: 
        !          1551: METHOD(crypter_t, set_key3, bool,
        !          1552:        private_des_crypter_t *this, chunk_t key)
        !          1553: {
        !          1554:        des_set_key((des_cblock*)(key.ptr) + 0, &this->ks3[0]);
        !          1555:        des_set_key((des_cblock*)(key.ptr) + 1, &this->ks3[1]);
        !          1556:        des_set_key((des_cblock*)(key.ptr) + 2, &this->ks3[2]);
        !          1557:        return TRUE;
        !          1558: }
        !          1559: 
        !          1560: METHOD(crypter_t, destroy, void,
        !          1561:        private_des_crypter_t *this)
        !          1562: {
        !          1563:        memwipe(this, sizeof(*this));
        !          1564:        free(this);
        !          1565: }
        !          1566: 
        !          1567: /*
        !          1568:  * Described in header
        !          1569:  */
        !          1570: des_crypter_t *des_crypter_create(encryption_algorithm_t algo)
        !          1571: {
        !          1572:        private_des_crypter_t *this;
        !          1573: 
        !          1574:        INIT(this,
        !          1575:                .public = {
        !          1576:                        .crypter = {
        !          1577:                                .get_block_size = _get_block_size,
        !          1578:                                .get_iv_size = _get_iv_size,
        !          1579:                                .get_key_size = _get_key_size,
        !          1580:                                .destroy = _destroy,
        !          1581:                        },
        !          1582:                },
        !          1583:        );
        !          1584: 
        !          1585:        /* use functions depending on algorithm */
        !          1586:        switch (algo)
        !          1587:        {
        !          1588:                case ENCR_DES:
        !          1589:                        this->key_size = sizeof(des_cblock);
        !          1590:                        this->public.crypter.set_key = _set_key;
        !          1591:                        this->public.crypter.encrypt = _encrypt;
        !          1592:                        this->public.crypter.decrypt = _decrypt;
        !          1593:                        break;
        !          1594:                case ENCR_3DES:
        !          1595:                        this->key_size = 3 * sizeof(des_cblock);
        !          1596:                        this->public.crypter.set_key = _set_key3;
        !          1597:                        this->public.crypter.encrypt = _encrypt3;
        !          1598:                        this->public.crypter.decrypt = _decrypt3;
        !          1599:                        break;
        !          1600:                case ENCR_DES_ECB:
        !          1601:                        this->key_size = sizeof(des_cblock);
        !          1602:                        this->public.crypter.set_key = _set_key;
        !          1603:                        this->public.crypter.encrypt = _encrypt_ecb;
        !          1604:                        this->public.crypter.decrypt = _decrypt_ecb;
        !          1605:                        break;
        !          1606:                default:
        !          1607:                        free(this);
        !          1608:                        return NULL;
        !          1609:        }
        !          1610:        return &this->public;
        !          1611: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>