// SPDX-License-Identifier: GPL-2.0

/*
 * Copyright (C) 2022 Huawei Technologies Duesseldorf GmbH
 *
 * Author: Roberto Sassu <roberto.sassu@huawei.com>
 */

#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <endian.h>
#include <limits.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/mman.h>
#include <linux/keyctl.h>
#include <sys/xattr.h>
#include <linux/fsverity.h>
#include <test_progs.h>

#include "test_verify_pkcs7_sig.skel.h"
#include "test_sig_in_xattr.skel.h"

#define MAX_DATA_SIZE (1024 * 1024)
#define MAX_SIG_SIZE 1024

#define VERIFY_USE_SECONDARY_KEYRING (1UL)
#define VERIFY_USE_PLATFORM_KEYRING  (2UL)

#ifndef SHA256_DIGEST_SIZE
#define SHA256_DIGEST_SIZE      32
#endif

/* In stripped ARM and x86-64 modules, ~ is surprisingly rare. */
#define MODULE_SIG_STRING "~Module signature appended~\n"

/*
 * Module signature information block.
 *
 * The constituents of the signature section are, in order:
 *
 *	- Signer's name
 *	- Key identifier
 *	- Signature data
 *	- Information block
 */
struct module_signature {
	__u8	algo;		/* Public-key crypto algorithm [0] */
	__u8	hash;		/* Digest algorithm [0] */
	__u8	id_type;	/* Key identifier type [PKEY_ID_PKCS7] */
	__u8	signer_len;	/* Length of signer's name [0] */
	__u8	key_id_len;	/* Length of key identifier [0] */
	__u8	__pad[3];
	__be32	sig_len;	/* Length of signature data */
};

struct data {
	__u8 data[MAX_DATA_SIZE];
	__u32 data_len;
	__u8 sig[MAX_SIG_SIZE];
	__u32 sig_len;
};

static bool kfunc_not_supported;

static int libbpf_print_cb(enum libbpf_print_level level, const char *fmt,
			   va_list args)
{
	if (level == LIBBPF_WARN)
		vprintf(fmt, args);

	if (strcmp(fmt, "libbpf: extern (func ksym) '%s': not found in kernel or module BTFs\n"))
		return 0;

	if (strcmp(va_arg(args, char *), "bpf_verify_pkcs7_signature"))
		return 0;

	kfunc_not_supported = true;
	return 0;
}

static int _run_setup_process(const char *setup_dir, const char *cmd)
{
	int child_pid, child_status;

	child_pid = fork();
	if (child_pid == 0) {
		execlp("./verify_sig_setup.sh", "./verify_sig_setup.sh", cmd,
		       setup_dir, NULL);
		exit(errno);

	} else if (child_pid > 0) {
		waitpid(child_pid, &child_status, 0);
		return WEXITSTATUS(child_status);
	}

	return -EINVAL;
}

static int populate_data_item_str(const char *tmp_dir, struct data *data_item)
{
	struct stat st;
	char data_template[] = "/tmp/dataXXXXXX";
	char path[PATH_MAX];
	int ret, fd, child_status, child_pid;

	data_item->data_len = 4;
	memcpy(data_item->data, "test", data_item->data_len);

	fd = mkstemp(data_template);
	if (fd == -1)
		return -errno;

	ret = write(fd, data_item->data, data_item->data_len);

	close(fd);

	if (ret != data_item->data_len) {
		ret = -EIO;
		goto out;
	}

	child_pid = fork();

	if (child_pid == -1) {
		ret = -errno;
		goto out;
	}

	if (child_pid == 0) {
		snprintf(path, sizeof(path), "%s/signing_key.pem", tmp_dir);

		return execlp("./sign-file", "./sign-file", "-d", "sha256",
			      path, path, data_template, NULL);
	}

	waitpid(child_pid, &child_status, 0);

	ret = WEXITSTATUS(child_status);
	if (ret)
		goto out;

	snprintf(path, sizeof(path), "%s.p7s", data_template);

	ret = stat(path, &st);
	if (ret == -1) {
		ret = -errno;
		goto out;
	}

	if (st.st_size > sizeof(data_item->sig)) {
		ret = -EINVAL;
		goto out_sig;
	}

	data_item->sig_len = st.st_size;

	fd = open(path, O_RDONLY);
	if (fd == -1) {
		ret = -errno;
		goto out_sig;
	}

	ret = read(fd, data_item->sig, data_item->sig_len);

	close(fd);

	if (ret != data_item->sig_len) {
		ret = -EIO;
		goto out_sig;
	}

	ret = 0;
out_sig:
	unlink(path);
out:
	unlink(data_template);
	return ret;
}

