// SPDX-License-Identifier: GPL-2.0-or-later
/* Public-key operation keyctls
 *
 * Copyright (C) 2016 Red Hat, Inc. All Rights Reserved.
 * Written by David Howells (dhowells@redhat.com)
 */

#include <linux/slab.h>
#include <linux/err.h>
#include <linux/key.h>
#include <linux/keyctl.h>
#include <linux/parser.h>
#include <linux/uaccess.h>
#include <keys/user-type.h>
#include "internal.h"

static void keyctl_pkey_params_free(struct kernel_pkey_params *params)
{
	kfree(params->info);
	key_put(params->key);
}

enum {
	Opt_err,
	Opt_enc,		/* "enc=<encoding>" eg. "enc=oaep" */
	Opt_hash,		/* "hash=<digest-name>" eg. "hash=sha1" */
};

static const match_table_t param_keys = {
	{ Opt_enc,	"enc=%s" },
	{ Opt_hash,	"hash=%s" },
	{ Opt_err,	NULL }
};

/*
 * Parse the information string which consists of key=val pairs.
 */
static int keyctl_pkey_params_parse(struct kernel_pkey_params *params)
{
	unsigned long token_mask = 0;
	substring_t args[MAX_OPT_ARGS];
	char *c = params->info, *p, *q;
	int token;

	while ((p = strsep(&c, " \t"))) {
		if (*p == '\0' || *p == ' ' || *p == '\t')
			continue;
		token = match_token(p, param_keys, args);
		if (token == Opt_err)
			return -EINVAL;
		if (__test_and_set_bit(token, &token_mask))
			return -EINVAL;
		q = args[0].from;
		if (!q[0])
			return -EINVAL;

		switch (token) {
		case Opt_enc:
			params->encoding = q;
			break;

		case Opt_hash:
			params->hash_algo = q;
			break;

		default:
			return -EINVAL;
		}
	}

	return 0;
}

/*
 * Interpret parameters.  Callers must always call the free function
 * on params, even if an error is returned.
 */
static int keyctl_pkey_params_get(key_serial_t id,
				  const char __user *_info,
				  struct kernel_pkey_params *params)
{
	key_ref_t key_ref;
	void *p;
	int ret;

	memset(params, 0, sizeof(*params));
	params->encoding = "raw";

	p = strndup_user(_info, PAGE_SIZE);
	if (IS_ERR(p))
		return PTR_ERR(p);
	params->info = p;

	ret = keyctl_pkey_params_parse(params);
	if (ret < 0)
		return ret;

	key_ref = lookup_user_key(id, 0, KEY_NEED_SEARCH);
	if (IS_ERR(key_ref))
		return PTR_ERR(key_ref);
	params->key = key_ref_to_ptr(key_ref);

	if (!params->key->type->asym_query)
		return -EOPNOTSUPP;

	return 0;
}

/*
 * Get parameters from userspace.  Callers must always call the free function
 * on params, even if an error is returned.
 */
static int keyctl_pkey_params_get_2(const struct keyctl_pkey_params __user *_params,
				    const char __user *_info,
				    int op,
				    struct kernel_pkey_params *params)
{
	struct keyctl_pkey_params uparams;
	struct kernel_pkey_query info;
	int ret;

	memset(params, 0, sizeof(*params));
	params->encoding = "raw";

	if (copy_from_user(&uparams, _params, sizeof(uparams)) != 0)
		return -EFAULT;

	ret = keyctl_pkey_params_get(uparams.key_id, _info, params);
	if (ret < 0)
		return ret;

	ret = params->key->type->asym_query(params, &info);
	if (ret < 0)
		return ret;

	switch (op) {
	case KEYCTL_PKEY_ENCRYPT:
	case KEYCTL_PKEY_DECRYPT:
		if (uparams.in_len  > info.max_enc_size ||
		    uparams.out_len > info.max_dec_size)
			return -EINVAL;
		break;
	case KEYCTL_PKEY_SIGN:
	case KEYCTL_PKEY_VERIFY:
		if (uparams.in_len  > info.max_sig_size ||
		    uparams.out_len > info.max_data_size)
			return -EINVAL;
		break;
	default:
		BUG();
	}

	params->in_len  = uparams.in_len;
	params->out_len = uparams.out_len;
	return 0;
}

/*
 * Query information about an asymmetric key.
 */
