linux-ppp.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Re: [2/2]: ppp_mppe inclusion
@ 2004-07-20 20:47 Matt Domsch
  2004-07-30 19:33 ` Oleg Makarenko
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: Matt Domsch @ 2004-07-20 20:47 UTC (permalink / raw)
  To: linux-ppp

On Tue, Jul 20, 2004 at 03:45:40PM -0500, Matt Domsch wrote:
> This mail will be followed by two patches, for comment on proposed
> solution.  I've compiled this, but am not able to test this week.
>
> 2: ppp_mppe.patch adds the ppp_mppe compressor, which implements
> Microsoft Point-to-Point Tunnelling Protocol.

-- 
Matt Domsch
Sr. Software Engineer, Lead Engineer
Dell Linux Solutions linux.dell.com & www.dell.com/linux
Linux on Dell mailing lists @ http://lists.us.dell.com

You can import this changeset into BK by piping this whole message to
'| bk receive [path to repository]' or apply the patch as usual.

=================================

ChangeSet@1.1850, 2004-07-20 16:29:53-04:00, Matt_Domsch@dell.com
  PPP: Add drivers/net/ppp_mppe.c, Makefile and Kconfig entries
  
  Microsoft Point-to-Point Tunnelling Protocol support
  utilizes ppp_generic and kernel crypto routines.


 Kconfig    |    6 
 Makefile   |    1 
 ppp_mppe.c |  706 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 ppp_mppe.h |   87 +++++++
 4 files changed, 800 insertions(+)


diff -Nru a/drivers/net/Kconfig b/drivers/net/Kconfig
--- a/drivers/net/Kconfig	2004-07-20 16:37:04 -04:00
+++ b/drivers/net/Kconfig	2004-07-20 16:37:04 -04:00
@@ -2460,6 +2460,12 @@
 	  module; it is called bsd_comp and will show up in the directory
 	  modules once you have said "make modules". If unsure, say N.
 
+config PPP_MPPE
+       tristate "PPP MPPE compression (encryption)"
+       depends on PPP
+       ---help---
+         Support for the MPPE Encryption protocol.
+
 config PPPOE
 	tristate "PPP over Ethernet (EXPERIMENTAL)"
 	depends on EXPERIMENTAL && PPP
diff -Nru a/drivers/net/Makefile b/drivers/net/Makefile
--- a/drivers/net/Makefile	2004-07-20 16:37:04 -04:00
+++ b/drivers/net/Makefile	2004-07-20 16:37:04 -04:00
@@ -100,6 +100,7 @@
 obj-$(CONFIG_PPP_SYNC_TTY) += ppp_synctty.o
 obj-$(CONFIG_PPP_DEFLATE) += ppp_deflate.o
 obj-$(CONFIG_PPP_BSDCOMP) += bsd_comp.o
+obj-$(CONFIG_PPP_MPPE) += ppp_mppe.o
 obj-$(CONFIG_PPPOE) += pppox.o pppoe.o
 
 obj-$(CONFIG_SLIP) += slip.o
diff -Nru a/drivers/net/ppp_mppe.c b/drivers/net/ppp_mppe.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/net/ppp_mppe.c	2004-07-20 16:37:04 -04:00
@@ -0,0 +1,706 @@
+/*
+ * ppp_mppe_compress.c - interface MPPE to the PPP code.
+ * This version is for use with Linux kernel 2.2.19+, 2.4.18+ and 2.6.2+.
+ *
+ * By Frank Cusack <frank@google.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.
+ *
+ * ALTERNATIVELY, provided that this notice is retained in full, this product
+ * may be distributed under the terms of the GNU General Public License (GPL),
+ * in which case the provisions of the GPL apply INSTEAD OF those given above.
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *
+ * Changelog:
+ *      06/18/04 - Matt Domsch <Matt_Domsch@dell.com>
+ *                 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 <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/version.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/crypto.h>
+#include <linux/mm.h>
+#include <linux/ppp_defs.h>
+#include <linux/ppp-comp.h>
+#include <asm/scatterlist.h>
+
+#include "ppp_mppe.h"
+
+MODULE_AUTHOR("Frank Cusack <frank@google.com>");
+MODULE_DESCRIPTION("Point-to-Point Protocol Microsoft Point-to-Point Encryption support");
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_ALIAS("ppp-compress-" __stringify(CI_MPPE));
+MODULE_VERSION("1.0.0");
+
+static void
+setup_sg(struct scatterlist *sg, const void *address, unsigned int length)
+{
+	sg[0].page = virt_to_page(address);
+	sg[0].offset = offset_in_page(address);
+
+	if (sg[0].offset + length <= PAGE_SIZE) {
+		sg[0].length = length;
+		sg[1].page = 0;
+		sg[1].offset = 0;
+		sg[1].length = 0;
+	} else {
+		sg[0].length = PAGE_SIZE - sg[0].offset;
+		sg[1].length = length - sg[0].length;
+		sg[1].page = virt_to_page(address + sg[0].length);
+		sg[1].offset = offset_in_page(address + sg[0].length);	/* 0 */
+	}
+}
+
+/*
+ * State for an MPPE (de)compressor.
+ */
+struct ppp_mppe_state {
+	struct crypto_tfm *arc4;
+	struct crypto_tfm *sha1;
+	unsigned char *sha1_digest;
+	unsigned char master_key[MPPE_MAX_KEY_LEN];
+	unsigned char session_key[MPPE_MAX_KEY_LEN];
+	unsigned keylen;	/* key length in bytes             */
+	/* NB: 128-bit = 16, 40-bit = 8! */
+	/* If we want to support 56-bit,   */
+	/* the unit has to change to bits  */
+	unsigned char bits;	/* MPPE control bits */
+	unsigned ccount;	/* 12-bit coherency count (seqno)  */
+	unsigned stateful;	/* stateful mode flag */
+	int discard;		/* stateful mode packet loss flag */
+	int sanity_errors;	/* take down LCP if too many */
+	int unit;
+	int debug;
+	struct compstat stats;
+};
+
+/* struct 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)[4] & 0xf0)
+#define MPPE_CCOUNT(p) ((((p)[4] & 0x0f) << 8) + (p)[5])
+#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 */
+
+#define SHA1_PAD_SIZE 40
+/*
+ * Key Derivation, from RFC 3078, RFC 3079.
+ * Equivalent to Get_Key() for MS-CHAP as described in RFC 3079.
+ */
+static void get_new_key_from_sha(struct ppp_mppe_state * state, unsigned char *InterimKey)
+{
+	static const unsigned char SHApad1[SHA1_PAD_SIZE] +	    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	};
+	static const unsigned char SHApad2[SHA1_PAD_SIZE] +	    { 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
+		0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
+		0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
+		0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2
+	};
+	struct scatterlist sg[2];
+
+	crypto_digest_init(state->sha1);
+	setup_sg(sg, state->master_key, state->keylen);
+	crypto_digest_update(state->sha1, sg, state->keylen);
+	setup_sg(sg, SHApad1, sizeof(SHApad1));
+	crypto_digest_update(state->sha1, sg, sizeof(SHApad1));
+	setup_sg(sg, state->session_key, state->keylen);
+	crypto_digest_update(state->sha1, sg, state->keylen);
+	setup_sg(sg, SHApad2, sizeof(SHApad2));
+	crypto_digest_update(state->sha1, sg, sizeof(SHApad2));
+	crypto_digest_final(state->sha1, state->sha1_digest);
+	memcpy(InterimKey, state->sha1_digest, state->keylen);
+}
+
+/*
+ * 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(struct ppp_mppe_state * state, int initial_key)
+{
+	unsigned char InterimKey[MPPE_MAX_KEY_LEN];
+	struct scatterlist sg_in[2], sg_out[2];
+
+	get_new_key_from_sha(state, InterimKey);
+	if (!initial_key) {
+		crypto_cipher_setkey(state->arc4, InterimKey, state->keylen);
+		setup_sg(sg_in, InterimKey, state->keylen);
+		setup_sg(sg_out, state->session_key, state->keylen);
+		crypto_cipher_encrypt(state->arc4, sg_out, sg_in,
+				      state->keylen);
+	} else {
+		memcpy(state->session_key, InterimKey, state->keylen);
+	}
+	if (state->keylen = 8) {
+		/* See RFC 3078 */
+		state->session_key[0] = 0xd1;
+		state->session_key[1] = 0x26;
+		state->session_key[2] = 0x9e;
+	}
+	crypto_cipher_setkey(state->arc4, state->session_key, state->keylen);
+}
+
+/*
+ * Allocate space for a (de)compressor.
+ */
+static void *mppe_alloc(unsigned char *options, int optlen)
+{
+	struct ppp_mppe_state *state;
+	unsigned int digestsize;
+
+	if (optlen != CILEN_MPPE + sizeof(state->master_key)
+	    || options[0] != CI_MPPE || options[1] != CILEN_MPPE)
+		goto out;
+
+	state = (struct ppp_mppe_state *) kmalloc(sizeof(*state), GFP_KERNEL);
+	if (state = NULL)
+		goto out;
+
+	memset(state, 0, sizeof(*state));
+
+	state->arc4 = crypto_alloc_tfm("arc4", 0);
+	if (!state->arc4)
+		goto out_free;
+	state->sha1 = crypto_alloc_tfm("sha1", 0);
+	if (!state->sha1)
+		goto out_arc4;
+	digestsize = crypto_tfm_alg_digestsize(state->sha1);
+	if (digestsize < MPPE_MAX_KEY_LEN)
+		goto out_sha1;
+	state->sha1_digest = kmalloc(digestsize, GFP_KERNEL);
+	if (!state->sha1_digest)
+		goto out_sha1;
+
+	/* Save keys. */
+	memcpy(state->master_key, &options[CILEN_MPPE],
+	       sizeof(state->master_key));
+	memcpy(state->session_key, state->master_key,
+	       sizeof(state->master_key));
+	/*
+	 * We defer initial key generation until mppe_init(), as mppe_alloc()
+	 * is called frequently during negotiation.
+	 */
+
+	return (void *)state;
+
+      out_sha1:
+	crypto_free_tfm(state->sha1);
+      out_arc4:
+	crypto_free_tfm(state->arc4);
+      out_free:
+	kfree(state);
+      out:
+	return NULL;
+}
+
+/*
+ * Deallocate space for a (de)compressor.
+ */
+static void mppe_free(void *arg)
+{
+	struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
+
+	if (state) {
+		if (state->arc4)
+			crypto_free_tfm(state->arc4);
+		if (state->sha1)
+			crypto_free_tfm(state->sha1);
+		if (state->sha1_digest)
+			kfree(state->sha1_digest);
+		kfree(state);
+	}
+}
+
+/* 
+ * Initialize (de)compressor state.
+ */
+static int
+mppe_init(void *arg, unsigned char *options, int optlen, int unit, int debug,
+	  const char *debugstr)
+{
+	struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
+	unsigned char mppe_opts;
+
+	if (optlen != CILEN_MPPE
+	    || options[0] != CI_MPPE || options[1] != CILEN_MPPE)
+		return 0;
+
+	MPPE_CI_TO_OPTS(&options[2], mppe_opts);
+	if (mppe_opts & MPPE_OPT_128)
+		state->keylen = 16;
+	else if (mppe_opts & MPPE_OPT_40)
+		state->keylen = 8;
+	else {
+		printk(KERN_WARNING "%s[%d]: unknown key length\n", debugstr,
+		       unit);
+		return 0;
+	}
+	if (mppe_opts & MPPE_OPT_STATEFUL)
+		state->stateful = 1;
+
+	/* Generate the initial session key. */
+	mppe_rekey(state, 1);
+
+	if (debug) {
+		int i;
+		char mkey[sizeof(state->master_key) * 2 + 1];
+		char skey[sizeof(state->session_key) * 2 + 1];
+
+		printk(KERN_DEBUG "%s[%d]: initialized with %d-bit %s mode\n",
+		       debugstr, unit, (state->keylen = 16) ? 128 : 40,
+		       (state->stateful) ? "stateful" : "stateless");
+
+		for (i = 0; i < sizeof(state->master_key); i++)
+			sprintf(mkey + i * 2, "%.2x", state->master_key[i]);
+		for (i = 0; i < sizeof(state->session_key); i++)
+			sprintf(skey + i * 2, "%.2x", state->session_key[i]);
+		printk(KERN_DEBUG
+		       "%s[%d]: keys: master: %s initial session: %s\n",
+		       debugstr, unit, mkey, skey);
+	}
+
+	/*
+	 * 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;
+
+	state->unit = unit;
+	state->debug = debug;
+
+	return 1;
+}
+
+static int
+mppe_comp_init(void *arg, unsigned char *options, int optlen, int unit,
+	       int hdrlen, int debug)
+{
+	/* ARGSUSED */
+	return mppe_init(arg, options, optlen, unit, debug, "mppe_comp_init");
+}
+
+/*
+ * 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.)
+ */
+static void mppe_comp_reset(void *arg)
+{
+	struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
+
+	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.
+ */
+static int
+mppe_compress(void *arg, unsigned char *ibuf, unsigned char *obuf,
+	      int isize, int osize)
+{
+	struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
+	int proto;
+	struct scatterlist sg_in[2], sg_out[2];
+
+	/*
+	 * Check that the protocol is in the range we handle.
+	 */
+	proto = PPP_PROTOCOL(ibuf);
+	if (proto < 0x0021 || proto > 0x00fa)
+		return 0;
+
+	/* Make sure we have enough room to generate an encrypted packet. */
+	if (osize < isize + MPPE_OVHD + 2) {
+		/* Drop the packet if we should encrypt it, but can't. */
+		printk(KERN_DEBUG "mppe_compress[%d]: osize too small! "
+		       "(have: %d need: %d)\n", state->unit,
+		       osize, osize + MPPE_OVHD + 2);
+		return -1;
+	}
+
+	osize = isize + MPPE_OVHD + 2;
+
+	/*
+	 * Copy over the PPP header and set control bits.
+	 */
+	obuf[0] = PPP_ADDRESS(ibuf);
+	obuf[1] = PPP_CONTROL(ibuf);
+	obuf[2] = PPP_COMP >> 8;	/* isize + MPPE_OVHD + 1 */
+	obuf[3] = PPP_COMP;	/* isize + MPPE_OVHD + 2 */
+	obuf += PPP_HDRLEN;
+
+	state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE;
+	if (state->debug >= 7)
+		printk(KERN_DEBUG "mppe_compress[%d]: ccount %d\n", state->unit,
+		       state->ccount);
+	obuf[0] = state->ccount >> 8;
+	obuf[1] = state->ccount & 0xff;
+
+	if (!state->stateful ||	/* stateless mode     */
+	    ((state->ccount & 0xff) = 0xff) ||	/* "flag" packet      */
+	    (state->bits & MPPE_BIT_FLUSHED)) {	/* CCP Reset-Request  */
+		/* We must rekey */
+		if (state->debug && state->stateful)
+			printk(KERN_DEBUG "mppe_compress[%d]: rekeying\n",
+			       state->unit);
+		mppe_rekey(state, 0);
+		state->bits |= MPPE_BIT_FLUSHED;
+	}
+	obuf[0] |= state->bits;
+	state->bits &= ~MPPE_BIT_FLUSHED;	/* reset for next xmit */
+
+	obuf += MPPE_OVHD;
+	ibuf += 2;		/* skip to proto field */
+	isize -= 2;
+
+	/* Encrypt packet */
+	setup_sg(sg_in, ibuf, isize);
+	setup_sg(sg_out, obuf, osize);
+	crypto_cipher_encrypt(state->arc4, sg_out, sg_in, isize);
+
+	state->stats.unc_bytes += isize;
+	state->stats.unc_packets++;
+	state->stats.comp_bytes += osize;
+	state->stats.comp_packets++;
+
+	return osize;
+}
+
+/*
+ * Since every frame grows by MPPE_OVHD + 2 bytes, this is always going
+ * to look bad ... and the longer the link is up the worse it will get.
+ */
+static void mppe_comp_stats(void *arg, struct compstat *stats)
+{
+	struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
+
+	*stats = state->stats;
+}
+
+static int
+mppe_decomp_init(void *arg, unsigned char *options, int optlen, int unit,
+		 int hdrlen, int mru, int debug)
+{
+	/* ARGSUSED */
+	return mppe_init(arg, options, optlen, unit, debug, "mppe_decomp_init");
+}
+
+/*
+ * We received a CCP Reset-Ack.  Just ignore it.
+ */
+static void mppe_decomp_reset(void *arg)
+{
+	/* ARGSUSED */
+	return;
+}
+
+/*
+ * Decompress (decrypt) an MPPE packet.
+ */
+static int
+mppe_decompress(void *arg, unsigned char *ibuf, int isize, unsigned char *obuf,
+		int osize)
+{
+	struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
+	unsigned ccount;
+	int flushed = MPPE_BITS(ibuf) & MPPE_BIT_FLUSHED;
+	int sanity = 0;
+	struct scatterlist sg_in[2], sg_out[2];
+
+	if (isize <= PPP_HDRLEN + MPPE_OVHD) {
+		if (state->debug)
+			printk(KERN_DEBUG
+			       "mppe_decompress[%d]: short pkt (%d)\n",
+			       state->unit, isize);
+		return DECOMP_ERROR;
+	}
+
+	/*
+	 * Make sure we have enough room to decrypt the packet.
+	 * Note that for our test we only subtract 1 byte whereas in
+	 * mppe_compress() we added 2 bytes (+MPPE_OVHD);
+	 * this is to account for possible PFC.
+	 */
+	if (osize < isize - MPPE_OVHD - 1) {
+		printk(KERN_DEBUG "mppe_decompress[%d]: osize too small! "
+		       "(have: %d need: %d)\n", state->unit,
+		       osize, isize - MPPE_OVHD - 1);
+		return DECOMP_ERROR;
+	}
+	osize = isize - MPPE_OVHD - 2;	/* assume no PFC */
+
+	ccount = MPPE_CCOUNT(ibuf);
+	if (state->debug >= 7)
+		printk(KERN_DEBUG "mppe_decompress[%d]: ccount %d\n",
+		       state->unit, ccount);
+
+	/* sanity checks -- terminate with extreme prejudice */
+	if (!(MPPE_BITS(ibuf) & MPPE_BIT_ENCRYPTED)) {
+		printk(KERN_DEBUG
+		       "mppe_decompress[%d]: ENCRYPTED bit not set!\n",
+		       state->unit);
+		state->sanity_errors += 100;
+		sanity = 1;
+	}
+	if (!state->stateful && !flushed) {
+		printk(KERN_DEBUG "mppe_decompress[%d]: FLUSHED bit not set in "
+		       "stateless mode!\n", state->unit);
+		state->sanity_errors += 100;
+		sanity = 1;
+	}
+	if (state->stateful && ((ccount & 0xff) = 0xff) && !flushed) {
+		printk(KERN_DEBUG "mppe_decompress[%d]: FLUSHED bit not set on "
+		       "flag packet!\n", state->unit);
+		state->sanity_errors += 100;
+		sanity = 1;
+	}
+
+	if (sanity) {
+		if (state->sanity_errors < SANITY_MAX)
+			return DECOMP_ERROR;
+		else
+			/*
+			 * 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.
+			 */
+			return DECOMP_FATALERROR;
+	}
+
+	/*
+	 * Check the coherency count.
+	 */
+
+	if (!state->stateful) {
+		/* 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;
+				return DECOMP_ERROR;
+			}
+		} else {
+			/* discard state */
+			if (!flushed) {
+				/* ccp.c will be silent (no additional CCP Reset-Requests). */
+				return DECOMP_ERROR;
+			} 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);
+	}
+
+	/*
+	 * Fill in the first part of the PPP header.  The protocol field
+	 * comes from the decrypted data.
+	 */
+	obuf[0] = PPP_ADDRESS(ibuf);	/* +1 */
+	obuf[1] = PPP_CONTROL(ibuf);	/* +1 */
+	obuf += 2;
+	ibuf += PPP_HDRLEN + MPPE_OVHD;
+	isize -= PPP_HDRLEN + MPPE_OVHD;	/* -6 */
+	/* net osize: isize-4 */
+
+	/*
+	 * Decrypt the first byte in order to check if it is
+	 * a compressed or uncompressed protocol field.
+	 */
+	setup_sg(sg_in, ibuf, 1);
+	setup_sg(sg_out, obuf, 1);
+	crypto_cipher_decrypt(state->arc4, sg_out, sg_in, 1);
+
+	/*
+	 * Do PFC decompression.
+	 * This would be nicer if we were given the actual sk_buff
+	 * instead of a char *.
+	 */
+	if ((obuf[0] & 0x01) != 0) {
+		obuf[1] = obuf[0];
+		obuf[0] = 0;
+		obuf++;
+		osize++;
+	}
+
+	/* And finally, decrypt the rest of the packet. */
+	setup_sg(sg_in, ibuf + 1, isize - 1);
+	setup_sg(sg_out, obuf + 1, osize - 1);
+	crypto_cipher_decrypt(state->arc4, sg_out, sg_in, isize - 1);
+
+	state->stats.unc_bytes += osize;
+	state->stats.unc_packets++;
+	state->stats.comp_bytes += isize;
+	state->stats.comp_packets++;
+
+	/* good packet credit */
+	state->sanity_errors >>= 1;
+
+	return osize;
+}
+
+/*
+ * Incompressible data has arrived (this should never happen!).
+ * We should probably drop the link if the protocol is in the range
+ * of what should be encrypted.  At the least, we should drop this
+ * packet.  (How to do this?)
+ */
+static void mppe_incomp(void *arg, unsigned char *ibuf, int icnt)
+{
+	struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
+
+	if (state->debug &&
+	    (PPP_PROTOCOL(ibuf) >= 0x0021 && PPP_PROTOCOL(ibuf) <= 0x00fa))
+		printk(KERN_DEBUG
+		       "mppe_incomp[%d]: incompressible (unencrypted) data! "
+		       "(proto %04x)\n", state->unit, PPP_PROTOCOL(ibuf));
+
+	state->stats.inc_bytes += icnt;
+	state->stats.inc_packets++;
+	state->stats.unc_bytes += icnt;
+	state->stats.unc_packets++;
+}
+
+/*************************************************************
+ * Module interface table
+ *************************************************************/
+
+/*
+ * Procedures exported to if_ppp.c.
+ */
+static struct compressor ppp_mppe = {
+	.compress_proto = CI_MPPE,
+	.comp_alloc     = mppe_alloc,
+	.comp_free      = mppe_free,
+	.comp_init      = mppe_comp_init,
+	.comp_reset     = mppe_comp_reset,
+	.compress       = mppe_compress,
+	.comp_stat      = mppe_comp_stats,
+	.decomp_alloc   = mppe_alloc,
+	.decomp_free    = mppe_free,
+	.decomp_init    = mppe_decomp_init,
+	.decomp_reset   = mppe_decomp_reset,
+	.decompress     = mppe_decompress,
+	.incomp         = mppe_incomp,
+	.decomp_stat    = mppe_comp_stats,
+	.owner          = THIS_MODULE,
+	.comp_skb_extra_space = MPPE_COMPRESS_PAD,
+	.decomp_skb_extra_space = MPPE_DECOMPRESS_PAD,
+	.must_compress  = 1,
+};
+
+/*
+ * ppp_mppe_init()
+ *
+ * Prior to allowing load, try to load the arc4 and sha1 crypto
+ * libraries.  The actual use will be allocated later, but
+ * this way the module will fail to insmod if they aren't available.
+ */
+
+static int __init ppp_mppe_init(void)
+{
+	if (!(crypto_alg_available("arc4", 0) &&
+	      crypto_alg_available("sha1", 0)))
+		return -ENODEV;
+
+	int answer = ppp_register_compressor(&ppp_mppe);
+
+	if (answer = 0)
+		printk(KERN_INFO "PPP MPPE Compression module registered\n");
+	return answer;
+}
+
+static void __exit ppp_mppe_cleanup(void)
+{
+	ppp_unregister_compressor(&ppp_mppe);
+}
+
+module_init(ppp_mppe_init);
+module_exit(ppp_mppe_cleanup);
diff -Nru a/drivers/net/ppp_mppe.h b/drivers/net/ppp_mppe.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/net/ppp_mppe.h	2004-07-20 16:37:04 -04:00
@@ -0,0 +1,87 @@
+#define MPPE_COMPRESS_PAD       8       /* MPPE growth per frame */
+#define MPPE_DECOMPRESS_PAD   128
+#define MPPE_MAX_KEY_LEN       16      /* largest key length (128-bit) */
+
+/* option bits for ccp_options.mppe */
+#define MPPE_OPT_40            0x01    /* 40 bit */
+#define MPPE_OPT_128           0x02    /* 128 bit */
+#define MPPE_OPT_STATEFUL      0x04    /* stateful mode */
+/* unsupported opts */
+#define MPPE_OPT_56            0x08    /* 56 bit */
+#define MPPE_OPT_MPPC          0x10    /* MPPC compression */
+#define MPPE_OPT_D             0x20    /* Unknown */
+#define MPPE_OPT_UNSUPPORTED (MPPE_OPT_56|MPPE_OPT_MPPC|MPPE_OPT_D)
+#define MPPE_OPT_UNKNOWN       0x40    /* Bits !defined in RFC 3078 were set */
+
+/*
+ * This is not nice ... the alternative is a bitfield struct though.
+ * And unfortunately, we cannot share the same bits for the option
+ * names above since C and H are the same bit.  We could do a u_int32
+ * but then we have to do a htonl() all the time and/or we still need
+ * to know which octet is which.
+ */
+#define MPPE_C_BIT             0x01    /* MPPC */
+#define MPPE_D_BIT             0x10    /* Obsolete, usage unknown */
+#define MPPE_L_BIT             0x20    /* 40-bit */
+#define MPPE_S_BIT             0x40    /* 128-bit */
+#define MPPE_M_BIT             0x80    /* 56-bit, not supported */
+#define MPPE_H_BIT             0x01    /* Stateless (in a different byte) */
+
+/* Does not include H bit; used for least significant octet only. */
+#define MPPE_ALL_BITS (MPPE_D_BIT|MPPE_L_BIT|MPPE_S_BIT|MPPE_M_BIT|MPPE_H_BIT)
+
+/* Build a CI from mppe opts (see RFC 3078) */
+#define MPPE_OPTS_TO_CI(opts, ci)              \
+    do {                                       \
+       u_char *ptr = ci; /* u_char[4] */       \
+                                               \
+       /* H bit */                             \
+       if (opts & MPPE_OPT_STATEFUL)           \
+           *ptr++ = 0x0;                       \
+       else                                    \
+           *ptr++ = MPPE_H_BIT;                \
+       *ptr++ = 0;                             \
+       *ptr++ = 0;                             \
+                                               \
+       /* S,L bits */                          \
+       *ptr = 0;                               \
+       if (opts & MPPE_OPT_128)                \
+           *ptr |= MPPE_S_BIT;                 \
+       if (opts & MPPE_OPT_40)                 \
+           *ptr |= MPPE_L_BIT;                 \
+       /* M,D,C bits not supported */          \
+    } while (/* CONSTCOND */ 0)
+
+/* The reverse of the above */
+#define MPPE_CI_TO_OPTS(ci, opts)              \
+    do {                                       \
+       u_char *ptr = ci; /* u_char[4] */       \
+                                               \
+       opts = 0;                               \
+                                               \
+       /* H bit */                             \
+       if (!(ptr[0] & MPPE_H_BIT))             \
+           opts |= MPPE_OPT_STATEFUL;          \
+                                               \
+       /* S,L bits */                          \
+       if (ptr[3] & MPPE_S_BIT)                \
+           opts |= MPPE_OPT_128;               \
+       if (ptr[3] & MPPE_L_BIT)                \
+           opts |= MPPE_OPT_40;                \
+                                               \
+       /* M,D,C bits */                        \
+       if (ptr[3] & MPPE_M_BIT)                \
+           opts |= MPPE_OPT_56;                \
+       if (ptr[3] & MPPE_D_BIT)                \
+           opts |= MPPE_OPT_D;                 \
+       if (ptr[3] & MPPE_C_BIT)                \
+           opts |= MPPE_OPT_MPPC;              \
+                                               \
+       /* Other bits */                        \
+       if (ptr[0] & ~MPPE_H_BIT)               \
+           opts |= MPPE_OPT_UNKNOWN;           \
+       if (ptr[1] || ptr[2])                   \
+           opts |= MPPE_OPT_UNKNOWN;           \
+       if (ptr[3] & ~MPPE_ALL_BITS)            \
+           opts |= MPPE_OPT_UNKNOWN;           \
+    } while (/* CONSTCOND */ 0)

=================================

This BitKeeper patch contains the following changesets:
1.1850
## Wrapped with gzip_uu ##


M'XL( '""_4   ]1;;7?:2++^#+^BXSG)0,R+)/!+[#AW",8)&P=S ,]L;N+#
MD:4&="TD1A)QO.OL;[]5U2VIA8039S(?UI-)0.JNKJ[7I[K+O[#+D ='I?=F
M%$U/_65H+<J_L+=^&!V5;.ZZ#<M?PH.1[\.#YM*F$4;S^J:Y7*UXTW6\]9>Z
MT=@KPZ"A&5D+]ID'X5%);[22)]'º^51KTWE^>=4;E\<L*Z"].;\S&/V,E)
M.?*#SZ9KA[^9T<+UO484F%ZXY)&):]\G0^\-33/@OSW]H*7M[=_K^UK[X-[2
M;5TWVSJW-:-]N-\N*QOY+=Y EDA;.T ZQH&FW6M[K8-6^93I#?UP3V-:NZDM- V-Z?M'QHNCO59=:Q]I&BLBRG;;K*Z57[.?RW^W;+'A<'C$.K;-[,!!<38]
M'C57J]449=ZP:L#/#9\Y+F>F9[-WEN_-G#GC7A0X/(3Y\.>]8P5^Z,\B-O0M+ZI'?IT^L,G:\V 'CC=GP\"/?,MW6;A>K?P@@FGKR'&=?_&0X6IS[O' L6B1
M&Q[ -&8%=ZO(9X$/ ST>-LKOF/'B0#\L#U.=ENN/_"F7-5,KORJ4\GVQ"%0]
MOFCMW6NMO8/#^T.[S?7]_5;;T*P7MGWPXQ3W[XU]> !,/:Qå:L%$71;0UL
M3-?VC,-[WFYSS3S0]=D+S7YQ</AMWE1Z*6?M^];^07O_4>):;&ZN91A[QGVK
MI>]=VR_V#RVK;5JZ]>,4#^[;[?8>BNM?#KQV?Q-Q8;E_>-/P@_G'6(A7&6K2
M<$E>NM8"@BVCU;K7#P\.C/L#?KAW;>QS;EC[QMX6']Q&3A57NPVV05&G6/$8
M@@;\EJ&HC[:,*<\89^WR[_!_<8#Y*U9*X2<7>UI[#\8>[>^(/19[[43O.%_Q
M@,3!'@CXS2V2>L=PDQ /MKP?L=S^_\FT+X>&_@-QXV]2AOY(91QH^W]/*CAC
M.D98"D47K![<TA_8^5;Q/EZ&?8T!_^7F\S)[SF)*4^!W%? P!/^H,\@;/)B9
M%F?OA\,>[))%"XY9BEF^S1LX<;)P0DK]CN\Q^#CS [8..;MUH@4[1Z.)4XC1
M,!KZB]T:?&A#UMVE]&(T]AO&+E)"8J_OV!E([H9UUZ%IW;"7,_SVV]SWYRY'
M4;ZB-;O^ZBYPYHN(5:PJ0YG6X*\6_M5F;VAPC?4]BP9W7)?1X)#!OGCPF=OQ
M<N>.Q;V0'^'G(0^63DB[@&W"#FJPQ]5ÂU]VYG!O\BM[820:J_7$0=!P&8Q
MS]Z:@4C'3A0B(=NWUDM(R68D);+@ ;^^8W/82L3M&EL%_F?'YC:0,",2J'GM
M?^:T'#&*5#P_ N:8"2HQ@Q 4P4S8!PR!1-]@0NK)ZO Y(8IRAR0-'-TA'7B/
MZP+__ OIE8%^G.7*=5(Q=,XGO=&@,^G_WCO_D.</J$MN'!1A9 ( L)&CV=IU
M:V( S+'7%G&^-._8-5=$9;.U9T-@P9V".2V!A1E]>3.X9&\0:I@N&ZZO74 <
M4B.L\F9X7JTA.5CG=N$ F+3,D-,TX@\5E1(:GJ.DW#O6'XPGO<XINSB#%SY,
MF(.S>$+ \7:E]( ,J&1)-AMPGDCSF-WY:UC-@[TJ^G90I'83I"<,0E""IX_?
MG F+XY-P ;*YEI1PSAGR,8ZU>N8#:;*B8\9!J[!*[&=&O(HD60.M"C(54!GP
M'S!_A3.K: ?,-:-T\G8QJ"H#L2/]A;_BP@Y@I[<.F""H%IP#5%\31& X^Z,_
M>7MQ.6&=P0?V1V<TZ@PF'XX32^2H 20FS2ZQ2=B$H/&^-^J^A4F=U_WS_N0#
MFNA9?S+HC<?L[&+$.FS8&4WZ7:PBV/!R-+P8]\ 'QISL09!X0-PSTAD(U$;;
M=<-4 !] T2'PZ-IL88('!MSB8"\V,\D9OZU*0<:$B#\7 2]21'K,G!EZ3HWM!@Y&##^O9$$@U;0(6S6V]X)-.(@+@JT+X;?&QFLDT6II-?8::C0<^;[#&. G
M7:_K+>V L<MQ1^R,0B2E'->?'XDEX$?;;^J'38B0=<IF3&0S]K(HM;U*9BD_
M4#!N1O1]9@96F\)?N##UI#Y@@4D&"Z;C%9$2,09K$;+56[)*\<IHZGN"R\GX
MB)DV1J)?',]RUS9G+V,C7KRB12,>1D@%=?R.F"I:#7YBS[GF,S2%‹SMHQ]
M?W$Z/>UUIR#0-[UI]^)R,&GBL_X@\TS&I42+N1^;0\2U3.E.("P8URQ_*J>[
M(5#5%/ 5MI1[ Z%F#8FOX(W00-&;5$*Y5X[G1$7/L4X/BUZ$KGE=^!SBA%?(
ML:@3"_>R+'J*N,/FL\+5X5T=X4CVG1DNFR%(%4(:A%#:CR+2G;12V8'GH+;+
M\]ZT<PD!:E39^0:XV*D>QS-.>^/NJ#^<]"\&E9V-2CHIG[?6VCV/Y( &)TML
MA?1YO]L;C'N5G=,U!)37X],FY"_E?>>\WQE7=N+=8]*N[[#I5 @M^EVY\B
M'JNF<W[OC<;$*A04#0V)?2J'"$$L]MEW['+(H_5J&LXK0 3R-%,$R)Z'<\0Z
M'GS$L>PY^!PN6H/4%CISD>PCYG)O'BVJY7^72^'\HW;56)ESSD[89R>(II$_
MQ:\5.176EX/\V2S$TQXF/DP=;W/@IW()XF0E,WQ7KL9>GD#L!X<;]_^W5V6P
MM"0K7Y_(<<?BA9XPI:5/$@Z49\ET?/:5<1<B6P'Q9&D(1BI_!83DAWC<%K:*
M9 6;5>=4"S@OEEUN8JGYG&D88DI?RU]!K@+9C\$,1!($2$,POF+S:FQ9?M"@
MJ"3M(BD#0IJ%NA8OA%]/H]D2[ -"_G'A&\P!\":Q&VMA!N+IU';F$*MS+Y=F
M"'8XO>%W'Y&WZ?O./Z?O>A^FY[W!56YPR F@?WLT# "AD$#@8ZP<",+7=Y Q
M,D$:Q07#!J^/F&X<UJ\=/)J$ZJ_&VEK\[?!)/*P_8[=0VP!ZP70N?9OM[>/(
M6DH-\_P:@BW BA '6I2-\1.,"\6P[-;P.?%+&@)OC ((,#0Z.]@"K!#12-T@
M_BP?"PS/NF/T"CR)_^GYU8U%2)^ VFAF_ 6A+)B&:\YI,'HY8$#+#.SC4G[<
M"H(FF*/K@^EEYH0F;/5NRH/ #\0F(O,&X!:D=7;>'2(,BGP?5 U0-)Z#TCF6
M2_+K]5RQ)[!,7)A6#X_+7X_)E%FAA39(0I! ,+5120 +_$+?1<TZ?=V?3#LE
M[<NAAHPI@3DRKP%>W8+L6"7@52(0F7@(:A<2>0U$VII449?Y'I0;%8!W!&LY
M5GS<KA;.[,),XX=FGL),G6825H<_X,-<[ '8A 2VY!)3;$X].[\<O^Vî(A
MY,?T!MW1A^%$'75:0&M<6559!?[ZV+YBSYCV9:95LX.Z!(C$,'6@-JNRER_9
M815B%3[>NRJ<.!T/.]T>P[UJ<K\fX$F8@0NK)Z%*SR*R._WXO>WIR4C\1ZH
M]8(%-^VFM%A%LN/.  H,C!LE?5^L]=[\PJ[].5C$S+0B")/HX%CI1+X+D#_:
M6'#\MJ-/AYU3D1?:FHRR[R#,G/+ ^2QA_"SPEVQTUF4 S0]K\:<7!'-[?ZYA
M' 0E"B)O(++#[$J58O3[<1U*H2'6B#8/+2C'!'I4"335U,[F,-_CMQ@4I[CJ
M%,)MI3B<2X]6$KL(T'T\YG&6P(5([X*Z@ 39H;#[E6GK'S-2N&(GY1+&TG^C
MRJ%"^:&_(>W]=\Z&='O\'4(S'A#:S*C]V-_$^'_C[%AH.30*D,:X(E0H@84 
M#E.,SQ4RW_HK!!0$,1-4"PA6ODL!1?)(H &<D"6Y7D'1S56B,&5>,"VSCG2!
M&@4H?U:1WZN/H)^?6+03!>W\K5LQ-C@R?G0K11,A9IKNQKSTBQR%TY9\::WN
M*FDH*AJ8WU"*<X<\@ "ZI'Q!:2#@B/U,=^X'3K18YF)RR*T&.VBT*";_P?$L
M$Y/R[<*,?@WIS"82!U<!1$P\YI)G&K?RV/:.+3D P7Q$IHA+JW\K#B/\(>!A
MNJAFBK[9V)'*HQ#Q%CH0^ KX$"IHZJ^CV)VVY GB0TD QZ(<>Z*R1;61U*OE
MK$ (4[ CL3]2!U8$*I4"PU,M#QA\S&C8Q'<ZQ0:3$BEEN4P($ALPIU02E4".
MFE(82NLL8N+!?7R5Q:WZG"H*(5. 'WB*&=LDH>-2?A$H\K!6_6+KQ\7O=?'>
MV-_RWA#O7W#!TK=5^3W23EVOX[H^GG-)@$:UYI8J,_62Y^00)DZM;. 1<78M"O^ +[A>.:U%-[V)_E'+/U'(8,# ^)0<,0A*[,D)Z_;!?^@,!8MH$<-R^:,J
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
M2R='=4MJBU_P[L2 EB[B$-:'CW9NB\5U64:NA$ZZ)KXY8DXL.CIK4D.7@,J
M?2*#UN.,4CGOC-G%(EPUS2QH?[)IEC^ZAX(M5"K;P/]/W9^?W1^UU8N8]#,V
M%]_\TM-<Z,X2>:GT1E,\+_9;NI##UQAM2QC%)AAOL<V?^OVgKHA[^B+(]'
MD_Y_ZK3&2OK_J[NVYK:-*_QL_@HHDW;(6J9$BJ+ILG(BBW&EJ2QY3+MYRG! 
M$!1ATP"'(",[5?/;>ZZ+Q947Q9T)'Q(+V+/7LV?/?N>")^I7@+BWB:@@L%ZB
MR%U$M>Y #L*_/Z)"X3I3_UXH@Q!& ?IH+- 7!4(@<D$E,?YX38"9:/5>M%RN
M%^)<\(1E:G:(K\_?GU\7G2@*$N4M(L91H6@G&*0E!=,[O68+-*1WBO2*0FUC
M.$_N9YB#(7,+/3A3R4/UEM[,'G')Q_U@.;T5=+W=3.ZB.EX)&9%N'6'L^O(S
M&J18O3EZ9)^HK60.TB@!MRG,B&NE)5]F"NK[MU80"UJ!/ K)QQ ,OGG(8-29
M0*B&H)BY\X2S%<AWZG#Y24P N?M\0VN@27B2GC#9IN5;#9?#7@^<VU3_I%Y:
MC)1(HJ*>MVAZ)F@[#BC@H Z'*>@E%"P#(\J; AI-[6UIKZP>$8]D6!G3*(#>
MDX)'3*7"VHET_9VEZL&9Y8F990\MI8,KY_T<I_'#@CJ?)F^<]FFWG/U8%/!0
M&9(H6\WC?JV@!XDZGV+4<[9C($ !NMYGUA6,(RB*&9 25RL)FH\-1JWTQ(>H
MH,E9$DYL&Y29=N?5>D75MEYTVTJ+SE<!C,4AR^)EM$!QA4:M-]^#!/;C7'5]
M,F@JN=@U [P=H?"6ZB8<P((7L/AKZ,V641C\)N$P5#;3_(2W$<XHLF%JQQT9
M]A=AH^Q=(?ELD?T:N5X0_&FPC!'>@;N&A!,E.*_8M WN3T 1U0!GMQ^SRSC)
M!5_1]HF[<K=!@I%?GEKP;0DDG"G&$%8"9Q5?P_H6D%52 NM]UM6 Q-"7B^K?
M6=U^UI&#2^9K8-V)>+[HC@,S&"TG+/!(P<7S7‚J!(;%,P+YGT)K;_3<VH,
MTX706C::PX;56GE(31:C$E)K-6R<?\!7B$0E4S=#MJO?D^H 4C($_7PIIA *
M#>3\(92DA4R_3OQI!-V:UE0) 39"MG(%&; O;'5E#PJ%:Z&0 TXE&99PA)3I
MZT-V]=8_"=/CFQ+]4W@<I ?L-@RMP%UK7VB7>&45-K=%;]&\X[&;W-S*UX#+
M17:YW=?#;J82YBR$*7> .0MAT@*8$V;Q+HHF1D/$;"\KVWDBK1^_?*GN7F7X
MZ)7A?KJ]HYR@^%]WN228K,XI@]C %N)9":]!E(4'#376RTL\$]PQ^L:JC8X!
MT6FED1+K@)6G\!2I:.PG9D(0=>?,(W/?%5NY%)-F C(6FY.C?AG=6SKY#R5V
M]("&O1V8YJ$F]H<ZM":V$+&\Y VR" *(%1;N;@7O_W&F-ME"J"![T>8!JXM<
M:LWKZ]#,=X,X( .ML#GB+\>=+WE,I:!K!7LE2)D$O'"59?6@:JNL-U%G-AIS
M]V-^Y'] :4RL;&+D]@1O'O,[2B*_EI'G3]:HT/A?,""?58M@.@(&:GHI'-@R
M!HA3CC(9\!UP9E/?C-3"+\ZTA_*.'=II.<\L#W?SFG))V:_Q@7F+0'KJK7EJ
MBK!&E"U"3P^M_CFY:BAGA]9"EHY<+;3&6$:P=QU+³R6L>2&8EE%+#>6D^M
M0CJ:LSSFGY0RXTF5TO'P'G.<](CYJbCKAPO-%]".+6JN/]Y=5PQ,E3DCG[
M-!XA6N>.V&E?,4:X_J!>AZ&[=GO%I?FZ9)='.^XH&28<(X>:U""5>8\C)R1_
MT]MEP YCN";W>+V<1R[<5%?L^8=_L%:22K_$QS+2SX/QTEUJLCBCO7!F/KX1
M:HC"A/.#D:-'36'I>_<K>UGRUB6:J1O,:6.%,3R6X^@KNL'A+<#]%5[COFY*
MFJ/$\N*,F%G20\43@TX#QD)-U-#=R%1E12(9">\XQ25-C%'#<JUY]M/-[>"G
M?_.9$:+W6 QJ':P!÷IWP7D[IM(@_I?M8^)8[;2H/*6.1^N;E[?.M_A=8*N
M/>K-A>ZL,G':AH^(,FI.TC&N-&4II!-T!#QESY0'AW6X7B23A6_6X::N8[7<
M Y[KU,S#>WF';=6S;<'KTJ2ILRV2IL[V2YJZ9:[:DJ2IW3]CTM09)DW%49:E
M]9S5WCFY"?B_9$W“7R65.K5Z/W_%LF3>6$Q-LD39WMES2U]SR3P\22]W*^
M].3_FI$$'256,X<X17.VI.I(GQI V6KWTB6L,$:IO-4UC9 S)US\K&1'=<EF
MU'!$4Q)[/^<40J3&\Q8C\0%HD@*4[11'YCC6#Z^QTB2\& >K0AH,\4C1M(4&
M7Y01::"-(>H(D;'*D)\6D,(SN&%PZB7$'1:K?-8?K/&TF^EZ3VJ$%V6]H 0]
M%DWK.%G&"Z,UXC0640^<=(MMI?X@\4E%1!]NAA_>OKU]AY:ZNM7YAU2GDK\&
MC:(Z_G5S^_.-:;BC#;_"Q3[@XG8>F1ZC&X)FJBJB,0:(*"(20NXYI&7,X:P)
MX93ZE2(^7)P_]JD2?9HA0<ZW&V+"5V"PU1J-H.(K[[DAX90S=)K'*F/<!H87
MR7.9>)&2W[J(O7%67#;O7)".<^EDJ4&[^×RP_<4UUG#2?<ZJ2-M:#?*I0-
MC1\ WV7A4KZ*PGF]X;CBH8\NZ)K<%2_%*W)6]_V)>"N1PSHG>XR\E4_.U?0G
M:SII88#&VPP;F#U#3)3;^@44ANUNQW$T]REE3XPIY-8EC'1=4(GA/DEDEJ49
M%M 8QM%<:%FB-P5$/272/&BTTF:#9JNXK)JBH;'PUC'GL3,)IE,TN3$@F0BS
M <+4E$-+$C]>(COT4<%E')I #@>!B& :>&A>Y+5#7XYFKD_GUS2#0]F!M"8/
MR<P^)!/VD$S#0S*<!O?JU3J8DS_4%2/')%9)0-5C*\]#/MD7AEQBZ.7%%<9Y
MQH>.%S124^1PT#/P[W^<[7X:)0U;@G&8Q0H57R_HXSSS0\S3];>C+,&V/T, 
M]5V*2-V.0.)9BR,MBPCPAP-X^I0261SW-[5 )JI=QI!J(5G87$.&(.E.66<>
M2[#MSUZ'X>&U9@W<LDN;.[1AX3#LMW(,U(HZ"0\+9[6ZA<YQKH&*%JXWM(""
M^'!P>,'SE)5568+_.F*R1'_MVYOA>_@/.B7B99#V_'M"W5&[-.GJ^.3*'0U)
M<+47D-=E_"?:X[0FN[#*SBWL)44.ZC!DMK%8TKA13( _&H>RBBUW^B4$NXYA
MMQU(H4(P@A,S MH@U1LJ-P;8@MEUJ6CA>H\6.OF%?]0L63NP?)XJQO!FCS&<
M=LO'D&]AL$<+@PV"+=W"Q1XMH K9KR#8YF>OPRTY(>RZ#K3??K<VW$YCD-M*
MOXA 6VC]0B%S\*_V+WGA_T>T<)*,0;6_5$-[ME!U7F1A-?,UKXT?0]O_<U.U
MCW?N\K?@TX^+:!Q]V?2MJ>/6\4GGM-UY.#GIO3@E=*?7R<$[G4IXI_6MOHZ&
M'T8SX$V$-S/M/>)H]'&L"MC'E-T#]&D=MYU6+1I_?/9]'=;S]=4_1VBLHT0J
M:$E+>I5;8_U(&RSQ-_M$5LW]M/C\8Q1/YMO5" O=:K6Z)Z<=6.AVZP5__*CW
M?,>%_D;?/N*%SDPSKK:,@# ^_+17Q6)KT3W6NMWIMIUN399-VU=AL%H&;(Q.
M4'\;%=(P;OSTRG=*,_$7?CB)T×B/0IM#;SYPMLU(B0H2045TB$ZK=R5JOI
>OPFJI_G*(GN>KS^?33MM=_S"\VK_ _94>&G<<0  
 

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [2/2]: ppp_mppe inclusion
  2004-07-20 20:47 [2/2]: ppp_mppe inclusion Matt Domsch
@ 2004-07-30 19:33 ` Oleg Makarenko
  2004-07-31 18:34 ` Matt Domsch
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Oleg Makarenko @ 2004-07-30 19:33 UTC (permalink / raw)
  To: linux-ppp

[-- Attachment #1: Type: text/plain, Size: 3057 bytes --]

Matt Domsch wrote:

>On Tue, Jul 20, 2004 at 03:45:40PM -0500, Matt Domsch wrote:
>  
>
>>This mail will be followed by two patches, for comment on proposed
>>solution.  I've compiled this, but am not able to test this week.
>>    
>>

Great work, Matt. Thank you for your patches. Any chances to see them 
integrated in 2.6 any time soon?

The only problem is that they do not work for me and never did :) I get 
kernel panic with your patches and wonder how others don't get the same 
result?

Please find attached somewhat (I hope) improved patches that finaly do 
work for me

The problems with your original patches:

1. setup_sg(). Do you really need to split the data this way? The 
documentation on crypto api and scatterlists is not very helpful so I 
could be wrong here but in my reading  of crypto/digest.c/update() (for 
ex)  you may just have a single sg[0] even if the data doesn't fit into 
a single page.  All pages just need to be contiguous. It probably 
doesn't hirt but is it really needed?  I have removed this split from 
your patch just to test it. Seems to work fine.

2.  For some reason you can not use non GFP_KERNEL memory and scatter 
lists or at least mix them in crypto_digest().  That is why sha_pad is 
now in struct state {}.

3.  In get_new_key_from_sha() the code like 

   crypto_digest_update(state->sha1, sg, state->keylen)

looks suspicious as the last parameter (in my reading of digest.c) 
should be the number of elements in sg[] array not the data length. That 
seems to be the reason for my kernel panics. With your setup_sg() the 
last parameter should be 1 or 2. Or may be you could replace all four 
digest_update calls with a single call with properly initilaized sg[4] 
(to make some use from scatterlist) . See the modified patch for details.

4. in ppp_generic.c/pad_compress_skb() the following code:

       } else if (len == 0) {
               /* didn't compress, or CCP not up yet */
               kfree_skb(new_skb);
               new_skb = NULL;
               ...
        return new_skb;

also looks suspicious as later I read

               skb = pad_compress_skb(ppp, skb);
               if (!skb)
                       goto drop;

I think you don't want to drop packets with len == 0.  At least the 
previous mppe enabled ppp_generic.c code don't do that.  I've changed 
new_skb = NULL above to new_skb = skb, see the patch. IPCP can not be 
established without this modification.

Please try these patches and let me know your results. Hope they can be 
useful for you.

And btw,
What do think on crypto api in kernel? It looks like a performance 
killer for the small size block ciphers and especially for the arc4 
(with its single byte block), doesn't it? Or have I missed something?
Why do we need so many calls just to encrypt a single byte (see the for 
loop in crypto/cipher.c/crypt())?
Does it make any sense to cond_resched() for every encrypted (i.e. for 
every sent) byte (as crypt() does for arc4)?
Some benchmarks against this new patches would be very interesting.

=oleg


[-- Attachment #2: ppp_mppe1-moleg.patch.gz --]
[-- Type: application/x-gzip, Size: 1565 bytes --]

[-- Attachment #3: ppp_mppe2-moleg.patch.gz --]
[-- Type: application/x-gzip, Size: 8035 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [2/2]: ppp_mppe inclusion
  2004-07-20 20:47 [2/2]: ppp_mppe inclusion Matt Domsch
  2004-07-30 19:33 ` Oleg Makarenko
