1c942fddfSThomas 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