Home | History | Annotate | Download | only in src
      1 /*-
      2  * Copyright (c) 2000 Semen Ustimenko <semenu (at) FreeBSD.org>
      3  * All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  * 1. Redistributions of source code must retain the above copyright
      9  *    notice, this list of conditions and the following disclaimer.
     10  * 2. Redistributions in binary form must reproduce the above copyright
     11  *    notice, this list of conditions and the following disclaimer in the
     12  *    documentation and/or other materials provided with the distribution.
     13  *
     14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     24  * SUCH DAMAGE.
     25  *
     26  * $FreeBSD: src/usr.sbin/ppp/mppe.c,v 1.28.26.1 2010/12/21 17:10:29 kensmith Exp $
     27  */
     28 
     29 #include <sys/param.h>
     30 
     31 #include <sys/socket.h>
     32 #include <netinet/in_systm.h>
     33 #include <netinet/in.h>
     34 #include <netinet/ip.h>
     35 #include <sys/un.h>
     36 
     37 #include <stdio.h>
     38 #include <stdlib.h>
     39 #include <string.h>
     40 #include <termios.h>
     41 #include <openssl/rc4.h>
     42 
     43 #include "defs.h"
     44 #include "mbuf.h"
     45 #include "log.h"
     46 #include "timer.h"
     47 #include "fsm.h"
     48 #include "lqr.h"
     49 #include "hdlc.h"
     50 #include "lcp.h"
     51 #include "ccp.h"
     52 #include "throughput.h"
     53 #include "layer.h"
     54 #include "link.h"
     55 #include "chap_ms.h"
     56 #include "proto.h"
     57 #include "mppe.h"
     58 #include "ua.h"
     59 #include "descriptor.h"
     60 #ifndef NORADIUS
     61 #include "radius.h"
     62 #endif
     63 #include "ncpaddr.h"
     64 #include "iplist.h"
     65 #include "slcompress.h"
     66 #include "ipcp.h"
     67 #include "ipv6cp.h"
     68 #include "filter.h"
     69 #include "mp.h"
     70 #include "ncp.h"
     71 #include "bundle.h"
     72 
     73 /*
     74  * Documentation:
     75  *
     76  * draft-ietf-pppext-mppe-04.txt
     77  * draft-ietf-pppext-mppe-keys-02.txt
     78  */
     79 
     80 #define	MPPE_OPT_STATELESS	0x1000000
     81 #define	MPPE_OPT_COMPRESSED	0x01
     82 #define	MPPE_OPT_40BIT		0x20
     83 #define	MPPE_OPT_56BIT		0x80
     84 #define	MPPE_OPT_128BIT		0x40
     85 #define	MPPE_OPT_BITMASK	0xe0
     86 #define	MPPE_OPT_MASK		(MPPE_OPT_STATELESS | MPPE_OPT_BITMASK)
     87 
     88 #define	MPPE_FLUSHED			0x8000
     89 #define	MPPE_ENCRYPTED			0x1000
     90 #define	MPPE_HEADER_BITMASK		0xf000
     91 #define	MPPE_HEADER_FLAG		0x00ff
     92 #define	MPPE_HEADER_FLAGMASK		0x00ff
     93 #define	MPPE_HEADER_FLAGSHIFT		8
     94 #define	MPPE_HEADER_STATEFUL_KEYCHANGES	16
     95 
     96 struct mppe_state {
     97   unsigned	stateless : 1;
     98   unsigned	flushnext : 1;
     99   unsigned	flushrequired : 1;
    100   int		cohnum;
    101   unsigned	keylen;			/* 8 or 16 bytes */
    102   int 		keybits;		/* 40, 56 or 128 bits */
    103   char		sesskey[MPPE_KEY_LEN];
    104   char		mastkey[MPPE_KEY_LEN];
    105   RC4_KEY	rc4key;
    106 };
    107 
    108 int MPPE_MasterKeyValid = 0;
    109 int MPPE_IsServer = 0;
    110 char MPPE_MasterKey[MPPE_KEY_LEN];
    111 
    112 /*
    113  * The peer has missed a packet.  Mark the next output frame to be FLUSHED
    114  */
    115 static int
    116 MPPEResetOutput(void *v)
    117 {
    118   struct mppe_state *mop = (struct mppe_state *)v;
    119 
    120   if (mop->stateless)
    121     log_Printf(LogCCP, "MPPE: Unexpected output channel reset\n");
    122   else {
    123     log_Printf(LogCCP, "MPPE: Output channel reset\n");
    124     mop->flushnext = 1;
    125   }
    126 
    127   return 0;		/* Ask FSM not to ACK */
    128 }
    129 
    130 static void
    131 MPPEReduceSessionKey(struct mppe_state *mp)
    132 {
    133   switch(mp->keybits) {
    134   case 40:
    135     mp->sesskey[2] = 0x9e;
    136     mp->sesskey[1] = 0x26;
    137   case 56:
    138     mp->sesskey[0] = 0xd1;
    139   case 128:
    140     break;
    141   }
    142 }
    143 
    144 static void
    145 MPPEKeyChange(struct mppe_state *mp)
    146 {
    147   char InterimKey[MPPE_KEY_LEN];
    148   RC4_KEY RC4Key;
    149 
    150   GetNewKeyFromSHA(mp->mastkey, mp->sesskey, mp->keylen, InterimKey);
    151   RC4_set_key(&RC4Key, mp->keylen, InterimKey);
    152   RC4(&RC4Key, mp->keylen, InterimKey, mp->sesskey);
    153 
    154   MPPEReduceSessionKey(mp);
    155 }
    156 
    157 static struct mbuf *
    158 MPPEOutput(void *v, struct ccp *ccp, struct link *l __unused, int pri __unused,
    159 	   u_short *proto, struct mbuf *mp)
    160 {
    161   struct mppe_state *mop = (struct mppe_state *)v;
    162   struct mbuf *mo;
    163   u_short nproto, prefix;
    164   int dictinit, ilen, len;
    165   char *rp;
    166 
    167   ilen = m_length(mp);
    168   dictinit = 0;
    169 
    170   log_Printf(LogDEBUG, "MPPE: Output: Proto %02x (%d bytes)\n", *proto, ilen);
    171   if (*proto < 0x21 && *proto > 0xFA) {
    172     log_Printf(LogDEBUG, "MPPE: Output: Not encrypting\n");
    173     ccp->compout += ilen;
    174     ccp->uncompout += ilen;
    175     return mp;
    176   }
    177 
    178   log_DumpBp(LogDEBUG, "MPPE: Output: Encrypt packet:", mp);
    179 
    180   /* Get mbuf for prefixes */
    181   mo = m_get(4, MB_CCPOUT);
    182   mo->m_next = mp;
    183 
    184   rp = MBUF_CTOP(mo);
    185   prefix = MPPE_ENCRYPTED | mop->cohnum;
    186 
    187   if (mop->stateless ||
    188       (mop->cohnum & MPPE_HEADER_FLAGMASK) == MPPE_HEADER_FLAG) {
    189     /* Change our key */
    190     log_Printf(LogDEBUG, "MPPEOutput: Key changed [%d]\n", mop->cohnum);
    191     MPPEKeyChange(mop);
    192     dictinit = 1;
    193   }
    194 
    195   if (mop->stateless || mop->flushnext) {
    196     prefix |= MPPE_FLUSHED;
    197     dictinit = 1;
    198     mop->flushnext = 0;
    199   }
    200 
    201   if (dictinit) {
    202     /* Initialise our dictionary */
    203     log_Printf(LogDEBUG, "MPPEOutput: Dictionary initialised [%d]\n",
    204                mop->cohnum);
    205     RC4_set_key(&mop->rc4key, mop->keylen, mop->sesskey);
    206   }
    207 
    208   /* Set MPPE packet prefix */
    209   ua_htons(&prefix, rp);
    210 
    211   /* Save encrypted protocol number */
    212   nproto = htons(*proto);
    213   RC4(&mop->rc4key, 2, (char *)&nproto, rp + 2);
    214 
    215   /* Encrypt main packet */
    216   rp = MBUF_CTOP(mp);
    217   RC4(&mop->rc4key, ilen, rp, rp);
    218 
    219   mop->cohnum++;
    220   mop->cohnum &= ~MPPE_HEADER_BITMASK;
    221 
    222   /* Set the protocol number */
    223   *proto = ccp_Proto(ccp);
    224   len = m_length(mo);
    225   ccp->uncompout += ilen;
    226   ccp->compout += len;
    227 
    228   log_Printf(LogDEBUG, "MPPE: Output: Encrypted: Proto %02x (%d bytes)\n",
    229              *proto, len);
    230 
    231   return mo;
    232 }
    233 
    234 static void
    235 MPPEResetInput(void *v __unused)
    236 {
    237   log_Printf(LogCCP, "MPPE: Unexpected input channel ack\n");
    238 }
    239 
    240 static struct mbuf *
    241 MPPEInput(void *v, struct ccp *ccp, u_short *proto, struct mbuf *mp)
    242 {
    243   struct mppe_state *mip = (struct mppe_state *)v;
    244   u_short prefix;
    245   char *rp;
    246   int dictinit, flushed, ilen, len, n;
    247 
    248   ilen = m_length(mp);
    249   dictinit = 0;
    250   ccp->compin += ilen;
    251 
    252   log_Printf(LogDEBUG, "MPPE: Input: Proto %02x (%d bytes)\n", *proto, ilen);
    253   log_DumpBp(LogDEBUG, "MPPE: Input: Packet:", mp);
    254 
    255   mp = mbuf_Read(mp, &prefix, 2);
    256   prefix = ntohs(prefix);
    257   flushed = prefix & MPPE_FLUSHED;
    258   prefix &= ~flushed;
    259   if ((prefix & MPPE_HEADER_BITMASK) != MPPE_ENCRYPTED) {
    260     log_Printf(LogERROR, "MPPE: Input: Invalid packet (flags = 0x%x)\n",
    261                (prefix & MPPE_HEADER_BITMASK) | flushed);
    262     m_freem(mp);
    263     return NULL;
    264   }
    265 
    266   prefix &= ~MPPE_HEADER_BITMASK;
    267 
    268   if (!flushed && mip->stateless) {
    269     log_Printf(LogCCP, "MPPEInput: Packet without MPPE_FLUSHED set"
    270                " in stateless mode\n");
    271     flushed = MPPE_FLUSHED;
    272     /* Should we really continue ? */
    273   }
    274 
    275   if (mip->stateless) {
    276     /* Change our key for each missed packet in stateless mode */
    277     while (prefix != mip->cohnum) {
    278       log_Printf(LogDEBUG, "MPPEInput: Key changed [%u]\n", prefix);
    279       MPPEKeyChange(mip);
    280       /*
    281        * mip->cohnum contains what we received last time in stateless
    282        * mode.
    283        */
    284       mip->cohnum++;
    285       mip->cohnum &= ~MPPE_HEADER_BITMASK;
    286     }
    287     dictinit = 1;
    288   } else {
    289     if (flushed) {
    290       /*
    291        * We can always process a flushed packet.
    292        * Catch up on any outstanding key changes.
    293        */
    294       n = (prefix >> MPPE_HEADER_FLAGSHIFT) -
    295           (mip->cohnum >> MPPE_HEADER_FLAGSHIFT);
    296       if (n < 0)
    297         n += MPPE_HEADER_STATEFUL_KEYCHANGES;
    298       while (n--) {
    299         log_Printf(LogDEBUG, "MPPEInput: Key changed during catchup [%u]\n",
    300                    prefix);
    301         MPPEKeyChange(mip);
    302       }
    303       mip->flushrequired = 0;
    304       mip->cohnum = prefix;
    305       dictinit = 1;
    306     }
    307 
    308     if (mip->flushrequired) {
    309       /*
    310        * Perhaps we should be lenient if
    311        * (prefix & MPPE_HEADER_FLAGMASK) == MPPE_HEADER_FLAG
    312        * The spec says that we shouldn't be though....
    313        */
    314       log_Printf(LogDEBUG, "MPPE: Not flushed - discarded\n");
    315       fsm_Output(&ccp->fsm, CODE_RESETREQ, ccp->fsm.reqid++, NULL, 0,
    316                  MB_CCPOUT);
    317       m_freem(mp);
    318       return NULL;
    319     }
    320 
    321     if (prefix != mip->cohnum) {
    322       /*
    323        * We're in stateful mode and didn't receive the expected
    324        * packet.  Send a reset request, but don't tell the CCP layer
    325        * about it as we don't expect to receive a Reset ACK !
    326        * Guess what... M$ invented this !
    327        */
    328       log_Printf(LogCCP, "MPPE: Input: Got seq %u, not %u\n",
    329                  prefix, mip->cohnum);
    330       fsm_Output(&ccp->fsm, CODE_RESETREQ, ccp->fsm.reqid++, NULL, 0,
    331                  MB_CCPOUT);
    332       mip->flushrequired = 1;
    333       m_freem(mp);
    334       return NULL;
    335     }
    336 
    337     if ((prefix & MPPE_HEADER_FLAGMASK) == MPPE_HEADER_FLAG) {
    338       log_Printf(LogDEBUG, "MPPEInput: Key changed [%u]\n", prefix);
    339       MPPEKeyChange(mip);
    340       dictinit = 1;
    341     } else if (flushed)
    342       dictinit = 1;
    343 
    344     /*
    345      * mip->cohnum contains what we expect to receive next time in stateful
    346      * mode.
    347      */
    348     mip->cohnum++;
    349     mip->cohnum &= ~MPPE_HEADER_BITMASK;
    350   }
    351 
    352   if (dictinit) {
    353     log_Printf(LogDEBUG, "MPPEInput: Dictionary initialised [%u]\n", prefix);
    354     RC4_set_key(&mip->rc4key, mip->keylen, mip->sesskey);
    355   }
    356 
    357   mp = mbuf_Read(mp, proto, 2);
    358   RC4(&mip->rc4key, 2, (char *)proto, (char *)proto);
    359   *proto = ntohs(*proto);
    360 
    361   rp = MBUF_CTOP(mp);
    362   len = m_length(mp);
    363   RC4(&mip->rc4key, len, rp, rp);
    364 
    365   log_Printf(LogDEBUG, "MPPEInput: Decrypted: Proto %02x (%d bytes)\n",
    366              *proto, len);
    367   log_DumpBp(LogDEBUG, "MPPEInput: Decrypted: Packet:", mp);
    368 
    369   ccp->uncompin += len;
    370 
    371   return mp;
    372 }
    373 
    374 static void
    375 MPPEDictSetup(void *v __unused, struct ccp *ccp __unused,
    376 	      u_short proto __unused, struct mbuf *mp __unused)
    377 {
    378   /* Nothing to see here */
    379 }
    380 
    381 static const char *
    382 MPPEDispOpts(struct fsm_opt *o)
    383 {
    384   static char buf[70];
    385   u_int32_t val;
    386   char ch;
    387   int len, n;
    388 
    389   ua_ntohl(o->data, &val);
    390   len = 0;
    391   if ((n = snprintf(buf, sizeof buf, "value 0x%08x ", (unsigned)val)) > 0)
    392     len += n;
    393   if (!(val & MPPE_OPT_BITMASK)) {
    394     if ((n = snprintf(buf + len, sizeof buf - len, "(0")) > 0)
    395       len += n;
    396   } else {
    397     ch = '(';
    398     if (val & MPPE_OPT_128BIT) {
    399       if ((n = snprintf(buf + len, sizeof buf - len, "%c128", ch)) > 0)
    400         len += n;
    401       ch = '/';
    402     }
    403     if (val & MPPE_OPT_56BIT) {
    404       if ((n = snprintf(buf + len, sizeof buf - len, "%c56", ch)) > 0)
    405         len += n;
    406       ch = '/';
    407     }
    408     if (val & MPPE_OPT_40BIT) {
    409       if ((n = snprintf(buf + len, sizeof buf - len, "%c40", ch)) > 0)
    410         len += n;
    411       ch = '/';
    412     }
    413   }
    414 
    415   if ((n = snprintf(buf + len, sizeof buf - len, " bits, state%s",
    416                     (val & MPPE_OPT_STATELESS) ? "less" : "ful")) > 0)
    417     len += n;
    418 
    419   if (val & MPPE_OPT_COMPRESSED) {
    420     if ((n = snprintf(buf + len, sizeof buf - len, ", compressed")) > 0)
    421       len += n;
    422   }
    423 
    424   snprintf(buf + len, sizeof buf - len, ")");
    425 
    426   return buf;
    427 }
    428 
    429 static int
    430 MPPEUsable(struct fsm *fp)
    431 {
    432   int ok;
    433 #ifndef NORADIUS
    434   struct radius *r = &fp->bundle->radius;
    435 
    436   /*
    437    * If the radius server gave us RAD_MICROSOFT_MS_MPPE_ENCRYPTION_TYPES,
    438    * use that instead of our configuration value.
    439    */
    440   if (*r->cfg.file) {
    441     ok = r->mppe.sendkeylen && r->mppe.recvkeylen;
    442     if (!ok)
    443       log_Printf(LogCCP, "MPPE: Not permitted by RADIUS server\n");
    444   } else
    445 #endif
    446   {
    447     struct lcp *lcp = &fp->link->lcp;
    448     ok = (lcp->want_auth == PROTO_CHAP && lcp->want_authtype == 0x81) ||
    449          (lcp->his_auth == PROTO_CHAP && lcp->his_authtype == 0x81);
    450     if (!ok)
    451       log_Printf(LogCCP, "MPPE: Not usable without CHAP81\n");
    452   }
    453 
    454   return ok;
    455 }
    456 
    457 static int
    458 MPPERequired(struct fsm *fp)
    459 {
    460 #ifndef NORADIUS
    461   /*
    462    * If the radius server gave us RAD_MICROSOFT_MS_MPPE_ENCRYPTION_POLICY,
    463    * use that instead of our configuration value.
    464    */
    465   if (*fp->bundle->radius.cfg.file && fp->bundle->radius.mppe.policy)
    466     return fp->bundle->radius.mppe.policy == MPPE_POLICY_REQUIRED ? 1 : 0;
    467 #endif
    468 
    469   return fp->link->ccp.cfg.mppe.required;
    470 }
    471 
    472 static u_int32_t
    473 MPPE_ConfigVal(struct bundle *bundle __unused, const struct ccp_config *cfg)
    474 {
    475   u_int32_t val;
    476 
    477   val = cfg->mppe.state == MPPE_STATELESS ? MPPE_OPT_STATELESS : 0;
    478 #ifndef NORADIUS
    479   /*
    480    * If the radius server gave us RAD_MICROSOFT_MS_MPPE_ENCRYPTION_TYPES,
    481    * use that instead of our configuration value.
    482    */
    483   if (*bundle->radius.cfg.file && bundle->radius.mppe.types) {
    484     if (bundle->radius.mppe.types & MPPE_TYPE_40BIT)
    485       val |= MPPE_OPT_40BIT;
    486     if (bundle->radius.mppe.types & MPPE_TYPE_128BIT)
    487       val |= MPPE_OPT_128BIT;
    488   } else
    489 #endif
    490     switch(cfg->mppe.keybits) {
    491     case 128:
    492       val |= MPPE_OPT_128BIT;
    493       break;
    494     case 56:
    495       val |= MPPE_OPT_56BIT;
    496       break;
    497     case 40:
    498       val |= MPPE_OPT_40BIT;
    499       break;
    500     case 0:
    501       val |= MPPE_OPT_128BIT | MPPE_OPT_56BIT | MPPE_OPT_40BIT;
    502       break;
    503     }
    504 
    505   return val;
    506 }
    507 
    508 /*
    509  * What options should we use for our first configure request
    510  */
    511 static void
    512 MPPEInitOptsOutput(struct bundle *bundle, struct fsm_opt *o,
    513                    const struct ccp_config *cfg)
    514 {
    515   u_int32_t mval;
    516 
    517   o->hdr.len = 6;
    518 
    519   if (!MPPE_MasterKeyValid) {
    520     log_Printf(LogCCP, "MPPE: MasterKey is invalid,"
    521                " MPPE is available only with CHAP81 authentication\n");
    522     mval = 0;
    523     ua_htonl(&mval, o->data);
    524     return;
    525   }
    526 
    527 
    528   mval = MPPE_ConfigVal(bundle, cfg);
    529   ua_htonl(&mval, o->data);
    530 }
    531 
    532 /*
    533  * Our CCP request was NAK'd with the given options
    534  */
    535 static int
    536 MPPESetOptsOutput(struct bundle *bundle, struct fsm_opt *o,
    537                   const struct ccp_config *cfg)
    538 {
    539   u_int32_t mval, peer;
    540 
    541   ua_ntohl(o->data, &peer);
    542 
    543   if (!MPPE_MasterKeyValid)
    544     /* Treat their NAK as a REJ */
    545     return MODE_NAK;
    546 
    547   mval = MPPE_ConfigVal(bundle, cfg);
    548 
    549   /*
    550    * If we haven't been configured with a specific number of keybits, allow
    551    * whatever the peer asks for.
    552    */
    553   if (!cfg->mppe.keybits) {
    554     mval &= ~MPPE_OPT_BITMASK;
    555     mval |= (peer & MPPE_OPT_BITMASK);
    556     if (!(mval & MPPE_OPT_BITMASK))
    557       mval |= MPPE_OPT_128BIT;
    558   }
    559 
    560   /* Adjust our statelessness */
    561   if (cfg->mppe.state == MPPE_ANYSTATE) {
    562     mval &= ~MPPE_OPT_STATELESS;
    563     mval |= (peer & MPPE_OPT_STATELESS);
    564   }
    565 
    566   ua_htonl(&mval, o->data);
    567 
    568   return MODE_ACK;
    569 }
    570 
    571 /*
    572  * The peer has requested the given options
    573  */
    574 static int
    575 MPPESetOptsInput(struct bundle *bundle, struct fsm_opt *o,
    576                  const struct ccp_config *cfg)
    577 {
    578   u_int32_t mval, peer;
    579   int res = MODE_ACK;
    580 
    581   ua_ntohl(o->data, &peer);
    582   if (!MPPE_MasterKeyValid) {
    583     if (peer != 0) {
    584       peer = 0;
    585       ua_htonl(&peer, o->data);
    586       return MODE_NAK;
    587     } else
    588       return MODE_ACK;
    589   }
    590 
    591   mval = MPPE_ConfigVal(bundle, cfg);
    592 
    593   if (peer & ~MPPE_OPT_MASK)
    594     /* He's asking for bits we don't know about */
    595     res = MODE_NAK;
    596 
    597   if (peer & MPPE_OPT_STATELESS) {
    598     if (cfg->mppe.state == MPPE_STATEFUL)
    599       /* Peer can't have stateless */
    600       res = MODE_NAK;
    601     else
    602       /* Peer wants stateless, that's ok */
    603       mval |= MPPE_OPT_STATELESS;
    604   } else {
    605     if (cfg->mppe.state == MPPE_STATELESS)
    606       /* Peer must have stateless */
    607       res = MODE_NAK;
    608     else
    609       /* Peer doesn't want stateless, that's ok */
    610       mval &= ~MPPE_OPT_STATELESS;
    611   }
    612 
    613   /* If we've got a configured number of keybits - the peer must use that */
    614   if (cfg->mppe.keybits) {
    615     ua_htonl(&mval, o->data);
    616     return peer == mval ? res : MODE_NAK;
    617   }
    618 
    619   /* If a specific number of bits hasn't been requested, we'll need to NAK */
    620   switch (peer & MPPE_OPT_BITMASK) {
    621   case MPPE_OPT_128BIT:
    622   case MPPE_OPT_56BIT:
    623   case MPPE_OPT_40BIT:
    624     break;
    625   default:
    626     res = MODE_NAK;
    627   }
    628 
    629   /* Suggest the best number of bits */
    630   mval &= ~MPPE_OPT_BITMASK;
    631   if (peer & MPPE_OPT_128BIT)
    632     mval |= MPPE_OPT_128BIT;
    633   else if (peer & MPPE_OPT_56BIT)
    634     mval |= MPPE_OPT_56BIT;
    635   else if (peer & MPPE_OPT_40BIT)
    636     mval |= MPPE_OPT_40BIT;
    637   else
    638     mval |= MPPE_OPT_128BIT;
    639   ua_htonl(&mval, o->data);
    640 
    641   return res;
    642 }
    643 
    644 static struct mppe_state *
    645 MPPE_InitState(struct fsm_opt *o)
    646 {
    647   struct mppe_state *mp;
    648   u_int32_t val;
    649 
    650   if ((mp = calloc(1, sizeof *mp)) != NULL) {
    651     ua_ntohl(o->data, &val);
    652 
    653     switch (val & MPPE_OPT_BITMASK) {
    654     case MPPE_OPT_128BIT:
    655       mp->keylen = 16;
    656       mp->keybits = 128;
    657       break;
    658     case MPPE_OPT_56BIT:
    659       mp->keylen = 8;
    660       mp->keybits = 56;
    661       break;
    662     case MPPE_OPT_40BIT:
    663       mp->keylen = 8;
    664       mp->keybits = 40;
    665       break;
    666     default:
    667       log_Printf(LogWARN, "Unexpected MPPE options 0x%08x\n", val);
    668       free(mp);
    669       return NULL;
    670     }
    671 
    672     mp->stateless = !!(val & MPPE_OPT_STATELESS);
    673   }
    674 
    675   return mp;
    676 }
    677 
    678 static void *
    679 MPPEInitInput(struct bundle *bundle __unused, struct fsm_opt *o)
    680 {
    681   struct mppe_state *mip;
    682 
    683   if (!MPPE_MasterKeyValid) {
    684     log_Printf(LogWARN, "MPPE: Cannot initialise without CHAP81\n");
    685     return NULL;
    686   }
    687 
    688   if ((mip = MPPE_InitState(o)) == NULL) {
    689     log_Printf(LogWARN, "MPPEInput: Cannot initialise - unexpected options\n");
    690     return NULL;
    691   }
    692 
    693   log_Printf(LogDEBUG, "MPPE: InitInput: %d-bits\n", mip->keybits);
    694 
    695 #ifndef NORADIUS
    696   if (*bundle->radius.cfg.file && bundle->radius.mppe.recvkey) {
    697     if (mip->keylen > bundle->radius.mppe.recvkeylen)
    698       mip->keylen = bundle->radius.mppe.recvkeylen;
    699     if (mip->keylen > sizeof mip->mastkey)
    700       mip->keylen = sizeof mip->mastkey;
    701     memcpy(mip->mastkey, bundle->radius.mppe.recvkey, mip->keylen);
    702   } else
    703 #endif
    704     GetAsymetricStartKey(MPPE_MasterKey, mip->mastkey, mip->keylen, 0,
    705                          MPPE_IsServer);
    706 
    707   GetNewKeyFromSHA(mip->mastkey, mip->mastkey, mip->keylen, mip->sesskey);
    708 
    709   MPPEReduceSessionKey(mip);
    710 
    711   log_Printf(LogCCP, "MPPE: Input channel initiated\n");
    712 
    713   if (!mip->stateless) {
    714     /*
    715      * We need to initialise our dictionary here as the first packet we
    716      * receive is unlikely to have the FLUSHED bit set.
    717      */
    718     log_Printf(LogDEBUG, "MPPEInitInput: Dictionary initialised [%d]\n",
    719                mip->cohnum);
    720     RC4_set_key(&mip->rc4key, mip->keylen, mip->sesskey);
    721   } else {
    722     /*
    723      * We do the first key change here as the first packet is expected
    724      * to have a sequence number of 0 and we'll therefore not expect
    725      * to have to change the key at that point.
    726      */
    727     log_Printf(LogDEBUG, "MPPEInitInput: Key changed [%d]\n", mip->cohnum);
    728     MPPEKeyChange(mip);
    729   }
    730 
    731   return mip;
    732 }
    733 
    734 static void *
    735 MPPEInitOutput(struct bundle *bundle __unused, struct fsm_opt *o)
    736 {
    737   struct mppe_state *mop;
    738 
    739   if (!MPPE_MasterKeyValid) {
    740     log_Printf(LogWARN, "MPPE: Cannot initialise without CHAP81\n");
    741     return NULL;
    742   }
    743 
    744   if ((mop = MPPE_InitState(o)) == NULL) {
    745     log_Printf(LogWARN, "MPPEOutput: Cannot initialise - unexpected options\n");
    746     return NULL;
    747   }
    748 
    749   log_Printf(LogDEBUG, "MPPE: InitOutput: %d-bits\n", mop->keybits);
    750 
    751 #ifndef NORADIUS
    752   if (*bundle->radius.cfg.file && bundle->radius.mppe.sendkey) {
    753     if (mop->keylen > bundle->radius.mppe.sendkeylen)
    754       mop->keylen = bundle->radius.mppe.sendkeylen;
    755     if (mop->keylen > sizeof mop->mastkey)
    756       mop->keylen = sizeof mop->mastkey;
    757     memcpy(mop->mastkey, bundle->radius.mppe.sendkey, mop->keylen);
    758   } else
    759 #endif
    760     GetAsymetricStartKey(MPPE_MasterKey, mop->mastkey, mop->keylen, 1,
    761                          MPPE_IsServer);
    762 
    763   GetNewKeyFromSHA(mop->mastkey, mop->mastkey, mop->keylen, mop->sesskey);
    764 
    765   MPPEReduceSessionKey(mop);
    766 
    767   log_Printf(LogCCP, "MPPE: Output channel initiated\n");
    768 
    769   if (!mop->stateless) {
    770     /*
    771      * We need to initialise our dictionary now as the first packet we
    772      * send won't have the FLUSHED bit set.
    773      */
    774     log_Printf(LogDEBUG, "MPPEInitOutput: Dictionary initialised [%d]\n",
    775                mop->cohnum);
    776     RC4_set_key(&mop->rc4key, mop->keylen, mop->sesskey);
    777   }
    778 
    779   return mop;
    780 }
    781 
    782 static void
    783 MPPETermInput(void *v)
    784 {
    785   free(v);
    786 }
    787 
    788 static void
    789 MPPETermOutput(void *v)
    790 {
    791   free(v);
    792 }
    793 
    794 const struct ccp_algorithm MPPEAlgorithm = {
    795   TY_MPPE,
    796   CCP_NEG_MPPE,
    797   MPPEDispOpts,
    798   MPPEUsable,
    799   MPPERequired,
    800   {
    801     MPPESetOptsInput,
    802     MPPEInitInput,
    803     MPPETermInput,
    804     MPPEResetInput,
    805     MPPEInput,
    806     MPPEDictSetup
    807   },
    808   {
    809     2,
    810     MPPEInitOptsOutput,
    811     MPPESetOptsOutput,
    812     MPPEInitOutput,
    813     MPPETermOutput,
    814     MPPEResetOutput,
    815     MPPEOutput
    816   },
    817 };
    818