help
          This option provides the core Cryptographic API.
 
+if CRYPTO
+
+config CRYPTO_ALGAPI
+       tristate
+       help
+         This option provides the API for cryptographic algorithms.
+
 config CRYPTO_HMAC
        bool "HMAC support"
-       depends on CRYPTO
        help
          HMAC: Keyed-Hashing for Message Authentication (RFC2104).
          This is required for IPSec.
 
 config CRYPTO_NULL
        tristate "Null algorithms"
-       depends on CRYPTO
+       select CRYPTO_ALGAPI
        help
          These are 'Null' algorithms, used by IPsec, which do nothing.
 
 config CRYPTO_MD4
        tristate "MD4 digest algorithm"
-       depends on CRYPTO
+       select CRYPTO_ALGAPI
        help
          MD4 message digest algorithm (RFC1320).
 
 config CRYPTO_MD5
        tristate "MD5 digest algorithm"
-       depends on CRYPTO
+       select CRYPTO_ALGAPI
        help
          MD5 message digest algorithm (RFC1321).
 
 config CRYPTO_SHA1
        tristate "SHA1 digest algorithm"
-       depends on CRYPTO
+       select CRYPTO_ALGAPI
        help
          SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2).
 
 config CRYPTO_SHA1_S390
        tristate "SHA1 digest algorithm (s390)"
-       depends on CRYPTO && S390
+       depends on S390
+       select CRYPTO_ALGAPI
        help
          This is the s390 hardware accelerated implementation of the
          SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2).
 
 config CRYPTO_SHA256
        tristate "SHA256 digest algorithm"
-       depends on CRYPTO
+       select CRYPTO_ALGAPI
        help
          SHA256 secure hash standard (DFIPS 180-2).
          
 
 config CRYPTO_SHA256_S390
        tristate "SHA256 digest algorithm (s390)"
-       depends on CRYPTO && S390
+       depends on S390
+       select CRYPTO_ALGAPI
        help
          This is the s390 hardware accelerated implementation of the
          SHA256 secure hash standard (DFIPS 180-2).
 
 config CRYPTO_SHA512
        tristate "SHA384 and SHA512 digest algorithms"
-       depends on CRYPTO
+       select CRYPTO_ALGAPI
        help
          SHA512 secure hash standard (DFIPS 180-2).
          
 
 config CRYPTO_WP512
        tristate "Whirlpool digest algorithms"
-       depends on CRYPTO
+       select CRYPTO_ALGAPI
        help
          Whirlpool hash algorithm 512, 384 and 256-bit hashes
 
 
 config CRYPTO_TGR192
        tristate "Tiger digest algorithms"
-       depends on CRYPTO
+       select CRYPTO_ALGAPI
        help
          Tiger hash algorithm 192, 160 and 128-bit hashes
 
 
 config CRYPTO_DES
        tristate "DES and Triple DES EDE cipher algorithms"
-       depends on CRYPTO
+       select CRYPTO_ALGAPI
        help
          DES cipher algorithm (FIPS 46-2), and Triple DES EDE (FIPS 46-3).
 
 config CRYPTO_DES_S390
        tristate "DES and Triple DES cipher algorithms (s390)"
-       depends on CRYPTO && S390
+       depends on S390
+       select CRYPTO_ALGAPI
        help
          DES cipher algorithm (FIPS 46-2), and Triple DES EDE (FIPS 46-3).
 
 config CRYPTO_BLOWFISH
        tristate "Blowfish cipher algorithm"
-       depends on CRYPTO
+       select CRYPTO_ALGAPI
        help
          Blowfish cipher algorithm, by Bruce Schneier.
          
 
 config CRYPTO_TWOFISH
        tristate "Twofish cipher algorithm"
-       depends on CRYPTO
+       select CRYPTO_ALGAPI
        select CRYPTO_TWOFISH_COMMON
        help
          Twofish cipher algorithm.
 
 config CRYPTO_TWOFISH_COMMON
        tristate
-       depends on CRYPTO
        help
          Common parts of the Twofish cipher algorithm shared by the
          generic c and the assembler implementations.
 
 config CRYPTO_TWOFISH_586
        tristate "Twofish cipher algorithms (i586)"
-       depends on CRYPTO && ((X86 || UML_X86) && !64BIT)
+       depends on (X86 || UML_X86) && !64BIT
+       select CRYPTO_ALGAPI
        select CRYPTO_TWOFISH_COMMON
        help
          Twofish cipher algorithm.
 
 config CRYPTO_TWOFISH_X86_64
        tristate "Twofish cipher algorithm (x86_64)"
