// SPDX-License-Identifier: GPL-2.0+
/*
 * SSH message parser.
 *
 * Copyright (C) 2019-2021 Maximilian Luz <luzmaximilian@gmail.com>
 */

#include <asm/unaligned.h>
#include <linux/compiler.h>
#include <linux/device.h>
#include <linux/types.h>

#include <linux/surface_aggregator/serial_hub.h>
#include "ssh_parser.h"

/**
 * sshp_validate_crc() - Validate a CRC in raw message data.
 * @src: The span of data over which the CRC should be computed.
 * @crc: The pointer to the expected u16 CRC value.
 *
 * Computes the CRC of the provided data span (@src), compares it to the CRC
 * stored at the given address (@crc), and returns the result of this
 * comparison, i.e. %true if equal. This function is intended to run on raw
 * input/message data.
 *
 * Return: Returns %true if the computed CRC matches the stored CRC, %false
 * otherwise.
 */
static bool sshp_validate_crc(const struct ssam_span *src, const u8 *crc)
{
	u16 actual = ssh_crc(src->ptr, src->len);
	u16 expected = get_unaligned_le16(crc);

	return actual == expected;
}

/**
 * sshp_starts_with_syn() - Check if the given data starts with SSH SYN bytes.
 * @src: The data span to check the start of.
 */
static bool sshp_starts_with_syn(const struct ssam_span *src)
{
	return src->len >= 2 && get_unaligned_le16(src->ptr) == SSH_MSG_SYN;
}

/**
 * sshp_find_syn() - Find SSH SYN bytes in the given data span.
 * @src: The data span to search in.
 * @rem: The span (output) indicating the remaining data, starting with SSH
 *       SYN bytes, if found.
 *
 * Search for SSH SYN bytes in the given source span. If found, set the @rem
 * span to the remaining data, starting with the first SYN bytes and capped by
 * the source span length, and return %true. This function does not copy any
 * data, but rather only sets pointers to the respective start addresses and
 * length values.
 *
 * If no SSH SYN bytes could be found, set the @rem span to the zero-length
 * span at the end of the source span and return %false.
 *
 * If partial SSH SYN bytes could be found at the end of the source span, set
 * the @rem span to cover these partial SYN bytes, capped by the end of the
 * source span, and return %false. This function should then be re-run once
 * more data is available.
 *
 * Return: Returns %true if a complete SSH SYN sequence could be found,
 * %false otherwise.
 */
bool sshp_find_syn(const struct ssam_span *src, struct ssam_span *rem)
{
	size_t i;

	for (i = 0; i < src->len - 1; i++) {
		if (likely(get_unaligned_le16(src->ptr + i) == SSH_MSG_SYN)) {
			rem->ptr = src->ptr + i;
			rem->len = src->len - i;
			return true;
		}
	}

	if (unlikely(src->ptr[src->len - 1] == (SSH_MSG_SYN & 0xff))) {
		rem->ptr = src->ptr + src->len - 1;
		rem->len = 1;
		return false;
	}

	rem->ptr = src->ptr + src->len;
	rem->len = 0;
	return false;
}

/**
 * sshp_parse_frame() - Parse SSH frame.
 * @dev: The device used for logging.
 * @source: The source to parse from.
 * @frame: The parsed frame (output).
 * @payload: The parsed payload (output).
 * @maxlen: The maximum supported message length.
 *
 * Parses and validates a SSH frame, including its payload, from the given
 * source. Sets the provided @frame pointer to the start of the frame and
 * writes the limits of the frame payload to the provided @payload span
 * pointer.
 *
 * This function does not copy any data, but rather only validates the message
 * data and sets pointers (and length values) to indicate the respective parts.
 *
 * If no complete SSH frame could be found, the frame pointer will be set to
 * the %NULL pointer and the payload span will be set to the null span (start
 * pointer %NULL, size zero).
 *
 * Return: Returns zero on success or if the frame is incomplete, %-ENOMSG if
 * the start of the message is invalid, %-EBADMSG if any (frame-header or
 * payload) CRC is invalid, or %-EMSGSIZE if the SSH message is bigger than
 * the maximum message length specified in the @maxlen parameter.
 */
