linux/crypto/lz4.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Cryptographic API.
   4 *
   5 * Copyright (c) 2013 Chanho Min <chanho.min@lge.com>
   6 */
   7
   8#include <linux/init.h>
   9#include <linux/module.h>
  10#include <linux/crypto.h>
  11#include <linux/vmalloc.h>
  12#include <linux/lz4.h>
  13#include <crypto/internal/scompress.h>
  14
  15struct lz4_ctx {
  16        void *lz4_comp_mem;
  17};
  18
  19static void *lz4_alloc_ctx(struct crypto_scomp *tfm)
  20{
  21        void *ctx;
  22
  23        ctx = vmalloc(LZ4_MEM_COMPRESS);
  24        if (!ctx)
  25                return ERR_PTR(-ENOMEM);
  26
  27        return ctx;
  28}
  29
  30static int lz4_init(struct crypto_tfm *tfm)
  31{
  32        struct lz4_ctx *ctx = crypto_tfm_ctx(tfm);
  33
  34        ctx->lz4_comp_mem = lz4_alloc_ctx(NULL);
  35        if (IS_ERR(ctx->lz4_comp_mem))
  36                return -ENOMEM;
  37
  38        return 0;
  39}
  40
  41static void lz4_free_ctx(struct crypto_scomp *tfm, void *ctx)
  42{
  43        vfree(ctx);
  44}
  45
  46static void lz4_exit(struct crypto_tfm *tfm)
  47{
  48        struct lz4_ctx *ctx = crypto_tfm_ctx(tfm);
  49
  50        lz4_free_ctx(NULL, ctx->lz4_comp_mem);
  51}
  52
  53static int __lz4_compress_crypto(const u8 *src, unsigned int slen,
  54                                 u8 *dst, unsigned int *dlen, void *ctx)
  55{
  56        int out_len = LZ4_compress_default(src, dst,
  57                slen, *dlen, ctx);
  58
  59        if (!out_len)
  60                return -EINVAL;
  61
  62        *dlen = out_len;
  63        return 0;
  64}
  65
  66static int lz4_scompress(struct crypto_scomp *tfm, const u8 *src,
  67                         unsigned int slen, u8 *dst, unsigned int *dlen,
  68                         void *ctx)
  69{
  70        return __lz4_compress_crypto(src, slen, dst, dlen, ctx);
  71}
  72
  73static int lz4_compress_crypto(struct crypto_tfm *tfm, const u8 *src,
  74                               unsigned int slen, u8 *dst, unsigned int *dlen)
  75{
  76        struct lz4_ctx *ctx = crypto_tfm_ctx(tfm);
  77
  78        return __lz4_compress_crypto(src, slen, dst, dlen, ctx->lz4_comp_mem);
  79}
  80
  81static int __lz4_decompress_crypto(const u8 *src, unsigned int slen,
  82                                   u8 *dst, unsigned int *dlen, void *ctx)
  83{
  84        int out_len = LZ4_decompress_safe(src, dst, slen, *dlen);
  85
  86        if (out_len < 0)
  87                return -EINVAL;
  88
  89        *dlen = out_len;
  90        return 0;
  91}
  92
  93static int lz4_sdecompress(struct crypto_scomp *tfm, const u8 *src,
  94                           unsigned int slen, u8 *dst, unsigned int *dlen,
  95                           void *ctx)
  96{
  97        return __lz4_decompress_crypto(src, slen, dst, dlen, NULL);
  98}
  99
 100static int lz4_decompress_crypto(struct crypto_tfm *tfm, const u8 *src,
 101                                 unsigned int slen, u8 *dst,
 102                                 unsigned int *dlen)
 103{
 104        return __lz4_decompress_crypto(src, slen, dst, dlen, NULL);
 105}
 106
 107static struct crypto_alg alg_lz4 = {
 108        .cra_name               = "lz4",
 109        .cra_driver_name        = "lz4-generic",
 110        .cra_flags              = CRYPTO_ALG_TYPE_COMPRESS,
 111        .cra_ctxsize            = sizeof(struct lz4_ctx),
 112        .cra_module             = THIS_MODULE,
 113        .cra_init               = lz4_init,
 114        .cra_exit               = lz4_exit,
 115        .cra_u                  = { .compress = {
 116        .coa_compress           = lz4_compress_crypto,
 117        .coa_decompress         = lz4_decompress_crypto } }
 118};
 119
 120static struct scomp_alg scomp = {
 121        .alloc_ctx              = lz4_alloc_ctx,
 122        .free_ctx               = lz4_free_ctx,
 123        .compress               = lz4_scompress,
 124        .decompress             = lz4_sdecompress,
 125        .base                   = {
 126                .cra_name       = "lz4",
 127                .cra_driver_name = "lz4-scomp",
 128                .cra_module      = THIS_MODULE,
 129        }
 130};
 131
 132static int __init lz4_mod_init(void)
 133{
 134        int ret;
 135
 136        ret = crypto_register_alg(&alg_lz4);
 137        if (ret)
 138                return ret;
 139
 140        ret = crypto_register_scomp(&scomp);
 141        if (ret) {
 142                crypto_unregister_alg(&alg_lz4);
 143                return ret;
 144        }
 145
 146        return ret;
 147}
 148
 149static void __exit lz4_mod_fini(void)
 150{
 151        crypto_unregister_alg(&alg_lz4);
 152        crypto_unregister_scomp(&scomp);
 153}
 154
 155subsys_initcall(lz4_mod_init);
 156module_exit(lz4_mod_fini);
 157
 158MODULE_LICENSE("GPL");
 159MODULE_DESCRIPTION("LZ4 Compression Algorithm");
 160MODULE_ALIAS_CRYPTO("lz4");
 161