summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crypto/api.c32
-rw-r--r--crypto/proc.c5
-rw-r--r--include/crypto/algapi.h8
-rw-r--r--include/linux/crypto.h3
4 files changed, 38 insertions, 10 deletions
diff --git a/crypto/api.c b/crypto/api.c
index bc4b7901acdf..edaa843d8e83 100644
--- a/crypto/api.c
+++ b/crypto/api.c
@@ -226,17 +226,18 @@ static int crypto_init_flags(struct crypto_tfm *tfm, u32 flags)
case CRYPTO_ALG_TYPE_COMPRESS:
return crypto_init_compress_flags(tfm, flags);
-
- default:
- break;
}
- BUG();
- return -EINVAL;
+ return 0;
}
static int crypto_init_ops(struct crypto_tfm *tfm)
{
+ const struct crypto_type *type = tfm->__crt_alg->cra_type;
+
+ if (type)
+ return type->init(tfm);
+
switch (crypto_tfm_alg_type(tfm)) {
case CRYPTO_ALG_TYPE_CIPHER:
return crypto_init_cipher_ops(tfm);
@@ -257,6 +258,14 @@ static int crypto_init_ops(struct crypto_tfm *tfm)
static void crypto_exit_ops(struct crypto_tfm *tfm)
{
+ const struct crypto_type *type = tfm->__crt_alg->cra_type;
+
+ if (type) {
+ if (type->exit)
+ type->exit(tfm);
+ return;
+ }
+
switch (crypto_tfm_alg_type(tfm)) {
case CRYPTO_ALG_TYPE_CIPHER:
crypto_exit_cipher_ops(tfm);
@@ -278,26 +287,31 @@ static void crypto_exit_ops(struct crypto_tfm *tfm)
static unsigned int crypto_ctxsize(struct crypto_alg *alg, int flags)
{
+ const struct crypto_type *type = alg->cra_type;
unsigned int len;
+ len = alg->cra_alignmask & ~(crypto_tfm_ctx_alignment() - 1);
+ if (type)
+ return len + type->ctxsize(alg);
+
switch (alg->cra_flags & CRYPTO_ALG_TYPE_MASK) {
default:
BUG();
case CRYPTO_ALG_TYPE_CIPHER:
- len = crypto_cipher_ctxsize(alg, flags);
+ len += crypto_cipher_ctxsize(alg, flags);
break;
case CRYPTO_ALG_TYPE_DIGEST:
- len = crypto_digest_ctxsize(alg, flags);
+ len += crypto_digest_ctxsize(alg, flags);
break;
case CRYPTO_ALG_TYPE_COMPRESS:
- len = crypto_compress_ctxsize(alg, flags);
+ len += crypto_compress_ctxsize(alg, flags);
break;
}
- return len + (alg->cra_alignmask & ~(crypto_tfm_ctx_alignment() - 1));
+ return len;
}
void crypto_shoot_alg(struct crypto_alg *alg)
diff --git a/crypto/proc.c b/crypto/proc.c
index 9e573b17e887..dabce0676f63 100644
--- a/crypto/proc.c
+++ b/crypto/proc.c
@@ -78,7 +78,10 @@ static int c_show(struct seq_file *m, void *p)
seq_printf(m, "type : compression\n");
break;
default:
- seq_printf(m, "type : unknown\n");
+ if (alg->cra_type && alg->cra_type->show)
+ alg->cra_type->show(m, alg);
+ else
+ seq_printf(m, "type : unknown\n");
break;
}
diff --git a/include/crypto/algapi.h b/include/crypto/algapi.h
index 1a598f829417..c533c0a291af 100644
--- a/include/crypto/algapi.h
+++ b/include/crypto/algapi.h
@@ -15,6 +15,14 @@
#include <linux/crypto.h>
struct module;
+struct seq_file;
+
+struct crypto_type {
+ unsigned int (*ctxsize)(struct crypto_alg *alg);
+ int (*init)(struct crypto_tfm *tfm);
+ void (*exit)(struct crypto_tfm *tfm);
+ void (*show)(struct seq_file *m, struct crypto_alg *alg);
+};
struct crypto_instance {
struct crypto_alg alg;
diff --git a/include/linux/crypto.h b/include/linux/crypto.h
index 6847ab0ea30e..8e9c407b00d2 100644
--- a/include/linux/crypto.h
+++ b/include/linux/crypto.h
@@ -90,6 +90,7 @@
struct scatterlist;
struct crypto_tfm;
+struct crypto_type;
struct cipher_desc {
struct crypto_tfm *tfm;
@@ -161,6 +162,8 @@ struct crypto_alg {
char cra_name[CRYPTO_MAX_ALG_NAME];
char cra_driver_name[CRYPTO_MAX_ALG_NAME];
+ const struct crypto_type *cra_type;
+
union {
struct cipher_alg cipher;
struct digest_alg digest;