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