Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0-only 2 : : /* 3 : : * Cryptographic API. 4 : : */ 5 : : 6 : : #include <linux/init.h> 7 : : #include <linux/module.h> 8 : : #include <linux/crypto.h> 9 : : #include <linux/vmalloc.h> 10 : : #include <linux/mm.h> 11 : : #include <linux/lzo.h> 12 : : #include <crypto/internal/scompress.h> 13 : : 14 : : struct lzo_ctx { 15 : : void *lzo_comp_mem; 16 : : }; 17 : : 18 : 0 : static void *lzo_alloc_ctx(struct crypto_scomp *tfm) 19 : : { 20 : : void *ctx; 21 : : 22 : : ctx = kvmalloc(LZO1X_MEM_COMPRESS, GFP_KERNEL); 23 : 0 : if (!ctx) 24 : : return ERR_PTR(-ENOMEM); 25 : : 26 : 0 : return ctx; 27 : : } 28 : : 29 : 0 : static int lzo_init(struct crypto_tfm *tfm) 30 : : { 31 : : struct lzo_ctx *ctx = crypto_tfm_ctx(tfm); 32 : : 33 : 0 : ctx->lzo_comp_mem = lzo_alloc_ctx(NULL); 34 : 0 : if (IS_ERR(ctx->lzo_comp_mem)) 35 : : return -ENOMEM; 36 : : 37 : 0 : return 0; 38 : : } 39 : : 40 : 0 : static void lzo_free_ctx(struct crypto_scomp *tfm, void *ctx) 41 : : { 42 : 0 : kvfree(ctx); 43 : 0 : } 44 : : 45 : 0 : static void lzo_exit(struct crypto_tfm *tfm) 46 : : { 47 : : struct lzo_ctx *ctx = crypto_tfm_ctx(tfm); 48 : : 49 : 0 : lzo_free_ctx(NULL, ctx->lzo_comp_mem); 50 : 0 : } 51 : : 52 : : static int __lzo_compress(const u8 *src, unsigned int slen, 53 : : u8 *dst, unsigned int *dlen, void *ctx) 54 : : { 55 : 0 : size_t tmp_len = *dlen; /* size_t(ulong) <-> uint on 64 bit */ 56 : : int err; 57 : : 58 : 0 : err = lzo1x_1_compress(src, slen, dst, &tmp_len, ctx); 59 : : 60 : 0 : if (err != LZO_E_OK) 61 : : return -EINVAL; 62 : : 63 : 0 : *dlen = tmp_len; 64 : : return 0; 65 : : } 66 : : 67 : 0 : static int lzo_compress(struct crypto_tfm *tfm, const u8 *src, 68 : : unsigned int slen, u8 *dst, unsigned int *dlen) 69 : : { 70 : : struct lzo_ctx *ctx = crypto_tfm_ctx(tfm); 71 : : 72 : 0 : return __lzo_compress(src, slen, dst, dlen, ctx->lzo_comp_mem); 73 : : } 74 : : 75 : 0 : static int lzo_scompress(struct crypto_scomp *tfm, const u8 *src, 76 : : unsigned int slen, u8 *dst, unsigned int *dlen, 77 : : void *ctx) 78 : : { 79 : 0 : return __lzo_compress(src, slen, dst, dlen, ctx); 80 : : } 81 : : 82 : : static int __lzo_decompress(const u8 *src, unsigned int slen, 83 : : u8 *dst, unsigned int *dlen) 84 : : { 85 : : int err; 86 : 0 : size_t tmp_len = *dlen; /* size_t(ulong) <-> uint on 64 bit */ 87 : : 88 : 0 : err = lzo1x_decompress_safe(src, slen, dst, &tmp_len); 89 : : 90 : 0 : if (err != LZO_E_OK) 91 : : return -EINVAL; 92 : : 93 : 0 : *dlen = tmp_len; 94 : : return 0; 95 : : } 96 : : 97 : 0 : static int lzo_decompress(struct crypto_tfm *tfm, const u8 *src, 98 : : unsigned int slen, u8 *dst, unsigned int *dlen) 99 : : { 100 : 0 : return __lzo_decompress(src, slen, dst, dlen); 101 : : } 102 : : 103 : 0 : static int lzo_sdecompress(struct crypto_scomp *tfm, const u8 *src, 104 : : unsigned int slen, u8 *dst, unsigned int *dlen, 105 : : void *ctx) 106 : : { 107 : 0 : return __lzo_decompress(src, slen, dst, dlen); 108 : : } 109 : : 110 : : static struct crypto_alg alg = { 111 : : .cra_name = "lzo", 112 : : .cra_driver_name = "lzo-generic", 113 : : .cra_flags = CRYPTO_ALG_TYPE_COMPRESS, 114 : : .cra_ctxsize = sizeof(struct lzo_ctx), 115 : : .cra_module = THIS_MODULE, 116 : : .cra_init = lzo_init, 117 : : .cra_exit = lzo_exit, 118 : : .cra_u = { .compress = { 119 : : .coa_compress = lzo_compress, 120 : : .coa_decompress = lzo_decompress } } 121 : : }; 122 : : 123 : : static struct scomp_alg scomp = { 124 : : .alloc_ctx = lzo_alloc_ctx, 125 : : .free_ctx = lzo_free_ctx, 126 : : .compress = lzo_scompress, 127 : : .decompress = lzo_sdecompress, 128 : : .base = { 129 : : .cra_name = "lzo", 130 : : .cra_driver_name = "lzo-scomp", 131 : : .cra_module = THIS_MODULE, 132 : : } 133 : : }; 134 : : 135 : 3 : static int __init lzo_mod_init(void) 136 : : { 137 : : int ret; 138 : : 139 : 3 : ret = crypto_register_alg(&alg); 140 : 3 : if (ret) 141 : : return ret; 142 : : 143 : 3 : ret = crypto_register_scomp(&scomp); 144 : 3 : if (ret) { 145 : 0 : crypto_unregister_alg(&alg); 146 : 0 : return ret; 147 : : } 148 : : 149 : : return ret; 150 : : } 151 : : 152 : 0 : static void __exit lzo_mod_fini(void) 153 : : { 154 : 0 : crypto_unregister_alg(&alg); 155 : 0 : crypto_unregister_scomp(&scomp); 156 : 0 : } 157 : : 158 : : subsys_initcall(lzo_mod_init); 159 : : module_exit(lzo_mod_fini); 160 : : 161 : : MODULE_LICENSE("GPL"); 162 : : MODULE_DESCRIPTION("LZO Compression Algorithm"); 163 : : MODULE_ALIAS_CRYPTO("lzo");