Back to home page

LXR

 
 

    


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