164 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*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 14struct lzorle_ctx {15 void *lzorle_comp_mem;16};17 18static void *lzorle_alloc_ctx(struct crypto_scomp *tfm)19{20 void *ctx;21 22 ctx = kvmalloc(LZO1X_MEM_COMPRESS, GFP_KERNEL);23 if (!ctx)24 return ERR_PTR(-ENOMEM);25 26 return ctx;27}28 29static int lzorle_init(struct crypto_tfm *tfm)30{31 struct lzorle_ctx *ctx = crypto_tfm_ctx(tfm);32 33 ctx->lzorle_comp_mem = lzorle_alloc_ctx(NULL);34 if (IS_ERR(ctx->lzorle_comp_mem))35 return -ENOMEM;36 37 return 0;38}39 40static void lzorle_free_ctx(struct crypto_scomp *tfm, void *ctx)41{42 kvfree(ctx);43}44 45static void lzorle_exit(struct crypto_tfm *tfm)46{47 struct lzorle_ctx *ctx = crypto_tfm_ctx(tfm);48 49 lzorle_free_ctx(NULL, ctx->lzorle_comp_mem);50}51 52static int __lzorle_compress(const u8 *src, unsigned int slen,53 u8 *dst, unsigned int *dlen, void *ctx)54{55 size_t tmp_len = *dlen; /* size_t(ulong) <-> uint on 64 bit */56 int err;57 58 err = lzorle1x_1_compress(src, slen, dst, &tmp_len, ctx);59 60 if (err != LZO_E_OK)61 return -EINVAL;62 63 *dlen = tmp_len;64 return 0;65}66 67static int lzorle_compress(struct crypto_tfm *tfm, const u8 *src,68 unsigned int slen, u8 *dst, unsigned int *dlen)69{70 struct lzorle_ctx *ctx = crypto_tfm_ctx(tfm);71 72 return __lzorle_compress(src, slen, dst, dlen, ctx->lzorle_comp_mem);73}74 75static int lzorle_scompress(struct crypto_scomp *tfm, const u8 *src,76 unsigned int slen, u8 *dst, unsigned int *dlen,77 void *ctx)78{79 return __lzorle_compress(src, slen, dst, dlen, ctx);80}81 82static int __lzorle_decompress(const u8 *src, unsigned int slen,83 u8 *dst, unsigned int *dlen)84{85 int err;86 size_t tmp_len = *dlen; /* size_t(ulong) <-> uint on 64 bit */87 88 err = lzo1x_decompress_safe(src, slen, dst, &tmp_len);89 90 if (err != LZO_E_OK)91 return -EINVAL;92 93 *dlen = tmp_len;94 return 0;95}96 97static int lzorle_decompress(struct crypto_tfm *tfm, const u8 *src,98 unsigned int slen, u8 *dst, unsigned int *dlen)99{100 return __lzorle_decompress(src, slen, dst, dlen);101}102 103static int lzorle_sdecompress(struct crypto_scomp *tfm, const u8 *src,104 unsigned int slen, u8 *dst, unsigned int *dlen,105 void *ctx)106{107 return __lzorle_decompress(src, slen, dst, dlen);108}109 110static struct crypto_alg alg = {111 .cra_name = "lzo-rle",112 .cra_driver_name = "lzo-rle-generic",113 .cra_flags = CRYPTO_ALG_TYPE_COMPRESS,114 .cra_ctxsize = sizeof(struct lzorle_ctx),115 .cra_module = THIS_MODULE,116 .cra_init = lzorle_init,117 .cra_exit = lzorle_exit,118 .cra_u = { .compress = {119 .coa_compress = lzorle_compress,120 .coa_decompress = lzorle_decompress } }121};122 123static struct scomp_alg scomp = {124 .alloc_ctx = lzorle_alloc_ctx,125 .free_ctx = lzorle_free_ctx,126 .compress = lzorle_scompress,127 .decompress = lzorle_sdecompress,128 .base = {129 .cra_name = "lzo-rle",130 .cra_driver_name = "lzo-rle-scomp",131 .cra_module = THIS_MODULE,132 }133};134 135static int __init lzorle_mod_init(void)136{137 int ret;138 139 ret = crypto_register_alg(&alg);140 if (ret)141 return ret;142 143 ret = crypto_register_scomp(&scomp);144 if (ret) {145 crypto_unregister_alg(&alg);146 return ret;147 }148 149 return ret;150}151 152static void __exit lzorle_mod_fini(void)153{154 crypto_unregister_alg(&alg);155 crypto_unregister_scomp(&scomp);156}157 158subsys_initcall(lzorle_mod_init);159module_exit(lzorle_mod_fini);160 161MODULE_LICENSE("GPL");162MODULE_DESCRIPTION("LZO-RLE Compression Algorithm");163MODULE_ALIAS_CRYPTO("lzo-rle");164