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