| 1 | --- a/crypto/Kconfig |
| 2 | +++ b/crypto/Kconfig |
| 3 | @@ -1008,6 +1008,13 @@ config CRYPTO_LZO |
| 4 | help |
| 5 | This is the LZO 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 | @@ -82,6 +82,7 @@ obj-$(CONFIG_CRYPTO_MICHAEL_MIC) += mich |
| 20 | obj-$(CONFIG_CRYPTO_CRC32C) += crc32c.o |
| 21 | obj-$(CONFIG_CRYPTO_AUTHENC) += authenc.o authencesn.o |
| 22 | obj-$(CONFIG_CRYPTO_LZO) += lzo.o |
| 23 | +obj-$(CONFIG_CRYPTO_XZ) += xz.o |
| 24 | obj-$(CONFIG_CRYPTO_RNG2) += rng.o |
| 25 | obj-$(CONFIG_CRYPTO_RNG2) += krng.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>"); |
| 147 | |