xref: /linux/crypto/lz4hc.c (revision d6ebf528)
10ea8530dSChanho Min // SPDX-License-Identifier: GPL-2.0-only
20ea8530dSChanho Min /*
30ea8530dSChanho Min  * Cryptographic API.
40ea8530dSChanho Min  *
50ea8530dSChanho Min  * Copyright (c) 2013 Chanho Min <chanho.min@lge.com>
60ea8530dSChanho Min  */
70ea8530dSChanho Min #include <linux/init.h>
80ea8530dSChanho Min #include <linux/module.h>
90ea8530dSChanho Min #include <linux/crypto.h>
100ea8530dSChanho Min #include <linux/vmalloc.h>
110ea8530dSChanho Min #include <linux/lz4.h>
120ea8530dSChanho Min #include <crypto/internal/scompress.h>
130ea8530dSChanho Min 
140ea8530dSChanho Min struct lz4hc_ctx {
150ea8530dSChanho Min 	void *lz4hc_comp_mem;
160ea8530dSChanho Min };
170ea8530dSChanho Min 
lz4hc_alloc_ctx(struct crypto_scomp * tfm)180ea8530dSChanho Min static void *lz4hc_alloc_ctx(struct crypto_scomp *tfm)
190ea8530dSChanho Min {
200ea8530dSChanho Min 	void *ctx;
210ea8530dSChanho Min 
220ea8530dSChanho Min 	ctx = vmalloc(LZ4HC_MEM_COMPRESS);
230ea8530dSChanho Min 	if (!ctx)
240ea8530dSChanho Min 		return ERR_PTR(-ENOMEM);
2591d53d96SGiovanni Cabiddu 
260ea8530dSChanho Min 	return ctx;
270ea8530dSChanho Min }
280ea8530dSChanho Min 
lz4hc_init(struct crypto_tfm * tfm)290ea8530dSChanho Min static int lz4hc_init(struct crypto_tfm *tfm)
300ea8530dSChanho Min {
3191d53d96SGiovanni Cabiddu 	struct lz4hc_ctx *ctx = crypto_tfm_ctx(tfm);
3291d53d96SGiovanni Cabiddu 
3391d53d96SGiovanni Cabiddu 	ctx->lz4hc_comp_mem = lz4hc_alloc_ctx(NULL);
3491d53d96SGiovanni Cabiddu 	if (IS_ERR(ctx->lz4hc_comp_mem))
3591d53d96SGiovanni Cabiddu 		return -ENOMEM;
3691d53d96SGiovanni Cabiddu 
3791d53d96SGiovanni Cabiddu 	return 0;
3891d53d96SGiovanni Cabiddu }
3991d53d96SGiovanni Cabiddu 
lz4hc_free_ctx(struct crypto_scomp * tfm,void * ctx)4091d53d96SGiovanni Cabiddu static void lz4hc_free_ctx(struct crypto_scomp *tfm, void *ctx)
4191d53d96SGiovanni Cabiddu {
420ea8530dSChanho Min 	vfree(ctx);
430ea8530dSChanho Min }
440ea8530dSChanho Min 
lz4hc_exit(struct crypto_tfm * tfm)450ea8530dSChanho Min static void lz4hc_exit(struct crypto_tfm *tfm)
4691d53d96SGiovanni Cabiddu {
4791d53d96SGiovanni Cabiddu 	struct lz4hc_ctx *ctx = crypto_tfm_ctx(tfm);
480ea8530dSChanho Min 
490ea8530dSChanho Min 	lz4hc_free_ctx(NULL, ctx->lz4hc_comp_mem);
500ea8530dSChanho Min }
510ea8530dSChanho Min 
__lz4hc_compress_crypto(const u8 * src,unsigned int slen,u8 * dst,unsigned int * dlen,void * ctx)520ea8530dSChanho Min static int __lz4hc_compress_crypto(const u8 *src, unsigned int slen,
5391d53d96SGiovanni Cabiddu 				   u8 *dst, unsigned int *dlen, void *ctx)
5491d53d96SGiovanni Cabiddu {
5591d53d96SGiovanni Cabiddu 	int out_len = LZ4_compress_HC(src, dst, slen,
5691d53d96SGiovanni Cabiddu 		*dlen, LZ4HC_DEFAULT_CLEVEL, ctx);
5791d53d96SGiovanni Cabiddu 
580ea8530dSChanho Min 	if (!out_len)
590ea8530dSChanho Min 		return -EINVAL;
600ea8530dSChanho Min 
610ea8530dSChanho Min 	*dlen = out_len;
6291d53d96SGiovanni Cabiddu 	return 0;
630ea8530dSChanho Min }
640ea8530dSChanho Min 
lz4hc_scompress(struct crypto_scomp * tfm,const u8 * src,unsigned int slen,u8 * dst,unsigned int * dlen,void * ctx)6591d53d96SGiovanni Cabiddu static int lz4hc_scompress(struct crypto_scomp *tfm, const u8 *src,
6691d53d96SGiovanni Cabiddu 			   unsigned int slen, u8 *dst, unsigned int *dlen,
670ea8530dSChanho Min 			   void *ctx)
6873a15ac6SSven Schmidt {
6973a15ac6SSven Schmidt 	return __lz4hc_compress_crypto(src, slen, dst, dlen, ctx);
700ea8530dSChanho Min }
7173a15ac6SSven Schmidt 
lz4hc_compress_crypto(struct crypto_tfm * tfm,const u8 * src,unsigned int slen,u8 * dst,unsigned int * dlen)720ea8530dSChanho Min static int lz4hc_compress_crypto(struct crypto_tfm *tfm, const u8 *src,
730ea8530dSChanho Min 				 unsigned int slen, u8 *dst,
7473a15ac6SSven Schmidt 				 unsigned int *dlen)
750ea8530dSChanho Min {
760ea8530dSChanho Min 	struct lz4hc_ctx *ctx = crypto_tfm_ctx(tfm);
770ea8530dSChanho Min 
7891d53d96SGiovanni Cabiddu 	return __lz4hc_compress_crypto(src, slen, dst, dlen,
7991d53d96SGiovanni Cabiddu 					ctx->lz4hc_comp_mem);
8091d53d96SGiovanni Cabiddu }
8191d53d96SGiovanni Cabiddu 
__lz4hc_decompress_crypto(const u8 * src,unsigned int slen,u8 * dst,unsigned int * dlen,void * ctx)8291d53d96SGiovanni Cabiddu static int __lz4hc_decompress_crypto(const u8 *src, unsigned int slen,
8391d53d96SGiovanni Cabiddu 				     u8 *dst, unsigned int *dlen, void *ctx)
8491d53d96SGiovanni Cabiddu {
8591d53d96SGiovanni Cabiddu 	int out_len = LZ4_decompress_safe(src, dst, slen, *dlen);
8691d53d96SGiovanni Cabiddu 
8791d53d96SGiovanni Cabiddu 	if (out_len < 0)
8891d53d96SGiovanni Cabiddu 		return -EINVAL;
8991d53d96SGiovanni Cabiddu 
9091d53d96SGiovanni Cabiddu 	*dlen = out_len;
9191d53d96SGiovanni Cabiddu 	return 0;
9291d53d96SGiovanni Cabiddu }
9391d53d96SGiovanni Cabiddu 
lz4hc_sdecompress(struct crypto_scomp * tfm,const u8 * src,unsigned int slen,u8 * dst,unsigned int * dlen,void * ctx)9491d53d96SGiovanni Cabiddu static int lz4hc_sdecompress(struct crypto_scomp *tfm, const u8 *src,
9591d53d96SGiovanni Cabiddu 			     unsigned int slen, u8 *dst, unsigned int *dlen,
9691d53d96SGiovanni Cabiddu 			     void *ctx)
970ea8530dSChanho Min {
9873a15ac6SSven Schmidt 	return __lz4hc_decompress_crypto(src, slen, dst, dlen, NULL);
990ea8530dSChanho Min }
10073a15ac6SSven Schmidt 
lz4hc_decompress_crypto(struct crypto_tfm * tfm,const u8 * src,unsigned int slen,u8 * dst,unsigned int * dlen)101cd15f102SMyungho Jung static int lz4hc_decompress_crypto(struct crypto_tfm *tfm, const u8 *src,
1020ea8530dSChanho Min 				   unsigned int slen, u8 *dst,
10373a15ac6SSven Schmidt 				   unsigned int *dlen)
10473a15ac6SSven Schmidt {
1050ea8530dSChanho Min 	return __lz4hc_decompress_crypto(src, slen, dst, dlen, NULL);
1060ea8530dSChanho Min }
10791d53d96SGiovanni Cabiddu 
10891d53d96SGiovanni Cabiddu static struct crypto_alg alg_lz4hc = {
10991d53d96SGiovanni Cabiddu 	.cra_name		= "lz4hc",
11091d53d96SGiovanni Cabiddu 	.cra_driver_name	= "lz4hc-generic",
11191d53d96SGiovanni Cabiddu 	.cra_flags		= CRYPTO_ALG_TYPE_COMPRESS,
11291d53d96SGiovanni Cabiddu 	.cra_ctxsize		= sizeof(struct lz4hc_ctx),
11391d53d96SGiovanni Cabiddu 	.cra_module		= THIS_MODULE,
11491d53d96SGiovanni Cabiddu 	.cra_init		= lz4hc_init,
11591d53d96SGiovanni Cabiddu 	.cra_exit		= lz4hc_exit,
11691d53d96SGiovanni Cabiddu 	.cra_u			= { .compress = {
11791d53d96SGiovanni Cabiddu 	.coa_compress		= lz4hc_compress_crypto,
11891d53d96SGiovanni Cabiddu 	.coa_decompress		= lz4hc_decompress_crypto } }
11991d53d96SGiovanni Cabiddu };
12091d53d96SGiovanni Cabiddu 
1210ea8530dSChanho Min static struct scomp_alg scomp = {
1220ea8530dSChanho Min 	.alloc_ctx		= lz4hc_alloc_ctx,
123*d6ebf528SEric Biggers 	.free_ctx		= lz4hc_free_ctx,
1240ea8530dSChanho Min 	.compress		= lz4hc_scompress,
1250ea8530dSChanho Min 	.decompress		= lz4hc_sdecompress,
1260ea8530dSChanho Min 	.base			= {
1270ea8530dSChanho Min 		.cra_name	= "lz4hc",
1280ea8530dSChanho Min 		.cra_driver_name = "lz4hc-scomp",
1290ea8530dSChanho Min 		.cra_module	 = THIS_MODULE,
1300ea8530dSChanho Min 	}
1310ea8530dSChanho Min };
1320ea8530dSChanho Min 
lz4hc_mod_init(void)1330ea8530dSChanho Min static int __init lz4hc_mod_init(void)
13491d53d96SGiovanni Cabiddu {
13591d53d96SGiovanni Cabiddu 	int ret;
13691d53d96SGiovanni Cabiddu 
13791d53d96SGiovanni Cabiddu 	ret = crypto_register_alg(&alg_lz4hc);
13891d53d96SGiovanni Cabiddu 	if (ret)
13991d53d96SGiovanni Cabiddu 		return ret;
14091d53d96SGiovanni Cabiddu 
14191d53d96SGiovanni Cabiddu 	ret = crypto_register_scomp(&scomp);
14291d53d96SGiovanni Cabiddu 	if (ret) {
14391d53d96SGiovanni Cabiddu 		crypto_unregister_alg(&alg_lz4hc);
14491d53d96SGiovanni Cabiddu 		return ret;
14591d53d96SGiovanni Cabiddu 	}
1460ea8530dSChanho Min 
1470ea8530dSChanho Min 	return ret;
14891d53d96SGiovanni Cabiddu }
14991d53d96SGiovanni Cabiddu 
lz4hc_mod_fini(void)15091d53d96SGiovanni Cabiddu static void __exit lz4hc_mod_fini(void)
15191d53d96SGiovanni Cabiddu {
15291d53d96SGiovanni Cabiddu 	crypto_unregister_alg(&alg_lz4hc);
15391d53d96SGiovanni Cabiddu 	crypto_unregister_scomp(&scomp);
15491d53d96SGiovanni Cabiddu }
15591d53d96SGiovanni Cabiddu 
15691d53d96SGiovanni Cabiddu subsys_initcall(lz4hc_mod_init);
15791d53d96SGiovanni Cabiddu module_exit(lz4hc_mod_fini);
15891d53d96SGiovanni Cabiddu 
15991d53d96SGiovanni Cabiddu MODULE_LICENSE("GPL");
16091d53d96SGiovanni Cabiddu MODULE_DESCRIPTION("LZ4HC Compression Algorithm");
1610ea8530dSChanho Min MODULE_ALIAS_CRYPTO("lz4hc");
1620ea8530dSChanho Min