int sshp_parse_frame(const struct device *dev, const struct ssam_span *source,
		     struct ssh_frame **frame, struct ssam_span *payload,
		     size_t maxlen)
{
	struct ssam_span sf;
	struct ssam_span sp;

	/* Initialize output. */
	*frame = NULL;
	payload->ptr = NULL;
	payload->len = 0;

	if (!sshp_starts_with_syn(source)) {
		dev_warn(dev, "rx: parser: invalid start of frame\n");
		return -ENOMSG;
	}

	/* Check for minimum packet length. */
	if (unlikely(source->len < SSH_MESSAGE_LENGTH(0))) {
		dev_dbg(dev, "rx: parser: not enough data for frame\n");
		return 0;
	}

	/* Pin down frame. */
	sf.ptr = source->ptr + sizeof(u16);
	sf.len = sizeof(struct ssh_frame);

	/* Validate frame CRC. */
	if (unlikely(!sshp_validate_crc(&sf, sf.ptr + sf.len))) {
		dev_warn(dev, "rx: parser: invalid frame CRC\n");
		return -EBADMSG;
	}

	/* Ensure packet does not exceed maximum length. */
	sp.len = get_unaligned_le16(&((struct ssh_frame *)sf.ptr)->len);
	if (unlikely(SSH_MESSAGE_LENGTH(sp.len) > maxlen)) {
		dev_warn(dev, "rx: parser: frame too large: %llu bytes\n",
			 SSH_MESSAGE_LENGTH(sp.len));
		return -EMSGSIZE;
	}

	/* Pin down payload. */
	sp.ptr = sf.ptr + sf.len + sizeof(u16);

	/* Check for frame + payload length. */
	if (source->len < SSH_MESSAGE_LENGTH(sp.len)) {
		dev_dbg(dev, "rx: parser: not enough data for payload\n");
		return 0;
	}

	/* Validate payload CRC. */
	if (unlikely(!sshp_validate_crc(&sp, sp.ptr + sp.len))) {
		dev_warn(dev, "rx: parser: invalid payload CRC\n");
		return -EBADMSG;
	}

	*frame = (struct ssh_frame *)sf.ptr;
	*payload = sp;

	dev_dbg(dev, "rx: parser: valid frame found (type: %#04x, len: %u)\n",
		(*frame)->type, (*frame)->len);

	return 0;
}

/**
 * sshp_parse_command() - Parse SSH command frame payload.
 * @dev: The device used for logging.
 * @source: The source to parse from.
 * @command: The parsed command (output).
 * @command_data: The parsed command data/payload (output).
 *
 * Parses and validates a SSH command frame payload. Sets the @command pointer
 * to the command header and the @command_data span to the command data (i.e.
 * payload of the command). This will result in a zero-length span if the
 * command does not have any associated data/payload. This function does not
 * check the frame-payload-type field, which should be checked by the caller
 * before calling this function.
 *
 * The @source parameter should be the complete frame payload, e.g. returned
 * by the sshp_parse_frame() command.
 *
 * This function does not copy any data, but rather only validates the frame
 * payload data and sets pointers (and length values) to indicate the
 * respective parts.
 *
 * Return: Returns zero on success or %-ENOMSG if @source does not represent a
 * valid command-type frame payload, i.e. is too short.
 */
int sshp_parse_command(const struct device *dev, const struct ssam_span *source,
		       struct ssh_command **command,
		       struct ssam_span *command_data)
{
	/* Check for minimum length. */
	if (unlikely(source->len < sizeof(struct ssh_command))) {
		*command = NULL;
		command_data->ptr = NULL;
		command_data->len = 0;

		dev_err(dev, "rx: parser: command payload is too short\n");
		return -ENOMSG;
	}

	*command = (struct ssh_command *)source->ptr;
	command_data->ptr = source->ptr + sizeof(struct ssh_command);
	command_data->len = source->len - sizeof(struct ssh_command);

	dev_dbg(dev, "rx: parser: valid command found (tc: %#04x, cid: %#04x)\n",
		(*command)->tc, (*command)->cid);

	return 0;
}
