linux/crypto/lz4hc.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#include <linux/init.h>
   8#include <linux/module.h>
   9#include <linux/crypto.h>
  10#include <linux/vmalloc.h>
  11#include <linux/lz4.h>
  12#include <crypto/internal/scompress.h>
  13
  14struct lz4hc_ctx {
  15        void *lz4hc_comp_mem;
  16};
  17
  18static void *lz4hc_alloc_ctx(struct crypto_scomp *tfm)
  19{
  20        void *ctx;
  21
  22        ctx = vmalloc(LZ4HC_MEM_COMPRESS);
  23        if (!ctx)
  24                return ERR_PTR(-ENOMEM);
  25
  26        return ctx;
  27}
  28
  29static int lz4hc_init(struct crypto_tfm *tfm)
  30{
  31        struct lz4hc_ctx *ctx = crypto_tfm_ctx(tfm);
  32
  33        ctx->lz4hc_comp_mem = lz4hc_alloc_ctx(NULL);
  34        if (IS_ERR(ctx->lz4hc_comp_mem))
  35                return -ENOMEM;
  36
  37        return 0;
  38}
  39
  40static void lz4hc_free_ctx(struct crypto_scomp *tfm, void *ctx)
  41{
  42        vfree(ctx);
  43}
  44
  45static void lz4hc_exit(struct crypto_tfm *tfm)
  46{
  47        struct lz4hc_ctx *ctx = crypto_tfm_ctx(tfm);
  48
  49        lz4hc_free_ctx(NULL, ctx->lz4hc_comp_mem);
  50}
  51
  52static int __lz4hc_compress_crypto(const u8 *src, unsigned int slen,
  53                                   u8 *dst, unsigned int *dlen, void *ctx)
  54{
  55        int out_len = LZ4_compress_HC(src, dst, slen,
  56                *dlen, LZ4HC_DEFAULT_CLEVEL, ctx);
  57
  58        if (!out_len)
  59                return -EINVAL;
  60
  61        *dlen = out_len;
  62        return 0;
  63}
  64
  65static int lz4hc_scompress(struct crypto_scomp *tfm, const u8 *src,
  66                           unsigned int slen, u8 *dst, unsigned int *dlen,
  67                           void *ctx)
  68{
  69        return __lz4hc_compress_crypto(src, slen, dst, dlen, ctx);
  70}
  71
  72static int lz4hc_compress_crypto(struct crypto_tfm *tfm, const u8 *src,
  73                                 unsigned int slen, u8 *dst,
  74                                 unsigned int *dlen)
  75{
  76        struct lz4hc_ctx *ctx = crypto_tfm_ctx(tfm);
  77
  78        return __lz4hc_compress_crypto(src, slen, dst, dlen,
  79                                        ctx->lz4hc_comp_mem);
  80}
  81
  82static int __lz4hc_decompress_crypto(const u8 *src, unsigned int slen,
  83                                     u8 *dst, unsigned int *dlen, void *ctx)
  84{
  85        int out_len = LZ4_decompress_safe(src, dst, slen, *dlen);
  86
  87        if (out_len < 0)
  88                return -EINVAL;
  89
  90        *dlen = out_len;
  91        return 0;
  92}
  93
  94static int lz4hc_sdecompress(struct crypto_scomp *tfm, const u8 *src,
  95                             unsigned int slen, u8 *dst, unsigned int *dlen,
  96                             void *ctx)
  97{
  98        return __lz4hc_decompress_crypto(src, slen, dst, dlen, NULL);
  99}
 100
 101static int lz4hc_decompress_crypto(struct crypto_tfm *tfm, const u8 *src,
 102                                   unsigned int slen, u8 *dst,
 103                                   unsigned int *dlen)
 104{
 105        return __lz4hc_decompress_crypto(src, slen, dst, dlen, NULL);
 106}
 107
 108static struct crypto_alg alg_lz4hc = {
 109        .cra_name               = "lz4hc",
 110        .cra_driver_name        = "lz4hc-generic",
 111        .cra_flags              = CRYPTO_ALG_TYPE_COMPRESS,
 112        .cra_ctxsize            = sizeof(struct lz4hc_ctx),
 113        .cra_module             = THIS_MODULE,
 114        .cra_init               = lz4hc_init,
 115        .cra_exit               = lz4hc_exit,
 116        .cra_u                  = { .compress = {
 117        .coa_compress           = lz4hc_compress_crypto,
 118        .coa_decompress         = lz4hc_decompress_crypto } }
 119};
 120
 121static struct scomp_alg scomp = {
 122        .alloc_ctx              = lz4hc_alloc_ctx,
 123        .free_ctx               = lz4hc_free_ctx,
 124        .compress               = lz4hc_scompress,
 125        .decompress             = lz4hc_sdecompress,
 126        .base                   = {
 127                .cra_name       = "lz4hc",
 128                .cra_driver_name = "lz4hc-scomp",
 129                .cra_module      = THIS_MODULE,
 130        }
 131};
 132
 133static int __init lz4hc_mod_init(void)
 134{
 135        int ret;
 136
 137        ret = crypto_register_alg(&alg_lz4hc);
 138        if (ret)
 139                return ret;
 140
 141        ret = crypto_register_scomp(&scomp);
 142        if (ret) {
 143                crypto_unregister_alg(&alg_lz4hc);
 144                return ret;
 145        }
 146
 147        return ret;
 148}
 149
 150static void __exit lz4hc_mod_fini(void)
 151{
 152        crypto_unregister_alg(&alg_lz4hc);
 153        crypto_unregister_scomp(&scomp);
 154}
 155
 156subsys_initcall(lz4hc_mod_init);
 157module_exit(lz4hc_mod_fini);
 158
 159MODULE_LICENSE("GPL");
 160MODULE_DESCRIPTION("LZ4HC Compression Algorithm");
 161MODULE_ALIAS_CRYPTO("lz4hc");
 162