Module Name:    src
Committed By:   drochner
Date:           Thu Feb 24 20:03:41 UTC 2011

Modified Files:
        src/sys/netipsec: xform_ipcomp.c
        src/sys/opencrypto: cryptodev.h cryptosoft.c cryptosoft_xform.c
            deflate.c deflate.h xform.c xform.h

Log Message:
small modifications in dealing with the unknown result size of compression/
decompression:
-seperate the IPCOMP specific rule that compression must not grow the
 data from general compression semantics: Introduce a special name
 CRYPTO_DEFLATE_COMP_NOGROW/comp_algo_deflate_nogrow to describe
 the IPCOMP semantics and use it there. (being here, fix the check
 so that equal size is considered failure as well as required by
 RFC2393)
 Customers of CRYPTO_DEFLATE_COMP/comp_algo_deflate now always get
 deflated data back, even if they are not smaller than the original.
-allow to pass a "size hint" to the DEFLATE decompression function
 which is used for the initial buffer allocation. Due to the changes
 done there, additional allocations and extra copies are avoided if the
 initial allocation is sufficient. Set the size hint to MCLBYTES (=2k)
 in IPCOMP which should be good for many use cases.


To generate a diff of this commit:
cvs rdiff -u -r1.24 -r1.25 src/sys/netipsec/xform_ipcomp.c
cvs rdiff -u -r1.17 -r1.18 src/sys/opencrypto/cryptodev.h
cvs rdiff -u -r1.27 -r1.28 src/sys/opencrypto/cryptosoft.c
cvs rdiff -u -r1.13 -r1.14 src/sys/opencrypto/cryptosoft_xform.c
cvs rdiff -u -r1.18 -r1.19 src/sys/opencrypto/deflate.c \
    src/sys/opencrypto/xform.c
cvs rdiff -u -r1.7 -r1.8 src/sys/opencrypto/deflate.h
cvs rdiff -u -r1.10 -r1.11 src/sys/opencrypto/xform.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/netipsec/xform_ipcomp.c
diff -u src/sys/netipsec/xform_ipcomp.c:1.24 src/sys/netipsec/xform_ipcomp.c:1.25
--- src/sys/netipsec/xform_ipcomp.c:1.24	Fri Feb 18 20:40:58 2011
+++ src/sys/netipsec/xform_ipcomp.c	Thu Feb 24 20:03:41 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: xform_ipcomp.c,v 1.24 2011/02/18 20:40:58 drochner Exp $	*/
+/*	$NetBSD: xform_ipcomp.c,v 1.25 2011/02/24 20:03:41 drochner Exp $	*/
 /*	$FreeBSD: src/sys/netipsec/xform_ipcomp.c,v 1.1.4.1 2003/01/24 05:11:36 sam Exp $	*/
 /* $OpenBSD: ip_ipcomp.c,v 1.1 2001/07/05 12:08:52 jjbg Exp $ */
 
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xform_ipcomp.c,v 1.24 2011/02/18 20:40:58 drochner Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xform_ipcomp.c,v 1.25 2011/02/24 20:03:41 drochner Exp $");
 
 /* IP payload compression protocol (IPComp), see RFC 2393 */
 #include "opt_inet.h"
@@ -96,7 +96,7 @@
 		return NULL;
 	switch (alg) {
 	case SADB_X_CALG_DEFLATE:
-		return &comp_algo_deflate;
+		return &comp_algo_deflate_nogrow;
 	}
 	return NULL;
 }
@@ -190,6 +190,7 @@
 
 	/* Crypto operation descriptor */
 	crp->crp_ilen = m->m_pkthdr.len - (skip + hlen);
+	crp->crp_olen = MCLBYTES; /* hint to decompression code */
 	crp->crp_flags = CRYPTO_F_IMBUF;
 	crp->crp_buf = m;
 	crp->crp_callback = ipcomp_input_cb;

