home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / kerberosIV / des / cbc_encrypt.c next >
Encoding:
C/C++ Source or Header  |  1990-01-02  |  5.4 KB  |  212 lines

  1. /*
  2.  * $Source: /afs/athena.mit.edu/astaff/project/kerberos/src/lib/des/RCS/cbc_encrypt.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.  * These routines form the library interface to the DES facilities.
  19.  *
  20.  * Originally written 8/85 by Steve Miller, MIT Project Athena.
  21.  */
  22.  
  23. #ifndef    lint
  24. static char rcsid_cbc_encrypt_c[] =
  25. "$Id: cbc_encrypt.c,v 4.10 90/01/02 13:46:14 jtkohl Exp $";
  26. #endif    lint
  27.  
  28. #include <mit-copyright.h>
  29. #include <stdio.h>
  30. #include <des.h>
  31.  
  32. extern int des_debug;
  33. extern int des_debug_print();
  34.  
  35. /*
  36.  * This routine performs DES cipher-block-chaining operation, either
  37.  * encrypting from cleartext to ciphertext, if encrypt != 0 or
  38.  * decrypting from ciphertext to cleartext, if encrypt == 0.
  39.  *
  40.  * The key schedule is passed as an arg, as well as the cleartext or
  41.  * ciphertext.    The cleartext and ciphertext should be in host order.
  42.  *
  43.  * NOTE-- the output is ALWAYS an multiple of 8 bytes long.  If not
  44.  * enough space was provided, your program will get trashed.
  45.  *
  46.  * For encryption, the cleartext string is null padded, at the end, to
  47.  * an integral multiple of eight bytes.
  48.  *
  49.  * For decryption, the ciphertext will be used in integral multiples
  50.  * of 8 bytes, but only the first "length" bytes returned into the
  51.  * cleartext.
  52.  */
  53.  
  54. int
  55. des_cbc_encrypt(in,out,length,key,iv,encrypt)
  56.     des_cblock *in;        /* >= length bytes of input text */
  57.     des_cblock *out;        /* >= length bytes of output text */
  58.     register long length;    /* in bytes */
  59.     int encrypt;        /* 0 ==> decrypt, else encrypt */
  60.     des_key_schedule key;        /* precomputed key schedule */
  61.     des_cblock *iv;        /* 8 bytes of ivec */
  62. {
  63.     register unsigned long *input = (unsigned long *) in;
  64.     register unsigned long *output = (unsigned long *) out;
  65.     register unsigned long *ivec = (unsigned long *) iv;
  66.  
  67.     unsigned long i,j;
  68.     static unsigned long t_input[2];
  69.     static unsigned long t_output[2];
  70.     static unsigned char *t_in_p;
  71.     static unsigned long xor_0, xor_1;
  72.  
  73.     t_in_p = (unsigned char *) t_input;
  74.     if (encrypt) {
  75. #ifdef MUSTALIGN
  76.     if ((long) ivec & 3) {
  77.         bcopy((char *)ivec++, (char *)&t_output[0], sizeof(t_output[0]));
  78.         bcopy((char *)ivec, (char *)&t_output[1], sizeof(t_output[1]));
  79.     }
  80.     else
  81. #endif
  82.     {
  83.         t_output[0] = *ivec++;
  84.         t_output[1] = *ivec;
  85.     }
  86.  
  87.     for (i = 0; length > 0; i++, length -= 8) {
  88.         /* get input */
  89. #ifdef MUSTALIGN
  90.         if ((long) input & 3) {
  91.         bcopy((char *)input++,(char *)&t_input[0],sizeof(t_input[0]));
  92.         bcopy((char *)input++,(char *)&t_input[1],sizeof(t_input[1]));
  93.         }
  94.         else
  95. #endif
  96.         {
  97.         t_input[0] = *input++;
  98.         t_input[1] = *input++;
  99.         }
  100.  
  101.         /* zero pad */
  102.         if (length < 8)
  103.         for (j = length; j <= 7; j++)
  104.             *(t_in_p+j)= 0;
  105.  
  106. #ifdef DEBUG
  107.         if (des_debug)
  108.         des_debug_print("clear",length,t_input[0],t_input[1]);
  109. #endif
  110.         /* do the xor for cbc into the temp */
  111.         t_input[0] ^= t_output[0];
  112.         t_input[1] ^= t_output[1];
  113.         /* encrypt */
  114.         (void) des_ecb_encrypt(t_input,t_output,key,encrypt);
  115.         /* copy temp output and save it for cbc */
  116. #ifdef MUSTALIGN
  117.         if ((long) output & 3) {
  118.         bcopy((char *)&t_output[0],(char *)output++,
  119.               sizeof(t_output[0]));
  120.         bcopy((char *)&t_output[1],(char *)output++,
  121.               sizeof(t_output[1]));
  122.         }
  123.         else
  124. #endif
  125.         {
  126.         *output++ = t_output[0];
  127.         *output++ = t_output[1];
  128.         }
  129.  
  130. #ifdef DEBUG
  131.         if (des_debug) {
  132.         des_debug_print("xor'ed",i,t_input[0],t_input[1]);
  133.         des_debug_print("cipher",i,t_output[0],t_output[1]);
  134.         }
  135. #endif
  136.     }
  137.     return 0;
  138.     }
  139.  
  140.     else {
  141.     /* decrypt */
  142. #ifdef MUSTALIGN
  143.     if ((long) ivec & 3) {
  144.         bcopy((char *)ivec++,(char *)&xor_0,sizeof(xor_0));
  145.         bcopy((char *)ivec,(char *)&xor_1,sizeof(xor_1));
  146.     }
  147.     else
  148. #endif
  149.     {
  150.         xor_0 = *ivec++;
  151.         xor_1 = *ivec;
  152.     }
  153.  
  154.     for (i = 0; length > 0; i++, length -= 8) {
  155.         /* get input */
  156. #ifdef MUSTALIGN
  157.         if ((long) input & 3) {
  158.         bcopy((char *)input++,(char *)&t_input[0],sizeof(t_input[0]));
  159.         bcopy((char *)input++,(char *)&t_input[1],sizeof(t_input[0]));
  160.         }
  161.         else
  162. #endif
  163.         {
  164.         t_input[0] = *input++;
  165.         t_input[1] = *input++;
  166.         }
  167.  
  168.         /* no padding for decrypt */
  169. #ifdef DEBUG
  170.         if (des_debug)
  171.         des_debug_print("cipher",i,t_input[0],t_input[1]);
  172. #else
  173. #ifdef lint
  174.         i = i;
  175. #endif
  176. #endif
  177.         /* encrypt */
  178.         (void) des_ecb_encrypt(t_input,t_output,key,encrypt);
  179. #ifdef DEBUG
  180.         if (des_debug)
  181.         des_debug_print("out pre xor",i,t_output[0],t_output[1]);
  182. #endif
  183.         /* do the xor for cbc into the output */
  184.         t_output[0] ^= xor_0;
  185.         t_output[1] ^= xor_1;
  186.         /* copy temp output */
  187. #ifdef MUSTALIGN
  188.         if ((long) output & 3) {
  189.         bcopy((char *)&t_output[0],(char *)output++,
  190.               sizeof(t_output[0]));
  191.         bcopy((char *)&t_output[1],(char *)output++,
  192.               sizeof(t_output[1]));
  193.         }
  194.         else
  195. #endif
  196.         {
  197.         *output++ = t_output[0];
  198.         *output++ = t_output[1];
  199.         }
  200.  
  201.         /* save xor value for next round */
  202.         xor_0 = t_input[0];
  203.         xor_1 = t_input[1];
  204. #ifdef DEBUG
  205.         if (des_debug)
  206.         des_debug_print("clear",i,t_output[0],t_output[1]);
  207. #endif
  208.     }
  209.     return 0;
  210.     }
  211. }
  212.