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