d2f9244ef5479c1f18786ffd9ca30db692297996
[openwrt/openwrt.git] / target / linux / generic / patches-4.4 / 540-crypto-xz-decompression-support.patch
1 --- a/crypto/Kconfig
2 +++ b/crypto/Kconfig
3 @@ -1545,6 +1545,13 @@ config CRYPTO_LZ4HC
4 help
5 This is the LZ4 high compression mode algorithm.
6
7 +config CRYPTO_XZ
8 + tristate "XZ compression algorithm"
9 + select CRYPTO_ALGAPI
10 + select XZ_DEC
11 + help
12 + This is the XZ algorithm. Only decompression is supported for now.
13 +
14 comment "Random Number Generation"
15
16 config CRYPTO_ANSI_CPRNG
17 --- a/crypto/Makefile
18 +++ b/crypto/Makefile
19 @@ -107,6 +107,7 @@ obj-$(CONFIG_CRYPTO_AUTHENC) += authenc.
20 obj-$(CONFIG_CRYPTO_LZO) += lzo.o
21 obj-$(CONFIG_CRYPTO_LZ4) += lz4.o
22 obj-$(CONFIG_CRYPTO_LZ4HC) += lz4hc.o
23 +obj-$(CONFIG_CRYPTO_XZ) += xz.o
24 obj-$(CONFIG_CRYPTO_842) += 842.o
25 obj-$(CONFIG_CRYPTO_RNG2) += rng.o
26 obj-$(CONFIG_CRYPTO_ANSI_CPRNG) += ansi_cprng.o
27 --- /dev/null
28 +++ b/crypto/xz.c
29 @@ -0,0 +1,117 @@
30 +/*
31 + * Cryptographic API.
32 + *
33 + * XZ decompression support.
34 + *
35 + * Copyright (c) 2012 Gabor Juhos <juhosg@openwrt.org>
36 + *
37 + * This program is free software; you can redistribute it and/or modify it
38 + * under the terms of the GNU General Public License version 2 as published by
39 + * the Free Software Foundation.
40 + *
41 + */
42 +#include <linux/init.h>
43 +#include <linux/module.h>
44 +#include <linux/crypto.h>
45 +#include <linux/xz.h>
46 +#include <linux/interrupt.h>
47 +#include <linux/mm.h>
48 +#include <linux/net.h>
49 +
50 +struct xz_comp_ctx {
51 + struct xz_dec *decomp_state;
52 + struct xz_buf decomp_buf;
53 +};
54 +
55 +static int crypto_xz_decomp_init(struct xz_comp_ctx *ctx)
56 +{
57 + ctx->decomp_state = xz_dec_init(XZ_SINGLE, 0);
58 + if (!ctx->decomp_state)
59 + return -ENOMEM;
60 +
61 + return 0;
62 +}
63 +
64 +static void crypto_xz_decomp_exit(struct xz_comp_ctx *ctx)
65 +{
66 + xz_dec_end(ctx->decomp_state);
67 +}
68 +
69 +static int crypto_xz_init(struct crypto_tfm *tfm)
70 +{
71 + struct xz_comp_ctx *ctx = crypto_tfm_ctx(tfm);
72 +
73 + return crypto_xz_decomp_init(ctx);
74 +}
75 +
76 +static void crypto_xz_exit(struct crypto_tfm *tfm)
77 +{
78 + struct xz_comp_ctx *ctx = crypto_tfm_ctx(tfm);
79 +
80 + crypto_xz_decomp_exit(ctx);
81 +}
82 +
83 +static int crypto_xz_compress(struct crypto_tfm *tfm, const u8 *src,
84 + unsigned int slen, u8 *dst, unsigned int *dlen)
85 +{
86 + return -EOPNOTSUPP;
87 +}
88 +
89 +static int crypto_xz_decompress(struct crypto_tfm *tfm, const u8 *src,
90 + unsigned int slen, u8 *dst, unsigned int *dlen)
91 +{
92 + struct xz_comp_ctx *dctx = crypto_tfm_ctx(tfm);
93 + struct xz_buf *xz_buf = &dctx->decomp_buf;
94 + int ret;
95 +
96 + memset(xz_buf, '\0', sizeof(struct xz_buf));
97 +
98 + xz_buf->in = (u8 *) src;
99 + xz_buf->in_pos = 0;
100 + xz_buf->in_size = slen;
101 + xz_buf->out = (u8 *) dst;
102 + xz_buf->out_pos = 0;
103 + xz_buf->out_size = *dlen;
104 +
105 + ret = xz_dec_run(dctx->decomp_state, xz_buf);
106 + if (ret != XZ_STREAM_END) {
107 + ret = -EINVAL;
108 + goto out;
109 + }
110 +
111 + *dlen = xz_buf->out_pos;
112 + ret = 0;
113 +
114 +out:
115 + return ret;
116 +}
117 +
118 +static struct crypto_alg crypto_xz_alg = {
119 + .cra_name = "xz",
120 + .cra_flags = CRYPTO_ALG_TYPE_COMPRESS,
121 + .cra_ctxsize = sizeof(struct xz_comp_ctx),
122 + .cra_module = THIS_MODULE,
123 + .cra_list = LIST_HEAD_INIT(crypto_xz_alg.cra_list),
124 + .cra_init = crypto_xz_init,
125 + .cra_exit = crypto_xz_exit,
126 + .cra_u = { .compress = {
127 + .coa_compress = crypto_xz_compress,
128 + .coa_decompress = crypto_xz_decompress } }
129 +};
130 +
131 +static int __init crypto_xz_mod_init(void)
132 +{
133 + return crypto_register_alg(&crypto_xz_alg);
134 +}
135 +
136 +static void __exit crypto_xz_mod_exit(void)
137 +{
138 + crypto_unregister_alg(&crypto_xz_alg);
139 +}
140 +
141 +module_init(crypto_xz_mod_init);
142 +module_exit(crypto_xz_mod_exit);
143 +
144 +MODULE_LICENSE("GPL v2");
145 +MODULE_DESCRIPTION("Crypto XZ decompression support");
146 +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");