/* Crypto operations using stored keys
 *
 * Copyright (c) 2016, Intel Corporation
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version
 * 2 of the License, or (at your option) any later version.
 */

#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/scatterlist.h>
#include <linux/crypto.h>
#include <crypto/hash.h>
#include <crypto/kpp.h>
#include <crypto/dh.h>
#include <keys/user-type.h>
#include "internal.h"

static ssize_t dh_data_from_key(key_serial_t keyid, void **data)
{
	struct key *key;
	key_ref_t key_ref;
	long status;
	ssize_t ret;

	key_ref = lookup_user_key(keyid, 0, KEY_NEED_READ);
	if (IS_ERR(key_ref)) {
		ret = -ENOKEY;
		goto error;
	}

	key = key_ref_to_ptr(key_ref);

	ret = -EOPNOTSUPP;
	if (key->type == &key_type_user) {
		down_read(&key->sem);
		status = key_validate(key);
		if (status == 0) {
			const struct user_key_payload *payload;
			uint8_t *duplicate;

			payload = user_key_payload_locked(key);

			duplicate = kmemdup(payload->data, payload->datalen,
					    GFP_KERNEL);
			if (duplicate) {
				*data = duplicate;
				ret = payload->datalen;
			} else {
				ret = -ENOMEM;
			}
		}
		up_read(&key->sem);
	}

	key_put(key);
error:
	return ret;
}

static void dh_free_data(struct dh *dh)
{
	kzfree(dh->key);
	kzfree(dh->p);
	kzfree(dh->g);
}

struct dh_completion {
	struct completion completion;
	int err;
};

static void dh_crypto_done(struct crypto_async_request *req, int err)
{
	struct dh_completion *compl = req->data;

	if (err == -EINPROGRESS)
		return;

	compl->err = err;
	complete(&compl->completion);
}

struct kdf_sdesc {
	struct shash_desc shash;
	char ctx[];
};

static int kdf_alloc(struct kdf_sdesc **sdesc_ret, char *hashname)
{
	struct crypto_shash *tfm;
	struct kdf_sdesc *sdesc;
	int size;
	int err;

	/* allocate synchronous hash */
	tfm = crypto_alloc_shash(hashname, 0, 0);
	if (IS_ERR(tfm)) {
		pr_info("could not allocate digest TFM handle %s\n", hashname);
		return PTR_ERR(tfm);
	}

	err = -EINVAL;
	if (crypto_shash_digestsize(tfm) == 0)
		goto out_free_tfm;

	err = -ENOMEM;
	size = sizeof(struct shash_desc) + crypto_shash_descsize(tfm);
	sdesc = kmalloc(size, GFP_KERNEL);
	if (!sdesc)
		goto out_free_tfm;
	sdesc->shash.tfm = tfm;
	sdesc->shash.flags = 0x0;

	*sdesc_ret = sdesc;

	return 0;

out_free_tfm:
	crypto_free_shash(tfm);
	return err;
}

static void kdf_dealloc(struct kdf_sdesc *sdesc)
{
	if (!sdesc)
		return;

	if (sdesc->shash.tfm)
		crypto_free_shash(sdesc->shash.tfm);

	kzfree(sdesc);
}

/*
 * Implementation of the KDF in counter mode according to SP800-108 section 5.1
 * as well as SP800-56A section 5.8.1 (Single-step KDF).
 *
 * SP800-56A:
 * The src pointer is defined as Z || other info where Z is the shared secret
 * from DH and other info is an arbitrary string (see SP800-56A section
 * 5.8.1.2).
 */
