// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2019 Microsoft Corporation.
 *
 * Author:  Jaskaran Singh Khurana <jaskarankhurana@linux.microsoft.com>
 *
 */
#include <linux/device-mapper.h>
#include <linux/verification.h>
#include <keys/user-type.h>
#include <linux/module.h>
#include "dm-verity.h"
#include "dm-verity-verify-sig.h"

#define DM_VERITY_VERIFY_ERR(s) DM_VERITY_ROOT_HASH_VERIFICATION " " s

static bool require_signatures;
module_param(require_signatures, bool, 0444);
MODULE_PARM_DESC(require_signatures,
		"Verify the roothash of dm-verity hash tree");

#define DM_VERITY_IS_SIG_FORCE_ENABLED() \
	(require_signatures != false)

bool verity_verify_is_sig_opt_arg(const char *arg_name)
{
	return (!strcasecmp(arg_name,
			    DM_VERITY_ROOT_HASH_VERIFICATION_OPT_SIG_KEY));
}

static int verity_verify_get_sig_from_key(const char *key_desc,
					struct dm_verity_sig_opts *sig_opts)
{
	struct key *key;
	const struct user_key_payload *ukp;
	int ret = 0;

	key = request_key(&key_type_user,
			key_desc, NULL);
	if (IS_ERR(key))
		return PTR_ERR(key);

	down_read(&key->sem);

	ukp = user_key_payload_locked(key);
	if (!ukp) {
		ret = -EKEYREVOKED;
		goto end;
	}

	sig_opts->sig = kmalloc(ukp->datalen, GFP_KERNEL);
	if (!sig_opts->sig) {
		ret = -ENOMEM;
		goto end;
	}
	sig_opts->sig_size = ukp->datalen;

	memcpy(sig_opts->sig, ukp->data, sig_opts->sig_size);

end:
	up_read(&key->sem);
	key_put(key);

	return ret;
}

int verity_verify_sig_parse_opt_args(struct dm_arg_set *as,
				     struct dm_verity *v,
				     struct dm_verity_sig_opts *sig_opts,
				     unsigned int *argc,
				     const char *arg_name)
{
	struct dm_target *ti = v->ti;
	int ret;
	const char *sig_key = NULL;

	if (v->signature_key_desc) {
		ti->error = DM_VERITY_VERIFY_ERR("root_hash_sig_key_desc already specified");
		return -EINVAL;
	}

	if (!*argc) {
		ti->error = DM_VERITY_VERIFY_ERR("Signature key not specified");
		return -EINVAL;
	}

	sig_key = dm_shift_arg(as);
	(*argc)--;

	ret = verity_verify_get_sig_from_key(sig_key, sig_opts);
	if (ret < 0) {
		ti->error = DM_VERITY_VERIFY_ERR("Invalid key specified");
		return ret;
	}

	v->signature_key_desc = kstrdup(sig_key, GFP_KERNEL);
	if (!v->signature_key_desc) {
		ti->error = DM_VERITY_VERIFY_ERR("Could not allocate memory for signature key");
		return -ENOMEM;
	}

	return 0;
}

/*
 * verify_verify_roothash - Verify the root hash of the verity hash device
 *			     using builtin trusted keys.
 *
 * @root_hash: For verity, the roothash/data to be verified.
 * @root_hash_len: Size of the roothash/data to be verified.
 * @sig_data: The trusted signature that verifies the roothash/data.
 * @sig_len: Size of the signature.
 *
 */
int verity_verify_root_hash(const void *root_hash, size_t root_hash_len,
			    const void *sig_data, size_t sig_len)
{
	int ret;

	if (!root_hash || root_hash_len == 0)
		return -EINVAL;

	if (!sig_data  || sig_len == 0) {
		if (DM_VERITY_IS_SIG_FORCE_ENABLED())
			return -ENOKEY;
		else
			return 0;
	}

	ret = verify_pkcs7_signature(root_hash, root_hash_len, sig_data,
				sig_len,
#ifdef CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG_SECONDARY_KEYRING
				VERIFY_USE_SECONDARY_KEYRING,
#else
				NULL,
#endif
				VERIFYING_UNSPECIFIED_SIGNATURE, NULL, NULL);

	return ret;
}

void verity_verify_sig_opts_cleanup(struct dm_verity_sig_opts *sig_opts)
{
	kfree(sig_opts->sig);
	sig_opts->sig = NULL;
	sig_opts->sig_size = 0;
}
