]> git.ozlabs.org Git - ppp.git/blob - linux/mppe/ppp_mppe_compress.c
verify enough buffer space to decompress a packet
[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     obuf[0] = state->ccount >> 8;
337     obuf[1] = state->ccount & 0xff;
338
339     if (!state->stateful ||                     /* stateless mode     */
340         ((state->ccount & 0xff) == 0xff) ||     /* "flag" packet      */
341         (state->bits & MPPE_BIT_FLUSHED)) {     /* CCP Reset-Request  */
342         /* We must rekey */
343         if (state->debug && state->stateful)
344             printk(KERN_DEBUG "mppe_compress[%d]: rekeying\n", state->unit);
345         mppe_rekey(state, 0);
346         state->bits |= MPPE_BIT_FLUSHED;
347     }
348     obuf[0] |= state->bits;
349     state->bits &= ~MPPE_BIT_FLUSHED;   /* reset for next xmit */
350
351     obuf  += MPPE_OVHD;
352     ibuf  += 2; /* skip to proto field */
353     isize -= 2;
354
355     /* Encrypt packet */
356     arcfour_encrypt(&state->arcfour_context, ibuf, isize, obuf);
357
358     state->stats.unc_bytes += isize;
359     state->stats.unc_packets++;
360     state->stats.comp_bytes += osize;
361     state->stats.comp_packets++;
362
363     return osize;
364 }
365
366 /*
367  * Since every frame grows by MPPE_OVHD + 2 bytes, this is always going
368  * to look bad ... and the longer the link is up the worse it will get.
369  */
370 static void
371 mppe_comp_stats(void *arg, struct compstat *stats)
372 {
373     ppp_mppe_state *state = (ppp_mppe_state *) arg;
374
375     *stats = state->stats;
376 }
377
378
379 static int
380 mppe_decomp_init(void *arg, unsigned char *options, int optlen, int unit,
381                  int hdrlen, int mru, int debug)
382 {
383     /* ARGSUSED */
384     return mppe_init(arg, options, optlen, unit, debug, "mppe_decomp_init");
385 }
386
387 /*
388  * We received a CCP Reset-Ack.  Just ignore it.
389  */
390 static void
391 mppe_decomp_reset(void *arg)
392 {
393     /* ARGSUSED */
394     return;
395 }
396
397 /*
398  * Decompress (decrypt) an MPPE packet.
399  */
400 int
401 mppe_decompress(void *arg, unsigned char *ibuf, int isize, unsigned char *obuf,
402                 int osize)
403 {
404     ppp_mppe_state *state = (ppp_mppe_state *) arg;
405     unsigned ccount;
406     int flushed = MPPE_BITS(ibuf) & MPPE_BIT_FLUSHED;
407     int sanity = 0;
408
409     if (isize <= PPP_HDRLEN + MPPE_OVHD) {
410         if (state->debug)
411             printk(KERN_DEBUG "mppe_decompress[%d]: short pkt (%d)\n",
412                    state->unit, isize);
413         return DECOMP_ERROR;
414     }
415
416     /* Make sure we have enough room to decrypt the packet. */
417     if (osize < isize - MPPE_OVHD - 2) {
418         printk(KERN_DEBUG "mppe_decompress[%d]: osize too small! "
419                "(have: %d need: %d)\n", state->unit,
420                osize, isize - MPPE_OVHD - 2);
421         return DECOMP_ERROR;
422     }
423     osize = isize - MPPE_OVHD - 2;
424
425     ccount = MPPE_CCOUNT(ibuf);
426
427     /* sanity checks -- terminate with extreme prejudice */
428     if (!(MPPE_BITS(ibuf) & MPPE_BIT_ENCRYPTED)) {
429         printk(KERN_DEBUG "mppe_decompress[%d]: ENCRYPTED bit not set!\n",
430                state->unit);
431         state->sanity_errors += 100;
432         sanity = 1;
433     }
434     if (!state->stateful && !flushed) {
435         printk(KERN_DEBUG "mppe_decompress[%d]: FLUSHED bit not set in "
436                "stateless mode!\n", state->unit);
437         state->sanity_errors += 100;
438         sanity = 1;
439     }
440     if (state->stateful && ((ccount & 0xff) == 0xff) && !flushed) {
441         printk(KERN_DEBUG "mppe_decompress[%d]: FLUSHED bit not set on "
442                "flag packet!\n", state->unit);
443         state->sanity_errors += 100;
444         sanity = 1;
445     }
446
447     if (sanity) {
448         if (state->sanity_errors < SANITY_MAX)
449             return DECOMP_ERROR;
450         else
451             /*
452              * Take LCP down if the peer is sending too many bogons.
453              * We don't want to do this for a single or just a few
454              * instances since it could just be due to packet corruption.
455              */
456             return DECOMP_FATALERROR;
457     }
458
459     /*
460      * Check the coherency count.
461      */
462
463     if (!state->stateful) {
464         /* RFC 3078, sec 8.1.  Rekey for every packet. */
465         while (state->ccount != ccount) {
466             mppe_rekey(state, 0);
467             state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE;
468         }
469     } else {
470         /* RFC 3078, sec 8.2. */
471         if (!state->discard) {
472             /* normal state */
473             state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE;
474             if (ccount != state->ccount) {
475                 /*
476                  * (ccount > state->ccount)
477                  * Packet loss detected, enter the discard state.
478                  * Signal the peer to rekey (by sending a CCP Reset-Request).
479                  */
480                 state->discard = 1;
481                 return DECOMP_ERROR;
482             }
483         } else {
484             /* discard state */
485            if (!flushed) {
486                 /* ccp.c will be silent (no additional CCP Reset-Requests). */
487                 return DECOMP_ERROR;
488             } else {
489                 /* Rekey for every missed "flag" packet. */
490                 while ((ccount & ~0xff) != (state->ccount & ~0xff)) {
491                     mppe_rekey(state, 0);
492                     state->ccount = (state->ccount + 256) % MPPE_CCOUNT_SPACE;
493                 }
494
495                 /* reset */
496                 state->discard = 0;
497                 state->ccount = ccount;
498                 /*
499                  * Another problem with RFC 3078 here.  It implies that the
500                  * peer need not send a Reset-Ack packet.  But RFC 1962
501                  * requires it.  Hopefully, M$ does send a Reset-Ack; even
502                  * though it isn't required for MPPE synchronization, it is
503                  * required to reset CCP state.
504                  */
505             }
506         }
507         if (flushed)
508             mppe_rekey(state, 0);
509     }
510
511     /*
512      * Fill in the first part of the PPP header.  The protocol field
513      * comes from the decrypted data.
514      */
515     obuf[0] = PPP_ADDRESS(ibuf);        /* +1 */
516     obuf[1] = PPP_CONTROL(ibuf);        /* +1 */
517     obuf  += 2;
518     ibuf  += PPP_HDRLEN + MPPE_OVHD;
519     isize -= PPP_HDRLEN + MPPE_OVHD;    /* -6 */
520                                         /* net osize: isize-4 */
521
522     /* And finally, decrypt the packet. */
523     arcfour_decrypt(&state->arcfour_context, ibuf, isize, obuf);
524
525     state->stats.unc_bytes += osize;
526     state->stats.unc_packets++;
527     state->stats.comp_bytes += isize;
528     state->stats.comp_packets++;
529
530     /* good packet credit */
531     state->sanity_errors >>= 1;
532
533     return osize;
534 }
535
536 /*
537  * Incompressible data has arrived (this should never happen!).
538  * We should probably drop the link if the protocol is in the range
539  * of what should be encrypted.  At the least, we should drop this
540  * packet.  (How to do this?)
541  */
542 static void
543 mppe_incomp(void *arg, unsigned char *ibuf, int icnt)
544 {
545     ppp_mppe_state *state = (ppp_mppe_state *) arg;
546
547     if (state->debug &&
548         (PPP_PROTOCOL(ibuf) >= 0x0021 && PPP_PROTOCOL(ibuf) <= 0x00fa))
549         printk(KERN_DEBUG "mppe_incomp[%d]: incompressible (unencrypted) data! "
550                "(proto %04x)\n", state->unit, PPP_PROTOCOL(ibuf));
551
552     state->stats.inc_bytes += icnt;
553     state->stats.inc_packets++;
554     state->stats.unc_bytes += icnt;
555     state->stats.unc_packets++;
556 }
557
558 /*************************************************************
559  * Module interface table
560  *************************************************************/
561
562 /* These are in ppp.c (2.2.x) or ppp_generic.c (2.4.x) */
563 extern int  ppp_register_compressor   (struct compressor *cp);
564 extern void ppp_unregister_compressor (struct compressor *cp);
565
566 /*
567  * Procedures exported to if_ppp.c.
568  */
569 struct compressor ppp_mppe = {
570     CI_MPPE,            /* compress_proto */
571     mppe_alloc,         /* comp_alloc */
572     mppe_free,          /* comp_free */
573     mppe_comp_init,     /* comp_init */
574     mppe_comp_reset,    /* comp_reset */
575     mppe_compress,      /* compress */
576     mppe_comp_stats,    /* comp_stat */
577     mppe_alloc,         /* decomp_alloc */
578     mppe_free,          /* decomp_free */
579     mppe_decomp_init,   /* decomp_init */
580     mppe_decomp_reset,  /* decomp_reset */
581     mppe_decompress,    /* decompress */
582     mppe_incomp,        /* incomp */
583     mppe_comp_stats,    /* decomp_stat */
584 };
585
586 /* 2.2 compatibility defines */
587 #ifndef __init
588 #define __init
589 #endif
590 #ifndef __exit
591 #define __exit
592 #endif
593 #ifndef MODULE_LICENSE
594 #define MODULE_LICENSE(license)
595 #endif
596
597 int __init
598 ppp_mppe_init(void)
599 {  
600     int answer = ppp_register_compressor(&ppp_mppe);
601
602     if (answer == 0)
603         printk(KERN_INFO "PPP MPPE Compression module registered\n");
604     return answer;
605 }
606
607 void __exit
608 ppp_mppe_cleanup(void)
609 {
610     ppp_unregister_compressor(&ppp_mppe);
611 }
612
613 module_init(ppp_mppe_init);
614 module_exit(ppp_mppe_cleanup);
615 MODULE_LICENSE("BSD without advertisement clause");