Index: src/sys/opencrypto/cryptodev.h
diff -u src/sys/opencrypto/cryptodev.h:1.17 src/sys/opencrypto/cryptodev.h:1.18
--- src/sys/opencrypto/cryptodev.h:1.17	Fri Sep  4 08:58:44 2009
+++ src/sys/opencrypto/cryptodev.h	Thu Feb 24 20:03:41 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: cryptodev.h,v 1.17 2009/09/04 08:58:44 he Exp $ */
+/*	$NetBSD: cryptodev.h,v 1.18 2011/02/24 20:03:41 drochner Exp $ */
 /*	$FreeBSD: src/sys/opencrypto/cryptodev.h,v 1.2.2.6 2003/07/02 17:04:50 sam Exp $	*/
 /*	$OpenBSD: cryptodev.h,v 1.33 2002/07/17 23:52:39 art Exp $	*/
 
@@ -132,8 +132,9 @@
 #define CRYPTO_MD5_HMAC_96	19 
 #define CRYPTO_SHA1_HMAC_96	20
 #define CRYPTO_RIPEMD160_HMAC_96	21
-#define CRYPTO_GZIP_COMP	22 /* Deflate compression algorithm */
-#define CRYPTO_ALGORITHM_MAX	23 /* Keep updated - see below */
+#define CRYPTO_GZIP_COMP	22 /* gzip compression algorithm */
+#define CRYPTO_DEFLATE_COMP_NOGROW 23 /* Deflate, fail if not compressible */
+#define CRYPTO_ALGORITHM_MAX	24 /* Keep updated - see below */
 
 /* Algorithm flags */
 #define	CRYPTO_ALG_FLAG_SUPPORTED	0x01 /* Algorithm is supported */

Index: src/sys/opencrypto/cryptosoft.c
diff -u src/sys/opencrypto/cryptosoft.c:1.27 src/sys/opencrypto/cryptosoft.c:1.28
--- src/sys/opencrypto/cryptosoft.c:1.27	Thu Feb 10 21:00:42 2011
+++ src/sys/opencrypto/cryptosoft.c	Thu Feb 24 20:03:41 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: cryptosoft.c,v 1.27 2011/02/10 21:00:42 drochner Exp $ */
+/*	$NetBSD: cryptosoft.c,v 1.28 2011/02/24 20:03:41 drochner Exp $ */
 /*	$FreeBSD: src/sys/opencrypto/cryptosoft.c,v 1.2.2.1 2002/11/21 23:34:23 sam Exp $	*/
 /*	$OpenBSD: cryptosoft.c,v 1.35 2002/04/26 08:43:50 deraadt Exp $	*/
 
@@ -24,7 +24,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.27 2011/02/10 21:00:42 drochner Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.28 2011/02/24 20:03:41 drochner Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -535,7 +535,8 @@
 	if (crd->crd_flags & CRD_F_COMP)
 		result = cxf->compress(data, crd->crd_len, &out);
 	else
-		result = cxf->decompress(data, crd->crd_len, &out);
+		result = cxf->decompress(data, crd->crd_len, &out,
+					 *res_size);
 
 	free(data, M_CRYPTO_DATA);
 	if (result == 0)
@@ -546,12 +547,12 @@
 	 */
 	*res_size = (int)result;
 	/* Check the compressed size when doing compression */