static int populate_data_item_mod(struct data *data_item)
{
	char mod_path[PATH_MAX], *mod_path_ptr;
	struct stat st;
	void *mod;
	FILE *fp;
	struct module_signature ms;
	int ret, fd, modlen, marker_len, sig_len;

	data_item->data_len = 0;

	if (stat("/lib/modules", &st) == -1)
		return 0;

	/* Requires CONFIG_TCP_CONG_BIC=m. */
	fp = popen("find /lib/modules/$(uname -r) -name tcp_bic.ko", "r");
	if (!fp)
		return 0;

	mod_path_ptr = fgets(mod_path, sizeof(mod_path), fp);
	pclose(fp);

	if (!mod_path_ptr)
		return 0;

	mod_path_ptr = strchr(mod_path, '\n');
	if (!mod_path_ptr)
		return 0;

	*mod_path_ptr = '\0';

	if (stat(mod_path, &st) == -1)
		return 0;

	modlen = st.st_size;
	marker_len = sizeof(MODULE_SIG_STRING) - 1;

	fd = open(mod_path, O_RDONLY);
	if (fd == -1)
		return -errno;

	mod = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);

	close(fd);

	if (mod == MAP_FAILED)
		return -errno;

	if (strncmp(mod + modlen - marker_len, MODULE_SIG_STRING, marker_len)) {
		ret = -EINVAL;
		goto out;
	}

	modlen -= marker_len;

	memcpy(&ms, mod + (modlen - sizeof(ms)), sizeof(ms));

	sig_len = __be32_to_cpu(ms.sig_len);
	modlen -= sig_len + sizeof(ms);

	if (modlen > sizeof(data_item->data)) {
		ret = -E2BIG;
		goto out;
	}

	memcpy(data_item->data, mod, modlen);
	data_item->data_len = modlen;

	if (sig_len > sizeof(data_item->sig)) {
		ret = -E2BIG;
		goto out;
	}

	memcpy(data_item->sig, mod + modlen, sig_len);
	data_item->sig_len = sig_len;
	ret = 0;
out:
	munmap(mod, st.st_size);
	return ret;
}