@ 2004-07-31 18:34 ` Matt Domsch
  2004-08-30 22:42 ` [pptp-devel] " Matt Domsch
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Matt Domsch @ 2004-07-31 18:34 UTC (permalink / raw)
  To: linux-ppp

On Fri, Jul 30, 2004 at 11:33:09PM +0400, Oleg Makarenko wrote:
> The only problem is that they do not work for me and never did :) I get 
> kernel panic with your patches and wonder how others don't get the same 
> result?
> 
> Please find attached somewhat (I hope) improved patches that finaly do 
> work for me

Thanks for the patches Oleg.  I've been out of town, and heads-down on
other issues this week, so I'm not ignoring you, just otherwise
committed.  I'll try to find some time this next week to review and
respond properly.  At first glance I think your fixes are correct.  I
appreciate your patience.

Thanks,
Matt
-- 
Matt Domsch
Sr. Software Engineer, Lead Engineer
Dell Linux Solutions linux.dell.com & www.dell.com/linux
Linux on Dell mailing lists @ http://lists.us.dell.com

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [pptp-devel] Re: [2/2]: ppp_mppe inclusion
  2004-07-20 20:47 [2/2]: ppp_mppe inclusion Matt Domsch
  2004-07-30 19:33 ` Oleg Makarenko
  2004-07-31 18:34 ` Matt Domsch
