/*
 *  sound/soc/codecs/rt5510-param.c
 *  Driver to Richtek RT5510 SPKAMP Param
 *
 *  Copyright (C) 2018 Richtek Technology Inc.
 *  cy_huang <cy_huang@richtek.com>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2 as
 *  published by the Free Software Foundation.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *  See http://www.gnu.org/licenses/gpl-2.0.html for more details.
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/version.h>
#include <sound/soc.h>
/* param security purpose */
#include <linux/crypto.h>
#include <linux/scatterlist.h>
#include <crypto/akcipher.h>
#include <crypto/algapi.h>
#include <linux/crc32.h>
#include <crypto/hash.h>

#include "rt5510.h"

struct rt5510_param_drvdata {
	struct device *dev;
	struct rt5510_chip *chip;
	void *param;
	int param_size;
};

struct sec_header {
	char tag[8];
	u16 BHV;
	u16 MSHV;
	u32 TBS;
	char ICTagString[16];
	char BinDesc[96];
	char date[16];
	u32 EHO;
	u32 EHS;
	u32 EDS;
	u32 CRC;
	char AuthorInfo[80];
	u8 upub_key[144];
	u8 uinfo_sig[128];
	u8 hinfo_sig[128];
} __packed;

/* rsa 1024 sig */
#define SIG_SIZE	(128)
/* rsa 1024 pub key */
#define PUBKEY_SIZE	(140)
/* SHA256 Digest */
#define DIG_SIZE	(32)
/* Current Support Header version ver 1.0 */
#define MIN_HEADER_VER	(0x0100)

static const uint8_t def_pub_key[PUBKEY_SIZE] = {
	0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xca, 0x46, 0x23, 0xf8, 0xac,
	0x77, 0xcd, 0x0c, 0xa7, 0x3d, 0xbe, 0x27, 0xd7, 0x1d, 0xdc, 0x48, 0x57,
	0x12, 0xfc, 0x39, 0x78, 0xf5, 0x49, 0x99, 0x4e, 0x03, 0x90, 0x3e, 0x6d,
	0xa7, 0xdd, 0x9d, 0x66, 0x78, 0x3d, 0xe8, 0x83, 0x16, 0x15, 0x15, 0x03,
	0x4a, 0x20, 0x99, 0xc1, 0x75, 0x6a, 0xfe, 0x37, 0xae, 0x89, 0x8d, 0xb7,
	0xf5, 0x51, 0xb6, 0xf0, 0xca, 0xd5, 0x9b, 0xd2, 0x91, 0xdb, 0xf9, 0x01,
	0x78, 0x02, 0x8e, 0xdf, 0x23, 0xcb, 0x52, 0x43, 0xb1, 0x8d, 0xde, 0x1a,
	0x7d, 0x0f, 0xce, 0xd8, 0x65, 0xc7, 0x57, 0x04, 0xd8, 0xf6, 0x54, 0xee,
	0x15, 0x62, 0xb1, 0x07, 0x81, 0xd4, 0xf6, 0x08, 0xe7, 0x53, 0xa7, 0xad,
	0x7f, 0x5f, 0x58, 0x62, 0xd2, 0xee, 0xb5, 0x40, 0x9d, 0x0b, 0x83, 0x07,
	0x30, 0xd1, 0x13, 0xba, 0x43, 0x25, 0x56, 0xc7, 0x1f, 0x34, 0xed, 0x80,
	0x6f, 0x50, 0xe7, 0x02, 0x03, 0x01, 0x00, 0x01,
};

