// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2015 Pengutronix, Steffen Trumtrar <kernel@pengutronix.de>
 * Copyright (C) 2021 Pengutronix, Ahmad Fatoum <kernel@pengutronix.de>
 */

#define pr_fmt(fmt) "caam blob_gen: " fmt

#include <linux/bitfield.h>
#include <linux/device.h>
#include <soc/fsl/caam-blob.h>

#include "compat.h"
#include "desc_constr.h"
#include "desc.h"
#include "error.h"
#include "intern.h"
#include "jr.h"
#include "regs.h"

#define CAAM_BLOB_DESC_BYTES_MAX					\
	/* Command to initialize & stating length of descriptor */	\
	(CAAM_CMD_SZ +							\
	/* Command to append the key-modifier + key-modifier data */	\
	 CAAM_CMD_SZ + CAAM_BLOB_KEYMOD_LENGTH +			\
	/* Command to include input key + pointer to the input key */	\
	 CAAM_CMD_SZ + CAAM_PTR_SZ_MAX +				\
	/* Command to include output key + pointer to the output key */	\
	 CAAM_CMD_SZ + CAAM_PTR_SZ_MAX +				\
	/* Command describing the operation to perform */		\
	 CAAM_CMD_SZ)

struct caam_blob_priv {
	struct device jrdev;
};

struct caam_blob_job_result {
	int err;
	struct completion completion;
};

static void caam_blob_job_done(struct device *dev, u32 *desc, u32 err, void *context)
{
	struct caam_blob_job_result *res = context;
	int ecode = 0;

	dev_dbg(dev, "%s %d: err 0x%x\n", __func__, __LINE__, err);

	if (err)
		ecode = caam_jr_strstatus(dev, err);

	res->err = ecode;

	/*
	 * Upon completion, desc points to a buffer containing a CAAM job
	 * descriptor which encapsulates data into an externally-storable
	 * blob.
	 */
	complete(&res->completion);
}

int caam_process_blob(struct caam_blob_priv *priv,
		      struct caam_blob_info *info, bool encap)
{
	const struct caam_drv_private *ctrlpriv;
	struct caam_blob_job_result testres;
	struct device *jrdev = &priv->jrdev;
	dma_addr_t dma_in, dma_out;
	int op = OP_PCLID_BLOB;
	size_t output_len;
	u32 *desc;
	u32 moo;
	int ret;

	if (info->key_mod_len > CAAM_BLOB_KEYMOD_LENGTH)
		return -EINVAL;

	if (encap) {
		op |= OP_TYPE_ENCAP_PROTOCOL;
		output_len = info->input_len + CAAM_BLOB_OVERHEAD;
	} else {
		op |= OP_TYPE_DECAP_PROTOCOL;
		output_len = info->input_len - CAAM_BLOB_OVERHEAD;
	}

	desc = kzalloc(CAAM_BLOB_DESC_BYTES_MAX, GFP_KERNEL | GFP_DMA);
	if (!desc)
		return -ENOMEM;

	dma_in = dma_map_single(jrdev, info->input, info->input_len,
				DMA_TO_DEVICE);
	if (dma_mapping_error(jrdev, dma_in)) {
		dev_err(jrdev, "unable to map input DMA buffer\n");
		ret = -ENOMEM;
		goto out_free;
	}

	dma_out = dma_map_single(jrdev, info->output, output_len,
				 DMA_FROM_DEVICE);
	if (dma_mapping_error(jrdev, dma_out)) {
		dev_err(jrdev, "unable to map output DMA buffer\n");
		ret = -ENOMEM;
		goto out_unmap_in;
	}

	ctrlpriv = dev_get_drvdata(jrdev->parent);
	moo = FIELD_GET(CSTA_MOO, rd_reg32(&ctrlpriv->ctrl->perfmon.status));
	if (moo != CSTA_MOO_SECURE && moo != CSTA_MOO_TRUSTED)
		dev_warn(jrdev,
			 "using insecure test key, enable HAB to use unique device key!\n");

	/*
	 * A data blob is encrypted using a blob key (BK); a random number.
	 * The BK is used as an AES-CCM key. The initial block (B0) and the
	 * initial counter (Ctr0) are generated automatically and stored in
	 * Class 1 Context DWords 0+1+2+3. The random BK is stored in the
	 * Class 1 Key Register. Operation Mode is set to AES-CCM.
	 */

	init_job_desc(desc, 0);
	append_key_as_imm(desc, info->key_mod, info->key_mod_len,
			  info->key_mod_len, CLASS_2 | KEY_DEST_CLASS_REG);
	append_seq_in_ptr_intlen(desc, dma_in, info->input_len, 0);
	append_seq_out_ptr_intlen(desc, dma_out, output_len, 0);
	append_operation(desc, op);

	print_hex_dump_debug("data@"__stringify(__LINE__)": ",
			     DUMP_PREFIX_ADDRESS, 16, 1, info->input,
			     info->input_len, false);
	print_hex_dump_debug("jobdesc@"__stringify(__LINE__)": ",
			     DUMP_PREFIX_ADDRESS, 16, 1, desc,
			     desc_bytes(desc), false);

	testres.err = 0;
	init_completion(&testres.completion);

	ret = caam_jr_enqueue(jrdev, desc, caam_blob_job_done, &testres);
	if (ret == -EINPROGRESS) {
		wait_for_completion(&testres.completion);
		ret = testres.err;
		print_hex_dump_debug("output@"__stringify(__LINE__)": ",
				     DUMP_PREFIX_ADDRESS, 16, 1, info->output,
				     output_len, false);
	}

	if (ret == 0)
		info->output_len = output_len;

	dma_unmap_single(jrdev, dma_out, output_len, DMA_FROM_DEVICE);
out_unmap_in:
	dma_unmap_single(jrdev, dma_in, info->input_len, DMA_TO_DEVICE);
out_free:
	kfree(desc);

	return ret;
}
EXPORT_SYMBOL(caam_process_blob);

struct caam_blob_priv *caam_blob_gen_init(void)
{
	struct caam_drv_private *ctrlpriv;
	struct device *jrdev;

	/*
	 * caam_blob_gen_init() may expectedly fail with -ENODEV, e.g. when
	 * CAAM driver didn't probe or when SoC lacks BLOB support. An
	 * error would be harsh in this case, so we stick to info level.
	 */

	jrdev = caam_jr_alloc();
	if (IS_ERR(jrdev)) {
		pr_info("job ring requested, but none currently available\n");
		return ERR_PTR(-ENODEV);
	}

	ctrlpriv = dev_get_drvdata(jrdev->parent);
	if (!ctrlpriv->blob_present) {
		dev_info(jrdev, "no hardware blob generation support\n");
		caam_jr_free(jrdev);
		return ERR_PTR(-ENODEV);
	}

	return container_of(jrdev, struct caam_blob_priv, jrdev);
}
EXPORT_SYMBOL(caam_blob_gen_init);

void caam_blob_gen_exit(struct caam_blob_priv *priv)
{
	caam_jr_free(&priv->jrdev);
}
EXPORT_SYMBOL(caam_blob_gen_exit);
