Re: [PATCH] crypto: compress - Add pcomp interface

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



	Hi Herbert,

On Thu, 19 Feb 2009, Herbert Xu wrote:
> On Thu, Feb 19, 2009 at 10:12:18AM +0100, Geert Uytterhoeven wrote:
> > IIUC, my setup() routines should decode the parameters using nla_parse()?
> 
> Right.
> 
> > And the caller of a setup() routine should encode the data. But how? All the
> > nla_put*() routines seem to be targeted at skb's.
> 
> The callers in the kernel should just lay it out on the stack, e.g.,
> 
> 	struct {
> 		struct nlattr foo;
> 		u32 foo_val;
> 		struct nlattr bar;
> 		u32 bar_val;
> 		...
> 	};
> 
> Note that the netlink alignment is 4 so u32 doesn't need any padding
> though u8/u16 would need padding before the next nlattr.  Although
> for our purposes u32 should be sufficient.
> 
> > The only place where nla_parse() is called with a void */length pair is
> > net/sched/em_meta.c:em_meta_change(). But I can find no place where the actual
> > TCA_EM_META_* fields are encoded.
> 
> For simple things like u32 the format is just header followed by
> the u32.  See nla_get_u32 for details.

Is the below (on top of my last patch series) what you have in mind?

Notes:
  - I had to drop the `const' from the `params' pointers of
    pcomp_alg.{,de}compress_setup().
    Trying to make nla_parse() take const nlattr structures instead seems to
    open a big can of worms...
  - I should add a dependency of CONFIG_CRYPTO_ZLIB on CONFIG_NET (due to the
    need for nla_parse()). However, I don't like that.

Thanks for your comments!

diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index 4703137..b50c3c6 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -919,7 +919,8 @@ static int test_pcomp(struct crypto_pcomp *tfm,
 	for (i = 0; i < ctcount; i++) {
 		struct comp_request req;
 
-		error = crypto_compress_setup(tfm, ctemplate[i].params);
+		error = crypto_compress_setup(tfm, ctemplate[i].params,
+					      ctemplate[i].paramsize);
 		if (error) {
 			pr_err("alg: pcomp: compression setup failed on test "
 			       "%d for %s: error=%d\n", i + 1, algo, error);
@@ -986,7 +987,8 @@ static int test_pcomp(struct crypto_pcomp *tfm,
 	for (i = 0; i < dtcount; i++) {
 		struct comp_request req;
 
-		error = crypto_decompress_setup(tfm, dtemplate[i].params);
+		error = crypto_decompress_setup(tfm, dtemplate[i].params,
+						dtemplate[i].paramsize);
 		if (error) {
 			pr_err("alg: pcomp: decompression setup failed on "
 			       "test %d for %s: error=%d\n", i + 1, algo,
diff --git a/crypto/testmgr.h b/crypto/testmgr.h
index 098c033..526f00a 100644
--- a/crypto/testmgr.h
+++ b/crypto/testmgr.h
@@ -15,7 +15,9 @@
 #ifndef _CRYPTO_TESTMGR_H
 #define _CRYPTO_TESTMGR_H
 
+#include <linux/netlink.h>
 #include <linux/zlib.h>
+
 #include <crypto/compress.h>
 
 #define MAX_DIGEST_SIZE		64
@@ -8351,7 +8353,8 @@ struct comp_testvec {
 };
 
 struct pcomp_testvec {
-	const void *params;
+	void *params;
+	unsigned int paramsize;
 	int inlen, outlen;
 	char input[COMP_BUF_SIZE];
 	char output[COMP_BUF_SIZE];
@@ -8440,21 +8443,60 @@ static struct comp_testvec deflate_decomp_tv_template[] = {
 #define ZLIB_COMP_TEST_VECTORS 2
 #define ZLIB_DECOMP_TEST_VECTORS 2
 
-static const struct zlib_comp_params deflate_comp_params = {
-	.level			= Z_DEFAULT_COMPRESSION,
-	.method			= Z_DEFLATED,
-	.windowBits		= -11,
-	.memLevel		= MAX_MEM_LEVEL,
-	.strategy		= Z_DEFAULT_STRATEGY
+static const struct {
+	struct nlattr nla;
+	int val;
+} deflate_comp_params[] = {
+	{
+		.nla = {
+			.nla_len	= NLA_HDRLEN + sizeof(int),
+			.nla_type	= ZLIB_COMP_LEVEL,
+		},
+		.val			= Z_DEFAULT_COMPRESSION,
+	}, {
+		.nla = {
+			.nla_len	= NLA_HDRLEN + sizeof(int),
+			.nla_type	= ZLIB_COMP_METHOD,
+		},
+		.val			= Z_DEFLATED,
+	}, {
+		.nla = {
+			.nla_len	= NLA_HDRLEN + sizeof(int),
+			.nla_type	= ZLIB_COMP_WINDOWBITS,
+		},
+		.val			= -11,
+	}, {
+		.nla = {
+			.nla_len	= NLA_HDRLEN + sizeof(int),
+			.nla_type	= ZLIB_COMP_MEMLEVEL,
+		},
+		.val			= MAX_MEM_LEVEL,
+	}, {
+		.nla = {
+			.nla_len	= NLA_HDRLEN + sizeof(int),
+			.nla_type	= ZLIB_COMP_STRATEGY,
+		},
+		.val			= Z_DEFAULT_STRATEGY,
+	}
 };
 
-static const struct zlib_decomp_params deflate_decomp_params = {
-	.windowBits		= -11,
+static const struct {
+	struct nlattr nla;
+	int val;
+} deflate_decomp_params[] = {
+	{
+		.nla = {
+			.nla_len	= NLA_HDRLEN + sizeof(int),
+			.nla_type	= ZLIB_DECOMP_WINDOWBITS,
+		},
+		.val			= -11,
+	}
 };
 
 static struct pcomp_testvec zlib_comp_tv_template[] = {
 	{
 		.params = &deflate_comp_params,
+		.paramsize = sizeof(deflate_comp_params),
 		.inlen	= 70,
 		.outlen	= 38,
 		.input	= "Join us now and share the software "
@@ -8466,6 +8508,7 @@ static struct pcomp_testvec zlib_comp_tv_template[] = {
 			  "\x71\xbc\x08\x2b\x01\x00",
 	}, {
 		.params = &deflate_comp_params,
+		.paramsize = sizeof(deflate_comp_params),
 		.inlen	= 191,
 		.outlen	= 122,
 		.input	= "This document describes a compression method based on the DEFLATE"
@@ -8493,6 +8536,7 @@ static struct pcomp_testvec zlib_comp_tv_template[] = {
 static struct pcomp_testvec zlib_decomp_tv_template[] = {
 	{
 		.params = &deflate_decomp_params,
+		.paramsize = sizeof(deflate_decomp_params),
 		.inlen	= 122,
 		.outlen	= 191,
 		.input	= "\x5d\x8d\x31\x0e\xc2\x30\x10\x04"
@@ -8516,6 +8560,7 @@ static struct pcomp_testvec zlib_decomp_tv_template[] = {
 			"the DEFLATE algorithm to the IP Payload Compression Protocol.",
 	}, {
 		.params = &deflate_decomp_params,
+		.paramsize = sizeof(deflate_decomp_params),
 		.inlen	= 38,
 		.outlen	= 70,
 		.input	= "\xf3\xca\xcf\xcc\x53\x28\x2d\x56"
diff --git a/crypto/zlib.c b/crypto/zlib.c
index 77b865d..33609ba 100644
--- a/crypto/zlib.c
+++ b/crypto/zlib.c
@@ -33,11 +33,13 @@
 
 #include <crypto/internal/compress.h>
 
+#include <net/netlink.h>
+
 
 struct zlib_ctx {
-	struct zlib_decomp_params decomp_params;
 	struct z_stream_s comp_stream;
 	struct z_stream_s decomp_stream;
+	int decomp_windowBits;
 };
 
 
@@ -77,13 +79,18 @@ static void zlib_exit(struct crypto_tfm *tfm)
 }
 
 
-static int zlib_compress_setup(struct crypto_pcomp *tfm, const void *params)
+static int zlib_compress_setup(struct crypto_pcomp *tfm, void *params,
+			       unsigned int len)
 {
 	struct zlib_ctx *ctx = crypto_tfm_ctx(crypto_pcomp_tfm(tfm));
-	const struct zlib_comp_params *zparams = params;
 	struct z_stream_s *stream = &ctx->comp_stream;
+	struct nlattr *tb[ZLIB_COMP_MAX + 1];
 	size_t workspacesize;
-	int ret = 0;
+	int ret;
+
+	ret = nla_parse(tb, ZLIB_COMP_MAX, params, len, NULL);
+	if (ret)
+		return ret;
 
 	zlib_comp_exit(ctx);
 
@@ -93,9 +100,22 @@ static int zlib_compress_setup(struct crypto_pcomp *tfm, const void *params)
 		return -ENOMEM;
 
 	memset(stream->workspace, 0, workspacesize);
-	ret = zlib_deflateInit2(stream, zparams->level, zparams->method,
-				zparams->windowBits, zparams->memLevel,
-				zparams->strategy);
+	ret = zlib_deflateInit2(stream,
+				tb[ZLIB_COMP_LEVEL]
+					? nla_get_u32(tb[ZLIB_COMP_LEVEL])
+					: Z_DEFAULT_COMPRESSION,
+				tb[ZLIB_COMP_METHOD]
+					? nla_get_u32(tb[ZLIB_COMP_METHOD])
+					: Z_DEFLATED,
+				tb[ZLIB_COMP_WINDOWBITS]
+					? nla_get_u32(tb[ZLIB_COMP_WINDOWBITS])
+					: MAX_WBITS,
+				tb[ZLIB_COMP_MEMLEVEL]
+					? nla_get_u32(tb[ZLIB_COMP_MEMLEVEL])
+					: DEF_MEM_LEVEL,
+				tb[ZLIB_COMP_STRATEGY]
+					? nla_get_u32(tb[ZLIB_COMP_STRATEGY])
+					: Z_DEFAULT_STRATEGY);
 	if (ret != Z_OK) {
 		vfree(stream->workspace);
 		stream->workspace = NULL;
@@ -187,22 +207,29 @@ static int zlib_compress_final(struct crypto_pcomp *tfm,
 }
 
 
-static int zlib_decompress_setup(struct crypto_pcomp *tfm, const void *params)
+static int zlib_decompress_setup(struct crypto_pcomp *tfm, void *params,
+				 unsigned int len)
 {
 	struct zlib_ctx *ctx = crypto_tfm_ctx(crypto_pcomp_tfm(tfm));
-	const struct zlib_decomp_params *zparams = params;
 	struct z_stream_s *stream = &ctx->decomp_stream;
+	struct nlattr *tb[ZLIB_DECOMP_MAX + 1];
 	int ret = 0;
 
+	ret = nla_parse(tb, ZLIB_DECOMP_MAX, params, len, NULL);
+	if (ret)
+		return ret;
+
 	zlib_decomp_exit(ctx);
 
-	ctx->decomp_params = *zparams;
+	ctx->decomp_windowBits = tb[ZLIB_DECOMP_WINDOWBITS]
+				 ? nla_get_u32(tb[ZLIB_DECOMP_WINDOWBITS])
+				 : DEF_WBITS;
 
 	stream->workspace = kzalloc(zlib_inflate_workspacesize(), GFP_KERNEL);
 	if (!stream->workspace)
 		return -ENOMEM;
 
-	ret = zlib_inflateInit2(stream, zparams->windowBits);
+	ret = zlib_inflateInit2(stream, ctx->decomp_windowBits);
 	if (ret != Z_OK) {
 		kfree(stream->workspace);
 		stream->workspace = NULL;
@@ -277,7 +304,7 @@ static int zlib_decompress_final(struct crypto_pcomp *tfm,
 	stream->next_out = req->next_out;
 	stream->avail_out = req->avail_out;
 
-	if (dctx->decomp_params.windowBits < 0) {
+	if (dctx->decomp_windowBits < 0) {
 		ret = zlib_inflate(stream, Z_SYNC_FLUSH);
 		/*
 		 * Work around a bug in zlib, which sometimes wants to taste an
diff --git a/fs/squashfs/super.c b/fs/squashfs/super.c
index 12ed86d..62be5ae 100644
--- a/fs/squashfs/super.c
+++ b/fs/squashfs/super.c
@@ -39,6 +39,8 @@
 
 #include <crypto/compress.h>
 
+#include <net/netlink.h>
+
 #include "squashfs_fs.h"
 #include "squashfs_fs_sb.h"
 #include "squashfs_fs_i.h"
@@ -81,7 +83,16 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
 	unsigned short flags;
 	unsigned int fragments;
 	u64 lookup_table_start;
-	struct zlib_decomp_params params = { .windowBits = DEF_WBITS };
+	struct {
+		struct nlattr nla;
+		int val;
+	} params = {
+		.nla = {
+			.nla_len	= nla_attr_size(sizeof(int)),
+			.nla_type	= ZLIB_DECOMP_WINDOWBITS,
+		},
+		.val			= DEF_WBITS,
+	};
 	int err;
 
 	TRACE("Entered squashfs_fill_superblock\n");
@@ -102,7 +113,7 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
 		goto failed_pcomp;
 	}
 
-	err = crypto_decompress_setup(msblk->tfm, &params);
+	err = crypto_decompress_setup(msblk->tfm, &params, sizeof(params));
 	if (err) {
 		ERROR("Failed to set up decompression parameters\n");
 		goto failure;
diff --git a/include/crypto/compress.h b/include/crypto/compress.h
index 67ba57d..86163ef 100644
--- a/include/crypto/compress.h
+++ b/include/crypto/compress.h
@@ -30,30 +30,40 @@ struct comp_request {
 	unsigned int avail_out;		/* bytes available at next_out */
 };
 
-struct zlib_comp_params {
-	int level;			/* e.g. Z_DEFAULT_COMPRESSION */
-	int method;			/* e.g. Z_DEFLATED */
-	int windowBits;			/* e.g. MAX_WBITS */
-	int memLevel;			/* e.g. DEF_MEM_LEVEL */
-	int strategy;			/* e.g. Z_DEFAULT_STRATEGY */
+enum zlib_comp_params {
+	ZLIB_COMP_LEVEL = 1,		/* e.g. Z_DEFAULT_COMPRESSION */
+	ZLIB_COMP_METHOD,		/* e.g. Z_DEFLATED */
+	ZLIB_COMP_WINDOWBITS,		/* e.g. MAX_WBITS */
+	ZLIB_COMP_MEMLEVEL,		/* e.g. DEF_MEM_LEVEL */
+	ZLIB_COMP_STRATEGY,		/* e.g. Z_DEFAULT_STRATEGY */
+	__ZLIB_COMP_MAX,
 };
 
-struct zlib_decomp_params {
-	int windowBits;			/* e.g. DEF_WBITS */
+#define ZLIB_COMP_MAX	(__ZLIB_COMP_MAX - 1)
+
+
+enum zlib_decomp_params {
+	ZLIB_DECOMP_WINDOWBITS = 1,	/* e.g. DEF_WBITS */
+	__ZLIB_DECOMP_MAX,
 };
 
+#define ZLIB_DECOMP_MAX	(__ZLIB_DECOMP_MAX - 1)
+
+
 struct crypto_pcomp {
 	struct crypto_tfm base;
 };
 
 struct pcomp_alg {
-	int (*compress_setup)(struct crypto_pcomp *tfm, const void *params);
+	int (*compress_setup)(struct crypto_pcomp *tfm, void *params,
+			      unsigned int len);
 	int (*compress_init)(struct crypto_pcomp *tfm);
 	int (*compress_update)(struct crypto_pcomp *tfm,
 			       struct comp_request *req);
 	int (*compress_final)(struct crypto_pcomp *tfm,
 			      struct comp_request *req);
-	int (*decompress_setup)(struct crypto_pcomp *tfm, const void *params);
+	int (*decompress_setup)(struct crypto_pcomp *tfm, void *params,
+				unsigned int len);
 	int (*decompress_init)(struct crypto_pcomp *tfm);
 	int (*decompress_update)(struct crypto_pcomp *tfm,
 				 struct comp_request *req);
@@ -87,9 +97,9 @@ static inline struct pcomp_alg *crypto_pcomp_alg(struct crypto_pcomp *tfm)
 }
 
 static inline int crypto_compress_setup(struct crypto_pcomp *tfm,
-					const void *params)
+					void *params, unsigned int len)
 {
-	return crypto_pcomp_alg(tfm)->compress_setup(tfm, params);
+	return crypto_pcomp_alg(tfm)->compress_setup(tfm, params, len);
 }
 
 static inline int crypto_compress_init(struct crypto_pcomp *tfm)
@@ -110,9 +120,9 @@ static inline int crypto_compress_final(struct crypto_pcomp *tfm,
 }
 
 static inline int crypto_decompress_setup(struct crypto_pcomp *tfm,
-					  const void *params)
+					  void *params, unsigned int len)
 {
-	return crypto_pcomp_alg(tfm)->decompress_setup(tfm, params);
+	return crypto_pcomp_alg(tfm)->decompress_setup(tfm, params, len);
 }
 
 static inline int crypto_decompress_init(struct crypto_pcomp *tfm)

With kind regards,

Geert Uytterhoeven
Software Architect

Sony Techsoft Centre Europe
The Corporate Village · Da Vincilaan 7-D1 · B-1935 Zaventem · Belgium

Phone:    +32 (0)2 700 8453
Fax:      +32 (0)2 700 8622
E-mail:   Geert.Uytterhoeven@xxxxxxxxxxx
Internet: http://www.sony-europe.com/

A division of Sony Europe (Belgium) N.V.
VAT BE 0413.825.160 · RPR Brussels
Fortis · BIC GEBABEBB · IBAN BE41293037680010
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Kernel]     [Gnu Classpath]     [Gnu Crypto]     [DM Crypt]     [Netfilter]     [Bugtraq]

  Powered by Linux