10b77abb3SZoltan Sogor /* 20b77abb3SZoltan Sogor * Cryptographic API. 30b77abb3SZoltan Sogor * 40b77abb3SZoltan Sogor * This program is free software; you can redistribute it and/or modify it 50b77abb3SZoltan Sogor * under the terms of the GNU General Public License version 2 as published by 60b77abb3SZoltan Sogor * the Free Software Foundation. 70b77abb3SZoltan Sogor * 80b77abb3SZoltan Sogor * This program is distributed in the hope that it will be useful, but WITHOUT 90b77abb3SZoltan Sogor * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 100b77abb3SZoltan Sogor * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 110b77abb3SZoltan Sogor * more details. 120b77abb3SZoltan Sogor * 130b77abb3SZoltan Sogor * You should have received a copy of the GNU General Public License along with 140b77abb3SZoltan Sogor * this program; if not, write to the Free Software Foundation, Inc., 51 150b77abb3SZoltan Sogor * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 160b77abb3SZoltan Sogor * 170b77abb3SZoltan Sogor */ 180b77abb3SZoltan Sogor 190b77abb3SZoltan Sogor #include <linux/init.h> 200b77abb3SZoltan Sogor #include <linux/module.h> 210b77abb3SZoltan Sogor #include <linux/crypto.h> 220b77abb3SZoltan Sogor #include <linux/vmalloc.h> 2342614b05SEric Dumazet #include <linux/mm.h> 240b77abb3SZoltan Sogor #include <linux/lzo.h> 25ac9d2c4bSGiovanni Cabiddu #include <crypto/internal/scompress.h> 260b77abb3SZoltan Sogor 270b77abb3SZoltan Sogor struct lzo_ctx { 280b77abb3SZoltan Sogor void *lzo_comp_mem; 290b77abb3SZoltan Sogor }; 300b77abb3SZoltan Sogor 31ac9d2c4bSGiovanni Cabiddu static void *lzo_alloc_ctx(struct crypto_scomp *tfm) 32ac9d2c4bSGiovanni Cabiddu { 33ac9d2c4bSGiovanni Cabiddu void *ctx; 34ac9d2c4bSGiovanni Cabiddu 35752ade68SMichal Hocko ctx = kvmalloc(LZO1X_MEM_COMPRESS, GFP_KERNEL); 36ac9d2c4bSGiovanni Cabiddu if (!ctx) 37ac9d2c4bSGiovanni Cabiddu return ERR_PTR(-ENOMEM); 38ac9d2c4bSGiovanni Cabiddu 39ac9d2c4bSGiovanni Cabiddu return ctx; 40ac9d2c4bSGiovanni Cabiddu } 41ac9d2c4bSGiovanni Cabiddu 420b77abb3SZoltan Sogor static int lzo_init(struct crypto_tfm *tfm) 430b77abb3SZoltan Sogor { 440b77abb3SZoltan Sogor struct lzo_ctx *ctx = crypto_tfm_ctx(tfm); 450b77abb3SZoltan Sogor 46ac9d2c4bSGiovanni Cabiddu ctx->lzo_comp_mem = lzo_alloc_ctx(NULL); 47ac9d2c4bSGiovanni Cabiddu if (IS_ERR(ctx->lzo_comp_mem)) 480b77abb3SZoltan Sogor return -ENOMEM; 490b77abb3SZoltan Sogor 500b77abb3SZoltan Sogor return 0; 510b77abb3SZoltan Sogor } 520b77abb3SZoltan Sogor 53ac9d2c4bSGiovanni Cabiddu static void lzo_free_ctx(struct crypto_scomp *tfm, void *ctx) 54ac9d2c4bSGiovanni Cabiddu { 55ac9d2c4bSGiovanni Cabiddu kvfree(ctx); 56ac9d2c4bSGiovanni Cabiddu } 57ac9d2c4bSGiovanni Cabiddu 580b77abb3SZoltan Sogor static void lzo_exit(struct crypto_tfm *tfm) 590b77abb3SZoltan Sogor { 600b77abb3SZoltan Sogor struct lzo_ctx *ctx = crypto_tfm_ctx(tfm); 610b77abb3SZoltan Sogor 62ac9d2c4bSGiovanni Cabiddu lzo_free_ctx(NULL, ctx->lzo_comp_mem); 630b77abb3SZoltan Sogor } 640b77abb3SZoltan Sogor 65ac9d2c4bSGiovanni Cabiddu static int __lzo_compress(const u8 *src, unsigned int slen, 66ac9d2c4bSGiovanni Cabiddu u8 *dst, unsigned int *dlen, void *ctx) 670b77abb3SZoltan Sogor { 680b77abb3SZoltan Sogor size_t tmp_len = *dlen; /* size_t(ulong) <-> uint on 64 bit */ 690b77abb3SZoltan Sogor int err; 700b77abb3SZoltan Sogor 71ac9d2c4bSGiovanni Cabiddu err = lzo1x_1_compress(src, slen, dst, &tmp_len, ctx); 720b77abb3SZoltan Sogor 730b77abb3SZoltan Sogor if (err != LZO_E_OK) 740b77abb3SZoltan Sogor return -EINVAL; 750b77abb3SZoltan Sogor 760b77abb3SZoltan Sogor *dlen = tmp_len; 770b77abb3SZoltan Sogor return 0; 780b77abb3SZoltan Sogor } 790b77abb3SZoltan Sogor 80ac9d2c4bSGiovanni Cabiddu static int lzo_compress(struct crypto_tfm *tfm, const u8 *src, 810b77abb3SZoltan Sogor unsigned int slen, u8 *dst, unsigned int *dlen) 820b77abb3SZoltan Sogor { 83ac9d2c4bSGiovanni Cabiddu struct lzo_ctx *ctx = crypto_tfm_ctx(tfm); 84ac9d2c4bSGiovanni Cabiddu 85ac9d2c4bSGiovanni Cabiddu return __lzo_compress(src, slen, dst, dlen, ctx->lzo_comp_mem); 86ac9d2c4bSGiovanni Cabiddu } 87ac9d2c4bSGiovanni Cabiddu 88ac9d2c4bSGiovanni Cabiddu static int lzo_scompress(struct crypto_scomp *tfm, const u8 *src, 89ac9d2c4bSGiovanni Cabiddu unsigned int slen, u8 *dst, unsigned int *dlen, 90ac9d2c4bSGiovanni Cabiddu void *ctx) 91ac9d2c4bSGiovanni Cabiddu { 92ac9d2c4bSGiovanni Cabiddu return __lzo_compress(src, slen, dst, dlen, ctx); 93ac9d2c4bSGiovanni Cabiddu } 94ac9d2c4bSGiovanni Cabiddu 95ac9d2c4bSGiovanni Cabiddu static int __lzo_decompress(const u8 *src, unsigned int slen, 96ac9d2c4bSGiovanni Cabiddu u8 *dst, unsigned int *dlen) 97ac9d2c4bSGiovanni Cabiddu { 980b77abb3SZoltan Sogor int err; 990b77abb3SZoltan Sogor size_t tmp_len = *dlen; /* size_t(ulong) <-> uint on 64 bit */ 1000b77abb3SZoltan Sogor 1010b77abb3SZoltan Sogor err = lzo1x_decompress_safe(src, slen, dst, &tmp_len); 1020b77abb3SZoltan Sogor 1030b77abb3SZoltan Sogor if (err != LZO_E_OK) 1040b77abb3SZoltan Sogor return -EINVAL; 1050b77abb3SZoltan Sogor 1060b77abb3SZoltan Sogor *dlen = tmp_len; 1070b77abb3SZoltan Sogor return 0; 108ac9d2c4bSGiovanni Cabiddu } 1090b77abb3SZoltan Sogor 110ac9d2c4bSGiovanni Cabiddu static int lzo_decompress(struct crypto_tfm *tfm, const u8 *src, 111ac9d2c4bSGiovanni Cabiddu unsigned int slen, u8 *dst, unsigned int *dlen) 112ac9d2c4bSGiovanni Cabiddu { 113ac9d2c4bSGiovanni Cabiddu return __lzo_decompress(src, slen, dst, dlen); 114ac9d2c4bSGiovanni Cabiddu } 115ac9d2c4bSGiovanni Cabiddu 116ac9d2c4bSGiovanni Cabiddu static int lzo_sdecompress(struct crypto_scomp *tfm, const u8 *src, 117ac9d2c4bSGiovanni Cabiddu unsigned int slen, u8 *dst, unsigned int *dlen, 118ac9d2c4bSGiovanni Cabiddu void *ctx) 119ac9d2c4bSGiovanni Cabiddu { 120ac9d2c4bSGiovanni Cabiddu return __lzo_decompress(src, slen, dst, dlen); 1210b77abb3SZoltan Sogor } 1220b77abb3SZoltan Sogor 1230b77abb3SZoltan Sogor static struct crypto_alg alg = { 1240b77abb3SZoltan Sogor .cra_name = "lzo", 1250b77abb3SZoltan Sogor .cra_flags = CRYPTO_ALG_TYPE_COMPRESS, 1260b77abb3SZoltan Sogor .cra_ctxsize = sizeof(struct lzo_ctx), 1270b77abb3SZoltan Sogor .cra_module = THIS_MODULE, 1280b77abb3SZoltan Sogor .cra_init = lzo_init, 1290b77abb3SZoltan Sogor .cra_exit = lzo_exit, 1300b77abb3SZoltan Sogor .cra_u = { .compress = { 1310b77abb3SZoltan Sogor .coa_compress = lzo_compress, 1320b77abb3SZoltan Sogor .coa_decompress = lzo_decompress } } 1330b77abb3SZoltan Sogor }; 1340b77abb3SZoltan Sogor 135ac9d2c4bSGiovanni Cabiddu static struct scomp_alg scomp = { 136ac9d2c4bSGiovanni Cabiddu .alloc_ctx = lzo_alloc_ctx, 137ac9d2c4bSGiovanni Cabiddu .free_ctx = lzo_free_ctx, 138ac9d2c4bSGiovanni Cabiddu .compress = lzo_scompress, 139ac9d2c4bSGiovanni Cabiddu .decompress = lzo_sdecompress, 140ac9d2c4bSGiovanni Cabiddu .base = { 141ac9d2c4bSGiovanni Cabiddu .cra_name = "lzo", 142ac9d2c4bSGiovanni Cabiddu .cra_driver_name = "lzo-scomp", 143ac9d2c4bSGiovanni Cabiddu .cra_module = THIS_MODULE, 144ac9d2c4bSGiovanni Cabiddu } 145ac9d2c4bSGiovanni Cabiddu }; 146ac9d2c4bSGiovanni Cabiddu 1473af5b90bSKamalesh Babulal static int __init lzo_mod_init(void) 1480b77abb3SZoltan Sogor { 149ac9d2c4bSGiovanni Cabiddu int ret; 150ac9d2c4bSGiovanni Cabiddu 151ac9d2c4bSGiovanni Cabiddu ret = crypto_register_alg(&alg); 152ac9d2c4bSGiovanni Cabiddu if (ret) 153ac9d2c4bSGiovanni Cabiddu return ret; 154ac9d2c4bSGiovanni Cabiddu 155ac9d2c4bSGiovanni Cabiddu ret = crypto_register_scomp(&scomp); 156ac9d2c4bSGiovanni Cabiddu if (ret) { 157ac9d2c4bSGiovanni Cabiddu crypto_unregister_alg(&alg); 158ac9d2c4bSGiovanni Cabiddu return ret; 159ac9d2c4bSGiovanni Cabiddu } 160ac9d2c4bSGiovanni Cabiddu 161ac9d2c4bSGiovanni Cabiddu return ret; 1620b77abb3SZoltan Sogor } 1630b77abb3SZoltan Sogor 1643af5b90bSKamalesh Babulal static void __exit lzo_mod_fini(void) 1650b77abb3SZoltan Sogor { 1660b77abb3SZoltan Sogor crypto_unregister_alg(&alg); 167ac9d2c4bSGiovanni Cabiddu crypto_unregister_scomp(&scomp); 1680b77abb3SZoltan Sogor } 1690b77abb3SZoltan Sogor 170*c4741b23SEric Biggers subsys_initcall(lzo_mod_init); 1713af5b90bSKamalesh Babulal module_exit(lzo_mod_fini); 1720b77abb3SZoltan Sogor 1730b77abb3SZoltan Sogor MODULE_LICENSE("GPL"); 1740b77abb3SZoltan Sogor MODULE_DESCRIPTION("LZO Compression Algorithm"); 1755d26a105SKees Cook MODULE_ALIAS_CRYPTO("lzo"); 176