// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * SMB2 compression transform helpers.
 *
 * Copyright (C) 2026 Namjae Jeon <linkinjeon@kernel.org>
 */
#include <linux/module.h>
#include <linux/overflow.h>
#include <linux/string.h>
#include <linux/unaligned.h>

#include "compress.h"
#include "lz77.h"

#define SMB2_COMPRESSION_CHAINED_HDR_LEN \
	offsetof(struct smb2_compression_hdr, CompressionAlgorithm)
#define SMB2_COMPRESSION_PAYLOAD_BASE_LEN \
	(sizeof(struct smb2_compression_payload_hdr) - sizeof(__le32))

/*
 * A NONE payload carries bytes verbatim. Keep both cursors and remaining
 * lengths together so every chained payload handler applies identical bounds
 * accounting.
 */
static int smb_decompress_none(const u8 **src, u32 *slen, u8 **dst, u32 *dlen,
			       u32 len)
{
	if (len > *slen || len > *dlen)
		return -EINVAL;

	memcpy(*dst, *src, len);
	*src += len;
	*slen -= len;
	*dst += len;
	*dlen -= len;
	return 0;
}

/*
 * Pattern_V1 represents a run of one byte. Its wire payload is always the
 * fixed-size smb2_compression_pattern_v1 structure.
 */
static int smb_decompress_pattern(const u8 **src, u32 *slen, u8 **dst,
				  u32 *dlen, u32 len)
{
	const struct smb2_compression_pattern_v1 *pattern;
	u32 repetitions;

	if (len != sizeof(*pattern) || len > *slen)
		return -EINVAL;

	pattern = (const struct smb2_compression_pattern_v1 *)*src;
	repetitions = le32_to_cpu(pattern->Repetitions);
	if (repetitions > *dlen)
		return -EINVAL;

	memset(*dst, pattern->Pattern, repetitions);
	*src += len;
	*slen -= len;
	*dst += repetitions;
	*dlen -= repetitions;
	return 0;
}

/*
 * LZ77 payload Length includes the four-byte OriginalPayloadSize field.
 * Consume that field before passing the compressed stream to the raw codec.
 */
static int smb_decompress_lz77_payload(const u8 **src, u32 *slen, u8 **dst,
				       u32 *dlen, u32 len)
{
	u32 orig_size;
	int rc;

	if (len < sizeof(__le32) || len > *slen)
		return -EINVAL;

	orig_size = get_unaligned_le32(*src);
	if (orig_size > *dlen)
		return -EINVAL;

	*src += sizeof(__le32);
	*slen -= sizeof(__le32);
	len -= sizeof(__le32);

	rc = smb_lz77_decompress(*src, len, *dst, orig_size);
	if (rc)
		return rc;

	*src += len;
	*slen -= len;
	*dst += orig_size;
	*dlen -= orig_size;
	return 0;
}

static int smb_decompress_chained(__le16 alg, bool allow_chained,
				  bool allow_pattern,
				  const struct smb2_compression_hdr *hdr,
				  u32 slen, void *dst, u32 dlen)
{
	const struct smb2_compression_payload_hdr *payload;
	const u8 *src = (const u8 *)hdr + SMB2_COMPRESSION_CHAINED_HDR_LEN;
	u32 orig_size = le32_to_cpu(hdr->OriginalCompressedSegmentSize);
	u32 remaining = slen - SMB2_COMPRESSION_CHAINED_HDR_LEN;
	u8 *out = dst;
	u32 out_remaining = dlen;
	bool first = true;
	int rc;

	if (!allow_chained || orig_size != dlen)
		return -EINVAL;

	/*
	 * The chained transform has an eight-byte top-level header. The next
	 * bytes are a sequence of payload headers whose Length fields account
	 * for payload data, including OriginalPayloadSize where applicable.
	 */
	while (remaining) {
		__le16 payload_alg;
		__le16 flags;
		u32 len;

		if (remaining < SMB2_COMPRESSION_PAYLOAD_BASE_LEN)
			return -EINVAL;

		payload = (const struct smb2_compression_payload_hdr *)src;
		payload_alg = payload->CompressionAlgorithm;
		flags = payload->Flags;
		len = le32_to_cpu(payload->Length);

		/*
		 * CHAINED marks only the first payload. Requiring NONE on every
		 * later payload rejects ambiguous or independently chained data.
		 */
		if ((first && flags != cpu_to_le16(SMB2_COMPRESSION_FLAG_CHAINED)) ||
		    (!first && flags != cpu_to_le16(SMB2_COMPRESSION_FLAG_NONE)))
			return -EINVAL;

		src += SMB2_COMPRESSION_PAYLOAD_BASE_LEN;
		remaining -= SMB2_COMPRESSION_PAYLOAD_BASE_LEN;

		if (payload_alg == SMB3_COMPRESS_NONE) {
			rc = smb_decompress_none(&src, &remaining, &out,
						 &out_remaining, len);
		} else if (payload_alg == SMB3_COMPRESS_PATTERN) {
			if (!allow_pattern)
				return -EINVAL;
			rc = smb_decompress_pattern(&src, &remaining, &out,
						    &out_remaining, len);
		} else if (payload_alg == alg && alg == SMB3_COMPRESS_LZ77) {
			rc = smb_decompress_lz77_payload(&src, &remaining, &out,
							 &out_remaining, len);
		} else {
			return -EINVAL;
		}
		if (rc)
			return rc;
		first = false;
	}

	return out_remaining ? -EINVAL : 0;
}