-	if (crd->crd_flags & CRD_F_COMP) {
-		if (result > crd->crd_len) {
+	if (crd->crd_flags & CRD_F_COMP &&
+	    sw->sw_alg == CRYPTO_DEFLATE_COMP_NOGROW &&
+	    result >= crd->crd_len) {
 			/* Compression was useless, we lost time */
 			free(out, M_CRYPTO_DATA);
 			return 0;
-		}
 	}
 
 	COPYBACK(outtype, buf, crd->crd_skip, result, out);
@@ -788,6 +789,11 @@
 			(*swd)->sw_cxf = cxf;
 			break;
 
+		case CRYPTO_DEFLATE_COMP_NOGROW:
+			cxf = &swcr_comp_algo_deflate_nogrow;
+			(*swd)->sw_cxf = cxf;
+			break;
+
 		case CRYPTO_GZIP_COMP:
 			cxf = &swcr_comp_algo_gzip;
 			(*swd)->sw_cxf = cxf;
@@ -884,6 +890,7 @@
 			break;
 
 		case CRYPTO_DEFLATE_COMP:
+		case CRYPTO_DEFLATE_COMP_NOGROW:
 		case CRYPTO_GZIP_COMP:
 			cxf = swd->sw_cxf;
 			break;
@@ -983,6 +990,7 @@
 			break;
 
 		case CRYPTO_DEFLATE_COMP:
+		case CRYPTO_DEFLATE_COMP_NOGROW:
 		case CRYPTO_GZIP_COMP:
 			DPRINTF(("swcr_process: compdec for %d\n", sw->sw_alg));
 			if ((crp->crp_etype = swcr_compdec(crd, sw,
@@ -1036,6 +1044,7 @@
 	REGISTER(CRYPTO_SHA1);
 	REGISTER(CRYPTO_RIJNDAEL128_CBC);
 	REGISTER(CRYPTO_DEFLATE_COMP);
+	REGISTER(CRYPTO_DEFLATE_COMP_NOGROW);
 	REGISTER(CRYPTO_GZIP_COMP);
 #undef REGISTER
 }

Index: src/sys/opencrypto/cryptosoft_xform.c
diff -u src/sys/opencrypto/cryptosoft_xform.c:1.13 src/sys/opencrypto/cryptosoft_xform.c:1.14
--- src/sys/opencrypto/cryptosoft_xform.c:1.13	Fri Feb 18 19:56:02 2011
+++ src/sys/opencrypto/cryptosoft_xform.c	Thu Feb 24 20:03:41 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: cryptosoft_xform.c,v 1.13 2011/02/18 19:56:02 drochner Exp $ */
+/*	$NetBSD: cryptosoft_xform.c,v 1.14 2011/02/24 20:03:41 drochner Exp $ */
 /*	$FreeBSD: src/sys/opencrypto/xform.c,v 1.1.2.1 2002/11/21 23:34:23 sam Exp $	*/
 /*	$OpenBSD: xform.c,v 1.19 2002/08/16 22:47:25 dhartmei Exp $	*/
 
@@ -40,7 +40,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: cryptosoft_xform.c,v 1.13 2011/02/18 19:56:02 drochner Exp $");
+__KERNEL_RCSID(1, "$NetBSD: cryptosoft_xform.c,v 1.14 2011/02/24 20:03:41 drochner Exp $");
 
 #include <crypto/blowfish/blowfish.h>
 #include <crypto/cast128/cast128.h>
@@ -70,9 +70,9 @@
 };
 
 struct swcr_comp_algo {
-	const struct comp_algo *comp_algo;
+	const struct comp_algo *unused_comp_algo;
 	uint32_t (*compress)(uint8_t *, uint32_t, uint8_t **);
-	uint32_t (*decompress)(uint8_t *, uint32_t, uint8_t **);
+	uint32_t (*decompress)(uint8_t *, uint32_t, uint8_t **, int);
 };
 
 static void null_encrypt(void *, u_int8_t *);
@@ -124,9 +124,9 @@
 static	int SHA512Update_int(void *, const u_int8_t *, u_int16_t);
 
 static u_int32_t deflate_compress(u_int8_t *, u_int32_t, u_int8_t **);
-static u_int32_t deflate_decompress(u_int8_t *, u_int32_t, u_int8_t **);
+static u_int32_t deflate_decompress(u_int8_t *, u_int32_t, u_int8_t **, int);
 static u_int32_t gzip_compress(u_int8_t *, u_int32_t, u_int8_t **);
-static u_int32_t gzip_decompress(u_int8_t *, u_int32_t, u_int8_t **);
+static u_int32_t gzip_decompress(u_int8_t *, u_int32_t, u_int8_t **, int);
 
 /* Encryption instances */
 static const struct swcr_enc_xform swcr_enc_xform_null = {
@@ -280,6 +280,12 @@
 	deflate_decompress
 };
 
+static const struct swcr_comp_algo swcr_comp_algo_deflate_nogrow = {
+	&comp_algo_deflate_nogrow,
+	deflate_compress,
+	deflate_decompress
+};
+
 static const struct swcr_comp_algo swcr_comp_algo_gzip = {
 	&comp_algo_deflate,
 	gzip_compress,
@@ -638,23 +644,25 @@
 static u_int32_t
 deflate_compress(u_int8_t *data, u_int32_t size, u_int8_t **out)
 {
-	return deflate_global(data, size, 0, out);
+	return deflate_global(data, size, 0, out, 0);
 }
 
 static u_int32_t
-deflate_decompress(u_int8_t *data, u_int32_t size, u_int8_t **out)
+deflate_decompress(u_int8_t *data, u_int32_t size, u_int8_t **out,
+		   int size_hint)
 {
-	return deflate_global(data, size, 1, out);
+	return deflate_global(data, size, 1, out, size_hint);
 }
 
 static u_int32_t
 gzip_compress(u_int8_t *data, u_int32_t size, u_int8_t **out)
 {
-	return gzip_global(data, size, 0, out);
+	return gzip_global(data, size, 0, out, 0);
 }
 
 static u_int32_t
-gzip_decompress(u_int8_t *data, u_int32_t size, u_int8_t **out)
+gzip_decompress(u_int8_t *data, u_int32_t size, u_int8_t **out,
+		int size_hint)
 {
-	return gzip_global(data, size, 1, out);
+	return gzip_global(data, size, 1, out, size_hint);
 }

Index: src/sys/opencrypto/deflate.c
diff -u src/sys/opencrypto/deflate.c:1.18 src/sys/opencrypto/deflate.c:1.19
--- src/sys/opencrypto/deflate.c:1.18	Fri Feb 18 22:02:09 2011
+++ src/sys/opencrypto/deflate.c	Thu Feb 24 20:03:41 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: deflate.c,v 1.18 2011/02/18 22:02:09 drochner Exp $ */
+/*	$NetBSD: deflate.c,v 1.19 2011/02/24 20:03:41 drochner Exp $ */
 /*	$FreeBSD: src/sys/opencrypto/deflate.c,v 1.1.2.1 2002/11/21 23:34:23 sam Exp $	*/
 /* $OpenBSD: deflate.c,v 1.3 2001/08/20 02:45:22 hugh Exp $ */
 
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: deflate.c,v 1.18 2011/02/18 22:02:09 drochner Exp $");
+__KERNEL_RCSID(0, "$NetBSD: deflate.c,v 1.19 2011/02/24 20:03:41 drochner Exp $");
 
 #include <sys/types.h>
 #include <sys/malloc.h>
@@ -71,7 +71,8 @@
 }
 
 u_int32_t
-deflate_global(u_int8_t *data, u_int32_t size, int decomp, u_int8_t **out)
+deflate_global(u_int8_t *data, u_int32_t size, int decomp, u_int8_t **out,
+	       int size_hint)
 {
 	/* decomp indicates whether we compress (0) or decompress (1) */
 
@@ -100,7 +101,7 @@
 	 	 * updated while the decompression is going on
 	 	 */
 
-		buf[0].size = size * 4;
+		buf[0].size = MAX(size * 4, size_hint);
 	}
 	buf[0].out = malloc(buf[0].size, M_CRYPTO_DATA, M_NOWAIT);
 	if (buf[0].out == NULL)
@@ -218,7 +219,7 @@
 
 u_int32_t
 gzip_global(u_int8_t *data, u_int32_t size,
-	int decomp, u_int8_t **out)
+	int decomp, u_int8_t **out, int size_hint)
 {
 	/* decomp indicates whether we compress (0) or decompress (1) */
 	z_stream zbuf;
Index: src/sys/opencrypto/xform.c
diff -u src/sys/opencrypto/xform.c:1.18 src/sys/opencrypto/xform.c:1.19
--- src/sys/opencrypto/xform.c:1.18	Wed Mar 25 01:26:13 2009
+++ src/sys/opencrypto/xform.c	Thu Feb 24 20:03:41 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: xform.c,v 1.18 2009/03/25 01:26:13 darran Exp $ */
+/*	$NetBSD: xform.c,v 1.19 2011/02/24 20:03:41 drochner Exp $ */
 /*	$FreeBSD: src/sys/opencrypto/xform.c,v 1.1.2.1 2002/11/21 23:34:23 sam Exp $	*/
 /*	$OpenBSD: xform.c,v 1.19 2002/08/16 22:47:25 dhartmei Exp $	*/
 
@@ -40,7 +40,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xform.c,v 1.18 2009/03/25 01:26:13 darran Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xform.c,v 1.19 2011/02/24 20:03:41 drochner Exp $");
 
 #include <sys/param.h>
 #include <sys/malloc.h>
@@ -191,6 +191,11 @@
 	90
 };
 
+struct comp_algo comp_algo_deflate_nogrow = {
+	CRYPTO_DEFLATE_COMP_NOGROW, "Deflate",
+	90
+};
+
 struct comp_algo comp_algo_gzip = {
 	CRYPTO_GZIP_COMP, "GZIP",
 	90

Index: src/sys/opencrypto/deflate.h
diff -u src/sys/opencrypto/deflate.h:1.7 src/sys/opencrypto/deflate.h:1.8
--- src/sys/opencrypto/deflate.h:1.7	Wed Feb 16 19:08:58 2011
+++ src/sys/opencrypto/deflate.h	Thu Feb 24 20:03:41 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: deflate.h,v 1.7 2011/02/16 19:08:58 drochner Exp $ */
+/*	$NetBSD: deflate.h,v 1.8 2011/02/24 20:03:41 drochner Exp $ */
 /*	$FreeBSD: src/sys/opencrypto/deflate.h,v 1.1.2.1 2002/11/21 23:34:23 sam Exp $	*/
 /* $OpenBSD: deflate.h,v 1.3 2002/03/14 01:26:51 millert Exp $ */
 
@@ -44,8 +44,8 @@
 #define MINCOMP		2	/* won't be used, but must be defined */
 #define ZBUF		10
 
-u_int32_t deflate_global(u_int8_t *, u_int32_t, int, u_int8_t **);
-u_int32_t gzip_global(u_int8_t *, u_int32_t, int, u_int8_t **);
+u_int32_t deflate_global(u_int8_t *, u_int32_t, int, u_int8_t **, int);
+u_int32_t gzip_global(u_int8_t *, u_int32_t, int, u_int8_t **, int);
 void *z_alloc(void *, u_int, u_int);
 void z_free(void *, void *);
 

Index: src/sys/opencrypto/xform.h
diff -u src/sys/opencrypto/xform.h:1.10 src/sys/opencrypto/xform.h:1.11
--- src/sys/opencrypto/xform.h:1.10	Wed Mar 25 01:26:13 2009
+++ src/sys/opencrypto/xform.h	Thu Feb 24 20:03:41 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: xform.h,v 1.10 2009/03/25 01:26:13 darran Exp $ */
+/*	$NetBSD: xform.h,v 1.11 2011/02/24 20:03:41 drochner Exp $ */
 /*	$FreeBSD: src/sys/opencrypto/xform.h,v 1.1.2.1 2002/11/21 23:34:23 sam Exp $	*/
 /*	$OpenBSD: xform.h,v 1.10 2002/04/22 23:10:09 deraadt Exp $	*/
 
@@ -85,6 +85,7 @@
 extern struct auth_hash auth_hash_hmac_sha2_512;
 
 extern struct comp_algo comp_algo_deflate;
+extern struct comp_algo comp_algo_deflate_nogrow;
 extern struct comp_algo comp_algo_gzip;
 
 #ifdef _KERNEL

Reply via email to