Hi:

[CRYPTO] api: Add cryptomgr

The cryptomgr module is a simple manager of crypto algorithm instances.
It ensures that parameterised algorithms of the type tmpl(alg) (e.g.,
cbc(aes)) are always created.

This is meant to satisfy the needs for most users.  For more complex
cases such as deeper combinations or multiple parameters, a netlink
module will be created which allows arbitrary expressions to be parsed
in user-space.

Signed-off-by: Herbert Xu <[EMAIL PROTECTED]>

Cheers,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <[EMAIL PROTECTED]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--
diff --git a/crypto/Kconfig b/crypto/Kconfig
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -9,6 +9,14 @@ config CRYPTO
        help
          This option provides the core Cryptographic API.
 
+config CRYPTO_MANAGER
+       tristate "Cryptographic algorithm manager"
+       depends on CRYPTO
+       default m
+       help
+         Create default cryptographic template instantiations such as
+         cbc(aes).
+
 config CRYPTO_HMAC
        bool "HMAC support"
        depends on CRYPTO
diff --git a/crypto/Makefile b/crypto/Makefile
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -7,6 +7,7 @@ proc-crypto-$(CONFIG_PROC_FS) = proc.o
 obj-$(CONFIG_CRYPTO) += api.o scatterwalk.o cipher.o digest.o compress.o \
                        $(proc-crypto-y)
 
+obj-$(CONFIG_CRYPTO_MANAGER) += cryptomgr.o
 obj-$(CONFIG_CRYPTO_HMAC) += hmac.o
 obj-$(CONFIG_CRYPTO_NULL) += crypto_null.o
 obj-$(CONFIG_CRYPTO_MD4) += md4.o
diff --git a/crypto/api.c b/crypto/api.c
--- a/crypto/api.c
+++ b/crypto/api.c
@@ -22,6 +22,7 @@
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/kmod.h>
+#include <linux/module.h>
 #include <linux/notifier.h>
 #include <linux/param.h>
 #include <linux/rwsem.h>
@@ -199,6 +200,7 @@ static struct crypto_alg *crypto_alg_mod
 {
        struct crypto_alg *alg;
        struct crypto_alg *larval;
+       int ok;
 
        alg = try_then_request_module(crypto_alg_lookup(name), name);
        if (alg)
@@ -208,7 +210,13 @@ static struct crypto_alg *crypto_alg_mod
        if (!larval || !crypto_is_larval(larval))
                return larval;
 
-       if (crypto_notify(CRYPTO_MSG_ALG_REQUEST, larval) == NOTIFY_STOP)
+       ok = crypto_notify(CRYPTO_MSG_ALG_REQUEST, larval);
+       if (ok == NOTIFY_DONE) {
+               request_module("cryptomgr");
+               ok = crypto_notify(CRYPTO_MSG_ALG_REQUEST, larval);
+       }
+
+       if (ok == NOTIFY_STOP)
                alg = crypto_larval_wait(larval);
        else {
                crypto_mod_put(larval);
diff --git a/crypto/cryptomgr.c b/crypto/cryptomgr.c
new file mode 100644
--- /dev/null
+++ b/crypto/cryptomgr.c
@@ -0,0 +1,117 @@
+/*
+ * Create default crypto algorithm instances.
+ *
+ * Copyright (c) 2006 Herbert Xu <[EMAIL PROTECTED]>
+ *
+ * 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/crypto.h>
+#include <linux/ctype.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/notifier.h>
+#include <linux/rtnetlink.h>
+#include <linux/string.h>
+
+#include "internal.h"
+
+struct cryptomgr_param {
+       struct {
+               struct rtattr attr;
+               struct crypto_attr_alg data;
+       } alg;
+};
+
+static int cryptomgr_probe(struct crypto_larval *larval)
+{
+       struct cryptomgr_param param;
+       struct crypto_template *tmpl;
+       struct crypto_instance *inst;
+       const char *name = larval->alg.cra_name;
+       const char *p;
+       unsigned int len;
+
+       for (p = name; isalnum(*p) || *p == '-' || *p == '_'; p++)
+               ;
+
+       len = p - name;
+       if (!len || *p != '(')
+               return NOTIFY_OK;
+
+       memcpy(param.alg.data.name, name, len);
+       param.alg.data.name[len] = 0;
+
+       name = p + 1;
+       for (p = name; isalnum(*p) || *p == '-' || *p == '_'; p++)
+               ;
+
+       len = p - name;
+       if (!len || *p != ')' || p[1])
+               return NOTIFY_OK;
+
+       tmpl = crypto_lookup_template(param.alg.data.name);
+       if (!tmpl)
+               goto err;
+
+       param.alg.attr.rta_len = sizeof(param.alg);
+       param.alg.attr.rta_type = CRYPTOA_ALG;
+       memcpy(param.alg.data.name, name, len);
+       param.alg.data.name[len] = 0;
+
+       inst = tmpl->alloc(&param, sizeof(param));
+       if (IS_ERR(inst))
+               inst = NULL;
+       else if (crypto_register_instance(tmpl, inst)) {
+               tmpl->free(inst);
+               inst = NULL;
+       }
+
+       crypto_tmpl_put(tmpl);
+
+       if (!inst)
+               goto err;
+
+       return NOTIFY_STOP;
+
+err:
+       crypto_larval_error(larval->alg.cra_name);
+       return NOTIFY_STOP;
+}
+
+static int cryptomgr_notify(struct notifier_block *this, unsigned long msg,
+                           void *data)
+{
+       switch (msg) {
+       case CRYPTO_MSG_ALG_REQUEST:
+               return cryptomgr_probe(data);
+       }
+
+       return NOTIFY_DONE;
+}
+
+static struct notifier_block cryptomgr_notifier = {
+       .notifier_call = cryptomgr_notify,
+};
+
+static int __init cryptomgr_init(void)
+{
+       return crypto_register_notifier(&cryptomgr_notifier);
+}
+
+static void __exit cryptomgr_exit(void)
+{
+       int err = crypto_unregister_notifier(&cryptomgr_notifier);
+       BUG_ON(err);
+}
+
+module_init(cryptomgr_init);
+module_exit(cryptomgr_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Crypto Algorithm Manager");
diff --git a/include/linux/crypto.h b/include/linux/crypto.h
--- a/include/linux/crypto.h
+++ b/include/linux/crypto.h
@@ -239,6 +239,15 @@ struct crypto_tfm {
        char __crt_ctx[] __attribute__ ((__aligned__));
 };
 
+enum {
+       CRYPTOA_UNSPEC,
+       CRYPTOA_ALG,
+};
+
+struct crypto_attr_alg {
+       char name[CRYPTO_MAX_ALG_NAME];
+};
+
 /* 
  * Transform user interface.
  */
-
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to