// 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/overflow.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_flex(*ctx, workspace, size);
	if (!ctx)
		return ERR_PTR(-ENOMEM);

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

	return ctx;
}

static void deflate_free_stream(void *ctx)
{
	kvfree(ctx);
}

static struct crypto_acomp_streams deflate_streams = {
	.alloc_ctx = deflate_alloc_stream,
	.free_ctx = deflate_free_stream,
};

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;
			unsigned long avail_in;

			dcur = acomp_walk_next_dst(&walk);

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

			ret = zlib_inflate(stream, Z_NO_FLUSH);

			if (!dcur && avail_in == stream->avail_in) {
				out_of_space = true;
				break;
			}

			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");
