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