cregit-Linux how code gets into the kernel

Release 4.9 crypto/deflate.c

Directory: crypto
/*
 * Cryptographic API.
 *
 * Deflate algorithm (RFC 1951), implemented here primarily for use
 * by IPCOMP (RFC 3173 & RFC 2394).
 *
 * Copyright (c) 2003 James Morris <jmorris@intercode.com.au>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * FIXME: deflate transforms will require up to a total of about 436k of kernel
 * memory on i386 (390k for compression, the rest for decompression), as the
 * current zlib kernel code uses a worst case pre-allocation system by default.
 * This needs to be fixed so that the amount of memory required is properly
 * related to the  winbits and memlevel parameters.
 *
 * The default winbits of 11 should suit most packets, and it may be something
 * to configure on a per-tfm basis in the future.
 *
 * Currently, compression history is not maintained between tfm calls, as
 * it is not needed for IPCOMP and keeps the code simpler.  It can be
 * implemented if someone wants it.
 */
#include <linux/init.h>
#include <linux/module.h>
#include <linux/crypto.h>
#include <linux/zlib.h>
#include <linux/vmalloc.h>
#include <linux/interrupt.h>
#include <linux/mm.h>
#include <linux/net.h>


#define DEFLATE_DEF_LEVEL		Z_DEFAULT_COMPRESSION

#define DEFLATE_DEF_WINBITS		11

#define DEFLATE_DEF_MEMLEVEL		MAX_MEM_LEVEL


struct deflate_ctx {
	
struct z_stream_s comp_stream;
	
struct z_stream_s decomp_stream;
};


static int deflate_comp_init(struct deflate_ctx *ctx) { int ret = 0; struct z_stream_s *stream = &ctx->comp_stream; stream->workspace = vzalloc(zlib_deflate_workspacesize( -DEFLATE_DEF_WINBITS, DEFLATE_DEF_MEMLEVEL)); if (!stream->workspace) { ret = -ENOMEM; goto out; } ret = zlib_deflateInit2(stream, DEFLATE_DEF_LEVEL, Z_DEFLATED, -DEFLATE_DEF_WINBITS, DEFLATE_DEF_MEMLEVEL, Z_DEFAULT_STRATEGY); if (ret != Z_OK) { ret = -EINVAL; goto out_free; } out: return ret; out_free: vfree(stream->workspace); goto out; }

Contributors

PersonTokensPropCommitsCommitProp
james morrisjames morris10293.58%133.33%
james kenistonjames keniston65.50%133.33%
joe perchesjoe perches10.92%133.33%
Total109100.00%3100.00%


static int deflate_decomp_init(struct deflate_ctx *ctx) { int ret = 0; struct z_stream_s *stream = &ctx->decomp_stream; stream->workspace = vzalloc(zlib_inflate_workspacesize()); if (!stream->workspace) { ret = -ENOMEM; goto out; } ret = zlib_inflateInit2(stream, -DEFLATE_DEF_WINBITS); if (ret != Z_OK) { ret = -EINVAL; goto out_free; } out: return ret; out_free: vfree(stream->workspace); goto out; }

Contributors

PersonTokensPropCommitsCommitProp
james morrisjames morris9497.92%150.00%
david s. millerdavid s. miller22.08%150.00%
Total96100.00%2100.00%


static void deflate_comp_exit(struct deflate_ctx *ctx) { zlib_deflateEnd(&ctx->comp_stream); vfree(ctx->comp_stream.workspace); }

Contributors

PersonTokensPropCommitsCommitProp
james morrisjames morris2071.43%150.00%
artem bityutskiyartem bityutskiy828.57%150.00%
Total28100.00%2100.00%


static void deflate_decomp_exit(struct deflate_ctx *ctx) { zlib_inflateEnd(&ctx->decomp_stream); vfree(ctx->decomp_stream.workspace); }

Contributors

PersonTokensPropCommitsCommitProp
james morrisjames morris1967.86%133.33%
artem bityutskiyartem bityutskiy828.57%133.33%
david s. millerdavid s. miller13.57%133.33%
Total28100.00%3100.00%


static int deflate_init(struct crypto_tfm *tfm) { struct deflate_ctx *ctx = crypto_tfm_ctx(tfm); int ret; ret = deflate_comp_init(ctx); if (ret) goto out; ret = deflate_decomp_init(ctx); if (ret) deflate_comp_exit(ctx); out: return ret; }

Contributors

