161 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*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