static int rt5510_param_header_digest(struct device *dev, const void *in,
				      int in_cnt, void *out, int out_cnt)
{
	struct crypto_shash *tfm;
	int ret;

	dev_dbg(dev, "%s ++\n", __func__);
	if (!dev || !in || !out || !in_cnt || out_cnt != DIG_SIZE)
		return -EINVAL;
	/* sha256 digest gen */
	tfm = crypto_alloc_shash("sha256", 0, 0);
	if (IS_ERR(tfm))
		return PTR_ERR(tfm);
	{
		SHASH_DESC_ON_STACK(desc, tfm);
		desc->tfm = tfm;
		desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
		ret = crypto_shash_digest(desc, in, in_cnt, out);
		if (ret < 0)
			dev_err(dev, "%s: gen digest fail\n", __func__);
		shash_desc_zero(desc);
	}
	crypto_free_shash(tfm);
	dev_dbg(dev, "%s --\n", __func__);
	return ret;
}

struct crypto_result {
	struct completion completion;
	int err;
};

static const u8 RSA_digest_info_SHA256[] = {
	0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
	0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
	0x00, 0x04, 0x20
};

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

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

static int pkcs_1_v1_5_decode_emsa(struct device *dev, const u8 *in, int inlen)
{
	const u8 *asn1_template = RSA_digest_info_SHA256;
	int asn1_size = ARRAY_SIZE(RSA_digest_info_SHA256);
	int hash_size = 32;
	unsigned int t_offset, ps_end, ps_start, i;

	if (!dev || !in || !inlen)
		return -EINVAL;
	if (inlen < 2 + 1 + asn1_size + hash_size)
		return -EINVAL;

	ps_start = 2;
	if (in[0] != 0x00 && in[1] != 0x01) {
		dev_err(dev, "[in[0] == %02u], [in[1] = %02u]\n", in[0], in[1]);
		return -EBADMSG;
	}
	t_offset = inlen - (asn1_size + hash_size);
	ps_end = t_offset - 1;
	if (in[ps_end] != 0x00) {
		dev_err(dev, "[in[T-1] == %02u]\n", in[ps_end]);
		return -EBADMSG;
	}
	for (i = ps_start; i < ps_end; i++) {
		if (in[i] != 0xff) {
			dev_err(dev, "[in[PS%x] == %02u]\n", i - 2, in[i]);
			return -EBADMSG;
		}
	}
	if (crypto_memneq(asn1_template, in + t_offset, asn1_size) != 0) {
		dev_err(dev, "[in[T] ASN.1 mismatch]\n");
		return -EBADMSG;
	}
	return t_offset + asn1_size;
}

static int rt5510_param_sig_output(struct device *dev,
				   const void *pubkey, int pubkey_size,
				   const void *sig, int sig_size,
				   const void *dig, int dig_size)
{
	struct crypto_result compl;
	struct crypto_akcipher *tfm;
	struct akcipher_request *req;
	struct scatterlist sig_sg, digest_sg;
	void *output;
	unsigned int outlen;
	int ret = 0;

	dev_dbg(dev, "%s ++\n", __func__);
	if (!dev || !pubkey || pubkey_size < PUBKEY_SIZE ||
		!sig || sig_size < SIG_SIZE || !dig || dig_size < DIG_SIZE)
		return -EINVAL;
	tfm = crypto_alloc_akcipher("rsa", 0, 0);
	if (IS_ERR(tfm))
		return PTR_ERR(tfm);
	req = akcipher_request_alloc(tfm, GFP_KERNEL);
	if (!req)
		goto err_free_tfm;
	ret = crypto_akcipher_set_pub_key(tfm, pubkey, pubkey_size);
	if (ret < 0)
		goto err_free_req;
	outlen = crypto_akcipher_maxsize(tfm);
	output = devm_kzalloc(dev, outlen, GFP_KERNEL);
	if (!output)
		goto err_free_req;
	sg_init_one(&sig_sg, sig, sig_size);
	sg_init_one(&digest_sg, output, outlen);
	akcipher_request_set_crypt(req, &sig_sg, &digest_sg, sig_size, outlen);
	init_completion(&compl.completion);
	akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
				      CRYPTO_TFM_REQ_MAY_SLEEP,
				      rt5510_param_key_verify_done, &compl);
	ret = crypto_akcipher_verify(req);
	if (ret == -EINPROGRESS) {
		wait_for_completion(&compl.completion);
		ret = compl.err;
	}
	if (ret < 0)
		goto out_free_output;
	ret = pkcs_1_v1_5_decode_emsa(dev, output, req->dst_len);
	if (ret < 0)
		goto out_free_output;
	if (memcmp(dig, output + ret, DIG_SIZE) != 0)
		ret = -EKEYREJECTED;
	else
		ret = 0;
	dev_dbg(dev, "%s result [%d] --\n", __func__, ret);
