OSDN Git Service

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