/*-
 * Copyright (c) 2000 Semen Ustimenko <semenu@FreeBSD.org>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $FreeBSD: src/usr.sbin/ppp/mppe.c,v 1.28.26.1 2010/12/21 17:10:29 kensmith Exp $
 */

#include <sys/param.h>

#include <sys/socket.h>
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <sys/un.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <openssl/rc4.h>

#include "defs.h"
#include "mbuf.h"
#include "log.h"
#include "timer.h"
#include "fsm.h"
#include "lqr.h"
#include "hdlc.h"
#include "lcp.h"
#include "ccp.h"
#include "throughput.h"
#include "layer.h"
#include "link.h"
#include "chap_ms.h"
#include "proto.h"
#include "mppe.h"
#include "ua.h"
#include "descriptor.h"
#ifndef NORADIUS
#include "radius.h"
#endif
#include "ncpaddr.h"
#include "iplist.h"
#include "slcompress.h"
#include "ipcp.h"
#include "ipv6cp.h"
#include "filter.h"
#include "mp.h"
#include "ncp.h"
#include "bundle.h"

/*
 * Documentation:
 *
 * draft-ietf-pppext-mppe-04.txt
 * draft-ietf-pppext-mppe-keys-02.txt
 */

#define	MPPE_OPT_STATELESS	0x1000000
#define	MPPE_OPT_COMPRESSED	0x01
#define	MPPE_OPT_40BIT		0x20
#define	MPPE_OPT_56BIT		0x80
#define	MPPE_OPT_128BIT		0x40
#define	MPPE_OPT_BITMASK	0xe0
#define	MPPE_OPT_MASK		(MPPE_OPT_STATELESS | MPPE_OPT_BITMASK)

#define	MPPE_FLUSHED			0x8000
#define	MPPE_ENCRYPTED			0x1000
#define	MPPE_HEADER_BITMASK		0xf000
#define	MPPE_HEADER_FLAG		0x00ff
#define	MPPE_HEADER_FLAGMASK		0x00ff
#define	MPPE_HEADER_FLAGSHIFT		8
#define	MPPE_HEADER_STATEFUL_KEYCHANGES	16

struct mppe_state {
  unsigned	stateless : 1;
  unsigned	flushnext : 1;
  unsigned	flushrequired : 1;
  int		cohnum;
  unsigned	keylen;			/* 8 or 16 bytes */
  int 		keybits;		/* 40, 56 or 128 bits */
  char		sesskey[MPPE_KEY_LEN];
  char		mastkey[MPPE_KEY_LEN];
  RC4_KEY	rc4key;
};

int MPPE_MasterKeyValid = 0;
int MPPE_IsServer = 0;
char MPPE_MasterKey[MPPE_KEY_LEN];

/*
 * The peer has missed a packet.  Mark the next output frame to be FLUSHED
 */
static int
MPPEResetOutput(void *v)
{
  struct mppe_state *mop = (struct mppe_state *)v;

  if (mop->stateless)
    log_Printf(LogCCP, "MPPE: Unexpected output channel reset\n");
  else {
    log_Printf(LogCCP, "MPPE: Output channel reset\n");
    mop->flushnext = 1;
  }

  return 0;		/* Ask FSM not to ACK */
}

static void
MPPEReduceSessionKey(struct mppe_state *mp)
{
  switch(mp->keybits) {
  case 40:
    mp->sesskey[2] = 0x9e;
    mp->sesskey[1] = 0x26;
  case 56:
    mp->sesskey[0] = 0xd1;
  case 128:
    break;
  }
}

static void
MPPEKeyChange(struct mppe_state *mp)
{
  char InterimKey[MPPE_KEY_LEN];
  RC4_KEY RC4Key;

  GetNewKeyFromSHA(mp->mastkey, mp->sesskey, mp->keylen, InterimKey);
  RC4_set_key(&RC4Key, mp->keylen, InterimKey);
  RC4(&RC4Key, mp->keylen, InterimKey, mp->sesskey);

  MPPEReduceSessionKey(mp);
}

