diff -Naur tomato/release/src/linux/linux/arch/mips/crypto/Config.help tomato121/release/src/linux/linux/arch/mips/crypto/Config.help
--- tomato/release/src/linux/linux/arch/mips/crypto/Config.help	1970-01-01 10:00:00.000000000 +1000
+++ tomato121/release/src/linux/linux/arch/mips/crypto/Config.help	2008-04-21 17:28:52.000000000 +1000
@@ -0,0 +1,94 @@
+Cryptographic API
+CONFIG_CRYPTO
+  If you answer 'Y' to this option, the cryptographic kernel API
+  framework will be enabled, and you'll be presented with additional
+  questions about cryptographic algorithms and kernel components
+  making use of the cryptographic API.
+
+  See also <file:Documentation/crypto/cryptoapi.txt>
+
+  The latest version of this component can be found at
+  <http://www.kernel.org/pub/linux/crypto/>
+
+  If you don't need cryptographic extensions, say N.
+
+Crypto ciphers
+CONFIG_CIPHERS
+  Ciphers basically help us scramble data so that other people don't
+  get access to it. Useful applications for this include hiding hard
+  drive contents or network traffic from unauthorized eyes. Compare a
+  file encrypted with a cipher with very good safe: The document is in
+  it, you can carry the document with you (if the safe is not too
+  heavy), but others can steal it, too. However, they will not be able
+  to read the document if the safe is any good.
+
+  Mathematically speaking, a cipher is a parameter-dependant function
+  E(K, ) that takes a fixed-length block M (usually 64 or 128 bits)
+  and maps it onto another (usually equal-sized) block C=E(K,M) in such
+  a way that, without knowledge of the "key" K, it is hard to compute
+
+  1. M, if C and the function E are given,
+
+  2. C, if M is given and the function E is known.
+
+  M is called the 'plaintext' and C the 'ciphertext'. The above
+  properties are commonly described as "All the security of the cipher
+  lies in its key". However, there always exists the inverse function
+  D(K, ) of E(K, ) such that D(K,E(K,M))=M for any M.  The ideal
+  cipher is one where it is impossible to compute M if you have C, but
+  not K. In this case, the easiest way to break the cipher is to use
+  'brute-force', i.e. try all K in turn until you hit the right
+  one. With most ciphers in this library, K is a 128-bit number. Here,
+  brute-force attacks are infeasible since they require testing all
+  2^128 possible keys K, which would take far too long on any
+  conceivable computer (some big multiple of the age of the universe
+  for example).
+
+  Unfortunately, the ideal cipher has not been found yet, so most
+  ciphers in this library, or certain 'reduced-round' versions
+  thereof, can be broken faster than brute-force. A cipher is secure,
+  if it cannot be broken _much_ faster than brute-force and
+  brute-force is infeasible.
+
+  If you say 'Y', you are able to select a variety of
+  ciphers for the Cipher-API. Ciphers you select below can then be
+  used by cryptographic kernel modules. If you say 'N' here, those
+  modules will use their own implementations or even not work at all.
+
+  If unsure, say 'N'.
+
+Digest algorithms
+CONFIG_DIGESTS
+  A message digest (or 'one-way function' or 'hash') is a function H
+  that maps an arbitrary-length message M onto a 128-bit or 160-bit
+  number h=H(M) such that the following conditions are satisfied:
+
+  1. For a given M, it is easy to compute h=H(M).
+
+  2. For a given h, it is hard to find M such that h=H(M).
+
+  3. For a given M, it is hard to find another message M' such that
+     H(M')=H(M).
+
+  4. It is hard to find M, M' such that H(M)=H(M').
+
+  This makes the name 'one-way function' plausible. Hashes are widely
+  used by cryptographic programs. E.g. the Linux kernel uses a hash to
+  generate random numbers.
+
+# Marc Mutz <Marc@Mutz.com>: this will be the help text, once this
+# functionality is in place:
+#  If you say 'Y' here and select the SHA-1 message digest below,
+#  then the drivers for /dev/random and /dev/urandom will use the
+#  digest api instead of their own implementation. This will not work
+#  if you build as modules.
+#
+  If you say 'Y', cryptographic modules are able to use
+  the Digest-API if they need a hash function. If you say 'N' here,
+  they will use their own implementations (which will probably
+  increase the size of the compiled kernel if there are more than one
+  such modules).
+
+  If unsure, say 'N'.
+
+#EOF
diff -Naur tomato/release/src/linux/linux/arch/mips/crypto/Config.in tomato121/release/src/linux/linux/arch/mips/crypto/Config.in
--- tomato/release/src/linux/linux/arch/mips/crypto/Config.in	1970-01-01 10:00:00.000000000 +1000
+++ tomato121/release/src/linux/linux/arch/mips/crypto/Config.in	2008-04-21 17:28:52.000000000 +1000
@@ -0,0 +1,18 @@
+# $Id: Config.in,v 1.1.2.1 2004/05/23 12:29:03 nikki Exp $
+
+mainmenu_option next_comment
+comment 'Cryptography support (CryptoAPI)'
+
+tristate 'CryptoAPI support' CONFIG_CRYPTO
+
+dep_mbool 'Cipher Algorithms' CONFIG_CIPHERS $CONFIG_CRYPTO
+source crypto/ciphers/Config.in
+
+dep_mbool 'Digest Algorithms' CONFIG_DIGESTS $CONFIG_CRYPTO
+source crypto/digests/Config.in
+
+dep_mbool 'Crypto Devices' CONFIG_CRYPTODEV $CONFIG_CRYPTO
+source crypto/drivers/Config.in
+
+endmenu
+
diff -Naur tomato/release/src/linux/linux/arch/mips/crypto/cryptoapi.c tomato121/release/src/linux/linux/arch/mips/crypto/cryptoapi.c
--- tomato/release/src/linux/linux/arch/mips/crypto/cryptoapi.c	1970-01-01 10:00:00.000000000 +1000
+++ tomato121/release/src/linux/linux/arch/mips/crypto/cryptoapi.c	2008-04-21 17:28:52.000000000 +1000
@@ -0,0 +1,725 @@
+/* $Id: cryptoapi.c,v 1.1.2.1 2004/05/23 12:29:03 nikki Exp $
+ *
+ * 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 (C)  1998 Alexander Kjeldaas.
+ *                2001 Herbert Valerio Riedel
+ *
+ * This module 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. 
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/version.h>
+
+#include <linux/init.h>
+#include <linux/config.h>
+#include <linux/string.h>
+#include <linux/crypto.h>
+#include <linux/proc_fs.h>
+
+#ifdef CONFIG_KMOD
+#include <linux/kmod.h>
+#endif /* CONFIG_KMOD */
+
+#ifdef MODULE_LICENSE
+MODULE_LICENSE("GPL");
+#endif
+#ifdef MODULE_DESCRIPTION
+MODULE_DESCRIPTION ("CryptoAPI core module");
+#endif
+
+static struct proc_dir_entry *proc_crypto;
+
+static struct cipher_context *
+default_realloc_cipher_context(struct cipher_context *old_cx,
+			       struct cipher_implementation *,
+			       int max_key_len);
+
+static struct digest_context *
+default_realloc_digest_context(struct digest_context *old_cx,
+			       struct digest_implementation *);
+
+static void default_wipe_context(struct cipher_context *cx);
+
+static void default_free_cipher_context(struct cipher_context *cx);
+static void default_free_digest_context(struct digest_context *cx);
+
+static void default_lock(void);
+static void default_unlock(void);
+
+/* ciphers */
+static int default_encrypt(struct cipher_context *cx, 
+			   const u8 *in, u8 *out, int size);
+static int default_encrypt_atomic(struct cipher_context *cx, 
+				  const u8 *in, u8 *out, int size);
+static int default_encrypt_iv(struct cipher_context *cx, 
+			      const u8 *in, u8 *out, int size,
+			      const u8 *iv);
+static int default_encrypt_atomic_iv(struct cipher_context *cx, 
+				     const u8 *in, u8 *out, int size,
+				     const u8 *iv);
+
+static int default_decrypt(struct cipher_context *cx, 
+			   const u8 *in, u8 *out, int size);
+static int default_decrypt_atomic(struct cipher_context *cx, 
+				  const u8 *in, u8 *out, int size);
+
+static int default_decrypt_iv(struct cipher_context *cx, 
+			      const u8 *in, u8 *out, int size, const u8 *iv);
+static int default_decrypt_atomic_iv(struct cipher_context *cx, 
+				     const u8 *in, u8 *out, int size,
+				     const u8 *iv);
+
+static int default_set_key(struct cipher_context *cx, 
+			   const u8 *key, int key_len);
+static int default_set_key_atomic(struct cipher_context *cx, 
+				  const u8 *key, int key_len);
+
+/* digests */
+static int default_open (struct digest_context *cx);
+static int default_open_atomic (struct digest_context *cx);
+
+static int default_update(struct digest_context *cx, const u8 *in, int size);
+static int default_update_atomic(struct digest_context *cx, 
+				 const u8 *in, int size);
+
+static int default_digest(struct digest_context *cx, u8 *out);
+static int default_digest_atomic(struct digest_context *cx, u8 *out);
+
+static int default_close(struct digest_context *cx, u8 *out);
+static int default_close_atomic(struct digest_context *cx, u8 *out);
+
+static int default_hmac(struct digest_context *cx, const u8 *key, int key_len,
+				const u8 *in, int size, u8 *hmac);
+static int default_hmac_atomic(struct digest_context *cx, const u8 *key, int key_len,
+			       const u8 *in, int size, u8 *hmac);
+
+#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);
+static void crypto_create_proc(void);
+static void crypto_delete_proc(void);
+#endif /* CONFIG_PROC_FS */
+
+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 /* CONFIG_PROC_FS */
+	},
+	/* cipher */
+	{ TRANSFORM_CIPHER, "cipher", RW_LOCK_UNLOCKED, &ciphers, 
+#ifdef CONFIG_PROC_FS
+	  NULL, &cipher_read_proc 
+#endif /* CONFIG_PROC_FS */
+	}
+};
+
+#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 /* defined(CONFIG_PROC_FS) */
+
+
+/**
+ * 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;
+	int n;
+#endif /* CONFIG_KMOD */
+
+	if (tgroup >= MAX_TRANSFORM)
+		return NULL;
+	tg = &transforms[tgroup];
+
+#ifdef CONFIG_KMOD
+	n = strlen(name) + strlen(tg->tg_name) + 3;
+	if (n >= 200) n = 200;
+	snprintf(module_name, n, "%s-%s-", tg->tg_name, name);
+retry:
+#endif /* CONFIG_KMOD */
+	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 /* CONFIG_KMOD */
+	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);
+#ifdef CONFIG_PROC_FS
+		ti->t_proc = create_proc_read_entry(ti->t_name,
+						    S_IFREG|S_IRUGO,
+						    tg->tg_proc_parent_dir,
+						    tg->read_proc, (void *)ti);
+#endif /* CONFIG_PROC_FS */
+	}
+	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 /* CONFIG_PROC_FS */
+
+	if (!ret) {
+		MOD_DEC_USE_COUNT;
+//		printk(KERN_INFO "cryptoapi: Unregistered %s (%d)\n",
+//		       ti->t_name, ti->t_flags);
+	}
+
+	return ret;
+}
+
+int 
+register_cipher(struct cipher_implementation *ci)
+{
+	if (!ci->realloc_context) 
+		ci->realloc_context = default_realloc_cipher_context;
+
+	if (!ci->wipe_context) 
+		ci->wipe_context = default_wipe_context;
+
+	if (!ci->free_context) 
+		ci->free_context = default_free_cipher_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_iv = default_encrypt_iv;
+		ci->encrypt_atomic_iv = default_encrypt_atomic_iv;
+		ci->decrypt_iv = default_decrypt_iv;
+		ci->decrypt_atomic_iv = default_decrypt_atomic_iv;
+
+		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)
+{
+	if (!di->realloc_context)
+		di->realloc_context = default_realloc_digest_context;
+
+	if (!di->free_context)
+		di->free_context = default_free_digest_context;
+
+	if (!di->lock)
+		di->lock = default_lock;
+
+	if (!di->unlock)
+		di->unlock = default_unlock;
+
+	if (di->_open && di->_update && di->_digest &&
+	    di->_close && di->_hmac) 
+	{
+		di->open = default_open;
+		di->open_atomic = default_open_atomic;
+
+		di->update = default_update;
+		di->update_atomic = default_update_atomic;
+
+		di->digest = default_digest;
+		di->digest_atomic = default_digest_atomic;
+
+		di->close = default_close;
+		di->close_atomic = default_close_atomic;
+
+		di->hmac = default_hmac;
+		di->hmac_atomic = default_hmac_atomic;
+		di->trans.t_atomicapi = 1;
+	}
+
+	if (!di->open || !di->update || !di->digest || !di->close)
+		return -EINVAL;
+
+	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_cipher_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;
+}
+
+struct digest_context *
+default_realloc_digest_context(struct digest_context *old_cx,
+			       struct digest_implementation *di)
+{
+	struct digest_context *cx;
+
+	if (old_cx)
+		di->free_context (old_cx);
+
+	cx = kmalloc(sizeof (struct digest_context) +
+		      di->working_size, GFP_KERNEL);
+	if (!cx)
+		return NULL;
+
+	cx->di = di;
+
+	/* let digest_info point behind the context */
+	cx->digest_info = (void *)((char *)cx) + sizeof(struct digest_context);
+
+	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_cipher_context(struct cipher_context *cx)
+{
+	kfree(cx);
+}
+
+void
+default_free_digest_context(struct digest_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)
+{
+	return cx->ci->_encrypt(cx, in, out, size, 0, cx->iv);
+}
+
+static int 
+default_encrypt_atomic(struct cipher_context *cx, const u8 *in, u8 *out, 
+		       int size)
+{
+	return cx->ci->_encrypt(cx, in, out, size, 1, cx->iv);
+}
+
+static int 
+default_encrypt_iv(struct cipher_context *cx, const u8 *in, u8 *out, int size,
+		const u8 *iv)
+{
+	return cx->ci->_encrypt(cx, in, out, size, 0, iv);
+}
+
+static int 
+default_encrypt_atomic_iv(struct cipher_context *cx, const u8 *in, u8 *out, 
+		          int size, const u8 *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)
+{
+	return cx->ci->_decrypt(cx, in, out, size, 0, cx->iv);
+}
+
+static int 
+default_decrypt_atomic(struct cipher_context *cx, const u8 *in, u8 *out, 
+		       int size)
+{
+	return cx->ci->_decrypt(cx, in, out, size, 1, cx->iv);
+}
+
+static int 
+default_decrypt_iv(struct cipher_context *cx, const u8 *in, u8 *out, int size,
+		const u8 *iv)
+{
+	return cx->ci->_decrypt(cx, in, out, size, 0, iv);
+}
+
+static int 
+default_decrypt_atomic_iv(struct cipher_context *cx, const u8 *in, u8 *out, 
+		       int size, const u8 *iv)
+{
+	return cx->ci->_decrypt(cx, in, out, size, 1, iv);
+}
+
+
+static int
+default_set_key(struct cipher_context *cx, const u8 *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 u8 *key, 
+		       int key_len)
+{
+	return cx->ci->_set_key(cx, key, key_len, 1);
+}
+
+static int
+default_open (struct digest_context *cx)
+{
+  return cx->di->_open (cx, 0);
+}
+
+static int
+default_open_atomic (struct digest_context *cx)
+{
+	return cx->di->_open (cx, 1);
+}
+
+static int
+default_update(struct digest_context *cx, const u8 *in, int size)
+{
+	return cx->di->_update (cx, in, size, 0);
+}
+
+static int
+default_update_atomic(struct digest_context *cx, const u8 *in, int size)
+{
+	return cx->di->_update (cx, in, size, 1);
+}
+
+static int
+default_digest(struct digest_context *cx, u8 *out)
+{
+	return cx->di->_digest (cx, out, 0);
+}
+
+static int
+default_digest_atomic(struct digest_context *cx, u8 *out)
+{
+	return cx->di->_digest (cx, out, 1);
+}
+
+static int
+default_close(struct digest_context *cx, u8 *out)
+{
+	return cx->di->_close (cx, out, 0);
+}
+
+static int
+default_close_atomic(struct digest_context *cx, u8 *out)
+{
+	return cx->di->_close (cx, out, 1);
+}
+
+static int
+default_hmac (struct digest_context *cx, const u8 *key, int key_len,
+	     const u8 *in, int size, u8 *hmac)
+{
+	if (!(cx && key && in && hmac)) {
+		printk (KERN_ERR "%s: some parameter is null\n", __PRETTY_FUNCTION__);
+		return -EINVAL;
+	}
+
+	return cx->di->_hmac (cx, key, key_len, in, size, hmac, 0);
+}
+
+static int
+default_hmac_atomic (struct digest_context *cx, const u8 *key, int key_len,
+		    const u8 *in, int size, u8 *hmac)
+{
+	if (!(cx && key && in && hmac)) {
+		printk (KERN_ERR "%s: some parameter is null\n", __PRETTY_FUNCTION__);
+		return -EINVAL;
+	}
+
+	return cx->di->_hmac (cx, key, key_len, in, size, hmac, 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;
+}
+
+static void crypto_create_proc(void)
+{
+	int i;
+
+	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);
+	}
+}
+
+static void crypto_delete_proc(void)
+{
+	int i;
+
+	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 /* CONFIG_PROC_FS */
+
+static int __init
+init_cryptoapi(void)
+{
+#ifdef CONFIG_PROC_FS
+	crypto_create_proc();
+#endif /* CONFIG_PROC_FS */
+
+//	printk(KERN_INFO "cryptoapi: loaded\n");
+
+	return 0;
+}
+
+static void __exit
+cleanup_cryptoapi(void) 
+{
+#ifdef CONFIG_PROC_FS
+	crypto_delete_proc();
+#endif /* CONFIG_PROC_FS */
+
+//	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);
+
+/* 
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * Emacs will notice this stuff at the end of the file and automatically
+ * adjust the settings for this buffer only.  This must remain at the end
+ * of the file.
+ * ---------------------------------------------------------------------------     
+ * Local variables:
+ * c-indent-level: 8
+ * c-brace-imaginary-offset: 0
+ * c-brace-offset: -8
+ * c-argdecl-indent: 8
+ * c-label-offset: -8
+ * c-continued-statement-offset: 8
+ * c-continued-brace-offset: 0
+ * End:
+ */
diff -Naur tomato/release/src/linux/linux/arch/mips/crypto/Makefile tomato121/release/src/linux/linux/arch/mips/crypto/Makefile
--- tomato/release/src/linux/linux/arch/mips/crypto/Makefile	1970-01-01 10:00:00.000000000 +1000
+++ tomato121/release/src/linux/linux/arch/mips/crypto/Makefile	2008-04-21 17:28:52.000000000 +1000
@@ -0,0 +1,21 @@
+#
+# Makefile for the Linux kernel crypto library.
+#
+# 1 Dec 2001, Herbert Valerio Riedel <hvr@kernel.org>
+#
+
+mod-subdirs := ciphers digests drivers
+
+O_TARGET := crypto.o
+
+export-objs := cryptoapi.o
+
+obj-$(CONFIG_CRYPTO)           += cryptoapi.o
+
+subdir-$(CONFIG_CIPHERS)       += ciphers
+subdir-$(CONFIG_DIGESTS)       += digests
+subdir-$(CONFIG_CRYPTODEV)     += drivers
+
+obj-y += $(join $(subdir-y),$(subdir-y:%=/%.o))
+
+include $(TOPDIR)/Rules.make
