]> pilppa.org Git - familiar-h63xx-build.git/blob - org.handhelds.familiar/packages/linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/mppe-20040216.patch
OE tree imported from monotone branch org.openembedded.oz354fam083 at revision 8b12e3...
[familiar-h63xx-build.git] / org.handhelds.familiar / packages / linux / opensimpad-2.4.25-vrs2-pxa1-jpm1 / mppe-20040216.patch
1
2 #
3 # Patch managed by http://www.holgerschurig.de/patcher.html
4 #
5
6 --- linux-2.4.25/drivers/net/Config.in~mppe-20040216
7 +++ linux-2.4.25/drivers/net/Config.in
8 @@ -327,6 +327,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 '  PPP MPPE compression (encryption)' 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 --- /dev/null
17 +++ linux-2.4.25/drivers/net/arcfour.c
18 @@ -0,0 +1,75 @@
19 +/*
20 + * arcfour.c
21 + * by Frank Cusack <frank@google.com>
22 + * 100% public domain
23 + *
24 + * Implemented from the description in _Applied Cryptography_, 2nd ed.
25 + *
26 + * ** Distribution ** of this software is unlimited and unrestricted.
27 + *
28 + * ** Use ** of this software is almost certainly legal; however, refer
29 + * to <http://theory.lcs.mit.edu/~rivest/faq.html>.
30 + */
31 +
32 +#include "arcfour.h"
33 +#if defined(__linux__)
34 +#include <linux/string.h>
35 +#endif
36 +
37 +#define swap(a, b)             \
38 +{                              \
39 +    unsigned char t = b;       \
40 +    b = a;                     \
41 +    a = t;                     \
42 +}
43 +
44 +/*
45 + * Initialize arcfour from a key.
46 + */
47 +void
48 +arcfour_setkey(arcfour_context *context, const unsigned char *key,
49 +              unsigned keylen)
50 +{
51 +    unsigned i, j;
52 +    unsigned char K[256];
53 +
54 +    context->i = context->j = 0;
55 +
56 +    for (i = 0; i < 256; i++) {
57 +       context->S[i] = i;
58 +       K[i] = key[i % keylen];
59 +    }
60 +
61 +    j = 0;
62 +    for (i = 0; i < 256; i++) {
63 +       j = (j + context->S[i] + K[i]) % 256;
64 +       swap(context->S[i], context->S[j]);
65 +    }
66 +
67 +    memset(K, 0, sizeof(K));
68 +}
69 +
70 +/*
71 + * plaintext -> ciphertext (or vice versa)
72 + */
73 +void
74 +arcfour_encrypt(arcfour_context *context, const unsigned char *in, unsigned len,
75 +               unsigned char *out)
76 +{
77 +    unsigned i = context->i;
78 +    unsigned j = context->j;
79 +    unsigned char *S = context->S;
80 +    unsigned char K;
81 +
82 +    while (len--) {
83 +       i = (i + 1) % 256;
84 +       j = (j + S[i]) % 256;
85 +       swap(S[i], S[j]);
86 +       K = S[(S[i] + S[j]) % 256];
87 +       *out++ = *in++ ^ K;
88 +    }
89 +
90 +    context->i = i;
91 +    context->j = j;
92 +}
93 +
94 --- /dev/null
95 +++ linux-2.4.25/drivers/net/arcfour.h
96 @@ -0,0 +1,17 @@
97 +/* arcfour.h */
98 +
99 +#ifndef _ARCFOUR_H
100 +#define _ARCFOUR_H
101 +
102 +typedef struct {
103 +    unsigned i;
104 +    unsigned j;
105 +    unsigned char S[256];
106 +} arcfour_context;
107 +
108 +extern void arcfour_setkey(arcfour_context *, const unsigned char *, unsigned);
109 +extern void arcfour_encrypt(arcfour_context *, const unsigned char *, unsigned,
110 +                           unsigned char *);
111 +#define arcfour_decrypt arcfour_encrypt
112 +
113 +#endif /* _ARCFOUR_H */
114 --- linux-2.4.25/drivers/net/ppp_generic.c~mppe-20040216
115 +++ linux-2.4.25/drivers/net/ppp_generic.c
116 @@ -102,6 +102,7 @@
117         spinlock_t      rlock;          /* lock for receive side 58 */
118         spinlock_t      wlock;          /* lock for transmit side 5c */
119         int             mru;            /* max receive unit 60 */
120 +       int             mru_alloc;      /* MAX(1500,MRU) for dev_alloc_skb() */
121         unsigned int    flags;          /* control bits 64 */
122         unsigned int    xstate;         /* transmit state bits 68 */
123         unsigned int    rstate;         /* receive state bits 6c */
124 @@ -129,6 +130,7 @@
125         struct sock_fprog pass_filter;  /* filter for packets to pass */
126         struct sock_fprog active_filter;/* filter for pkts to reset idle */
127  #endif /* CONFIG_PPP_FILTER */
128 +       int             xpad;           /* ECP or CCP (MPPE) transmit padding */
129  };
130  
131  /*
132 @@ -552,7 +554,9 @@
133         case PPPIOCSMRU:
134                 if (get_user(val, (int *) arg))
135                         break;
136 -               ppp->mru = val;
137 +               ppp->mru_alloc = ppp->mru = val;
138 +               if (ppp->mru_alloc < PPP_MRU)
139 +                   ppp->mru_alloc = PPP_MRU;   /* increase for broken peers */
140                 err = 0;
141                 break;
142  
143 @@ -1031,8 +1035,8 @@
144         /* try to do packet compression */
145         if ((ppp->xstate & SC_COMP_RUN) && ppp->xc_state != 0
146             && proto != PPP_LCP && proto != PPP_CCP) {
147 -               new_skb = alloc_skb(ppp->dev->mtu + ppp->dev->hard_header_len,
148 -                                   GFP_ATOMIC);
149 +               new_skb = alloc_skb(ppp->dev->mtu + ppp->dev->hard_header_len
150 +                                   + ppp->xpad, GFP_ATOMIC);
151                 if (new_skb == 0) {
152                         printk(KERN_ERR "PPP: no memory (comp pkt)\n");
153                         goto drop;
154 @@ -1044,15 +1048,28 @@
155                 /* compressor still expects A/C bytes in hdr */
156                 len = ppp->xcomp->compress(ppp->xc_state, skb->data - 2,
157                                            new_skb->data, skb->len + 2,
158 -                                          ppp->dev->mtu + PPP_HDRLEN);
159 +                                          ppp->dev->mtu + ppp->xpad
160 +                                          + PPP_HDRLEN);
161                 if (len > 0 && (ppp->flags & SC_CCP_UP)) {
162                         kfree_skb(skb);
163                         skb = new_skb;
164                         skb_put(skb, len);
165                         skb_pull(skb, 2);       /* pull off A/C bytes */
166 -               } else {
167 +               } else if (len == 0) {
168                         /* didn't compress, or CCP not up yet */
169                         kfree_skb(new_skb);
170 +               } else {
171 +                       /*
172 +                        * (len < 0)
173 +                        * MPPE requires that we do not send unencrypted
174 +                        * frames.  The compressor will return -1 if we
175 +                        * should drop the frame.  We cannot simply test
176 +                        * the compress_proto because MPPE and MPPC share
177 +                        * the same number.
178 +                        */
179 +                       printk(KERN_ERR "ppp: compressor dropped pkt\n");
180 +                       kfree_skb(new_skb);
181 +                       goto drop;
182                 }
183         }
184  
185 @@ -1540,14 +1557,15 @@
186         int len;
187  
188         if (proto == PPP_COMP) {
189 -               ns = dev_alloc_skb(ppp->mru + PPP_HDRLEN);
190 +               ns = dev_alloc_skb(ppp->mru_alloc + PPP_HDRLEN);
191                 if (ns == 0) {
192                         printk(KERN_ERR "ppp_decompress_frame: no memory\n");
193                         goto err;
194                 }
195                 /* the decompressor still expects the A/C bytes in the hdr */
196                 len = ppp->rcomp->decompress(ppp->rc_state, skb->data - 2,
197 -                               skb->len + 2, ns->data, ppp->mru + PPP_HDRLEN);
198 +                               skb->len + 2, ns->data,
199 +                               ppp->mru_alloc + PPP_HDRLEN);
200                 if (len < 0) {
201                         /* Pass the compressed frame to pppd as an
202                            error indication. */
203 @@ -1982,6 +2000,20 @@
204                                 ocomp->comp_free(ostate);
205                         err = 0;
206                 }
207 +               if (ccp_option[0] == CI_MPPE)
208 +                       /*
209 +                        * pppd (userland) has reduced the MTU by MPPE_PAD,
210 +                        * to accomodate "compressor" growth.  We must
211 +                        * increase the space allocated for compressor
212 +                        * output in ppp_send_frame() accordingly.  Note
213 +                        * that from a purist's view, it may be more correct
214 +                        * to require multilink and fragment large packets,
215 +                        * but that seems inefficient compared to this
216 +                        * little trick.
217 +                        */
218 +                       ppp->xpad = MPPE_PAD;
219 +               else
220 +                       ppp->xpad = 0;
221  
222         } else {
223                 state = cp->decomp_alloc(ccp_option, data.length);
224 @@ -2253,6 +2285,7 @@
225         /* Initialize the new ppp unit */
226         ppp->file.index = unit;
227         ppp->mru = PPP_MRU;
228 +       ppp->mru_alloc = PPP_MRU;
229         init_ppp_file(&ppp->file, INTERFACE);
230         ppp->file.hdrlen = PPP_HDRLEN - 2;      /* don't count proto bytes */
231         for (i = 0; i < NUM_NP; ++i)
232 --- /dev/null
233 +++ linux-2.4.25/drivers/net/ppp_mppe_compress.c
234 @@ -0,0 +1,643 @@
235 +/*
236 + *  ==FILEVERSION 20020521==
237 + *
238 + * ppp_mppe_compress.c - interface MPPE to the PPP code.
239 + * This version is for use with Linux kernel 2.2.19+ and 2.4.x.
240 + *
241 + * By Frank Cusack <frank@google.com>.
242 + * Copyright (c) 2002 Google, Inc.
243 + * All rights reserved.
244 + *
245 + * Permission to use, copy, modify, and distribute this software and its
246 + * documentation is hereby granted, provided that the above copyright
247 + * notice appears in all copies.  This software is provided without any
248 + * warranty, express or implied.
249 + *
250 + * Changelog:
251 + *      2/15/04 - TS: added #include <version.h> and testing for Kernel
252 + *                    version before using 
253 + *                    MOD_DEC_USAGE_COUNT/MOD_INC_USAGE_COUNT which are
254 + *                    depreciated in 2.6
255 + */
256 +
257 +#include <linux/module.h>
258 +#include <linux/kernel.h>
259 +#include <linux/version.h>
260 +#include <linux/init.h>
261 +#include <linux/types.h>
262 +#include <linux/slab.h>
263 +#include <linux/string.h>
264 +
265 +#include <linux/ppp_defs.h>
266 +#include <linux/ppp-comp.h>
267 +
268 +#include "arcfour.h"
269 +#include "sha1.h"
270 +
271 +/*
272 + * State for an MPPE (de)compressor.
273 + */
274 +typedef struct ppp_mppe_state {
275 +    unsigned char      master_key[MPPE_MAX_KEY_LEN];
276 +    unsigned char      session_key[MPPE_MAX_KEY_LEN];
277 +    arcfour_context    arcfour_context; /* encryption state */
278 +    unsigned           keylen;         /* key length in bytes             */
279 +                                       /* NB: 128-bit == 16, 40-bit == 8! */
280 +                                       /* If we want to support 56-bit,   */
281 +                                       /* the unit has to change to bits  */
282 +    unsigned char      bits;           /* MPPE control bits */
283 +    unsigned           ccount;         /* 12-bit coherency count (seqno)  */
284 +    unsigned           stateful;       /* stateful mode flag */
285 +    int                        discard;        /* stateful mode packet loss flag */
286 +    int                        sanity_errors;  /* take down LCP if too many */
287 +    int                        unit;
288 +    int                        debug;
289 +    struct compstat    stats;
290 +} ppp_mppe_state;
291 +
292 +/* ppp_mppe_state.bits definitions */
293 +#define MPPE_BIT_A     0x80    /* Encryption table were (re)inititalized */
294 +#define MPPE_BIT_B     0x40    /* MPPC only (not implemented) */
295 +#define MPPE_BIT_C     0x20    /* MPPC only (not implemented) */
296 +#define MPPE_BIT_D     0x10    /* This is an encrypted frame */
297 +
298 +#define MPPE_BIT_FLUSHED       MPPE_BIT_A
299 +#define MPPE_BIT_ENCRYPTED     MPPE_BIT_D
300 +
301 +#define MPPE_BITS(p) ((p)[4] & 0xf0)
302 +#define MPPE_CCOUNT(p) ((((p)[4] & 0x0f) << 8) + (p)[5])
303 +#define MPPE_CCOUNT_SPACE 0x1000       /* The size of the ccount space */
304 +
305 +#define MPPE_OVHD      2               /* MPPE overhead/packet */
306 +#define SANITY_MAX     1600            /* Max bogon factor we will tolerate */
307 +
308 +static void    GetNewKeyFromSHA __P((unsigned char *StartKey,
309 +                                     unsigned char *SessionKey,
310 +                                     unsigned SessionKeyLength,
311 +                                     unsigned char *InterimKey));
312 +static void    mppe_rekey __P((ppp_mppe_state *state, int));
313 +static void    *mppe_alloc __P((unsigned char *options, int optlen));
314 +static void    mppe_free __P((void *state));
315 +static int     mppe_init __P((void *state, unsigned char *options,
316 +                              int optlen, int unit, int debug, const char *));
317 +static int     mppe_comp_init __P((void *state, unsigned char *options,
318 +                                   int optlen,
319 +                                   int unit, int hdrlen, int debug));
320 +static int     mppe_decomp_init __P((void *state, unsigned char *options,
321 +                                     int optlen, int unit,
322 +                                     int hdrlen, int mru, int debug));
323 +static int     mppe_compress __P((void *state, unsigned char *ibuf,
324 +                                  unsigned char *obuf,
325 +                                  int isize, int osize));
326 +static void    mppe_incomp __P((void *state, unsigned char *ibuf, int icnt));
327 +static int     mppe_decompress __P((void *state, unsigned char *ibuf,
328 +                                    int isize, unsigned char *obuf,int osize));
329 +static void    mppe_comp_reset __P((void *state));
330 +static void    mppe_decomp_reset __P((void *state));
331 +static void    mppe_comp_stats __P((void *state, struct compstat *stats));
332 +
333 +
334 +/*
335 + * Key Derivation, from RFC 3078, RFC 3079.
336 + * Equivalent to Get_Key() for MS-CHAP as described in RFC 3079.
337 + */
338 +static void
339 +GetNewKeyFromSHA(unsigned char *MasterKey, unsigned char *SessionKey,
340 +                unsigned SessionKeyLength, unsigned char *InterimKey)
341 +{
342 +    SHA1_CTX Context;
343 +    unsigned char Digest[SHA1_SIGNATURE_SIZE];
344 +
345 +    unsigned char SHApad1[40] =
346 +    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
347 +      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
348 +      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
349 +      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
350 +    unsigned char SHApad2[40] =
351 +    { 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
352 +      0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
353 +      0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
354 +      0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2 };
355 +
356 +    /* assert(SessionKeyLength <= SHA1_SIGNATURE_SIZE); */
357 +
358 +    SHA1_Init(&Context);
359 +    SHA1_Update(&Context, MasterKey, SessionKeyLength);
360 +    SHA1_Update(&Context, SHApad1, sizeof(SHApad1));
361 +    SHA1_Update(&Context, SessionKey, SessionKeyLength);
362 +    SHA1_Update(&Context, SHApad2, sizeof(SHApad2));
363 +    SHA1_Final(Digest, &Context);
364 +
365 +    memcpy(InterimKey, Digest, SessionKeyLength);
366 +}
367 +
368 +/*
369 + * Perform the MPPE rekey algorithm, from RFC 3078, sec. 7.3.
370 + * Well, not what's written there, but rather what they meant.
371 + */
372 +static void
373 +mppe_rekey(ppp_mppe_state *state, int initial_key)
374 +{
375 +    unsigned char InterimKey[MPPE_MAX_KEY_LEN];
376 +
377 +    GetNewKeyFromSHA(state->master_key, state->session_key,
378 +                    state->keylen, InterimKey);
379 +    if (!initial_key) {
380 +       arcfour_setkey(&state->arcfour_context, InterimKey, state->keylen);
381 +       arcfour_encrypt(&state->arcfour_context, InterimKey, state->keylen,
382 +                       state->session_key);
383 +    } else {
384 +       memcpy(state->session_key, InterimKey, state->keylen);
385 +    }
386 +    if (state->keylen == 8) {
387 +       /* See RFC 3078 */
388 +       state->session_key[0] = 0xd1;
389 +       state->session_key[1] = 0x26;
390 +       state->session_key[2] = 0x9e;
391 +    }
392 +    arcfour_setkey(&state->arcfour_context, state->session_key, state->keylen);
393 +}
394 +
395 +
396 +/*
397 + * Allocate space for a (de)compressor.
398 + */
399 +static void *
400 +mppe_alloc(unsigned char *options, int optlen)
401 +{
402 +    ppp_mppe_state *state;
403 +
404 +    if (optlen != CILEN_MPPE + sizeof(state->master_key)
405 +       || options[0] != CI_MPPE
406 +       || options[1] != CILEN_MPPE)
407 +       return NULL;
408 +
409 +    state = (ppp_mppe_state *) kmalloc(sizeof(*state), GFP_KERNEL);
410 +    if (state == NULL)
411 +       return NULL;
412 +
413 +/* 
414 +   Added to avoid module warnings about MOD_INC 
415 +   being depreciated in 2.6.x 
416 +*/ 
417 +#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) )
418 +    try_module_get(THIS_MODULE);
419 +#else
420 +    MOD_INC_USE_COUNT;
421 +#endif
422 +    memset(state, 0, sizeof(*state));
423 +
424 +    /* Save keys. */
425 +    memcpy(state->master_key, &options[CILEN_MPPE], sizeof(state->master_key));
426 +    memcpy(state->session_key, state->master_key, sizeof(state->master_key));
427 +    /*
428 +     * We defer initial key generation until mppe_init(), as mppe_alloc()
429 +     * is called frequently during negotiation.
430 +     */
431 +
432 +    return (void *) state;
433 +}
434 +
435 +/*
436 + * Deallocate space for a (de)compressor.
437 + */
438 +static void
439 +mppe_free(void *arg)
440 +{
441 +    ppp_mppe_state *state = (ppp_mppe_state *) arg;
442 +
443 +    if (state) {
444 +       kfree(state);
445 +/* 
446 +   Added to avoid module warnings about MOD_DEC_USE_COUNT 
447 +   being depreciated in 2.6.x 
448 +*/ 
449 +#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) )
450 +        module_put(THIS_MODULE);
451 +#else
452 +       MOD_DEC_USE_COUNT;
453 +#endif
454 +    }
455 +}
456 +
457 +
458 +/* 
459 + * Initialize (de)compressor state.
460 + */
461 +static int
462 +mppe_init(void *arg, unsigned char *options, int optlen, int unit, int debug,
463 +         const char *debugstr)
464 +{
465 +    ppp_mppe_state *state = (ppp_mppe_state *) arg;
466 +    unsigned char mppe_opts;
467 +
468 +    if (optlen != CILEN_MPPE
469 +       || options[0] != CI_MPPE
470 +       || options[1] != CILEN_MPPE)
471 +       return 0;
472 +
473 +    MPPE_CI_TO_OPTS(&options[2], mppe_opts);
474 +    if (mppe_opts & MPPE_OPT_128)
475 +       state->keylen = 16;
476 +    else if (mppe_opts & MPPE_OPT_40)
477 +       state->keylen = 8;
478 +    else {
479 +       printk(KERN_WARNING "%s[%d]: unknown key length\n", debugstr, unit);
480 +       return 0;
481 +    }
482 +    if (mppe_opts & MPPE_OPT_STATEFUL)
483 +       state->stateful = 1;
484 +
485 +    /* Generate the initial session key. */
486 +    mppe_rekey(state, 1);
487 +
488 +    if (debug) {
489 +       int i;
490 +       char mkey[sizeof(state->master_key) * 2 + 1];
491 +       char skey[sizeof(state->session_key) * 2 + 1];
492 +
493 +       printk(KERN_DEBUG "%s[%d]: initialized with %d-bit %s mode\n", debugstr,
494 +              unit, (state->keylen == 16)? 128: 40,
495 +              (state->stateful)? "stateful": "stateless");
496 +
497 +       for (i = 0; i < sizeof(state->master_key); i++)
498 +           sprintf(mkey + i * 2, "%.2x", state->master_key[i]);
499 +       for (i = 0; i < sizeof(state->session_key); i++)
500 +           sprintf(skey + i * 2, "%.2x", state->session_key[i]);
501 +       printk(KERN_DEBUG "%s[%d]: keys: master: %s initial session: %s\n",
502 +              debugstr, unit, mkey, skey);
503 +    }
504 +
505 +    /*
506 +     * Initialize the coherency count.  The initial value is not specified
507 +     * in RFC 3078, but we can make a reasonable assumption that it will
508 +     * start at 0.  Setting it to the max here makes the comp/decomp code
509 +     * do the right thing (determined through experiment).
510 +     */
511 +    state->ccount = MPPE_CCOUNT_SPACE - 1;
512 +
513 +    /*
514 +     * Note that even though we have initialized the key table, we don't
515 +     * set the FLUSHED bit.  This is contrary to RFC 3078, sec. 3.1.
516 +     */
517 +    state->bits = MPPE_BIT_ENCRYPTED;
518 +
519 +    state->unit  = unit;
520 +    state->debug = debug;
521 +
522 +    return 1;
523 +}
524 +
525 +
526 +
527 +static int
528 +mppe_comp_init(void *arg, unsigned char *options, int optlen, int unit,
529 +              int hdrlen, int debug)
530 +{
531 +    /* ARGSUSED */
532 +    return mppe_init(arg, options, optlen, unit, debug, "mppe_comp_init");
533 +}
534 +
535 +/*
536 + * We received a CCP Reset-Request (actually, we are sending a Reset-Ack),
537 + * tell the compressor to rekey.  Note that we MUST NOT rekey for
538 + * every CCP Reset-Request; we only rekey on the next xmit packet.
539 + * We might get multiple CCP Reset-Requests if our CCP Reset-Ack is lost.
540 + * So, rekeying for every CCP Reset-Request is broken as the peer will not
541 + * know how many times we've rekeyed.  (If we rekey and THEN get another
542 + * CCP Reset-Request, we must rekey again.)
543 + */
544 +static void
545 +mppe_comp_reset(void *arg)
546 +{
547 +    ppp_mppe_state *state = (ppp_mppe_state *) arg;
548 +
549 +    state->bits |= MPPE_BIT_FLUSHED;
550 +}
551 +
552 +/*
553 + * Compress (encrypt) a packet.
554 + * It's strange to call this a compressor, since the output is always
555 + * MPPE_OVHD + 2 bytes larger than the input.
556 + */
557 +int
558 +mppe_compress(void *arg, unsigned char *ibuf, unsigned char *obuf,
559 +             int isize, int osize)
560 +{
561 +    ppp_mppe_state *state = (ppp_mppe_state *) arg;
562 +    int proto;
563 +
564 +    /*
565 +     * Check that the protocol is in the range we handle.
566 +     */
567 +    proto = PPP_PROTOCOL(ibuf);
568 +    if (proto < 0x0021 || proto > 0x00fa)
569 +       return 0;
570 +
571 +    /* Make sure we have enough room to generate an encrypted packet. */
572 +    if (osize < isize + MPPE_OVHD + 2) {
573 +       /* Drop the packet if we should encrypt it, but can't. */
574 +       printk(KERN_DEBUG "mppe_compress[%d]: osize too small! "
575 +              "(have: %d need: %d)\n", state->unit,
576 +              osize, osize + MPPE_OVHD + 2);
577 +       return -1;
578 +    }
579 +
580 +    osize = isize + MPPE_OVHD + 2;
581 +
582 +    /*
583 +     * Copy over the PPP header and set control bits.
584 +     */
585 +    obuf[0] = PPP_ADDRESS(ibuf);
586 +    obuf[1] = PPP_CONTROL(ibuf);
587 +    obuf[2] = PPP_COMP >> 8;           /* isize + MPPE_OVHD + 1 */
588 +    obuf[3] = PPP_COMP;                        /* isize + MPPE_OVHD + 2 */
589 +    obuf += PPP_HDRLEN;
590 +
591 +    state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE;
592 +    if (state->debug >= 7)
593 +       printk(KERN_DEBUG "mppe_compress[%d]: ccount %d\n", state->unit,
594 +              state->ccount);
595 +    obuf[0] = state->ccount >> 8;
596 +    obuf[1] = state->ccount & 0xff;
597 +
598 +    if (!state->stateful ||                    /* stateless mode     */
599 +       ((state->ccount & 0xff) == 0xff) ||     /* "flag" packet      */
600 +       (state->bits & MPPE_BIT_FLUSHED)) {     /* CCP Reset-Request  */
601 +       /* We must rekey */
602 +       if (state->debug && state->stateful)
603 +           printk(KERN_DEBUG "mppe_compress[%d]: rekeying\n", state->unit);
604 +       mppe_rekey(state, 0);
605 +       state->bits |= MPPE_BIT_FLUSHED;
606 +    }
607 +    obuf[0] |= state->bits;
608 +    state->bits &= ~MPPE_BIT_FLUSHED;  /* reset for next xmit */
609 +
610 +    obuf  += MPPE_OVHD;
611 +    ibuf  += 2;        /* skip to proto field */
612 +    isize -= 2;
613 +
614 +    /* Encrypt packet */
615 +    arcfour_encrypt(&state->arcfour_context, ibuf, isize, obuf);
616 +
617 +    state->stats.unc_bytes += isize;
618 +    state->stats.unc_packets++;
619 +    state->stats.comp_bytes += osize;
620 +    state->stats.comp_packets++;
621 +
622 +    return osize;
623 +}
624 +
625 +/*
626 + * Since every frame grows by MPPE_OVHD + 2 bytes, this is always going
627 + * to look bad ... and the longer the link is up the worse it will get.
628 + */
629 +static void
630 +mppe_comp_stats(void *arg, struct compstat *stats)
631 +{
632 +    ppp_mppe_state *state = (ppp_mppe_state *) arg;
633 +
634 +    *stats = state->stats;
635 +}
636 +
637 +
638 +static int
639 +mppe_decomp_init(void *arg, unsigned char *options, int optlen, int unit,
640 +                int hdrlen, int mru, int debug)
641 +{
642 +    /* ARGSUSED */
643 +    return mppe_init(arg, options, optlen, unit, debug, "mppe_decomp_init");
644 +}
645 +
646 +/*
647 + * We received a CCP Reset-Ack.  Just ignore it.
648 + */
649 +static void
650 +mppe_decomp_reset(void *arg)
651 +{
652 +    /* ARGSUSED */
653 +    return;
654 +}
655 +
656 +/*
657 + * Decompress (decrypt) an MPPE packet.
658 + */
659 +int
660 +mppe_decompress(void *arg, unsigned char *ibuf, int isize, unsigned char *obuf,
661 +               int osize)
662 +{
663 +    ppp_mppe_state *state = (ppp_mppe_state *) arg;
664 +    unsigned ccount;
665 +    int flushed = MPPE_BITS(ibuf) & MPPE_BIT_FLUSHED;
666 +    int sanity = 0;
667 +
668 +    if (isize <= PPP_HDRLEN + MPPE_OVHD) {
669 +       if (state->debug)
670 +           printk(KERN_DEBUG "mppe_decompress[%d]: short pkt (%d)\n",
671 +                  state->unit, isize);
672 +       return DECOMP_ERROR;
673 +    }
674 +
675 +    /* Make sure we have enough room to decrypt the packet. */
676 +    if (osize < isize - MPPE_OVHD - 2) {
677 +       printk(KERN_DEBUG "mppe_decompress[%d]: osize too small! "
678 +              "(have: %d need: %d)\n", state->unit,
679 +              osize, isize - MPPE_OVHD - 2);
680 +       return DECOMP_ERROR;
681 +    }
682 +    osize = isize - MPPE_OVHD - 2;
683 +
684 +    ccount = MPPE_CCOUNT(ibuf);
685 +    if (state->debug >= 7)
686 +       printk(KERN_DEBUG "mppe_decompress[%d]: ccount %d\n", state->unit,
687 +              ccount);
688 +
689 +    /* sanity checks -- terminate with extreme prejudice */
690 +    if (!(MPPE_BITS(ibuf) & MPPE_BIT_ENCRYPTED)) {
691 +       printk(KERN_DEBUG "mppe_decompress[%d]: ENCRYPTED bit not set!\n",
692 +              state->unit);
693 +       state->sanity_errors += 100;
694 +       sanity = 1;
695 +    }
696 +    if (!state->stateful && !flushed) {
697 +       printk(KERN_DEBUG "mppe_decompress[%d]: FLUSHED bit not set in "
698 +              "stateless mode!\n", state->unit);
699 +       state->sanity_errors += 100;
700 +       sanity = 1;
701 +    }
702 +    if (state->stateful && ((ccount & 0xff) == 0xff) && !flushed) {
703 +       printk(KERN_DEBUG "mppe_decompress[%d]: FLUSHED bit not set on "
704 +              "flag packet!\n", state->unit);
705 +       state->sanity_errors += 100;
706 +       sanity = 1;
707 +    }
708 +
709 +    if (sanity) {
710 +       if (state->sanity_errors < SANITY_MAX)
711 +           return DECOMP_ERROR;
712 +       else
713 +           /*
714 +            * Take LCP down if the peer is sending too many bogons.
715 +            * We don't want to do this for a single or just a few
716 +            * instances since it could just be due to packet corruption.
717 +            */
718 +           return DECOMP_FATALERROR;
719 +    }
720 +
721 +    /*
722 +     * Check the coherency count.
723 +     */
724 +
725 +    if (!state->stateful) {
726 +       /* RFC 3078, sec 8.1.  Rekey for every packet. */
727 +       while (state->ccount != ccount) {
728 +           mppe_rekey(state, 0);
729 +           state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE;
730 +       }
731 +    } else {
732 +       /* RFC 3078, sec 8.2. */
733 +       if (!state->discard) {
734 +           /* normal state */
735 +           state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE;
736 +           if (ccount != state->ccount) {
737 +               /*
738 +                * (ccount > state->ccount)
739 +                * Packet loss detected, enter the discard state.
740 +                * Signal the peer to rekey (by sending a CCP Reset-Request).
741 +                */
742 +               state->discard = 1;
743 +               return DECOMP_ERROR;
744 +           }
745 +       } else {
746 +           /* discard state */
747 +          if (!flushed) {
748 +               /* ccp.c will be silent (no additional CCP Reset-Requests). */
749 +               return DECOMP_ERROR;
750 +           } else {
751 +               /* Rekey for every missed "flag" packet. */
752 +               while ((ccount & ~0xff) != (state->ccount & ~0xff)) {
753 +                   mppe_rekey(state, 0);
754 +                   state->ccount = (state->ccount + 256) % MPPE_CCOUNT_SPACE;
755 +               }
756 +
757 +               /* reset */
758 +               state->discard = 0;
759 +               state->ccount = ccount;
760 +               /*
761 +                * Another problem with RFC 3078 here.  It implies that the
762 +                * peer need not send a Reset-Ack packet.  But RFC 1962
763 +                * requires it.  Hopefully, M$ does send a Reset-Ack; even
764 +                * though it isn't required for MPPE synchronization, it is
765 +                * required to reset CCP state.
766 +                */
767 +           }
768 +       }
769 +       if (flushed)
770 +           mppe_rekey(state, 0);
771 +    }
772 +
773 +    /*
774 +     * Fill in the first part of the PPP header.  The protocol field
775 +     * comes from the decrypted data.
776 +     */
777 +    obuf[0] = PPP_ADDRESS(ibuf);       /* +1 */
778 +    obuf[1] = PPP_CONTROL(ibuf);       /* +1 */
779 +    obuf  += 2;
780 +    ibuf  += PPP_HDRLEN + MPPE_OVHD;
781 +    isize -= PPP_HDRLEN + MPPE_OVHD;   /* -6 */
782 +                                       /* net osize: isize-4 */
783 +
784 +    /* And finally, decrypt the packet. */
785 +    arcfour_decrypt(&state->arcfour_context, ibuf, isize, obuf);
786 +
787 +    state->stats.unc_bytes += osize;
788 +    state->stats.unc_packets++;
789 +    state->stats.comp_bytes += isize;
790 +    state->stats.comp_packets++;
791 +
792 +    /* good packet credit */
793 +    state->sanity_errors >>= 1;
794 +
795 +    return osize;
796 +}
797 +
798 +/*
799 + * Incompressible data has arrived (this should never happen!).
800 + * We should probably drop the link if the protocol is in the range
801 + * of what should be encrypted.  At the least, we should drop this
802 + * packet.  (How to do this?)
803 + */
804 +static void
805 +mppe_incomp(void *arg, unsigned char *ibuf, int icnt)
806 +{
807 +    ppp_mppe_state *state = (ppp_mppe_state *) arg;
808 +
809 +    if (state->debug &&
810 +       (PPP_PROTOCOL(ibuf) >= 0x0021 && PPP_PROTOCOL(ibuf) <= 0x00fa))
811 +       printk(KERN_DEBUG "mppe_incomp[%d]: incompressible (unencrypted) data! "
812 +              "(proto %04x)\n", state->unit, PPP_PROTOCOL(ibuf));
813 +
814 +    state->stats.inc_bytes += icnt;
815 +    state->stats.inc_packets++;
816 +    state->stats.unc_bytes += icnt;
817 +    state->stats.unc_packets++;
818 +}
819 +
820 +/*************************************************************
821 + * Module interface table
822 + *************************************************************/
823 +
824 +/* These are in ppp.c (2.2.x) or ppp_generic.c (2.4.x) */
825 +extern int  ppp_register_compressor   (struct compressor *cp);
826 +extern void ppp_unregister_compressor (struct compressor *cp);
827 +
828 +/*
829 + * Procedures exported to if_ppp.c.
830 + */
831 +struct compressor ppp_mppe = {
832 +    CI_MPPE,           /* compress_proto */
833 +    mppe_alloc,                /* comp_alloc */
834 +    mppe_free,         /* comp_free */
835 +    mppe_comp_init,    /* comp_init */
836 +    mppe_comp_reset,   /* comp_reset */
837 +    mppe_compress,     /* compress */
838 +    mppe_comp_stats,   /* comp_stat */
839 +    mppe_alloc,                /* decomp_alloc */
840 +    mppe_free,         /* decomp_free */
841 +    mppe_decomp_init,  /* decomp_init */
842 +    mppe_decomp_reset, /* decomp_reset */
843 +    mppe_decompress,   /* decompress */
844 +    mppe_incomp,       /* incomp */
845 +    mppe_comp_stats,   /* decomp_stat */
846 +};
847 +
848 +/* 2.2 compatibility defines */
849 +#ifndef __init
850 +#define __init
851 +#endif
852 +#ifndef __exit
853 +#define __exit
854 +#endif
855 +#ifndef MODULE_LICENSE
856 +#define MODULE_LICENSE(license)
857 +#endif
858 +
859 +int __init
860 +ppp_mppe_init(void)
861 +{  
862 +    int answer = ppp_register_compressor(&ppp_mppe);
863 +
864 +    if (answer == 0)
865 +       printk(KERN_INFO "PPP MPPE Compression module registered\n");
866 +    return answer;
867 +}
868 +
869 +void __exit
870 +ppp_mppe_cleanup(void)
871 +{
872 +    ppp_unregister_compressor(&ppp_mppe);
873 +}
874 +
875 +module_init(ppp_mppe_init);
876 +module_exit(ppp_mppe_cleanup);
877 +MODULE_LICENSE("BSD without advertisement clause");
878 --- /dev/null
879 +++ linux-2.4.25/drivers/net/sha1.c
880 @@ -0,0 +1,185 @@
881 +/*
882 + * ftp://ftp.funet.fi/pub/crypt/hash/sha/sha1.c
883 + * 
884 + * SHA-1 in C
885 + * By Steve Reid <steve@edmweb.com>
886 + * 100% Public Domain
887 + * 
888 + * Test Vectors (from FIPS PUB 180-1)
889 + * "abc"
890 + * A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
891 + * "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
892 + * 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
893 + * A million repetitions of "a"
894 + * 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
895 + */
896 +
897 +/* #define SHA1HANDSOFF * Copies data before messing with it. */
898 +
899 +#if defined(__linux__)
900 +#include <asm/byteorder.h>
901 +#include <linux/string.h>
902 +#elif defined(__solaris__)
903 +#include <sys/isa_defs.h>
904 +#include <sys/ddi.h>
905 +#include <sys/sunddi.h>
906 +#define memcpy(d, s, c) bcopy(s, d, c)
907 +#define memset(d, b, c) bzero(d, c)
908 +#endif
909 +
910 +#include "sha1.h"
911 +
912 +static void SHA1_Transform(unsigned long[5], const unsigned char[64]);
913 +
914 +#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
915 +
916 +/* blk0() and blk() perform the initial expand. */
917 +/* I got the idea of expanding during the round function from SSLeay */
918 +#if defined(__LITTLE_ENDIAN) || defined(_LITTLE_ENDIAN)
919 +#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
920 +    |(rol(block->l[i],8)&0x00FF00FF))
921 +#elif defined(__BIG_ENDIAN) || defined(_BIG_ENDIAN)
922 +#define blk0(i) block->l[i]
923 +#else
924 +#error Endianness not defined
925 +#endif
926 +#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
927 +    ^block->l[(i+2)&15]^block->l[i&15],1))
928 +
929 +/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
930 +#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
931 +#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
932 +#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
933 +#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
934 +#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
935 +
936 +
937 +/* Hash a single 512-bit block. This is the core of the algorithm. */
938 +
939 +static void
940 +SHA1_Transform(unsigned long state[5], const unsigned char buffer[64])
941 +{
942 +    unsigned long a, b, c, d, e;
943 +    typedef union {
944 +       unsigned char c[64];
945 +       unsigned long l[16];
946 +    } CHAR64LONG16;
947 +    CHAR64LONG16 *block;
948 +
949 +#ifdef SHA1HANDSOFF
950 +    static unsigned char workspace[64];
951 +    block = (CHAR64LONG16 *) workspace;
952 +    memcpy(block, buffer, 64);
953 +#else
954 +    block = (CHAR64LONG16 *) buffer;
955 +#endif
956 +    /* Copy context->state[] to working vars */
957 +    a = state[0];
958 +    b = state[1];
959 +    c = state[2];
960 +    d = state[3];
961 +    e = state[4];
962 +    /* 4 rounds of 20 operations each. Loop unrolled. */
963 +    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);
964 +    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);
965 +    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);
966 +    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);
967 +    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);
968 +    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);
969 +    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);
970 +    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);
971 +    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);
972 +    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);
973 +    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);
974 +    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);
975 +    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);
976 +    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);
977 +    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);
978 +    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);
979 +    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);
980 +    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);
981 +    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);
982 +    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);
983 +    /* Add the working vars back into context.state[] */
984 +    state[0] += a;
985 +    state[1] += b;
986 +    state[2] += c;
987 +    state[3] += d;
988 +    state[4] += e;
989 +    /* Wipe variables */
990 +    a = b = c = d = e = 0;
991 +}
992 +
993 +
994 +/* SHA1Init - Initialize new context */
995 +
996 +void
997 +SHA1_Init(SHA1_CTX *context)
998 +{
999 +    /* SHA1 initialization constants */
1000 +    context->state[0] = 0x67452301;
1001 +    context->state[1] = 0xEFCDAB89;
1002 +    context->state[2] = 0x98BADCFE;
1003 +    context->state[3] = 0x10325476;
1004 +    context->state[4] = 0xC3D2E1F0;
1005 +    context->count[0] = context->count[1] = 0;
1006 +}
1007 +
1008 +
1009 +/* Run your data through this. */
1010 +
1011 +void
1012 +SHA1_Update(SHA1_CTX *context, const unsigned char *data, unsigned int len)
1013 +{
1014 +    unsigned int i, j;
1015 +
1016 +    j = (context->count[0] >> 3) & 63;
1017 +    if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++;
1018 +    context->count[1] += (len >> 29);
1019 +    if ((j + len) > 63) {
1020 +       memcpy(&context->buffer[j], data, (i = 64-j));
1021 +       SHA1_Transform(context->state, context->buffer);
1022 +       for ( ; i + 63 < len; i += 64) {
1023 +           SHA1_Transform(context->state, &data[i]);
1024 +       }
1025 +       j = 0;
1026 +    }
1027 +    else
1028 +       i = 0;
1029 +
1030 +    memcpy(&context->buffer[j], &data[i], len - i);
1031 +}
1032 +
1033 +
1034 +/* Add padding and return the message digest. */
1035 +
1036 +void
1037 +SHA1_Final(unsigned char digest[20], SHA1_CTX *context)
1038 +{
1039 +    unsigned long i, j;
1040 +    unsigned char finalcount[8];
1041 +
1042 +    for (i = 0; i < 8; i++) {
1043 +        finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
1044 +         >> ((3-(i & 3)) * 8) ) & 255);  /* Endian independent */
1045 +    }
1046 +    SHA1_Update(context, (unsigned char *) "\200", 1);
1047 +    while ((context->count[0] & 504) != 448) {
1048 +       SHA1_Update(context, (unsigned char *) "\0", 1);
1049 +    }
1050 +    SHA1_Update(context, finalcount, 8);  /* Should cause a SHA1Transform() */
1051 +    for (i = 0; i < 20; i++) {
1052 +       digest[i] = (unsigned char)
1053 +                    ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
1054 +    }
1055 +    /* Wipe variables */
1056 +    i = j = 0;
1057 +    memset(context->buffer, 0, 64);
1058 +    memset(context->state, 0, 20);
1059 +    memset(context->count, 0, 8);
1060 +    memset(&finalcount, 0, 8);
1061 +#ifdef SHA1HANDSOFF  /* make SHA1Transform overwrite it's own static vars */
1062 +    SHA1Transform(context->state, context->buffer);
1063 +#endif
1064 +}
1065 +
1066 --- /dev/null
1067 +++ linux-2.4.25/drivers/net/sha1.h
1068 @@ -0,0 +1,18 @@
1069 +/* sha1.h */
1070 +
1071 +#ifndef _SHA1_H
1072 +#define _SHA1_H
1073 +
1074 +typedef struct {
1075 +    unsigned long state[5];
1076 +    unsigned long count[2];
1077 +    unsigned char buffer[64];
1078 +} SHA1_CTX;
1079 +
1080 +#define SHA1_SIGNATURE_SIZE 20
1081 +
1082 +extern void SHA1_Init(SHA1_CTX *);
1083 +extern void SHA1_Update(SHA1_CTX *, const unsigned char *, unsigned int);
1084 +extern void SHA1_Final(unsigned char[SHA1_SIGNATURE_SIZE], SHA1_CTX *);
1085 +
1086 +#endif /* _SHA1_H */
1087 --- linux-2.4.25/include/linux/ppp-comp.h~mppe-20040216
1088 +++ linux-2.4.25/include/linux/ppp-comp.h
1089 @@ -187,6 +187,100 @@
1090  #define DEFLATE_CHK_SEQUENCE   0
1091  
1092  /*
1093 + * Definitions for MPPE.
1094 + */
1095 +
1096 +#define CI_MPPE                        18      /* config option for MPPE */
1097 +#define CILEN_MPPE             6       /* length of config option */
1098 +
1099 +#define MPPE_PAD               4       /* MPPE growth per frame */
1100 +#define MPPE_MAX_KEY_LEN       16      /* largest key length (128-bit) */
1101 +
1102 +/* option bits for ccp_options.mppe */
1103 +#define MPPE_OPT_40            0x01    /* 40 bit */
1104 +#define MPPE_OPT_128           0x02    /* 128 bit */
1105 +#define MPPE_OPT_STATEFUL      0x04    /* stateful mode */
1106 +/* unsupported opts */
1107 +#define MPPE_OPT_56            0x08    /* 56 bit */
1108 +#define MPPE_OPT_MPPC          0x10    /* MPPC compression */
1109 +#define MPPE_OPT_D             0x20    /* Unknown */
1110 +#define MPPE_OPT_UNSUPPORTED (MPPE_OPT_56|MPPE_OPT_MPPC|MPPE_OPT_D)
1111 +#define MPPE_OPT_UNKNOWN       0x40    /* Bits !defined in RFC 3078 were set */
1112 +
1113 +/*
1114 + * This is not nice ... the alternative is a bitfield struct though.
1115 + * And unfortunately, we cannot share the same bits for the option
1116 + * names above since C and H are the same bit.  We could do a u_int32
1117 + * but then we have to do a htonl() all the time and/or we still need
1118 + * to know which octet is which.
1119 + */
1120 +#define MPPE_C_BIT             0x01    /* MPPC */
1121 +#define MPPE_D_BIT             0x10    /* Obsolete, usage unknown */
1122 +#define MPPE_L_BIT             0x20    /* 40-bit */
1123 +#define MPPE_S_BIT             0x40    /* 128-bit */
1124 +#define MPPE_M_BIT             0x80    /* 56-bit, not supported */
1125 +#define MPPE_H_BIT             0x01    /* Stateless (in a different byte) */
1126 +
1127 +/* Does not include H bit; used for least significant octet only. */
1128 +#define MPPE_ALL_BITS (MPPE_D_BIT|MPPE_L_BIT|MPPE_S_BIT|MPPE_M_BIT|MPPE_H_BIT)
1129 +
1130 +/* Build a CI from mppe opts (see RFC 3078) */
1131 +#define MPPE_OPTS_TO_CI(opts, ci)              \
1132 +    do {                                       \
1133 +       u_char *ptr = ci; /* u_char[4] */       \
1134 +                                               \
1135 +       /* H bit */                             \
1136 +       if (opts & MPPE_OPT_STATEFUL)           \
1137 +           *ptr++ = 0x0;                       \
1138 +       else                                    \
1139 +           *ptr++ = MPPE_H_BIT;                \
1140 +       *ptr++ = 0;                             \
1141 +       *ptr++ = 0;                             \
1142 +                                               \
1143 +       /* S,L bits */                          \
1144 +       *ptr = 0;                               \
1145 +       if (opts & MPPE_OPT_128)                \
1146 +           *ptr |= MPPE_S_BIT;                 \
1147 +       if (opts & MPPE_OPT_40)                 \
1148 +           *ptr |= MPPE_L_BIT;                 \
1149 +       /* M,D,C bits not supported */          \
1150 +    } while (/* CONSTCOND */ 0)
1151 +
1152 +/* The reverse of the above */
1153 +#define MPPE_CI_TO_OPTS(ci, opts)              \
1154 +    do {                                       \
1155 +       u_char *ptr = ci; /* u_char[4] */       \
1156 +                                               \
1157 +       opts = 0;                               \
1158 +                                               \
1159 +       /* H bit */                             \
1160 +       if (!(ptr[0] & MPPE_H_BIT))             \
1161 +           opts |= MPPE_OPT_STATEFUL;          \
1162 +                                               \
1163 +       /* S,L bits */                          \
1164 +       if (ptr[3] & MPPE_S_BIT)                \
1165 +           opts |= MPPE_OPT_128;               \
1166 +       if (ptr[3] & MPPE_L_BIT)                \
1167 +           opts |= MPPE_OPT_40;                \
1168 +                                               \
1169 +       /* M,D,C bits */                        \
1170 +       if (ptr[3] & MPPE_M_BIT)                \
1171 +           opts |= MPPE_OPT_56;                \
1172 +       if (ptr[3] & MPPE_D_BIT)                \
1173 +           opts |= MPPE_OPT_D;                 \
1174 +       if (ptr[3] & MPPE_C_BIT)                \
1175 +           opts |= MPPE_OPT_MPPC;              \
1176 +                                               \
1177 +       /* Other bits */                        \
1178 +       if (ptr[0] & ~MPPE_H_BIT)               \
1179 +           opts |= MPPE_OPT_UNKNOWN;           \
1180 +       if (ptr[1] || ptr[2])                   \
1181 +           opts |= MPPE_OPT_UNKNOWN;           \
1182 +       if (ptr[3] & ~MPPE_ALL_BITS)            \
1183 +           opts |= MPPE_OPT_UNKNOWN;           \
1184 +    } while (/* CONSTCOND */ 0)
1185 +
1186 +/*
1187   * Definitions for other, as yet unsupported, compression methods.
1188   */
1189  
1190 --- linux-2.4.25/drivers/net/Makefile~mppe-20040216
1191 +++ linux-2.4.25/drivers/net/Makefile
1192 @@ -18,8 +18,9 @@
1193  export-objs     :=     8390.o arlan.o aironet4500_core.o aironet4500_card.o \
1194                         ppp_async.o ppp_generic.o slhc.o pppox.o auto_irq.o \
1195                         net_init.o mii.o
1196 -list-multi     :=      rcpci.o
1197 +list-multi     :=      rcpci.o ppp_mppe.o
1198  rcpci-objs     :=      rcpci45.o rclanmtl.o
1199 +ppp_mppe-objs   :=      ppp_mppe_compress.o sha1.o arcfour.o
1200  
1201  ifeq ($(CONFIG_TULIP),y)
1202    obj-y += tulip/tulip.o
1203 @@ -163,6 +164,14 @@
1204  obj-$(CONFIG_PPP_BSDCOMP) += bsd_comp.o
1205  obj-$(CONFIG_PPPOE) += pppox.o pppoe.o
1206  
1207 +ifeq ($(CONFIG_PPP_MPPE),y)
1208 +  obj-y += $(ppp_mppe-objs)
1209 +else
1210 +  ifeq ($(CONFIG_PPP_MPPE),m)
1211 +    obj-m += ppp_mppe.o
1212 +  endif
1213 +endif
1214 +
1215  obj-$(CONFIG_SLIP) += slip.o
1216  ifeq ($(CONFIG_SLIP_COMPRESSED),y)
1217    obj-$(CONFIG_SLIP) += slhc.o
1218 @@ -269,3 +278,7 @@
1219  
1220  rcpci.o: $(rcpci-objs)
1221         $(LD) -r -o $@ $(rcpci-objs)
1222 +
1223 +ppp_mppe.o: $(ppp_mppe-objs)
1224 +       $(LD) -r -o $@ $(ppp_mppe-objs)
1225 +