static struct mbuf *
MPPEOutput(void *v, struct ccp *ccp, struct link *l __unused, int pri __unused,
	   u_short *proto, struct mbuf *mp)
{
  struct mppe_state *mop = (struct mppe_state *)v;
  struct mbuf *mo;
  u_short nproto, prefix;
  int dictinit, ilen, len;
  char *rp;

  ilen = m_length(mp);
  dictinit = 0;

  log_Printf(LogDEBUG, "MPPE: Output: Proto %02x (%d bytes)\n", *proto, ilen);
  if (*proto < 0x21 && *proto > 0xFA) {
    log_Printf(LogDEBUG, "MPPE: Output: Not encrypting\n");
    ccp->compout += ilen;
    ccp->uncompout += ilen;
    return mp;
  }

  log_DumpBp(LogDEBUG, "MPPE: Output: Encrypt packet:", mp);

  /* Get mbuf for prefixes */
  mo = m_get(4, MB_CCPOUT);
  mo->m_next = mp;

  rp = MBUF_CTOP(mo);
  prefix = MPPE_ENCRYPTED | mop->cohnum;

  if (mop->stateless ||
      (mop->cohnum & MPPE_HEADER_FLAGMASK) == MPPE_HEADER_FLAG) {
    /* Change our key */
    log_Printf(LogDEBUG, "MPPEOutput: Key changed [%d]\n", mop->cohnum);
    MPPEKeyChange(mop);
    dictinit = 1;
  }

  if (mop->stateless || mop->flushnext) {
    prefix |= MPPE_FLUSHED;
    dictinit = 1;
    mop->flushnext = 0;
  }

  if (dictinit) {
    /* Initialise our dictionary */
    log_Printf(LogDEBUG, "MPPEOutput: Dictionary initialised [%d]\n",
               mop->cohnum);
    RC4_set_key(&mop->rc4key, mop->keylen, mop->sesskey);
  }

  /* Set MPPE packet prefix */
  ua_htons(&prefix, rp);

  /* Save encrypted protocol number */
  nproto = htons(*proto);
  RC4(&mop->rc4key, 2, (char *)&nproto, rp + 2);

  /* Encrypt main packet */
  rp = MBUF_CTOP(mp);
  RC4(&mop->rc4key, ilen, rp, rp);

  mop->cohnum++;
  mop->cohnum &= ~MPPE_HEADER_BITMASK;

  /* Set the protocol number */
  *proto = ccp_Proto(ccp);
  len = m_length(mo);
  ccp->uncompout += ilen;
  ccp->compout += len;

  log_Printf(LogDEBUG, "MPPE: Output: Encrypted: Proto %02x (%d bytes)\n",
             *proto, len);

  return mo;
}

static void
MPPEResetInput(void *v __unused)
{
  log_Printf(LogCCP, "MPPE: Unexpected input channel ack\n");
}