out_free_output:
	devm_kfree(dev, output);
err_free_req:
	akcipher_request_free(req);
err_free_tfm:
	crypto_free_akcipher(tfm);
	return ret;
}

static int rt5510_param_header_check_signature(struct device *dev,
					       const char *buf, size_t cnt)
{
	const struct sec_header *header = (const struct sec_header *)buf;
	u8 digest[DIG_SIZE];
	int ret;

	/* verify user info sig AuthorInfo to UserPubkey first */
	memset(digest, 0, DIG_SIZE);
	ret = rt5510_param_header_digest(dev, (void *)header + 160,
					 224, digest, DIG_SIZE);
	if (ret < 0) {
		dev_err(dev, "digest fail\n");
		return ret;
	}
	ret = rt5510_param_sig_output(dev, def_pub_key, PUBKEY_SIZE,
				      header->uinfo_sig, SIG_SIZE, digest,
				      DIG_SIZE);
	if (ret < 0) {
		dev_err(dev, "user info sig fail\n");
		return ret;
	}
	/* verify header info sig tag to crc first */
	memset(digest, 0, DIG_SIZE);
	ret = rt5510_param_header_digest(dev, (void *)header, 160,
					 digest, DIG_SIZE);
	if (ret < 0) {
		dev_err(dev, "digest fail\n");
		return ret;
	}
	ret = rt5510_param_sig_output(dev, header->upub_key, PUBKEY_SIZE,
				      header->hinfo_sig, SIG_SIZE, digest,
				      DIG_SIZE);
	if (ret < 0) {
		dev_err(dev, "header info sig fail\n");
		return ret;
	}
	return 0;
}

static int rt5510_param_header_validate(struct device *dev,
					const char *buf, size_t cnt)
{
	const struct sec_header *header = (const struct sec_header *)buf;
	u32 size;
	int ret;

	if (header->MSHV > MIN_HEADER_VER) {
		dev_err(dev, "not support header version 0x%04x", header->MSHV);
		return -ENOTSUPP;
	}
	/* check signature pub_key digest */
	ret = rt5510_param_header_check_signature(dev, buf, cnt);
	if (ret < 0) {
		dev_err(dev, "check header signature fail\n");
		return ret;
	}
	/* check bin size match */
	size = (u32)sizeof(*header) + header->EHO + header->EHS + header->EDS;
	if (size != header->TBS || size != cnt) {
		dev_err(dev, "check size fail\n");
		return -EINVAL;
	}
	return 0;
}

static int rt5510_param_data_validate(struct device *dev,
				      const char *buf, size_t cnt)
{
	const struct sec_header *header = (const struct sec_header *)buf;
	u8 *data;
	int offset;
	u32 crc;

	offset = sizeof(*header) + header->EHO + header->EHS;
	data = (u8 *)(buf + offset);
	crc = crc32_be(-1, data, header->EDS);
	if (crc != header->CRC) {
		dev_err(dev, "crc 0x%08x, h_crc = 0x%08x not match\n",
			crc, header->CRC);
		return -EINVAL;
	}
	return 0;
}

