/*
 * mppe.c - interface MPPE to the PPP code.
 *
 * By Frank Cusack <fcusack@fcusack.com>.
 * Copyright (c) 2002,2003,2004 Google, Inc.
 * All rights reserved.
 *
 * License:
 * Permission to use, copy, modify, and distribute this software and its
 * documentation is hereby granted, provided that the above copyright
 * notice appears in all copies.  This software is provided without any
 * warranty, express or implied.
 *
 * Changelog:
 *      08/12/05 - Matt Domsch <Matt_Domsch@dell.com>
 *                 Only need extra skb padding on transmit, not receive.
 *      06/18/04 - Matt Domsch <Matt_Domsch@dell.com>, Oleg Makarenko <mole@quadra.ru>
 *                 Use Linux kernel 2.6 arc4 and sha1 routines rather than
 *                 providing our own.
 *      2/15/04 - TS: added #include <version.h> and testing for Kernel
 *                    version before using
 *                    MOD_DEC_USAGE_COUNT/MOD_INC_USAGE_COUNT which are
 *                    deprecated in 2.6
 */

#include "netif/ppp/ppp_opts.h"
#if PPP_SUPPORT && MPPE_SUPPORT  /* don't build if not configured for use in lwipopts.h */

#include <string.h>

#include "lwip/err.h"

#include "netif/ppp/ppp_impl.h"
#include "netif/ppp/ccp.h"
#include "netif/ppp/mppe.h"
#include "netif/ppp/pppdebug.h"
#include "netif/ppp/pppcrypt.h"

#define SHA1_SIGNATURE_SIZE 20

/* ppp_mppe_state.bits definitions */
#define MPPE_BIT_A	0x80	/* Encryption table were (re)inititalized */
#define MPPE_BIT_B	0x40	/* MPPC only (not implemented) */
#define MPPE_BIT_C	0x20	/* MPPC only (not implemented) */
#define MPPE_BIT_D	0x10	/* This is an encrypted frame */

#define MPPE_BIT_FLUSHED	MPPE_BIT_A
#define MPPE_BIT_ENCRYPTED	MPPE_BIT_D

#define MPPE_BITS(p) ((p)[0] & 0xf0)
#define MPPE_CCOUNT(p) ((((p)[0] & 0x0f) << 8) + (p)[1])
#define MPPE_CCOUNT_SPACE 0x1000	/* The size of the ccount space */

#define MPPE_OVHD	2	/* MPPE overhead/packet */
#define SANITY_MAX	1600	/* Max bogon factor we will tolerate */

/*
 * Perform the MPPE rekey algorithm, from RFC 3078, sec. 7.3.
 * Well, not what's written there, but rather what they meant.
 */
static void mppe_rekey(ppp_mppe_state * state, int initial_key)
{
	lwip_sha1_context sha1_ctx;
	u8_t sha1_digest[SHA1_SIGNATURE_SIZE];

	/*
	 * Key Derivation, from RFC 3078, RFC 3079.
	 * Equivalent to Get_Key() for MS-CHAP as described in RFC 3079.
	 */
	lwip_sha1_init(&sha1_ctx);
	lwip_sha1_starts(&sha1_ctx);
	lwip_sha1_update(&sha1_ctx, state->master_key, state->keylen);
	lwip_sha1_update(&sha1_ctx, mppe_sha1_pad1, SHA1_PAD_SIZE);
	lwip_sha1_update(&sha1_ctx, state->session_key, state->keylen);
	lwip_sha1_update(&sha1_ctx, mppe_sha1_pad2, SHA1_PAD_SIZE);
	lwip_sha1_finish(&sha1_ctx, sha1_digest);
	lwip_sha1_free(&sha1_ctx);
	MEMCPY(state->session_key, sha1_digest, state->keylen);

	if (!initial_key) {
		lwip_arc4_init(&state->arc4);
		lwip_arc4_setup(&state->arc4, sha1_digest, state->keylen);
		lwip_arc4_crypt(&state->arc4, state->session_key, state->keylen);
		lwip_arc4_free(&state->arc4);
	}
	if (state->keylen == 8) {
		/* See RFC 3078 */
		state->session_key[0] = 0xd1;
		state->session_key[1] = 0x26;
		state->session_key[2] = 0x9e;
	}
	lwip_arc4_init(&state->arc4);
	lwip_arc4_setup(&state->arc4, state->session_key, state->keylen);
}