static struct mbuf *
MPPEInput(void *v, struct ccp *ccp, u_short *proto, struct mbuf *mp)
{
  struct mppe_state *mip = (struct mppe_state *)v;
  u_short prefix;
  char *rp;
  int dictinit, flushed, ilen, len, n;

  ilen = m_length(mp);
  dictinit = 0;
  ccp->compin += ilen;

  log_Printf(LogDEBUG, "MPPE: Input: Proto %02x (%d bytes)\n", *proto, ilen);
  log_DumpBp(LogDEBUG, "MPPE: Input: Packet:", mp);

  mp = mbuf_Read(mp, &prefix, 2);
  prefix = ntohs(prefix);
  flushed = prefix & MPPE_FLUSHED;
  prefix &= ~flushed;
  if ((prefix & MPPE_HEADER_BITMASK) != MPPE_ENCRYPTED) {
    log_Printf(LogERROR, "MPPE: Input: Invalid packet (flags = 0x%x)\n",
               (prefix & MPPE_HEADER_BITMASK) | flushed);
    m_freem(mp);
    return NULL;
  }

  prefix &= ~MPPE_HEADER_BITMASK;

  if (!flushed && mip->stateless) {
    log_Printf(LogCCP, "MPPEInput: Packet without MPPE_FLUSHED set"
               " in stateless mode\n");
    flushed = MPPE_FLUSHED;
    /* Should we really continue ? */
  }

  if (mip->stateless) {
    /* Change our key for each missed packet in stateless mode */
    while (prefix != mip->cohnum) {
      log_Printf(LogDEBUG, "MPPEInput: Key changed [%u]\n", prefix);
      MPPEKeyChange(mip);
      /*
       * mip->cohnum contains what we received last time in stateless
       * mode.
       */
      mip->cohnum++;
      mip->cohnum &= ~MPPE_HEADER_BITMASK;
    }
    dictinit = 1;
  } else {
    if (flushed) {
      /*
       * We can always process a flushed packet.
       * Catch up on any outstanding key changes.
       */
      n = (prefix >> MPPE_HEADER_FLAGSHIFT) -
          (mip->cohnum >> MPPE_HEADER_FLAGSHIFT);
      if (n < 0)
        n += MPPE_HEADER_STATEFUL_KEYCHANGES;
      while (n--) {
        log_Printf(LogDEBUG, "MPPEInput: Key changed during catchup [%u]\n",
                   prefix);
        MPPEKeyChange(mip);
      }
      mip->flushrequired = 0;
      mip->cohnum = prefix;
      dictinit = 1;
    }

    if (mip->flushrequired) {
      /*
       * Perhaps we should be lenient if
       * (prefix & MPPE_HEADER_FLAGMASK) == MPPE_HEADER_FLAG
       * The spec says that we shouldn't be though....
       */
      log_Printf(LogDEBUG, "MPPE: Not flushed - discarded\n");
      fsm_Output(&ccp->fsm, CODE_RESETREQ, ccp->fsm.reqid++, NULL, 0,
                 MB_CCPOUT);
      m_freem(mp);
      return NULL;
    }

    if (prefix != mip->cohnum) {
      /*
       * We're in stateful mode and didn't receive the expected
       * packet.  Send a reset request, but don't tell the CCP layer
       * about it as we don't expect to receive a Reset ACK !
       * Guess what... M$ invented this !
       */
      log_Printf(LogCCP, "MPPE: Input: Got seq %u, not %u\n",
                 prefix, mip->cohnum);
      fsm_Output(&ccp->fsm, CODE_RESETREQ, ccp->fsm.reqid++, NULL, 0,
                 MB_CCPOUT);
      mip->flushrequired = 1;
      m_freem(mp);
      return NULL;
    }

    if ((prefix & MPPE_HEADER_FLAGMASK) == MPPE_HEADER_FLAG) {
      log_Printf(LogDEBUG, "MPPEInput: Key changed [%u]\n", prefix);
      MPPEKeyChange(mip);
      dictinit = 1;
    } else if (flushed)
      dictinit = 1;

    /*
     * mip->cohnum contains what we expect to receive next time in stateful
     * mode.
     */
    mip->cohnum++;
    mip->cohnum &= ~MPPE_HEADER_BITMASK;
  }

  if (dictinit) {
    log_Printf(LogDEBUG, "MPPEInput: Dictionary initialised [%u]\n", prefix);
    RC4_set_key(&mip->rc4key, mip->keylen, mip->sesskey);
  }

  mp = mbuf_Read(mp, proto, 2);
  RC4(&mip->rc4key, 2, (char *)proto, (char *)proto);
  *proto = ntohs(*proto);

  rp = MBUF_CTOP(mp);
  len = m_length(mp);
  RC4(&mip->rc4key, len, rp, rp);

  log_Printf(LogDEBUG, "MPPEInput: Decrypted: Proto %02x (%d bytes)\n",
             *proto, len);
  log_DumpBp(LogDEBUG, "MPPEInput: Decrypted: Packet:", mp);

  ccp->uncompin += len;

  return mp;
}

static void
MPPEDictSetup(void *v __unused, struct ccp *ccp __unused,
	      u_short proto __unused, struct mbuf *mp __unused)
{
  /* Nothing to see here */
}

static const char *
MPPEDispOpts(struct fsm_opt *o)
{
  static char buf[70];
  u_int32_t val;
  char ch;
  int len, n;

  ua_ntohl(o->data, &val);
  len = 0;
  if ((n = snprintf(buf, sizeof buf, "value 0x%08x ", (unsigned)val)) > 0)
    len += n;
  if (!(val & MPPE_OPT_BITMASK)) {
    if ((n = snprintf(buf + len, sizeof buf - len, "(0")) > 0)
      len += n;
  } else {
    ch = '(';
    if (val & MPPE_OPT_128BIT) {
      if ((n = snprintf(buf + len, sizeof buf - len, "%c128", ch)) > 0)
        len += n;
      ch = '/';
    }
    if (val & MPPE_OPT_56BIT) {
      if ((n = snprintf(buf + len, sizeof buf - len, "%c56", ch)) > 0)
        len += n;
      ch = '/';
    }
    if (val & MPPE_OPT_40BIT) {
      if ((n = snprintf(buf + len, sizeof buf - len, "%c40", ch)) > 0)
        len += n;
      ch = '/';
    }
  }

  if ((n = snprintf(buf + len, sizeof buf - len, " bits, state%s",
                    (val & MPPE_OPT_STATELESS) ? "less" : "ful")) > 0)
    len += n;

  if (val & MPPE_OPT_COMPRESSED) {
    if ((n = snprintf(buf + len, sizeof buf - len, ", compressed")) > 0)
      len += n;
  }

  snprintf(buf + len, sizeof buf - len, ")");

  return buf;
}

