diff -Nur linux-2.4.10/Makefile linux-int-2.4.10/Makefile
--- linux-2.4.10/Makefile	Sun Sep 23 19:02:30 2001
+++ linux-int-2.4.10/Makefile	Sat Sep 29 11:16:54 2001
@@ -119,9 +119,10 @@
 
 CORE_FILES	=kernel/kernel.o mm/mm.o fs/fs.o ipc/ipc.o
 NETWORKS	=net/network.o
+CRYPTO		=crypto/crypto.o
 
 LIBS		=$(TOPDIR)/lib/lib.a
-SUBDIRS		=kernel drivers mm fs net ipc lib
+SUBDIRS		=kernel drivers mm fs net ipc lib crypto
 
 DRIVERS-n :=
 DRIVERS-y :=
@@ -242,7 +243,7 @@
 
 export	CPPFLAGS CFLAGS AFLAGS
 
-export	NETWORKS DRIVERS LIBS HEAD LDFLAGS LINKFLAGS MAKEBOOT ASFLAGS
+export	NETWORKS CRYPTO DRIVERS LIBS HEAD LDFLAGS LINKFLAGS MAKEBOOT ASFLAGS
 
 .S.s:
 	$(CPP) $(AFLAGS) -traditional -o $*.s $<
@@ -261,6 +262,7 @@
 		$(CORE_FILES) \
 		$(DRIVERS) \
 		$(NETWORKS) \
+		$(CRYPTO) \
 		$(LIBS) \
 		--end-group \
 		-o vmlinux
diff -Nur linux-2.4.10/arch/i386/config.in linux-int-2.4.10/arch/i386/config.in
--- linux-2.4.10/arch/i386/config.in	Tue Sep 18 07:52:35 2001
+++ linux-int-2.4.10/arch/i386/config.in	Sat Sep 29 11:16:54 2001
@@ -277,6 +277,8 @@
 
 source drivers/md/Config.in
 
+source crypto/Config.in
+
 if [ "$CONFIG_NET" = "y" ]; then
    source net/Config.in
 fi
diff -Nur linux-2.4.10/crypto/Config.in linux-int-2.4.10/crypto/Config.in
--- linux-2.4.10/crypto/Config.in	Thu Jan  1 01:00:00 1970
+++ linux-int-2.4.10/crypto/Config.in	Sat Sep 29 11:16:54 2001
@@ -0,0 +1,40 @@
+#
+# Crypto Library Configuration
+#
+mainmenu_option next_comment
+comment 'Crypto options'
+tristate 'CryptoAPI support' CONFIG_CRYPTO
+
+dep_tristate 'loop cryptographic filter (EXPERIMENTAL)' CONFIG_CRYPTOLOOP $CONFIG_CRYPTO $CONFIG_BLK_DEV_LOOP
+dep_mbool ' use 512-blocks for IV calculation' CONFIG_CRYPTOLOOP_512IV $CONFIG_CRYPTOLOOP
+
+dep_tristate 'Crypto ciphers' CONFIG_CIPHERS $CONFIG_CRYPTO
+if [ "$CONFIG_CIPHERS" != "n" ]; then
+	dep_tristate ' AES cipher (EXPERIMENTAL)' CONFIG_CIPHER_AES $CONFIG_CIPHERS
+#
+	comment 'AES Finalist Ciphers (128 bit blocksize)'
+	dep_tristate ' Twofish cipher (EXPERIMENTAL)' CONFIG_CIPHER_TWOFISH $CONFIG_CIPHERS
+	dep_tristate ' MARS cipher (EXPERIMENTAL)' CONFIG_CIPHER_MARS $CONFIG_CIPHERS
+	dep_tristate ' RC6 cipher (EXPERIMENTAL)' CONFIG_CIPHER_RC6 $CONFIG_CIPHERS
+	dep_tristate ' Serpent cipher (EXPERIMENTAL)' CONFIG_CIPHER_SERPENT $CONFIG_CIPHERS
+#
+	comment 'Other Ciphers submitted as AES Candidates:'
+	dep_tristate ' DFC cipher (EXPERIMENTAL)' CONFIG_CIPHER_DFC $CONFIG_CIPHERS
+#
+	comment 'Other ciphers (64 bit blocksize)'
+	dep_tristate ' Blowfish cipher (EXPERIMENTAL)' CONFIG_CIPHER_BLOWFISH $CONFIG_CIPHERS
+ 	dep_tristate ' IDEA cipher (EXPERIMENTAL)' CONFIG_CIPHER_IDEA $CONFIG_CIPHERS
+	dep_tristate ' RC5 cipher (EXPERIMENTAL)' CONFIG_CIPHER_RC5 $CONFIG_CIPHERS
+ 	dep_tristate ' DES EDE3 cipher (3DES, EXPERIMENTAL)' CONFIG_CIPHER_DES_EDE3 $CONFIG_CIPHERS
+	dep_tristate ' DES cipher (DEPRECATED)' CONFIG_CIPHER_DES $CONFIG_CIPHERS
+#
+	comment 'Debugging'
+	dep_tristate ' DUMMY cipher (DEPRECATED)' CONFIG_CIPHER_DUMMY $CONFIG_CIPHERS
+fi
+
+dep_tristate 'Digest algorithms' CONFIG_DIGEST $CONFIG_CRYPTO
+if [ "$CONFIG_DIGEST" != "n" ]; then
+	dep_tristate ' MD5 digest (EXPERIMENTAL)' CONFIG_DIGEST_MD5 $CONFIG_DIGEST
+	dep_tristate ' SHA1 digest (EXPERIMENTAL)' CONFIG_DIGEST_SHA1 $CONFIG_DIGEST
+fi
+endmenu
diff -Nur linux-2.4.10/crypto/Makefile linux-int-2.4.10/crypto/Makefile
--- linux-2.4.10/crypto/Makefile	Thu Jan  1 01:00:00 1970
+++ linux-int-2.4.10/crypto/Makefile	Sat Sep 29 11:16:54 2001
@@ -0,0 +1,32 @@
+#
+# Makefile for the Linux kernel crypto library.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (not a .c file).
+#
+# Note 2! The CFLAGS definitions are now in the main makefile.
+
+O_TARGET := crypto.o
+
+export-objs = cryptoapi.o
+
+obj-$(CONFIG_CRYPTO)          += cryptoapi.o
+obj-$(CONFIG_CRYPTOLOOP)      += cryptoloop.o
+
+obj-$(CONFIG_CIPHER_AES)      += cipher-aes.o
+obj-$(CONFIG_CIPHER_BLOWFISH) += cipher-blowfish.o
+obj-$(CONFIG_CIPHER_DES)      += cipher-des.o
+obj-$(CONFIG_CIPHER_DES_EDE3) += cipher-des-ede3.o
+obj-$(CONFIG_CIPHER_DUMMY)    += cipher-dummy.o
+obj-$(CONFIG_CIPHER_DFC)      += cipher-dfc.o
+obj-$(CONFIG_CIPHER_IDEA)     += cipher-idea.o
+obj-$(CONFIG_CIPHER_MARS)     += cipher-mars.o
+obj-$(CONFIG_CIPHER_RC5)      += cipher-rc5.o
+obj-$(CONFIG_CIPHER_RC6)      += cipher-rc6.o
+obj-$(CONFIG_CIPHER_SERPENT)  += cipher-serpent.o
+obj-$(CONFIG_CIPHER_TWOFISH)  += cipher-twofish.o
+obj-$(CONFIG_DIGEST_MD5)      += digest-md5.o
+obj-$(CONFIG_DIGEST_SHA1)     += digest-sha1.o
+
+include $(TOPDIR)/Rules.make
diff -Nur linux-2.4.10/crypto/cipher-aes.c linux-int-2.4.10/crypto/cipher-aes.c
--- linux-2.4.10/crypto/cipher-aes.c	Thu Jan  1 01:00:00 1970
+++ linux-int-2.4.10/crypto/cipher-aes.c	Sat Sep 29 11:16:54 2001
@@ -0,0 +1,451 @@
+/* NOTE: This implementation has been changed from the original
+   source.  See ChangeLog for more information.
+   Maintained by Alexander Kjeldaas <astor@fast.no>
+ */
+
+// Copyright in this code is held by Dr B.R. Gladman but free direct or
+// derivative use is permitted subject to acknowledgement of its origin
+// and subject to any constraints placed on the use of the algorithm by
+// its designers (if such constraints may exist, this will be indicated
+// below).
+//
+// Dr. B. R. Gladman (brian.gladman@btinternet.com). 25th January 2000.
+//
+// This is an implementation of Rijndael, an encryption algorithm designed
+// by Daemen and Rijmen and submitted as a candidate algorithm for the
+// Advanced Encryption Standard programme of the US National Institute of
+// Standards and Technology.
+//
+// The designers of Rijndael have not placed any constraints on the use of
+// this algorithm.
+
+/* Some changes from the Gladman version:
+    s/RIJNDAEL(e_key)/E_KEY/g
+    s/RIJNDAEL(d_key)/D_KEY/g
+*/
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/wordops.h>
+#include <linux/crypto.h>
+#include <asm/byteorder.h>
+
+#if 0
+#define rotl rotl32
+#define rotr rotr32
+#else
+#define rotl generic_rotl32
+#define rotr generic_rotr32
+#endif
+
+#define u32_in(x) le32_to_cpu(*(u32 *)(x))
+#define u32_out(to, from) (*(u32 *)(to) = cpu_to_le32(from))
+
+#define E_KEY ((u32 *) cx->keyinfo)
+#define D_KEY ((u32 *) (cx->keyinfo + 60))
+
+static u8 pow_tab[256];
+static u8 log_tab[256];
+static u8 sbx_tab[256];
+static u8 isb_tab[256];
+static u32 rco_tab[10];
+static u32 ft_tab[4][256];
+static u32 it_tab[4][256];
+
+static u32 fl_tab[4][256];
+static u32 il_tab[4][256];
+
+static inline u8
+f_mult (u8 a, u8 b)
+{
+	u8 aa = log_tab[a], cc = aa + log_tab[b];
+
+	return pow_tab[cc + (cc < aa ? 1 : 0)];
+}
+
+#define ff_mult(a,b)    (a && b ? f_mult(a, b) : 0)
+
+#define f_rn(bo, bi, n, k)					\
+    bo[n] =  ft_tab[0][byte(bi[n],0)] ^				\
+             ft_tab[1][byte(bi[(n + 1) & 3],1)] ^		\
+             ft_tab[2][byte(bi[(n + 2) & 3],2)] ^		\
+             ft_tab[3][byte(bi[(n + 3) & 3],3)] ^ *(k + n)
+
+#define i_rn(bo, bi, n, k)					\
+    bo[n] =  it_tab[0][byte(bi[n],0)] ^				\
+             it_tab[1][byte(bi[(n + 3) & 3],1)] ^		\
+             it_tab[2][byte(bi[(n + 2) & 3],2)] ^		\
+             it_tab[3][byte(bi[(n + 1) & 3],3)] ^ *(k + n)
+
+#define ls_box(x)				\
+    ( fl_tab[0][byte(x, 0)] ^			\
+      fl_tab[1][byte(x, 1)] ^			\
+      fl_tab[2][byte(x, 2)] ^			\
+      fl_tab[3][byte(x, 3)] )
+
+#define f_rl(bo, bi, n, k)					\
+    bo[n] =  fl_tab[0][byte(bi[n],0)] ^				\
+             fl_tab[1][byte(bi[(n + 1) & 3],1)] ^		\
+             fl_tab[2][byte(bi[(n + 2) & 3],2)] ^		\
+             fl_tab[3][byte(bi[(n + 3) & 3],3)] ^ *(k + n)
+
+#define i_rl(bo, bi, n, k)					\
+    bo[n] =  il_tab[0][byte(bi[n],0)] ^				\
+             il_tab[1][byte(bi[(n + 3) & 3],1)] ^		\
+             il_tab[2][byte(bi[(n + 2) & 3],2)] ^		\
+             il_tab[3][byte(bi[(n + 1) & 3],3)] ^ *(k + n)
+
+static void
+gen_tabs (void)
+{
+	u32 i, t;
+	u8 p, q;
+
+	// log and power tables for GF(2**8) finite field with
+	// 0x011b as modular polynomial - the simplest prmitive
+	// root is 0x03, used here to generate the tables
+
+	for (i = 0, p = 1; i < 256; ++i) {
+		pow_tab[i] = (u8) p;
+		log_tab[p] = (u8) i;
+
+		p ^= (p << 1) ^ (p & 0x80 ? 0x01b : 0);
+	}
+
+	log_tab[1] = 0;
+
+	for (i = 0, p = 1; i < 10; ++i) {
+		rco_tab[i] = p;
+
+		p = (p << 1) ^ (p & 0x80 ? 0x01b : 0);
+	}
+
+	for (i = 0; i < 256; ++i) {
+		p = (i ? pow_tab[255 - log_tab[i]] : 0);
+		q = ((p >> 7) | (p << 1)) ^ ((p >> 6) | (p << 2));
+		p ^= 0x63 ^ q ^ ((q >> 6) | (q << 2));
+		sbx_tab[i] = p;
+		isb_tab[p] = (u8) i;
+	}
+
+	for (i = 0; i < 256; ++i) {
+		p = sbx_tab[i];
+
+		t = p;
+		fl_tab[0][i] = t;
+		fl_tab[1][i] = rotl (t, 8);
+		fl_tab[2][i] = rotl (t, 16);
+		fl_tab[3][i] = rotl (t, 24);
+
+		t = ((u32) ff_mult (2, p)) |
+		    ((u32) p << 8) |
+		    ((u32) p << 16) | ((u32) ff_mult (3, p) << 24);
+
+		ft_tab[0][i] = t;
+		ft_tab[1][i] = rotl (t, 8);
+		ft_tab[2][i] = rotl (t, 16);
+		ft_tab[3][i] = rotl (t, 24);
+
+		p = isb_tab[i];
+
+		t = p;
+		il_tab[0][i] = t;
+		il_tab[1][i] = rotl (t, 8);
+		il_tab[2][i] = rotl (t, 16);
+		il_tab[3][i] = rotl (t, 24);
+
+		t = ((u32) ff_mult (14, p)) |
+		    ((u32) ff_mult (9, p) << 8) |
+		    ((u32) ff_mult (13, p) << 16) |
+		    ((u32) ff_mult (11, p) << 24);
+
+		it_tab[0][i] = t;
+		it_tab[1][i] = rotl (t, 8);
+		it_tab[2][i] = rotl (t, 16);
+		it_tab[3][i] = rotl (t, 24);
+	}
+}
+
+#define star_x(x) (((x) & 0x7f7f7f7f) << 1) ^ ((((x) & 0x80808080) >> 7) * 0x1b)
+
+#define imix_col(y,x)       \
+    u   = star_x(x);        \
+    v   = star_x(u);        \
+    w   = star_x(v);        \
+    t   = w ^ (x);          \
+   (y)  = u ^ v ^ w;        \
+   (y) ^= rotr(u ^ t,  8) ^ \
+          rotr(v ^ t, 16) ^ \
+          rotr(t,24)
+
+// initialise the key schedule from the user supplied key
+
+#define loop4(i)                                    \
+{   t = rotr(t,  8); t = ls_box(t) ^ rco_tab[i];    \
+    t ^= E_KEY[4 * i];     E_KEY[4 * i + 4] = t;    \
+    t ^= E_KEY[4 * i + 1]; E_KEY[4 * i + 5] = t;    \
+    t ^= E_KEY[4 * i + 2]; E_KEY[4 * i + 6] = t;    \
+    t ^= E_KEY[4 * i + 3]; E_KEY[4 * i + 7] = t;    \
+}
+
+#define loop6(i)                                    \
+{   t = rotr(t,  8); t = ls_box(t) ^ rco_tab[i];    \
+    t ^= E_KEY[6 * i];     E_KEY[6 * i + 6] = t;    \
+    t ^= E_KEY[6 * i + 1]; E_KEY[6 * i + 7] = t;    \
+    t ^= E_KEY[6 * i + 2]; E_KEY[6 * i + 8] = t;    \
+    t ^= E_KEY[6 * i + 3]; E_KEY[6 * i + 9] = t;    \
+    t ^= E_KEY[6 * i + 4]; E_KEY[6 * i + 10] = t;   \
+    t ^= E_KEY[6 * i + 5]; E_KEY[6 * i + 11] = t;   \
+}
+
+#define loop8(i)                                    \
+{   t = rotr(t,  8); ; t = ls_box(t) ^ rco_tab[i];  \
+    t ^= E_KEY[8 * i];     E_KEY[8 * i + 8] = t;    \
+    t ^= E_KEY[8 * i + 1]; E_KEY[8 * i + 9] = t;    \
+    t ^= E_KEY[8 * i + 2]; E_KEY[8 * i + 10] = t;   \
+    t ^= E_KEY[8 * i + 3]; E_KEY[8 * i + 11] = t;   \
+    t  = E_KEY[8 * i + 4] ^ ls_box(t);    \
+    E_KEY[8 * i + 12] = t;                \
+    t ^= E_KEY[8 * i + 5]; E_KEY[8 * i + 13] = t;   \
+    t ^= E_KEY[8 * i + 6]; E_KEY[8 * i + 14] = t;   \
+    t ^= E_KEY[8 * i + 7]; E_KEY[8 * i + 15] = t;   \
+}
+
+static int
+aes_set_key (struct cipher_context *cx, const unsigned char *in_key,
+	     int key_len, int atomic)
+{
+	u32 i, t, u, v, w;
+	u32 k_len;
+
+	if (key_len != 16 && key_len != 24 && key_len != 32)
+		return -EINVAL;	/* unsupported key length */
+
+	k_len = (key_len * 8 + 31) / 32;
+	cx->key_length = k_len * 4;
+
+	E_KEY[0] = u32_in (in_key);
+	E_KEY[1] = u32_in (in_key + 4);
+	E_KEY[2] = u32_in (in_key + 8);
+	E_KEY[3] = u32_in (in_key + 12);
+
+	switch (k_len) {
+	case 4:
+		t = E_KEY[3];
+		for (i = 0; i < 10; ++i)
+			loop4 (i);
+		break;
+
+	case 6:
+		E_KEY[4] = u32_in (in_key + 16);
+		t = E_KEY[5] = u32_in (in_key + 20);
+		for (i = 0; i < 8; ++i)
+			loop6 (i);
+		break;
+
+	case 8:
+		E_KEY[4] = u32_in (in_key + 16);
+		E_KEY[5] = u32_in (in_key + 20);
+		E_KEY[6] = u32_in (in_key + 24);
+		t = E_KEY[7] = u32_in (in_key + 28);
+		for (i = 0; i < 7; ++i)
+			loop8 (i);
+		break;
+	}
+
+	D_KEY[0] = E_KEY[0];
+	D_KEY[1] = E_KEY[1];
+	D_KEY[2] = E_KEY[2];
+	D_KEY[3] = E_KEY[3];
+
+	for (i = 4; i < 4 * k_len + 24; ++i) {
+		imix_col (D_KEY[i], E_KEY[i]);
+	}
+
+	return 0;
+}
+
+// encrypt a block of text
+
+#define f_nround(bo, bi, k) \
+    f_rn(bo, bi, 0, k);     \
+    f_rn(bo, bi, 1, k);     \
+    f_rn(bo, bi, 2, k);     \
+    f_rn(bo, bi, 3, k);     \
+    k += 4
+
+#define f_lround(bo, bi, k) \
+    f_rl(bo, bi, 0, k);     \
+    f_rl(bo, bi, 1, k);     \
+    f_rl(bo, bi, 2, k);     \
+    f_rl(bo, bi, 3, k)
+
+static int
+aes_encrypt (struct cipher_context *cx,
+	     const u8 *in, u8 *out, int size, int atomic)
+{
+	u32 b0[4], b1[4], *kp;
+	u32 k_len = cx->key_length >> 2;
+
+	b0[0] = u32_in (in) ^ E_KEY[0];
+	b0[1] = u32_in (in + 4) ^ E_KEY[1];
+	b0[2] = u32_in (in + 8) ^ E_KEY[2];
+	b0[3] = u32_in (in + 12) ^ E_KEY[3];
+
+	kp = E_KEY + 4;
+
+	if (k_len > 6) {
+		f_nround (b1, b0, kp);
+		f_nround (b0, b1, kp);
+	}
+
+	if (k_len > 4) {
+		f_nround (b1, b0, kp);
+		f_nround (b0, b1, kp);
+	}
+
+	f_nround (b1, b0, kp);
+	f_nround (b0, b1, kp);
+	f_nround (b1, b0, kp);
+	f_nround (b0, b1, kp);
+	f_nround (b1, b0, kp);
+	f_nround (b0, b1, kp);
+	f_nround (b1, b0, kp);
+	f_nround (b0, b1, kp);
+	f_nround (b1, b0, kp);
+	f_lround (b0, b1, kp);
+
+	u32_out (out, b0[0]);
+	u32_out (out + 4, b0[1]);
+	u32_out (out + 8, b0[2]);
+	u32_out (out + 12, b0[3]);
+
+	return 0;
+}
+
+// decrypt a block of text
+
+#define i_nround(bo, bi, k) \
+    i_rn(bo, bi, 0, k);     \
+    i_rn(bo, bi, 1, k);     \
+    i_rn(bo, bi, 2, k);     \
+    i_rn(bo, bi, 3, k);     \
+    k -= 4
+
+#define i_lround(bo, bi, k) \
+    i_rl(bo, bi, 0, k);     \
+    i_rl(bo, bi, 1, k);     \
+    i_rl(bo, bi, 2, k);     \
+    i_rl(bo, bi, 3, k)
+
+static int
+aes_decrypt (struct cipher_context *cx,
+	     const u8 *in, u8 *out, int size, int atomic)
+{
+	u32 b0[4], b1[4], *kp;
+	u32 k_len = cx->key_length >> 2;
+
+	b0[0] = u32_in (in) ^ E_KEY[4 * k_len + 24];
+	b0[1] = u32_in (in + 4) ^ E_KEY[4 * k_len + 25];
+	b0[2] = u32_in (in + 8) ^ E_KEY[4 * k_len + 26];
+	b0[3] = u32_in (in + 12) ^ E_KEY[4 * k_len + 27];
+
+	kp = D_KEY + 4 * (k_len + 5);
+
+	if (k_len > 6) {
+		i_nround (b1, b0, kp);
+		i_nround (b0, b1, kp);
+	}
+
+	if (k_len > 4) {
+		i_nround (b1, b0, kp);
+		i_nround (b0, b1, kp);
+	}
+
+	i_nround (b1, b0, kp);
+	i_nround (b0, b1, kp);
+	i_nround (b1, b0, kp);
+	i_nround (b0, b1, kp);
+	i_nround (b1, b0, kp);
+	i_nround (b0, b1, kp);
+	i_nround (b1, b0, kp);
+	i_nround (b0, b1, kp);
+	i_nround (b1, b0, kp);
+	i_lround (b0, b1, kp);
+
+	u32_out (out, b0[0]);
+	u32_out (out + 4, b0[1]);
+	u32_out (out + 8, b0[2]);
+	u32_out (out + 12, b0[3]);
+
+	return 0;
+}
+
+static void
+aes_lock (void)
+{
+	MOD_INC_USE_COUNT;
+}
+
+static void
+aes_unlock (void)
+{
+	MOD_DEC_USE_COUNT;
+}
+
+#define CIPHER_BITS_128
+#define CIPHER_NAME(x) aes##x
+#include "gen-cbc.h"
+#include "gen-ecb.h"
+
+#define AES_KEY_SCHEDULE_SIZE ((60+60)*sizeof(u32))
+
+static struct cipher_implementation aes_ecb = {
+	{{NULL, NULL}, CIPHER_MODE_ECB, "aes-ecb"},
+      blocksize:16,
+      ivsize:0,
+      key_schedule_size:AES_KEY_SCHEDULE_SIZE,
+      key_size_mask:CIPHER_KEYSIZE_128 | CIPHER_KEYSIZE_192 |
+	    CIPHER_KEYSIZE_256,
+	INIT_CIPHER_BLKOPS (aes_ecb),
+	INIT_CIPHER_OPS (aes)
+};
+
+static struct cipher_implementation aes_cbc = {
+	{{NULL, NULL}, CIPHER_MODE_CBC, "aes-cbc"},
+      blocksize:16,
+      ivsize:16,
+      key_schedule_size:AES_KEY_SCHEDULE_SIZE,
+      key_size_mask:CIPHER_KEYSIZE_128 | CIPHER_KEYSIZE_192 |
+	    CIPHER_KEYSIZE_256,
+	INIT_CIPHER_BLKOPS (aes_cbc),
+	INIT_CIPHER_OPS (aes)
+};
+
+static int __init
+init_aes (void)
+{
+	gen_tabs ();
+
+	if (register_cipher (&aes_ecb))
+		printk (KERN_WARNING "Couldn't register aes-ecb encryption\n");
+	if (register_cipher (&aes_cbc))
+		printk (KERN_WARNING "Couldn't register aes-cbc encryption\n");
+
+	return 0;
+}
+
+static void __exit
+cleanup_aes (void)
+{
+	if (unregister_cipher (&aes_ecb))
+		printk (KERN_WARNING
+			"Couldn't unregister aes-ecb encryption\n");
+	if (unregister_cipher (&aes_cbc))
+		printk (KERN_WARNING
+			"Couldn't unregister aes-cbc encryption\n");
+}
+
+module_init (init_aes);
+module_exit (cleanup_aes);
diff -Nur linux-2.4.10/crypto/cipher-blowfish.c linux-int-2.4.10/crypto/cipher-blowfish.c
--- linux-2.4.10/crypto/cipher-blowfish.c	Thu Jan  1 01:00:00 1970
+++ linux-int-2.4.10/crypto/cipher-blowfish.c	Sat Sep 29 11:16:54 2001
@@ -0,0 +1,520 @@
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <asm/byteorder.h>
+#include <linux/crypto.h>
+
+#define Bswap(x) __le32_to_cpu(x)
+
+static u32 bf_pbox[16 + 2] = {
+	0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
+	0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
+	0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
+	0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
+	0x9216d5d9, 0x8979fb1b,
+};
+
+static u32 bf_sbox[256 * 4] = {
+	0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
+	0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
+	0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
+	0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
+	0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
+	0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
+	0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
+	0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
+	0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
+	0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
+	0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
+	0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
+	0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
+	0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
+	0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
+	0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
+	0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
+	0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
+	0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
+	0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
+	0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
+	0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
+	0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
+	0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
+	0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
+	0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
+	0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
+	0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
+	0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
+	0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
+	0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
+	0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
+	0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
+	0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
+	0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
+	0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
+	0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
+	0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
+	0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
+	0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
+	0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
+	0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
+	0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
+	0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
+	0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
+	0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
+	0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
+	0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
+	0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
+	0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
+	0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
+	0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
+	0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
+	0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
+	0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
+	0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
+	0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
+	0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
+	0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
+	0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
+	0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
+	0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
+	0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
+	0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a,
+	0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
+	0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
+	0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
+	0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
+	0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
+	0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
+	0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
+	0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
+	0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
+	0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
+	0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
+	0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
+	0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
+	0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
+	0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
+	0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
+	0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
+	0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
+	0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
+	0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
+	0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
+	0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
+	0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
+	0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
+	0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
+	0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
+	0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
+	0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
+	0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
+	0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
+	0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
+	0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
+	0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
+	0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
+	0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
+	0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
+	0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
+	0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
+	0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
+	0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
+	0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
+	0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
+	0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
+	0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
+	0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
+	0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
+	0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
+	0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
+	0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
+	0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
+	0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
+	0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
+	0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
+	0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
+	0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
+	0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
+	0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
+	0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
+	0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
+	0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
+	0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
+	0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
+	0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
+	0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7,
+	0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
+	0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
+	0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
+	0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
+	0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
+	0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
+	0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
+	0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
+	0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
+	0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
+	0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
+	0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
+	0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
+	0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
+	0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
+	0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
+	0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
+	0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
+	0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
+	0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
+	0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
+	0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
+	0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
+	0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
+	0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
+	0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
+	0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
+	0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
+	0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
+	0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
+	0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
+	0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
+	0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
+	0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
+	0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
+	0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
+	0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
+	0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
+	0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
+	0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
+	0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
+	0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
+	0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
+	0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
+	0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
+	0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
+	0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
+	0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
+	0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
+	0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
+	0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
+	0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
+	0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
+	0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
+	0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
+	0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
+	0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
+	0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
+	0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
+	0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
+	0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
+	0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
+	0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
+	0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0,
+	0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
+	0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
+	0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
+	0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
+	0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
+	0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
+	0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
+	0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
+	0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
+	0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
+	0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
+	0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
+	0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
+	0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
+	0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
+	0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
+	0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
+	0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
+	0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
+	0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
+	0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
+	0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
+	0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
+	0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
+	0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
+	0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
+	0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
+	0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
+	0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
+	0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
+	0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
+	0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
+	0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
+	0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
+	0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
+	0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
+	0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
+	0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
+	0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
+	0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
+	0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
+	0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
+	0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
+	0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
+	0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
+	0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
+	0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
+	0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
+	0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
+	0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
+	0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
+	0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
+	0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
+	0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
+	0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
+	0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
+	0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
+	0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
+	0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
+	0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
+	0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
+	0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
+	0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
+	0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6,
+};
+
+typedef struct blow_key {
+	u32 P[18];
+	u32 S[1024];
+} blow_key;
+
+/* 
+ * Round loop unrolling macros, S is a pointer to a S-Box array
+ * organized in 4 unsigned longs at a row.
+ */
+
+#define GET32_3(x) (((x) & 0xff))
+#define GET32_2(x) (((x) >> (8)) & (0xff))
+#define GET32_1(x) (((x) >> (16)) & (0xff))
+#define GET32_0(x) (((x) >> (24)) & (0xff))
+
+#define bf_F(x) (((S[GET32_0(x)] + S[256 + GET32_1(x)]) ^ \
+          S[512 + GET32_2(x)]) + S[768 + GET32_3(x)])
+
+#define ROUND(a, b, n) b^=P[n];a ^= bf_F(b)
+
+/*
+ * The blowfish encipher, processes 64-bit blocks.
+ * NOTE: This function MUSTN'T respect endianess 
+ */
+
+int
+blowfish_encrypt (struct cipher_context *cx,
+		  const u8 * in8, u8 * out8, int size, int atomic)
+{
+	blow_key *key = (blow_key *) cx->keyinfo;
+	u32 *in_blk = (u32 *) in8;
+	u32 *out_blk = (u32 *) out8;
+
+	u32 yl, yr;
+
+	u32 *P = key->P;
+	u32 *S = key->S;
+
+	for (; size >= 8; size -= 8) {
+		yl = *(in_blk++);
+		yr = *(in_blk++);
+
+		ROUND (yr, yl, 0);
+		ROUND (yl, yr, 1);
+		ROUND (yr, yl, 2);
+		ROUND (yl, yr, 3);
+		ROUND (yr, yl, 4);
+		ROUND (yl, yr, 5);
+		ROUND (yr, yl, 6);
+		ROUND (yl, yr, 7);
+		ROUND (yr, yl, 8);
+		ROUND (yl, yr, 9);
+		ROUND (yr, yl, 10);
+		ROUND (yl, yr, 11);
+		ROUND (yr, yl, 12);
+		ROUND (yl, yr, 13);
+		ROUND (yr, yl, 14);
+		ROUND (yl, yr, 15);
+
+		/* yl and yr are switched */
+		yl ^= P[16];
+		yr ^= P[17];
+
+		*(out_blk++) = yr;
+		*(out_blk++) = yl;
+	}
+	return 0;
+}
+
+int
+blowfish_decrypt (struct cipher_context *cx,
+		  const u8 * in8, u8 * out8, int size, int atomic)
+{
+	blow_key *key = (blow_key *) cx->keyinfo;
+	u32 *in_blk = (u32 *) in8;
+	u32 *out_blk = (u32 *) out8;
+
+	u32 yl, yr;
+
+	u32 *P = key->P;
+	u32 *S = key->S;
+
+	for (; size >= 8; size -= 8) {
+		yl = *(in_blk++);
+		yr = *(in_blk++);
+
+		ROUND (yr, yl, 17);
+		ROUND (yl, yr, 16);
+		ROUND (yr, yl, 15);
+		ROUND (yl, yr, 14);
+		ROUND (yr, yl, 13);
+		ROUND (yl, yr, 12);
+		ROUND (yr, yl, 11);
+		ROUND (yl, yr, 10);
+		ROUND (yr, yl, 9);
+		ROUND (yl, yr, 8);
+		ROUND (yr, yl, 7);
+		ROUND (yl, yr, 6);
+		ROUND (yr, yl, 5);
+		ROUND (yl, yr, 4);
+		ROUND (yr, yl, 3);
+		ROUND (yl, yr, 2);
+
+		/* yl and yr are switched */
+		yl ^= P[1];
+		yr ^= P[0];
+
+		*(out_blk++) = yr;
+		*(out_blk++) = yl;
+	}
+	return 0;
+}
+
+/* Sets the blowfish S and P boxes for encryption and decryption. */
+
+int
+blowfish_set_key (struct cipher_context *cx,
+		  const unsigned char *key, int key_len, int atomic)
+{
+	blow_key *key2 = (blow_key *) cx->keyinfo;
+	short i;
+	short j;
+	short count;
+	u32 data[2];
+	u32 temp;
+	u32 *P = key2->P;
+	u32 *S = key2->S;
+
+	/* Check key length. */
+
+	if (key_len != 8 && key_len != 16 && key_len != 20 && key_len != 24 && key_len != 32)
+		return -EINVAL; /* unsupported key length */
+
+	/* Copy the initialization s-boxes */
+
+	for (i = 0, count = 0; i < 256; i++)
+		for (j = 0; j < 4; j++, count++)
+			S[count] = bf_sbox[count];
+
+	/* Set the p-boxes */
+
+	for (i = 0; i < 16 + 2; i++)
+		P[i] = bf_pbox[i];
+
+	/* Actual subkey generation */
+
+	for (j = 0, i = 0; i < 16 + 2; i++) {
+		temp = (((u32) key[j] << 24) |
+			((u32) key[(j + 1) % key_len] << 16) |
+			((u32) key[(j + 2) % key_len] << 8) |
+			((u32) key[(j + 3) % key_len]));
+
+		P[i] = P[i] ^ temp;
+		j = (j + 4) % key_len;
+	}
+
+	data[0] = 0x00000000;
+	data[1] = 0x00000000;
+
+	for (i = 0; i < 16 + 2; i += 2) {
+		blowfish_encrypt (cx, (u8 *) data, (u8 *) data, 8, atomic);
+
+		P[i] = data[0];
+		P[i + 1] = data[1];
+	}
+
+	for (i = 0; i < 4; i++) {
+		for (j = 0, count = i * 256; j < 256; j += 2, count += 2) {
+			blowfish_encrypt (cx, (u8 *) data, (u8 *) data, 8,
+					  atomic);
+
+			S[count] = data[0];
+			S[count + 1] = data[1];
+		}
+	}
+	return 0;
+}
+
+static void
+blowfish_lock (void)
+{
+	MOD_INC_USE_COUNT;
+}
+
+static void
+blowfish_unlock (void)
+{
+	MOD_DEC_USE_COUNT;
+}
+
+#define CIPHER_BITS_64
+#define CIPHER_NAME(x) blowfish##x
+#include "gen-cbc.h"
+#include "gen-ecb.h"
+
+#define BLOWFISH_KEY_SCHEDULE_SIZE ((18+1024)*sizeof(u32))
+
+static struct cipher_implementation blowfish_ecb = {
+	{{NULL, NULL}, CIPHER_MODE_ECB, "blowfish-ecb"},
+      blocksize:8,
+      ivsize:0,
+      key_schedule_size:sizeof (blow_key),
+      key_size_mask:CIPHER_KEYSIZE_128 | CIPHER_KEYSIZE_160 |
+	    CIPHER_KEYSIZE_192 | CIPHER_KEYSIZE_256,
+	INIT_CIPHER_BLKOPS (blowfish_ecb),
+	INIT_CIPHER_OPS (blowfish)
+};
+
+static struct cipher_implementation blowfish_cbc = {
+	{{NULL, NULL}, CIPHER_MODE_CBC, "blowfish-cbc"},
+      blocksize:8,
+      ivsize:8,
+      key_schedule_size:sizeof (blow_key),
+      key_size_mask:CIPHER_KEYSIZE_128 | CIPHER_KEYSIZE_160 |
+	    CIPHER_KEYSIZE_192 | CIPHER_KEYSIZE_256,
+	INIT_CIPHER_BLKOPS (blowfish_cbc),
+	INIT_CIPHER_OPS (blowfish)
+};
+
+static int __init
+init_blowfish (void)
+{
+	if (register_cipher (&blowfish_ecb))
+		printk (KERN_WARNING
+			"Couldn't register blowfish-ecb encryption\n");
+	if (register_cipher (&blowfish_cbc))
+		printk (KERN_WARNING
+			"Couldn't register blowfish-cbc encryption\n");
+
+	return 0;
+}
+
+static void __exit
+cleanup_blowfish (void)
+{
+	if (unregister_cipher (&blowfish_ecb))
+		printk (KERN_WARNING
+			"Couldn't unregister blowfish-ecb encryption\n");
+	if (unregister_cipher (&blowfish_cbc))
+		printk (KERN_WARNING
+			"Couldn't unregister blowfish-cbc encryption\n");
+}
+
+module_init (init_blowfish);
+module_exit (cleanup_blowfish);
diff -Nur linux-2.4.10/crypto/cipher-des-ede3.c linux-int-2.4.10/crypto/cipher-des-ede3.c
--- linux-2.4.10/crypto/cipher-des-ede3.c	Thu Jan  1 01:00:00 1970
+++ linux-int-2.4.10/crypto/cipher-des-ede3.c	Sat Sep 29 11:16:54 2001
@@ -0,0 +1,1325 @@
+
+/*
+ * triple DES (DES EDE3) created from kerneli DES implementation by
+ * Gisle Sælensminde <gisle@ii.uib.no>. Original DES sourcecode created
+ * by descore. Descore is under GPL and made by Dana L. How
+ * <how@isl.stanford.edu>, and modified by Raimar Falke
+ * <rf13@inf.tu-dresden.de> for the Linux-Kernel.
+ *
+ * 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.
+ *
+ * This implementation accept 24, 16 or 8 byte keys for 3-key 3DES,
+ * 2-key 3DES or DES compatibility mode respectivly. Other key lengths
+ * are rejected. The parity bits, which is the least significant bit 
+ * of each byte are always set to the correct value.
+ *
+ * In DES there are four weak and six pairs of semi-weak keys. For 3DES 
+ * none of the keys should be weak, and no pair of semi-weak keys should 
+ * appear among the three DES subkeys. If the key is (pseudo)random, the
+ * chance of selecting a weak key is negligtable, and the test can safly
+ * be omited. Such (pseudo)random keys are usually the result of a key
+ * exchange protocol or the output of a cryptographic hash function. If
+ * the key is selected by the user, the key can not be expected to be
+ * random, and it can be desirable to check the keys. Since it's
+ * possible for a user to directly select the key bits in some
+ * applications of kerneli crypto API, we do check for weak keys.
+ *
+ * More specifically, a key is rejected if any of the DES subkeys are
+ * weak or semi-weak. This is done because we reuse the check from the
+ * original kerneli DES implementation. This function reject any key if
+ * it is weak or semi-weak. As a result we may unnecessarily reject some
+ * strong keys. In future releases this test should be improved, or
+ * better; we should not let the user select the exact key bits, and
+ * remove the need for checking.
+ *
+ * A DES_EDE3 key degenerates to DES if any of the DES subkeys K1 and
+ * K2 or K2 and K3 are equal, even we have 112 key bits. This should be
+ * avoided, unless we operate in DES compatibility mode. Again such keys
+ * are unlikely if the key is random.  To have K1 = K3 is 2-key 3DES,
+ * which not have such security problems. An exception from this policy
+ * is done for DES compatibility mode, where all three keys are equal.
+ */
+
+#include <linux/string.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <asm/byteorder.h>
+#include <linux/crypto.h>
+
+#define ROR(d,c,o)      d = d >> c | d << o
+
+typedef u8 DesData[8];
+typedef u32 DesKeys[32];
+
+static u32 des_keymap[] = {
+ 0x02080008, 0x02082000, 0x00002008, 0x00000000,
+ 0x02002000, 0x00080008, 0x02080000, 0x02082008,
+ 0x00000008, 0x02000000, 0x00082000, 0x00002008,
+ 0x00082008, 0x02002008, 0x02000008, 0x02080000,
+ 0x00002000, 0x00082008, 0x00080008, 0x02002000,
+ 0x02082008, 0x02000008, 0x00000000, 0x00082000,
+ 0x02000000, 0x00080000, 0x02002008, 0x02080008,
+ 0x00080000, 0x00002000, 0x02082000, 0x00000008,
+ 0x00080000, 0x00002000, 0x02000008, 0x02082008,
+ 0x00002008, 0x02000000, 0x00000000, 0x00082000,
+ 0x02080008, 0x02002008, 0x02002000, 0x00080008,
+ 0x02082000, 0x00000008, 0x00080008, 0x02002000,
+ 0x02082008, 0x00080000, 0x02080000, 0x02000008,
+ 0x00082000, 0x00002008, 0x02002008, 0x02080000,
+ 0x00000008, 0x02082000, 0x00082008, 0x00000000,
+ 0x02000000, 0x02080008, 0x00002000, 0x00082008,
+
+ 0x08000004, 0x00020004, 0x00000000, 0x08020200,
+ 0x00020004, 0x00000200, 0x08000204, 0x00020000,
+ 0x00000204, 0x08020204, 0x00020200, 0x08000000,
+ 0x08000200, 0x08000004, 0x08020000, 0x00020204,
+ 0x00020000, 0x08000204, 0x08020004, 0x00000000,
+ 0x00000200, 0x00000004, 0x08020200, 0x08020004,
+ 0x08020204, 0x08020000, 0x08000000, 0x00000204,
+ 0x00000004, 0x00020200, 0x00020204, 0x08000200,
+ 0x00000204, 0x08000000, 0x08000200, 0x00020204,
+ 0x08020200, 0x00020004, 0x00000000, 0x08000200,
+ 0x08000000, 0x00000200, 0x08020004, 0x00020000,
+ 0x00020004, 0x08020204, 0x00020200, 0x00000004,
+ 0x08020204, 0x00020200, 0x00020000, 0x08000204,
+ 0x08000004, 0x08020000, 0x00020204, 0x00000000,
+ 0x00000200, 0x08000004, 0x08000204, 0x08020200,
+ 0x08020000, 0x00000204, 0x00000004, 0x08020004,
+
+ 0x80040100, 0x01000100, 0x80000000, 0x81040100,
+ 0x00000000, 0x01040000, 0x81000100, 0x80040000,
+ 0x01040100, 0x81000000, 0x01000000, 0x80000100,
+ 0x81000000, 0x80040100, 0x00040000, 0x01000000,
+ 0x81040000, 0x00040100, 0x00000100, 0x80000000,
+ 0x00040100, 0x81000100, 0x01040000, 0x00000100,
+ 0x80000100, 0x00000000, 0x80040000, 0x01040100,
+ 0x01000100, 0x81040000, 0x81040100, 0x00040000,
+ 0x81040000, 0x80000100, 0x00040000, 0x81000000,
+ 0x00040100, 0x01000100, 0x80000000, 0x01040000,
+ 0x81000100, 0x00000000, 0x00000100, 0x80040000,
+ 0x00000000, 0x81040000, 0x01040100, 0x00000100,
+ 0x01000000, 0x81040100, 0x80040100, 0x00040000,
+ 0x81040100, 0x80000000, 0x01000100, 0x80040100,
+ 0x80040000, 0x00040100, 0x01040000, 0x81000100,
+ 0x80000100, 0x01000000, 0x81000000, 0x01040100,
+
+ 0x04010801, 0x00000000, 0x00010800, 0x04010000,
+ 0x04000001, 0x00000801, 0x04000800, 0x00010800,
+ 0x00000800, 0x04010001, 0x00000001, 0x04000800,
+ 0x00010001, 0x04010800, 0x04010000, 0x00000001,
+ 0x00010000, 0x04000801, 0x04010001, 0x00000800,
+ 0x00010801, 0x04000000, 0x00000000, 0x00010001,
+ 0x04000801, 0x00010801, 0x04010800, 0x04000001,
+ 0x04000000, 0x00010000, 0x00000801, 0x04010801,
+ 0x00010001, 0x04010800, 0x04000800, 0x00010801,
+ 0x04010801, 0x00010001, 0x04000001, 0x00000000,
+ 0x04000000, 0x00000801, 0x00010000, 0x04010001,
+ 0x00000800, 0x04000000, 0x00010801, 0x04000801,
+ 0x04010800, 0x00000800, 0x00000000, 0x04000001,
+ 0x00000001, 0x04010801, 0x00010800, 0x04010000,
+ 0x04010001, 0x00010000, 0x00000801, 0x04000800,
+ 0x04000801, 0x00000001, 0x04010000, 0x00010800,
+
+ 0x00000400, 0x00000020, 0x00100020, 0x40100000,
+ 0x40100420, 0x40000400, 0x00000420, 0x00000000,
+ 0x00100000, 0x40100020, 0x40000020, 0x00100400,
+ 0x40000000, 0x00100420, 0x00100400, 0x40000020,
+ 0x40100020, 0x00000400, 0x40000400, 0x40100420,
+ 0x00000000, 0x00100020, 0x40100000, 0x00000420,
+ 0x40100400, 0x40000420, 0x00100420, 0x40000000,
+ 0x40000420, 0x40100400, 0x00000020, 0x00100000,
+ 0x40000420, 0x00100400, 0x40100400, 0x40000020,
+ 0x00000400, 0x00000020, 0x00100000, 0x40100400,
+ 0x40100020, 0x40000420, 0x00000420, 0x00000000,
+ 0x00000020, 0x40100000, 0x40000000, 0x00100020,
+ 0x00000000, 0x40100020, 0x00100020, 0x00000420,
+ 0x40000020, 0x00000400, 0x40100420, 0x00100000,
+ 0x00100420, 0x40000000, 0x40000400, 0x40100420,
+ 0x40100000, 0x00100420, 0x00100400, 0x40000400,
+
+ 0x00800000, 0x00001000, 0x00000040, 0x00801042,
+ 0x00801002, 0x00800040, 0x00001042, 0x00801000,
+ 0x00001000, 0x00000002, 0x00800002, 0x00001040,
+ 0x00800042, 0x00801002, 0x00801040, 0x00000000,
+ 0x00001040, 0x00800000, 0x00001002, 0x00000042,
+ 0x00800040, 0x00001042, 0x00000000, 0x00800002,
+ 0x00000002, 0x00800042, 0x00801042, 0x00001002,
+ 0x00801000, 0x00000040, 0x00000042, 0x00801040,
+ 0x00801040, 0x00800042, 0x00001002, 0x00801000,
+ 0x00001000, 0x00000002, 0x00800002, 0x00800040,
+ 0x00800000, 0x00001040, 0x00801042, 0x00000000,
+ 0x00001042, 0x00800000, 0x00000040, 0x00001002,
+ 0x00800042, 0x00000040, 0x00000000, 0x00801042,
+ 0x00801002, 0x00801040, 0x00000042, 0x00001000,
+ 0x00001040, 0x00801002, 0x00800040, 0x00000042,
+ 0x00000002, 0x00001042, 0x00801000, 0x00800002,
+
+ 0x10400000, 0x00404010, 0x00000010, 0x10400010,
+ 0x10004000, 0x00400000, 0x10400010, 0x00004010,
+ 0x00400010, 0x00004000, 0x00404000, 0x10000000,
+ 0x10404010, 0x10000010, 0x10000000, 0x10404000,
+ 0x00000000, 0x10004000, 0x00404010, 0x00000010,
+ 0x10000010, 0x10404010, 0x00004000, 0x10400000,
+ 0x10404000, 0x00400010, 0x10004010, 0x00404000,
+ 0x00004010, 0x00000000, 0x00400000, 0x10004010,
+ 0x00404010, 0x00000010, 0x10000000, 0x00004000,
+ 0x10000010, 0x10004000, 0x00404000, 0x10400010,
+ 0x00000000, 0x00404010, 0x00004010, 0x10404000,
+ 0x10004000, 0x00400000, 0x10404010, 0x10000000,
+ 0x10004010, 0x10400000, 0x00400000, 0x10404010,
+ 0x00004000, 0x00400010, 0x10400010, 0x00004010,
+ 0x00400010, 0x00000000, 0x10404000, 0x10000010,
+ 0x10400000, 0x10004010, 0x00000010, 0x00404000,
+
+ 0x00208080, 0x00008000, 0x20200000, 0x20208080,
+ 0x00200000, 0x20008080, 0x20008000, 0x20200000,
+ 0x20008080, 0x00208080, 0x00208000, 0x20000080,
+ 0x20200080, 0x00200000, 0x00000000, 0x20008000,
+ 0x00008000, 0x20000000, 0x00200080, 0x00008080,
+ 0x20208080, 0x00208000, 0x20000080, 0x00200080,
+ 0x20000000, 0x00000080, 0x00008080, 0x20208000,
+ 0x00000080, 0x20200080, 0x20208000, 0x00000000,
+ 0x00000000, 0x20208080, 0x00200080, 0x20008000,
+ 0x00208080, 0x00008000, 0x20000080, 0x00200080,
+ 0x20208000, 0x00000080, 0x00008080, 0x20200000,
+ 0x20008080, 0x20000000, 0x20200000, 0x00208000,
+ 0x20208080, 0x00008080, 0x00208000, 0x20200080,
+ 0x00200000, 0x20000080, 0x20008000, 0x00000000,
+ 0x00008000, 0x00200000, 0x20200080, 0x00208080,
+ 0x20000000, 0x20208000, 0x00000080, 0x20008080,
+};
+
+static u8 rotors[] = {
+ 34, 13,  5, 46, 47, 18, 32, 41, 11, 53, 33, 20,
+ 14, 36, 30, 24, 49,  2, 15, 37, 42, 50,  0, 21,
+ 38, 48,  6, 26, 39,  4, 52, 25, 12, 27, 31, 40,
+  1, 17, 28, 29, 23, 51, 35,  7,  3, 22,  9, 43,
+
+ 41, 20, 12, 53, 54, 25, 39, 48, 18, 31, 40, 27,
+ 21, 43, 37,  0,  1,  9, 22, 44, 49,  2,  7, 28,
+ 45, 55, 13, 33, 46, 11,  6, 32, 19, 34, 38, 47,
+  8, 24, 35, 36, 30,  3, 42, 14, 10, 29, 16, 50,
+
+ 55, 34, 26, 38, 11, 39, 53,  5, 32, 45, 54, 41,
+ 35,  2, 51, 14, 15, 23, 36,  3,  8, 16, 21, 42,
+  6, 12, 27, 47, 31, 25, 20, 46, 33, 48, 52,  4,
+ 22,  7, 49, 50, 44, 17,  1, 28, 24, 43, 30,  9,
+
+ 12, 48, 40, 52, 25, 53, 38, 19, 46,  6, 11, 55,
+ 49, 16, 10, 28, 29, 37, 50, 17, 22, 30, 35,  1,
+ 20, 26, 41,  4, 45, 39, 34, 31, 47,  5, 13, 18,
+ 36, 21,  8,  9,  3,  0, 15, 42,  7,  2, 44, 23,
+
+ 26,  5, 54, 13, 39, 38, 52, 33, 31, 20, 25, 12,
+  8, 30, 24, 42, 43, 51,  9,  0, 36, 44, 49, 15,
+ 34, 40, 55, 18,  6, 53, 48, 45,  4, 19, 27, 32,
+ 50, 35, 22, 23, 17, 14, 29,  1, 21, 16,  3, 37,
+
+ 40, 19, 11, 27, 53, 52, 13, 47, 45, 34, 39, 26,
+ 22, 44,  7,  1,  2, 10, 23, 14, 50,  3,  8, 29,
+ 48, 54, 12, 32, 20, 38,  5,  6, 18, 33, 41, 46,
+  9, 49, 36, 37,  0, 28, 43, 15, 35, 30, 17, 51,
+
+ 54, 33, 25, 41, 38, 13, 27,  4,  6, 48, 53, 40,
+ 36,  3, 21, 15, 16, 24, 37, 28,  9, 17, 22, 43,
+  5, 11, 26, 46, 34, 52, 19, 20, 32, 47, 55, 31,
+ 23,  8, 50, 51, 14, 42,  2, 29, 49, 44,  0, 10,
+
+ 11, 47, 39, 55, 52, 27, 41, 18, 20,  5, 38, 54,
+ 50, 17, 35, 29, 30,  7, 51, 42, 23,  0, 36,  2,
+ 19, 25, 40, 31, 48, 13, 33, 34, 46,  4, 12, 45,
+ 37, 22,  9, 10, 28,  1, 16, 43,  8,  3, 14, 24,
+
+ 18, 54, 46,  5,  6, 34, 48, 25, 27, 12, 45,  4,
+  2, 24, 42, 36, 37, 14,  3, 49, 30,  7, 43,  9,
+ 26, 32, 47, 38, 55, 20, 40, 41, 53, 11, 19, 52,
+ 44, 29, 16, 17, 35,  8, 23, 50, 15, 10, 21,  0,
+
+ 32, 11, 31, 19, 20, 48,  5, 39, 41, 26,  6, 18,
+ 16,  7,  1, 50, 51, 28, 17,  8, 44, 21,  2, 23,
+ 40, 46,  4, 52, 12, 34, 54, 55, 38, 25, 33, 13,
+  3, 43, 30,  0, 49, 22, 37,  9, 29, 24, 35, 14,
+
+ 46, 25, 45, 33, 34,  5, 19, 53, 55, 40, 20, 32,
+ 30, 21, 15,  9, 10, 42,  0, 22,  3, 35, 16, 37,
+ 54, 31, 18, 13, 26, 48, 11, 12, 52, 39, 47, 27,
+ 17,  2, 44, 14,  8, 36, 51, 23, 43,  7, 49, 28,
+
+ 31, 39,  6, 47, 48, 19, 33, 38, 12, 54, 34, 46,
+ 44, 35, 29, 23, 24,  1, 14, 36, 17, 49, 30, 51,
+ 11, 45, 32, 27, 40,  5, 25, 26, 13, 53,  4, 41,
+  0, 16,  3, 28, 22, 50, 10, 37,  2, 21,  8, 42,
+
+ 45, 53, 20,  4,  5, 33, 47, 52, 26, 11, 48, 31,
+  3, 49, 43, 37,  7, 15, 28, 50,  0,  8, 44, 10,
+ 25,  6, 46, 41, 54, 19, 39, 40, 27, 38, 18, 55,
+ 14, 30, 17, 42, 36,  9, 24, 51, 16, 35, 22,  1,
+
+  6, 38, 34, 18, 19, 47,  4, 13, 40, 25,  5, 45,
+ 17,  8,  2, 51, 21, 29, 42,  9, 14, 22,  3, 24,
+ 39, 20, 31, 55, 11, 33, 53, 54, 41, 52, 32, 12,
+ 28, 44,  0,  1, 50, 23,  7, 10, 30, 49, 36, 15,
+
+ 20, 52, 48, 32, 33,  4, 18, 27, 54, 39, 19,  6,
+  0, 22, 16, 10, 35, 43,  1, 23, 28, 36, 17,  7,
+ 53, 34, 45, 12, 25, 47, 38, 11, 55, 13, 46, 26,
+ 42,  3, 14, 15,  9, 37, 21, 24, 44,  8, 50, 29,
+
+ 27,  6, 55, 39, 40, 11, 25, 34,  4, 46, 26, 13,
+  7, 29, 23, 17, 42, 50,  8, 30, 35, 43, 24, 14,
+ 31, 41, 52, 19, 32, 54, 45, 18,  5, 20, 53, 33,
+ 49, 10, 21, 22, 16, 44, 28,  0, 51, 15,  2, 36,
+};
+
+static char parity[] = {
+8,1,0,8,0,8,8,0,0,8,8,0,8,0,2,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,3,
+0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,
+0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,
+8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,
+0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,
+8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,
+8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,
+4,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,5,0,8,0,8,8,0,0,8,8,0,8,0,6,8,
+};
+
+static int des_part_set_key(u32 *method, const unsigned char *key);
+
+static int des_ede3_set_key(struct cipher_context *cx, 
+			    const unsigned char *key, int keybytes, int atomic)
+{
+    u32 *method;
+    int status,i;
+    unsigned char lkey[24];
+    unsigned char n1, n2;
+    method=(u32 *)cx->keyinfo;
+    
+    /* asign keybits based on keylength */
+    switch(keybytes) {
+    case 24:
+	    memcpy(lkey,key,24);
+	    break;
+    case 16:
+	    memcpy(lkey,key,16);
+	    memcpy(lkey+16,key,8);
+	    break;
+    case 8:
+	    memcpy(lkey,key,8);
+	    memcpy(lkey+8,key,8);
+	    memcpy(lkey+16,key,8);
+	    break;
+    default:
+	    return -EINVAL;
+    }
+
+    /* set the correct parity bit for each byte in the key*/
+    for(i=0; i<24; i++){
+	    n1 = lkey[i] & 0xfe;
+	    n2 = n1 ^ (n1 >> 4);
+	    n2 ^= (n2 >> 2);
+	    n2 ^= (n2 >> 1);
+	    lkey[i] = n1 | (~n2 & 0x01);	    
+    }
+    
+    /* check for degenerate keys */
+    if(keybytes > 8 &&
+       (memcmp(lkey,lkey+8,8)==0 || memcmp(lkey+8,lkey+16,8)==0))
+	    return -2;
+
+    if((status = des_part_set_key(method, lkey)) != 0) 
+	    return status;
+    if((status = des_part_set_key(method+32, lkey+8)) != 0) 
+	    return status;
+    if((status = des_part_set_key(method+64, lkey+16)) != 0) 
+	    return status;
+    
+    return 0;
+}
+
+static int des_part_set_key(u32 *method, const unsigned char *key)
+{
+    register u32 n, w;
+    register char * b0, * b1;
+    char bits0[56], bits1[56];
+
+    /* check for weak keys */
+    b0 = parity;
+    n  = b0[key[0]]; n <<= 4;
+    n |= b0[key[1]]; n <<= 4;
+    n |= b0[key[2]]; n <<= 4;
+    n |= b0[key[3]]; n <<= 4;
+    n |= b0[key[4]]; n <<= 4;
+    n |= b0[key[5]]; n <<= 4;
+    n |= b0[key[6]]; n <<= 4;
+    n |= b0[key[7]];
+    w  = 0X88888888L;
+    if ( !((n - (w >> 3)) & w) ) {  /* 1 in 10^10 keys passes this test */
+	  if ( n < 0X41415151 ) {
+            if ( n < 0X31312121 ) {
+                if ( n < 0X14141515 ) {
+                    /* 01 01 01 01 01 01 01 01 */
+                    if ( n == 0X11111111 ) return -2;
+                    /* 01 1F 01 1F 01 0E 01 0E */
+                    if ( n == 0X13131212 ) return -2;
+                } else {
+                    /* 01 E0 01 E0 01 F1 01 F1 */
+                    if ( n == 0X14141515 ) return -2;
+                    /* 01 FE 01 FE 01 FE 01 FE */
+                    if ( n == 0X16161616 ) return -2;
+                }
+            } else {
+                if ( n < 0X34342525 ) {
+                    /* 1F 01 1F 01 0E 01 0E 01 */
+                    if ( n == 0X31312121 ) return -2;
+                    /* 1F 1F 1F 1F 0E 0E 0E 0E */   /* ? */
+                    if ( n == 0X33332222 ) return -2;
+                } else {
+                    /* 1F E0 1F E0 0E F1 0E F1 */
+                    if ( n == 0X34342525 ) return -2;
+                    /* 1F FE 1F FE 0E FE 0E FE */
+                    if ( n == 0X36362626 ) return -2;
+                }
+            }
+        } else {
+            if ( n < 0X61616161 ) {
+                if ( n < 0X44445555 ) {
+                    /* E0 01 E0 01 F1 01 F1 01 */
+                    if ( n == 0X41415151 ) return -2;
+                    /* E0 1F E0 1F F1 0E F1 0E */
+                    if ( n == 0X43435252 ) return -2;
+                } else {
+                    /* E0 E0 E0 E0 F1 F1 F1 F1 */   /* ? */
+                    if ( n == 0X44445555 ) return -2;
+                    /* E0 FE E0 FE F1 FE F1 FE */
+                    if ( n == 0X46465656 ) return -2;
+                }
+            } else {
+                if ( n < 0X64646565 ) {
+                    /* FE 01 FE 01 FE 01 FE 01 */
+                    if ( n == 0X61616161 ) return -2;
+                    /* FE 1F FE 1F FE 0E FE 0E */
+                    if ( n == 0X63636262 ) return -2;
+                } else {
+                    /* FE E0 FE E0 FE F1 FE F1 */
+                    if ( n == 0X64646565 ) return -2;
+                    /* FE FE FE FE FE FE FE FE */
+                    if ( n == 0X66666666 ) return -2;
+                }
+            }
+        }
+    }
+
+    /* explode the bits */
+    n = 56;
+    b0 = bits0;
+    b1 = bits1;
+    do {
+        w = (256 | *key++) << 2;
+        do {
+            --n;
+            b1[n] = 8 & w;
+            w >>= 1;
+            b0[n] = 4 & w;
+        } while ( w >= 16 );
+    } while ( n );
+
+    /* put the bits in the correct places */
+    n = 16;
+    key = rotors;
+    do {
+        w   = (b1[key[ 0   ]] | b0[key[ 1   ]]) << 4;
+        w  |= (b1[key[ 2   ]] | b0[key[ 3   ]]) << 2;
+        w  |=  b1[key[ 4   ]] | b0[key[ 5   ]];
+        w <<= 8;
+        w  |= (b1[key[ 6   ]] | b0[key[ 7   ]]) << 4;
+        w  |= (b1[key[ 8   ]] | b0[key[ 9   ]]) << 2;
+        w  |=  b1[key[10   ]] | b0[key[11   ]];
+        w <<= 8;
+        w  |= (b1[key[12   ]] | b0[key[13   ]]) << 4;
+        w  |= (b1[key[14   ]] | b0[key[15   ]]) << 2;
+        w  |=  b1[key[16   ]] | b0[key[17   ]];
+        w <<= 8;
+        w  |= (b1[key[18   ]] | b0[key[19   ]]) << 4;
+        w  |= (b1[key[20   ]] | b0[key[21   ]]) << 2;
+        w  |=  b1[key[22   ]] | b0[key[23   ]];
+
+        method[0] = w;
+
+        w   = (b1[key[ 0+24]] | b0[key[ 1+24]]) << 4;
+        w  |= (b1[key[ 2+24]] | b0[key[ 3+24]]) << 2;
+        w  |=  b1[key[ 4+24]] | b0[key[ 5+24]];
+        w <<= 8;
+        w  |= (b1[key[ 6+24]] | b0[key[ 7+24]]) << 4;
+        w  |= (b1[key[ 8+24]] | b0[key[ 9+24]]) << 2;
+        w  |=  b1[key[10+24]] | b0[key[11+24]];
+        w <<= 8;
+        w  |= (b1[key[12+24]] | b0[key[13+24]]) << 4;
+        w  |= (b1[key[14+24]] | b0[key[15+24]]) << 2;
+        w  |=  b1[key[16+24]] | b0[key[17+24]];
+        w <<= 8;
+        w  |= (b1[key[18+24]] | b0[key[19+24]]) << 4;
+        w  |= (b1[key[20+24]] | b0[key[21+24]]) << 2;
+        w  |=  b1[key[22+24]] | b0[key[23+24]];
+
+        ROR(w, 4, 28);      /* could be eliminated */
+        method[1] = w;
+
+        key += 48;
+        method  += 2;
+    } while ( --n );
+    return 0;
+}
+
+static void DesSmallFipsEncrypt (DesData d, DesKeys r, DesData s)
+{
+    register u32 x, y, z;
+
+    x  = s [7];
+    x <<= 8;
+    x |= s [6];
+    x <<= 8;
+    x |= s [5];
+    x <<= 8;
+    x |= s [4];
+    y  = s [3];
+    y <<= 8;
+    y |= s [2];
+    y <<= 8;
+    y |= s [1];
+    y <<= 8;
+    y |= s [0];
+    z  = ((x >> 004) ^ y) & 0X0F0F0F0FL;
+    x ^= z << 004;
+    y ^= z;
+    z  = ((y >> 020) ^ x) & 0X0000FFFFL;
+    y ^= z << 020;
+    x ^= z;
+    z  = ((x >> 002) ^ y) & 0X33333333L;
+    x ^= z << 002;
+    y ^= z;
+    z  = ((y >> 010) ^ x) & 0X00FF00FFL;
+    y ^= z << 010;
+    x ^= z;
+    x  = x >> 1 | x << 31;
+    z  = (x ^ y) & 0X55555555L;
+    y ^= z;
+    x ^= z;
+    y  = y >> 1 | y << 31;
+    z  = r [0];
+    z ^= y;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [1];
+    z ^= y;
+    z  = z << 4 | z >> 28;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [2];
+    z ^= x;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [3];
+    z ^= x;
+    z  = z << 4 | z >> 28;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [4];
+    z ^= y;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [5];
+    z ^= y;
+    z  = z << 4 | z >> 28;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [6];
+    z ^= x;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [7];
+    z ^= x;
+    z  = z << 4 | z >> 28;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [8];
+    z ^= y;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [9];
+    z ^= y;
+    z  = z << 4 | z >> 28;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [10];
+    z ^= x;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [11];
+    z ^= x;
+    z  = z << 4 | z >> 28;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [12];
+    z ^= y;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [13];
+    z ^= y;
+    z  = z << 4 | z >> 28;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [14];
+    z ^= x;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [15];
+    z ^= x;
+    z  = z << 4 | z >> 28;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [16];
+    z ^= y;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [17];
+    z ^= y;
+    z  = z << 4 | z >> 28;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [18];
+    z ^= x;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [19];
+    z ^= x;
+    z  = z << 4 | z >> 28;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [20];
+    z ^= y;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [21];
+    z ^= y;
+    z  = z << 4 | z >> 28;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [22];
+    z ^= x;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [23];
+    z ^= x;
+    z  = z << 4 | z >> 28;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [24];
+    z ^= y;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [25];
+    z ^= y;
+    z  = z << 4 | z >> 28;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [26];
+    z ^= x;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [27];
+    z ^= x;
+    z  = z << 4 | z >> 28;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [28];
+    z ^= y;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [29];
+    z ^= y;
+    z  = z << 4 | z >> 28;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [30];
+    z ^= x;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [31];
+    z ^= x;
+    z  = z << 4 | z >> 28;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    x  = x << 1 | x >> 31;
+    z  = (x ^ y) & 0X55555555L;
+    y ^= z;
+    x ^= z;
+    y  = y << 1 | y >> 31;
+    z  = ((x >> 010) ^ y) & 0X00FF00FFL;
+    x ^= z << 010;
+    y ^= z;
+    z  = ((y >> 002) ^ x) & 0X33333333L;
+    y ^= z << 002;
+    x ^= z;
+    z  = ((x >> 020) ^ y) & 0X0000FFFFL;
+    x ^= z << 020;
+    y ^= z;
+    z  = ((y >> 004) ^ x) & 0X0F0F0F0FL;
+    y ^= z << 004;
+    x ^= z;
+    d [0] = x;
+    x >>= 8;
+    d [1] = x;
+    x >>= 8;
+    d [2] = x;
+    x >>= 8;
+    d [3] = x;
+    d [4] = y;
+    y >>= 8;
+    d [5] = y;
+    y >>= 8;
+    d [6] = y;
+    y >>= 8;
+    d [7] = y;
+    return;
+}
+
+static void DesSmallFipsDecrypt (u8 *d, u32 *r, u8 *s)
+{
+    register u32 x, y, z;
+    x  = s [7];
+    x <<= 8;
+    x |= s [6];
+    x <<= 8;
+    x |= s [5];
+    x <<= 8;
+    x |= s [4];
+    y  = s [3];
+    y <<= 8;
+    y |= s [2];
+    y <<= 8;
+    y |= s [1];
+    y <<= 8;
+    y |= s [0];
+    z  = ((x >> 004) ^ y) & 0X0F0F0F0FL;
+    x ^= z << 004;
+    y ^= z;
+    z  = ((y >> 020) ^ x) & 0X0000FFFFL;
+    y ^= z << 020;
+    x ^= z;
+    z  = ((x >> 002) ^ y) & 0X33333333L;
+    x ^= z << 002;
+    y ^= z;
+    z  = ((y >> 010) ^ x) & 0X00FF00FFL;
+    y ^= z << 010;
+    x ^= z;
+    x  = x >> 1 | x << 31;
+    z  = (x ^ y) & 0X55555555L;
+    y ^= z;
+    x ^= z;
+    y  = y >> 1 | y << 31;
+    z  = r [31];
+    z ^= y;
+    z  = z << 4 | z >> 28;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [30];
+    z ^= y;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [29];
+    z ^= x;
+    z  = z << 4 | z >> 28;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [28];
+    z ^= x;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [27];
+    z ^= y;
+    z  = z << 4 | z >> 28;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [26];
+    z ^= y;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [25];
+    z ^= x;
+    z  = z << 4 | z >> 28;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [24];
+    z ^= x;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [23];
+    z ^= y;
+    z  = z << 4 | z >> 28;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [22];
+    z ^= y;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [21];
+    z ^= x;
+    z  = z << 4 | z >> 28;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [20];
+    z ^= x;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [19];
+    z ^= y;
+    z  = z << 4 | z >> 28;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [18];
+    z ^= y;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [17];
+    z ^= x;
+    z  = z << 4 | z >> 28;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [16];
+    z ^= x;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [15];
+    z ^= y;
+    z  = z << 4 | z >> 28;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [14];
+    z ^= y;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [13];
+    z ^= x;
+    z  = z << 4 | z >> 28;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [12];
+    z ^= x;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [11];
+    z ^= y;
+    z  = z << 4 | z >> 28;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [10];
+    z ^= y;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [9];
+    z ^= x;
+    z  = z << 4 | z >> 28;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [8];
+    z ^= x;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [7];
+    z ^= y;
+    z  = z << 4 | z >> 28;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [6];
+    z ^= y;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [5];
+    z ^= x;
+    z  = z << 4 | z >> 28;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [4];
+    z ^= x;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [3];
+    z ^= y;
+    z  = z << 4 | z >> 28;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [2];
+    z ^= y;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [1];
+    z ^= x;
+    z  = z << 4 | z >> 28;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [0];
+    z ^= x;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    x  = x << 1 | x >> 31;
+    z  = (x ^ y) & 0X55555555L;
+    y ^= z;
+    x ^= z;
+    y  = y << 1 | y >> 31;
+    z  = ((x >> 010) ^ y) & 0X00FF00FFL;
+    x ^= z << 010;
+    y ^= z;
+    z  = ((y >> 002) ^ x) & 0X33333333L;
+    y ^= z << 002;
+    x ^= z;
+    z  = ((x >> 020) ^ y) & 0X0000FFFFL;
+    x ^= z << 020;
+    y ^= z;
+    z  = ((y >> 004) ^ x) & 0X0F0F0F0FL;
+    y ^= z << 004;
+    x ^= z;
+    d [0] = x;
+    x >>= 8;
+    d [1] = x;
+    x >>= 8;
+    d [2] = x;
+    x >>= 8;
+    d [3] = x;
+    d [4] = y;
+    y >>= 8;
+    d [5] = y;
+    y >>= 8;
+    d [6] = y;
+    y >>= 8;
+    d [7] = y;
+    return;
+}
+
+
+static int des_ede3_encrypt(struct cipher_context *cx,
+			    const u8 *in, u8 *out, int size, int atomic)
+{
+	u8 input_buffer[8], trans_buffer1[8];
+	u8 trans_buffer2[8], output_buffer[8];
+
+	u32 *key_sched;
+
+	key_sched = cx->keyinfo;
+
+	for (; size >= 8; size -= 8) {
+		memcpy(&input_buffer, in, 8);
+		in += 8;
+		DesSmallFipsEncrypt(trans_buffer1,key_sched,input_buffer);
+		DesSmallFipsDecrypt(trans_buffer2,key_sched+32,trans_buffer1);
+		DesSmallFipsEncrypt(output_buffer,key_sched+64,trans_buffer2);
+		memcpy(out, &output_buffer, 8);
+		out += 8;
+	}
+	return 0;
+}
+
+static int des_ede3_decrypt(struct cipher_context *cx,
+			    const u8 *in, u8 *out, int size, int atomic)
+{
+  	u8 input_buffer[8], trans_buffer1[8];
+	u8 trans_buffer2[8], output_buffer[8];
+
+	u32 *key_sched;
+
+	key_sched = cx->keyinfo;
+
+	for (; size >= 8; size -= 8) {
+		memcpy(&input_buffer, in, 8);
+		in += 8;
+		DesSmallFipsDecrypt(trans_buffer1,key_sched+64,input_buffer);
+		DesSmallFipsEncrypt(trans_buffer2,key_sched+32,trans_buffer1);
+		DesSmallFipsDecrypt(output_buffer,key_sched,trans_buffer2);		
+		memcpy(out, &output_buffer, 8);
+		out += 8;
+	}
+	return 0;
+}
+
+
+static void des_ede3_lock(void)
+{
+	MOD_INC_USE_COUNT;
+}
+
+static void des_ede3_unlock(void)
+{
+	MOD_DEC_USE_COUNT;
+}   
+
+
+#define CIPHER_BITS_64
+#define CIPHER_NAME(x) des_ede3##x
+#include "gen-cbc.h"
+#include "gen-ecb.h"
+
+#define DES_EDE3_KEY_SCHEDULE_SIZE (3*32*sizeof(u32))
+
+static struct cipher_implementation des_ede3_ecb = {
+	{{NULL,NULL}, CIPHER_MODE_ECB, "des_ede3-ecb"},
+	blocksize: 8,
+	ivsize: 0,
+	key_schedule_size: DES_EDE3_KEY_SCHEDULE_SIZE,
+	key_size_mask: CIPHER_KEYSIZE_64,
+	INIT_CIPHER_BLKOPS(des_ede3_ecb),
+	INIT_CIPHER_OPS(des_ede3)
+};
+
+static struct cipher_implementation des_ede3_cbc = {
+	{{NULL,NULL}, CIPHER_MODE_CBC, "des_ede3-cbc"},
+	blocksize: 8,
+	ivsize: 8,
+	key_schedule_size: DES_EDE3_KEY_SCHEDULE_SIZE,
+	key_size_mask: CIPHER_KEYSIZE_64 | CIPHER_KEYSIZE_128 | 
+	               CIPHER_KEYSIZE_192,
+	INIT_CIPHER_BLKOPS(des_ede3_cbc),
+	INIT_CIPHER_OPS(des_ede3)
+};
+
+static int __init init_des_ede3(void)
+{
+    if (register_cipher(&des_ede3_ecb))
+        printk(KERN_WARNING "Couldn't register des_ede3-ecb encryption\n");
+    if (register_cipher(&des_ede3_cbc))
+        printk(KERN_WARNING "Couldn't register des_ede3-cbc encryption\n");
+
+    return 0;
+}
+
+static void __exit cleanup_des_ede3(void)
+{
+	if (unregister_cipher(&des_ede3_ecb))
+		printk(KERN_WARNING "Couldn't unregister des_ede3-ecb encryption\n");
+	if (unregister_cipher(&des_ede3_cbc))
+		printk(KERN_WARNING "Couldn't unregister des_ede3-cbc encryption\n");
+}
+
+module_init(init_des_ede3);
+module_exit(cleanup_des_ede3);
diff -Nur linux-2.4.10/crypto/cipher-des.c linux-int-2.4.10/crypto/cipher-des.c
--- linux-2.4.10/crypto/cipher-des.c	Thu Jan  1 01:00:00 1970
+++ linux-int-2.4.10/crypto/cipher-des.c	Sat Sep 29 11:16:54 2001
@@ -0,0 +1,1238 @@
+/*
+ * Sourcecode created by descore. Descore is under GPL and from 
+ * Dana L. How <how@isl.stanford.edu>.
+ *
+ * Modified by Raimar Falke <rf13@inf.tu-dresden.de> for the Linux-Kernel.
+ * 
+ * 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.
+ */
+
+#include <linux/string.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <asm/byteorder.h>
+#include <linux/crypto.h>
+
+#define ROR(d,c,o)      d = d >> c | d << o
+
+typedef u8 DesData[8];
+typedef u32 DesKeys[32];
+
+u32 des_keymap[] = {
+ 0x02080008, 0x02082000, 0x00002008, 0x00000000,
+ 0x02002000, 0x00080008, 0x02080000, 0x02082008,
+ 0x00000008, 0x02000000, 0x00082000, 0x00002008,
+ 0x00082008, 0x02002008, 0x02000008, 0x02080000,
+ 0x00002000, 0x00082008, 0x00080008, 0x02002000,
+ 0x02082008, 0x02000008, 0x00000000, 0x00082000,
+ 0x02000000, 0x00080000, 0x02002008, 0x02080008,
+ 0x00080000, 0x00002000, 0x02082000, 0x00000008,
+ 0x00080000, 0x00002000, 0x02000008, 0x02082008,
+ 0x00002008, 0x02000000, 0x00000000, 0x00082000,
+ 0x02080008, 0x02002008, 0x02002000, 0x00080008,
+ 0x02082000, 0x00000008, 0x00080008, 0x02002000,
+ 0x02082008, 0x00080000, 0x02080000, 0x02000008,
+ 0x00082000, 0x00002008, 0x02002008, 0x02080000,
+ 0x00000008, 0x02082000, 0x00082008, 0x00000000,
+ 0x02000000, 0x02080008, 0x00002000, 0x00082008,
+
+ 0x08000004, 0x00020004, 0x00000000, 0x08020200,
+ 0x00020004, 0x00000200, 0x08000204, 0x00020000,
+ 0x00000204, 0x08020204, 0x00020200, 0x08000000,
+ 0x08000200, 0x08000004, 0x08020000, 0x00020204,
+ 0x00020000, 0x08000204, 0x08020004, 0x00000000,
+ 0x00000200, 0x00000004, 0x08020200, 0x08020004,
+ 0x08020204, 0x08020000, 0x08000000, 0x00000204,
+ 0x00000004, 0x00020200, 0x00020204, 0x08000200,
+ 0x00000204, 0x08000000, 0x08000200, 0x00020204,
+ 0x08020200, 0x00020004, 0x00000000, 0x08000200,
+ 0x08000000, 0x00000200, 0x08020004, 0x00020000,
+ 0x00020004, 0x08020204, 0x00020200, 0x00000004,
+ 0x08020204, 0x00020200, 0x00020000, 0x08000204,
+ 0x08000004, 0x08020000, 0x00020204, 0x00000000,
+ 0x00000200, 0x08000004, 0x08000204, 0x08020200,
+ 0x08020000, 0x00000204, 0x00000004, 0x08020004,
+
+ 0x80040100, 0x01000100, 0x80000000, 0x81040100,
+ 0x00000000, 0x01040000, 0x81000100, 0x80040000,
+ 0x01040100, 0x81000000, 0x01000000, 0x80000100,
+ 0x81000000, 0x80040100, 0x00040000, 0x01000000,
+ 0x81040000, 0x00040100, 0x00000100, 0x80000000,
+ 0x00040100, 0x81000100, 0x01040000, 0x00000100,
+ 0x80000100, 0x00000000, 0x80040000, 0x01040100,
+ 0x01000100, 0x81040000, 0x81040100, 0x00040000,
+ 0x81040000, 0x80000100, 0x00040000, 0x81000000,
+ 0x00040100, 0x01000100, 0x80000000, 0x01040000,
+ 0x81000100, 0x00000000, 0x00000100, 0x80040000,
+ 0x00000000, 0x81040000, 0x01040100, 0x00000100,
+ 0x01000000, 0x81040100, 0x80040100, 0x00040000,
+ 0x81040100, 0x80000000, 0x01000100, 0x80040100,
+ 0x80040000, 0x00040100, 0x01040000, 0x81000100,
+ 0x80000100, 0x01000000, 0x81000000, 0x01040100,
+
+ 0x04010801, 0x00000000, 0x00010800, 0x04010000,
+ 0x04000001, 0x00000801, 0x04000800, 0x00010800,
+ 0x00000800, 0x04010001, 0x00000001, 0x04000800,
+ 0x00010001, 0x04010800, 0x04010000, 0x00000001,
+ 0x00010000, 0x04000801, 0x04010001, 0x00000800,
+ 0x00010801, 0x04000000, 0x00000000, 0x00010001,
+ 0x04000801, 0x00010801, 0x04010800, 0x04000001,
+ 0x04000000, 0x00010000, 0x00000801, 0x04010801,
+ 0x00010001, 0x04010800, 0x04000800, 0x00010801,
+ 0x04010801, 0x00010001, 0x04000001, 0x00000000,
+ 0x04000000, 0x00000801, 0x00010000, 0x04010001,
+ 0x00000800, 0x04000000, 0x00010801, 0x04000801,
+ 0x04010800, 0x00000800, 0x00000000, 0x04000001,
+ 0x00000001, 0x04010801, 0x00010800, 0x04010000,
+ 0x04010001, 0x00010000, 0x00000801, 0x04000800,
+ 0x04000801, 0x00000001, 0x04010000, 0x00010800,
+
+ 0x00000400, 0x00000020, 0x00100020, 0x40100000,
+ 0x40100420, 0x40000400, 0x00000420, 0x00000000,
+ 0x00100000, 0x40100020, 0x40000020, 0x00100400,
+ 0x40000000, 0x00100420, 0x00100400, 0x40000020,
+ 0x40100020, 0x00000400, 0x40000400, 0x40100420,
+ 0x00000000, 0x00100020, 0x40100000, 0x00000420,
+ 0x40100400, 0x40000420, 0x00100420, 0x40000000,
+ 0x40000420, 0x40100400, 0x00000020, 0x00100000,
+ 0x40000420, 0x00100400, 0x40100400, 0x40000020,
+ 0x00000400, 0x00000020, 0x00100000, 0x40100400,
+ 0x40100020, 0x40000420, 0x00000420, 0x00000000,
+ 0x00000020, 0x40100000, 0x40000000, 0x00100020,
+ 0x00000000, 0x40100020, 0x00100020, 0x00000420,
+ 0x40000020, 0x00000400, 0x40100420, 0x00100000,
+ 0x00100420, 0x40000000, 0x40000400, 0x40100420,
+ 0x40100000, 0x00100420, 0x00100400, 0x40000400,
+
+ 0x00800000, 0x00001000, 0x00000040, 0x00801042,
+ 0x00801002, 0x00800040, 0x00001042, 0x00801000,
+ 0x00001000, 0x00000002, 0x00800002, 0x00001040,
+ 0x00800042, 0x00801002, 0x00801040, 0x00000000,
+ 0x00001040, 0x00800000, 0x00001002, 0x00000042,
+ 0x00800040, 0x00001042, 0x00000000, 0x00800002,
+ 0x00000002, 0x00800042, 0x00801042, 0x00001002,
+ 0x00801000, 0x00000040, 0x00000042, 0x00801040,
+ 0x00801040, 0x00800042, 0x00001002, 0x00801000,
+ 0x00001000, 0x00000002, 0x00800002, 0x00800040,
+ 0x00800000, 0x00001040, 0x00801042, 0x00000000,
+ 0x00001042, 0x00800000, 0x00000040, 0x00001002,
+ 0x00800042, 0x00000040, 0x00000000, 0x00801042,
+ 0x00801002, 0x00801040, 0x00000042, 0x00001000,
+ 0x00001040, 0x00801002, 0x00800040, 0x00000042,
+ 0x00000002, 0x00001042, 0x00801000, 0x00800002,
+
+ 0x10400000, 0x00404010, 0x00000010, 0x10400010,
+ 0x10004000, 0x00400000, 0x10400010, 0x00004010,
+ 0x00400010, 0x00004000, 0x00404000, 0x10000000,
+ 0x10404010, 0x10000010, 0x10000000, 0x10404000,
+ 0x00000000, 0x10004000, 0x00404010, 0x00000010,
+ 0x10000010, 0x10404010, 0x00004000, 0x10400000,
+ 0x10404000, 0x00400010, 0x10004010, 0x00404000,
+ 0x00004010, 0x00000000, 0x00400000, 0x10004010,
+ 0x00404010, 0x00000010, 0x10000000, 0x00004000,
+ 0x10000010, 0x10004000, 0x00404000, 0x10400010,
+ 0x00000000, 0x00404010, 0x00004010, 0x10404000,
+ 0x10004000, 0x00400000, 0x10404010, 0x10000000,
+ 0x10004010, 0x10400000, 0x00400000, 0x10404010,
+ 0x00004000, 0x00400010, 0x10400010, 0x00004010,
+ 0x00400010, 0x00000000, 0x10404000, 0x10000010,
+ 0x10400000, 0x10004010, 0x00000010, 0x00404000,
+
+ 0x00208080, 0x00008000, 0x20200000, 0x20208080,
+ 0x00200000, 0x20008080, 0x20008000, 0x20200000,
+ 0x20008080, 0x00208080, 0x00208000, 0x20000080,
+ 0x20200080, 0x00200000, 0x00000000, 0x20008000,
+ 0x00008000, 0x20000000, 0x00200080, 0x00008080,
+ 0x20208080, 0x00208000, 0x20000080, 0x00200080,
+ 0x20000000, 0x00000080, 0x00008080, 0x20208000,
+ 0x00000080, 0x20200080, 0x20208000, 0x00000000,
+ 0x00000000, 0x20208080, 0x00200080, 0x20008000,
+ 0x00208080, 0x00008000, 0x20000080, 0x00200080,
+ 0x20208000, 0x00000080, 0x00008080, 0x20200000,
+ 0x20008080, 0x20000000, 0x20200000, 0x00208000,
+ 0x20208080, 0x00008080, 0x00208000, 0x20200080,
+ 0x00200000, 0x20000080, 0x20008000, 0x00000000,
+ 0x00008000, 0x00200000, 0x20200080, 0x00208080,
+ 0x20000000, 0x20208000, 0x00000080, 0x20008080,
+};
+
+static u8 rotors[] = {
+ 34, 13,  5, 46, 47, 18, 32, 41, 11, 53, 33, 20,
+ 14, 36, 30, 24, 49,  2, 15, 37, 42, 50,  0, 21,
+ 38, 48,  6, 26, 39,  4, 52, 25, 12, 27, 31, 40,
+  1, 17, 28, 29, 23, 51, 35,  7,  3, 22,  9, 43,
+
+ 41, 20, 12, 53, 54, 25, 39, 48, 18, 31, 40, 27,
+ 21, 43, 37,  0,  1,  9, 22, 44, 49,  2,  7, 28,
+ 45, 55, 13, 33, 46, 11,  6, 32, 19, 34, 38, 47,
+  8, 24, 35, 36, 30,  3, 42, 14, 10, 29, 16, 50,
+
+ 55, 34, 26, 38, 11, 39, 53,  5, 32, 45, 54, 41,
+ 35,  2, 51, 14, 15, 23, 36,  3,  8, 16, 21, 42,
+  6, 12, 27, 47, 31, 25, 20, 46, 33, 48, 52,  4,
+ 22,  7, 49, 50, 44, 17,  1, 28, 24, 43, 30,  9,
+
+ 12, 48, 40, 52, 25, 53, 38, 19, 46,  6, 11, 55,
+ 49, 16, 10, 28, 29, 37, 50, 17, 22, 30, 35,  1,
+ 20, 26, 41,  4, 45, 39, 34, 31, 47,  5, 13, 18,
+ 36, 21,  8,  9,  3,  0, 15, 42,  7,  2, 44, 23,
+
+ 26,  5, 54, 13, 39, 38, 52, 33, 31, 20, 25, 12,
+  8, 30, 24, 42, 43, 51,  9,  0, 36, 44, 49, 15,
+ 34, 40, 55, 18,  6, 53, 48, 45,  4, 19, 27, 32,
+ 50, 35, 22, 23, 17, 14, 29,  1, 21, 16,  3, 37,
+
+ 40, 19, 11, 27, 53, 52, 13, 47, 45, 34, 39, 26,
+ 22, 44,  7,  1,  2, 10, 23, 14, 50,  3,  8, 29,
+ 48, 54, 12, 32, 20, 38,  5,  6, 18, 33, 41, 46,
+  9, 49, 36, 37,  0, 28, 43, 15, 35, 30, 17, 51,
+
+ 54, 33, 25, 41, 38, 13, 27,  4,  6, 48, 53, 40,
+ 36,  3, 21, 15, 16, 24, 37, 28,  9, 17, 22, 43,
+  5, 11, 26, 46, 34, 52, 19, 20, 32, 47, 55, 31,
+ 23,  8, 50, 51, 14, 42,  2, 29, 49, 44,  0, 10,
+
+ 11, 47, 39, 55, 52, 27, 41, 18, 20,  5, 38, 54,
+ 50, 17, 35, 29, 30,  7, 51, 42, 23,  0, 36,  2,
+ 19, 25, 40, 31, 48, 13, 33, 34, 46,  4, 12, 45,
+ 37, 22,  9, 10, 28,  1, 16, 43,  8,  3, 14, 24,
+
+ 18, 54, 46,  5,  6, 34, 48, 25, 27, 12, 45,  4,
+  2, 24, 42, 36, 37, 14,  3, 49, 30,  7, 43,  9,
+ 26, 32, 47, 38, 55, 20, 40, 41, 53, 11, 19, 52,
+ 44, 29, 16, 17, 35,  8, 23, 50, 15, 10, 21,  0,
+
+ 32, 11, 31, 19, 20, 48,  5, 39, 41, 26,  6, 18,
+ 16,  7,  1, 50, 51, 28, 17,  8, 44, 21,  2, 23,
+ 40, 46,  4, 52, 12, 34, 54, 55, 38, 25, 33, 13,
+  3, 43, 30,  0, 49, 22, 37,  9, 29, 24, 35, 14,
+
+ 46, 25, 45, 33, 34,  5, 19, 53, 55, 40, 20, 32,
+ 30, 21, 15,  9, 10, 42,  0, 22,  3, 35, 16, 37,
+ 54, 31, 18, 13, 26, 48, 11, 12, 52, 39, 47, 27,
+ 17,  2, 44, 14,  8, 36, 51, 23, 43,  7, 49, 28,
+
+ 31, 39,  6, 47, 48, 19, 33, 38, 12, 54, 34, 46,
+ 44, 35, 29, 23, 24,  1, 14, 36, 17, 49, 30, 51,
+ 11, 45, 32, 27, 40,  5, 25, 26, 13, 53,  4, 41,
+  0, 16,  3, 28, 22, 50, 10, 37,  2, 21,  8, 42,
+
+ 45, 53, 20,  4,  5, 33, 47, 52, 26, 11, 48, 31,
+  3, 49, 43, 37,  7, 15, 28, 50,  0,  8, 44, 10,
+ 25,  6, 46, 41, 54, 19, 39, 40, 27, 38, 18, 55,
+ 14, 30, 17, 42, 36,  9, 24, 51, 16, 35, 22,  1,
+
+  6, 38, 34, 18, 19, 47,  4, 13, 40, 25,  5, 45,
+ 17,  8,  2, 51, 21, 29, 42,  9, 14, 22,  3, 24,
+ 39, 20, 31, 55, 11, 33, 53, 54, 41, 52, 32, 12,
+ 28, 44,  0,  1, 50, 23,  7, 10, 30, 49, 36, 15,
+
+ 20, 52, 48, 32, 33,  4, 18, 27, 54, 39, 19,  6,
+  0, 22, 16, 10, 35, 43,  1, 23, 28, 36, 17,  7,
+ 53, 34, 45, 12, 25, 47, 38, 11, 55, 13, 46, 26,
+ 42,  3, 14, 15,  9, 37, 21, 24, 44,  8, 50, 29,
+
+ 27,  6, 55, 39, 40, 11, 25, 34,  4, 46, 26, 13,
+  7, 29, 23, 17, 42, 50,  8, 30, 35, 43, 24, 14,
+ 31, 41, 52, 19, 32, 54, 45, 18,  5, 20, 53, 33,
+ 49, 10, 21, 22, 16, 44, 28,  0, 51, 15,  2, 36,
+};
+
+static char parity[] = {
+8,1,0,8,0,8,8,0,0,8,8,0,8,0,2,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,3,
+0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,
+0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,
+8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,
+0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,
+8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,
+8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,
+4,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,5,0,8,0,8,8,0,0,8,8,0,8,0,6,8,
+};
+
+/* set up the method list from the key */
+
+static int des_set_key(struct cipher_context *cx, 
+		       const unsigned char *key, int key_len, int atomic)
+{
+    register u32 n, w;
+    register char *b0, *b1;
+    char bits0[56], bits1[56];
+    u32 *method;
+
+    if (key_len != 8)
+      return -EINVAL; /* unsupported key length */
+
+    method = (u32 *) cx->keyinfo;
+
+    /* check for bad parity and weak keys */
+    b0 = parity;
+    n  = b0[key[0]]; n <<= 4;
+    n |= b0[key[1]]; n <<= 4;
+    n |= b0[key[2]]; n <<= 4;
+    n |= b0[key[3]]; n <<= 4;
+    n |= b0[key[4]]; n <<= 4;
+    n |= b0[key[5]]; n <<= 4;
+    n |= b0[key[6]]; n <<= 4;
+    n |= b0[key[7]];
+    w  = 0X88888888L;
+    /* report bad parity in key */
+    if ( n & w )
+        return -1;
+    /* report a weak or semi-weak key */
+    if ( !((n - (w >> 3)) & w) ) {  /* 1 in 10^10 keys passes this test */
+        if ( n < 0X41415151 ) {
+            if ( n < 0X31312121 ) {
+                if ( n < 0X14141515 ) {
+                    /* 01 01 01 01 01 01 01 01 */
+                    if ( n == 0X11111111 ) return -2;
+                    /* 01 1F 01 1F 01 0E 01 0E */
+                    if ( n == 0X13131212 ) return -2;
+                } else {
+                    /* 01 E0 01 E0 01 F1 01 F1 */
+                    if ( n == 0X14141515 ) return -2;
+                    /* 01 FE 01 FE 01 FE 01 FE */
+                    if ( n == 0X16161616 ) return -2;
+                }
+            } else {
+                if ( n < 0X34342525 ) {
+                    /* 1F 01 1F 01 0E 01 0E 01 */
+                    if ( n == 0X31312121 ) return -2;
+                    /* 1F 1F 1F 1F 0E 0E 0E 0E */   /* ? */
+                    if ( n == 0X33332222 ) return -2;
+                } else {
+                    /* 1F E0 1F E0 0E F1 0E F1 */
+                    if ( n == 0X34342525 ) return -2;
+                    /* 1F FE 1F FE 0E FE 0E FE */
+                    if ( n == 0X36362626 ) return -2;
+                }
+            }
+        } else {
+            if ( n < 0X61616161 ) {
+                if ( n < 0X44445555 ) {
+                    /* E0 01 E0 01 F1 01 F1 01 */
+                    if ( n == 0X41415151 ) return -2;
+                    /* E0 1F E0 1F F1 0E F1 0E */
+                    if ( n == 0X43435252 ) return -2;
+                } else {
+                    /* E0 E0 E0 E0 F1 F1 F1 F1 */   /* ? */
+                    if ( n == 0X44445555 ) return -2;
+                    /* E0 FE E0 FE F1 FE F1 FE */
+                    if ( n == 0X46465656 ) return -2;
+                }
+            } else {
+                if ( n < 0X64646565 ) {
+                    /* FE 01 FE 01 FE 01 FE 01 */
+                    if ( n == 0X61616161 ) return -2;
+                    /* FE 1F FE 1F FE 0E FE 0E */
+                    if ( n == 0X63636262 ) return -2;
+                } else {
+                    /* FE E0 FE E0 FE F1 FE F1 */
+                    if ( n == 0X64646565 ) return -2;
+                    /* FE FE FE FE FE FE FE FE */
+                    if ( n == 0X66666666 ) return -2;
+                }
+            }
+        }
+    }
+
+    /* explode the bits */
+    n = 56;
+    b0 = bits0;
+    b1 = bits1;
+    do {
+        w = (256 | *key++) << 2;
+        do {
+            --n;
+            b1[n] = 8 & w;
+            w >>= 1;
+            b0[n] = 4 & w;
+        } while ( w >= 16 );
+    } while ( n );
+
+    /* put the bits in the correct places */
+    n = 16;
+    key = rotors;
+    do {
+        w   = (b1[key[ 0   ]] | b0[key[ 1   ]]) << 4;
+        w  |= (b1[key[ 2   ]] | b0[key[ 3   ]]) << 2;
+        w  |=  b1[key[ 4   ]] | b0[key[ 5   ]];
+        w <<= 8;
+        w  |= (b1[key[ 6   ]] | b0[key[ 7   ]]) << 4;
+        w  |= (b1[key[ 8   ]] | b0[key[ 9   ]]) << 2;
+        w  |=  b1[key[10   ]] | b0[key[11   ]];
+        w <<= 8;
+        w  |= (b1[key[12   ]] | b0[key[13   ]]) << 4;
+        w  |= (b1[key[14   ]] | b0[key[15   ]]) << 2;
+        w  |=  b1[key[16   ]] | b0[key[17   ]];
+        w <<= 8;
+        w  |= (b1[key[18   ]] | b0[key[19   ]]) << 4;
+        w  |= (b1[key[20   ]] | b0[key[21   ]]) << 2;
+        w  |=  b1[key[22   ]] | b0[key[23   ]];
+
+        method[0] = w;
+
+        w   = (b1[key[ 0+24]] | b0[key[ 1+24]]) << 4;
+        w  |= (b1[key[ 2+24]] | b0[key[ 3+24]]) << 2;
+        w  |=  b1[key[ 4+24]] | b0[key[ 5+24]];
+        w <<= 8;
+        w  |= (b1[key[ 6+24]] | b0[key[ 7+24]]) << 4;
+        w  |= (b1[key[ 8+24]] | b0[key[ 9+24]]) << 2;
+        w  |=  b1[key[10+24]] | b0[key[11+24]];
+        w <<= 8;
+        w  |= (b1[key[12+24]] | b0[key[13+24]]) << 4;
+        w  |= (b1[key[14+24]] | b0[key[15+24]]) << 2;
+        w  |=  b1[key[16+24]] | b0[key[17+24]];
+        w <<= 8;
+        w  |= (b1[key[18+24]] | b0[key[19+24]]) << 4;
+        w  |= (b1[key[20+24]] | b0[key[21+24]]) << 2;
+        w  |=  b1[key[22+24]] | b0[key[23+24]];
+
+        ROR(w, 4, 28);      /* could be eliminated */
+        method[1] = w;
+
+        key += 48;
+        method  += 2;
+    } while ( --n );
+    return 0;
+}
+
+
+static void DesSmallFipsEncrypt (DesData d, DesKeys r, DesData s)
+{
+    register u32 x, y, z;
+
+    x  = s [7];
+    x <<= 8;
+    x |= s [6];
+    x <<= 8;
+    x |= s [5];
+    x <<= 8;
+    x |= s [4];
+    y  = s [3];
+    y <<= 8;
+    y |= s [2];
+    y <<= 8;
+    y |= s [1];
+    y <<= 8;
+    y |= s [0];
+    z  = ((x >> 004) ^ y) & 0X0F0F0F0FL;
+    x ^= z << 004;
+    y ^= z;
+    z  = ((y >> 020) ^ x) & 0X0000FFFFL;
+    y ^= z << 020;
+    x ^= z;
+    z  = ((x >> 002) ^ y) & 0X33333333L;
+    x ^= z << 002;
+    y ^= z;
+    z  = ((y >> 010) ^ x) & 0X00FF00FFL;
+    y ^= z << 010;
+    x ^= z;
+    x  = x >> 1 | x << 31;
+    z  = (x ^ y) & 0X55555555L;
+    y ^= z;
+    x ^= z;
+    y  = y >> 1 | y << 31;
+    z  = r [0];
+    z ^= y;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [1];
+    z ^= y;
+    z  = z << 4 | z >> 28;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [2];
+    z ^= x;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [3];
+    z ^= x;
+    z  = z << 4 | z >> 28;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [4];
+    z ^= y;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [5];
+    z ^= y;
+    z  = z << 4 | z >> 28;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [6];
+    z ^= x;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [7];
+    z ^= x;
+    z  = z << 4 | z >> 28;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [8];
+    z ^= y;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [9];
+    z ^= y;
+    z  = z << 4 | z >> 28;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [10];
+    z ^= x;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [11];
+    z ^= x;
+    z  = z << 4 | z >> 28;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [12];
+    z ^= y;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [13];
+    z ^= y;
+    z  = z << 4 | z >> 28;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [14];
+    z ^= x;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [15];
+    z ^= x;
+    z  = z << 4 | z >> 28;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [16];
+    z ^= y;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [17];
+    z ^= y;
+    z  = z << 4 | z >> 28;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [18];
+    z ^= x;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [19];
+    z ^= x;
+    z  = z << 4 | z >> 28;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [20];
+    z ^= y;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [21];
+    z ^= y;
+    z  = z << 4 | z >> 28;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [22];
+    z ^= x;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [23];
+    z ^= x;
+    z  = z << 4 | z >> 28;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [24];
+    z ^= y;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [25];
+    z ^= y;
+    z  = z << 4 | z >> 28;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [26];
+    z ^= x;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [27];
+    z ^= x;
+    z  = z << 4 | z >> 28;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [28];
+    z ^= y;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [29];
+    z ^= y;
+    z  = z << 4 | z >> 28;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [30];
+    z ^= x;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [31];
+    z ^= x;
+    z  = z << 4 | z >> 28;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    x  = x << 1 | x >> 31;
+    z  = (x ^ y) & 0X55555555L;
+    y ^= z;
+    x ^= z;
+    y  = y << 1 | y >> 31;
+    z  = ((x >> 010) ^ y) & 0X00FF00FFL;
+    x ^= z << 010;
+    y ^= z;
+    z  = ((y >> 002) ^ x) & 0X33333333L;
+    y ^= z << 002;
+    x ^= z;
+    z  = ((x >> 020) ^ y) & 0X0000FFFFL;
+    x ^= z << 020;
+    y ^= z;
+    z  = ((y >> 004) ^ x) & 0X0F0F0F0FL;
+    y ^= z << 004;
+    x ^= z;
+    d [0] = x;
+    x >>= 8;
+    d [1] = x;
+    x >>= 8;
+    d [2] = x;
+    x >>= 8;
+    d [3] = x;
+    d [4] = y;
+    y >>= 8;
+    d [5] = y;
+    y >>= 8;
+    d [6] = y;
+    y >>= 8;
+    d [7] = y;
+    return;
+}
+
+static void DesSmallFipsDecrypt (u8 *d, u32 *r, u8 *s)
+{
+    register u32 x, y, z;
+    x  = s [7];
+    x <<= 8;
+    x |= s [6];
+    x <<= 8;
+    x |= s [5];
+    x <<= 8;
+    x |= s [4];
+    y  = s [3];
+    y <<= 8;
+    y |= s [2];
+    y <<= 8;
+    y |= s [1];
+    y <<= 8;
+    y |= s [0];
+    z  = ((x >> 004) ^ y) & 0X0F0F0F0FL;
+    x ^= z << 004;
+    y ^= z;
+    z  = ((y >> 020) ^ x) & 0X0000FFFFL;
+    y ^= z << 020;
+    x ^= z;
+    z  = ((x >> 002) ^ y) & 0X33333333L;
+    x ^= z << 002;
+    y ^= z;
+    z  = ((y >> 010) ^ x) & 0X00FF00FFL;
+    y ^= z << 010;
+    x ^= z;
+    x  = x >> 1 | x << 31;
+    z  = (x ^ y) & 0X55555555L;
+    y ^= z;
+    x ^= z;
+    y  = y >> 1 | y << 31;
+    z  = r [31];
+    z ^= y;
+    z  = z << 4 | z >> 28;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [30];
+    z ^= y;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [29];
+    z ^= x;
+    z  = z << 4 | z >> 28;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [28];
+    z ^= x;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [27];
+    z ^= y;
+    z  = z << 4 | z >> 28;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [26];
+    z ^= y;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [25];
+    z ^= x;
+    z  = z << 4 | z >> 28;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [24];
+    z ^= x;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [23];
+    z ^= y;
+    z  = z << 4 | z >> 28;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [22];
+    z ^= y;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [21];
+    z ^= x;
+    z  = z << 4 | z >> 28;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [20];
+    z ^= x;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [19];
+    z ^= y;
+    z  = z << 4 | z >> 28;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [18];
+    z ^= y;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [17];
+    z ^= x;
+    z  = z << 4 | z >> 28;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [16];
+    z ^= x;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [15];
+    z ^= y;
+    z  = z << 4 | z >> 28;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [14];
+    z ^= y;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [13];
+    z ^= x;
+    z  = z << 4 | z >> 28;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [12];
+    z ^= x;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [11];
+    z ^= y;
+    z  = z << 4 | z >> 28;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [10];
+    z ^= y;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [9];
+    z ^= x;
+    z  = z << 4 | z >> 28;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [8];
+    z ^= x;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [7];
+    z ^= y;
+    z  = z << 4 | z >> 28;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [6];
+    z ^= y;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [5];
+    z ^= x;
+    z  = z << 4 | z >> 28;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [4];
+    z ^= x;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [3];
+    z ^= y;
+    z  = z << 4 | z >> 28;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [2];
+    z ^= y;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    x ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    z  = r [1];
+    z ^= x;
+    z  = z << 4 | z >> 28;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z));
+    z  = r [0];
+    z ^= x;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z));
+    z >>= 8;
+    y ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z));
+    x  = x << 1 | x >> 31;
+    z  = (x ^ y) & 0X55555555L;
+    y ^= z;
+    x ^= z;
+    y  = y << 1 | y >> 31;
+    z  = ((x >> 010) ^ y) & 0X00FF00FFL;
+    x ^= z << 010;
+    y ^= z;
+    z  = ((y >> 002) ^ x) & 0X33333333L;
+    y ^= z << 002;
+    x ^= z;
+    z  = ((x >> 020) ^ y) & 0X0000FFFFL;
+    x ^= z << 020;
+    y ^= z;
+    z  = ((y >> 004) ^ x) & 0X0F0F0F0FL;
+    y ^= z << 004;
+    x ^= z;
+    d [0] = x;
+    x >>= 8;
+    d [1] = x;
+    x >>= 8;
+    d [2] = x;
+    x >>= 8;
+    d [3] = x;
+    d [4] = y;
+    y >>= 8;
+    d [5] = y;
+    y >>= 8;
+    d [6] = y;
+    y >>= 8;
+    d [7] = y;
+    return;
+}
+
+static int des_encrypt(struct cipher_context *cx,
+                const u8 *in, u8 *out, int size, int atomic)
+{
+	u8 input_buffer[8];
+	u8 output_buffer[8];
+    
+	for (; size >= 8; size -= 8) {
+		memcpy(&input_buffer, in, 8);
+		in += 8;
+		DesSmallFipsEncrypt(output_buffer,cx->keyinfo,input_buffer);
+		memcpy(out, &output_buffer, 8);
+		out += 8;
+	}
+	return 0;
+}
+
+static int des_decrypt(struct cipher_context *cx,
+                const u8 *in, u8 *out, int size, int atomic)
+{
+	u8 input_buffer[8];
+	u8 output_buffer[8];
+    
+	for (; size >= 8; size -= 8) {
+		memcpy(&input_buffer, in, 8);
+		in += 8;
+		DesSmallFipsDecrypt(output_buffer,cx->keyinfo,input_buffer);
+		memcpy(out, &output_buffer, 8);
+		out += 8;
+	}
+	return 0;
+}
+
+static void des_lock(void)
+{
+	MOD_INC_USE_COUNT;
+}
+
+static void des_unlock(void)
+{
+	MOD_DEC_USE_COUNT;
+}   
+
+
+#define CIPHER_BITS_64
+#define CIPHER_NAME(x) des##x
+#include "gen-cbc.h"
+#include "gen-ecb.h"
+
+#define DES_KEY_SCHEDULE_SIZE (32*sizeof(u32))
+
+static struct cipher_implementation des_ecb = {
+	{{NULL,NULL}, CIPHER_MODE_ECB, "des-ecb"},
+	blocksize: 8,
+	ivsize: 0,
+	key_schedule_size: DES_KEY_SCHEDULE_SIZE,
+	key_size_mask: CIPHER_KEYSIZE_64,
+	INIT_CIPHER_BLKOPS(des_ecb),
+	INIT_CIPHER_OPS(des)
+};
+
+static struct cipher_implementation des_cbc = {
+	{{NULL,NULL}, CIPHER_MODE_CBC, "des-cbc"},
+	blocksize: 8,
+	ivsize: 8,
+	key_schedule_size: DES_KEY_SCHEDULE_SIZE,
+	key_size_mask: CIPHER_KEYSIZE_64,
+	INIT_CIPHER_BLKOPS(des_cbc),
+	INIT_CIPHER_OPS(des)
+};
+
+static int __init init_des(void)
+{
+    if (register_cipher(&des_ecb))
+        printk(KERN_WARNING "Couldn't register des-ecb encryption\n");
+    if (register_cipher(&des_cbc))
+        printk(KERN_WARNING "Couldn't register des-cbc encryption\n");
+
+    return 0;
+}
+
+static void __exit cleanup_des(void)
+{
+	if (unregister_cipher(&des_ecb))
+		printk(KERN_WARNING "Couldn't unregister des-ecb encryption\n");
+	if (unregister_cipher(&des_cbc))
+		printk(KERN_WARNING "Couldn't unregister des-cbc encryption\n");
+}
+
+module_init(init_des);
+module_exit(cleanup_des);
diff -Nur linux-2.4.10/crypto/cipher-dfc.c linux-int-2.4.10/crypto/cipher-dfc.c
--- linux-2.4.10/crypto/cipher-dfc.c	Thu Jan  1 01:00:00 1970
+++ linux-int-2.4.10/crypto/cipher-dfc.c	Sat Sep 29 11:16:54 2001
@@ -0,0 +1,488 @@
+/* NOTE: This implementation has been changed from the original
+   source.  See ChangeLog for more information.
+   Maintained by Alexander Kjeldaas <astor@fast.no>
+ */
+
+/* This is an independent implementation of the DFC encryption      */
+/* algorithm designed by a team at CNRS and France Telecom and      */
+/* submitted as a candidate in the US NIST Advanced Encryption      */
+/* Standard (AES) programme.                                        */
+/*                                                                  */
+/* 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 DFC place on its use.         */
+/*                                                                  */
+/* My thanks go to Serge Vaudenay of the Ecole Normale Superieure   */
+/* for providing test vectors. This implementation has also been    */
+/* tested with an independent implementation by Dr Russell Bradford */
+/* (Department of Mathematical Sciences, University of Bath, Bath,  */
+/* UK) and checks out.   My thanks go to Russell for his help in    */
+/* comparing our implementations and finding bugs (and for help in  */
+/* resolving 'endian' issues before test vectors became available). */
+/*                                                                  */
+/* Dr Brian Gladman (gladman@seven77.demon.co.uk) 27th July 1998    */
+/*                                                                  */
+
+/* The EES string is as follows (the abstract contains an error in 
+   the last line of this sequence which changes KC and KD):
+
+    0xb7e15162, 0x8aed2a6a, 0xbf715880, 0x9cf4f3c7, 
+    0x62e7160f, 0x38b4da56, 0xa784d904, 0x5190cfef, 
+    0x324e7738, 0x926cfbe5, 0xf4bf8d8d, 0x8c31d763,
+    0xda06c80a, 0xbb1185eb, 0x4f7c7b57, 0x57f59584, 
+
+    0x90cfd47d, 0x7c19bb42, 0x158d9554, 0xf7b46bce, 
+    0xd55c4d79, 0xfd5f24d6, 0x613c31c3, 0x839a2ddf,
+    0x8a9a276b, 0xcfbfa1c8, 0x77c56284, 0xdab79cd4, 
+    0xc2b3293d, 0x20e9e5ea, 0xf02ac60a, 0xcc93ed87, 
+
+    0x4422a52e, 0xcb238fee, 0xe5ab6add, 0x835fd1a0,
+    0x753d0a8f, 0x78e537d2, 0xb95bb79d, 0x8dcaec64, 
+    0x2c1e9f23, 0xb829b5c2, 0x780bf387, 0x37df8bb3, 
+    0x00d01334, 0xa0d0bd86, 0x45cbfa73, 0xa6160ffe,
+
+    0x393c48cb, 0xbbca060f, 0x0ff8ec6d, 0x31beb5cc, 
+    0xeed7f2f0, 0xbb088017, 0x163bc60d, 0xf45a0ecb, 
+    0x1bcd289b, 0x06cbbfea, 0x21ad08e1, 0x847f3f73,
+    0x78d56ced, 0x94640d6e, 0xf0d3d37b, 0xe67008e1, 
+    
+    0x86d1bf27, 0x5b9b241d, 0xeb64749a, 0x47dfdfb9, 
+
+    Where:
+
+    EES = RT(0) | RT(1) | ... | RT(63) | KD | KC
+
+    Note that the abstract describing DFC is written 
+    in big endian notation with the most significant 
+    digits of a sequence of digits placed at the low
+    index positions in arrays. This format is used
+    here and is only converted to machine format at
+    the point that maths is done on any numbers in 
+    the round function.
+    
+    The key input is thus treated as an array of 32 
+    bit words numbered from 0..3, 0..5 or 0..7 
+    depending on key length.  The first (leftmost) 
+    bit of this key string as defined in the DFC 
+    abstract is the most significant bit of word 0 
+    and the rightmost bit of this string is the least 
+    signicant bit of the highest numbered key word.
+
+    The input and output blocks for the cipher are 
+    also treated as arrays of 32 bit words numbered
+    from 0..3.  The most significant bit of word 0 is
+    the 1st (leftmost) bit of the 128 bit input string 
+    and the least significant bit of word 3 is the 
+    last (rightmost) bit.
+    
+    Note that the inputs, the output and the key are
+    in Intel little endian format when BYTE_SWAP is 
+    defined
+
+Timing data:
+
+Algorithm: dfc (dfc2.c)
+128 bit key:
+Key Setup:    7373 cycles
+Encrypt:      1748 cycles =    14.6 mbits/sec
+Decrypt:      1755 cycles =    14.6 mbits/sec
+Mean:         1752 cycles =    14.6 mbits/sec
+192 bit key:
+Key Setup:    7359 cycles
+Encrypt:      1757 cycles =    14.6 mbits/sec
+Decrypt:      1765 cycles =    14.5 mbits/sec
+Mean:         1761 cycles =    14.5 mbits/sec
+256 bit key:
+Key Setup:    7320 cycles
+Encrypt:      1750 cycles =    14.6 mbits/sec
+Decrypt:      1749 cycles =    14.6 mbits/sec
+Mean:         1749 cycles =    14.6 mbits/sec
+
+*/
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/wordops.h>
+#include <linux/crypto.h>
+
+#include <asm/byteorder.h>
+
+#if 0
+#define rotl rotl32
+#define rotr rotr32
+#else
+#define rotl generic_rotl32
+#define rotr generic_rotr32
+#endif
+
+#define bswap(x)  __be32_to_cpu(x)
+#define io_swap(x)  __cpu_to_be32(x)
+
+#define BYTE_SWAP
+
+/* The following arrays are all stored in big endian    */
+/* format with 32 bit words at lower array positions    */
+/* being more significant in multi-word values          */
+
+static const u32 rt64[64] = 
+{
+    0xb7e15162, 0x8aed2a6a, 0xbf715880, 0x9cf4f3c7, 
+    0x62e7160f, 0x38b4da56, 0xa784d904, 0x5190cfef, 
+    0x324e7738, 0x926cfbe5, 0xf4bf8d8d, 0x8c31d763,
+    0xda06c80a, 0xbb1185eb, 0x4f7c7b57, 0x57f59584, 
+
+    0x90cfd47d, 0x7c19bb42, 0x158d9554, 0xf7b46bce, 
+    0xd55c4d79, 0xfd5f24d6, 0x613c31c3, 0x839a2ddf,
+    0x8a9a276b, 0xcfbfa1c8, 0x77c56284, 0xdab79cd4, 
+    0xc2b3293d, 0x20e9e5ea, 0xf02ac60a, 0xcc93ed87, 
+
+    0x4422a52e, 0xcb238fee, 0xe5ab6add, 0x835fd1a0,
+    0x753d0a8f, 0x78e537d2, 0xb95bb79d, 0x8dcaec64, 
+    0x2c1e9f23, 0xb829b5c2, 0x780bf387, 0x37df8bb3, 
+    0x00d01334, 0xa0d0bd86, 0x45cbfa73, 0xa6160ffe,
+
+    0x393c48cb, 0xbbca060f, 0x0ff8ec6d, 0x31beb5cc, 
+    0xeed7f2f0, 0xbb088017, 0x163bc60d, 0xf45a0ecb, 
+    0x1bcd289b, 0x06cbbfea, 0x21ad08e1, 0x847f3f73,
+    0x78d56ced, 0x94640d6e, 0xf0d3d37b, 0xe67008e1, 
+};
+
+static const u32  kc = 0xeb64749a;
+
+static const u32  kd2[2] = 
+{
+    0x86d1bf27, 0x5b9b241d  
+};
+
+static const u32  ka2[6] = 
+{
+    0xb7e15162, 0x8aed2a6a, 
+    0xbf715880, 0x9cf4f3c7, 
+    0x62e7160f, 0x38b4da56, 
+};
+
+static const u32  kb2[6] =
+{
+    0xa784d904, 0x5190cfef, 
+    0x324e7738, 0x926cfbe5, 
+    0xf4bf8d8d, 0x8c31d763,
+};
+
+static const u32  ks8[8] = 
+{   0xda06c80a, 0xbb1185eb, 0x4f7c7b57, 0x57f59584, 
+    0x90cfd47d, 0x7c19bb42, 0x158d9554, 0xf7b46bce,
+};
+
+#define lo(x)   ((x) & 0x0000ffff)
+#define hi(x)   ((x) >> 16)
+
+static void mult_64(u32 r[4], const u32 x[2], const u32 y[2])
+{   u32  x0, x1, x2, x3, y0, y1, y2, y3, t0, t1, t2, t3, c;
+
+    x0 = lo(x[1]); x1 = hi(x[1]); x2 = lo(x[0]); x3 = hi(x[0]);
+    y0 = lo(y[1]); y1 = hi(y[1]); y2 = lo(y[0]); y3 = hi(y[0]);
+
+    t0 = x0 * y0; r[0] = lo(t0); c = hi(t0);
+
+    t0 = x0 * y1; t1 = x1 * y0; c += lo(t0) + lo(t1);
+    r[0] += (c << 16); c = hi(c) + hi(t0) + hi(t1);
+
+    t0 = x0 * y2; t1 = x1 * y1; t2 = x2 * y0;
+    c += lo(t0) + lo(t1) + lo(t2); r[1] = lo(c);
+    c = hi(c) + hi(t0) + hi(t1) + hi(t2);
+
+    t0 = x0 * y3; t1 = x1 * y2; t2 = x2 * y1; t3 = x3 * y0;
+    c += lo(t0) + lo(t1) + lo(t2) + lo(t3); r[1] += (c << 16); 
+    c = hi(c) + hi(t0) + hi(t1) + hi(t2) + hi(t3);
+
+    t0 = x1 * y3; t1 = x2 * y2; t2 = x3 * y1;
+    c += lo(t0) + lo(t1) + lo(t2); r[2] = lo(c);
+    c = hi(c) + hi(t0) + hi(t1) + hi(t2);
+
+    t0 = x2 * y3; t1 = x3 * y2; c += lo(t0) + lo(t1);
+    r[2] += (c << 16); c = hi(c) + hi(t0) + hi(t1);
+
+    r[3] = c + x3 * y3;
+};
+
+inline static void add_64(u32 r[4], const u32 hi, const u32 lo)
+{
+    if((r[0] += lo) < lo)
+        if(!++r[1])
+            if(!++r[2])
+                ++r[3];
+
+    if((r[1] += hi) < hi)
+        if(!++r[2])
+            ++r[3];
+};
+
+static void mult_13(u32 r[3])
+{   u32  c, d;
+
+    c = 13 * lo(r[0]);
+    d = hi(r[0]);
+    r[0] = lo(c);
+    c = hi(c) + 13 * d;
+    r[0] += (c << 16);
+    c = hi(c) + 13 * lo(r[1]);
+    d = hi(r[1]);
+    r[1] = lo(c); 
+    c = hi(c) + 13 * d;
+    r[1] += (c << 16);
+    r[2] = hi(c);
+};
+
+/* Where necessary this is where conversion from big endian to  */
+/* little endian format is performed.  Since all the maths is   */
+/* little endian care is needed when 64 bit blocks are being    */
+/* used to get them in the right order by reversing the order   */
+/* in which these are stored. This applies to the key array     */
+/* which gives the two values A and B and to the constant KD.   */
+/* Since the input and output blocks are big endian we also     */
+/* have to invert the order of the 32 bit words in the 64 bit   */
+/* blocks being processed.                                      */ 
+
+static void r_fun(u32 outp[2], const u32 inp[2], const u32 key[4])
+{   u32 acc[5], b, t;
+
+    mult_64(acc, inp, key);  add_64(acc, key[2], key[3]);
+
+    /* we need the value in the accumulator mod 2^64 + 13 so if */
+    /* the accumulator value is hi * 2^64 + lo we need to find  */
+    /* a k value such that r = hi * 2^64 + lo - k * (2^64 + 13) */
+    /* is 0 <= r < 2^64 + 13.  We can see that k will be close  */
+    /* to hi in value - it may equal hi but will not be greater */
+    /* and we can let k = hi - e with e >= 0 so that r is given */
+    /* by r = e * (2^64 + 13) + lo - 13 * hi. If we compute the */
+    /* lo - 13 * hi value, the overflow into the top 64 bits of */
+    /* the accumulator has to be 'zeroed' by the e * (2^64 + 13)*/
+    /* term and this sets the e value (in fact such an overlow  */
+    /* is only removed when the lower word is higher than 12).  */
+
+    mult_13(&acc[2]);   /* multiply top of accumulator by 13    */
+
+    /* calculate lo - 13 * hi in acc[0] and acc[1] with any     */
+    /* overflow into top 64 bits in b                           */
+
+    t = acc[0]; acc[0] -= acc[2]; b = (acc[0] > t ? 1 : 0);
+
+    t = acc[1]; acc[1] -= acc[3] + b;
+    b = (acc[1] > t ? 1 : (acc[1] == t ? b : 0));
+
+    b = 13 * (acc[4] + b);  /* overflow into top 64 bits of acc */
+
+    if(((acc[0] += b) < b) && !(++acc[1]))
+    {
+        if(acc[0] > 12)
+
+            acc[0] -= 13;
+    }
+
+    /* do the confusion permutation */
+
+    t = acc[1] ^ kc; b = acc[0] ^ rt64[acc[1] >> 26];  
+    
+    b += kd2[0] + ((t += kd2[1]) < kd2[1] ? 1 : 0);
+
+    outp[0] ^= b; outp[1] ^= t; 
+};
+
+static int dfc_set_key(struct cipher_context *cx, const unsigned char *key, 
+		       int key_len, int atomic)
+{   u32 *in_key = (u32 *)key;
+    /* l_key - storage for the key schedule */
+    u32 *l_key   = cx->keyinfo;
+    u32  i, lk[32], rk[4];
+
+    if (key_len != 16 && key_len != 24 && key_len != 32)
+      return -EINVAL; /* unsupported key length */
+
+    key_len *= 8;
+
+    for(i = 0; i < key_len / 32; ++i)
+      lk[i] = io_swap(in_key[i]);
+
+    /* pad the key with the KS array            */
+
+    for(i = 0; i < 8 - key_len / 32; ++i)    /* K|KS */
+      lk[i + key_len / 32] = ks8[i];
+
+    /* do the reordering of the key parameters  */
+    /* the OAP[1]|OBP[1]|OAP[2]... sequence is  */
+    /* at lk[0]... and the other at lk[16]...   */
+    
+    lk[18] = lk[5]; lk[19] = lk[2]; /* EBP */ 
+    lk[16] = lk[1]; lk[17] = lk[6]; /* EAP */
+    lk[ 2] = lk[4]; lk[ 3] = lk[3]; /* OBP */
+    lk[ 0] = lk[0]; lk[ 1] = lk[7]; /* OAP */
+
+    /* create other elements using KA and KB    */
+
+    for(i = 0; i < 6; i += 2)
+    {
+        lk[i + i +   4] = lk[ 0] ^ ka2[i];      /* OAP[i] ms */
+        lk[i + i +   5] = lk[ 1] ^ ka2[i + 1];  /* OAP[i] ls */
+        lk[i + i +   6] = lk[ 2] ^ kb2[i];      /* OBP[i] ms */
+        lk[i + i +   7] = lk[ 3] ^ kb2[i + 1];  /* OBP[i] ls */
+        lk[i + i +  20] = lk[16] ^ ka2[i];      /* EAP[i] ms */
+        lk[i + i +  21] = lk[17] ^ ka2[i + 1];  /* EAP[i] ls */
+        lk[i + i +  22] = lk[18] ^ kb2[i];      /* EBP[i] ms */
+        lk[i + i +  23] = lk[19] ^ kb2[i + 1];  /* EBP[i] ls */
+    }
+
+    rk[0] = rk[1] = rk[2] = rk[3] = 0;
+
+    /* do the 4 round key mixing encryption     */
+
+    for(i = 0; i < 32; i += 8)
+    {
+        r_fun(rk, rk + 2, lk);      /*  R2|R1   */
+        r_fun(rk + 2, rk, lk +  4); /*  R2|R3   */
+        r_fun(rk, rk + 2, lk +  8); /*  R4|R3   */
+        r_fun(rk + 2, rk, lk + 12); /*  R4|R5   */
+
+        /* keep key in big endian format with   */
+        /* the most significant 32 bit words    */
+        /* first (lowest) in the key schedule   */
+        /* - note that the upper and lower 64   */
+        /* bit blocks are in inverse order at   */
+        /* this point in the loop               */
+
+        l_key[i + 0] = rk[2]; l_key[i + 1] = rk[3]; 
+        l_key[i + 2] = rk[0]; l_key[i + 3] = rk[1]; 
+
+        r_fun(rk + 2, rk, lk + 16); /*  R1|R2   */
+        r_fun(rk, rk + 2, lk + 20); /*  R3|R2   */
+        r_fun(rk + 2, rk, lk + 24); /*  R3|R4   */  
+        r_fun(rk, rk + 2, lk + 28); /*  R5|R4   */
+
+        l_key[i + 4] = rk[0]; l_key[i + 5] = rk[1]; 
+        l_key[i + 6] = rk[2]; l_key[i + 7] = rk[3];
+    }
+    
+    return 0;
+};
+
+static int dfc_encrypt(struct cipher_context *cx, const u8 *in, u8 *out, 
+		int size, int atomic)
+{   u32 *l_key = cx->keyinfo;
+    u32 *in_blk = (u32 *)in;
+    u32 *out_blk = (u32 *)out;
+    u32  blk[4];
+
+    /* the input/output format is big endian -  */
+    /* any reversals needed are performed when  */
+    /* maths is done in the round function      */
+
+    blk[0] = io_swap(in_blk[0]); blk[1] = io_swap(in_blk[1]);
+    blk[2] = io_swap(in_blk[2]); blk[3] = io_swap(in_blk[3]);
+
+    r_fun(blk, blk + 2, l_key +  0); /*  R2|R1  */ 
+    r_fun(blk + 2, blk, l_key +  4); /*  R2|R3  */
+    r_fun(blk, blk + 2, l_key +  8); /*  R4|R3  */
+    r_fun(blk + 2, blk, l_key + 12); /*  R4|R5  */
+    r_fun(blk, blk + 2, l_key + 16); /*  R6|R5  */
+    r_fun(blk + 2, blk, l_key + 20); /*  R6|R7  */
+    r_fun(blk, blk + 2, l_key + 24); /*  R8|R7  */
+    r_fun(blk + 2, blk, l_key + 28); /*  R8|R9  */
+
+    /* swap order to obtain the result R9|R8    */
+
+    out_blk[0] = io_swap(blk[2]); out_blk[1] = io_swap(blk[3]);
+    out_blk[2] = io_swap(blk[0]); out_blk[3] = io_swap(blk[1]);
+    return 0;
+};
+
+static int dfc_decrypt(struct cipher_context *cx, const u8 *in, u8 *out, 
+		int size, int atomic)
+{   u32 *l_key = cx->keyinfo;
+    u32 *in_blk = (u32 *)in;
+    u32 *out_blk = (u32 *)out;
+    u32 blk[4];
+
+    /* the input/output format is big endian -  */
+    /* any reversals needed are performed when  */
+    /* maths is done in the round function      */
+
+    blk[0] = io_swap(in_blk[0]); blk[1] = io_swap(in_blk[1]);
+    blk[2] = io_swap(in_blk[2]); blk[3] = io_swap(in_blk[3]);
+
+    r_fun(blk, blk + 2, l_key + 28); /*  R7|R8  */
+    r_fun(blk + 2, blk, l_key + 24); /*  R7|R6  */
+    r_fun(blk, blk + 2, l_key + 20); /*  R5|R6  */
+    r_fun(blk + 2, blk, l_key + 16); /*  R5|R4  */
+    r_fun(blk, blk + 2, l_key + 12); /*  R3|R4  */
+    r_fun(blk + 2, blk, l_key +  8); /*  R3|R2  */
+    r_fun(blk, blk + 2, l_key +  4); /*  R1|R2  */
+    r_fun(blk + 2, blk, l_key     ); /*  R1|R0  */ 
+
+    /* swap order to obtain the result R1|R0    */
+
+    out_blk[0] = io_swap(blk[2]); out_blk[1] = io_swap(blk[3]);
+    out_blk[2] = io_swap(blk[0]); out_blk[3] = io_swap(blk[1]);   
+    return 0;
+};
+
+static void dfc_lock(void)
+{
+	MOD_INC_USE_COUNT;
+}
+
+static void dfc_unlock(void)
+{
+	MOD_DEC_USE_COUNT;
+}   
+
+#define CIPHER_BITS_128
+#define CIPHER_NAME(x) dfc##x
+#include "gen-cbc.h"
+#include "gen-ecb.h"
+
+#define DFC_KEY_SCHEDULE_SIZE (32*sizeof(u32))
+
+static struct cipher_implementation dfc_ecb = {
+	{{NULL,NULL}, CIPHER_MODE_ECB, "dfc-ecb"},
+	blocksize: 16,
+	ivsize: 0,
+	key_schedule_size: DFC_KEY_SCHEDULE_SIZE,
+	key_size_mask: CIPHER_KEYSIZE_128 | CIPHER_KEYSIZE_192 | 
+                       CIPHER_KEYSIZE_256,
+	INIT_CIPHER_BLKOPS(dfc_ecb),
+	INIT_CIPHER_OPS(dfc)
+};
+
+static struct cipher_implementation dfc_cbc = {
+	{{NULL,NULL}, CIPHER_MODE_CBC, "dfc-cbc"},
+	blocksize: 16,
+	ivsize: 16,
+	key_schedule_size: DFC_KEY_SCHEDULE_SIZE,
+	key_size_mask: CIPHER_KEYSIZE_128 | CIPHER_KEYSIZE_192 | 
+                       CIPHER_KEYSIZE_256,
+	INIT_CIPHER_BLKOPS(dfc_cbc),
+	INIT_CIPHER_OPS(dfc)
+};
+
+
+static int __init init_dfc(void)
+{
+	if (register_cipher(&dfc_ecb))
+		printk(KERN_WARNING "Couldn't register dfc-ecb encryption\n");
+	if (register_cipher(&dfc_cbc))
+		printk(KERN_WARNING "Couldn't register dfc-cbc encryption\n");
+
+	return 0;
+}
+
+static void __exit cleanup_dfc(void)
+{
+	if (unregister_cipher(&dfc_ecb))
+		printk(KERN_WARNING "Couldn't unregister dfc-ecb encryption\n");
+	if (unregister_cipher(&dfc_cbc))
+		printk(KERN_WARNING "Couldn't unregister dfc-cbc encryption\n");
+}
+
+module_init(init_dfc);
+module_exit(cleanup_dfc);
diff -Nur linux-2.4.10/crypto/cipher-dummy.c linux-int-2.4.10/crypto/cipher-dummy.c
--- linux-2.4.10/crypto/cipher-dummy.c	Thu Jan  1 01:00:00 1970
+++ linux-int-2.4.10/crypto/cipher-dummy.c	Sat Sep 29 11:16:54 2001
@@ -0,0 +1,124 @@
+/*
+ * Dummy CIPHER module
+ *
+ * this is a dummy cipher module for debugging purposes, it may server as 
+ * skeleton for new ciphers as well
+ *
+ * by hvr@gnu.org
+ */
+
+#include <asm/byteorder.h>
+#include <linux/crypto.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/string.h>
+
+static int
+dummy_encrypt (struct cipher_context *cx, const u8 *in8, u8 *out8,
+	       int size, int atomic)
+{
+	memmove (out8, in8, size);
+	return 0;
+}
+
+static int
+dummy_decrypt (struct cipher_context *cx, const u8 *in8, u8 *out8,
+	       int size, int atomic)
+{
+	memmove (out8, in8, size);
+	return 0;
+}
+
+static int
+dummy_set_key (struct cipher_context *cx, const unsigned char *key, int key_len,
+	       int atomic)
+{
+	printk (KERN_DEBUG "%s: key_len=%d atomic=%d\n",
+		__PRETTY_FUNCTION__, key_len, atomic);
+
+	if (key_len != 16 && key_len != 20 && key_len != 24 && key_len != 32)
+		return -EINVAL;	/* unsupported key length */
+
+	return 0;
+}
+
+static void
+dummy_lock (void)
+{
+	printk (KERN_DEBUG "%s\n", __PRETTY_FUNCTION__);
+
+	MOD_INC_USE_COUNT;
+}
+
+static void
+dummy_unlock (void)
+{
+	printk (KERN_DEBUG "%s\n", __PRETTY_FUNCTION__);
+
+	MOD_DEC_USE_COUNT;
+}
+
+#define CIPHER_BITS_64
+#define CIPHER_NAME(x) dummy##x
+#include "gen-cbc.h"
+#include "gen-ecb.h"
+
+#define DUMMY_KEY_SCHEDULE_SIZE ((18+1024)*sizeof(u32))
+
+static struct cipher_implementation dummy_ecb = {
+	{{NULL, NULL}, CIPHER_MODE_ECB, "dummy-ecb"},
+      blocksize:8,
+      ivsize:0,
+      key_schedule_size:0,
+      key_size_mask:CIPHER_KEYSIZE_128 | CIPHER_KEYSIZE_160 | CIPHER_KEYSIZE_192 |
+	    CIPHER_KEYSIZE_256,
+	INIT_CIPHER_BLKOPS (dummy_ecb),
+	INIT_CIPHER_OPS (dummy)
+};
+
+static struct cipher_implementation dummy_cbc = {
+	{{NULL, NULL}, CIPHER_MODE_CBC, "dummy-cbc"},
+      blocksize:8,
+      ivsize:8,
+      key_schedule_size:0,
+      key_size_mask:CIPHER_KEYSIZE_128 | CIPHER_KEYSIZE_160 | CIPHER_KEYSIZE_192 |
+	    CIPHER_KEYSIZE_256,
+	INIT_CIPHER_BLKOPS (dummy_cbc),
+	INIT_CIPHER_OPS (dummy)
+};
+
+static int __init
+init_dummy (void)
+{
+	printk (KERN_DEBUG "%s\n", __PRETTY_FUNCTION__);
+
+	if (register_cipher (&dummy_ecb))
+		printk (KERN_WARNING
+			"Couldn't register dummy-ecb encryption\n");
+
+	if (register_cipher (&dummy_cbc))
+		printk (KERN_WARNING
+			"Couldn't register dummy-cbc encryption\n");
+
+	return 0;
+}
+
+static void __exit
+cleanup_dummy (void)
+{
+	printk (KERN_DEBUG "%s\n", __PRETTY_FUNCTION__);
+
+	if (unregister_cipher (&dummy_ecb))
+		printk (KERN_WARNING
+			"Couldn't unregister dummy-ecb encryption\n");
+
+	if (unregister_cipher (&dummy_cbc))
+		printk (KERN_WARNING
+			"Couldn't unregister dummy-cbc encryption\n");
+}
+
+module_init (init_dummy);
+module_exit (cleanup_dummy);
+
+/* eof */
diff -Nur linux-2.4.10/crypto/cipher-idea.c linux-int-2.4.10/crypto/cipher-idea.c
--- linux-2.4.10/crypto/cipher-idea.c	Thu Jan  1 01:00:00 1970
+++ linux-int-2.4.10/crypto/cipher-idea.c	Sat Sep 29 11:16:54 2001
@@ -0,0 +1,412 @@
+/*
+ *    idea.c - C source code for IDEA block cipher.
+ *      IDEA (International Data Encryption Algorithm), formerly known as
+ *      IPES (Improved Proposed Encryption Standard).
+ *      Algorithm developed by Xuejia Lai and James L. Massey, of ETH Zurich.
+ *      This implementation modified and derived from original C code
+ *      developed by Xuejia Lai.
+ *      Zero-based indexing added, names changed from IPES to IDEA.
+ *      CFB functions added.  Random number routines added.
+ *
+ *      Extensively optimized and restructured by Colin Plumb.
+ *
+ *      There are two adjustments that can be made to this code to
+ *      speed it up.  Defaults may be used for PCs.  Only the -DIDEA32
+ *      pays off significantly if selectively set or not set.
+ *      Experiment to see what works best for your machine.
+ *
+ *      Multiplication: default is inline, -DAVOID_JUMPS uses a
+ *              different version that does not do any conditional
+ *              jumps (a few percent worse on a SPARC), while
+ *              -DSMALL_CACHE takes it out of line to stay
+ *              within a small on-chip code cache.
+ *      Variables: normally, 16-bit variables are used, but some
+ *              machines (notably RISCs) do not have 16-bit registers,
+ *              so they do a great deal of masking.  -DIDEA32 uses "int"
+ *              register variables and masks explicitly only where
+ *              necessary.  On a SPARC, for example, this boosts
+ *              performace by 30%.
+ *
+ *      The IDEA(tm) block cipher is covered by patents held by ETH and a
+ *      Swiss company called Ascom-Tech AG.  The Swiss patent number is
+ *      PCT/CH91/00117, the European patent number is EP 0 482 154 B1, and
+ *      the U.S. patent number is US005214703.  IDEA(tm) is a trademark of
+ *      Ascom-Tech AG.  There is no license fee required for noncommercial
+ *      use.  Commercial users may obtain licensing details from Dieter
+ *      Profos, Ascom Tech AG, Solothurn Lab, Postfach 151, 4502 Solothurn,
+ *      Switzerland, Tel +41 65 242885, Fax +41 65 235761.
+ *
+ *      The IDEA block cipher uses a 64-bit block size, and a 128-bit key
+ *      size.  It breaks the 64-bit cipher block into four 16-bit words
+ *      because all of the primitive inner operations are done with 16-bit
+ *      arithmetic.  It likewise breaks the 128-bit cipher key into eight
+ *      16-bit words.
+ *
+ *      For further information on the IDEA cipher, see the book:
+ *        Xuejia Lai, "On the Design and Security of Block Ciphers",
+ *        ETH Series on Information Processing (ed. J.L. Massey) Vol 1,
+ *        Hartung-Gorre Verlag, Konstanz, Switzerland, 1992.  ISBN
+ *        3-89191-573-X.
+ *
+ *      This code runs on arrays of bytes by taking pairs in big-endian
+ *      order to make the 16-bit words that IDEA uses internally.  This
+ *      produces the same result regardless of the byte order of the
+ *      native CPU.
+ */
+
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <asm/byteorder.h>
+#include <linux/crypto.h>
+#include <linux/string.h>
+
+#define IDEAKEYSIZE 16
+#define IDEABLOCKSIZE 8
+
+#define IDEAROUNDS 8
+#define IDEAKEYLEN (6*IDEAROUNDS+4)
+
+#define low16(x) ((x) & 0xFFFF)
+typedef unsigned char byte;
+
+typedef struct {
+    u16 ek[IDEAKEYLEN];
+    u16 dk[IDEAKEYLEN];
+} IDEA_context;
+
+#if defined(__mc68000__) || defined (__sparc__) || defined (__PPC__) \
+    || (defined(__mips__) && (defined(MIPSEB) || defined (__MIPSEB__)) )
+#define BIG_ENDIAN_HOST 1
+#else
+#define LITTLE_ENDIAN_HOST 1
+#endif
+
+/* 
+ * Compute the multiplicative inverse of x, modulo 65537, using
+ * Euclid's algorithm. It is unrolled twice to avoid swapping the
+ * registers each iteration, and some subtracts of t have been changed
+ * to adds.
+ */
+static u16 mulInv(u16 x)
+{
+    u16 t0, t1;
+    u16 q, y;
+
+    if (x <= 1)
+        return x;               /* 0 and 1 are self-inverse */
+    t1 = 0x10001L / x;          /* Since x >= 2, this fits into 16 bits */
+    y = 0x10001L % x;
+    if (y == 1)
+        return low16(1 - t1);
+    t0 = 1;
+    do {
+        q = x / y;
+        x = x % y;
+        t0 += q * t1;
+        if (x == 1)
+            return t0;
+        q = y / x;
+        y = y % x;
+        t1 += q * t0;
+    } while (y != 1);
+    return low16(1 - t1);
+}
+
+/*
+ * Expand a 128-bit user key to a working encryption key ek
+ */
+static void ideaExpandKey(byte const *userkey, u16 * ek)
+{
+    int i, j;
+
+    for (j = 0; j < 8; j++) {
+        ek[j] = (userkey[0] << 8) + userkey[1];
+        userkey += 2;
+    }
+    for (i = 0; j < IDEAKEYLEN; j++) {
+        i++;
+        ek[i + 7] = ek[i & 7] << 9 | ek[(i + 1) & 7] >> 7;
+        ek += i & 8;
+        i &= 7;
+    }
+}
+
+/* 
+ * Compute IDEA decryption key dk from an expanded IDEA encryption key
+ * ek Note that the input and output may be the same.  Thus, the key
+ * is inverted into an internal buffer, and then copied to the output.
+ */
+static void ideaInvertKey(u16 const *ek, u16 dk[IDEAKEYLEN])
+{
+    int i;
+    u16 t1, t2, t3;
+    u16 temp[IDEAKEYLEN];
+    u16 *p = temp + IDEAKEYLEN;
+
+    t1 = mulInv(*ek++);
+    t2 = -*ek++;
+    t3 = -*ek++;
+    *--p = mulInv(*ek++);
+    *--p = t3;
+    *--p = t2;
+    *--p = t1;
+
+    for (i = 0; i < IDEAROUNDS - 1; i++) {
+        t1 = *ek++;
+        *--p = *ek++;
+        *--p = t1;
+
+        t1 = mulInv(*ek++);
+        t2 = -*ek++;
+        t3 = -*ek++;
+        *--p = mulInv(*ek++);
+        *--p = t2;
+        *--p = t3;
+        *--p = t1;
+    }
+    t1 = *ek++;
+    *--p = *ek++;
+    *--p = t1;
+
+    t1 = mulInv(*ek++);
+    t2 = -*ek++;
+    t3 = -*ek++;
+    *--p = mulInv(*ek++);
+    *--p = t3;
+    *--p = t2;
+    *--p = t1;
+	/* Copy and destroy temp copy */
+    memcpy(dk, temp, sizeof(temp));
+	memset(&temp,0,sizeof(temp));
+}
+
+/* IDEA encryption/decryption algorithm */
+/* Note that in and out can be the same buffer */
+static void ideaCipher(u16 const inbuf[4], u16 outbuf[4],
+                       u16 const *key)
+{
+    register u16 x1, x2, x3, x4, s2, s3;
+    u16 *in, *out;
+    register u16 t16;        /* Temporaries needed by MUL macro */
+    register u32 t32;
+    int r = IDEAROUNDS;
+#define MUL(x,y) \
+        ((t16 = (y)) ? \
+                (x=low16(x)) ? \
+                        t32 = (u32)x*t16, \
+                        x = low16(t32), \
+                        t16 = t32>>16, \
+                        x = (x-t16)+(x<t16) \
+                : \
+                        (x = 1-t16) \
+        : \
+                (x = 1-x))
+
+    in = (u16 *) inbuf;
+    x1 = *in++;
+    x2 = *in++;
+    x3 = *in++;
+    x4 = *in;
+#ifndef LITTLE_ENDIAN_HOST
+    x1 = (x1 >> 8) | (x1 << 8);
+    x2 = (x2 >> 8) | (x2 << 8);
+    x3 = (x3 >> 8) | (x3 << 8);
+    x4 = (x4 >> 8) | (x4 << 8);
+#endif
+    do {
+        MUL(x1, *key++);
+        x2 += *key++;
+        x3 += *key++;
+        MUL(x4, *key++);
+
+        s3 = x3;
+        x3 ^= x1;
+        MUL(x3, *key++);
+        s2 = x2;
+        x2 ^= x4;
+        x2 += x3;
+        MUL(x2, *key++);
+        x3 += x2;
+
+        x1 ^= x2;
+        x4 ^= x3;
+
+        x2 ^= s3;
+        x3 ^= s2;
+    } while (--r);
+    MUL(x1, *key++);
+    x3 += *key++;
+    x2 += *key++;
+    MUL(x4, *key);
+
+    out = (u16 *) outbuf;
+#ifdef LITTLE_ENDIAN_HOST
+    *out++ = x1;
+    *out++ = x3;
+    *out++ = x2;
+    *out = x4;
+#else
+    x1 = low16(x1);
+    x2 = low16(x2);
+    x3 = low16(x3);
+    x4 = low16(x4);
+    *out++ = (x1 >> 8) | (x1 << 8);
+    *out++ = (x3 >> 8) | (x3 << 8);
+    *out++ = (x2 >> 8) | (x2 << 8);
+    *out = (x4 >> 8) | (x4 << 8);
+#endif
+}
+
+int idea_encrypt(struct cipher_context *cx,
+		 const u8 *in, u8 *out, int size, int atomic)
+{
+	IDEA_context *c=(IDEA_context *)cx->keyinfo;
+
+	u16 input_buffer[4];
+	u16 output_buffer[4];
+	u32 *in_blk = (u32 *)in;
+	u32 *out_blk = (u32 *)out;
+	u32 n;
+	
+	for (; size >= 8; size -= 8)
+    {
+		n=*in_blk++;
+		input_buffer[0]=n & 0xffff;
+		n=n>>16;
+		input_buffer[1]=n & 0xffff;
+
+		n=*in_blk++;
+		input_buffer[2]=n & 0xffff;
+		n=n>>16;
+		input_buffer[3]=n & 0xffff;
+
+		ideaCipher( input_buffer,output_buffer, c->ek );
+
+		n=0;
+		n|=output_buffer[1];
+		n=n<<16;
+		n|=output_buffer[0];
+
+		*out_blk++=n;
+
+		n=0;
+		n|=output_buffer[3];
+		n=n<<16;
+		n|=output_buffer[2];
+
+		*out_blk++=n;
+	}
+	return 0;
+}
+
+int idea_decrypt(struct cipher_context *cx, 
+		 const u8 *in, u8 *out, int size, int atomic)
+{
+	IDEA_context *c=(IDEA_context *)cx->keyinfo;
+
+	u16 input_buffer[8];
+	u16 output_buffer[8];
+	u32 *in_blk = (u32 *)in;
+	u32 *out_blk = (u32 *)out;
+	u32 n;
+
+	for (; size >= 8; size -= 8)
+    {
+		n=*in_blk++;
+		input_buffer[0]=n & 0xffff;
+		n=n>>16;
+		input_buffer[1]=n & 0xffff;
+
+		n=*in_blk++;
+		input_buffer[2]=n & 0xffff;
+		n=n>>16;
+		input_buffer[3]=n & 0xffff;
+
+		ideaCipher( input_buffer,output_buffer, c->dk );
+
+		n=0;
+		n|=output_buffer[1];
+		n=n<<16;
+		n|=output_buffer[0];
+
+		*out_blk++=n;
+
+		n=0;
+		n|=output_buffer[3];
+		n=n<<16;
+		n|=output_buffer[2];
+
+		*out_blk++=n;
+	}
+	return 0;
+}
+
+int idea_set_key(struct cipher_context *cx, 
+		 const unsigned char *key, int keybytes, int atomic)
+{
+	IDEA_context *c=(IDEA_context *)cx->keyinfo;
+
+	if(keybytes != 16)
+		return -EINVAL;
+
+    ideaExpandKey(key, c->ek);
+    ideaInvertKey(c->ek, c->dk);
+    return 0;
+}
+
+static void idea_lock(void)
+{
+	MOD_INC_USE_COUNT;
+}
+
+static void idea_unlock(void)
+{
+	MOD_DEC_USE_COUNT;
+}   
+
+#define CIPHER_BITS_64
+#define CIPHER_NAME(x) idea##x
+#include "gen-cbc.h"
+#include "gen-ecb.h"
+
+
+static struct cipher_implementation idea_ecb = {
+	{{NULL,NULL}, CIPHER_MODE_ECB, "idea-ecb"},
+	blocksize: 8,
+	ivsize: 0,
+	key_schedule_size: sizeof(IDEA_context),
+	key_size_mask: CIPHER_KEYSIZE_128,
+	INIT_CIPHER_BLKOPS(idea_ecb),
+	INIT_CIPHER_OPS(idea)
+};
+
+static struct cipher_implementation idea_cbc = {
+	{{NULL,NULL}, CIPHER_MODE_CBC, "idea-cbc"},
+	blocksize: 8,
+	ivsize: 8,
+	key_schedule_size: sizeof(IDEA_context),
+	key_size_mask: CIPHER_KEYSIZE_128,
+	INIT_CIPHER_BLKOPS(idea_cbc),
+	INIT_CIPHER_OPS(idea)
+};
+
+static int __init init_idea(void)
+{
+    if (register_cipher(&idea_ecb))
+        printk(KERN_WARNING "Couldn't register idea-ecb encryption\n");
+    if (register_cipher(&idea_cbc))
+        printk(KERN_WARNING "Couldn't register idea-cbc encryption\n");
+    return 0;
+}
+
+static void __exit cleanup_idea(void)
+{
+	if (unregister_cipher(&idea_ecb))
+		printk(KERN_WARNING "Couldn't unregister idea-ecb encryption\n");
+	if (unregister_cipher(&idea_cbc))
+		printk(KERN_WARNING "Couldn't unregister idea-cbc encryption\n");
+}
+
+module_init(init_idea);
+module_exit(cleanup_idea);
diff -Nur linux-2.4.10/crypto/cipher-mars.c linux-int-2.4.10/crypto/cipher-mars.c
--- linux-2.4.10/crypto/cipher-mars.c	Thu Jan  1 01:00:00 1970
+++ linux-int-2.4.10/crypto/cipher-mars.c	Sat Sep 29 11:16:56 2001
@@ -0,0 +1,625 @@
+/* NOTE: This implementation has been changed from the original source */
+
+/* Copyright in this code is held by Dr B.R. Gladman but free direct or
+ * derivative use is permit1ed subject to acknowledgement of its origin
+ * and subject to any constraints placed on the use of the algorithm by
+ * its designers (if such constraints may exist, this will be indicated
+ * below).
+ *
+ * Dr. B. R. Gladman (brian.gladman@btinternet.com). 25th January 2000.
+ *
+ * This is an implementation of MARS, an encryption algorithm designed by
+ * a team at IBM and submit1ed as a candidate algorithm for the Advanced
+ * Encryption Standard programme of the US National Institute of Standards
+ * and Technology.
+ *
+ * The MARS algorithm is covered by a pending patent application owned by
+ * IBM, who intend to offer a royalty free license under any issued patent
+ * that results from such application if MARS is selected as the AES
+ * algorithm.  In the interim, you may evaluate the MARS algorithm for
+ * your personal, lawful, non-profit purposes as an end user.
+ *
+ * NOTE: this is the revised second round variant of MARS */
+
+/* For an update regarding licensing see
+ * http://www.tivoli.com/news/press/pressreleases/en/2000/mars.html */
+
+/* Use first round variant of MARS */
+/* #define CIPHER_MARS_ROUND_1 */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/wordops.h>
+#include <linux/crypto.h>
+
+#if 0
+#define rotl rotl32
+#define rotr rotr32
+#else
+#define rotl generic_rotl32
+#define rotr generic_rotr32
+#endif
+
+const static u32 s_box[] = {
+	0x09d0c479, 0x28c8ffe0, 0x84aa6c39, 0x9dad7287,	/* 0x000 */
+	0x7dff9be3, 0xd4268361, 0xc96da1d4, 0x7974cc93,
+	0x85d0582e, 0x2a4b5705, 0x1ca16a62, 0xc3bd279d,
+	0x0f1f25e5, 0x5160372f, 0xc695c1fb, 0x4d7ff1e4,
+	0xae5f6bf4, 0x0d72ee46, 0xff23de8a, 0xb1cf8e83,	/* 0x010 */
+	0xf14902e2, 0x3e981e42, 0x8bf53eb6, 0x7f4bf8ac,
+	0x83631f83, 0x25970205, 0x76afe784, 0x3a7931d4,
+	0x4f846450, 0x5c64c3f6, 0x210a5f18, 0xc6986a26,
+	0x28f4e826, 0x3a60a81c, 0xd340a664, 0x7ea820c4,	/* 0x020 */
+	0x526687c5, 0x7eddd12b, 0x32a11d1d, 0x9c9ef086,
+	0x80f6e831, 0xab6f04ad, 0x56fb9b53, 0x8b2e095c,
+	0xb68556ae, 0xd2250b0d, 0x294a7721, 0xe21fb253,
+	0xae136749, 0xe82aae86, 0x93365104, 0x99404a66,	/* 0x030 */
+	0x78a784dc, 0xb69ba84b, 0x04046793, 0x23db5c1e,
+	0x46cae1d6, 0x2fe28134, 0x5a223942, 0x1863cd5b,
+	0xc190c6e3, 0x07dfb846, 0x6eb88816, 0x2d0dcc4a,
+	0xa4ccae59, 0x3798670d, 0xcbfa9493, 0x4f481d45,	/* 0x040 */
+	0xeafc8ca8, 0xdb1129d6, 0xb0449e20, 0x0f5407fb,
+	0x6167d9a8, 0xd1f45763, 0x4daa96c3, 0x3bec5958,
+	0xababa014, 0xb6ccd201, 0x38d6279f, 0x02682215,
+	0x8f376cd5, 0x092c237e, 0xbfc56593, 0x32889d2c,	/* 0x050 */
+	0x854b3e95, 0x05bb9b43, 0x7dcd5dcd, 0xa02e926c,
+	0xfae527e5, 0x36a1c330, 0x3412e1ae, 0xf257f462,
+	0x3c4f1d71, 0x30a2e809, 0x68e5f551, 0x9c61ba44,
+	0x5ded0ab8, 0x75ce09c8, 0x9654f93e, 0x698c0cca,	/* 0x060 */
+	0x243cb3e4, 0x2b062b97, 0x0f3b8d9e, 0x00e050df,
+	0xfc5d6166, 0xe35f9288, 0xc079550d, 0x0591aee8,
+	0x8e531e74, 0x75fe3578, 0x2f6d829a, 0xf60b21ae,
+	0x95e8eb8d, 0x6699486b, 0x901d7d9b, 0xfd6d6e31,	/* 0x070 */
+	0x1090acef, 0xe0670dd8, 0xdab2e692, 0xcd6d4365,
+	0xe5393514, 0x3af345f0, 0x6241fc4d, 0x460da3a3,
+	0x7bcf3729, 0x8bf1d1e0, 0x14aac070, 0x1587ed55,
+	0x3afd7d3e, 0xd2f29e01, 0x29a9d1f6, 0xefb10c53,	/* 0x080 */
+	0xcf3b870f, 0xb414935c, 0x664465ed, 0x024acac7,
+	0x59a744c1, 0x1d2936a7, 0xdc580aa6, 0xcf574ca8,
+	0x040a7a10, 0x6cd81807, 0x8a98be4c, 0xaccea063,
+	0xc33e92b5, 0xd1e0e03d, 0xb322517e, 0x2092bd13,	/* 0x090 */
+	0x386b2c4a, 0x52e8dd58, 0x58656dfb, 0x50820371,
+	0x41811896, 0xe337ef7e, 0xd39fb119, 0xc97f0df6,
+	0x68fea01b, 0xa150a6e5, 0x55258962, 0xeb6ff41b,
+	0xd7c9cd7a, 0xa619cd9e, 0xbcf09576, 0x2672c073,	/* 0x0a0 */
+	0xf003fb3c, 0x4ab7a50b, 0x1484126a, 0x487ba9b1,
+	0xa64fc9c6, 0xf6957d49, 0x38b06a75, 0xdd805fcd,
+	0x63d094cf, 0xf51c999e, 0x1aa4d343, 0xb8495294,
+	0xce9f8e99, 0xbffcd770, 0xc7c275cc, 0x378453a7,	/* 0x0b0 */
+	0x7b21be33, 0x397f41bd, 0x4e94d131, 0x92cc1f98,
+	0x5915ea51, 0x99f861b7, 0xc9980a88, 0x1d74fd5f,
+	0xb0a495f8, 0x614deed0, 0xb5778eea, 0x5941792d,
+	0xfa90c1f8, 0x33f824b4, 0xc4965372, 0x3ff6d550,	/* 0x0c0 */
+	0x4ca5fec0, 0x8630e964, 0x5b3fbbd6, 0x7da26a48,
+	0xb203231a, 0x04297514, 0x2d639306, 0x2eb13149,
+	0x16a45272, 0x532459a0, 0x8e5f4872, 0xf966c7d9,
+	0x07128dc0, 0x0d44db62, 0xafc8d52d, 0x06316131,	/* 0x0d0 */
+	0xd838e7ce, 0x1bc41d00, 0x3a2e8c0f, 0xea83837e,
+	0xb984737d, 0x13ba4891, 0xc4f8b949, 0xa6d6acb3,
+	0xa215cdce, 0x8359838b, 0x6bd1aa31, 0xf579dd52,
+	0x21b93f93, 0xf5176781, 0x187dfdde, 0xe94aeb76,	/* 0x0e0 */
+	0x2b38fd54, 0x431de1da, 0xab394825, 0x9ad3048f,
+	0xdfea32aa, 0x659473e3, 0x623f7863, 0xf3346c59,
+	0xab3ab685, 0x3346a90b, 0x6b56443e, 0xc6de01f8,
+	0x8d421fc0, 0x9b0ed10c, 0x88f1a1e9, 0x54c1f029,	/* 0x0f0 */
+	0x7dead57b, 0x8d7ba426, 0x4cf5178a, 0x551a7cca,
+	0x1a9a5f08, 0xfcd651b9, 0x25605182, 0xe11fc6c3,
+	0xb6fd9676, 0x337b3027, 0xb7c8eb14, 0x9e5fd030,
+
+	0x6b57e354, 0xad913cf7, 0x7e16688d, 0x58872a69,	/* 0x100 */
+	0x2c2fc7df, 0xe389ccc6, 0x30738df1, 0x0824a734,
+	0xe1797a8b, 0xa4a8d57b, 0x5b5d193b, 0xc8a8309b,
+	0x73f9a978, 0x73398d32, 0x0f59573e, 0xe9df2b03,
+	0xe8a5b6c8, 0x848d0704, 0x98df93c2, 0x720a1dc3,	/* 0x110 */
+	0x684f259a, 0x943ba848, 0xa6370152, 0x863b5ea3,
+	0xd17b978b, 0x6d9b58ef, 0x0a700dd4, 0xa73d36bf,
+	0x8e6a0829, 0x8695bc14, 0xe35b3447, 0x933ac568,
+	0x8894b022, 0x2f511c27, 0xddfbcc3c, 0x006662b6,	/* 0x120 */
+	0x117c83fe, 0x4e12b414, 0xc2bca766, 0x3a2fec10,
+	0xf4562420, 0x55792e2a, 0x46f5d857, 0xceda25ce,
+	0xc3601d3b, 0x6c00ab46, 0xefac9c28, 0xb3c35047,
+	0x611dfee3, 0x257c3207, 0xfdd58482, 0x3b14d84f,	/* 0x130 */
+	0x23becb64, 0xa075f3a3, 0x088f8ead, 0x07adf158,
+	0x7796943c, 0xfacabf3d, 0xc09730cd, 0xf7679969,
+	0xda44e9ed, 0x2c854c12, 0x35935fa3, 0x2f057d9f,
+	0x690624f8, 0x1cb0bafd, 0x7b0dbdc6, 0x810f23bb,	/* 0x140 */
+	0xfa929a1a, 0x6d969a17, 0x6742979b, 0x74ac7d05,
+	0x010e65c4, 0x86a3d963, 0xf907b5a0, 0xd0042bd3,
+	0x158d7d03, 0x287a8255, 0xbba8366f, 0x096edc33,
+	0x21916a7b, 0x77b56b86, 0x951622f9, 0xa6c5e650,	/* 0x150 */
+	0x8cea17d1, 0xcd8c62bc, 0xa3d63433, 0x358a68fd,
+	0x0f9b9d3c, 0xd6aa295b, 0xfe33384a, 0xc000738e,
+	0xcd67eb2f, 0xe2eb6dc2, 0x97338b02, 0x06c9f246,
+	0x419cf1ad, 0x2b83c045, 0x3723f18a, 0xcb5b3089,	/* 0x160 */
+	0x160bead7, 0x5d494656, 0x35f8a74b, 0x1e4e6c9e,
+	0x000399bd, 0x67466880, 0xb4174831, 0xacf423b2,
+	0xca815ab3, 0x5a6395e7, 0x302a67c5, 0x8bdb446b,
+	0x108f8fa4, 0x10223eda, 0x92b8b48b, 0x7f38d0ee,	/* 0x170 */
+	0xab2701d4, 0x0262d415, 0xaf224a30, 0xb3d88aba,
+	0xf8b2c3af, 0xdaf7ef70, 0xcc97d3b7, 0xe9614b6c,
+	0x2baebff4, 0x70f687cf, 0x386c9156, 0xce092ee5,
+	0x01e87da6, 0x6ce91e6a, 0xbb7bcc84, 0xc7922c20,	/* 0x180 */
+	0x9d3b71fd, 0x060e41c6, 0xd7590f15, 0x4e03bb47,
+	0x183c198e, 0x63eeb240, 0x2ddbf49a, 0x6d5cba54,
+	0x923750af, 0xf9e14236, 0x7838162b, 0x59726c72,
+	0x81b66760, 0xbb2926c1, 0x48a0ce0d, 0xa6c0496d,	/* 0x190 */
+	0xad43507b, 0x718d496a, 0x9df057af, 0x44b1bde6,
+	0x054356dc, 0xde7ced35, 0xd51a138b, 0x62088cc9,
+	0x35830311, 0xc96efca2, 0x686f86ec, 0x8e77cb68,
+	0x63e1d6b8, 0xc80f9778, 0x79c491fd, 0x1b4c67f2,	/* 0x1a0 */
+	0x72698d7d, 0x5e368c31, 0xf7d95e2e, 0xa1d3493f,
+	0xdcd9433e, 0x896f1552, 0x4bc4ca7a, 0xa6d1baf4,
+	0xa5a96dcc, 0x0bef8b46, 0xa169fda7, 0x74df40b7,
+	0x4e208804, 0x9a756607, 0x038e87c8, 0x20211e44,	/* 0x1b0 */
+	0x8b7ad4bf, 0xc6403f35, 0x1848e36d, 0x80bdb038,
+	0x1e62891c, 0x643d2107, 0xbf04d6f8, 0x21092c8c,
+	0xf644f389, 0x0778404e, 0x7b78adb8, 0xa2c52d53,
+	0x42157abe, 0xa2253e2e, 0x7bf3f4ae, 0x80f594f9,	/* 0x1c0 */
+	0x953194e7, 0x77eb92ed, 0xb3816930, 0xda8d9336,
+	0xbf447469, 0xf26d9483, 0xee6faed5, 0x71371235,
+	0xde425f73, 0xb4e59f43, 0x7dbe2d4e, 0x2d37b185,
+	0x49dc9a63, 0x98c39d98, 0x1301c9a2, 0x389b1bbf,	/* 0x1d0 */
+	0x0c18588d, 0xa421c1ba, 0x7aa3865c, 0x71e08558,
+	0x3c5cfcaa, 0x7d239ca4, 0x0297d9dd, 0xd7dc2830,
+	0x4b37802b, 0x7428ab54, 0xaeee0347, 0x4b3fbb85,
+	0x692f2f08, 0x134e578e, 0x36d9e0bf, 0xae8b5fcf,	/* 0x1e0 */
+	0xedb93ecf, 0x2b27248e, 0x170eb1ef, 0x7dc57fd6,
+	0x1e760f16, 0xb1136601, 0x864e1b9b, 0xd7ea7319,
+	0x3ab871bd, 0xcfa4d76f, 0xe31bd782, 0x0dbeb469,
+	0xabb96061, 0x5370f85d, 0xffb07e37, 0xda30d0fb,	/* 0x1f0 */
+	0xebc977b6, 0x0b98b40f, 0x3a4d0fe6, 0xdf4fc26b,
+	0x159cf22a, 0xc298d6e2, 0x2b78ef6a, 0x61a94ac0,
+	0xab561187, 0x14eea0f0, 0xdf0d4164, 0x19af70ee
+};
+
+const static u32 b_tab[4] = {
+	0xa4a8d57b, 0x5b5d193b, 0xc8a8309b, 0x73f9a978	/* s_box[265..268] */
+};
+
+#define f_mix(a,b,c,d)                  \
+        r = rotr(a, 8);                 \
+        b ^= s_box[a & 255];            \
+        b += s_box[(r & 255) + 256];    \
+        r = rotr(a, 16);                \
+        a  = rotr(a, 24);               \
+        c += s_box[r & 255];            \
+        d ^= s_box[(a & 255) + 256]
+
+#define b_mix(a,b,c,d)                  \
+        r = rotl(a, 8);                 \
+        b ^= s_box[(a & 255) + 256];    \
+        c -= s_box[r & 255];            \
+        r = rotl(a, 16);                \
+        a  = rotl(a, 24);               \
+        d -= s_box[(r & 255) + 256];    \
+        d ^= s_box[a & 255]
+
+#define f_ktr(a,b,c,d,i)    \
+    m = a + l_key[i];       \
+    a = rotl(a, 13);        \
+    r = a * l_key[i + 1];   \
+    l = s_box[m & 511];     \
+    r = rotl(r, 5);         \
+    c += rotl(m, r);        \
+    l ^= r;                 \
+    r = rotl(r, 5);         \
+    l ^= r;                 \
+    d ^= r;                 \
+    b += rotl(l, r)
+
+#define r_ktr(a,b,c,d,i)    \
+    r = a * l_key[i + 1];   \
+    a = rotr(a, 13);        \
+    m = a + l_key[i];       \
+    l = s_box[m & 511];     \
+    r = rotl(r, 5);         \
+    l ^= r;                 \
+    c -= rotl(m, r);        \
+    r = rotl(r, 5);         \
+    l ^= r;                 \
+    d ^= r;                 \
+    b -= rotl(l, r)
+
+#if defined(CIPHER_MARS_ROUND_1)
+static int
+mars_set_key (struct cipher_context *cx, const unsigned char *key, int key_len,
+	      int atomic)
+{
+	u32 i, j, m, w;
+	u32 *in_key = (u32 *) key;
+	u32 *l_key = cx->keyinfo;
+	u32 vk[47] = {
+		0x09d0c479, 0x28c8ffe0, 0x84aa6c39, 0x9dad7287, 0x7dff9be3,
+		0xd4268361, 0xc96da1d4	/* s_box[0..6] */
+	};
+
+	if (key_len != 16 && key_len != 24 && key_len != 32)
+		return -EINVAL;	/* unsupported key length */
+
+	m = key_len / 4 - 1;
+
+	for (i = j = 0; i < 39; ++i) {
+		vk[i + 7] = rotl (vk[i] ^ vk[i + 5], 3) ^ in_key[j] ^ i;
+		j = (j == m ? 0 : j + 1);
+	}
+
+	vk[46] = key_len / 4;
+
+	for (j = 0; j < 7; ++j) {
+		for (i = 1; i < 40; ++i)
+			vk[i + 7] =
+			    rotl (vk[i + 7] + s_box[vk[i + 6] & 511], 9);
+
+		vk[7] = rotl (vk[7] + s_box[vk[46] & 511], 9);
+	}
+
+	for (i = j = 0; i < 40; ++i) {
+		l_key[j] = vk[i + 7];
+		j = (j < 33 ? j + 7 : j - 33);
+	}
+
+	for (i = 5; i < 37; i += 2) {
+		w = l_key[i] | 3;
+		m = (~w ^ (w >> 1)) & 0x7fffffff;
+		m &= (m >> 1) & (m >> 2);
+		m &= (m >> 3) & (m >> 6);
+
+		if (m) {
+			m <<= 1;
+			m |= (m << 1);
+			m |= (m << 2);
+			m |= (m << 4);
+			m |= (m << 1) & ~w & 0x80000000;
+			m &= 0xfffffffc;
+			w ^= (rotl (b_tab[l_key[i] & 3], l_key[i + 3] & 31) &
+			      m);
+		}
+
+		l_key[i] = w;
+	}
+
+	return 0;
+};
+#else /* defined(CIPHER_MARS_ROUND_1) */
+static int
+mars_set_key (struct cipher_context *cx, const unsigned char *key, int key_len,
+	      int atomic)
+{
+	u32 i, j, m, t1, t2, *kp;
+	u32 *in_key = (u32 *) key;
+	u32 *l_key = cx->keyinfo;
+	u32 t_key[15];		/* key mixing array */
+
+	if (key_len != 16 && key_len != 24 && key_len != 32)
+		return -EINVAL;	/* unsupported key length */
+
+	m = key_len / 4;
+
+	for (i = 0; i < m; ++i)
+		t_key[i] = in_key[i];
+
+	t_key[i++] = m;
+
+	for (; i < 15; ++i)
+		t_key[i] = 0;
+
+	kp = l_key;
+
+#define tk1(j) t1 = t_key[j] ^= rotl(t1 ^ t_key[(j + 8) % 15], 3) ^ (i + 4 * j)
+#define tk2(j) t2 = t_key[j] ^= rotl(t2 ^ t_key[(j + 8) % 15], 3) ^ (i + 4 * j)
+#define tk3(j) t_key[j] = t1 = rotl(t_key[j] + s_box[t1 & 511], 9)
+
+	for (i = 0; i < 4; ++i) {
+		t1 = t_key[13];
+		t2 = t_key[14];
+
+		tk1 (0);
+		tk2 (1);
+		tk1 (2);
+		tk2 (3);
+		tk1 (4);
+		tk2 (5);
+		tk1 (6);
+		tk2 (7);
+		tk1 (8);
+		tk2 (9);
+		tk1 (10);
+		tk2 (11);
+		tk1 (12);
+		tk2 (13);
+		tk1 (14);
+
+		tk3 (0);
+		tk3 (1);
+		tk3 (2);
+		tk3 (3);
+		tk3 (4);
+		tk3 (5);
+		tk3 (6);
+		tk3 (7);
+		tk3 (8);
+		tk3 (9);
+		tk3 (10);
+		tk3 (11);
+		tk3 (12);
+		tk3 (13);
+		tk3 (14);
+
+		tk3 (0);
+		tk3 (1);
+		tk3 (2);
+		tk3 (3);
+		tk3 (4);
+		tk3 (5);
+		tk3 (6);
+		tk3 (7);
+		tk3 (8);
+		tk3 (9);
+		tk3 (10);
+		tk3 (11);
+		tk3 (12);
+		tk3 (13);
+		tk3 (14);
+
+		tk3 (0);
+		tk3 (1);
+		tk3 (2);
+		tk3 (3);
+		tk3 (4);
+		tk3 (5);
+		tk3 (6);
+		tk3 (7);
+		tk3 (8);
+		tk3 (9);
+		tk3 (10);
+		tk3 (11);
+		tk3 (12);
+		tk3 (13);
+		tk3 (14);
+
+		tk3 (0);
+		tk3 (1);
+		tk3 (2);
+		tk3 (3);
+		tk3 (4);
+		tk3 (5);
+		tk3 (6);
+		tk3 (7);
+		tk3 (8);
+		tk3 (9);
+		tk3 (10);
+		tk3 (11);
+		tk3 (12);
+		tk3 (13);
+		tk3 (14);
+
+		*kp++ = t_key[0];
+		*kp++ = t_key[4];
+		*kp++ = t_key[8];
+		*kp++ = t_key[12];
+		*kp++ = t_key[1];
+		*kp++ = t_key[5];
+		*kp++ = t_key[9];
+		*kp++ = t_key[13];
+		*kp++ = t_key[2];
+		*kp++ = t_key[6];
+	}
+
+	for (i = 5; i < 37; i += 2) {
+		j = l_key[i] | 3;
+		m = (~j ^ (j >> 1)) & 0x7fffffff;
+		m &= (m >> 1) & (m >> 2);
+		m &= (m >> 3) & (m >> 6);
+
+		if (m) {
+			m <<= 1;
+			m |= (m << 1);
+			m |= (m << 2);
+			m |= (m << 4);
+			m &= 0xfffffffc;
+			j ^= (rotl (b_tab[l_key[i] & 3], l_key[i - 1]) & m);
+		}
+
+		l_key[i] = j;
+	}
+
+	return 0;
+}
+#endif /* defined(CIPHER_MARS_ROUND_1) */
+
+static int
+mars_encrypt (struct cipher_context *cx, const u8 *in, u8 *out, int size,
+	      int atomic)
+{
+	u32 a, b, c, d, l, m, r;
+	u32 *l_key = cx->keyinfo;
+	u32 *in_blk = (u32 *) in;
+	u32 *out_blk = (u32 *) out;
+
+	a = in_blk[0] + l_key[0];
+	b = in_blk[1] + l_key[1];
+	c = in_blk[2] + l_key[2];
+	d = in_blk[3] + l_key[3];
+
+	f_mix (a, b, c, d);
+	a += d;
+	f_mix (b, c, d, a);
+	b += c;
+	f_mix (c, d, a, b);
+	f_mix (d, a, b, c);
+	f_mix (a, b, c, d);
+	a += d;
+	f_mix (b, c, d, a);
+	b += c;
+	f_mix (c, d, a, b);
+	f_mix (d, a, b, c);
+
+	f_ktr (a, b, c, d, 4);
+	f_ktr (b, c, d, a, 6);
+	f_ktr (c, d, a, b, 8);
+	f_ktr (d, a, b, c, 10);
+	f_ktr (a, b, c, d, 12);
+	f_ktr (b, c, d, a, 14);
+	f_ktr (c, d, a, b, 16);
+	f_ktr (d, a, b, c, 18);
+	f_ktr (a, d, c, b, 20);
+	f_ktr (b, a, d, c, 22);
+	f_ktr (c, b, a, d, 24);
+	f_ktr (d, c, b, a, 26);
+	f_ktr (a, d, c, b, 28);
+	f_ktr (b, a, d, c, 30);
+	f_ktr (c, b, a, d, 32);
+	f_ktr (d, c, b, a, 34);
+
+	b_mix (a, b, c, d);
+	b_mix (b, c, d, a);
+	c -= b;
+	b_mix (c, d, a, b);
+	d -= a;
+	b_mix (d, a, b, c);
+	b_mix (a, b, c, d);
+	b_mix (b, c, d, a);
+	c -= b;
+	b_mix (c, d, a, b);
+	d -= a;
+	b_mix (d, a, b, c);
+
+	out_blk[0] = a - l_key[36];
+	out_blk[1] = b - l_key[37];
+	out_blk[2] = c - l_key[38];
+	out_blk[3] = d - l_key[39];
+
+	return 0;
+}
+
+static int
+mars_decrypt (struct cipher_context *cx, const u8 *in, u8 *out, int size,
+	      int atomic)
+{
+	u32 a, b, c, d, l, m, r;
+	u32 *l_key = cx->keyinfo;
+	u32 *in_blk = (u32 *) in;
+	u32 *out_blk = (u32 *) out;
+
+	d = in_blk[0] + l_key[36];
+	c = in_blk[1] + l_key[37];
+	b = in_blk[2] + l_key[38];
+	a = in_blk[3] + l_key[39];
+
+	f_mix (a, b, c, d);
+	a += d;
+	f_mix (b, c, d, a);
+	b += c;
+	f_mix (c, d, a, b);
+	f_mix (d, a, b, c);
+	f_mix (a, b, c, d);
+	a += d;
+	f_mix (b, c, d, a);
+	b += c;
+	f_mix (c, d, a, b);
+	f_mix (d, a, b, c);
+
+	r_ktr (a, b, c, d, 34);
+	r_ktr (b, c, d, a, 32);
+	r_ktr (c, d, a, b, 30);
+	r_ktr (d, a, b, c, 28);
+	r_ktr (a, b, c, d, 26);
+	r_ktr (b, c, d, a, 24);
+	r_ktr (c, d, a, b, 22);
+	r_ktr (d, a, b, c, 20);
+	r_ktr (a, d, c, b, 18);
+	r_ktr (b, a, d, c, 16);
+	r_ktr (c, b, a, d, 14);
+	r_ktr (d, c, b, a, 12);
+	r_ktr (a, d, c, b, 10);
+	r_ktr (b, a, d, c, 8);
+	r_ktr (c, b, a, d, 6);
+	r_ktr (d, c, b, a, 4);
+
+	b_mix (a, b, c, d);
+	b_mix (b, c, d, a);
+	c -= b;
+	b_mix (c, d, a, b);
+	d -= a;
+	b_mix (d, a, b, c);
+	b_mix (a, b, c, d);
+	b_mix (b, c, d, a);
+	c -= b;
+	b_mix (c, d, a, b);
+	d -= a;
+	b_mix (d, a, b, c);
+
+	out_blk[0] = d - l_key[0];
+	out_blk[1] = c - l_key[1];
+	out_blk[2] = b - l_key[2];
+	out_blk[3] = a - l_key[3];
+
+	return 0;
+}
+
+static void
+mars_lock (void)
+{
+	MOD_INC_USE_COUNT;
+}
+
+static void
+mars_unlock (void)
+{
+	MOD_DEC_USE_COUNT;
+}
+
+#define CIPHER_BITS_128
+#define CIPHER_NAME(x) mars##x
+#include "gen-cbc.h"
+#include "gen-ecb.h"
+
+#define MARS_KEY_SCHEDULE_SIZE (40*sizeof(u32))
+
+static struct cipher_implementation mars_ecb = {
+	{{NULL, NULL}, CIPHER_MODE_ECB, "mars-ecb"},
+      blocksize:16,
+      ivsize:0,
+      key_schedule_size:MARS_KEY_SCHEDULE_SIZE,
+      key_size_mask:CIPHER_KEYSIZE_128 | CIPHER_KEYSIZE_192 |
+	    CIPHER_KEYSIZE_256,
+	INIT_CIPHER_BLKOPS (mars_ecb),
+	INIT_CIPHER_OPS (mars)
+};
+
+static struct cipher_implementation mars_cbc = {
+	{{NULL, NULL}, CIPHER_MODE_CBC, "mars-cbc"},
+      blocksize:16,
+      ivsize:16,
+      key_schedule_size:MARS_KEY_SCHEDULE_SIZE,
+      key_size_mask:CIPHER_KEYSIZE_128 | CIPHER_KEYSIZE_192 |
+	    CIPHER_KEYSIZE_256,
+	INIT_CIPHER_BLKOPS (mars_cbc),
+	INIT_CIPHER_OPS (mars)
+};
+
+static int __init
+init_mars (void)
+{
+	if (register_cipher (&mars_ecb))
+		printk (KERN_WARNING "Couldn't register mars-ecb encryption\n");
+	if (register_cipher (&mars_cbc))
+		printk (KERN_WARNING "Couldn't register mars-cbc encryption\n");
+
+	return 0;
+}
+
+static void __exit
+cleanup_mars (void)
+{
+	if (unregister_cipher (&mars_ecb))
+		printk (KERN_WARNING
+			"Couldn't unregister mars-ecb encryption\n");
+	if (unregister_cipher (&mars_cbc))
+		printk (KERN_WARNING
+			"Couldn't unregister mars-cbc encryption\n");
+}
+
+module_init (init_mars);
+module_exit (cleanup_mars);
diff -Nur linux-2.4.10/crypto/cipher-rc5.c linux-int-2.4.10/crypto/cipher-rc5.c
--- linux-2.4.10/crypto/cipher-rc5.c	Thu Jan  1 01:00:00 1970
+++ linux-int-2.4.10/crypto/cipher-rc5.c	Sat Sep 29 11:16:56 2001
@@ -0,0 +1,231 @@
+/*
+ * rc5.c				RC5-32/16/b
+ *
+ * Copyright (c) 1999 Pekka Riikonen <priikone@poseidon.pspt.fi>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish, dis-
+ * tribute, sublicense, and/or sell copies of the Software, and to permit
+ * persons to whom the Software is furnished to do so, subject to the fol-
+ * lowing conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
+ * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT
+ * SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABIL-
+ * ITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the authors shall
+ * not be used in advertising or otherwise to promote the sale, use or
+ * other dealings in this Software without prior written authorization from
+ * the authors.
+ *
+ */
+
+/*
+ * Based on RC5 reference code and on description of Bruce Schneier's 
+ * Applied Cryptography.
+ *
+ * This implementation has a word size of 32 bits, a rounds of 16 and 
+ * variable key length from 128 and 192 up to 256 bits.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/errno.h> 
+#include <linux/init.h>  
+#include <linux/string.h>  
+#include <linux/crypto.h> 
+#include <linux/wordops.h> 
+
+/* RC5 definitions */
+#define w	32	/* word size, in bits */
+#define r	16	/* rounds */
+#define b	16	/* minimum key size in bytes */
+#define c	8	/* same for 128,  192 and 256 bits key */
+#define t	34	/* size of table S, t = 2 * (r + 1) */
+
+/* RC5 encryption */
+#define RC5E(i, A, B)				\
+		A = A ^ B;			\
+		A = rotl(A, B) + S[i];		\
+		B = B ^ A;			\
+		B = rotl(B, A) + S[i + 1];
+
+/* RC5 decryption */
+#define RC5D(i, A, B)				\
+		B = B - S[i + 1];		\
+		B = rotr(B, A) ^ A;		\
+		A = A - S[i];			\
+		A = rotr(A, B) ^ B;
+
+#if 0
+#define rotl rotl32
+#define rotr rotr32
+#else
+#define rotl generic_rotl32
+#define rotr generic_rotr32
+#endif
+
+/* Sets RC5 key */
+
+int rc5_set_key(struct cipher_context *cx, const unsigned char *key, int key_len,
+		int atomic)
+{
+	u32 *in_key = (u32 *)key;
+	u32 *out_key = cx->keyinfo;		/* S */
+	u32 i, j, k, A, B, L[c];
+
+	if (key_len != 16 && key_len != 24 && key_len != 32)
+		return -EINVAL; /* unsupported key length */
+
+	key_len *= 8;
+
+	/* init L */
+	for (i = 0; i < key_len / w; i++)
+		L[i] = in_key[i];
+
+	/* init key array (S) */
+	out_key[0] = 0xb7e15163;
+	for (i = 1; i < t; i++)
+		out_key[i] = out_key[i - 1] + 0x9e3779b9;
+
+	/* mix L and key array (S) */
+	A = B = 0;
+	for (k = i = j = 0; k < (3 * t); k++) {
+		A = rotl(out_key[i] + (A + B), 3);
+		B += A;
+		B = rotl(L[j] + B, B);
+		out_key[i] = A;
+		L[j] = B;
+		i = (i + 1) % t;
+		j = (j + 1) % c;
+	}
+
+	return 0;
+}
+
+/* Encrypts *one* block at a time. */
+
+int rc5_encrypt(struct cipher_context *cx,
+                const u8 *in8, u8 *out8, int size, int atomic)
+{
+	u32 A, B;
+	u32 *in = (u32 *)in8;
+	u32 *out = (u32 *)out8;
+
+	u32 *S = cx->keyinfo;
+	A = in[0] + S[0];
+	B = in[1] + S[1];
+
+	RC5E(2, A, B); RC5E(4, A, B);
+	RC5E(6, A, B); RC5E(8, A, B);
+	RC5E(10, A, B); RC5E(12, A, B);
+	RC5E(14, A, B); RC5E(16, A, B);
+	RC5E(18, A, B); RC5E(20, A, B);
+	RC5E(22, A, B); RC5E(24, A, B);
+	RC5E(26, A, B); RC5E(28, A, B);
+	RC5E(30, A, B); RC5E(32, A, B);
+
+	out[0] = A;
+	out[1] = B;
+
+	return 0;
+}
+
+/* Decrypts *one* block at a time. */
+
+int rc5_decrypt(struct cipher_context *cx,
+                const u8 *in8, u8 *out8, int size, int atomic)
+{
+	u32 A, B;
+	u32 *in = (u32 *)in8;
+	u32 *out = (u32 *)out8;
+
+	u32 *S = cx->keyinfo;
+	A = in[0];
+	B = in[1];
+
+	RC5D(32, A, B); RC5D(30, A, B); 
+	RC5D(28, A, B); RC5D(26, A, B); 
+	RC5D(24, A, B); RC5D(22, A, B); 
+	RC5D(20, A, B); RC5D(18, A, B);
+	RC5D(16, A, B); RC5D(14, A, B);
+	RC5D(12, A, B); RC5D(10, A, B);
+	RC5D(8, A, B); RC5D(6, A, B);
+	RC5D(4, A, B); RC5D(2, A, B);
+
+	out[0] = A - S[0];
+	out[1] = B - S[1];
+
+	return 0;
+}   
+
+static void rc5_lock(void)
+{
+	MOD_INC_USE_COUNT;
+}
+
+static void rc5_unlock(void)
+{
+	MOD_DEC_USE_COUNT;
+}
+
+
+#define CIPHER_BITS_64
+#define CIPHER_NAME(x) rc5##x
+#include "gen-cbc.h"
+#include "gen-ecb.h"
+
+#define RC5_KEY_SCHEDULE_SIZE (34*sizeof(u32))
+
+static struct cipher_implementation rc5_ecb = {
+	{{NULL,NULL}, CIPHER_MODE_ECB, "rc5-ecb"},
+	blocksize: 8,
+	ivsize: 0,
+	key_schedule_size: RC5_KEY_SCHEDULE_SIZE,
+	key_size_mask: CIPHER_KEYSIZE_128 | CIPHER_KEYSIZE_192 | 
+                       CIPHER_KEYSIZE_256,
+	INIT_CIPHER_BLKOPS(rc5_ecb),
+	INIT_CIPHER_OPS(rc5)
+};
+
+static struct cipher_implementation rc5_cbc = {
+	{{NULL,NULL}, CIPHER_MODE_CBC, "rc5-cbc"},
+	blocksize: 8,
+	ivsize: 8,
+	key_schedule_size: RC5_KEY_SCHEDULE_SIZE,
+	key_size_mask: CIPHER_KEYSIZE_128 | CIPHER_KEYSIZE_192 | 
+                       CIPHER_KEYSIZE_256,
+	INIT_CIPHER_BLKOPS(rc5_cbc),
+	INIT_CIPHER_OPS(rc5)
+};
+
+
+static int __init init_rc5(void)
+{
+    if (register_cipher(&rc5_ecb))
+        printk(KERN_WARNING "Couldn't register RC5-ecb encryption\n");
+    if (register_cipher(&rc5_cbc))
+        printk(KERN_WARNING "Couldn't register RC5-cbc encryption\n");
+
+    return 0;
+}
+
+static void __exit cleanup_rc5(void)
+{
+	if (unregister_cipher(&rc5_ecb))
+		printk(KERN_WARNING "Couldn't unregister RC5_ecb encryption\n");
+	if (unregister_cipher(&rc5_cbc))
+		printk(KERN_WARNING "Couldn't unregister RC5-cbc encryption\n");
+}
+
+module_init(init_rc5);
+module_exit(cleanup_rc5);
diff -Nur linux-2.4.10/crypto/cipher-rc6.c linux-int-2.4.10/crypto/cipher-rc6.c
--- linux-2.4.10/crypto/cipher-rc6.c	Thu Jan  1 01:00:00 1970
+++ linux-int-2.4.10/crypto/cipher-rc6.c	Sat Sep 29 11:16:56 2001
@@ -0,0 +1,219 @@
+/* NOTE: This implementation has been changed from the original
+   source.  See ChangeLog for more information.
+   Maintained by Alexander Kjeldaas <astor@fast.no>
+ */
+
+/* This is an independent implementation of the RC6 algorithm that	*/
+/* Ron Rivest and RSA Labs have submitted as a candidate for the	*/
+/* NIST AES activity.  Refer to RSA Labs and Ron Rivest for any 	*/
+/* copyright, patent or license issues for the RC6 algorithm.		*/
+/*																	*/
+/* 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	*/
+/* constraints that are placed on the exploitation of RC6 by its	*/
+/* designers.														*/
+/*																	*/
+/* Dr Brian Gladman (gladman@seven77.demon.co.uk) 18th July 1998	*/
+/*
+   Timing data:
+
+Algorithm: rc6 (rc62.c)
+128 bit key:
+Key Setup:    1580 cycles
+Encrypt:       286 cycles =    89.6 mbits/sec
+Decrypt:       236 cycles =   108.6 mbits/sec
+Mean:          261 cycles =    98.2 mbits/sec
+192 bit key:
+Key Setup:    1882 cycles
+Encrypt:       286 cycles =    89.5 mbits/sec
+Decrypt:       235 cycles =   108.9 mbits/sec
+Mean:          261 cycles =    98.3 mbits/sec
+256 bit key:
+Key Setup:    1774 cycles
+Encrypt:       285 cycles =    89.7 mbits/sec
+Decrypt:       236 cycles =   108.3 mbits/sec
+Mean:          261 cycles =    98.1 mbits/sec
+
+*/
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/wordops.h>
+#include <linux/crypto.h>
+
+#if 0
+#define rotl rotl32
+#define rotr rotr32
+#else
+#define rotl generic_rotl32
+#define rotr generic_rotr32
+#endif
+
+#define f_rnd(i,a,b,c,d)				   \
+		u = rotl(d * (d + d + 1), 5);	   \
+		t = rotl(b * (b + b + 1), 5);	   \
+		a = rotl(a ^ t, u) + l_key[i];	   \
+		c = rotl(c ^ u, t) + l_key[i + 1]
+
+#define i_rnd(i,a,b,c,d)				   \
+		u = rotl(d * (d + d + 1), 5);	   \
+		t = rotl(b * (b + b + 1), 5);	   \
+		c = rotr(c - l_key[i + 1], t) ^ u; \
+		a = rotr(a - l_key[i], u) ^ t
+
+/* initialise the key schedule from the user supplied key	*/
+
+int rc6_set_key(struct cipher_context *cx, const unsigned char *key, int key_len,
+		int atomic)
+{       u32 *in_key = (u32 *)key;
+        /* l_key - storage for the key schedule */
+        u32 *l_key   = cx->keyinfo;
+	u32	i, j, k, a, b, l[8], t;
+
+	if (key_len != 16 && key_len != 24 && key_len != 32)
+		return -EINVAL; /* unsupported key length */
+
+	key_len *= 8;
+
+	l_key[0] = 0xb7e15163;
+
+	for(k = 1; k < 44; ++k)
+		
+		l_key[k] = l_key[k - 1] + 0x9e3779b9;
+
+	for(k = 0; k < key_len / 32; ++k)
+
+		l[k] = in_key[k];
+
+	t = (key_len / 32) - 1;
+
+	a = b = i = j = 0;
+
+	for(k = 0; k < 132; ++k)
+	{	a = rotl(l_key[i] + a + b, 3); b += a;
+		b = rotl(l[j] + b, b);
+		l_key[i] = a; l[j] = b;
+		i = (i == 43 ? 0 : i + 1);
+		j = (j == t ? 0 : j + 1);
+	}
+
+	return 0;
+};
+
+/* encrypt a block of text	*/
+
+int rc6_encrypt(struct cipher_context *cx, 
+		const u8 *in, u8 *out, int size, int atomic)
+{       u32 *l_key = cx->keyinfo;
+	u32 *in_blk = (u32 *)in;
+	u32 *out_blk = (u32 *)out;
+	u32	a,b,c,d,t,u;
+
+	a = in_blk[0]; b = in_blk[1] + l_key[0];
+	c = in_blk[2]; d = in_blk[3] + l_key[1];
+
+	f_rnd( 2,a,b,c,d); f_rnd( 4,b,c,d,a);
+	f_rnd( 6,c,d,a,b); f_rnd( 8,d,a,b,c);
+	f_rnd(10,a,b,c,d); f_rnd(12,b,c,d,a);
+	f_rnd(14,c,d,a,b); f_rnd(16,d,a,b,c);
+	f_rnd(18,a,b,c,d); f_rnd(20,b,c,d,a);
+	f_rnd(22,c,d,a,b); f_rnd(24,d,a,b,c);
+	f_rnd(26,a,b,c,d); f_rnd(28,b,c,d,a);
+	f_rnd(30,c,d,a,b); f_rnd(32,d,a,b,c);
+	f_rnd(34,a,b,c,d); f_rnd(36,b,c,d,a);
+	f_rnd(38,c,d,a,b); f_rnd(40,d,a,b,c);
+
+	out_blk[0] = a + l_key[42]; out_blk[1] = b;
+	out_blk[2] = c + l_key[43]; out_blk[3] = d;
+	return 0;
+};
+
+/* decrypt a block of text	*/
+
+int rc6_decrypt(struct cipher_context *cx, const u8 *in, u8 *out, int size,
+		int atomic)
+{       u32 *l_key = cx->keyinfo;
+	u32 *in_blk = (u32 *)in;
+	u32 *out_blk = (u32 *)out;
+	u32 a,b,c,d,t,u;
+
+	d = in_blk[3]; c = in_blk[2] - l_key[43]; 
+	b = in_blk[1]; a = in_blk[0] - l_key[42];
+
+	i_rnd(40,d,a,b,c); i_rnd(38,c,d,a,b);
+	i_rnd(36,b,c,d,a); i_rnd(34,a,b,c,d);
+	i_rnd(32,d,a,b,c); i_rnd(30,c,d,a,b);
+	i_rnd(28,b,c,d,a); i_rnd(26,a,b,c,d);
+	i_rnd(24,d,a,b,c); i_rnd(22,c,d,a,b);
+	i_rnd(20,b,c,d,a); i_rnd(18,a,b,c,d);
+	i_rnd(16,d,a,b,c); i_rnd(14,c,d,a,b);
+	i_rnd(12,b,c,d,a); i_rnd(10,a,b,c,d);
+	i_rnd( 8,d,a,b,c); i_rnd( 6,c,d,a,b);
+	i_rnd( 4,b,c,d,a); i_rnd( 2,a,b,c,d);
+
+	out_blk[3] = d - l_key[1]; out_blk[2] = c; 
+	out_blk[1] = b - l_key[0]; out_blk[0] = a; 
+	return 0;
+};
+
+static void rc6_lock(void)
+{
+	MOD_INC_USE_COUNT;
+}
+
+static void rc6_unlock(void)
+{
+	MOD_DEC_USE_COUNT;
+}   
+
+#define CIPHER_BITS_128
+#define CIPHER_NAME(x) rc6##x
+#include "gen-cbc.h"
+#include "gen-ecb.h"
+
+#define RC6_KEY_SCHEDULE_SIZE (44*sizeof(u32))
+
+static struct cipher_implementation rc6_ecb = {
+	{{NULL,NULL}, CIPHER_MODE_ECB, "rc6-ecb"},
+	blocksize: 16,
+	ivsize: 0,
+	key_schedule_size: RC6_KEY_SCHEDULE_SIZE,
+	key_size_mask: CIPHER_KEYSIZE_128 | CIPHER_KEYSIZE_192 | 
+                       CIPHER_KEYSIZE_256,
+	INIT_CIPHER_BLKOPS(rc6_ecb),
+	INIT_CIPHER_OPS(rc6)
+};
+
+static struct cipher_implementation rc6_cbc = {
+	{{NULL,NULL}, CIPHER_MODE_CBC, "rc6-cbc"},
+	blocksize: 16,
+	ivsize: 16,
+	key_schedule_size: RC6_KEY_SCHEDULE_SIZE,
+	key_size_mask: CIPHER_KEYSIZE_128 | CIPHER_KEYSIZE_192 | 
+                       CIPHER_KEYSIZE_256,
+	INIT_CIPHER_BLKOPS(rc6_cbc),
+	INIT_CIPHER_OPS(rc6)
+};
+
+static int __init init_rc6(void)
+{
+	if (register_cipher(&rc6_ecb))
+		printk(KERN_WARNING "Couldn't register rc6-ecb encryption\n");
+	if (register_cipher(&rc6_cbc))
+		printk(KERN_WARNING "Couldn't register rc6-cbc encryption\n");
+
+	return 0;
+}
+
+static void __exit cleanup_rc6(void)
+{
+	if (unregister_cipher(&rc6_ecb))
+		printk(KERN_WARNING "Couldn't unregister rc6-ecb encryption\n");
+	if (unregister_cipher(&rc6_cbc))
+		printk(KERN_WARNING "Couldn't unregister rc6-cbc encryption\n");
+}
+
+module_init(init_rc6);
+module_exit(cleanup_rc6);
diff -Nur linux-2.4.10/crypto/cipher-serpent.c linux-int-2.4.10/crypto/cipher-serpent.c
--- linux-2.4.10/crypto/cipher-serpent.c	Thu Jan  1 01:00:00 1970
+++ linux-int-2.4.10/crypto/cipher-serpent.c	Sat Sep 29 11:16:56 2001
@@ -0,0 +1,1049 @@
+
+/* 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. 
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/wordops.h>
+#include <linux/crypto.h>
+
+#include <asm/byteorder.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(struct cipher_context *cx, const unsigned char *key, int key_len,
+		    int atomic)
+{   u32 *in_key = (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 -EINVAL; /* 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(struct cipher_context *cx, const u8 *in, 
+		    u8 *out, int size, int atomic)
+{    u32 *l_key = cx->keyinfo;
+     const u32 *in_blk = (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(struct cipher_context *cx, const u8 *in,
+		    u8 *out, int size, int atomic)
+{   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;
+};
+
+
+static void serpent_lock(void)
+{
+	MOD_INC_USE_COUNT;
+}
+
+static void serpent_unlock(void)
+{
+	MOD_DEC_USE_COUNT;
+}   
+
+
+#define CIPHER_BITS_128
+#define CIPHER_NAME(x) serpent##x
+#include "gen-cbc.h"
+#include "gen-ecb.h"
+
+#define SERPENT_KEY_SCHEDULE_SIZE (140*sizeof(u32))
+
+static struct cipher_implementation serpent_ecb = {
+	{{NULL,NULL}, CIPHER_MODE_ECB, "serpent-ecb"},
+	blocksize: 16,
+	ivsize: 0,
+	key_schedule_size: SERPENT_KEY_SCHEDULE_SIZE,
+	key_size_mask: CIPHER_KEYSIZE_128 | CIPHER_KEYSIZE_192 | 
+                       CIPHER_KEYSIZE_256,
+	INIT_CIPHER_BLKOPS(serpent_ecb),
+	INIT_CIPHER_OPS(serpent)
+};
+
+static struct cipher_implementation serpent_cbc = {
+	{{NULL,NULL}, CIPHER_MODE_CBC, "serpent-cbc"},
+	blocksize: 16,
+	ivsize: 16,
+	key_schedule_size: SERPENT_KEY_SCHEDULE_SIZE,
+	key_size_mask: CIPHER_KEYSIZE_128 | CIPHER_KEYSIZE_192 | 
+                       CIPHER_KEYSIZE_256,
+	INIT_CIPHER_BLKOPS(serpent_cbc),
+	INIT_CIPHER_OPS(serpent)
+};
+
+static int __init init_serpent(void)
+{
+	if (register_cipher(&serpent_ecb))
+		printk(KERN_WARNING "Couldn't register serpent-ecb encryption\n");
+	if (register_cipher(&serpent_cbc))
+		printk(KERN_WARNING "Couldn't register serpent-cbc encryption\n");
+
+	return 0;
+}
+
+static void __exit cleanup_serpent(void)
+{
+	if (unregister_cipher(&serpent_ecb))
+		printk(KERN_WARNING "Couldn't unregister serpent-ecb encryption\n");
+	if (unregister_cipher(&serpent_cbc))
+		printk(KERN_WARNING "Couldn't unregister serpent-cbc encryption\n");
+}
+
+module_init(init_serpent);
+module_exit(cleanup_serpent);
diff -Nur linux-2.4.10/crypto/cipher-twofish.c linux-int-2.4.10/crypto/cipher-twofish.c
--- linux-2.4.10/crypto/cipher-twofish.c	Thu Jan  1 01:00:00 1970
+++ linux-int-2.4.10/crypto/cipher-twofish.c	Sat Sep 29 11:16:56 2001
@@ -0,0 +1,927 @@
+/* NOTE: This implementation has been changed from the original
+ * source. See ChangeLog for more information.
+ * Maintained by Marc Mutz <Marc@Mutz.com>
+ */
+
+/* Twofish for GPG
+ * By Matthew Skala <mskala@ansuz.sooke.bc.ca>, July 26, 1998
+ * 256-bit key length added March 20, 1999
+ * Some modifications to reduce the text size by Werner Koch, April, 1998
+ *
+ * The original author has disclaimed all copyright interest in this
+ * code and thus putting it in the public domain.
+ *
+ * This code is a "clean room" implementation, written from the paper
+ * _Twofish: A 128-Bit Block Cipher_ by Bruce Schneier, John Kelsey,
+ * Doug Whiting, David Wagner, Chris Hall, and Niels Ferguson, available
+ * through http://www.counterpane.com/twofish.html
+ *
+ * For background information on multiplication in finite fields, used for
+ * the matrix operations in the key schedule, see the book _Contemporary
+ * Abstract Algebra_ by Joseph A. Gallian, especially chapter 22 in the
+ * Third Edition.
+ *
+ * Only the 128- and 256-bit key sizes are supported.  This code is intended
+ * for GNU C on a 32-bit system, but it should work almost anywhere.  Loops
+ * are unrolled, precomputation tables are used, etc., for maximum speed at
+ * some cost in memory consumption. */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/wordops.h>
+#include <linux/crypto.h>
+
+#if 0 /* shouldn't this be #ifdef rotl32 ?
+       * Look at wordops.h: It includes asm/wordops.h.
+       * Anyway, we have to search in the macros for rot's,
+       * since they seem to be defined in a generic way. */
+#define rotl rotl32
+#define rotr rotr32
+#else
+#define rotl generic_rotl32
+#define rotr generic_rotr32
+#endif
+
+/* Structure for an expanded Twofish key.  s contains the key-dependent
+ * S-boxes composed with the MDS matrix; w contains the eight "whitening"
+ * subkeys, K[0] through K[7].	k holds the remaining, "round" subkeys.  Note
+ * that k[i] corresponds to what the Twofish paper calls K[i+8]. */
+typedef struct {
+   u32 s[4][256], w[8], k[32];
+} TWOFISH_context;
+
+/* The large precomputed tables for the Twofish cipher (twofish.c)
+ * Taken from the same source as twofish.c
+ * Marc Mutz <Marc@Mutz.com>
+ */
+
+/* These two tables are the q0 and q1 permutations, exactly as described in
+ * the Twofish paper. */
+
+static const u8 q0[256] = {
+   0xA9, 0x67, 0xB3, 0xE8, 0x04, 0xFD, 0xA3, 0x76, 0x9A, 0x92, 0x80, 0x78,
+   0xE4, 0xDD, 0xD1, 0x38, 0x0D, 0xC6, 0x35, 0x98, 0x18, 0xF7, 0xEC, 0x6C,
+   0x43, 0x75, 0x37, 0x26, 0xFA, 0x13, 0x94, 0x48, 0xF2, 0xD0, 0x8B, 0x30,
+   0x84, 0x54, 0xDF, 0x23, 0x19, 0x5B, 0x3D, 0x59, 0xF3, 0xAE, 0xA2, 0x82,
+   0x63, 0x01, 0x83, 0x2E, 0xD9, 0x51, 0x9B, 0x7C, 0xA6, 0xEB, 0xA5, 0xBE,
+   0x16, 0x0C, 0xE3, 0x61, 0xC0, 0x8C, 0x3A, 0xF5, 0x73, 0x2C, 0x25, 0x0B,
+   0xBB, 0x4E, 0x89, 0x6B, 0x53, 0x6A, 0xB4, 0xF1, 0xE1, 0xE6, 0xBD, 0x45,
+   0xE2, 0xF4, 0xB6, 0x66, 0xCC, 0x95, 0x03, 0x56, 0xD4, 0x1C, 0x1E, 0xD7,
+   0xFB, 0xC3, 0x8E, 0xB5, 0xE9, 0xCF, 0xBF, 0xBA, 0xEA, 0x77, 0x39, 0xAF,
+   0x33, 0xC9, 0x62, 0x71, 0x81, 0x79, 0x09, 0xAD, 0x24, 0xCD, 0xF9, 0xD8,
+   0xE5, 0xC5, 0xB9, 0x4D, 0x44, 0x08, 0x86, 0xE7, 0xA1, 0x1D, 0xAA, 0xED,
+   0x06, 0x70, 0xB2, 0xD2, 0x41, 0x7B, 0xA0, 0x11, 0x31, 0xC2, 0x27, 0x90,
+   0x20, 0xF6, 0x60, 0xFF, 0x96, 0x5C, 0xB1, 0xAB, 0x9E, 0x9C, 0x52, 0x1B,
+   0x5F, 0x93, 0x0A, 0xEF, 0x91, 0x85, 0x49, 0xEE, 0x2D, 0x4F, 0x8F, 0x3B,
+   0x47, 0x87, 0x6D, 0x46, 0xD6, 0x3E, 0x69, 0x64, 0x2A, 0xCE, 0xCB, 0x2F,
+   0xFC, 0x97, 0x05, 0x7A, 0xAC, 0x7F, 0xD5, 0x1A, 0x4B, 0x0E, 0xA7, 0x5A,
+   0x28, 0x14, 0x3F, 0x29, 0x88, 0x3C, 0x4C, 0x02, 0xB8, 0xDA, 0xB0, 0x17,
+   0x55, 0x1F, 0x8A, 0x7D, 0x57, 0xC7, 0x8D, 0x74, 0xB7, 0xC4, 0x9F, 0x72,
+   0x7E, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34, 0x6E, 0x50, 0xDE, 0x68,
+   0x65, 0xBC, 0xDB, 0xF8, 0xC8, 0xA8, 0x2B, 0x40, 0xDC, 0xFE, 0x32, 0xA4,
+   0xCA, 0x10, 0x21, 0xF0, 0xD3, 0x5D, 0x0F, 0x00, 0x6F, 0x9D, 0x36, 0x42,
+   0x4A, 0x5E, 0xC1, 0xE0
+};
+
+static const u8 q1[256] = {
+   0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8, 0x4A, 0xD3, 0xE6, 0x6B,
+   0x45, 0x7D, 0xE8, 0x4B, 0xD6, 0x32, 0xD8, 0xFD, 0x37, 0x71, 0xF1, 0xE1,
+   0x30, 0x0F, 0xF8, 0x1B, 0x87, 0xFA, 0x06, 0x3F, 0x5E, 0xBA, 0xAE, 0x5B,
+   0x8A, 0x00, 0xBC, 0x9D, 0x6D, 0xC1, 0xB1, 0x0E, 0x80, 0x5D, 0xD2, 0xD5,
+   0xA0, 0x84, 0x07, 0x14, 0xB5, 0x90, 0x2C, 0xA3, 0xB2, 0x73, 0x4C, 0x54,
+   0x92, 0x74, 0x36, 0x51, 0x38, 0xB0, 0xBD, 0x5A, 0xFC, 0x60, 0x62, 0x96,
+   0x6C, 0x42, 0xF7, 0x10, 0x7C, 0x28, 0x27, 0x8C, 0x13, 0x95, 0x9C, 0xC7,
+   0x24, 0x46, 0x3B, 0x70, 0xCA, 0xE3, 0x85, 0xCB, 0x11, 0xD0, 0x93, 0xB8,
+   0xA6, 0x83, 0x20, 0xFF, 0x9F, 0x77, 0xC3, 0xCC, 0x03, 0x6F, 0x08, 0xBF,
+   0x40, 0xE7, 0x2B, 0xE2, 0x79, 0x0C, 0xAA, 0x82, 0x41, 0x3A, 0xEA, 0xB9,
+   0xE4, 0x9A, 0xA4, 0x97, 0x7E, 0xDA, 0x7A, 0x17, 0x66, 0x94, 0xA1, 0x1D,
+   0x3D, 0xF0, 0xDE, 0xB3, 0x0B, 0x72, 0xA7, 0x1C, 0xEF, 0xD1, 0x53, 0x3E,
+   0x8F, 0x33, 0x26, 0x5F, 0xEC, 0x76, 0x2A, 0x49, 0x81, 0x88, 0xEE, 0x21,
+   0xC4, 0x1A, 0xEB, 0xD9, 0xC5, 0x39, 0x99, 0xCD, 0xAD, 0x31, 0x8B, 0x01,
+   0x18, 0x23, 0xDD, 0x1F, 0x4E, 0x2D, 0xF9, 0x48, 0x4F, 0xF2, 0x65, 0x8E,
+   0x78, 0x5C, 0x58, 0x19, 0x8D, 0xE5, 0x98, 0x57, 0x67, 0x7F, 0x05, 0x64,
+   0xAF, 0x63, 0xB6, 0xFE, 0xF5, 0xB7, 0x3C, 0xA5, 0xCE, 0xE9, 0x68, 0x44,
+   0xE0, 0x4D, 0x43, 0x69, 0x29, 0x2E, 0xAC, 0x15, 0x59, 0xA8, 0x0A, 0x9E,
+   0x6E, 0x47, 0xDF, 0x34, 0x35, 0x6A, 0xCF, 0xDC, 0x22, 0xC9, 0xC0, 0x9B,
+   0x89, 0xD4, 0xED, 0xAB, 0x12, 0xA2, 0x0D, 0x52, 0xBB, 0x02, 0x2F, 0xA9,
+   0xD7, 0x61, 0x1E, 0xB4, 0x50, 0x04, 0xF6, 0xC2, 0x16, 0x25, 0x86, 0x56,
+   0x55, 0x09, 0xBE, 0x91
+};
+
+/* These MDS tables are actually tables of MDS composed with q0 and q1,
+ * because it is only ever used that way and we can save some time by
+ * precomputing.  Of course the main saving comes from precomputing the
+ * GF(2^8) multiplication involved in the MDS matrix multiply; by looking
+ * things up in these tables we reduce the matrix multiply to four lookups
+ * and three XORs.  Semi-formally, the definition of these tables is:
+ * mds[0][i] = MDS (q1[i] 0 0 0)^T  mds[1][i] = MDS (0 q0[i] 0 0)^T
+ * mds[2][i] = MDS (0 0 q1[i] 0)^T  mds[3][i] = MDS (0 0 0 q0[i])^T
+ * where ^T means "transpose", the matrix multiply is performed in GF(2^8)
+ * represented as GF(2)[x]/v(x) where v(x)=x^8+x^6+x^5+x^3+1 as described
+ * by Schneier et al, and I'm casually glossing over the byte/word
+ * conversion issues. */
+
+static const u32 mds[4][256] = {
+   {0xBCBC3275, 0xECEC21F3, 0x202043C6, 0xB3B3C9F4, 0xDADA03DB, 0x02028B7B,
+    0xE2E22BFB, 0x9E9EFAC8, 0xC9C9EC4A, 0xD4D409D3, 0x18186BE6, 0x1E1E9F6B,
+    0x98980E45, 0xB2B2387D, 0xA6A6D2E8, 0x2626B74B, 0x3C3C57D6, 0x93938A32,
+    0x8282EED8, 0x525298FD, 0x7B7BD437, 0xBBBB3771, 0x5B5B97F1, 0x474783E1,
+    0x24243C30, 0x5151E20F, 0xBABAC6F8, 0x4A4AF31B, 0xBFBF4887, 0x0D0D70FA,
+    0xB0B0B306, 0x7575DE3F, 0xD2D2FD5E, 0x7D7D20BA, 0x666631AE, 0x3A3AA35B,
+    0x59591C8A, 0x00000000, 0xCDCD93BC, 0x1A1AE09D, 0xAEAE2C6D, 0x7F7FABC1,
+    0x2B2BC7B1, 0xBEBEB90E, 0xE0E0A080, 0x8A8A105D, 0x3B3B52D2, 0x6464BAD5,
+    0xD8D888A0, 0xE7E7A584, 0x5F5FE807, 0x1B1B1114, 0x2C2CC2B5, 0xFCFCB490,
+    0x3131272C, 0x808065A3, 0x73732AB2, 0x0C0C8173, 0x79795F4C, 0x6B6B4154,
+    0x4B4B0292, 0x53536974, 0x94948F36, 0x83831F51, 0x2A2A3638, 0xC4C49CB0,
+    0x2222C8BD, 0xD5D5F85A, 0xBDBDC3FC, 0x48487860, 0xFFFFCE62, 0x4C4C0796,
+    0x4141776C, 0xC7C7E642, 0xEBEB24F7, 0x1C1C1410, 0x5D5D637C, 0x36362228,
+    0x6767C027, 0xE9E9AF8C, 0x4444F913, 0x1414EA95, 0xF5F5BB9C, 0xCFCF18C7,
+    0x3F3F2D24, 0xC0C0E346, 0x7272DB3B, 0x54546C70, 0x29294CCA, 0xF0F035E3,
+    0x0808FE85, 0xC6C617CB, 0xF3F34F11, 0x8C8CE4D0, 0xA4A45993, 0xCACA96B8,
+    0x68683BA6, 0xB8B84D83, 0x38382820, 0xE5E52EFF, 0xADAD569F, 0x0B0B8477,
+    0xC8C81DC3, 0x9999FFCC, 0x5858ED03, 0x19199A6F, 0x0E0E0A08, 0x95957EBF,
+    0x70705040, 0xF7F730E7, 0x6E6ECF2B, 0x1F1F6EE2, 0xB5B53D79, 0x09090F0C,
+    0x616134AA, 0x57571682, 0x9F9F0B41, 0x9D9D803A, 0x111164EA, 0x2525CDB9,
+    0xAFAFDDE4, 0x4545089A, 0xDFDF8DA4, 0xA3A35C97, 0xEAEAD57E, 0x353558DA,
+    0xEDEDD07A, 0x4343FC17, 0xF8F8CB66, 0xFBFBB194, 0x3737D3A1, 0xFAFA401D,
+    0xC2C2683D, 0xB4B4CCF0, 0x32325DDE, 0x9C9C71B3, 0x5656E70B, 0xE3E3DA72,
+    0x878760A7, 0x15151B1C, 0xF9F93AEF, 0x6363BFD1, 0x3434A953, 0x9A9A853E,
+    0xB1B1428F, 0x7C7CD133, 0x88889B26, 0x3D3DA65F, 0xA1A1D7EC, 0xE4E4DF76,
+    0x8181942A, 0x91910149, 0x0F0FFB81, 0xEEEEAA88, 0x161661EE, 0xD7D77321,
+    0x9797F5C4, 0xA5A5A81A, 0xFEFE3FEB, 0x6D6DB5D9, 0x7878AEC5, 0xC5C56D39,
+    0x1D1DE599, 0x7676A4CD, 0x3E3EDCAD, 0xCBCB6731, 0xB6B6478B, 0xEFEF5B01,
+    0x12121E18, 0x6060C523, 0x6A6AB0DD, 0x4D4DF61F, 0xCECEE94E, 0xDEDE7C2D,
+    0x55559DF9, 0x7E7E5A48, 0x2121B24F, 0x03037AF2, 0xA0A02665, 0x5E5E198E,
+    0x5A5A6678, 0x65654B5C, 0x62624E58, 0xFDFD4519, 0x0606F48D, 0x404086E5,
+    0xF2F2BE98, 0x3333AC57, 0x17179067, 0x05058E7F, 0xE8E85E05, 0x4F4F7D64,
+    0x89896AAF, 0x10109563, 0x74742FB6, 0x0A0A75FE, 0x5C5C92F5, 0x9B9B74B7,
+    0x2D2D333C, 0x3030D6A5, 0x2E2E49CE, 0x494989E9, 0x46467268, 0x77775544,
+    0xA8A8D8E0, 0x9696044D, 0x2828BD43, 0xA9A92969, 0xD9D97929, 0x8686912E,
+    0xD1D187AC, 0xF4F44A15, 0x8D8D1559, 0xD6D682A8, 0xB9B9BC0A, 0x42420D9E,
+    0xF6F6C16E, 0x2F2FB847, 0xDDDD06DF, 0x23233934, 0xCCCC6235, 0xF1F1C46A,
+    0xC1C112CF, 0x8585EBDC, 0x8F8F9E22, 0x7171A1C9, 0x9090F0C0, 0xAAAA539B,
+    0x0101F189, 0x8B8BE1D4, 0x4E4E8CED, 0x8E8E6FAB, 0xABABA212, 0x6F6F3EA2,
+    0xE6E6540D, 0xDBDBF252, 0x92927BBB, 0xB7B7B602, 0x6969CA2F, 0x3939D9A9,
+    0xD3D30CD7, 0xA7A72361, 0xA2A2AD1E, 0xC3C399B4, 0x6C6C4450, 0x07070504,
+    0x04047FF6, 0x272746C2, 0xACACA716, 0xD0D07625, 0x50501386, 0xDCDCF756,
+    0x84841A55, 0xE1E15109, 0x7A7A25BE, 0x1313EF91},
+
+   {0xA9D93939, 0x67901717, 0xB3719C9C, 0xE8D2A6A6, 0x04050707, 0xFD985252,
+    0xA3658080, 0x76DFE4E4, 0x9A084545, 0x92024B4B, 0x80A0E0E0, 0x78665A5A,
+    0xE4DDAFAF, 0xDDB06A6A, 0xD1BF6363, 0x38362A2A, 0x0D54E6E6, 0xC6432020,
+    0x3562CCCC, 0x98BEF2F2, 0x181E1212, 0xF724EBEB, 0xECD7A1A1, 0x6C774141,
+    0x43BD2828, 0x7532BCBC, 0x37D47B7B, 0x269B8888, 0xFA700D0D, 0x13F94444,
+    0x94B1FBFB, 0x485A7E7E, 0xF27A0303, 0xD0E48C8C, 0x8B47B6B6, 0x303C2424,
+    0x84A5E7E7, 0x54416B6B, 0xDF06DDDD, 0x23C56060, 0x1945FDFD, 0x5BA33A3A,
+    0x3D68C2C2, 0x59158D8D, 0xF321ECEC, 0xAE316666, 0xA23E6F6F, 0x82165757,
+    0x63951010, 0x015BEFEF, 0x834DB8B8, 0x2E918686, 0xD9B56D6D, 0x511F8383,
+    0x9B53AAAA, 0x7C635D5D, 0xA63B6868, 0xEB3FFEFE, 0xA5D63030, 0xBE257A7A,
+    0x16A7ACAC, 0x0C0F0909, 0xE335F0F0, 0x6123A7A7, 0xC0F09090, 0x8CAFE9E9,
+    0x3A809D9D, 0xF5925C5C, 0x73810C0C, 0x2C273131, 0x2576D0D0, 0x0BE75656,
+    0xBB7B9292, 0x4EE9CECE, 0x89F10101, 0x6B9F1E1E, 0x53A93434, 0x6AC4F1F1,
+    0xB499C3C3, 0xF1975B5B, 0xE1834747, 0xE66B1818, 0xBDC82222, 0x450E9898,
+    0xE26E1F1F, 0xF4C9B3B3, 0xB62F7474, 0x66CBF8F8, 0xCCFF9999, 0x95EA1414,
+    0x03ED5858, 0x56F7DCDC, 0xD4E18B8B, 0x1C1B1515, 0x1EADA2A2, 0xD70CD3D3,
+    0xFB2BE2E2, 0xC31DC8C8, 0x8E195E5E, 0xB5C22C2C, 0xE9894949, 0xCF12C1C1,
+    0xBF7E9595, 0xBA207D7D, 0xEA641111, 0x77840B0B, 0x396DC5C5, 0xAF6A8989,
+    0x33D17C7C, 0xC9A17171, 0x62CEFFFF, 0x7137BBBB, 0x81FB0F0F, 0x793DB5B5,
+    0x0951E1E1, 0xADDC3E3E, 0x242D3F3F, 0xCDA47676, 0xF99D5555, 0xD8EE8282,
+    0xE5864040, 0xC5AE7878, 0xB9CD2525, 0x4D049696, 0x44557777, 0x080A0E0E,
+    0x86135050, 0xE730F7F7, 0xA1D33737, 0x1D40FAFA, 0xAA346161, 0xED8C4E4E,
+    0x06B3B0B0, 0x706C5454, 0xB22A7373, 0xD2523B3B, 0x410B9F9F, 0x7B8B0202,
+    0xA088D8D8, 0x114FF3F3, 0x3167CBCB, 0xC2462727, 0x27C06767, 0x90B4FCFC,
+    0x20283838, 0xF67F0404, 0x60784848, 0xFF2EE5E5, 0x96074C4C, 0x5C4B6565,
+    0xB1C72B2B, 0xAB6F8E8E, 0x9E0D4242, 0x9CBBF5F5, 0x52F2DBDB, 0x1BF34A4A,
+    0x5FA63D3D, 0x9359A4A4, 0x0ABCB9B9, 0xEF3AF9F9, 0x91EF1313, 0x85FE0808,
+    0x49019191, 0xEE611616, 0x2D7CDEDE, 0x4FB22121, 0x8F42B1B1, 0x3BDB7272,
+    0x47B82F2F, 0x8748BFBF, 0x6D2CAEAE, 0x46E3C0C0, 0xD6573C3C, 0x3E859A9A,
+    0x6929A9A9, 0x647D4F4F, 0x2A948181, 0xCE492E2E, 0xCB17C6C6, 0x2FCA6969,
+    0xFCC3BDBD, 0x975CA3A3, 0x055EE8E8, 0x7AD0EDED, 0xAC87D1D1, 0x7F8E0505,
+    0xD5BA6464, 0x1AA8A5A5, 0x4BB72626, 0x0EB9BEBE, 0xA7608787, 0x5AF8D5D5,
+    0x28223636, 0x14111B1B, 0x3FDE7575, 0x2979D9D9, 0x88AAEEEE, 0x3C332D2D,
+    0x4C5F7979, 0x02B6B7B7, 0xB896CACA, 0xDA583535, 0xB09CC4C4, 0x17FC4343,
+    0x551A8484, 0x1FF64D4D, 0x8A1C5959, 0x7D38B2B2, 0x57AC3333, 0xC718CFCF,
+    0x8DF40606, 0x74695353, 0xB7749B9B, 0xC4F59797, 0x9F56ADAD, 0x72DAE3E3,
+    0x7ED5EAEA, 0x154AF4F4, 0x229E8F8F, 0x12A2ABAB, 0x584E6262, 0x07E85F5F,
+    0x99E51D1D, 0x34392323, 0x6EC1F6F6, 0x50446C6C, 0xDE5D3232, 0x68724646,
+    0x6526A0A0, 0xBC93CDCD, 0xDB03DADA, 0xF8C6BABA, 0xC8FA9E9E, 0xA882D6D6,
+    0x2BCF6E6E, 0x40507070, 0xDCEB8585, 0xFE750A0A, 0x328A9393, 0xA48DDFDF,
+    0xCA4C2929, 0x10141C1C, 0x2173D7D7, 0xF0CCB4B4, 0xD309D4D4, 0x5D108A8A,
+    0x0FE25151, 0x00000000, 0x6F9A1919, 0x9DE01A1A, 0x368F9494, 0x42E6C7C7,
+    0x4AECC9C9, 0x5EFDD2D2, 0xC1AB7F7F, 0xE0D8A8A8},
+
+   {0xBC75BC32, 0xECF3EC21, 0x20C62043, 0xB3F4B3C9, 0xDADBDA03, 0x027B028B,
+    0xE2FBE22B, 0x9EC89EFA, 0xC94AC9EC, 0xD4D3D409, 0x18E6186B, 0x1E6B1E9F,
+    0x9845980E, 0xB27DB238, 0xA6E8A6D2, 0x264B26B7, 0x3CD63C57, 0x9332938A,
+    0x82D882EE, 0x52FD5298, 0x7B377BD4, 0xBB71BB37, 0x5BF15B97, 0x47E14783,
+    0x2430243C, 0x510F51E2, 0xBAF8BAC6, 0x4A1B4AF3, 0xBF87BF48, 0x0DFA0D70,
+    0xB006B0B3, 0x753F75DE, 0xD25ED2FD, 0x7DBA7D20, 0x66AE6631, 0x3A5B3AA3,
+    0x598A591C, 0x00000000, 0xCDBCCD93, 0x1A9D1AE0, 0xAE6DAE2C, 0x7FC17FAB,
+    0x2BB12BC7, 0xBE0EBEB9, 0xE080E0A0, 0x8A5D8A10, 0x3BD23B52, 0x64D564BA,
+    0xD8A0D888, 0xE784E7A5, 0x5F075FE8, 0x1B141B11, 0x2CB52CC2, 0xFC90FCB4,
+    0x312C3127, 0x80A38065, 0x73B2732A, 0x0C730C81, 0x794C795F, 0x6B546B41,
+    0x4B924B02, 0x53745369, 0x9436948F, 0x8351831F, 0x2A382A36, 0xC4B0C49C,
+    0x22BD22C8, 0xD55AD5F8, 0xBDFCBDC3, 0x48604878, 0xFF62FFCE, 0x4C964C07,
+    0x416C4177, 0xC742C7E6, 0xEBF7EB24, 0x1C101C14, 0x5D7C5D63, 0x36283622,
+    0x672767C0, 0xE98CE9AF, 0x441344F9, 0x149514EA, 0xF59CF5BB, 0xCFC7CF18,
+    0x3F243F2D, 0xC046C0E3, 0x723B72DB, 0x5470546C, 0x29CA294C, 0xF0E3F035,
+    0x088508FE, 0xC6CBC617, 0xF311F34F, 0x8CD08CE4, 0xA493A459, 0xCAB8CA96,
+    0x68A6683B, 0xB883B84D, 0x38203828, 0xE5FFE52E, 0xAD9FAD56, 0x0B770B84,
+    0xC8C3C81D, 0x99CC99FF, 0x580358ED, 0x196F199A, 0x0E080E0A, 0x95BF957E,
+    0x70407050, 0xF7E7F730, 0x6E2B6ECF, 0x1FE21F6E, 0xB579B53D, 0x090C090F,
+    0x61AA6134, 0x57825716, 0x9F419F0B, 0x9D3A9D80, 0x11EA1164, 0x25B925CD,
+    0xAFE4AFDD, 0x459A4508, 0xDFA4DF8D, 0xA397A35C, 0xEA7EEAD5, 0x35DA3558,
+    0xED7AEDD0, 0x431743FC, 0xF866F8CB, 0xFB94FBB1, 0x37A137D3, 0xFA1DFA40,
+    0xC23DC268, 0xB4F0B4CC, 0x32DE325D, 0x9CB39C71, 0x560B56E7, 0xE372E3DA,
+    0x87A78760, 0x151C151B, 0xF9EFF93A, 0x63D163BF, 0x345334A9, 0x9A3E9A85,
+    0xB18FB142, 0x7C337CD1, 0x8826889B, 0x3D5F3DA6, 0xA1ECA1D7, 0xE476E4DF,
+    0x812A8194, 0x91499101, 0x0F810FFB, 0xEE88EEAA, 0x16EE1661, 0xD721D773,
+    0x97C497F5, 0xA51AA5A8, 0xFEEBFE3F, 0x6DD96DB5, 0x78C578AE, 0xC539C56D,
+    0x1D991DE5, 0x76CD76A4, 0x3EAD3EDC, 0xCB31CB67, 0xB68BB647, 0xEF01EF5B,
+    0x1218121E, 0x602360C5, 0x6ADD6AB0, 0x4D1F4DF6, 0xCE4ECEE9, 0xDE2DDE7C,
+    0x55F9559D, 0x7E487E5A, 0x214F21B2, 0x03F2037A, 0xA065A026, 0x5E8E5E19,
+    0x5A785A66, 0x655C654B, 0x6258624E, 0xFD19FD45, 0x068D06F4, 0x40E54086,
+    0xF298F2BE, 0x335733AC, 0x17671790, 0x057F058E, 0xE805E85E, 0x4F644F7D,
+    0x89AF896A, 0x10631095, 0x74B6742F, 0x0AFE0A75, 0x5CF55C92, 0x9BB79B74,
+    0x2D3C2D33, 0x30A530D6, 0x2ECE2E49, 0x49E94989, 0x46684672, 0x77447755,
+    0xA8E0A8D8, 0x964D9604, 0x284328BD, 0xA969A929, 0xD929D979, 0x862E8691,
+    0xD1ACD187, 0xF415F44A, 0x8D598D15, 0xD6A8D682, 0xB90AB9BC, 0x429E420D,
+    0xF66EF6C1, 0x2F472FB8, 0xDDDFDD06, 0x23342339, 0xCC35CC62, 0xF16AF1C4,
+    0xC1CFC112, 0x85DC85EB, 0x8F228F9E, 0x71C971A1, 0x90C090F0, 0xAA9BAA53,
+    0x018901F1, 0x8BD48BE1, 0x4EED4E8C, 0x8EAB8E6F, 0xAB12ABA2, 0x6FA26F3E,
+    0xE60DE654, 0xDB52DBF2, 0x92BB927B, 0xB702B7B6, 0x692F69CA, 0x39A939D9,
+    0xD3D7D30C, 0xA761A723, 0xA21EA2AD, 0xC3B4C399, 0x6C506C44, 0x07040705,
+    0x04F6047F, 0x27C22746, 0xAC16ACA7, 0xD025D076, 0x50865013, 0xDC56DCF7,
+    0x8455841A, 0xE109E151, 0x7ABE7A25, 0x139113EF},
+
+   {0xD939A9D9, 0x90176790, 0x719CB371, 0xD2A6E8D2, 0x05070405, 0x9852FD98,
+    0x6580A365, 0xDFE476DF, 0x08459A08, 0x024B9202, 0xA0E080A0, 0x665A7866,
+    0xDDAFE4DD, 0xB06ADDB0, 0xBF63D1BF, 0x362A3836, 0x54E60D54, 0x4320C643,
+    0x62CC3562, 0xBEF298BE, 0x1E12181E, 0x24EBF724, 0xD7A1ECD7, 0x77416C77,
+    0xBD2843BD, 0x32BC7532, 0xD47B37D4, 0x9B88269B, 0x700DFA70, 0xF94413F9,
+    0xB1FB94B1, 0x5A7E485A, 0x7A03F27A, 0xE48CD0E4, 0x47B68B47, 0x3C24303C,
+    0xA5E784A5, 0x416B5441, 0x06DDDF06, 0xC56023C5, 0x45FD1945, 0xA33A5BA3,
+    0x68C23D68, 0x158D5915, 0x21ECF321, 0x3166AE31, 0x3E6FA23E, 0x16578216,
+    0x95106395, 0x5BEF015B, 0x4DB8834D, 0x91862E91, 0xB56DD9B5, 0x1F83511F,
+    0x53AA9B53, 0x635D7C63, 0x3B68A63B, 0x3FFEEB3F, 0xD630A5D6, 0x257ABE25,
+    0xA7AC16A7, 0x0F090C0F, 0x35F0E335, 0x23A76123, 0xF090C0F0, 0xAFE98CAF,
+    0x809D3A80, 0x925CF592, 0x810C7381, 0x27312C27, 0x76D02576, 0xE7560BE7,
+    0x7B92BB7B, 0xE9CE4EE9, 0xF10189F1, 0x9F1E6B9F, 0xA93453A9, 0xC4F16AC4,
+    0x99C3B499, 0x975BF197, 0x8347E183, 0x6B18E66B, 0xC822BDC8, 0x0E98450E,
+    0x6E1FE26E, 0xC9B3F4C9, 0x2F74B62F, 0xCBF866CB, 0xFF99CCFF, 0xEA1495EA,
+    0xED5803ED, 0xF7DC56F7, 0xE18BD4E1, 0x1B151C1B, 0xADA21EAD, 0x0CD3D70C,
+    0x2BE2FB2B, 0x1DC8C31D, 0x195E8E19, 0xC22CB5C2, 0x8949E989, 0x12C1CF12,
+    0x7E95BF7E, 0x207DBA20, 0x6411EA64, 0x840B7784, 0x6DC5396D, 0x6A89AF6A,
+    0xD17C33D1, 0xA171C9A1, 0xCEFF62CE, 0x37BB7137, 0xFB0F81FB, 0x3DB5793D,
+    0x51E10951, 0xDC3EADDC, 0x2D3F242D, 0xA476CDA4, 0x9D55F99D, 0xEE82D8EE,
+    0x8640E586, 0xAE78C5AE, 0xCD25B9CD, 0x04964D04, 0x55774455, 0x0A0E080A,
+    0x13508613, 0x30F7E730, 0xD337A1D3, 0x40FA1D40, 0x3461AA34, 0x8C4EED8C,
+    0xB3B006B3, 0x6C54706C, 0x2A73B22A, 0x523BD252, 0x0B9F410B, 0x8B027B8B,
+    0x88D8A088, 0x4FF3114F, 0x67CB3167, 0x4627C246, 0xC06727C0, 0xB4FC90B4,
+    0x28382028, 0x7F04F67F, 0x78486078, 0x2EE5FF2E, 0x074C9607, 0x4B655C4B,
+    0xC72BB1C7, 0x6F8EAB6F, 0x0D429E0D, 0xBBF59CBB, 0xF2DB52F2, 0xF34A1BF3,
+    0xA63D5FA6, 0x59A49359, 0xBCB90ABC, 0x3AF9EF3A, 0xEF1391EF, 0xFE0885FE,
+    0x01914901, 0x6116EE61, 0x7CDE2D7C, 0xB2214FB2, 0x42B18F42, 0xDB723BDB,
+    0xB82F47B8, 0x48BF8748, 0x2CAE6D2C, 0xE3C046E3, 0x573CD657, 0x859A3E85,
+    0x29A96929, 0x7D4F647D, 0x94812A94, 0x492ECE49, 0x17C6CB17, 0xCA692FCA,
+    0xC3BDFCC3, 0x5CA3975C, 0x5EE8055E, 0xD0ED7AD0, 0x87D1AC87, 0x8E057F8E,
+    0xBA64D5BA, 0xA8A51AA8, 0xB7264BB7, 0xB9BE0EB9, 0x6087A760, 0xF8D55AF8,
+    0x22362822, 0x111B1411, 0xDE753FDE, 0x79D92979, 0xAAEE88AA, 0x332D3C33,
+    0x5F794C5F, 0xB6B702B6, 0x96CAB896, 0x5835DA58, 0x9CC4B09C, 0xFC4317FC,
+    0x1A84551A, 0xF64D1FF6, 0x1C598A1C, 0x38B27D38, 0xAC3357AC, 0x18CFC718,
+    0xF4068DF4, 0x69537469, 0x749BB774, 0xF597C4F5, 0x56AD9F56, 0xDAE372DA,
+    0xD5EA7ED5, 0x4AF4154A, 0x9E8F229E, 0xA2AB12A2, 0x4E62584E, 0xE85F07E8,
+    0xE51D99E5, 0x39233439, 0xC1F66EC1, 0x446C5044, 0x5D32DE5D, 0x72466872,
+    0x26A06526, 0x93CDBC93, 0x03DADB03, 0xC6BAF8C6, 0xFA9EC8FA, 0x82D6A882,
+    0xCF6E2BCF, 0x50704050, 0xEB85DCEB, 0x750AFE75, 0x8A93328A, 0x8DDFA48D,
+    0x4C29CA4C, 0x141C1014, 0x73D72173, 0xCCB4F0CC, 0x09D4D309, 0x108A5D10,
+    0xE2510FE2, 0x00000000, 0x9A196F9A, 0xE01A9DE0, 0x8F94368F, 0xE6C742E6,
+    0xECC94AEC, 0xFDD25EFD, 0xAB7FC1AB, 0xD8A8E0D8}
+};
+
+/* The exp_to_poly and poly_to_exp tables are used to perform efficient
+ * operations in GF(2^8) represented as GF(2)[x]/w(x) where
+ * w(x)=x^8+x^6+x^3+x^2+1.  We care about doing that because it's part of the
+ * definition of the RS matrix in the key schedule.  Elements of that field
+ * are polynomials of degree not greater than 7 and all coefficients 0 or 1,
+ * which can be represented naturally by bytes (just substitute x=2).  In that
+ * form, GF(2^8) addition is the same as bitwise XOR, but GF(2^8)
+ * multiplication is inefficient without hardware support.  To multiply
+ * faster, I make use of the fact x is a generator for the nonzero elements,
+ * so that every element p of GF(2)[x]/w(x) is either 0 or equal to (x)^n for
+ * some n in 0..254.  Note that that caret is exponentiation in GF(2^8),
+ * *not* polynomial notation.  So if I want to compute pq where p and q are
+ * in GF(2^8), I can just say:
+ *    1. if p=0 or q=0 then pq=0
+ *    2. otherwise, find m and n such that p=x^m and q=x^n
+ *    3. pq=(x^m)(x^n)=x^(m+n), so add m and n and find pq
+ * The translations in steps 2 and 3 are looked up in the tables
+ * poly_to_exp (for step 2) and exp_to_poly (for step 3).  To see this
+ * in action, look at the CALC_S macro.  As additional wrinkles, note that
+ * one of my operands is always a constant, so the poly_to_exp lookup on it
+ * is done in advance; I included the original values in the comments so
+ * readers can have some chance of recognizing that this *is* the RS matrix
+ * from the Twofish paper.  I've only included the table entries I actually
+ * need; I never do a lookup on a variable input of zero and the biggest
+ * exponents I'll ever see are 254 (variable) and 237 (constant), so they'll
+ * never sum to more than 491.	I'm repeating part of the exp_to_poly table
+ * so that I don't have to do mod-255 reduction in the exponent arithmetic.
+ * Since I know my constant operands are never zero, I only have to worry
+ * about zero values in the variable operand, and I do it with a simple
+ * conditional branch.	I know conditionals are expensive, but I couldn't
+ * see a non-horrible way of avoiding them, and I did manage to group the
+ * statements so that each if covers four group multiplications. */
+
+static const u8 poly_to_exp[255] = {
+   0x00, 0x01, 0x17, 0x02, 0x2E, 0x18, 0x53, 0x03, 0x6A, 0x2F, 0x93, 0x19,
+   0x34, 0x54, 0x45, 0x04, 0x5C, 0x6B, 0xB6, 0x30, 0xA6, 0x94, 0x4B, 0x1A,
+   0x8C, 0x35, 0x81, 0x55, 0xAA, 0x46, 0x0D, 0x05, 0x24, 0x5D, 0x87, 0x6C,
+   0x9B, 0xB7, 0xC1, 0x31, 0x2B, 0xA7, 0xA3, 0x95, 0x98, 0x4C, 0xCA, 0x1B,
+   0xE6, 0x8D, 0x73, 0x36, 0xCD, 0x82, 0x12, 0x56, 0x62, 0xAB, 0xF0, 0x47,
+   0x4F, 0x0E, 0xBD, 0x06, 0xD4, 0x25, 0xD2, 0x5E, 0x27, 0x88, 0x66, 0x6D,
+   0xD6, 0x9C, 0x79, 0xB8, 0x08, 0xC2, 0xDF, 0x32, 0x68, 0x2C, 0xFD, 0xA8,
+   0x8A, 0xA4, 0x5A, 0x96, 0x29, 0x99, 0x22, 0x4D, 0x60, 0xCB, 0xE4, 0x1C,
+   0x7B, 0xE7, 0x3B, 0x8E, 0x9E, 0x74, 0xF4, 0x37, 0xD8, 0xCE, 0xF9, 0x83,
+   0x6F, 0x13, 0xB2, 0x57, 0xE1, 0x63, 0xDC, 0xAC, 0xC4, 0xF1, 0xAF, 0x48,
+   0x0A, 0x50, 0x42, 0x0F, 0xBA, 0xBE, 0xC7, 0x07, 0xDE, 0xD5, 0x78, 0x26,
+   0x65, 0xD3, 0xD1, 0x5F, 0xE3, 0x28, 0x21, 0x89, 0x59, 0x67, 0xFC, 0x6E,
+   0xB1, 0xD7, 0xF8, 0x9D, 0xF3, 0x7A, 0x3A, 0xB9, 0xC6, 0x09, 0x41, 0xC3,
+   0xAE, 0xE0, 0xDB, 0x33, 0x44, 0x69, 0x92, 0x2D, 0x52, 0xFE, 0x16, 0xA9,
+   0x0C, 0x8B, 0x80, 0xA5, 0x4A, 0x5B, 0xB5, 0x97, 0xC9, 0x2A, 0xA2, 0x9A,
+   0xC0, 0x23, 0x86, 0x4E, 0xBC, 0x61, 0xEF, 0xCC, 0x11, 0xE5, 0x72, 0x1D,
+   0x3D, 0x7C, 0xEB, 0xE8, 0xE9, 0x3C, 0xEA, 0x8F, 0x7D, 0x9F, 0xEC, 0x75,
+   0x1E, 0xF5, 0x3E, 0x38, 0xF6, 0xD9, 0x3F, 0xCF, 0x76, 0xFA, 0x1F, 0x84,
+   0xA0, 0x70, 0xED, 0x14, 0x90, 0xB3, 0x7E, 0x58, 0xFB, 0xE2, 0x20, 0x64,
+   0xD0, 0xDD, 0x77, 0xAD, 0xDA, 0xC5, 0x40, 0xF2, 0x39, 0xB0, 0xF7, 0x49,
+   0xB4, 0x0B, 0x7F, 0x51, 0x15, 0x43, 0x91, 0x10, 0x71, 0xBB, 0xEE, 0xBF,
+   0x85, 0xC8, 0xA1
+};
+
+static const u8 exp_to_poly[492] = {
+   0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x4D, 0x9A, 0x79, 0xF2,
+   0xA9, 0x1F, 0x3E, 0x7C, 0xF8, 0xBD, 0x37, 0x6E, 0xDC, 0xF5, 0xA7, 0x03,
+   0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0xCD, 0xD7, 0xE3, 0x8B, 0x5B, 0xB6,
+   0x21, 0x42, 0x84, 0x45, 0x8A, 0x59, 0xB2, 0x29, 0x52, 0xA4, 0x05, 0x0A,
+   0x14, 0x28, 0x50, 0xA0, 0x0D, 0x1A, 0x34, 0x68, 0xD0, 0xED, 0x97, 0x63,
+   0xC6, 0xC1, 0xCF, 0xD3, 0xEB, 0x9B, 0x7B, 0xF6, 0xA1, 0x0F, 0x1E, 0x3C,
+   0x78, 0xF0, 0xAD, 0x17, 0x2E, 0x5C, 0xB8, 0x3D, 0x7A, 0xF4, 0xA5, 0x07,
+   0x0E, 0x1C, 0x38, 0x70, 0xE0, 0x8D, 0x57, 0xAE, 0x11, 0x22, 0x44, 0x88,
+   0x5D, 0xBA, 0x39, 0x72, 0xE4, 0x85, 0x47, 0x8E, 0x51, 0xA2, 0x09, 0x12,
+   0x24, 0x48, 0x90, 0x6D, 0xDA, 0xF9, 0xBF, 0x33, 0x66, 0xCC, 0xD5, 0xE7,
+   0x83, 0x4B, 0x96, 0x61, 0xC2, 0xC9, 0xDF, 0xF3, 0xAB, 0x1B, 0x36, 0x6C,
+   0xD8, 0xFD, 0xB7, 0x23, 0x46, 0x8C, 0x55, 0xAA, 0x19, 0x32, 0x64, 0xC8,
+   0xDD, 0xF7, 0xA3, 0x0B, 0x16, 0x2C, 0x58, 0xB0, 0x2D, 0x5A, 0xB4, 0x25,
+   0x4A, 0x94, 0x65, 0xCA, 0xD9, 0xFF, 0xB3, 0x2B, 0x56, 0xAC, 0x15, 0x2A,
+   0x54, 0xA8, 0x1D, 0x3A, 0x74, 0xE8, 0x9D, 0x77, 0xEE, 0x91, 0x6F, 0xDE,
+   0xF1, 0xAF, 0x13, 0x26, 0x4C, 0x98, 0x7D, 0xFA, 0xB9, 0x3F, 0x7E, 0xFC,
+   0xB5, 0x27, 0x4E, 0x9C, 0x75, 0xEA, 0x99, 0x7F, 0xFE, 0xB1, 0x2F, 0x5E,
+   0xBC, 0x35, 0x6A, 0xD4, 0xE5, 0x87, 0x43, 0x86, 0x41, 0x82, 0x49, 0x92,
+   0x69, 0xD2, 0xE9, 0x9F, 0x73, 0xE6, 0x81, 0x4F, 0x9E, 0x71, 0xE2, 0x89,
+   0x5F, 0xBE, 0x31, 0x62, 0xC4, 0xC5, 0xC7, 0xC3, 0xCB, 0xDB, 0xFB, 0xBB,
+   0x3B, 0x76, 0xEC, 0x95, 0x67, 0xCE, 0xD1, 0xEF, 0x93, 0x6B, 0xD6, 0xE1,
+   0x8F, 0x53, 0xA6, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x4D,
+   0x9A, 0x79, 0xF2, 0xA9, 0x1F, 0x3E, 0x7C, 0xF8, 0xBD, 0x37, 0x6E, 0xDC,
+   0xF5, 0xA7, 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0xCD, 0xD7, 0xE3,
+   0x8B, 0x5B, 0xB6, 0x21, 0x42, 0x84, 0x45, 0x8A, 0x59, 0xB2, 0x29, 0x52,
+   0xA4, 0x05, 0x0A, 0x14, 0x28, 0x50, 0xA0, 0x0D, 0x1A, 0x34, 0x68, 0xD0,
+   0xED, 0x97, 0x63, 0xC6, 0xC1, 0xCF, 0xD3, 0xEB, 0x9B, 0x7B, 0xF6, 0xA1,
+   0x0F, 0x1E, 0x3C, 0x78, 0xF0, 0xAD, 0x17, 0x2E, 0x5C, 0xB8, 0x3D, 0x7A,
+   0xF4, 0xA5, 0x07, 0x0E, 0x1C, 0x38, 0x70, 0xE0, 0x8D, 0x57, 0xAE, 0x11,
+   0x22, 0x44, 0x88, 0x5D, 0xBA, 0x39, 0x72, 0xE4, 0x85, 0x47, 0x8E, 0x51,
+   0xA2, 0x09, 0x12, 0x24, 0x48, 0x90, 0x6D, 0xDA, 0xF9, 0xBF, 0x33, 0x66,
+   0xCC, 0xD5, 0xE7, 0x83, 0x4B, 0x96, 0x61, 0xC2, 0xC9, 0xDF, 0xF3, 0xAB,
+   0x1B, 0x36, 0x6C, 0xD8, 0xFD, 0xB7, 0x23, 0x46, 0x8C, 0x55, 0xAA, 0x19,
+   0x32, 0x64, 0xC8, 0xDD, 0xF7, 0xA3, 0x0B, 0x16, 0x2C, 0x58, 0xB0, 0x2D,
+   0x5A, 0xB4, 0x25, 0x4A, 0x94, 0x65, 0xCA, 0xD9, 0xFF, 0xB3, 0x2B, 0x56,
+   0xAC, 0x15, 0x2A, 0x54, 0xA8, 0x1D, 0x3A, 0x74, 0xE8, 0x9D, 0x77, 0xEE,
+   0x91, 0x6F, 0xDE, 0xF1, 0xAF, 0x13, 0x26, 0x4C, 0x98, 0x7D, 0xFA, 0xB9,
+   0x3F, 0x7E, 0xFC, 0xB5, 0x27, 0x4E, 0x9C, 0x75, 0xEA, 0x99, 0x7F, 0xFE,
+   0xB1, 0x2F, 0x5E, 0xBC, 0x35, 0x6A, 0xD4, 0xE5, 0x87, 0x43, 0x86, 0x41,
+   0x82, 0x49, 0x92, 0x69, 0xD2, 0xE9, 0x9F, 0x73, 0xE6, 0x81, 0x4F, 0x9E,
+   0x71, 0xE2, 0x89, 0x5F, 0xBE, 0x31, 0x62, 0xC4, 0xC5, 0xC7, 0xC3, 0xCB
+};
+
+
+/* The table constants are indices of
+ * S-box entries, preprocessed through q0 and q1. */
+static const u8 calc_sb_tbl[512] = {
+    0xA9, 0x75, 0x67, 0xF3, 0xB3, 0xC6, 0xE8, 0xF4,
+    0x04, 0xDB, 0xFD, 0x7B, 0xA3, 0xFB, 0x76, 0xC8,
+    0x9A, 0x4A, 0x92, 0xD3, 0x80, 0xE6, 0x78, 0x6B,
+    0xE4, 0x45, 0xDD, 0x7D, 0xD1, 0xE8, 0x38, 0x4B,
+    0x0D, 0xD6, 0xC6, 0x32, 0x35, 0xD8, 0x98, 0xFD,
+    0x18, 0x37, 0xF7, 0x71, 0xEC, 0xF1, 0x6C, 0xE1,
+    0x43, 0x30, 0x75, 0x0F, 0x37, 0xF8, 0x26, 0x1B,
+    0xFA, 0x87, 0x13, 0xFA, 0x94, 0x06, 0x48, 0x3F,
+    0xF2, 0x5E, 0xD0, 0xBA, 0x8B, 0xAE, 0x30, 0x5B,
+    0x84, 0x8A, 0x54, 0x00, 0xDF, 0xBC, 0x23, 0x9D,
+    0x19, 0x6D, 0x5B, 0xC1, 0x3D, 0xB1, 0x59, 0x0E,
+    0xF3, 0x80, 0xAE, 0x5D, 0xA2, 0xD2, 0x82, 0xD5,
+    0x63, 0xA0, 0x01, 0x84, 0x83, 0x07, 0x2E, 0x14,
+    0xD9, 0xB5, 0x51, 0x90, 0x9B, 0x2C, 0x7C, 0xA3,
+    0xA6, 0xB2, 0xEB, 0x73, 0xA5, 0x4C, 0xBE, 0x54,
+    0x16, 0x92, 0x0C, 0x74, 0xE3, 0x36, 0x61, 0x51,
+    0xC0, 0x38, 0x8C, 0xB0, 0x3A, 0xBD, 0xF5, 0x5A,
+    0x73, 0xFC, 0x2C, 0x60, 0x25, 0x62, 0x0B, 0x96,
+    0xBB, 0x6C, 0x4E, 0x42, 0x89, 0xF7, 0x6B, 0x10,
+    0x53, 0x7C, 0x6A, 0x28, 0xB4, 0x27, 0xF1, 0x8C,
+    0xE1, 0x13, 0xE6, 0x95, 0xBD, 0x9C, 0x45, 0xC7,
+    0xE2, 0x24, 0xF4, 0x46, 0xB6, 0x3B, 0x66, 0x70,
+    0xCC, 0xCA, 0x95, 0xE3, 0x03, 0x85, 0x56, 0xCB,
+    0xD4, 0x11, 0x1C, 0xD0, 0x1E, 0x93, 0xD7, 0xB8,
+    0xFB, 0xA6, 0xC3, 0x83, 0x8E, 0x20, 0xB5, 0xFF,
+    0xE9, 0x9F, 0xCF, 0x77, 0xBF, 0xC3, 0xBA, 0xCC,
+    0xEA, 0x03, 0x77, 0x6F, 0x39, 0x08, 0xAF, 0xBF,
+    0x33, 0x40, 0xC9, 0xE7, 0x62, 0x2B, 0x71, 0xE2,
+    0x81, 0x79, 0x79, 0x0C, 0x09, 0xAA, 0xAD, 0x82,
+    0x24, 0x41, 0xCD, 0x3A, 0xF9, 0xEA, 0xD8, 0xB9,
+    0xE5, 0xE4, 0xC5, 0x9A, 0xB9, 0xA4, 0x4D, 0x97,
+    0x44, 0x7E, 0x08, 0xDA, 0x86, 0x7A, 0xE7, 0x17,
+    0xA1, 0x66, 0x1D, 0x94, 0xAA, 0xA1, 0xED, 0x1D,
+    0x06, 0x3D, 0x70, 0xF0, 0xB2, 0xDE, 0xD2, 0xB3,
+    0x41, 0x0B, 0x7B, 0x72, 0xA0, 0xA7, 0x11, 0x1C,
+    0x31, 0xEF, 0xC2, 0xD1, 0x27, 0x53, 0x90, 0x3E,
+    0x20, 0x8F, 0xF6, 0x33, 0x60, 0x26, 0xFF, 0x5F,
+    0x96, 0xEC, 0x5C, 0x76, 0xB1, 0x2A, 0xAB, 0x49,
+    0x9E, 0x81, 0x9C, 0x88, 0x52, 0xEE, 0x1B, 0x21,
+    0x5F, 0xC4, 0x93, 0x1A, 0x0A, 0xEB, 0xEF, 0xD9,
+    0x91, 0xC5, 0x85, 0x39, 0x49, 0x99, 0xEE, 0xCD,
+    0x2D, 0xAD, 0x4F, 0x31, 0x8F, 0x8B, 0x3B, 0x01,
+    0x47, 0x18, 0x87, 0x23, 0x6D, 0xDD, 0x46, 0x1F,
+    0xD6, 0x4E, 0x3E, 0x2D, 0x69, 0xF9, 0x64, 0x48,
+    0x2A, 0x4F, 0xCE, 0xF2, 0xCB, 0x65, 0x2F, 0x8E,
+    0xFC, 0x78, 0x97, 0x5C, 0x05, 0x58, 0x7A, 0x19,
+    0xAC, 0x8D, 0x7F, 0xE5, 0xD5, 0x98, 0x1A, 0x57,
+    0x4B, 0x67, 0x0E, 0x7F, 0xA7, 0x05, 0x5A, 0x64,
+    0x28, 0xAF, 0x14, 0x63, 0x3F, 0xB6, 0x29, 0xFE,
+    0x88, 0xF5, 0x3C, 0xB7, 0x4C, 0x3C, 0x02, 0xA5,
+    0xB8, 0xCE, 0xDA, 0xE9, 0xB0, 0x68, 0x17, 0x44,
+    0x55, 0xE0, 0x1F, 0x4D, 0x8A, 0x43, 0x7D, 0x69,
+    0x57, 0x29, 0xC7, 0x2E, 0x8D, 0xAC, 0x74, 0x15,
+    0xB7, 0x59, 0xC4, 0xA8, 0x9F, 0x0A, 0x72, 0x9E,
+    0x7E, 0x6E, 0x15, 0x47, 0x22, 0xDF, 0x12, 0x34,
+    0x58, 0x35, 0x07, 0x6A, 0x99, 0xCF, 0x34, 0xDC,
+    0x6E, 0x22, 0x50, 0xC9, 0xDE, 0xC0, 0x68, 0x9B,
+    0x65, 0x89, 0xBC, 0xD4, 0xDB, 0xED, 0xF8, 0xAB,
+    0xC8, 0x12, 0xA8, 0xA2, 0x2B, 0x0D, 0x40, 0x52,
+    0xDC, 0xBB, 0xFE, 0x02, 0x32, 0x2F, 0xA4, 0xA9,
+    0xCA, 0xD7, 0x10, 0x61, 0x21, 0x1E, 0xF0, 0xB4,
+    0xD3, 0x50, 0x5D, 0x04, 0x0F, 0xF6, 0x00, 0xC2,
+    0x6F, 0x16, 0x9D, 0x25, 0x36, 0x86, 0x42, 0x56,
+    0x4A, 0x55, 0x5E, 0x09, 0xC1, 0xBE, 0xE0, 0x91
+};
+
+/* Macro to perform one column of the RS matrix multiplication.  The
+ * parameters a, b, c, and d are the four bytes of output; i is the index
+ * of the key bytes, and w, x, y, and z, are the column of constants from
+ * the RS matrix, preprocessed through the poly_to_exp table. */
+
+#define CALC_S(a, b, c, d, i, w, x, y, z) \
+   if (key[i]) { \
+      tmp = poly_to_exp[key[i] - 1]; \
+      (a) ^= exp_to_poly[tmp + (w)]; \
+      (b) ^= exp_to_poly[tmp + (x)]; \
+      (c) ^= exp_to_poly[tmp + (y)]; \
+      (d) ^= exp_to_poly[tmp + (z)]; \
+   }
+
+/* Macros to calculate the key-dependent S-boxes for a 128-bit key using
+ * the S vector from CALC_S.  CALC_SB_2 computes a single entry in all
+ * four S-boxes, where i is the index of the entry to compute, and a and b
+ * are the index numbers preprocessed through the q0 and q1 tables
+ * respectively. */
+
+#define CALC_SB_2(i, a, b) \
+   ctx->s[0][i] = mds[0][q0[(a) ^ sa] ^ se]; \
+   ctx->s[1][i] = mds[1][q0[(b) ^ sb] ^ sf]; \
+   ctx->s[2][i] = mds[2][q1[(a) ^ sc] ^ sg]; \
+   ctx->s[3][i] = mds[3][q1[(b) ^ sd] ^ sh]
+
+/* Macro exactly like CALC_SB_2, but for 192-bit keys. */
+
+#define CALC_SB192_2(i, a, b) \
+   ctx->s[0][i] = mds[0][q0[q0[(b) ^ sa] ^ se] ^ si]; \
+   ctx->s[1][i] = mds[1][q0[q1[(b) ^ sb] ^ sf] ^ sj]; \
+   ctx->s[2][i] = mds[2][q1[q0[(a) ^ sc] ^ sg] ^ sk]; \
+   ctx->s[3][i] = mds[3][q1[q1[(a) ^ sd] ^ sh] ^ sl];
+
+/* Macro exactly like CALC_SB_2, but for 256-bit keys. */
+
+#define CALC_SB256_2(i, a, b) \
+   ctx->s[0][i] = mds[0][q0[q0[q1[(b) ^ sa] ^ se] ^ si] ^ sm]; \
+   ctx->s[1][i] = mds[1][q0[q1[q1[(a) ^ sb] ^ sf] ^ sj] ^ sn]; \
+   ctx->s[2][i] = mds[2][q1[q0[q0[(a) ^ sc] ^ sg] ^ sk] ^ so]; \
+   ctx->s[3][i] = mds[3][q1[q1[q0[(b) ^ sd] ^ sh] ^ sl] ^ sp];
+
+/* Macros to calculate the whitening and round subkeys.  CALC_K_2 computes the
+ * last two stages of the h() function for a given index (either 2i or 2i+1).
+ * a, b, c, and d are the four bytes going into the last two stages.  For
+ * 128-bit keys, this is the entire h() function and a and c are the index
+ * preprocessed through q0 and q1 respectively; for longer keys they are the
+ * output of previous stages.  j is the index of the first key byte to use.
+ * CALC_K computes a pair of subkeys for 128-bit Twofish, by calling CALC_K_2
+ * twice, doing the Psuedo-Hadamard Transform, and doing the necessary
+ * rotations.  Its parameters are: a, the array to write the results into,
+ * j, the index of the first output entry, k and l, the preprocessed indices
+ * for index 2i, and m and n, the preprocessed indices for index 2i+1.
+ * CALC_K192_2 expands CALC_K_2 to handle 192-bit keys, by doing an
+ * additional lookup-and-XOR stage.  The parameters a, b, c and d are the
+ * four bytes going into the last three stages.  For 192-bit keys, c = d
+ * are the index preprocessed through q0, and a = b are the index
+ * preprocessed through q1; j is the index of the first key byte to use.
+ * CALC_K192 is identical to CALC_K but for using the CALC_K192_2 macro
+ * instead of CALC_K_2.
+ * CALC_K256_2 expands CALC_K192_2 to handle 256-bit keys, by doing an
+ * additional lookup-and-XOR stage.  The parameters a and b are the index
+ * preprocessed through q0 and q1 respectively; j is the index of the first
+ * key byte to use.  CALC_K256 is identical to CALC_K but for using the
+ * CALC_K256_2 macro instead of CALC_K_2. */
+
+#define CALC_K_2(a, b, c, d, j) \
+     mds[0][q0[a ^ key[(j) + 8]] ^ key[j]] \
+   ^ mds[1][q0[b ^ key[(j) + 9]] ^ key[(j) + 1]] \
+   ^ mds[2][q1[c ^ key[(j) + 10]] ^ key[(j) + 2]] \
+   ^ mds[3][q1[d ^ key[(j) + 11]] ^ key[(j) + 3]]
+
+#define CALC_K(a, j, k, l, m, n) \
+   x = CALC_K_2 (k, l, k, l, 0); \
+   y = CALC_K_2 (m, n, m, n, 4); \
+   y = (y << 8) + (y >> 24); \
+   x += y; y += x; ctx->a[j] = x; \
+   ctx->a[(j) + 1] = (y << 9) + (y >> 23)
+
+#define CALC_K192_2(a, b, c, d, j) \
+   CALC_K_2 (q0[a ^ key[(j) + 16]], \
+	     q1[b ^ key[(j) + 17]], \
+	     q0[c ^ key[(j) + 18]], \
+	     q1[d ^ key[(j) + 19]], j)
+
+#define CALC_K192(a, j, k, l, m, n) \
+   x = CALC_K192_2 (l, l, k, k, 0); \
+   y = CALC_K192_2 (n, n, m, m, 4); \
+   y = (y << 8) + (y >> 24); \
+   x += y; y += x; ctx->a[j] = x; \
+   ctx->a[(j) + 1] = (y << 9) + (y >> 23)
+
+#define CALC_K256_2(a, b, j) \
+   CALC_K192_2 (q1[b ^ key[(j) + 24]], \
+	        q1[a ^ key[(j) + 25]], \
+	        q0[a ^ key[(j) + 26]], \
+	        q0[b ^ key[(j) + 27]], j)
+
+#define CALC_K256(a, j, k, l, m, n) \
+   x = CALC_K256_2 (k, l, 0); \
+   y = CALC_K256_2 (m, n, 4); \
+   y = (y << 8) + (y >> 24); \
+   x += y; y += x; ctx->a[j] = x; \
+   ctx->a[(j) + 1] = (y << 9) + (y >> 23)
+
+/* Perform the key setup. */
+
+static int twofish_set_key (struct cipher_context *cx, 
+			    const unsigned char *key, int key_len, int atomic)
+{
+        TWOFISH_context *ctx = (TWOFISH_context *)cx->keyinfo;
+
+	int i, j, k;
+
+	/* Temporaries for CALC_K. */
+	u32 x, y;
+
+	/* The S vector used to key the S-boxes, split up into individual bytes.
+	 * 128-bit keys use only sa through sh; 256-bit use all of them. */
+	u8 sa = 0, sb = 0, sc = 0, sd = 0, se = 0, sf = 0, sg = 0, sh = 0;
+	u8 si = 0, sj = 0, sk = 0, sl = 0, sm = 0, sn = 0, so = 0, sp = 0;
+
+	/* Temporary for CALC_S. */
+	u8 tmp;
+
+	/* Check key length. */
+	if (key_len != 16 && key_len != 24 && key_len != 32)
+		return -EINVAL; /* unsupported key length */
+
+	/* Compute the first two words of the S vector.  The magic numbers are
+	 * the entries of the RS matrix, preprocessed through poly_to_exp. The
+	 * numbers in the comments are the original (polynomial form) matrix
+	 * entries. */
+	CALC_S (sa, sb, sc, sd, 0, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */
+	CALC_S (sa, sb, sc, sd, 1, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */
+	CALC_S (sa, sb, sc, sd, 2, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */
+	CALC_S (sa, sb, sc, sd, 3, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */
+	CALC_S (sa, sb, sc, sd, 4, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */
+	CALC_S (sa, sb, sc, sd, 5, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */
+	CALC_S (sa, sb, sc, sd, 6, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */
+	CALC_S (sa, sb, sc, sd, 7, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */
+	CALC_S (se, sf, sg, sh, 8, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */
+	CALC_S (se, sf, sg, sh, 9, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */
+	CALC_S (se, sf, sg, sh, 10, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */
+	CALC_S (se, sf, sg, sh, 11, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */
+	CALC_S (se, sf, sg, sh, 12, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */
+	CALC_S (se, sf, sg, sh, 13, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */
+	CALC_S (se, sf, sg, sh, 14, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */
+	CALC_S (se, sf, sg, sh, 15, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */
+
+	if (key_len == 24 || key_len == 32) { /* 192- or 256-bit key */
+		/* Calculate the third word of the S vector */
+		CALC_S (si, sj, sk, sl, 16, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */
+		CALC_S (si, sj, sk, sl, 17, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */
+		CALC_S (si, sj, sk, sl, 18, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */
+		CALC_S (si, sj, sk, sl, 19, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */
+		CALC_S (si, sj, sk, sl, 20, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */
+		CALC_S (si, sj, sk, sl, 21, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */
+		CALC_S (si, sj, sk, sl, 22, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */
+		CALC_S (si, sj, sk, sl, 23, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */
+	}
+
+	if (key_len == 32) { /* 256-bit key */
+		/* Calculate the fourth word of the S vector */
+		CALC_S (sm, sn, so, sp, 24, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */
+		CALC_S (sm, sn, so, sp, 25, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */
+		CALC_S (sm, sn, so, sp, 26, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */
+		CALC_S (sm, sn, so, sp, 27, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */
+		CALC_S (sm, sn, so, sp, 28, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */
+		CALC_S (sm, sn, so, sp, 29, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */
+		CALC_S (sm, sn, so, sp, 30, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */
+		CALC_S (sm, sn, so, sp, 31, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */
+
+		/* Compute the S-boxes. */
+		for ( i = j = 0, k = 1; i < 256; i++, j += 2, k += 2 ) {
+			CALC_SB256_2( i, calc_sb_tbl[j], calc_sb_tbl[k] );
+		}
+
+		/* Calculate whitening and round subkeys.  The constants are
+		 * indices of subkeys, preprocessed through q0 and q1. */
+		CALC_K256 (w, 0, 0xA9, 0x75, 0x67, 0xF3);
+		CALC_K256 (w, 2, 0xB3, 0xC6, 0xE8, 0xF4);
+		CALC_K256 (w, 4, 0x04, 0xDB, 0xFD, 0x7B);
+		CALC_K256 (w, 6, 0xA3, 0xFB, 0x76, 0xC8);
+		CALC_K256 (k, 0, 0x9A, 0x4A, 0x92, 0xD3);
+		CALC_K256 (k, 2, 0x80, 0xE6, 0x78, 0x6B);
+		CALC_K256 (k, 4, 0xE4, 0x45, 0xDD, 0x7D);
+		CALC_K256 (k, 6, 0xD1, 0xE8, 0x38, 0x4B);
+		CALC_K256 (k, 8, 0x0D, 0xD6, 0xC6, 0x32);
+		CALC_K256 (k, 10, 0x35, 0xD8, 0x98, 0xFD);
+		CALC_K256 (k, 12, 0x18, 0x37, 0xF7, 0x71);
+		CALC_K256 (k, 14, 0xEC, 0xF1, 0x6C, 0xE1);
+		CALC_K256 (k, 16, 0x43, 0x30, 0x75, 0x0F);
+		CALC_K256 (k, 18, 0x37, 0xF8, 0x26, 0x1B);
+		CALC_K256 (k, 20, 0xFA, 0x87, 0x13, 0xFA);
+		CALC_K256 (k, 22, 0x94, 0x06, 0x48, 0x3F);
+		CALC_K256 (k, 24, 0xF2, 0x5E, 0xD0, 0xBA);
+		CALC_K256 (k, 26, 0x8B, 0xAE, 0x30, 0x5B);
+		CALC_K256 (k, 28, 0x84, 0x8A, 0x54, 0x00);
+		CALC_K256 (k, 30, 0xDF, 0xBC, 0x23, 0x9D);
+	} else if (key_len == 24) { /* 192-bit key */
+		/* Compute the S-boxes. */
+		for ( i = j = 0, k = 1; i < 256; i++, j += 2, k += 2 ) {
+		        CALC_SB192_2( i, calc_sb_tbl[j], calc_sb_tbl[k] );
+		}
+
+		/* Calculate whitening and round subkeys.  The constants are
+		 * indices of subkeys, preprocessed through q0 and q1. */
+		CALC_K192 (w, 0, 0xA9, 0x75, 0x67, 0xF3);
+		CALC_K192 (w, 2, 0xB3, 0xC6, 0xE8, 0xF4);
+		CALC_K192 (w, 4, 0x04, 0xDB, 0xFD, 0x7B);
+		CALC_K192 (w, 6, 0xA3, 0xFB, 0x76, 0xC8);
+		CALC_K192 (k, 0, 0x9A, 0x4A, 0x92, 0xD3);
+		CALC_K192 (k, 2, 0x80, 0xE6, 0x78, 0x6B);
+		CALC_K192 (k, 4, 0xE4, 0x45, 0xDD, 0x7D);
+		CALC_K192 (k, 6, 0xD1, 0xE8, 0x38, 0x4B);
+		CALC_K192 (k, 8, 0x0D, 0xD6, 0xC6, 0x32);
+		CALC_K192 (k, 10, 0x35, 0xD8, 0x98, 0xFD);
+		CALC_K192 (k, 12, 0x18, 0x37, 0xF7, 0x71);
+		CALC_K192 (k, 14, 0xEC, 0xF1, 0x6C, 0xE1);
+		CALC_K192 (k, 16, 0x43, 0x30, 0x75, 0x0F);
+		CALC_K192 (k, 18, 0x37, 0xF8, 0x26, 0x1B);
+		CALC_K192 (k, 20, 0xFA, 0x87, 0x13, 0xFA);
+		CALC_K192 (k, 22, 0x94, 0x06, 0x48, 0x3F);
+		CALC_K192 (k, 24, 0xF2, 0x5E, 0xD0, 0xBA);
+		CALC_K192 (k, 26, 0x8B, 0xAE, 0x30, 0x5B);
+		CALC_K192 (k, 28, 0x84, 0x8A, 0x54, 0x00);
+		CALC_K192 (k, 30, 0xDF, 0xBC, 0x23, 0x9D);
+	} else { /* 128-bit key */
+		/* Compute the S-boxes. */
+		for ( i = j = 0, k = 1; i < 256; i++, j += 2, k += 2 ) {
+			CALC_SB_2( i, calc_sb_tbl[j], calc_sb_tbl[k] );
+		}
+
+		/* Calculate whitening and round subkeys.  The constants are
+		 * indices of subkeys, preprocessed through q0 and q1. */
+		CALC_K (w, 0, 0xA9, 0x75, 0x67, 0xF3);
+		CALC_K (w, 2, 0xB3, 0xC6, 0xE8, 0xF4);
+		CALC_K (w, 4, 0x04, 0xDB, 0xFD, 0x7B);
+		CALC_K (w, 6, 0xA3, 0xFB, 0x76, 0xC8);
+		CALC_K (k, 0, 0x9A, 0x4A, 0x92, 0xD3);
+		CALC_K (k, 2, 0x80, 0xE6, 0x78, 0x6B);
+		CALC_K (k, 4, 0xE4, 0x45, 0xDD, 0x7D);
+		CALC_K (k, 6, 0xD1, 0xE8, 0x38, 0x4B);
+		CALC_K (k, 8, 0x0D, 0xD6, 0xC6, 0x32);
+		CALC_K (k, 10, 0x35, 0xD8, 0x98, 0xFD);
+		CALC_K (k, 12, 0x18, 0x37, 0xF7, 0x71);
+		CALC_K (k, 14, 0xEC, 0xF1, 0x6C, 0xE1);
+		CALC_K (k, 16, 0x43, 0x30, 0x75, 0x0F);
+		CALC_K (k, 18, 0x37, 0xF8, 0x26, 0x1B);
+		CALC_K (k, 20, 0xFA, 0x87, 0x13, 0xFA);
+		CALC_K (k, 22, 0x94, 0x06, 0x48, 0x3F);
+		CALC_K (k, 24, 0xF2, 0x5E, 0xD0, 0xBA);
+		CALC_K (k, 26, 0x8B, 0xAE, 0x30, 0x5B);
+		CALC_K (k, 28, 0x84, 0x8A, 0x54, 0x00);
+		CALC_K (k, 30, 0xDF, 0xBC, 0x23, 0x9D);
+	}
+
+	return 0;
+}
+
+/* Macros to compute the g() function in the encryption and decryption
+ * rounds.  G1 is the straight g() function; G2 includes the 8-bit
+ * rotation for the high 32-bit word. */
+
+#define G1(a) \
+     (ctx->s[0][(a) & 0xFF]) ^ (ctx->s[1][((a) >> 8) & 0xFF]) \
+   ^ (ctx->s[2][((a) >> 16) & 0xFF]) ^ (ctx->s[3][(a) >> 24])
+
+#define G2(b) \
+     (ctx->s[1][(b) & 0xFF]) ^ (ctx->s[2][((b) >> 8) & 0xFF]) \
+   ^ (ctx->s[3][((b) >> 16) & 0xFF]) ^ (ctx->s[0][(b) >> 24])
+
+/* Encryption and decryption Feistel rounds.  Each one calls the two g()
+ * macros, does the PHT, and performs the XOR and the appropriate bit
+ * rotations.  The parameters are the round number (used to select subkeys),
+ * and the four 32-bit chunks of the text. */
+
+#define ENCROUND(n, a, b, c, d) \
+   x = G1 (a); y = G2 (b); \
+   x += y; y += x + ctx->k[2 * (n) + 1]; \
+   (c) ^= x + ctx->k[2 * (n)]; \
+   (c) = ((c) >> 1) + ((c) << 31); \
+   (d) = (((d) << 1)+((d) >> 31)) ^ y
+
+#define DECROUND(n, a, b, c, d) \
+   x = G1 (a); y = G2 (b); \
+   x += y; y += x; \
+   (d) ^= y + ctx->k[2 * (n) + 1]; \
+   (d) = ((d) >> 1) + ((d) << 31); \
+   (c) = (((c) << 1)+((c) >> 31)); \
+   (c) ^= (x + ctx->k[2 * (n)])
+
+/* Encryption and decryption cycles; each one is simply two Feistel rounds
+ * with the 32-bit chunks re-ordered to simulate the "swap" */
+
+#define ENCCYCLE(n) \
+   ENCROUND (2 * (n), a, b, c, d); \
+   ENCROUND (2 * (n) + 1, c, d, a, b)
+
+#define DECCYCLE(n) \
+   DECROUND (2 * (n) + 1, c, d, a, b); \
+   DECROUND (2 * (n), a, b, c, d)
+
+/* Macros to convert the input and output bytes into 32-bit words,
+ * and simultaneously perform the whitening step.  INPACK packs word
+ * number n into the variable named by x, using whitening subkey number m.
+ * OUTUNPACK unpacks word number n from the variable named by x, using
+ * whitening subkey number m. */
+
+#define INPACK(n, x, m) \
+   x = in[4 * (n)] ^ (in[4 * (n) + 1] << 8) \
+     ^ (in[4 * (n) + 2] << 16) ^ (in[4 * (n) + 3] << 24) ^ ctx->w[m]
+
+#define OUTUNPACK(n, x, m) \
+   x ^= ctx->w[m]; \
+   out[4 * (n)] = x; out[4 * (n) + 1] = x >> 8; \
+   out[4 * (n) + 2] = x >> 16; out[4 * (n) + 3] = x >> 24
+
+/* Encrypt one block.  in and out may be the same. */
+
+static int twofish_encrypt (struct cipher_context *cx,
+			    const u8 *in, u8 *out, int size, int atomic)
+{
+        TWOFISH_context *ctx = (TWOFISH_context *)cx->keyinfo;
+
+	/* The four 32-bit chunks of the text. */
+	u32 a, b, c, d;
+	
+	/* Temporaries used by the round function. */
+	u32 x, y;
+	
+	/* Input whitening and packing. */
+	INPACK (0, a, 0);
+	INPACK (1, b, 1);
+	INPACK (2, c, 2);
+	INPACK (3, d, 3);
+	
+	/* Encryption Feistel cycles. */
+	ENCCYCLE (0);
+	ENCCYCLE (1);
+	ENCCYCLE (2);
+	ENCCYCLE (3);
+	ENCCYCLE (4);
+	ENCCYCLE (5);
+	ENCCYCLE (6);
+	ENCCYCLE (7);
+	
+	/* Output whitening and unpacking. */
+	OUTUNPACK (0, c, 4);
+	OUTUNPACK (1, d, 5);
+	OUTUNPACK (2, a, 6);
+	OUTUNPACK (3, b, 7);
+	
+	return 0;
+}
+
+/* Decrypt one block.  in and out may be the same. */
+
+static int twofish_decrypt (struct cipher_context *cx,
+			    const u8 *in, u8 *out, int size, int atomic)
+{
+        TWOFISH_context *ctx = (TWOFISH_context *)cx->keyinfo;
+  
+	/* The four 32-bit chunks of the text. */
+	u32 a, b, c, d;
+	
+	/* Temporaries used by the round function. */
+	u32 x, y;
+	
+	/* Input whitening and packing. */
+	INPACK (0, c, 4);
+	INPACK (1, d, 5);
+	INPACK (2, a, 6);
+	INPACK (3, b, 7);
+	
+	/* Encryption Feistel cycles. */
+	DECCYCLE (7);
+	DECCYCLE (6);
+	DECCYCLE (5);
+	DECCYCLE (4);
+	DECCYCLE (3);
+	DECCYCLE (2);
+	DECCYCLE (1);
+	DECCYCLE (0);
+
+	/* Output whitening and unpacking. */
+	OUTUNPACK (0, a, 0);
+	OUTUNPACK (1, b, 1);
+	OUTUNPACK (2, c, 2);
+	OUTUNPACK (3, d, 3);
+
+	return 0;
+}
+
+static void twofish_lock(void)
+{
+        MOD_INC_USE_COUNT;
+}
+
+static void twofish_unlock(void)
+{
+        MOD_DEC_USE_COUNT;
+}
+
+#define CIPHER_BITS_128
+#define CIPHER_NAME(x) twofish##x
+#include "gen-cbc.h"
+#include "gen-ecb.h"
+
+
+static struct cipher_implementation twofish_ecb = {
+	{{NULL,NULL}, CIPHER_MODE_ECB, "twofish-ecb"},
+	blocksize: 16,
+	ivsize: 0,
+	key_schedule_size: sizeof(TWOFISH_context),
+	key_size_mask: CIPHER_KEYSIZE_128 | CIPHER_KEYSIZE_192 | 
+                       CIPHER_KEYSIZE_256,
+	INIT_CIPHER_BLKOPS(twofish_ecb),
+	INIT_CIPHER_OPS(twofish)
+};
+
+static struct cipher_implementation twofish_cbc = {
+	{{NULL,NULL}, CIPHER_MODE_CBC, "twofish-cbc"},
+	blocksize: 16,
+	ivsize: 16,
+	key_schedule_size: sizeof(TWOFISH_context),
+	key_size_mask: CIPHER_KEYSIZE_128 | CIPHER_KEYSIZE_192 | 
+                       CIPHER_KEYSIZE_256,
+	INIT_CIPHER_BLKOPS(twofish_cbc),
+	INIT_CIPHER_OPS(twofish)
+};
+
+static int __init init_twofish(void)
+{
+        if (register_cipher(&twofish_ecb))
+	        printk(KERN_WARNING "Couldn't register twofish-ecb encryption\n");
+        if (register_cipher(&twofish_cbc))
+	        printk(KERN_WARNING "Couldn't register twofish-cbc encryption\n");
+
+	return 0;
+}
+
+static void __exit cleanup_twofish(void)
+{
+        if (unregister_cipher(&twofish_ecb))
+	        printk(KERN_WARNING "Couldn't unregister twofish-ecb encryption\n");
+        if (unregister_cipher(&twofish_cbc))
+	        printk(KERN_WARNING "Couldn't unregister twofish-cbc encryption\n");
+}
+
+module_init(init_twofish);
+module_exit(cleanup_twofish);
diff -Nur linux-2.4.10/crypto/cryptoapi.c linux-int-2.4.10/crypto/cryptoapi.c
--- linux-2.4.10/crypto/cryptoapi.c	Thu Jan  1 01:00:00 1970
+++ linux-int-2.4.10/crypto/cryptoapi.c	Sat Sep 29 11:16:56 2001
@@ -0,0 +1,471 @@
+/*
+ * crypto/cryptoapi.c
+ *
+ * Written by Alexander Kjeldaas <astor@fast.no> 1998-11-15
+ *
+ * 2000-10-15 Harald Welte <laforge@gnumonks.org>
+ * 		- ported to Linux 2.4 
+ * 
+ * Copyright 1998 by Alexander Kjeldaas. Redistribution of this file
+ * is permitted under the GNU Public License.
+ */
+
+#include <linux/module.h>
+#include <linux/version.h>
+
+#ifdef CONFIG_KMOD
+#include <linux/kmod.h>
+#endif 
+
+#include <linux/init.h>
+#include <linux/config.h>
+#include <linux/string.h>
+#include <linux/crypto.h>
+#include <linux/proc_fs.h>
+
+
+static struct proc_dir_entry *proc_crypto;
+
+static struct cipher_context *
+default_realloc_context(struct cipher_context *old_cx,
+			struct cipher_implementation *,
+			int max_key_len);
+static void default_wipe_context(struct cipher_context *cx);
+static void default_free_context(struct cipher_context *cx);
+static void default_lock(void);
+static void default_unlock(void);
+static int default_encrypt(struct cipher_context *cx, 
+			   const u8 *in, u8 *out, int size,
+			   const u32 iv[]);
+static int default_encrypt_atomic(struct cipher_context *cx, 
+				  const u8 *in, u8 *out, int size,
+				  const u32 iv[]);
+static int default_decrypt(struct cipher_context *cx, 
+			   const u8 *in, u8 *out, int size, const u32 iv[]);
+static int default_decrypt_atomic(struct cipher_context *cx, 
+				  const u8 *in, u8 *out, int size,
+				  const u32 iv[]);
+static int default_set_key(struct cipher_context *cx, 
+			   const unsigned char *key, int key_len);
+static int default_set_key_atomic(struct cipher_context *cx, 
+				  const unsigned char *key, int key_len);
+
+
+#ifdef CONFIG_PROC_FS
+static int cipher_read_proc(char *page, char **start, off_t off,
+			int count, int *eof, void *data);
+static int digest_read_proc(char *page, char **start, off_t off,
+			int count, int *eof, void *data);
+#endif
+
+static LIST_HEAD(ciphers);
+static LIST_HEAD(digests);
+
+static struct transform_group transforms[MAX_TRANSFORM] = {
+	/* digest */
+	{ TRANSFORM_DIGEST, "digest", RW_LOCK_UNLOCKED, &digests, 
+#ifdef CONFIG_PROC_FS
+	  NULL, &digest_read_proc 
+#endif
+	},
+	/* cipher */
+	{ TRANSFORM_CIPHER, "cipher", RW_LOCK_UNLOCKED, &ciphers, 
+#ifdef CONFIG_PROC_FS
+	  NULL, &cipher_read_proc 
+#endif
+	}
+};
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0) && defined(CONFIG_PROC_FS)
+static struct proc_dir_entry *
+create_proc_read_entry(const char *name,
+		       mode_t mode, struct proc_dir_entry *base, 
+		       read_proc_t *read_proc, void * data)
+{
+	struct proc_dir_entry *res=create_proc_entry(name,mode,base);
+	if (res) {
+		res->read_proc=read_proc;
+		res->data=data;
+	}
+	return res;
+}
+
+#endif
+
+
+/**
+ * find_transform_by_name - Find transform implementation
+ * @name: The name of the transform.
+ * @tgroup: The identifier for the transform group the transform belongs to.
+ *
+ * Returns a ptr to the transform on success, NULL on failure.
+ * Valid tgroup values are:
+ *
+ * %TRANSFORM_CIPHER - When looking for ciphers
+ *
+ * %TRANSFORM_DIGEST - When looking for digests
+ *
+ * You might want to use the wrapper-functions
+ * find_cipher_by_name(const char *name), and
+ * find_digest_by_name(const char *name) instead of this one.
+ */                                                                             
+struct transform_implementation *
+find_transform_by_name(const char *name, int tgroup, int atomicapi)
+{
+	struct list_head *tmp;
+	struct transform_group *tg;
+#ifdef CONFIG_KMOD
+	char module_name[200];
+	char *p;
+#endif
+
+	if (tgroup >= MAX_TRANSFORM)
+		return NULL;
+	tg = &transforms[tgroup];
+
+#ifdef CONFIG_KMOD
+	sprintf(module_name, "%s-%s-", tg->tg_name, name);
+retry:
+#endif
+	read_lock(&tg->tg_lock);
+	for (tmp = tg->tg_head->next; tmp != tg->tg_head; tmp = tmp->next) {
+		struct transform_implementation *t;
+		t = list_entry(tmp, struct transform_implementation, t_list);
+		if (strcmp(t->t_name, name) == 0) {
+			if (!atomicapi || t->t_atomicapi) {
+				read_unlock(&tg->tg_lock);
+				return t;
+			}
+		}
+	}
+
+	/* transform not found */
+	read_unlock(&tg->tg_lock);
+
+#ifdef CONFIG_KMOD
+	/* We try loading more and more general modules in succession.
+	 * For example, if the module_name initially is set to
+	 * "cipher-blowfish-cbc", we first try a module called
+	 * "cipher-blowfish-cbc", then "cipher-blowfish" */
+	if ((p = strrchr(module_name, '-')) != NULL) {
+		*p = 0;
+		printk(KERN_DEBUG "cryptoapi: trying %s\n", module_name);
+		request_module(module_name);
+		goto retry;
+	}
+#endif
+	return NULL;
+}
+
+/**
+ * register_transform - Register new transform.
+ * @ti: Initialized transform implementation struct.
+ * @tgroup: The identifier for the transform group the transform should belong to.
+ *
+ * Adds a transform from the crypto API. ti->t_group is set to point
+ * to the correct transform group according to tgroup, the transform
+ * is added to the group's transform-list, and a /proc files are
+ * created if CONFIG_PROC_FS=y Returns 0 on success.  Valid tgroup
+ * values are:
+ *
+ * %TRANSFORM_CIPHER - When adding ciphers
+ *
+ * %TRANSFORM_DIGEST - When adding digests
+ *
+ */                                                                             
+int 
+register_transform(struct transform_implementation *ti, int tgroup)
+{
+	int err = 0;
+	struct transform_group *tg;
+	
+	if (tgroup >= MAX_TRANSFORM) {
+		return -1;
+	}
+	INIT_LIST_HEAD(&ti->t_list);
+	tg = ti->t_group = &transforms[tgroup];
+	write_lock(&ti->t_group->tg_lock);
+	list_add(&ti->t_list, ti->t_group->tg_head);
+	write_unlock(&ti->t_group->tg_lock);
+	if (!err) {
+		MOD_INC_USE_COUNT;
+		printk(KERN_INFO "cryptoapi: Registered %s (%d)\n", 
+			ti->t_name, ti->t_flags);
+		ti->t_proc = create_proc_read_entry(ti->t_name,
+						S_IFREG|S_IRUGO,
+						tg->tg_proc_parent_dir,
+						tg->read_proc, (void *)ti);
+	}
+	return err;
+}
+
+/**
+ * unregister_transform - Unregister new transform.
+ * @ti: Initialized transform implementation struct.
+ *
+ * Removes a transform from the crypto API.  Returns 0 on success,
+ * non-zero on failure to remove /proc entry.
+ *
+ */                                                                             
+int 
+unregister_transform(struct transform_implementation *ti)
+{
+	int ret = 0;
+
+	if (!list_empty(&ti->t_list)) {
+		write_lock(&ti->t_group->tg_lock);
+		list_del(&ti->t_list);
+		write_unlock(&ti->t_group->tg_lock);
+		ret = 0;
+	}
+
+#ifdef CONFIG_PROC_FS
+	if (ti->t_proc) {
+		ti->t_proc = NULL;
+		remove_proc_entry(ti->t_name, ti->t_group->tg_proc_parent_dir);
+	}
+#endif
+
+	if (!ret) 
+		MOD_DEC_USE_COUNT;
+
+	return ret;
+}
+
+
+int 
+register_cipher(struct cipher_implementation *ci)
+{
+	if (!ci->realloc_context) {
+		ci->realloc_context = default_realloc_context;
+	}
+	if (!ci->wipe_context) {
+		ci->wipe_context = default_wipe_context;
+	}
+	if (!ci->free_context) {
+		ci->free_context = default_free_context;
+	}
+	if (!ci->lock) {
+		ci->lock = default_lock;
+	}
+	if (!ci->unlock) {
+		ci->unlock = default_unlock;
+	}
+
+	if (ci->_encrypt && ci->_decrypt && ci->_set_key) {
+		ci->encrypt = default_encrypt;
+		ci->encrypt_atomic = default_encrypt_atomic;
+		ci->decrypt = default_decrypt;
+		ci->decrypt_atomic = default_decrypt_atomic;
+		ci->set_key = default_set_key;
+		ci->set_key_atomic = default_set_key_atomic;
+		ci->trans.t_atomicapi = 1;
+	}
+
+	if (!ci->encrypt || !ci->decrypt || !ci->set_key) {
+		return -EINVAL;
+	}
+	return register_transform((struct transform_implementation *)ci,
+				  TRANSFORM_CIPHER);
+}
+
+int 
+register_digest(struct digest_implementation *di)
+{
+	return register_transform((struct transform_implementation *)di,
+				  TRANSFORM_DIGEST);
+}
+
+int 
+unregister_cipher(struct cipher_implementation *ci)
+{
+	return unregister_transform((struct transform_implementation *)ci);
+}
+
+int 
+unregister_digest(struct digest_implementation *ci)
+{
+	return unregister_transform((struct transform_implementation *)ci);
+}
+
+
+struct cipher_context *
+default_realloc_context(struct cipher_context *old_cx,
+			struct cipher_implementation *ci,
+			int max_key_len)
+{
+	struct cipher_context *cx;
+	/* Default ciphers need the same amount of memory for any key
+           size */
+	if (old_cx) {
+		return old_cx;
+	}
+	cx = kmalloc(sizeof(struct cipher_context) +
+		     ci->key_schedule_size, GFP_KERNEL);
+	if (!cx) {
+		return NULL;
+	}
+	cx->ci = ci;
+	cx->keyinfo = (void *)((char *)cx)+sizeof(struct cipher_context);
+	(void) max_key_len; /* Make gcc happy */
+	return cx;
+}
+
+void
+default_wipe_context(struct cipher_context *cx)
+{
+	struct cipher_implementation *ci = cx->ci;
+	u32 *keyinfo = cx->keyinfo;
+	memset(cx->keyinfo, 0, ci->key_schedule_size);
+	memset(cx, 0, sizeof(struct cipher_context));
+	cx->ci = ci;
+	cx->keyinfo = keyinfo;
+}
+
+void
+default_free_context(struct cipher_context *cx)
+{
+	kfree(cx);
+}
+
+void 
+default_lock(void)
+{
+}
+
+void
+default_unlock(void)
+{
+}
+
+
+static int 
+default_encrypt(struct cipher_context *cx, const u8 *in, u8 *out, int size,
+		const u32 iv[])
+{
+	return cx->ci->_encrypt(cx, in, out, size, 0, iv);
+}
+
+static int 
+default_encrypt_atomic(struct cipher_context *cx, const u8 *in, u8 *out, 
+		       int size, const u32 iv[])
+{
+	return cx->ci->_encrypt(cx, in, out, size, 1, iv);
+}
+
+
+static int 
+default_decrypt(struct cipher_context *cx, const u8 *in, u8 *out, int size,
+		const u32 iv[])
+{
+	return cx->ci->_decrypt(cx, in, out, size, 0, iv);
+}
+
+static int 
+default_decrypt_atomic(struct cipher_context *cx, const u8 *in, u8 *out, 
+		       int size, const u32 iv[])
+{
+	return cx->ci->_decrypt(cx, in, out, size, 1, iv);
+}
+
+static int
+default_set_key(struct cipher_context *cx, const unsigned char *key, int key_len)
+{
+	return cx->ci->_set_key(cx, key, key_len, 0);
+}
+
+static int
+default_set_key_atomic(struct cipher_context *cx, const unsigned char *key, 
+		       int key_len)
+{
+	return cx->ci->_set_key(cx, key, key_len, 1);
+}
+
+#ifdef CONFIG_PROC_FS
+static int cipher_read_proc(char *page, char **start, off_t off,
+			    int count, int *eof, void *data)
+{
+	struct cipher_implementation *ci;
+	int len = 0;
+	
+	ci = (struct cipher_implementation *)data;
+
+	len = sprintf(page,
+		      "cipher_name:       %s\n"
+		      "cipher_flags:      %d\n"
+		      "blocksize:         %d\n"
+		      "keysize_mask:      0x%08x\n"
+		      "ivsize:            %d\n"
+		      "key_schedule_size: %d\n",
+		      ci->trans.t_name, ci->trans.t_flags, 
+		      ci->blocksize, ci->key_size_mask,
+		      ci->ivsize, ci->key_schedule_size);
+	*eof=1;
+
+	return len;
+}
+
+static int digest_read_proc(char *page, char **start, off_t off,
+			int count, int *eof, void *data)
+{
+	struct digest_implementation *ci;
+	int len = 0;
+	
+	ci = (struct digest_implementation *)data;
+
+	len = sprintf(page, "digest_name:       %s\n"
+		      "digest_flags:      %d\n"
+		      "blocksize:         %d\n"
+		      "working_size:      %d\n",
+		      ci->trans.t_name, ci->trans.t_flags, 
+		      ci->blocksize, ci->working_size);
+	*eof=1;
+
+	return len;
+}
+#endif
+
+
+static int __init
+init_cryptoapi(void)
+{
+	int i;
+
+#ifdef CONFIG_PROC_FS
+	proc_crypto = proc_mkdir("crypto", NULL);
+
+	for (i = 0; i<sizeof(transforms)/sizeof(struct transform_group); i++) {
+		transforms[i].tg_proc_parent_dir = 
+			proc_mkdir(transforms[i].tg_name, proc_crypto);
+	}
+#endif
+	printk(KERN_INFO "cryptoapi: loaded\n");
+	return 0;
+}
+
+static void __exit
+cleanup_cryptoapi(void) 
+{
+	int i;
+
+#ifdef CONFIG_PROC_FS
+	for (i = 0; i<sizeof(transforms)/sizeof(struct transform_group); i++) {
+		struct proc_dir_entry *p = transforms[i].tg_proc_parent_dir;
+		remove_proc_entry(transforms[i].tg_name, p);
+	}
+	remove_proc_entry("crypto", NULL);
+#endif
+	printk(KERN_INFO "cryptoapi: unloaded\n");
+}
+
+module_init(init_cryptoapi);
+module_exit(cleanup_cryptoapi);
+
+
+EXPORT_SYMBOL(find_transform_by_name);
+EXPORT_SYMBOL(register_transform);
+EXPORT_SYMBOL(unregister_transform);
+EXPORT_SYMBOL(register_cipher);
+EXPORT_SYMBOL(unregister_cipher);
+EXPORT_SYMBOL(register_digest);
+EXPORT_SYMBOL(unregister_digest);
diff -Nur linux-2.4.10/crypto/cryptoloop.c linux-int-2.4.10/crypto/cryptoloop.c
--- linux-2.4.10/crypto/cryptoloop.c	Thu Jan  1 01:00:00 1970
+++ linux-int-2.4.10/crypto/cryptoloop.c	Sat Sep 29 11:16:56 2001
@@ -0,0 +1,245 @@
+/* 
+   Linux loop encryption enabling module
+
+   $Id: cryptoapi-2.4.10.diff,v 1.1 2002/02/25 20:29:11 andros Exp $
+
+   Written by Herbert Valerio Riedel <hvr@gnu.org> 
+
+   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
+ */
+
+/* use ./configure --enable-iv-mode-sector */
+/* #define USE_LO_IV_MODE_SECTOR */
+
+/* #define CRYPTOLOOP_DEBUG */
+
+/* use atomic crypto functions */
+/* #define CRYPTOLOOP_ATOMIC */
+
+#include <linux/module.h>
+#include <linux/version.h>
+
+#ifdef CONFIG_KMOD
+#include <linux/kmod.h>
+#endif 
+
+#include <linux/init.h>
+#include <linux/config.h>
+#include <linux/string.h>
+#include <linux/crypto.h>
+#include <linux/loop.h>
+#include <linux/blk.h>
+
+#ifdef CONFIG_CRYPTOLOOP_512IV
+# define USE_LO_IV_MODE_SECTOR
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,3)
+# error you need at least kernel 2.4.3 -- unless you know exacty what you are doing
+#endif
+
+#if !defined(LO_CRYPT_CRYPTOAPI)
+# warning LO_CRYPT_CRYPTOAPI not (yet) defined in kernel header
+# define LO_CRYPT_CRYPTOAPI 18
+#endif
+
+static inline int
+loop_get_bs(struct loop_device *lo)
+{
+  int bs = 0;
+
+  if (blksize_size[MAJOR(lo->lo_device)])
+    bs = blksize_size[MAJOR(lo->lo_device)][MINOR(lo->lo_device)];
+  if (!bs)
+    bs = BLOCK_SIZE;        
+
+  return bs;
+}
+
+static int 
+transfer_cryptoapi(struct loop_device *lo, int cmd, char *raw_buf,
+                   char *loop_buf, int size, int real_block)
+{ 
+  struct cipher_context * cx = (struct cipher_context *) lo->key_data;
+  struct cipher_implementation *ci = cx->ci;
+  int (*encdecfunc)(struct cipher_context *cx, const u8 *in, u8 *out, 
+		    int size, const u32 iv[]);
+  char *in, *out;
+
+  if (cmd == READ) {
+#if defined(CRYPTOLOOP_ATOMIC)
+    encdecfunc = ci->decrypt_atomic;
+#else
+    encdecfunc = ci->decrypt;
+#endif
+    in = raw_buf;
+    out = loop_buf;
+  } else {
+#if defined(CRYPTOLOOP_ATOMIC)
+    encdecfunc = ci->encrypt_atomic;
+#else
+    encdecfunc = ci->encrypt;
+#endif
+    in = loop_buf;
+    out = raw_buf;
+  }
+
+#if defined(CRYPTOLOOP_DEBUG)
+#warning CRYPTOLOOP_DEBUG enabled
+  printk (KERN_DEBUG "cryptoxfer: cmd=%d size=%d iv=%d blksize=%d\n", 
+	  cmd, size, real_block, loop_get_bs (lo));
+#endif
+
+#if defined(USE_LO_IV_MODE_SECTOR)
+#warning USE_LO_IV_MODE_SECTOR enabled -- hope you know what this means
+  /* split up transfer request into 512 byte data blocks */
+  while (size > 0) {
+    int _size = (size > LO_IV_SECTOR_SIZE) ? LO_IV_SECTOR_SIZE : size;    
+    u32 iv[4] = { 0, };
+
+    iv[0] = cpu_to_le32 (real_block);
+    encdecfunc (cx, in, out, _size, iv);
+
+    real_block++;
+    size -= _size;
+    in += _size;
+    out += _size;
+  }
+#else
+  {
+    u32 iv[4] = { 0, };
+    iv[0] = cpu_to_le32 (real_block);
+    encdecfunc (cx, in, out, size, iv);
+  }
+#endif
+
+  return 0;
+}
+
+static int 
+cryptoapi_status(struct loop_device *lo, struct loop_info *info)
+{
+  int err = -EINVAL;
+  char cipher[LO_NAME_SIZE];
+  struct cipher_implementation *ci;
+  struct cipher_context *cx;
+
+#if defined(USE_LO_IV_MODE_SECTOR)
+# if !defined(LO_IV_MODE_SECTOR)
+# error You dont seem have a kernel patched for this to work...
+# endif
+  /* encryption breaks for non sector aligned offsets */
+  if (info->lo_offset % LO_IV_SECTOR_SIZE) 
+    goto out;
+
+  lo->lo_iv_mode = LO_IV_MODE_SECTOR;
+#endif
+
+  strncpy(cipher, info->lo_name, LO_NAME_SIZE);
+  cipher[LO_NAME_SIZE - 1] = 0;
+                
+  ci = find_cipher_by_name(cipher, 1);
+  if (!ci)
+    goto out;
+
+  ci->lock();
+  err = -ENOMEM;
+  cx = ci->realloc_context(NULL, ci, info->lo_encrypt_key_size);
+  if (!cx)
+    goto out_ci;
+  cx->ci = ci;
+  ci->wipe_context(cx);
+  if (ci->set_key(cx, info->lo_encrypt_key, 
+		  info->lo_encrypt_key_size)) {
+    err = -EINVAL;
+    goto out_key;
+  }
+  lo->key_data = cx;
+  err = 0;
+  goto out;
+
+ out_key:
+  ci->wipe_context(cx);
+  ci->free_context(cx);
+ out_ci:
+  ci->unlock();
+ out:
+  if (!err) {
+    MOD_INC_USE_COUNT;
+  }
+	  
+  return err;
+}
+
+static int 
+cryptoapi_release(struct loop_device *lo)
+{ 
+  struct cipher_context *cx = (struct cipher_context *) lo->key_data;
+
+  if (cx != NULL) { 
+    cx->ci->wipe_context(cx);
+    cx->ci->unlock();
+    cx->ci->free_context(cx);
+    lo->key_data=NULL;
+    MOD_DEC_USE_COUNT;
+    return 0;
+  }
+
+  printk (KERN_ERR "cryptoapi_release(): cx == NULL ????\n");
+  return -EINVAL;
+}
+
+struct loop_func_table cryptoloop_funcs = { 
+  number: LO_CRYPT_CRYPTOAPI,
+  transfer: transfer_cryptoapi,
+  init: cryptoapi_status,
+  release: cryptoapi_release
+};      
+
+static int __init
+init_cryptoloop(void)
+{
+  int rc;
+
+  if ((rc = loop_register_transfer (&cryptoloop_funcs)))
+    {
+      printk(KERN_ERR "cryptoloop: register loop transfer function failed\n");
+      return rc;
+    }
+
+  printk(KERN_INFO "cryptoloop: loaded\n");
+  return 0;
+}
+
+static void __exit
+cleanup_cryptoloop(void) 
+{
+  if (loop_unregister_transfer (LO_CRYPT_CRYPTOAPI))
+    printk(KERN_ERR "cryptoloop: unregistering transfer funcs failed\n");
+
+  printk(KERN_INFO "cryptoloop: unloaded\n");
+}
+
+module_init(init_cryptoloop);
+module_exit(cleanup_cryptoloop);
+
+/* 
+ * Local variables:
+ *  c-file-style: "gnu"
+ *  tab-width: 8
+ *  indent-tabs-mode: nil
+ * End:
+ */
diff -Nur linux-2.4.10/crypto/digest-md5.c linux-int-2.4.10/crypto/digest-md5.c
--- linux-2.4.10/crypto/digest-md5.c	Thu Jan  1 01:00:00 1970
+++ linux-int-2.4.10/crypto/digest-md5.c	Sat Sep 29 11:16:56 2001
@@ -0,0 +1,101 @@
+
+/*
+ * Source code by Alan Smithee, mailed to maintainer on pulped trees.
+ *
+ * Glue that ties the standard MD5 code to the rest of the system.
+ * Everything below this line is GPL.  
+ *
+ */
+
+#include <linux/types.h>
+#include <asm/uaccess.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/crypto.h>
+#include "md5.h"
+#include "md5c.c"
+
+static int
+md5_open (struct digest_context *cx)
+{
+	if (!cx || !cx->digest_info)
+		return -EINVAL;
+
+	MD5Init ((struct MD5_CTX *) cx->digest_info);
+
+	return 0;
+}
+
+static int
+md5_update (struct digest_context *cx, u8 *in, int size)
+{
+	if (!cx || !in || !cx->digest_info)
+		return -EINVAL;
+
+	MD5Update ((struct MD5_CTX *) cx->digest_info, in, size);
+
+	return 0;
+}
+
+static int
+md5_digest (struct digest_context *cx, u8 *out)
+{
+	struct MD5_CTX tmp;
+
+	if (!cx || !out || !cx->digest_info)
+		return -EINVAL;
+
+	memcpy (&tmp, (struct MD5_CTX *) cx->digest_info, 
+		sizeof (struct MD5_CTX));
+	MD5Final (out, &tmp);
+
+	return 0;
+}
+
+static int
+md5_close (struct digest_context *cx, u8 *out)
+{
+	u8 tmp[16];
+
+	if (!cx || !cx->digest_info)
+		return -EINVAL;
+	
+	if (out == 0)
+		out = tmp;
+
+	MD5Final (out, (struct MD5_CTX *) cx->digest_info);
+
+	return 0;
+}
+
+static void md5_lock (void)
+{
+	MOD_INC_USE_COUNT;
+}
+
+static void md5_unlock(void)
+{
+	MOD_DEC_USE_COUNT;
+}
+
+static struct digest_implementation md5 = {
+	{{NULL,NULL}, 0, "md5"},
+	blocksize: 16,
+	working_size: sizeof(MD5_CTX),
+	INIT_DIGEST_OPS(md5)
+};
+
+static int __init init_md5 (void)
+{
+	printk ("MD5 Message Digest Algorithm (c) RSA Systems, Inc\n");
+	register_digest (&md5);
+	return 0;
+}
+
+static void __exit cleanup_md5 (void)
+{
+	unregister_digest (&md5);
+}
+
+module_init(init_md5);
+module_exit(cleanup_md5);
diff -Nur linux-2.4.10/crypto/digest-sha1.c linux-int-2.4.10/crypto/digest-sha1.c
--- linux-2.4.10/crypto/digest-sha1.c	Thu Jan  1 01:00:00 1970
+++ linux-int-2.4.10/crypto/digest-sha1.c	Sat Sep 29 11:16:56 2001
@@ -0,0 +1,99 @@
+/*
+ * Modified by Andrew McDonald <andrew@mcdonald.org.uk> from md5glue
+ * by Alan Smithee, mailed to maintainer on pulped trees.
+ *
+ * Glue that ties the standard SHA1 code to the rest of the system.
+ * Everything below this line is GPL.  
+ *
+ */
+
+#include <linux/types.h>
+#include <asm/uaccess.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/crypto.h>
+#include "sha1c.c"
+
+static int
+sha1_open (struct digest_context *cx)
+{
+	if (!cx || !cx->digest_info)
+		return -EINVAL;
+
+	SHA1Init ((struct SHA1_CTX *) cx->digest_info);
+
+	return 0;
+}
+
+static int
+sha1_update (struct digest_context *cx, u8 *in, int size)
+{
+	if (!cx || !in || !cx->digest_info)
+		return -EINVAL;
+
+	SHA1Update ((struct SHA1_CTX *) cx->digest_info, in, size);
+
+	return 0;
+}
+
+static int
+sha1_digest (struct digest_context *cx, u8 *out)
+{
+	struct SHA1_CTX tmp;
+
+	if (!cx || !out || !cx->digest_info)
+		return -EINVAL;
+
+	memcpy (&tmp, (struct SHA1_CTX *) cx->digest_info, 
+		sizeof (struct SHA1_CTX));
+	SHA1Final (out, &tmp);
+
+	return 0;
+}
+
+static int
+sha1_close (struct digest_context *cx, u8 *out)
+{
+	u8 tmp[16];
+
+	if (!cx || !cx->digest_info)
+		return -EINVAL;
+	
+	if (out == 0)
+		out = tmp;
+
+	SHA1Final (out, (struct SHA1_CTX *) cx->digest_info);
+
+	return 0;
+}
+
+static void sha1_lock (void)
+{
+	MOD_INC_USE_COUNT;
+}
+
+static void sha1_unlock(void)
+{
+	MOD_DEC_USE_COUNT;
+}
+
+static struct digest_implementation sha1 = {
+	{{NULL,NULL}, 0, "sha1"},
+	blocksize: 20,
+	working_size: sizeof(struct SHA1_CTX),
+	INIT_DIGEST_OPS(sha1)
+};
+
+static int __init init_sha1 (void)
+{
+	register_digest (&sha1);
+	return 0;
+}
+
+static void __exit cleanup_sha1 (void)
+{
+	unregister_digest (&sha1);
+}
+
+module_init(init_sha1);
+module_exit(cleanup_sha1);
diff -Nur linux-2.4.10/crypto/gen-cbc.h linux-int-2.4.10/crypto/gen-cbc.h
--- linux-2.4.10/crypto/gen-cbc.h	Thu Jan  1 01:00:00 1970
+++ linux-int-2.4.10/crypto/gen-cbc.h	Sat Sep 29 11:16:56 2001
@@ -0,0 +1,95 @@
+
+#include <linux/string.h>
+
+#if defined(CIPHER_BITS_128)
+# define BS 16
+#else
+# define BS 8
+#endif
+
+/*  
+ * These functions only use the XOR operator on the data, so no
+ * endianness problems should occur.
+ */
+
+static int CIPHER_NAME(_cbc_encrypt)(struct cipher_context *cx, const u8 *in_blk, 
+				     u8 *out_blk, int size, int atomic, const u32 iv[])
+{
+	u8 tmp[BS];
+	((u32 *)tmp)[0] = iv[0]; 
+	((u32 *)tmp)[1] = iv[1];
+#ifdef CIPHER_BITS_128
+	((u32 *)tmp)[2] = iv[2]; 
+	((u32 *)tmp)[3] = iv[3];
+#endif
+	for (size -= BS; size >= 0; size -= BS) {
+		((u32 *)tmp)[0] ^= ((u32 *)in_blk)[0];
+		((u32 *)tmp)[1] ^= ((u32 *)in_blk)[1];
+#ifdef CIPHER_BITS_128
+		((u32 *)tmp)[2] ^= ((u32 *)in_blk)[2];
+		((u32 *)tmp)[3] ^= ((u32 *)in_blk)[3];
+#endif
+		CIPHER_NAME(_encrypt)(cx, tmp, tmp, BS, atomic);
+		memcpy(out_blk, tmp, sizeof(tmp));
+		in_blk += BS; out_blk += BS;
+		if (!atomic && current->need_resched) 
+			schedule();
+
+	} /* for */
+
+	if (size != -BS) {
+		memset(tmp, 0, sizeof(tmp));
+		memcpy(tmp, in_blk, size+BS);
+		((u32 *)tmp)[0] ^= ((u32 *)out_blk)[0 - BS/4]; 
+		((u32 *)tmp)[1] ^= ((u32 *)out_blk)[1 - BS/4];
+#ifdef CIPHER_BITS_128
+		((u32 *)tmp)[2] ^= ((u32 *)out_blk)[2 - BS/4];
+		((u32 *)tmp)[3] ^= ((u32 *)out_blk)[3 - BS/4];
+#endif
+		CIPHER_NAME(_encrypt)(cx, tmp, out_blk, BS, atomic);
+	} /* if */
+
+	return 0;
+}
+
+static int CIPHER_NAME(_cbc_decrypt)(struct cipher_context *cx, const u8 *in_blk, 
+				     u8 *out_blk, int size, int atomic, const u32 iv[])
+{
+	u8 tmp[BS], tmp2[BS];
+	((u32 *)tmp)[0] = iv[0]; 
+	((u32 *)tmp)[1] = iv[1];
+#ifdef CIPHER_BITS_128
+	((u32 *)tmp)[2] = iv[2]; 
+	((u32 *)tmp)[3] = iv[3];
+#endif
+
+	for (size -= BS; size >= 0; size -= BS) {
+		CIPHER_NAME(_decrypt)(cx, in_blk, tmp2, BS, atomic);
+		((u32 *)tmp2)[0] ^= ((u32 *)tmp)[0];
+		((u32 *)tmp2)[1] ^= ((u32 *)tmp)[1];
+#ifdef CIPHER_BITS_128
+		((u32 *)tmp2)[2] ^= ((u32 *)tmp)[2];
+		((u32 *)tmp2)[3] ^= ((u32 *)tmp)[3];
+#endif
+		memcpy(tmp, in_blk, sizeof(tmp));
+		memcpy(out_blk, tmp2, BS);
+		in_blk += BS; out_blk += BS;
+		if (!atomic && current->need_resched) {
+			schedule();
+		}
+	}
+
+	if (size != -BS) { 
+		CIPHER_NAME(_decrypt)(cx, in_blk, tmp2, BS, atomic);
+		((u32 *)tmp2)[0] ^= ((u32 *)tmp)[0];
+		((u32 *)tmp2)[1] ^= ((u32 *)tmp)[1];
+#ifdef CIPHER_BITS_128
+		((u32 *)tmp2)[2] ^= ((u32 *)tmp)[2];
+		((u32 *)tmp2)[3] ^= ((u32 *)tmp)[3];
+#endif
+		memcpy(out_blk, tmp2, size+BS);
+	}
+	return 0;
+}
+
+#undef BS
diff -Nur linux-2.4.10/crypto/gen-ecb.h linux-int-2.4.10/crypto/gen-ecb.h
--- linux-2.4.10/crypto/gen-ecb.h	Thu Jan  1 01:00:00 1970
+++ linux-int-2.4.10/crypto/gen-ecb.h	Sat Sep 29 11:16:56 2001
@@ -0,0 +1,48 @@
+
+#include <linux/string.h>
+
+#if defined(CIPHER_BITS_128)
+# define BS 16
+#else
+# define BS 8
+#endif
+
+static int CIPHER_NAME(_ecb_encrypt)(struct cipher_context *cx, const u8 *in_blk, 
+				     u8 *out_blk, int size, int atomic, const u32 iv[])
+{
+	u8 tmp[BS];
+	for (size -= BS; size >= 0; size -= BS) {
+		CIPHER_NAME(_encrypt)(cx, in_blk, out_blk, BS, atomic);
+		in_blk += BS; out_blk += BS;
+		if (!atomic && current->need_resched) {
+			schedule();
+		}
+	}
+	if (size != -BS) {
+		memset(tmp, 0, sizeof(tmp));
+		memcpy(tmp, in_blk, size+BS);
+		CIPHER_NAME(_encrypt)(cx, tmp, out_blk, BS, atomic);
+	}
+	return 0;
+}
+
+static int CIPHER_NAME(_ecb_decrypt)(struct cipher_context *cx, const u8 *in_blk, 
+				     u8 *out_blk, int size, int atomic, const u32 iv[])
+{
+	u8 tmp[BS];
+	for (size -= BS; size >= 0; size -= BS) {
+		CIPHER_NAME(_decrypt)(cx, in_blk, out_blk, BS, atomic);
+		in_blk += BS; out_blk += BS;
+		if (!atomic && current->need_resched) {
+			schedule();
+		}
+	}
+	if (size != -BS) {
+		CIPHER_NAME(_decrypt)(cx, in_blk, tmp, BS, atomic);
+		memcpy(out_blk, tmp, size+BS);
+	}
+	return 0;
+}
+
+
+#undef BS
diff -Nur linux-2.4.10/crypto/md5.h linux-int-2.4.10/crypto/md5.h
--- linux-2.4.10/crypto/md5.h	Thu Jan  1 01:00:00 1970
+++ linux-int-2.4.10/crypto/md5.h	Sat Sep 29 11:16:56 2001
@@ -0,0 +1,56 @@
+/* md5.h - header file for md5c.c
+ */
+
+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+   rights reserved.
+
+   License to copy and use this software is granted provided that it
+   is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+   Algorithm" in all material mentioning or referencing this software
+   or this function.
+
+   License is also granted to make and use derivative works provided
+   that such works are identified as "derived from the RSA Data
+   Security, Inc. MD5 Message-Digest Algorithm" in all material
+   mentioning or referencing the derived work.
+   
+   RSA Data Security, Inc. makes no representations concerning either
+   the merchantability of this software or the suitability of this
+   software for any particular purpose. It is provided "as is" without
+   express or implied warranty of any kind.
+   
+   These notices must be retained in any copies of any part of this
+   documentation and/or software.
+*/
+
+
+#ifndef _CRYPTO_MD5_H
+#define _CRYPTO_MD5_H
+
+/* MD5 context. */
+struct MD5_CTX {
+	u32 state[4];                                   /* state (ABCD) */
+	u32 count[2];        /* number of bits, modulo 2^64 (lsb first) */
+	unsigned char buffer[64];                       /* input buffer */
+};
+
+typedef struct MD5_CTX MD5_CTX;
+
+static void MD5Init (struct MD5_CTX *);
+static void MD5Update (struct MD5_CTX *, unsigned char *, unsigned int);
+static void MD5Final (unsigned char x[16], struct MD5_CTX *);
+
+#endif /* _CRYPTO_MD5_H */
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -Nur linux-2.4.10/crypto/md5c.c linux-int-2.4.10/crypto/md5c.c
--- linux-2.4.10/crypto/md5c.c	Thu Jan  1 01:00:00 1970
+++ linux-int-2.4.10/crypto/md5c.c	Sat Sep 29 11:16:56 2001
@@ -0,0 +1,319 @@
+/* The MD5 implementation below was modified by Alexander Kjeldaas
+   <astor@fast.no> 1999-09-15 for readability purposes, and for
+   inclusion into the Linux kernel */
+
+/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
+ */
+
+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+rights reserved.
+
+License to copy and use this software is granted provided that it
+is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+Algorithm" in all material mentioning or referencing this software
+or this function.
+
+License is also granted to make and use derivative works provided
+that such works are identified as "derived from the RSA Data
+Security, Inc. MD5 Message-Digest Algorithm" in all material
+mentioning or referencing the derived work.
+
+RSA Data Security, Inc. makes no representations concerning either
+the merchantability of this software or the suitability of this
+software for any particular purpose. It is provided "as is"
+without express or implied warranty of any kind.
+
+These notices must be retained in any copies of any part of this
+documentation and/or software.
+ */
+
+#include <linux/config.h>
+#include <linux/string.h>
+#include <asm/byteorder.h>
+#include <linux/crypto.h>
+#include "md5.h"
+
+/* Start of Linux Kernel port */
+typedef u32 UINT4;
+typedef u8  *POINTER;
+#define PROTO_LIST(x) x
+#define MD5_memcpy memcpy
+#define MD5_memset memset
+
+/* Encodes input (UINT4) into output (unsigned char). Assumes len is
+  a multiple of 4.
+ */
+#ifdef __LITTLE_ENDIAN
+#define Encode memcpy
+#define Decode memcpy
+#else
+static void Encode (unsigned char *output,
+		    UINT4 *input,
+		    unsigned int len)
+{
+  unsigned int i;
+  UINT4 *out = (UINT4 *)output;
+  len <<= 2;
+
+  for (i = 0; i < len; i++) {
+	  out[i] = cpu_to_le32(input[i]);
+  }
+}
+
+/* Decodes input (unsigned char) into output (UINT4). Assumes len is
+  a multiple of 4.
+ */
+static void Decode (UINT4 *output,
+		    unsigned char *input,
+		    unsigned int len)
+{
+  unsigned int i;
+  UINT4 *in = (UINT4 *)input;
+  len <<= 2;
+
+  for (i = 0; i < len; i++) {
+	  output[i] = le32_to_cpu(in[i]);
+  }
+}
+
+#endif /* __LITTLE_ENDIAN */
+/* End of Linux Kernel port */
+
+
+/* Constants for MD5Transform routine.
+ */
+#define S11 7
+#define S12 12
+#define S13 17
+#define S14 22
+#define S21 5
+#define S22 9
+#define S23 14
+#define S24 20
+#define S31 4
+#define S32 11
+#define S33 16
+#define S34 23
+#define S41 6
+#define S42 10
+#define S43 15
+#define S44 21
+
+static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64]));
+
+static unsigned char PADDING[64] = {
+  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/* F, G, H and I are basic MD5 functions.
+ */
+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
+#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define I(x, y, z) ((y) ^ ((x) | (~z)))
+
+/* ROTATE_LEFT rotates x left n bits.
+ */
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
+
+/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
+Rotation is separate from addition to prevent recomputation.
+ */
+#define FF(a, b, c, d, x, s, ac) { \
+ (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+  }
+#define GG(a, b, c, d, x, s, ac) { \
+ (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+  }
+#define HH(a, b, c, d, x, s, ac) { \
+ (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+  }
+#define II(a, b, c, d, x, s, ac) { \
+ (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+  }
+
+/* MD5 initialization. Begins an MD5 operation, writing a new context.
+ */
+static void MD5Init (MD5_CTX *context)                   /* context */
+{
+  context->count[0] = context->count[1] = 0;
+  /* Load magic initialization constants.
+*/
+  context->state[0] = 0x67452301;
+  context->state[1] = 0xefcdab89;
+  context->state[2] = 0x98badcfe;
+  context->state[3] = 0x10325476;
+}
+
+/* MD5 block update operation. Continues an MD5 message-digest
+  operation, processing another message block, and updating the
+  context.
+ */
+static void MD5Update (MD5_CTX *context,                 /* context */
+		unsigned char *input,                /* input block */
+		unsigned int inputLen)     /* length of input block */
+{
+  unsigned int i, index, partLen;
+
+  /* Compute number of bytes mod 64 */
+  index = (unsigned int)((context->count[0] >> 3) & 0x3F);
+
+  /* Update number of bits */
+  if ((context->count[0] += ((UINT4)inputLen << 3))
+   < ((UINT4)inputLen << 3))
+ context->count[1]++;
+  context->count[1] += ((UINT4)inputLen >> 29);
+
+  partLen = 64 - index;
+
+  /* Transform as many times as possible.
+*/
+  if (inputLen >= partLen) {
+ MD5_memcpy
+   ((POINTER)&context->buffer[index], (POINTER)input, partLen);
+ MD5Transform (context->state, context->buffer);
+
+ for (i = partLen; i + 63 < inputLen; i += 64)
+   MD5Transform (context->state, &input[i]);
+
+ index = 0;
+  }
+  else
+ i = 0;
+
+  /* Buffer remaining input */
+  MD5_memcpy
+ ((POINTER)&context->buffer[index], (POINTER)&input[i],
+  inputLen-i);
+}
+
+/* MD5 finalization. Ends an MD5 message-digest operation, writing the
+  the message digest and zeroizing the context.
+ */
+static void MD5Final (unsigned char digest[16],  /* message digest */
+		      MD5_CTX *context)                 /* context */
+{
+  unsigned char bits[8];
+  unsigned int index, padLen;
+
+  /* Save number of bits */
+  Encode (bits, context->count, 8);
+
+  /* Pad out to 56 mod 64.
+*/
+  index = (unsigned int)((context->count[0] >> 3) & 0x3f);
+  padLen = (index < 56) ? (56 - index) : (120 - index);
+  MD5Update (context, PADDING, padLen);
+
+  /* Append length (before padding) */
+  MD5Update (context, bits, 8);
+  /* Store state in digest */
+  Encode (digest, context->state, 16);
+
+  /* Zeroize sensitive information.
+*/
+  MD5_memset ((POINTER)context, 0, sizeof (*context));
+}
+
+/* MD5 basic transformation. Transforms state based on block.
+ */
+static void MD5Transform (UINT4 state[4],
+			  unsigned char block[64])
+{
+  UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
+
+  Decode (x, block, 64);
+
+  /* Round 1 */
+  FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
+  FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
+  FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
+  FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
+  FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
+  FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
+  FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
+  FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
+  FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
+  FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
+  FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
+  FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
+  FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
+  FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
+  FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
+  FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
+
+ /* Round 2 */
+  GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
+  GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
+  GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
+  GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
+  GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
+  GG (d, a, b, c, x[10], S22,  0x2441453); /* 22 */
+  GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
+  GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
+  GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
+  GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
+  GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
+  GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
+  GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
+  GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
+  GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
+  GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
+
+  /* Round 3 */
+  HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
+  HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
+  HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
+  HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
+  HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
+  HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
+  HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
+  HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
+  HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
+  HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
+  HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
+  HH (b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */
+  HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
+  HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
+  HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
+  HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
+
+  /* Round 4 */
+  II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
+  II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
+  II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
+  II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
+  II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
+  II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
+  II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
+  II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
+  II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
+  II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
+  II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
+  II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
+  II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
+  II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
+  II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
+  II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
+
+  state[0] += a;
+  state[1] += b;
+  state[2] += c;
+  state[3] += d;
+
+  /* Zeroize sensitive information.
+*/
+  MD5_memset ((POINTER)x, 0, sizeof (x));
+}
+
+
diff -Nur linux-2.4.10/crypto/sha1c.c linux-int-2.4.10/crypto/sha1c.c
--- linux-2.4.10/crypto/sha1c.c	Thu Jan  1 01:00:00 1970
+++ linux-int-2.4.10/crypto/sha1c.c	Sat Sep 29 11:16:56 2001
@@ -0,0 +1,183 @@
+/*
+Modified for kerneli by Andrew McDonald <andrew@mcdonald.org.uk>
+from:
+
+SHA-1 in C
+By Steve Reid <steve@edmweb.com>
+100% Public Domain
+Available from:
+ftp://ftp.zedz.net/pub/crypto/crypto/HASH/sha/sha1.c
+
+Test Vectors (from FIPS PUB 180-1)
+"abc"
+  A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
+"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
+  84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
+A million repetitions of "a"
+  34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
+*/
+
+#define SHA1HANDSOFF /* Copies data before messing with it. */
+
+#include <linux/string.h>
+
+struct SHA1_CTX {
+	unsigned long state[5];
+	unsigned long count[2];
+	unsigned char buffer[64];
+};
+
+static void SHA1Transform(unsigned long state[5], unsigned char buffer[64]);
+static void SHA1Init(struct SHA1_CTX* context);
+static void SHA1Update(struct SHA1_CTX* context, unsigned char* data, 
+		       unsigned int len);
+static void SHA1Final(unsigned char digest[20], struct SHA1_CTX* context);
+
+#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
+
+/* blk0() and blk() perform the initial expand. */
+/* I got the idea of expanding during the round function from SSLeay */
+#ifdef __LITTLE_ENDIAN
+#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
+    |(rol(block->l[i],8)&0x00FF00FF))
+#else
+#define blk0(i) block->l[i]
+#endif /* __LITTLE_ENDIAN */
+#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
+    ^block->l[(i+2)&15]^block->l[i&15],1))
+
+/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
+#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
+#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
+#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
+#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
+#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
+
+
+/* Hash a single 512-bit block. This is the core of the algorithm. */
+
+void SHA1Transform(unsigned long state[5], unsigned char buffer[64])
+{
+	unsigned long a, b, c, d, e;
+	typedef union {
+		unsigned char c[64];
+		unsigned long l[16];
+	} CHAR64LONG16;
+	CHAR64LONG16* block;
+#ifdef SHA1HANDSOFF
+	static unsigned char workspace[64];
+	block = (CHAR64LONG16*)workspace;
+	memcpy(block, buffer, 64);
+#else
+	block = (CHAR64LONG16*)buffer;
+#endif
+	/* Copy context->state[] to working vars */
+	a = state[0];
+	b = state[1];
+	c = state[2];
+	d = state[3];
+	e = state[4];
+	/* 4 rounds of 20 operations each. Loop unrolled. */
+	R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
+	R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
+	R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
+	R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
+	R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
+	R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
+	R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
+	R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
+	R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
+	R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
+	R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
+	R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
+	R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
+	R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
+	R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
+	R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
+	R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
+	R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
+	R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
+	R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
+	/* Add the working vars back into context.state[] */
+	state[0] += a;
+	state[1] += b;
+	state[2] += c;
+	state[3] += d;
+	state[4] += e;
+	/* Wipe variables */
+	a = b = c = d = e = 0;
+}
+
+
+/* SHA1Init - Initialize new context */
+
+void SHA1Init(struct SHA1_CTX* context)
+{
+	/* SHA1 initialization constants */
+	context->state[0] = 0x67452301;
+	context->state[1] = 0xEFCDAB89;
+	context->state[2] = 0x98BADCFE;
+	context->state[3] = 0x10325476;
+	context->state[4] = 0xC3D2E1F0;
+	context->count[0] = context->count[1] = 0;
+}
+
+
+/* Run your data through this. */
+
+void SHA1Update(struct SHA1_CTX* context, unsigned char* data, unsigned int len)
+{
+	unsigned int i, j;
+
+	j = (context->count[0] >> 3) & 63;
+	if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++;
+	context->count[1] += (len >> 29);
+	if ((j + len) > 63) {
+		memcpy(&context->buffer[j], data, (i = 64-j));
+		SHA1Transform(context->state, context->buffer);
+		for ( ; i + 63 < len; i += 64) {
+			SHA1Transform(context->state, &data[i]);
+		}
+		j = 0;
+	}
+	else i = 0;
+	memcpy(&context->buffer[j], &data[i], len - i);
+}
+
+
+/* Add padding and return the message digest. */
+
+void SHA1Final(unsigned char digest[20], struct SHA1_CTX* context)
+{
+	unsigned long i, j;
+	unsigned char finalcount[8];
+
+	for (i = 0; i < 8; i++) {
+		finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
+				 >> ((3-(i & 3)) * 8) ) & 255); 
+                                 /* Endian independent */
+	}
+	SHA1Update(context, (unsigned char *)"\200", 1);
+	while ((context->count[0] & 504) != 448) {
+		SHA1Update(context, (unsigned char *)"\0", 1);
+	}
+	SHA1Update(context, finalcount, 8);  /* Should cause a SHA1Transform() */
+	for (i = 0; i < 20; i++) {
+		digest[i] = (unsigned char)
+			((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
+	}
+	/* Wipe variables */
+	i = j = 0;
+	memset(context->buffer, 0, 64);
+	memset(context->state, 0, 20);
+	memset(context->count, 0, 8);
+	memset(&finalcount, 0, 8);
+#ifdef SHA1HANDSOFF  /* make SHA1Transform overwrite it's own static vars */
+	SHA1Transform(context->state, context->buffer);
+#endif
+}
+
+
+
+
+
diff -Nur linux-2.4.10/drivers/block/loop.c linux-int-2.4.10/drivers/block/loop.c
--- linux-2.4.10/drivers/block/loop.c	Mon Sep 17 22:16:30 2001
+++ linux-int-2.4.10/drivers/block/loop.c	Sat Sep 29 11:16:56 2001
@@ -36,6 +36,9 @@
  * Al Viro too.
  * Jens Axboe <axboe@suse.de>, Nov 2000
  *
+ * Fixed and made IV calculation customizable by lo_iv_mode
+ * Herbert Valerio Riedel <hvr@gnu.org>, Apr 2001
+ *
  * Still To Fix:
  * - Advisory locking is ignored here. 
  * - Should use an own CAP_* category instead of CAP_SYS_ADMIN 
@@ -168,6 +171,43 @@
 					lo->lo_device);
 }
 
+static inline int loop_get_bs(struct loop_device *lo)
+{
+	int bs = 0;
+
+	if (blksize_size[MAJOR(lo->lo_device)])
+		bs = blksize_size[MAJOR(lo->lo_device)][MINOR(lo->lo_device)];
+	if (!bs)
+		bs = BLOCK_SIZE;	
+
+	return bs;
+}
+
+static inline unsigned long loop_get_iv(struct loop_device *lo,
+					unsigned long sector)
+{
+	unsigned long offset, IV;
+	int bs;
+
+	switch (lo->lo_iv_mode) {
+		case LO_IV_MODE_SECTOR:
+			IV = sector + (lo->lo_offset >> LO_IV_SECTOR_BITS);
+			break;
+
+		default:
+			printk (KERN_WARNING "loop: unexpected lo_iv_mode\n");
+		case LO_IV_MODE_DEFAULT:
+			bs = loop_get_bs(lo);
+			IV = sector / (bs >> 9) + lo->lo_offset / bs;
+			offset = ((sector % (bs >> 9)) << 9) + lo->lo_offset % bs;
+			if (offset >= bs)
+				IV++;
+			break;
+	}
+
+	return IV;
+}
+
 static int lo_send(struct loop_device *lo, struct buffer_head *bh, int bsize,
 		   loff_t pos)
 {
@@ -185,7 +225,8 @@
 	len = bh->b_size;
 	data = bh->b_data;
 	while (len > 0) {
-		int IV = index * (PAGE_CACHE_SIZE/bsize) + offset/bsize;
+		unsigned long IV = loop_get_iv(lo, (pos - lo->lo_offset) >> LO_IV_SECTOR_BITS);
+
 		size = PAGE_CACHE_SIZE - offset;
 		if (size > len)
 			size = len;
@@ -236,7 +277,10 @@
 	unsigned long count = desc->count;
 	struct lo_read_data *p = (struct lo_read_data*)desc->buf;
 	struct loop_device *lo = p->lo;
-	int IV = page->index * (PAGE_CACHE_SIZE/p->bsize) + offset/p->bsize;
+	unsigned long IV = loop_get_iv(lo,
+		((page->index <<  (PAGE_CACHE_SHIFT - LO_IV_SECTOR_BITS))
+		+ (offset >> LO_IV_SECTOR_BITS)
+		- (lo->lo_offset >> LO_IV_SECTOR_BITS)));
 
 	if (size > count)
 		size = count;
@@ -276,32 +320,6 @@
 	return desc.error;
 }
 
-static inline int loop_get_bs(struct loop_device *lo)
-{
-	int bs = 0;
-
-	if (blksize_size[MAJOR(lo->lo_device)])
-		bs = blksize_size[MAJOR(lo->lo_device)][MINOR(lo->lo_device)];
-	if (!bs)
-		bs = BLOCK_SIZE;	
-
-	return bs;
-}
-
-static inline unsigned long loop_get_iv(struct loop_device *lo,
-					unsigned long sector)
-{
-	int bs = loop_get_bs(lo);
-	unsigned long offset, IV;
-
-	IV = sector / (bs >> 9) + lo->lo_offset / bs;
-	offset = ((sector % (bs >> 9)) << 9) + lo->lo_offset % bs;
-	if (offset >= bs)
-		IV++;
-
-	return IV;
-}
-
 static int do_bh_filebacked(struct loop_device *lo, struct buffer_head *bh, int rw)
 {
 	loff_t pos;
@@ -663,6 +681,7 @@
 	lo->lo_backing_file = file;
 	lo->transfer = NULL;
 	lo->ioctl = NULL;
+	lo->lo_iv_mode = LO_IV_MODE_DEFAULT;
 	figure_loop_size(lo);
 	lo->old_gfp_mask = inode->i_mapping->gfp_mask;
 	inode->i_mapping->gfp_mask = GFP_NOIO;
@@ -672,7 +691,7 @@
 		bs = blksize_size[MAJOR(lo_device)][MINOR(lo_device)];
 	if (!bs)
 		bs = BLOCK_SIZE;
-
+	  
 	set_blocksize(dev, bs);
 
 	lo->lo_bh = lo->lo_bhtail = NULL;
diff -Nur linux-2.4.10/include/asm-i386/wordops.h linux-int-2.4.10/include/asm-i386/wordops.h
--- linux-2.4.10/include/asm-i386/wordops.h	Thu Jan  1 01:00:00 1970
+++ linux-int-2.4.10/include/asm-i386/wordops.h	Sat Sep 29 11:16:56 2001
@@ -0,0 +1,20 @@
+#ifndef _I386_WORDOPS_H
+#define _I386_WORDOPS_H
+
+extern __inline__ int rotr32(__u32 x, int n)
+{
+	if (n == 32 || n == 0 || n == -32)
+		return x;
+	__asm__("rorl %1,%0" : "=r"(x) : "ir"(n));
+	return x;
+}
+
+extern __inline__ int rotl32(__u32 x, int n)
+{
+	if (n == 32 || n == 0 || n == -32)
+		return x;
+	__asm__("roll %1,%0" : "=r"(x) : "ir"(n));
+	return x;
+}
+
+#endif
diff -Nur linux-2.4.10/include/linux/crypto.h linux-int-2.4.10/include/linux/crypto.h
--- linux-2.4.10/include/linux/crypto.h	Thu Jan  1 01:00:00 1970
+++ linux-int-2.4.10/include/linux/crypto.h	Sat Sep 29 11:16:56 2001
@@ -0,0 +1,277 @@
+#ifndef _LINUX_CRYPTO_H
+#define _LINUX_CRYPTO_H
+
+/*
+ * include/linux/crypto.h
+ *
+ * Written by Alexander Kjeldaas <astor@fast.no> 1998-10-13
+ *
+ * Copyright 1998 by Alexander Kjeldaas. This code is licensed under
+ * an X11-like license.  See LICENSE.crypto for details.
+ *
+ */
+
+#define TRANSFORM_DIGEST 0
+#define TRANSFORM_CIPHER 1
+#define MAX_TRANSFORM    2
+
+#define CIPHER_MODES       0xFFFF0000 /* used to mask the mode *\
+				       * part of the cipher id */
+#define CIPHER_MODE_ECB    0x00000000
+#define CIPHER_MODE_CBC    0x00010000
+#define CIPHER_MODE_CTR    0x00020000 /* not implemented yet */
+
+/* Allowed keysizes: This is just a set of commonly found values. If
+ * you need additional ones, you can place them here. Note that
+ * CIPHER_KEY_ANY really means _any_ key length (that is a multiple of
+ * 8 bits, just limited by MAX_KEY_SIZE*32. This is not important now,
+ * but might become so if we choose to support keylengths greater than
+ * 256 bits. There are many ciphers that can take keys that are longer
+ * (e.g. blowfish: 448 bits). If you want to say all key lengths up to
+ * 256, play safe and use 0xFFFFFFFF-1 as keysize_mask.
+ * CIPHER_KEYSIZE_NONE means that the cipher does not expect a key. It
+ * is only used for 'none' encryption.
+ */
+
+#define CIPHER_KEYSIZE_ANY  0xFFFFFFFF
+#define CIPHER_KEYSIZE_NONE 0x00000000
+
+#define CIPHER_KEYSIZE_40   0x00000010
+#define CIPHER_KEYSIZE_56   0x00000040
+#define CIPHER_KEYSIZE_64   0x00000080
+#define CIPHER_KEYSIZE_80   0x00000200
+#define CIPHER_KEYSIZE_96   0x00000800
+#define CIPHER_KEYSIZE_112  0x00002000
+#define CIPHER_KEYSIZE_128  0x00008000
+#define CIPHER_KEYSIZE_160  0x00080000
+#define CIPHER_KEYSIZE_168  0x00100000
+#define CIPHER_KEYSIZE_192  0x00800000
+#define CIPHER_KEYSIZE_256  0x80000000
+
+
+#ifdef __KERNEL__
+
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/proc_fs.h>
+#include <linux/spinlock.h>
+#include <asm/page.h>
+#include <asm/semaphore.h>
+
+/* A transform group is a group of transforms that behave in a similar
+ * fashion */
+
+struct transform_group {
+	int tg_id;
+	char *tg_name;  /* "cipher" or "digest" */
+	rwlock_t tg_lock;
+	struct list_head *tg_head;
+#ifdef CONFIG_PROC_FS
+	struct proc_dir_entry *tg_proc_parent_dir;
+	int (*read_proc)(char *page, char **start, off_t off,
+			 int count, int *eof, void *data);
+#endif
+};
+
+/* A transform is something that can be found by id or name. Ciphers
+   and digests are types of transforms. */
+
+struct transform_implementation {
+	struct list_head t_list;
+	int t_flags;
+	char *t_name;
+        int t_atomicapi;
+	struct transform_group *t_group;
+#ifdef CONFIG_PROC_FS
+	/* keep track of the allocated proc_dir_entry */
+	struct proc_dir_entry *t_proc;
+#endif
+};
+
+/* Cipher data structures */
+
+struct cipher_context;
+struct cipher_implementation {
+	struct transform_implementation trans;
+	int blocksize;         /* in bytes */
+	int ivsize;            /* in bytes */
+	int key_schedule_size; /* in bytes. 0 if the schedule size is
+                                  variable. */
+	u32 key_size_mask;     /* bit 0 set = 8 bit, ... , 
+				* bit 31 set = 256 bit */
+
+	/*
+	 * Encrypt the plaintext pointed to by "in".  Write output to
+	 * "out". Size of plaintext is "size".  Output buffer must be
+	 * able to hold "size" bytes plus padding necessary to make it
+	 * a multiple of the cipher blocksize. size <= 0 is
+	 * undefined. Returns 0 on success, non-zero on
+	 * failure. 
+         *
+         * encrypt        - Function might sleep. This function will 
+         *                  always exist.
+
+	 * encrypt_atomic - Will never sleep + always SW implementation.  
+         *                  This function will exist if atomicapi==1 was 
+         *                  set in find_cipher_by_name where this 
+         *                  cipher_implementation was returned.
+	 */
+	int (*encrypt)(struct cipher_context *cx, 
+		       const u8 *in, u8 *out, int size, const u32 iv[]);
+
+
+        int (*encrypt_atomic) (struct cipher_context *cx,
+                               const u8 *in, u8 *out, int size, 
+			       const u32 iv[]);
+
+	/*
+	 * Decrypt the ciphertext pointed to by "in".  Write output to
+	 * "out". Size of plaintext is "size".  Input buffer is "size"
+	 * bytes plus padding necessary to make it a multiple of the
+	 * cipher blocksize. size <= 0 is undefined. Returns 0 on
+	 * success, non-zero on failure. 
+	 *
+	 */
+	int (*decrypt)(struct cipher_context *cx,
+		       const u8 *in, u8 *out, int size, const u32 iv[]);
+
+	int (*decrypt_atomic)(struct cipher_context *cx,
+                              const u8 *in, u8 *out, int size, 
+			      const u32 iv[]);
+
+	int (*set_key)(struct cipher_context *cx, 
+		       const unsigned char *key, int key_len);
+
+	int (*set_key_atomic)(struct cipher_context *cx, 
+                              const unsigned char *key, int key_len);
+
+        /* The following functions are optional.  Most ciphers will
+         * not need to specify them, and a default implementation will
+         * be used.  
+         */
+
+        /* Realloc a cipher_context that can hold the key schedule for
+         * a given key.  If no cipher_context is given, allocate a new
+         * cipher_context.  
+         */
+
+        struct cipher_context *
+        (*realloc_context)(struct cipher_context *old_cx,
+                           struct cipher_implementation *ci,
+                           int max_key_len);
+        void (*wipe_context)(struct cipher_context *cx);
+        void (*free_context)(struct cipher_context *cx);
+
+	/* lock and unlock manage the module use counts */ 
+	void (*lock)(void);
+	void (*unlock)(void);
+
+        /* The following functions are used by software
+         * implementations that wish to provide a single function that
+         * implements atomic and non-atomic versions of encrypt,
+         * decrypt, and set_key. If these functions are set,
+         * register_cipher will provide generic implementations of
+         * encrypt*, decrypt*, and set_key*.  However these functions
+         * should not be called directly by users since they will only
+         * exist for software-based cipher implementations.  */
+
+        int (*_encrypt) (struct cipher_context *cx,
+                         const u8 *in, u8 *out, int size, int atomic, 
+			 const u32 iv[]);
+	int (*_decrypt)(struct cipher_context *cx,
+                        const u8 *in, u8 *out, int size, int atomic, 
+			const u32 iv[]);
+	int (*_set_key)(struct cipher_context *cx, 
+                        const unsigned char *key, int key_len, int atomic);
+
+};
+
+#define MAX_IV_SIZE  32              /* 32 byte - 256 bit */
+
+struct cipher_context {
+	struct cipher_implementation *ci;
+        int may_sleep;      /* cipher implementation (sw) might sleep */
+        int keyinfo_size;   /* in bytes - usually equal to
+                             * ci->key_schedule_size. */
+	u32 *keyinfo;
+	int key_length;     /* in bytes */
+        /* u8 iv[MAX_IV_SIZE]; */
+};
+
+
+/* Digest data structures */
+
+struct digest_context;
+struct digest_implementation {
+	struct transform_implementation trans;
+	int blocksize;           /* in bytes */
+	int working_size;        /* in bytes */
+
+	int (*open)(struct digest_context *cx);
+	int (*update)(struct digest_context *cx, u8 *in, int size);
+	int (*digest)(struct digest_context *cx, u8 *out);
+	int (*close)(struct digest_context *cx, u8 *out);
+
+	/* lock and unlock manage the module use counts */
+	void (*lock)(void);
+	void (*unlock)(void);
+};
+
+struct digest_context {
+	struct digest_implementation *di;
+	u32 *digest_info;
+};
+
+
+struct transform_implementation *find_transform_by_name(const char *name, 
+							int tgroup, 
+                                                        int atomicapi);
+
+static inline struct cipher_implementation *
+find_cipher_by_name(const char *name, int atomicapi)
+{
+	return (struct cipher_implementation *)
+		find_transform_by_name(name, TRANSFORM_CIPHER, atomicapi);
+}
+	
+static inline struct digest_implementation *
+find_digest_by_name(const char *name, int atomicapi)
+{
+	return (struct digest_implementation *)
+		find_transform_by_name(name, TRANSFORM_DIGEST, atomicapi);
+}
+
+int register_transform(struct transform_implementation *ti, int tgroup);
+int register_cipher(struct cipher_implementation *ci);
+int register_digest(struct digest_implementation *di);
+
+int unregister_transform(struct transform_implementation *ti);
+int unregister_cipher(struct cipher_implementation *ci);
+int unregister_digest(struct digest_implementation *ci);
+ 
+
+/* Utility macros */
+
+#define INIT_CIPHER_BLKOPS(name)		\
+        _encrypt: name##_encrypt,		\
+        _decrypt: name##_decrypt
+
+#define INIT_CIPHER_OPS(name)			\
+        _set_key: name##_set_key,		\
+        lock:    name##_lock,			\
+        unlock:  name##_unlock
+
+#define INIT_DIGEST_OPS(name)			\
+        open:   name##_open,			\
+	update: name##_update,			\
+	digest: name##_digest,			\
+	close:  name##_close,			\
+	lock:   name##_lock,			\
+	unlock: name##_unlock
+
+
+#define byte(x, nr) ((unsigned char)((x) >> (nr*8)))
+
+#endif /* __KERNEL__ */
+
+#endif
diff -Nur linux-2.4.10/include/linux/loop.h linux-int-2.4.10/include/linux/loop.h
--- linux-2.4.10/include/linux/loop.h	Mon Sep 17 22:16:30 2001
+++ linux-int-2.4.10/include/linux/loop.h	Sat Sep 29 11:16:56 2001
@@ -24,6 +24,13 @@
 	Lo_rundown,
 };
 
+/* IV calculation related constants */
+#define LO_IV_MODE_DEFAULT 0 /* old logical block size based mode */
+#define LO_IV_MODE_SECTOR  1 /* calculate IV based on relative 
+				512 byte sectors */
+#define LO_IV_SECTOR_BITS 9
+#define LO_IV_SECTOR_SIZE (1 << LO_IV_SECTOR_BITS)
+
 struct loop_device {
 	int		lo_number;
 	int		lo_refcnt;
@@ -56,6 +63,8 @@
 	struct semaphore	lo_ctl_mutex;
 	struct semaphore	lo_bh_mutex;
 	atomic_t		lo_pending;
+
+	int			lo_iv_mode;
 };
 
 typedef	int (* transfer_proc_t)(struct loop_device *, int cmd,
@@ -122,6 +131,7 @@
 #define LO_CRYPT_IDEA     6
 #define LO_CRYPT_DUMMY    9
 #define LO_CRYPT_SKIPJACK 10
+#define LO_CRYPT_CRYPTOAPI 18  /* international crypto patch */
 #define MAX_LO_CRYPT	20
 
 #ifdef __KERNEL__
diff -Nur linux-2.4.10/include/linux/wordops.h linux-int-2.4.10/include/linux/wordops.h
--- linux-2.4.10/include/linux/wordops.h	Thu Jan  1 01:00:00 1970
+++ linux-int-2.4.10/include/linux/wordops.h	Sat Sep 29 11:16:56 2001
@@ -0,0 +1,12 @@
+#ifndef _LINUX_WORDOPS_H
+#define _LINUX_WORDOPS_H
+
+#include <linux/types.h>
+
+#define generic_rotr32(x,n) (((x) >> ((int)(n))) | ((x) << (32 - (int)(n))))
+
+#define generic_rotl32(x, n) (((x) << ((int)(n))) | ((x) >> (32 - (int)(n))))
+
+#include <asm/wordops.h>
+
+#endif
