]> pilppa.org Git - familiar-h63xx-build.git/blob - org.handhelds.familiar/packages/linux/linux-wrt-2.4.20/150-mppe-mppc-0.98.patch
OE tree imported from monotone branch org.openembedded.oz354fam083 at revision 8b12e3...
[familiar-h63xx-build.git] / org.handhelds.familiar / packages / linux / linux-wrt-2.4.20 / 150-mppe-mppc-0.98.patch
1
2 #
3 # Patch managed by http://www.mn-logistik.de/unsupported/pxa250/patcher
4 #
5
6 --- linux-2.4.20/drivers/net/Config.in~150-mppe-mppc-0.98       2005-01-07 02:52:47.191946000 -0500
7 +++ linux-2.4.20/drivers/net/Config.in  2005-01-07 02:57:48.408155016 -0500
8 @@ -288,6 +288,7 @@
9     dep_tristate '  PPP support for sync tty ports' CONFIG_PPP_SYNC_TTY $CONFIG_PPP
10     dep_tristate '  PPP Deflate compression' CONFIG_PPP_DEFLATE $CONFIG_PPP
11     dep_tristate '  PPP BSD-Compress compression' CONFIG_PPP_BSDCOMP $CONFIG_PPP
12 +   dep_tristate '  Microsoft PPP compression/encryption (MPPC/MPPE)' CONFIG_PPP_MPPE $CONFIG_PPP
13     if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
14        dep_tristate '  PPP over Ethernet (EXPERIMENTAL)' CONFIG_PPPOE $CONFIG_PPP
15     fi
16 --- linux-2.4.20/drivers/net/Makefile~150-mppe-mppc-0.98        2005-01-07 02:54:46.352831000 -0500
17 +++ linux-2.4.20/drivers/net/Makefile   2005-01-07 02:57:48.409154864 -0500
18 @@ -18,8 +18,9 @@
19  export-objs     :=     8390.o arlan.o aironet4500_core.o aironet4500_card.o \
20                         ppp_async.o ppp_generic.o slhc.o pppox.o auto_irq.o \
21                         net_init.o mii.o
22 -list-multi     :=      rcpci.o
23 +list-multi     :=      rcpci.o ppp_mppe_mppc.o
24  rcpci-objs     :=      rcpci45.o rclanmtl.o
25 +ppp_mppe_c-objs        :=      ppp_mppe_mppc_comp.o ppp_mppe_crypto.o
26  
27  # subdir-m += mac
28  subdir-m += diag
29 @@ -159,6 +160,15 @@
30  obj-$(CONFIG_PPP_SYNC_TTY) += ppp_synctty.o
31  obj-$(CONFIG_PPP_DEFLATE) += ppp_deflate.o
32  obj-$(CONFIG_PPP_BSDCOMP) += bsd_comp.o
33 +
34 +ifeq ($(CONFIG_PPP_MPPE),y)
35 +  obj-y += $(ppp_mppe_c-objs)
36 +else
37 +  ifeq ($(CONFIG_PPP_MPPE),m)
38 +    obj-m += ppp_mppe_mppc.o
39 +  endif
40 +endif
41 +
42  obj-$(CONFIG_PPPOE) += pppox.o pppoe.o
43  
44  obj-$(CONFIG_SLIP) += slip.o
45 @@ -291,3 +301,5 @@
46  rcpci.o: $(rcpci-objs)
47         $(LD) -r -o $@ $(rcpci-objs)
48  
49 +ppp_mppe_mppc.o: $(ppp_mppe_c-objs)
50 +       $(LD) -r -o $@ $(ppp_mppe_c-objs)
51 --- linux-2.4.20/drivers/net/ppp_generic.c~150-mppe-mppc-0.98   2002-11-28 18:53:14.000000000 -0500
52 +++ linux-2.4.20/drivers/net/ppp_generic.c      2005-01-07 02:57:48.414154104 -0500
53 @@ -19,7 +19,7 @@
54   * PPP driver, written by Michael Callahan and Al Longyear, and
55   * subsequently hacked by Paul Mackerras.
56   *
57 - * ==FILEVERSION 20020217==
58 + * ==FILEVERSION 20030706==
59   */
60  
61  #include <linux/config.h>
62 @@ -102,6 +102,7 @@
63         spinlock_t      rlock;          /* lock for receive side 58 */
64         spinlock_t      wlock;          /* lock for transmit side 5c */
65         int             mru;            /* max receive unit 60 */
66 +       int             mru_alloc;      /* MAX(1500,MRU) for dev_alloc_skb() */
67         unsigned int    flags;          /* control bits 64 */
68         unsigned int    xstate;         /* transmit state bits 68 */
69         unsigned int    rstate;         /* receive state bits 6c */
70 @@ -129,6 +130,7 @@
71         struct sock_fprog pass_filter;  /* filter for packets to pass */
72         struct sock_fprog active_filter;/* filter for pkts to reset idle */
73  #endif /* CONFIG_PPP_FILTER */
74 +       int             xpad;           /* ECP or CCP (MPPE) transmit padding */
75  };
76  
77  /*
78 @@ -552,7 +554,9 @@
79         case PPPIOCSMRU:
80                 if (get_user(val, (int *) arg))
81                         break;
82 -               ppp->mru = val;
83 +               ppp->mru_alloc = ppp->mru = val;
84 +               if (ppp->mru_alloc < PPP_MRU)
85 +                   ppp->mru_alloc = PPP_MRU;   /* increase for broken peers */
86                 err = 0;
87                 break;
88  
89 @@ -1024,14 +1028,35 @@
90         case PPP_CCP:
91                 /* peek at outbound CCP frames */
92                 ppp_ccp_peek(ppp, skb, 0);
93 +               /*
94 +                * When LZS or MPPE/MPPC is negotiated we don't send
95 +                * CCP_RESETACK after receiving CCP_RESETREQ; in fact pppd
96 +                * sends such a packet but we silently discard it here
97 +                */
98 +               if (CCP_CODE(skb->data+2) == CCP_RESETACK
99 +                   && (ppp->xcomp->compress_proto == CI_MPPE
100 +                       || ppp->xcomp->compress_proto == CI_LZS)) {
101 +                   --ppp->stats.tx_packets;
102 +                   ppp->stats.tx_bytes -= skb->len - 2;
103 +                   kfree_skb(skb);
104 +                   return;
105 +               }
106                 break;
107         }
108  
109         /* try to do packet compression */
110         if ((ppp->xstate & SC_COMP_RUN) && ppp->xc_state != 0
111             && proto != PPP_LCP && proto != PPP_CCP) {
112 -               new_skb = alloc_skb(ppp->dev->mtu + ppp->dev->hard_header_len,
113 -                                   GFP_ATOMIC);
114 +               int comp_ovhd = 0;
115 +               /* because of possible data expansion when MPPC or LZS
116 +                  is used, allocate compressor's buffer about 12.5% bigger
117 +                  than MTU */
118 +               if (ppp->xcomp->compress_proto == CI_MPPE)
119 +                   comp_ovhd = (((ppp->dev->mtu * 9) / 8) + 1);
120 +               else if (ppp->xcomp->compress_proto == CI_LZS)
121 +                   comp_ovhd = (((ppp->dev->mtu * 9) / 8) + 1) + LZS_OVHD;
122 +               new_skb = alloc_skb(ppp->dev->mtu + ppp->dev->hard_header_len
123 +                                   + ppp->xpad + comp_ovhd, GFP_ATOMIC);
124                 if (new_skb == 0) {
125                         printk(KERN_ERR "PPP: no memory (comp pkt)\n");
126                         goto drop;
127 @@ -1043,15 +1068,28 @@
128                 /* compressor still expects A/C bytes in hdr */
129                 len = ppp->xcomp->compress(ppp->xc_state, skb->data - 2,
130                                            new_skb->data, skb->len + 2,
131 -                                          ppp->dev->mtu + PPP_HDRLEN);
132 +                                          ppp->dev->mtu + ppp->xpad
133 +                                          + PPP_HDRLEN);
134                 if (len > 0 && (ppp->flags & SC_CCP_UP)) {
135                         kfree_skb(skb);
136                         skb = new_skb;
137                         skb_put(skb, len);
138                         skb_pull(skb, 2);       /* pull off A/C bytes */
139 -               } else {
140 +               } else if (len == 0) {
141                         /* didn't compress, or CCP not up yet */
142                         kfree_skb(new_skb);
143 +               } else {
144 +                       /*
145 +                        * (len < 0)
146 +                        * MPPE requires that we do not send unencrypted
147 +                        * frames.  The compressor will return -1 if we
148 +                        * should drop the frame.  We cannot simply test
149 +                        * the compress_proto because MPPE and MPPC share
150 +                        * the same number.
151 +                        */
152 +                       printk(KERN_ERR "ppp: compressor dropped pkt\n");
153 +                       kfree_skb(new_skb);
154 +                       goto drop;
155                 }
156         }
157  
158 @@ -1539,14 +1577,15 @@
159         int len;
160  
161         if (proto == PPP_COMP) {
162 -               ns = dev_alloc_skb(ppp->mru + PPP_HDRLEN);
163 +               ns = dev_alloc_skb(ppp->mru_alloc + PPP_HDRLEN);
164                 if (ns == 0) {
165                         printk(KERN_ERR "ppp_decompress_frame: no memory\n");
166                         goto err;
167                 }
168                 /* the decompressor still expects the A/C bytes in the hdr */
169                 len = ppp->rcomp->decompress(ppp->rc_state, skb->data - 2,
170 -                               skb->len + 2, ns->data, ppp->mru + PPP_HDRLEN);
171 +                               skb->len + 2, ns->data,
172 +                               ppp->mru_alloc + PPP_HDRLEN);
173                 if (len < 0) {
174                         /* Pass the compressed frame to pppd as an
175                            error indication. */
176 @@ -1572,7 +1611,12 @@
177         return skb;
178  
179   err:
180 -       ppp->rstate |= SC_DC_ERROR;
181 +       if (ppp->rcomp->compress_proto != CI_MPPE
182 +           && ppp->rcomp->compress_proto != CI_LZS) {
183 +           /* If decompression protocol isn't MPPE/MPPC or LZS, we set
184 +            SC_DC_ERROR flag and wait for CCP_RESETACK */
185 +           ppp->rstate |= SC_DC_ERROR;
186 +       }
187         ppp_receive_error(ppp);
188         return skb;
189  }
190 @@ -1981,6 +2025,20 @@
191                                 ocomp->comp_free(ostate);
192                         err = 0;
193                 }
194 +               if (ccp_option[0] == CI_MPPE)
195 +                       /*
196 +                        * pppd (userland) has reduced the MTU by MPPE_PAD,
197 +                        * to accomodate "compressor" growth.  We must
198 +                        * increase the space allocated for compressor
199 +                        * output in ppp_send_frame() accordingly.  Note
200 +                        * that from a purist's view, it may be more correct
201 +                        * to require multilink and fragment large packets,
202 +                        * but that seems inefficient compared to this
203 +                        * little trick.
204 +                        */
205 +                       ppp->xpad = MPPE_PAD;
206 +               else
207 +                       ppp->xpad = 0;
208  
209         } else {
210                 state = cp->decomp_alloc(ccp_option, data.length);
211 @@ -2252,6 +2310,7 @@
212         /* Initialize the new ppp unit */
213         ppp->file.index = unit;
214         ppp->mru = PPP_MRU;
215 +       ppp->mru_alloc = PPP_MRU;
216         init_ppp_file(&ppp->file, INTERFACE);
217         ppp->file.hdrlen = PPP_HDRLEN - 2;      /* don't count proto bytes */
218         for (i = 0; i < NUM_NP; ++i)
219 --- /dev/null   2004-04-06 13:56:48.000000000 -0400
220 +++ linux-2.4.20/drivers/net/ppp_mppe_crypto.c  2005-01-07 02:57:48.414154104 -0500
221 @@ -0,0 +1,257 @@
222 +/*
223 + * ppp_mppe_crypto.c - cryptografic funtions for MPPE
224 + *
225 + *  This code is Public Domain. Please see comments below.
226 + *
227 + *  I have just put SHA1 and ARCFOUR implementations into one file
228 + *  in order to not pollute kernel namespace. 
229 + *
230 + *  Jan Dubiec <jdx@slackware.pl>, 2003-07-08
231 + */
232 +
233 +/*
234 + * ftp://ftp.funet.fi/pub/crypt/hash/sha/sha1.c
235 + * 
236 + * SHA-1 in C
237 + * By Steve Reid <steve@edmweb.com>
238 + * 100% Public Domain
239 + * 
240 + * Test Vectors (from FIPS PUB 180-1)
241 + * "abc"
242 + * A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
243 + * "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
244 + * 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
245 + * A million repetitions of "a"
246 + * 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
247 + */
248 +
249 +/* #define SHA1HANDSOFF * Copies data before messing with it. */
250 +
251 +#if defined(__linux__)
252 +#include <asm/byteorder.h>
253 +#include <linux/string.h>
254 +#elif defined(__solaris__)
255 +#include <sys/isa_defs.h>
256 +#include <sys/ddi.h>
257 +#include <sys/sunddi.h>
258 +#define memcpy(d, s, c) bcopy(s, d, c)
259 +#define memset(d, b, c) bzero(d, c)
260 +#endif
261 +
262 +#include "ppp_mppe_crypto.h"
263 +
264 +static void SHA1_Transform(unsigned long[5], const unsigned char[64]);
265 +
266 +#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
267 +
268 +/* blk0() and blk() perform the initial expand. */
269 +/* I got the idea of expanding during the round function from SSLeay */
270 +#if defined(__LITTLE_ENDIAN) || defined(_LITTLE_ENDIAN)
271 +#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
272 +    |(rol(block->l[i],8)&0x00FF00FF))
273 +#elif defined(__BIG_ENDIAN) || defined(_BIG_ENDIAN)
274 +#define blk0(i) block->l[i]
275 +#else
276 +#error Endianness not defined
277 +#endif
278 +#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
279 +    ^block->l[(i+2)&15]^block->l[i&15],1))
280 +
281 +/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
282 +#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
283 +#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
284 +#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
285 +#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
286 +#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
287 +
288 +/* Hash a single 512-bit block. This is the core of the algorithm. */
289 +static void
290 +SHA1_Transform(unsigned long state[5], const unsigned char buffer[64])
291 +{
292 +    unsigned long a, b, c, d, e;
293 +    typedef union {
294 +       unsigned char c[64];
295 +       unsigned long l[16];
296 +    } CHAR64LONG16;
297 +    CHAR64LONG16 *block;
298 +
299 +#ifdef SHA1HANDSOFF
300 +    static unsigned char workspace[64];
301 +    block = (CHAR64LONG16 *) workspace;
302 +    memcpy(block, buffer, 64);
303 +#else
304 +    block = (CHAR64LONG16 *) buffer;
305 +#endif
306 +    /* Copy context->state[] to working vars */
307 +    a = state[0];
308 +    b = state[1];
309 +    c = state[2];
310 +    d = state[3];
311 +    e = state[4];
312 +    /* 4 rounds of 20 operations each. Loop unrolled. */
313 +    R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
314 +    R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
315 +    R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
316 +    R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
317 +    R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
318 +    R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
319 +    R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
320 +    R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
321 +    R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
322 +    R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
323 +    R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
324 +    R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
325 +    R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
326 +    R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
327 +    R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
328 +    R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
329 +    R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
330 +    R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
331 +    R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
332 +    R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
333 +    /* Add the working vars back into context.state[] */
334 +    state[0] += a;
335 +    state[1] += b;
336 +    state[2] += c;
337 +    state[3] += d;
338 +    state[4] += e;
339 +    /* Wipe variables */
340 +    a = b = c = d = e = 0;
341 +}
342 +
343 +/* SHA1Init - Initialize new context */
344 +void
345 +SHA1_Init(SHA1_CTX *context)
346 +{
347 +    /* SHA1 initialization constants */
348 +    context->state[0] = 0x67452301;
349 +    context->state[1] = 0xEFCDAB89;
350 +    context->state[2] = 0x98BADCFE;
351 +    context->state[3] = 0x10325476;
352 +    context->state[4] = 0xC3D2E1F0;
353 +    context->count[0] = context->count[1] = 0;
354 +}
355 +
356 +/* Run your data through this. */
357 +void
358 +SHA1_Update(SHA1_CTX *context, const unsigned char *data, unsigned int len)
359 +{
360 +    unsigned int i, j;
361 +
362 +    j = (context->count[0] >> 3) & 63;
363 +    if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++;
364 +    context->count[1] += (len >> 29);
365 +    if ((j + len) > 63) {
366 +       memcpy(&context->buffer[j], data, (i = 64-j));
367 +       SHA1_Transform(context->state, context->buffer);
368 +       for ( ; i + 63 < len; i += 64) {
369 +           SHA1_Transform(context->state, &data[i]);
370 +       }
371 +       j = 0;
372 +    }
373 +    else
374 +       i = 0;
375 +
376 +    memcpy(&context->buffer[j], &data[i], len - i);
377 +}
378 +
379 +/* Add padding and return the message digest. */
380 +void
381 +SHA1_Final(unsigned char digest[20], SHA1_CTX *context)
382 +{
383 +    unsigned long i, j;
384 +    unsigned char finalcount[8];
385 +
386 +    for (i = 0; i < 8; i++) {
387 +        finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
388 +         >> ((3-(i & 3)) * 8) ) & 255);  /* Endian independent */
389 +    }
390 +    SHA1_Update(context, (unsigned char *) "\200", 1);
391 +    while ((context->count[0] & 504) != 448) {
392 +       SHA1_Update(context, (unsigned char *) "\0", 1);
393 +    }
394 +    SHA1_Update(context, finalcount, 8);  /* Should cause a SHA1Transform() */
395 +    for (i = 0; i < 20; i++) {
396 +       digest[i] = (unsigned char)
397 +                    ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
398 +    }
399 +    /* Wipe variables */
400 +    i = j = 0;
401 +    memset(context->buffer, 0, 64);
402 +    memset(context->state, 0, 20);
403 +    memset(context->count, 0, 8);
404 +    memset(&finalcount, 0, 8);
405 +#ifdef SHA1HANDSOFF  /* make SHA1Transform overwrite it's own static vars */
406 +    SHA1Transform(context->state, context->buffer);
407 +#endif
408 +}
409 +
410 +/*
411 + * arcfour.c
412 + * by Frank Cusack <frank@google.com>
413 + * 100% public domain
414 + *
415 + * Implemented from the description in _Applied Cryptography_, 2nd ed.
416 + *
417 + * ** Distribution ** of this software is unlimited and unrestricted.
418 + *
419 + * ** Use ** of this software is almost certainly legal; however, refer
420 + * to <http://theory.lcs.mit.edu/~rivest/faq.html>.
421 + */
422 +
423 +#define swap(a, b)             \
424 +{                              \
425 +    unsigned char t = b;       \
426 +    b = a;                     \
427 +    a = t;                     \
428 +}
429 +
430 +/*
431 + * Initialize arcfour from a key.
432 + */
433 +void
434 +arcfour_setkey(arcfour_context *context, const unsigned char *key,
435 +              unsigned keylen)
436 +{
437 +    unsigned i, j;
438 +    unsigned char K[256];
439 +
440 +    context->i = context->j = 0;
441 +
442 +    for (i = 0; i < 256; i++) {
443 +       context->S[i] = i;
444 +       K[i] = key[i % keylen];
445 +    }
446 +
447 +    j = 0;
448 +    for (i = 0; i < 256; i++) {
449 +       j = (j + context->S[i] + K[i]) % 256;
450 +       swap(context->S[i], context->S[j]);
451 +    }
452 +
453 +    memset(K, 0, sizeof(K));
454 +}
455 +
456 +/*
457 + * plaintext -> ciphertext (or vice versa)
458 + */
459 +void
460 +arcfour_encrypt(arcfour_context *context, const unsigned char *in, unsigned len,
461 +               unsigned char *out)
462 +{
463 +    unsigned i = context->i;
464 +    unsigned j = context->j;
465 +    unsigned char *S = context->S;
466 +    unsigned char K;
467 +
468 +    while (len--) {
469 +       i = (i + 1) % 256;
470 +       j = (j + S[i]) % 256;
471 +       swap(S[i], S[j]);
472 +       K = S[(S[i] + S[j]) % 256];
473 +       *out++ = *in++ ^ K;
474 +    }
475 +
476 +    context->i = i;
477 +    context->j = j;
478 +}
479 --- /dev/null   2004-04-06 13:56:48.000000000 -0400
480 +++ linux-2.4.20/drivers/net/ppp_mppe_crypto.h  2005-01-07 02:57:48.415153952 -0500
481 @@ -0,0 +1,40 @@
482 +/*
483 + * ppp_mppe_crypto.h - cryptografic funtion prototypes for MPPE
484 + *
485 + *  This code is Public Domain. Please see comments below.
486 + *
487 + *  I have just put SHA1 and ARCFOUR declarations into one file
488 + *  in order to not pollute kernel namespace. 
489 + *
490 + *  Jan Dubiec <jdx@slackware.pl>, 2003-07-08
491 + */
492 +
493 +#ifndef _PPP_MPPE_CRYPTO_
494 +#define _PPP_MPPE_CRYPTO_
495 +
496 +/* SHA1 definitions and prototypes */
497 +typedef struct {
498 +    unsigned long state[5];
499 +    unsigned long count[2];
500 +    unsigned char buffer[64];
501 +} SHA1_CTX;
502 +
503 +#define SHA1_SIGNATURE_SIZE 20
504 +
505 +extern void SHA1_Init(SHA1_CTX *);
506 +extern void SHA1_Update(SHA1_CTX *, const unsigned char *, unsigned int);
507 +extern void SHA1_Final(unsigned char[SHA1_SIGNATURE_SIZE], SHA1_CTX *);
508 +
509 +/* ARCFOUR (aka RC4) definitions and prototypes */
510 +typedef struct {
511 +    unsigned i;
512 +    unsigned j;
513 +    unsigned char S[256];
514 +} arcfour_context;
515 +
516 +extern void arcfour_setkey(arcfour_context *, const unsigned char *, unsigned);
517 +extern void arcfour_encrypt(arcfour_context *, const unsigned char *, unsigned,
518 +                           unsigned char *);
519 +#define arcfour_decrypt arcfour_encrypt
520 +
521 +#endif /* _PPP_MPPE_CRYPTO_ */
522 --- /dev/null   2004-04-06 13:56:48.000000000 -0400
523 +++ linux-2.4.20/drivers/net/ppp_mppe_mppc_comp.c       2005-01-07 02:57:48.417153648 -0500
524 @@ -0,0 +1,1144 @@
525 +/*
526 + * ppp_mppe_mppc_comp.c - MPPC/MPPE "compressor/decompressor" module.
527 + *
528 + * Copyright (c) 1994 Árpád Magosányi <mag@bunuel.tii.matav.hu>
529 + * Copyright (c) 1999 Tim Hockin, Cobalt Networks Inc. <thockin@cobaltnet.com>
530 + * Copyright (c) 2002, 2003 Jan Dubiec <jdx@slackware.pl>
531 + * 
532 + * Permission to use, copy, modify, and distribute this software and its
533 + * documentation is hereby granted, provided that the above copyright
534 + * notice appears in all copies. This software is provided without any
535 + * warranty, express or implied.
536 + *
537 + * The code is based on MPPE kernel module written by Árpád Magosányi and
538 + * Tim Hockin which can be found on http://planetmirror.com/pub/mppe/.
539 + * I have added MPPC and 56 bit session keys support in MPPE.
540 + *
541 + * WARNING! Although this is open source code, its usage in some countries
542 + * (in particular in the USA) may violate Stac Inc. patent for MPPC.
543 + *
544 + * Compile command:
545 + * gcc -O2 -Wall -I/usr/src/linux/include -D__KERNEL__ -DMODULE -c ppp_mppe_mppc_comp.c
546 + *
547 + *  ==FILEVERSION 20030807==
548 + *
549 + */
550 +
551 +#include <linux/module.h>
552 +#include <linux/slab.h>
553 +#include <linux/vmalloc.h>
554 +#include <linux/init.h>
555 +
556 +#include <linux/ppp_defs.h>
557 +#include <linux/ppp-comp.h>
558 +
559 +#include "ppp_mppe_crypto.h"
560 +
561 +/*
562 + * State for a mppc/mppe "(de)compressor".
563 + */
564 +struct ppp_mppe_state {
565 +    arcfour_context arcfour_context;
566 +    u8         master_key[MPPE_MAX_KEY_LEN];
567 +    u8         session_key[MPPE_MAX_KEY_LEN];
568 +    u8         mppc;           /* do we use compression (MPPC)? */
569 +    u8         mppe;           /* do we use encryption (MPPE)? */
570 +    u8         keylen;         /* key length in bytes */
571 +    u8         bitkeylen;      /* key length in bits */
572 +    u16                ccount;         /* coherency counter */
573 +    u16                bits;           /* MPPC/MPPE control bits */
574 +    u8         stateless;      /* do we use stateless mode? */
575 +    u8         nextflushed;    /* set A bit in the next outgoing packet;
576 +                                  used only by compressor*/
577 +    u8         flushexpected;  /* drop packets until A bit is received;
578 +                                  used only by decompressor*/
579 +    u8         *hist;          /* MPPC history */
580 +    u16                *hash;          /* Hash table; used only by compressor */
581 +    u16                histptr;        /* history "cursor" */
582 +    int                unit;
583 +    int                debug;
584 +    int                mru;
585 +    struct compstat stats;
586 +};
587 +
588 +#define MPPE_OVHD              2       /* MPPE overhead */
589 +#define MPPE_HIST_LEN          8192    /* MPPC history size */
590 +#define MPPE_MAX_CCOUNT                0x0FFF  /* max. coherency counter value */
591 +
592 +#define MPPE_BIT_FLUSHED       0x80    /* bit A */
593 +#define MPPE_BIT_RESET         0x40    /* bit B */
594 +#define MPPE_BIT_COMP          0x20    /* bit C */
595 +#define MPPE_BIT_ENCRYPTED     0x10    /* bit D */
596 +
597 +#define MPPE_SALT0             0xD1    /* values used in MPPE key derivation */
598 +#define MPPE_SALT1             0x26    /* according to RFC3079 */
599 +#define MPPE_SALT2             0x9E
600 +
601 +#define MPPE_CCOUNT(x)         ((((x)[4] & 0x0f) << 8) + (x)[5])
602 +#define MPPE_BITS(x)           ((x)[4] & 0xf0)
603 +#define MPPE_CTRLHI(x)         ((((x)->ccount & 0xf00)>>8)|((x)->bits))
604 +#define MPPE_CTRLLO(x)         ((x)->ccount & 0xff)
605 +
606 +/*
607 + * Key Derivation, from RFC 3078, RFC 3079.
608 + * Equivalent to Get_Key() for MS-CHAP as described in RFC 3079.
609 + */
610 +static void
611 +GetNewKeyFromSHA(unsigned char *MasterKey, unsigned char *SessionKey,
612 +                unsigned long SessionKeyLength, unsigned char *InterimKey)
613 +{
614 +    /*Pads used in key derivation */
615 +    static unsigned char  SHAPad1[40] =
616 +    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
617 +      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
618 +      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
619 +      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
620 +
621 +    static unsigned char  SHAPad2[40] =
622 +    { 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2,
623 +      0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2,
624 +      0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2,
625 +      0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2 };
626 +
627 +    SHA1_CTX Context;
628 +    unsigned char Digest[SHA1_SIGNATURE_SIZE];
629 +
630 +    SHA1_Init(&Context);
631 +    SHA1_Update(&Context, MasterKey, SessionKeyLength);
632 +    SHA1_Update(&Context, SHAPad1, sizeof(SHAPad1));
633 +    SHA1_Update(&Context, SessionKey, SessionKeyLength);
634 +    SHA1_Update(&Context, SHAPad2, sizeof(SHAPad2));
635 +    SHA1_Final(Digest,&Context);
636 +    memcpy(InterimKey, Digest, SessionKeyLength);
637 +}
638 +
639 +static void
640 +mppe_change_key(struct ppp_mppe_state *state, int initialize)
641 +{
642 +    unsigned char InterimKey[MPPE_MAX_KEY_LEN];
643 +
644 +    GetNewKeyFromSHA(state->master_key, state->session_key,
645 +                    state->keylen, InterimKey);
646 +    if (initialize) {
647 +       memcpy(state->session_key, InterimKey, state->keylen);
648 +    } else {
649 +       arcfour_setkey(&state->arcfour_context, InterimKey, state->keylen);
650 +       arcfour_encrypt(&state->arcfour_context, InterimKey, state->keylen,
651 +                       state->session_key);
652 +    }
653 +    if (state->keylen == 8) {
654 +       if (state->bitkeylen == 40) {
655 +           state->session_key[0] = MPPE_SALT0;
656 +           state->session_key[1] = MPPE_SALT1;
657 +           state->session_key[2] = MPPE_SALT2;
658 +       } else {
659 +           state->session_key[0] = MPPE_SALT0;
660 +       }
661 +    }
662 +    arcfour_setkey(&state->arcfour_context, state->session_key, state->keylen);
663 +}
664 +
665 +/* increase 12-bit coherency counter */
666 +static inline void
667 +mppe_increase_ccount(struct ppp_mppe_state *state)
668 +{
669 +    state->ccount = (state->ccount + 1) & MPPE_MAX_CCOUNT;
670 +    if (state->mppe) {
671 +       if (state->stateless) {
672 +           mppe_change_key(state, 0);
673 +           state->nextflushed = 1;
674 +       } else {
675 +           if ((state->ccount & 0xff) == 0xff) {
676 +               mppe_change_key(state, 0);
677 +               state->nextflushed = 1;
678 +           }
679 +       }
680 +    }
681 +}
682 +
683 +/* allocate space for a MPPE/MPPC (de)compressor.  */
684 +/*   comp != 0 -> init compressor */
685 +/*   comp = 0 -> init decompressor */
686 +static void *
687 +mppe_alloc(unsigned char *options, int opt_len, int comp)
688 +{
689 +    struct ppp_mppe_state *state;
690 +    u8* fname;
691 +
692 +    fname = comp ? "mppe_comp_alloc" : "mppe_decomp_alloc";
693 +
694 +    /*  
695 +       Hack warning - additionally to the standard MPPC/MPPE configuration
696 +       options, pppd passes to the (de)copressor 8 or 16 byte session key.
697 +       Therefore options[1] contains MPPC/MPPE configuration option length
698 +       (CILEN_MPPE = 6), but the real options length, depending on the key
699 +       length, is 6+8 or 6+16.
700 +    */
701 +    if (opt_len < CILEN_MPPE) {
702 +       printk(KERN_WARNING "%s: wrong options length: %u\n", fname, opt_len);
703 +       return NULL;
704 +    }
705 +
706 +    if (options[0] != CI_MPPE || options[1] != CILEN_MPPE ||
707 +       (options[2] & ~MPPE_STATELESS) != 0 ||
708 +       options[3] != 0 || options[4] != 0 ||
709 +       (options[5] & ~(MPPE_128BIT|MPPE_56BIT|MPPE_40BIT|MPPE_MPPC)) != 0 ||
710 +       (options[5] & (MPPE_128BIT|MPPE_56BIT|MPPE_40BIT|MPPE_MPPC)) == 0) {
711 +       printk(KERN_WARNING "%s: options rejected: o[0]=%02x, o[1]=%02x, "
712 +              "o[2]=%02x, o[3]=%02x, o[4]=%02x, o[5]=%02x\n", fname, options[0],
713 +              options[1], options[2], options[3], options[4], options[5]);
714 +       return NULL;
715 +    }
716 +
717 +    state = (struct ppp_mppe_state *)kmalloc(sizeof(*state), GFP_KERNEL);
718 +    if (state == NULL) {
719 +       printk(KERN_ERR "%s: cannot allocate space for %scompressor\n", fname,
720 +              comp ? "" : "de");
721 +       return NULL;
722 +    }
723 +    memset(state, 0, sizeof(struct ppp_mppe_state));
724 +
725 +    state->mppc = options[5] & MPPE_MPPC;      /* Do we use MPPC? */
726 +    state->mppe = options[5] & (MPPE_128BIT | MPPE_56BIT |
727 +       MPPE_40BIT);                            /* Do we use MPPE? */
728 +
729 +    if (state->mppc) {
730 +       /* allocate MPPC history */
731 +       state->hist = (u8*)vmalloc(2*MPPE_HIST_LEN*sizeof(u8));
732 +       if (state->hist == NULL) {
733 +           kfree(state);
734 +           printk(KERN_ERR "%s: cannot allocate space for MPPC history\n",
735 +                  fname);
736 +           return NULL;
737 +       }
738 +
739 +       /* allocate hashtable for MPPC compressor */
740 +       if (comp) {
741 +           state->hash = (u16*)vmalloc(MPPE_HIST_LEN*sizeof(u16));
742 +           if (state->hash == NULL) {
743 +               vfree(state->hist);
744 +               kfree(state);
745 +               printk(KERN_ERR "%s: cannot allocate space for MPPC history\n",
746 +                      fname);
747 +               return NULL;
748 +           }
749 +       }
750 +    }
751 +
752 +    MOD_INC_USE_COUNT;
753 +
754 +    if (state->mppe) { /* specific for MPPE */
755 +       memcpy(state->master_key, options+CILEN_MPPE, MPPE_MAX_KEY_LEN);
756 +       memcpy(state->session_key, state->master_key, MPPE_MAX_KEY_LEN);
757 +       /* initial key generation is done in mppe_init() */
758 +    }
759 +
760 +    return (void *) state;
761 +}
762 +
763 +static void *
764 +mppe_comp_alloc(unsigned char *options, int opt_len)
765 +{
766 +    return mppe_alloc(options, opt_len, 1);
767 +}
768 +
769 +static void *
770 +mppe_decomp_alloc(unsigned char *options, int opt_len)
771 +{
772 +    return mppe_alloc(options, opt_len, 0);
773 +}
774 +
775 +/* cleanup the (de)compressor */
776 +static void
777 +mppe_comp_free(void *arg)
778 +{
779 +    struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
780 +
781 +    if (state != NULL) {
782 +       if (state->hist != NULL)
783 +           vfree(state->hist);
784 +       if (state->hash != NULL)
785 +           vfree(state->hash);
786 +       kfree(state);
787 +    }
788 +    MOD_DEC_USE_COUNT;
789 +}
790 +
791 +/* init MPPC/MPPE (de)compresor */
792 +/*   comp != 0 -> init compressor */
793 +/*   comp = 0 -> init decompressor */
794 +static int
795 +mppe_init(void *arg, unsigned char *options, int opt_len, int unit,
796 +         int hdrlen, int mru, int debug, int comp)
797 +{
798 +    struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
799 +    u8* fname;
800 +
801 +    fname = comp ? "mppe_comp_init" : "mppe_decomp_init";
802 +
803 +    if (opt_len < CILEN_MPPE) {
804 +       if (debug)
805 +           printk(KERN_WARNING "%s: wrong options length: %u\n",
806 +                  fname, opt_len);
807 +       return 0;
808 +    }
809 +
810 +    if (options[0] != CI_MPPE || options[1] != CILEN_MPPE ||
811 +       (options[2] & ~MPPE_STATELESS) != 0 ||
812 +       options[3] != 0 || options[4] != 0 ||
813 +       (options[5] & ~(MPPE_56BIT|MPPE_128BIT|MPPE_40BIT|MPPE_MPPC)) != 0 ||
814 +       (options[5] & (MPPE_56BIT|MPPE_128BIT|MPPE_40BIT|MPPE_MPPC)) == 0) {
815 +       if (debug)
816 +           printk(KERN_WARNING "%s: options rejected: o[0]=%02x, o[1]=%02x, "
817 +                  "o[2]=%02x, o[3]=%02x, o[4]=%02x, o[5]=%02x\n", fname,
818 +                  options[0], options[1], options[2], options[3], options[4],
819 +                  options[5]);
820 +       return 0;
821 +    }
822 +
823 +    if ((options[5] & ~MPPE_MPPC) != MPPE_128BIT &&
824 +       (options[5] & ~MPPE_MPPC) != MPPE_56BIT &&
825 +       (options[5] & ~MPPE_MPPC) != MPPE_40BIT &&
826 +       (options[5] & MPPE_MPPC) != MPPE_MPPC) {
827 +       if (debug)
828 +           printk(KERN_WARNING "%s: don't know what to do: o[5]=%02x\n",
829 +                  fname, options[5]);
830 +       return 0;
831 +    }
832 +
833 +    state->mppc = options[5] & MPPE_MPPC;      /* Do we use MPPC? */
834 +    state->mppe = options[5] & (MPPE_128BIT | MPPE_56BIT |
835 +       MPPE_40BIT);                            /* Do we use MPPE? */
836 +    state->stateless = options[2] & MPPE_STATELESS; /* Do we use stateless mode? */
837 +
838 +    switch (state->mppe) {
839 +    case MPPE_40BIT:     /* 40 bit key */
840 +       state->keylen = 8;
841 +       state->bitkeylen = 40;
842 +       break;
843 +    case MPPE_56BIT:     /* 56 bit key */
844 +       state->keylen = 8;
845 +       state->bitkeylen = 56;
846 +       break;
847 +    case MPPE_128BIT:     /* 128 bit key */
848 +       state->keylen = 16;
849 +       state->bitkeylen = 128;
850 +       break;
851 +    default:
852 +       state->keylen = 0;
853 +       state->bitkeylen = 0;
854 +    }
855 +
856 +    state->ccount = MPPE_MAX_CCOUNT;
857 +    state->bits = 0;
858 +    state->unit  = unit;
859 +    state->debug = debug;
860 +    state->histptr = MPPE_HIST_LEN;
861 +    if (state->mppc) { /* reset history if MPPC was negotiated */
862 +       memset(state->hist, 0, 2*MPPE_HIST_LEN*sizeof(u8));
863 +    }
864 +
865 +    if (state->mppe) { /* generate initial session keys */
866 +       mppe_change_key(state, 1);
867 +    }
868 +
869 +    if (comp) { /* specific for compressor */
870 +       state->nextflushed = 1;
871 +    } else { /* specific for decompressor */
872 +       state->mru = mru;
873 +       state->flushexpected = 1;
874 +    }
875 +
876 +    return 1;
877 +}
878 +
879 +static int
880 +mppe_comp_init(void *arg, unsigned char *options, int opt_len, int unit,
881 +              int hdrlen, int debug)
882 +{
883 +    return mppe_init(arg, options, opt_len, unit, hdrlen, 0, debug, 1);
884 +}
885 +
886 +
887 +static int
888 +mppe_decomp_init(void *arg, unsigned char *options, int opt_len, int unit,
889 +                int hdrlen, int mru, int debug)
890 +{
891 +    return mppe_init(arg, options, opt_len, unit, hdrlen, mru, debug, 0);
892 +}
893 +
894 +static void
895 +mppe_comp_reset(void *arg)
896 +{
897 +    struct ppp_mppe_state *state = (struct ppp_mppe_state *)arg;
898 +
899 +    if (state->debug)
900 +       printk(KERN_DEBUG "%s%d: resetting MPPC/MPPE compressor\n",
901 +              __FUNCTION__, state->unit);
902 +
903 +    state->nextflushed = 1;
904 +    if (state->mppe)
905 +       arcfour_setkey(&state->arcfour_context, state->session_key,
906 +                      state->keylen);
907 +}
908 +
909 +static void
910 +mppe_decomp_reset(void *arg)
911 +{
912 +    /* When MPPC/MPPE is in use, we shouldn't receive any CCP Reset-Ack.
913 +       But when we receive such a packet, we just ignore it. */
914 +    return;
915 +}
916 +
917 +static void
918 +mppe_stats(void *arg, struct compstat *stats)
919 +{
920 +    struct ppp_mppe_state *state = (struct ppp_mppe_state *)arg;
921 +
922 +    *stats = state->stats;
923 +}
924 +
925 +/***************************/
926 +/**** Compression stuff ****/
927 +/***************************/
928 +/* inserts 1 to max. 8 bits into the output buffer */
929 +static inline void putbits8(u8 *buf, u32 val, const u32 n, u32 *i, u32 *l)
930 +{
931 +    buf += *i;
932 +    if (*l >= n) {
933 +       *l = (*l) - n;
934 +       val <<= *l;
935 +       *buf = *buf | (val & 0xff);
936 +       if (*l == 0) {
937 +           *l = 8;
938 +           (*i)++;
939 +           *(++buf) = 0;
940 +       }
941 +    } else {
942 +       (*i)++;
943 +       *l = 8 - n + (*l);
944 +       val <<= *l;
945 +       *buf = *buf | ((val >> 8) & 0xff);
946 +       *(++buf) = val & 0xff;
947 +    }
948 +}
949 +
950 +/* inserts 9 to max. 16 bits into the output buffer */
951 +static inline void putbits16(u8 *buf, u32 val, const u32 n, u32 *i, u32 *l)
952 +{
953 +    buf += *i;
954 +    if (*l >= n - 8) {
955 +       (*i)++;
956 +       *l = 8 - n + (*l);
957 +       val <<= *l;
958 +       *buf = *buf | ((val >> 8) & 0xff);
959 +       *(++buf) = val & 0xff;
960 +       if (*l == 0) {
961 +           *l = 8;
962 +           (*i)++;
963 +           *(++buf) = 0;
964 +       }
965 +    } else {
966 +       (*i)++; (*i)++;
967 +       *l = 16 - n + (*l);
968 +       val <<= *l;
969 +       *buf = *buf | ((val >> 16) & 0xff);
970 +       *(++buf) = (val >> 8) & 0xff;
971 +       *(++buf) = val & 0xff;
972 +    }
973 +}
974 +
975 +/* inserts 17 to max. 24 bits into the output buffer */
976 +static inline void putbits24(u8 *buf, u32 val, const u32 n, u32 *i, u32 *l)
977 +{
978 +    buf += *i;
979 +    if (*l >= n - 16) {
980 +       (*i)++; (*i)++;
981 +       *l = 16 - n + (*l);
982 +       val <<= *l;
983 +       *buf = *buf | ((val >> 16) & 0xff);
984 +       *(++buf) = (val >> 8) & 0xff;
985 +       *(++buf) = val & 0xff;
986 +       if (*l == 0) {
987 +           *l = 8;
988 +           (*i)++;
989 +           *(++buf) = 0;
990 +       }
991 +    } else {
992 +       (*i)++; (*i)++; (*i)++;
993 +       *l = 24 - n + (*l);
994 +       val <<= *l;
995 +       *buf = *buf | ((val >> 24) & 0xff);
996 +       *(++buf) = (val >> 16) & 0xff;
997 +       *(++buf) = (val >> 8) & 0xff;
998 +       *(++buf) = val & 0xff;
999 +    }
1000 +}
1001 +
1002 +static int
1003 +mppc_compress(struct ppp_mppe_state *state, unsigned char *ibuf,
1004 +             unsigned char *obuf, int isize, int osize)
1005 +{
1006 +    u32 olen, off, len, idx, i, l;
1007 +    u8 *hist, *sbuf, *p, *q, *r, *s;
1008 +
1009 +    /*  
1010 +       At this point, to avoid possible buffer overflow caused by packet
1011 +       expansion during/after compression,  we should make sure that
1012 +       osize >= (((isize*9)/8)+1)+2, but we don't do that because in
1013 +       ppp_generic.c we just allocate bigger obuf.
1014 +
1015 +       Maximum MPPC packet expansion is 12.5%. This is the worst case when
1016 +       all octets in the input buffer are >= 0x80 and we cannot find any
1017 +       repeated tokens. Additionally we have to reserve 2 bytes for MPPE/MPPC
1018 +       status bits and coherency counter.
1019 +    */
1020 +
1021 +    hist = state->hist + MPPE_HIST_LEN;
1022 +    /* check if there is enough room at the end of the history */
1023 +    if (state->histptr + isize >= 2*MPPE_HIST_LEN) {
1024 +       state->bits |= MPPE_BIT_RESET;
1025 +       state->histptr = MPPE_HIST_LEN;
1026 +       memcpy(state->hist, hist, MPPE_HIST_LEN);
1027 +    }
1028 +    /* add packet to the history; isize must be <= MPPE_HIST_LEN */
1029 +    sbuf = state->hist + state->histptr;
1030 +    memcpy(sbuf, ibuf, isize);
1031 +    state->histptr += isize;
1032 +
1033 +    /* compress data */
1034 +    r = sbuf + isize;
1035 +    *obuf = olen = i = 0;
1036 +    l = 8;
1037 +    while (i < isize - 2) {
1038 +       s = q = sbuf + i;
1039 +       idx = ((40542*((((s[0]<<4)^s[1])<<4)^s[2]))>>4) & 0x1FFF;
1040 +       p = hist + state->hash[idx];
1041 +       state->hash[idx] = (u16) (s - hist);
1042 +       off = s - p;
1043 +       if (off > 8191 || off < 1 || *p++ != *s++ || *p++ != *s++ || *p++ != *s++)
1044 +           goto literal;
1045 +       if (r - q >= 64) {
1046 +           *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ ||
1047 +           *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ ||
1048 +           *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ ||
1049 +           *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ ||
1050 +           *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ ||
1051 +           *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ ||
1052 +           *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ ||
1053 +           *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ ||
1054 +           *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ ||
1055 +           *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ ||
1056 +           *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ ||
1057 +           *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ ||
1058 +           *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ ||
1059 +           *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ ||
1060 +           *p++ != *s++ || *p++ != *s++ || *p++ != *s++ || *p++ != *s++ ||
1061 +           *p++ != *s++;
1062 +           if (s - q == 64) {
1063 +               p--; s--;
1064 +               while((*p++ == *s++) && (s < r));
1065 +           }
1066 +       } else {
1067 +           while((*p++ == *s++) && (s < r));
1068 +       }
1069 +       len = s - q - 1;
1070 +       i += len;
1071 +
1072 +       /* at least 3 character match found; code data */
1073 +       /* encode offset */
1074 +       if (off < 64) {                 /* 10-bit offset; 0 <= offset < 64 */
1075 +           putbits16(obuf, 0x3c0|off, 10, &olen, &l);
1076 +       } else if (off < 320) {         /* 12-bit offset; 64 <= offset < 320 */
1077 +           putbits16(obuf, 0xe00|(off-64), 12, &olen, &l);
1078 +       } else if (off < 8192) {        /* 16-bit offset; 320 <= offset < 8192 */
1079 +           putbits16(obuf, 0xc000|(off-320), 16, &olen, &l);
1080 +       } else {
1081 +           /* This shouldn't happen; we return 0 what means "packet expands",
1082 +           and we send packet uncompressed. */
1083 +           if (state->debug)
1084 +               printk(KERN_DEBUG "%s%d: wrong offset value: %d\n",
1085 +                      __FUNCTION__, state->unit, off);
1086 +           return 0;
1087 +       }
1088 +       /* encode length of match */
1089 +       if (len < 4) {                  /* length = 3 */
1090 +           putbits8(obuf, 0, 1, &olen, &l);
1091 +       } else if (len < 8) {           /* 4 <= length < 8 */
1092 +           putbits8(obuf, 0x08|(len&0x03), 4, &olen, &l);
1093 +       } else if (len < 16) {          /* 8 <= length < 16 */
1094 +           putbits8(obuf, 0x30|(len&0x07), 6, &olen, &l);
1095 +       } else if (len < 32) {          /* 16 <= length < 32 */
1096 +           putbits8(obuf, 0xe0|(len&0x0f), 8, &olen, &l);
1097 +       } else if (len < 64) {          /* 32 <= length < 64 */
1098 +           putbits16(obuf, 0x3c0|(len&0x1f), 10, &olen, &l);
1099 +       } else if (len < 128) {         /* 64 <= length < 128 */
1100 +           putbits16(obuf, 0xf80|(len&0x3f), 12, &olen, &l);
1101 +       } else if (len < 256) {         /* 128 <= length < 256 */
1102 +           putbits16(obuf, 0x3f00|(len&0x7f), 14, &olen, &l);
1103 +       } else if (len < 512) {         /* 256 <= length < 512 */
1104 +           putbits16(obuf, 0xfe00|(len&0xff), 16, &olen, &l);
1105 +       } else if (len < 1024) {        /* 512 <= length < 1024 */
1106 +           putbits24(obuf, 0x3fc00|(len&0x1ff), 18, &olen, &l);
1107 +       } else if (len < 2048) {        /* 1024 <= length < 2048 */
1108 +           putbits24(obuf, 0xff800|(len&0x3ff), 20, &olen, &l);
1109 +       } else if (len < 4096) {        /* 2048 <= length < 4096 */
1110 +           putbits24(obuf, 0x3ff000|(len&0x7ff), 22, &olen, &l);
1111 +       } else if (len < 8192) {        /* 4096 <= length < 8192 */
1112 +           putbits24(obuf, 0xffe000|(len&0xfff), 24, &olen, &l);
1113 +       } else {
1114 +           /* This shouldn't happen; we return 0 what means "packet expands",
1115 +           and send packet uncompressed. */
1116 +           if (state->debug)
1117 +               printk(KERN_DEBUG "%s%d: wrong length of match value: %d\n",
1118 +                      __FUNCTION__, state->unit, len);
1119 +           return 0;
1120 +       }
1121 +       continue;
1122 +
1123 +    literal:
1124 +       /* no match found; encode literal byte */
1125 +       if (ibuf[i] < 0x80) {           /* literal byte < 0x80 */
1126 +           putbits8(obuf, (u32) ibuf[i++], 8, &olen, &l);
1127 +       } else {                        /* literal byte >= 0x80 */
1128 +           putbits16(obuf, (u32) (0x100|(ibuf[i++]&0x7f)), 9, &olen, &l);
1129 +       }
1130 +    }
1131 +
1132 +    /* Add remaining octets to the output */
1133 +    while(isize - i > 0) {
1134 +       if (ibuf[i] < 0x80) {   /* literal byte < 0x80 */
1135 +           putbits8(obuf, (u32) ibuf[i++], 8, &olen, &l);
1136 +       } else {                /* literal byte >= 0x80 */
1137 +           putbits16(obuf, (u32) (0x100|(ibuf[i++]&0x7f)), 9, &olen, &l);
1138 +       }
1139 +    }
1140 +    /* Reset unused bits of the last output octet */
1141 +    if ((l != 0) && (l != 8)) {
1142 +       putbits8(obuf, 0, l, &olen, &l);
1143 +    }
1144 +
1145 +    return (int) olen;
1146 +}
1147 +
1148 +int
1149 +mppe_compress(void *arg, unsigned char *ibuf, unsigned char *obuf,
1150 +             int isize, int osize)
1151 +{
1152 +    struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
1153 +    int proto, olen, complen;
1154 +    unsigned char *wptr;
1155 +
1156 +    /* Check that the protocol is in the range we handle. */
1157 +    proto = PPP_PROTOCOL(ibuf);
1158 +    if (proto < 0x0021 || proto > 0x00fa)
1159 +       return 0;
1160 +
1161 +    wptr = obuf;
1162 +    /* Copy over the PPP header */
1163 +    wptr[0] = PPP_ADDRESS(ibuf);
1164 +    wptr[1] = PPP_CONTROL(ibuf);
1165 +    wptr[2] = PPP_COMP >> 8;
1166 +    wptr[3] = PPP_COMP;
1167 +    wptr += PPP_HDRLEN + MPPE_OVHD; /* Leave two octets for MPPE/MPPC bits */
1168 +
1169 +    mppe_increase_ccount(state);
1170 +
1171 +    if (state->nextflushed) {
1172 +       if (!state->stateless) {
1173 +           state->nextflushed = 0;
1174 +       }
1175 +       state->bits |= MPPE_BIT_FLUSHED;
1176 +       if (state->mppc) { /* reset history */
1177 +           state->bits |= MPPE_BIT_RESET;
1178 +           state->histptr = MPPE_HIST_LEN;
1179 +           memset(state->hist + MPPE_HIST_LEN, 0, MPPE_HIST_LEN*sizeof(u8));
1180 +       }
1181 +    }
1182 +
1183 +    if (state->mppc && !state->mppe) { /* Do only compression */
1184 +       complen = mppc_compress(state, ibuf+2, wptr, isize-2,
1185 +                               osize-PPP_HDRLEN-MPPE_OVHD);
1186 +       if ((complen > isize) || (complen == 0)) {
1187 +           /* packet expands */
1188 +           state->nextflushed = 1;
1189 +           memcpy(wptr, ibuf+2, isize-2);
1190 +           olen = isize + (PPP_HDRLEN / 2) + MPPE_OVHD;
1191 +           (state->stats).inc_bytes += olen;
1192 +           (state->stats).inc_packets++;
1193 +       } else {
1194 +           state->bits |= MPPE_BIT_COMP;
1195 +           olen = complen + PPP_HDRLEN + MPPE_OVHD;
1196 +           (state->stats).comp_bytes += olen;
1197 +           (state->stats).comp_packets++;
1198 +       }
1199 +    } else {
1200 +       if (!state->mppc && state->mppe) { /* Do only encryption */
1201 +           /* read from ibuf, write to wptr, adjust for PPP_HDRLEN */
1202 +           arcfour_encrypt(&state->arcfour_context, ibuf+2, isize-2, wptr);
1203 +           state->bits |= MPPE_BIT_ENCRYPTED;
1204 +           olen = isize + (PPP_HDRLEN / 2) + MPPE_OVHD;
1205 +           (state->stats).inc_bytes += olen;
1206 +           (state->stats).inc_packets++;
1207 +       } else { /* Do compression and then encryption - RFC3078 */
1208 +           complen = mppc_compress(state, ibuf+2, wptr, isize-2,
1209 +                                   osize-PPP_HDRLEN-MPPE_OVHD);
1210 +           if ((complen > isize) || (complen == 0)) {
1211 +               /* packet expands */
1212 +               memcpy(wptr, ibuf+2, isize-2);
1213 +               state->nextflushed = 1;
1214 +               arcfour_encrypt(&state->arcfour_context, ibuf+2, isize-2, wptr);
1215 +               olen = isize + (PPP_HDRLEN / 2) + MPPE_OVHD;
1216 +               (state->stats).inc_bytes += olen;
1217 +               (state->stats).inc_packets++;
1218 +           } else {
1219 +               state->bits |= MPPE_BIT_COMP;
1220 +               /* Hack warning !!! RC4 implementation which we use does
1221 +                  encryption "in place" - it means that input and output
1222 +                  buffers can be *the same* memory area. Therefore we don't
1223 +                  need to use a temporary buffer. But be careful - other
1224 +                  implementations don't have to be so nice.
1225 +                  I used to use ibuf as temporary buffer here, but it led
1226 +                  packet sniffers into error. Thanks to Wilfried Weissmann
1227 +                  for pointing that. */
1228 +               arcfour_encrypt(&state->arcfour_context, wptr, complen, wptr);
1229 +               olen = complen + PPP_HDRLEN + MPPE_OVHD;
1230 +               (state->stats).comp_bytes += olen;
1231 +               (state->stats).comp_packets++;
1232 +           }
1233 +           state->bits |= MPPE_BIT_ENCRYPTED;
1234 +       }
1235 +    }
1236 +
1237 +    /* write status bits and coherency counter into the output buffer */
1238 +    wptr = obuf + PPP_HDRLEN;
1239 +    wptr[0] = MPPE_CTRLHI(state);
1240 +    wptr[1] = MPPE_CTRLLO(state);
1241 +
1242 +    state->bits = 0;
1243 +
1244 +    (state->stats).unc_bytes += isize;
1245 +    (state->stats).unc_packets++;
1246 +
1247 +    return olen;
1248 +}
1249 +
1250 +/***************************/
1251 +/*** Decompression stuff ***/
1252 +/***************************/
1253 +static inline u32 getbits(const u8 *buf, const u32 n, u32 *i, u32 *l)
1254 +{
1255 +    static u32 m[] = {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
1256 +    u32 res, ol;
1257 +
1258 +    ol = *l;
1259 +    if (*l >= n) {
1260 +       *l = (*l) - n;
1261 +       res = (buf[*i] & m[ol]) >> (*l);
1262 +       if (*l == 0) {
1263 +           *l = 8;
1264 +           (*i)++;
1265 +       }
1266 +    } else {
1267 +       *l = 8 - n + (*l);
1268 +       res = (buf[(*i)++] & m[ol]) << 8;
1269 +       res = (res | buf[*i]) >> (*l);
1270 +    }
1271 +
1272 +    return res;
1273 +}
1274 +
1275 +static inline u32 getbyte(const u8 *buf, const u32 i, const u32 l)
1276 +{
1277 +    if (l == 8) {
1278 +       return buf[i];
1279 +    } else {
1280 +       return (((buf[i] << 8) | buf[i+1]) >> l) & 0xff;
1281 +    }
1282 +}
1283 +
1284 +static inline void lamecopy(u8 *dst, u8 *src, u32 len)
1285 +{
1286 +    while (len--)
1287 +       *dst++ = *src++;
1288 +}
1289 +
1290 +static int
1291 +mppc_decompress(struct ppp_mppe_state *state, unsigned char *ibuf,
1292 +               unsigned char *obuf, int isize, int osize)
1293 +{
1294 +    u32 olen, off, len, bits, val, sig, i, l;
1295 +    u8 *history, *s;
1296 +
1297 +    history = state->hist + state->histptr;
1298 +    olen = len = i = 0;
1299 +    l = 8;
1300 +    bits = isize * 8;
1301 +    while (bits >= 8) {
1302 +       val = getbyte(ibuf, i++, l);
1303 +       if (val < 0x80) {               /* literal byte < 0x80 */
1304 +           if (state->histptr < 2*MPPE_HIST_LEN) {
1305 +               /* copy uncompressed byte to the history */
1306 +               (state->hist)[(state->histptr)++] = (u8) val;
1307 +           } else {
1308 +               /* buffer overflow; drop packet */
1309 +               if (state->debug)
1310 +                   printk(KERN_ERR "%s%d: trying to write outside history "
1311 +                          "buffer\n", __FUNCTION__, state->unit);
1312 +               return DECOMP_ERROR;
1313 +           }
1314 +           olen++;
1315 +           bits -= 8;
1316 +           continue;
1317 +       }
1318 +
1319 +       sig = val & 0xc0;
1320 +       if (sig == 0x80) {              /* literal byte >= 0x80 */
1321 +           if (state->histptr < 2*MPPE_HIST_LEN) {
1322 +               /* copy uncompressed byte to the history */
1323 +               (state->hist)[(state->histptr)++] = 
1324 +                   (u8) (0x80|((val&0x3f)<<1)|getbits(ibuf, 1 , &i ,&l));
1325 +           } else {
1326 +               /* buffer overflow; drop packet */
1327 +               if (state->debug)
1328 +                   printk(KERN_ERR "%s%d: trying to write outside history "
1329 +                          "buffer\n", __FUNCTION__, state->unit);
1330 +               return DECOMP_ERROR;
1331 +           }
1332 +           olen++;
1333 +           bits -= 9;
1334 +           continue;
1335 +       }
1336 +
1337 +       /* Not a literal byte so it must be an (offset,length) pair */
1338 +       /* decode offset */
1339 +       sig = val & 0xf0;
1340 +       if (sig == 0xf0) {              /* 10-bit offset; 0 <= offset < 64 */
1341 +           off = (((val&0x0f)<<2)|getbits(ibuf, 2 , &i ,&l));
1342 +           bits -= 10;
1343 +       } else {
1344 +           if (sig == 0xe0) {          /* 12-bit offset; 64 <= offset < 320 */
1345 +               off = ((((val&0x0f)<<4)|getbits(ibuf, 4 , &i ,&l))+64);
1346 +               bits -= 12;
1347 +           } else {
1348 +               if ((sig&0xe0) == 0xc0) {/* 16-bit offset; 320 <= offset < 8192 */
1349 +                   off = ((((val&0x1f)<<8)|getbyte(ibuf, i++, l))+320);
1350 +                   bits -= 16;
1351 +                   if (off > MPPE_HIST_LEN - 1) {
1352 +                       if (state->debug)
1353 +                           printk(KERN_DEBUG "%s%d: too big offset value: %d\n",
1354 +                                  __FUNCTION__, state->unit, off);
1355 +                       return DECOMP_ERROR;
1356 +                   }
1357 +               } else {                /* this shouldn't happen */
1358 +                   if (state->debug)
1359 +                       printk(KERN_DEBUG "%s%d: cannot decode offset value\n",
1360 +                              __FUNCTION__, state->unit);
1361 +                   return DECOMP_ERROR;
1362 +               }
1363 +           }
1364 +       }
1365 +       /* decode length of match */
1366 +       val = getbyte(ibuf, i, l);
1367 +       if ((val & 0x80) == 0x00) {                     /* len = 3 */
1368 +           len = 3;
1369 +           bits--;
1370 +           getbits(ibuf, 1 , &i ,&l);
1371 +       } else if ((val & 0xc0) == 0x80) {              /* 4 <= len < 8 */
1372 +           len = 0x04 | ((val>>4) & 0x03);
1373 +           bits -= 4;
1374 +           getbits(ibuf, 4 , &i ,&l);
1375 +       } else if ((val & 0xe0) == 0xc0) {              /* 8 <= len < 16 */
1376 +           len = 0x08 | ((val>>2) & 0x07);
1377 +           bits -= 6;
1378 +           getbits(ibuf, 6 , &i ,&l);
1379 +       } else if ((val & 0xf0) == 0xe0) {              /* 16 <= len < 32 */
1380 +           len = 0x10 | (val & 0x0f);
1381 +           bits -= 8;
1382 +           i++;
1383 +       } else {
1384 +           bits -= 8;
1385 +           val = (val << 8) | getbyte(ibuf, ++i, l);
1386 +           if ((val & 0xf800) == 0xf000) {             /* 32 <= len < 64 */
1387 +               len = 0x0020 | ((val >> 6) & 0x001f);
1388 +               bits -= 2;
1389 +               getbits(ibuf, 2 , &i ,&l);
1390 +           } else if ((val & 0xfc00) == 0xf800) {      /* 64 <= len < 128 */
1391 +               len = 0x0040 | ((val >> 4) & 0x003f);
1392 +               bits -= 4;
1393 +               getbits(ibuf, 4 , &i ,&l);
1394 +           } else if ((val & 0xfe00) == 0xfc00) {      /* 128 <= len < 256 */
1395 +               len = 0x0080 | ((val >> 2) & 0x007f);
1396 +               bits -= 6;
1397 +               getbits(ibuf, 6 , &i ,&l);
1398 +           } else if ((val & 0xff00) == 0xfe00) {      /* 256 <= len < 512 */
1399 +               len = 0x0100 | (val & 0x00ff);
1400 +               bits -= 8;
1401 +               i++;
1402 +           } else {
1403 +               bits -= 8;
1404 +               val = (val << 8) | getbyte(ibuf, ++i, l);
1405 +               if ((val & 0xff8000) == 0xff0000) {     /* 512 <= len < 1024 */
1406 +                   len = 0x000200 | ((val >> 6) & 0x0001ff);
1407 +                   bits -= 2;
1408 +                   getbits(ibuf, 2 , &i ,&l);
1409 +               } else if ((val & 0xffc000) == 0xff8000) {/* 1024 <= len < 2048 */
1410 +                   len = 0x000400 | ((val >> 4) & 0x0003ff);
1411 +                   bits -= 4;
1412 +                   getbits(ibuf, 4 , &i ,&l);
1413 +               } else if ((val & 0xffe000) == 0xffc000) {/* 2048 <= len < 4096 */
1414 +                   len = 0x000800 | ((val >> 2) & 0x0007ff);
1415 +                   bits -= 6;
1416 +                   getbits(ibuf, 6 , &i ,&l);
1417 +               } else if ((val & 0xfff000) == 0xffe000) {/* 4096 <= len < 8192 */
1418 +                   len = 0x001000 | (val & 0x000fff);
1419 +                   bits -= 8;
1420 +                   i++;
1421 +               } else {                                /* this shouldn't happen */
1422 +                   if (state->debug)
1423 +                       printk(KERN_DEBUG "%s%d: wrong length code: 0x%X\n",
1424 +                              __FUNCTION__, state->unit, val);
1425 +                   return DECOMP_ERROR;
1426 +               }
1427 +           }
1428 +       }
1429 +       s = state->hist + state->histptr;
1430 +       state->histptr += len;
1431 +       olen += len;
1432 +       if (state->histptr < 2*MPPE_HIST_LEN) {
1433 +           /* copy uncompressed bytes to the history */
1434 +
1435 +           /* In some cases len may be greater than off. It means that memory
1436 +            * areas pointed by s and s-off overlap. I used to use memmove()
1437 +            * here, because I thought that it acts as libc's version. But
1438 +            * I was wrong. I got strange errors sometimes. Wilfried suggested
1439 +            * using of byte by byte copying here and strange errors disappeared.
1440 +            */
1441 +           lamecopy(s, s-off, len);
1442 +       } else {
1443 +           /* buffer overflow; drop packet */
1444 +           if (state->debug)
1445 +               printk(KERN_ERR "%s%d: trying to write outside history "
1446 +                      "buffer\n", __FUNCTION__, state->unit);
1447 +           return DECOMP_ERROR;
1448 +       }
1449 +    }
1450 +
1451 +    if (olen <= osize) {
1452 +       /* copy uncompressed packet to the output buffer */
1453 +       memcpy(obuf, history, olen);
1454 +    } else {
1455 +       /* buffer overflow; drop packet */
1456 +       if (state->debug)
1457 +           printk(KERN_ERR "%s%d: too big uncompressed packet: %d\n",
1458 +                  __FUNCTION__, state->unit, olen+(PPP_HDRLEN/2));
1459 +       return DECOMP_ERROR;
1460 +    }
1461 +
1462 +    return (int) olen;
1463 +}
1464 +
1465 +int
1466 +mppe_decompress(void *arg, unsigned char *ibuf, int isize,
1467 +               unsigned char *obuf, int osize)
1468 +{
1469 +    struct ppp_mppe_state *state = (struct ppp_mppe_state *)arg;
1470 +    int seq, bits, uncomplen;
1471 +
1472 +    if (isize <= PPP_HDRLEN + MPPE_OVHD) {
1473 +       if (state->debug) {
1474 +           printk(KERN_DEBUG "%s%d: short packet (len=%d)\n",  __FUNCTION__,
1475 +                  state->unit, isize);
1476 +       }
1477 +       return DECOMP_ERROR;
1478 +    }
1479 +
1480 +    /* Get coherency counter and control bits from input buffer */
1481 +    seq = MPPE_CCOUNT(ibuf);
1482 +    bits = MPPE_BITS(ibuf);
1483 +
1484 +    if (state->stateless) {
1485 +       /* RFC 3078, sec 8.1. */
1486 +       mppe_increase_ccount(state);
1487 +       if ((seq != state->ccount) && state->debug)
1488 +           printk(KERN_DEBUG "%s%d: bad sequence number: %d, expected: %d\n",
1489 +                  __FUNCTION__, state->unit, seq, state->ccount);
1490 +       while (seq != state->ccount)
1491 +           mppe_increase_ccount(state);
1492 +    } else {
1493 +       /* RFC 3078, sec 8.2. */
1494 +       if (state->flushexpected) { /* discard state */
1495 +           if ((bits & MPPE_BIT_FLUSHED)) { /* we received expected FLUSH bit */
1496 +               while (seq != state->ccount)
1497 +                   mppe_increase_ccount(state);
1498 +               state->flushexpected = 0;
1499 +           } else /* drop packet*/
1500 +               return DECOMP_ERROR;
1501 +       } else { /* normal state */
1502 +           mppe_increase_ccount(state);
1503 +           if (seq != state->ccount) {
1504 +               /* Packet loss detected, enter the discard state. */
1505 +               if (state->debug)
1506 +                   printk(KERN_DEBUG "%s%d: bad sequence number: %d, expected: %d\n",
1507 +                          __FUNCTION__, state->unit, seq, state->ccount);
1508 +               state->flushexpected = 1;
1509 +               return DECOMP_ERROR;
1510 +           }
1511 +       }
1512 +       if (state->mppe && (bits & MPPE_BIT_FLUSHED)) {
1513 +           arcfour_setkey(&state->arcfour_context, state->session_key,
1514 +                          state->keylen);
1515 +       }
1516 +    }
1517 +
1518 +    if (state->mppc && (bits & (MPPE_BIT_FLUSHED | MPPE_BIT_RESET))) {
1519 +       state->histptr = MPPE_HIST_LEN;
1520 +       if ((bits & MPPE_BIT_FLUSHED)) {
1521 +           memset(state->hist + MPPE_HIST_LEN, 0, MPPE_HIST_LEN*sizeof(u8));
1522 +       } else
1523 +           if ((bits & MPPE_BIT_RESET)) {
1524 +               memcpy(state->hist, state->hist+MPPE_HIST_LEN, MPPE_HIST_LEN);
1525 +           }
1526 +    }
1527 +
1528 +    /* Fill in the first part of the PPP header. The protocol field
1529 +       comes from the decompressed data. */
1530 +    obuf[0] = PPP_ADDRESS(ibuf);
1531 +    obuf[1] = PPP_CONTROL(ibuf);
1532 +    obuf += PPP_HDRLEN / 2;
1533 +
1534 +    if (state->mppe) { /* process encrypted packet */
1535 +       if ((bits & MPPE_BIT_ENCRYPTED)) {
1536 +           /* OK, packet encrypted, so decrypt it */
1537 +           if (state->mppc && (bits & MPPE_BIT_COMP)) {
1538 +               /* Hack warning !!! RC4 implementation which we use does
1539 +                  decryption "in place" - it means that input and output
1540 +                  buffers can be *the same* memory area. Therefore we don't
1541 +                  need to use a temporary buffer. But be careful - other
1542 +                  implementations don't have to be so nice. */
1543 +               arcfour_decrypt(&state->arcfour_context, ibuf+PPP_HDRLEN+MPPE_OVHD,
1544 +                               isize-PPP_HDRLEN-MPPE_OVHD, ibuf+PPP_HDRLEN+MPPE_OVHD);
1545 +               uncomplen = mppc_decompress(state, ibuf+PPP_HDRLEN+MPPE_OVHD,
1546 +                                           obuf, isize-PPP_HDRLEN-MPPE_OVHD,
1547 +                                           osize-(PPP_HDRLEN/2));
1548 +               if (uncomplen == DECOMP_ERROR) {
1549 +                   state->flushexpected = 1;
1550 +                   return DECOMP_ERROR;
1551 +               }
1552 +               uncomplen += PPP_HDRLEN / 2;
1553 +               (state->stats).comp_bytes += isize;
1554 +               (state->stats).comp_packets++;
1555 +           } else {
1556 +               arcfour_decrypt(&state->arcfour_context, ibuf+PPP_HDRLEN+MPPE_OVHD,
1557 +                               isize-PPP_HDRLEN-MPPE_OVHD, obuf);
1558 +               uncomplen = isize - (PPP_HDRLEN / 2) - MPPE_OVHD;
1559 +               (state->stats).inc_bytes += isize;
1560 +               (state->stats).inc_packets++;
1561 +           }
1562 +       } else { /* this shouldn't happen */
1563 +           if (state->debug)
1564 +               printk(KERN_ERR "%s%d: encryption negotiated but not an "
1565 +                      "encrypted packet received\n", __FUNCTION__, state->unit);
1566 +           mppe_change_key(state, 0);
1567 +           state->flushexpected = 1;
1568 +           return DECOMP_ERROR;
1569 +       }
1570 +    } else {
1571 +       if (state->mppc) { /* no MPPE, only MPPC */
1572 +           if ((bits & MPPE_BIT_COMP)) {
1573 +               uncomplen = mppc_decompress(state, ibuf+PPP_HDRLEN+MPPE_OVHD,
1574 +                                           obuf, isize-PPP_HDRLEN-MPPE_OVHD,
1575 +                                           osize-(PPP_HDRLEN/2));
1576 +               if (uncomplen == DECOMP_ERROR) {
1577 +                   state->flushexpected = 1;
1578 +                   return DECOMP_ERROR;
1579 +               }
1580 +               uncomplen += PPP_HDRLEN / 2;
1581 +               (state->stats).comp_bytes += isize;
1582 +               (state->stats).comp_packets++;
1583 +           } else {
1584 +               memcpy(obuf, ibuf+PPP_HDRLEN+MPPE_OVHD,
1585 +                      isize-PPP_HDRLEN-MPPE_OVHD);
1586 +               uncomplen = isize - (PPP_HDRLEN / 2) - MPPE_OVHD;
1587 +               (state->stats).inc_bytes += isize;
1588 +               (state->stats).inc_packets++;
1589 +           }
1590 +       } else { /* this shouldn't happen */
1591 +           if (state->debug)
1592 +               printk(KERN_ERR "%s%d: error - no MPPC nor MPPE negotiated\n",
1593 +                      __FUNCTION__, state->unit);
1594 +           state->flushexpected = 1;
1595 +           return DECOMP_ERROR;
1596 +       }
1597 +    }
1598 +
1599 +    (state->stats).unc_bytes += uncomplen;
1600 +    (state->stats).unc_packets++;
1601 +
1602 +    return uncomplen;
1603 +}
1604 +
1605 +
1606 +/************************************************************
1607 + * Module interface table
1608 + ************************************************************/
1609 +
1610 +/* These are in ppp_generic.c */
1611 +extern int  ppp_register_compressor   (struct compressor *cp);
1612 +extern void ppp_unregister_compressor (struct compressor *cp);
1613 +
1614 +/*
1615 + * Functions exported to ppp_generic.c.
1616 + */
1617 +struct compressor ppp_mppe = {
1618 +    CI_MPPE,           /* compress_proto */
1619 +    mppe_comp_alloc,   /* comp_alloc */
1620 +    mppe_comp_free,    /* comp_free */
1621 +    mppe_comp_init,    /* comp_init */
1622 +    mppe_comp_reset,   /* comp_reset */
1623 +    mppe_compress,     /* compress */
1624 +    mppe_stats,                /* comp_stat */
1625 +    mppe_decomp_alloc, /* decomp_alloc */
1626 +    mppe_comp_free,    /* decomp_free */
1627 +    mppe_decomp_init,  /* decomp_init */
1628 +    mppe_decomp_reset, /* decomp_reset */
1629 +    mppe_decompress,   /* decompress */
1630 +    NULL,              /* incomp */
1631 +    mppe_stats,                /* decomp_stat */
1632 +};
1633 +
1634 +/*
1635 +  In case of MPPC/MPPE there is no need to process incompressible data
1636 +  because such a data is sent in MPPC/MPPE frame. Therefore the (*incomp)
1637 +  callback function isn't needed.
1638 +*/
1639 +
1640 +/************************************************************
1641 + * Module support routines
1642 + ************************************************************/
1643 +
1644 +int __init mppe_module_init(void)
1645 +{
1646 +    int answer = ppp_register_compressor(&ppp_mppe);
1647 +    if (answer == 0) {
1648 +       printk(KERN_INFO "MPPE/MPPC encryption/compression module registered\n");
1649 +    }
1650 +    return answer;
1651 +}
1652 +
1653 +void __exit mppe_module_cleanup(void)
1654 +{
1655 +    if (MOD_IN_USE) {
1656 +       printk (KERN_INFO "MPPE/MPPC module busy, removing delayed\n");
1657 +    } else {
1658 +       ppp_unregister_compressor (&ppp_mppe);
1659 +       printk(KERN_INFO "MPPE/MPPC encryption/compression module unregistered\n");
1660 +    }
1661 +}
1662 +
1663 +module_init(mppe_module_init);
1664 +module_exit(mppe_module_cleanup);
1665 +
1666 +MODULE_AUTHOR("Jan Dubiec <jdx@slackware.pl>");
1667 +MODULE_DESCRIPTION("MPPE/MPPC encryption/compression module for Linux");
1668 +MODULE_LICENSE("Dual BSD/GPL");
1669 --- linux-2.4.20/include/linux/ppp-comp.h~150-mppe-mppc-0.98    1999-08-06 13:44:11.000000000 -0400
1670 +++ linux-2.4.20/include/linux/ppp-comp.h       2005-01-07 02:58:08.293132040 -0500
1671 @@ -24,7 +24,7 @@
1672   * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
1673   * OR MODIFICATIONS.
1674   *
1675 - * $Id: ppp-comp.h,v 1.6 1997/11/27 06:04:44 paulus Exp $
1676 + * $Id: ppp-comp.h,v 1.10 2002/12/06 09:49:15 paulus Exp $
1677   */
1678  
1679  /*
1680 @@ -78,7 +78,7 @@
1681  
1682         /* Compress a packet */
1683         int     (*compress) (void *state, unsigned char *rptr,
1684 -                             unsigned char *obuf, int isize, int osize);
1685 +                            unsigned char *obuf, int isize, int osize);
1686  
1687         /* Return compression statistics */
1688         void    (*comp_stat) (void *state, struct compstat *stats);
1689 @@ -99,7 +99,7 @@
1690  
1691         /* Decompress a packet. */
1692         int     (*decompress) (void *state, unsigned char *ibuf, int isize,
1693 -                               unsigned char *obuf, int osize);
1694 +                              unsigned char *obuf, int osize);
1695  
1696         /* Update state for an incompressible packet received */
1697         void    (*incomp) (void *state, unsigned char *ibuf, int icnt);
1698 @@ -187,6 +187,127 @@
1699  #define DEFLATE_CHK_SEQUENCE   0
1700  
1701  /*
1702 + * Definitions for MPPE.
1703 + */
1704 +
1705 +#define CI_MPPE                        18      /* config option for MPPE */
1706 +#define CILEN_MPPE             6       /* length of config option */
1707 +
1708 +#define MPPE_PAD               4       /* MPPE growth per frame */
1709 +#define MPPE_MAX_KEY_LEN       16      /* largest key length (128-bit) */
1710 +
1711 +/* option bits for ccp_options.mppe */
1712 +#define MPPE_OPT_40            0x01    /* 40 bit */
1713 +#define MPPE_OPT_128           0x02    /* 128 bit */
1714 +#define MPPE_OPT_STATEFUL      0x04    /* stateful mode */
1715 +/* unsupported opts */
1716 +#define MPPE_OPT_56            0x08    /* 56 bit */
1717 +#define MPPE_OPT_MPPC          0x10    /* MPPC compression */
1718 +#define MPPE_OPT_D             0x20    /* Unknown */
1719 +#define MPPE_OPT_UNSUPPORTED (MPPE_OPT_56|MPPE_OPT_MPPC|MPPE_OPT_D)
1720 +#define MPPE_OPT_UNKNOWN       0x40    /* Bits !defined in RFC 3078 were set */
1721 +
1722 +/*
1723 + * This is not nice ... the alternative is a bitfield struct though.
1724 + * And unfortunately, we cannot share the same bits for the option
1725 + * names above since C and H are the same bit.  We could do a u_int32
1726 + * but then we have to do a htonl() all the time and/or we still need
1727 + * to know which octet is which.
1728 + */
1729 +#define MPPE_C_BIT             0x01    /* MPPC */
1730 +#define MPPE_D_BIT             0x10    /* Obsolete, usage unknown */
1731 +#define MPPE_L_BIT             0x20    /* 40-bit */
1732 +#define MPPE_S_BIT             0x40    /* 128-bit */
1733 +#define MPPE_M_BIT             0x80    /* 56-bit, not supported */
1734 +#define MPPE_H_BIT             0x01    /* Stateless (in a different byte) */
1735 +
1736 +/* Does not include H bit; used for least significant octet only. */
1737 +#define MPPE_ALL_BITS (MPPE_D_BIT|MPPE_L_BIT|MPPE_S_BIT|MPPE_M_BIT|MPPE_H_BIT)
1738 +
1739 +/* Build a CI from mppe opts (see RFC 3078) */
1740 +#define MPPE_OPTS_TO_CI(opts, ci)              \
1741 +    do {                                       \
1742 +       u_char *ptr = ci; /* u_char[4] */       \
1743 +                                               \
1744 +       /* H bit */                             \
1745 +       if (opts & MPPE_OPT_STATEFUL)           \
1746 +           *ptr++ = 0x0;                       \
1747 +       else                                    \
1748 +           *ptr++ = MPPE_H_BIT;                \
1749 +       *ptr++ = 0;                             \
1750 +       *ptr++ = 0;                             \
1751 +                                               \
1752 +       /* S,L bits */                          \
1753 +       *ptr = 0;                               \
1754 +       if (opts & MPPE_OPT_128)                \
1755 +           *ptr |= MPPE_S_BIT;                 \
1756 +       if (opts & MPPE_OPT_40)                 \
1757 +           *ptr |= MPPE_L_BIT;                 \
1758 +       /* M,D,C bits not supported */          \
1759 +    } while (/* CONSTCOND */ 0)
1760 +
1761 +/* The reverse of the above */
1762 +#define MPPE_CI_TO_OPTS(ci, opts)              \
1763 +    do {                                       \
1764 +       u_char *ptr = ci; /* u_char[4] */       \
1765 +                                               \
1766 +       opts = 0;                               \
1767 +                                               \
1768 +       /* H bit */                             \
1769 +       if (!(ptr[0] & MPPE_H_BIT))             \
1770 +           opts |= MPPE_OPT_STATEFUL;          \
1771 +                                               \
1772 +       /* S,L bits */                          \
1773 +       if (ptr[3] & MPPE_S_BIT)                \
1774 +           opts |= MPPE_OPT_128;               \
1775 +       if (ptr[3] & MPPE_L_BIT)                \
1776 +           opts |= MPPE_OPT_40;                \
1777 +                                               \
1778 +       /* M,D,C bits */                        \
1779 +       if (ptr[3] & MPPE_M_BIT)                \
1780 +           opts |= MPPE_OPT_56;                \
1781 +       if (ptr[3] & MPPE_D_BIT)                \
1782 +           opts |= MPPE_OPT_D;                 \
1783 +       if (ptr[3] & MPPE_C_BIT)                \
1784 +           opts |= MPPE_OPT_MPPC;              \
1785 +                                               \
1786 +       /* Other bits */                        \
1787 +       if (ptr[0] & ~MPPE_H_BIT)               \
1788 +           opts |= MPPE_OPT_UNKNOWN;           \
1789 +       if (ptr[1] || ptr[2])                   \
1790 +           opts |= MPPE_OPT_UNKNOWN;           \
1791 +       if (ptr[3] & ~MPPE_ALL_BITS)            \
1792 +           opts |= MPPE_OPT_UNKNOWN;           \
1793 +    } while (/* CONSTCOND */ 0)
1794 +
1795 +/* MPPE/MPPC definitions by J.D.*/
1796 +#define MPPE_STATELESS          MPPE_H_BIT     /* configuration bit H */
1797 +#define MPPE_40BIT              MPPE_L_BIT     /* configuration bit L */
1798 +#define MPPE_56BIT              MPPE_M_BIT     /* configuration bit M */
1799 +#define MPPE_128BIT             MPPE_S_BIT     /* configuration bit S */
1800 +#define MPPE_MPPC               MPPE_C_BIT     /* configuration bit C */
1801 +
1802 +/*
1803 + * Definitions for Stac LZS.
1804 + */
1805 +
1806 +#define CI_LZS                 17      /* config option for Stac LZS */
1807 +#define CILEN_LZS              5       /* length of config option */
1808 +
1809 +#define LZS_OVHD               4       /* max. LZS overhead */
1810 +#define LZS_HIST_LEN           2048    /* LZS history size */
1811 +#define LZS_MAX_CCOUNT         0x0FFF  /* max. coherency counter value */
1812 +
1813 +#define LZS_MODE_NONE          0
1814 +#define LZS_MODE_LCB           1
1815 +#define LZS_MODE_CRC           2
1816 +#define LZS_MODE_SEQ           3
1817 +#define LZS_MODE_EXT           4
1818 +
1819 +#define LZS_EXT_BIT_FLUSHED    0x80    /* bit A */
1820 +#define LZS_EXT_BIT_COMP       0x20    /* bit C */
1821 +
1822 +/*
1823   * Definitions for other, as yet unsupported, compression methods.
1824   */
1825