]> asedeno.scripts.mit.edu Git - 1ts-debian.git/blob - zephyr/lib/quad_cksum.c
tag a copy before we start messing with ZNotice_t
[1ts-debian.git] / zephyr / lib / quad_cksum.c
1 /* Lifted from the krb5 1.6 source tree and hacked slightly to fit in here
2    Karl Ramm 12/21/08 */
3 /*
4  * lib/des425/quad_cksum.c
5  *
6  * Copyright 1985, 1986, 1987, 1988,1990 by the Massachusetts Institute
7  * of Technology.
8  * All Rights Reserved.
9  *
10  * Export of this software from the United States of America may
11  *   require a specific license from the United States Government.
12  *   It is the responsibility of any person or organization contemplating
13  *   export to obtain such a license before exporting.
14  * 
15  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
16  * distribute this software and its documentation for any purpose and
17  * without fee is hereby granted, provided that the above copyright
18  * notice appear in all copies and that both that copyright notice and
19  * this permission notice appear in supporting documentation, and that
20  * the name of M.I.T. not be used in advertising or publicity pertaining
21  * to distribution of the software without specific, written prior
22  * permission.  Furthermore if you modify this software you must label
23  * your software as modified software and not distribute it in such a
24  * fashion that it might be confused with the original M.I.T. software.
25  * M.I.T. makes no representations about the suitability of
26  * this software for any purpose.  It is provided "as is" without express
27  * or implied warranty.
28  *
29  *
30  * This routine does not implement:
31  *
32  *
33  * Quadratic Congruential Manipulation Dectection Code
34  *
35  * ref: "Message Authentication"
36  *              R.R. Jueneman, S. M. Matyas, C.H. Meyer
37  *              IEEE Communications Magazine,
38  *              Sept 1985 Vol 23 No 9 p 29-40
39  *
40  * This routine, part of the Athena DES library built for the Kerberos
41  * authentication system, calculates a manipulation detection code for
42  * a message.  It is a much faster alternative to the DES-checksum
43  * method. No guarantees are offered for its security.
44  *
45  * Implementation for 4.2bsd
46  * by S.P. Miller       Project Athena/MIT
47  */
48
49 /*
50  * Algorithm (per paper):
51  *              define:
52  *              message to be composed of n m-bit blocks X1,...,Xn
53  *              optional secret seed S in block X1
54  *              MDC in block Xn+1
55  *              prime modulus N
56  *              accumulator Z
57  *              initial (secret) value of accumulator C
58  *              N, C, and S are known at both ends
59  *              C and , optionally, S, are hidden from the end users
60  *              then
61  *                      (read array references as subscripts over time)
62  *                      Z[0] = c;
63  *                      for i = 1...n
64  *                              Z[i] = (Z[i+1] + X[i])**2 modulo N
65  *                      X[n+1] = Z[n] = MDC
66  *
67  *              Then pick
68  *                      N = 2**31 -1
69  *                      m = 16
70  *                      iterate 4 times over plaintext, also use Zn
71  *                      from iteration j as seed for iteration j+1,
72  *                      total MDC is then a 128 bit array of the four
73  *                      Zn;
74  *
75  *                      return the last Zn and optionally, all
76  *                      four as output args.
77  *
78  * Modifications:
79  *      To inhibit brute force searches of the seed space, this
80  *      implementation is modified to have
81  *      Z       = 64 bit accumulator
82  *      C       = 64 bit C seed
83  *      N       = 2**63 - 1
84  *  S   = S seed is not implemented here
85  *      arithmetic is not quite real double integer precision, since we
86  *      cant get at the carry or high order results from multiply,
87  *      but nontheless is 64 bit arithmetic.
88  */
89 /*
90  * This code purports to implement the above algorithm, but fails.
91  *
92  * First of all, there was an implicit mod 2**32 being done on the
93  * machines where this was developed because of their word sizes, and
94  * for compabitility this has to be done on machines with 64-bit
95  * words, so we make it explicit.
96  *
97  * Second, in the squaring operation, I really doubt the carry-over
98  * from the low 31-bit half of the accumulator is being done right,
99  * and using a modulus of 0x7fffffff on the low half of the
100  * accumulator seems completely wrong.  And I challenge anyone to
101  * explain where the number 83653421 comes from.
102  *
103  * --Ken Raeburn  2001-04-06
104  */
105
106
107 /* System include files */
108 #include <stdio.h>
109 #include <errno.h>
110
111 #include <internal.h>
112
113 /* Definitions for byte swapping */
114
115 /* vax byte order is LSB first. This is not performance critical, and
116    is far more readable this way. */
117 #define four_bytes_vax_to_nets(x) ((((((x[3]<<8)|x[2])<<8)|x[1])<<8)|x[0])
118 #define vaxtohl(x) four_bytes_vax_to_nets(((const unsigned char *)(x)))
119 #define two_bytes_vax_to_nets(x) ((x[1]<<8)|x[0])
120 #define vaxtohs(x) two_bytes_vax_to_nets(((const unsigned char *)(x)))
121
122 /*** Routines ***************************************************** */
123 #ifdef HAVE_KRB5
124 unsigned long
125 z_quad_cksum(const unsigned char *in,   /* input block */
126              krb5_ui_4 *out,            /* optional longer output */
127              long length,               /* original length in bytes */
128              int out_count,             /* number of iterations */
129              unsigned char *c_seed      /* secret seed, 8 bytes */
130              )
131 {
132
133     /*
134      * this routine both returns the low order of the final (last in
135      * time) 32bits of the checksum, and if "out" is not a null
136      * pointer, a longer version, up to entire 32 bytes of the
137      * checksum is written unto the address pointed to.
138      */
139
140     register krb5_ui_4 z;
141     register krb5_ui_4 z2;
142     register krb5_ui_4 x;
143     register krb5_ui_4 x2;
144     const unsigned char *p;
145     register krb5_int32 len;
146     register int i;
147
148     /* use all 8 bytes of seed */
149
150     z = vaxtohl(c_seed);
151     z2 = vaxtohl((const char *)c_seed+4);
152     if (out == NULL)
153         out_count = 1;          /* default */
154
155     /* This is repeated n times!! */
156     for (i = 1; i <=4 && i<= out_count; i++) {
157         len = length;
158         p = in;
159         while (len) {
160             /*
161              * X = Z + Input ... sort of.  Carry out from low half
162              * isn't done, so we're using all 32 bits of x now.
163              */
164             if (len > 1) {
165                 x = (z + vaxtohs(p));
166                 p += 2;
167                 len -= 2;
168             }
169             else {
170                 x = (z + *(const unsigned char *)p++);
171                 len = 0;
172             }
173             x2 = z2;
174             /*
175              * I think this is supposed to be a squaring operation.
176              * What it really is, I haven't figured out yet.
177              *
178              * Explicit mod 2**32 is for backwards compatibility.  Why
179              * mod 0x7fffffff and not 0x80000000 on the low half of
180              * the (supposed) accumulator?  And where does the number
181              * 83653421 come from??
182              */
183             z  = (((x * x) + (x2 * x2)) & 0xffffffff) % 0x7fffffff;
184             z2 = ((x * (x2+83653421)) & 0xffffffff) % 0x7fffffff; /* modulo */
185         }
186
187         if (out != NULL) {
188             *out++ = z;
189             *out++ = z2;
190         }
191     }
192     /* return final z value as 32 bit version of checksum */
193     return z;
194 }
195 #endif