Index: freeswan/libcrypto/libserpent/Makefile
diff -u /dev/null freeswan/libcrypto/libserpent/Makefile:1.1.2.2
--- /dev/null	Fri Jul 12 16:03:47 2002
+++ freeswan/libcrypto/libserpent/Makefile	Mon Jun  3 22:24:31 2002
@@ -0,0 +1,20 @@
+CFLAGS=-O3 -omit-frame-pointer -D__KERNEL__  -Wall $(EXTRA_CFLAGS)
+INC=-I../include 
+LIBOBJ=serpent.o serpent_cbc.o
+BLIB=libserpent.a
+
+.c.o:
+	$(CC) $(CPPFLAGS) $(CFLAGS) $(INC) -c $< -o $@
+
+$(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
Index: freeswan/libcrypto/libserpent/serpent.c
diff -u /dev/null freeswan/libcrypto/libserpent/serpent.c:1.1.2.2
--- /dev/null	Fri Jul 12 16:03:47 2002
+++ freeswan/libcrypto/libserpent/serpent.c	Mon Jun  3 22:24:31 2002
@@ -0,0 +1,992 @@
+
+/* Optimized implementation of the Serpent AES candidate algorithm
+ * Designed by Anderson, Biham and Knudsen and Implemented by 
+ * Gisle Sælensminde 2000. 
+ *
+ * The implementation is based on the pentium optimised sboxes of
+ * Dag Arne Osvik. Even these sboxes are designed to be optimal for x86 
+ * processors they are efficient on other processors as well, but the speedup 
+ * isn't so impressive compared to other implementations.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License
+ * as published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version. 
+ */
+
+#ifdef __KERNEL__
+#include <linux/init.h>
+#include <linux/types.h>
+
+#include <asm/byteorder.h>
+#else
+#include <sys/types.h>
+#include <asm/byteorder.h>
+#endif
+
+#include "serpent.h"
+
+#define rotl(reg, val) ((reg << val) | (reg >> (32 - val)))
+#define rotr(reg, val) ((reg >> val) | (reg << (32 - val)))
+ 
+#define io_swap(x)  __cpu_to_be32(x)
+
+#define BLOCK_SWAP
+
+/* The sbox functions. The first four parameters is the input bits, and 
+ * the last is a tempoary. These parameters are also used for output, but
+ * the bit order is permuted. The output bit order from S0 is
+ * (1 4 2 0 3), where 3 is the (now useless) tempoary. 
+ */
+
+#define S0(r0,r1,r2,r3,r4) \
+      r3 = r3 ^ r0; \
+      r4 = r1; \
+      r1 = r1 & r3; \
+      r4 = r4 ^ r2; \
+      r1 = r1 ^ r0; \
+      r0 = r0 | r3; \
+      r0 = r0 ^ r4; \
+      r4 = r4 ^ r3; \
+      r3 = r3 ^ r2; \
+      r2 = r2 | r1; \
+      r2 = r2 ^ r4; \
+      r4 = -1 ^ r4; \
+      r4 = r4 | r1; \
+      r1 = r1 ^ r3; \
+      r1 = r1 ^ r4; \
+      r3 = r3 | r0; \
+      r1 = r1 ^ r3; \
+      r4 = r4 ^ r3; 
+
+#define S1(r0,r1,r2,r3,r4) \
+      r1 = -1 ^ r1; \
+      r4 = r0; \
+      r0 = r0 ^ r1; \
+      r4 = r4 | r1; \
+      r4 = r4 ^ r3; \
+      r3 = r3 & r0; \
+      r2 = r2 ^ r4; \
+      r3 = r3 ^ r1; \
+      r3 = r3 | r2; \
+      r0 = r0 ^ r4; \
+      r3 = r3 ^ r0; \
+      r1 = r1 & r2; \
+      r0 = r0 | r1; \
+      r1 = r1 ^ r4; \
+      r0 = r0 ^ r2; \
+      r4 = r4 | r3; \
+      r0 = r0 ^ r4; \
+      r4 = -1 ^ r4; \
+      r1 = r1 ^ r3; \
+      r4 = r4 & r2; \
+      r1 = -1 ^ r1; \
+      r4 = r4 ^ r0; \
+      r1 = r1 ^ r4; 
+
+#define S2(r0,r1,r2,r3,r4) \
+      r4 = r0; \
+      r0 = r0 & r2; \
+      r0 = r0 ^ r3; \
+      r2 = r2 ^ r1; \
+      r2 = r2 ^ r0; \
+      r3 = r3 | r4; \
+      r3 = r3 ^ r1; \
+      r4 = r4 ^ r2; \
+      r1 = r3; \
+      r3 = r3 | r4; \
+      r3 = r3 ^ r0; \
+      r0 = r0 & r1; \
+      r4 = r4 ^ r0; \
+      r1 = r1 ^ r3; \
+      r1 = r1 ^ r4; \
+      r4 = -1 ^ r4; 
+
+#define S3(r0,r1,r2,r3,r4) \
+      r4 = r0 ; \
+      r0 = r0 | r3; \
+      r3 = r3 ^ r1; \
+      r1 = r1 & r4; \
+      r4 = r4 ^ r2; \
+      r2 = r2 ^ r3; \
+      r3 = r3 & r0; \
+      r4 = r4 | r1; \
+      r3 = r3 ^ r4; \
+      r0 = r0 ^ r1; \
+      r4 = r4 & r0; \
+      r1 = r1 ^ r3; \
+      r4 = r4 ^ r2; \
+      r1 = r1 | r0; \
+      r1 = r1 ^ r2; \
+      r0 = r0 ^ r3; \
+      r2 = r1; \
+      r1 = r1 | r3; \
+      r1 = r1 ^ r0; 
+
+#define S4(r0,r1,r2,r3,r4) \
+      r1 = r1 ^ r3; \
+      r3 = -1 ^ r3; \
+      r2 = r2 ^ r3; \
+      r3 = r3 ^ r0; \
+      r4 = r1; \
+      r1 = r1 & r3; \
+      r1 = r1 ^ r2; \
+      r4 = r4 ^ r3; \
+      r0 = r0 ^ r4; \
+      r2 = r2 & r4; \
+      r2 = r2 ^ r0; \
+      r0 = r0 & r1; \
+      r3 = r3 ^ r0; \
+      r4 = r4 | r1; \
+      r4 = r4 ^ r0; \
+      r0 = r0 | r3; \
+      r0 = r0 ^ r2; \
+      r2 = r2 & r3; \
+      r0 = -1 ^ r0; \
+      r4 = r4 ^ r2; 
+
+#define S5(r0,r1,r2,r3,r4) \
+      r0 = r0 ^ r1; \
+      r1 = r1 ^ r3; \
+      r3 = -1 ^ r3; \
+      r4 = r1; \
+      r1 = r1 & r0; \
+      r2 = r2 ^ r3; \
+      r1 = r1 ^ r2; \
+      r2 = r2 | r4; \
+      r4 = r4 ^ r3; \
+      r3 = r3 & r1; \
+      r3 = r3 ^ r0; \
+      r4 = r4 ^ r1; \
+      r4 = r4 ^ r2; \
+      r2 = r2 ^ r0; \
+      r0 = r0 & r3; \
+      r2 = -1 ^ r2; \
+      r0 = r0 ^ r4; \
+      r4 = r4 | r3; \
+      r2 = r2 ^ r4; 
+
+#define S6(r0,r1,r2,r3,r4) \
+      r2 = -1 ^ r2; \
+      r4 = r3; \
+      r3 = r3 & r0; \
+      r0 = r0 ^ r4; \
+      r3 = r3 ^ r2; \
+      r2 = r2 | r4; \
+      r1 = r1 ^ r3; \
+      r2 = r2 ^ r0; \
+      r0 = r0 | r1; \
+      r2 = r2 ^ r1; \
+      r4 = r4 ^ r0; \
+      r0 = r0 | r3; \
+      r0 = r0 ^ r2; \
+      r4 = r4 ^ r3; \
+      r4 = r4 ^ r0; \
+      r3 = -1 ^ r3; \
+      r2 = r2 & r4; \
+      r2 = r2 ^ r3; 
+
+#define S7(r0,r1,r2,r3,r4) \
+      r4 = r2; \
+      r2 = r2 & r1; \
+      r2 = r2 ^ r3; \
+      r3 = r3 & r1; \
+      r4 = r4 ^ r2; \
+      r2 = r2 ^ r1; \
+      r1 = r1 ^ r0; \
+      r0 = r0 | r4; \
+      r0 = r0 ^ r2; \
+      r3 = r3 ^ r1; \
+      r2 = r2 ^ r3; \
+      r3 = r3 & r0; \
+      r3 = r3 ^ r4; \
+      r4 = r4 ^ r2; \
+      r2 = r2 & r0; \
+      r4 = -1 ^ r4; \
+      r2 = r2 ^ r4; \
+      r4 = r4 & r0; \
+      r1 = r1 ^ r3; \
+      r4 = r4 ^ r1; 
+
+/* The inverse sboxes */
+
+#define I0(r0,r1,r2,r3,r4) \
+      r2 = r2 ^ -1; \
+      r4 = r1; \
+      r1 = r1 | r0; \
+      r4 = r4 ^ -1; \
+      r1 = r1 ^ r2; \
+      r2 = r2 | r4; \
+      r1 = r1 ^ r3; \
+      r0 = r0 ^ r4; \
+      r2 = r2 ^ r0; \
+      r0 = r0 & r3; \
+      r4 = r4 ^ r0; \
+      r0 = r0 | r1; \
+      r0 = r0 ^ r2; \
+      r3 = r3 ^ r4; \
+      r2 = r2 ^ r1; \
+      r3 = r3 ^ r0; \
+      r3 = r3 ^ r1; \
+      r2 = r2 & r3; \
+      r4 = r4 ^ r2; 
+ 
+#define I1(r0,r1,r2,r3,r4) \
+      r4 = r1; \
+      r1 = r1 ^ r3; \
+      r3 = r3 & r1; \
+      r4 = r4 ^ r2; \
+      r3 = r3 ^ r0; \
+      r0 = r0 | r1; \
+      r2 = r2 ^ r3; \
+      r0 = r0 ^ r4; \
+      r0 = r0 | r2; \
+      r1 = r1 ^ r3; \
+      r0 = r0 ^ r1; \
+      r1 = r1 | r3; \
+      r1 = r1 ^ r0; \
+      r4 = r4 ^ -1; \
+      r4 = r4 ^ r1; \
+      r1 = r1 | r0; \
+      r1 = r1 ^ r0; \
+      r1 = r1 | r4; \
+      r3 = r3 ^ r1; 
+
+#define I2(r0,r1,r2,r3,r4) \
+      r2 = r2 ^ r3; \
+      r3 = r3 ^ r0; \
+      r4 =  r3; \
+      r3 = r3 & r2; \
+      r3 = r3 ^ r1; \
+      r1 = r1 | r2; \
+      r1 = r1 ^ r4; \
+      r4 = r4 & r3; \
+      r2 = r2 ^ r3; \
+      r4 = r4 & r0; \
+      r4 = r4 ^ r2; \
+      r2 = r2 & r1; \
+      r2 = r2 | r0; \
+      r3 = r3 ^ -1; \
+      r2 = r2 ^ r3; \
+      r0 = r0 ^ r3; \
+      r0 = r0 & r1; \
+      r3 = r3 ^ r4; \
+      r3 = r3 ^ r0; 
+
+#define I3(r0,r1,r2,r3,r4) \
+      r4 =  r2; \
+      r2 = r2 ^ r1; \
+      r0 = r0 ^ r2; \
+      r4 = r4 & r2; \
+      r4 = r4 ^ r0; \
+      r0 = r0 & r1; \
+      r1 = r1 ^ r3; \
+      r3 = r3 | r4; \
+      r2 = r2 ^ r3; \
+      r0 = r0 ^ r3; \
+      r1 = r1 ^ r4; \
+      r3 = r3 & r2; \
+      r3 = r3 ^ r1; \
+      r1 = r1 ^ r0; \
+      r1 = r1 | r2; \
+      r0 = r0 ^ r3; \
+      r1 = r1 ^ r4; \
+      r0 = r0 ^ r1; 
+
+#define I4(r0,r1,r2,r3,r4) \
+      r4 =  r2; \
+      r2 = r2 & r3; \
+      r2 = r2 ^ r1; \
+      r1 = r1 | r3; \
+      r1 = r1 & r0; \
+      r4 = r4 ^ r2; \
+      r4 = r4 ^ r1; \
+      r1 = r1 & r2; \
+      r0 = r0 ^ -1; \
+      r3 = r3 ^ r4; \
+      r1 = r1 ^ r3; \
+      r3 = r3 & r0; \
+      r3 = r3 ^ r2; \
+      r0 = r0 ^ r1; \
+      r2 = r2 & r0; \
+      r3 = r3 ^ r0; \
+      r2 = r2 ^ r4; \
+      r2 = r2 | r3; \
+      r3 = r3 ^ r0; \
+      r2 = r2 ^ r1; 
+
+#define I5(r0,r1,r2,r3,r4) \
+      r1 = r1 ^ -1; \
+      r4 = r3; \
+      r2 = r2 ^ r1; \
+      r3 = r3 | r0; \
+      r3 = r3 ^ r2; \
+      r2 = r2 | r1; \
+      r2 = r2 & r0; \
+      r4 = r4 ^ r3; \
+      r2 = r2 ^ r4; \
+      r4 = r4 | r0; \
+      r4 = r4 ^ r1; \
+      r1 = r1 & r2; \
+      r1 = r1 ^ r3; \
+      r4 = r4 ^ r2; \
+      r3 = r3 & r4; \
+      r4 = r4 ^ r1; \
+      r3 = r3 ^ r0; \
+      r3 = r3 ^ r4; \
+      r4 = r4 ^ -1; 
+
+
+#define I6(r0,r1,r2,r3,r4) \
+      r0 = r0 ^ r2; \
+      r4 = r2; \
+      r2 = r2 & r0; \
+      r4 = r4 ^ r3; \
+      r2 = r2 ^ -1; \
+      r3 = r3 ^ r1; \
+      r2 = r2 ^ r3; \
+      r4 = r4 | r0; \
+      r0 = r0 ^ r2; \
+      r3 = r3 ^ r4; \
+      r4 = r4 ^ r1; \
+      r1 = r1 & r3; \
+      r1 = r1 ^ r0; \
+      r0 = r0 ^ r3; \
+      r0 = r0 | r2; \
+      r3 = r3 ^ r1; \
+      r4 = r4 ^ r0; 
+
+#define I7(r0,r1,r2,r3,r4) \
+      r4 = r2; \
+      r2 = r2 ^ r0; \
+      r0 = r0 & r3; \
+      r4 = r4 | r3; \
+      r2 = r2 ^ -1; \
+      r3 = r3 ^ r1; \
+      r1 = r1 | r0; \
+      r0 = r0 ^ r2; \
+      r2 = r2 & r4; \
+      r3 = r3 & r4; \
+      r1 = r1 ^ r2; \
+      r2 = r2 ^ r0; \
+      r0 = r0 | r2; \
+      r4 = r4 ^ r1; \
+      r0 = r0 ^ r3; \
+      r3 = r3 ^ r4; \
+      r4 = r4 | r0; \
+      r3 = r3 ^ r2; \
+      r4 = r4 ^ r2; 
+
+/* forward and inverse linear transformations */
+
+#define LINTRANS(r0,r1,r2,r3,r4) \
+      r0 = rotl(r0, 13); \
+      r2 = rotl(r2, 3); \
+      r3 = r3 ^ r2; \
+      r4 = r0 << 3; \
+      r1 = r1 ^ r0; \
+      r3 = r3 ^ r4; \
+      r1 = r1 ^ r2; \
+      r3 = rotl(r3, 7); \
+      r1 = rotl(r1, 1); \
+      r2 = r2 ^ r3; \
+      r4 = r1 << 7; \
+      r0 = r0 ^ r1; \
+      r2 = r2 ^ r4; \
+      r0 = r0 ^ r3; \
+      r2 = rotl(r2, 22); \
+      r0 = rotl(r0, 5);
+     
+#define ILINTRANS(r0,r1,r2,r3,r4) \
+      r2 = rotr(r2, 22); \
+      r0 = rotr(r0, 5); \
+      r2 = r2 ^ r3; \
+      r4 = r1 << 7; \
+      r0 = r0 ^ r1; \
+      r2 = r2 ^ r4; \
+      r0 = r0 ^ r3; \
+      r3 = rotr(r3, 7); \
+      r1 = rotr(r1, 1); \
+      r3 = r3 ^ r2; \
+      r4 = r0 << 3; \
+      r1 = r1 ^ r0; \
+      r3 = r3 ^ r4; \
+      r1 = r1 ^ r2; \
+      r2 = rotr(r2, 3); \
+      r0 = rotr(r0, 13); 
+
+
+#define KEYMIX(r0,r1,r2,r3,r4,IN) \
+      r0  = r0 ^ l_key[IN+8]; \
+      r1  = r1 ^ l_key[IN+9]; \
+      r2  = r2 ^ l_key[IN+10]; \
+      r3  = r3 ^ l_key[IN+11]; 
+
+#define GETKEY(r0, r1, r2, r3, IN) \
+      r0 = l_key[IN+8]; \
+      r1 = l_key[IN+9]; \
+      r2 = l_key[IN+10]; \
+      r3 = l_key[IN+11]; 
+
+#define SETKEY(r0, r1, r2, r3, IN) \
+      l_key[IN+8] = r0; \
+      l_key[IN+9] = r1; \
+      l_key[IN+10] = r2; \
+      l_key[IN+11] = r3;
+
+/* initialise the key schedule from the user supplied key   */
+
+int serpent_set_key(serpent_context *cx, const unsigned char *key, int key_len)
+{   const u32 *in_key = (const u32 *)key;
+    /* l_key - storage for the key schedule */
+    u32 *l_key   = cx->keyinfo;
+    u32  i,lk,r0,r1,r2,r3,r4;
+
+    if (key_len != 16 && key_len != 24 && key_len != 32)
+      return -1; /* unsupported key length */
+    
+    key_len *= 8;
+
+    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] &= lk - 1;
+        l_key[i] |= 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); 
+    }
+
+      GETKEY(r0, r1, r2, r3, 0);
+      S3(r0,r1,r2,r3,r4);
+      SETKEY(r1, r2, r3, r4, 0) 
+
+      GETKEY(r0, r1, r2, r3, 4);
+      S2(r0,r1,r2,r3,r4);
+      SETKEY(r2, r3, r1, r4, 4) 
+
+      GETKEY(r0, r1, r2, r3, 8);
+      S1(r0,r1,r2,r3,r4);
+      SETKEY(r3, r1, r2, r0, 8) 
+
+      GETKEY(r0, r1, r2, r3, 12);
+      S0(r0,r1,r2,r3,r4);
+      SETKEY(r1, r4, r2, r0, 12) 
+
+      GETKEY(r0, r1, r2, r3, 16);
+      S7(r0,r1,r2,r3,r4);
+      SETKEY(r2, r4, r3, r0, 16) 
+
+      GETKEY(r0, r1, r2, r3, 20);
+      S6(r0,r1,r2,r3,r4) 
+      SETKEY(r0, r1, r4, r2, 20) 
+
+      GETKEY(r0, r1, r2, r3, 24);
+      S5(r0,r1,r2,r3,r4);
+      SETKEY(r1, r3, r0, r2, 24) 
+
+      GETKEY(r0, r1, r2, r3, 28);
+      S4(r0,r1,r2,r3,r4) 
+      SETKEY(r1, r4, r0, r3, 28) 
+
+      GETKEY(r0, r1, r2, r3, 32);
+      S3(r0,r1,r2,r3,r4);
+      SETKEY(r1, r2, r3, r4, 32) 
+
+      GETKEY(r0, r1, r2, r3, 36);
+      S2(r0,r1,r2,r3,r4);
+      SETKEY(r2, r3, r1, r4, 36) 
+
+      GETKEY(r0, r1, r2, r3, 40);
+      S1(r0,r1,r2,r3,r4);
+      SETKEY(r3, r1, r2, r0, 40) 
+
+      GETKEY(r0, r1, r2, r3, 44);
+      S0(r0,r1,r2,r3,r4);
+      SETKEY(r1, r4, r2, r0, 44) 
+
+      GETKEY(r0, r1, r2, r3, 48);
+      S7(r0,r1,r2,r3,r4);
+      SETKEY(r2, r4, r3, r0, 48) 
+
+      GETKEY(r0, r1, r2, r3, 52);
+      S6(r0,r1,r2,r3,r4) 
+      SETKEY(r0, r1, r4, r2, 52) 
+
+      GETKEY(r0, r1, r2, r3, 56);
+      S5(r0,r1,r2,r3,r4);
+      SETKEY(r1, r3, r0, r2, 56) 
+
+      GETKEY(r0, r1, r2, r3, 60);
+      S4(r0,r1,r2,r3,r4) 
+      SETKEY(r1, r4, r0, r3, 60) 
+
+      GETKEY(r0, r1, r2, r3, 64);
+      S3(r0,r1,r2,r3,r4);
+      SETKEY(r1, r2, r3, r4, 64) 
+
+      GETKEY(r0, r1, r2, r3, 68);
+      S2(r0,r1,r2,r3,r4);
+      SETKEY(r2, r3, r1, r4, 68) 
+
+      GETKEY(r0, r1, r2, r3, 72);
+      S1(r0,r1,r2,r3,r4);
+      SETKEY(r3, r1, r2, r0, 72) 
+
+      GETKEY(r0, r1, r2, r3, 76);
+      S0(r0,r1,r2,r3,r4);
+      SETKEY(r1, r4, r2, r0, 76) 
+
+      GETKEY(r0, r1, r2, r3, 80);
+      S7(r0,r1,r2,r3,r4);
+      SETKEY(r2, r4, r3, r0, 80) 
+
+      GETKEY(r0, r1, r2, r3, 84);
+      S6(r0,r1,r2,r3,r4) 
+      SETKEY(r0, r1, r4, r2, 84) 
+
+      GETKEY(r0, r1, r2, r3, 88);
+      S5(r0,r1,r2,r3,r4);
+      SETKEY(r1, r3, r0, r2, 88) 
+
+      GETKEY(r0, r1, r2, r3, 92);
+      S4(r0,r1,r2,r3,r4) 
+      SETKEY(r1, r4, r0, r3, 92) 
+
+      GETKEY(r0, r1, r2, r3, 96);
+      S3(r0,r1,r2,r3,r4);
+      SETKEY(r1, r2, r3, r4, 96) 
+
+      GETKEY(r0, r1, r2, r3, 100);
+      S2(r0,r1,r2,r3,r4);
+      SETKEY(r2, r3, r1, r4, 100) 
+
+      GETKEY(r0, r1, r2, r3, 104);
+      S1(r0,r1,r2,r3,r4);
+      SETKEY(r3, r1, r2, r0, 104) 
+
+      GETKEY(r0, r1, r2, r3, 108);
+      S0(r0,r1,r2,r3,r4);
+      SETKEY(r1, r4, r2, r0, 108) 
+
+      GETKEY(r0, r1, r2, r3, 112);
+      S7(r0,r1,r2,r3,r4);
+      SETKEY(r2, r4, r3, r0, 112) 
+
+      GETKEY(r0, r1, r2, r3, 116);
+      S6(r0,r1,r2,r3,r4) 
+      SETKEY(r0, r1, r4, r2, 116) 
+
+      GETKEY(r0, r1, r2, r3, 120);
+      S5(r0,r1,r2,r3,r4);
+      SETKEY(r1, r3, r0, r2, 120) 
+
+      GETKEY(r0, r1, r2, r3, 124);
+      S4(r0,r1,r2,r3,r4) 
+      SETKEY(r1, r4, r0, r3, 124) 
+
+      GETKEY(r0, r1, r2, r3, 128);
+      S3(r0,r1,r2,r3,r4);
+      SETKEY(r1, r2, r3, r4, 128) 
+
+    return 0;
+};
+
+/* Encryption and decryption functions. The rounds are fully inlined. 
+ * The sboxes alters the bit order of the output, and the altered
+ * bit ordrer is used progressivly. */
+
+/* encrypt a block of text */
+
+int serpent_encrypt(serpent_context *cx, const u8 *in, 
+		    u8 *out)
+{    u32 *l_key = cx->keyinfo;
+     const u32 *in_blk = (const u32 *) in;
+     u32 *out_blk = (u32 *) out;
+     u32  r0,r1,r2,r3,r4;
+    
+#ifdef  BLOCK_SWAP
+    r0 = io_swap(in_blk[3]); r1 = io_swap(in_blk[2]); 
+    r2 = io_swap(in_blk[1]); r3 = io_swap(in_blk[0]);
+#else
+    r0 = in_blk[0]; r1 = in_blk[1]; r2 = in_blk[2]; r3 = in_blk[3];
+#endif
+
+      /* round 1  */
+      KEYMIX(r0,r1,r2,r3,r4,0);
+      S0(r0,r1,r2,r3,r4);
+      LINTRANS(r1,r4,r2,r0,r3);
+
+      /* round 2  */
+      KEYMIX(r1,r4,r2,r0,r3,4);
+      S1(r1,r4,r2,r0,r3);
+      LINTRANS(r0,r4,r2,r1,r3);
+
+      /* round 3  */
+      KEYMIX(r0,r4,r2,r1,r3,8);
+      S2(r0,r4,r2,r1,r3);
+      LINTRANS(r2,r1,r4,r3,r0);
+
+      /* round 4  */
+      KEYMIX(r2,r1,r4,r3,r0,12);
+      S3(r2,r1,r4,r3,r0);
+      LINTRANS(r1,r4,r3,r0,r2);
+
+      /* round 5  */
+      KEYMIX(r1,r4,r3,r0,r2,16);
+      S4(r1,r4,r3,r0,r2) 
+      LINTRANS(r4,r2,r1,r0,r3);
+
+      /* round 6  */
+      KEYMIX(r4,r2,r1,r0,r3,20);
+      S5(r4,r2,r1,r0,r3);
+      LINTRANS(r2,r0,r4,r1,r3);
+
+      /* round 7  */
+      KEYMIX(r2,r0,r4,r1,r3,24);
+      S6(r2,r0,r4,r1,r3) 
+      LINTRANS(r2,r0,r3,r4,r1);
+
+      /* round 8  */
+      KEYMIX(r2,r0,r3,r4,r1,28);
+      S7(r2,r0,r3,r4,r1);
+      LINTRANS(r3,r1,r4,r2,r0);
+
+      /* round 9  */
+      KEYMIX(r3,r1,r4,r2,r0,32);
+      S0(r3,r1,r4,r2,r0);
+      LINTRANS(r1,r0,r4,r3,r2);
+
+      /* round 10  */
+      KEYMIX(r1,r0,r4,r3,r2,36);
+      S1(r1,r0,r4,r3,r2);
+      LINTRANS(r3,r0,r4,r1,r2);
+
+      /* round 11  */
+      KEYMIX(r3,r0,r4,r1,r2,40);
+      S2(r3,r0,r4,r1,r2);
+      LINTRANS(r4,r1,r0,r2,r3);
+
+      /* round 12  */
+      KEYMIX(r4,r1,r0,r2,r3,44);
+      S3(r4,r1,r0,r2,r3);
+      LINTRANS(r1,r0,r2,r3,r4);
+
+      /* round 13  */
+      KEYMIX(r1,r0,r2,r3,r4,48);
+      S4(r1,r0,r2,r3,r4) 
+      LINTRANS(r0,r4,r1,r3,r2);
+
+      /* round 14  */
+      KEYMIX(r0,r4,r1,r3,r2,52);
+      S5(r0,r4,r1,r3,r2);
+      LINTRANS(r4,r3,r0,r1,r2);
+
+      /* round 15  */
+      KEYMIX(r4,r3,r0,r1,r2,56);
+      S6(r4,r3,r0,r1,r2) 
+      LINTRANS(r4,r3,r2,r0,r1);
+
+      /* round 16  */
+      KEYMIX(r4,r3,r2,r0,r1,60);
+      S7(r4,r3,r2,r0,r1);
+      LINTRANS(r2,r1,r0,r4,r3);
+
+      /* round 17  */
+      KEYMIX(r2,r1,r0,r4,r3,64);
+      S0(r2,r1,r0,r4,r3);
+      LINTRANS(r1,r3,r0,r2,r4);
+
+      /* round 18  */
+      KEYMIX(r1,r3,r0,r2,r4,68);
+      S1(r1,r3,r0,r2,r4);
+      LINTRANS(r2,r3,r0,r1,r4);
+
+      /* round 19  */
+      KEYMIX(r2,r3,r0,r1,r4,72);
+      S2(r2,r3,r0,r1,r4);
+      LINTRANS(r0,r1,r3,r4,r2);
+
+      /* round 20  */
+      KEYMIX(r0,r1,r3,r4,r2,76);
+      S3(r0,r1,r3,r4,r2);
+      LINTRANS(r1,r3,r4,r2,r0);
+
+      /* round 21  */
+      KEYMIX(r1,r3,r4,r2,r0,80);
+      S4(r1,r3,r4,r2,r0) 
+      LINTRANS(r3,r0,r1,r2,r4);
+
+      /* round 22  */
+      KEYMIX(r3,r0,r1,r2,r4,84);
+      S5(r3,r0,r1,r2,r4);
+      LINTRANS(r0,r2,r3,r1,r4);
+
+      /* round 23  */
+      KEYMIX(r0,r2,r3,r1,r4,88);
+      S6(r0,r2,r3,r1,r4) 
+      LINTRANS(r0,r2,r4,r3,r1);
+
+      /* round 24  */
+      KEYMIX(r0,r2,r4,r3,r1,92);
+      S7(r0,r2,r4,r3,r1);
+      LINTRANS(r4,r1,r3,r0,r2);
+
+      /* round 25  */
+      KEYMIX(r4,r1,r3,r0,r2,96);
+      S0(r4,r1,r3,r0,r2);
+      LINTRANS(r1,r2,r3,r4,r0);
+
+      /* round 26  */
+      KEYMIX(r1,r2,r3,r4,r0,100);
+      S1(r1,r2,r3,r4,r0);
+      LINTRANS(r4,r2,r3,r1,r0);
+
+      /* round 27  */
+      KEYMIX(r4,r2,r3,r1,r0,104);
+      S2(r4,r2,r3,r1,r0);
+      LINTRANS(r3,r1,r2,r0,r4);
+
+      /* round 28  */
+      KEYMIX(r3,r1,r2,r0,r4,108);
+      S3(r3,r1,r2,r0,r4);
+      LINTRANS(r1,r2,r0,r4,r3);
+
+      /* round 29  */
+      KEYMIX(r1,r2,r0,r4,r3,112);
+      S4(r1,r2,r0,r4,r3) 
+      LINTRANS(r2,r3,r1,r4,r0);
+
+      /* round 30  */
+      KEYMIX(r2,r3,r1,r4,r0,116);
+      S5(r2,r3,r1,r4,r0);
+      LINTRANS(r3,r4,r2,r1,r0);
+
+      /* round 31  */
+      KEYMIX(r3,r4,r2,r1,r0,120);
+      S6(r3,r4,r2,r1,r0) 
+      LINTRANS(r3,r4,r0,r2,r1);
+
+      /* round 32  */
+      KEYMIX(r3,r4,r0,r2,r1,124);
+      S7(r3,r4,r0,r2,r1);
+      KEYMIX(r0,r1,r2,r3,r4,128);
+
+    
+#ifdef  BLOCK_SWAP
+    out_blk[3] = io_swap(r0); out_blk[2] = io_swap(r1); 
+    out_blk[1] = io_swap(r2); out_blk[0] = io_swap(r3);
+#else
+    out_blk[0] = r0; out_blk[1] = r1; out_blk[2] = r2; out_blk[3] = r3;
+#endif
+    return 0;
+};
+
+/* decrypt a block of text  */
+
+int serpent_decrypt(serpent_context *cx, const u8 *in,
+		    u8 *out)
+{   u32 *l_key = cx->keyinfo;
+    const u32 *in_blk = (const u32 *)in;
+    u32 *out_blk = (u32 *)out;
+    u32  r0,r1,r2,r3,r4;
+    
+#ifdef  BLOCK_SWAP
+    r0 = io_swap(in_blk[3]); r1 = io_swap(in_blk[2]); 
+    r2 = io_swap(in_blk[1]); r3 = io_swap(in_blk[0]);
+#else
+    r0 = in_blk[0]; r1 = in_blk[1]; r2 = in_blk[2]; r3 = in_blk[3];
+#endif
+
+      /* round 1 */
+      KEYMIX(r0,r1,r2,r3,r4,128);
+      I7(r0,r1,r2,r3,r4);
+      KEYMIX(r3,r0,r1,r4,r2,124);
+
+      /* round 2  */
+      ILINTRANS(r3,r0,r1,r4,r2);
+      I6(r3,r0,r1,r4,r2);
+      KEYMIX(r0,r1,r2,r4,r3,120);
+
+      /* round 3  */
+      ILINTRANS(r0,r1,r2,r4,r3);
+      I5(r0,r1,r2,r4,r3);
+      KEYMIX(r1,r3,r4,r2,r0,116);
+
+      /* round 4  */
+      ILINTRANS(r1,r3,r4,r2,r0);
+      I4(r1,r3,r4,r2,r0);
+      KEYMIX(r1,r2,r4,r0,r3,112);
+
+      /* round 5  */
+      ILINTRANS(r1,r2,r4,r0,r3);
+      I3(r1,r2,r4,r0,r3);
+      KEYMIX(r4,r2,r0,r1,r3,108);
+
+      /* round 6  */
+      ILINTRANS(r4,r2,r0,r1,r3);
+      I2(r4,r2,r0,r1,r3);
+      KEYMIX(r2,r3,r0,r1,r4,104);
+
+      /* round 7  */
+      ILINTRANS(r2,r3,r0,r1,r4);
+      I1(r2,r3,r0,r1,r4);
+      KEYMIX(r4,r2,r1,r0,r3,100);
+
+      /* round 8  */
+      ILINTRANS(r4,r2,r1,r0,r3);
+      I0(r4,r2,r1,r0,r3);
+      KEYMIX(r4,r3,r2,r0,r1,96);
+
+      /* round 9  */
+      ILINTRANS(r4,r3,r2,r0,r1);
+      I7(r4,r3,r2,r0,r1);
+      KEYMIX(r0,r4,r3,r1,r2,92);
+
+      /* round 10  */
+      ILINTRANS(r0,r4,r3,r1,r2);
+      I6(r0,r4,r3,r1,r2);
+      KEYMIX(r4,r3,r2,r1,r0,88);
+
+      /* round 11  */
+      ILINTRANS(r4,r3,r2,r1,r0);
+      I5(r4,r3,r2,r1,r0);
+      KEYMIX(r3,r0,r1,r2,r4,84);
+
+      /* round 12  */
+      ILINTRANS(r3,r0,r1,r2,r4);
+      I4(r3,r0,r1,r2,r4);
+      KEYMIX(r3,r2,r1,r4,r0,80);
+
+      /* round 13  */
+      ILINTRANS(r3,r2,r1,r4,r0);
+      I3(r3,r2,r1,r4,r0);
+      KEYMIX(r1,r2,r4,r3,r0,76);
+
+      /* round 14  */
+      ILINTRANS(r1,r2,r4,r3,r0);
+      I2(r1,r2,r4,r3,r0);
+      KEYMIX(r2,r0,r4,r3,r1,72);
+
+      /* round 15  */
+      ILINTRANS(r2,r0,r4,r3,r1);
+      I1(r2,r0,r4,r3,r1);
+      KEYMIX(r1,r2,r3,r4,r0,68);
+
+      /* round 16  */
+      ILINTRANS(r1,r2,r3,r4,r0);
+      I0(r1,r2,r3,r4,r0);
+      KEYMIX(r1,r0,r2,r4,r3,64);
+
+      /* round 17  */
+      ILINTRANS(r1,r0,r2,r4,r3);
+      I7(r1,r0,r2,r4,r3);
+      KEYMIX(r4,r1,r0,r3,r2,60);
+
+      /* round 18  */
+      ILINTRANS(r4,r1,r0,r3,r2);
+      I6(r4,r1,r0,r3,r2);
+      KEYMIX(r1,r0,r2,r3,r4,56);
+
+      /* round 19  */
+      ILINTRANS(r1,r0,r2,r3,r4);
+      I5(r1,r0,r2,r3,r4);
+      KEYMIX(r0,r4,r3,r2,r1,52);
+
+      /* round 20  */
+      ILINTRANS(r0,r4,r3,r2,r1);
+      I4(r0,r4,r3,r2,r1);
+      KEYMIX(r0,r2,r3,r1,r4,48);
+
+      /* round 21  */
+      ILINTRANS(r0,r2,r3,r1,r4);
+      I3(r0,r2,r3,r1,r4);
+      KEYMIX(r3,r2,r1,r0,r4,44);
+
+      /* round 22  */
+      ILINTRANS(r3,r2,r1,r0,r4);
+      I2(r3,r2,r1,r0,r4);
+      KEYMIX(r2,r4,r1,r0,r3,40);
+
+      /* round 23  */
+      ILINTRANS(r2,r4,r1,r0,r3);
+      I1(r2,r4,r1,r0,r3);
+      KEYMIX(r3,r2,r0,r1,r4,36);
+
+      /* round 24  */
+      ILINTRANS(r3,r2,r0,r1,r4);
+      I0(r3,r2,r0,r1,r4);
+      KEYMIX(r3,r4,r2,r1,r0,32);
+
+      /* round 25  */
+      ILINTRANS(r3,r4,r2,r1,r0);
+      I7(r3,r4,r2,r1,r0);
+      KEYMIX(r1,r3,r4,r0,r2,28);
+
+      /* round 26  */
+      ILINTRANS(r1,r3,r4,r0,r2);
+      I6(r1,r3,r4,r0,r2);
+      KEYMIX(r3,r4,r2,r0,r1,24);
+
+      /* round 27  */
+      ILINTRANS(r3,r4,r2,r0,r1);
+      I5(r3,r4,r2,r0,r1);
+      KEYMIX(r4,r1,r0,r2,r3,20);
+
+      /* round 28  */
+      ILINTRANS(r4,r1,r0,r2,r3);
+      I4(r4,r1,r0,r2,r3);
+      KEYMIX(r4,r2,r0,r3,r1,16);
+
+      /* round 29  */
+      ILINTRANS(r4,r2,r0,r3,r1);
+      I3(r4,r2,r0,r3,r1);
+      KEYMIX(r0,r2,r3,r4,r1,12);
+
+      /* round 30  */
+      ILINTRANS(r0,r2,r3,r4,r1);
+      I2(r0,r2,r3,r4,r1);
+      KEYMIX(r2,r1,r3,r4,r0,8);
+
+      /* round 31  */
+      ILINTRANS(r2,r1,r3,r4,r0);
+      I1(r2,r1,r3,r4,r0);
+      KEYMIX(r0,r2,r4,r3,r1,4);
+
+      /* round 32  */
+      ILINTRANS(r0,r2,r4,r3,r1);
+      I0(r0,r2,r4,r3,r1);
+      KEYMIX(r0,r1,r2,r3,r4,0);
+    
+#ifdef  BLOCK_SWAP
+    out_blk[3] = io_swap(r0); out_blk[2] = io_swap(r1); 
+    out_blk[1] = io_swap(r2); out_blk[0] = io_swap(r3);
+#else
+    out_blk[0] = r0; out_blk[1] = r1; out_blk[2] = r2; out_blk[3] = r3;
+#endif
+    return 0;
+};
+
+
Index: freeswan/libcrypto/libserpent/serpent.h
diff -u /dev/null freeswan/libcrypto/libserpent/serpent.h:1.1.2.1
--- /dev/null	Fri Jul 12 16:03:47 2002
+++ freeswan/libcrypto/libserpent/serpent.h	Mon Apr 15 12:13:42 2002
@@ -0,0 +1,17 @@
+#ifndef SERPENT_H
+#define SERPENT_H
+#ifdef __KERNEL__
+#include <linux/types.h>
+#else
+#include <sys/types.h>
+#define u32 u_int32_t
+#define u8 u_int8_t
+#endif
+struct serpent_context {
+	u32  keyinfo[140]; /* storage for the key schedule         */
+};
+typedef struct serpent_context serpent_context;
+int serpent_set_key(serpent_context *ctx, const u8 * in_key, int key_len);
+int serpent_decrypt(serpent_context *ctx, const u8 * in_blk, u8 * out_blk);
+int serpent_encrypt(serpent_context *ctx, const u8 * in_blk, u8 * out_blk);
+#endif /* SERPENT_H */
Index: freeswan/libcrypto/libserpent/serpent_cbc.c
diff -u /dev/null freeswan/libcrypto/libserpent/serpent_cbc.c:1.1.2.2
--- /dev/null	Fri Jul 12 16:03:47 2002
+++ freeswan/libcrypto/libserpent/serpent_cbc.c	Mon Jun  3 22:24:31 2002
@@ -0,0 +1,8 @@
+#ifdef __KERNEL__
+#include <linux/types.h>
+#else
+#include <sys/types.h>
+#endif
+#include "serpent_cbc.h"
+#include "cbc_generic.h"
+CBC_IMPL_BLK16(serpent_cbc_encrypt, serpent_context, u_int8_t *, serpent_encrypt, serpent_decrypt);
Index: freeswan/libcrypto/libserpent/serpent_cbc.h
diff -u /dev/null freeswan/libcrypto/libserpent/serpent_cbc.h:1.1.2.2
--- /dev/null	Fri Jul 12 16:03:47 2002
+++ freeswan/libcrypto/libserpent/serpent_cbc.h	Mon Jun  3 22:24:31 2002
@@ -0,0 +1,3 @@
+/* Glue header */
+#include "serpent.h"
+int serpent_cbc_encrypt(serpent_context *ctx, const u_int8_t * in, u_int8_t * out, int ilen, const u_int8_t * iv, int encrypt);
Index: freeswan/libcrypto/libserpent/test_main.c
diff -u /dev/null freeswan/libcrypto/libserpent/test_main.c:1.1.2.1
--- /dev/null	Fri Jul 12 16:03:47 2002
+++ freeswan/libcrypto/libserpent/test_main.c	Mon Apr 15 12:13:42 2002
@@ -0,0 +1,34 @@
+#include <stdio.h>
+#include <string.h>
+#include "serpent_cbc.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;
+}
Index: freeswan/klips/net/ipsec/alg/ipsec_alg_serpent.c
diff -u /dev/null freeswan/klips/net/ipsec/alg/ipsec_alg_serpent.c:1.1.2.3
--- /dev/null	Fri Jul 12 16:03:47 2002
+++ freeswan/klips/net/ipsec/alg/ipsec_alg_serpent.c	Tue May 21 13:25:53 2002
@@ -0,0 +1,134 @@
+/*
+ * ipsec_alg SERPENT cipher stubs
+ *
+ * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
+ * 
+ * $Id: ipsec_alg_serpent.c,v 1.1.2.3 2002/05/21 16:25:53 jjo Exp $
+ * 
+ * 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>
+
+/*	
+ *	special case: ipsec core modular with this static algo inside:
+ *	must avoid MODULE magic for this file
+ */
+#if CONFIG_IPSEC_MODULE && CONFIG_IPSEC_ALG_SERPENT
+#undef MODULE
+#endif
+
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <linux/kernel.h> /* printk() */
+#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_alg.h"
+#include "libserpent/serpent.h"
+#include "libserpent/serpent_cbc.h"
+
+#define ESP_SERPENT		252	/* from ipsec drafts */
+
+/* 128, 192 or 256 */
+#define ESP_SERPENT_KEY_SZ_MIN	16 	/* 128 bit secret key */
+#define ESP_SERPENT_KEY_SZ_MAX	32 	/* 256 bit secret key */
+#define ESP_SERPENT_CBC_BLK_LEN	16	/* SERPENT-CBC block size */
+
+MODULE_AUTHOR("JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>");
+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");
+
+static int _serpent_set_key(__u8 * key_e, const __u8 * key, int keysize) {
+	serpent_context *ctx=(serpent_context *)key_e;
+	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(ctx, key,  keysize);
+	return 0;
+}
+static int _serpent_cbc_encrypt(__u8 * key_e, __u8 * in, __u8 * out, int ilen, const __u8 * iv, int encrypt) {
+	serpent_context *ctx=(serpent_context *)key_e;
+	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(ctx, in, out, ilen, iv, encrypt);
+	return ilen;
+}
+static struct ipsec_alg_enc ipsec_alg_SERPENT = {
+	ixt_version:	IPSEC_ALG_VERSION,
+	ixt_module:	THIS_MODULE,
+	ixt_refcnt:	ATOMIC_INIT(0),
+	ixt_alg_type:	IPSEC_ALG_TYPE_ENCRYPT,
+	ixt_alg_id: 	ESP_SERPENT,
+	ixt_name: 	"serpent",
+	ixt_blocksize:	ESP_SERPENT_CBC_BLK_LEN,
+	ixt_keyminbits:	ESP_SERPENT_KEY_SZ_MIN * 8,
+	ixt_keymaxbits:	ESP_SERPENT_KEY_SZ_MAX * 8,
+	ixt_e_keylen:	ESP_SERPENT_KEY_SZ_MAX,
+	ixt_e_ctx_size:	sizeof(serpent_context),
+	ixt_e_set_key:	_serpent_set_key,
+	ixt_e_cbc_encrypt:_serpent_cbc_encrypt,
+};
+	
+IPSEC_ALG_MODULE_INIT(ipsec_serpent_init)
+{
+	int ret, test_ret;
+	if (keyminbits)
+		ipsec_alg_SERPENT.ixt_keyminbits=keyminbits;
+	if (keymaxbits) {
+		ipsec_alg_SERPENT.ixt_keymaxbits=keymaxbits;
+		if (keymaxbits*8>ipsec_alg_SERPENT.ixt_keymaxbits)
+			ipsec_alg_SERPENT.ixt_e_keylen=keymaxbits*8;
+	}
+	ret=register_ipsec_alg_enc(&ipsec_alg_SERPENT);
+	printk(__FUNCTION__ "(alg_type=%d alg_id=%d name=%s): ret=%d\n",
+			ipsec_alg_SERPENT.ixt_alg_type,
+			ipsec_alg_SERPENT.ixt_alg_id,
+			ipsec_alg_SERPENT.ixt_name,
+			ret);
+	if (ret==0 && test) {
+		test_ret=ipsec_alg_test(
+				ipsec_alg_SERPENT.ixt_alg_type,
+				ipsec_alg_SERPENT.ixt_alg_id,
+				test);
+		printk(__FUNCTION__ "(alg_type=%d alg_id=%d): test_ret=%d\n",
+				ipsec_alg_SERPENT.ixt_alg_type,
+				ipsec_alg_SERPENT.ixt_alg_id,
+				test_ret);
+	}
+	return ret;
+}
+IPSEC_ALG_MODULE_EXIT(ipsec_serpent_fini)
+{
+	unregister_ipsec_alg_enc(&ipsec_alg_SERPENT);
+	return;
+}
+#ifdef MODULE_LICENSE
+MODULE_LICENSE("GPL");
+#endif
Index: freeswan/klips/net/ipsec/alg/Makefile.alg_serpent
diff -u /dev/null freeswan/klips/net/ipsec/alg/Makefile.alg_serpent:1.1.2.4
--- /dev/null	Fri Jul 12 16:03:47 2002
+++ freeswan/klips/net/ipsec/alg/Makefile.alg_serpent	Tue Jun  4 10:15:47 2002
@@ -0,0 +1,21 @@
+MOD_SERPENT := ipsec_serpent.o
+
+ALG_MODULES += $(MOD_SERPENT)
+ALG_SUBDIRS += libserpent
+
+obj-$(CONFIG_IPSEC_ALG_SERPENT) += $(MOD_SERPENT)
+static_init-func-$(CONFIG_IPSEC_ALG_SERPENT)+= ipsec_serpent_init
+alg_obj-$(CONFIG_IPSEC_ALG_SERPENT) += ipsec_alg_serpent.o
+
+SERPENT_OBJS=ipsec_alg_serpent.o libserpent/libserpent.a
+$(MOD_SERPENT) : libserpent $(SERPENT_OBJS)
+	$(LD) -r $(SERPENT_OBJS) -o $@
+
+libserpent : $(LIBCRYPTO)/libserpent 
+	test -d $@ || mkdir $@ ;exit 0
+	test -d $@/asm || mkdir $@/asm;exit 0
+	cd $@ && ln -sf $?/Makefile $?/*.[chS] .
+
+libserpent/libserpent.a:
+	( cd libserpent && \
+		$(MAKE) CC='$(CC)' CFLAGS='$(CFLAGS) $(EXTRA_CFLAGS)' EXTRA_CFLAGS='$(EXTRA_CFLAGS)' libserpent.a ;)
Index: freeswan/klips/net/ipsec/alg/Config.alg_serpent.in
diff -u /dev/null freeswan/klips/net/ipsec/alg/Config.alg_serpent.in:1.1.2.1
--- /dev/null	Fri Jul 12 16:03:47 2002
+++ freeswan/klips/net/ipsec/alg/Config.alg_serpent.in	Mon Apr 15 12:13:42 2002
@@ -0,0 +1,3 @@
+if [ "$CONFIG_IPSEC_ALG" = "y" ]; then
+  tristate '        SERPENT encryption algorithm' CONFIG_IPSEC_ALG_SERPENT
+fi
Index: freeswan/pluto/alg/ike_alg_serpent.c
diff -u /dev/null freeswan/pluto/alg/ike_alg_serpent.c:1.1.2.2
--- /dev/null	Fri Jul 12 16:03:47 2002
+++ freeswan/pluto/alg/ike_alg_serpent.c	Fri May 24 16:32:51 2002
@@ -0,0 +1,68 @@
+#include <stdio.h>
+#include <string.h>
+#include <stddef.h>
+#include <sys/types.h>
+#include <freeswan.h>
+
+#include "constants.h"
+#include "defs.h"
+#include "log.h"
+#include "libserpent/serpent_cbc.h"
+#include "alg_info.h"
+#include "ike_alg.h"
+
+#define  SERPENT_CBC_BLOCK_SIZE	(128/BITS_PER_BYTE)
+#define  SERPENT_KEY_MIN_LEN	128
+#define  SERPENT_KEY_DEF_LEN	128
+#define  SERPENT_KEY_MAX_LEN	256
+
+/* draft-ietf-ipsec-ciph-aes-cbc-02.txt */
+#define  OAKLEY_SERPENT_CBC	65004
+static void
+do_serpent(u_int8_t *buf, size_t buf_size, u_int8_t *key, size_t key_size, u_int8_t *iv, bool enc)
+{
+    serpent_context serpent_ctx;
+    char iv_bak[SERPENT_CBC_BLOCK_SIZE];
+    char *new_iv = NULL;	/* logic will avoid copy to NULL */
+
+
+    serpent_set_key(&serpent_ctx, key, key_size);
+    /*	
+     *	my SERPENT cbc does not touch passed IV (optimization for
+     *	ESP handling), so I must "emulate" des-like IV
+     *	crunching
+     */
+    if (!enc)
+	    memcpy(new_iv=iv_bak, 
+			    (char*) buf + buf_size-SERPENT_CBC_BLOCK_SIZE,
+			    SERPENT_CBC_BLOCK_SIZE);
+
+    serpent_cbc_encrypt(&serpent_ctx, buf, buf, buf_size, iv, enc);
+
+    if (enc)
+	    new_iv = (char*) buf + buf_size-SERPENT_CBC_BLOCK_SIZE;
+
+    memcpy(iv, new_iv, SERPENT_CBC_BLOCK_SIZE);
+}
+struct encrypt_desc encrypt_desc_serpent =
+{
+	algo_type: 	IKE_ALG_ENCRYPT,
+	algo_id:   	OAKLEY_SERPENT_CBC,
+	algo_next: 	NULL,
+	enc_ctxsize: 	sizeof(struct serpent_context),
+	enc_blocksize: 	SERPENT_CBC_BLOCK_SIZE,
+        keyminlen: 	SERPENT_KEY_MIN_LEN,
+        keydeflen: 	SERPENT_KEY_DEF_LEN,
+        keymaxlen: 	SERPENT_KEY_MAX_LEN,
+        do_crypt: 	do_serpent,
+};
+int ike_alg_serpent_init(void);
+int
+ike_alg_serpent_init(void)
+{
+	int ret = ike_alg_register_enc(&encrypt_desc_serpent);
+	return ret;
+}
+/*
+IKE_ALG_INIT_NAME: ike_alg_serpent_init
+*/
Index: freeswan/pluto/alg/Makefile.ike_alg_serpent
diff -u /dev/null freeswan/pluto/alg/Makefile.ike_alg_serpent:1.1.2.2
--- /dev/null	Fri Jul 12 16:03:47 2002
+++ freeswan/pluto/alg/Makefile.ike_alg_serpent	Mon Jun  3 22:24:31 2002
@@ -0,0 +1,12 @@
+ALG:=serpent
+DIR_SERPENT:=$(LIBCRYPTO)/libserpent
+ALG_DIRS := $(ALG_DIRS) $(DIR_SERPENT)
+ALG_LIBS := $(ALG_LIBS) $(DIR_SERPENT)/libserpent.a
+ALG_SRCS := $(ALG_SRCS) ike_alg_$(ALG).c
+ALG_OBJS := $(ALG_OBJS) ike_alg_$(ALG).o
+
+$(DIR_SERPENT)/libserpent.a:
+	make -C $(DIR_SERPENT) CFLAGS="$(CFLAGS)" libserpent.a
+
+ike_alg_$(ALG).o: ike_alg_$(ALG).c
+	$(CC) -I $(LIBCRYPTO) -I$(DIR_SERPENT) $(COPTS) $(ALLFLAGS) -c $<
--- freeswan/klips/net/ipsec/alg/Config.in	Sun Dec 16 10:24:55 2001
+++ freeswan/klips/net/ipsec/alg/Config.in	Sun Dec 16 10:24:52 2001
@@ -1000,0 +1001 @@
+source net/ipsec/alg/Config.alg_serpent.in
