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 
0021 #include <linux/init.h>
0022 #include <linux/module.h>
0023 #include <linux/crypto.h>
0024 #include <linux/vmalloc.h>
0025 #include <linux/lz4.h>
0026 #include <crypto/internal/scompress.h>
0027 
0028 struct lz4_ctx {
0029     void *lz4_comp_mem;
0030 };
0031 
0032 static void *lz4_alloc_ctx(struct crypto_scomp *tfm)
0033 {
0034     void *ctx;
0035 
0036     ctx = vmalloc(LZ4_MEM_COMPRESS);
0037     if (!ctx)
0038         return ERR_PTR(-ENOMEM);
0039 
0040     return ctx;
0041 }
0042 
0043 static int lz4_init(struct crypto_tfm *tfm)
0044 {
0045     struct lz4_ctx *ctx = crypto_tfm_ctx(tfm);
0046 
0047     ctx->lz4_comp_mem = lz4_alloc_ctx(NULL);
0048     if (IS_ERR(ctx->lz4_comp_mem))
0049         return -ENOMEM;
0050 
0051     return 0;
0052 }
0053 
0054 static void lz4_free_ctx(struct crypto_scomp *tfm, void *ctx)
0055 {
0056     vfree(ctx);
0057 }
0058 
0059 static void lz4_exit(struct crypto_tfm *tfm)
0060 {
0061     struct lz4_ctx *ctx = crypto_tfm_ctx(tfm);
0062 
0063     lz4_free_ctx(NULL, ctx->lz4_comp_mem);
0064 }
0065 
0066 static int __lz4_compress_crypto(const u8 *src, unsigned int slen,
0067                  u8 *dst, unsigned int *dlen, void *ctx)
0068 {
0069     size_t tmp_len = *dlen;
0070     int err;
0071 
0072     err = lz4_compress(src, slen, dst, &tmp_len, ctx);
0073 
0074     if (err < 0)
0075         return -EINVAL;
0076 
0077     *dlen = tmp_len;
0078     return 0;
0079 }
0080 
0081 static int lz4_scompress(struct crypto_scomp *tfm, const u8 *src,
0082              unsigned int slen, u8 *dst, unsigned int *dlen,
0083              void *ctx)
0084 {
0085     return __lz4_compress_crypto(src, slen, dst, dlen, ctx);
0086 }
0087 
0088 static int lz4_compress_crypto(struct crypto_tfm *tfm, const u8 *src,
0089                    unsigned int slen, u8 *dst, unsigned int *dlen)
0090 {
0091     struct lz4_ctx *ctx = crypto_tfm_ctx(tfm);
0092 
0093     return __lz4_compress_crypto(src, slen, dst, dlen, ctx->lz4_comp_mem);
0094 }
0095 
0096 static int __lz4_decompress_crypto(const u8 *src, unsigned int slen,
0097                    u8 *dst, unsigned int *dlen, void *ctx)
0098 {
0099     int err;
0100     size_t tmp_len = *dlen;
0101     size_t __slen = slen;
0102 
0103     err = lz4_decompress_unknownoutputsize(src, __slen, dst, &tmp_len);
0104     if (err < 0)
0105         return -EINVAL;
0106 
0107     *dlen = tmp_len;
0108     return err;
0109 }
0110 
0111 static int lz4_sdecompress(struct crypto_scomp *tfm, const u8 *src,
0112                unsigned int slen, u8 *dst, unsigned int *dlen,
0113                void *ctx)
0114 {
0115     return __lz4_decompress_crypto(src, slen, dst, dlen, NULL);
0116 }
0117 
0118 static int lz4_decompress_crypto(struct crypto_tfm *tfm, const u8 *src,
0119                  unsigned int slen, u8 *dst,
0120                  unsigned int *dlen)
0121 {
0122     return __lz4_decompress_crypto(src, slen, dst, dlen, NULL);
0123 }
0124 
0125 static struct crypto_alg alg_lz4 = {
0126     .cra_name       = "lz4",
0127     .cra_flags      = CRYPTO_ALG_TYPE_COMPRESS,
0128     .cra_ctxsize        = sizeof(struct lz4_ctx),
0129     .cra_module     = THIS_MODULE,
0130     .cra_list       = LIST_HEAD_INIT(alg_lz4.cra_list),
0131     .cra_init       = lz4_init,
0132     .cra_exit       = lz4_exit,
0133     .cra_u          = { .compress = {
0134     .coa_compress       = lz4_compress_crypto,
0135     .coa_decompress     = lz4_decompress_crypto } }
0136 };
0137 
0138 static struct scomp_alg scomp = {
0139     .alloc_ctx      = lz4_alloc_ctx,
0140     .free_ctx       = lz4_free_ctx,
0141     .compress       = lz4_scompress,
0142     .decompress     = lz4_sdecompress,
0143     .base           = {
0144         .cra_name   = "lz4",
0145         .cra_driver_name = "lz4-scomp",
0146         .cra_module  = THIS_MODULE,
0147     }
0148 };
0149 
0150 static int __init lz4_mod_init(void)
0151 {
0152     int ret;
0153 
0154     ret = crypto_register_alg(&alg_lz4);
0155     if (ret)
0156         return ret;
0157 
0158     ret = crypto_register_scomp(&scomp);
0159     if (ret) {
0160         crypto_unregister_alg(&alg_lz4);
0161         return ret;
0162     }
0163 
0164     return ret;
0165 }
0166 
0167 static void __exit lz4_mod_fini(void)
0168 {
0169     crypto_unregister_alg(&alg_lz4);
0170     crypto_unregister_scomp(&scomp);
0171 }
0172 
0173 module_init(lz4_mod_init);
0174 module_exit(lz4_mod_fini);
0175 
0176 MODULE_LICENSE("GPL");
0177 MODULE_DESCRIPTION("LZ4 Compression Algorithm");
0178 MODULE_ALIAS_CRYPTO("lz4");