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

  1. /*
  2.  * $Source: /afs/athena.mit.edu/astaff/project/kerberos/src/lib/des/RCS/quad_cksum.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.  * Quadratic Congruential Manipulation Dectection Code
  12.  *
  13.  * ref: "Message Authentication"
  14.  *        R.R. Jueneman, S. M. Matyas, C.H. Meyer
  15.  *        IEEE Communications Magazine,
  16.  *        Sept 1985 Vol 23 No 9 p 29-40
  17.  *
  18.  * This routine, part of the Athena DES library built for the Kerberos
  19.  * authentication system, calculates a manipulation detection code for
  20.  * a message.  It is a much faster alternative to the DES-checksum
  21.  * method. No guarantees are offered for its security.    Refer to the
  22.  * paper noted above for more information
  23.  *
  24.  * Implementation for 4.2bsd
  25.  * by S.P. Miller    Project Athena/MIT
  26.  */
  27.  
  28. /*
  29.  * Algorithm (per paper):
  30.  *        define:
  31.  *        message to be composed of n m-bit blocks X1,...,Xn
  32.  *        optional secret seed S in block X1
  33.  *        MDC in block Xn+1
  34.  *        prime modulus N
  35.  *        accumulator Z
  36.  *        initial (secret) value of accumulator C
  37.  *        N, C, and S are known at both ends
  38.  *        C and , optionally, S, are hidden from the end users
  39.  *        then
  40.  *            (read array references as subscripts over time)
  41.  *            Z[0] = c;
  42.  *            for i = 1...n
  43.  *                Z[i] = (Z[i+1] + X[i])**2 modulo N
  44.  *            X[n+1] = Z[n] = MDC
  45.  *
  46.  *        Then pick
  47.  *            N = 2**31 -1
  48.  *            m = 16
  49.  *            iterate 4 times over plaintext, also use Zn
  50.  *            from iteration j as seed for iteration j+1,
  51.  *            total MDC is then a 128 bit array of the four
  52.  *            Zn;
  53.  *
  54.  *            return the last Zn and optionally, all
  55.  *            four as output args.
  56.  *
  57.  * Modifications:
  58.  *    To inhibit brute force searches of the seed space, this
  59.  *    implementation is modified to have
  60.  *    Z    = 64 bit accumulator
  61.  *    C    = 64 bit C seed
  62.  *    N    = 2**63 - 1
  63.  *  S    = S seed is not implemented here
  64.  *    arithmetic is not quite real double integer precision, since we
  65.  *    cant get at the carry or high order results from multiply,
  66.  *    but nontheless is 64 bit arithmetic.
  67.  */
  68.  
  69. #ifndef    lint
  70. static char rcsid_quad_cksum_c[] =
  71. "$Id: quad_cksum.c,v 4.13 90/01/02 13:46:34 jtkohl Exp $";
  72. #endif    lint
  73.  
  74. #include <mit-copyright.h>
  75.  
  76. /* System include files */
  77. #include <stdio.h>
  78. #include <errno.h>
  79.  
  80. /* Application include files */
  81. #include <des.h>
  82. #include "des_internal.h"
  83. /* Definitions for byte swapping */
  84.  
  85. #ifdef LSBFIRST
  86. #ifdef MUSTALIGN
  87. static unsigned long vaxtohl();
  88. static unsigned short vaxtohs();
  89. #else /* ! MUSTALIGN */
  90. #define vaxtohl(x) *((unsigned long *)(x))
  91. #define vaxtohs(x) *((unsigned short *)(x))
  92. #endif /* MUSTALIGN */
  93. #else /* !LSBFIRST */
  94. static unsigned long four_bytes_vax_to_nets();
  95. #define vaxtohl(x) four_bytes_vax_to_nets((char *)(x))
  96. static unsigned short two_bytes_vax_to_nets();
  97. #define vaxtohs(x) two_bytes_vax_to_nets((char *)(x))
  98. #endif
  99.  
  100. /* Externals */
  101. extern char *errmsg();
  102. extern int errno;
  103. extern int des_debug;
  104.  
  105. /*** Routines ***************************************************** */
  106.  
  107. unsigned long
  108. des_quad_cksum(in,out,length,out_count,c_seed)
  109.     des_cblock *c_seed;        /* secret seed, 8 bytes */
  110.     unsigned char *in;        /* input block */
  111.     unsigned long *out;        /* optional longer output */
  112.     int out_count;        /* number of iterations */
  113.     long length;        /* original length in bytes */
  114. {
  115.  
  116.     /*
  117.      * this routine both returns the low order of the final (last in
  118.      * time) 32bits of the checksum, and if "out" is not a null
  119.      * pointer, a longer version, up to entire 32 bytes of the
  120.      * checksum is written unto the address pointed to.
  121.      */
  122.  
  123.     register unsigned long z;
  124.     register unsigned long z2;
  125.     register unsigned long x;
  126.     register unsigned long x2;
  127.     register unsigned char *p;
  128.     register long len;
  129.     register int i;
  130.  
  131.     /* use all 8 bytes of seed */
  132.  
  133.     z = vaxtohl(c_seed);
  134.     z2 = vaxtohl((char *)c_seed+4);
  135.     if (out == NULL)
  136.     out_count = 1;        /* default */
  137.  
  138.     /* This is repeated n times!! */
  139.     for (i = 1; i <=4 && i<= out_count; i++) {
  140.     len = length;
  141.     p = in;
  142.     while (len) {
  143.         if (len > 1) {
  144.         x = (z + vaxtohs(p));
  145.         p += 2;
  146.         len -= 2;
  147.         }
  148.         else {
  149.         x = (z + *(char *)p++);
  150.         len = 0;
  151.         }
  152.         x2 = z2;
  153.         z  = ((x * x) + (x2 * x2)) % 0x7fffffff;
  154.         z2 = (x * (x2+83653421))   % 0x7fffffff; /* modulo */
  155.         if (des_debug & 8)
  156.         printf("%d %d\n",z,z2);
  157.     }
  158.  
  159.     if (out != NULL) {
  160.         *out++ = z;
  161.         *out++ = z2;
  162.     }
  163.     }
  164.     /* return final z value as 32 bit version of checksum */
  165.     return z;
  166. }
  167. #ifdef MSBFIRST
  168.  
  169. static unsigned short two_bytes_vax_to_nets(p)
  170.     char *p;
  171. {
  172.     union {
  173.     char pieces[2];
  174.     unsigned short result;
  175.     } short_conv;
  176.  
  177.     short_conv.pieces[0] = p[1];
  178.     short_conv.pieces[1] = p[0];
  179.     return(short_conv.result);
  180. }
  181.  
  182. static unsigned long four_bytes_vax_to_nets(p)
  183.     char *p;
  184. {
  185.     static union {
  186.     char pieces[4];
  187.     unsigned long result;
  188.     } long_conv;
  189.  
  190.     long_conv.pieces[0] = p[3];
  191.     long_conv.pieces[1] = p[2];
  192.     long_conv.pieces[2] = p[1];
  193.     long_conv.pieces[3] = p[0];
  194.     return(long_conv.result);
  195. }
  196.  
  197. #endif
  198. #ifdef LSBFIRST
  199. #ifdef MUSTALIGN
  200. static unsigned long vaxtohl(x)
  201. char *x;
  202. {
  203.     unsigned long val;
  204.     bcopy(x, (char *)&val, sizeof(val));
  205.     return(val);
  206.  
  207. static unsigned short vaxtohs(x)
  208. char *x;
  209. {
  210.     unsigned short val;
  211.     bcopy(x, (char *)&val, sizeof(val));
  212.     return(val);
  213. #endif /* MUSTALIGN */
  214. #endif /* LSBFIRST */
  215.