/*
 * Set key, used by MSCHAP before mppe_init() is actually called by CCP so we
 * don't have to keep multiple copies of keys.
 */
void mppe_set_key(ppp_pcb *pcb, ppp_mppe_state *state, u8_t *key) {
	LWIP_UNUSED_ARG(pcb);
	MEMCPY(state->master_key, key, MPPE_MAX_KEY_LEN);
}

/*
 * Initialize (de)compressor state.
 */
void
mppe_init(ppp_pcb *pcb, ppp_mppe_state *state, u8_t options)
{
#if PPP_DEBUG
	const u8_t *debugstr = (const u8_t*)"mppe_comp_init";
	if (&pcb->mppe_decomp == state) {
	    debugstr = (const u8_t*)"mppe_decomp_init";
	}
#endif /* PPP_DEBUG */

	/* Save keys. */
	MEMCPY(state->session_key, state->master_key, sizeof(state->master_key));

	if (options & MPPE_OPT_128)
		state->keylen = 16;
	else if (options & MPPE_OPT_40)
		state->keylen = 8;
	else {
		PPPDEBUG(LOG_DEBUG, ("%s[%d]: unknown key length\n", debugstr,
			pcb->netif->num));
		lcp_close(pcb, "MPPE required but peer negotiation failed");
		return;
	}
	if (options & MPPE_OPT_STATEFUL)
		state->stateful = 1;

	/* Generate the initial session key. */
	mppe_rekey(state, 1);

#if PPP_DEBUG
	{
		int i;
		char mkey[sizeof(state->master_key) * 2 + 1];
		char skey[sizeof(state->session_key) * 2 + 1];

		PPPDEBUG(LOG_DEBUG, ("%s[%d]: initialized with %d-bit %s mode\n",
		       debugstr, pcb->netif->num, (state->keylen == 16) ? 128 : 40,
		       (state->stateful) ? "stateful" : "stateless"));

		for (i = 0; i < (int)sizeof(state->master_key); i++)
			sprintf(mkey + i * 2, "%02x", state->master_key[i]);
		for (i = 0; i < (int)sizeof(state->session_key); i++)
			sprintf(skey + i * 2, "%02x", state->session_key[i]);
		PPPDEBUG(LOG_DEBUG,
		       ("%s[%d]: keys: master: %s initial session: %s\n",
		       debugstr, pcb->netif->num, mkey, skey));
	}
#endif /* PPP_DEBUG */

	/*
	 * Initialize the coherency count.  The initial value is not specified
	 * in RFC 3078, but we can make a reasonable assumption that it will
	 * start at 0.  Setting it to the max here makes the comp/decomp code
	 * do the right thing (determined through experiment).
	 */
	state->ccount = MPPE_CCOUNT_SPACE - 1;

	/*
	 * Note that even though we have initialized the key table, we don't
	 * set the FLUSHED bit.  This is contrary to RFC 3078, sec. 3.1.
	 */
	state->bits = MPPE_BIT_ENCRYPTED;
}

/*
 * We received a CCP Reset-Request (actually, we are sending a Reset-Ack),
 * tell the compressor to rekey.  Note that we MUST NOT rekey for
 * every CCP Reset-Request; we only rekey on the next xmit packet.
 * We might get multiple CCP Reset-Requests if our CCP Reset-Ack is lost.
 * So, rekeying for every CCP Reset-Request is broken as the peer will not
 * know how many times we've rekeyed.  (If we rekey and THEN get another
 * CCP Reset-Request, we must rekey again.)
 */
