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