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>