-       depends on CRYPTO && ((X86 || UML_X86) && 64BIT)
+       depends on (X86 || UML_X86) && 64BIT
+       select CRYPTO_ALGAPI
        select CRYPTO_TWOFISH_COMMON
        help
          Twofish cipher algorithm (x86_64).
 
 config CRYPTO_SERPENT
        tristate "Serpent cipher algorithm"
-       depends on CRYPTO
+       select CRYPTO_ALGAPI
        help
          Serpent cipher algorithm, by Anderson, Biham & Knudsen.
 
 
 config CRYPTO_AES
        tristate "AES cipher algorithms"
-       depends on CRYPTO
+       select CRYPTO_ALGAPI
        help
          AES cipher algorithms (FIPS-197). AES uses the Rijndael 
          algorithm.
 
 config CRYPTO_AES_586
        tristate "AES cipher algorithms (i586)"
-       depends on CRYPTO && ((X86 || UML_X86) && !64BIT)
+       depends on (X86 || UML_X86) && !64BIT
+       select CRYPTO_ALGAPI
        help
          AES cipher algorithms (FIPS-197). AES uses the Rijndael 
          algorithm.
 
 config CRYPTO_AES_X86_64
        tristate "AES cipher algorithms (x86_64)"
-       depends on CRYPTO && ((X86 || UML_X86) && 64BIT)
+       depends on (X86 || UML_X86) && 64BIT
+       select CRYPTO_ALGAPI
        help
          AES cipher algorithms (FIPS-197). AES uses the Rijndael 
          algorithm.
 
 config CRYPTO_AES_S390
        tristate "AES cipher algorithms (s390)"
-       depends on CRYPTO && S390
+       depends on S390
+       select CRYPTO_ALGAPI
        help
          This is the s390 hardware accelerated implementation of the
          AES cipher algorithms (FIPS-197). AES uses the Rijndael
 
 config CRYPTO_CAST5
        tristate "CAST5 (CAST-128) cipher algorithm"
-       depends on CRYPTO
+       select CRYPTO_ALGAPI
        help
          The CAST5 encryption algorithm (synonymous with CAST-128) is
          described in RFC2144.
 
 config CRYPTO_CAST6
        tristate "CAST6 (CAST-256) cipher algorithm"
-       depends on CRYPTO
+       select CRYPTO_ALGAPI
        help
          The CAST6 encryption algorithm (synonymous with CAST-256) is
          described in RFC2612.
 
 config CRYPTO_TEA
        tristate "TEA, XTEA and XETA cipher algorithms"
-       depends on CRYPTO
+       select CRYPTO_ALGAPI
        help
          TEA cipher algorithm.
 
 
 config CRYPTO_ARC4
        tristate "ARC4 cipher algorithm"
-       depends on CRYPTO
+       select CRYPTO_ALGAPI
        help
          ARC4 cipher algorithm.
 
 
 config CRYPTO_KHAZAD
        tristate "Khazad cipher algorithm"
-       depends on CRYPTO
+       select CRYPTO_ALGAPI
        help
          Khazad cipher algorithm.
 
 
 config CRYPTO_ANUBIS
        tristate "Anubis cipher algorithm"
-       depends on CRYPTO
+       select CRYPTO_ALGAPI
        help
          Anubis cipher algorithm.
 
 
 config CRYPTO_DEFLATE
        tristate "Deflate compression algorithm"
-       depends on CRYPTO
+       select CRYPTO_ALGAPI
        select ZLIB_INFLATE
        select ZLIB_DEFLATE
        help
 
 config CRYPTO_MICHAEL_MIC
        tristate "Michael MIC keyed digest algorithm"
-       depends on CRYPTO
+       select CRYPTO_ALGAPI
        help
          Michael MIC is used for message integrity protection in TKIP
          (IEEE 802.11i). This algorithm is required for TKIP, but it
 
 config CRYPTO_CRC32C
        tristate "CRC32c CRC algorithm"
-       depends on CRYPTO
+       select CRYPTO_ALGAPI
        select LIBCRC32C
        help
          Castagnoli, et al Cyclic Redundancy-Check Algorithm.  Used
 
 config CRYPTO_TEST
        tristate "Testing module"
-       depends on CRYPTO && m
+       depends on m
+       select CRYPTO_ALGAPI
        help
          Quick & dirty crypto test module.
 
 source "drivers/crypto/Kconfig"
-endmenu
 
+endif  # if CRYPTO
+
+endmenu
 
 # Cryptographic API
 #
 
