xref: /openbmc/linux/crypto/deflate.c (revision 453431a5)
12874c5fdSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds  * Cryptographic API.
41da177e4SLinus Torvalds  *
51da177e4SLinus Torvalds  * Deflate algorithm (RFC 1951), implemented here primarily for use
61da177e4SLinus Torvalds  * by IPCOMP (RFC 3173 & RFC 2394).
71da177e4SLinus Torvalds  *
81da177e4SLinus Torvalds  * Copyright (c) 2003 James Morris <jmorris@intercode.com.au>
91da177e4SLinus Torvalds  *
101da177e4SLinus Torvalds  * FIXME: deflate transforms will require up to a total of about 436k of kernel
111da177e4SLinus Torvalds  * memory on i386 (390k for compression, the rest for decompression), as the
121da177e4SLinus Torvalds  * current zlib kernel code uses a worst case pre-allocation system by default.
131da177e4SLinus Torvalds  * This needs to be fixed so that the amount of memory required is properly
141da177e4SLinus Torvalds  * related to the  winbits and memlevel parameters.
151da177e4SLinus Torvalds  *
161da177e4SLinus Torvalds  * The default winbits of 11 should suit most packets, and it may be something
171da177e4SLinus Torvalds  * to configure on a per-tfm basis in the future.
181da177e4SLinus Torvalds  *
191da177e4SLinus Torvalds  * Currently, compression history is not maintained between tfm calls, as
201da177e4SLinus Torvalds  * it is not needed for IPCOMP and keeps the code simpler.  It can be
211da177e4SLinus Torvalds  * implemented if someone wants it.
221da177e4SLinus Torvalds  */
231da177e4SLinus Torvalds #include <linux/init.h>
241da177e4SLinus Torvalds #include <linux/module.h>
251da177e4SLinus Torvalds #include <linux/crypto.h>
261da177e4SLinus Torvalds #include <linux/zlib.h>
271da177e4SLinus Torvalds #include <linux/vmalloc.h>
281da177e4SLinus Torvalds #include <linux/interrupt.h>
291da177e4SLinus Torvalds #include <linux/mm.h>
301da177e4SLinus Torvalds #include <linux/net.h>
31f6ded09dSGiovanni Cabiddu #include <crypto/internal/scompress.h>
321da177e4SLinus Torvalds 
331da177e4SLinus Torvalds #define DEFLATE_DEF_LEVEL		Z_DEFAULT_COMPRESSION
341da177e4SLinus Torvalds #define DEFLATE_DEF_WINBITS		11
351da177e4SLinus Torvalds #define DEFLATE_DEF_MEMLEVEL		MAX_MEM_LEVEL
361da177e4SLinus Torvalds 
371da177e4SLinus Torvalds struct deflate_ctx {
381da177e4SLinus Torvalds 	struct z_stream_s comp_stream;
391da177e4SLinus Torvalds 	struct z_stream_s decomp_stream;
401da177e4SLinus Torvalds };
411da177e4SLinus Torvalds 
deflate_comp_init(struct deflate_ctx * ctx,int format)42a368f43dSGiovanni Cabiddu static int deflate_comp_init(struct deflate_ctx *ctx, int format)
431da177e4SLinus Torvalds {
441da177e4SLinus Torvalds 	int ret = 0;
451da177e4SLinus Torvalds 	struct z_stream_s *stream = &ctx->comp_stream;
461da177e4SLinus Torvalds 
47565d76cbSJim Keniston 	stream->workspace = vzalloc(zlib_deflate_workspacesize(
48a368f43dSGiovanni Cabiddu 				    MAX_WBITS, MAX_MEM_LEVEL));
491da177e4SLinus Torvalds 	if (!stream->workspace) {
501da177e4SLinus Torvalds 		ret = -ENOMEM;
511da177e4SLinus Torvalds 		goto out;
521da177e4SLinus Torvalds 	}
53a368f43dSGiovanni Cabiddu 	if (format)
54a368f43dSGiovanni Cabiddu 		ret = zlib_deflateInit(stream, 3);
55a368f43dSGiovanni Cabiddu 	else
561da177e4SLinus Torvalds 		ret = zlib_deflateInit2(stream, DEFLATE_DEF_LEVEL, Z_DEFLATED,
57a368f43dSGiovanni Cabiddu 					-DEFLATE_DEF_WINBITS,
58a368f43dSGiovanni Cabiddu 					DEFLATE_DEF_MEMLEVEL,
591da177e4SLinus Torvalds 					Z_DEFAULT_STRATEGY);
601da177e4SLinus Torvalds 	if (ret != Z_OK) {
611da177e4SLinus Torvalds 		ret = -EINVAL;
621da177e4SLinus Torvalds 		goto out_free;
631da177e4SLinus Torvalds 	}
641da177e4SLinus Torvalds out:
651da177e4SLinus Torvalds 	return ret;
661da177e4SLinus Torvalds out_free:
671da177e4SLinus Torvalds 	vfree(stream->workspace);
681da177e4SLinus Torvalds 	goto out;
691da177e4SLinus Torvalds }
701da177e4SLinus Torvalds 
deflate_decomp_init(struct deflate_ctx * ctx,int format)71a368f43dSGiovanni Cabiddu static int deflate_decomp_init(struct deflate_ctx *ctx, int format)
721da177e4SLinus Torvalds {
731da177e4SLinus Torvalds 	int ret = 0;
741da177e4SLinus Torvalds 	struct z_stream_s *stream = &ctx->decomp_stream;
751da177e4SLinus Torvalds 
767ab24bfdSDavid S. Miller 	stream->workspace = vzalloc(zlib_inflate_workspacesize());
771da177e4SLinus Torvalds 	if (!stream->workspace) {
781da177e4SLinus Torvalds 		ret = -ENOMEM;
791da177e4SLinus Torvalds 		goto out;
801da177e4SLinus Torvalds 	}
81a368f43dSGiovanni Cabiddu 	if (format)
82a368f43dSGiovanni Cabiddu 		ret = zlib_inflateInit(stream);
83a368f43dSGiovanni Cabiddu 	else
841da177e4SLinus Torvalds 		ret = zlib_inflateInit2(stream, -DEFLATE_DEF_WINBITS);
851da177e4SLinus Torvalds 	if (ret != Z_OK) {
861da177e4SLinus Torvalds 		ret = -EINVAL;
871da177e4SLinus Torvalds 		goto out_free;
881da177e4SLinus Torvalds 	}
891da177e4SLinus Torvalds out:
901da177e4SLinus Torvalds 	return ret;
911da177e4SLinus Torvalds out_free:
927ab24bfdSDavid S. Miller 	vfree(stream->workspace);
931da177e4SLinus Torvalds 	goto out;
941da177e4SLinus Torvalds }
951da177e4SLinus Torvalds 
deflate_comp_exit(struct deflate_ctx * ctx)961da177e4SLinus Torvalds static void deflate_comp_exit(struct deflate_ctx *ctx)
971da177e4SLinus Torvalds {
989ffb7146SArtem B. Bityuckiy 	zlib_deflateEnd(&ctx->comp_stream);
991da177e4SLinus Torvalds 	vfree(ctx->comp_stream.workspace);
1001da177e4SLinus Torvalds }
1011da177e4SLinus Torvalds 
deflate_decomp_exit(struct deflate_ctx * ctx)1021da177e4SLinus Torvalds static void deflate_decomp_exit(struct deflate_ctx *ctx)
1031da177e4SLinus Torvalds {
1049ffb7146SArtem B. Bityuckiy 	zlib_inflateEnd(&ctx->decomp_stream);
1057ab24bfdSDavid S. Miller 	vfree(ctx->decomp_stream.workspace);
1061da177e4SLinus Torvalds }
1071da177e4SLinus Torvalds 
__deflate_init(void * ctx,int format)108a368f43dSGiovanni Cabiddu static int __deflate_init(void *ctx, int format)
1091da177e4SLinus Torvalds {
1101da177e4SLinus Torvalds 	int ret;
1111da177e4SLinus Torvalds 
112a368f43dSGiovanni Cabiddu 	ret = deflate_comp_init(ctx, format);
1131da177e4SLinus Torvalds 	if (ret)
1141da177e4SLinus Torvalds 		goto out;
115a368f43dSGiovanni Cabiddu 	ret = deflate_decomp_init(ctx, format);
1161da177e4SLinus Torvalds 	if (ret)
1171da177e4SLinus Torvalds 		deflate_comp_exit(ctx);
1181da177e4SLinus Torvalds out:
1191da177e4SLinus Torvalds 	return ret;
1201da177e4SLinus Torvalds }
1211da177e4SLinus Torvalds 
gen_deflate_alloc_ctx(struct crypto_scomp * tfm,int format)122a368f43dSGiovanni Cabiddu static void *gen_deflate_alloc_ctx(struct crypto_scomp *tfm, int format)
123f6ded09dSGiovanni Cabiddu {
124f6ded09dSGiovanni Cabiddu 	struct deflate_ctx *ctx;
125f6ded09dSGiovanni Cabiddu 	int ret;
126f6ded09dSGiovanni Cabiddu 
127f6ded09dSGiovanni Cabiddu 	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
128f6ded09dSGiovanni Cabiddu 	if (!ctx)
129f6ded09dSGiovanni Cabiddu 		return ERR_PTR(-ENOMEM);
130f6ded09dSGiovanni Cabiddu 
131a368f43dSGiovanni Cabiddu 	ret = __deflate_init(ctx, format);
132f6ded09dSGiovanni Cabiddu 	if (ret) {
133f6ded09dSGiovanni Cabiddu 		kfree(ctx);
134f6ded09dSGiovanni Cabiddu 		return ERR_PTR(ret);
135f6ded09dSGiovanni Cabiddu 	}
136f6ded09dSGiovanni Cabiddu 
137f6ded09dSGiovanni Cabiddu 	return ctx;
138f6ded09dSGiovanni Cabiddu }
139f6ded09dSGiovanni Cabiddu 
deflate_alloc_ctx(struct crypto_scomp * tfm)140a368f43dSGiovanni Cabiddu static void *deflate_alloc_ctx(struct crypto_scomp *tfm)
141a368f43dSGiovanni Cabiddu {
142a368f43dSGiovanni Cabiddu 	return gen_deflate_alloc_ctx(tfm, 0);
143a368f43dSGiovanni Cabiddu }
144a368f43dSGiovanni Cabiddu 
zlib_deflate_alloc_ctx(struct crypto_scomp * tfm)145a368f43dSGiovanni Cabiddu static void *zlib_deflate_alloc_ctx(struct crypto_scomp *tfm)
146a368f43dSGiovanni Cabiddu {
147a368f43dSGiovanni Cabiddu 	return gen_deflate_alloc_ctx(tfm, 1);
148a368f43dSGiovanni Cabiddu }
149a368f43dSGiovanni Cabiddu 
deflate_init(struct crypto_tfm * tfm)150f6ded09dSGiovanni Cabiddu static int deflate_init(struct crypto_tfm *tfm)
1511da177e4SLinus Torvalds {
1526c2bb98bSHerbert Xu 	struct deflate_ctx *ctx = crypto_tfm_ctx(tfm);
1536c2bb98bSHerbert Xu 
154a368f43dSGiovanni Cabiddu 	return __deflate_init(ctx, 0);
155f6ded09dSGiovanni Cabiddu }
156f6ded09dSGiovanni Cabiddu 
__deflate_exit(void * ctx)157f6ded09dSGiovanni Cabiddu static void __deflate_exit(void *ctx)
158f6ded09dSGiovanni Cabiddu {
1591da177e4SLinus Torvalds 	deflate_comp_exit(ctx);
1601da177e4SLinus Torvalds 	deflate_decomp_exit(ctx);
1611da177e4SLinus Torvalds }
1621da177e4SLinus Torvalds 
deflate_free_ctx(struct crypto_scomp * tfm,void * ctx)163f6ded09dSGiovanni Cabiddu static void deflate_free_ctx(struct crypto_scomp *tfm, void *ctx)
164f6ded09dSGiovanni Cabiddu {
165f6ded09dSGiovanni Cabiddu 	__deflate_exit(ctx);
166453431a5SWaiman Long 	kfree_sensitive(ctx);
167f6ded09dSGiovanni Cabiddu }
168f6ded09dSGiovanni Cabiddu 
deflate_exit(struct crypto_tfm * tfm)169f6ded09dSGiovanni Cabiddu static void deflate_exit(struct crypto_tfm *tfm)
170f6ded09dSGiovanni Cabiddu {
171f6ded09dSGiovanni Cabiddu 	struct deflate_ctx *ctx = crypto_tfm_ctx(tfm);
172f6ded09dSGiovanni Cabiddu 
173f6ded09dSGiovanni Cabiddu 	__deflate_exit(ctx);
174f6ded09dSGiovanni Cabiddu }
175f6ded09dSGiovanni Cabiddu 
__deflate_compress(const u8 * src,unsigned int slen,u8 * dst,unsigned int * dlen,void * ctx)176f6ded09dSGiovanni Cabiddu static int __deflate_compress(const u8 *src, unsigned int slen,
177f6ded09dSGiovanni Cabiddu 			      u8 *dst, unsigned int *dlen, void *ctx)
1781da177e4SLinus Torvalds {
1791da177e4SLinus Torvalds 	int ret = 0;
180f6ded09dSGiovanni Cabiddu 	struct deflate_ctx *dctx = ctx;
1811da177e4SLinus Torvalds 	struct z_stream_s *stream = &dctx->comp_stream;
1821da177e4SLinus Torvalds 
1831da177e4SLinus Torvalds 	ret = zlib_deflateReset(stream);
1841da177e4SLinus Torvalds 	if (ret != Z_OK) {
1851da177e4SLinus Torvalds 		ret = -EINVAL;
1861da177e4SLinus Torvalds 		goto out;
1871da177e4SLinus Torvalds 	}
1881da177e4SLinus Torvalds 
1891da177e4SLinus Torvalds 	stream->next_in = (u8 *)src;
1901da177e4SLinus Torvalds 	stream->avail_in = slen;
1911da177e4SLinus Torvalds 	stream->next_out = (u8 *)dst;
1921da177e4SLinus Torvalds 	stream->avail_out = *dlen;
1931da177e4SLinus Torvalds 
1941da177e4SLinus Torvalds 	ret = zlib_deflate(stream, Z_FINISH);
1951da177e4SLinus Torvalds 	if (ret != Z_STREAM_END) {
1961da177e4SLinus Torvalds 		ret = -EINVAL;
1971da177e4SLinus Torvalds 		goto out;
1981da177e4SLinus Torvalds 	}
1991da177e4SLinus Torvalds 	ret = 0;
2001da177e4SLinus Torvalds 	*dlen = stream->total_out;
2011da177e4SLinus Torvalds out:
2021da177e4SLinus Torvalds 	return ret;
2031da177e4SLinus Torvalds }
2041da177e4SLinus Torvalds 
deflate_compress(struct crypto_tfm * tfm,const u8 * src,unsigned int slen,u8 * dst,unsigned int * dlen)205f6ded09dSGiovanni Cabiddu static int deflate_compress(struct crypto_tfm *tfm, const u8 *src,
2066c2bb98bSHerbert Xu 			    unsigned int slen, u8 *dst, unsigned int *dlen)
2071da177e4SLinus Torvalds {
208f6ded09dSGiovanni Cabiddu 	struct deflate_ctx *dctx = crypto_tfm_ctx(tfm);
209f6ded09dSGiovanni Cabiddu 
210f6ded09dSGiovanni Cabiddu 	return __deflate_compress(src, slen, dst, dlen, dctx);
211f6ded09dSGiovanni Cabiddu }
212f6ded09dSGiovanni Cabiddu 
deflate_scompress(struct crypto_scomp * tfm,const u8 * src,unsigned int slen,u8 * dst,unsigned int * dlen,void * ctx)213f6ded09dSGiovanni Cabiddu static int deflate_scompress(struct crypto_scomp *tfm, const u8 *src,
214f6ded09dSGiovanni Cabiddu 			     unsigned int slen, u8 *dst, unsigned int *dlen,
215f6ded09dSGiovanni Cabiddu 			     void *ctx)
216f6ded09dSGiovanni Cabiddu {
217f6ded09dSGiovanni Cabiddu 	return __deflate_compress(src, slen, dst, dlen, ctx);
218f6ded09dSGiovanni Cabiddu }
219f6ded09dSGiovanni Cabiddu 
__deflate_decompress(const u8 * src,unsigned int slen,u8 * dst,unsigned int * dlen,void * ctx)220f6ded09dSGiovanni Cabiddu static int __deflate_decompress(const u8 *src, unsigned int slen,
221f6ded09dSGiovanni Cabiddu 				u8 *dst, unsigned int *dlen, void *ctx)
222f6ded09dSGiovanni Cabiddu {
2231da177e4SLinus Torvalds 
2241da177e4SLinus Torvalds 	int ret = 0;
225f6ded09dSGiovanni Cabiddu 	struct deflate_ctx *dctx = ctx;
2261da177e4SLinus Torvalds 	struct z_stream_s *stream = &dctx->decomp_stream;
2271da177e4SLinus Torvalds 
2281da177e4SLinus Torvalds 	ret = zlib_inflateReset(stream);
2291da177e4SLinus Torvalds 	if (ret != Z_OK) {
2301da177e4SLinus Torvalds 		ret = -EINVAL;
2311da177e4SLinus Torvalds 		goto out;
2321da177e4SLinus Torvalds 	}
2331da177e4SLinus Torvalds 
2341da177e4SLinus Torvalds 	stream->next_in = (u8 *)src;
2351da177e4SLinus Torvalds 	stream->avail_in = slen;
2361da177e4SLinus Torvalds 	stream->next_out = (u8 *)dst;
2371da177e4SLinus Torvalds 	stream->avail_out = *dlen;
2381da177e4SLinus Torvalds 
2391da177e4SLinus Torvalds 	ret = zlib_inflate(stream, Z_SYNC_FLUSH);
2401da177e4SLinus Torvalds 	/*
2411da177e4SLinus Torvalds 	 * Work around a bug in zlib, which sometimes wants to taste an extra
2421da177e4SLinus Torvalds 	 * byte when being used in the (undocumented) raw deflate mode.
2431da177e4SLinus Torvalds 	 * (From USAGI).
2441da177e4SLinus Torvalds 	 */
2451da177e4SLinus Torvalds 	if (ret == Z_OK && !stream->avail_in && stream->avail_out) {
2461da177e4SLinus Torvalds 		u8 zerostuff = 0;
2471da177e4SLinus Torvalds 		stream->next_in = &zerostuff;
2481da177e4SLinus Torvalds 		stream->avail_in = 1;
2491da177e4SLinus Torvalds 		ret = zlib_inflate(stream, Z_FINISH);
2501da177e4SLinus Torvalds 	}
2511da177e4SLinus Torvalds 	if (ret != Z_STREAM_END) {
2521da177e4SLinus Torvalds 		ret = -EINVAL;
2531da177e4SLinus Torvalds 		goto out;
2541da177e4SLinus Torvalds 	}
2551da177e4SLinus Torvalds 	ret = 0;
2561da177e4SLinus Torvalds 	*dlen = stream->total_out;
2571da177e4SLinus Torvalds out:
2581da177e4SLinus Torvalds 	return ret;
2591da177e4SLinus Torvalds }
2601da177e4SLinus Torvalds 
deflate_decompress(struct crypto_tfm * tfm,const u8 * src,unsigned int slen,u8 * dst,unsigned int * dlen)261f6ded09dSGiovanni Cabiddu static int deflate_decompress(struct crypto_tfm *tfm, const u8 *src,
262f6ded09dSGiovanni Cabiddu 			      unsigned int slen, u8 *dst, unsigned int *dlen)
263f6ded09dSGiovanni Cabiddu {
264f6ded09dSGiovanni Cabiddu 	struct deflate_ctx *dctx = crypto_tfm_ctx(tfm);
265f6ded09dSGiovanni Cabiddu 
266f6ded09dSGiovanni Cabiddu 	return __deflate_decompress(src, slen, dst, dlen, dctx);
267f6ded09dSGiovanni Cabiddu }
268f6ded09dSGiovanni Cabiddu 
deflate_sdecompress(struct crypto_scomp * tfm,const u8 * src,unsigned int slen,u8 * dst,unsigned int * dlen,void * ctx)269f6ded09dSGiovanni Cabiddu static int deflate_sdecompress(struct crypto_scomp *tfm, const u8 *src,
270f6ded09dSGiovanni Cabiddu 			       unsigned int slen, u8 *dst, unsigned int *dlen,
271f6ded09dSGiovanni Cabiddu 			       void *ctx)
272f6ded09dSGiovanni Cabiddu {
273f6ded09dSGiovanni Cabiddu 	return __deflate_decompress(src, slen, dst, dlen, ctx);
274f6ded09dSGiovanni Cabiddu }
275f6ded09dSGiovanni Cabiddu 
2761da177e4SLinus Torvalds static struct crypto_alg alg = {
2771da177e4SLinus Torvalds 	.cra_name		= "deflate",
278d6ebf528SEric Biggers 	.cra_driver_name	= "deflate-generic",
2791da177e4SLinus Torvalds 	.cra_flags		= CRYPTO_ALG_TYPE_COMPRESS,
2801da177e4SLinus Torvalds 	.cra_ctxsize		= sizeof(struct deflate_ctx),
2811da177e4SLinus Torvalds 	.cra_module		= THIS_MODULE,
282c7fc0599SHerbert Xu 	.cra_init		= deflate_init,
283c7fc0599SHerbert Xu 	.cra_exit		= deflate_exit,
2841da177e4SLinus Torvalds 	.cra_u			= { .compress = {
2851da177e4SLinus Torvalds 	.coa_compress 		= deflate_compress,
2861da177e4SLinus Torvalds 	.coa_decompress  	= deflate_decompress } }
2871da177e4SLinus Torvalds };
2881da177e4SLinus Torvalds 
289a368f43dSGiovanni Cabiddu static struct scomp_alg scomp[] = { {
290f6ded09dSGiovanni Cabiddu 	.alloc_ctx		= deflate_alloc_ctx,
291f6ded09dSGiovanni Cabiddu 	.free_ctx		= deflate_free_ctx,
292f6ded09dSGiovanni Cabiddu 	.compress		= deflate_scompress,
293f6ded09dSGiovanni Cabiddu 	.decompress		= deflate_sdecompress,
294f6ded09dSGiovanni Cabiddu 	.base			= {
295f6ded09dSGiovanni Cabiddu 		.cra_name	= "deflate",
296f6ded09dSGiovanni Cabiddu 		.cra_driver_name = "deflate-scomp",
297f6ded09dSGiovanni Cabiddu 		.cra_module	 = THIS_MODULE,
298f6ded09dSGiovanni Cabiddu 	}
299a368f43dSGiovanni Cabiddu }, {
300a368f43dSGiovanni Cabiddu 	.alloc_ctx		= zlib_deflate_alloc_ctx,
301a368f43dSGiovanni Cabiddu 	.free_ctx		= deflate_free_ctx,
302a368f43dSGiovanni Cabiddu 	.compress		= deflate_scompress,
303a368f43dSGiovanni Cabiddu 	.decompress		= deflate_sdecompress,
304a368f43dSGiovanni Cabiddu 	.base			= {
305a368f43dSGiovanni Cabiddu 		.cra_name	= "zlib-deflate",
306a368f43dSGiovanni Cabiddu 		.cra_driver_name = "zlib-deflate-scomp",
307a368f43dSGiovanni Cabiddu 		.cra_module	 = THIS_MODULE,
308a368f43dSGiovanni Cabiddu 	}
309a368f43dSGiovanni Cabiddu } };
310f6ded09dSGiovanni Cabiddu 
deflate_mod_init(void)3113af5b90bSKamalesh Babulal static int __init deflate_mod_init(void)
3121da177e4SLinus Torvalds {
313f6ded09dSGiovanni Cabiddu 	int ret;
314f6ded09dSGiovanni Cabiddu 
315f6ded09dSGiovanni Cabiddu 	ret = crypto_register_alg(&alg);
316f6ded09dSGiovanni Cabiddu 	if (ret)
317f6ded09dSGiovanni Cabiddu 		return ret;
318f6ded09dSGiovanni Cabiddu 
319a368f43dSGiovanni Cabiddu 	ret = crypto_register_scomps(scomp, ARRAY_SIZE(scomp));
320f6ded09dSGiovanni Cabiddu 	if (ret) {
321f6ded09dSGiovanni Cabiddu 		crypto_unregister_alg(&alg);
322f6ded09dSGiovanni Cabiddu 		return ret;
323f6ded09dSGiovanni Cabiddu 	}
324f6ded09dSGiovanni Cabiddu 
325f6ded09dSGiovanni Cabiddu 	return ret;
3261da177e4SLinus Torvalds }
3271da177e4SLinus Torvalds 
deflate_mod_fini(void)3283af5b90bSKamalesh Babulal static void __exit deflate_mod_fini(void)
3291da177e4SLinus Torvalds {
3301da177e4SLinus Torvalds 	crypto_unregister_alg(&alg);
331a368f43dSGiovanni Cabiddu 	crypto_unregister_scomps(scomp, ARRAY_SIZE(scomp));
3321da177e4SLinus Torvalds }
3331da177e4SLinus Torvalds 
334c4741b23SEric Biggers subsys_initcall(deflate_mod_init);
3353af5b90bSKamalesh Babulal module_exit(deflate_mod_fini);
3361da177e4SLinus Torvalds 
3371da177e4SLinus Torvalds MODULE_LICENSE("GPL");
3381da177e4SLinus Torvalds MODULE_DESCRIPTION("Deflate Compression Algorithm for IPCOMP");
3391da177e4SLinus Torvalds MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>");
3405d26a105SKees Cook MODULE_ALIAS_CRYPTO("deflate");
341