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