Commit 6c1e4919 authored by James Morris's avatar James Morris

[CRYPTO]: Use kmod to try to autoload modules.

parent cd74bb13
......@@ -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
......
......@@ -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 @@ int crypto_unregister_alg(struct crypto_alg *alg)
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;
......
/*
* 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;
}
......@@ -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);
......
......@@ -37,28 +37,29 @@
#define CRYPTO_MODE_MASK 0x0ff00000
#define CRYPTO_ALG_MASK 0x000fffff
#define CRYPTO_TYPE_CIPHER 0x00000000
#define CRYPTO_TYPE_DIGEST 0x10000000
#define CRYPTO_TYPE_COMP 0x20000000
#define CRYPTO_TYPE_CIPHER 0x10000000
#define CRYPTO_TYPE_DIGEST 0x20000000
#define CRYPTO_TYPE_COMP 0x40000000
#define CRYPTO_MODE_ECB 0x00000000
#define CRYPTO_MODE_CBC 0x00100000
#define CRYPTO_MODE_CFB 0x00200000
#define CRYPTO_MODE_CTR 0x00400000
#define CRYPTO_MODE_ECB 0x00100000
#define CRYPTO_MODE_CBC 0x00200000
#define CRYPTO_MODE_CFB 0x00400000
#define CRYPTO_MODE_CTR 0x00800000
#define CRYPTO_ALG_NULL 0x00000000
#define CRYPTO_ALG_NULL 0x00000001
#define CRYPTO_ALG_DES (0x00000001|CRYPTO_TYPE_CIPHER)
#define CRYPTO_ALG_DES (0x00000002|CRYPTO_TYPE_CIPHER)
#define CRYPTO_ALG_DES_ECB (CRYPTO_ALG_DES|CRYPTO_MODE_ECB)
#define CRYPTO_ALG_DES_CBC (CRYPTO_ALG_DES|CRYPTO_MODE_CBC)
#define CRYPTO_ALG_DES3_EDE (0x00000002|CRYPTO_TYPE_CIPHER)
#define CRYPTO_ALG_DES3_EDE (0x00000003|CRYPTO_TYPE_CIPHER)
#define CRYPTO_ALG_DES3_EDE_ECB (CRYPTO_ALG_DES3_EDE|CRYPTO_MODE_ECB)
#define CRYPTO_ALG_DES3_EDE_CBC (CRYPTO_ALG_DES3_EDE|CRYPTO_MODE_CBC)
#define CRYPTO_ALG_MD5 (0x00000f00|CRYPTO_TYPE_DIGEST)
#define CRYPTO_ALG_SHA1 (0x00000f01|CRYPTO_TYPE_DIGEST)
#define CRYPTO_UNSPEC 0
#define CRYPTO_MAX_ALG_NAME 64
#define CRYPTO_MAX_BLOCK_SIZE 16
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment