mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Christophe Saout <christophe@saout.de>
To: Matt Mackall <mpm@selenic.com>
Cc: Jean-Luc Cooke <jlcooke@certainkey.com>,
	linux-kernel@vger.kernel.org,
	James Morris <jmorris@intercode.com.au>
Subject: Re: [PATCH/proposal] dm-crypt: add digest-based iv generation mode
Date: Fri, 27 Feb 2004 19:37:27 +0100	[thread overview]
Message-ID: <20040227183718.GA1880@leto.cs.pocnet.net> (raw)
In-Reply-To: <1077897901.29711.44.camel@leto.cs.pocnet.net>

Hi,

I just hacked together what I wrote. Compiles but untested.

diff -Nur linux.orig/crypto/api.c linux/crypto/api.c
--- linux.orig/crypto/api.c	2004-02-27 19:25:58.445326056 +0100
+++ linux/crypto/api.c	2004-02-27 19:26:44.451332080 +0100
@@ -96,6 +96,26 @@
 	return -EINVAL;
 }
 
+static int crypto_copy_ops(struct crypto_tfm *tfm)
+{
+	switch (crypto_tfm_alg_type(tfm)) {
+	case CRYPTO_ALG_TYPE_CIPHER:
+		return crypto_copy_cipher_ops(tfm);
+		
+	case CRYPTO_ALG_TYPE_DIGEST:
+		return crypto_copy_digest_ops(tfm);
+		
+	case CRYPTO_ALG_TYPE_COMPRESS:
+		return crypto_copy_compress_ops(tfm);
+
+	default:
+		break;
+	}
+
+	BUG();
+	return -EINVAL;
+}
+
 static void crypto_exit_ops(struct crypto_tfm *tfm)
 {
 	switch (crypto_tfm_alg_type(tfm)) {
@@ -117,6 +137,62 @@
 	}
 }
 
+static int __crypto_init_tfm(struct crypto_tfm *tfm, struct crypto_alg *alg,
+			     u32 flags)
+{
+	memset(tfm, 0, crypto_alg_tfm_size(alg));
+
+	tfm->__crt_alg = alg;
+
+	if (crypto_init_flags(tfm, flags))
+		return -EINVAL;
+
+	if (crypto_init_ops(tfm)) {
+		crypto_exit_ops(tfm);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+unsigned int crypto_lookup_alg_tfm_size(const char *name, u32 flags)
+{
+	struct crypto_alg *alg;
+	unsigned int size;
+
+	alg = crypto_alg_mod_lookup(name);
+	if (alg == NULL)
+		return 0;
+
+	size = crypto_alg_tfm_size(alg);
+
+	crypto_alg_put(alg);
+	/* hmm, there's a window to race between here and crypto_init_tfm */
+
+	return size;
+}
+
+int crypto_init_tfm(struct crypto_tfm *tfm, const char *name, u32 flags)
+{
+	struct crypto_alg *alg;
+	int ret = -EINVAL;
+
+	alg = crypto_alg_mod_lookup(name);
+	if (alg == NULL)
+		goto out;
+
+	ret = __crypto_init_tfm(tfm, alg, flags);
+	if (ret < 0)
+		goto out_put;
+
+	goto out;
+
+out_put:
+	crypto_alg_put(alg);
+out:
+	return ret;
+}
+
 struct crypto_tfm *crypto_alloc_tfm(const char *name, u32 flags)
 {
 	struct crypto_tfm *tfm = NULL;
@@ -126,21 +202,12 @@
 	if (alg == NULL)
 		goto out;
 	
-	tfm = kmalloc(sizeof(*tfm) + alg->cra_ctxsize, GFP_KERNEL);
+	tfm = kmalloc(crypto_alg_tfm_size(alg), GFP_KERNEL);
 	if (tfm == NULL)
 		goto out_put;
 
-	memset(tfm, 0, sizeof(*tfm) + alg->cra_ctxsize);
-	
-	tfm->__crt_alg = alg;
-	
-	if (crypto_init_flags(tfm, flags))
+	if (__crypto_init_tfm(tfm, alg, flags) < 0)
 		goto out_free_tfm;
-		
-	if (crypto_init_ops(tfm)) {
-		crypto_exit_ops(tfm);
-		goto out_free_tfm;
-	}
 
 	goto out;
 
@@ -153,13 +220,52 @@
 	return tfm;
 }
 
-void crypto_free_tfm(struct crypto_tfm *tfm)
+void crypto_exit_tfm(struct crypto_tfm *tfm)
 {
 	crypto_exit_ops(tfm);
 	crypto_alg_put(tfm->__crt_alg);
+}
+
+void crypto_free_tfm(struct crypto_tfm *tfm)
+{
+	crypto_exit_tfm(tfm);
 	kfree(tfm);
 }
 
+int crypto_copy_tfm(struct crypto_tfm *dst, struct crypto_tfm *src)
+{
+	int ret;
+
+	memcpy(dst, src, crypto_tfm_size(src));
+	crypto_alg_get(dst->__crt_alg);
+
+	ret = crypto_copy_ops(dst);
+	if (ret < 0)
+		crypto_alg_put(dst->__crt_alg);
+
+	return ret;
+}
+
+struct crypto_tfm *crypto_clone_tfm(struct crypto_tfm *orig)
+{
+	struct crypto_tfm *clone = NULL;
+
+	clone = kmalloc(crypto_tfm_size(orig), GFP_KERNEL);
+	if (clone == NULL)
+		goto out;
+
+	if (crypto_copy_tfm(clone, orig) < 0)
+		goto out_free_tfm;
+
+	goto out;
+
+out_free_tfm:
+	kfree(clone);
+	clone = NULL;
+out:
+	return clone;
+}
+
 int crypto_register_alg(struct crypto_alg *alg)
 {
 	int ret = 0;
diff -Nur linux.orig/crypto/cipher.c linux/crypto/cipher.c
--- linux.orig/crypto/cipher.c	2004-02-27 19:25:58.513315720 +0100
+++ linux/crypto/cipher.c	2004-02-27 19:26:44.457331168 +0100
@@ -281,7 +281,7 @@
 	    	}
 	    	
 		ops->cit_ivsize = crypto_tfm_alg_blocksize(tfm);
-	    	ops->cit_iv = kmalloc(ops->cit_ivsize, GFP_KERNEL);
+		ops->cit_iv = kmalloc(ops->cit_ivsize, GFP_KERNEL);
 		if (ops->cit_iv == NULL)
 			ret = -ENOMEM;
 	}
@@ -290,6 +290,24 @@
 	return ret;
 }
 