static void test_verify_pkcs7_sig_from_map(void)
{
	libbpf_print_fn_t old_print_cb;
	char tmp_dir_template[] = "/tmp/verify_sigXXXXXX";
	char *tmp_dir;
	struct test_verify_pkcs7_sig *skel = NULL;
	struct bpf_map *map;
	struct data data;
	int ret, zero = 0;

	/* Trigger creation of session keyring. */
	syscall(__NR_request_key, "keyring", "_uid.0", NULL,
		KEY_SPEC_SESSION_KEYRING);

	tmp_dir = mkdtemp(tmp_dir_template);
	if (!ASSERT_OK_PTR(tmp_dir, "mkdtemp"))
		return;

	ret = _run_setup_process(tmp_dir, "setup");
	if (!ASSERT_OK(ret, "_run_setup_process"))
		goto close_prog;

	skel = test_verify_pkcs7_sig__open();
	if (!ASSERT_OK_PTR(skel, "test_verify_pkcs7_sig__open"))
		goto close_prog;

	old_print_cb = libbpf_set_print(libbpf_print_cb);
	ret = test_verify_pkcs7_sig__load(skel);
	libbpf_set_print(old_print_cb);

	if (ret < 0 && kfunc_not_supported) {
		printf(
		  "%s:SKIP:bpf_verify_pkcs7_signature() kfunc not supported\n",
		  __func__);
		test__skip();
		goto close_prog;
	}

	if (!ASSERT_OK(ret, "test_verify_pkcs7_sig__load"))
		goto close_prog;

	ret = test_verify_pkcs7_sig__attach(skel);
	if (!ASSERT_OK(ret, "test_verify_pkcs7_sig__attach"))
		goto close_prog;

	map = bpf_object__find_map_by_name(skel->obj, "data_input");
	if (!ASSERT_OK_PTR(map, "data_input not found"))
		goto close_prog;

	skel->bss->monitored_pid = getpid();

	/* Test without data and signature. */
	skel->bss->user_keyring_serial = KEY_SPEC_SESSION_KEYRING;

	ret = bpf_map_update_elem(bpf_map__fd(map), &zero, &data, BPF_ANY);
	if (!ASSERT_LT(ret, 0, "bpf_map_update_elem data_input"))
		goto close_prog;

	/* Test successful signature verification with session keyring. */
	ret = populate_data_item_str(tmp_dir, &data);
	if (!ASSERT_OK(ret, "populate_data_item_str"))
		goto close_prog;

	ret = bpf_map_update_elem(bpf_map__fd(map), &zero, &data, BPF_ANY);
	if (!ASSERT_OK(ret, "bpf_map_update_elem data_input"))
		goto close_prog;

	/* Test successful signature verification with testing keyring. */
	skel->bss->user_keyring_serial = syscall(__NR_request_key, "keyring",
						 "ebpf_testing_keyring", NULL,
						 KEY_SPEC_SESSION_KEYRING);

	ret = bpf_map_update_elem(bpf_map__fd(map), &zero, &data, BPF_ANY);
	if (!ASSERT_OK(ret, "bpf_map_update_elem data_input"))
		goto close_prog;

	/*
	 * Ensure key_task_permission() is called and rejects the keyring
	 * (no Search permission).
	 */
	syscall(__NR_keyctl, KEYCTL_SETPERM, skel->bss->user_keyring_serial,
		0x37373737);

	ret = bpf_map_update_elem(bpf_map__fd(map), &zero, &data, BPF_ANY);
	if (!ASSERT_LT(ret, 0, "bpf_map_update_elem data_input"))
		goto close_prog;

	syscall(__NR_keyctl, KEYCTL_SETPERM, skel->bss->user_keyring_serial,
		0x3f3f3f3f);

	/*
	 * Ensure key_validate() is called and rejects the keyring (key expired)
	 */
	syscall(__NR_keyctl, KEYCTL_SET_TIMEOUT,
		skel->bss->user_keyring_serial, 1);
	sleep(1);

	ret = bpf_map_update_elem(bpf_map__fd(map), &zero, &data, BPF_ANY);
	if (!ASSERT_LT(ret, 0, "bpf_map_update_elem data_input"))
		goto close_prog;

	skel->bss->user_keyring_serial = KEY_SPEC_SESSION_KEYRING;

	/* Test with corrupted data (signature verification should fail). */
	data.data[0] = 'a';
	ret = bpf_map_update_elem(bpf_map__fd(map), &zero, &data, BPF_ANY);
	if (!ASSERT_LT(ret, 0, "bpf_map_update_elem data_input"))
		goto close_prog;

	ret = populate_data_item_mod(&data);
	if (!ASSERT_OK(ret, "populate_data_item_mod"))
		goto close_prog;

	/* Test signature verification with system keyrings. */
	if (data.data_len) {
		skel->bss->user_keyring_serial = 0;
		skel->bss->system_keyring_id = 0;

		ret = bpf_map_update_elem(bpf_map__fd(map), &zero, &data,
					  BPF_ANY);
		if (!ASSERT_OK(ret, "bpf_map_update_elem data_input"))
			goto close_prog;

		skel->bss->system_keyring_id = VERIFY_USE_SECONDARY_KEYRING;

		ret = bpf_map_update_elem(bpf_map__fd(map), &zero, &data,
					  BPF_ANY);
		if (!ASSERT_OK(ret, "bpf_map_update_elem data_input"))
			goto close_prog;

		skel->bss->system_keyring_id = VERIFY_USE_PLATFORM_KEYRING;

		ret = bpf_map_update_elem(bpf_map__fd(map), &zero, &data,
					  BPF_ANY);
		ASSERT_LT(ret, 0, "bpf_map_update_elem data_input");
	}

close_prog:
	_run_setup_process(tmp_dir, "cleanup");

	if (!skel)
		return;

	skel->bss->monitored_pid = 0;
	test_verify_pkcs7_sig__destroy(skel);
}

static int get_signature_size(const char *sig_path)
{
	struct stat st;

	if (stat(sig_path, &st) == -1)
		return -1;

	return st.st_size;
}

static int add_signature_to_xattr(const char *data_path, const char *sig_path)
{
	char sig[MAX_SIG_SIZE] = {0};
	int fd, size, ret;

	if (sig_path) {
		fd = open(sig_path, O_RDONLY);
		if (fd < 0)
			return -1;

		size = read(fd, sig, MAX_SIG_SIZE);
		close(fd);
		if (size <= 0)
			return -1;
	} else {
		/* no sig_path, just write 32 bytes of zeros */
		size = 32;
	}
	ret = setxattr(data_path, "user.sig", sig, size, 0);
	if (!ASSERT_OK(ret, "setxattr"))
		return -1;

	return 0;
}

