zlib.c 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. /*
  2. * Cryptographic API.
  3. *
  4. * Zlib algorithm
  5. *
  6. * Copyright 2008 Sony Corporation
  7. *
  8. * Based on deflate.c, which is
  9. * Copyright (c) 2003 James Morris <jmorris@intercode.com.au>
  10. *
  11. * This program is free software; you can redistribute it and/or modify it
  12. * under the terms of the GNU General Public License as published by the Free
  13. * Software Foundation; either version 2 of the License, or (at your option)
  14. * any later version.
  15. *
  16. * FIXME: deflate transforms will require up to a total of about 436k of kernel
  17. * memory on i386 (390k for compression, the rest for decompression), as the
  18. * current zlib kernel code uses a worst case pre-allocation system by default.
  19. * This needs to be fixed so that the amount of memory required is properly
  20. * related to the winbits and memlevel parameters.
  21. */
  22. #define pr_fmt(fmt) "%s: " fmt, __func__
  23. #include <linux/init.h>
  24. #include <linux/module.h>
  25. #include <linux/zlib.h>
  26. #include <linux/vmalloc.h>
  27. #include <linux/interrupt.h>
  28. #include <linux/mm.h>
  29. #include <linux/net.h>
  30. #include <linux/slab.h>
  31. #include <crypto/internal/compress.h>
  32. #include <net/netlink.h>
  33. struct zlib_ctx {
  34. struct z_stream_s comp_stream;
  35. struct z_stream_s decomp_stream;
  36. int decomp_windowBits;
  37. };
  38. static void zlib_comp_exit(struct zlib_ctx *ctx)
  39. {
  40. struct z_stream_s *stream = &ctx->comp_stream;
  41. if (stream->workspace) {
  42. zlib_deflateEnd(stream);
  43. vfree(stream->workspace);
  44. stream->workspace = NULL;
  45. }
  46. }
  47. static void zlib_decomp_exit(struct zlib_ctx *ctx)
  48. {
  49. struct z_stream_s *stream = &ctx->decomp_stream;
  50. if (stream->workspace) {
  51. zlib_inflateEnd(stream);
  52. kfree(stream->workspace);
  53. stream->workspace = NULL;
  54. }
  55. }
  56. static int zlib_init(struct crypto_tfm *tfm)
  57. {
  58. return 0;
  59. }
  60. static void zlib_exit(struct crypto_tfm *tfm)
  61. {
  62. struct zlib_ctx *ctx = crypto_tfm_ctx(tfm);
  63. zlib_comp_exit(ctx);
  64. zlib_decomp_exit(ctx);
  65. }
  66. static int zlib_compress_setup(struct crypto_pcomp *tfm, void *params,
  67. unsigned int len)
  68. {
  69. struct zlib_ctx *ctx = crypto_tfm_ctx(crypto_pcomp_tfm(tfm));
  70. struct z_stream_s *stream = &ctx->comp_stream;
  71. struct nlattr *tb[ZLIB_COMP_MAX + 1];
  72. size_t workspacesize;
  73. int ret;
  74. ret = nla_parse(tb, ZLIB_COMP_MAX, params, len, NULL);
  75. if (ret)
  76. return ret;
  77. zlib_comp_exit(ctx);
  78. workspacesize = zlib_deflate_workspacesize();
  79. stream->workspace = vmalloc(workspacesize);
  80. if (!stream->workspace)
  81. return -ENOMEM;
  82. memset(stream->workspace, 0, workspacesize);
  83. ret = zlib_deflateInit2(stream,
  84. tb[ZLIB_COMP_LEVEL]
  85. ? nla_get_u32(tb[ZLIB_COMP_LEVEL])
  86. : Z_DEFAULT_COMPRESSION,
  87. tb[ZLIB_COMP_METHOD]
  88. ? nla_get_u32(tb[ZLIB_COMP_METHOD])
  89. : Z_DEFLATED,
  90. tb[ZLIB_COMP_WINDOWBITS]
  91. ? nla_get_u32(tb[ZLIB_COMP_WINDOWBITS])
  92. : MAX_WBITS,
  93. tb[ZLIB_COMP_MEMLEVEL]
  94. ? nla_get_u32(tb[ZLIB_COMP_MEMLEVEL])
  95. : DEF_MEM_LEVEL,
  96. tb[ZLIB_COMP_STRATEGY]
  97. ? nla_get_u32(tb[ZLIB_COMP_STRATEGY])
  98. : Z_DEFAULT_STRATEGY);
  99. if (ret != Z_OK) {
  100. vfree(stream->workspace);
  101. stream->workspace = NULL;
  102. return -EINVAL;
  103. }
  104. return 0;
  105. }
  106. static int zlib_compress_init(struct crypto_pcomp *tfm)
  107. {
  108. int ret;
  109. struct zlib_ctx *dctx = crypto_tfm_ctx(crypto_pcomp_tfm(tfm));
  110. struct z_stream_s *stream = &dctx->comp_stream;
  111. ret = zlib_deflateReset(stream);
  112. if (ret != Z_OK)
  113. return -EINVAL;
  114. return 0;
  115. }
  116. static int zlib_compress_update(struct crypto_pcomp *tfm,
  117. struct comp_request *req)
  118. {
  119. int ret;
  120. struct zlib_ctx *dctx = crypto_tfm_ctx(crypto_pcomp_tfm(tfm));
  121. struct z_stream_s *stream = &dctx->comp_stream;
  122. pr_debug("avail_in %u, avail_out %u\n", req->avail_in, req->avail_out);
  123. stream->next_in = req->next_in;
  124. stream->avail_in = req->avail_in;
  125. stream->next_out = req->next_out;
  126. stream->avail_out = req->avail_out;
  127. ret = zlib_deflate(stream, Z_NO_FLUSH);
  128. switch (ret) {
  129. case Z_OK:
  130. break;
  131. case Z_BUF_ERROR:
  132. pr_debug("zlib_deflate could not make progress\n");
  133. return -EAGAIN;
  134. default:
  135. pr_debug("zlib_deflate failed %d\n", ret);
  136. return -EINVAL;
  137. }
  138. ret = req->avail_out - stream->avail_out;
  139. pr_debug("avail_in %u, avail_out %u (consumed %u, produced %u)\n",
  140. stream->avail_in, stream->avail_out,
  141. req->avail_in - stream->avail_in, ret);
  142. req->next_in = stream->next_in;
  143. req->avail_in = stream->avail_in;
  144. req->next_out = stream->next_out;
  145. req->avail_out = stream->avail_out;
  146. return ret;
  147. }
  148. static int zlib_compress_final(struct crypto_pcomp *tfm,
  149. struct comp_request *req)
  150. {
  151. int ret;
  152. struct zlib_ctx *dctx = crypto_tfm_ctx(crypto_pcomp_tfm(tfm));
  153. struct z_stream_s *stream = &dctx->comp_stream;
  154. pr_debug("avail_in %u, avail_out %u\n", req->avail_in, req->avail_out);
  155. stream->next_in = req->next_in;
  156. stream->avail_in = req->avail_in;
  157. stream->next_out = req->next_out;
  158. stream->avail_out = req->avail_out;
  159. ret = zlib_deflate(stream, Z_FINISH);
  160. if (ret != Z_STREAM_END) {
  161. pr_debug("zlib_deflate failed %d\n", ret);
  162. return -EINVAL;
  163. }
  164. ret = req->avail_out - stream->avail_out;
  165. pr_debug("avail_in %u, avail_out %u (consumed %u, produced %u)\n",
  166. stream->avail_in, stream->avail_out,
  167. req->avail_in - stream->avail_in, ret);
  168. req->next_in = stream->next_in;
  169. req->avail_in = stream->avail_in;
  170. req->next_out = stream->next_out;
  171. req->avail_out = stream->avail_out;
  172. return ret;
  173. }
  174. static int zlib_decompress_setup(struct crypto_pcomp *tfm, void *params,
  175. unsigned int len)
  176. {
  177. struct zlib_ctx *ctx = crypto_tfm_ctx(crypto_pcomp_tfm(tfm));
  178. struct z_stream_s *stream = &ctx->decomp_stream;
  179. struct nlattr *tb[ZLIB_DECOMP_MAX + 1];
  180. int ret = 0;
  181. ret = nla_parse(tb, ZLIB_DECOMP_MAX, params, len, NULL);
  182. if (ret)
  183. return ret;
  184. zlib_decomp_exit(ctx);
  185. ctx->decomp_windowBits = tb[ZLIB_DECOMP_WINDOWBITS]
  186. ? nla_get_u32(tb[ZLIB_DECOMP_WINDOWBITS])
  187. : DEF_WBITS;
  188. stream->workspace = kzalloc(zlib_inflate_workspacesize(), GFP_KERNEL);
  189. if (!stream->workspace)
  190. return -ENOMEM;
  191. ret = zlib_inflateInit2(stream, ctx->decomp_windowBits);
  192. if (ret != Z_OK) {
  193. kfree(stream->workspace);
  194. stream->workspace = NULL;
  195. return -EINVAL;
  196. }
  197. return 0;
  198. }
  199. static int zlib_decompress_init(struct crypto_pcomp *tfm)
  200. {
  201. int ret;
  202. struct zlib_ctx *dctx = crypto_tfm_ctx(crypto_pcomp_tfm(tfm));
  203. struct z_stream_s *stream = &dctx->decomp_stream;
  204. ret = zlib_inflateReset(stream);
  205. if (ret != Z_OK)
  206. return -EINVAL;
  207. return 0;
  208. }
  209. static int zlib_decompress_update(struct crypto_pcomp *tfm,
  210. struct comp_request *req)
  211. {
  212. int ret;
  213. struct zlib_ctx *dctx = crypto_tfm_ctx(crypto_pcomp_tfm(tfm));
  214. struct z_stream_s *stream = &dctx->decomp_stream;
  215. pr_debug("avail_in %u, avail_out %u\n", req->avail_in, req->avail_out);
  216. stream->next_in = req->next_in;
  217. stream->avail_in = req->avail_in;
  218. stream->next_out = req->next_out;
  219. stream->avail_out = req->avail_out;
  220. ret = zlib_inflate(stream, Z_SYNC_FLUSH);
  221. switch (ret) {
  222. case Z_OK:
  223. case Z_STREAM_END:
  224. break;
  225. case Z_BUF_ERROR:
  226. pr_debug("zlib_inflate could not make progress\n");
  227. return -EAGAIN;
  228. default:
  229. pr_debug("zlib_inflate failed %d\n", ret);
  230. return -EINVAL;
  231. }
  232. ret = req->avail_out - stream->avail_out;
  233. pr_debug("avail_in %u, avail_out %u (consumed %u, produced %u)\n",
  234. stream->avail_in, stream->avail_out,
  235. req->avail_in - stream->avail_in, ret);
  236. req->next_in = stream->next_in;
  237. req->avail_in = stream->avail_in;
  238. req->next_out = stream->next_out;
  239. req->avail_out = stream->avail_out;
  240. return ret;
  241. }
  242. static int zlib_decompress_final(struct crypto_pcomp *tfm,
  243. struct comp_request *req)
  244. {
  245. int ret;
  246. struct zlib_ctx *dctx = crypto_tfm_ctx(crypto_pcomp_tfm(tfm));
  247. struct z_stream_s *stream = &dctx->decomp_stream;
  248. pr_debug("avail_in %u, avail_out %u\n", req->avail_in, req->avail_out);
  249. stream->next_in = req->next_in;
  250. stream->avail_in = req->avail_in;
  251. stream->next_out = req->next_out;
  252. stream->avail_out = req->avail_out;
  253. if (dctx->decomp_windowBits < 0) {
  254. ret = zlib_inflate(stream, Z_SYNC_FLUSH);
  255. /*
  256. * Work around a bug in zlib, which sometimes wants to taste an
  257. * extra byte when being used in the (undocumented) raw deflate
  258. * mode. (From USAGI).
  259. */
  260. if (ret == Z_OK && !stream->avail_in && stream->avail_out) {
  261. const void *saved_next_in = stream->next_in;
  262. u8 zerostuff = 0;
  263. stream->next_in = &zerostuff;
  264. stream->avail_in = 1;
  265. ret = zlib_inflate(stream, Z_FINISH);
  266. stream->next_in = saved_next_in;
  267. stream->avail_in = 0;
  268. }
  269. } else
  270. ret = zlib_inflate(stream, Z_FINISH);
  271. if (ret != Z_STREAM_END) {
  272. pr_debug("zlib_inflate failed %d\n", ret);
  273. return -EINVAL;
  274. }
  275. ret = req->avail_out - stream->avail_out;
  276. pr_debug("avail_in %u, avail_out %u (consumed %u, produced %u)\n",
  277. stream->avail_in, stream->avail_out,
  278. req->avail_in - stream->avail_in, ret);
  279. req->next_in = stream->next_in;
  280. req->avail_in = stream->avail_in;
  281. req->next_out = stream->next_out;
  282. req->avail_out = stream->avail_out;
  283. return ret;
  284. }
  285. static struct pcomp_alg zlib_alg = {
  286. .compress_setup = zlib_compress_setup,
  287. .compress_init = zlib_compress_init,
  288. .compress_update = zlib_compress_update,
  289. .compress_final = zlib_compress_final,
  290. .decompress_setup = zlib_decompress_setup,
  291. .decompress_init = zlib_decompress_init,
  292. .decompress_update = zlib_decompress_update,
  293. .decompress_final = zlib_decompress_final,
  294. .base = {
  295. .cra_name = "zlib",
  296. .cra_flags = CRYPTO_ALG_TYPE_PCOMPRESS,
  297. .cra_ctxsize = sizeof(struct zlib_ctx),
  298. .cra_module = THIS_MODULE,
  299. .cra_init = zlib_init,
  300. .cra_exit = zlib_exit,
  301. }
  302. };
  303. static int __init zlib_mod_init(void)
  304. {
  305. return crypto_register_pcomp(&zlib_alg);
  306. }
  307. static void __exit zlib_mod_fini(void)
  308. {
  309. crypto_unregister_pcomp(&zlib_alg);
  310. }
  311. module_init(zlib_mod_init);
  312. module_exit(zlib_mod_fini);
  313. MODULE_LICENSE("GPL");
  314. MODULE_DESCRIPTION("Zlib Compression Algorithm");
  315. MODULE_AUTHOR("Sony Corporation");