long keyctl_pkey_query(key_serial_t id,
		       const char __user *_info,
		       struct keyctl_pkey_query __user *_res)
{
	struct kernel_pkey_params params;
	struct kernel_pkey_query res;
	long ret;

	ret = keyctl_pkey_params_get(id, _info, &params);
	if (ret < 0)
		goto error;

	ret = params.key->type->asym_query(&params, &res);
	if (ret < 0)
		goto error;

	ret = -EFAULT;
	if (copy_to_user(_res, &res, sizeof(res)) == 0 &&
	    clear_user(_res->__spare, sizeof(_res->__spare)) == 0)
		ret = 0;

error:
	keyctl_pkey_params_free(&params);
	return ret;
}

/*
 * Encrypt/decrypt/sign
 *
 * Encrypt data, decrypt data or sign data using a public key.
 *
 * _info is a string of supplementary information in key=val format.  For
 * instance, it might contain:
 *
 *	"enc=pkcs1 hash=sha256"
 *
 * where enc= specifies the encoding and hash= selects the OID to go in that
 * particular encoding if required.  If enc= isn't supplied, it's assumed that
 * the caller is supplying raw values.
 *
 * If successful, the amount of data written into the output buffer is
 * returned.
 */
long keyctl_pkey_e_d_s(int op,
		       const struct keyctl_pkey_params __user *_params,
		       const char __user *_info,
		       const void __user *_in,
		       void __user *_out)
{
	struct kernel_pkey_params params;
	void *in, *out;
	long ret;

	ret = keyctl_pkey_params_get_2(_params, _info, op, &params);
	if (ret < 0)
		goto error_params;

	ret = -EOPNOTSUPP;
	if (!params.key->type->asym_eds_op)
		goto error_params;

	switch (op) {
	case KEYCTL_PKEY_ENCRYPT:
		params.op = kernel_pkey_encrypt;
		break;
	case KEYCTL_PKEY_DECRYPT:
		params.op = kernel_pkey_decrypt;
		break;
	case KEYCTL_PKEY_SIGN:
		params.op = kernel_pkey_sign;
		break;
	default:
		BUG();
	}

	in = memdup_user(_in, params.in_len);
	if (IS_ERR(in)) {
		ret = PTR_ERR(in);
		goto error_params;
	}

	ret = -ENOMEM;
	out = kmalloc(params.out_len, GFP_KERNEL);
	if (!out)
		goto error_in;

	ret = params.key->type->asym_eds_op(&params, in, out);
	if (ret < 0)
		goto error_out;

	if (copy_to_user(_out, out, ret) != 0)
		ret = -EFAULT;

error_out:
	kfree(out);
error_in:
	kfree(in);
error_params:
	keyctl_pkey_params_free(&params);
	return ret;
}

/*
 * Verify a signature.
 *
 * Verify a public key signature using the given key, or if not given, search
 * for a matching key.
 *
 * _info is a string of supplementary information in key=val format.  For
 * instance, it might contain:
 *
 *	"enc=pkcs1 hash=sha256"
 *
 * where enc= specifies the signature blob encoding and hash= selects the OID
 * to go in that particular encoding.  If enc= isn't supplied, it's assumed
 * that the caller is supplying raw values.
 *
 * If successful, 0 is returned.
 */
long keyctl_pkey_verify(const struct keyctl_pkey_params __user *_params,
			const char __user *_info,
			const void __user *_in,
			const void __user *_in2)
{
	struct kernel_pkey_params params;
	void *in, *in2;
	long ret;

	ret = keyctl_pkey_params_get_2(_params, _info, KEYCTL_PKEY_VERIFY,
				       &params);
	if (ret < 0)
		goto error_params;

	ret = -EOPNOTSUPP;
	if (!params.key->type->asym_verify_signature)
		goto error_params;

	in = memdup_user(_in, params.in_len);
	if (IS_ERR(in)) {
		ret = PTR_ERR(in);
		goto error_params;
	}

	in2 = memdup_user(_in2, params.in2_len);
	if (IS_ERR(in2)) {
		ret = PTR_ERR(in2);
		goto error_in;
	}

	params.op = kernel_pkey_verify;
	ret = params.key->type->asym_verify_signature(&params, in, in2);

	kfree(in2);
error_in:
	kfree(in);
error_params:
	keyctl_pkey_params_free(&params);
	return ret;
}
