lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <2fb2db33-9d45-442a-bfb9-55173751f20f@kernel.org>
Date: Mon, 20 Jan 2025 13:23:33 +0100
From: Krzysztof Kozlowski <krzk@...nel.org>
To: Pankaj Gupta <pankaj.gupta@....com>, Jonathan Corbet <corbet@....net>,
 Rob Herring <robh@...nel.org>, Krzysztof Kozlowski <krzk+dt@...nel.org>,
 Conor Dooley <conor+dt@...nel.org>, Shawn Guo <shawnguo@...nel.org>,
 Sascha Hauer <s.hauer@...gutronix.de>,
 Pengutronix Kernel Team <kernel@...gutronix.de>,
 Fabio Estevam <festevam@...il.com>
Cc: linux-doc@...r.kernel.org, linux-kernel@...r.kernel.org,
 devicetree@...r.kernel.org, imx@...ts.linux.dev,
 linux-arm-kernel@...ts.infradead.org
Subject: Re: [PATCH v12 4/5] firmware: imx: add driver for NXP EdgeLock
 Enclave

On 20/01/2025 17:52, Pankaj Gupta wrote:
> NXP hardware IP(s) for secure-enclaves like Edgelock Enclave(ELE),
> are embedded in the SoC to support the features like HSM, SHE & V2X,
> using message based communication interface.

Fix your machine so this is not a "future" work.

> 
> The secure enclave FW communicates on a dedicated messaging unit(MU)
> based interface(s) with application core, where kernel is running.
> It exists on specific i.MX processors. e.g. i.MX8ULP, i.MX93.
> 
> This patch adds the driver for communication interface to secure-enclave,

Please do not use "This commit/patch/change", but imperative mood. See
longer explanation here:
https://elixir.bootlin.com/linux/v5.17.1/source/Documentation/process/submitting-patches.rst#L95


> for exchanging messages with NXP secure enclave HW IP(s) like EdgeLock
> Enclave (ELE) from Kernel-space, used by kernel management layers like
> - DM-Crypt.
> 
> Signed-off-by: Pankaj Gupta <pankaj.gupta@....com>
> ---



