// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright 2021 Google LLC
 *
 * This program provides commands that dump certain types of output from the
 * fips140 kernel module, as required by the FIPS lab for evaluation purposes.
 *
 * While the fips140 kernel module can only be accessed directly by other kernel
 * code, an easy-to-use userspace utility program was desired for lab testing.
 * When possible, this program uses AF_ALG to access the crypto algorithms; this
 * requires that the kernel has AF_ALG enabled.  Where AF_ALG isn't sufficient,
 * a custom device node /dev/fips140 is used instead; this requires that the
 * fips140 module is loaded and has evaluation testing support compiled in.
 *
 * This program can be compiled and run on an Android device as follows:
 *
 *	NDK_DIR=$HOME/android-ndk-r23b  # adjust directory path as needed
 *	$NDK_DIR/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android31-clang \
 *		fips140_lab_util.c -O2 -Wall -o fips140_lab_util
 *	adb push fips140_lab_util /data/local/tmp/
 *	adb root
 *	adb shell /data/local/tmp/fips140_lab_util
 */

#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <limits.h>
#include <linux/if_alg.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/sysmacros.h>
#include <unistd.h>

#include "../../crypto/fips140-eval-testing-uapi.h"

/* ---------------------------------------------------------------------------
 *			       Utility functions
 * ---------------------------------------------------------------------------*/

#define ARRAY_SIZE(A)	(sizeof(A) / sizeof((A)[0]))
#define MIN(a, b)	((a) < (b) ? (a) : (b))
#define MAX(a, b)	((a) > (b) ? (a) : (b))

static void __attribute__((noreturn))
do_die(const char *format, va_list va, int err)
{
	fputs("ERROR: ", stderr);
	vfprintf(stderr, format, va);
	if (err)
		fprintf(stderr, ": %s", strerror(err));
	putc('\n', stderr);
	exit(1);
}

static void __attribute__((noreturn, format(printf, 1, 2)))
die_errno(const char *format, ...)
{
	va_list va;

	va_start(va, format);
	do_die(format, va, errno);
	va_end(va);
}

static void __attribute__((noreturn, format(printf, 1, 2)))
die(const char *format, ...)
{
	va_list va;

	va_start(va, format);
	do_die(format, va, 0);
	va_end(va);
}

static void __attribute__((noreturn))
assertion_failed(const char *expr, const char *file, int line)
{
	die("Assertion failed: %s at %s:%d", expr, file, line);
}

#define ASSERT(e) ({ if (!(e)) assertion_failed(#e, __FILE__, __LINE__); })

static void rand_bytes(uint8_t *bytes, size_t count)
{
	size_t i;

	for (i = 0; i < count; i++)
		bytes[i] = rand();
}

static const char *booltostr(bool b)
{
	return b ? "true" : "false";
}

static const char *bytes_to_hex(const uint8_t *bytes, size_t count)
{
	static char hex[1025];
	size_t i;

	ASSERT(count <= 512);
	for (i = 0; i < count; i++)
		sprintf(&hex[2*i], "%02x", bytes[i]);
	return hex;
}

static void full_write(int fd, const void *buf, size_t count)
{
	while (count) {
		ssize_t ret = write(fd, buf, count);

		if (ret < 0)
			die_errno("write failed");
		buf += ret;
		count -= ret;
	}
}

enum {
	OPT_AMOUNT,
	OPT_ITERATIONS,
};

static void usage(void);

/* ---------------------------------------------------------------------------
 *			      /dev/fips140 ioctls
 * ---------------------------------------------------------------------------*/

static int get_fips140_device_number(void)
{
	FILE *f;
	char line[128];
	int number;
	char name[32];

	f = fopen("/proc/devices", "r");
	if (!f)
		die_errno("Failed to open /proc/devices");
	while (fgets(line, sizeof(line), f)) {
		if (sscanf(line, "%d %31s", &number, name) == 2 &&
		    strcmp(name, "fips140") == 0)
			return number;
	}
	fclose(f);
	die("fips140 device node is unavailable.\n"
"The fips140 device node is only available when the fips140 module is loaded\n"
"and has been built with evaluation testing support.");
}

