// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2024 ARM Limited.
 */

#define _GNU_SOURCE

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>

#include <sys/socket.h>

#include <linux/kernel.h>
#include <linux/if_alg.h>

#define DATA_SIZE (16 * 4096)

static int base, sock;

static int digest_len;
static char *ref;
static char *digest;
static char *alg_name;

static struct iovec data_iov;
static int zerocopy[2];
static int sigs;
static int iter;

static void handle_exit_signal(int sig, siginfo_t *info, void *context)
{
	printf("Terminated by signal %d, iterations=%d, signals=%d\n",
	       sig, iter, sigs);
	exit(0);
}

static void handle_kick_signal(int sig, siginfo_t *info, void *context)
{
	sigs++;
}

static char *drivers[] = {
	"crct10dif-arm64-ce",
	/* "crct10dif-arm64-neon", - Same priority as generic */
	"sha1-ce",
	"sha224-arm64",
	"sha224-arm64-neon",
	"sha224-ce",
	"sha256-arm64",
	"sha256-arm64-neon",
	"sha256-ce",
	"sha384-ce",
	"sha512-ce",
	"sha3-224-ce",
	"sha3-256-ce",
	"sha3-384-ce",
	"sha3-512-ce",
	"sm3-ce",
	"sm3-neon",
};

static bool create_socket(void)
{
	FILE *proc;
	struct sockaddr_alg addr;
	char buf[1024];
	char *c, *driver_name;
	bool is_shash, match;
	int ret, i;

	ret = socket(AF_ALG, SOCK_SEQPACKET, 0);
	if (ret < 0) {
		if (errno == EAFNOSUPPORT) {
			printf("AF_ALG not supported\n");
			return false;
		}

		printf("Failed to create AF_ALG socket: %s (%d)\n",
		       strerror(errno), errno);
		return false;
	}
	base = ret;

	memset(&addr, 0, sizeof(addr));
	addr.salg_family = AF_ALG;
	strncpy((char *)addr.salg_type, "hash", sizeof(addr.salg_type));

	proc = fopen("/proc/crypto", "r");
	if (!proc) {
		printf("Unable to open /proc/crypto\n");
		return false;
	}

	driver_name = NULL;
	is_shash = false;
	match = false;

	/* Look through /proc/crypto for a driver with kernel mode FP usage */
	while (!match) {
		c = fgets(buf, sizeof(buf), proc);
		if (!c) {
			if (feof(proc)) {
				printf("Nothing found in /proc/crypto\n");
				return false;
			}
			continue;
		}

		/* Algorithm descriptions are separated by a blank line */
		if (*c == '\n') {
			if (is_shash && driver_name) {
				for (i = 0; i < ARRAY_SIZE(drivers); i++) {
					if (strcmp(drivers[i],
						   driver_name) == 0) {
						match = true;
					}
				}
			}

			if (!match) {
				digest_len = 0;

				free(driver_name);
				driver_name = NULL;

				free(alg_name);
				alg_name = NULL;

				is_shash = false;
			}
			continue;
		}

		/* Remove trailing newline */
		c = strchr(buf, '\n');
		if (c)
			*c = '\0';

		/* Find the field/value separator and start of the value */
		c = strchr(buf, ':');
		if (!c)
			continue;
		c += 2;

		if (strncmp(buf, "digestsize", strlen("digestsize")) == 0)
			sscanf(c, "%d", &digest_len);

		if (strncmp(buf, "name", strlen("name")) == 0)
			alg_name = strdup(c);

		if (strncmp(buf, "driver", strlen("driver")) == 0)
			driver_name = strdup(c);

		if (strncmp(buf, "type", strlen("type")) == 0)
			if (strncmp(c, "shash", strlen("shash")) == 0)
				is_shash = true;
	}

	strncpy((char *)addr.salg_name, alg_name,
		sizeof(addr.salg_name) - 1);

	ret = bind(base, (struct sockaddr *)&addr, sizeof(addr));
	if (ret < 0) {
		printf("Failed to bind %s: %s (%d)\n",
		       addr.salg_name, strerror(errno), errno);
		return false;
	}

	ret = accept(base, NULL, 0);
	if (ret < 0) {
		printf("Failed to accept %s: %s (%d)\n",
		       addr.salg_name, strerror(errno), errno);
		return false;
	}

	sock = ret;

	ret = pipe(zerocopy);
	if (ret != 0) {
		printf("Failed to create zerocopy pipe: %s (%d)\n",
		       strerror(errno), errno);
		return false;
	}

	ref = malloc(digest_len);
	if (!ref) {
		printf("Failed to allocated %d byte reference\n", digest_len);
		return false;
	}

	digest = malloc(digest_len);
	if (!digest) {
		printf("Failed to allocated %d byte digest\n", digest_len);
		return false;
	}

	return true;
}