> +int ele_fetch_soc_info(struct se_if_priv *priv, void *data)
> +{
> +	int err;
> +
> +	err = ele_get_info(priv, data);
> +	if (err < 0)
> +		return err;
> +
> +	return err;
> +}
> +
> +int ele_ping(struct se_if_priv *priv)
> +{
> +	struct se_api_msg *tx_msg __free(kfree) = NULL;
> +	struct se_api_msg *rx_msg __free(kfree) = NULL;
> +	int ret = 0;
> +
> +	if (!priv) {
> +		ret = -EINVAL;
> +		goto exit;

This does not make sense. return.... but is this even possible?


> +	}
> +
> +	tx_msg = kzalloc(ELE_PING_REQ_SZ, GFP_KERNEL);
> +	if (!tx_msg) {
> +		ret = -ENOMEM;

return -ENOMEM.

> +		goto exit;

Please read in coding style how gotos are supposed to be used.

> +	}
> +
> +	rx_msg = kzalloc(ELE_PING_RSP_SZ, GFP_KERNEL);
> +	if (!rx_msg) {
> +		ret = -ENOMEM;
> +		goto exit;
> +	}
> +
> +	ret = se_fill_cmd_msg_hdr(priv,
> +				      (struct se_msg_hdr *)&tx_msg->header,
> +				      ELE_PING_REQ, ELE_PING_REQ_SZ, true);


Fix your coding style - run checkpatch strict on this.

> +	if (ret) {
> +		dev_err(priv->dev, "Error: se_fill_cmd_msg_hdr failed.\n");
> +		goto exit;
> +	}
> +


...

> +int ele_get_info(struct se_if_priv *priv, struct ele_dev_info *s_info);
> +int ele_fetch_soc_info(struct se_if_priv *priv, void *data);
> +int ele_ping(struct se_if_priv *priv);
> +int ele_service_swap(struct se_if_priv *priv,
> +		     phys_addr_t addr,
> +		     u32 addr_size, u16 flag);
> +int ele_fw_authenticate(struct se_if_priv *priv, phys_addr_t addr);
> +#endif
> diff --git a/drivers/firmware/imx/ele_common.c b/drivers/firmware/imx/ele_common.c
> new file mode 100644
> index 000000000000..67d1fa761172
> --- /dev/null
> +++ b/drivers/firmware/imx/ele_common.c
> @@ -0,0 +1,324 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright 2024 NXP
> + */
> +
> +#include "ele_base_msg.h"
> +#include "ele_common.h"
> +
> +u32 se_add_msg_crc(u32 *msg, u32 msg_len)
> +{
> +	u32 nb_words = msg_len / (u32)sizeof(u32);
> +	u32 crc = 0;
> +	u32 i;
> +
> +	for (i = 0; i < nb_words - 1; i++)
> +		crc ^= *(msg + i);
> +
> +	return crc;
> +}
> +
> +int ele_msg_rcv(struct se_if_priv *priv,
> +		struct se_clbk_handle *se_clbk_hdl)
> +{
> +	int err = 0;
> +
> +	do {
> +		/* If callback is executed before entrying to wait state,

It is not a networking device. Use Linux coding style.

You already got such comment long time ago and not much improved.


> +
> +static int se_if_probe(struct platform_device *pdev)
> +{
> +	const struct se_if_node_info_list *info_list;
> +	const struct se_if_node_info *info;
> +	struct device *dev = &pdev->dev;
> +	struct se_fw_load_info *load_fw;
> +	struct se_if_priv *priv;
> +	u32 idx;
> +	int ret;
> +
> +	idx = GET_IDX_FROM_DEV_NODE_NAME(dev->of_node);


NAK. Node can be called firmware and your entire driver collapes.

> +	info_list = device_get_match_data(dev);
> +	if (idx >= info_list->num_mu) {
> +		dev_err(dev,
> +			"Incorrect node name :%s\n",
> +			dev->of_node->full_name);

Nope. "firmware" or "secure" are correct node names. Where did you
document this ABI?

> +		dev_err(dev,
> +			"%s-<index>, acceptable index range is 0..%d\n",
> +			dev->of_node->name,
> +			info_list->num_mu - 1);
> +		ret = -EINVAL;
> +		return ret;
> +	}
> +
> +	info = &info_list->info[idx];
> +	if (!info) {
> +		ret = -EINVAL;
> +		goto exit;
> +	}
> +
> +	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> +	if (!priv) {
> +		ret = -ENOMEM;
> +		goto exit;

Nope, You don't get how common exit works. You are supposed to clean up
in comon exit paths, not print error paths, especially ones which are
not welcomed - like here.

> +	}
> +
> +	priv->dev = dev;
> +	priv->if_defs = &info->if_defs;
> +	dev_set_drvdata(dev, priv);
> +
> +	ret = devm_add_action(dev, se_if_probe_cleanup, pdev);
> +	if (ret)
> +		goto exit;
> +
> +
> +	/* Mailbox client configuration */
> +	priv->se_mb_cl.dev		= dev;
> +	priv->se_mb_cl.tx_block		= false;
> +	priv->se_mb_cl.knows_txdone	= true;
> +	priv->se_mb_cl.rx_callback	= se_if_rx_callback;
> +
> +	ret = se_if_request_channel(dev, &priv->tx_chan,
> +			&priv->se_mb_cl, MBOX_TX_NAME);
> +	if (ret)
> +		goto exit;
> +
> +	ret = se_if_request_channel(dev, &priv->rx_chan,
> +			&priv->se_mb_cl, MBOX_RX_NAME);
> +	if (ret)
> +		goto exit;
> +
> +	mutex_init(&priv->se_if_cmd_lock);
> +
> +	init_completion(&priv->waiting_rsp_clbk_hdl.done);
> +	init_completion(&priv->cmd_receiver_clbk_hdl.done);
> +
> +	if (info->pool_name) {
> +		priv->mem_pool = of_gen_pool_get(dev->of_node,
> +							 info->pool_name, 0);
> +		if (!priv->mem_pool) {
> +			dev_err(dev,
> +				"Unable to get sram pool = %s\n",
> +				info->pool_name);
> +			goto exit;

Why do you print erros twice?

> +		}
> +	}
> +
> +	if (info->reserved_dma_ranges) {
> +		ret = of_reserved_mem_device_init(dev);
> +		if (ret) {
> +			dev_err(dev,
> +				"failed to init reserved memory region %d\n",
> +				ret);
> +			goto exit;
> +		}
> +	}
> +
> +	if (info->if_defs.se_if_type == SE_TYPE_ID_HSM) {
> +		ret = se_soc_info(priv);
> +		if (ret) {
> +			dev_err(dev,
> +				"failed[%pe] to fetch SoC Info\n", ERR_PTR(ret));
> +			goto exit;
> +		}
> +	}
> +
> +	/* By default, there is no pending FW to be loaded.*/
> +	if (info_list->se_fw_img_nm.prim_fw_nm_in_rfs ||
> +			info_list->se_fw_img_nm.seco_fw_nm_in_rfs) {
> +		load_fw = get_load_fw_instance(priv);
> +		load_fw->se_fw_img_nm = &info_list->se_fw_img_nm;
> +		load_fw->is_fw_loaded = false;
> +
> +		if (info_list->se_fw_img_nm.prim_fw_nm_in_rfs) {
> +			/* allocate buffer where SE store encrypted IMEM */
> +			load_fw->imem.buf = dmam_alloc_coherent(priv->dev, ELE_IMEM_SIZE,
> +								&load_fw->imem.phyaddr,
> +								GFP_KERNEL);
> +			if (!load_fw->imem.buf) {
> +				dev_err(priv->dev,
> +					"dmam-alloc-failed: To store encr-IMEM.\n");
> +				ret = -ENOMEM;
> +				goto exit;
> +			}
> +			load_fw->imem_mgmt = true;
> +		}
> +	}
> +	dev_info(dev, "i.MX secure-enclave: %s%d interface to firmware, configured.\n",
> +			SE_TYPE_STR_HSM,
> +			priv->if_defs->se_instance_id);

Drop probe success. Useless.

> +	return ret;
> +
> +exit:
> +	/* if execution control reaches here, if probe fails.
> +	 */

Obvious comment.

> +	return dev_err_probe(dev, ret, "%s: Probe failed.", __func__);

Drop. I think I asked already long time - like 10 revisiosn ago - to
drop simple function debug messages. Look at other drivers how exit
paths are handled.



Best regards,
Krzysztof

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