// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Cryptographic API.
 *
 * Deflate algorithm (RFC 1951), implemented here primarily for use
 * by IPCOMP (RFC 3173 & RFC 2394).
 *
 * Copyright (c) 2003 James Morris <jmorris@intercode.com.au>
 * Copyright (c) 2023 Google, LLC. <ardb@kernel.org>
 * Copyright (c) 2025 Herbert Xu <herbert@gondor.apana.org.au>
 */
#include <crypto/internal/acompress.h>
#include <crypto/scatterwalk.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/percpu.h>
#include <linux/scatterlist.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/zlib.h>

#define DEFLATE_DEF_LEVEL		Z_DEFAULT_COMPRESSION
#define DEFLATE_DEF_WINBITS		11
#define DEFLATE_DEF_MEMLEVEL		MAX_MEM_LEVEL

struct deflate_stream {
	struct z_stream_s stream;
	u8 workspace[];
};

static DEFINE_MUTEX(deflate_stream_lock);

static void *deflate_alloc_stream(void)
{
	size_t size = max(zlib_inflate_workspacesize(),
			  zlib_deflate_workspacesize(-DEFLATE_DEF_WINBITS,
						     DEFLATE_DEF_MEMLEVEL));
	struct deflate_stream *ctx;

	ctx = kvmalloc(sizeof(*ctx) + size, GFP_KERNEL);
	if (!ctx)
		return ERR_PTR(-ENOMEM);

	ctx->stream.workspace = ctx->workspace;

	return ctx;
}

static struct crypto_acomp_streams deflate_streams = {
	.alloc_ctx = deflate_alloc_stream,
	.cfree_ctx = kvfree,
};

static int deflate_compress_one(struct acomp_req *req,
				struct deflate_stream *ds)
{
	struct z_stream_s *stream = &ds->stream;
	struct acomp_walk walk;
	int ret;

	ret = acomp_walk_virt(&walk, req, true);
	if (ret)
		return ret;

	do {
		unsigned int dcur;

		dcur = acomp_walk_next_dst(&walk);
		if (!dcur)
			return -ENOSPC;

		stream->avail_out = dcur;
		stream->next_out = walk.dst.virt.addr;

		do {
			int flush = Z_FINISH;
			unsigned int scur;

			stream->avail_in = 0;
			stream->next_in = NULL;

			scur = acomp_walk_next_src(&walk);
			if (scur) {
				if (acomp_walk_more_src(&walk, scur))
					flush = Z_NO_FLUSH;
				stream->avail_in = scur;
				stream->next_in = walk.src.virt.addr;
			}

			ret = zlib_deflate(stream, flush);

			if (scur) {
				scur -= stream->avail_in;
				acomp_walk_done_src(&walk, scur);
			}
		} while (ret == Z_OK && stream->avail_out);

		acomp_walk_done_dst(&walk, dcur);
	} while (ret == Z_OK);

	if (ret != Z_STREAM_END)
		return -EINVAL;

	req->dlen = stream->total_out;
	return 0;
}

static int deflate_compress(struct acomp_req *req)
{
	struct crypto_acomp_stream *s;
	struct deflate_stream *ds;
	int err;

	s = crypto_acomp_lock_stream_bh(&deflate_streams);
	ds = s->ctx;

	err = zlib_deflateInit2(&ds->stream, DEFLATE_DEF_LEVEL, Z_DEFLATED,
				-DEFLATE_DEF_WINBITS, DEFLATE_DEF_MEMLEVEL,
				Z_DEFAULT_STRATEGY);
	if (err != Z_OK) {
		err = -EINVAL;
		goto out;
	}

	err = deflate_compress_one(req, ds);

out:
	crypto_acomp_unlock_stream_bh(s);

	return err;
}

static int deflate_decompress_one(struct acomp_req *req,
				  struct deflate_stream *ds)
{
	struct z_stream_s *stream = &ds->stream;
	bool out_of_space = false;
	struct acomp_walk walk;
	int ret;

	ret = acomp_walk_virt(&walk, req, true);
	if (ret)
		return ret;

	do {
		unsigned int scur;

		stream->avail_in = 0;
		stream->next_in = NULL;

		scur = acomp_walk_next_src(&walk);
		if (scur) {
			stream->avail_in = scur;
			stream->next_in = walk.src.virt.addr;
		}

		do {
			unsigned int dcur;

			dcur = acomp_walk_next_dst(&walk);
			if (!dcur) {
				out_of_space = true;
				break;
			}

			stream->avail_out = dcur;
			stream->next_out = walk.dst.virt.addr;

			ret = zlib_inflate(stream, Z_NO_FLUSH);

			dcur -= stream->avail_out;
			acomp_walk_done_dst(&walk, dcur);
		} while (ret == Z_OK && stream->avail_in);

		if (scur)
			acomp_walk_done_src(&walk, scur);

		if (out_of_space)
			return -ENOSPC;
	} while (ret == Z_OK);

	if (ret != Z_STREAM_END)
		return -EINVAL;

	req->dlen = stream->total_out;
	return 0;
}

static int deflate_decompress(struct acomp_req *req)
{
	struct crypto_acomp_stream *s;
	struct deflate_stream *ds;
	int err;

	s = crypto_acomp_lock_stream_bh(&deflate_streams);
	ds = s->ctx;

	err = zlib_inflateInit2(&ds->stream, -DEFLATE_DEF_WINBITS);
	if (err != Z_OK) {
		err = -EINVAL;
		goto out;
	}

	err = deflate_decompress_one(req, ds);

out:
	crypto_acomp_unlock_stream_bh(s);

	return err;
}

static int deflate_init(struct crypto_acomp *tfm)
{
	int ret;

	mutex_lock(&deflate_stream_lock);
	ret = crypto_acomp_alloc_streams(&deflate_streams);
	mutex_unlock(&deflate_stream_lock);

	return ret;
}

static struct acomp_alg acomp = {
	.compress		= deflate_compress,
	.decompress		= deflate_decompress,
	.init			= deflate_init,
	.base.cra_name		= "deflate",
	.base.cra_driver_name	= "deflate-generic",
	.base.cra_flags		= CRYPTO_ALG_REQ_VIRT,
	.base.cra_module	= THIS_MODULE,
};

static int __init deflate_mod_init(void)
{
	return crypto_register_acomp(&acomp);
}

static void __exit deflate_mod_fini(void)
{
	crypto_unregister_acomp(&acomp);
	crypto_acomp_free_streams(&deflate_streams);
}

module_init(deflate_mod_init);
module_exit(deflate_mod_fini);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Deflate Compression Algorithm for IPCOMP");
MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>");
MODULE_AUTHOR("Ard Biesheuvel <ardb@kernel.org>");
MODULE_AUTHOR("Herbert Xu <herbert@gondor.apana.org.au>");
MODULE_ALIAS_CRYPTO("deflate");
MODULE_ALIAS_CRYPTO("deflate-generic");
