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 lzo_ctx {15 void *lzo_comp_mem;16};17 18static void *lzo_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 lzo_init(struct crypto_tfm *tfm)30{31 struct lzo_ctx *ctx = crypto_tfm_ctx(tfm);32 33 ctx->lzo_comp_mem = lzo_alloc_ctx(NULL);34 if (IS_ERR(ctx->lzo_comp_mem))35 return -ENOMEM;36 37 return 0;38}39 40static void lzo_free_ctx(struct crypto_scomp *tfm, void *ctx)41{42 kvfree(ctx);43}44 45static void lzo_exit(struct crypto_tfm *tfm)46{47 struct lzo_ctx *ctx = crypto_tfm_ctx(tfm);48 49 lzo_free_ctx(NULL, ctx->lzo_comp_mem);50}51 52static int __lzo_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 = lzo1x_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 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 return __lzo_compress(src, slen, dst, dlen, ctx->lzo_comp_mem);73}74 75static int lzo_scompress(struct crypto_scomp *tfm, const u8 *src,76 unsigned int slen, u8 *dst, unsigned int *dlen,77 void *ctx)78{79 return __lzo_compress(src, slen, dst, dlen, ctx);80}81 82static int __lzo_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 lzo_decompress(struct crypto_tfm *tfm, const u8 *src,98 unsigned int slen, u8 *dst, unsigned int *dlen)99{100 return __lzo_decompress(src, slen, dst, dlen);101}102 103static int lzo_sdecompress(struct crypto_scomp *tfm, const u8 *src,104 unsigned int slen, u8 *dst, unsigned int *dlen,105 void *ctx)106{107 return __lzo_decompress(src, slen, dst, dlen);108}109 110static 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 123static 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 135static int __init lzo_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 lzo_mod_fini(void)153{154 crypto_unregister_alg(&alg);155 crypto_unregister_scomp(&scomp);156}157 158subsys_initcall(lzo_mod_init);159module_exit(lzo_mod_fini);160 161MODULE_LICENSE("GPL");162MODULE_DESCRIPTION("LZO Compression Algorithm");163MODULE_ALIAS_CRYPTO("lzo");164