static int kdf_ctr(struct kdf_sdesc *sdesc, const u8 *src, unsigned int slen,
		   u8 *dst, unsigned int dlen, unsigned int zlen)
{
	struct shash_desc *desc = &sdesc->shash;
	unsigned int h = crypto_shash_digestsize(desc->tfm);
	int err = 0;
	u8 *dst_orig = dst;
	__be32 counter = cpu_to_be32(1);

	while (dlen) {
		err = crypto_shash_init(desc);
		if (err)
			goto err;

		err = crypto_shash_update(desc, (u8 *)&counter, sizeof(__be32));
		if (err)
			goto err;

		if (zlen && h) {
			u8 tmpbuffer[h];
			size_t chunk = min_t(size_t, zlen, h);
			memset(tmpbuffer, 0, chunk);

			do {
				err = crypto_shash_update(desc, tmpbuffer,
							  chunk);
				if (err)
					goto err;

				zlen -= chunk;
				chunk = min_t(size_t, zlen, h);
			} while (zlen);
		}

		if (src && slen) {
			err = crypto_shash_update(desc, src, slen);
			if (err)
				goto err;
		}

		if (dlen < h) {
			u8 tmpbuffer[h];

			err = crypto_shash_final(desc, tmpbuffer);
			if (err)
				goto err;
			memcpy(dst, tmpbuffer, dlen);
			memzero_explicit(tmpbuffer, h);
			return 0;
		} else {
			err = crypto_shash_final(desc, dst);
			if (err)
				goto err;

			dlen -= h;
			dst += h;
			counter = cpu_to_be32(be32_to_cpu(counter) + 1);
		}
	}

	return 0;

err:
	memzero_explicit(dst_orig, dlen);
	return err;
}

static int keyctl_dh_compute_kdf(struct kdf_sdesc *sdesc,
				 char __user *buffer, size_t buflen,
				 uint8_t *kbuf, size_t kbuflen, size_t lzero)
{
	uint8_t *outbuf = NULL;
	int ret;

	outbuf = kmalloc(buflen, GFP_KERNEL);
	if (!outbuf) {
		ret = -ENOMEM;
		goto err;
	}

	ret = kdf_ctr(sdesc, kbuf, kbuflen, outbuf, buflen, lzero);
	if (ret)
		goto err;

	ret = buflen;
	if (copy_to_user(buffer, outbuf, buflen) != 0)
		ret = -EFAULT;

err:
	kzfree(outbuf);
	return ret;
}

long __keyctl_dh_compute(struct keyctl_dh_params __user *params,
			 char __user *buffer, size_t buflen,
			 struct keyctl_kdf_params *kdfcopy)
{
	long ret;
	ssize_t dlen;
	int secretlen;
	int outlen;
	struct keyctl_dh_params pcopy;
	struct dh dh_inputs;
	struct scatterlist outsg;
	struct dh_completion compl;
	struct crypto_kpp *tfm;
	struct kpp_request *req;
	uint8_t *secret;
	uint8_t *outbuf;
	struct kdf_sdesc *sdesc = NULL;

	if (!params || (!buffer && buflen)) {
		ret = -EINVAL;
		goto out1;
	}
	if (copy_from_user(&pcopy, params, sizeof(pcopy)) != 0) {
		ret = -EFAULT;
		goto out1;
	}

	if (kdfcopy) {
		char *hashname;

		if (memchr_inv(kdfcopy->__spare, 0, sizeof(kdfcopy->__spare))) {
			ret = -EINVAL;
			goto out1;
		}

		if (buflen > KEYCTL_KDF_MAX_OUTPUT_LEN ||
		    kdfcopy->otherinfolen > KEYCTL_KDF_MAX_OI_LEN) {
			ret = -EMSGSIZE;
			goto out1;
		}

		/* get KDF name string */
		hashname = strndup_user(kdfcopy->hashname, CRYPTO_MAX_ALG_NAME);
		if (IS_ERR(hashname)) {
			ret = PTR_ERR(hashname);
			goto out1;
		}

		/* allocate KDF from the kernel crypto API */
		ret = kdf_alloc(&sdesc, hashname);
		kfree(hashname);
		if (ret)
			goto out1;
	}

	memset(&dh_inputs, 0, sizeof(dh_inputs));

	dlen = dh_data_from_key(pcopy.prime, &dh_inputs.p);
	if (dlen < 0) {
		ret = dlen;
		goto out1;
	}
	dh_inputs.p_size = dlen;

