Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Release 1.0
[palacios.git] / geekos / src / lwip / netif / ppp / md5.c
1 /*
2  ***********************************************************************
3  ** md5.c -- the source code for MD5 routines                         **
4  ** RSA Data Security, Inc. MD5 Message-Digest Algorithm              **
5  ** Created: 2/17/90 RLR                                              **
6  ** Revised: 1/91 SRD,AJ,BSK,JT Reference C ver., 7/10 constant corr. **
7  ***********************************************************************
8  */
9
10 /*
11  ***********************************************************************
12  ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved.  **
13  **                                                                   **
14  ** License to copy and use this software is granted provided that    **
15  ** it is identified as the "RSA Data Security, Inc. MD5 Message-     **
16  ** Digest Algorithm" in all material mentioning or referencing this  **
17  ** software or this function.                                        **
18  **                                                                   **
19  ** License is also granted to make and use derivative works          **
20  ** provided that such works are identified as "derived from the RSA  **
21  ** Data Security, Inc. MD5 Message-Digest Algorithm" in all          **
22  ** material mentioning or referencing the derived work.              **
23  **                                                                   **
24  ** RSA Data Security, Inc. makes no representations concerning       **
25  ** either the merchantability of this software or the suitability    **
26  ** of this software for any particular purpose.  It is provided "as  **
27  ** is" without express or implied warranty of any kind.              **
28  **                                                                   **
29  ** These notices must be retained in any copies of any part of this  **
30  ** documentation and/or software.                                    **
31  ***********************************************************************
32  */
33
34 #include "lwip/opt.h"
35
36 #if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */
37
38 #if CHAP_SUPPORT || MD5_SUPPORT
39
40 #include "ppp.h"
41 #include "pppdebug.h"
42
43 #include "md5.h"
44
45 /*
46  ***********************************************************************
47  **  Message-digest routines:                                         **
48  **  To form the message digest for a message M                       **
49  **    (1) Initialize a context buffer mdContext using MD5Init        **
50  **    (2) Call MD5Update on mdContext and M                          **
51  **    (3) Call MD5Final on mdContext                                 **
52  **  The message digest is now in mdContext->digest[0...15]           **
53  ***********************************************************************
54  */
55
56 /* forward declaration */
57 static void Transform (u32_t *buf, u32_t *in);
58
59 static unsigned char PADDING[64] = {
60   0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
61   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
62   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
63   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
64   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
65   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
66   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
67   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
68 };
69
70 /* F, G, H and I are basic MD5 functions */
71 #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
72 #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
73 #define H(x, y, z) ((x) ^ (y) ^ (z))
74 #define I(x, y, z) ((y) ^ ((x) | (~z)))
75
76 /* ROTATE_LEFT rotates x left n bits */
77 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
78
79 /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */
80 /* Rotation is separate from addition to prevent recomputation */
81 #define FF(a, b, c, d, x, s, ac) \
82   {(a) += F ((b), (c), (d)) + (x) + (u32_t)(ac); \
83    (a) = ROTATE_LEFT ((a), (s)); \
84    (a) += (b); \
85   }
86 #define GG(a, b, c, d, x, s, ac) \
87   {(a) += G ((b), (c), (d)) + (x) + (u32_t)(ac); \
88    (a) = ROTATE_LEFT ((a), (s)); \
89    (a) += (b); \
90   }
91 #define HH(a, b, c, d, x, s, ac) \
92   {(a) += H ((b), (c), (d)) + (x) + (u32_t)(ac); \
93    (a) = ROTATE_LEFT ((a), (s)); \
94    (a) += (b); \
95   }
96 #define II(a, b, c, d, x, s, ac) \
97   {(a) += I ((b), (c), (d)) + (x) + (u32_t)(ac); \
98    (a) = ROTATE_LEFT ((a), (s)); \
99    (a) += (b); \
100   }
101
102 #ifdef __STDC__
103 #define UL(x) x##UL
104 #else
105 #ifdef WIN32
106 #define UL(x) x##UL
107 #else
108 #define UL(x) x
109 #endif
110 #endif
111
112 /* The routine MD5Init initializes the message-digest context
113    mdContext. All fields are set to zero.
114  */
115 void
116 MD5Init (MD5_CTX *mdContext)
117 {
118   mdContext->i[0] = mdContext->i[1] = (u32_t)0;
119
120   /* Load magic initialization constants. */
121   mdContext->buf[0] = (u32_t)0x67452301UL;
122   mdContext->buf[1] = (u32_t)0xefcdab89UL;
123   mdContext->buf[2] = (u32_t)0x98badcfeUL;
124   mdContext->buf[3] = (u32_t)0x10325476UL;
125 }
126
127 /* The routine MD5Update updates the message-digest context to
128    account for the presence of each of the characters inBuf[0..inLen-1]
129    in the message whose digest is being computed.
130  */
131 void
132 MD5Update(MD5_CTX *mdContext, unsigned char *inBuf, unsigned int inLen)
133 {
134   u32_t in[16];
135   int mdi;
136   unsigned int i, ii;
137
138 #if 0
139   ppp_trace(LOG_INFO, "MD5Update: %u:%.*H\n", inLen, MIN(inLen, 20) * 2, inBuf);
140   ppp_trace(LOG_INFO, "MD5Update: %u:%s\n", inLen, inBuf);
141 #endif
142   
143   /* compute number of bytes mod 64 */
144   mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
145
146   /* update number of bits */
147   if ((mdContext->i[0] + ((u32_t)inLen << 3)) < mdContext->i[0]) {
148     mdContext->i[1]++;
149   }
150   mdContext->i[0] += ((u32_t)inLen << 3);
151   mdContext->i[1] += ((u32_t)inLen >> 29);
152
153   while (inLen--) {
154     /* add new character to buffer, increment mdi */
155     mdContext->in[mdi++] = *inBuf++;
156
157     /* transform if necessary */
158     if (mdi == 0x40) {
159       for (i = 0, ii = 0; i < 16; i++, ii += 4) {
160         in[i] = (((u32_t)mdContext->in[ii+3]) << 24) |
161                 (((u32_t)mdContext->in[ii+2]) << 16) |
162                 (((u32_t)mdContext->in[ii+1]) << 8)  |
163                 ((u32_t)mdContext->in[ii]);
164       }
165       Transform (mdContext->buf, in);
166       mdi = 0;
167     }
168   }
169 }
170
171 /* The routine MD5Final terminates the message-digest computation and
172    ends with the desired message digest in mdContext->digest[0...15].
173  */
174 void
175 MD5Final (unsigned char hash[], MD5_CTX *mdContext)
176 {
177   u32_t in[16];
178   int mdi;
179   unsigned int i, ii;
180   unsigned int padLen;
181
182   /* save number of bits */
183   in[14] = mdContext->i[0];
184   in[15] = mdContext->i[1];
185
186   /* compute number of bytes mod 64 */
187   mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
188
189   /* pad out to 56 mod 64 */
190   padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi);
191   MD5Update (mdContext, PADDING, padLen);
192
193   /* append length in bits and transform */
194   for (i = 0, ii = 0; i < 14; i++, ii += 4) {
195     in[i] = (((u32_t)mdContext->in[ii+3]) << 24) |
196             (((u32_t)mdContext->in[ii+2]) << 16) |
197             (((u32_t)mdContext->in[ii+1]) << 8)  |
198             ((u32_t)mdContext->in[ii]);
199   }
200   Transform (mdContext->buf, in);
201
202   /* store buffer in digest */
203   for (i = 0, ii = 0; i < 4; i++, ii += 4) {
204     mdContext->digest[ii]   = (unsigned char)(mdContext->buf[i] & 0xFF);
205     mdContext->digest[ii+1] =
206       (unsigned char)((mdContext->buf[i] >> 8)  & 0xFF);
207     mdContext->digest[ii+2] =
208       (unsigned char)((mdContext->buf[i] >> 16) & 0xFF);
209     mdContext->digest[ii+3] =
210       (unsigned char)((mdContext->buf[i] >> 24) & 0xFF);
211   }
212   SMEMCPY(hash, mdContext->digest, 16);
213 }
214
215 /* Basic MD5 step. Transforms buf based on in.
216  */
217 static void
218 Transform (u32_t *buf, u32_t *in)
219 {
220   u32_t a = buf[0], b = buf[1], c = buf[2], d = buf[3];
221
222   /* Round 1 */
223 #define S11 7
224 #define S12 12
225 #define S13 17
226 #define S14 22
227   FF ( a, b, c, d, in[ 0], S11, UL(3614090360)); /* 1 */
228   FF ( d, a, b, c, in[ 1], S12, UL(3905402710)); /* 2 */
229   FF ( c, d, a, b, in[ 2], S13, UL( 606105819)); /* 3 */
230   FF ( b, c, d, a, in[ 3], S14, UL(3250441966)); /* 4 */
231   FF ( a, b, c, d, in[ 4], S11, UL(4118548399)); /* 5 */
232   FF ( d, a, b, c, in[ 5], S12, UL(1200080426)); /* 6 */
233   FF ( c, d, a, b, in[ 6], S13, UL(2821735955)); /* 7 */
234   FF ( b, c, d, a, in[ 7], S14, UL(4249261313)); /* 8 */
235   FF ( a, b, c, d, in[ 8], S11, UL(1770035416)); /* 9 */
236   FF ( d, a, b, c, in[ 9], S12, UL(2336552879)); /* 10 */
237   FF ( c, d, a, b, in[10], S13, UL(4294925233)); /* 11 */
238   FF ( b, c, d, a, in[11], S14, UL(2304563134)); /* 12 */
239   FF ( a, b, c, d, in[12], S11, UL(1804603682)); /* 13 */
240   FF ( d, a, b, c, in[13], S12, UL(4254626195)); /* 14 */
241   FF ( c, d, a, b, in[14], S13, UL(2792965006)); /* 15 */
242   FF ( b, c, d, a, in[15], S14, UL(1236535329)); /* 16 */
243
244   /* Round 2 */
245 #define S21 5
246 #define S22 9
247 #define S23 14
248 #define S24 20
249   GG ( a, b, c, d, in[ 1], S21, UL(4129170786)); /* 17 */
250   GG ( d, a, b, c, in[ 6], S22, UL(3225465664)); /* 18 */
251   GG ( c, d, a, b, in[11], S23, UL( 643717713)); /* 19 */
252   GG ( b, c, d, a, in[ 0], S24, UL(3921069994)); /* 20 */
253   GG ( a, b, c, d, in[ 5], S21, UL(3593408605)); /* 21 */
254   GG ( d, a, b, c, in[10], S22, UL(  38016083)); /* 22 */
255   GG ( c, d, a, b, in[15], S23, UL(3634488961)); /* 23 */
256   GG ( b, c, d, a, in[ 4], S24, UL(3889429448)); /* 24 */
257   GG ( a, b, c, d, in[ 9], S21, UL( 568446438)); /* 25 */
258   GG ( d, a, b, c, in[14], S22, UL(3275163606)); /* 26 */
259   GG ( c, d, a, b, in[ 3], S23, UL(4107603335)); /* 27 */
260   GG ( b, c, d, a, in[ 8], S24, UL(1163531501)); /* 28 */
261   GG ( a, b, c, d, in[13], S21, UL(2850285829)); /* 29 */
262   GG ( d, a, b, c, in[ 2], S22, UL(4243563512)); /* 30 */
263   GG ( c, d, a, b, in[ 7], S23, UL(1735328473)); /* 31 */
264   GG ( b, c, d, a, in[12], S24, UL(2368359562)); /* 32 */
265
266   /* Round 3 */
267 #define S31 4
268 #define S32 11
269 #define S33 16
270 #define S34 23
271   HH ( a, b, c, d, in[ 5], S31, UL(4294588738)); /* 33 */
272   HH ( d, a, b, c, in[ 8], S32, UL(2272392833)); /* 34 */
273   HH ( c, d, a, b, in[11], S33, UL(1839030562)); /* 35 */
274   HH ( b, c, d, a, in[14], S34, UL(4259657740)); /* 36 */
275   HH ( a, b, c, d, in[ 1], S31, UL(2763975236)); /* 37 */
276   HH ( d, a, b, c, in[ 4], S32, UL(1272893353)); /* 38 */
277   HH ( c, d, a, b, in[ 7], S33, UL(4139469664)); /* 39 */
278   HH ( b, c, d, a, in[10], S34, UL(3200236656)); /* 40 */
279   HH ( a, b, c, d, in[13], S31, UL( 681279174)); /* 41 */
280   HH ( d, a, b, c, in[ 0], S32, UL(3936430074)); /* 42 */
281   HH ( c, d, a, b, in[ 3], S33, UL(3572445317)); /* 43 */
282   HH ( b, c, d, a, in[ 6], S34, UL(  76029189)); /* 44 */
283   HH ( a, b, c, d, in[ 9], S31, UL(3654602809)); /* 45 */
284   HH ( d, a, b, c, in[12], S32, UL(3873151461)); /* 46 */
285   HH ( c, d, a, b, in[15], S33, UL( 530742520)); /* 47 */
286   HH ( b, c, d, a, in[ 2], S34, UL(3299628645)); /* 48 */
287
288   /* Round 4 */
289 #define S41 6
290 #define S42 10
291 #define S43 15
292 #define S44 21
293   II ( a, b, c, d, in[ 0], S41, UL(4096336452)); /* 49 */
294   II ( d, a, b, c, in[ 7], S42, UL(1126891415)); /* 50 */
295   II ( c, d, a, b, in[14], S43, UL(2878612391)); /* 51 */
296   II ( b, c, d, a, in[ 5], S44, UL(4237533241)); /* 52 */
297   II ( a, b, c, d, in[12], S41, UL(1700485571)); /* 53 */
298   II ( d, a, b, c, in[ 3], S42, UL(2399980690)); /* 54 */
299   II ( c, d, a, b, in[10], S43, UL(4293915773)); /* 55 */
300   II ( b, c, d, a, in[ 1], S44, UL(2240044497)); /* 56 */
301   II ( a, b, c, d, in[ 8], S41, UL(1873313359)); /* 57 */
302   II ( d, a, b, c, in[15], S42, UL(4264355552)); /* 58 */
303   II ( c, d, a, b, in[ 6], S43, UL(2734768916)); /* 59 */
304   II ( b, c, d, a, in[13], S44, UL(1309151649)); /* 60 */
305   II ( a, b, c, d, in[ 4], S41, UL(4149444226)); /* 61 */
306   II ( d, a, b, c, in[11], S42, UL(3174756917)); /* 62 */
307   II ( c, d, a, b, in[ 2], S43, UL( 718787259)); /* 63 */
308   II ( b, c, d, a, in[ 9], S44, UL(3951481745)); /* 64 */
309
310   buf[0] += a;
311   buf[1] += b;
312   buf[2] += c;
313   buf[3] += d;
314 }
315
316 #endif /* CHAP_SUPPORT || MD5_SUPPORT */
317
318 #endif /* PPP_SUPPORT */