|
|
1.1 ! root 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: ! 208: static unsigned short vaxtohs(x) ! 209: char *x; ! 210: { ! 211: unsigned short val; ! 212: bcopy(x, (char *)&val, sizeof(val)); ! 213: return(val); ! 214: } ! 215: #endif /* MUSTALIGN */ ! 216: #endif /* LSBFIRST */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.