1 // SPDX-License-Identifier: GPL-2.0-or-later
5 * Deflate algorithm (RFC 1951), implemented here primarily for use
6 * by IPCOMP (RFC 3173 & RFC 2394).
8 * Copyright (c) 2003 James Morris <jmorris@intercode.com.au>
10 * FIXME: deflate transforms will require up to a total of about 436k of kernel
11 * memory on i386 (390k for compression, the rest for decompression), as the
12 * current zlib kernel code uses a worst case pre-allocation system by default.
13 * This needs to be fixed so that the amount of memory required is properly
14 * related to the winbits and memlevel parameters.
16 * The default winbits of 11 should suit most packets, and it may be something
17 * to configure on a per-tfm basis in the future.
19 * Currently, compression history is not maintained between tfm calls, as
20 * it is not needed for IPCOMP and keeps the code simpler. It can be
21 * implemented if someone wants it.
23 #include <linux/init.h>
24 #include <linux/module.h>
25 #include <linux/crypto.h>
26 #include <linux/zlib.h>
27 #include <linux/vmalloc.h>
28 #include <linux/interrupt.h>
30 #include <linux/net.h>
31 #include <crypto/internal/scompress.h>
33 #define DEFLATE_DEF_LEVEL Z_DEFAULT_COMPRESSION
34 #define DEFLATE_DEF_WINBITS 11
35 #define DEFLATE_DEF_MEMLEVEL MAX_MEM_LEVEL
38 struct z_stream_s comp_stream
;
39 struct z_stream_s decomp_stream
;
42 static int deflate_comp_init(struct deflate_ctx
*ctx
, int format
)
45 struct z_stream_s
*stream
= &ctx
->comp_stream
;
47 stream
->workspace
= vzalloc(zlib_deflate_workspacesize(
48 MAX_WBITS
, MAX_MEM_LEVEL
));
49 if (!stream
->workspace
) {
54 ret
= zlib_deflateInit(stream
, 3);
56 ret
= zlib_deflateInit2(stream
, DEFLATE_DEF_LEVEL
, Z_DEFLATED
,
67 vfree(stream
->workspace
);
71 static int deflate_decomp_init(struct deflate_ctx
*ctx
, int format
)
74 struct z_stream_s
*stream
= &ctx
->decomp_stream
;
76 stream
->workspace
= vzalloc(zlib_inflate_workspacesize());
77 if (!stream
->workspace
) {
82 ret
= zlib_inflateInit(stream
);
84 ret
= zlib_inflateInit2(stream
, -DEFLATE_DEF_WINBITS
);
92 vfree(stream
->workspace
);
96 static void deflate_comp_exit(struct deflate_ctx
*ctx
)
98 zlib_deflateEnd(&ctx
->comp_stream
);
99 vfree(ctx
->comp_stream
.workspace
);
102 static void deflate_decomp_exit(struct deflate_ctx
*ctx
)
104 zlib_inflateEnd(&ctx
->decomp_stream
);
105 vfree(ctx
->decomp_stream
.workspace
);
108 static int __deflate_init(void *ctx
, int format
)
112 ret
= deflate_comp_init(ctx
, format
);
115 ret
= deflate_decomp_init(ctx
, format
);
117 deflate_comp_exit(ctx
);
122 static void *gen_deflate_alloc_ctx(struct crypto_scomp
*tfm
, int format
)
124 struct deflate_ctx
*ctx
;
127 ctx
= kzalloc(sizeof(*ctx
), GFP_KERNEL
);
129 return ERR_PTR(-ENOMEM
);
131 ret
= __deflate_init(ctx
, format
);
140 static void *deflate_alloc_ctx(struct crypto_scomp
*tfm
)
142 return gen_deflate_alloc_ctx(tfm
, 0);
145 static void *zlib_deflate_alloc_ctx(struct crypto_scomp
*tfm
)
147 return gen_deflate_alloc_ctx(tfm
, 1);
150 static int deflate_init(struct crypto_tfm
*tfm
)
152 struct deflate_ctx
*ctx
= crypto_tfm_ctx(tfm
);
154 return __deflate_init(ctx
, 0);
157 static void __deflate_exit(void *ctx
)
159 deflate_comp_exit(ctx
);
160 deflate_decomp_exit(ctx
);
163 static void deflate_free_ctx(struct crypto_scomp
*tfm
, void *ctx
)
166 kfree_sensitive(ctx
);
169 static void deflate_exit(struct crypto_tfm
*tfm
)
171 struct deflate_ctx
*ctx
= crypto_tfm_ctx(tfm
);
176 static int __deflate_compress(const u8
*src
, unsigned int slen
,
177 u8
*dst
, unsigned int *dlen
, void *ctx
)
180 struct deflate_ctx
*dctx
= ctx
;
181 struct z_stream_s
*stream
= &dctx
->comp_stream
;
183 ret
= zlib_deflateReset(stream
);
189 stream
->next_in
= (u8
*)src
;
190 stream
->avail_in
= slen
;
191 stream
->next_out
= (u8
*)dst
;
192 stream
->avail_out
= *dlen
;
194 ret
= zlib_deflate(stream
, Z_FINISH
);
195 if (ret
!= Z_STREAM_END
) {
200 *dlen
= stream
->total_out
;
205 static int deflate_compress(struct crypto_tfm
*tfm
, const u8
*src
,
206 unsigned int slen
, u8
*dst
, unsigned int *dlen
)
208 struct deflate_ctx
*dctx
= crypto_tfm_ctx(tfm
);
210 return __deflate_compress(src
, slen
, dst
, dlen
, dctx
);
213 static int deflate_scompress(struct crypto_scomp
*tfm
, const u8
*src
,
214 unsigned int slen
, u8
*dst
, unsigned int *dlen
,
217 return __deflate_compress(src
, slen
, dst
, dlen
, ctx
);
220 static int __deflate_decompress(const u8
*src
, unsigned int slen
,
221 u8
*dst
, unsigned int *dlen
, void *ctx
)
225 struct deflate_ctx
*dctx
= ctx
;
226 struct z_stream_s
*stream
= &dctx
->decomp_stream
;
228 ret
= zlib_inflateReset(stream
);
234 stream
->next_in
= (u8
*)src
;
235 stream
->avail_in
= slen
;
236 stream
->next_out
= (u8
*)dst
;
237 stream
->avail_out
= *dlen
;
239 ret
= zlib_inflate(stream
, Z_SYNC_FLUSH
);
241 * Work around a bug in zlib, which sometimes wants to taste an extra
242 * byte when being used in the (undocumented) raw deflate mode.
245 if (ret
== Z_OK
&& !stream
->avail_in
&& stream
->avail_out
) {
247 stream
->next_in
= &zerostuff
;
248 stream
->avail_in
= 1;
249 ret
= zlib_inflate(stream
, Z_FINISH
);
251 if (ret
!= Z_STREAM_END
) {
256 *dlen
= stream
->total_out
;
261 static int deflate_decompress(struct crypto_tfm
*tfm
, const u8
*src
,
262 unsigned int slen
, u8
*dst
, unsigned int *dlen
)
264 struct deflate_ctx
*dctx
= crypto_tfm_ctx(tfm
);
266 return __deflate_decompress(src
, slen
, dst
, dlen
, dctx
);
269 static int deflate_sdecompress(struct crypto_scomp
*tfm
, const u8
*src
,
270 unsigned int slen
, u8
*dst
, unsigned int *dlen
,
273 return __deflate_decompress(src
, slen
, dst
, dlen
, ctx
);
276 static struct crypto_alg alg
= {
277 .cra_name
= "deflate",
278 .cra_driver_name
= "deflate-generic",
279 .cra_flags
= CRYPTO_ALG_TYPE_COMPRESS
,
280 .cra_ctxsize
= sizeof(struct deflate_ctx
),
281 .cra_module
= THIS_MODULE
,
282 .cra_init
= deflate_init
,
283 .cra_exit
= deflate_exit
,
284 .cra_u
= { .compress
= {
285 .coa_compress
= deflate_compress
,
286 .coa_decompress
= deflate_decompress
} }
289 static struct scomp_alg scomp
[] = { {
290 .alloc_ctx
= deflate_alloc_ctx
,
291 .free_ctx
= deflate_free_ctx
,
292 .compress
= deflate_scompress
,
293 .decompress
= deflate_sdecompress
,
295 .cra_name
= "deflate",
296 .cra_driver_name
= "deflate-scomp",
297 .cra_module
= THIS_MODULE
,
300 .alloc_ctx
= zlib_deflate_alloc_ctx
,
301 .free_ctx
= deflate_free_ctx
,
302 .compress
= deflate_scompress
,
303 .decompress
= deflate_sdecompress
,
305 .cra_name
= "zlib-deflate",
306 .cra_driver_name
= "zlib-deflate-scomp",
307 .cra_module
= THIS_MODULE
,
311 static int __init
deflate_mod_init(void)
315 ret
= crypto_register_alg(&alg
);
319 ret
= crypto_register_scomps(scomp
, ARRAY_SIZE(scomp
));
321 crypto_unregister_alg(&alg
);
328 static void __exit
deflate_mod_fini(void)
330 crypto_unregister_alg(&alg
);
331 crypto_unregister_scomps(scomp
, ARRAY_SIZE(scomp
));
334 subsys_initcall(deflate_mod_init
);
335 module_exit(deflate_mod_fini
);
337 MODULE_LICENSE("GPL");
338 MODULE_DESCRIPTION("Deflate Compression Algorithm for IPCOMP");
339 MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>");
340 MODULE_ALIAS_CRYPTO("deflate");