Release bumped to "gts4".
[tac_plus.git] / md4.c
1 /*
2    Copyright (c) 1995-1998 by Cisco systems, Inc.
3
4    Permission to use, copy, modify, and distribute this software for
5    any purpose and without fee is hereby granted, provided that this
6    copyright and permission notice appear on all copies of the
7    software and supporting documentation, the name of Cisco Systems,
8    Inc. not be used in advertising or publicity pertaining to
9    distribution of the program without specific prior permission, and
10    notice be given in supporting documentation that modification,
11    copying and distribution is by permission of Cisco Systems, Inc.
12
13    Cisco Systems, Inc. makes no representations about the suitability
14    of this software for any purpose.  THIS SOFTWARE IS PROVIDED ``AS
15    IS'' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
16    WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
17    FITNESS FOR A PARTICULAR PURPOSE.
18 */
19
20 /* MD4C.C - RSA Data Security, Inc., MD4 message-digest algorithm
21  * $Id$
22  */
23
24 /* Copyright (C) 1990-2, RSA Data Security, Inc. All rights reserved.
25
26    License to copy and use this software is granted provided that it
27    is identified as the "RSA Data Security, Inc. MD4 Message-Digest
28    Algorithm" in all material mentioning or referencing this software
29    or this function.
30
31    License is also granted to make and use derivative works provided
32    that such works are identified as "derived from the RSA Data
33    Security, Inc. MD4 Message-Digest Algorithm" in all material
34    mentioning or referencing the derived work.
35
36    RSA Data Security, Inc. makes no representations concerning either
37    the merchantability of this software or the suitability of this
38    software for any particular purpose. It is provided "as is"
39    without express or implied warranty of any kind.
40
41    These notices must be retained in any copies of any part of this
42    documentation and/or software.
43  */
44
45
46 #include "tac_plus.h"
47
48 #ifdef MSCHAP
49
50 #include <string.h>
51
52 #include "md4.h"
53 /*
54 #include "master.h"
55 #include <ciscolib.h>
56 */
57
58
59 typedef unsigned char *POINTER;
60 typedef unsigned short int UINT2;
61 typedef unsigned long int UINT4;
62
63 static void MD4Transform TAC_ARGS((UINT4 state[4], const unsigned char block[64]));
64 static void Encode TAC_ARGS((unsigned char *output, UINT4 *input, unsigned int len));
65 static void Decode TAC_ARGS((UINT4 *output, const unsigned char *input, unsigned int len));
66
67
68 /* Constants for MD4Transform routine.
69  */
70 #define S11 3
71 #define S12 7
72 #define S13 11
73 #define S14 19
74 #define S21 3
75 #define S22 5
76 #define S23 9
77 #define S24 13
78 #define S31 3
79 #define S32 9
80 #define S33 11
81 #define S34 15
82
83 static unsigned char PADDING[64] = {
84   0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
85   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
86   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
87 };
88
89 /* F, G and H are basic MD4 functions.
90  */
91 #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
92 #define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
93 #define H(x, y, z) ((x) ^ (y) ^ (z))
94
95 /* ROTATE_LEFT rotates x left n bits.
96  */
97 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
98
99 /* FF, GG and HH are transformations for rounds 1, 2 and 3 */
100 /* Rotation is separate from addition to prevent recomputation */
101 #define FF(a, b, c, d, x, s) { \
102     (a) += F ((b), (c), (d)) + (x); \
103     (a) = ROTATE_LEFT ((a), (s)); \
104   }
105 #define GG(a, b, c, d, x, s) { \
106     (a) += G ((b), (c), (d)) + (x) + (UINT4)0x5a827999; \
107     (a) = ROTATE_LEFT ((a), (s)); \
108   }
109 #define HH(a, b, c, d, x, s) { \
110     (a) += H ((b), (c), (d)) + (x) + (UINT4)0x6ed9eba1; \
111     (a) = ROTATE_LEFT ((a), (s)); \
112   }
113
114 /* MD4 initialization. Begins an MD4 operation, writing a new context.
115  */
116
117 void MD4Init TAC_ARGS((MD4_CTX *context));
118
119 void MD4Init (context)
120 MD4_CTX *context;                                        /* context */
121 {
122   context->count[0] = context->count[1] = 0;
123
124   /* Load magic initialization constants.
125    */
126   context->state[0] = 0x67452301;
127   context->state[1] = 0xefcdab89;
128   context->state[2] = 0x98badcfe;
129   context->state[3] = 0x10325476;
130 }
131
132 /* MD4 block update operation. Continues an MD4 message-digest
133      operation, processing another message block, and updating the
134      context.
135  */
136
137 void MD4Update TAC_ARGS((MD4_CTX *context, const unsigned char *input, unsigned int inputLen));
138
139 void MD4Update (context, input, inputLen)
140 MD4_CTX *context;                                        /* context */
141 const unsigned char *input;                                /* input block */
142 unsigned int inputLen;                     /* length of input block */
143 {
144   unsigned int i, index, partLen;
145
146   /* Compute number of bytes mod 64 */
147   index = (unsigned int)((context->count[0] >> 3) & 0x3F);
148   /* Update number of bits */
149   if ((context->count[0] += ((UINT4)inputLen << 3))
150       < ((UINT4)inputLen << 3))
151     context->count[1]++;
152   context->count[1] += ((UINT4)inputLen >> 29);
153
154   partLen = 64 - index;
155   /* Transform as many times as possible.
156    */
157   if (inputLen >= partLen) {
158     memcpy
159       ((POINTER)&context->buffer[index], (POINTER)input, partLen);
160     MD4Transform (context->state, context->buffer);
161
162     for (i = partLen; i + 63 < inputLen; i += 64)
163       MD4Transform (context->state, &input[i]);
164
165     index = 0;
166   }
167   else
168     i = 0;
169
170   /* Buffer remaining input */
171   memcpy
172     ((POINTER)&context->buffer[index], (POINTER)&input[i],
173      inputLen-i);
174 }
175
176 /* MD4 finalization. Ends an MD4 message-digest operation, writing the
177      the message digest and zeroizing the context.
178  */
179
180 void MD4Final TAC_ARGS((unsigned char digest[16], MD4_CTX *context));
181
182 void MD4Final (digest, context)
183 unsigned char digest[16];                         /* message digest */
184 MD4_CTX *context;                                        /* context */
185 {
186   unsigned char bits[8];
187   unsigned int index, padLen;
188
189   /* Save number of bits */
190   Encode (bits, context->count, 8);
191
192   /* Pad out to 56 mod 64.
193    */
194   index = (unsigned int)((context->count[0] >> 3) & 0x3f);
195   padLen = (index < 56) ? (56 - index) : (120 - index);
196   MD4Update (context, PADDING, padLen);
197
198   /* Append length (before padding) */
199   MD4Update (context, bits, 8);
200   /* Store state in digest */
201   Encode (digest, context->state, 16);
202
203   /* Zeroize sensitive information.
204    */
205   memset ((POINTER)context, 0, sizeof (*context));
206 }
207
208 /* MD4 basic transformation. Transforms state based on block.
209  */
210
211 static void MD4Transform TAC_ARGS((UINT4 state[4], const unsigned char block[64]));
212
213 static void MD4Transform (state, block)
214 UINT4 state[4];
215 const unsigned char block[64];
216 {
217   UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
218
219   Decode (x, block, 64);
220
221   /* Round 1 */
222   FF (a, b, c, d, x[ 0], S11); /* 1 */
223   FF (d, a, b, c, x[ 1], S12); /* 2 */
224   FF (c, d, a, b, x[ 2], S13); /* 3 */
225   FF (b, c, d, a, x[ 3], S14); /* 4 */
226   FF (a, b, c, d, x[ 4], S11); /* 5 */
227   FF (d, a, b, c, x[ 5], S12); /* 6 */
228   FF (c, d, a, b, x[ 6], S13); /* 7 */
229   FF (b, c, d, a, x[ 7], S14); /* 8 */
230   FF (a, b, c, d, x[ 8], S11); /* 9 */
231   FF (d, a, b, c, x[ 9], S12); /* 10 */
232   FF (c, d, a, b, x[10], S13); /* 11 */
233   FF (b, c, d, a, x[11], S14); /* 12 */
234   FF (a, b, c, d, x[12], S11); /* 13 */
235   FF (d, a, b, c, x[13], S12); /* 14 */
236   FF (c, d, a, b, x[14], S13); /* 15 */
237   FF (b, c, d, a, x[15], S14); /* 16 */
238
239   /* Round 2 */
240   GG (a, b, c, d, x[ 0], S21); /* 17 */
241   GG (d, a, b, c, x[ 4], S22); /* 18 */
242   GG (c, d, a, b, x[ 8], S23); /* 19 */
243   GG (b, c, d, a, x[12], S24); /* 20 */
244   GG (a, b, c, d, x[ 1], S21); /* 21 */
245   GG (d, a, b, c, x[ 5], S22); /* 22 */
246   GG (c, d, a, b, x[ 9], S23); /* 23 */
247   GG (b, c, d, a, x[13], S24); /* 24 */
248   GG (a, b, c, d, x[ 2], S21); /* 25 */
249   GG (d, a, b, c, x[ 6], S22); /* 26 */
250   GG (c, d, a, b, x[10], S23); /* 27 */
251   GG (b, c, d, a, x[14], S24); /* 28 */
252   GG (a, b, c, d, x[ 3], S21); /* 29 */
253   GG (d, a, b, c, x[ 7], S22); /* 30 */
254   GG (c, d, a, b, x[11], S23); /* 31 */
255   GG (b, c, d, a, x[15], S24); /* 32 */
256
257   /* Round 3 */
258   HH (a, b, c, d, x[ 0], S31); /* 33 */
259   HH (d, a, b, c, x[ 8], S32); /* 34 */
260   HH (c, d, a, b, x[ 4], S33); /* 35 */
261   HH (b, c, d, a, x[12], S34); /* 36 */
262   HH (a, b, c, d, x[ 2], S31); /* 37 */
263   HH (d, a, b, c, x[10], S32); /* 38 */
264   HH (c, d, a, b, x[ 6], S33); /* 39 */
265   HH (b, c, d, a, x[14], S34); /* 40 */
266   HH (a, b, c, d, x[ 1], S31); /* 41 */
267   HH (d, a, b, c, x[ 9], S32); /* 42 */
268   HH (c, d, a, b, x[ 5], S33); /* 43 */
269   HH (b, c, d, a, x[13], S34); /* 44 */
270   HH (a, b, c, d, x[ 3], S31); /* 45 */
271   HH (d, a, b, c, x[11], S32); /* 46 */
272   HH (c, d, a, b, x[ 7], S33); /* 47 */
273   HH (b, c, d, a, x[15], S34); /* 48 */
274
275   state[0] += a;
276   state[1] += b;
277   state[2] += c;
278   state[3] += d;
279
280   /* Zeroize sensitive information.
281    */
282   memset ((POINTER)x, 0, sizeof (x));
283 }
284
285 /* Encodes input (UINT4) into output (unsigned char). Assumes len is
286      a multiple of 4.
287  */
288
289 static void Encode TAC_ARGS((unsigned char *output, UINT4 *input, unsigned int len));
290
291 static void Encode (output, input, len)
292 unsigned char *output;
293 UINT4 *input;
294 unsigned int len;
295 {
296   unsigned int i, j;
297
298   for (i = 0, j = 0; j < len; i++, j += 4) {
299     output[j] = (unsigned char)(input[i] & 0xff);
300     output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
301     output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
302     output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
303   }
304 }
305
306 /* Decodes input (unsigned char) into output (UINT4). Assumes len is
307      a multiple of 4.
308  */
309
310 static void Decode TAC_ARGS((UINT4 *output, const unsigned char *input, unsigned int len));
311
312 static void Decode (output, input, len)
313 UINT4 *output;
314 const unsigned char *input;
315 unsigned int len;
316 {
317   unsigned int i, j;
318
319   for (i = 0, j = 0; j < len; i++, j += 4)
320     output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
321       (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
322 }
323
324 #else /* MSCHAP */
325
326 TAC_SOURCEFILE_EMPTY
327
328 #endif /* MSCHAP */