static bool compute_digest(void *buf)
{
	struct iovec iov;
	int ret, wrote;

	iov = data_iov;
	while (iov.iov_len) {
		ret = vmsplice(zerocopy[1], &iov, 1, SPLICE_F_GIFT);
		if (ret < 0) {
			printf("Failed to send buffer: %s (%d)\n",
			       strerror(errno), errno);
			return false;
		}

		wrote = ret;
		ret = splice(zerocopy[0], NULL, sock, NULL, wrote, 0);
		if (ret < 0) {
			printf("Failed to splice buffer: %s (%d)\n",
			       strerror(errno), errno);
		} else if (ret != wrote) {
			printf("Short splice: %d < %d\n", ret, wrote);
		}

		iov.iov_len -= wrote;
		iov.iov_base += wrote;
	}

reread:
	ret = recv(sock, buf, digest_len, 0);
	if (ret == 0) {
		printf("No digest returned\n");
		return false;
	}
	if (ret != digest_len) {
		if (errno == -EAGAIN)
			goto reread;
		printf("Failed to get digest: %s (%d)\n",
		       strerror(errno), errno);
		return false;
	}

	return true;
}

int main(void)
{
	char *data;
	struct sigaction sa;
	int ret;

	/* Ensure we have unbuffered output */
	setvbuf(stdout, NULL, _IOLBF, 0);

	/* The parent will communicate with us via signals */
	memset(&sa, 0, sizeof(sa));
	sa.sa_sigaction = handle_exit_signal;
	sa.sa_flags = SA_RESTART | SA_SIGINFO;
	sigemptyset(&sa.sa_mask);
	ret = sigaction(SIGTERM, &sa, NULL);
	if (ret < 0)
		printf("Failed to install SIGTERM handler: %s (%d)\n",
		       strerror(errno), errno);

	sa.sa_sigaction = handle_kick_signal;
	ret = sigaction(SIGUSR2, &sa, NULL);
	if (ret < 0)
		printf("Failed to install SIGUSR2 handler: %s (%d)\n",
		       strerror(errno), errno);

	data = malloc(DATA_SIZE);
	if (!data) {
		printf("Failed to allocate data buffer\n");
		return EXIT_FAILURE;
	}
	memset(data, 0, DATA_SIZE);

	data_iov.iov_base = data;
	data_iov.iov_len = DATA_SIZE;

	/*
	 * If we can't create a socket assume it's a lack of system
	 * support and fall back to a basic FPSIMD test for the
	 * benefit of fp-stress.
	 */
	if (!create_socket()) {
		execl("./fpsimd-test", "./fpsimd-test", NULL);
		printf("Failed to fall back to fspimd-test: %d (%s)\n",
			errno, strerror(errno));
		return EXIT_FAILURE;
	}

	/*
	 * Compute a reference digest we hope is repeatable, we do
	 * this at runtime partly to make it easier to play with
	 * parameters.
	 */
	if (!compute_digest(ref)) {
		printf("Failed to compute reference digest\n");
		return EXIT_FAILURE;
	}

	printf("AF_ALG using %s\n", alg_name);

	while (true) {
		if (!compute_digest(digest)) {
			printf("Failed to compute digest, iter=%d\n", iter);
			return EXIT_FAILURE;
		}

		if (memcmp(ref, digest, digest_len) != 0) {
			printf("Digest mismatch, iter=%d\n", iter);
			return EXIT_FAILURE;
		}

		iter++;
	}

	return EXIT_FAILURE;
}
