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