]> git.ozlabs.org Git - ppp.git/blob - linux/mppe/ppp_mppe_compress.c
add debugging for coherency count
[ppp.git] / linux / mppe / ppp_mppe_compress.c
1 /*
2  *  ==FILEVERSION 20020521==
3  *
4  * ppp_mppe_compress.c - interface MPPE to the PPP code.
5  * This version is for use with Linux kernel 2.2.19+ and 2.4.x.
6  *
7  * By Frank Cusack <frank@google.com>.
8  * Copyright (c) 2002 Google, Inc.
9  * All rights reserved.
10  *
11  * Permission to use, copy, modify, and distribute this software and its
12  * documentation is hereby granted, provided that the above copyright
13  * notice appears in all copies.  This software is provided without any
14  * warranty, express or implied.
15  *
16  */
17
18 #include <linux/module.h>
19 #include <linux/kernel.h>
20 #include <linux/init.h>
21 #include <linux/types.h>
22 #include <linux/slab.h>
23 #include <linux/string.h>
24
25 #include <linux/ppp_defs.h>
26 #include <linux/ppp-comp.h>
27
28 #include "arcfour.h"
29 #include "sha1.h"
30
31 /*
32  * State for an MPPE (de)compressor.
33  */
34 typedef struct ppp_mppe_state {
35     unsigned char       master_key[MPPE_MAX_KEY_LEN];
36     unsigned char       session_key[MPPE_MAX_KEY_LEN];
37     arcfour_context     arcfour_context; /* encryption state */
38     unsigned            keylen;         /* key length in bytes             */
39                                         /* NB: 128-bit == 16, 40-bit == 8! */
40                                         /* If we want to support 56-bit,   */
41                                         /* the unit has to change to bits  */
42     unsigned char       bits;           /* MPPE control bits */
43     unsigned            ccount;         /* 12-bit coherency count (seqno)  */
44     unsigned            stateful;       /* stateful mode flag */
45     int                 discard;        /* stateful mode packet loss flag */
46     int                 sanity_errors;  /* take down LCP if too many */
47     int                 unit;
48     int                 debug;
49     struct compstat     stats;
50 } ppp_mppe_state;
51
52 /* ppp_mppe_state.bits definitions */
53 #define MPPE_BIT_A      0x80    /* Encryption table were (re)inititalized */
54 #define MPPE_BIT_B      0x40    /* MPPC only (not implemented) */
55 #define MPPE_BIT_C      0x20    /* MPPC only (not implemented) */
56 #define MPPE_BIT_D      0x10    /* This is an encrypted frame */
57
58 #define MPPE_BIT_FLUSHED        MPPE_BIT_A
59 #define MPPE_BIT_ENCRYPTED      MPPE_BIT_D
60
61 #define MPPE_BITS(p) ((p)[4] & 0xf0)
62 #define MPPE_CCOUNT(p) ((((p)[4] & 0x0f) << 8) + (p)[5])
63 #define MPPE_CCOUNT_SPACE 0x1000        /* The size of the ccount space */
64
65 #define MPPE_OVHD       2               /* MPPE overhead/packet */
66 #define SANITY_MAX      1600            /* Max bogon factor we will tolerate */
67
68 static void     GetNewKeyFromSHA __P((unsigned char *StartKey,
69                                       unsigned char *SessionKey,
70                                       unsigned SessionKeyLength,
71                                       unsigned char *InterimKey));
72 static void     mppe_rekey __P((ppp_mppe_state *state, int));
73 static void     *mppe_alloc __P((unsigned char *options, int optlen));
74 static void     mppe_free __P((void *state));
75 static int      mppe_init __P((void *state, unsigned char *options,
76                                int optlen, int unit, int debug, const char *));
77 static int      mppe_comp_init __P((void *state, unsigned char *options,
78                                     int optlen,
79                                     int unit, int hdrlen, int debug));
80 static int      mppe_decomp_init __P((void *state, unsigned char *options,
81                                       int optlen, int unit,
82                                       int hdrlen, int mru, int debug));
83 static int      mppe_compress __P((void *state, unsigned char *ibuf,
84                                    unsigned char *obuf,
85                                    int isize, int osize));
86 static void     mppe_incomp __P((void *state, unsigned char *ibuf, int icnt));
87 static int      mppe_decompress __P((void *state, unsigned char *ibuf,
88                                      int isize, unsigned char *obuf,int osize));
89 static void     mppe_comp_reset __P((void *state));
90 static void     mppe_decomp_reset __P((void *state));
91 static void     mppe_comp_stats __P((void *state, struct compstat *stats));
92
93
94 /*
95  * Key Derivation, from RFC 3078, RFC 3079.
96  * Equivalent to Get_Key() for MS-CHAP as described in RFC 3079.
97  */
98 static void
99 GetNewKeyFromSHA(unsigned char *MasterKey, unsigned char *SessionKey,
100                  unsigned SessionKeyLength, unsigned char *InterimKey)
101 {
102     SHA1_CTX Context;
103     unsigned char Digest[SHA1_SIGNATURE_SIZE];
104
105     unsigned char SHApad1[40] =
106     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
107       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
108       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
109       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
110     unsigned char SHApad2[40] =
111     { 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
112       0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
113       0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
114       0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2 };
115
116     /* assert(SessionKeyLength <= SHA1_SIGNATURE_SIZE); */
117
118     SHA1_Init(&Context);
119     SHA1_Update(&Context, MasterKey, SessionKeyLength);
120     SHA1_Update(&Context, SHApad1, sizeof(SHApad1));
121     SHA1_Update(&Context, SessionKey, SessionKeyLength);
122     SHA1_Update(&Context, SHApad2, sizeof(SHApad2));
123     SHA1_Final(Digest, &Context);
124
125     memcpy(InterimKey, Digest, SessionKeyLength);
126 }
127
128 /*
129  * Perform the MPPE rekey algorithm, from RFC 3078, sec. 7.3.
130  * Well, not what's written there, but rather what they meant.
131  */
132 static void
133 mppe_rekey(ppp_mppe_state *state, int initial_key)
134 {
135     unsigned char InterimKey[MPPE_MAX_KEY_LEN];
136
137     GetNewKeyFromSHA(state->master_key, state->session_key,
138                      state->keylen, InterimKey);
139     if (!initial_key) {
140         arcfour_setkey(&state->arcfour_context, InterimKey, state->keylen);
141         arcfour_encrypt(&state->arcfour_context, InterimKey, state->keylen,
142                         state->session_key);
143     } else {
144         memcpy(state->session_key, InterimKey, state->keylen);
145     }
146     if (state->keylen == 8) {
147         /* See RFC 3078 */
148         state->session_key[0] = 0xd1;
149         state->session_key[1] = 0x26;
150         state->session_key[2] = 0x9e;
151     }
152     arcfour_setkey(&state->arcfour_context, state->session_key, state->keylen);
153 }
154
155
156 /*
157  * Allocate space for a (de)compressor.
158  */
159 static void *
160 mppe_alloc(unsigned char *options, int optlen)
161 {
162     ppp_mppe_state *state;
163
164     if (optlen != CILEN_MPPE + sizeof(state->master_key)
165         || options[0] != CI_MPPE
166         || options[1] != CILEN_MPPE)
167         return NULL;
168
169     state = (ppp_mppe_state *) kmalloc(sizeof(*state), GFP_KERNEL);
170     if (state == NULL)
171         return NULL;
172
173     MOD_INC_USE_COUNT;
174     memset(state, 0, sizeof(*state));
175
176     /* Save keys. */
177     memcpy(state->master_key, &options[CILEN_MPPE], sizeof(state->master_key));
178     memcpy(state->session_key, state->master_key, sizeof(state->master_key));
179     /*
180      * We defer initial key generation until mppe_init(), as mppe_alloc()
181      * is called frequently during negotiation.
182      */
183
184     return (void *) state;
185 }
186
187 /*
188  * Deallocate space for a (de)compressor.
189  */
190 static void
191 mppe_free(void *arg)
192 {
193     ppp_mppe_state *state = (ppp_mppe_state *) arg;
194
195     if (state) {
196         kfree(state);
197         MOD_DEC_USE_COUNT;
198     }
199 }
200
201
202 /* 
203  * Initialize (de)compressor state.
204  */
205 static int
206 mppe_init(void *arg, unsigned char *options, int optlen, int unit, int debug,
207           const char *debugstr)
208 {
209     ppp_mppe_state *state = (ppp_mppe_state *) arg;
210     unsigned char mppe_opts;
211
212     if (optlen != CILEN_MPPE
213         || options[0] != CI_MPPE
214         || options[1] != CILEN_MPPE)
215         return 0;
216
217     MPPE_CI_TO_OPTS(&options[2], mppe_opts);
218     if (mppe_opts & MPPE_OPT_128)
219         state->keylen = 16;
220     else if (mppe_opts & MPPE_OPT_40)
221         state->keylen = 8;
222     else {
223         printk(KERN_WARNING "%s[%d]: unknown key length\n", debugstr, unit);
224         return 0;
225     }
226     if (mppe_opts & MPPE_OPT_STATEFUL)
227         state->stateful = 1;
228
229     /* Generate the initial session key. */
230     mppe_rekey(state, 1);
231
232     if (debug) {
233         int i;
234         char mkey[sizeof(state->master_key) * 2 + 1];
235         char skey[sizeof(state->session_key) * 2 + 1];
236
237         printk(KERN_DEBUG "%s[%d]: initialized with %d-bit %s mode\n", debugstr,
238                unit, (state->keylen == 16)? 128: 40,
239                (state->stateful)? "stateful": "stateless");
240
241         for (i = 0; i < sizeof(state->master_key); i++)
242             sprintf(mkey + i * 2, "%.2x", state->master_key[i]);
243         for (i = 0; i < sizeof(state->session_key); i++)
244             sprintf(skey + i * 2, "%.2x", state->session_key[i]);
245         printk(KERN_DEBUG "%s[%d]: keys: master: %s initial session: %s\n",
246                debugstr, unit, mkey, skey);
247     }
248
249     /*
250      * Initialize the coherency count.  The initial value is not specified
251      * in RFC 3078, but we can make a reasonable assumption that it will
252      * start at 0.  Setting it to the max here makes the comp/decomp code
253      * do the right thing (determined through experiment).
254      */
255     state->ccount = MPPE_CCOUNT_SPACE - 1;
256
257     /*
258      * Note that even though we have initialized the key table, we don't
259      * set the FLUSHED bit.  This is contrary to RFC 3078, sec. 3.1.
260      */
261     state->bits = MPPE_BIT_ENCRYPTED;
262
263     state->unit  = unit;
264     state->debug = debug;
265
266     return 1;
267 }
268
269
270
271 static int
272 mppe_comp_init(void *arg, unsigned char *options, int optlen, int unit,
273                int hdrlen, int debug)
274 {
275     /* ARGSUSED */
276     return mppe_init(arg, options, optlen, unit, debug, "mppe_comp_init");
277 }
278
279 /*
280  * We received a CCP Reset-Request (actually, we are sending a Reset-Ack),
281  * tell the compressor to rekey.  Note that we MUST NOT rekey for
282  * every CCP Reset-Request; we only rekey on the next xmit packet.
283  * We might get multiple CCP Reset-Requests if our CCP Reset-Ack is lost.
284  * So, rekeying for every CCP Reset-Request is broken as the peer will not
285  * know how many times we've rekeyed.  (If we rekey and THEN get another
286  * CCP Reset-Request, we must rekey again.)
287  */
288 static void
289 mppe_comp_reset(void *arg)
290 {
291     ppp_mppe_state *state = (ppp_mppe_state *) arg;
292
293     state->bits |= MPPE_BIT_FLUSHED;
294 }
295
296 /*
297  * Compress (encrypt) a packet.
298  * It's strange to call this a compressor, since the output is always
299  * MPPE_OVHD + 2 bytes larger than the input.
300  */
301 int
302 mppe_compress(void *arg, unsigned char *ibuf, unsigned char *obuf,
303               int isize, int osize)
304 {
305     ppp_mppe_state *state = (ppp_mppe_state *) arg;
306     int proto;
307
308     /*
309      * Check that the protocol is in the range we handle.
310      */
311     proto = PPP_PROTOCOL(ibuf);
312     if (proto < 0x0021 || proto > 0x00fa)
313         return 0;
314
315     /* Make sure we have enough room to generate an encrypted packet. */
316     if (osize < isize + MPPE_OVHD + 2) {
317         /* Drop the packet if we should encrypt it, but can't. */
318         printk(KERN_DEBUG "mppe_compress[%d]: osize too small! "
319                "(have: %d need: %d)\n", state->unit,
320                osize, osize + MPPE_OVHD + 2);
321         return -1;
322     }
323
324     osize = isize + MPPE_OVHD + 2;
325
326     /*
327      * Copy over the PPP header and set control bits.
328      */
329     obuf[0] = PPP_ADDRESS(ibuf);
330     obuf[1] = PPP_CONTROL(ibuf);
331     obuf[2] = PPP_COMP >> 8;            /* isize + MPPE_OVHD + 1 */
332     obuf[3] = PPP_COMP;                 /* isize + MPPE_OVHD + 2 */
333     obuf += PPP_HDRLEN;
334
335     state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE;
336     if (state->debug >= 7)
337         printk(KERN_DEBUG "mppe_compress[%d]: ccount %d\n", state->unit,
338                state->ccount);
339     obuf[0] = state->ccount >> 8;
340     obuf[1] = state->ccount & 0xff;
341
342     if (!state->stateful ||                     /* stateless mode     */
343         ((state->ccount & 0xff) == 0xff) ||     /* "flag" packet      */
344         (state->bits & MPPE_BIT_FLUSHED)) {     /* CCP Reset-Request  */
345         /* We must rekey */
346         if (state->debug && state->stateful)
347             printk(KERN_DEBUG "mppe_compress[%d]: rekeying\n", state->unit);
348         mppe_rekey(state, 0);
349         state->bits |= MPPE_BIT_FLUSHED;
350     }
351     obuf[0] |= state->bits;
352     state->bits &= ~MPPE_BIT_FLUSHED;   /* reset for next xmit */
353
354     obuf  += MPPE_OVHD;
355     ibuf  += 2; /* skip to proto field */
356     isize -= 2;
357
358     /* Encrypt packet */
359     arcfour_encrypt(&state->arcfour_context, ibuf, isize, obuf);
360
361     state->stats.unc_bytes += isize;
362     state->stats.unc_packets++;
363     state->stats.comp_bytes += osize;
364     state->stats.comp_packets++;
365
366     return osize;
367 }
368
369 /*
370  * Since every frame grows by MPPE_OVHD + 2 bytes, this is always going
371  * to look bad ... and the longer the link is up the worse it will get.
372  */
373 static void
374 mppe_comp_stats(void *arg, struct compstat *stats)
375 {
376     ppp_mppe_state *state = (ppp_mppe_state *) arg;
377
378     *stats = state->stats;
379 }
380
381
382 static int
383 mppe_decomp_init(void *arg, unsigned char *options, int optlen, int unit,
384                  int hdrlen, int mru, int debug)
385 {
386     /* ARGSUSED */
387     return mppe_init(arg, options, optlen, unit, debug, "mppe_decomp_init");
388 }
389
390 /*
391  * We received a CCP Reset-Ack.  Just ignore it.
392  */
393 static void
394 mppe_decomp_reset(void *arg)
395 {
396     /* ARGSUSED */
397     return;
398 }
399
400 /*
401  * Decompress (decrypt) an MPPE packet.
402  */
403 int
404 mppe_decompress(void *arg, unsigned char *ibuf, int isize, unsigned char *obuf,
405                 int osize)
406 {
407     ppp_mppe_state *state = (ppp_mppe_state *) arg;
408     unsigned ccount;
409     int flushed = MPPE_BITS(ibuf) & MPPE_BIT_FLUSHED;
410     int sanity = 0;
411
412     if (isize <= PPP_HDRLEN + MPPE_OVHD) {
413         if (state->debug)
414             printk(KERN_DEBUG "mppe_decompress[%d]: short pkt (%d)\n",
415                    state->unit, isize);
416         return DECOMP_ERROR;
417     }
418
419     /* Make sure we have enough room to decrypt the packet. */
420     if (osize < isize - MPPE_OVHD - 2) {
421         printk(KERN_DEBUG "mppe_decompress[%d]: osize too small! "
422                "(have: %d need: %d)\n", state->unit,
423                osize, isize - MPPE_OVHD - 2);
424         return DECOMP_ERROR;
425     }
426     osize = isize - MPPE_OVHD - 2;
427
428     ccount = MPPE_CCOUNT(ibuf);
429     if (state->debug >= 7)
430         printk(KERN_DEBUG "mppe_decompress[%d]: ccount %d\n", state->unit,
431                ccount);
432
433     /* sanity checks -- terminate with extreme prejudice */
434     if (!(MPPE_BITS(ibuf) & MPPE_BIT_ENCRYPTED)) {
435         printk(KERN_DEBUG "mppe_decompress[%d]: ENCRYPTED bit not set!\n",
436                state->unit);
437         state->sanity_errors += 100;
438         sanity = 1;
439     }
440     if (!state->stateful && !flushed) {
441         printk(KERN_DEBUG "mppe_decompress[%d]: FLUSHED bit not set in "
442                "stateless mode!\n", state->unit);
443         state->sanity_errors += 100;
444         sanity = 1;
445     }
446     if (state->stateful && ((ccount & 0xff) == 0xff) && !flushed) {
447         printk(KERN_DEBUG "mppe_decompress[%d]: FLUSHED bit not set on "
448                "flag packet!\n", state->unit);
449         state->sanity_errors += 100;
450         sanity = 1;
451     }
452
453     if (sanity) {
454         if (state->sanity_errors < SANITY_MAX)
455             return DECOMP_ERROR;
456         else
457             /*
458              * Take LCP down if the peer is sending too many bogons.
459              * We don't want to do this for a single or just a few
460              * instances since it could just be due to packet corruption.
461              */
462             return DECOMP_FATALERROR;
463     }
464
465     /*
466      * Check the coherency count.
467      */
468
469     if (!state->stateful) {
470         /* RFC 3078, sec 8.1.  Rekey for every packet. */
471         while (state->ccount != ccount) {
472             mppe_rekey(state, 0);
473             state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE;
474         }
475     } else {
476         /* RFC 3078, sec 8.2. */
477         if (!state->discard) {
478             /* normal state */
479             state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE;
480             if (ccount != state->ccount) {
481                 /*
482                  * (ccount > state->ccount)
483                  * Packet loss detected, enter the discard state.
484                  * Signal the peer to rekey (by sending a CCP Reset-Request).
485                  */
486                 state->discard = 1;
487                 return DECOMP_ERROR;
488             }
489         } else {
490             /* discard state */
491            if (!flushed) {
492                 /* ccp.c will be silent (no additional CCP Reset-Requests). */
493                 return DECOMP_ERROR;
494             } else {
495                 /* Rekey for every missed "flag" packet. */
496                 while ((ccount & ~0xff) != (state->ccount & ~0xff)) {
497                     mppe_rekey(state, 0);
498                     state->ccount = (state->ccount + 256) % MPPE_CCOUNT_SPACE;
499                 }
500
501                 /* reset */
502                 state->discard = 0;
503                 state->ccount = ccount;
504                 /*
505                  * Another problem with RFC 3078 here.  It implies that the
506                  * peer need not send a Reset-Ack packet.  But RFC 1962
507                  * requires it.  Hopefully, M$ does send a Reset-Ack; even
508                  * though it isn't required for MPPE synchronization, it is
509                  * required to reset CCP state.
510                  */
511             }
512         }
513         if (flushed)
514             mppe_rekey(state, 0);
515     }
516
517     /*
518      * Fill in the first part of the PPP header.  The protocol field
519      * comes from the decrypted data.
520      */
521     obuf[0] = PPP_ADDRESS(ibuf);        /* +1 */
522     obuf[1] = PPP_CONTROL(ibuf);        /* +1 */
523     obuf  += 2;
524     ibuf  += PPP_HDRLEN + MPPE_OVHD;
525     isize -= PPP_HDRLEN + MPPE_OVHD;    /* -6 */
526                                         /* net osize: isize-4 */
527
528     /* And finally, decrypt the packet. */
529     arcfour_decrypt(&state->arcfour_context, ibuf, isize, obuf);
530
531     state->stats.unc_bytes += osize;
532     state->stats.unc_packets++;
533     state->stats.comp_bytes += isize;
534     state->stats.comp_packets++;
535
536     /* good packet credit */
537     state->sanity_errors >>= 1;
538
539     return osize;
540 }
541
542 /*
543  * Incompressible data has arrived (this should never happen!).
544  * We should probably drop the link if the protocol is in the range
545  * of what should be encrypted.  At the least, we should drop this
546  * packet.  (How to do this?)
547  */
548 static void
549 mppe_incomp(void *arg, unsigned char *ibuf, int icnt)
550 {
551     ppp_mppe_state *state = (ppp_mppe_state *) arg;
552
553     if (state->debug &&
554         (PPP_PROTOCOL(ibuf) >= 0x0021 && PPP_PROTOCOL(ibuf) <= 0x00fa))
555         printk(KERN_DEBUG "mppe_incomp[%d]: incompressible (unencrypted) data! "
556                "(proto %04x)\n", state->unit, PPP_PROTOCOL(ibuf));
557
558     state->stats.inc_bytes += icnt;
559     state->stats.inc_packets++;
560     state->stats.unc_bytes += icnt;
561     state->stats.unc_packets++;
562 }
563
564 /*************************************************************
565  * Module interface table
566  *************************************************************/
567
568 /* These are in ppp.c (2.2.x) or ppp_generic.c (2.4.x) */
569 extern int  ppp_register_compressor   (struct compressor *cp);
570 extern void ppp_unregister_compressor (struct compressor *cp);
571
572 /*
573  * Procedures exported to if_ppp.c.
574  */
575 struct compressor ppp_mppe = {
576     CI_MPPE,            /* compress_proto */
577     mppe_alloc,         /* comp_alloc */
578     mppe_free,          /* comp_free */
579     mppe_comp_init,     /* comp_init */
580     mppe_comp_reset,    /* comp_reset */
581     mppe_compress,      /* compress */
582     mppe_comp_stats,    /* comp_stat */
583     mppe_alloc,         /* decomp_alloc */
584     mppe_free,          /* decomp_free */
585     mppe_decomp_init,   /* decomp_init */
586     mppe_decomp_reset,  /* decomp_reset */
587     mppe_decompress,    /* decompress */
588     mppe_incomp,        /* incomp */
589     mppe_comp_stats,    /* decomp_stat */
590 };
591
592 /* 2.2 compatibility defines */
593 #ifndef __init
594 #define __init
595 #endif
596 #ifndef __exit
597 #define __exit
598 #endif
599 #ifndef MODULE_LICENSE
600 #define MODULE_LICENSE(license)
601 #endif
602
603 int __init
604 ppp_mppe_init(void)
605 {  
606     int answer = ppp_register_compressor(&ppp_mppe);
607
608     if (answer == 0)
609         printk(KERN_INFO "PPP MPPE Compression module registered\n");
610     return answer;
611 }
612
613 void __exit
614 ppp_mppe_cleanup(void)
615 {
616     ppp_unregister_compressor(&ppp_mppe);
617 }
618
619 module_init(ppp_mppe_init);
620 module_exit(ppp_mppe_cleanup);
621 MODULE_LICENSE("BSD without advertisement clause");