RT-AC56 3.0.0.4.374.37 core
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / crypto / deflate.c
blob090c51d105827fdc128913089365855174f46e0b
2 #include <linux/init.h>
3 #include <linux/module.h>
4 #include <linux/crypto.h>
5 #include <linux/zlib.h>
6 #include <linux/vmalloc.h>
7 #include <linux/interrupt.h>
8 #include <linux/mm.h>
9 #include <linux/net.h>
10 #include <linux/slab.h>
12 #define DEFLATE_DEF_LEVEL Z_DEFAULT_COMPRESSION
13 #define DEFLATE_DEF_WINBITS 11
14 #define DEFLATE_DEF_MEMLEVEL MAX_MEM_LEVEL
16 struct deflate_ctx {
17 struct z_stream_s comp_stream;
18 struct z_stream_s decomp_stream;
21 static int deflate_comp_init(struct deflate_ctx *ctx)
23 int ret = 0;
24 struct z_stream_s *stream = &ctx->comp_stream;
26 stream->workspace = vmalloc(zlib_deflate_workspacesize());
27 if (!stream->workspace) {
28 ret = -ENOMEM;
29 goto out;
31 memset(stream->workspace, 0, zlib_deflate_workspacesize());
32 ret = zlib_deflateInit2(stream, DEFLATE_DEF_LEVEL, Z_DEFLATED,
33 -DEFLATE_DEF_WINBITS, DEFLATE_DEF_MEMLEVEL,
34 Z_DEFAULT_STRATEGY);
35 if (ret != Z_OK) {
36 ret = -EINVAL;
37 goto out_free;
39 out:
40 return ret;
41 out_free:
42 vfree(stream->workspace);
43 goto out;
46 static int deflate_decomp_init(struct deflate_ctx *ctx)
48 int ret = 0;
49 struct z_stream_s *stream = &ctx->decomp_stream;
51 stream->workspace = kzalloc(zlib_inflate_workspacesize(), GFP_KERNEL);
52 if (!stream->workspace) {
53 ret = -ENOMEM;
54 goto out;
56 ret = zlib_inflateInit2(stream, -DEFLATE_DEF_WINBITS);
57 if (ret != Z_OK) {
58 ret = -EINVAL;
59 goto out_free;
61 out:
62 return ret;
63 out_free:
64 kfree(stream->workspace);
65 goto out;
68 static void deflate_comp_exit(struct deflate_ctx *ctx)
70 zlib_deflateEnd(&ctx->comp_stream);
71 vfree(ctx->comp_stream.workspace);
74 static void deflate_decomp_exit(struct deflate_ctx *ctx)
76 zlib_inflateEnd(&ctx->decomp_stream);
77 kfree(ctx->decomp_stream.workspace);
80 static int deflate_init(struct crypto_tfm *tfm)
82 struct deflate_ctx *ctx = crypto_tfm_ctx(tfm);
83 int ret;
85 ret = deflate_comp_init(ctx);
86 if (ret)
87 goto out;
88 ret = deflate_decomp_init(ctx);
89 if (ret)
90 deflate_comp_exit(ctx);
91 out:
92 return ret;
95 static void deflate_exit(struct crypto_tfm *tfm)
97 struct deflate_ctx *ctx = crypto_tfm_ctx(tfm);
99 deflate_comp_exit(ctx);
100 deflate_decomp_exit(ctx);
103 static int deflate_compress(struct crypto_tfm *tfm, const u8 *src,
104 unsigned int slen, u8 *dst, unsigned int *dlen)
106 int ret = 0;
107 struct deflate_ctx *dctx = crypto_tfm_ctx(tfm);
108 struct z_stream_s *stream = &dctx->comp_stream;
110 ret = zlib_deflateReset(stream);
111 if (ret != Z_OK) {
112 ret = -EINVAL;
113 goto out;
116 stream->next_in = (u8 *)src;
117 stream->avail_in = slen;
118 stream->next_out = (u8 *)dst;
119 stream->avail_out = *dlen;
121 ret = zlib_deflate(stream, Z_FINISH);
122 if (ret != Z_STREAM_END) {
123 ret = -EINVAL;
124 goto out;
126 ret = 0;
127 *dlen = stream->total_out;
128 out:
129 return ret;
132 static int deflate_decompress(struct crypto_tfm *tfm, const u8 *src,
133 unsigned int slen, u8 *dst, unsigned int *dlen)
136 int ret = 0;
137 struct deflate_ctx *dctx = crypto_tfm_ctx(tfm);
138 struct z_stream_s *stream = &dctx->decomp_stream;
140 ret = zlib_inflateReset(stream);
141 if (ret != Z_OK) {
142 ret = -EINVAL;
143 goto out;
146 stream->next_in = (u8 *)src;
147 stream->avail_in = slen;
148 stream->next_out = (u8 *)dst;
149 stream->avail_out = *dlen;
151 ret = zlib_inflate(stream, Z_SYNC_FLUSH);
152 if (ret == Z_OK && !stream->avail_in && stream->avail_out) {
153 u8 zerostuff = 0;
154 stream->next_in = &zerostuff;
155 stream->avail_in = 1;
156 ret = zlib_inflate(stream, Z_FINISH);
158 if (ret != Z_STREAM_END) {
159 ret = -EINVAL;
160 goto out;
162 ret = 0;
163 *dlen = stream->total_out;
164 out:
165 return ret;
168 static struct crypto_alg alg = {
169 .cra_name = "deflate",
170 .cra_flags = CRYPTO_ALG_TYPE_COMPRESS,
171 .cra_ctxsize = sizeof(struct deflate_ctx),
172 .cra_module = THIS_MODULE,
173 .cra_list = LIST_HEAD_INIT(alg.cra_list),
174 .cra_init = deflate_init,
175 .cra_exit = deflate_exit,
176 .cra_u = { .compress = {
177 .coa_compress = deflate_compress,
178 .coa_decompress = deflate_decompress } }
181 static int __init deflate_mod_init(void)
183 return crypto_register_alg(&alg);
186 static void __exit deflate_mod_fini(void)
188 crypto_unregister_alg(&alg);
191 module_init(deflate_mod_init);
192 module_exit(deflate_mod_fini);
194 MODULE_LICENSE("GPL");
195 MODULE_DESCRIPTION("Deflate Compression Algorithm for IPCOMP");
196 MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>");