static void create_fips140_node_if_needed(void)
{
	struct stat stbuf;
	int major;

	if (stat("/dev/fips140", &stbuf) == 0)
		return;

	major = get_fips140_device_number();
	if (mknod("/dev/fips140", S_IFCHR | 0600, makedev(major, 1)) != 0)
		die_errno("Failed to create fips140 device node");
}

static int fips140_dev_fd = -1;

static int fips140_ioctl(int cmd, const void *arg)
{
	if (fips140_dev_fd < 0) {
		create_fips140_node_if_needed();
		fips140_dev_fd = open("/dev/fips140", O_RDONLY);
		if (fips140_dev_fd < 0)
			die_errno("Failed to open /dev/fips140");
	}
	return ioctl(fips140_dev_fd, cmd, arg);
}

static bool fips140_is_approved_service(const char *name)
{
	int ret = fips140_ioctl(FIPS140_IOCTL_IS_APPROVED_SERVICE, name);

	if (ret < 0)
		die_errno("FIPS140_IOCTL_IS_APPROVED_SERVICE unexpectedly failed");
	if (ret == 1)
		return true;
	if (ret == 0)
		return false;
	die("FIPS140_IOCTL_IS_APPROVED_SERVICE returned unexpected value %d",
	    ret);
}

static const char *fips140_module_version(void)
{
	static char buf[256];
	int ret;

	memset(buf, 0, sizeof(buf));
	ret = fips140_ioctl(FIPS140_IOCTL_MODULE_VERSION, buf);
	if (ret < 0)
		die_errno("FIPS140_IOCTL_MODULE_VERSION unexpectedly failed");
	if (ret != 0)
		die("FIPS140_IOCTL_MODULE_VERSION returned unexpected value %d",
		    ret);
	return buf;
}

/* ---------------------------------------------------------------------------
 *				AF_ALG utilities
 * ---------------------------------------------------------------------------*/

#define AF_ALG_MAX_RNG_REQUEST_SIZE	128

static int get_alg_fd(const char *alg_type, const char *alg_name)
{
	struct sockaddr_alg addr = {};
	int alg_fd;

	alg_fd = socket(AF_ALG, SOCK_SEQPACKET, 0);
	if (alg_fd < 0)
		die("Failed to create AF_ALG socket.\n"
"AF_ALG is only available when it has been enabled in the kernel.\n");

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

	if (bind(alg_fd, (void *)&addr, sizeof(addr)) != 0)
		die_errno("Failed to bind AF_ALG socket to %s %s",
			  alg_type, alg_name);
	return alg_fd;
}

static int get_req_fd(int alg_fd, const char *alg_name)
{
	int req_fd = accept(alg_fd, NULL, NULL);

	if (req_fd < 0)
		die_errno("Failed to get request file descriptor for %s",
			  alg_name);
	return req_fd;
}

/* ---------------------------------------------------------------------------
 *			   dump_jitterentropy command
 * ---------------------------------------------------------------------------*/

static void dump_from_jent_fd(int fd, size_t count)
{
	uint8_t buf[AF_ALG_MAX_RNG_REQUEST_SIZE];

	while (count) {
		ssize_t ret;

		memset(buf, 0, sizeof(buf));
		ret = read(fd, buf, MIN(count, sizeof(buf)));
		if (ret < 0)
			die_errno("error reading from jitterentropy_rng");
		full_write(STDOUT_FILENO, buf, ret);
		count -= ret;
	}
}