+int crypto_copy_cipher_ops(struct crypto_tfm *tfm)
+{
+	struct cipher_tfm *ops = &tfm->crt_cipher;
+
+	if (tfm->crt_cipher.cit_iv) {
+		void *new_cit_iv;
+
+		new_cit_iv = kmalloc(ops->cit_ivsize, GFP_KERNEL);
+		if (new_cit_iv == NULL)
+			return -ENOMEM;
+
+		memcpy(new_cit_iv, ops->cit_iv, ops->cit_ivsize);
+		ops->cit_iv = new_cit_iv;
+	}
+
+	return 0;
+}
+
 void crypto_exit_cipher_ops(struct crypto_tfm *tfm)
 {
 	if (tfm->crt_cipher.cit_iv)
diff -Nur linux.orig/crypto/compress.c linux/crypto/compress.c
--- linux.orig/crypto/compress.c	2004-02-27 19:25:58.514315568 +0100
+++ linux/crypto/compress.c	2004-02-27 19:26:44.457331168 +0100
@@ -57,6 +57,11 @@
 	return ret;
 }
 
+int crypto_copy_compress_ops(struct crypto_tfm *tfm)
+{
+	return tfm->__crt_alg->cra_compress.coa_copy(crypto_tfm_ctx(tfm));
+}
+
 void crypto_exit_compress_ops(struct crypto_tfm *tfm)
 {
 	tfm->__crt_alg->cra_compress.coa_exit(crypto_tfm_ctx(tfm));
diff -Nur linux.orig/crypto/deflate.c linux/crypto/deflate.c
--- linux.orig/crypto/deflate.c	2004-02-27 19:25:58.515315416 +0100
+++ linux/crypto/deflate.c	2004-02-27 19:26:44.458331016 +0100
@@ -55,6 +55,40 @@
 	return 0;
 }
 
