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> 23*42614b05SEric Dumazet #include <linux/mm.h> 240b77abb3SZoltan Sogor #include <linux/lzo.h> 250b77abb3SZoltan Sogor 260b77abb3SZoltan Sogor struct lzo_ctx { 270b77abb3SZoltan Sogor void *lzo_comp_mem; 280b77abb3SZoltan Sogor }; 290b77abb3SZoltan Sogor 300b77abb3SZoltan Sogor static int lzo_init(struct crypto_tfm *tfm) 310b77abb3SZoltan Sogor { 320b77abb3SZoltan Sogor struct lzo_ctx *ctx = crypto_tfm_ctx(tfm); 330b77abb3SZoltan Sogor 34*42614b05SEric Dumazet ctx->lzo_comp_mem = kmalloc(LZO1X_MEM_COMPRESS, 35*42614b05SEric Dumazet GFP_KERNEL | __GFP_NOWARN | __GFP_REPEAT); 36*42614b05SEric Dumazet if (!ctx->lzo_comp_mem) 370b77abb3SZoltan Sogor ctx->lzo_comp_mem = vmalloc(LZO1X_MEM_COMPRESS); 380b77abb3SZoltan Sogor if (!ctx->lzo_comp_mem) 390b77abb3SZoltan Sogor return -ENOMEM; 400b77abb3SZoltan Sogor 410b77abb3SZoltan Sogor return 0; 420b77abb3SZoltan Sogor } 430b77abb3SZoltan Sogor 440b77abb3SZoltan Sogor static void lzo_exit(struct crypto_tfm *tfm) 450b77abb3SZoltan Sogor { 460b77abb3SZoltan Sogor struct lzo_ctx *ctx = crypto_tfm_ctx(tfm); 470b77abb3SZoltan Sogor 48*42614b05SEric Dumazet if (is_vmalloc_addr(ctx->lzo_comp_mem)) 490b77abb3SZoltan Sogor vfree(ctx->lzo_comp_mem); 50*42614b05SEric Dumazet else 51*42614b05SEric Dumazet kfree(ctx->lzo_comp_mem); 520b77abb3SZoltan Sogor } 530b77abb3SZoltan Sogor 540b77abb3SZoltan Sogor static int lzo_compress(struct crypto_tfm *tfm, const u8 *src, 550b77abb3SZoltan Sogor unsigned int slen, u8 *dst, unsigned int *dlen) 560b77abb3SZoltan Sogor { 570b77abb3SZoltan Sogor struct lzo_ctx *ctx = crypto_tfm_ctx(tfm); 580b77abb3SZoltan Sogor size_t tmp_len = *dlen; /* size_t(ulong) <-> uint on 64 bit */ 590b77abb3SZoltan Sogor int err; 600b77abb3SZoltan Sogor 610b77abb3SZoltan Sogor err = lzo1x_1_compress(src, slen, dst, &tmp_len, ctx->lzo_comp_mem); 620b77abb3SZoltan Sogor 630b77abb3SZoltan Sogor if (err != LZO_E_OK) 640b77abb3SZoltan Sogor return -EINVAL; 650b77abb3SZoltan Sogor 660b77abb3SZoltan Sogor *dlen = tmp_len; 670b77abb3SZoltan Sogor return 0; 680b77abb3SZoltan Sogor } 690b77abb3SZoltan Sogor 700b77abb3SZoltan Sogor static int lzo_decompress(struct crypto_tfm *tfm, const u8 *src, 710b77abb3SZoltan Sogor unsigned int slen, u8 *dst, unsigned int *dlen) 720b77abb3SZoltan Sogor { 730b77abb3SZoltan Sogor int err; 740b77abb3SZoltan Sogor size_t tmp_len = *dlen; /* size_t(ulong) <-> uint on 64 bit */ 750b77abb3SZoltan Sogor 760b77abb3SZoltan Sogor err = lzo1x_decompress_safe(src, slen, dst, &tmp_len); 770b77abb3SZoltan Sogor 780b77abb3SZoltan Sogor if (err != LZO_E_OK) 790b77abb3SZoltan Sogor return -EINVAL; 800b77abb3SZoltan Sogor 810b77abb3SZoltan Sogor *dlen = tmp_len; 820b77abb3SZoltan Sogor return 0; 830b77abb3SZoltan Sogor 840b77abb3SZoltan Sogor } 850b77abb3SZoltan Sogor 860b77abb3SZoltan Sogor static struct crypto_alg alg = { 870b77abb3SZoltan Sogor .cra_name = "lzo", 880b77abb3SZoltan Sogor .cra_flags = CRYPTO_ALG_TYPE_COMPRESS, 890b77abb3SZoltan Sogor .cra_ctxsize = sizeof(struct lzo_ctx), 900b77abb3SZoltan Sogor .cra_module = THIS_MODULE, 910b77abb3SZoltan Sogor .cra_init = lzo_init, 920b77abb3SZoltan Sogor .cra_exit = lzo_exit, 930b77abb3SZoltan Sogor .cra_u = { .compress = { 940b77abb3SZoltan Sogor .coa_compress = lzo_compress, 950b77abb3SZoltan Sogor .coa_decompress = lzo_decompress } } 960b77abb3SZoltan Sogor }; 970b77abb3SZoltan Sogor 983af5b90bSKamalesh Babulal static int __init lzo_mod_init(void) 990b77abb3SZoltan Sogor { 1000b77abb3SZoltan Sogor return crypto_register_alg(&alg); 1010b77abb3SZoltan Sogor } 1020b77abb3SZoltan Sogor 1033af5b90bSKamalesh Babulal static void __exit lzo_mod_fini(void) 1040b77abb3SZoltan Sogor { 1050b77abb3SZoltan Sogor crypto_unregister_alg(&alg); 1060b77abb3SZoltan Sogor } 1070b77abb3SZoltan Sogor 1083af5b90bSKamalesh Babulal module_init(lzo_mod_init); 1093af5b90bSKamalesh Babulal module_exit(lzo_mod_fini); 1100b77abb3SZoltan Sogor 1110b77abb3SZoltan Sogor MODULE_LICENSE("GPL"); 1120b77abb3SZoltan Sogor MODULE_DESCRIPTION("LZO Compression Algorithm"); 113