From e853c3cfa8cc24869ecd2526e589bcb176bc12e9 Mon Sep 17 00:00:00 2001
From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Tue, 22 Aug 2006 00:06:54 +1000
Subject: [PATCH] [CRYPTO] api: Added crypto_type support

This patch adds the crypto_type structure which will be used for all new
crypto algorithm types, beginning with block ciphers.

The primary purpose of this abstraction is to allow different crypto_type
objects for crypto algorithms of the same type, in particular, there will
be a different crypto_type objects for asynchronous algorithms.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
---
 crypto/api.c            | 32 +++++++++++++++++++++++---------
 crypto/proc.c           |  5 ++++-
 include/crypto/algapi.h |  8 ++++++++
 include/linux/crypto.h  |  3 +++
 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;
-- 
GitLab