static int
MPPEUsable(struct fsm *fp)
{
  int ok;
#ifndef NORADIUS
  struct radius *r = &fp->bundle->radius;

  /*
   * If the radius server gave us RAD_MICROSOFT_MS_MPPE_ENCRYPTION_TYPES,
   * use that instead of our configuration value.
   */
  if (*r->cfg.file) {
    ok = r->mppe.sendkeylen && r->mppe.recvkeylen;
    if (!ok)
      log_Printf(LogCCP, "MPPE: Not permitted by RADIUS server\n");
  } else
#endif
  {
    struct lcp *lcp = &fp->link->lcp;
    ok = (lcp->want_auth == PROTO_CHAP && lcp->want_authtype == 0x81) ||
         (lcp->his_auth == PROTO_CHAP && lcp->his_authtype == 0x81);
    if (!ok)
      log_Printf(LogCCP, "MPPE: Not usable without CHAP81\n");
  }

  return ok;
}

static int
MPPERequired(struct fsm *fp)
{
#ifndef NORADIUS
  /*
   * If the radius server gave us RAD_MICROSOFT_MS_MPPE_ENCRYPTION_POLICY,
   * use that instead of our configuration value.
   */
  if (*fp->bundle->radius.cfg.file && fp->bundle->radius.mppe.policy)
    return fp->bundle->radius.mppe.policy == MPPE_POLICY_REQUIRED ? 1 : 0;
#endif

  return fp->link->ccp.cfg.mppe.required;
}

static u_int32_t
MPPE_ConfigVal(struct bundle *bundle __unused, const struct ccp_config *cfg)
{
  u_int32_t val;

  val = cfg->mppe.state == MPPE_STATELESS ? MPPE_OPT_STATELESS : 0;
#ifndef NORADIUS
  /*
   * If the radius server gave us RAD_MICROSOFT_MS_MPPE_ENCRYPTION_TYPES,
   * use that instead of our configuration value.
   */
  if (*bundle->radius.cfg.file && bundle->radius.mppe.types) {
    if (bundle->radius.mppe.types & MPPE_TYPE_40BIT)
      val |= MPPE_OPT_40BIT;
    if (bundle->radius.mppe.types & MPPE_TYPE_128BIT)
      val |= MPPE_OPT_128BIT;
  } else
#endif
    switch(cfg->mppe.keybits) {
    case 128:
      val |= MPPE_OPT_128BIT;
      break;
    case 56:
      val |= MPPE_OPT_56BIT;
      break;
    case 40:
      val |= MPPE_OPT_40BIT;
      break;
    case 0:
      val |= MPPE_OPT_128BIT | MPPE_OPT_56BIT | MPPE_OPT_40BIT;
      break;
    }

  return val;
}

/*
 * What options should we use for our first configure request
 */
static void
MPPEInitOptsOutput(struct bundle *bundle, struct fsm_opt *o,
                   const struct ccp_config *cfg)
{
  u_int32_t mval;

  o->hdr.len = 6;

  if (!MPPE_MasterKeyValid) {
    log_Printf(LogCCP, "MPPE: MasterKey is invalid,"
               " MPPE is available only with CHAP81 authentication\n");
    mval = 0;
    ua_htonl(&mval, o->data);
    return;
  }


  mval = MPPE_ConfigVal(bundle, cfg);
  ua_htonl(&mval, o->data);
}

/*
 * Our CCP request was NAK'd with the given options
 */