static int smb_decompress_unchained(__le16 alg,
				    const struct smb2_compression_hdr *hdr,
				    u32 slen, void *dst, u32 dlen)
{
	u32 orig_size, offset, comp_size;

	if (hdr->CompressionAlgorithm != alg ||
	    !smb_compress_alg_valid(hdr->CompressionAlgorithm, false))
		return -EINVAL;

	orig_size = le32_to_cpu(hdr->OriginalCompressedSegmentSize);
	offset = le32_to_cpu(hdr->Offset);
	if (offset > slen - sizeof(*hdr) || offset > dlen ||
	    orig_size > dlen - offset || orig_size + offset != dlen)
		return -EINVAL;

	memcpy(dst, (const u8 *)hdr + sizeof(*hdr), offset);
	comp_size = slen - sizeof(*hdr) - offset;
	return smb_lz77_decompress((const u8 *)hdr + sizeof(*hdr) + offset,
				   comp_size, (u8 *)dst + offset, orig_size);
}

/**
 * smb_compression_decompress() - decode an SMB2 compression transform
 * @alg: negotiated general-purpose compression algorithm
 * @allow_chained: whether chained transforms were negotiated
 * @allow_pattern: whether Pattern_V1 payloads were negotiated
 * @src: transform header followed by compressed payload data
 * @slen: total number of bytes available at @src
 * @dst: output buffer for the reconstructed SMB2 message
 * @dlen: exact expected size of the reconstructed SMB2 message
 *
 * Validate the transform type and negotiated capabilities before dispatching
 * to the chained or unchained decoder. The caller supplies the expected output
 * size after applying its transport-specific message size limits.
 *
 * Return: 0 on success, otherwise a negative errno.
 */
int smb_compression_decompress(__le16 alg, bool allow_chained,
			       bool allow_pattern, const void *src, u32 slen,
			       void *dst, u32 dlen)
{
	const struct smb2_compression_hdr *hdr = src;

	if (!src || !dst || slen < sizeof(*hdr) ||
	    hdr->ProtocolId != SMB2_COMPRESSION_TRANSFORM_ID ||
	    alg == SMB3_COMPRESS_NONE)
		return -EINVAL;

	if (hdr->Flags == cpu_to_le16(SMB2_COMPRESSION_FLAG_CHAINED))
		return smb_decompress_chained(alg, allow_chained, allow_pattern,
					      hdr, slen, dst, dlen);

	if (hdr->Flags != cpu_to_le16(SMB2_COMPRESSION_FLAG_NONE))
		return -EINVAL;

	return smb_decompress_unchained(alg, hdr, slen, dst, dlen);
}
EXPORT_SYMBOL_GPL(smb_compression_decompress);

struct smb_compression_builder {
	u8 *pos;
	u32 remaining;
	bool first;
};

/*
 * Reserve one chained payload header and initialize its common fields.
 * OriginalPayloadSize is present only for LZNT1/LZ77/LZ77+Huffman payloads.
 */
static struct smb2_compression_payload_hdr *
smb_compression_add_payload(struct smb_compression_builder *builder,
			    __le16 alg, u32 payload_len, bool orig_size)
{
	struct smb2_compression_payload_hdr *payload;
	u32 hdr_len = SMB2_COMPRESSION_PAYLOAD_BASE_LEN;
	u32 total_len;

	if (orig_size)
		hdr_len += sizeof(payload->OriginalPayloadSize);
	if (check_add_overflow(hdr_len, payload_len, &total_len) ||
	    total_len > builder->remaining)
		return NULL;

	payload = (struct smb2_compression_payload_hdr *)builder->pos;
	payload->CompressionAlgorithm = alg;
	payload->Flags = cpu_to_le16(builder->first ?
		SMB2_COMPRESSION_FLAG_CHAINED : SMB2_COMPRESSION_FLAG_NONE);
	payload->Length = cpu_to_le32(payload_len +
		(orig_size ? sizeof(payload->OriginalPayloadSize) : 0));

	builder->pos += hdr_len;
	builder->remaining -= hdr_len;
	builder->first = false;
	return payload;
}