@ 2004-08-30 22:42 ` Matt Domsch
  2004-08-30 22:48 ` Matt Domsch
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Matt Domsch @ 2004-08-30 22:42 UTC (permalink / raw)
  To: linux-ppp

On Fri, Jul 30, 2004 at 11:33:09PM +0400, Oleg Makarenko wrote:
> Great work, Matt. Thank you for your patches. Any chances to see them 
> integrated in 2.6 any time soon?

That'll depend on how many people are testing it I suppose. :-)  I've
just now gotten back to this, sorry for the delay.
 
> The only problem is that they do not work for me and never did :) I get 
> kernel panic with your patches and wonder how others don't get the same 
> result?
> 
> Please find attached somewhat (I hope) improved patches that finaly do 
> work for me

Thanks much.  I've merged these into my bk tree at
http://mdomsch.bkbits.net/linux-2.6-mppe

along with this simple patch which makes use of setup_sg() rather than
hand-coding it four times.

ChangeSet@1.1803.13.4, 2004-08-30 15:29:05-04:00, Matt_Domsch@dell.com
  ppp_mppe: use setup_sg() in get_hew_key_from_sha(), bump version


 ppp_mppe.c |   27 +++++----------------------
 1 files changed, 5 insertions(+), 22 deletions(-)


diff -Nru a/drivers/net/ppp_mppe.c b/drivers/net/ppp_mppe.c
--- a/drivers/net/ppp_mppe.c	2004-08-30 17:37:29 -04:00
+++ b/drivers/net/ppp_mppe.c	2004-08-30 17:37:29 -04:00
@@ -61,7 +61,7 @@
 MODULE_DESCRIPTION("Point-to-Point Protocol Microsoft Point-to-Point Encryption support");
 MODULE_LICENSE("Dual BSD/GPL");
 MODULE_ALIAS("ppp-compress-" __stringify(CI_MPPE));