void mppe_comp_reset(ppp_pcb *pcb, ppp_mppe_state *state)
{
	LWIP_UNUSED_ARG(pcb);
	state->bits |= MPPE_BIT_FLUSHED;
}

/*
 * Compress (encrypt) a packet.
 * It's strange to call this a compressor, since the output is always
 * MPPE_OVHD + 2 bytes larger than the input.
 */
err_t
mppe_compress(ppp_pcb *pcb, ppp_mppe_state *state, struct pbuf **pb, u16_t protocol)
{
	struct pbuf *n, *np;
	u8_t *pl;
	err_t err;

	LWIP_UNUSED_ARG(pcb);

	/* TCP stack requires that we don't change the packet payload, therefore we copy
	 * the whole packet before encryption.
	 */
	np = pbuf_alloc(PBUF_RAW, MPPE_OVHD + sizeof(protocol) + (*pb)->tot_len, PBUF_POOL);
	if (!np) {
		return ERR_MEM;
	}

	/* Hide MPPE header + protocol */
	pbuf_header(np, -(s16_t)(MPPE_OVHD + sizeof(protocol)));

	if ((err = pbuf_copy(np, *pb)) != ERR_OK) {
		pbuf_free(np);
		return err;
	}

	/* Reveal MPPE header + protocol */
	pbuf_header(np, (s16_t)(MPPE_OVHD + sizeof(protocol)));

	*pb = np;
	pl = (u8_t*)np->payload;

	state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE;
	PPPDEBUG(LOG_DEBUG, ("mppe_compress[%d]: ccount %d\n", pcb->netif->num, state->ccount));
	/* FIXME: use PUT* macros */
	pl[0] = state->ccount>>8;
	pl[1] = state->ccount;

	if (!state->stateful ||	/* stateless mode     */
	    ((state->ccount & 0xff) == 0xff) ||	/* "flag" packet      */
	    (state->bits & MPPE_BIT_FLUSHED)) {	/* CCP Reset-Request  */
		/* We must rekey */
		if (state->stateful) {
			PPPDEBUG(LOG_DEBUG, ("mppe_compress[%d]: rekeying\n", pcb->netif->num));
		}
		mppe_rekey(state, 0);
		state->bits |= MPPE_BIT_FLUSHED;
	}
	pl[0] |= state->bits;
	state->bits &= ~MPPE_BIT_FLUSHED;	/* reset for next xmit */
	pl += MPPE_OVHD;

	/* Add protocol */
	/* FIXME: add PFC support */
	pl[0] = protocol >> 8;
	pl[1] = protocol;

	/* Hide MPPE header */
	pbuf_header(np, -(s16_t)MPPE_OVHD);

	/* Encrypt packet */
	for (n = np; n != NULL; n = n->next) {
		lwip_arc4_crypt(&state->arc4, (u8_t*)n->payload, n->len);
		if (n->tot_len == n->len) {
			break;
		}
	}

	/* Reveal MPPE header */
	pbuf_header(np, (s16_t)MPPE_OVHD);

	return ERR_OK;
}

/*
 * We received a CCP Reset-Ack.  Just ignore it.
 */
void mppe_decomp_reset(ppp_pcb *pcb, ppp_mppe_state *state)
{
	LWIP_UNUSED_ARG(pcb);
	LWIP_UNUSED_ARG(state);
	return;
}

/*
 * Decompress (decrypt) an MPPE packet.
 */