	dlen = dh_data_from_key(pcopy.base, &dh_inputs.g);
	if (dlen < 0) {
		ret = dlen;
		goto out2;
	}
	dh_inputs.g_size = dlen;

	dlen = dh_data_from_key(pcopy.private, &dh_inputs.key);
	if (dlen < 0) {
		ret = dlen;
		goto out2;
	}
	dh_inputs.key_size = dlen;

	secretlen = crypto_dh_key_len(&dh_inputs);
	secret = kmalloc(secretlen, GFP_KERNEL);
	if (!secret) {
		ret = -ENOMEM;
		goto out2;
	}
	ret = crypto_dh_encode_key(secret, secretlen, &dh_inputs);
	if (ret)
		goto out3;

	tfm = crypto_alloc_kpp("dh", CRYPTO_ALG_TYPE_KPP, 0);
	if (IS_ERR(tfm)) {
		ret = PTR_ERR(tfm);
		goto out3;
	}

	ret = crypto_kpp_set_secret(tfm, secret, secretlen);
	if (ret)
		goto out4;

	outlen = crypto_kpp_maxsize(tfm);

	if (!kdfcopy) {
		/*
		 * When not using a KDF, buflen 0 is used to read the
		 * required buffer length
		 */
		if (buflen == 0) {
			ret = outlen;
			goto out4;
		} else if (outlen > buflen) {
			ret = -EOVERFLOW;
			goto out4;
		}
	}

	outbuf = kzalloc(kdfcopy ? (outlen + kdfcopy->otherinfolen) : outlen,
			 GFP_KERNEL);
	if (!outbuf) {
		ret = -ENOMEM;
		goto out4;
	}

	sg_init_one(&outsg, outbuf, outlen);

	req = kpp_request_alloc(tfm, GFP_KERNEL);
	if (!req) {
		ret = -ENOMEM;
		goto out5;
	}

	kpp_request_set_input(req, NULL, 0);
	kpp_request_set_output(req, &outsg, outlen);
	init_completion(&compl.completion);
	kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
				 CRYPTO_TFM_REQ_MAY_SLEEP,
				 dh_crypto_done, &compl);

	/*
	 * For DH, generate_public_key and generate_shared_secret are
	 * the same calculation
	 */
	ret = crypto_kpp_generate_public_key(req);
	if (ret == -EINPROGRESS) {
		wait_for_completion(&compl.completion);
		ret = compl.err;
		if (ret)
			goto out6;
	}

	if (kdfcopy) {
		/*
		 * Concatenate SP800-56A otherinfo past DH shared secret -- the
		 * input to the KDF is (DH shared secret || otherinfo)
		 */
		if (copy_from_user(outbuf + req->dst_len, kdfcopy->otherinfo,
				   kdfcopy->otherinfolen) != 0) {
			ret = -EFAULT;
			goto out6;
		}

		ret = keyctl_dh_compute_kdf(sdesc, buffer, buflen, outbuf,
					    req->dst_len + kdfcopy->otherinfolen,
					    outlen - req->dst_len);
	} else if (copy_to_user(buffer, outbuf, req->dst_len) == 0) {
		ret = req->dst_len;
	} else {
		ret = -EFAULT;
	}

out6:
	kpp_request_free(req);
out5:
	kzfree(outbuf);
out4:
	crypto_free_kpp(tfm);
out3:
	kzfree(secret);
out2:
	dh_free_data(&dh_inputs);
out1:
	kdf_dealloc(sdesc);
	return ret;
}

long keyctl_dh_compute(struct keyctl_dh_params __user *params,
		       char __user *buffer, size_t buflen,
		       struct keyctl_kdf_params __user *kdf)
{
	struct keyctl_kdf_params kdfcopy;

	if (!kdf)
		return __keyctl_dh_compute(params, buffer, buflen, NULL);

	if (copy_from_user(&kdfcopy, kdf, sizeof(kdfcopy)) != 0)
		return -EFAULT;

	return __keyctl_dh_compute(params, buffer, buflen, &kdfcopy);
}