PersonTokensPropCommitsCommitProp
james morrisjames morris4677.97%150.00%
herbert xuherbert xu1322.03%150.00%
Total59100.00%2100.00%


static void deflate_exit(struct crypto_tfm *tfm) { struct deflate_ctx *ctx = crypto_tfm_ctx(tfm); deflate_comp_exit(ctx); deflate_decomp_exit(ctx); }

Contributors

PersonTokensPropCommitsCommitProp
james morrisjames morris1858.06%150.00%
herbert xuherbert xu1341.94%150.00%
Total31100.00%2100.00%


static int deflate_compress(struct crypto_tfm *tfm, const u8 *src, unsigned int slen, u8 *dst, unsigned int *dlen) { int ret = 0; struct deflate_ctx *dctx = crypto_tfm_ctx(tfm); struct z_stream_s *stream = &dctx->comp_stream; ret = zlib_deflateReset(stream); if (ret != Z_OK) { ret = -EINVAL; goto out; } stream->next_in = (u8 *)src; stream->avail_in = slen; stream->next_out = (u8 *)dst; stream->avail_out = *dlen; ret = zlib_deflate(stream, Z_FINISH); if (ret != Z_STREAM_END) { ret = -EINVAL; goto out; } ret = 0; *dlen = stream->total_out; out: return ret; }

Contributors

PersonTokensPropCommitsCommitProp
james morrisjames morris14495.36%150.00%
herbert xuherbert xu74.64%150.00%
Total151100.00%2100.00%


static int deflate_decompress(struct crypto_tfm *tfm, const u8 *src, unsigned int slen, u8 *dst, unsigned int *dlen) { int ret = 0; struct deflate_ctx *dctx = crypto_tfm_ctx(tfm); struct z_stream_s *stream = &dctx->decomp_stream; ret = zlib_inflateReset(stream); if (ret != Z_OK) { ret = -EINVAL; goto out; } stream->next_in = (u8 *)src; stream->avail_in = slen; stream->next_out = (u8 *)dst; stream->avail_out = *dlen; ret = zlib_inflate(stream, Z_SYNC_FLUSH); /* * Work around a bug in zlib, which sometimes wants to taste an extra * byte when being used in the (undocumented) raw deflate mode. * (From USAGI). */ if (ret == Z_OK && !stream->avail_in && stream->avail_out) { u8 zerostuff = 0; stream->next_in = &zerostuff; stream->avail_in = 1; ret = zlib_inflate(stream, Z_FINISH); } if (ret != Z_STREAM_END) { ret = -EINVAL; goto out; } ret = 0; *dlen = stream->total_out; out: return ret; }

Contributors

PersonTokensPropCommitsCommitProp
james morrisjames morris18996.43%266.67%
herbert xuherbert xu73.57%133.33%
Total196100.00%3100.00%

static struct crypto_alg alg = { .cra_name = "deflate", .cra_flags = CRYPTO_ALG_TYPE_COMPRESS, .cra_ctxsize = sizeof(struct deflate_ctx), .cra_module = THIS_MODULE, .cra_init = deflate_init, .cra_exit = deflate_exit, .cra_u = { .compress = { .coa_compress = deflate_compress, .coa_decompress = deflate_decompress } } };
static int __init deflate_mod_init(void) { return crypto_register_alg(&alg); }

Contributors

PersonTokensPropCommitsCommitProp
james morrisjames morris1593.75%150.00%
kamalesh babulalkamalesh babulal16.25%150.00%
Total16100.00%2100.00%


static void __exit deflate_mod_fini(void) { crypto_unregister_alg(&alg); }

Contributors

PersonTokensPropCommitsCommitProp
james morrisjames morris1493.33%150.00%
kamalesh babulalkamalesh babulal16.67%150.00%
Total15100.00%2100.00%

module_init(deflate_mod_init); module_exit(deflate_mod_fini); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Deflate Compression Algorithm for IPCOMP"); MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>"); MODULE_ALIAS_CRYPTO("deflate");

Overall Contributors

PersonTokensPropCommitsCommitProp
james morrisjames morris78490.11%325.00%
herbert xuherbert xu505.75%216.67%
artem bityutskiyartem bityutskiy161.84%18.33%
james kenistonjames keniston60.69%18.33%
kees cookkees cook50.57%18.33%
kamalesh babulalkamalesh babulal40.46%18.33%
david s. millerdavid s. miller30.34%18.33%
joe perchesjoe perches10.11%18.33%
richard hartmannrichard hartmann10.11%18.33%
Total870100.00%12100.00%
Directory: crypto