1/* MD4C.C - RSA Data Security, Inc., MD4 message-digest algorithm
2 */
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/cdefs.h>
27__FBSDID("$FreeBSD$");
28
29#include <sys/param.h>
30#include <sys/systm.h>
31#include <sys/md4.h>
32
33typedef unsigned char *POINTER;
34typedef u_int16_t UINT2;
35typedef u_int32_t UINT4;
36
37#define PROTO_LIST(list) list
38
39/* Constants for MD4Transform routine.
40 */
41#define S11 3
42#define S12 7
43#define S13 11
44#define S14 19
45#define S21 3
46#define S22 5
47#define S23 9
48#define S24 13
49#define S31 3
50#define S32 9
51#define S33 11
52#define S34 15
53
54static void MD4Transform PROTO_LIST ((UINT4 [4], const unsigned char [64]));
55static void Encode PROTO_LIST
56  ((unsigned char *, UINT4 *, unsigned int));
57static void Decode PROTO_LIST
58  ((UINT4 *, const unsigned char *, unsigned int));
59
60static unsigned char PADDING[64] = {
61  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
62  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
63  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
64};
65
66/* F, G and H are basic MD4 functions.
67 */
68#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
69#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
70#define H(x, y, z) ((x) ^ (y) ^ (z))
71
72/* ROTATE_LEFT rotates x left n bits.
73 */
74#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
75
76/* FF, GG and HH are transformations for rounds 1, 2 and 3 */
77/* Rotation is separate from addition to prevent recomputation */
78#define FF(a, b, c, d, x, s) { \
79    (a) += F ((b), (c), (d)) + (x); \
80    (a) = ROTATE_LEFT ((a), (s)); \
81  }
82#define GG(a, b, c, d, x, s) { \
83    (a) += G ((b), (c), (d)) + (x) + (UINT4)0x5a827999; \
84    (a) = ROTATE_LEFT ((a), (s)); \
85  }
86#define HH(a, b, c, d, x, s) { \
87    (a) += H ((b), (c), (d)) + (x) + (UINT4)0x6ed9eba1; \
88    (a) = ROTATE_LEFT ((a), (s)); \
89  }
90
91/* MD4 initialization. Begins an MD4 operation, writing a new context.
92 */
93void MD4Init (context)
94MD4_CTX *context;                                        /* context */
95{
96  context->count[0] = context->count[1] = 0;
97
98  /* Load magic initialization constants.
99   */
100  context->state[0] = 0x67452301;
101  context->state[1] = 0xefcdab89;
102  context->state[2] = 0x98badcfe;
103  context->state[3] = 0x10325476;
104}
105
106/* MD4 block update operation. Continues an MD4 message-digest
107     operation, processing another message block, and updating the
108     context.
109 */
110void MD4Update (context, input, inputLen)
111MD4_CTX *context;                                        /* context */
112const unsigned char *input;                                /* input block */
113unsigned int inputLen;                     /* length of input block */
114{
115  unsigned int i, index, partLen;
116
117  /* Compute number of bytes mod 64 */
118  index = (unsigned int)((context->count[0] >> 3) & 0x3F);
119  /* Update number of bits */
120  if ((context->count[0] += ((UINT4)inputLen << 3))
121      < ((UINT4)inputLen << 3))
122    context->count[1]++;
123  context->count[1] += ((UINT4)inputLen >> 29);
124
125  partLen = 64 - index;
126  /* Transform as many times as possible.
127   */
128  if (inputLen >= partLen) {
129    bcopy(input, &context->buffer[index], partLen);
130    MD4Transform (context->state, context->buffer);
131
132    for (i = partLen; i + 63 < inputLen; i += 64)
133      MD4Transform (context->state, &input[i]);
134
135    index = 0;
136  }
137  else
138    i = 0;
139
140  /* Buffer remaining input */
141  bcopy(&input[i], &context->buffer[index], 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  bzero((POINTER)context, 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  bzero((POINTER)x, 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