static int cmd_dump_jitterentropy(int argc, char *argv[])
{
	static const struct option longopts[] = {
		{ "amount", required_argument, NULL, OPT_AMOUNT },
		{ "iterations", required_argument, NULL, OPT_ITERATIONS },
		{ NULL, 0, NULL, 0 },
	};
	size_t amount = 128;
	size_t iterations = 1;
	size_t i;
	int c;

	while ((c = getopt_long(argc, argv, "", longopts, NULL)) != -1) {
		switch (c) {
		case OPT_AMOUNT:
			amount = strtoul(optarg, NULL, 0);
			if (amount <= 0 || amount >= ULONG_MAX)
				die("invalid argument to --amount");
			break;
		case OPT_ITERATIONS:
			iterations = strtoul(optarg, NULL, 0);
			if (iterations <= 0 || iterations >= ULONG_MAX)
				die("invalid argument to --iterations");
			break;
		default:
			usage();
			return 1;
		}
	}

	for (i = 0; i < iterations; i++) {
		int alg_fd = get_alg_fd("rng", "jitterentropy_rng");
		int req_fd = get_req_fd(alg_fd, "jitterentropy_rng");

		dump_from_jent_fd(req_fd, amount);

		close(req_fd);
		close(alg_fd);
	}
	return 0;
}

/* ---------------------------------------------------------------------------
 *			  show_invalid_inputs command
 * ---------------------------------------------------------------------------*/

enum direction {
	UNSPECIFIED,
	DECRYPT,
	ENCRYPT,
};

static const struct invalid_input_test {
	const char *alg_type;
	const char *alg_name;
	const char *key;
	size_t key_size;
	const char *msg;
	size_t msg_size;
	const char *iv;
	size_t iv_size;
	enum direction direction;
	int setkey_error;
	int crypt_error;
} invalid_input_tests[] = {
	{
		.alg_type = "skcipher",
		.alg_name = "cbc(aes)",
		.key_size = 16,
	}, {
		.alg_type = "skcipher",
		.alg_name = "cbc(aes)",
		.key_size = 17,
		.setkey_error = EINVAL,
	}, {
		.alg_type = "skcipher",
		.alg_name = "cbc(aes)",
		.key_size = 24,
	}, {
		.alg_type = "skcipher",
		.alg_name = "cbc(aes)",
		.key_size = 32,
	}, {
		.alg_type = "skcipher",
		.alg_name = "cbc(aes)",
		.key_size = 33,
		.setkey_error = EINVAL,
	}, {
		.alg_type = "skcipher",
		.alg_name = "cbc(aes)",
		.key_size = 16,
		.msg_size = 1,
		.direction = DECRYPT,
		.crypt_error = EINVAL,
	}, {
		.alg_type = "skcipher",
		.alg_name = "cbc(aes)",
		.key_size = 16,
		.msg_size = 16,
		.direction = ENCRYPT,
	}, {
		.alg_type = "skcipher",
		.alg_name = "cbc(aes)",
		.key_size = 16,
		.msg_size = 17,
		.direction = ENCRYPT,
		.crypt_error = EINVAL,
	}, {
		.alg_type = "hash",
		.alg_name = "cmac(aes)",
		.key_size = 29,
		.setkey_error = EINVAL,
	}, {
		.alg_type = "skcipher",
		.alg_name = "xts(aes)",
		.key_size = 32,
	}, {
		.alg_type = "skcipher",
		.alg_name = "xts(aes)",
		.key = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
		       "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0",
		.key_size = 32,
		.setkey_error = EINVAL,
	}
};

static const char *describe_crypt_op(const struct invalid_input_test *t)
{
	if (t->direction == ENCRYPT)
		return "encryption";
	if (t->direction == DECRYPT)
		return "decryption";
	if (strcmp(t->alg_type, "hash") == 0)
		return "hashing";
	ASSERT(0);
}