err_t
mppe_decompress(ppp_pcb *pcb, ppp_mppe_state *state, struct pbuf **pb)
{
	struct pbuf *n0 = *pb, *n;
	u8_t *pl;
	u16_t ccount;
	u8_t flushed;

	/* MPPE Header */
	if (n0->len < MPPE_OVHD) {
		PPPDEBUG(LOG_DEBUG,
		       ("mppe_decompress[%d]: short pkt (%d)\n",
		       pcb->netif->num, n0->len));
		state->sanity_errors += 100;
		goto sanity_error;
	}

	pl = (u8_t*)n0->payload;
	flushed = MPPE_BITS(pl) & MPPE_BIT_FLUSHED;
	ccount = MPPE_CCOUNT(pl);
	PPPDEBUG(LOG_DEBUG, ("mppe_decompress[%d]: ccount %d\n",
	       pcb->netif->num, ccount));

	/* sanity checks -- terminate with extreme prejudice */
	if (!(MPPE_BITS(pl) & MPPE_BIT_ENCRYPTED)) {
		PPPDEBUG(LOG_DEBUG,
		       ("mppe_decompress[%d]: ENCRYPTED bit not set!\n",
		       pcb->netif->num));
		state->sanity_errors += 100;
		goto sanity_error;
	}
	if (!state->stateful && !flushed) {
		PPPDEBUG(LOG_DEBUG, ("mppe_decompress[%d]: FLUSHED bit not set in "
		       "stateless mode!\n", pcb->netif->num));
		state->sanity_errors += 100;
		goto sanity_error;
	}
	if (state->stateful && ((ccount & 0xff) == 0xff) && !flushed) {
		PPPDEBUG(LOG_DEBUG, ("mppe_decompress[%d]: FLUSHED bit not set on "
		       "flag packet!\n", pcb->netif->num));
		state->sanity_errors += 100;
		goto sanity_error;
	}

	/*
	 * Check the coherency count.
	 */

	if (!state->stateful) {
		/* Discard late packet */
		if ((ccount - state->ccount) % MPPE_CCOUNT_SPACE > MPPE_CCOUNT_SPACE / 2) {
			state->sanity_errors++;
			goto sanity_error;
		}

		/* RFC 3078, sec 8.1.  Rekey for every packet. */
		while (state->ccount != ccount) {
			mppe_rekey(state, 0);
			state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE;
		}
	} else {
		/* RFC 3078, sec 8.2. */
		if (!state->discard) {
			/* normal state */
			state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE;
			if (ccount != state->ccount) {
				/*
				 * (ccount > state->ccount)
				 * Packet loss detected, enter the discard state.
				 * Signal the peer to rekey (by sending a CCP Reset-Request).
				 */
				state->discard = 1;
				ccp_resetrequest(pcb);
				return ERR_BUF;
			}
		} else {
			/* discard state */
			if (!flushed) {
				/* ccp.c will be silent (no additional CCP Reset-Requests). */
				return ERR_BUF;
			} else {
				/* Rekey for every missed "flag" packet. */
				while ((ccount & ~0xff) !=
				       (state->ccount & ~0xff)) {
					mppe_rekey(state, 0);
					state->ccount =
					    (state->ccount +
					     256) % MPPE_CCOUNT_SPACE;
				}

				/* reset */
				state->discard = 0;
				state->ccount = ccount;
				/*
				 * Another problem with RFC 3078 here.  It implies that the
				 * peer need not send a Reset-Ack packet.  But RFC 1962
				 * requires it.  Hopefully, M$ does send a Reset-Ack; even
				 * though it isn't required for MPPE synchronization, it is
				 * required to reset CCP state.
				 */
			}
		}
		if (flushed)
			mppe_rekey(state, 0);
	}

	/* Hide MPPE header */
	pbuf_header(n0, -(s16_t)(MPPE_OVHD));

	/* Decrypt the packet. */
	for (n = n0; n != NULL; n = n->next) {
		lwip_arc4_crypt(&state->arc4, (u8_t*)n->payload, n->len);
		if (n->tot_len == n->len) {
			break;
		}
	}

	/* good packet credit */
	state->sanity_errors >>= 1;

	return ERR_OK;

sanity_error:
	if (state->sanity_errors >= SANITY_MAX) {
		/*
		 * Take LCP down if the peer is sending too many bogons.
		 * We don't want to do this for a single or just a few
		 * instances since it could just be due to packet corruption.
		 */
		lcp_close(pcb, "Too many MPPE errors");
	}
	return ERR_BUF;
}

#endif /* PPP_SUPPORT && MPPE_SUPPORT */