-proc-crypto-$(CONFIG_PROC_FS) = proc.o
+obj-$(CONFIG_CRYPTO) += api.o scatterwalk.o cipher.o digest.o compress.o
 
-obj-$(CONFIG_CRYPTO) += api.o scatterwalk.o cipher.o digest.o compress.o \
-                       $(proc-crypto-y)
+crypto_algapi-$(CONFIG_PROC_FS) += proc.o
+crypto_algapi-objs := algapi.o $(crypto_algapi-y)
+obj-$(CONFIG_CRYPTO_ALGAPI) += crypto_algapi.o
 
 obj-$(CONFIG_CRYPTO_HMAC) += hmac.o
 obj-$(CONFIG_CRYPTO_NULL) += crypto_null.o
 
--- /dev/null
+/*
+ * Cryptographic API for algorithms (i.e., low-level API).
+ *
+ * Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au>
+ *
+ * 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.
+ *
+ */
+
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+
+#include "internal.h"
+
+static inline int crypto_set_driver_name(struct crypto_alg *alg)
+{
+       static const char suffix[] = "-generic";
+       char *driver_name = alg->cra_driver_name;
+       int len;
+
+       if (*driver_name)
+               return 0;
+
+       len = strlcpy(driver_name, alg->cra_name, CRYPTO_MAX_ALG_NAME);
+       if (len + sizeof(suffix) > CRYPTO_MAX_ALG_NAME)
+               return -ENAMETOOLONG;
+
+       memcpy(driver_name + len, suffix, sizeof(suffix));
+       return 0;
+}
+
+int crypto_register_alg(struct crypto_alg *alg)
+{
+       int ret;
+       struct crypto_alg *q;
+
+       if (alg->cra_alignmask & (alg->cra_alignmask + 1))
+               return -EINVAL;
+
+       if (alg->cra_alignmask & alg->cra_blocksize)
+               return -EINVAL;
+
+       if (alg->cra_blocksize > PAGE_SIZE / 8)
+               return -EINVAL;
+
+       if (alg->cra_priority < 0)
+               return -EINVAL;
+       
+       ret = crypto_set_driver_name(alg);
+       if (unlikely(ret))
+               return ret;
+
+       down_write(&crypto_alg_sem);
+       
+       list_for_each_entry(q, &crypto_alg_list, cra_list) {
+               if (q == alg) {
+                       ret = -EEXIST;
+                       goto out;
+               }
+       }
+       
+       list_add(&alg->cra_list, &crypto_alg_list);
+       atomic_set(&alg->cra_refcnt, 1);
+out:   
+       up_write(&crypto_alg_sem);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(crypto_register_alg);
+
+int crypto_unregister_alg(struct crypto_alg *alg)
+{
+       int ret = -ENOENT;
+       struct crypto_alg *q;
+       
+       down_write(&crypto_alg_sem);
+       list_for_each_entry(q, &crypto_alg_list, cra_list) {
+               if (alg == q) {
+                       list_del(&alg->cra_list);
+                       ret = 0;
+                       goto out;
+               }
+       }
+out:   
+       up_write(&crypto_alg_sem);
+
+       if (ret)
+               return ret;
+
+       BUG_ON(atomic_read(&alg->cra_refcnt) != 1);
+       if (alg->cra_destroy)
+               alg->cra_destroy(alg);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(crypto_unregister_alg);
+
+static int __init crypto_algapi_init(void)
+{
+       crypto_init_proc();
+       return 0;
+}
+
+static void __exit crypto_algapi_exit(void)
+{
+       crypto_exit_proc();
+}
+
+module_init(crypto_algapi_init);
+module_exit(crypto_algapi_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Cryptographic algorithms API");
 
  *
  */
 
-#include <linux/compiler.h>
-#include <linux/init.h>
-#include <linux/crypto.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/kmod.h>
-#include <linux/rwsem.h>
 #include <linux/slab.h>
 #include <linux/string.h>
 #include "internal.h"
 
 LIST_HEAD(crypto_alg_list);
+EXPORT_SYMBOL_GPL(crypto_alg_list);
 DECLARE_RWSEM(crypto_alg_sem);
+EXPORT_SYMBOL_GPL(crypto_alg_sem);
 
 static inline struct crypto_alg *crypto_alg_get(struct crypto_alg *alg)
 {
        kfree(tfm);
 }
 
-static inline int crypto_set_driver_name(struct crypto_alg *alg)
-{
-       static const char suffix[] = "-generic";
-       char *driver_name = alg->cra_driver_name;
-       int len;
-
-       if (*driver_name)
-               return 0;
-
-       len = strlcpy(driver_name, alg->cra_name, CRYPTO_MAX_ALG_NAME);
-       if (len + sizeof(suffix) > CRYPTO_MAX_ALG_NAME)
-               return -ENAMETOOLONG;
-
-       memcpy(driver_name + len, suffix, sizeof(suffix));
-       return 0;
-}
-
-int crypto_register_alg(struct crypto_alg *alg)
-{
-       int ret;
-       struct crypto_alg *q;
-
-       if (alg->cra_alignmask & (alg->cra_alignmask + 1))
-               return -EINVAL;
-
-       if (alg->cra_alignmask & alg->cra_blocksize)
-               return -EINVAL;
-
-       if (alg->cra_blocksize > PAGE_SIZE / 8)
-               return -EINVAL;
-
-       if (alg->cra_priority < 0)
-               return -EINVAL;
-       
-       ret = crypto_set_driver_name(alg);
-       if (unlikely(ret))
-               return ret;
-
-       down_write(&crypto_alg_sem);
-       
-       list_for_each_entry(q, &crypto_alg_list, cra_list) {
-               if (q == alg) {
-                       ret = -EEXIST;
-                       goto out;
-               }
-       }
-       
-       list_add(&alg->cra_list, &crypto_alg_list);
-       atomic_set(&alg->cra_refcnt, 1);
-out:   
-       up_write(&crypto_alg_sem);
-       return ret;
-}
-
-int crypto_unregister_alg(struct crypto_alg *alg)
-{
-       int ret = -ENOENT;
-       struct crypto_alg *q;
-       
-       down_write(&crypto_alg_sem);
-       list_for_each_entry(q, &crypto_alg_list, cra_list) {
-               if (alg == q) {
-                       list_del(&alg->cra_list);
-                       ret = 0;
-                       goto out;
-               }
-       }
-out:   
-       up_write(&crypto_alg_sem);
-
-       if (ret)
-               return ret;
-
-       BUG_ON(atomic_read(&alg->cra_refcnt) != 1);
-       if (alg->cra_destroy)
-               alg->cra_destroy(alg);
-
-       return 0;
-}
-
 int crypto_alg_available(const char *name, u32 flags)
 {
        int ret = 0;
        return ret;
 }
 
-static int __init init_crypto(void)
-{
-       printk(KERN_INFO "Initializing Cryptographic API\n");
-       crypto_init_proc();
-       return 0;
-}
-
-__initcall(init_crypto);
-
-EXPORT_SYMBOL_GPL(crypto_register_alg);
-EXPORT_SYMBOL_GPL(crypto_unregister_alg);
 EXPORT_SYMBOL_GPL(crypto_alloc_tfm);
 EXPORT_SYMBOL_GPL(crypto_free_tfm);
 EXPORT_SYMBOL_GPL(crypto_alg_available);
 
  */
 #ifndef _CRYPTO_INTERNAL_H
 #define _CRYPTO_INTERNAL_H
-#include <linux/crypto.h>
+
+#include <crypto/algapi.h>
 #include <linux/mm.h>
 #include <linux/highmem.h>
 #include <linux/interrupt.h>
 
 #ifdef CONFIG_PROC_FS
 void __init crypto_init_proc(void);
+void __exit crypto_exit_proc(void);
 #else
 static inline void crypto_init_proc(void)
 { }
+static inline void crypto_exit_proc(void)
+{ }
 #endif
 
 static inline unsigned int crypto_digest_ctxsize(struct crypto_alg *alg,
 
        if (proc)
                proc->proc_fops = &proc_crypto_ops;
 }
+
+void __exit crypto_exit_proc(void)
+{
+       remove_proc_entry("crypto", NULL);
+}
 
 
 config CRYPTO_DEV_PADLOCK
        tristate "Support for VIA PadLock ACE"
-       depends on CRYPTO && X86_32
+       depends on X86_32
+       select CRYPTO_ALGAPI
        help
          Some VIA processors come with an integrated crypto engine
          (so called VIA PadLock ACE, Advanced Cryptography Engine)
 
--- /dev/null
+/*
+ * Cryptographic API for algorithms (i.e., low-level API).
+ *
+ * Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au>
+ *
+ * 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.
+ *
+ */
+#ifndef _CRYPTO_ALGAPI_H
+#define _CRYPTO_ALGAPI_H
+
+#include <linux/crypto.h>
+
+#endif /* _CRYPTO_ALGAPI_H */
+