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