static int rt5510_param_data_trigger(struct device *dev,
				     const char *buf, size_t count)
{
	struct rt5510_param_drvdata *p_drvdata = dev_get_drvdata(dev);
	const struct sec_header *header = (const struct sec_header *)buf;
	void *data;
	u32 data_len;
	int ret;

	/* copy buf to private variable */
	if (p_drvdata->param) {
		devm_kfree(dev, p_drvdata->param);
		p_drvdata->param = NULL;
		p_drvdata->param_size = 0;
	}
	if (!p_drvdata->param) {
		p_drvdata->param = devm_kzalloc(dev, count, GFP_KERNEL);
		if (!p_drvdata->param)
			return -ENOMEM;
		p_drvdata->param_size = count;
		memcpy(p_drvdata->param, buf, count);
	}
	data = (void *)(buf + sizeof(*header) + header->EHO + header->EHS);
	data_len = header->EDS;
	ret = rt5510_codec_trigger_param_write(p_drvdata->chip, data, data_len);
	if (ret < 0) {
		dev_err(dev, "trigger parameter write fail\n");
		return ret;
	}
	return 0;
}

static ssize_t rt5510_param_file_show(struct device *dev,
				      struct device_attribute *attr, char *buf)
{
	struct rt5510_param_drvdata *p_drvdata = dev_get_drvdata(dev);

	if (!p_drvdata->param)
		return scnprintf(buf, PAGE_SIZE, "no proprietary param\n");
	memcpy(buf, p_drvdata->param, p_drvdata->param_size);
	return p_drvdata->param_size;
}

static ssize_t rt5510_param_file_store(struct device *dev,
				       struct device_attribute *attr,
				       const char *buf, size_t count)
{
	int ret;

	if (count < sizeof(struct sec_header))
		return -EINVAL;
	ret = rt5510_param_header_validate(dev, buf, count);
	if (ret < 0) {
		dev_err(dev, "parameter check header fail\n");
		return ret;
	}
	ret = rt5510_param_data_validate(dev, buf, count);
	if (ret < 0) {
		dev_err(dev, "parameter check data fail\n");
		return ret;
	}
	ret = rt5510_param_data_trigger(dev, buf, count);
	if (ret < 0) {
		dev_err(dev, "parameter trigger data fail\n");
		return ret;
	}
	return count;
}

static const DEVICE_ATTR(prop_params, 0644, rt5510_param_file_show,
			 rt5510_param_file_store);

static int rt5510_param_probe(struct platform_device *pdev)
{
	struct rt5510_chip *chip = dev_get_drvdata(pdev->dev.parent);
	struct rt5510_param_drvdata *p_drvdata = NULL;
	int ret = 0;

	dev_info(&pdev->dev, "%s: ++\n", __func__);
	p_drvdata = devm_kzalloc(&pdev->dev, sizeof(*p_drvdata), GFP_KERNEL);
	if (!p_drvdata)
		return -ENOMEM;
	/* drvdata initialize */
	p_drvdata->dev = &pdev->dev;
	p_drvdata->chip = chip;
	platform_set_drvdata(pdev, p_drvdata);
	ret = device_create_file(&pdev->dev, &dev_attr_prop_params);
	if (ret < 0)
		goto cfile_fail;
	dev_info(&pdev->dev, "%s: --\n", __func__);
	return 0;
cfile_fail:
	devm_kfree(&pdev->dev, p_drvdata);
	platform_set_drvdata(pdev, NULL);
	return ret;
}

static int rt5510_param_remove(struct platform_device *pdev)
{
	struct rt5510_param_drvdata *p_drvdata = platform_get_drvdata(pdev);

	dev_dbg(p_drvdata->dev, "%s: ++\n", __func__);
	dev_dbg(p_drvdata->dev, "%s: --\n", __func__);
	return 0;
}

static const struct platform_device_id rt5510_param_pdev_id[] = {
	{ "rt5510-param", 0},
	{ },
};
MODULE_DEVICE_TABLE(platform, rt5510_param_pdev_id);

static struct platform_driver rt5510_param_driver = {
	.driver = {
		.name = "rt5510-param",
		.owner = THIS_MODULE,
	},
	.probe = rt5510_param_probe,
	.remove = rt5510_param_remove,
	.id_table = rt5510_param_pdev_id,
};
module_platform_driver(rt5510_param_driver);
