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