Back to home page

LXR

 
 

    


0001 /*
0002  * Cryptographic API.
0003  *
0004  * Copyright (c) 2013 Chanho Min <chanho.min@lge.com>
0005  *
0006  * This program is free software; you can redistribute it and/or modify it
0007  * under the terms of the GNU General Public License version 2 as published by
0008  * the Free Software Foundation.
0009  *
0010  * This program is distributed in the hope that it will be useful, but WITHOUT
0011  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0012  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
0013  * more details.
0014  *
0015  * You should have received a copy of the GNU General Public License along with
0016  * this program; if not, write to the Free Software Foundation, Inc., 51
0017  * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
0018  *
0019  */
0020 #include <linux/init.h>
0021 #include <linux/module.h>
0022 #include <linux/crypto.h>
0023 #include <linux/vmalloc.h>
0024 #include <linux/lz4.h>
0025 #include <crypto/internal/scompress.h>
0026 
0027 struct lz4hc_ctx {
0028     void *lz4hc_comp_mem;
0029 };
0030 
0031 static void *lz4hc_alloc_ctx(struct crypto_scomp *tfm)
0032 {
0033     void *ctx;
0034 
0035     ctx = vmalloc(LZ4HC_MEM_COMPRESS);
0036     if (!ctx)
0037         return ERR_PTR(-ENOMEM);
0038 
0039     return ctx;
0040 }
0041 
0042 static int lz4hc_init(struct crypto_tfm *tfm)
0043 {
0044     struct lz4hc_ctx *ctx = crypto_tfm_ctx(tfm);
0045 
0046     ctx->lz4hc_comp_mem = lz4hc_alloc_ctx(NULL);
0047     if (IS_ERR(ctx->lz4hc_comp_mem))
0048         return -ENOMEM;
0049 
0050     return 0;
0051 }
0052 
0053 static void lz4hc_free_ctx(struct crypto_scomp *tfm, void *ctx)
0054 {
0055     vfree(ctx);
0056 }
0057 
0058 static void lz4hc_exit(struct crypto_tfm *tfm)
0059 {
0060     struct lz4hc_ctx *ctx = crypto_tfm_ctx(tfm);
0061 
0062     lz4hc_free_ctx(NULL, ctx->lz4hc_comp_mem);
0063 }
0064 
0065 static int __lz4hc_compress_crypto(const u8 *src, unsigned int slen,
0066                    u8 *dst, unsigned int *dlen, void *ctx)
0067 {
0068     size_t tmp_len = *dlen;
0069     int err;
0070 
0071     err = lz4hc_compress(src, slen, dst, &tmp_len, ctx);
0072 
0073     if (err < 0)
0074         return -EINVAL;
0075 
0076     *dlen = tmp_len;
0077     return 0;
0078 }
0079 
0080 static int lz4hc_scompress(struct crypto_scomp *tfm, const u8 *src,
0081                unsigned int slen, u8 *dst, unsigned int *dlen,
0082                void *ctx)
0083 {
0084     return __lz4hc_compress_crypto(src, slen, dst, dlen, ctx);
0085 }
0086 
0087 static int lz4hc_compress_crypto(struct crypto_tfm *tfm, const u8 *src,
0088                  unsigned int slen, u8 *dst,
0089                  unsigned int *dlen)
0090 {
0091     struct lz4hc_ctx *ctx = crypto_tfm_ctx(tfm);
0092 
0093     return __lz4hc_compress_crypto(src, slen, dst, dlen,
0094                     ctx->lz4hc_comp_mem);
0095 }
0096 
0097 static int __lz4hc_decompress_crypto(const u8 *src, unsigned int slen,
0098                      u8 *dst, unsigned int *dlen, void *ctx)
0099 {
0100     int err;
0101     size_t tmp_len = *dlen;
0102     size_t __slen = slen;
0103 
0104     err = lz4_decompress_unknownoutputsize(src, __slen, dst, &tmp_len);
0105     if (err < 0)
0106         return -EINVAL;
0107 
0108     *dlen = tmp_len;
0109     return err;
0110 }
0111 
0112 static int lz4hc_sdecompress(struct crypto_scomp *tfm, const u8 *src,
0113                  unsigned int slen, u8 *dst, unsigned int *dlen,
0114                  void *ctx)
0115 {
0116     return __lz4hc_decompress_crypto(src, slen, dst, dlen, NULL);
0117 }
0118 
0119 static int lz4hc_decompress_crypto(struct crypto_tfm *tfm, const u8 *src,
0120                    unsigned int slen, u8 *dst,
0121                    unsigned int *dlen)
0122 {
0123     return __lz4hc_decompress_crypto(src, slen, dst, dlen, NULL);
0124 }
0125 
0126 static struct crypto_alg alg_lz4hc = {
0127     .cra_name       = "lz4hc",
0128     .cra_flags      = CRYPTO_ALG_TYPE_COMPRESS,
0129     .cra_ctxsize        = sizeof(struct lz4hc_ctx),
0130     .cra_module     = THIS_MODULE,
0131     .cra_list       = LIST_HEAD_INIT(alg_lz4hc.cra_list),
0132     .cra_init       = lz4hc_init,
0133     .cra_exit       = lz4hc_exit,
0134     .cra_u          = { .compress = {
0135     .coa_compress       = lz4hc_compress_crypto,
0136     .coa_decompress     = lz4hc_decompress_crypto } }
0137 };
0138 
0139 static struct scomp_alg scomp = {
0140     .alloc_ctx      = lz4hc_alloc_ctx,
0141     .free_ctx       = lz4hc_free_ctx,
0142     .compress       = lz4hc_scompress,
0143     .decompress     = lz4hc_sdecompress,
0144     .base           = {
0145         .cra_name   = "lz4hc",
0146         .cra_driver_name = "lz4hc-scomp",
0147         .cra_module  = THIS_MODULE,
0148     }
0149 };
0150 
0151 static int __init lz4hc_mod_init(void)
0152 {
0153     int ret;
0154 
0155     ret = crypto_register_alg(&alg_lz4hc);
0156     if (ret)
0157         return ret;
0158 
0159     ret = crypto_register_scomp(&scomp);
0160     if (ret) {
0161         crypto_unregister_alg(&alg_lz4hc);
0162         return ret;
0163     }
0164 
0165     return ret;
0166 }
0167 
0168 static void __exit lz4hc_mod_fini(void)
0169 {
0170     crypto_unregister_alg(&alg_lz4hc);
0171     crypto_unregister_scomp(&scomp);
0172 }
0173 
0174 module_init(lz4hc_mod_init);
0175 module_exit(lz4hc_mod_fini);
0176 
0177 MODULE_LICENSE("GPL");
0178 MODULE_DESCRIPTION("LZ4HC Compression Algorithm");
0179 MODULE_ALIAS_CRYPTO("lz4hc");