xref: /linux/crypto/842.c (revision c942fddf)
1*c942fddfSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
235a1fc18SSeth Jennings /*
32062c5b6SDan Streetman  * Cryptographic API for the 842 software compression algorithm.
435a1fc18SSeth Jennings  *
52062c5b6SDan Streetman  * Copyright (C) IBM Corporation, 2011-2015
635a1fc18SSeth Jennings  *
72062c5b6SDan Streetman  * Original Authors: Robert Jennings <rcj@linux.vnet.ibm.com>
835a1fc18SSeth Jennings  *                   Seth Jennings <sjenning@linux.vnet.ibm.com>
92062c5b6SDan Streetman  *
102062c5b6SDan Streetman  * Rewrite: Dan Streetman <ddstreet@ieee.org>
112062c5b6SDan Streetman  *
122062c5b6SDan Streetman  * This is the software implementation of compression and decompression using
132062c5b6SDan Streetman  * the 842 format.  This uses the software 842 library at lib/842/ which is
142062c5b6SDan Streetman  * only a reference implementation, and is very, very slow as compared to other
152062c5b6SDan Streetman  * software compressors.  You probably do not want to use this software
162062c5b6SDan Streetman  * compression.  If you have access to the PowerPC 842 compression hardware, you
172062c5b6SDan Streetman  * want to use the 842 hardware compression interface, which is at:
182062c5b6SDan Streetman  * drivers/crypto/nx/nx-842-crypto.c
1935a1fc18SSeth Jennings  */
2035a1fc18SSeth Jennings 
2135a1fc18SSeth Jennings #include <linux/init.h>
2235a1fc18SSeth Jennings #include <linux/module.h>
2335a1fc18SSeth Jennings #include <linux/crypto.h>
242062c5b6SDan Streetman #include <linux/sw842.h>
256a8de3aeSGiovanni Cabiddu #include <crypto/internal/scompress.h>
2635a1fc18SSeth Jennings 
272062c5b6SDan Streetman struct crypto842_ctx {
286a8de3aeSGiovanni Cabiddu 	void *wmem;	/* working memory for compress */
2935a1fc18SSeth Jennings };
3035a1fc18SSeth Jennings 
crypto842_alloc_ctx(struct crypto_scomp * tfm)316a8de3aeSGiovanni Cabiddu static void *crypto842_alloc_ctx(struct crypto_scomp *tfm)
326a8de3aeSGiovanni Cabiddu {
336a8de3aeSGiovanni Cabiddu 	void *ctx;
346a8de3aeSGiovanni Cabiddu 
356a8de3aeSGiovanni Cabiddu 	ctx = kmalloc(SW842_MEM_COMPRESS, GFP_KERNEL);
366a8de3aeSGiovanni Cabiddu 	if (!ctx)
376a8de3aeSGiovanni Cabiddu 		return ERR_PTR(-ENOMEM);
386a8de3aeSGiovanni Cabiddu 
396a8de3aeSGiovanni Cabiddu 	return ctx;
406a8de3aeSGiovanni Cabiddu }
416a8de3aeSGiovanni Cabiddu 
crypto842_init(struct crypto_tfm * tfm)426a8de3aeSGiovanni Cabiddu static int crypto842_init(struct crypto_tfm *tfm)
436a8de3aeSGiovanni Cabiddu {
446a8de3aeSGiovanni Cabiddu 	struct crypto842_ctx *ctx = crypto_tfm_ctx(tfm);
456a8de3aeSGiovanni Cabiddu 
466a8de3aeSGiovanni Cabiddu 	ctx->wmem = crypto842_alloc_ctx(NULL);
476a8de3aeSGiovanni Cabiddu 	if (IS_ERR(ctx->wmem))
486a8de3aeSGiovanni Cabiddu 		return -ENOMEM;
496a8de3aeSGiovanni Cabiddu 
506a8de3aeSGiovanni Cabiddu 	return 0;
516a8de3aeSGiovanni Cabiddu }
526a8de3aeSGiovanni Cabiddu 
crypto842_free_ctx(struct crypto_scomp * tfm,void * ctx)536a8de3aeSGiovanni Cabiddu static void crypto842_free_ctx(struct crypto_scomp *tfm, void *ctx)
546a8de3aeSGiovanni Cabiddu {
556a8de3aeSGiovanni Cabiddu 	kfree(ctx);
566a8de3aeSGiovanni Cabiddu }
576a8de3aeSGiovanni Cabiddu 
crypto842_exit(struct crypto_tfm * tfm)586a8de3aeSGiovanni Cabiddu static void crypto842_exit(struct crypto_tfm *tfm)
596a8de3aeSGiovanni Cabiddu {
606a8de3aeSGiovanni Cabiddu 	struct crypto842_ctx *ctx = crypto_tfm_ctx(tfm);
616a8de3aeSGiovanni Cabiddu 
626a8de3aeSGiovanni Cabiddu 	crypto842_free_ctx(NULL, ctx->wmem);
636a8de3aeSGiovanni Cabiddu }
646a8de3aeSGiovanni Cabiddu 
crypto842_compress(struct crypto_tfm * tfm,const u8 * src,unsigned int slen,u8 * dst,unsigned int * dlen)652062c5b6SDan Streetman static int crypto842_compress(struct crypto_tfm *tfm,
662062c5b6SDan Streetman 			      const u8 *src, unsigned int slen,
672062c5b6SDan Streetman 			      u8 *dst, unsigned int *dlen)
6835a1fc18SSeth Jennings {
692062c5b6SDan Streetman 	struct crypto842_ctx *ctx = crypto_tfm_ctx(tfm);
7035a1fc18SSeth Jennings 
712062c5b6SDan Streetman 	return sw842_compress(src, slen, dst, dlen, ctx->wmem);
7235a1fc18SSeth Jennings }
7335a1fc18SSeth Jennings 
crypto842_scompress(struct crypto_scomp * tfm,const u8 * src,unsigned int slen,u8 * dst,unsigned int * dlen,void * ctx)746a8de3aeSGiovanni Cabiddu static int crypto842_scompress(struct crypto_scomp *tfm,
756a8de3aeSGiovanni Cabiddu 			       const u8 *src, unsigned int slen,
766a8de3aeSGiovanni Cabiddu 			       u8 *dst, unsigned int *dlen, void *ctx)
776a8de3aeSGiovanni Cabiddu {
786a8de3aeSGiovanni Cabiddu 	return sw842_compress(src, slen, dst, dlen, ctx);
796a8de3aeSGiovanni Cabiddu }
806a8de3aeSGiovanni Cabiddu 
crypto842_decompress(struct crypto_tfm * tfm,const u8 * src,unsigned int slen,u8 * dst,unsigned int * dlen)812062c5b6SDan Streetman static int crypto842_decompress(struct crypto_tfm *tfm,
822062c5b6SDan Streetman 				const u8 *src, unsigned int slen,
832062c5b6SDan Streetman 				u8 *dst, unsigned int *dlen)
8435a1fc18SSeth Jennings {
852062c5b6SDan Streetman 	return sw842_decompress(src, slen, dst, dlen);
8635a1fc18SSeth Jennings }
8735a1fc18SSeth Jennings 
crypto842_sdecompress(struct crypto_scomp * tfm,const u8 * src,unsigned int slen,u8 * dst,unsigned int * dlen,void * ctx)886a8de3aeSGiovanni Cabiddu static int crypto842_sdecompress(struct crypto_scomp *tfm,
896a8de3aeSGiovanni Cabiddu 				 const u8 *src, unsigned int slen,
906a8de3aeSGiovanni Cabiddu 				 u8 *dst, unsigned int *dlen, void *ctx)
916a8de3aeSGiovanni Cabiddu {
926a8de3aeSGiovanni Cabiddu 	return sw842_decompress(src, slen, dst, dlen);
936a8de3aeSGiovanni Cabiddu }
946a8de3aeSGiovanni Cabiddu 
9535a1fc18SSeth Jennings static struct crypto_alg alg = {
9635a1fc18SSeth Jennings 	.cra_name		= "842",
972062c5b6SDan Streetman 	.cra_driver_name	= "842-generic",
982062c5b6SDan Streetman 	.cra_priority		= 100,
9935a1fc18SSeth Jennings 	.cra_flags		= CRYPTO_ALG_TYPE_COMPRESS,
1002062c5b6SDan Streetman 	.cra_ctxsize		= sizeof(struct crypto842_ctx),
10135a1fc18SSeth Jennings 	.cra_module		= THIS_MODULE,
1026a8de3aeSGiovanni Cabiddu 	.cra_init		= crypto842_init,
1036a8de3aeSGiovanni Cabiddu 	.cra_exit		= crypto842_exit,
10435a1fc18SSeth Jennings 	.cra_u			= { .compress = {
1052062c5b6SDan Streetman 	.coa_compress		= crypto842_compress,
1062062c5b6SDan Streetman 	.coa_decompress		= crypto842_decompress } }
10735a1fc18SSeth Jennings };
10835a1fc18SSeth Jennings 
1096a8de3aeSGiovanni Cabiddu static struct scomp_alg scomp = {
1106a8de3aeSGiovanni Cabiddu 	.alloc_ctx		= crypto842_alloc_ctx,
1116a8de3aeSGiovanni Cabiddu 	.free_ctx		= crypto842_free_ctx,
1126a8de3aeSGiovanni Cabiddu 	.compress		= crypto842_scompress,
1136a8de3aeSGiovanni Cabiddu 	.decompress		= crypto842_sdecompress,
1146a8de3aeSGiovanni Cabiddu 	.base			= {
1156a8de3aeSGiovanni Cabiddu 		.cra_name	= "842",
1166a8de3aeSGiovanni Cabiddu 		.cra_driver_name = "842-scomp",
1176a8de3aeSGiovanni Cabiddu 		.cra_priority	 = 100,
1186a8de3aeSGiovanni Cabiddu 		.cra_module	 = THIS_MODULE,
1196a8de3aeSGiovanni Cabiddu 	}
1206a8de3aeSGiovanni Cabiddu };
1216a8de3aeSGiovanni Cabiddu 
crypto842_mod_init(void)1222062c5b6SDan Streetman static int __init crypto842_mod_init(void)
12335a1fc18SSeth Jennings {
1246a8de3aeSGiovanni Cabiddu 	int ret;
1256a8de3aeSGiovanni Cabiddu 
1266a8de3aeSGiovanni Cabiddu 	ret = crypto_register_alg(&alg);
1276a8de3aeSGiovanni Cabiddu 	if (ret)
1286a8de3aeSGiovanni Cabiddu 		return ret;
1296a8de3aeSGiovanni Cabiddu 
1306a8de3aeSGiovanni Cabiddu 	ret = crypto_register_scomp(&scomp);
1316a8de3aeSGiovanni Cabiddu 	if (ret) {
1326a8de3aeSGiovanni Cabiddu 		crypto_unregister_alg(&alg);
1336a8de3aeSGiovanni Cabiddu 		return ret;
1346a8de3aeSGiovanni Cabiddu 	}
1356a8de3aeSGiovanni Cabiddu 
1366a8de3aeSGiovanni Cabiddu 	return ret;
13735a1fc18SSeth Jennings }
138c4741b23SEric Biggers subsys_initcall(crypto842_mod_init);
13935a1fc18SSeth Jennings 
crypto842_mod_exit(void)1402062c5b6SDan Streetman static void __exit crypto842_mod_exit(void)
14135a1fc18SSeth Jennings {
14235a1fc18SSeth Jennings 	crypto_unregister_alg(&alg);
1436a8de3aeSGiovanni Cabiddu 	crypto_unregister_scomp(&scomp);
14435a1fc18SSeth Jennings }
1452062c5b6SDan Streetman module_exit(crypto842_mod_exit);
14635a1fc18SSeth Jennings 
14735a1fc18SSeth Jennings MODULE_LICENSE("GPL");
1482062c5b6SDan Streetman MODULE_DESCRIPTION("842 Software Compression Algorithm");
1495d26a105SKees Cook MODULE_ALIAS_CRYPTO("842");
1502062c5b6SDan Streetman MODULE_ALIAS_CRYPTO("842-generic");
1512062c5b6SDan Streetman MODULE_AUTHOR("Dan Streetman <ddstreet@ieee.org>");
152