linux/crypto/lzo.c
<<
>>
Prefs
   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
  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