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