=== freeswan-ext-v0.6-1.94-ext_serpent.diff ===
--- freeswan-1.94/klips/net/ipsec/ext/Config.ext_serpent.in	Wed Dec 31 21:00:00 1969
+++ freeswan-1.94.jjo/klips/net/ipsec/ext/Config.ext_serpent.in	Sun Dec 16 10:04:30 2001
@@ -0,0 +1,3 @@
+if [ "$CONFIG_IPSEC_EXT_ALG" = "y" ]; then
+  tristate '        SERPENT encryption algorithm' CONFIG_IPSEC_ENC_SERPENT
+fi
--- freeswan-1.94/klips/net/ipsec/ext/Makefile.ext_serpent	Wed Dec 31 21:00:00 1969
+++ freeswan-1.94.jjo/klips/net/ipsec/ext/Makefile.ext_serpent	Sun Dec 16 09:43:57 2001
@@ -0,0 +1,16 @@
+EXT_MODULES += ipsec_serpent.o
+
+obj-$(CONFIG_IPSEC_ENC_SERPENT) += ipsec_serpent.o
+
+IPSEC_EXT_SERPENT_OBJS=ipsec_ext_serpent.o libserpent/libserpent.a
+ipsec_serpent.o: $(IPSEC_EXT_SERPENT_OBJS)
+	$(LD) -r $(IPSEC_EXT_SERPENT_OBJS) -o $@
+
+libserpent/libserpent.a:
+	( cd libserpent && \
+		$(MAKE) CC='$(CC)' CFLAGS='$(CFLAGS) $(EXTRA_CFLAGS)' EXTRA_CFLAGS='$(EXTRA_CFLAGS)' libserpent.a ;)
+
+# Serpent libs
+ifeq ($(CONFIG_IPSEC_ENC_SERPENT), y)
+obj-y += libserpent/libserpent.a
+endif
--- freeswan-1.94/klips/net/ipsec/ext/ipsec_ext_serpent.c	Wed Dec 31 21:00:00 1969
+++ freeswan-1.94.jjo/klips/net/ipsec/ext/ipsec_ext_serpent.c	Mon Dec 17 20:07:30 2001
@@ -0,0 +1,126 @@
+/*
+ * ipsec_ext SERPENT cipher stubs
+ *
+ * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
+ * 
+ * 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.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ * 
+ * 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.
+ *
+ */
+#include <linux/config.h>
+#include <linux/version.h>
+
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <linux/kernel.h> /* printk() */
+#include <kversions.h>
+#include <linux/errno.h>  /* error codes */
+#include <linux/types.h>  /* size_t */
+#include <linux/string.h>
+
+/* Check if __exit is defined, if not null it */
+#ifndef __exit
+#define __exit
+#endif
+
+/*	Low freeswan header coupling	*/
+#include "ipsec_ext.h"
+#include "libserpent/serpent.h"
+#include "libserpent/cbc_serpent.h"
+
+#define ESP_SERPENT		252	/* from ipsec drafts */
+
+#define ESP_SERPENT_KEY_SZ	16 	/* 128 bit secret key */
+#define ESP_SERPENT_CBC_BLK_LEN	16	/* SERPENT-CBC block size */
+
+static int debug=0;
+MODULE_PARM(debug, "i");
+static int test=0;
+MODULE_PARM(test, "i");
+static int keyminbits=0;
+MODULE_PARM(keyminbits, "i");
+static int keymaxbits=0;
+MODULE_PARM(keymaxbits, "i");
+
+struct esp_serpent
+{
+	__u32   esp_spi;			/* Security Parameters Index */
+	__u32   esp_rpl;			/* Replay counter */
+	__u8    esp_iv[ESP_SERPENT_CBC_BLK_LEN];	/* iv */
+};
+struct serpent_eks{
+	serpent_context	serpent_ctx;
+};
+static int _serpent_set_key(caddr_t key_e, caddr_t key, int keysize) {
+	serpent_context *serpent_ctx_p=&((struct serpent_eks*)key_e)->serpent_ctx;
+	if (debug > 0)
+		printk(KERN_DEBUG "klips_debug:_serpent_set_key:"
+				"key_e=%p key=%p keysize=%d\n",
+				key_e, key, keysize);
+	serpent_set_key(serpent_ctx_p, (const u4byte *)key,  keysize);
+	return 0;
+}
+static int _serpent_cbc_encrypt(caddr_t key_e, caddr_t in, caddr_t out, int ilen, caddr_t iv, int encrypt) {
+	serpent_context *serpent_ctx_p=&((struct serpent_eks*)key_e)->serpent_ctx;
+	if (debug > 0)
+		printk(KERN_DEBUG "klips_debug:_serpent_cbc_encrypt:"
+				"key_e=%p in=%p out=%p ilen=%d iv=%p encrypt=%d\n",
+				key_e, in, out, ilen, iv, encrypt);
+	serpent_cbc_encrypt(serpent_ctx_p, in, out, ilen, iv, encrypt);
+	return ilen;
+}
+static struct ipsec_ext ipsec_ext_SERPENT = {
+	name: 		"serpent",
+	enc_alg: 	ESP_SERPENT,
+	blocksize:	ESP_SERPENT_CBC_BLK_LEN, 
+	esphlen:	sizeof(struct esp_serpent),
+	keyminbits:	96,
+	keymaxbits:	128,
+	keysize:	16,
+	key_e_size:	sizeof(struct serpent_eks),
+	refcnt:		ATOMIC_INIT(0),
+	new_key:	NULL,
+	set_key:	_serpent_set_key,
+	cbc_encrypt:	_serpent_cbc_encrypt,
+	support_p:	NULL,
+};
+	
+static int __init ipsec_serpent_init(void)
+{
+	int ret, test_ret;
+	if (keyminbits)
+		ipsec_ext_SERPENT.keyminbits=keyminbits;
+	if (keymaxbits) {
+		ipsec_ext_SERPENT.keymaxbits=keymaxbits;
+		if (keymaxbits*8>ipsec_ext_SERPENT.keymaxbits)
+			ipsec_ext_SERPENT.keysize=keymaxbits*8;
+	}
+	ret=register_ipsec_ext(&ipsec_ext_SERPENT);
+	printk(__FUNCTION__ "(enc_alg=%d name=%s): ret=%d\n", 
+			ipsec_ext_SERPENT.enc_alg, ipsec_ext_SERPENT.name, ret);
+	if (test) {
+		test_ret=ipsec_ext_test(ipsec_ext_SERPENT.enc_alg, test);
+		printk(__FUNCTION__ "(enc_alg=%d): test_ret=%d\n", 
+				ipsec_ext_SERPENT.enc_alg, test_ret);
+	}
+	return ret;
+}
+static void __exit ipsec_serpent_fini(void)
+{
+	unregister_ipsec_ext(&ipsec_ext_SERPENT);
+	return;
+}
+#ifdef MODULE_LICENSE
+MODULE_LICENSE("GPL");
+#endif
+
+module_init(ipsec_serpent_init);
+module_exit(ipsec_serpent_fini);
--- freeswan-1.94/klips/net/ipsec/ext/libserpent/serpent.c	Wed Dec 31 21:00:00 1969
+++ freeswan-1.94.jjo/klips/net/ipsec/ext/libserpent/serpent.c	Thu Dec 13 11:02:25 2001
@@ -0,0 +1,667 @@
+
+/* This is an independent implementation of the encryption algorithm:   */
+/*                                                                      */
+/*         Serpent by Ross Anderson, Eli Biham and Lars Knudsen         */
+/*                                                                      */
+/* which is a candidate algorithm in the Advanced Encryption Standard   */
+/* programme of the US National Institute of Standards and Technology.  */
+/*                                                                      */
+/* Copyright in this implementation is held by Dr B R Gladman but I     */
+/* hereby give permission for its free direct or derivative use subject */
+/* to acknowledgment of its origin and compliance with any conditions   */
+/* that the originators of the algorithm place on its exploitation.     */
+/*                                                                      */
+/* Dr Brian Gladman (gladman@seven77.demon.co.uk) 14th January 1999     */
+
+/* Timing data for Serpent (serpent.c)
+
+Core timing without I/O endian conversion:
+
+128 bit key:
+Key Setup:    2402 cycles
+Encrypt:       952 cycles =    26.9 mbits/sec
+Decrypt:       914 cycles =    28.0 mbits/sec
+Mean:          933 cycles =    27.4 mbits/sec
+
+192 bit key:
+Key Setup:    2449 cycles
+Encrypt:       952 cycles =    26.9 mbits/sec
+Decrypt:       914 cycles =    28.0 mbits/sec
+Mean:          933 cycles =    27.4 mbits/sec
+
+256 bit key:
+Key Setup:    2349 cycles
+Encrypt:       952 cycles =    26.9 mbits/sec
+Decrypt:       914 cycles =    28.0 mbits/sec
+Mean:          933 cycles =    27.4 mbits/sec
+
+Full timing with I/O endian conversion:
+
+128 bit key:
+Key Setup:    2415 cycles
+Encrypt:       985 cycles =    26.0 mbits/sec
+Decrypt:       954 cycles =    26.8 mbits/sec
+Mean:          970 cycles =    26.4 mbits/sec
+
+192 bit key:
+Key Setup:    2438 cycles
+Encrypt:       985 cycles =    26.0 mbits/sec
+Decrypt:       954 cycles =    26.8 mbits/sec
+Mean:          970 cycles =    26.4 mbits/sec
+
+256 bit key:
+Key Setup:    2463 cycles
+Encrypt:       985 cycles =    26.0 mbits/sec
+Decrypt:       954 cycles =    26.8 mbits/sec
+Mean:          970 cycles =    26.4 mbits/sec
+
+*/
+
+#include "serpent.h"
+/*
+#include <linux/wordops.h>
+#include <linux/byteorder/swab.h>
+#define rotr	generic_rotr32
+#define rotl	generic_rotl32
+#define bswap	swab32
+*/
+#define rotr(x,n)   (((x) >> ((int)(n))) | ((x) << (32 - (int)(n))))
+#define rotl(x,n)   (((x) << ((int)(n))) | ((x) >> (32 - (int)(n))))
+#define bswap(x)    (rotl(x, 8) & 0x00ff00ff | rotr(x, 8) & 0xff00ff00)
+/* Extract byte from a 32 bit quantity (little endian notation)     */ 
+#define byte(x,n)   ((u1byte)((x) >> (8 * n)))
+
+/* 	un-globalize these variables */
+#define l_key ctx->l_key
+
+#undef BLOCK_SWAP
+
+#ifdef CORE_TIME
+#  undef    BLOCK_SWAP
+#endif
+
+/* Partially optimised Serpent S Box boolean functions derived  */
+/* using a recursive descent analyser but without a full search */
+/* of all subtrees. This set of S boxes is the result of work   */
+/* by Sam Simpson and Brian Gladman using the spare time on a   */
+/* cluster of high capacity servers to search for S boxes with  */
+/* this customised search engine.                               */
+/*                                                              */
+/* Copyright:   Dr B. R Gladman (gladman@seven77.demon.co.uk)   */
+/*              and Sam Simpson (s.simpson@mia.co.uk)           */ 
+/*              17th December 1998                              */
+/*                                                              */
+/* We hereby give permission for information in this file to be */
+/* used freely subject only to acknowledgement of its origin    */
+
+/* 15 terms */
+
+#define sb0(a,b,c,d,e,f,g,h)    \
+    t1 = a ^ d;     \
+    t2 = a & d;     \
+    t3 = c ^ t1;    \
+    t6 = b & t1;    \
+    t4 = b ^ t3;    \
+    t10 = ~t3;      \
+    h = t2 ^ t4;    \
+    t7 = a ^ t6;    \
+    t14 = ~t7;      \
+    t8 = c | t7;    \
+    t11 = t3 ^ t7;  \
+    g = t4 ^ t8;    \
+    t12 = h & t11;  \
+    f = t10 ^ t12;  \
+    e = t12 ^ t14
+
+/* 15 terms */
+
+#define ib0(a,b,c,d,e,f,g,h)    \
+    t1 = ~a;        \
+    t2 = a ^ b;     \
+    t3 = t1 | t2;   \
+    t4 = d ^ t3;    \
+    t7 = d & t2;    \
+    t5 = c ^ t4;    \
+    t8 = t1 ^ t7;   \
+    g = t2 ^ t5;    \
+    t11 = a & t4;   \
+    t9 = g & t8;    \
+    t14 = t5 ^ t8;  \
+    f = t4 ^ t9;    \
+    t12 = t5 | f;   \
+    h = t11 ^ t12;  \
+    e = h ^ t14
+
+/* 14 terms!  */
+
+#define sb1(a,b,c,d,e,f,g,h)    \
+    t1 = ~a;        \
+    t2 = b ^ t1;    \
+    t3 = a | t2;    \
+    t4 = d | t2;    \
+    t5 = c ^ t3;    \
+    g = d ^ t5;     \
+    t7 = b ^ t4;    \
+    t8 = t2 ^ g;    \
+    t9 = t5 & t7;   \
+    h = t8 ^ t9;    \
+    t11 = t5 ^ t7;  \
+    f = h ^ t11;    \
+    t13 = t8 & t11; \
+    e = t5 ^ t13
+
+/* 17 terms */
+
+#define ib1(a,b,c,d,e,f,g,h)    \
+    t1 = a ^ d;     \
+    t2 = a & b;     \
+    t3 = b ^ c;     \
+    t4 = a ^ t3;    \
+    t5 = b | d;     \
+    t7 = c | t1;    \
+    h = t4 ^ t5;    \
+    t8 = b ^ t7;    \
+    t11 = ~t2;      \
+    t9 = t4 & t8;   \
+    f = t1 ^ t9;    \
+    t13 = t9 ^ t11; \
+    t12 = h & f;    \
+    g = t12 ^ t13;  \
+    t15 = a & d;    \
+    t16 = c ^ t13;  \
+    e = t15 ^ t16
+
+/* 16 terms */
+
+#define sb2(a,b,c,d,e,f,g,h)    \
+    t1 = ~a;        \
+    t2 = b ^ d;     \
+    t3 = c & t1;    \
+    t13 = d | t1;   \
+    e = t2 ^ t3;    \
+    t5 = c ^ t1;    \
+    t6 = c ^ e;     \
+    t7 = b & t6;    \
+    t10 = e | t5;   \
+    h = t5 ^ t7;    \
+    t9 = d | t7;    \
+    t11 = t9 & t10; \
+    t14 = t2 ^ h;   \
+    g = a ^ t11;    \
+    t15 = g ^ t13;  \
+    f = t14 ^ t15
+
+/* 16 terms */
+
+#define ib2(a,b,c,d,e,f,g,h)    \
+    t1 = b ^ d;     \
+    t2 = ~t1;       \
+    t3 = a ^ c;     \
+    t4 = c ^ t1;    \
+    t7 = a | t2;    \
+    t5 = b & t4;    \
+    t8 = d ^ t7;    \
+    t11 = ~t4;      \
+    e = t3 ^ t5;    \
+    t9 = t3 | t8;   \
+    t14 = d & t11;  \
+    h = t1 ^ t9;    \
+    t12 = e | h;    \
+    f = t11 ^ t12;  \
+    t15 = t3 ^ t12; \
+    g = t14 ^ t15
+
+/* 17 terms */
+
+#define sb3(a,b,c,d,e,f,g,h)    \
+    t1 = a ^ c;     \
+    t2 = d ^ t1;    \
+    t3 = a & t2;    \
+    t4 = d ^ t3;    \
+    t5 = b & t4;    \
+    g = t2 ^ t5;    \
+    t7 = a | g;     \
+    t8 = b | d;     \
+    t11 = a | d;    \
+    t9 = t4 & t7;   \
+    f = t8 ^ t9;    \
+    t12 = b ^ t11;  \
+    t13 = g ^ t9;   \
+    t15 = t3 ^ t8;  \
+    h = t12 ^ t13;  \
+    t16 = c & t15;  \
+    e = t12 ^ t16
+
+/* 16 term solution that performs less well than 17 term one
+   in my environment (PPro/PII)                                  
+
+#define sb3(a,b,c,d,e,f,g,h)    \
+    t1 = a ^ b;     \
+    t2 = a & c;     \
+    t3 = a | d;     \
+    t4 = c ^ d;     \
+    t5 = t1 & t3;   \
+    t6 = t2 | t5;   \
+    g = t4 ^ t6;    \
+    t8 = b ^ t3;    \
+    t9 = t6 ^ t8;   \
+    t10 = t4 & t9;  \
+    e = t1 ^ t10;   \
+    t12 = g & e;    \
+    f = t9 ^ t12;   \
+    t14 = b | d;    \
+    t15 = t4 ^ t12; \
+    h = t14 ^ t15
+*/
+
+/* 17 terms */
+
+#define ib3(a,b,c,d,e,f,g,h)    \
+    t1 = b ^ c;     \
+    t2 = b | c;     \
+    t3 = a ^ c;     \
+    t7 = a ^ d;     \
+    t4 = t2 ^ t3;   \
+    t5 = d | t4;    \
+    t9 = t2 ^ t7;   \
+    e = t1 ^ t5;    \
+    t8 = t1 | t5;   \
+    t11 = a & t4;   \
+    g = t8 ^ t9;    \
+    t12 = e | t9;   \
+    f = t11 ^ t12;  \
+    t14 = a & g;    \
+    t15 = t2 ^ t14; \
+    t16 = e & t15;  \
+    h = t4 ^ t16
+
+/* 15 terms */
+
+#define sb4(a,b,c,d,e,f,g,h)    \
+    t1 = a ^ d;     \
+    t2 = d & t1;    \
+    t3 = c ^ t2;    \
+    t4 = b | t3;    \
+    h = t1 ^ t4;    \
+    t6 = ~b;        \
+    t7 = t1 | t6;   \
+    e = t3 ^ t7;    \
+    t9 = a & e;     \
+    t10 = t1 ^ t6;  \
+    t11 = t4 & t10; \
+    g = t9 ^ t11;   \
+    t13 = a ^ t3;   \
+    t14 = t10 & g;  \
+    f = t13 ^ t14
+
+/* 17 terms */
+
+#define ib4(a,b,c,d,e,f,g,h)    \
+    t1 = c ^ d;     \
+    t2 = c | d;     \
+    t3 = b ^ t2;    \
+    t4 = a & t3;    \
+    f = t1 ^ t4;    \
+    t6 = a ^ d;     \
+    t7 = b | d;     \
+    t8 = t6 & t7;   \
+    h = t3 ^ t8;    \
+    t10 = ~a;       \
+    t11 = c ^ h;    \
+    t12 = t10 | t11;\
+    e = t3 ^ t12;   \
+    t14 = c | t4;   \
+    t15 = t7 ^ t14; \
+    t16 = h | t10;  \
+    g = t15 ^ t16
+
+/* 16 terms */
+
+#define sb5(a,b,c,d,e,f,g,h)    \
+    t1 = ~a;        \
+    t2 = a ^ b;     \
+    t3 = a ^ d;     \
+    t4 = c ^ t1;    \
+    t5 = t2 | t3;   \
+    e = t4 ^ t5;    \
+    t7 = d & e;     \
+    t8 = t2 ^ e;    \
+    t10 = t1 | e;   \
+    f = t7 ^ t8;    \
+    t11 = t2 | t7;  \
+    t12 = t3 ^ t10; \
+    t14 = b ^ t7;   \
+    g = t11 ^ t12;  \
+    t15 = f & t12;  \
+    h = t14 ^ t15
+
+/* 16 terms */
+
+#define ib5(a,b,c,d,e,f,g,h)    \
+    t1 = ~c;        \
+    t2 = b & t1;    \
+    t3 = d ^ t2;    \
+    t4 = a & t3;    \
+    t5 = b ^ t1;    \
+    h = t4 ^ t5;    \
+    t7 = b | h;     \
+    t8 = a & t7;    \
+    f = t3 ^ t8;    \
+    t10 = a | d;    \
+    t11 = t1 ^ t7;  \
+    e = t10 ^ t11;  \
+    t13 = a ^ c;    \
+    t14 = b & t10;  \
+    t15 = t4 | t13; \
+    g = t14 ^ t15
+
+/* 15 terms */
+
+#define sb6(a,b,c,d,e,f,g,h)    \
+    t1 = ~a;        \
+    t2 = a ^ d;     \
+    t3 = b ^ t2;    \
+    t4 = t1 | t2;   \
+    t5 = c ^ t4;    \
+    f = b ^ t5;     \
+    t13 = ~t5;      \
+    t7 = t2 | f;    \
+    t8 = d ^ t7;    \
+    t9 = t5 & t8;   \
+    g = t3 ^ t9;    \
+    t11 = t5 ^ t8;  \
+    e = g ^ t11;    \
+    t14 = t3 & t11; \
+    h = t13 ^ t14
+
+/* 15 terms */
+
+#define ib6(a,b,c,d,e,f,g,h)    \
+    t1 = ~a;        \
+    t2 = a ^ b;     \
+    t3 = c ^ t2;    \
+    t4 = c | t1;    \
+    t5 = d ^ t4;    \
+    t13 = d & t1;   \
+    f = t3 ^ t5;    \
+    t7 = t3 & t5;   \
+    t8 = t2 ^ t7;   \
+    t9 = b | t8;    \
+    h = t5 ^ t9;    \
+    t11 = b | h;    \
+    e = t8 ^ t11;   \
+    t14 = t3 ^ t11; \
+    g = t13 ^ t14
+
+/* 17 terms */
+
+#define sb7(a,b,c,d,e,f,g,h)    \
+    t1 = ~c;        \
+    t2 = b ^ c;     \
+    t3 = b | t1;    \
+    t4 = d ^ t3;    \
+    t5 = a & t4;    \
+    t7 = a ^ d;     \
+    h = t2 ^ t5;    \
+    t8 = b ^ t5;    \
+    t9 = t2 | t8;   \
+    t11 = d & t3;   \
+    f = t7 ^ t9;    \
+    t12 = t5 ^ f;   \
+    t15 = t1 | t4;  \
+    t13 = h & t12;  \
+    g = t11 ^ t13;  \
+    t16 = t12 ^ g;  \
+    e = t15 ^ t16
+
+/* 17 terms */
+
+#define ib7(a,b,c,d,e,f,g,h)    \
+    t1 = a & b;     \
+    t2 = a | b;     \
+    t3 = c | t1;    \
+    t4 = d & t2;    \
+    h = t3 ^ t4;    \
+    t6 = ~d;        \
+    t7 = b ^ t4;    \
+    t8 = h ^ t6;    \
+    t11 = c ^ t7;   \
+    t9 = t7 | t8;   \
+    f = a ^ t9;     \
+    t12 = d | f;    \
+    e = t11 ^ t12;  \
+    t14 = a & h;    \
+    t15 = t3 ^ f;   \
+    t16 = e ^ t14;  \
+    g = t15 ^ t16
+
+#define k_xor(r,a,b,c,d)    \
+    a ^= l_key[4 * r +  8]; \
+    b ^= l_key[4 * r +  9]; \
+    c ^= l_key[4 * r + 10]; \
+    d ^= l_key[4 * r + 11]
+
+#define k_set(r,a,b,c,d)    \
+    a = l_key[4 * r +  8];  \
+    b = l_key[4 * r +  9];  \
+    c = l_key[4 * r + 10];  \
+    d = l_key[4 * r + 11]
+
+#define k_get(r,a,b,c,d)    \
+    l_key[4 * r +  8] = a;  \
+    l_key[4 * r +  9] = b;  \
+    l_key[4 * r + 10] = c;  \
+    l_key[4 * r + 11] = d
+
+/* the linear transformation and its inverse    */
+
+#define rot(a,b,c,d)    \
+    a = rotl(a, 13);    \
+    c = rotl(c, 3);     \
+    d ^= c ^ (a << 3);  \
+    b ^= a ^ c;         \
+    d = rotl(d, 7);     \
+    b = rotl(b, 1);     \
+    a ^= b ^ d;         \
+    c ^= d ^ (b << 7);  \
+    a = rotl(a, 5);     \
+    c = rotl(c, 22)
+
+#define irot(a,b,c,d)   \
+    c = rotr(c, 22);    \
+    a = rotr(a, 5);     \
+    c ^= d ^ (b << 7);  \
+    a ^= b ^ d;         \
+    d = rotr(d, 7);     \
+    b = rotr(b, 1);     \
+    d ^= c ^ (a << 3);  \
+    b ^= a ^ c;         \
+    c = rotr(c, 3);     \
+    a = rotr(a, 13)
+
+
+/* initialise the key schedule from the user supplied key   */
+
+u4byte *serpent_set_key(serpent_context *ctx, const u4byte in_key[], const u4byte key_len)
+{   u4byte  i,lk,a,b,c,d,e,f,g,h;
+    u4byte  t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16;
+
+    if(key_len < 0 || key_len > 256)
+
+        return (u4byte*)0;
+
+    i = 0; lk = (key_len + 31) / 32;
+    
+    while(i < lk)
+    {
+#ifdef  BLOCK_SWAP
+        l_key[i] = io_swap(in_key[lk - i - 1]);
+#else
+        l_key[i] = in_key[i];
+#endif  
+        i++;
+    }
+
+    if(key_len < 256)
+    {
+        while(i < 8)
+
+            l_key[i++] = 0;
+
+        i = key_len / 32; lk = 1 << key_len % 32; 
+
+        l_key[i] = (l_key[i] & (lk - 1)) | lk;
+    }
+
+    for(i = 0; i < 132; ++i)
+    {
+        lk = l_key[i] ^ l_key[i + 3] ^ l_key[i + 5] 
+                                ^ l_key[i + 7] ^ 0x9e3779b9 ^ i;
+
+        l_key[i + 8] = (lk << 11) | (lk >> 21); 
+    }
+
+    k_set( 0,a,b,c,d);sb3(a,b,c,d,e,f,g,h);k_get( 0,e,f,g,h);
+    k_set( 1,a,b,c,d);sb2(a,b,c,d,e,f,g,h);k_get( 1,e,f,g,h);
+    k_set( 2,a,b,c,d);sb1(a,b,c,d,e,f,g,h);k_get( 2,e,f,g,h);
+    k_set( 3,a,b,c,d);sb0(a,b,c,d,e,f,g,h);k_get( 3,e,f,g,h);
+    k_set( 4,a,b,c,d);sb7(a,b,c,d,e,f,g,h);k_get( 4,e,f,g,h);
+    k_set( 5,a,b,c,d);sb6(a,b,c,d,e,f,g,h);k_get( 5,e,f,g,h);
+    k_set( 6,a,b,c,d);sb5(a,b,c,d,e,f,g,h);k_get( 6,e,f,g,h);
+    k_set( 7,a,b,c,d);sb4(a,b,c,d,e,f,g,h);k_get( 7,e,f,g,h);
+    k_set( 8,a,b,c,d);sb3(a,b,c,d,e,f,g,h);k_get( 8,e,f,g,h);
+    k_set( 9,a,b,c,d);sb2(a,b,c,d,e,f,g,h);k_get( 9,e,f,g,h);
+    k_set(10,a,b,c,d);sb1(a,b,c,d,e,f,g,h);k_get(10,e,f,g,h);
+    k_set(11,a,b,c,d);sb0(a,b,c,d,e,f,g,h);k_get(11,e,f,g,h);
+    k_set(12,a,b,c,d);sb7(a,b,c,d,e,f,g,h);k_get(12,e,f,g,h);
+    k_set(13,a,b,c,d);sb6(a,b,c,d,e,f,g,h);k_get(13,e,f,g,h);
+    k_set(14,a,b,c,d);sb5(a,b,c,d,e,f,g,h);k_get(14,e,f,g,h);
+    k_set(15,a,b,c,d);sb4(a,b,c,d,e,f,g,h);k_get(15,e,f,g,h);
+    k_set(16,a,b,c,d);sb3(a,b,c,d,e,f,g,h);k_get(16,e,f,g,h);
+    k_set(17,a,b,c,d);sb2(a,b,c,d,e,f,g,h);k_get(17,e,f,g,h);
+    k_set(18,a,b,c,d);sb1(a,b,c,d,e,f,g,h);k_get(18,e,f,g,h);
+    k_set(19,a,b,c,d);sb0(a,b,c,d,e,f,g,h);k_get(19,e,f,g,h);
+    k_set(20,a,b,c,d);sb7(a,b,c,d,e,f,g,h);k_get(20,e,f,g,h);
+    k_set(21,a,b,c,d);sb6(a,b,c,d,e,f,g,h);k_get(21,e,f,g,h);
+    k_set(22,a,b,c,d);sb5(a,b,c,d,e,f,g,h);k_get(22,e,f,g,h);
+    k_set(23,a,b,c,d);sb4(a,b,c,d,e,f,g,h);k_get(23,e,f,g,h);
+    k_set(24,a,b,c,d);sb3(a,b,c,d,e,f,g,h);k_get(24,e,f,g,h);
+    k_set(25,a,b,c,d);sb2(a,b,c,d,e,f,g,h);k_get(25,e,f,g,h);
+    k_set(26,a,b,c,d);sb1(a,b,c,d,e,f,g,h);k_get(26,e,f,g,h);
+    k_set(27,a,b,c,d);sb0(a,b,c,d,e,f,g,h);k_get(27,e,f,g,h);
+    k_set(28,a,b,c,d);sb7(a,b,c,d,e,f,g,h);k_get(28,e,f,g,h);
+    k_set(29,a,b,c,d);sb6(a,b,c,d,e,f,g,h);k_get(29,e,f,g,h);
+    k_set(30,a,b,c,d);sb5(a,b,c,d,e,f,g,h);k_get(30,e,f,g,h);
+    k_set(31,a,b,c,d);sb4(a,b,c,d,e,f,g,h);k_get(31,e,f,g,h);
+    k_set(32,a,b,c,d);sb3(a,b,c,d,e,f,g,h);k_get(32,e,f,g,h);
+
+    return l_key;
+};
+
+/* encrypt a block of text  */
+
+void serpent_encrypt(serpent_context *ctx, const u4byte in_blk[4], u4byte out_blk[])
+{   u4byte  a,b,c,d,e,f,g,h;
+    u4byte  t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16;
+    
+#ifdef  BLOCK_SWAP
+    a = io_swap(in_blk[3]); b = io_swap(in_blk[2]); 
+    c = io_swap(in_blk[1]); d = io_swap(in_blk[0]);
+#else
+    a = in_blk[0]; b = in_blk[1]; c = in_blk[2]; d = in_blk[3];
+#endif
+
+    k_xor( 0,a,b,c,d); sb0(a,b,c,d,e,f,g,h); rot(e,f,g,h); 
+    k_xor( 1,e,f,g,h); sb1(e,f,g,h,a,b,c,d); rot(a,b,c,d); 
+    k_xor( 2,a,b,c,d); sb2(a,b,c,d,e,f,g,h); rot(e,f,g,h); 
+    k_xor( 3,e,f,g,h); sb3(e,f,g,h,a,b,c,d); rot(a,b,c,d); 
+    k_xor( 4,a,b,c,d); sb4(a,b,c,d,e,f,g,h); rot(e,f,g,h); 
+    k_xor( 5,e,f,g,h); sb5(e,f,g,h,a,b,c,d); rot(a,b,c,d); 
+    k_xor( 6,a,b,c,d); sb6(a,b,c,d,e,f,g,h); rot(e,f,g,h); 
+    k_xor( 7,e,f,g,h); sb7(e,f,g,h,a,b,c,d); rot(a,b,c,d); 
+    k_xor( 8,a,b,c,d); sb0(a,b,c,d,e,f,g,h); rot(e,f,g,h); 
+    k_xor( 9,e,f,g,h); sb1(e,f,g,h,a,b,c,d); rot(a,b,c,d); 
+    k_xor(10,a,b,c,d); sb2(a,b,c,d,e,f,g,h); rot(e,f,g,h); 
+    k_xor(11,e,f,g,h); sb3(e,f,g,h,a,b,c,d); rot(a,b,c,d); 
+    k_xor(12,a,b,c,d); sb4(a,b,c,d,e,f,g,h); rot(e,f,g,h); 
+    k_xor(13,e,f,g,h); sb5(e,f,g,h,a,b,c,d); rot(a,b,c,d); 
+    k_xor(14,a,b,c,d); sb6(a,b,c,d,e,f,g,h); rot(e,f,g,h); 
+    k_xor(15,e,f,g,h); sb7(e,f,g,h,a,b,c,d); rot(a,b,c,d); 
+    k_xor(16,a,b,c,d); sb0(a,b,c,d,e,f,g,h); rot(e,f,g,h); 
+    k_xor(17,e,f,g,h); sb1(e,f,g,h,a,b,c,d); rot(a,b,c,d); 
+    k_xor(18,a,b,c,d); sb2(a,b,c,d,e,f,g,h); rot(e,f,g,h); 
+    k_xor(19,e,f,g,h); sb3(e,f,g,h,a,b,c,d); rot(a,b,c,d); 
+    k_xor(20,a,b,c,d); sb4(a,b,c,d,e,f,g,h); rot(e,f,g,h); 
+    k_xor(21,e,f,g,h); sb5(e,f,g,h,a,b,c,d); rot(a,b,c,d); 
+    k_xor(22,a,b,c,d); sb6(a,b,c,d,e,f,g,h); rot(e,f,g,h); 
+    k_xor(23,e,f,g,h); sb7(e,f,g,h,a,b,c,d); rot(a,b,c,d); 
+    k_xor(24,a,b,c,d); sb0(a,b,c,d,e,f,g,h); rot(e,f,g,h); 
+    k_xor(25,e,f,g,h); sb1(e,f,g,h,a,b,c,d); rot(a,b,c,d); 
+    k_xor(26,a,b,c,d); sb2(a,b,c,d,e,f,g,h); rot(e,f,g,h); 
+    k_xor(27,e,f,g,h); sb3(e,f,g,h,a,b,c,d); rot(a,b,c,d); 
+    k_xor(28,a,b,c,d); sb4(a,b,c,d,e,f,g,h); rot(e,f,g,h); 
+    k_xor(29,e,f,g,h); sb5(e,f,g,h,a,b,c,d); rot(a,b,c,d); 
+    k_xor(30,a,b,c,d); sb6(a,b,c,d,e,f,g,h); rot(e,f,g,h); 
+    k_xor(31,e,f,g,h); sb7(e,f,g,h,a,b,c,d); k_xor(32,a,b,c,d); 
+    
+#ifdef  BLOCK_SWAP
+    out_blk[3] = io_swap(a); out_blk[2] = io_swap(b); 
+    out_blk[1] = io_swap(c); out_blk[0] = io_swap(d);
+#else
+    out_blk[0] = a; out_blk[1] = b; out_blk[2] = c; out_blk[3] = d;
+#endif
+};
+
+/* decrypt a block of text  */
+
+void serpent_decrypt(serpent_context *ctx, const u4byte in_blk[4], u4byte out_blk[4])
+{   u4byte  a,b,c,d,e,f,g,h;
+    u4byte  t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16;
+    
+#ifdef  BLOCK_SWAP
+    a = io_swap(in_blk[3]); b = io_swap(in_blk[2]); 
+    c = io_swap(in_blk[1]); d = io_swap(in_blk[0]);
+#else
+    a = in_blk[0]; b = in_blk[1]; c = in_blk[2]; d = in_blk[3];
+#endif
+
+    k_xor(32,a,b,c,d); ib7(a,b,c,d,e,f,g,h); k_xor(31,e,f,g,h);
+    irot(e,f,g,h); ib6(e,f,g,h,a,b,c,d); k_xor(30,a,b,c,d);
+    irot(a,b,c,d); ib5(a,b,c,d,e,f,g,h); k_xor(29,e,f,g,h);
+    irot(e,f,g,h); ib4(e,f,g,h,a,b,c,d); k_xor(28,a,b,c,d);
+    irot(a,b,c,d); ib3(a,b,c,d,e,f,g,h); k_xor(27,e,f,g,h);
+    irot(e,f,g,h); ib2(e,f,g,h,a,b,c,d); k_xor(26,a,b,c,d);
+    irot(a,b,c,d); ib1(a,b,c,d,e,f,g,h); k_xor(25,e,f,g,h);
+    irot(e,f,g,h); ib0(e,f,g,h,a,b,c,d); k_xor(24,a,b,c,d);
+    irot(a,b,c,d); ib7(a,b,c,d,e,f,g,h); k_xor(23,e,f,g,h);
+    irot(e,f,g,h); ib6(e,f,g,h,a,b,c,d); k_xor(22,a,b,c,d);
+    irot(a,b,c,d); ib5(a,b,c,d,e,f,g,h); k_xor(21,e,f,g,h);
+    irot(e,f,g,h); ib4(e,f,g,h,a,b,c,d); k_xor(20,a,b,c,d);
+    irot(a,b,c,d); ib3(a,b,c,d,e,f,g,h); k_xor(19,e,f,g,h);
+    irot(e,f,g,h); ib2(e,f,g,h,a,b,c,d); k_xor(18,a,b,c,d);
+    irot(a,b,c,d); ib1(a,b,c,d,e,f,g,h); k_xor(17,e,f,g,h);
+    irot(e,f,g,h); ib0(e,f,g,h,a,b,c,d); k_xor(16,a,b,c,d);
+    irot(a,b,c,d); ib7(a,b,c,d,e,f,g,h); k_xor(15,e,f,g,h);
+    irot(e,f,g,h); ib6(e,f,g,h,a,b,c,d); k_xor(14,a,b,c,d);
+    irot(a,b,c,d); ib5(a,b,c,d,e,f,g,h); k_xor(13,e,f,g,h);
+    irot(e,f,g,h); ib4(e,f,g,h,a,b,c,d); k_xor(12,a,b,c,d);
+    irot(a,b,c,d); ib3(a,b,c,d,e,f,g,h); k_xor(11,e,f,g,h);
+    irot(e,f,g,h); ib2(e,f,g,h,a,b,c,d); k_xor(10,a,b,c,d);
+    irot(a,b,c,d); ib1(a,b,c,d,e,f,g,h); k_xor( 9,e,f,g,h);
+    irot(e,f,g,h); ib0(e,f,g,h,a,b,c,d); k_xor( 8,a,b,c,d);
+    irot(a,b,c,d); ib7(a,b,c,d,e,f,g,h); k_xor( 7,e,f,g,h);
+    irot(e,f,g,h); ib6(e,f,g,h,a,b,c,d); k_xor( 6,a,b,c,d);
+    irot(a,b,c,d); ib5(a,b,c,d,e,f,g,h); k_xor( 5,e,f,g,h);
+    irot(e,f,g,h); ib4(e,f,g,h,a,b,c,d); k_xor( 4,a,b,c,d);
+    irot(a,b,c,d); ib3(a,b,c,d,e,f,g,h); k_xor( 3,e,f,g,h);
+    irot(e,f,g,h); ib2(e,f,g,h,a,b,c,d); k_xor( 2,a,b,c,d);
+    irot(a,b,c,d); ib1(a,b,c,d,e,f,g,h); k_xor( 1,e,f,g,h);
+    irot(e,f,g,h); ib0(e,f,g,h,a,b,c,d); k_xor( 0,a,b,c,d);
+    
+#ifdef  BLOCK_SWAP
+    out_blk[3] = io_swap(a); out_blk[2] = io_swap(b); 
+    out_blk[1] = io_swap(c); out_blk[0] = io_swap(d);
+#else
+    out_blk[0] = a; out_blk[1] = b; out_blk[2] = c; out_blk[3] = d;
+#endif
+};
--- freeswan-1.94/klips/net/ipsec/ext/libserpent/Makefile	Wed Dec 31 21:00:00 1969
+++ freeswan-1.94.jjo/klips/net/ipsec/ext/libserpent/Makefile	Thu Dec 13 12:12:05 2001
@@ -0,0 +1,18 @@
+ifndef CFLAGS
+CFLAGS=-Wall -O3 -omit-frame-pointer -I../../../../../lib -I../../libfreeswan $(EXTRA_CFLAGS) -I/usr/src/linux/include
+endif
+LIBOBJ=serpent.o cbc_serpent.o
+BLIB=libserpent.a
+
+$(BLIB): $(LIBOBJ)
+	/bin/rm -f $(BLIB)
+	ar cr $(BLIB) $(LIBOBJ)
+	-if test -s /bin/ranlib; then /bin/ranlib $(BLIB); \
+	else if test -s /usr/bin/ranlib; then /usr/bin/ranlib $(BLIB); \
+	else exit 0; fi; fi
+
+test: test_main.o $(BLIB)
+	$(CC) -o $@ $^ 
+
+clean:
+	rm -f *.[oa] core $(TARGET) test
--- freeswan-1.94/klips/net/ipsec/ext/libserpent/test_main.c	Wed Dec 31 21:00:00 1969
+++ freeswan-1.94.jjo/klips/net/ipsec/ext/libserpent/test_main.c	Thu Dec 13 10:52:17 2001
@@ -0,0 +1,34 @@
+#include <stdio.h>
+#include <string.h>
+#include "cbc_serpent.h"
+#define BLOCK_SIZE	16
+#define KEY_SIZE 	128	/* bits */
+#define KEY 		"1234567890123456"
+#define STR 		"hola guaso como estaisss ... 012"
+#define STRSZ		(sizeof(STR)-1)
+
+#define BLKLEN 		BLOCK_SIZE
+#define CONTEXT_T  	serpent_context
+static int pretty_print(const unsigned char *buf, int count) {
+	int i=0;
+	for (;i<count;i++) printf ("%02hhx ", buf[i]);
+	putchar('\n');
+	return i;
+}
+//#define SIZE STRSZ/2
+#define SIZE STRSZ
+int main() {
+	int ret;
+	char buf0[SIZE+1], buf1[SIZE+1];
+	char IV[BLOCK_SIZE];
+	CONTEXT_T ac;	
+	serpent_set_key(&ac, (void *)KEY, KEY_SIZE);
+	memset(buf0, 0, sizeof (buf0));
+	memset(buf1, 0, sizeof (buf1));
+	serpent_cbc_encrypt(&ac, STR, buf0, SIZE, IV, 1);
+	pretty_print(buf0, SIZE);
+	printf("size=%d ret=%d\n%s\n", SIZE, ret, buf0);
+	ret=serpent_cbc_encrypt(&ac, buf0, buf1, SIZE, IV, 0);
+	printf("size=%d ret=%d\n%s\n", SIZE, ret, buf1);
+	return 0;
+}
--- freeswan-1.94/klips/net/ipsec/ext/libserpent/cbc_serpent.c	Wed Dec 31 21:00:00 1969
+++ freeswan-1.94.jjo/klips/net/ipsec/ext/libserpent/cbc_serpent.c	Thu Dec 13 10:53:51 2001
@@ -0,0 +1,3 @@
+#include "cbc_serpent.h"
+#include "cbc_generic.h"
+CBC_IMPL_BLK16(serpent_cbc_encrypt, serpent_context, u4byte*, serpent_encrypt, serpent_decrypt);
--- freeswan-1.94/klips/net/ipsec/ext/libserpent/cbc_serpent.h	Wed Dec 31 21:00:00 1969
+++ freeswan-1.94.jjo/klips/net/ipsec/ext/libserpent/cbc_serpent.h	Thu Dec 13 10:54:08 2001
@@ -0,0 +1,3 @@
+/* Glue header */
+#include "serpent.h"
+int serpent_cbc_encrypt(serpent_context *ctx, unsigned char * in, unsigned char * out, int ilen, unsigned char * iv, int encrypt);
--- freeswan-1.94/klips/net/ipsec/ext/libserpent/serpent.h	Wed Dec 31 21:00:00 1969
+++ freeswan-1.94.jjo/klips/net/ipsec/ext/libserpent/serpent.h	Thu Dec 13 11:09:47 2001
@@ -0,0 +1,17 @@
+#ifndef SERPENT_H
+#define SERPENT_H
+#ifdef __KERNEL__
+#include <linux/types.h>
+#else
+#include <sys/types.h>
+#endif
+#define u4byte u_int32_t
+#define u1byte u_int8_t
+struct serpent_context {
+	u4byte  l_key[140]; /* storage for the key schedule         */
+};
+typedef struct serpent_context serpent_context;
+u4byte *serpent_set_key(serpent_context *ctx, const u4byte in_key[], const u4byte key_len);
+void serpent_decrypt(serpent_context *ctx, const u4byte in_blk[4], u4byte out_blk[4]);
+void serpent_encrypt(serpent_context *ctx, const u4byte in_blk[4], u4byte out_blk[]);
+#endif /* SERPENT_H */
--- freeswan-1.94.jjo/klips/net/ipsec/ext/Config.in	Sun Dec 16 10:24:55 2001
+++ freeswan-1.94.jjo/klips/net/ipsec/ext/Config.in	Sun Dec 16 10:24:52 2001
@@ -0,0 +1 @@
+source net/ipsec/ext/Config.ext_serpent.in

