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