-MODULE_VERSION("1.0.0");
+MODULE_VERSION("1.0.1");
 
 static void
 setup_sg(struct scatterlist *sg, const void *address, unsigned int length)
@@ -122,28 +122,11 @@
 static void get_new_key_from_sha(struct ppp_mppe_state * state, unsigned char *InterimKey)
 {
 	struct scatterlist sg[4];
-	char *p;
-	
 
-	p = state->master_key;
-	sg[0].page = virt_to_page(p);
-	sg[0].offset = offset_in_page(p);
-	sg[0].length = state->keylen;
-
-	p = state->SHApad1;
-	sg[1].page = virt_to_page(p);
-	sg[1].offset = offset_in_page(p);
-	sg[1].length = sizeof(state->SHApad1);
-
-	p = state->session_key;
-	sg[2].page = virt_to_page(p);
-	sg[2].offset = offset_in_page(p);
-	sg[2].length = state->keylen;
-
-	p = state->SHApad2;
-	sg[3].page = virt_to_page(p);
-	sg[3].offset = offset_in_page(p);
-	sg[3].length = sizeof(state->SHApad2);
+	setup_sg(&sg[0], state->master_key, state->keylen);
+	setup_sg(&sg[1], state->SHApad1, sizeof(state->SHApad1));
+	setup_sg(&sg[2], state->session_key, state->keylen);
+	setup_sg(&sg[3], state->SHApad2, sizeof(state->SHApad2));
 
 	crypto_digest_digest (state->sha1, sg, 4, state->sha1_digest);
 


> 2.  For some reason you can not use non GFP_KERNEL memory and scatter 
> lists or at least mix them in crypto_digest().  That is why sha_pad is 
> now in struct state {}.

OK for now I suppose.  I'll ask the crypto folks what's up with that.
I obviously prefer to have that stuff in a .rodata section allocated
once, rather than "waste" 80 bytes per connection.

Thanks for being patient with me and for your continued testing.

-- 
Matt Domsch
Sr. Software Engineer, Lead Engineer
Dell Linux Solutions linux.dell.com & www.dell.com/linux
Linux on Dell mailing lists @ http://lists.us.dell.com

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [pptp-devel] Re: [2/2]: ppp_mppe inclusion
  2004-07-20 20:47 [2/2]: ppp_mppe inclusion Matt Domsch
                   ` (2 preceding siblings ...)
  2004-08-30 22:42 ` [pptp-devel] " Matt Domsch
@ 2004-08-30 22:48 ` Matt Domsch
  2004-08-31 22:23 ` Oleg Makarenko
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Matt Domsch @ 2004-08-30 22:48 UTC (permalink / raw)
  To: linux-ppp

On Mon, Aug 30, 2004 at 05:42:05PM -0500, Matt Domsch wrote:
> On Fri, Jul 30, 2004 at 11:33:09PM +0400, Oleg Makarenko wrote:
> > 2.  For some reason you can not use non GFP_KERNEL memory and scatter 
> > lists or at least mix them in crypto_digest().  That is why sha_pad is 
> > now in struct state {}.

Can you describe what happens when you do?


-- 
Matt Domsch
Sr. Software Engineer, Lead Engineer
Dell Linux Solutions linux.dell.com & www.dell.com/linux
Linux on Dell mailing lists @ http://lists.us.dell.com

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [pptp-devel] Re: [2/2]: ppp_mppe inclusion
  2004-07-20 20:47 [2/2]: ppp_mppe inclusion Matt Domsch
                   ` (3 preceding siblings ...)
  2004-08-30 22:48 ` Matt Domsch
@ 2004-08-31 22:23 ` Oleg Makarenko
  2004-09-05 18:23 ` Oleg Makarenko
  2004-10-12 17:14 ` Matt Domsch
  6 siblings, 0 replies; 8+ messages in thread
From: Oleg Makarenko @ 2004-08-31 22:23 UTC (permalink / raw)
  To: linux-ppp

Matt Domsch wrote:

>On Mon, Aug 30, 2004 at 05:42:05PM -0500, Matt Domsch wrote:
>  
>
>>On Fri, Jul 30, 2004 at 11:33:09PM +0400, Oleg Makarenko wrote:
>>    
>>
>>>2.  For some reason you can not use non GFP_KERNEL memory and scatter 
>>>lists or at least mix them in crypto_digest().  That is why sha_pad is 
>>>now in struct state {}.
>>>      
>>>
>
>Can you describe what happens when you do?
>
>
>  
>
It didn't crash/panic and everything seems to work fine but the digest 
was incorrect.

When I'd looked at the actual data that were passed to sha1_update() I 
saw all FF's instead of  00's (or F2's) for pad1 (pad2).

The only difference was the memory type and to verify that that is the 
reason for wrong calculated hash value  (and only as a workaround) I've 
placed pads to struct state. Struct state is already gfp_kernel so there 
were no need to bother with malloc/free :)

Actually I don't know what is wrong here and what is the right way to 
solve it. Is it by design or is it a bug in crypto?

It is easy to add one more test for sha1 using static memory and I hope 
I'll be able to reproduce the problem.

I'll try tomorrow and let you know the results.

regards,
Oleg










^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [pptp-devel] Re: [2/2]: ppp_mppe inclusion
  2004-07-20 20:47 [2/2]: ppp_mppe inclusion Matt Domsch
                   ` (4 preceding siblings ...)
  2004-08-31 22:23 ` Oleg Makarenko
@ 2004-09-05 18:23 ` Oleg Makarenko
  2004-10-12 17:14 ` Matt Domsch
  6 siblings, 0 replies; 8+ messages in thread
From: Oleg Makarenko @ 2004-09-05 18:23 UTC (permalink / raw)
  To: linux-ppp

[-- Attachment #1: Type: text/plain, Size: 674 bytes --]

Hi Matt

Matt Domsch wrote:

>On Mon, Aug 30, 2004 at 05:42:05PM -0500, Matt Domsch wrote:
>  
>
>>On Fri, Jul 30, 2004 at 11:33:09PM +0400, Oleg Makarenko wrote:
>>    
>>
>>>2.  For some reason you can not use non GFP_KERNEL memory and scatter 
>>>lists or at least mix them in crypto_digest().  That is why sha_pad is 
>>>now in struct state {}.
>>>      
>>>
>
>Can you describe what happens when you do?
>  
>

please try the attached patch for tcrypt.c to see what is going on 
yourself.  modrpobe the resulting module with mode=2 parameter to test 
sha1 and see how it fails the tests.

For mode=0 (or without any parameter) you should get kernel panic.

=oleg







[-- Attachment #2: tcrypt.diff --]
[-- Type: text/x-patch, Size: 610 bytes --]

--- tcrypt.c.orig	2004-08-14 09:37:38.000000000 +0400
+++ tcrypt.c	2004-09-05 21:11:19.000000000 +0400
@@ -58,6 +58,8 @@
 static char *xbuf;
 static char *tvmem;
 
+static char tvmem_buf[TVMEMSIZE];
+
 static char *check[] = {
 	"des", "md5", "des3_ede", "rot13", "sha1", "sha256", "blowfish",
 	"twofish", "serpent", "sha384", "sha512", "md4", "aes", "cast6", 
@@ -820,7 +822,8 @@
 static int __init
 init(void)
 {
-	tvmem = kmalloc(TVMEMSIZE, GFP_KERNEL);
+	tvmem = &tvmem_buf[0];
+
 	if (tvmem == NULL)
 		return -ENOMEM;
 
@@ -833,7 +836,6 @@
 	do_test();
 
 	kfree(xbuf);
-	kfree(tvmem);
 	return 0;
 }
 

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [pptp-devel] Re: [2/2]: ppp_mppe inclusion
  2004-07-20 20:47 [2/2]: ppp_mppe inclusion Matt Domsch
                   ` (5 preceding siblings ...)
  2004-09-05 18:23 ` Oleg Makarenko
@ 2004-10-12 17:14 ` Matt Domsch
  6 siblings, 0 replies; 8+ messages in thread
From: Matt Domsch @ 2004-10-12 17:14 UTC (permalink / raw)
  To: linux-ppp

On Mon, Aug 30, 2004 at 05:42:05PM -0500, Matt Domsch wrote:
> On Fri, Jul 30, 2004 at 11:33:09PM +0400, Oleg Makarenko wrote:
> > Please find attached somewhat (I hope) improved patches that finaly do 
> > work for me
> 
> Thanks much.  I've merged these into my bk tree at
> http://mdomsch.bkbits.net/linux-2.6-mppe

Oleg, reviewing this code again finally.

Patch below moves these out of the per-connection struct into a
driver-local struct.  It's a win if you've got more than one mppe
connection, saving 80 bytes.

Everyone - have you been using this code?  How's it work for you?
Does the approach to using must_compress=1 work?  Is there ever a case
where compression is enabled and running, but somehow a message is
sent to disable it, and a packet isn't compressed(encrypted)?  That
was Paul's concern before considering merging it into mainline.

Thanks,
Matt

-- 
Matt Domsch
Sr. Software Engineer, Lead Engineer
Dell Linux Solutions linux.dell.com & www.dell.com/linux
Linux on Dell mailing lists @ http://lists.us.dell.com

=== drivers/net/ppp_mppe.c 1.3 vs edited ==--- 1.3/drivers/net/ppp_mppe.c	2004-08-30 14:28:51 -05:00
+++ edited/drivers/net/ppp_mppe.c	2004-10-12 11:59:18 -05:00
@@ -61,7 +61,7 @@
 MODULE_DESCRIPTION("Point-to-Point Protocol Microsoft Point-to-Point Encryption support");
 MODULE_LICENSE("Dual BSD/GPL");
 MODULE_ALIAS("ppp-compress-" __stringify(CI_MPPE));
-MODULE_VERSION("1.0.1");
+MODULE_VERSION("1.0.2");
 
 static void
 setup_sg(struct scatterlist *sg, const void *address, unsigned int length)
@@ -74,6 +74,23 @@
 #define SHA1_PAD_SIZE 40
 
 /*
+ * kernel crypto API needs its arguments to be in kmalloc'd memory, not in the module
+ * static data area.  That means sha_pad needs to be kmalloc'd.
+ */
+
+struct sha_pad {
+	unsigned char sha_pad1[SHA1_PAD_SIZE];
+	unsigned char sha_pad2[SHA1_PAD_SIZE];
+};
+static struct sha_pad *sha_pad;
+
+static inline void sha_pad_init(struct sha_pad *shapad)
+{
+	memset(shapad->sha_pad1, 0x00, sizeof(shapad->sha_pad1));
+	memset(shapad->sha_pad2, 0xF2, sizeof(shapad->sha_pad2));
+}
+
+/*
  * State for an MPPE (de)compressor.
  */
 struct ppp_mppe_state {
@@ -82,9 +99,6 @@
 	unsigned char *sha1_digest;
 	unsigned char master_key[MPPE_MAX_KEY_LEN];
 	unsigned char session_key[MPPE_MAX_KEY_LEN];
-	unsigned char SHApad1[SHA1_PAD_SIZE];
-	unsigned char SHApad2[SHA1_PAD_SIZE];
-
 	unsigned keylen;	/* key length in bytes             */
 	/* NB: 128-bit = 16, 40-bit = 8! */
 	/* If we want to support 56-bit,   */
@@ -124,9 +138,9 @@
 	struct scatterlist sg[4];
 
 	setup_sg(&sg[0], state->master_key, state->keylen);
-	setup_sg(&sg[1], state->SHApad1, sizeof(state->SHApad1));
+	setup_sg(&sg[1], sha_pad->sha_pad1, sizeof(sha_pad->sha_pad1));
 	setup_sg(&sg[2], state->session_key, state->keylen);
-	setup_sg(&sg[3], state->SHApad2, sizeof(state->SHApad2));
+	setup_sg(&sg[3], sha_pad->sha_pad2, sizeof(sha_pad->sha_pad2));
 
 	crypto_digest_digest (state->sha1, sg, 4, state->sha1_digest);
 
@@ -203,8 +217,6 @@
 	memcpy(state->session_key, state->master_key,
 	       sizeof(state->master_key));
 
-	memset(state->SHApad2, 0xf2, sizeof(state->SHApad2));
-
 	/*
 	 * We defer initial key generation until mppe_init(), as mppe_alloc()
 	 * is called frequently during negotiation.
@@ -686,6 +698,11 @@
 	if (!(crypto_alg_available("arc4", 0) &&
 	      crypto_alg_available("sha1", 0)))
 		return -ENODEV;
+
+	sha_pad = kmalloc(sizeof(struct sha_pad), GFP_KERNEL);
+	if (!sha_pad)
+		return -ENOMEM;
+	sha_pad_init(sha_pad);
 
 	answer = ppp_register_compressor(&ppp_mppe);
 

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2004-10-12 17:14 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-07-20 20:47 [2/2]: ppp_mppe inclusion Matt Domsch
2004-07-30 19:33 ` Oleg Makarenko
2004-07-31 18:34 ` Matt Domsch
2004-08-30 22:42 ` [pptp-devel] " Matt Domsch
2004-08-30 22:48 ` Matt Domsch
2004-08-31 22:23 ` Oleg Makarenko
2004-09-05 18:23 ` Oleg Makarenko
2004-10-12 17:14 ` Matt Domsch

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).