home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / kerberosIV / des / des.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-01-21  |  10.6 KB  |  459 lines

  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.  
  459.