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