2 Copyright (c) 1995-1998 by Cisco systems, Inc.
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.
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.
20 /* MD4C.C - RSA Data Security, Inc., MD4 message-digest algorithm
24 /* Copyright (C) 1990-2, RSA Data Security, Inc. All rights reserved.
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
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.
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.
41 These notices must be retained in any copies of any part of this
42 documentation and/or software.
59 typedef unsigned char *POINTER;
60 typedef unsigned short int UINT2;
61 typedef unsigned long int UINT4;
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));
68 /* Constants for MD4Transform routine.
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
89 /* F, G and H are basic MD4 functions.
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))
95 /* ROTATE_LEFT rotates x left n bits.
97 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
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)); \
105 #define GG(a, b, c, d, x, s) { \
106 (a) += G ((b), (c), (d)) + (x) + (UINT4)0x5a827999; \
107 (a) = ROTATE_LEFT ((a), (s)); \
109 #define HH(a, b, c, d, x, s) { \
110 (a) += H ((b), (c), (d)) + (x) + (UINT4)0x6ed9eba1; \
111 (a) = ROTATE_LEFT ((a), (s)); \
114 /* MD4 initialization. Begins an MD4 operation, writing a new context.
117 void MD4Init TAC_ARGS((MD4_CTX *context));
119 void MD4Init (context)
120 MD4_CTX *context; /* context */
122 context->count[0] = context->count[1] = 0;
124 /* Load magic initialization constants.
126 context->state[0] = 0x67452301;
127 context->state[1] = 0xefcdab89;
128 context->state[2] = 0x98badcfe;
129 context->state[3] = 0x10325476;
132 /* MD4 block update operation. Continues an MD4 message-digest
133 operation, processing another message block, and updating the
137 void MD4Update TAC_ARGS((MD4_CTX *context, const unsigned char *input, unsigned int inputLen));
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 */
144 unsigned int i, index, partLen;
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))
152 context->count[1] += ((UINT4)inputLen >> 29);
154 partLen = 64 - index;
155 /* Transform as many times as possible.
157 if (inputLen >= partLen) {
159 ((POINTER)&context->buffer[index], (POINTER)input, partLen);
160 MD4Transform (context->state, context->buffer);
162 for (i = partLen; i + 63 < inputLen; i += 64)
163 MD4Transform (context->state, &input[i]);
170 /* Buffer remaining input */
172 ((POINTER)&context->buffer[index], (POINTER)&input[i],
176 /* MD4 finalization. Ends an MD4 message-digest operation, writing the
177 the message digest and zeroizing the context.
180 void MD4Final TAC_ARGS((unsigned char digest[16], MD4_CTX *context));
182 void MD4Final (digest, context)
183 unsigned char digest[16]; /* message digest */
184 MD4_CTX *context; /* context */
186 unsigned char bits[8];
187 unsigned int index, padLen;
189 /* Save number of bits */
190 Encode (bits, context->count, 8);
192 /* Pad out to 56 mod 64.
194 index = (unsigned int)((context->count[0] >> 3) & 0x3f);
195 padLen = (index < 56) ? (56 - index) : (120 - index);
196 MD4Update (context, PADDING, padLen);
198 /* Append length (before padding) */
199 MD4Update (context, bits, 8);
200 /* Store state in digest */
201 Encode (digest, context->state, 16);
203 /* Zeroize sensitive information.
205 memset ((POINTER)context, 0, sizeof (*context));
208 /* MD4 basic transformation. Transforms state based on block.
211 static void MD4Transform TAC_ARGS((UINT4 state[4], const unsigned char block[64]));
213 static void MD4Transform (state, block)
215 const unsigned char block[64];
217 UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
219 Decode (x, block, 64);
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 */
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 */
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 */
280 /* Zeroize sensitive information.
282 memset ((POINTER)x, 0, sizeof (x));
285 /* Encodes input (UINT4) into output (unsigned char). Assumes len is
289 static void Encode TAC_ARGS((unsigned char *output, UINT4 *input, unsigned int len));
291 static void Encode (output, input, len)
292 unsigned char *output;
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);
306 /* Decodes input (unsigned char) into output (UINT4). Assumes len is
310 static void Decode TAC_ARGS((UINT4 *output, const unsigned char *input, unsigned int len));
312 static void Decode (output, input, len)
314 const unsigned char *input;
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);