static int
MPPESetOptsOutput(struct bundle *bundle, struct fsm_opt *o,
                  const struct ccp_config *cfg)
{
  u_int32_t mval, peer;

  ua_ntohl(o->data, &peer);

  if (!MPPE_MasterKeyValid)
    /* Treat their NAK as a REJ */
    return MODE_NAK;

  mval = MPPE_ConfigVal(bundle, cfg);

  /*
   * If we haven't been configured with a specific number of keybits, allow
   * whatever the peer asks for.
   */
  if (!cfg->mppe.keybits) {
    mval &= ~MPPE_OPT_BITMASK;
    mval |= (peer & MPPE_OPT_BITMASK);
    if (!(mval & MPPE_OPT_BITMASK))
      mval |= MPPE_OPT_128BIT;
  }

  /* Adjust our statelessness */
  if (cfg->mppe.state == MPPE_ANYSTATE) {
    mval &= ~MPPE_OPT_STATELESS;
    mval |= (peer & MPPE_OPT_STATELESS);
  }

  ua_htonl(&mval, o->data);

  return MODE_ACK;
}

/*
 * The peer has requested the given options
 */
static int
MPPESetOptsInput(struct bundle *bundle, struct fsm_opt *o,
                 const struct ccp_config *cfg)
{
  u_int32_t mval, peer;
  int res = MODE_ACK;

  ua_ntohl(o->data, &peer);
  if (!MPPE_MasterKeyValid) {
    if (peer != 0) {
      peer = 0;
      ua_htonl(&peer, o->data);
      return MODE_NAK;
    } else
      return MODE_ACK;
  }

  mval = MPPE_ConfigVal(bundle, cfg);

  if (peer & ~MPPE_OPT_MASK)
    /* He's asking for bits we don't know about */
    res = MODE_NAK;

  if (peer & MPPE_OPT_STATELESS) {
    if (cfg->mppe.state == MPPE_STATEFUL)
      /* Peer can't have stateless */
      res = MODE_NAK;
    else
      /* Peer wants stateless, that's ok */
      mval |= MPPE_OPT_STATELESS;
  } else {
    if (cfg->mppe.state == MPPE_STATELESS)
      /* Peer must have stateless */
      res = MODE_NAK;
    else
      /* Peer doesn't want stateless, that's ok */
      mval &= ~MPPE_OPT_STATELESS;
  }

  /* If we've got a configured number of keybits - the peer must use that */
  if (cfg->mppe.keybits) {
    ua_htonl(&mval, o->data);
    return peer == mval ? res : MODE_NAK;
  }

  /* If a specific number of bits hasn't been requested, we'll need to NAK */
  switch (peer & MPPE_OPT_BITMASK) {
  case MPPE_OPT_128BIT:
  case MPPE_OPT_56BIT:
  case MPPE_OPT_40BIT:
    break;
  default:
    res = MODE_NAK;
  }

  /* Suggest the best number of bits */
  mval &= ~MPPE_OPT_BITMASK;
  if (peer & MPPE_OPT_128BIT)
    mval |= MPPE_OPT_128BIT;
  else if (peer & MPPE_OPT_56BIT)
    mval |= MPPE_OPT_56BIT;
  else if (peer & MPPE_OPT_40BIT)
    mval |= MPPE_OPT_40BIT;
  else
    mval |= MPPE_OPT_128BIT;
  ua_htonl(&mval, o->data);

  return res;
}

static struct mppe_state *
MPPE_InitState(struct fsm_opt *o)
{
  struct mppe_state *mp;
  u_int32_t val;

  if ((mp = calloc(1, sizeof *mp)) != NULL) {
    ua_ntohl(o->data, &val);

    switch (val & MPPE_OPT_BITMASK) {
    case MPPE_OPT_128BIT:
      mp->keylen = 16;
      mp->keybits = 128;
      break;
    case MPPE_OPT_56BIT:
      mp->keylen = 8;
      mp->keybits = 56;
      break;
    case MPPE_OPT_40BIT:
      mp->keylen = 8;
      mp->keybits = 40;
      break;
    default:
      log_Printf(LogWARN, "Unexpected MPPE options 0x%08x\n", val);
      free(mp);
      return NULL;
    }

    mp->stateless = !!(val & MPPE_OPT_STATELESS);
  }

  return mp;
}