static bool af_alg_setkey(const struct invalid_input_test *t, int alg_fd)
{
	const uint8_t *key = (const uint8_t *)t->key;
	uint8_t _key[t->key_size];

	if (t->key_size == 0)
		return true;

	if (t->key == NULL) {
		rand_bytes(_key, t->key_size);
		key = _key;
	}
	if (setsockopt(alg_fd, SOL_ALG, ALG_SET_KEY, key, t->key_size) != 0) {
		printf("%s: setting %zu-byte key failed with error '%s'\n",
		       t->alg_name, t->key_size, strerror(errno));
		printf("\tkey was %s\n\n", bytes_to_hex(key, t->key_size));
		ASSERT(t->setkey_error == errno);
		return false;
	}
	printf("%s: setting %zu-byte key succeeded\n",
	       t->alg_name, t->key_size);
	printf("\tkey was %s\n\n", bytes_to_hex(key, t->key_size));
	ASSERT(t->setkey_error == 0);
	return true;
}

static void af_alg_process_msg(const struct invalid_input_test *t, int alg_fd)
{
	struct iovec iov;
	struct msghdr hdr = {
		.msg_iov = &iov,
		.msg_iovlen = 1,
	};
	const uint8_t *msg = (const uint8_t *)t->msg;
	uint8_t *_msg = NULL;
	uint8_t *output = NULL;
	uint8_t *control = NULL;
	size_t controllen = 0;
	struct cmsghdr *cmsg;
	int req_fd;

	if (t->msg_size == 0)
		return;

	req_fd = get_req_fd(alg_fd, t->alg_name);

	if (t->msg == NULL) {
		_msg = malloc(t->msg_size);
		rand_bytes(_msg, t->msg_size);
		msg = _msg;
	}
	output = malloc(t->msg_size);
	iov.iov_base = (void *)msg;
	iov.iov_len = t->msg_size;

	if (t->direction != UNSPECIFIED)
		controllen += CMSG_SPACE(sizeof(uint32_t));
	if (t->iv_size)
		controllen += CMSG_SPACE(sizeof(struct af_alg_iv) + t->iv_size);
	control = calloc(1, controllen);
	hdr.msg_control = control;
	hdr.msg_controllen = controllen;
	cmsg = CMSG_FIRSTHDR(&hdr);
	if (t->direction != UNSPECIFIED) {
		cmsg->cmsg_level = SOL_ALG;
		cmsg->cmsg_type = ALG_SET_OP;
		cmsg->cmsg_len = CMSG_LEN(sizeof(uint32_t));
		*(uint32_t *)CMSG_DATA(cmsg) = t->direction == DECRYPT ?
				ALG_OP_DECRYPT : ALG_OP_ENCRYPT;
		cmsg = CMSG_NXTHDR(&hdr, cmsg);
	}
	if (t->iv_size) {
		struct af_alg_iv *alg_iv;

		cmsg->cmsg_level = SOL_ALG;
		cmsg->cmsg_type = ALG_SET_IV;
		cmsg->cmsg_len = CMSG_LEN(sizeof(*alg_iv) + t->iv_size);
		alg_iv = (struct af_alg_iv *)CMSG_DATA(cmsg);
		alg_iv->ivlen = t->iv_size;
		memcpy(alg_iv->iv, t->iv, t->iv_size);
	}

	if (sendmsg(req_fd, &hdr, 0) != t->msg_size)
		die_errno("sendmsg failed");

	if (read(req_fd, output, t->msg_size) != t->msg_size) {
		printf("%s: %s of %zu-byte message failed with error '%s'\n",
		       t->alg_name, describe_crypt_op(t), t->msg_size,
		       strerror(errno));
		printf("\tmessage was %s\n\n", bytes_to_hex(msg, t->msg_size));
		ASSERT(t->crypt_error == errno);
	} else {
		printf("%s: %s of %zu-byte message succeeded\n",
		       t->alg_name, describe_crypt_op(t), t->msg_size);
		printf("\tmessage was %s\n\n", bytes_to_hex(msg, t->msg_size));
		ASSERT(t->crypt_error == 0);
	}
	free(_msg);
	free(output);
	free(control);
	close(req_fd);
}