static int smb_compression_add_pattern(struct smb_compression_builder *builder,
				       u8 pattern, u32 repetitions)
{
	struct smb2_compression_pattern_v1 *payload;

	if (!smb_compression_add_payload(builder, SMB3_COMPRESS_PATTERN,
					 sizeof(*payload), false))
		return -ENOSPC;

	payload = (struct smb2_compression_pattern_v1 *)builder->pos;
	payload->Pattern = pattern;
	payload->Reserved1 = 0;
	payload->Reserved2 = 0;
	payload->Repetitions = cpu_to_le32(repetitions);
	builder->pos += sizeof(*payload);
	builder->remaining -= sizeof(*payload);
	return 0;
}

static int smb_compression_add_none(struct smb_compression_builder *builder,
				    const u8 *src, u32 len)
{
	if (!smb_compression_add_payload(builder, SMB3_COMPRESS_NONE, len, false))
		return -ENOSPC;

	memcpy(builder->pos, src, len);
	builder->pos += len;
	builder->remaining -= len;
	return 0;
}

static int smb_compression_add_lz77(struct smb_compression_builder *builder,
				    const u8 *src, u32 len)
{
	struct smb2_compression_payload_hdr *payload;
	u32 comp_len;
	int rc;

	if (builder->remaining <= sizeof(*payload))
		return -ENOSPC;

	comp_len = builder->remaining - sizeof(*payload);
	payload = smb_compression_add_payload(builder, SMB3_COMPRESS_LZ77,
					      comp_len, true);
	if (!payload)
		return -ENOSPC;

	rc = smb_lz77_compress(src, len, builder->pos, &comp_len);
	if (rc)
		return rc;

	payload->Length = cpu_to_le32(comp_len +
				      sizeof(payload->OriginalPayloadSize));
	payload->OriginalPayloadSize = cpu_to_le32(len);
	builder->pos += comp_len;
	builder->remaining -= comp_len;
	return 0;
}

/**
 * smb_compression_compress_chained() - build a chained SMB2 transform
 * @alg: negotiated general-purpose compression algorithm
 * @allow_pattern: whether Pattern_V1 was negotiated
 * @src: complete uncompressed SMB2 message
 * @slen: size of @src
 * @dst: output buffer for the transform
 * @dlen: input capacity of @dst and output transform size
 *
 * Following the algorithm in [MS-SMB2] 3.1.4.4, encode sufficiently long
 * repeated runs at the front and back as Pattern_V1 payloads. Compress a
 * middle region larger than 1 KiB with LZ77; smaller middle regions are
 * represented by a chained NONE payload.
 *
 * This helper does not decide whether the final transform is smaller than the
 * original message. The transport caller owns that policy decision.
 *
 * Return: 0 on success, otherwise a negative errno.
 */
int smb_compression_compress_chained(__le16 alg, bool allow_pattern,
				     const void *src, u32 slen,
				     void *dst, u32 *dlen)
{
	struct smb2_compression_hdr *hdr = dst;
	struct smb_compression_builder builder;
	const u8 *input = src;
	u32 forward = 0, backward = 0, middle_len;
	int rc;

	if (!src || !dst || !dlen || alg != SMB3_COMPRESS_LZ77 ||
	    *dlen <= SMB2_COMPRESSION_CHAINED_HDR_LEN || !slen)
		return -EINVAL;

	hdr->ProtocolId = SMB2_COMPRESSION_TRANSFORM_ID;
	hdr->OriginalCompressedSegmentSize = cpu_to_le32(slen);
	builder.pos = (u8 *)dst + SMB2_COMPRESSION_CHAINED_HDR_LEN;
	builder.remaining = *dlen - SMB2_COMPRESSION_CHAINED_HDR_LEN;
	builder.first = true;

	if (allow_pattern && slen > 32) {
		for (forward = 1; forward < slen; forward++) {
			if (input[forward] != input[0])
				break;
		}
		if (forward <= 32)
			forward = 0;

		for (backward = 1; backward < slen - forward; backward++) {
			if (input[slen - backward - 1] != input[slen - 1])
				break;
		}
		if (backward <= 32)
			backward = 0;
	}

	if (forward) {
		rc = smb_compression_add_pattern(&builder, input[0], forward);
		if (rc)
			return rc;
	}

	middle_len = slen - forward - backward;
	if (middle_len > 1024)
		rc = smb_compression_add_lz77(&builder, input + forward,
					      middle_len);
	else if (middle_len)
		rc = smb_compression_add_none(&builder,
					      input + forward, middle_len);
	else
		rc = 0;
	if (rc)
		return rc;

	if (backward) {
		rc = smb_compression_add_pattern(&builder, input[slen - 1],
						 backward);
		if (rc)
			return rc;
	}

	*dlen = builder.pos - (u8 *)dst;
	return 0;
}
EXPORT_SYMBOL_GPL(smb_compression_compress_chained);