static void *
MPPEInitInput(struct bundle *bundle __unused, struct fsm_opt *o)
{
  struct mppe_state *mip;

  if (!MPPE_MasterKeyValid) {
    log_Printf(LogWARN, "MPPE: Cannot initialise without CHAP81\n");
    return NULL;
  }

  if ((mip = MPPE_InitState(o)) == NULL) {
    log_Printf(LogWARN, "MPPEInput: Cannot initialise - unexpected options\n");
    return NULL;
  }

  log_Printf(LogDEBUG, "MPPE: InitInput: %d-bits\n", mip->keybits);

#ifndef NORADIUS
  if (*bundle->radius.cfg.file && bundle->radius.mppe.recvkey) {
    if (mip->keylen > bundle->radius.mppe.recvkeylen)
      mip->keylen = bundle->radius.mppe.recvkeylen;
    if (mip->keylen > sizeof mip->mastkey)
      mip->keylen = sizeof mip->mastkey;
    memcpy(mip->mastkey, bundle->radius.mppe.recvkey, mip->keylen);
  } else
#endif
    GetAsymetricStartKey(MPPE_MasterKey, mip->mastkey, mip->keylen, 0,
                         MPPE_IsServer);

  GetNewKeyFromSHA(mip->mastkey, mip->mastkey, mip->keylen, mip->sesskey);

  MPPEReduceSessionKey(mip);

  log_Printf(LogCCP, "MPPE: Input channel initiated\n");

  if (!mip->stateless) {
    /*
     * We need to initialise our dictionary here as the first packet we
     * receive is unlikely to have the FLUSHED bit set.
     */
    log_Printf(LogDEBUG, "MPPEInitInput: Dictionary initialised [%d]\n",
               mip->cohnum);
    RC4_set_key(&mip->rc4key, mip->keylen, mip->sesskey);
  } else {
    /*
     * We do the first key change here as the first packet is expected
     * to have a sequence number of 0 and we'll therefore not expect
     * to have to change the key at that point.
     */
    log_Printf(LogDEBUG, "MPPEInitInput: Key changed [%d]\n", mip->cohnum);
    MPPEKeyChange(mip);
  }

  return mip;
}

static void *
MPPEInitOutput(struct bundle *bundle __unused, struct fsm_opt *o)
{
  struct mppe_state *mop;

  if (!MPPE_MasterKeyValid) {
    log_Printf(LogWARN, "MPPE: Cannot initialise without CHAP81\n");
    return NULL;
  }

  if ((mop = MPPE_InitState(o)) == NULL) {
    log_Printf(LogWARN, "MPPEOutput: Cannot initialise - unexpected options\n");
    return NULL;
  }

  log_Printf(LogDEBUG, "MPPE: InitOutput: %d-bits\n", mop->keybits);

#ifndef NORADIUS
  if (*bundle->radius.cfg.file && bundle->radius.mppe.sendkey) {
    if (mop->keylen > bundle->radius.mppe.sendkeylen)
      mop->keylen = bundle->radius.mppe.sendkeylen;
    if (mop->keylen > sizeof mop->mastkey)
      mop->keylen = sizeof mop->mastkey;
    memcpy(mop->mastkey, bundle->radius.mppe.sendkey, mop->keylen);
  } else
#endif
    GetAsymetricStartKey(MPPE_MasterKey, mop->mastkey, mop->keylen, 1,
                         MPPE_IsServer);

  GetNewKeyFromSHA(mop->mastkey, mop->mastkey, mop->keylen, mop->sesskey);

  MPPEReduceSessionKey(mop);

  log_Printf(LogCCP, "MPPE: Output channel initiated\n");

  if (!mop->stateless) {
    /*
     * We need to initialise our dictionary now as the first packet we
     * send won't have the FLUSHED bit set.
     */
    log_Printf(LogDEBUG, "MPPEInitOutput: Dictionary initialised [%d]\n",
               mop->cohnum);
    RC4_set_key(&mop->rc4key, mop->keylen, mop->sesskey);
  }

  return mop;
}

static void
MPPETermInput(void *v)
{
  free(v);
}

static void
MPPETermOutput(void *v)
{
  free(v);
}

const struct ccp_algorithm MPPEAlgorithm = {
  TY_MPPE,
  CCP_NEG_MPPE,
  MPPEDispOpts,
  MPPEUsable,
  MPPERequired,
  {
    MPPESetOptsInput,
    MPPEInitInput,
    MPPETermInput,
    MPPEResetInput,
    MPPEInput,
    MPPEDictSetup
  },
  {
    2,
    MPPEInitOptsOutput,
    MPPESetOptsOutput,
    MPPEInitOutput,
    MPPETermOutput,
    MPPEResetOutput,
    MPPEOutput
  },
};
