linux/crypto/lz4hc.c
<<
>>
Prefs
   1/*
   2 * Cryptographic API.
   3 *
   4 * Copyright (c) 2013 Chanho Min <chanho.min@lge.com>
   5 *
   6 * This program is free software; you can redistribute it and/or modify it
   7 * under the terms of the GNU General Public License version 2 as published by
   8 * the Free Software Foundation.
   9 *
  10 * This program is distributed in the hope that it will be useful, but WITHOUT
  11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  13 * more details.
  14 *
  15 * You should have received a copy of the GNU General Public License along with
  16 * this program; if not, write to the Free Software Foundation, Inc., 51
  17 * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  18 *
  19 */
  20#include <linux/init.h>
  21#include <linux/module.h>
  22#include <linux/crypto.h>
  23#include <linux/vmalloc.h>
  24#include <linux/lz4.h>
  25#include <crypto/internal/scompress.h>
  26
  27struct lz4hc_ctx {
  28        void *lz4hc_comp_mem;
  29};
  30
  31static void *lz4hc_alloc_ctx(struct crypto_scomp *tfm)
  32{
  33        void *ctx;
  34
  35        ctx = vmalloc(LZ4HC_MEM_COMPRESS);
  36        if (!ctx)
  37                return ERR_PTR(-ENOMEM);
  38
  39        return ctx;
  40}
  41
  42static int lz4hc_init(struct crypto_tfm *tfm)
  43{
  44        struct lz4hc_ctx *ctx = crypto_tfm_ctx(tfm);
  45
  46        ctx->lz4hc_comp_mem = lz4hc_alloc_ctx(NULL);
  47        if (IS_ERR(ctx->lz4hc_comp_mem))
  48                return -ENOMEM;
  49
  50        return 0;
  51}
  52
  53static void lz4hc_free_ctx(struct crypto_scomp *tfm, void *ctx)
  54{
  55        vfree(ctx);
  56}
  57
  58static void lz4hc_exit(struct crypto_tfm *tfm)
  59{
  60        struct lz4hc_ctx *ctx = crypto_tfm_ctx(tfm);
  61
  62        lz4hc_free_ctx(NULL, ctx->lz4hc_comp_mem);
  63}
  64
  65static int __lz4hc_compress_crypto(const u8 *src, unsigned int slen,
  66                                   u8 *dst, unsigned int *dlen, void *ctx)
  67{
  68        int out_len = LZ4_compress_HC(src, dst, slen,
  69                *dlen, LZ4HC_DEFAULT_CLEVEL, ctx);
  70
  71        if (!out_len)
  72                return -EINVAL;
  73
  74        *dlen = out_len;
  75        return 0;
  76}
  77
  78static int lz4hc_scompress(struct crypto_scomp *tfm, const u8 *src,
  79                           unsigned int slen, u8 *dst, unsigned int *dlen,
  80                           void *ctx)
  81{
  82        return __lz4hc_compress_crypto(src, slen, dst, dlen, ctx);
  83}
  84
  85static int lz4hc_compress_crypto(struct crypto_tfm *tfm, const u8 *src,
  86                                 unsigned int slen, u8 *dst,
  87                                 unsigned int *dlen)
  88{
  89        struct lz4hc_ctx *ctx = crypto_tfm_ctx(tfm);
  90
  91        return __lz4hc_compress_crypto(src, slen, dst, dlen,
  92                                        ctx->lz4hc_comp_mem);
  93}
  94
  95static int __lz4hc_decompress_crypto(const u8 *src, unsigned int slen,
  96                                     u8 *dst, unsigned int *dlen, void *ctx)
  97{
  98        int out_len = LZ4_decompress_safe(src, dst, slen, *dlen);
  99
 100        if (out_len < 0)
 101                return -EINVAL;
 102
 103        *dlen = out_len;
 104        return 0;
 105}
 106
 107static int lz4hc_sdecompress(struct crypto_scomp *tfm, const u8 *src,
 108                             unsigned int slen, u8 *dst, unsigned int *dlen,
 109                             void *ctx)
 110{
 111        return __lz4hc_decompress_crypto(src, slen, dst, dlen, NULL);
 112}
 113
 114static int lz4hc_decompress_crypto(struct crypto_tfm *tfm, const u8 *src,
 115                                   unsigned int slen, u8 *dst,
 116                                   unsigned int *dlen)
 117{
 118        return __lz4hc_decompress_crypto(src, slen, dst, dlen, NULL);
 119}
 120
 121static struct crypto_alg alg_lz4hc = {
 122        .cra_name               = "lz4hc",
 123        .cra_flags              = CRYPTO_ALG_TYPE_COMPRESS,
 124        .cra_ctxsize            = sizeof(struct lz4hc_ctx),
 125        .cra_module             = THIS_MODULE,
 126        .cra_list               = LIST_HEAD_INIT(alg_lz4hc.cra_list),
 127        .cra_init               = lz4hc_init,
 128        .cra_exit               = lz4hc_exit,
 129        .cra_u                  = { .compress = {
 130        .coa_compress           = lz4hc_compress_crypto,
 131        .coa_decompress         = lz4hc_decompress_crypto } }
 132};
 133
 134static struct scomp_alg scomp = {
 135        .alloc_ctx              = lz4hc_alloc_ctx,
 136        .free_ctx               = lz4hc_free_ctx,
 137        .compress               = lz4hc_scompress,
 138        .decompress             = lz4hc_sdecompress,
 139        .base                   = {
 140                .cra_name       = "lz4hc",
 141                .cra_driver_name = "lz4hc-scomp",
 142                .cra_module      = THIS_MODULE,
 143        }
 144};
 145
 146static int __init lz4hc_mod_init(void)
 147{
 148        int ret;
 149
 150        ret = crypto_register_alg(&alg_lz4hc);
 151        if (ret)
 152                return ret;
 153
 154        ret = crypto_register_scomp(&scomp);
 155        if (ret) {
 156                crypto_unregister_alg(&alg_lz4hc);
 157                return ret;
 158        }
 159
 160        return ret;
 161}
 162
 163static void __exit lz4hc_mod_fini(void)
 164{
 165        crypto_unregister_alg(&alg_lz4hc);
 166        crypto_unregister_scomp(&scomp);
 167}
 168
 169module_init(lz4hc_mod_init);
 170module_exit(lz4hc_mod_fini);
 171
 172MODULE_LICENSE("GPL");
 173MODULE_DESCRIPTION("LZ4HC Compression Algorithm");
 174MODULE_ALIAS_CRYPTO("lz4hc");
 175