static int test_open_file(struct test_sig_in_xattr *skel, char *data_path,
			  pid_t pid, bool should_success, char *name)
{
	int ret;

	skel->bss->monitored_pid = pid;
	ret = open(data_path, O_RDONLY);
	close(ret);
	skel->bss->monitored_pid = 0;

	if (should_success) {
		if (!ASSERT_GE(ret, 0, name))
			return -1;
	} else {
		if (!ASSERT_LT(ret, 0, name))
			return -1;
	}
	return 0;
}

static void test_pkcs7_sig_fsverity(void)
{
	char data_path[PATH_MAX];
	char sig_path[PATH_MAX];
	char tmp_dir_template[] = "/tmp/verify_sigXXXXXX";
	char *tmp_dir;
	struct test_sig_in_xattr *skel = NULL;
	pid_t pid;
	int ret;

	tmp_dir = mkdtemp(tmp_dir_template);
	if (!ASSERT_OK_PTR(tmp_dir, "mkdtemp"))
		return;

	snprintf(data_path, PATH_MAX, "%s/data-file", tmp_dir);
	snprintf(sig_path, PATH_MAX, "%s/sig-file", tmp_dir);

	ret = _run_setup_process(tmp_dir, "setup");
	if (!ASSERT_OK(ret, "_run_setup_process"))
		goto out;

	ret = _run_setup_process(tmp_dir, "fsverity-create-sign");

	if (ret) {
		printf("%s: SKIP: fsverity [sign|enable] doesn't work.\n"
		       "To run this test, try enable CONFIG_FS_VERITY and enable FSVerity for the filesystem.\n",
		       __func__);
		test__skip();
		goto out;
	}

	skel = test_sig_in_xattr__open();
	if (!ASSERT_OK_PTR(skel, "test_sig_in_xattr__open"))
		goto out;
	ret = get_signature_size(sig_path);
	if (!ASSERT_GT(ret, 0, "get_signature_size"))
		goto out;
	skel->bss->sig_size = ret;
	skel->bss->user_keyring_serial = syscall(__NR_request_key, "keyring",
						 "ebpf_testing_keyring", NULL,
						 KEY_SPEC_SESSION_KEYRING);
	memcpy(skel->bss->digest, "FSVerity", 8);

	ret = test_sig_in_xattr__load(skel);
	if (!ASSERT_OK(ret, "test_sig_in_xattr__load"))
		goto out;

	ret = test_sig_in_xattr__attach(skel);
	if (!ASSERT_OK(ret, "test_sig_in_xattr__attach"))
		goto out;

	pid = getpid();

	/* Case 1: fsverity is not enabled, open should succeed */
	if (test_open_file(skel, data_path, pid, true, "open_1"))
		goto out;

	/* Case 2: fsverity is enabled, xattr is missing, open should
	 * fail
	 */
	ret = _run_setup_process(tmp_dir, "fsverity-enable");
	if (!ASSERT_OK(ret, "fsverity-enable"))
		goto out;
	if (test_open_file(skel, data_path, pid, false, "open_2"))
		goto out;

	/* Case 3: fsverity is enabled, xattr has valid signature, open
	 * should succeed
	 */
	ret = add_signature_to_xattr(data_path, sig_path);
	if (!ASSERT_OK(ret, "add_signature_to_xattr_1"))
		goto out;

	if (test_open_file(skel, data_path, pid, true, "open_3"))
		goto out;

	/* Case 4: fsverity is enabled, xattr has invalid signature, open
	 * should fail
	 */
	ret = add_signature_to_xattr(data_path, NULL);
	if (!ASSERT_OK(ret, "add_signature_to_xattr_2"))
		goto out;
	test_open_file(skel, data_path, pid, false, "open_4");

out:
	_run_setup_process(tmp_dir, "cleanup");
	if (!skel)
		return;

	skel->bss->monitored_pid = 0;
	test_sig_in_xattr__destroy(skel);
}

void test_verify_pkcs7_sig(void)
{
	if (test__start_subtest("pkcs7_sig_from_map"))
		test_verify_pkcs7_sig_from_map();
	if (test__start_subtest("pkcs7_sig_fsverity"))
		test_pkcs7_sig_fsverity();
}