+static int deflate_copy(void *ctx)
+{
+	struct deflate_ctx *dctx = ctx;
+	struct z_stream_s *stream = &dctx->comp_stream;
+	unsigned int size;
+	void *new_workspace;
+
+	if (dctx->comp_initialized) {
+		new_workspace = __vmalloc(size = zlib_deflate_workspacesize(),
+		                          deflate_gfp()|__GFP_HIGHMEM,
+		                          PAGE_KERNEL);
+		if (!new_workspace)
+			return -ENOMEM;
+
+		memcpy(new_workspace, stream->workspace, size);
+		stream->workspace = new_workspace;
+	}
+	if (dctx->decomp_initialized) {
+		new_workspace = kmalloc(size = zlib_inflate_workspacesize(),
+		                        deflate_gfp());
+		if (!new_workspace) {
+			if (dctx->comp_initialized)
+				vfree(stream->workspace);
+
+			return -ENOMEM;
+		}
+
+		memcpy(new_workspace, stream->workspace, size);
+		stream->workspace = new_workspace;
+	}
+
+	return 0;
+}
+
 static void deflate_exit(void *ctx)
 {
 	struct deflate_ctx *dctx = ctx;
@@ -77,7 +111,7 @@
 	stream->workspace = __vmalloc(zlib_deflate_workspacesize(),
 	                              deflate_gfp()|__GFP_HIGHMEM,
 	                              PAGE_KERNEL);
-	if (!stream->workspace ) {
+	if (!stream->workspace) {
 		ret = -ENOMEM;
 		goto out;
 	}
@@ -212,6 +246,7 @@
 	.cra_list		= LIST_HEAD_INIT(alg.cra_list),
 	.cra_u			= { .compress = {
 	.coa_init		= deflate_init,
+	.coa_copy		= deflate_copy,
 	.coa_exit		= deflate_exit,
 	.coa_compress 		= deflate_compress,
 	.coa_decompress  	= deflate_decompress } }
diff -Nur linux.orig/crypto/digest.c linux/crypto/digest.c
--- linux.orig/crypto/digest.c	2004-02-27 19:25:58.517315112 +0100
+++ linux/crypto/digest.c	2004-02-27 19:26:44.459330864 +0100
@@ -76,6 +76,11 @@
 	return crypto_alloc_hmac_block(tfm);
 }
 
+int crypto_copy_digest_ops(struct crypto_tfm *tfm)
+{
+	return crypto_clone_hmac_block(tfm);
+}
+
 void crypto_exit_digest_ops(struct crypto_tfm *tfm)
 {
 	crypto_free_hmac_block(tfm);
diff -Nur linux.orig/crypto/hmac.c linux/crypto/hmac.c
--- linux.orig/crypto/hmac.c	2004-02-27 19:25:58.517315112 +0100
+++ linux/crypto/hmac.c	2004-02-27 19:26:44.459330864 +0100
@@ -44,7 +44,24 @@
 		ret = -ENOMEM;
 
 	return ret;
-		
+}
+
+int crypto_clone_hmac_block(struct crypto_tfm *tfm)
+{
+	void *new_hmac_block;
+	int ret = 0;
+
+	BUG_ON(!crypto_tfm_alg_blocksize(tfm));
+
+	new_hmac_block = kmalloc(crypto_tfm_alg_blocksize(tfm), GFP_KERNEL);
+	if (new_hmac_block != NULL) {
+		memcpy(new_hmac_block, tfm->crt_digest.dit_hmac_block,
+		       crypto_tfm_alg_blocksize(tfm));
+		tfm->crt_digest.dit_hmac_block = new_hmac_block;
+	} else
+		ret = -ENOMEM;
+
+	return ret;
 }
 
 void crypto_free_hmac_block(struct crypto_tfm *tfm)
diff -Nur linux.orig/crypto/internal.h linux/crypto/internal.h
--- linux.orig/crypto/internal.h	2004-02-27 19:25:58.518314960 +0100
+++ linux/crypto/internal.h	2004-02-27 19:26:44.459330864 +0100
@@ -59,6 +59,7 @@
 
 #ifdef CONFIG_CRYPTO_HMAC
 int crypto_alloc_hmac_block(struct crypto_tfm *tfm);
+int crypto_copy_hmac_block(struct crypto_tfm *tfm);
 void crypto_free_hmac_block(struct crypto_tfm *tfm);
 #else
 static inline int crypto_alloc_hmac_block(struct crypto_tfm *tfm)
@@ -85,6 +86,10 @@
 int crypto_init_cipher_ops(struct crypto_tfm *tfm);
 int crypto_init_compress_ops(struct crypto_tfm *tfm);
 
+int crypto_copy_digest_ops(struct crypto_tfm *tfm);
+int crypto_copy_cipher_ops(struct crypto_tfm *tfm);
+int crypto_copy_compress_ops(struct crypto_tfm *tfm);
+
 void crypto_exit_digest_ops(struct crypto_tfm *tfm);
 void crypto_exit_cipher_ops(struct crypto_tfm *tfm);
 void crypto_exit_compress_ops(struct crypto_tfm *tfm);
diff -Nur linux.orig/include/linux/crypto.h linux/include/linux/crypto.h
--- linux.orig/include/linux/crypto.h	2004-02-27 19:25:51.934315880 +0100
+++ linux/include/linux/crypto.h	2004-02-27 19:26:32.639127808 +0100
@@ -80,6 +80,7 @@
 
 struct compress_alg {
 	int (*coa_init)(void *ctx);
+	int (*coa_copy)(void *ctx);
 	void (*coa_exit)(void *ctx);
 	int (*coa_compress)(void *ctx, const u8 *src, unsigned int slen,
 	                    u8 *dst, unsigned int *dlen);
@@ -191,7 +192,13 @@
 /* 
  * Transform user interface.
  */
- 
+
+#define crypto_alg_tfm_size(alg)	(sizeof(struct crypto_tfm) + \
+					(alg)->cra_ctxsize)
+#define crypto_tfm_size(tfm)		crypto_alg_tfm_size((tfm)->__crt_alg)
+
+unsigned int crypto_lookup_alg_tfm_size(const char *alg_name, u32 tfm_flags);
+
 /*
  * crypto_alloc_tfm() will first attempt to locate an already loaded algorithm.
  * If that fails and the kernel supports dynamically loadable modules, it
@@ -200,10 +207,20 @@
  *
  * crypto_free_tfm() frees up the transform and any associated resources,
  * then drops the refcount on the associated algorithm.
+ *
+ * crypto_init_tfm() and crypto_exit_tfm() do the same except that the user
+ * has to do the memory allocation.
  */
+int crypto_init_tfm(struct crypto_tfm *tfm, const char *alg_name,
+                    u32 tfm_flags);
 struct crypto_tfm *crypto_alloc_tfm(const char *alg_name, u32 tfm_flags);
+
+void crypto_exit_tfm(struct crypto_tfm *tfm);
 void crypto_free_tfm(struct crypto_tfm *tfm);
 
+int crypto_copy_tfm(struct crypto_tfm *dst_tfm, struct crypto_tfm *src_tfm);
+struct crypto_tfm *crypto_clone_tfm(struct crypto_tfm *orig_tfm);
+
 /*
  * Transform helpers which query the underlying algorithm.
  */

  reply	other threads:[~2004-02-27 18:47 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-02-19 17:02 Christophe Saout
2004-02-19 19:18 ` Andrew Morton
2004-02-20 17:14   ` Jean-Luc Cooke
2004-02-20 18:53     ` Christophe Saout
2004-02-20 19:09       ` Jean-Luc Cooke
2004-02-20 19:23         ` Christophe Saout
2004-02-20 21:23         ` James Morris
2004-02-20 22:40       ` Christophe Saout
2004-02-21  0:07         ` James Morris
2004-02-21  2:17     ` Christophe Saout
2004-02-24 19:11       ` Matt Mackall
2004-02-24 19:43         ` Christophe Saout
2004-02-24 20:38           ` Matt Mackall
2004-02-25 21:43             ` Matt Mackall
2004-02-26 19:35               ` Christophe Saout
2004-02-26 20:02                 ` Matt Mackall
2004-02-27 16:05                   ` Christophe Saout
2004-02-27 18:37                     ` Christophe Saout [this message]
2004-02-27 20:02                     ` Matt Mackall
2004-02-27 20:13                       ` Christophe Saout
2004-02-27 20:55                         ` Matt Mackall
2004-02-27 21:16                           ` Christophe Saout
2004-02-28  0:39                             ` Matt Mackall
2004-02-28 13:02                               ` Christophe Saout
2004-02-24 22:26           ` James Morris
2004-02-24 22:31             ` Christophe Saout
2004-02-24 22:45               ` James Morris
2004-02-24 20:01         ` James Morris
2004-02-24 20:24           ` Matt Mackall
2004-02-25  2:25         ` Christophe Saout
2004-02-25  3:05           ` Jean-Luc Cooke
2004-02-23  0:35 ` Fruhwirth Clemens
2004-02-23 13:44   ` Jean-Luc Cooke
2004-02-23 15:36     ` James Morris
     [not found] <20040223214738.GD24799@certainkey.com>
     [not found] ` <Xine.LNX.4.44.0402231710390.21142-100000@thoron.boston.redhat.com>
2004-02-24 20:22   ` Jean-Luc Cooke
2004-02-24 22:17     ` James Morris
2004-02-24 22:44       ` Jean-Luc Cooke
2004-02-25 13:52         ` James Morris
2004-02-25 15:11           ` Jean-Luc Cooke

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20040227183718.GA1880@leto.cs.pocnet.net \
    --to=christophe@saout.de \
    --cc=jlcooke@certainkey.com \
    --cc=jmorris@intercode.com.au \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mpm@selenic.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®