1/* MD4C.C - RSA Data Security, Inc., MD4 message-digest algorithm
2 */
3
4#include <sys/cdefs.h>
5__FBSDID("$FreeBSD$");
6
7/* Copyright (C) 1990-2, RSA Data Security, Inc. All rights reserved.
8
9   License to copy and use this software is granted provided that it
10   is identified as the "RSA Data Security, Inc. MD4 Message-Digest
11   Algorithm" in all material mentioning or referencing this software
12   or this function.
13
14   License is also granted to make and use derivative works provided
15   that such works are identified as "derived from the RSA Data
16   Security, Inc. MD4 Message-Digest Algorithm" in all material
17   mentioning or referencing the derived work.
18
19   RSA Data Security, Inc. makes no representations concerning either
20   the merchantability of this software or the suitability of this
21   software for any particular purpose. It is provided "as is"
22   without express or implied warranty of any kind.
23
24   These notices must be retained in any copies of any part of this
25   documentation and/or software.
26 */
27
28#include <sys/types.h>
29#include <string.h>
30#include "md4.h"
31
32typedef unsigned char *POINTER;
33typedef const unsigned char *CONST_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, in, inputLen)
111MD4_CTX *context;                                        /* context */
112const void *in;                                /* input block */
113unsigned int inputLen;                     /* length of input block */
114{
115  unsigned int i, idx, partLen;
116  const unsigned char *input = in;
117
118  /* Compute number of bytes mod 64 */
119  idx = (unsigned int)((context->count[0] >> 3) & 0x3F);
120  /* Update number of bits */
121  if ((context->count[0] += ((UINT4)inputLen << 3))
122      < ((UINT4)inputLen << 3))
123    context->count[1]++;
124  context->count[1] += ((UINT4)inputLen >> 29);
125
126  partLen = 64 - idx;
127  /* Transform as many times as possible.
128   */
129  if (inputLen >= partLen) {
130    memcpy
131      ((POINTER)&context->buffer[idx], (CONST_POINTER)input, partLen);
132    MD4Transform (context->state, context->buffer);
133
134    for (i = partLen; i + 63 < inputLen; i += 64)
135      MD4Transform (context->state, &input[i]);
136
137    idx = 0;
138  }
139  else
140    i = 0;
141
142  /* Buffer remaining input */
143  memcpy
144    ((POINTER)&context->buffer[idx], (CONST_POINTER)&input[i],
145     inputLen-i);
146}
147
148/* MD4 padding. */
149void MD4Pad (context)
150MD4_CTX *context;                                        /* context */
151{
152  unsigned char bits[8];
153  unsigned int idx, padLen;
154
155  /* Save number of bits */
156  Encode (bits, context->count, 8);
157
158  /* Pad out to 56 mod 64.
159   */
160  idx = (unsigned int)((context->count[0] >> 3) & 0x3f);
161  padLen = (idx < 56) ? (56 - idx) : (120 - idx);
162  MD4Update (context, PADDING, padLen);
163
164  /* Append length (before padding) */
165  MD4Update (context, bits, 8);
166}
167
168/* MD4 finalization. Ends an MD4 message-digest operation, writing the
169     the message digest and zeroizing the context.
170 */
171void MD4Final (digest, context)
172unsigned char digest[16];                         /* message digest */
173MD4_CTX *context;                                        /* context */
174{
175  /* Do padding */
176  MD4Pad (context);
177
178  /* Store state in digest */
179  Encode (digest, context->state, 16);
180
181  /* Zeroize sensitive information.
182   */
183  memset ((POINTER)context, 0, sizeof (*context));
184}
185
186/* MD4 basic transformation. Transforms state based on block.
187 */
188static void MD4Transform (state, block)
189UINT4 state[4];
190const unsigned char block[64];
191{
192  UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
193
194  Decode (x, block, 64);
195
196  /* Round 1 */
197  FF (a, b, c, d, x[ 0], S11); /* 1 */
198  FF (d, a, b, c, x[ 1], S12); /* 2 */
199  FF (c, d, a, b, x[ 2], S13); /* 3 */
200  FF (b, c, d, a, x[ 3], S14); /* 4 */
201  FF (a, b, c, d, x[ 4], S11); /* 5 */
202  FF (d, a, b, c, x[ 5], S12); /* 6 */
203  FF (c, d, a, b, x[ 6], S13); /* 7 */
204  FF (b, c, d, a, x[ 7], S14); /* 8 */
205  FF (a, b, c, d, x[ 8], S11); /* 9 */
206  FF (d, a, b, c, x[ 9], S12); /* 10 */
207  FF (c, d, a, b, x[10], S13); /* 11 */
208  FF (b, c, d, a, x[11], S14); /* 12 */
209  FF (a, b, c, d, x[12], S11); /* 13 */
210  FF (d, a, b, c, x[13], S12); /* 14 */
211  FF (c, d, a, b, x[14], S13); /* 15 */
212  FF (b, c, d, a, x[15], S14); /* 16 */
213
214  /* Round 2 */
215  GG (a, b, c, d, x[ 0], S21); /* 17 */
216  GG (d, a, b, c, x[ 4], S22); /* 18 */
217  GG (c, d, a, b, x[ 8], S23); /* 19 */
218  GG (b, c, d, a, x[12], S24); /* 20 */
219  GG (a, b, c, d, x[ 1], S21); /* 21 */
220  GG (d, a, b, c, x[ 5], S22); /* 22 */
221  GG (c, d, a, b, x[ 9], S23); /* 23 */
222  GG (b, c, d, a, x[13], S24); /* 24 */
223  GG (a, b, c, d, x[ 2], S21); /* 25 */
224  GG (d, a, b, c, x[ 6], S22); /* 26 */
225  GG (c, d, a, b, x[10], S23); /* 27 */
226  GG (b, c, d, a, x[14], S24); /* 28 */
227  GG (a, b, c, d, x[ 3], S21); /* 29 */
228  GG (d, a, b, c, x[ 7], S22); /* 30 */
229  GG (c, d, a, b, x[11], S23); /* 31 */
230  GG (b, c, d, a, x[15], S24); /* 32 */
231
232  /* Round 3 */
233  HH (a, b, c, d, x[ 0], S31); /* 33 */
234  HH (d, a, b, c, x[ 8], S32); /* 34 */
235  HH (c, d, a, b, x[ 4], S33); /* 35 */
236  HH (b, c, d, a, x[12], S34); /* 36 */
237  HH (a, b, c, d, x[ 2], S31); /* 37 */
238  HH (d, a, b, c, x[10], S32); /* 38 */
239  HH (c, d, a, b, x[ 6], S33); /* 39 */
240  HH (b, c, d, a, x[14], S34); /* 40 */
241  HH (a, b, c, d, x[ 1], S31); /* 41 */
242  HH (d, a, b, c, x[ 9], S32); /* 42 */
243  HH (c, d, a, b, x[ 5], S33); /* 43 */
244  HH (b, c, d, a, x[13], S34); /* 44 */
245  HH (a, b, c, d, x[ 3], S31); /* 45 */
246  HH (d, a, b, c, x[11], S32); /* 46 */
247  HH (c, d, a, b, x[ 7], S33); /* 47 */
248  HH (b, c, d, a, x[15], S34); /* 48 */
249
250  state[0] += a;
251  state[1] += b;
252  state[2] += c;
253  state[3] += d;
254
255  /* Zeroize sensitive information.
256   */
257  memset ((POINTER)x, 0, sizeof (x));
258}
259
260/* Encodes input (UINT4) into output (unsigned char). Assumes len is
261     a multiple of 4.
262 */
263static void Encode (output, input, len)
264unsigned char *output;
265UINT4 *input;
266unsigned int len;
267{
268  unsigned int i, j;
269
270  for (i = 0, j = 0; j < len; i++, j += 4) {
271    output[j] = (unsigned char)(input[i] & 0xff);
272    output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
273    output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
274    output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
275  }
276}
277
278/* Decodes input (unsigned char) into output (UINT4). Assumes len is
279     a multiple of 4.
280 */
281static void Decode (output, input, len)
282
283UINT4 *output;
284const unsigned char *input;
285unsigned int len;
286{
287  unsigned int i, j;
288
289  for (i = 0, j = 0; j < len; i++, j += 4)
290    output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
291      (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
292}
293