1/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
2 */
3
4/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
5rights reserved.
6
7License to copy and use this software is granted provided that it
8is identified as the "RSA Data Security, Inc. MD5 Message-Digest
9Algorithm" in all material mentioning or referencing this software
10or this function.
11
12License is also granted to make and use derivative works provided
13that such works are identified as "derived from the RSA Data
14Security, Inc. MD5 Message-Digest Algorithm" in all material
15mentioning or referencing the derived work.
16
17RSA Data Security, Inc. makes no representations concerning either
18the merchantability of this software or the suitability of this
19software for any particular purpose. It is provided "as is"
20without express or implied warranty of any kind.
21
22These notices must be retained in any copies of any part of this
23documentation and/or software.
24 */
25
26//#include "config.h"
27#include "md5global.h"
28#include "md5.h"
29#include <string.h>
30#include <stdio.h>
31#include <stdlib.h>
32
33/* Constants for MD5Transform routine.
34 */
35#define S11 7
36#define S12 12
37#define S13 17
38#define S14 22
39#define S21 5
40#define S22 9
41#define S23 14
42#define S24 20
43#define S31 4
44#define S32 11
45#define S33 16
46#define S34 23
47#define S41 6
48#define S42 10
49#define S43 15
50#define S44 21
51
52static void MD5_Transform PROTO_LIST ((UINT4 [4], unsigned char [64]));
53static void Encode PROTO_LIST
54  ((unsigned char *, UINT4 *, unsigned int));
55static void Decode PROTO_LIST
56  ((UINT4 *, unsigned char *, unsigned int));
57static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));
58static void MD5_memset PROTO_LIST ((POINTER, int, 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, H and I are basic MD5 functions.
67 */
68#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
69#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
70#define H(x, y, z) ((x) ^ (y) ^ (z))
71#define I(x, y, z) ((y) ^ ((x) | (~z)))
72
73/* ROTATE_LEFT rotates x left n bits.
74 */
75#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
76
77/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
78Rotation is separate from addition to prevent recomputation.
79 */
80#define FF(a, b, c, d, x, s, ac) { \
81 (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
82 (a) = ROTATE_LEFT ((a), (s)); \
83 (a) += (b); \
84  }
85#define GG(a, b, c, d, x, s, ac) { \
86 (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
87 (a) = ROTATE_LEFT ((a), (s)); \
88 (a) += (b); \
89  }
90#define HH(a, b, c, d, x, s, ac) { \
91 (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
92 (a) = ROTATE_LEFT ((a), (s)); \
93 (a) += (b); \
94  }
95#define II(a, b, c, d, x, s, ac) { \
96 (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
97 (a) = ROTATE_LEFT ((a), (s)); \
98 (a) += (b); \
99  }
100
101/* MD5 initialization. Begins an MD5 operation, writing a new context.
102 */
103void MD5_Init (MD5_CTX *context)
104                                        /* context */
105{
106  context->count[0] = context->count[1] = 0;
107  /* Load magic initialization constants.
108*/
109  context->state[0] = 0x67452301;
110  context->state[1] = 0xefcdab89;
111  context->state[2] = 0x98badcfe;
112  context->state[3] = 0x10325476;
113}
114
115/* MD5 block update operation. Continues an MD5 message-digest
116  operation, processing another message block, and updating the
117  context.
118 */
119void MD5_Update (MD5_CTX *context, unsigned char *input, unsigned int inputLen)
120                                        /* context */
121                                /* input block */
122                     /* length of input block */
123{
124  unsigned int i, index, partLen;
125
126  /* Compute number of bytes mod 64 */
127  index = (unsigned int)((context->count[0] >> 3) & 0x3F);
128
129  /* Update number of bits */
130  if ((context->count[0] += ((UINT4)inputLen << 3))
131   < ((UINT4)inputLen << 3))
132 context->count[1]++;
133  context->count[1] += ((UINT4)inputLen >> 29);
134
135  partLen = 64 - index;
136
137  /* Transform as many times as possible.
138*/
139  if (inputLen >= partLen) {
140 MD5_memcpy
141   ((POINTER)&context->buffer[index], (POINTER)input, partLen);
142 MD5_Transform (context->state, context->buffer);
143
144 for (i = partLen; i + 63 < inputLen; i += 64)
145   MD5_Transform (context->state, &input[i]);
146
147 index = 0;
148  }
149  else
150 i = 0;
151
152  /* Buffer remaining input */
153  MD5_memcpy
154 ((POINTER)&context->buffer[index], (POINTER)&input[i],
155  inputLen-i);
156}
157
158/* MD5 finalization. Ends an MD5 message-digest operation, writing the
159  the message digest and zeroizing the context.
160 */
161void MD5_Final (unsigned char digest[16], MD5_CTX *context)
162                         /* message digest */
163                                       /* context */
164{
165  unsigned char bits[8];
166  unsigned int index, padLen;
167
168  /* Save number of bits */
169  Encode (bits, context->count, 8);
170
171  /* Pad out to 56 mod 64.
172*/
173  index = (unsigned int)((context->count[0] >> 3) & 0x3f);
174  padLen = (index < 56) ? (56 - index) : (120 - index);
175  MD5_Update (context, PADDING, padLen);
176
177  /* Append length (before padding) */
178  MD5_Update (context, bits, 8);
179  /* Store state in digest */
180  Encode (digest, context->state, 16);
181
182  /* Zeroize sensitive information.
183*/
184  MD5_memset ((POINTER)context, 0, sizeof (*context));
185}
186
187/* MD5 basic transformation. Transforms state based on block.
188 */
189static void MD5_Transform (UINT4 state[4], unsigned char block[64])
190{
191  UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
192
193  Decode (x, block, 64);
194
195  /* Round 1 */
196  FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
197  FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
198  FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
199  FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
200  FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
201  FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
202  FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
203  FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
204  FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
205  FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
206  FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
207  FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
208  FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
209  FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
210  FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
211  FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
212
213 /* Round 2 */
214  GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
215  GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
216  GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
217  GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
218  GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
219  GG (d, a, b, c, x[10], S22,  0x2441453); /* 22 */
220  GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
221  GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
222  GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
223  GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
224  GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
225  GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
226  GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
227  GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
228  GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
229  GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
230
231  /* Round 3 */
232  HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
233  HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
234  HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
235  HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
236  HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
237  HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
238  HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
239  HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
240  HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
241  HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
242  HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
243  HH (b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */
244  HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
245  HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
246  HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
247  HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
248
249  /* Round 4 */
250  II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
251  II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
252  II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
253  II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
254  II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
255  II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
256  II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
257  II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
258  II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
259  II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
260  II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
261  II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
262  II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
263  II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
264  II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
265  II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
266
267  state[0] += a;
268  state[1] += b;
269  state[2] += c;
270  state[3] += d;
271
272  /* Zeroize sensitive information.
273*/
274  MD5_memset ((POINTER)x, 0, sizeof (x));
275}
276
277/* Encodes input (UINT4) into output (unsigned char). Assumes len is
278  a multiple of 4.
279 */
280static void Encode (unsigned char *output, UINT4 *input, unsigned int len)
281{
282  unsigned int i, j;
283
284  for (i = 0, j = 0; j < len; i++, j += 4) {
285 output[j] = (unsigned char)(input[i] & 0xff);
286 output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
287 output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
288 output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
289  }
290}
291
292/* Decodes input (unsigned char) into output (UINT4). Assumes len is
293  a multiple of 4.
294 */
295static void Decode (UINT4 *output, unsigned char *input, unsigned int len)
296{
297  unsigned int i, j;
298
299  for (i = 0, j = 0; j < len; i++, j += 4)
300 output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
301   (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
302}
303
304/* Note: Replace "for loop" with standard memcpy if possible.
305 */
306
307static void MD5_memcpy (POINTER output, POINTER input, unsigned int len)
308{
309  unsigned int i;
310
311  for (i = 0; i < len; i++)
312 output[i] = input[i];
313}
314
315/* Note: Replace "for loop" with standard memset if possible.
316 */
317static void MD5_memset (POINTER output, int value, unsigned int len)
318{
319  unsigned int i;
320
321  for (i = 0; i < len; i++)
322 ((char *)output)[i] = (char)value;
323}
324