static void test_invalid_input(const struct invalid_input_test *t)
{
	int alg_fd = get_alg_fd(t->alg_type, t->alg_name);

	if (af_alg_setkey(t, alg_fd))
		af_alg_process_msg(t, alg_fd);

	close(alg_fd);
}

static int cmd_show_invalid_inputs(int argc, char *argv[])
{
	int i;

	for (i = 0; i < ARRAY_SIZE(invalid_input_tests); i++)
		test_invalid_input(&invalid_input_tests[i]);
	return 0;
}

/* ---------------------------------------------------------------------------
 *			  show_module_version command
 * ---------------------------------------------------------------------------*/

static int cmd_show_module_version(int argc, char *argv[])
{
	printf("fips140_module_version() => \"%s\"\n",
	       fips140_module_version());
	return 0;
}

/* ---------------------------------------------------------------------------
 *			show_service_indicators command
 * ---------------------------------------------------------------------------*/

static const char * const default_services_to_show[] = {
	"aes",
	"cbc(aes)",
	"cbcmac(aes)",
	"cmac(aes)",
	"ctr(aes)",
	"cts(cbc(aes))",
	"ecb(aes)",
	"essiv(cbc(aes),sha256)",
	"gcm(aes)",
	"hmac(sha1)",
	"hmac(sha224)",
	"hmac(sha256)",
	"hmac(sha384)",
	"hmac(sha512)",
	"jitterentropy_rng",
	"sha1",
	"sha224",
	"sha256",
	"sha384",
	"sha512",
	"stdrng",
	"xcbc(aes)",
	"xts(aes)",
};

static int cmd_show_service_indicators(int argc, char *argv[])
{
	const char * const *services = default_services_to_show;
	int count = ARRAY_SIZE(default_services_to_show);
	int i;

	if (argc > 1) {
		services = (const char **)(argv + 1);
		count = argc - 1;
	}
	for (i = 0; i < count; i++) {
		printf("fips140_is_approved_service(\"%s\") => %s\n",
		       services[i],
		       booltostr(fips140_is_approved_service(services[i])));
	}
	return 0;
}

/* ---------------------------------------------------------------------------
 *				     main()
 * ---------------------------------------------------------------------------*/

static const struct command {
	const char *name;
	int (*func)(int argc, char *argv[]);
} commands[] = {
	{ "dump_jitterentropy", cmd_dump_jitterentropy },
	{ "show_invalid_inputs", cmd_show_invalid_inputs },
	{ "show_module_version", cmd_show_module_version },
	{ "show_service_indicators", cmd_show_service_indicators },
};

static void usage(void)
{
	fprintf(stderr,
"Usage:\n"
"       fips140_lab_util dump_jitterentropy [OPTION]...\n"
"       fips140_lab_util show_invalid_inputs\n"
"       fips140_lab_util show_module_version\n"
"       fips140_lab_util show_service_indicators [SERVICE]...\n"
"\n"
"Options for dump_jitterentropy:\n"
"  --amount=AMOUNT      Amount to dump in bytes per iteration (default 128)\n"
"  --iterations=COUNT   Number of start-up iterations (default 1)\n"
	);
}

int main(int argc, char *argv[])
{
	int i;

	if (argc < 2) {
		usage();
		return 2;
	}
	for (i = 1; i < argc; i++) {
		if (strcmp(argv[i], "--help") == 0) {
			usage();
			return 2;
		}
	}

	for (i = 0; i < ARRAY_SIZE(commands); i++) {
		if (strcmp(commands[i].name, argv[1]) == 0)
			return commands[i].func(argc - 1, argv + 1);
	}
	fprintf(stderr, "Unknown command: %s\n\n", argv[1]);
	usage();
	return 2;
}
