diff options
author | James Morris <jmorris@intercode.com.au> | 2002-10-24 17:48:28 -0700 |
---|---|---|
committer | James Morris <jmorris@intercode.com.au> | 2002-10-24 17:48:28 -0700 |
commit | 6c1e4919ac56f4c9ae9ed470475e6139f58a4804 (patch) | |
tree | 60a70ae9d774a9752ce0b1debb418987abb0fadd /crypto | |
parent | cd74bb134f87eb043425494861bec1afe98015e8 (diff) | |
download | history-6c1e4919ac56f4c9ae9ed470475e6139f58a4804.tar.gz |
[CRYPTO]: Use kmod to try to autoload modules.
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/Makefile | 1 | ||||
-rw-r--r-- | crypto/api.c | 152 | ||||
-rw-r--r-- | crypto/autoload.c | 44 | ||||
-rw-r--r-- | crypto/internal.h | 4 |
4 files changed, 127 insertions, 74 deletions
diff --git a/crypto/Makefile b/crypto/Makefile index 6c7f7fb6590e4d..262cff47dd3977 100644 --- a/crypto/Makefile +++ b/crypto/Makefile @@ -5,6 +5,7 @@ export-objs := api.o obj-$(CONFIG_CRYPTO) += api.o cipher.o digest.o compress.o +obj-$(CONFIG_KMOD) += autoload.o obj-$(CONFIG_CRYPTO_MD5) += md5.o obj-$(CONFIG_CRYPTO_SHA1) += sha1.o diff --git a/crypto/api.c b/crypto/api.c index cd245fc2afa511..ed04978a9cd0e0 100644 --- a/crypto/api.c +++ b/crypto/api.c @@ -25,76 +25,6 @@ static LIST_HEAD(crypto_alg_list); static struct rw_semaphore crypto_alg_sem; -static void *c_start(struct seq_file *m, loff_t *pos) -{ - struct list_head *v; - loff_t n = *pos; - - down_read(&crypto_alg_sem); - list_for_each(v, &crypto_alg_list) - if (!n--) - return list_entry(v, struct crypto_alg, cra_list); - return NULL; -} - -static void *c_next(struct seq_file *m, void *p, loff_t *pos) -{ - struct list_head *v = p; - - (*pos)++; - v = v->next; - return (v == &crypto_alg_list) ? - NULL : list_entry(v, struct crypto_alg, cra_list); -} - -static void c_stop(struct seq_file *m, void *p) -{ - up_read(&crypto_alg_sem); -} - -static int c_show(struct seq_file *m, void *p) -{ - struct crypto_alg *alg = (struct crypto_alg *)p; - - seq_printf(m, "name : %s\n", alg->cra_name); - seq_printf(m, "id : 0x%08x\n", alg->cra_id); - seq_printf(m, "blocksize : %Zd\n", alg->cra_blocksize); - - switch (alg->cra_id & CRYPTO_TYPE_MASK) { - case CRYPTO_TYPE_CIPHER: - seq_printf(m, "keysize : %Zd\n", alg->cra_cipher.cia_keysize); - seq_printf(m, "ivsize : %Zd\n", alg->cra_cipher.cia_ivsize); - break; - - case CRYPTO_TYPE_DIGEST: - seq_printf(m, "digestsize : %Zd\n", - alg->cra_digest.dia_digestsize); - break; - } - - seq_putc(m, '\n'); - return 0; -} - -static struct seq_operations crypto_seq_ops = { - .start = c_start, - .next = c_next, - .stop = c_stop, - .show = c_show -}; - -static int crypto_info_open(struct inode *inode, struct file *file) -{ - return seq_open(file, &crypto_seq_ops); -} - -struct file_operations proc_crypto_ops = { - .open = crypto_info_open, - .read = seq_read, - .llseek = seq_lseek, - .release = seq_release -}; - static inline int crypto_alg_get(struct crypto_alg *alg) { if (alg->cra_module) @@ -105,7 +35,8 @@ static inline int crypto_alg_get(struct crypto_alg *alg) static inline void crypto_alg_put(struct crypto_alg *alg) { - __MOD_DEC_USE_COUNT(alg->cra_module); + if (alg->cra_module) + __MOD_DEC_USE_COUNT(alg->cra_module); } struct crypto_alg *crypto_alg_lookup(u32 algid) @@ -149,15 +80,18 @@ static void crypto_init_ops(struct crypto_tfm *tfm) } } -/* - * Todo: try and load the module if the lookup fails. - */ struct crypto_tfm *crypto_alloc_tfm(u32 id) { struct crypto_tfm *tfm = NULL; struct crypto_alg *alg; alg = crypto_alg_lookup(id & CRYPTO_ALG_MASK); +#ifdef CONFIG_KMOD + if (alg == NULL) { + crypto_alg_autoload(id & CRYPTO_ALG_MASK); + alg = crypto_alg_lookup(id & CRYPTO_ALG_MASK); + } +#endif if (alg == NULL) goto out; @@ -251,6 +185,76 @@ out: return ret; } +static void *c_start(struct seq_file *m, loff_t *pos) +{ + struct list_head *v; + loff_t n = *pos; + + down_read(&crypto_alg_sem); + list_for_each(v, &crypto_alg_list) + if (!n--) + return list_entry(v, struct crypto_alg, cra_list); + return NULL; +} + +static void *c_next(struct seq_file *m, void *p, loff_t *pos) +{ + struct list_head *v = p; + + (*pos)++; + v = v->next; + return (v == &crypto_alg_list) ? + NULL : list_entry(v, struct crypto_alg, cra_list); +} + +static void c_stop(struct seq_file *m, void *p) +{ + up_read(&crypto_alg_sem); +} + +static int c_show(struct seq_file *m, void *p) +{ + struct crypto_alg *alg = (struct crypto_alg *)p; + + seq_printf(m, "name : %s\n", alg->cra_name); + seq_printf(m, "id : 0x%08x\n", alg->cra_id); + seq_printf(m, "blocksize : %Zd\n", alg->cra_blocksize); + + switch (alg->cra_id & CRYPTO_TYPE_MASK) { + case CRYPTO_TYPE_CIPHER: + seq_printf(m, "keysize : %Zd\n", alg->cra_cipher.cia_keysize); + seq_printf(m, "ivsize : %Zd\n", alg->cra_cipher.cia_ivsize); + break; + + case CRYPTO_TYPE_DIGEST: + seq_printf(m, "digestsize : %Zd\n", + alg->cra_digest.dia_digestsize); + break; + } + + seq_putc(m, '\n'); + return 0; +} + +static struct seq_operations crypto_seq_ops = { + .start = c_start, + .next = c_next, + .stop = c_stop, + .show = c_show +}; + +static int crypto_info_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &crypto_seq_ops); +} + +struct file_operations proc_crypto_ops = { + .open = crypto_info_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release +}; + static int __init init_crypto(void) { struct proc_dir_entry *proc; diff --git a/crypto/autoload.c b/crypto/autoload.c new file mode 100644 index 00000000000000..bc263cd4e22c7e --- /dev/null +++ b/crypto/autoload.c @@ -0,0 +1,44 @@ +/* + * Cryptographic API. + * + * Algorithm autoloader. + * + * Copyright (c) 2002 James Morris <jmorris@intercode.com.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/kernel.h> +#include <linux/types.h> +#include <linux/list.h> +#include <linux/string.h> +#include <linux/kmod.h> +#include <linux/crypto.h> +#include "internal.h" + +static struct { + u32 algid; + char *name; +} alg_modmap[] = { + { CRYPTO_ALG_DES, "des" }, + { CRYPTO_ALG_DES3_EDE, "des" }, + { CRYPTO_ALG_MD5, "md5" }, + { CRYPTO_ALG_SHA1, "sha1" }, +}; +#define ALG_MAX_MODMAP 4 + +void crypto_alg_autoload(u32 algid) +{ + int i; + + for (i = 0; i < ALG_MAX_MODMAP ; i++) { + if ((alg_modmap[i].algid & CRYPTO_ALG_MASK) == algid) { + request_module(alg_modmap[i].name); + break; + } + } + return; +} diff --git a/crypto/internal.h b/crypto/internal.h index bf717d9186ba09..706b6e6e5c419c 100644 --- a/crypto/internal.h +++ b/crypto/internal.h @@ -46,6 +46,10 @@ static inline void crypto_yield(struct crypto_tfm *tfm) cond_resched(); } +#ifdef CONFIG_KMOD +void crypto_alg_autoload(u32 algid); +#endif + void crypto_init_digest_ops(struct crypto_tfm *tfm); void crypto_init_cipher_ops(struct crypto_tfm *tfm); void crypto_init_compress_ops(struct crypto_tfm *tfm); |