All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/37] imx: hab/caam new feature and update
@ 2021-03-25  9:29 Peng Fan
  2021-03-25  9:30 ` [PATCH 01/37] imx8mn: evk: update MAINTAINERS Peng Fan
                   ` (37 more replies)
  0 siblings, 38 replies; 42+ messages in thread
From: Peng Fan @ 2021-03-25  9:29 UTC (permalink / raw)
  To: u-boot

From: Peng <peng.fan@nxp.com>

This patchset is to upstream NXP downstream caam, hab features
One more patch is to update maintainer for imx8mn_evk board.

Aymen Sghaier (6):
  crypto: caam: Add CAAM support to i.MX8M platforms
  crypto: caam: Fix build warnings pointer casting
  crypto: Add blob command support for i.MX8M platforms
  crypto: caam: Fix pointer size to 32bit for i.MX8M
  crypto: caam: Add secure memory vid 3 support
  crypto: caam: RNG4 TRNG errata

Breno Lima (13):
  imx: imx7 Support for Manufacturing Protection
  imx: Avoid hardcoded output ring size register offset (ORSR)
  imx: Ensure CAAM clock is enabled prior getting out_jr_size
  imx: Avoid hardcoded Job Ring Max size
  imx: hab: Enable hab.c to authenticate additional images in open
    configuration
  imx: hab: Check if IVT header is HABv4
  mx7ulp: hab: Add hab_status command for HABv4 M4 boot
  imx: hab: Fix build warnings in 32-bit targets
  crypto: fsl: blob: Flush dcache range for destination address
  mx6dq: hab: Fix chip version in hab.h code
  cmd: blob: Add IMX_HAB and CAAM supported SoCs as dependency
  cmd: blob: Instantiate RNG before running CMD_BLOB
  fsl_mfgprot: Fix typo in sign_mppubk()

Clement Faure (2):
  imx8m: Add DEK blob encapsulation for imx8m
  imx8: Add DEK blob encapsulation

Clement Le Marquis (1):
  imx: caam: new u-boot command to set PRIBLOB bitfield from CAAM SCFGR
    register to 0x3

Franck LENORMAND (3):
  crypto: caam: change JR running loop
  caam: enable support for iMX7ULP
  imx7ulp: Enable support for cmd blob

Peng (1):
  imx8mn: evk: update MAINTAINERS

Peng Fan (2):
  imx8m: add regs used by CAAM
  imx: HAB: Update hab codes to support ARM64 and i.MX8M

Utkarsh Gupta (2):
  imx: HAB: Validate IVT before authenticating image
  imx: hab: Display All HAB events via hab_status command

Ye Li (7):
  imx: hab: Add function to authenticate kernel image
  hab: Change calling to ROM API failsafe
  imx: HAB: Add support for iMX8MM
  iMX8M: Add support to enable CONFIG_IMX_HAB
  imx: cmd_dek: Enable DEK only for chips supporting CAAM
  crypto: caam: Add fsl caam driver
  crypto: fsl: refactor for 32 bit version CAAM support on ARM64

 arch/arm/Kconfig                             |   6 +
 arch/arm/dts/imx8mm-evk-u-boot.dtsi          |   7 +
 arch/arm/dts/imx8mn-ddr4-evk-u-boot.dtsi     |   6 +
 arch/arm/dts/imx8mp-evk-u-boot.dtsi          |   6 +
 arch/arm/include/asm/arch-imx/cpu.h          |   1 +
 arch/arm/include/asm/arch-imx8/image.h       |  11 +
 arch/arm/include/asm/arch-imx8m/clock.h      |   1 +
 arch/arm/include/asm/arch-imx8m/imx-regs.h   |  10 +
 arch/arm/include/asm/arch-mx7/crm_regs.h     |   8 +
 arch/arm/include/asm/arch-mx7ulp/imx-regs.h  |  12 +
 arch/arm/include/asm/mach-imx/hab.h          |  37 +-
 arch/arm/mach-imx/Kconfig                    |  44 +-
 arch/arm/mach-imx/Makefile                   |   3 +
 arch/arm/mach-imx/cmd_dek.c                  | 262 ++++++-
 arch/arm/mach-imx/cmd_mfgprot.c              | 150 ++++
 arch/arm/mach-imx/hab.c                      | 417 +++++++++--
 arch/arm/mach-imx/imx8/Kconfig               |   1 +
 arch/arm/mach-imx/imx8m/Kconfig              |   1 +
 arch/arm/mach-imx/imx8m/clock_imx8mm.c       |   8 +
 arch/arm/mach-imx/imx8m/clock_imx8mq.c       |   7 +
 arch/arm/mach-imx/mx7ulp/Kconfig             |   1 +
 arch/arm/mach-imx/priblob.c                  |  33 +
 board/freescale/imx8mn_evk/MAINTAINERS       |   3 +-
 cmd/Kconfig                                  |   8 +
 cmd/Makefile                                 |   1 +
 cmd/blob.c                                   |  16 +
 cmd/cmd_fsl_caam.c                           |  88 +++
 doc/imx/habv4/guides/mx6_mx7_secure_boot.txt |  25 +
 drivers/crypto/Makefile                      |   1 +
 drivers/crypto/fsl/Kconfig                   |   6 +
 drivers/crypto/fsl/Makefile                  |   4 +-
 drivers/crypto/fsl/desc.h                    |  49 +-
 drivers/crypto/fsl/desc_constr.h             |  28 +-
 drivers/crypto/fsl/fsl_blob.c                |   6 +
 drivers/crypto/fsl/fsl_hash.c                |   6 +-
 drivers/crypto/fsl/fsl_mfgprot.c             | 160 +++++
 drivers/crypto/fsl/jobdesc.c                 |  16 +-
 drivers/crypto/fsl/jr.c                      |  53 +-
 drivers/crypto/fsl/jr.h                      |  11 +-
 drivers/crypto/fsl/type.h                    |  16 +
 drivers/crypto/fsl_caam.c                    | 720 +++++++++++++++++++
 drivers/crypto/fsl_caam_internal.h           | 230 ++++++
 include/fsl_caam.h                           |  24 +
 include/fsl_sec.h                            |  54 +-
 44 files changed, 2388 insertions(+), 169 deletions(-)
 create mode 100644 arch/arm/mach-imx/cmd_mfgprot.c
 create mode 100644 arch/arm/mach-imx/priblob.c
 create mode 100644 cmd/cmd_fsl_caam.c
 create mode 100644 drivers/crypto/fsl/fsl_mfgprot.c
 create mode 100644 drivers/crypto/fsl/type.h
 create mode 100644 drivers/crypto/fsl_caam.c
 create mode 100644 drivers/crypto/fsl_caam_internal.h
 create mode 100644 include/fsl_caam.h

-- 
2.25.1

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH 01/37] imx8mn: evk: update MAINTAINERS
  2021-03-25  9:29 [PATCH 00/37] imx: hab/caam new feature and update Peng Fan
@ 2021-03-25  9:30 ` Peng Fan
  2021-03-25  9:30 ` [PATCH 02/37] imx8m: add regs used by CAAM Peng Fan
                   ` (36 subsequent siblings)
  37 siblings, 0 replies; 42+ messages in thread
From: Peng Fan @ 2021-03-25  9:30 UTC (permalink / raw)
  To: u-boot

From: Peng <peng.fan@nxp.com>

Add imx8mn_evk_defconfig to be maintained
Typo fix

Signed-off-by: Peng <peng.fan@nxp.com>
---
 board/freescale/imx8mn_evk/MAINTAINERS | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/board/freescale/imx8mn_evk/MAINTAINERS b/board/freescale/imx8mn_evk/MAINTAINERS
index 3b0653d3c8..6d110ccf22 100644
--- a/board/freescale/imx8mn_evk/MAINTAINERS
+++ b/board/freescale/imx8mn_evk/MAINTAINERS
@@ -1,6 +1,7 @@
-i.MX8MM EVK BOARD
+i.MX8MN EVK BOARD
 M:	Peng Fan <peng.fan@nxp.com>
 S:	Maintained
 F:	board/freescale/imx8mn_evk/
 F:	include/configs/imx8mn_evk.h
 F:	configs/imx8mn_ddr4_evk_defconfig
+F:	configs/imx8mn_evk_defconfig
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH 02/37] imx8m: add regs used by CAAM
  2021-03-25  9:29 [PATCH 00/37] imx: hab/caam new feature and update Peng Fan
  2021-03-25  9:30 ` [PATCH 01/37] imx8mn: evk: update MAINTAINERS Peng Fan
@ 2021-03-25  9:30 ` Peng Fan
  2021-03-25  9:30 ` [PATCH 03/37] imx: imx7 Support for Manufacturing Protection Peng Fan
                   ` (35 subsequent siblings)
  37 siblings, 0 replies; 42+ messages in thread
From: Peng Fan @ 2021-03-25  9:30 UTC (permalink / raw)
  To: u-boot

From: Peng Fan <peng.fan@nxp.com>

Add regs used by CAAM

Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 arch/arm/include/asm/arch-imx8m/imx-regs.h | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm/include/asm/arch-imx8m/imx-regs.h b/arch/arm/include/asm/arch-imx8m/imx-regs.h
index 49bac8c1fa..b800da13a1 100644
--- a/arch/arm/include/asm/arch-imx8m/imx-regs.h
+++ b/arch/arm/include/asm/arch-imx8m/imx-regs.h
@@ -65,6 +65,16 @@
 #define IOMUXC_GPR_GPR1_GPR_ENET_QOS_INTF_SEL_MASK 0x70000
 #define FEC_QUIRK_ENET_MAC
 
+#define CAAM_ARB_BASE_ADDR              (0x00100000)
+#define CAAM_ARB_END_ADDR               (0x00107FFF)
+#define CAAM_IPS_BASE_ADDR              (0x30900000)
+#define CONFIG_SYS_FSL_SEC_OFFSET       (0)
+#define CONFIG_SYS_FSL_SEC_ADDR         (CAAM_IPS_BASE_ADDR + \
+					 CONFIG_SYS_FSL_SEC_OFFSET)
+#define CONFIG_SYS_FSL_JR0_OFFSET       (0x1000)
+#define CONFIG_SYS_FSL_JR0_ADDR         (CONFIG_SYS_FSL_SEC_ADDR + \
+					 CONFIG_SYS_FSL_JR0_OFFSET)
+#define CONFIG_SYS_FSL_MAX_NUM_OF_SEC   1
 #if !defined(__ASSEMBLY__)
 #include <asm/types.h>
 #include <linux/bitops.h>
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH 03/37] imx: imx7 Support for Manufacturing Protection
  2021-03-25  9:29 [PATCH 00/37] imx: hab/caam new feature and update Peng Fan
  2021-03-25  9:30 ` [PATCH 01/37] imx8mn: evk: update MAINTAINERS Peng Fan
  2021-03-25  9:30 ` [PATCH 02/37] imx8m: add regs used by CAAM Peng Fan
@ 2021-03-25  9:30 ` Peng Fan
  2021-03-25  9:30 ` [PATCH 04/37] imx: Avoid hardcoded output ring size register offset (ORSR) Peng Fan
                   ` (34 subsequent siblings)
  37 siblings, 0 replies; 42+ messages in thread
From: Peng Fan @ 2021-03-25  9:30 UTC (permalink / raw)
  To: u-boot

From: Breno Lima <breno.lima@nxp.com>

This code was originally developed by Raul Cardenas <raul.casas@nxp.com>
and modified to be applied in U-Boot imx_v2017.03.

More information about the initial submission can be seen
in the link below:
https://lists.denx.de/pipermail/u-boot/2016-February/245273.html

i.MX7D has an a protection feature for Manufacturing process.
This feature uses asymmetric encryption to sign and verify
authenticated software handled between parties. This command
enables the use of such feature.

The private key is unique and generated once per device.
And it is stored in secure memory and only accessible by CAAM.
Therefore, the public key generation and signature functions
are the only functions available for the user.

The manufacturing-protection authentication process can be used to
authenticate the chip to the OEM's server.

Command usage:

Print the public key for the device.
- mfgprot pubk

Generates Signature over given data.
- mfgprot sign <data_address> <data_size>

Signed-off-by: Raul Ulises Cardenas <raul.casas@nxp.com>
Signed-off-by: Breno Lima <breno.lima@nxp.com>
Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>
Reviewed-by: Ye Li <ye.li@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 arch/arm/mach-imx/Kconfig        |   9 ++
 arch/arm/mach-imx/Makefile       |   1 +
 arch/arm/mach-imx/cmd_mfgprot.c  | 150 +++++++++++++++++++++++++++++
 drivers/crypto/fsl/Makefile      |   1 +
 drivers/crypto/fsl/desc.h        |   1 +
 drivers/crypto/fsl/fsl_mfgprot.c | 160 +++++++++++++++++++++++++++++++
 include/fsl_sec.h                |   8 ++
 7 files changed, 330 insertions(+)
 create mode 100644 arch/arm/mach-imx/cmd_mfgprot.c
 create mode 100644 drivers/crypto/fsl/fsl_mfgprot.c

diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 8f64e23195..6d40c7fc4b 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -99,6 +99,15 @@ config CMD_NANDBCB
 	  This is similar to kobs-ng, which is used in Linux as separate
 	  rootfs package.
 
+config FSL_MFGPROT
+	bool "Support the 'mfgprot' command"
+	depends on IMX_HAB && ARCH_MX7
+	help
+	  This option enables the manufacturing protection command
+	  which can be used has a protection feature for Manufacturing
+	  process. With this tool is possible to authenticate the
+	  chip to the OEM's server.
+
 config NXP_BOARD_REVISION
 	bool "Read NXP board revision from fuses"
 	depends on ARCH_MX6 || ARCH_MX7
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index e6b4654cd3..25f910b36a 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -35,6 +35,7 @@ ifeq ($(SOC),$(filter $(SOC),mx7))
 obj-y 	+= cpu.o
 obj-$(CONFIG_SYS_I2C_MXC) += i2c-mxv7.o
 obj-$(CONFIG_ENV_IS_IN_MMC) += mmc_env.o
+obj-$(CONFIG_FSL_MFGPROT) += cmd_mfgprot.o
 endif
 ifeq ($(SOC),$(filter $(SOC),mx5 mx6 mx7))
 obj-$(CONFIG_IMX_VIDEO_SKIP) += video.o
diff --git a/arch/arm/mach-imx/cmd_mfgprot.c b/arch/arm/mach-imx/cmd_mfgprot.c
new file mode 100644
index 0000000000..03fc7014e1
--- /dev/null
+++ b/arch/arm/mach-imx/cmd_mfgprot.c
@@ -0,0 +1,150 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
+ *
+ * These commands enable the use of the CAAM MPPubK-generation and MPSign
+ * functions in supported i.MX devices.
+ */
+
+#include <asm/byteorder.h>
+#include <asm/arch/clock.h>
+#include <linux/compiler.h>
+#include <command.h>
+#include <common.h>
+#include <environment.h>
+#include <fsl_sec.h>
+#include <mapmem.h>
+#include <memalign.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/**
+ * do_mfgprot() - Handle the "mfgprot" command-line command
+ * @cmdtp:  Command data struct pointer
+ * @flag:   Command flag
+ * @argc:   Command-line argument count
+ * @argv:   Array of command-line arguments
+ *
+ * Returns zero on success, CMD_RET_USAGE in case of misuse and negative
+ * on error.
+ */
+static int do_mfgprot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+	u8 *m_ptr, *dgst_ptr, *c_ptr, *d_ptr, *dst_ptr;
+	char *pubk, *sign, *sel;
+	int m_size, i, ret;
+	u32 m_addr;
+
+	pubk = "pubk";
+	sign = "sign";
+	sel = argv[1];
+
+	/* Enable HAB clock */
+	u32 jr_size = 4;
+	u32 out_jr_size = sec_in32(CONFIG_SYS_FSL_JR0_ADDR + 0x102c);
+
+	if (out_jr_size != jr_size) {
+		hab_caam_clock_enable(1);
+		sec_init();
+	}
+
+	if (strcmp(sel, pubk) == 0) {
+		dst_ptr = malloc_cache_aligned(FSL_CAAM_MP_PUBK_BYTES);
+		if (!dst_ptr)
+			return -ENOMEM;
+
+		ret = gen_mppubk(dst_ptr);
+		if (ret) {
+			free(dst_ptr);
+			return ret;
+		}
+
+		/* Output results */
+		puts("Public key:\n");
+		for (i = 0; i < FSL_CAAM_MP_PUBK_BYTES; i++)
+			printf("%02X", (dst_ptr)[i]);
+		puts("\n");
+		free(dst_ptr);
+
+	} else if (strcmp(sel, sign) == 0) {
+		if (argc != 4)
+			return CMD_RET_USAGE;
+
+		m_addr = simple_strtoul(argv[2], NULL, 16);
+		m_size = simple_strtoul(argv[3], NULL, 10);
+		m_ptr = map_physmem(m_addr, m_size, MAP_NOCACHE);
+		if (!m_ptr)
+			return -ENOMEM;
+
+		dgst_ptr = malloc_cache_aligned(FSL_CAAM_MP_MES_DGST_BYTES);
+		if (!dgst_ptr) {
+			ret = -ENOMEM;
+			goto free_m;
+		}
+
+		c_ptr = malloc_cache_aligned(FSL_CAAM_MP_PRVK_BYTES);
+		if (!c_ptr) {
+			ret = -ENOMEM;
+			goto free_dgst;
+		}
+
+		d_ptr = malloc_cache_aligned(FSL_CAAM_MP_PRVK_BYTES);
+		if (!d_ptr) {
+			ret = -ENOMEM;
+			goto free_c;
+		}
+
+		ret = sign_mppubk(m_ptr, m_size, dgst_ptr, c_ptr, d_ptr);
+		if (ret)
+			goto free_d;
+
+		/* Output results */
+		puts("Message: ");
+		for (i = 0; i < m_size; i++)
+			printf("%02X ", (m_ptr)[i]);
+		puts("\n");
+
+		puts("Message Representative Digest(SHA-256):\n");
+		for (i = 0; i < FSL_CAAM_MP_MES_DGST_BYTES; i++)
+			printf("%02X", (dgst_ptr)[i]);
+		puts("\n");
+
+		puts("Signature:\n");
+		puts("C:\n");
+		for (i = 0; i < FSL_CAAM_MP_PRVK_BYTES; i++)
+			printf("%02X", (c_ptr)[i]);
+		puts("\n");
+
+		puts("d:\n");
+		for (i = 0; i < FSL_CAAM_MP_PRVK_BYTES; i++)
+			printf("%02X", (d_ptr)[i]);
+		puts("\n");
+free_d:
+	free(d_ptr);
+free_c:
+	free(c_ptr);
+free_dgst:
+	free(dgst_ptr);
+free_m:
+	unmap_sysmem(m_ptr);
+
+	} else {
+		return CMD_RET_USAGE;
+	}
+	return ret;
+}
+
+/***************************************************/
+static char mfgprot_help_text[] =
+	"Usage:\n"
+	 "Print the public key for Manufacturing Protection\n"
+	 "\tmfgprot pubk\n"
+	 "Generates a Manufacturing Protection signature\n"
+	 "\tmfgprot sign <data_addr> <size>";
+
+U_BOOT_CMD(
+	mfgprot, 4, 1, do_mfgprot,
+	"Manufacturing Protection\n",
+	mfgprot_help_text
+);
diff --git a/drivers/crypto/fsl/Makefile b/drivers/crypto/fsl/Makefile
index a5e8d38e38..eb689c1b9f 100644
--- a/drivers/crypto/fsl/Makefile
+++ b/drivers/crypto/fsl/Makefile
@@ -8,3 +8,4 @@ obj-$(CONFIG_CMD_BLOB) += fsl_blob.o
 obj-$(CONFIG_CMD_DEKBLOB) += fsl_blob.o
 obj-$(CONFIG_RSA_FREESCALE_EXP) += fsl_rsa.o
 obj-$(CONFIG_FSL_CAAM_RNG) += rng.o
+obj-$(CONFIG_FSL_MFGPROT) += fsl_mfgprot.o
diff --git a/drivers/crypto/fsl/desc.h b/drivers/crypto/fsl/desc.h
index 3589e6ea02..9d1ae059a7 100644
--- a/drivers/crypto/fsl/desc.h
+++ b/drivers/crypto/fsl/desc.h
@@ -740,6 +740,7 @@ struct __packed pdb_mp_sign {
 };
 
 #define PDB_MP_CSEL_SHIFT	17
+#define PDB_MP_CSEL_WIDTH	4
 #define PDB_MP_CSEL_P256	0x3 << PDB_MP_CSEL_SHIFT	/* P-256 */
 #define PDB_MP_CSEL_P384	0x4 << PDB_MP_CSEL_SHIFT	/* P-384 */
 #define PDB_MP_CSEL_P521	0x5 << PDB_MP_CSEL_SHIFT	/* P-521 */
diff --git a/drivers/crypto/fsl/fsl_mfgprot.c b/drivers/crypto/fsl/fsl_mfgprot.c
new file mode 100644
index 0000000000..fa874e7a9b
--- /dev/null
+++ b/drivers/crypto/fsl/fsl_mfgprot.c
@@ -0,0 +1,160 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2014-2016 Freescale Semiconductor, Inc.
+ * Copyright 2017 NXP
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <fsl_sec.h>
+#include <memalign.h>
+#include "desc.h"
+#include "desc_constr.h"
+#include "jobdesc.h"
+#include "jr.h"
+
+/* Size of MFG descriptor */
+#define MFG_PUBK_DSC_WORDS 4
+#define MFG_SIGN_DSC_WORDS 8
+
+static void mfg_build_sign_dsc(u32 *dsc_ptr, const u8 *m, int size,
+			       u8 *dgst, u8 *c, u8 *d)
+{
+	u32 *dsc = dsc_ptr;
+	struct pdb_mp_sign *pdb;
+
+	init_job_desc_pdb(dsc, 0, sizeof(struct pdb_mp_sign));
+
+	pdb = (struct pdb_mp_sign *)desc_pdb(dsc);
+
+	/* Curve */
+	pdb->pdb_hdr = (PDB_MP_CSEL_P256);
+
+	/* Message Pointer */
+	pdb_add_ptr(&pdb->dma_addr_msg, virt_to_phys((void *)m));
+
+	/* mes-resp Pointer */
+	pdb_add_ptr(&pdb->dma_addr_hash, virt_to_phys((void *)dgst));
+
+	/* C Pointer */
+	pdb_add_ptr(&pdb->dma_addr_c_sig, virt_to_phys((void *)c));
+
+	/* d Pointer */
+	pdb_add_ptr(&pdb->dma_addr_d_sig, virt_to_phys((void *)d));
+
+	/* Message Size */
+	pdb->img_size = size;
+
+	/* MP PubK generate key command */
+	append_cmd(dsc, (CMD_OPERATION | OP_TYPE_DECAP_PROTOCOL |
+			 OP_PCLID_MP_SIGN));
+}
+
+static void mfg_build_pubk_dsc(u32 *dsc_ptr, u8 *dst)
+{
+	u32 *dsc = dsc_ptr;
+	struct pdb_mp_pub_k *pdb;
+
+	init_job_desc_pdb(dsc, 0, sizeof(struct pdb_mp_pub_k));
+
+	pdb = (struct pdb_mp_pub_k *)desc_pdb(dsc);
+
+	/* Curve */
+	pdb->pdb_hdr = (PDB_MP_CSEL_P256);
+
+	/* Message Pointer */
+	pdb_add_ptr(&pdb->dma_pkey, virt_to_phys((void *)dst));
+
+	/* MP Sign key command */
+	append_cmd(dsc, (CMD_OPERATION | OP_TYPE_DECAP_PROTOCOL |
+			 OP_PCLID_MP_PUB_KEY));
+}
+
+int gen_mppubk(u8 *dst)
+{
+	int size, ret;
+	u32 *dsc;
+
+	/* Job Descriptor initialization */
+	dsc = memalign(ARCH_DMA_MINALIGN,
+		       sizeof(uint32_t) * MFG_PUBK_DSC_WORDS);
+	if (!dsc) {
+		debug("Not enough memory for descriptor allocation\n");
+		return -ENOMEM;
+	}
+
+	mfg_build_pubk_dsc(dsc, dst);
+
+	size = roundup(sizeof(uint32_t) * MFG_PUBK_DSC_WORDS,
+		       ARCH_DMA_MINALIGN);
+	flush_dcache_range((unsigned long)dsc, (unsigned long)dsc + size);
+
+	size = roundup(FSL_CAAM_MP_PUBK_BYTES, ARCH_DMA_MINALIGN);
+	flush_dcache_range((unsigned long)dst, (unsigned long)dst + size);
+
+	/* Execute Job Descriptor */
+	puts("\nGenerating Manufacturing Protection Public Key\n");
+
+	ret = run_descriptor_jr(dsc);
+	if (ret) {
+		debug("Error in public key generation %d\n", ret);
+		goto err;
+	}
+
+	size = roundup(FSL_CAAM_MP_PUBK_BYTES, ARCH_DMA_MINALIGN);
+	invalidate_dcache_range((unsigned long)dst, (unsigned long)dst + size);
+err:
+	free(dsc);
+	return ret;
+}
+
+int sign_mppubk(const u8 *m, int data_size, u8 *dgst, u8 *c, u8 *d)
+{
+	int size, ret;
+	u32 *dsc;
+
+	/* Job Descriptor initialization */
+	dsc = memalign(ARCH_DMA_MINALIGN,
+		       sizeof(uint32_t) * MFG_SIGN_DSC_WORDS);
+	if (!dsc) {
+		debug("Not enough memory for descriptor allocation\n");
+		return -ENOMEM;
+	}
+
+	mfg_build_sign_dsc(dsc, m, data_size, dgst, c, d);
+
+	size = roundup(sizeof(uint32_t) * MFG_SIGN_DSC_WORDS,
+		       ARCH_DMA_MINALIGN);
+	flush_dcache_range((unsigned long)dsc, (unsigned long)dsc + size);
+
+	size = roundup(data_size, ARCH_DMA_MINALIGN);
+	flush_dcache_range((unsigned long)m, (unsigned long)m + size);
+
+	size = roundup(FSL_CAAM_MP_MES_DGST_BYTES, ARCH_DMA_MINALIGN);
+	flush_dcache_range((unsigned long)dgst, (unsigned long)dgst + size);
+
+	size = roundup(FSL_CAAM_MP_PRVK_BYTES, ARCH_DMA_MINALIGN);
+	flush_dcache_range((unsigned long)c, (unsigned long)c + size);
+	flush_dcache_range((unsigned long)d, (unsigned long)d + size);
+
+	/* Execute Job Descriptor */
+	puts("\nSigning message with Manufacturing Protection Public Key\n");
+
+	ret = run_descriptor_jr(dsc);
+	if (ret) {
+		debug("Error in public key generation %d\n", ret);
+		goto err;
+	}
+
+	size = roundup(FSL_CAAM_MP_MES_DGST_BYTES, ARCH_DMA_MINALIGN);
+	invalidate_dcache_range((unsigned long)dgst,
+				(unsigned long)dgst + size);
+
+	size = roundup(FSL_CAAM_MP_PRVK_BYTES, ARCH_DMA_MINALIGN);
+	invalidate_dcache_range((unsigned long)c, (unsigned long)c + size);
+	invalidate_dcache_range((unsigned long)d, (unsigned long)d + size);
+
+err:
+	free(dsc);
+	return ret;
+}
diff --git a/include/fsl_sec.h b/include/fsl_sec.h
index 1c6f1eb23e..40f1c5b10d 100644
--- a/include/fsl_sec.h
+++ b/include/fsl_sec.h
@@ -340,6 +340,10 @@ struct sg_entry {
 
 #endif
 
+#define FSL_CAAM_MP_PUBK_BYTES		    64
+#define FSL_CAAM_MP_PRVK_BYTES		    32
+#define FSL_CAAM_MP_MES_DGST_BYTES	    32
+
 /* blob_dek:
  * Encapsulates the src in a secure blob and stores it dst
  * @src: reference to the plaintext
@@ -349,6 +353,10 @@ struct sg_entry {
  */
 int blob_dek(const u8 *src, u8 *dst, u8 len);
 
+int gen_mppubk(u8 *dst);
+
+int sign_mppubk(const u8 *m, int data_size, u8 *dgst, u8 *c, u8 *d);
+
 #if defined(CONFIG_ARCH_C29X)
 int sec_init_idx(uint8_t);
 #endif
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH 04/37] imx: Avoid hardcoded output ring size register offset (ORSR)
  2021-03-25  9:29 [PATCH 00/37] imx: hab/caam new feature and update Peng Fan
                   ` (2 preceding siblings ...)
  2021-03-25  9:30 ` [PATCH 03/37] imx: imx7 Support for Manufacturing Protection Peng Fan
@ 2021-03-25  9:30 ` Peng Fan
  2021-03-25  9:30 ` [PATCH 05/37] imx: Ensure CAAM clock is enabled prior getting out_jr_size Peng Fan
                   ` (33 subsequent siblings)
  37 siblings, 0 replies; 42+ messages in thread
From: Peng Fan @ 2021-03-25  9:30 UTC (permalink / raw)
  To: u-boot

From: Breno Lima <breno.lima@nxp.com>

The CAAM output ring size register offset is currently defined in fsl_sec.h
as FSL_CAAM_ORSR_JRa_OFFSET, use this definition to avoid hardcoded value in
i.MX common code.

Signed-off-by: Breno Lima <breno.lima@nxp.com>
Reviewed-by: Ye Li <ye.li@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 arch/arm/mach-imx/cmd_dek.c     | 3 ++-
 arch/arm/mach-imx/cmd_mfgprot.c | 3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-imx/cmd_dek.c b/arch/arm/mach-imx/cmd_dek.c
index 49dd473af7..5bf92cbecf 100644
--- a/arch/arm/mach-imx/cmd_dek.c
+++ b/arch/arm/mach-imx/cmd_dek.c
@@ -28,7 +28,8 @@ static int blob_encap_dek(const u8 *src, u8 *dst, u32 len)
 	int ret = 0;
 	u32 jr_size = 4;
 
-	u32 out_jr_size = sec_in32(CONFIG_SYS_FSL_JR0_ADDR + 0x102c);
+	u32 out_jr_size = sec_in32(CONFIG_SYS_FSL_JR0_ADDR +
+				   FSL_CAAM_ORSR_JRa_OFFSET);
 	if (out_jr_size != jr_size) {
 		hab_caam_clock_enable(1);
 		sec_init();
diff --git a/arch/arm/mach-imx/cmd_mfgprot.c b/arch/arm/mach-imx/cmd_mfgprot.c
index 03fc7014e1..6e567027c0 100644
--- a/arch/arm/mach-imx/cmd_mfgprot.c
+++ b/arch/arm/mach-imx/cmd_mfgprot.c
@@ -42,7 +42,8 @@ static int do_mfgprot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
 
 	/* Enable HAB clock */
 	u32 jr_size = 4;
-	u32 out_jr_size = sec_in32(CONFIG_SYS_FSL_JR0_ADDR + 0x102c);
+	u32 out_jr_size = sec_in32(CONFIG_SYS_FSL_JR0_ADDR +
+				   FSL_CAAM_ORSR_JRa_OFFSET);
 
 	if (out_jr_size != jr_size) {
 		hab_caam_clock_enable(1);
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH 05/37] imx: Ensure CAAM clock is enabled prior getting out_jr_size
  2021-03-25  9:29 [PATCH 00/37] imx: hab/caam new feature and update Peng Fan
                   ` (3 preceding siblings ...)
  2021-03-25  9:30 ` [PATCH 04/37] imx: Avoid hardcoded output ring size register offset (ORSR) Peng Fan
@ 2021-03-25  9:30 ` Peng Fan
  2021-03-25  9:30 ` [PATCH 06/37] imx: Avoid hardcoded Job Ring Max size Peng Fan
                   ` (32 subsequent siblings)
  37 siblings, 0 replies; 42+ messages in thread
From: Peng Fan @ 2021-03-25  9:30 UTC (permalink / raw)
  To: u-boot

From: Breno Lima <breno.lima@nxp.com>

Prior calling sec_in32() we have to ensure CAAM clock is enabled, the
function sec_in32() is reading CAAM registers and if CAAM clock is disabled
the system will hang.

Signed-off-by: Breno Lima <breno.lima@nxp.com>
Reviewed-by: Ye Li <ye.li@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 arch/arm/mach-imx/cmd_dek.c     | 6 +++---
 arch/arm/mach-imx/cmd_mfgprot.c | 7 ++++---
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mach-imx/cmd_dek.c b/arch/arm/mach-imx/cmd_dek.c
index 5bf92cbecf..9a965576c7 100644
--- a/arch/arm/mach-imx/cmd_dek.c
+++ b/arch/arm/mach-imx/cmd_dek.c
@@ -28,12 +28,12 @@ static int blob_encap_dek(const u8 *src, u8 *dst, u32 len)
 	int ret = 0;
 	u32 jr_size = 4;
 
+	hab_caam_clock_enable(1);
+
 	u32 out_jr_size = sec_in32(CONFIG_SYS_FSL_JR0_ADDR +
 				   FSL_CAAM_ORSR_JRa_OFFSET);
-	if (out_jr_size != jr_size) {
-		hab_caam_clock_enable(1);
+	if (out_jr_size != jr_size)
 		sec_init();
-	}
 
 	if (!((len == 128) | (len == 192) | (len == 256))) {
 		debug("Invalid DEK size. Valid sizes are 128, 192 and 256b\n");
diff --git a/arch/arm/mach-imx/cmd_mfgprot.c b/arch/arm/mach-imx/cmd_mfgprot.c
index 6e567027c0..dd506a16e8 100644
--- a/arch/arm/mach-imx/cmd_mfgprot.c
+++ b/arch/arm/mach-imx/cmd_mfgprot.c
@@ -42,13 +42,14 @@ static int do_mfgprot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
 
 	/* Enable HAB clock */
 	u32 jr_size = 4;
+
+	hab_caam_clock_enable(1);
+
 	u32 out_jr_size = sec_in32(CONFIG_SYS_FSL_JR0_ADDR +
 				   FSL_CAAM_ORSR_JRa_OFFSET);
 
-	if (out_jr_size != jr_size) {
-		hab_caam_clock_enable(1);
+	if (out_jr_size != jr_size)
 		sec_init();
-	}
 
 	if (strcmp(sel, pubk) == 0) {
 		dst_ptr = malloc_cache_aligned(FSL_CAAM_MP_PUBK_BYTES);
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH 06/37] imx: Avoid hardcoded Job Ring Max size
  2021-03-25  9:29 [PATCH 00/37] imx: hab/caam new feature and update Peng Fan
                   ` (4 preceding siblings ...)
  2021-03-25  9:30 ` [PATCH 05/37] imx: Ensure CAAM clock is enabled prior getting out_jr_size Peng Fan
@ 2021-03-25  9:30 ` Peng Fan
  2021-03-25  9:30 ` [PATCH 07/37] imx: hab: Add function to authenticate kernel image Peng Fan
                   ` (31 subsequent siblings)
  37 siblings, 0 replies; 42+ messages in thread
From: Peng Fan @ 2021-03-25  9:30 UTC (permalink / raw)
  To: u-boot

From: Breno Lima <breno.lima@nxp.com>

Prior instantiating RNG we have to ensure if the CAAM job rings are
available. Avoid hardcoded job ring max size and use the definition at
fsl_sec.h

Signed-off-by: Breno Lima <breno.lima@nxp.com>
Reviewed-by: Ye Li <ye.li@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 arch/arm/mach-imx/cmd_dek.c     | 3 +--
 arch/arm/mach-imx/cmd_mfgprot.c | 4 +---
 2 files changed, 2 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-imx/cmd_dek.c b/arch/arm/mach-imx/cmd_dek.c
index 9a965576c7..bd380429c0 100644
--- a/arch/arm/mach-imx/cmd_dek.c
+++ b/arch/arm/mach-imx/cmd_dek.c
@@ -26,13 +26,12 @@
 static int blob_encap_dek(const u8 *src, u8 *dst, u32 len)
 {
 	int ret = 0;
-	u32 jr_size = 4;
 
 	hab_caam_clock_enable(1);
 
 	u32 out_jr_size = sec_in32(CONFIG_SYS_FSL_JR0_ADDR +
 				   FSL_CAAM_ORSR_JRa_OFFSET);
-	if (out_jr_size != jr_size)
+	if (out_jr_size != FSL_CAAM_MAX_JR_SIZE)
 		sec_init();
 
 	if (!((len == 128) | (len == 192) | (len == 256))) {
diff --git a/arch/arm/mach-imx/cmd_mfgprot.c b/arch/arm/mach-imx/cmd_mfgprot.c
index dd506a16e8..1430f61909 100644
--- a/arch/arm/mach-imx/cmd_mfgprot.c
+++ b/arch/arm/mach-imx/cmd_mfgprot.c
@@ -41,14 +41,12 @@ static int do_mfgprot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
 	sel = argv[1];
 
 	/* Enable HAB clock */
-	u32 jr_size = 4;
-
 	hab_caam_clock_enable(1);
 
 	u32 out_jr_size = sec_in32(CONFIG_SYS_FSL_JR0_ADDR +
 				   FSL_CAAM_ORSR_JRa_OFFSET);
 
-	if (out_jr_size != jr_size)
+	if (out_jr_size != FSL_CAAM_MAX_JR_SIZE)
 		sec_init();
 
 	if (strcmp(sel, pubk) == 0) {
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH 07/37] imx: hab: Add function to authenticate kernel image
  2021-03-25  9:29 [PATCH 00/37] imx: hab/caam new feature and update Peng Fan
                   ` (5 preceding siblings ...)
  2021-03-25  9:30 ` [PATCH 06/37] imx: Avoid hardcoded Job Ring Max size Peng Fan
@ 2021-03-25  9:30 ` Peng Fan
  2021-03-25  9:30 ` [PATCH 08/37] imx: HAB: Update hab codes to support ARM64 and i.MX8M Peng Fan
                   ` (30 subsequent siblings)
  37 siblings, 0 replies; 42+ messages in thread
From: Peng Fan @ 2021-03-25  9:30 UTC (permalink / raw)
  To: u-boot

From: Ye Li <ye.li@nxp.com>

When loading kernel image, the image size is parsed from header, so it
does not include the CSF and IVT.

Add back the authenticate_image function to wrap the imx_hab_authenticate_image
with calculating IVT offset and full image size.

Signed-off-by: Ye Li <ye.li@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 arch/arm/mach-imx/hab.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm/mach-imx/hab.c b/arch/arm/mach-imx/hab.c
index d0757d8b66..66ac440349 100644
--- a/arch/arm/mach-imx/hab.c
+++ b/arch/arm/mach-imx/hab.c
@@ -698,3 +698,15 @@ hab_authentication_exit:
 
 	return result;
 }
+
+int authenticate_image(u32 ddr_start, u32 raw_image_size)
+{
+	u32 ivt_offset;
+	size_t bytes;
+
+	ivt_offset = (raw_image_size + ALIGN_SIZE - 1) &
+					~(ALIGN_SIZE - 1);
+	bytes = ivt_offset + IVT_SIZE + CSF_PAD_SIZE;
+
+	return imx_hab_authenticate_image(ddr_start, bytes, ivt_offset);
+}
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH 08/37] imx: HAB: Update hab codes to support ARM64 and i.MX8M
  2021-03-25  9:29 [PATCH 00/37] imx: hab/caam new feature and update Peng Fan
                   ` (6 preceding siblings ...)
  2021-03-25  9:30 ` [PATCH 07/37] imx: hab: Add function to authenticate kernel image Peng Fan
@ 2021-03-25  9:30 ` Peng Fan
  2021-03-25  9:30 ` [PATCH 09/37] imx: HAB: Validate IVT before authenticating image Peng Fan
                   ` (29 subsequent siblings)
  37 siblings, 0 replies; 42+ messages in thread
From: Peng Fan @ 2021-03-25  9:30 UTC (permalink / raw)
  To: u-boot

From: Peng Fan <peng.fan@nxp.com>

There are some changes to support ARM64 i.MX8M platform in this patches:
1. The hab_rvt base and function vectors are different as i.MX6/7

2. Need to bypass an workaround for i.MX6 to fix problem in MMU.

3. The x18 register needed save & restore before calling any HAB API. According
   to ARM procedure call spec, the x18 is caller saved when it is used as
   temporary register. So calling HAB API may scratch this register, and
   cause crash once accessing the gd pointer.

   On ARMv7, the r9 is callee saved when it is used as variable register. So
   no need to save & restore it.

4. Add SEC_CONFIG fuse for iMX8M

When current EL is not EL3, the direct calling to HAB will fail because
CAAM/SNVS can't initialize at non-secure mode. In this case, we use
SIP call to run the HAB in ATF.

Signed-off-by: Ye Li <ye.li@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 arch/arm/include/asm/mach-imx/hab.h |  14 ++
 arch/arm/mach-imx/hab.c             | 229 +++++++++++++++++++++++++---
 2 files changed, 218 insertions(+), 25 deletions(-)

diff --git a/arch/arm/include/asm/mach-imx/hab.h b/arch/arm/include/asm/mach-imx/hab.h
index d8bd77075a..c4393ef443 100644
--- a/arch/arm/include/asm/mach-imx/hab.h
+++ b/arch/arm/include/asm/mach-imx/hab.h
@@ -165,6 +165,18 @@ typedef void hapi_clock_init_t(void);
 #define HAB_ENG_RTL		0x77   /* RTL simulation engine */
 #define HAB_ENG_SW		0xff   /* Software engine */
 
+#ifdef CONFIG_ARM64
+#define HAB_RVT_BASE                   0x00000880
+
+#define HAB_RVT_ENTRY			(*(ulong *)(HAB_RVT_BASE + 0x08))
+#define HAB_RVT_EXIT			(*(ulong *)(HAB_RVT_BASE + 0x10))
+#define HAB_RVT_CHECK_TARGET		(*(ulong *)(HAB_RVT_BASE + 0x18))
+#define HAB_RVT_AUTHENTICATE_IMAGE	(*(ulong *)(HAB_RVT_BASE + 0x20))
+#define HAB_RVT_REPORT_EVENT		(*(ulong *)(HAB_RVT_BASE + 0x40))
+#define HAB_RVT_REPORT_STATUS		(*(ulong *)(HAB_RVT_BASE + 0x48))
+#define HAB_RVT_FAILSAFE		(*(ulong *)(HAB_RVT_BASE + 0x50))
+#else
+
 #ifdef CONFIG_ROM_UNIFIED_SECTIONS
 #define HAB_RVT_BASE			0x00000100
 #else
@@ -186,6 +198,8 @@ typedef void hapi_clock_init_t(void);
 #define HAB_RVT_REPORT_STATUS		(*(uint32_t *)(HAB_RVT_BASE + 0x24))
 #define HAB_RVT_FAILSAFE		(*(uint32_t *)(HAB_RVT_BASE + 0x28))
 
+#endif /*CONFIG_ARM64*/
+
 #define HAB_CID_ROM 0 /**< ROM Caller ID */
 #define HAB_CID_UBOOT 1 /**< UBOOT Caller ID*/
 
diff --git a/arch/arm/mach-imx/hab.c b/arch/arm/mach-imx/hab.c
index 66ac440349..9ebdbe6ac3 100644
--- a/arch/arm/mach-imx/hab.c
+++ b/arch/arm/mach-imx/hab.c
@@ -10,10 +10,14 @@
 #include <mapmem.h>
 #include <image.h>
 #include <asm/io.h>
+#include <asm/global_data.h>
 #include <asm/system.h>
 #include <asm/arch/clock.h>
 #include <asm/arch/sys_proto.h>
 #include <asm/mach-imx/hab.h>
+#include <linux/arm-smccc.h>
+
+DECLARE_GLOBAL_DATA_PTR;
 
 #define ALIGN_SIZE		0x1000
 #define MX6DQ_PU_IROM_MMU_EN_VAR	0x009024a8
@@ -21,7 +25,7 @@
 #define MX6SL_PU_IROM_MMU_EN_VAR	0x00901c60
 #define IS_HAB_ENABLED_BIT \
 	(is_soc_type(MXC_SOC_MX7ULP) ? 0x80000000 :	\
-	 (is_soc_type(MXC_SOC_MX7) ? 0x2000000 : 0x2))
+	 ((is_soc_type(MXC_SOC_MX7) || is_soc_type(MXC_SOC_IMX8M)) ? 0x2000000 : 0x2))
 
 static int ivt_header_error(const char *err_str, struct ivt_header *ivt_hdr)
 {
@@ -48,6 +52,194 @@ static int verify_ivt_header(struct ivt_header *ivt_hdr)
 	return result;
 }
 
+#ifdef CONFIG_ARM64
+#define FSL_SIP_HAB		0xC2000007
+#define FSL_SIP_HAB_AUTHENTICATE	0x00
+#define FSL_SIP_HAB_ENTRY		0x01
+#define FSL_SIP_HAB_EXIT		0x02
+#define FSL_SIP_HAB_REPORT_EVENT	0x03
+#define FSL_SIP_HAB_REPORT_STATUS	0x04
+#define FSL_SIP_HAB_FAILSAFE		0x05
+#define FSL_SIP_HAB_CHECK_TARGET	0x06
+static volatile gd_t *gd_save;
+#endif
+
+static inline void save_gd(void)
+{
+#ifdef CONFIG_ARM64
+	gd_save = gd;
+#endif
+}
+
+static inline void restore_gd(void)
+{
+#ifdef CONFIG_ARM64
+	/*
+	 * Make will already error that reserving x18 is not supported at the
+	 * time of writing, clang: error: unknown argument: '-ffixed-x18'
+	 */
+	__asm__ volatile("mov x18, %0\n" : : "r" (gd_save));
+#endif
+}
+
+enum hab_status hab_rvt_report_event(enum hab_status status, u32 index,
+				     u8 *event, size_t *bytes)
+{
+	enum hab_status ret;
+	hab_rvt_report_event_t *hab_rvt_report_event_func;
+	struct arm_smccc_res res __maybe_unused;
+
+	hab_rvt_report_event_func =  (hab_rvt_report_event_t *)HAB_RVT_REPORT_EVENT;
+#if defined(CONFIG_ARM64)
+	if (current_el() != 3) {
+		/* call sip */
+		arm_smccc_smc(FSL_SIP_HAB, FSL_SIP_HAB_REPORT_EVENT, (unsigned long)index,
+			      (unsigned long)event, (unsigned long)bytes, 0, 0, 0, &res);
+		return (enum hab_status)res.a0;
+	}
+#endif
+
+	save_gd();
+	ret = hab_rvt_report_event_func(status, index, event, bytes);
+	restore_gd();
+
+	return ret;
+
+}
+
+enum hab_status hab_rvt_report_status(enum hab_config *config, enum hab_state *state)
+{
+	enum hab_status ret;
+	hab_rvt_report_status_t *hab_rvt_report_status_func;
+	struct arm_smccc_res res __maybe_unused;
+
+	hab_rvt_report_status_func = (hab_rvt_report_status_t *)HAB_RVT_REPORT_STATUS;
+#if defined(CONFIG_ARM64)
+	if (current_el() != 3) {
+		/* call sip */
+		arm_smccc_smc(FSL_SIP_HAB, FSL_SIP_HAB_REPORT_STATUS, (unsigned long)config,
+			      (unsigned long)state, 0, 0, 0, 0, &res);
+		return (enum hab_status)res.a0;
+	}
+#endif
+
+	save_gd();
+	ret = hab_rvt_report_status_func(config, state);
+	restore_gd();
+
+	return ret;
+}
+
+enum hab_status hab_rvt_entry(void)
+{
+	enum hab_status ret;
+	hab_rvt_entry_t *hab_rvt_entry_func;
+	struct arm_smccc_res res __maybe_unused;
+
+	hab_rvt_entry_func = (hab_rvt_entry_t *)HAB_RVT_ENTRY;
+#if defined(CONFIG_ARM64)
+	if (current_el() != 3) {
+		/* call sip */
+		arm_smccc_smc(FSL_SIP_HAB, FSL_SIP_HAB_ENTRY, 0, 0, 0, 0, 0, 0, &res);
+		return (enum hab_status)res.a0;
+	}
+#endif
+
+	save_gd();
+	ret = hab_rvt_entry_func();
+	restore_gd();
+
+	return ret;
+}
+
+enum hab_status hab_rvt_exit(void)
+{
+	enum hab_status ret;
+	hab_rvt_exit_t *hab_rvt_exit_func;
+	struct arm_smccc_res res __maybe_unused;
+
+	hab_rvt_exit_func =  (hab_rvt_exit_t *)HAB_RVT_EXIT;
+#if defined(CONFIG_ARM64)
+	if (current_el() != 3) {
+		/* call sip */
+		arm_smccc_smc(FSL_SIP_HAB, FSL_SIP_HAB_EXIT, 0, 0, 0, 0, 0, 0, &res);
+		return (enum hab_status)res.a0;
+	}
+#endif
+
+	save_gd();
+	ret = hab_rvt_exit_func();
+	restore_gd();
+
+	return ret;
+}
+
+void hab_rvt_failsafe(void)
+{
+	hab_rvt_failsafe_t *hab_rvt_failsafe_func;
+
+	hab_rvt_failsafe_func = (hab_rvt_failsafe_t *)HAB_RVT_FAILSAFE;
+#if defined(CONFIG_ARM64)
+	if (current_el() != 3) {
+		/* call sip */
+		arm_smccc_smc(FSL_SIP_HAB, FSL_SIP_HAB_FAILSAFE, 0, 0, 0, 0, 0, 0, NULL);
+		return;
+	}
+#endif
+
+	save_gd();
+	hab_rvt_failsafe_func();
+	restore_gd();
+}
+
+enum hab_status hab_rvt_check_target(enum hab_target type, const void *start,
+					       size_t bytes)
+{
+	enum hab_status ret;
+	hab_rvt_check_target_t *hab_rvt_check_target_func;
+	struct arm_smccc_res res __maybe_unused;
+
+	hab_rvt_check_target_func =  (hab_rvt_check_target_t *)HAB_RVT_CHECK_TARGET;
+#if defined(CONFIG_ARM64)
+	if (current_el() != 3) {
+		/* call sip */
+		arm_smccc_smc(FSL_SIP_HAB, FSL_SIP_HAB_CHECK_TARGET, (unsigned long)type,
+			      (unsigned long)start, (unsigned long)bytes, 0, 0, 0, &res);
+		return (enum hab_status)res.a0;
+	}
+#endif
+
+	save_gd();
+	ret = hab_rvt_check_target_func(type, start, bytes);
+	restore_gd();
+
+	return ret;
+}
+
+void *hab_rvt_authenticate_image(uint8_t cid, ptrdiff_t ivt_offset,
+				 void **start, size_t *bytes, hab_loader_callback_f_t loader)
+{
+	void *ret;
+	hab_rvt_authenticate_image_t *hab_rvt_authenticate_image_func;
+	struct arm_smccc_res res __maybe_unused;
+
+	hab_rvt_authenticate_image_func = (hab_rvt_authenticate_image_t *)HAB_RVT_AUTHENTICATE_IMAGE;
+#if defined(CONFIG_ARM64)
+	if (current_el() != 3) {
+		/* call sip */
+		arm_smccc_smc(FSL_SIP_HAB, FSL_SIP_HAB_AUTHENTICATE, (unsigned long)ivt_offset,
+			      (unsigned long)start, (unsigned long)bytes, 0, 0, 0, &res);
+		return (void *)res.a0;
+	}
+#endif
+
+	save_gd();
+	ret = hab_rvt_authenticate_image_func(cid, ivt_offset, start, bytes, loader);
+	restore_gd();
+
+	return ret;
+}
+
 #if !defined(CONFIG_SPL_BUILD)
 
 #define MAX_RECORD_BYTES     (8*1024) /* 4 kbytes */
@@ -253,12 +445,6 @@ static int get_hab_status(void)
 	size_t bytes = sizeof(event_data); /* Event size in bytes */
 	enum hab_config config = 0;
 	enum hab_state state = 0;
-	hab_rvt_report_event_t *hab_rvt_report_event;
-	hab_rvt_report_status_t *hab_rvt_report_status;
-
-	hab_rvt_report_event = (hab_rvt_report_event_t *)HAB_RVT_REPORT_EVENT;
-	hab_rvt_report_status =
-			(hab_rvt_report_status_t *)HAB_RVT_REPORT_STATUS;
 
 	if (imx_hab_is_enabled())
 		puts("\nSecure boot enabled\n");
@@ -493,7 +679,7 @@ static bool csf_is_valid(struct ivt *ivt, ulong start_addr, size_t bytes)
 		return false;
 	}
 
-	csf_hdr = (u8 *)ivt->csf;
+	csf_hdr = (u8 *)(ulong)ivt->csf;
 
 	/* Verify if CSF Header exist */
 	if (*csf_hdr != HAB_CMD_HDR) {
@@ -561,25 +747,15 @@ bool imx_hab_is_enabled(void)
 int imx_hab_authenticate_image(uint32_t ddr_start, uint32_t image_size,
 			       uint32_t ivt_offset)
 {
-	uint32_t load_addr = 0;
+	ulong load_addr = 0;
 	size_t bytes;
-	uint32_t ivt_addr = 0;
+	ulong ivt_addr = 0;
 	int result = 1;
 	ulong start;
-	hab_rvt_authenticate_image_t *hab_rvt_authenticate_image;
-	hab_rvt_entry_t *hab_rvt_entry;
-	hab_rvt_exit_t *hab_rvt_exit;
-	hab_rvt_check_target_t *hab_rvt_check_target;
 	struct ivt *ivt;
 	struct ivt_header *ivt_hdr;
 	enum hab_status status;
 
-	hab_rvt_authenticate_image =
-		(hab_rvt_authenticate_image_t *)HAB_RVT_AUTHENTICATE_IMAGE;
-	hab_rvt_entry = (hab_rvt_entry_t *)HAB_RVT_ENTRY;
-	hab_rvt_exit = (hab_rvt_exit_t *)HAB_RVT_EXIT;
-	hab_rvt_check_target = (hab_rvt_check_target_t *)HAB_RVT_CHECK_TARGET;
-
 	if (!imx_hab_is_enabled()) {
 		puts("hab fuse not enabled\n");
 		return 0;
@@ -591,7 +767,7 @@ int imx_hab_authenticate_image(uint32_t ddr_start, uint32_t image_size,
 	hab_caam_clock_enable(1);
 
 	/* Calculate IVT address header */
-	ivt_addr = ddr_start + ivt_offset;
+	ivt_addr = (ulong) (ddr_start + ivt_offset);
 	ivt = (struct ivt *)ivt_addr;
 	ivt_hdr = &ivt->hdr;
 
@@ -601,7 +777,7 @@ int imx_hab_authenticate_image(uint32_t ddr_start, uint32_t image_size,
 
 	/* Verify IVT body */
 	if (ivt->self != ivt_addr) {
-		printf("ivt->self 0x%08x pointer is 0x%08x\n",
+		printf("ivt->self 0x%08x pointer is 0x%08lx\n",
 		       ivt->self, ivt_addr);
 		goto hab_authentication_exit;
 	}
@@ -624,9 +800,9 @@ int imx_hab_authenticate_image(uint32_t ddr_start, uint32_t image_size,
 		goto hab_exit_failure_print_status;
 	}
 
-	status = hab_rvt_check_target(HAB_TGT_MEMORY, (void *)ddr_start, bytes);
+	status = hab_rvt_check_target(HAB_TGT_MEMORY, (void *)(ulong)ddr_start, bytes);
 	if (status != HAB_SUCCESS) {
-		printf("HAB check target 0x%08x-0x%08x fail\n",
+		printf("HAB check target 0x%08x-0x%08lx fail\n",
 		       ddr_start, ddr_start + bytes);
 		goto hab_exit_failure_print_status;
 	}
@@ -649,6 +825,8 @@ int imx_hab_authenticate_image(uint32_t ddr_start, uint32_t image_size,
 	printf("\tstart = 0x%08lx\n", start);
 	printf("\tbytes = 0x%x\n", bytes);
 #endif
+
+#ifndef CONFIG_ARM64
 	/*
 	 * If the MMU is enabled, we have to notify the ROM
 	 * code, or it won't flush the caches when needed.
@@ -676,8 +854,9 @@ int imx_hab_authenticate_image(uint32_t ddr_start, uint32_t image_size,
 			writel(1, MX6SL_PU_IROM_MMU_EN_VAR);
 		}
 	}
+#endif
 
-	load_addr = (uint32_t)hab_rvt_authenticate_image(
+	load_addr = (ulong)hab_rvt_authenticate_image(
 			HAB_CID_UBOOT,
 			ivt_offset, (void **)&start,
 			(size_t *)&bytes, NULL);
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH 09/37] imx: HAB: Validate IVT before authenticating image
  2021-03-25  9:29 [PATCH 00/37] imx: hab/caam new feature and update Peng Fan
                   ` (7 preceding siblings ...)
  2021-03-25  9:30 ` [PATCH 08/37] imx: HAB: Update hab codes to support ARM64 and i.MX8M Peng Fan
@ 2021-03-25  9:30 ` Peng Fan
  2021-03-25  9:30 ` [PATCH 10/37] hab: Change calling to ROM API failsafe Peng Fan
                   ` (28 subsequent siblings)
  37 siblings, 0 replies; 42+ messages in thread
From: Peng Fan @ 2021-03-25  9:30 UTC (permalink / raw)
  To: u-boot

From: Utkarsh Gupta <utkarsh.gupta@nxp.com>

Calling csf_is_valid() with an un-signed image may lead to data abort
as the CSF pointer could be pointing to a garbage address when accessed
in HAB_HDR_LEN(*(const struct hab_hdr *)(ulong)ivt_initial->csf).

Authenticate image from DDR location 0x80800000...
Check CSF for Write Data command before authenticating image
data abort
pc : [<fff5494c>]          lr : [<fff54910>]
reloc pc : [<8780294c>]    lr : [<87802910>]
sp : fdf45dc8  ip : 00000214     fp : 00000000
r10: fffb6170  r9 : fdf4fec0     r8 : 00722020
r7 : 80f20000  r6 : 80800000     r5 : 80800000  r4 : 00720000
r3 : 17a5aca3  r2 : 00000000     r1 : 80f2201f  r0 : 00000019
Flags: NzcV  IRQs off  FIQs off  Mode SVC_32
Resetting CPU ...

resetting ...

To avoid such errors during authentication process, validate IVT structure
by calling validate_ivt function which checks the following values in an IVT:

IVT_HEADER = 0x4X2000D1
ENTRY != 0x0
RES1 = 0x0
DCD = 0x0       /* Recommended */
SELF != 0x0     /* Absoulute address of IVT */
CSF != 0x0
RES2 = 0x0

This commit also checks if Image's start address is 4 byte aligned.

commit "0088d127 MLK-14945 HAB: Check if IVT valid before authenticating image"
removed as this patch addresses the issue.

Signed-off-by: Utkarsh Gupta <utkarsh.gupta@nxp.com>
Signed-off-by: Ye Li <ye.li@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 arch/arm/mach-imx/hab.c | 59 ++++++++++++++++++++++++++++++-----------
 1 file changed, 43 insertions(+), 16 deletions(-)

diff --git a/arch/arm/mach-imx/hab.c b/arch/arm/mach-imx/hab.c
index 9ebdbe6ac3..f2d5f744e8 100644
--- a/arch/arm/mach-imx/hab.c
+++ b/arch/arm/mach-imx/hab.c
@@ -728,6 +728,48 @@ static bool csf_is_valid(struct ivt *ivt, ulong start_addr, size_t bytes)
 	return true;
 }
 
+/*
+ * Validate IVT structure of the image being authenticated
+ */
+static int validate_ivt(struct ivt *ivt_initial)
+{
+	struct ivt_header *ivt_hdr = &ivt_initial->hdr;
+
+	if ((ulong)ivt_initial & 0x3) {
+		puts("Error: Image's start address is not 4 byte aligned\n");
+		return 0;
+	}
+
+	/* Check IVT fields before allowing authentication */
+	if ((!verify_ivt_header(ivt_hdr)) && \
+	    (ivt_initial->entry != 0x0) && \
+	    (ivt_initial->reserved1 == 0x0) && \
+	    (ivt_initial->self == \
+		   (uint32_t)((ulong)ivt_initial & 0xffffffff)) && \
+	    (ivt_initial->csf != 0x0) && \
+	    (ivt_initial->reserved2 == 0x0)) {
+		/* Report boot failure if DCD pointer is found in IVT */
+		if (ivt_initial->dcd != 0x0)
+			puts("Error: DCD pointer must be 0\n");
+		else
+			return 1;
+	}
+
+	puts("Error: Invalid IVT structure\n");
+	debug("\nAllowed IVT structure:\n");
+	debug("IVT HDR       = 0x4X2000D1\n");
+	debug("IVT ENTRY     = 0xXXXXXXXX\n");
+	debug("IVT RSV1      = 0x0\n");
+	debug("IVT DCD       = 0x0\n");		/* Recommended */
+	debug("IVT BOOT_DATA = 0xXXXXXXXX\n");	/* Commonly 0x0 */
+	debug("IVT SELF      = 0xXXXXXXXX\n");	/* = ddr_start + ivt_offset */
+	debug("IVT CSF       = 0xXXXXXXXX\n");
+	debug("IVT RSV2      = 0x0\n");
+
+	/* Invalid IVT structure */
+	return 0;
+}
+
 bool imx_hab_is_enabled(void)
 {
 	struct imx_sec_config_fuse_t *fuse =
@@ -753,7 +795,6 @@ int imx_hab_authenticate_image(uint32_t ddr_start, uint32_t image_size,
 	int result = 1;
 	ulong start;
 	struct ivt *ivt;
-	struct ivt_header *ivt_hdr;
 	enum hab_status status;
 
 	if (!imx_hab_is_enabled()) {
@@ -769,24 +810,10 @@ int imx_hab_authenticate_image(uint32_t ddr_start, uint32_t image_size,
 	/* Calculate IVT address header */
 	ivt_addr = (ulong) (ddr_start + ivt_offset);
 	ivt = (struct ivt *)ivt_addr;
-	ivt_hdr = &ivt->hdr;
 
 	/* Verify IVT header bugging out on error */
-	if (verify_ivt_header(ivt_hdr))
-		goto hab_authentication_exit;
-
-	/* Verify IVT body */
-	if (ivt->self != ivt_addr) {
-		printf("ivt->self 0x%08x pointer is 0x%08lx\n",
-		       ivt->self, ivt_addr);
+	if (!validate_ivt(ivt))
 		goto hab_authentication_exit;
-	}
-
-	/* Verify if IVT DCD pointer is NULL */
-	if (ivt->dcd) {
-		puts("Error: DCD pointer must be NULL\n");
-		goto hab_authentication_exit;
-	}
 
 	start = ddr_start;
 	bytes = image_size;
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH 10/37] hab: Change calling to ROM API failsafe
  2021-03-25  9:29 [PATCH 00/37] imx: hab/caam new feature and update Peng Fan
                   ` (8 preceding siblings ...)
  2021-03-25  9:30 ` [PATCH 09/37] imx: HAB: Validate IVT before authenticating image Peng Fan
@ 2021-03-25  9:30 ` Peng Fan
  2021-03-25  9:30 ` [PATCH 11/37] imx: hab: Enable hab.c to authenticate additional images in open configuration Peng Fan
                   ` (27 subsequent siblings)
  37 siblings, 0 replies; 42+ messages in thread
From: Peng Fan @ 2021-03-25  9:30 UTC (permalink / raw)
  To: u-boot

From: Ye Li <ye.li@nxp.com>

Modify to use hab_rvt_failsafe function for failsafe ROM API, not
directly call its ROM address. This function will wrap the sip call for iMX8M
platforms.

Signed-off-by: Ye Li <ye.li@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 arch/arm/mach-imx/hab.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/arch/arm/mach-imx/hab.c b/arch/arm/mach-imx/hab.c
index f2d5f744e8..bd00d4a458 100644
--- a/arch/arm/mach-imx/hab.c
+++ b/arch/arm/mach-imx/hab.c
@@ -539,14 +539,11 @@ static int do_authenticate_image(struct cmd_tbl *cmdtp, int flag, int argc,
 static int do_hab_failsafe(struct cmd_tbl *cmdtp, int flag, int argc,
 			   char *const argv[])
 {
-	hab_rvt_failsafe_t *hab_rvt_failsafe;
-
 	if (argc != 1) {
 		cmd_usage(cmdtp);
 		return 1;
 	}
 
-	hab_rvt_failsafe = (hab_rvt_failsafe_t *)HAB_RVT_FAILSAFE;
 	hab_rvt_failsafe();
 
 	return 0;
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH 11/37] imx: hab: Enable hab.c to authenticate additional images in open configuration
  2021-03-25  9:29 [PATCH 00/37] imx: hab/caam new feature and update Peng Fan
                   ` (9 preceding siblings ...)
  2021-03-25  9:30 ` [PATCH 10/37] hab: Change calling to ROM API failsafe Peng Fan
@ 2021-03-25  9:30 ` Peng Fan
  2021-03-25  9:30 ` [PATCH 12/37] imx: hab: Display All HAB events via hab_status command Peng Fan
                   ` (26 subsequent siblings)
  37 siblings, 0 replies; 42+ messages in thread
From: Peng Fan @ 2021-03-25  9:30 UTC (permalink / raw)
  To: u-boot

From: Breno Lima <breno.lima@nxp.com>

Currently it's not possible to authenticate additional boot images in HAB
open configuration.

The hab.c code is checking if the SEC_CONFIG[1] fuse is programmed prior
to calling the hab_authenticate_image() API function. Users cannot check
if their additional boot images has been correctly signed prior to closing
their device.

Enable hab.c to authenticate additional boot images in open mode so HAB
events can be retrieved through get_hab_status() function.

Signed-off-by: Breno Lima <breno.lima@nxp.com>
Reviewed-by: Ye Li <ye.li@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 arch/arm/mach-imx/hab.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/arch/arm/mach-imx/hab.c b/arch/arm/mach-imx/hab.c
index bd00d4a458..01ddfab699 100644
--- a/arch/arm/mach-imx/hab.c
+++ b/arch/arm/mach-imx/hab.c
@@ -794,10 +794,8 @@ int imx_hab_authenticate_image(uint32_t ddr_start, uint32_t image_size,
 	struct ivt *ivt;
 	enum hab_status status;
 
-	if (!imx_hab_is_enabled()) {
+	if (!imx_hab_is_enabled())
 		puts("hab fuse not enabled\n");
-		return 0;
-	}
 
 	printf("\nAuthenticate image from DDR location 0x%x...\n",
 	       ddr_start);
@@ -896,7 +894,7 @@ hab_exit_failure_print_status:
 
 hab_authentication_exit:
 
-	if (load_addr != 0)
+	if (load_addr != 0 || !imx_hab_is_enabled())
 		result = 0;
 
 	return result;
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH 12/37] imx: hab: Display All HAB events via hab_status command
  2021-03-25  9:29 [PATCH 00/37] imx: hab/caam new feature and update Peng Fan
                   ` (10 preceding siblings ...)
  2021-03-25  9:30 ` [PATCH 11/37] imx: hab: Enable hab.c to authenticate additional images in open configuration Peng Fan
@ 2021-03-25  9:30 ` Peng Fan
  2021-03-25  9:30 ` [PATCH 13/37] imx: hab: Check if IVT header is HABv4 Peng Fan
                   ` (25 subsequent siblings)
  37 siblings, 0 replies; 42+ messages in thread
From: Peng Fan @ 2021-03-25  9:30 UTC (permalink / raw)
  To: u-boot

From: Utkarsh Gupta <utkarsh.gupta@nxp.com>

Add ability for hab_status command to show All HAB events and not just
HAB failure events

Signed-off-by: Utkarsh Gupta <utkarsh.gupta@nxp.com>
Reviewed-by: Ye Li <ye.li@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 arch/arm/mach-imx/hab.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-imx/hab.c b/arch/arm/mach-imx/hab.c
index 01ddfab699..264e148ba6 100644
--- a/arch/arm/mach-imx/hab.c
+++ b/arch/arm/mach-imx/hab.c
@@ -456,8 +456,8 @@ static int get_hab_status(void)
 		printf("\nHAB Configuration: 0x%02x, HAB State: 0x%02x\n",
 		       config, state);
 
-		/* Display HAB Error events */
-		while (hab_rvt_report_event(HAB_FAILURE, index, event_data,
+		/* Display HAB events */
+		while (hab_rvt_report_event(HAB_STS_ANY, index, event_data,
 					&bytes) == HAB_SUCCESS) {
 			puts("\n");
 			printf("--------- HAB Event %d -----------------\n",
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH 13/37] imx: hab: Check if IVT header is HABv4
  2021-03-25  9:29 [PATCH 00/37] imx: hab/caam new feature and update Peng Fan
                   ` (11 preceding siblings ...)
  2021-03-25  9:30 ` [PATCH 12/37] imx: hab: Display All HAB events via hab_status command Peng Fan
@ 2021-03-25  9:30 ` Peng Fan
  2021-03-25  9:30 ` [PATCH 14/37] mx7ulp: hab: Add hab_status command for HABv4 M4 boot Peng Fan
                   ` (24 subsequent siblings)
  37 siblings, 0 replies; 42+ messages in thread
From: Peng Fan @ 2021-03-25  9:30 UTC (permalink / raw)
  To: u-boot

From: Breno Lima <breno.lima@nxp.com>

The HABv4 implementation in ROM checks if HAB major version
in IVT header is 4.x.

The current implementation in hab.c code is only validating
HAB v4.0 and HAB v4.1 and may be incompatible with newer
HABv4 versions.

Modify verify_ivt_header() function to align with HABv4
implementation in ROM code.

Signed-off-by: Breno Lima <breno.lima@nxp.com>
Reviewed-by: Ye Li <ye.li@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 arch/arm/include/asm/mach-imx/hab.h | 2 --
 arch/arm/mach-imx/hab.c             | 3 +--
 2 files changed, 1 insertion(+), 4 deletions(-)

diff --git a/arch/arm/include/asm/mach-imx/hab.h b/arch/arm/include/asm/mach-imx/hab.h
index c4393ef443..62218818f9 100644
--- a/arch/arm/include/asm/mach-imx/hab.h
+++ b/arch/arm/include/asm/mach-imx/hab.h
@@ -18,8 +18,6 @@
  */
 #define IVT_HEADER_MAGIC	0xD1
 #define IVT_TOTAL_LENGTH	0x20
-#define IVT_HEADER_V1		0x40
-#define IVT_HEADER_V2		0x41
 
 struct __packed ivt_header {
 	uint8_t		magic;
diff --git a/arch/arm/mach-imx/hab.c b/arch/arm/mach-imx/hab.c
index 264e148ba6..5f46df0f8b 100644
--- a/arch/arm/mach-imx/hab.c
+++ b/arch/arm/mach-imx/hab.c
@@ -45,8 +45,7 @@ static int verify_ivt_header(struct ivt_header *ivt_hdr)
 	if (be16_to_cpu(ivt_hdr->length) != IVT_TOTAL_LENGTH)
 		result = ivt_header_error("bad length", ivt_hdr);
 
-	if (ivt_hdr->version != IVT_HEADER_V1 &&
-	    ivt_hdr->version != IVT_HEADER_V2)
+	if ((ivt_hdr->version & HAB_MAJ_MASK) != HAB_MAJ_VER)
 		result = ivt_header_error("bad version", ivt_hdr);
 
 	return result;
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH 14/37] mx7ulp: hab: Add hab_status command for HABv4 M4 boot
  2021-03-25  9:29 [PATCH 00/37] imx: hab/caam new feature and update Peng Fan
                   ` (12 preceding siblings ...)
  2021-03-25  9:30 ` [PATCH 13/37] imx: hab: Check if IVT header is HABv4 Peng Fan
@ 2021-03-25  9:30 ` Peng Fan
  2021-03-25  9:30 ` [PATCH 15/37] imx: hab: Fix build warnings in 32-bit targets Peng Fan
                   ` (23 subsequent siblings)
  37 siblings, 0 replies; 42+ messages in thread
From: Peng Fan @ 2021-03-25  9:30 UTC (permalink / raw)
  To: u-boot

From: Breno Lima <breno.lima@nxp.com>

When booting in low power or dual boot modes the M4 binary is
authenticated by the M4 ROM code.

Add an option in hab_status command so users can retrieve M4 HAB
failure and warning events.

=> hab_status m4

   Secure boot disabled

   HAB Configuration: 0xf0, HAB State: 0x66
   No HAB Events Found!

Add command documentation in mx6_mx7_secure_boot.txt guide.

As HAB M4 API cannot be called from A7 core the code is parsing
the M4 HAB persistent memory region. The HAB persistent memory
stores HAB events, public keys and others HAB related information.

The HAB persistent memory region addresses and sizes can be found
in AN12263 "HABv4 RVT Guidelines and Recommendations".

Reviewed-by: Utkarsh Gupta <utkarsh.gupta@nxp.com>
Reviewed-by: Ye Li <ye.li@nxp.com>
Signed-off-by: Breno Lima <breno.lima@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 arch/arm/include/asm/mach-imx/hab.h          | 15 +++
 arch/arm/mach-imx/hab.c                      | 99 ++++++++++++++++++++
 doc/imx/habv4/guides/mx6_mx7_secure_boot.txt | 25 +++++
 3 files changed, 139 insertions(+)

diff --git a/arch/arm/include/asm/mach-imx/hab.h b/arch/arm/include/asm/mach-imx/hab.h
index 62218818f9..1085c37828 100644
--- a/arch/arm/include/asm/mach-imx/hab.h
+++ b/arch/arm/include/asm/mach-imx/hab.h
@@ -42,6 +42,15 @@ struct __packed hab_hdr {
 	u8 par;              /* Parameters field */
 };
 
+/* Default event structure */
+struct __packed evt_def {
+	struct hab_hdr hdr;		/* Header */
+	uint32_t sts;			/* Status */
+	uint32_t ctx;			/* Default context */
+	uint8_t *data;			/* Default data location */
+	size_t bytes;			/* Size of default data */
+};
+
 /* -------- start of HAB API updates ------------*/
 /* The following are taken from HAB4 SIS */
 
@@ -211,6 +220,12 @@ typedef void hapi_clock_init_t(void);
 #define IVT_SIZE			0x20
 #define CSF_PAD_SIZE			0x2000
 
+#define HAB_TAG_EVT		0xDB
+#define HAB_TAG_EVT_DEF		0x0C
+
+#define HAB_MAJ_VER		0x40
+#define HAB_MAJ_MASK		0xF0
+
 /* ----------- end of HAB API updates ------------*/
 
 int imx_hab_authenticate_image(uint32_t ddr_start, uint32_t image_size,
diff --git a/arch/arm/mach-imx/hab.c b/arch/arm/mach-imx/hab.c
index 5f46df0f8b..469ef0fd1c 100644
--- a/arch/arm/mach-imx/hab.c
+++ b/arch/arm/mach-imx/hab.c
@@ -27,6 +27,12 @@ DECLARE_GLOBAL_DATA_PTR;
 	(is_soc_type(MXC_SOC_MX7ULP) ? 0x80000000 :	\
 	 ((is_soc_type(MXC_SOC_MX7) || is_soc_type(MXC_SOC_IMX8M)) ? 0x2000000 : 0x2))
 
+#ifdef CONFIG_MX7ULP
+#define HAB_M4_PERSISTENT_START	((soc_rev() >= CHIP_REV_2_0) ? 0x20008040 : \
+				  0x20008180)
+#define HAB_M4_PERSISTENT_BYTES		0xB80
+#endif
+
 static int ivt_header_error(const char *err_str, struct ivt_header *ivt_hdr)
 {
 	printf("%s magic=0x%x length=0x%02x version=0x%x\n", err_str,
@@ -477,15 +483,99 @@ static int get_hab_status(void)
 	return 0;
 }
 
+#ifdef CONFIG_MX7ULP
+
+static int get_record_len(struct record *rec)
+{
+	return (size_t)((rec->len[0] << 8) + (rec->len[1]));
+}
+
+static int get_hab_status_m4(void)
+{
+	unsigned int index = 0;
+	uint8_t event_data[128];
+	size_t record_len, offset = 0;
+	enum hab_config config = 0;
+	enum hab_state state = 0;
+
+	if (imx_hab_is_enabled())
+		puts("\nSecure boot enabled\n");
+	else
+		puts("\nSecure boot disabled\n");
+
+	/*
+	 * HAB in both A7 and M4 gather the security state
+	 * and configuration of the chip from
+	 * shared SNVS module
+	 */
+	hab_rvt_report_status(&config, &state);
+	printf("\nHAB Configuration: 0x%02x, HAB State: 0x%02x\n",
+	       config, state);
+
+	struct record *rec = (struct record *)(HAB_M4_PERSISTENT_START);
+
+	record_len = get_record_len(rec);
+
+	/* Check if HAB persistent memory is valid */
+	if (rec->tag != HAB_TAG_EVT_DEF ||
+	    record_len != sizeof(struct evt_def) ||
+	    (rec->par & HAB_MAJ_MASK) != HAB_MAJ_VER) {
+		puts("\nERROR: Invalid HAB persistent memory\n");
+		return 1;
+	}
+
+	/* Parse events in HAB M4 persistent memory region */
+	while (offset < HAB_M4_PERSISTENT_BYTES) {
+		rec = (struct record *)(HAB_M4_PERSISTENT_START + offset);
+
+		record_len = get_record_len(rec);
+
+		if (rec->tag == HAB_TAG_EVT) {
+			memcpy(&event_data, rec, record_len);
+			puts("\n");
+			printf("--------- HAB Event %d -----------------\n",
+			       index + 1);
+			puts("event data:\n");
+			display_event(event_data, record_len);
+			puts("\n");
+			index++;
+		}
+
+		offset += record_len;
+
+		/* Ensure all records start on a word boundary */
+		if ((offset % 4) != 0)
+			offset =  offset + (4 - (offset % 4));
+	}
+
+	if (!index)
+		puts("No HAB Events Found!\n\n");
+
+	return 0;
+}
+#endif
+
 static int do_hab_status(struct cmd_tbl *cmdtp, int flag, int argc,
 			 char *const argv[])
 {
+#ifdef CONFIG_MX7ULP
+	if ((argc > 2)) {
+		cmd_usage(cmdtp);
+		return 1;
+	}
+
+	if (strcmp("m4", argv[1]) == 0)
+		get_hab_status_m4();
+	else
+		get_hab_status();
+#else
 	if ((argc != 1)) {
 		cmd_usage(cmdtp);
 		return 1;
 	}
 
 	get_hab_status();
+#endif
 
 	return 0;
 }
@@ -588,11 +678,20 @@ error:
 	return ret;
 }
 
+#ifdef CONFIG_MX7ULP
+U_BOOT_CMD(
+		hab_status, CONFIG_SYS_MAXARGS, 2, do_hab_status,
+		"display HAB status and events",
+		"hab_status - A7 HAB event and status\n"
+		"hab_status m4 - M4 HAB event and status"
+	  );
+#else
 U_BOOT_CMD(
 		hab_status, CONFIG_SYS_MAXARGS, 1, do_hab_status,
 		"display HAB status",
 		""
 	  );
+#endif
 
 U_BOOT_CMD(
 		hab_auth_img, 4, 0, do_authenticate_image,
diff --git a/doc/imx/habv4/guides/mx6_mx7_secure_boot.txt b/doc/imx/habv4/guides/mx6_mx7_secure_boot.txt
index 20fff937b6..53f71fbc3e 100644
--- a/doc/imx/habv4/guides/mx6_mx7_secure_boot.txt
+++ b/doc/imx/habv4/guides/mx6_mx7_secure_boot.txt
@@ -213,6 +213,30 @@ the example below:
   HAB Configuration: 0xf0, HAB State: 0x66
   No HAB Events Found!
 
+1.6.1 Verifying HAB events in i.MX7ULP
+---------------------------------------
+
+When booting i.MX7ULP in low power or dual boot modes the M4 binary is
+authenticated by an independent HAB in M4 ROM code using a
+different SRK key set.
+
+The U-Boot provides a M4 option in hab_status command so users can retrieve
+M4 HAB failure and warning events.
+
+- Verify HAB M4 events:
+
+  => hab_status m4
+
+  Secure boot disabled
+
+  HAB Configuration: 0xf0, HAB State: 0x66
+  No HAB Events Found!
+
+As HAB M4 API cannot be called from A7 core the command is parsing the M4 HAB
+persistent memory region, M4 software should not modify this reserved region.
+
+Details about HAB persistent memory region can be found in AN12263[2].
+
 1.7 Closing the device
 -----------------------
 
@@ -400,3 +424,4 @@ If no HAB events were found the zImage is successfully signed.
 References:
 [1] AN4581: "Secure Boot on i.MX 50, i.MX 53, i.MX 6 and i.MX 7 Series using
  HABv4" - Rev 2.
+[2] AN12263: "HABv4 RVT Guidelines and Recommendations" - Rev 0.
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH 15/37] imx: hab: Fix build warnings in 32-bit targets
  2021-03-25  9:29 [PATCH 00/37] imx: hab/caam new feature and update Peng Fan
                   ` (13 preceding siblings ...)
  2021-03-25  9:30 ` [PATCH 14/37] mx7ulp: hab: Add hab_status command for HABv4 M4 boot Peng Fan
@ 2021-03-25  9:30 ` Peng Fan
  2021-03-25  9:30 ` [PATCH 16/37] imx: HAB: Add support for iMX8MM Peng Fan
                   ` (22 subsequent siblings)
  37 siblings, 0 replies; 42+ messages in thread
From: Peng Fan @ 2021-03-25  9:30 UTC (permalink / raw)
  To: u-boot

From: Breno Lima <breno.lima@nxp.com>

When building 32-bit targets with CONFIG_SECURE_BOOT and DEBUG enabled
the following warnings are displayed:

arch/arm/mach-imx/hab.c:840:41: warning: format '%lx' expects argument \
of type 'long unsigned int', but argument 3 has type 'uint32_t \
{aka unsigned int}' [-Wformat=]
   printf("HAB check target 0x%08x-0x%08lx fail\n",
                                     ~~~~^
                                     %08x
          ddr_start, ddr_start + bytes);

arch/arm/mach-imx/hab.c:845:45: warning: format '%x' expects argument \
of type 'unsigned int', but argument 3 has type 'ulong \
{aka long unsigned int}' [-Wformat=]
  printf("\nivt_offset = 0x%x, ivt addr = 0x%x\n", ivt_offset, ivt_addr);
                                            ~^
                                            %lx

Fix warnings by providing the correct data type.

Reviewed-by: Ye Li <ye.li@nxp.com>
Signed-off-by: Breno Lima <breno.lima@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 arch/arm/mach-imx/hab.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-imx/hab.c b/arch/arm/mach-imx/hab.c
index 469ef0fd1c..00bd157d0e 100644
--- a/arch/arm/mach-imx/hab.c
+++ b/arch/arm/mach-imx/hab.c
@@ -923,11 +923,11 @@ int imx_hab_authenticate_image(uint32_t ddr_start, uint32_t image_size,
 	status = hab_rvt_check_target(HAB_TGT_MEMORY, (void *)(ulong)ddr_start, bytes);
 	if (status != HAB_SUCCESS) {
 		printf("HAB check target 0x%08x-0x%08lx fail\n",
-		       ddr_start, ddr_start + bytes);
+		       ddr_start, ddr_start + (ulong)bytes);
 		goto hab_exit_failure_print_status;
 	}
 #ifdef DEBUG
-	printf("\nivt_offset = 0x%x, ivt addr = 0x%x\n", ivt_offset, ivt_addr);
+	printf("\nivt_offset = 0x%x, ivt addr = 0x%lx\n", ivt_offset, ivt_addr);
 	printf("ivt entry = 0x%08x, dcd = 0x%08x, csf = 0x%08x\n", ivt->entry,
 	       ivt->dcd, ivt->csf);
 	puts("Dumping IVT\n");
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH 16/37] imx: HAB: Add support for iMX8MM
  2021-03-25  9:29 [PATCH 00/37] imx: hab/caam new feature and update Peng Fan
                   ` (14 preceding siblings ...)
  2021-03-25  9:30 ` [PATCH 15/37] imx: hab: Fix build warnings in 32-bit targets Peng Fan
@ 2021-03-25  9:30 ` Peng Fan
  2021-03-25  9:30 ` [PATCH 17/37] crypto: fsl: blob: Flush dcache range for destination address Peng Fan
                   ` (21 subsequent siblings)
  37 siblings, 0 replies; 42+ messages in thread
From: Peng Fan @ 2021-03-25  9:30 UTC (permalink / raw)
  To: u-boot

From: Ye Li <ye.li@nxp.com>

The imx8mm has changed the address of rvt_hab, use new address for imx8mm.

The authentication procedure is same as imx8mq. In u-boot, the authentication
uses SIP call to trap ATF to run HAB authenticate.

Users need to add CONFIG_SECURE_BOOT=y to defconfig to enable the feature.

Signed-off-by: Ye Li <ye.li@nxp.com>
Acked-by: Peng Fan <peng.fan@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 arch/arm/include/asm/mach-imx/hab.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/include/asm/mach-imx/hab.h b/arch/arm/include/asm/mach-imx/hab.h
index 1085c37828..d63b85378a 100644
--- a/arch/arm/include/asm/mach-imx/hab.h
+++ b/arch/arm/include/asm/mach-imx/hab.h
@@ -173,7 +173,11 @@ typedef void hapi_clock_init_t(void);
 #define HAB_ENG_SW		0xff   /* Software engine */
 
 #ifdef CONFIG_ARM64
+#ifdef CONFIG_IMX8MQ
 #define HAB_RVT_BASE                   0x00000880
+#else
+#define HAB_RVT_BASE                   0x00000900
+#endif
 
 #define HAB_RVT_ENTRY			(*(ulong *)(HAB_RVT_BASE + 0x08))
 #define HAB_RVT_EXIT			(*(ulong *)(HAB_RVT_BASE + 0x10))
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH 17/37] crypto: fsl: blob: Flush dcache range for destination address
  2021-03-25  9:29 [PATCH 00/37] imx: hab/caam new feature and update Peng Fan
                   ` (15 preceding siblings ...)
  2021-03-25  9:30 ` [PATCH 16/37] imx: HAB: Add support for iMX8MM Peng Fan
@ 2021-03-25  9:30 ` Peng Fan
  2021-03-25  9:30 ` [PATCH 18/37] iMX8M: Add support to enable CONFIG_IMX_HAB Peng Fan
                   ` (20 subsequent siblings)
  37 siblings, 0 replies; 42+ messages in thread
From: Peng Fan @ 2021-03-25  9:30 UTC (permalink / raw)
  To: u-boot

From: Breno Lima <breno.lima@nxp.com>

The blob command is not working on i.MX7D, i.MX8MQ and i.MX8MM
devices.

Due to different cache management it's necessary to flush dcache
range for destination address so data can be available in memory.

Add necessary operations in blob_encap() and blob_decap() functions.

Signed-off-by: Breno Lima <breno.lima@nxp.com>
Reviewed-by: Ye Li <ye.li@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 drivers/crypto/fsl/fsl_blob.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/crypto/fsl/fsl_blob.c b/drivers/crypto/fsl/fsl_blob.c
index d6bd861251..e8202cc569 100644
--- a/drivers/crypto/fsl/fsl_blob.c
+++ b/drivers/crypto/fsl/fsl_blob.c
@@ -65,6 +65,9 @@ int blob_decap(u8 *key_mod, u8 *src, u8 *dst, u32 len)
 	flush_dcache_range((unsigned long)desc,
 			   (unsigned long)desc + size);
 
+	flush_dcache_range((unsigned long)dst,
+			   (unsigned long)dst + size);
+
 	ret = run_descriptor_jr(desc);
 
 	if (ret) {
@@ -130,6 +133,9 @@ int blob_encap(u8 *key_mod, u8 *src, u8 *dst, u32 len)
 	flush_dcache_range((unsigned long)desc,
 			   (unsigned long)desc + size);
 
+	flush_dcache_range((unsigned long)dst,
+			   (unsigned long)dst + size);
+
 	ret = run_descriptor_jr(desc);
 
 	if (ret) {
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH 18/37] iMX8M: Add support to enable CONFIG_IMX_HAB
  2021-03-25  9:29 [PATCH 00/37] imx: hab/caam new feature and update Peng Fan
                   ` (16 preceding siblings ...)
  2021-03-25  9:30 ` [PATCH 17/37] crypto: fsl: blob: Flush dcache range for destination address Peng Fan
@ 2021-03-25  9:30 ` Peng Fan
  2021-03-25  9:30 ` [PATCH 19/37] imx: cmd_dek: Enable DEK only for chips supporting CAAM Peng Fan
                   ` (19 subsequent siblings)
  37 siblings, 0 replies; 42+ messages in thread
From: Peng Fan @ 2021-03-25  9:30 UTC (permalink / raw)
  To: u-boot

From: Ye Li <ye.li@nxp.com>

Add some SOC level codes and build configurations to use HAB lib for
CONFIG_IMX_HAB (secure boot), like adding the SEC_CONFIG fuse, enable
fuse driver, CAAM clock function, and add CAAM secure RAM to MMU table.

The FSL_CAAM is temporally not enabled for iMX8M when CONFIG_IMX_HAB is set,
because we don't need the CAAM driver for SPL.

Signed-off-by: Ye Li <ye.li@nxp.com>
Reviewed-by: Peng Fan <peng.fan@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 arch/arm/include/asm/arch-imx8m/clock.h | 1 +
 arch/arm/mach-imx/Kconfig               | 2 +-
 arch/arm/mach-imx/Makefile              | 1 +
 arch/arm/mach-imx/imx8m/clock_imx8mm.c  | 8 ++++++++
 arch/arm/mach-imx/imx8m/clock_imx8mq.c  | 7 +++++++
 5 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/arch/arm/include/asm/arch-imx8m/clock.h b/arch/arm/include/asm/arch-imx8m/clock.h
index c545eb82b6..77d9428a18 100644
--- a/arch/arm/include/asm/arch-imx8m/clock.h
+++ b/arch/arm/include/asm/arch-imx8m/clock.h
@@ -275,3 +275,4 @@ void enable_ocotp_clk(unsigned char enable);
 int enable_i2c_clk(unsigned char enable, unsigned int i2c_num);
 int set_clk_enet(enum enet_freq type);
 int set_clk_eqos(enum enet_freq type);
+void hab_caam_clock_enable(unsigned char enable);
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 6d40c7fc4b..8c00ad1391 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -43,7 +43,7 @@ config USE_IMXIMG_PLUGIN
 
 config IMX_HAB
 	bool "Support i.MX HAB features"
-	depends on ARCH_MX7 || ARCH_MX6 || ARCH_MX5
+	depends on ARCH_MX7 || ARCH_MX6 || ARCH_MX5 || ARCH_IMX8M
 	select FSL_CAAM if HAS_CAAM
 	imply CMD_DEKBLOB
 	help
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index 25f910b36a..63b3549d20 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -16,6 +16,7 @@ endif
 obj-$(CONFIG_ENV_IS_IN_MMC) += mmc_env.o
 obj-$(CONFIG_FEC_MXC) += mac.o
 obj-$(CONFIG_SYS_I2C_MXC) += i2c-mxv7.o
+obj-$(CONFIG_IMX_HAB) += hab.o
 obj-y += cpu.o
 endif
 
diff --git a/arch/arm/mach-imx/imx8m/clock_imx8mm.c b/arch/arm/mach-imx/imx8m/clock_imx8mm.c
index 4024dafca1..029d06f27f 100644
--- a/arch/arm/mach-imx/imx8m/clock_imx8mm.c
+++ b/arch/arm/mach-imx/imx8m/clock_imx8mm.c
@@ -21,6 +21,14 @@ DECLARE_GLOBAL_DATA_PTR;
 static struct anamix_pll *ana_pll = (struct anamix_pll *)ANATOP_BASE_ADDR;
 
 static u32 get_root_clk(enum clk_root_index clock_id);
+
+#ifdef CONFIG_IMX_HAB
+void hab_caam_clock_enable(unsigned char enable)
+{
+	/* The CAAM clock is always on for iMX8M */
+}
+#endif
+
 void enable_ocotp_clk(unsigned char enable)
 {
 	clock_enable(CCGR_OCOTP, !!enable);
diff --git a/arch/arm/mach-imx/imx8m/clock_imx8mq.c b/arch/arm/mach-imx/imx8m/clock_imx8mq.c
index 759ec6d114..8fecc60ecb 100644
--- a/arch/arm/mach-imx/imx8m/clock_imx8mq.c
+++ b/arch/arm/mach-imx/imx8m/clock_imx8mq.c
@@ -310,6 +310,13 @@ static u32 get_root_clk(enum clk_root_index clock_id)
 	return root_src_clk / (post_podf + 1) / (pre_podf + 1);
 }
 
+#ifdef CONFIG_IMX_HAB
+void hab_caam_clock_enable(unsigned char enable)
+{
+	/* The CAAM clock is always on for iMX8M */
+}
+#endif
+
 #ifdef CONFIG_MXC_OCOTP
 void enable_ocotp_clk(unsigned char enable)
 {
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH 19/37] imx: cmd_dek: Enable DEK only for chips supporting CAAM
  2021-03-25  9:29 [PATCH 00/37] imx: hab/caam new feature and update Peng Fan
                   ` (17 preceding siblings ...)
  2021-03-25  9:30 ` [PATCH 18/37] iMX8M: Add support to enable CONFIG_IMX_HAB Peng Fan
@ 2021-03-25  9:30 ` Peng Fan
  2021-03-25  9:30 ` [PATCH 20/37] mx6dq: hab: Fix chip version in hab.h code Peng Fan
                   ` (18 subsequent siblings)
  37 siblings, 0 replies; 42+ messages in thread
From: Peng Fan @ 2021-03-25  9:30 UTC (permalink / raw)
  To: u-boot

From: Ye Li <ye.li@nxp.com>

Since cmd_dek is using CAAM JR, so enable the CMD_DEK only when
HAS_CAAM is set

Signed-off-by: Ye Li <ye.li@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 arch/arm/mach-imx/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 8c00ad1391..ca06c1eaaf 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -45,7 +45,7 @@ config IMX_HAB
 	bool "Support i.MX HAB features"
 	depends on ARCH_MX7 || ARCH_MX6 || ARCH_MX5 || ARCH_IMX8M
 	select FSL_CAAM if HAS_CAAM
-	imply CMD_DEKBLOB
+	imply CMD_DEKBLOB if HAS_CAAM
 	help
 	  This option enables the support for secure boot (HAB).
 	  See doc/imx/habv4/* for more details.
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH 20/37] mx6dq: hab: Fix chip version in hab.h code
  2021-03-25  9:29 [PATCH 00/37] imx: hab/caam new feature and update Peng Fan
                   ` (18 preceding siblings ...)
  2021-03-25  9:30 ` [PATCH 19/37] imx: cmd_dek: Enable DEK only for chips supporting CAAM Peng Fan
@ 2021-03-25  9:30 ` Peng Fan
  2021-03-25  9:30 ` [PATCH 21/37] cmd: blob: Add IMX_HAB and CAAM supported SoCs as dependency Peng Fan
                   ` (17 subsequent siblings)
  37 siblings, 0 replies; 42+ messages in thread
From: Peng Fan @ 2021-03-25  9:30 UTC (permalink / raw)
  To: u-boot

From: Breno Lima <breno.lima@nxp.com>

Since commit 8891410c729b ("MLK-19848 mx6dq: Fix chip version issue for
rev1.3") it's not possible to call the HAB API functions on i.MX6DQ
SoC Rev 1.3:

Authenticate image from DDR location 0x12000000...
undefined instruction
pc : [<412c00dc>]          lr : [<8ff560bc>]
reloc pc : [<c8b6d0dc>]    lr : [<178030bc>]
sp : 8ef444a8  ip : 126e8068     fp : 8ff59aa8
r10: 8ffd51e4  r9 : 8ef50eb0     r8 : 006e8000
r7 : 00000000  r6 : 126ea01f     r5 : 0000002b  r4 : 126e8000
r3 : 412c00dd  r2 : 00000001     r1 : 00000001  r0 : 00000063
Flags: nzCv  IRQs off  FIQs off  Mode SVC_32
Resetting CPU ...

resetting ...

The hab.h code is defining the HAB API base address according to the
old SoC revision number, thus failing when calling the HAB API
authenticate_image() function.

Fix this issue by using mx6dq rev 1.3 instead of mx6dq rev 1.5.

Signed-off-by: Breno Lima <breno.lima@nxp.com>
Reviewed-by: Ye Li <ye.li@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 arch/arm/include/asm/arch-imx/cpu.h | 1 +
 arch/arm/include/asm/mach-imx/hab.h | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm/include/asm/arch-imx/cpu.h b/arch/arm/include/asm/arch-imx/cpu.h
index ef090eb2f2..bb13e07b66 100644
--- a/arch/arm/include/asm/arch-imx/cpu.h
+++ b/arch/arm/include/asm/arch-imx/cpu.h
@@ -62,6 +62,7 @@
 #define CHIP_REV_1_0            0x10
 #define CHIP_REV_1_1            0x11
 #define CHIP_REV_1_2            0x12
+#define CHIP_REV_1_3            0x13
 #define CHIP_REV_1_5            0x15
 #define CHIP_REV_2_0            0x20
 #define CHIP_REV_2_1            0x21
diff --git a/arch/arm/include/asm/mach-imx/hab.h b/arch/arm/include/asm/mach-imx/hab.h
index d63b85378a..2abf28ea45 100644
--- a/arch/arm/include/asm/mach-imx/hab.h
+++ b/arch/arm/include/asm/mach-imx/hab.h
@@ -195,7 +195,7 @@ typedef void hapi_clock_init_t(void);
 #define HAB_RVT_BASE_OLD		0x00000094
 #define HAB_RVT_BASE ((is_mx6dqp()) ?					\
 			HAB_RVT_BASE_NEW :				\
-			(is_mx6dq() && (soc_rev() >= CHIP_REV_1_5)) ?	\
+			(is_mx6dq() && (soc_rev() >= CHIP_REV_1_3)) ?	\
 			HAB_RVT_BASE_NEW :				\
 			(is_mx6sdl() && (soc_rev() >= CHIP_REV_1_2)) ?	\
 			HAB_RVT_BASE_NEW : HAB_RVT_BASE_OLD)
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH 21/37] cmd: blob: Add IMX_HAB and CAAM supported SoCs as dependency
  2021-03-25  9:29 [PATCH 00/37] imx: hab/caam new feature and update Peng Fan
                   ` (19 preceding siblings ...)
  2021-03-25  9:30 ` [PATCH 20/37] mx6dq: hab: Fix chip version in hab.h code Peng Fan
@ 2021-03-25  9:30 ` Peng Fan
  2021-03-25  9:30 ` [PATCH 22/37] cmd: blob: Instantiate RNG before running CMD_BLOB Peng Fan
                   ` (16 subsequent siblings)
  37 siblings, 0 replies; 42+ messages in thread
From: Peng Fan @ 2021-03-25  9:30 UTC (permalink / raw)
  To: u-boot

From: Breno Lima <breno.lima@nxp.com>

In order to build CMD_BLOB on i.MX CAAM supported devices it's
necessary to select IMX_HAB. Add IMX_HAB and CAAM supported
SoCs as dependency.

Signed-off-by: Breno Lima <breno.lima@nxp.com>
Reviewed-by: Ye Li <ye.li@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 cmd/Kconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/cmd/Kconfig b/cmd/Kconfig
index eff238cb38..1da4539baf 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -1959,6 +1959,8 @@ config CMD_AES
 
 config CMD_BLOB
 	bool "Enable the 'blob' command"
+	depends on !MX6ULL && !MX6SLL && !MX6SL && !IMX8M && !MX7ULP
+	select IMX_HAB if ARCH_MX6 || ARCH_MX7
 	help
 	  This is used with the Freescale secure boot mechanism.
 
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH 22/37] cmd: blob: Instantiate RNG before running CMD_BLOB
  2021-03-25  9:29 [PATCH 00/37] imx: hab/caam new feature and update Peng Fan
                   ` (20 preceding siblings ...)
  2021-03-25  9:30 ` [PATCH 21/37] cmd: blob: Add IMX_HAB and CAAM supported SoCs as dependency Peng Fan
@ 2021-03-25  9:30 ` Peng Fan
  2021-03-25  9:30 ` [PATCH 23/37] crypto: caam: change JR running loop Peng Fan
                   ` (15 subsequent siblings)
  37 siblings, 0 replies; 42+ messages in thread
From: Peng Fan @ 2021-03-25  9:30 UTC (permalink / raw)
  To: u-boot

From: Breno Lima <breno.lima@nxp.com>

U-Boot can instantiate CAAM RNG if needed by crypto operations.
Call sec_init() prior running a blob operation to ensure
RNG is correctly instantiated.

Make sure CAAM clock is enabled and check if a job ring is
available for that operation.

Signed-off-by: Breno Lima <breno.lima@nxp.com>
Reviewed-by: Ye Li <ye.li@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 cmd/blob.c        | 14 ++++++++++++++
 include/fsl_sec.h |  3 +++
 2 files changed, 17 insertions(+)

diff --git a/cmd/blob.c b/cmd/blob.c
index c80e6977b4..359c8940fb 100644
--- a/cmd/blob.c
+++ b/cmd/blob.c
@@ -9,6 +9,10 @@
 #include <malloc.h>
 #include <asm/byteorder.h>
 #include <linux/compiler.h>
+#if defined(CONFIG_ARCH_MX6) || defined(CONFIG_ARCH_MX7)
+#include <fsl_sec.h>
+#include <asm/arch/clock.h>
+#endif
 
 /**
  * blob_decap() - Decapsulate the data as a blob
@@ -74,6 +78,16 @@ static int do_blob(struct cmd_tbl *cmdtp, int flag, int argc,
 	src_ptr = (uint8_t *)(uintptr_t)src_addr;
 	dst_ptr = (uint8_t *)(uintptr_t)dst_addr;
 
+#if defined(CONFIG_ARCH_MX6) || defined(CONFIG_ARCH_MX7)
+
+	hab_caam_clock_enable(1);
+
+	u32 out_jr_size = sec_in32(CONFIG_SYS_FSL_JR0_ADDR +
+				   FSL_CAAM_ORSR_JRa_OFFSET);
+	if (out_jr_size != FSL_CAAM_MAX_JR_SIZE)
+		sec_init();
+#endif
+
 	if (enc)
 		ret = blob_encap(km_ptr, src_ptr, dst_ptr, len);
 	else
diff --git a/include/fsl_sec.h b/include/fsl_sec.h
index 40f1c5b10d..c661bd6ead 100644
--- a/include/fsl_sec.h
+++ b/include/fsl_sec.h
@@ -344,6 +344,9 @@ struct sg_entry {
 #define FSL_CAAM_MP_PRVK_BYTES		    32
 #define FSL_CAAM_MP_MES_DGST_BYTES	    32
 
+#define FSL_CAAM_ORSR_JRa_OFFSET	0x102c
+#define FSL_CAAM_MAX_JR_SIZE		4
+
 /* blob_dek:
  * Encapsulates the src in a secure blob and stores it dst
  * @src: reference to the plaintext
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH 23/37] crypto: caam: change JR running loop
  2021-03-25  9:29 [PATCH 00/37] imx: hab/caam new feature and update Peng Fan
                   ` (21 preceding siblings ...)
  2021-03-25  9:30 ` [PATCH 22/37] cmd: blob: Instantiate RNG before running CMD_BLOB Peng Fan
@ 2021-03-25  9:30 ` Peng Fan
  2021-03-25  9:30 ` [PATCH 24/37] caam: enable support for iMX7ULP Peng Fan
                   ` (14 subsequent siblings)
  37 siblings, 0 replies; 42+ messages in thread
From: Peng Fan @ 2021-03-25  9:30 UTC (permalink / raw)
  To: u-boot

From: Franck LENORMAND <franck.lenormand@nxp.com>

Signed-off-by: Franck LENORMAND <franck.lenormand@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 drivers/crypto/fsl/jr.c | 12 +++++++-----
 drivers/crypto/fsl/jr.h |  4 ++--
 2 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/crypto/fsl/jr.c b/drivers/crypto/fsl/jr.c
index 44273c345f..de5e68bf8e 100644
--- a/drivers/crypto/fsl/jr.c
+++ b/drivers/crypto/fsl/jr.c
@@ -21,6 +21,7 @@
 #include <asm/fsl_pamu.h>
 #endif
 #include <dm/lists.h>
+#include <linux/delay.h>
 
 #define CIRC_CNT(head, tail, size)	(((head) - (tail)) & (size - 1))
 #define CIRC_SPACE(head, tail, size)	CIRC_CNT((tail), (head) + 1, (size))
@@ -355,8 +356,8 @@ static void desc_done(uint32_t status, void *arg)
 
 static inline int run_descriptor_jr_idx(uint32_t *desc, uint8_t sec_idx)
 {
-	unsigned long long timeval = get_ticks();
-	unsigned long long timeout = usec2ticks(CONFIG_SEC_DEQ_TIMEOUT);
+	unsigned long long timeval = 0;
+	unsigned long long timeout = CONFIG_USEC_DEQ_TIMEOUT;
 	struct result op;
 	int ret = 0;
 
@@ -369,9 +370,10 @@ static inline int run_descriptor_jr_idx(uint32_t *desc, uint8_t sec_idx)
 		goto out;
 	}
 
-	timeval = get_ticks();
-	timeout = usec2ticks(CONFIG_SEC_DEQ_TIMEOUT);
 	while (op.done != 1) {
+		udelay(1);
+		timeval += 1;
+
 		ret = jr_dequeue(sec_idx);
 		if (ret) {
 			debug("Error in SEC deq\n");
@@ -379,7 +381,7 @@ static inline int run_descriptor_jr_idx(uint32_t *desc, uint8_t sec_idx)
 			goto out;
 		}
 
-		if ((get_ticks() - timeval) > timeout) {
+		if (timeval > timeout) {
 			debug("SEC Dequeue timed out\n");
 			ret = JQ_DEQ_TO_ERR;
 			goto out;
diff --git a/drivers/crypto/fsl/jr.h b/drivers/crypto/fsl/jr.h
index ffd3a19273..1a215143d9 100644
--- a/drivers/crypto/fsl/jr.h
+++ b/drivers/crypto/fsl/jr.h
@@ -10,8 +10,8 @@
 #include <linux/compiler.h>
 
 #define JR_SIZE 4
-/* Timeout currently defined as 90 sec */
-#define CONFIG_SEC_DEQ_TIMEOUT	90000000U
+/* Timeout currently defined as 10 sec */
+#define CONFIG_USEC_DEQ_TIMEOUT	10000000U
 
 #define DEFAULT_JR_ID		0
 #define DEFAULT_JR_LIODN	0
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH 24/37] caam: enable support for iMX7ULP
  2021-03-25  9:29 [PATCH 00/37] imx: hab/caam new feature and update Peng Fan
                   ` (22 preceding siblings ...)
  2021-03-25  9:30 ` [PATCH 23/37] crypto: caam: change JR running loop Peng Fan
@ 2021-03-25  9:30 ` Peng Fan
  2021-03-25  9:30 ` [PATCH 25/37] imx7ulp: Enable support for cmd blob Peng Fan
                   ` (13 subsequent siblings)
  37 siblings, 0 replies; 42+ messages in thread
From: Peng Fan @ 2021-03-25  9:30 UTC (permalink / raw)
  To: u-boot

From: Franck LENORMAND <franck.lenormand@nxp.com>

Signed-off-by: Franck LENORMAND <franck.lenormand@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 arch/arm/Kconfig                            |  3 +++
 arch/arm/include/asm/arch-mx7ulp/imx-regs.h | 12 ++++++++++++
 arch/arm/mach-imx/mx7ulp/Kconfig            |  1 +
 drivers/crypto/fsl/jobdesc.c                |  2 +-
 include/fsl_sec.h                           |  8 ++++----
 5 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 3307f2b3fc..70b9ad5b9f 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -875,6 +875,9 @@ config ARCH_MX31
 config ARCH_MX7ULP
 	bool "NXP MX7ULP"
 	select CPU_V7A
+	select SYS_FSL_HAS_SEC if IMX_HAB
+	select SYS_FSL_SEC_COMPAT_4
+	select SYS_FSL_SEC_LE
 	select ROM_UNIFIED_SECTIONS
 	imply MXC_GPIO
 	imply SYS_THUMB_BUILD
diff --git a/arch/arm/include/asm/arch-mx7ulp/imx-regs.h b/arch/arm/include/asm/arch-mx7ulp/imx-regs.h
index 9a420dc30b..cb0c2c15c0 100644
--- a/arch/arm/include/asm/arch-mx7ulp/imx-regs.h
+++ b/arch/arm/include/asm/arch-mx7ulp/imx-regs.h
@@ -16,6 +16,8 @@
 #define CAAM_SEC_SRAM_SIZE      (SZ_32K)
 #define CAAM_SEC_SRAM_END       (CAAM_SEC_SRAM_BASE + CAAM_SEC_SRAM_SIZE - 1)
 
+#define CAAM_ARB_BASE_ADDR      CAAM_SEC_SRAM_BASE
+
 #define OCRAM_0_BASE            (0x2F000000)
 #define OCRAM_0_SIZE            (SZ_128K)
 #define OCRAM_0_END             (OCRAM_0_BASE + OCRAM_0_SIZE - 1)
@@ -224,6 +226,16 @@
 #define IOMUXC_DDR_RBASE	((AIPS3_BASE + (AIPS3_SLOT_SIZE * IOMUXC_DDR_AIPS3_SLOT)))
 #define MMDC0_PCC_REG		(PCC3_RBASE + (4 * MMDC0_PCC3_SLOT))
 
+#define CAAM_IPS_BASE_ADDR              (AIPS2_BASE + 0x240000) /* 40240000 */
+
+#define CONFIG_SYS_FSL_SEC_OFFSET       0
+#define CONFIG_SYS_FSL_SEC_ADDR         (CAAM_IPS_BASE_ADDR + \
+					 CONFIG_SYS_FSL_SEC_OFFSET)
+#define CONFIG_SYS_FSL_JR0_OFFSET       0x1000
+#define CONFIG_SYS_FSL_JR0_ADDR         (CONFIG_SYS_FSL_SEC_ADDR + \
+					 CONFIG_SYS_FSL_JR0_OFFSET)
+#define CONFIG_SYS_FSL_MAX_NUM_OF_SEC   1
+
 #define IOMUXC_DPCR_DDR_DQS0	((IOMUXC_DDR_RBASE + (4 * 32)))
 #define IOMUXC_DPCR_DDR_DQS1	((IOMUXC_DDR_RBASE + (4 * 33)))
 #define IOMUXC_DPCR_DDR_DQS2	((IOMUXC_DDR_RBASE + (4 * 34)))
diff --git a/arch/arm/mach-imx/mx7ulp/Kconfig b/arch/arm/mach-imx/mx7ulp/Kconfig
index 6680f856c5..2ffac9cf7c 100644
--- a/arch/arm/mach-imx/mx7ulp/Kconfig
+++ b/arch/arm/mach-imx/mx7ulp/Kconfig
@@ -9,6 +9,7 @@ config LDO_ENABLED_MODE
 	  Select this option to enable the PMC1 LDO.
 
 config MX7ULP
+	select HAS_CAAM
 	bool
 
 choice
diff --git a/drivers/crypto/fsl/jobdesc.c b/drivers/crypto/fsl/jobdesc.c
index fbc1aeddee..8c3db64527 100644
--- a/drivers/crypto/fsl/jobdesc.c
+++ b/drivers/crypto/fsl/jobdesc.c
@@ -15,7 +15,7 @@
 #include "rsa_caam.h"
 #include <asm/cache.h>
 
-#if defined(CONFIG_MX6) || defined(CONFIG_MX7)
+#if defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_MX7ULP)
 /*!
  * Secure memory run command
  *
diff --git a/include/fsl_sec.h b/include/fsl_sec.h
index c661bd6ead..a98f6cb12a 100644
--- a/include/fsl_sec.h
+++ b/include/fsl_sec.h
@@ -195,7 +195,7 @@ typedef struct ccsr_sec {
 
 struct jr_regs {
 #if defined(CONFIG_SYS_FSL_SEC_LE) && \
-	!(defined(CONFIG_MX6) || defined(CONFIG_MX7))
+	!(defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_MX7ULP))
 	u32 irba_l;
 	u32 irba_h;
 #else
@@ -209,7 +209,7 @@ struct jr_regs {
 	u32 rsvd3;
 	u32 irja;
 #if defined(CONFIG_SYS_FSL_SEC_LE) && \
-	!(defined(CONFIG_MX6) || defined(CONFIG_MX7))
+	!(defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_MX7ULP))
 	u32 orba_l;
 	u32 orba_h;
 #else
@@ -242,7 +242,7 @@ struct jr_regs {
  */
 struct sg_entry {
 #if defined(CONFIG_SYS_FSL_SEC_LE) && \
-	!(defined(CONFIG_MX6) || defined(CONFIG_MX7))
+	!(defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_MX7ULP))
 	uint32_t addr_lo;	/* Memory Address - lo */
 	uint32_t addr_hi;	/* Memory Address of start of buffer - hi */
 #else
@@ -263,7 +263,7 @@ struct sg_entry {
 
 #define BLOB_SIZE(x)		((x) + 32 + 16) /* Blob buffer size */
 
-#if defined(CONFIG_MX6) || defined(CONFIG_MX7)
+#if defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_MX7ULP)
 /* Job Ring Base Address */
 #define JR_BASE_ADDR(x) (CONFIG_SYS_FSL_SEC_ADDR + 0x1000 * (x + 1))
 /* Secure Memory Offset varies accross versions */
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH 25/37] imx7ulp: Enable support for cmd blob
  2021-03-25  9:29 [PATCH 00/37] imx: hab/caam new feature and update Peng Fan
                   ` (23 preceding siblings ...)
  2021-03-25  9:30 ` [PATCH 24/37] caam: enable support for iMX7ULP Peng Fan
@ 2021-03-25  9:30 ` Peng Fan
  2021-03-25  9:30 ` [PATCH 26/37] crypto: caam: Add CAAM support to i.MX8M platforms Peng Fan
                   ` (12 subsequent siblings)
  37 siblings, 0 replies; 42+ messages in thread
From: Peng Fan @ 2021-03-25  9:30 UTC (permalink / raw)
  To: u-boot

From: Franck LENORMAND <franck.lenormand@nxp.com>

Signed-off-by: Franck LENORMAND <franck.lenormand@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 cmd/Kconfig | 4 ++--
 cmd/blob.c  | 6 ++++--
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/cmd/Kconfig b/cmd/Kconfig
index 1da4539baf..00bcc7826b 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -1959,8 +1959,8 @@ config CMD_AES
 
 config CMD_BLOB
 	bool "Enable the 'blob' command"
-	depends on !MX6ULL && !MX6SLL && !MX6SL && !IMX8M && !MX7ULP
-	select IMX_HAB if ARCH_MX6 || ARCH_MX7
+	depends on !MX6ULL && !MX6SLL && !MX6SL && !IMX8M
+	select IMX_HAB if ARCH_MX6 || ARCH_MX7 || ARCH_MX7ULP
 	help
 	  This is used with the Freescale secure boot mechanism.
 
diff --git a/cmd/blob.c b/cmd/blob.c
index 359c8940fb..4e244cd126 100644
--- a/cmd/blob.c
+++ b/cmd/blob.c
@@ -9,7 +9,8 @@
 #include <malloc.h>
 #include <asm/byteorder.h>
 #include <linux/compiler.h>
-#if defined(CONFIG_ARCH_MX6) || defined(CONFIG_ARCH_MX7)
+#if defined(CONFIG_ARCH_MX6) || defined(CONFIG_ARCH_MX7) || \
+	defined(CONFIG_ARCH_MX7ULP)
 #include <fsl_sec.h>
 #include <asm/arch/clock.h>
 #endif
@@ -78,7 +79,8 @@ static int do_blob(struct cmd_tbl *cmdtp, int flag, int argc,
 	src_ptr = (uint8_t *)(uintptr_t)src_addr;
 	dst_ptr = (uint8_t *)(uintptr_t)dst_addr;
 
-#if defined(CONFIG_ARCH_MX6) || defined(CONFIG_ARCH_MX7)
+#if defined(CONFIG_ARCH_MX6) || defined(CONFIG_ARCH_MX7) || \
+	defined(CONFIG_ARCH_MX7ULP)
 
 	hab_caam_clock_enable(1);
 
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH 26/37] crypto: caam: Add CAAM support to i.MX8M platforms
  2021-03-25  9:29 [PATCH 00/37] imx: hab/caam new feature and update Peng Fan
                   ` (24 preceding siblings ...)
  2021-03-25  9:30 ` [PATCH 25/37] imx7ulp: Enable support for cmd blob Peng Fan
@ 2021-03-25  9:30 ` Peng Fan
  2021-03-25  9:30 ` [PATCH 27/37] crypto: caam: Fix build warnings pointer casting Peng Fan
                   ` (11 subsequent siblings)
  37 siblings, 0 replies; 42+ messages in thread
From: Peng Fan @ 2021-03-25  9:30 UTC (permalink / raw)
  To: u-boot

From: Aymen Sghaier <aymen.sghaier@nxp.com>

This patch enable CAAM support for i.MX8M platforms.

Signed-off-by: Aymen Sghaier <aymen.sghaier@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 arch/arm/Kconfig                |  3 +++
 arch/arm/mach-imx/imx8m/Kconfig |  1 +
 drivers/crypto/fsl/jobdesc.c    |  4 +++-
 include/fsl_sec.h               | 13 +++++++++----
 4 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 70b9ad5b9f..76adf7fdb2 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -839,6 +839,9 @@ config ARCH_IMX8
 config ARCH_IMX8M
 	bool "NXP i.MX8M platform"
 	select ARM64
+	select SYS_FSL_HAS_SEC if IMX_HAB
+	select SYS_FSL_SEC_COMPAT_4
+	select SYS_FSL_SEC_LE
 	select DM
 	select SUPPORT_SPL
 	imply CMD_DM
diff --git a/arch/arm/mach-imx/imx8m/Kconfig b/arch/arm/mach-imx/imx8m/Kconfig
index 59a45f7b01..e7e1315bac 100644
--- a/arch/arm/mach-imx/imx8m/Kconfig
+++ b/arch/arm/mach-imx/imx8m/Kconfig
@@ -2,6 +2,7 @@ if ARCH_IMX8M
 
 config IMX8M
 	bool
+	select HAS_CAAM
 	select ROM_UNIFIED_SECTIONS
 
 config IMX8MQ
diff --git a/drivers/crypto/fsl/jobdesc.c b/drivers/crypto/fsl/jobdesc.c
index 8c3db64527..0120a5c977 100644
--- a/drivers/crypto/fsl/jobdesc.c
+++ b/drivers/crypto/fsl/jobdesc.c
@@ -4,6 +4,7 @@
  * Basic job descriptor construction
  *
  * Copyright 2014 Freescale Semiconductor, Inc.
+ * Copyright 2018 NXP
  *
  */
 
@@ -15,7 +16,8 @@
 #include "rsa_caam.h"
 #include <asm/cache.h>
 
-#if defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_MX7ULP)
+#if defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_MX7ULP) || \
+		defined(CONFIG_IMX8M)
 /*!
  * Secure memory run command
  *
diff --git a/include/fsl_sec.h b/include/fsl_sec.h
index a98f6cb12a..c531a14477 100644
--- a/include/fsl_sec.h
+++ b/include/fsl_sec.h
@@ -3,6 +3,7 @@
  * Common internal memory map for some Freescale SoCs
  *
  * Copyright 2014 Freescale Semiconductor, Inc.
+ * Copyright 2018 NXP
  */
 
 #ifndef __FSL_SEC_H
@@ -195,7 +196,8 @@ typedef struct ccsr_sec {
 
 struct jr_regs {
 #if defined(CONFIG_SYS_FSL_SEC_LE) && \
-	!(defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_MX7ULP))
+	!(defined(CONFIG_MX6) || defined(CONFIG_MX7) || \
+	  defined(CONFIG_MX7ULP) || defined(CONFIG_IMX8M))
 	u32 irba_l;
 	u32 irba_h;
 #else
@@ -209,7 +211,8 @@ struct jr_regs {
 	u32 rsvd3;
 	u32 irja;
 #if defined(CONFIG_SYS_FSL_SEC_LE) && \
-	!(defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_MX7ULP))
+	!(defined(CONFIG_MX6) || defined(CONFIG_MX7) || \
+	  defined(CONFIG_MX7ULP) || defined(CONFIG_IMX8M))
 	u32 orba_l;
 	u32 orba_h;
 #else
@@ -242,7 +245,8 @@ struct jr_regs {
  */
 struct sg_entry {
 #if defined(CONFIG_SYS_FSL_SEC_LE) && \
-	!(defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_MX7ULP))
+	!(defined(CONFIG_MX6) || defined(CONFIG_MX7) || \
+	  defined(CONFIG_MX7ULP) || defined(CONFIG_IMX8M))
 	uint32_t addr_lo;	/* Memory Address - lo */
 	uint32_t addr_hi;	/* Memory Address of start of buffer - hi */
 #else
@@ -263,7 +267,8 @@ struct sg_entry {
 
 #define BLOB_SIZE(x)		((x) + 32 + 16) /* Blob buffer size */
 
-#if defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_MX7ULP)
+#if defined(CONFIG_MX6) || defined(CONFIG_MX7) || \
+	defined(CONFIG_MX7ULP) || defined(CONFIG_IMX8M)
 /* Job Ring Base Address */
 #define JR_BASE_ADDR(x) (CONFIG_SYS_FSL_SEC_ADDR + 0x1000 * (x + 1))
 /* Secure Memory Offset varies accross versions */
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH 27/37] crypto: caam: Fix build warnings pointer casting
  2021-03-25  9:29 [PATCH 00/37] imx: hab/caam new feature and update Peng Fan
                   ` (25 preceding siblings ...)
  2021-03-25  9:30 ` [PATCH 26/37] crypto: caam: Add CAAM support to i.MX8M platforms Peng Fan
@ 2021-03-25  9:30 ` Peng Fan
  2021-03-25  9:30 ` [PATCH 28/37] crypto: Add blob command support for i.MX8M platforms Peng Fan
                   ` (10 subsequent siblings)
  37 siblings, 0 replies; 42+ messages in thread
From: Peng Fan @ 2021-03-25  9:30 UTC (permalink / raw)
  To: u-boot

From: Aymen Sghaier <aymen.sghaier@nxp.com>

  Enabling CAAM driver for i.MX8M platforms, a 64 bits architecture,
 lead to casting warnings: from/to pointer to/from integer with
 different size. This patch fix these warnings

Signed-off-by: Aymen Sghaier <aymen.sghaier@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 drivers/crypto/fsl/jr.c | 5 +++--
 include/fsl_sec.h       | 4 ++--
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/crypto/fsl/jr.c b/drivers/crypto/fsl/jr.c
index de5e68bf8e..68954db99a 100644
--- a/drivers/crypto/fsl/jr.c
+++ b/drivers/crypto/fsl/jr.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
  * Copyright 2008-2014 Freescale Semiconductor, Inc.
+ * Copyright 2018 NXP
  *
  * Based on CAAM driver in drivers/crypto/caam in Linux
  */
@@ -35,10 +36,10 @@ uint32_t sec_offset[CONFIG_SYS_FSL_MAX_NUM_OF_SEC] = {
 };
 
 #define SEC_ADDR(idx)	\
-	((CONFIG_SYS_FSL_SEC_ADDR + sec_offset[idx]))
+	(ulong)((CONFIG_SYS_FSL_SEC_ADDR + sec_offset[idx]))
 
 #define SEC_JR0_ADDR(idx)	\
-	(SEC_ADDR(idx) +	\
+	(ulong)(SEC_ADDR(idx) +	\
 	 (CONFIG_SYS_FSL_JR0_OFFSET - CONFIG_SYS_FSL_SEC_OFFSET))
 
 struct jobring jr0[CONFIG_SYS_FSL_MAX_NUM_OF_SEC];
diff --git a/include/fsl_sec.h b/include/fsl_sec.h
index c531a14477..dca0dd0328 100644
--- a/include/fsl_sec.h
+++ b/include/fsl_sec.h
@@ -13,8 +13,8 @@
 #include <asm/io.h>
 
 #ifdef CONFIG_SYS_FSL_SEC_LE
-#define sec_in32(a)       in_le32(a)
-#define sec_out32(a, v)   out_le32(a, v)
+#define sec_in32(a)       in_le32((ulong *)(ulong)a)
+#define sec_out32(a, v)   out_le32((ulong *)(ulong)a, v)
 #define sec_in16(a)       in_le16(a)
 #define sec_clrbits32     clrbits_le32
 #define sec_setbits32     setbits_le32
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH 28/37] crypto: Add blob command support for i.MX8M platforms
  2021-03-25  9:29 [PATCH 00/37] imx: hab/caam new feature and update Peng Fan
                   ` (26 preceding siblings ...)
  2021-03-25  9:30 ` [PATCH 27/37] crypto: caam: Fix build warnings pointer casting Peng Fan
@ 2021-03-25  9:30 ` Peng Fan
  2021-03-25  9:30 ` [PATCH 29/37] crypto: caam: Fix pointer size to 32bit for i.MX8M Peng Fan
                   ` (9 subsequent siblings)
  37 siblings, 0 replies; 42+ messages in thread
From: Peng Fan @ 2021-03-25  9:30 UTC (permalink / raw)
  To: u-boot

From: Aymen Sghaier <aymen.sghaier@nxp.com>

 This patch enable blob command for mScale platforms.

Signed-off-by: Aymen Sghaier <aymen.sghaier@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 cmd/Kconfig | 4 ++--
 cmd/blob.c  | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/cmd/Kconfig b/cmd/Kconfig
index 00bcc7826b..f73de2d75a 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -1959,8 +1959,8 @@ config CMD_AES
 
 config CMD_BLOB
 	bool "Enable the 'blob' command"
-	depends on !MX6ULL && !MX6SLL && !MX6SL && !IMX8M
-	select IMX_HAB if ARCH_MX6 || ARCH_MX7 || ARCH_MX7ULP
+	depends on !MX6ULL && !MX6SLL && !MX6SL
+	select IMX_HAB if ARCH_MX6 || ARCH_MX7 || ARCH_MX7ULP || ARCH_IMX8M
 	help
 	  This is used with the Freescale secure boot mechanism.
 
diff --git a/cmd/blob.c b/cmd/blob.c
index 4e244cd126..887219cc07 100644
--- a/cmd/blob.c
+++ b/cmd/blob.c
@@ -10,7 +10,7 @@
 #include <asm/byteorder.h>
 #include <linux/compiler.h>
 #if defined(CONFIG_ARCH_MX6) || defined(CONFIG_ARCH_MX7) || \
-	defined(CONFIG_ARCH_MX7ULP)
+	defined(CONFIG_ARCH_MX7ULP) || defined(CONFIG_ARCH_IMX8M)
 #include <fsl_sec.h>
 #include <asm/arch/clock.h>
 #endif
@@ -80,7 +80,7 @@ static int do_blob(struct cmd_tbl *cmdtp, int flag, int argc,
 	dst_ptr = (uint8_t *)(uintptr_t)dst_addr;
 
 #if defined(CONFIG_ARCH_MX6) || defined(CONFIG_ARCH_MX7) || \
-	defined(CONFIG_ARCH_MX7ULP)
+	defined(CONFIG_ARCH_MX7ULP) || defined(CONFIG_ARCH_IMX8M)
 
 	hab_caam_clock_enable(1);
 
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH 29/37] crypto: caam: Fix pointer size to 32bit for i.MX8M
  2021-03-25  9:29 [PATCH 00/37] imx: hab/caam new feature and update Peng Fan
                   ` (27 preceding siblings ...)
  2021-03-25  9:30 ` [PATCH 28/37] crypto: Add blob command support for i.MX8M platforms Peng Fan
@ 2021-03-25  9:30 ` Peng Fan
  2021-03-25  9:30 ` [PATCH 30/37] crypto: caam: Add secure memory vid 3 support Peng Fan
                   ` (8 subsequent siblings)
  37 siblings, 0 replies; 42+ messages in thread
From: Peng Fan @ 2021-03-25  9:30 UTC (permalink / raw)
  To: u-boot

From: Aymen Sghaier <aymen.sghaier@nxp.com>

  The CAAM block used in i.MX8M is 32 bits address size but when the flag
 PHYS_64BIT is enabled for armv8, the CAAM driver will try to use a
 wrong pointer size.
  This patch fixes this issue.

Signed-off-by: Aymen Sghaier <aymen.sghaier@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 drivers/crypto/fsl/desc_constr.h | 29 +++++++++++++++--------------
 drivers/crypto/fsl/fsl_hash.c    |  3 ++-
 drivers/crypto/fsl/jobdesc.c     | 13 +++++++------
 drivers/crypto/fsl/jr.c          | 16 ++++++++--------
 drivers/crypto/fsl/jr.h          |  7 ++++---
 5 files changed, 36 insertions(+), 32 deletions(-)

diff --git a/drivers/crypto/fsl/desc_constr.h b/drivers/crypto/fsl/desc_constr.h
index b82ba83e73..9edb8dc64a 100644
--- a/drivers/crypto/fsl/desc_constr.h
+++ b/drivers/crypto/fsl/desc_constr.h
@@ -3,6 +3,7 @@
  * caam descriptor construction helper functions
  *
  * Copyright 2008-2014 Freescale Semiconductor, Inc.
+ * Copyright 2018 NXP
  *
  * Based on desc_constr.h file in linux drivers/crypto/caam
  */
@@ -12,7 +13,7 @@
 
 #define IMMEDIATE (1 << 23)
 #define CAAM_CMD_SZ sizeof(u32)
-#define CAAM_PTR_SZ sizeof(dma_addr_t)
+#define CAAM_PTR_SZ sizeof(u32)
 #define CAAM_DESC_BYTES_MAX (CAAM_CMD_SZ * MAX_CAAM_DESCSIZE)
 #define DESC_JOB_IO_LEN (CAAM_CMD_SZ * 5 + CAAM_PTR_SZ * 3)
 
@@ -35,7 +36,7 @@
 			       LDST_SRCDST_WORD_DECOCTRL | \
 			       (LDOFF_ENABLE_AUTO_NFIFO << LDST_OFFSET_SHIFT))
 
-#ifdef CONFIG_PHYS_64BIT
+#if defined(CONFIG_PHYS_64BIT) && !defined(CONFIG_IMX8M)
 struct ptr_addr_t {
 #ifdef CONFIG_SYS_FSL_SEC_LE
 	u32 low;
@@ -49,9 +50,9 @@ struct ptr_addr_t {
 };
 #endif
 
-static inline void pdb_add_ptr(dma_addr_t *offset, dma_addr_t ptr)
+static inline void pdb_add_ptr(u32 *offset, u32 ptr)
 {
-#ifdef CONFIG_PHYS_64BIT
+#if defined(CONFIG_PHYS_64BIT) && !defined(CONFIG_IMX8M)
 	/* The Position of low and high part of 64 bit address
 	 * will depend on the endianness of CAAM Block */
 	struct ptr_addr_t *ptr_addr = (struct ptr_addr_t *)offset;
@@ -102,11 +103,11 @@ static inline void init_job_desc_pdb(u32 *desc, u32 options, size_t pdb_bytes)
 		       options);
 }
 
-static inline void append_ptr(u32 *desc, dma_addr_t ptr)
+static inline void append_ptr(u32 *desc, uint32_t ptr)
 {
-	dma_addr_t *offset = (dma_addr_t *)desc_end(desc);
+	u32 *offset = (u32 *)desc_end(desc);
 
-#ifdef CONFIG_PHYS_64BIT
+#if defined(CONFIG_PHYS_64BIT) && !defined(CONFIG_IMX8M)
 	/* The Position of low and high part of 64 bit address
 	 * will depend on the endianness of CAAM Block */
 	struct ptr_addr_t *ptr_addr = (struct ptr_addr_t *)offset;
@@ -159,7 +160,7 @@ static inline u32 *write_cmd(u32 *desc, u32 command)
 	return desc + 1;
 }
 
-static inline void append_cmd_ptr(u32 *desc, dma_addr_t ptr, int len,
+static inline void append_cmd_ptr(u32 *desc, uint32_t ptr, int len,
 				  u32 command)
 {
 	append_cmd(desc, command | len);
@@ -167,7 +168,7 @@ static inline void append_cmd_ptr(u32 *desc, dma_addr_t ptr, int len,
 }
 
 /* Write length after pointer, rather than inside command */
-static inline void append_cmd_ptr_extlen(u32 *desc, dma_addr_t ptr,
+static inline void append_cmd_ptr_extlen(u32 *desc, uint32_t ptr,
 					 unsigned int len, u32 command)
 {
 	append_cmd(desc, command);
@@ -225,7 +226,7 @@ APPEND_CMD_LEN(seq_fifo_load, SEQ_FIFO_LOAD)
 APPEND_CMD_LEN(seq_fifo_store, SEQ_FIFO_STORE)
 
 #define APPEND_CMD_PTR(cmd, op) \
-static inline void append_##cmd(u32 *desc, dma_addr_t ptr, unsigned int len, \
+static inline void append_##cmd(u32 *desc, uint32_t ptr, unsigned int len, \
 				u32 options) \
 { \
 	PRINT_POS; \
@@ -236,7 +237,7 @@ APPEND_CMD_PTR(load, LOAD)
 APPEND_CMD_PTR(fifo_load, FIFO_LOAD)
 APPEND_CMD_PTR(fifo_store, FIFO_STORE)
 
-static inline void append_store(u32 *desc, dma_addr_t ptr, unsigned int len,
+static inline void append_store(u32 *desc, uint32_t ptr, unsigned int len,
 				u32 options)
 {
 	u32 cmd_src;
@@ -254,7 +255,7 @@ static inline void append_store(u32 *desc, dma_addr_t ptr, unsigned int len,
 }
 
 #define APPEND_SEQ_PTR_INTLEN(cmd, op) \
-static inline void append_seq_##cmd##_ptr_intlen(u32 *desc, dma_addr_t ptr, \
+static inline void append_seq_##cmd##_ptr_intlen(u32 *desc, uint32_t ptr, \
 						 unsigned int len, \
 						 u32 options) \
 { \
@@ -278,7 +279,7 @@ APPEND_CMD_PTR_TO_IMM(load, LOAD);
 APPEND_CMD_PTR_TO_IMM(fifo_load, FIFO_LOAD);
 
 #define APPEND_CMD_PTR_EXTLEN(cmd, op) \
-static inline void append_##cmd##_extlen(u32 *desc, dma_addr_t ptr, \
+static inline void append_##cmd##_extlen(u32 *desc, uint32_t ptr, \
 					 unsigned int len, u32 options) \
 { \
 	PRINT_POS; \
@@ -292,7 +293,7 @@ APPEND_CMD_PTR_EXTLEN(seq_out_ptr, SEQ_OUT_PTR)
  * the size of its type
  */
 #define APPEND_CMD_PTR_LEN(cmd, op, type) \
-static inline void append_##cmd(u32 *desc, dma_addr_t ptr, \
+static inline void append_##cmd(u32 *desc, uint32_t ptr, \
 				type len, u32 options) \
 { \
 	PRINT_POS; \
diff --git a/drivers/crypto/fsl/fsl_hash.c b/drivers/crypto/fsl/fsl_hash.c
index 61f953e8a6..75500a621f 100644
--- a/drivers/crypto/fsl/fsl_hash.c
+++ b/drivers/crypto/fsl/fsl_hash.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
  * Copyright 2014 Freescale Semiconductor, Inc.
+ * Copyright 2018 NXP
  *
  */
 
@@ -95,7 +96,7 @@ static int caam_hash_update(void *hash_ctx, const void *buf,
 		return -EINVAL;
 	}
 
-#ifdef CONFIG_PHYS_64BIT
+#if defined(CONFIG_PHYS_64BIT) && !defined(CONFIG_IMX8M)
 	sec_out32(&ctx->sg_tbl[ctx->sg_num].addr_hi, (uint32_t)(addr >> 32));
 #else
 	sec_out32(&ctx->sg_tbl[ctx->sg_num].addr_hi, 0x0);
diff --git a/drivers/crypto/fsl/jobdesc.c b/drivers/crypto/fsl/jobdesc.c
index 0120a5c977..cd9d064657 100644
--- a/drivers/crypto/fsl/jobdesc.c
+++ b/drivers/crypto/fsl/jobdesc.c
@@ -165,9 +165,10 @@ int inline_cnstr_jobdesc_blob_dek(uint32_t *desc, const uint8_t *plain_txt,
 
 	append_u32(desc, aad_w2);
 
-	append_cmd_ptr(desc, (dma_addr_t)SEC_MEM_PAGE1, in_sz, CMD_SEQ_IN_PTR);
+	append_cmd_ptr(desc, (uint32_t)SEC_MEM_PAGE1, in_sz, CMD_SEQ_IN_PTR);
 
-	append_cmd_ptr(desc, (dma_addr_t)dek_blob + 8, out_sz, CMD_SEQ_OUT_PTR);
+	append_cmd_ptr(desc, (uint32_t)((ulong)dek_blob + 8),
+		       out_sz, CMD_SEQ_OUT_PTR);
 
 	append_operation(desc, OP_TYPE_ENCAP_PROTOCOL | OP_PCLID_BLOB |
 						OP_PCLID_SECMEM);
@@ -183,7 +184,7 @@ void inline_cnstr_jobdesc_hash(uint32_t *desc,
 	/* SHA 256 , output is of length 32 words */
 	uint32_t storelen = alg_size;
 	u32 options;
-	dma_addr_t dma_addr_in, dma_addr_out;
+	u32 dma_addr_in, dma_addr_out;
 
 	dma_addr_in = virt_to_phys((void *)msg);
 	dma_addr_out = virt_to_phys((void *)digest);
@@ -212,7 +213,7 @@ void inline_cnstr_jobdesc_blob_encap(uint32_t *desc, uint8_t *key_idnfr,
 				     uint8_t *plain_txt, uint8_t *enc_blob,
 				     uint32_t in_sz)
 {
-	dma_addr_t dma_addr_key_idnfr, dma_addr_in, dma_addr_out;
+	u32 dma_addr_key_idnfr, dma_addr_in, dma_addr_out;
 	uint32_t key_sz = KEY_IDNFR_SZ_BYTES;
 	/* output blob will have 32 bytes key blob in beginning and
 	 * 16 byte HMAC identifier at end of data blob */
@@ -237,7 +238,7 @@ void inline_cnstr_jobdesc_blob_decap(uint32_t *desc, uint8_t *key_idnfr,
 				     uint8_t *enc_blob, uint8_t *plain_txt,
 				     uint32_t out_sz)
 {
-	dma_addr_t dma_addr_key_idnfr, dma_addr_in, dma_addr_out;
+	u32 dma_addr_key_idnfr, dma_addr_in, dma_addr_out;
 	uint32_t key_sz = KEY_IDNFR_SZ_BYTES;
 	uint32_t in_sz = out_sz + KEY_BLOB_SIZE + MAC_SIZE;
 
@@ -313,7 +314,7 @@ void inline_cnstr_jobdesc_pkha_rsaexp(uint32_t *desc,
 				      struct pk_in_params *pkin, uint8_t *out,
 				      uint32_t out_siz)
 {
-	dma_addr_t dma_addr_e, dma_addr_a, dma_addr_n, dma_addr_out;
+	u32 dma_addr_e, dma_addr_a, dma_addr_n, dma_addr_out;
 
 	dma_addr_e = virt_to_phys((void *)pkin->e);
 	dma_addr_a = virt_to_phys((void *)pkin->a);
diff --git a/drivers/crypto/fsl/jr.c b/drivers/crypto/fsl/jr.c
index 68954db99a..060a012eb2 100644
--- a/drivers/crypto/fsl/jr.c
+++ b/drivers/crypto/fsl/jr.c
@@ -87,13 +87,13 @@ static void jr_initregs(uint8_t sec_idx)
 	phys_addr_t ip_base = virt_to_phys((void *)jr->input_ring);
 	phys_addr_t op_base = virt_to_phys((void *)jr->output_ring);
 
-#ifdef CONFIG_PHYS_64BIT
+#if defined(CONFIG_PHYS_64BIT) && !defined(CONFIG_IMX8M)
 	sec_out32(&regs->irba_h, ip_base >> 32);
 #else
 	sec_out32(&regs->irba_h, 0x0);
 #endif
 	sec_out32(&regs->irba_l, (uint32_t)ip_base);
-#ifdef CONFIG_PHYS_64BIT
+#if defined(CONFIG_PHYS_64BIT) && !defined(CONFIG_IMX8M)
 	sec_out32(&regs->orba_h, op_base >> 32);
 #else
 	sec_out32(&regs->orba_h, 0x0);
@@ -119,7 +119,7 @@ static int jr_init(uint8_t sec_idx)
 	jr->liodn = DEFAULT_JR_LIODN;
 #endif
 	jr->size = JR_SIZE;
-	jr->input_ring = (dma_addr_t *)memalign(ARCH_DMA_MINALIGN,
+	jr->input_ring = (uint32_t *)memalign(ARCH_DMA_MINALIGN,
 				JR_SIZE * sizeof(dma_addr_t));
 	if (!jr->input_ring)
 		return -1;
@@ -196,7 +196,7 @@ static int jr_enqueue(uint32_t *desc_addr,
 	uint32_t desc_word;
 	int length = desc_len(desc_addr);
 	int i;
-#ifdef CONFIG_PHYS_64BIT
+#if defined(CONFIG_PHYS_64BIT) && !defined(CONFIG_IMX8M)
 	uint32_t *addr_hi, *addr_lo;
 #endif
 
@@ -223,7 +223,7 @@ static int jr_enqueue(uint32_t *desc_addr,
 				  sizeof(struct jr_info), ARCH_DMA_MINALIGN);
 	flush_dcache_range(start, end);
 
-#ifdef CONFIG_PHYS_64BIT
+#if defined(CONFIG_PHYS_64BIT) && !defined(CONFIG_IMX8M)
 	/* Write the 64 bit Descriptor address on Input Ring.
 	 * The 32 bit hign and low part of the address will
 	 * depend on endianness of SEC block.
@@ -272,7 +272,7 @@ static int jr_dequeue(int sec_idx)
 	int idx, i, found;
 	void (*callback)(uint32_t status, void *arg);
 	void *arg = NULL;
-#ifdef CONFIG_PHYS_64BIT
+#if defined(CONFIG_PHYS_64BIT) && !defined(CONFIG_IMX8M)
 	uint32_t *addr_hi, *addr_lo;
 #else
 	uint32_t *addr;
@@ -284,7 +284,7 @@ static int jr_dequeue(int sec_idx)
 		found = 0;
 
 		phys_addr_t op_desc;
-	#ifdef CONFIG_PHYS_64BIT
+	#if defined(CONFIG_PHYS_64BIT) && !defined(CONFIG_IMX8M)
 		/* Read the 64 bit Descriptor address from Output Ring.
 		 * The 32 bit hign and low part of the address will
 		 * depend on endianness of SEC block.
@@ -678,7 +678,7 @@ int sec_init_idx(uint8_t sec_idx)
 	mcr = (mcr & ~MCFGR_AWCACHE_MASK) | (0x2 << MCFGR_AWCACHE_SHIFT);
 #endif
 
-#ifdef CONFIG_PHYS_64BIT
+#if defined(CONFIG_PHYS_64BIT) && !defined(CONFIG_IMX8M)
 	mcr |= (1 << MCFGR_PS_SHIFT);
 #endif
 	sec_out32(&sec->mcfgr, mcr);
diff --git a/drivers/crypto/fsl/jr.h b/drivers/crypto/fsl/jr.h
index 1a215143d9..92566dd2d6 100644
--- a/drivers/crypto/fsl/jr.h
+++ b/drivers/crypto/fsl/jr.h
@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * Copyright 2008-2014 Freescale Semiconductor, Inc.
+ * Copyright 2018 NXP
  *
  */
 
@@ -41,8 +42,8 @@
 #define RNG4_MAX_HANDLES	2
 
 struct op_ring {
-	phys_addr_t desc;
-	uint32_t status;
+	u32 desc;
+	u32 status;
 } __packed;
 
 struct jr_info {
@@ -83,7 +84,7 @@ struct jobring {
 	 * by SEC
 	 */
 	/*Circular  Ring of i/p descriptors */
-	dma_addr_t *input_ring;
+	u32 *input_ring;
 	/* Circular Ring of o/p descriptors */
 	/* Circula Ring containing info regarding descriptors in i/p
 	 * and o/p ring
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH 30/37] crypto: caam: Add secure memory vid 3 support
  2021-03-25  9:29 [PATCH 00/37] imx: hab/caam new feature and update Peng Fan
                   ` (28 preceding siblings ...)
  2021-03-25  9:30 ` [PATCH 29/37] crypto: caam: Fix pointer size to 32bit for i.MX8M Peng Fan
@ 2021-03-25  9:30 ` Peng Fan
  2021-03-25  9:30 ` [PATCH 31/37] crypto: caam: Add fsl caam driver Peng Fan
                   ` (7 subsequent siblings)
  37 siblings, 0 replies; 42+ messages in thread
From: Peng Fan @ 2021-03-25  9:30 UTC (permalink / raw)
  To: u-boot

From: Aymen Sghaier <aymen.sghaier@nxp.com>

In i.MX8M platforms the secure memory block has a newer version
than those used in i.MX6/7 platforms, this patch update the driver
to use the correct registers offsets.

Signed-off-by: Aymen Sghaier <aymen.sghaier@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 include/fsl_sec.h | 22 +++++++++++++++-------
 1 file changed, 15 insertions(+), 7 deletions(-)

diff --git a/include/fsl_sec.h b/include/fsl_sec.h
index dca0dd0328..09ce916297 100644
--- a/include/fsl_sec.h
+++ b/include/fsl_sec.h
@@ -276,7 +276,8 @@ struct sg_entry {
 #define SM_V2_OFFSET 0xa00
 /*Secure Memory Versioning */
 #define SMVID_V2 0x20105
-#define SM_VERSION(x)  (x < SMVID_V2 ? 1 : 2)
+#define SM_VERSION(x)  ({typeof(x) _x = x; \
+		_x < SMVID_V2 ? 1 : (_x < 0x20300 ? 2 : 3); })
 #define SM_OFFSET(x)  (x == 1 ? SM_V1_OFFSET : SM_V2_OFFSET)
 /* CAAM Job Ring 0 Registers */
 /* Secure Memory Partition Owner register */
@@ -303,8 +304,10 @@ struct sg_entry {
 #define SM_CMD(v)		(v == 1 ? 0x0 : 0x1E4)
 #define SM_STATUS(v)		(v == 1 ? 0x8 : 0x1EC)
 #define SM_PERM(v)		(v == 1 ?  0x10 : 0x4)
-#define SM_GROUP2(v)		(v == 1 ? 0x14 : 0x8)
-#define SM_GROUP1(v)		(v == 1 ? 0x18 : 0xC)
+#define SM_GROUP2(v)		({typeof(v) _v = v; \
+		_v == 1 ? 0x14 : (_v == 2 ? 0x8 : 0xC); })
+#define SM_GROUP1(v)		({typeof(v) _v = v; \
+		_v == 1 ? 0x18 : (_v == 2 ? 0xC : 0x8); })
 #define CMD_PAGE_ALLOC		0x1
 #define CMD_PAGE_DEALLOC	0x2
 #define CMD_PART_DEALLOC	0x3
@@ -322,10 +325,15 @@ struct sg_entry {
 #define SEC_MEM_PAGE2		(CAAM_ARB_BASE_ADDR + 0x2000)
 #define SEC_MEM_PAGE3		(CAAM_ARB_BASE_ADDR + 0x3000)
 
-#define JR_MID			2               /* Matches ROM configuration */
-#define KS_G1			(1 << JR_MID)   /* CAAM only */
-#define PERM			0x0000B008      /* Clear on release, lock SMAP
-						 * lock SMAG group 1 Blob */
+#ifdef CONFIG_IMX8M
+#define JR_MID    (1)         /* Matches ATF configuration */
+#define KS_G1     (0x10000 << JR_MID) /* CAAM only */
+#define PERM      (0xB080)    /* CSP, SMAP_LCK, SMAG_LCK, G1_BLOB */
+#else
+#define JR_MID    (2)         /* Matches ROM configuration */
+#define KS_G1     BIT(JR_MID) /* CAAM only */
+#define PERM      (0xB008)    /* CSP, SMAP_LCK, SMAG_LCK, G1_BLOB */
+#endif /* CONFIG_IMX8M */
 
 /* HAB WRAPPED KEY header */
 #define WRP_HDR_SIZE		0x08
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH 31/37] crypto: caam: Add fsl caam driver
  2021-03-25  9:29 [PATCH 00/37] imx: hab/caam new feature and update Peng Fan
                   ` (29 preceding siblings ...)
  2021-03-25  9:30 ` [PATCH 30/37] crypto: caam: Add secure memory vid 3 support Peng Fan
@ 2021-03-25  9:30 ` Peng Fan
  2021-04-08 18:24   ` Stefano Babic
  2021-03-25  9:30 ` [PATCH 32/37] crypto: caam: RNG4 TRNG errata Peng Fan
                   ` (6 subsequent siblings)
  37 siblings, 1 reply; 42+ messages in thread
From: Peng Fan @ 2021-03-25  9:30 UTC (permalink / raw)
  To: u-boot

From: Ye Li <ye.li@nxp.com>

Add the fsl CAAM driver and new commands to implement DEK blob operations,
like "caam genblob" to generate encrypted blob and "caam decap" to output
orignal plain data.

 The following reasons lead to instantiate the TRNG into U-Boot/SPL:

 - On some i.MX platforms Linux Kernel could not instantiate RNG
 - RNG could be used/needed by M4/M0 cores before Kernel stage
 - Having the RNG instantiation implemented only once for
   almost i.MX platforms

Signed-off-by: Aymen Sghaier <aymen.sghaier@nxp.com>
Signed-off-by: Ye Li <ye.li@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 arch/arm/include/asm/arch-mx7/crm_regs.h |   8 +
 cmd/Kconfig                              |   6 +
 cmd/Makefile                             |   1 +
 cmd/cmd_fsl_caam.c                       |  88 +++
 drivers/crypto/Makefile                  |   1 +
 drivers/crypto/fsl_caam.c                | 715 +++++++++++++++++++++++
 drivers/crypto/fsl_caam_internal.h       | 229 ++++++++
 include/fsl_caam.h                       |  24 +
 8 files changed, 1072 insertions(+)
 create mode 100644 cmd/cmd_fsl_caam.c
 create mode 100644 drivers/crypto/fsl_caam.c
 create mode 100644 drivers/crypto/fsl_caam_internal.h
 create mode 100644 include/fsl_caam.h

diff --git a/arch/arm/include/asm/arch-mx7/crm_regs.h b/arch/arm/include/asm/arch-mx7/crm_regs.h
index bfa68a9d2a..a000ae05d7 100644
--- a/arch/arm/include/asm/arch-mx7/crm_regs.h
+++ b/arch/arm/include/asm/arch-mx7/crm_regs.h
@@ -1998,6 +1998,14 @@ struct mxc_ccm_anatop_reg {
 #define TEMPMON_HW_ANADIG_TEMPSENSE_TRIM_TOG_T_MUX_ADDR_SHIFT 29
 #define TEMPMON_HW_ANADIG_TEMPSENSE_TRIM_TOG_T_MUX_ADDR(x) (((uint32_t)(((uint32_t)(x))<<TEMPMON_HW_ANADIG_TEMPSENSE_TRIM_TOG_T_MUX_ADDR_SHIFT))&TEMPMON_HW_ANADIG_TEMPSENSE_TRIM_TOG_T_MUX_ADDR_MASK)
 
+#define MXC_CCM_CCGR36_CAAM_DOMAIN3_OFFSET                     12
+#define MXC_CCM_CCGR36_CAAM_DOMAIN3_MASK                       (3 << MXC_CCM_CCGR36_CAAM_DOMAIN3_OFFSET)
+#define MXC_CCM_CCGR36_CAAM_DOMAIN2_OFFSET                     8
+#define MXC_CCM_CCGR36_CAAM_DOMAIN2_MASK                       (3 << MXC_CCM_CCGR36_CAAM_DOMAIN2_OFFSET)
+#define MXC_CCM_CCGR36_CAAM_DOMAIN1_OFFSET                     4
+#define MXC_CCM_CCGR36_CAAM_DOMAIN1_MASK                       (3 << MXC_CCM_CCGR36_CAAM_DOMAIN1_OFFSET)
+#define MXC_CCM_CCGR36_CAAM_DOMAIN0_OFFSET                     0
+#define MXC_CCM_CCGR36_CAAM_DOMAIN0_MASK                       (3 << MXC_CCM_CCGR36_CAAM_DOMAIN0_OFFSET)
 
 #define CCM_GPR(i)		(CCM_BASE_ADDR + CCM_GPR0_OFFSET + 0x10 * (i))
 #define CCM_OBSERVE(i)		(CCM_BASE_ADDR + CCM_OBSERVE0_OFFSET + 0x10 * (i))
diff --git a/cmd/Kconfig b/cmd/Kconfig
index f73de2d75a..aeecfed974 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -397,6 +397,12 @@ config CMD_SPL_WRITE_SIZE
 	  flash used by Falcon-mode boot. See the documentation until CMD_SPL
 	  for detail.
 
+config CMD_FSL_CAAM_KB
+	bool "Freescale i.MX CAAM command"
+	help
+	  Implement the "caam" command to generate DEK blob for one block of data
+	  or decap the DEK blob to its original data.
+
 config CMD_THOR_DOWNLOAD
 	bool "thor - TIZEN 'thor' download"
 	select DFU
diff --git a/cmd/Makefile b/cmd/Makefile
index 567e2b79d2..d46ffd7021 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -70,6 +70,7 @@ obj-$(CONFIG_CMD_FLASH) += flash.o
 obj-$(CONFIG_CMD_FPGA) += fpga.o
 obj-$(CONFIG_CMD_FPGAD) += fpgad.o
 obj-$(CONFIG_CMD_FS_GENERIC) += fs.o
+obj-$(CONFIG_CMD_FSL_CAAM_KB) += cmd_fsl_caam.o
 obj-$(CONFIG_CMD_FUSE) += fuse.o
 obj-$(CONFIG_CMD_GETTIME) += gettime.o
 obj-$(CONFIG_CMD_GPIO) += gpio.o
diff --git a/cmd/cmd_fsl_caam.c b/cmd/cmd_fsl_caam.c
new file mode 100644
index 0000000000..d41d672320
--- /dev/null
+++ b/cmd/cmd_fsl_caam.c
@@ -0,0 +1,88 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2012-2016 Freescale Semiconductor, Inc.
+ */
+
+#include <common.h>
+#include <command.h>
+#include <fsl_caam.h>
+
+static int do_caam(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	int ret, i;
+
+	if (argc < 2)
+		return CMD_RET_USAGE;
+
+	if (strcmp(argv[1], "genblob") == 0) {
+		if (argc != 5)
+			return CMD_RET_USAGE;
+
+		void *data_addr;
+		void *blob_addr;
+		int size;
+
+		data_addr = (void *)simple_strtoul(argv[2], NULL, 16);
+		blob_addr = (void *)simple_strtoul(argv[3], NULL, 16);
+		size = simple_strtoul(argv[4], NULL, 10);
+		if (size <= 48)
+			return CMD_RET_USAGE;
+
+		caam_open();
+		ret = caam_gen_blob((uint32_t)data_addr, (uint32_t)blob_addr, (uint32_t)size);
+
+		if (ret != SUCCESS) {
+			printf("Error during blob encap operation: 0x%x\n", ret);
+			return 0;
+		}
+
+		/* Print the generated DEK blob */
+		printf("DEK blob is available at 0x%08X and equals:\n", (unsigned int)blob_addr);
+		for (i = 0; i < size; i++)
+			printf("%02X ", ((uint8_t *)blob_addr)[i]);
+		printf("\n\n");
+
+		return 1;
+	} else if (strcmp(argv[1], "decap") == 0) {
+		if (argc != 5)
+			return CMD_RET_USAGE;
+
+		void *blob_addr;
+		void *data_addr;
+		int size;
+
+		blob_addr = (void *)simple_strtoul(argv[2], NULL, 16);
+		data_addr = (void *)simple_strtoul(argv[3], NULL, 16);
+		size      = simple_strtoul(argv[4], NULL, 10);
+		if (size <= 48)
+			return CMD_RET_USAGE;
+
+		caam_open();
+		ret = caam_decap_blob((uint32_t)(data_addr), (uint32_t)(blob_addr), (uint32_t)size);
+		if (ret != SUCCESS) {
+			printf("Error during blob decap operation: 0x%x\n", ret);
+		} else {
+			printf("Success, blob decap@SM PAGE1 original data is:\n");
+			int i = 0;
+
+			for (i = 0; i < size; i++) {
+				printf("0x%x  ", *(unsigned char *)(data_addr + i));
+				if (i % 16 == 0)
+					printf("\n");
+			}
+			printf("\n");
+		}
+
+		return 1;
+	}
+
+	return CMD_RET_USAGE;
+}
+
+U_BOOT_CMD(
+	caam, 5, 1, do_caam,
+	"Freescale i.MX CAAM command",
+	"caam genblob data_addr blob_addr data_size\n \
+	caam decap blobaddr data_addr data_size\n \
+	\n "
+	);
diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
index efbd1d3fca..6069dd5b29 100644
--- a/drivers/crypto/Makefile
+++ b/drivers/crypto/Makefile
@@ -4,5 +4,6 @@
 # 	http://www.samsung.com
 
 obj-$(CONFIG_EXYNOS_ACE_SHA)	+= ace_sha.o
+obj-$(CONFIG_FSL_CAAM_KB)      += fsl_caam.o
 obj-y += rsa_mod_exp/
 obj-y += fsl/
diff --git a/drivers/crypto/fsl_caam.c b/drivers/crypto/fsl_caam.c
new file mode 100644
index 0000000000..ccdf131635
--- /dev/null
+++ b/drivers/crypto/fsl_caam.c
@@ -0,0 +1,715 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2012-2016, Freescale Semiconductor, Inc.
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <memalign.h>
+#include <asm/io.h>
+#ifndef CONFIG_ARCH_MX7ULP
+#include <asm/arch/crm_regs.h>
+#else
+#include <asm/arch/pcc.h>
+#endif /* CONFIG_ARCH_MX7ULP */
+#include "fsl_caam_internal.h"
+#include "fsl/desc_constr.h"
+#include <fsl_caam.h>
+#include <cpu_func.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static void rng_init(void);
+static void caam_clock_enable(void);
+static int do_cfg_jrqueue(void);
+static int do_job(u32 *desc);
+static int jr_reset(void);
+
+/*
+ * Structures
+ */
+/* Definition of input ring object */
+struct inring_entry {
+	u32 desc; /* Pointer to input descriptor */
+};
+
+/* Definition of output ring object */
+struct outring_entry {
+	u32 desc;   /* Pointer to output descriptor */
+	u32 status; /* Status of the Job Ring       */
+};
+
+/* Main job ring data structure */
+struct jr_data_st {
+	struct inring_entry  *inrings;
+	struct outring_entry *outrings;
+	u32 status;  /* Ring buffers init status */
+	u32 *desc;   /* Pointer to output descriptor */
+	u32 raw_addr[DESC_MAX_SIZE * 2];
+};
+
+/*
+ * Global variables
+ */
+#if defined(CONFIG_SPL_BUILD)
+static struct jr_data_st g_jrdata = {0};
+#else
+static struct jr_data_st g_jrdata = {0, 0, 0xFFFFFFFF};
+#endif
+
+static u8 skeymod[] = {
+	0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08,
+	0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00
+};
+
+/*
+ * Local functions
+ */
+static void dump_error(void)
+{
+	int i;
+
+	debug("Dump CAAM Error\n");
+	debug("MCFGR 0x%08X\n", __raw_readl(CAAM_MCFGR));
+	debug("FAR  0x%08X\n", __raw_readl(CAAM_FAR));
+	debug("FAMR 0x%08X\n", __raw_readl(CAAM_FAMR));
+	debug("FADR 0x%08X\n", __raw_readl(CAAM_FADR));
+	debug("CSTA 0x%08X\n", __raw_readl(CAAM_STA));
+	debug("RTMCTL 0x%X\n", __raw_readl(CAAM_RTMCTL));
+	debug("RTSTATUS 0x%X\n", __raw_readl(CAAM_RTSTATUS));
+	debug("RDSTA 0x%X\n", __raw_readl(CAAM_RDSTA));
+
+	for (i = 0; i < desc_len(g_jrdata.desc); i++)
+		debug("desc[%d]: 0x%08x\n", i, g_jrdata.desc[i]);
+}
+
+/*!
+ * Secure memory run command.
+ *
+ * @param   sec_mem_cmd  Secure memory command register
+ * @return  cmd_status  Secure memory command status register
+ */
+u32 secmem_set_cmd_1(u32 sec_mem_cmd)
+{
+	u32 temp_reg;
+
+	__raw_writel(sec_mem_cmd, CAAM_SMCJR0);
+	do {
+		temp_reg = __raw_readl(CAAM_SMCSJR0);
+	} while (temp_reg & CMD_COMPLETE);
+
+	return temp_reg;
+}
+
+/*!
+ * Use CAAM to decapsulate a blob to secure memory.
+ * Such blob of secret key cannot be read once decrypted,
+ * but can still be used for enc/dec operation of user's data.
+ *
+ * @param   blob_addr  Location address of the blob.
+ *
+ * @return  SUCCESS or ERROR_XXX
+ */
+u32 caam_decap_blob(u32 plain_text, u32 blob_addr, u32 size)
+{
+	u32 ret = SUCCESS;
+	u32 key_sz = sizeof(skeymod);
+	u32 *decap_desc = g_jrdata.desc;
+
+	/* prepare job descriptor */
+	init_job_desc(decap_desc, 0);
+	append_load(decap_desc, PTR2CAAMDMA(skeymod), key_sz,
+		    LDST_CLASS_2_CCB | LDST_SRCDST_BYTE_KEY);
+	append_seq_in_ptr_intlen(decap_desc, blob_addr, size + 48, 0);
+	append_seq_out_ptr_intlen(decap_desc, plain_text, size, 0);
+	append_operation(decap_desc, OP_TYPE_DECAP_PROTOCOL | OP_PCLID_BLOB);
+
+	flush_dcache_range((uintptr_t)blob_addr & ALIGN_MASK,
+			   ((uintptr_t)blob_addr & ALIGN_MASK)
+			    + ROUND(2 * size, ARCH_DMA_MINALIGN));
+	flush_dcache_range((uintptr_t)plain_text & ALIGN_MASK,
+			   (plain_text & ALIGN_MASK)
+			   + ROUND(2 * size, ARCH_DMA_MINALIGN));
+
+	/* Run descriptor with result written to blob buffer */
+	ret = do_job(decap_desc);
+
+	if (ret != SUCCESS)
+		printf("Error: blob decap job failed 0x%x\n", ret);
+
+	return ret;
+}
+
+/*!
+ * Use CAAM to generate a blob.
+ *
+ * @param   plain_data_addr  Location address of the plain data.
+ * @param   blob_addr  Location address of the blob.
+ *
+ * @return  SUCCESS or ERROR_XXX
+ */
+u32 caam_gen_blob(u32 plain_data_addr, u32 blob_addr, u32 size)
+{
+	u32 ret = SUCCESS;
+	u32 key_sz = sizeof(skeymod);
+	u32 *encap_desc = g_jrdata.desc;
+	/* Buffer to hold the resulting blob */
+	u8 *blob = (u8 *)CAAMDMA2PTR(blob_addr);
+
+	/* initialize the blob array */
+	memset(blob, 0, size);
+
+	/* prepare job descriptor */
+	init_job_desc(encap_desc, 0);
+	append_load(encap_desc, PTR2CAAMDMA(skeymod), key_sz,
+		    LDST_CLASS_2_CCB | LDST_SRCDST_BYTE_KEY);
+	append_seq_in_ptr_intlen(encap_desc, plain_data_addr, size, 0);
+	append_seq_out_ptr_intlen(encap_desc, PTR2CAAMDMA(blob), size + 48, 0);
+	append_operation(encap_desc, OP_TYPE_ENCAP_PROTOCOL | OP_PCLID_BLOB);
+
+	flush_dcache_range((uintptr_t)plain_data_addr & ALIGN_MASK,
+			   (plain_data_addr & ALIGN_MASK)
+			   + ROUND(2 * size, ARCH_DMA_MINALIGN));
+	flush_dcache_range((uintptr_t)blob & ALIGN_MASK,
+			   ((uintptr_t)blob & ALIGN_MASK)
+			   + ROUND(2 * size, ARCH_DMA_MINALIGN));
+
+	ret = do_job(encap_desc);
+
+	if (ret != SUCCESS)
+		printf("Error: blob encap job failed 0x%x\n", ret);
+
+	return ret;
+}
+
+u32 caam_hwrng(u8 *output_ptr, u32 output_len)
+{
+	u32 ret = SUCCESS;
+	u32 *hwrng_desc = g_jrdata.desc;
+	/* Buffer to hold the resulting output*/
+	u8 *output = (u8 *)output_ptr;
+
+	/* initialize the output array */
+	memset(output, 0, output_len);
+
+	/* prepare job descriptor */
+	init_job_desc(hwrng_desc, 0);
+	append_operation(hwrng_desc, OP_ALG_ALGSEL_RNG | OP_TYPE_CLASS1_ALG);
+	append_fifo_store(hwrng_desc, PTR2CAAMDMA(output),
+			  output_len, FIFOST_TYPE_RNGSTORE);
+
+	/* flush cache */
+	flush_dcache_range((uintptr_t)hwrng_desc & ALIGN_MASK,
+			   ((uintptr_t)hwrng_desc & ALIGN_MASK)
+			   + ROUND(DESC_MAX_SIZE, ARCH_DMA_MINALIGN));
+
+	ret = do_job(hwrng_desc);
+
+	flush_dcache_range((uintptr_t)output & ALIGN_MASK,
+			   ((uintptr_t)output & ALIGN_MASK)
+			   + ROUND(2 * output_len, ARCH_DMA_MINALIGN));
+
+	if (ret != SUCCESS)
+		printf("Error: RNG generate failed 0x%x\n", ret);
+
+	return ret;
+}
+
+/*!
+ * Initialize the CAAM.
+ *
+ */
+void caam_open(void)
+{
+	u32 temp_reg;
+	int ret;
+
+	/* switch on the clock */
+#ifndef CONFIG_ARCH_IMX8
+	caam_clock_enable();
+#endif
+
+	/* reset the CAAM */
+	temp_reg = __raw_readl(CAAM_MCFGR) |
+			CAAM_MCFGR_DMARST | CAAM_MCFGR_SWRST;
+	__raw_writel(temp_reg,  CAAM_MCFGR);
+	while (__raw_readl(CAAM_MCFGR) & CAAM_MCFGR_DMARST)
+		;
+
+	jr_reset();
+	ret = do_cfg_jrqueue();
+
+	if (ret != SUCCESS) {
+		printf("Error CAAM JR initialization\n");
+		return;
+	}
+
+	/* Check if the RNG is already instantiated */
+	temp_reg = __raw_readl(CAAM_RDSTA);
+	if (temp_reg == (RDSTA_IF0 | RDSTA_IF1 | RDSTA_SKVN)) {
+		printf("RNG already instantiated 0x%X\n", temp_reg);
+		return;
+	}
+
+	rng_init();
+}
+
+static void caam_clock_enable(void)
+{
+#if defined(CONFIG_ARCH_MX6)
+	struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
+	u32 reg;
+
+	reg = __raw_readl(&mxc_ccm->CCGR0);
+
+	reg |= (MXC_CCM_CCGR0_CAAM_SECURE_MEM_MASK |
+		MXC_CCM_CCGR0_CAAM_WRAPPER_ACLK_MASK |
+		MXC_CCM_CCGR0_CAAM_WRAPPER_IPG_MASK);
+
+	__raw_writel(reg, &mxc_ccm->CCGR0);
+
+#ifndef CONFIG_MX6UL
+	/* EMI slow clk */
+	reg = __raw_readl(&mxc_ccm->CCGR6);
+	reg |= MXC_CCM_CCGR6_EMI_SLOW_MASK;
+
+	__raw_writel(reg, &mxc_ccm->CCGR6);
+#endif
+
+#elif defined(CONFIG_ARCH_MX7)
+	HW_CCM_CCGR_SET(36, MXC_CCM_CCGR36_CAAM_DOMAIN0_MASK);
+#elif defined(CONFIG_ARCH_MX7ULP)
+	pcc_clock_enable(PER_CLK_CAAM, true);
+#endif
+}
+
+static void kick_trng(u32 ent_delay)
+{
+	u32 samples  = 512; /* number of bits to generate and test */
+	u32 mono_min = 195;
+	u32 mono_max = 317;
+	u32 mono_range  = mono_max - mono_min;
+	u32 poker_min = 1031;
+	u32 poker_max = 1600;
+	u32 poker_range = poker_max - poker_min + 1;
+	u32 retries    = 2;
+	u32 lrun_max   = 32;
+	s32 run_1_min   = 27;
+	s32 run_1_max   = 107;
+	s32 run_1_range = run_1_max - run_1_min;
+	s32 run_2_min   = 7;
+	s32 run_2_max   = 62;
+	s32 run_2_range = run_2_max - run_2_min;
+	s32 run_3_min   = 0;
+	s32 run_3_max   = 39;
+	s32 run_3_range = run_3_max - run_3_min;
+	s32 run_4_min   = -1;
+	s32 run_4_max   = 26;
+	s32 run_4_range = run_4_max - run_4_min;
+	s32 run_5_min   = -1;
+	s32 run_5_max   = 18;
+	s32 run_5_range = run_5_max - run_5_min;
+	s32 run_6_min   = -1;
+	s32 run_6_max   = 17;
+	s32 run_6_range = run_6_max - run_6_min;
+	u32 val;
+
+	/* Put RNG in program mode */
+	setbits_le32(CAAM_RTMCTL, RTMCTL_PGM);
+	/* Configure the RNG Entropy Delay
+	 * Performance-wise, it does not make sense to
+	 * set the delay to a value that is lower
+	 * than the last one that worked (i.e. the state handles
+	 * were instantiated properly. Thus, instead of wasting
+	 * time trying to set the values controlling the sample
+	 * frequency, the function simply returns.
+	 */
+	val = __raw_readl(CAAM_RTSDCTL);
+	val &= BM_TRNG_ENT_DLY;
+	val >>= BS_TRNG_ENT_DLY;
+	if (ent_delay < val) {
+		/* Put RNG4 into run mode */
+		clrbits_le32(CAAM_RTMCTL, RTMCTL_PGM);
+		return;
+	}
+
+	val = (ent_delay << BS_TRNG_ENT_DLY) | samples;
+	__raw_writel(val, CAAM_RTSDCTL);
+
+	/* min. freq. count, equal to 1/2 of the entropy sample length */
+	__raw_writel(ent_delay >> 1, CAAM_RTFRQMIN);
+
+	/* max. freq. count, equal to 32 times the entropy sample length */
+	__raw_writel(ent_delay << 5, CAAM_RTFRQMAX);
+
+	__raw_writel((retries << 16) | lrun_max, CAAM_RTSCMISC);
+	__raw_writel(poker_max, CAAM_RTPKRMAX);
+	__raw_writel(poker_range, CAAM_RTPKRRNG);
+	__raw_writel((mono_range << 16) | mono_max, CAAM_RTSCML);
+	__raw_writel((run_1_range << 16) | run_1_max, CAAM_RTSCR1L);
+	__raw_writel((run_2_range << 16) | run_2_max, CAAM_RTSCR2L);
+	__raw_writel((run_3_range << 16) | run_3_max, CAAM_RTSCR3L);
+	__raw_writel((run_4_range << 16) | run_4_max, CAAM_RTSCR4L);
+	__raw_writel((run_5_range << 16) | run_5_max, CAAM_RTSCR5L);
+	__raw_writel((run_6_range << 16) | run_6_max, CAAM_RTSCR6PL);
+
+	val = __raw_readl(CAAM_RTMCTL);
+	/*
+	 * Select raw sampling in both entropy shifter
+	 * and statistical checker
+	 */
+	val &= ~BM_TRNG_SAMP_MODE;
+	val |= TRNG_SAMP_MODE_RAW_ES_SC;
+	/* Put RNG4 into run mode */
+	val &= ~RTMCTL_PGM;
+/*test with sample mode only */
+	__raw_writel(val, CAAM_RTMCTL);
+
+	/* Clear the ERR bit in RTMCTL if set. The TRNG error can occur when the
+	 * RNG clock is not within 1/2x to 8x the system clock.
+	 * This error is possible if ROM code does not initialize the system PLLs
+	 * immediately after PoR.
+	 */
+	/* setbits_le32(CAAM_RTMCTL, RTMCTL_ERR); */
+}
+
+/*
+ *  Descriptors to instantiate SH0, SH1, load the keys
+ */
+static const u32 rng_inst_sh0_desc[] = {
+	/* Header, don't setup the size */
+	CAAM_HDR_CTYPE | CAAM_HDR_ONE | CAAM_HDR_START_INDEX(0),
+	/* Operation instantiation (sh0) */
+	CAAM_PROTOP_CTYPE | CAAM_C1_RNG | ALGO_RNG_SH(0) | ALGO_RNG_INSTANTIATE,
+};
+
+static const u32 rng_inst_sh1_desc[] = {
+	/* wait for done - Jump to next entry */
+	CAAM_C1_JUMP | CAAM_JUMP_LOCAL | CAAM_JUMP_TST_ALL_COND_TRUE
+		| CAAM_JUMP_OFFSET(1),
+	/* Clear written register (write 1) */
+	CAAM_C0_LOAD_IMM | CAAM_DST_CLEAR_WRITTEN | sizeof(u32),
+	0x00000001,
+	/* Operation instantiation (sh1) */
+	CAAM_PROTOP_CTYPE | CAAM_C1_RNG | ALGO_RNG_SH(1)
+		| ALGO_RNG_INSTANTIATE,
+};
+
+static const u32 rng_inst_load_keys[] = {
+	/* wait for done - Jump to next entry */
+	CAAM_C1_JUMP | CAAM_JUMP_LOCAL | CAAM_JUMP_TST_ALL_COND_TRUE
+		| CAAM_JUMP_OFFSET(1),
+	/* Clear written register (write 1) */
+	CAAM_C0_LOAD_IMM | CAAM_DST_CLEAR_WRITTEN | sizeof(u32),
+	0x00000001,
+	/* Generate the Key */
+	CAAM_PROTOP_CTYPE | CAAM_C1_RNG | BM_ALGO_RNG_SK | ALGO_RNG_GENERATE,
+};
+
+static void do_inst_desc(u32 *desc, u32 status)
+{
+	u32 *pdesc = desc;
+	u8  desc_len;
+	bool add_sh0   = false;
+	bool add_sh1   = false;
+	bool load_keys = false;
+
+	/*
+	 * Modify the the descriptor to remove if necessary:
+	 *  - The key loading
+	 *  - One of the SH already instantiated
+	 */
+	desc_len = RNG_DESC_SH0_SIZE;
+	if ((status & RDSTA_IF0) != RDSTA_IF0)
+		add_sh0 = true;
+
+	if ((status & RDSTA_IF1) != RDSTA_IF1) {
+		add_sh1 = true;
+		if (add_sh0)
+			desc_len += RNG_DESC_SH1_SIZE;
+	}
+
+	if ((status & RDSTA_SKVN) != RDSTA_SKVN) {
+		load_keys = true;
+		desc_len += RNG_DESC_KEYS_SIZE;
+	}
+
+	/* Copy the SH0 descriptor anyway */
+	memcpy(pdesc, rng_inst_sh0_desc, sizeof(rng_inst_sh0_desc));
+	pdesc += RNG_DESC_SH0_SIZE;
+
+	if (load_keys) {
+		debug("RNG - Load keys\n");
+		memcpy(pdesc, rng_inst_load_keys, sizeof(rng_inst_load_keys));
+		pdesc += RNG_DESC_KEYS_SIZE;
+	}
+
+	if (add_sh1) {
+		if (add_sh0) {
+			debug("RNG - Instantiation of SH0 and SH1\n");
+			/* Add the sh1 descriptor */
+			memcpy(pdesc, rng_inst_sh1_desc,
+			       sizeof(rng_inst_sh1_desc));
+		} else {
+			debug("RNG - Instantiation of SH1 only\n");
+			/* Modify the SH0 descriptor to instantiate only SH1 */
+			desc[1] &= ~BM_ALGO_RNG_SH;
+			desc[1] |= ALGO_RNG_SH(1);
+		}
+	}
+
+	/* Setup the descriptor size */
+	desc[0] &= ~(0x3F);
+	desc[0] |= CAAM_HDR_DESCLEN(desc_len);
+}
+
+static int jr_reset(void)
+{
+	/*
+	 * Function reset the Job Ring HW
+	 * Reset is done in 2 steps:
+	 *  - Flush all pending jobs (Set RESET bit)
+	 *  - Reset the Job Ring (Set RESET bit second time)
+	 */
+	u16 timeout = 10000;
+	u32 reg_val;
+
+	/* Mask interrupts to poll for reset completion status */
+	setbits_le32(CAAM_JRCFGR0_LS, BM_JRCFGR_LS_IMSK);
+
+	/* Initiate flush (required prior to reset) */
+	__raw_writel(JRCR_RESET, CAAM_JRCR0);
+	do {
+		reg_val = __raw_readl(CAAM_JRINTR0);
+		reg_val &= BM_JRINTR_HALT;
+	} while ((reg_val == JRINTR_HALT_ONGOING) && --timeout);
+
+	if (!timeout  || reg_val != JRINTR_HALT_DONE) {
+		printf("Failed to flush job ring\n");
+		return ERROR_ANY;
+	}
+
+	/* Initiate reset */
+	timeout = 100;
+	__raw_writel(JRCR_RESET, CAAM_JRCR0);
+	do {
+		reg_val = __raw_readl(CAAM_JRCR0);
+	} while ((reg_val & JRCR_RESET) && --timeout);
+
+	if (!timeout) {
+		printf("Failed to reset job ring\n");
+		return ERROR_ANY;
+	}
+
+	return 0;
+}
+
+static int do_job(u32 *desc)
+{
+	int ret;
+	phys_addr_t p_desc = virt_to_phys(desc);
+
+	if (__raw_readl(CAAM_IRSAR0) == 0)
+		return ERROR_ANY;
+	g_jrdata.inrings[0].desc = p_desc;
+
+	flush_dcache_range((uintptr_t)g_jrdata.inrings & ALIGN_MASK,
+			   ((uintptr_t)g_jrdata.inrings & ALIGN_MASK)
+			   + ROUND(DESC_MAX_SIZE, ARCH_DMA_MINALIGN));
+	flush_dcache_range((uintptr_t)desc & ALIGN_MASK,
+			   ((uintptr_t)desc & ALIGN_MASK)
+			   + ROUND(DESC_MAX_SIZE, ARCH_DMA_MINALIGN));
+
+	/* Inform HW that a new JR is available */
+	__raw_writel(1, CAAM_IRJAR0);
+	while (__raw_readl(CAAM_ORSFR0) == 0)
+		;
+
+	flush_dcache_range((uintptr_t)g_jrdata.outrings & ALIGN_MASK,
+			   ((uintptr_t)g_jrdata.outrings & ALIGN_MASK)
+			   + ROUND(DESC_MAX_SIZE, ARCH_DMA_MINALIGN));
+
+	if (PTR2CAAMDMA(desc) == g_jrdata.outrings[0].desc) {
+		ret = g_jrdata.outrings[0].status;
+	} else {
+		dump_error();
+		ret = ERROR_ANY;
+	}
+
+	/* Acknowledge interrupt */
+	setbits_le32(CAAM_JRINTR0, JRINTR_JRI);
+
+	/* Remove the JR from the output list even if no JR caller found */
+	__raw_writel(1, CAAM_ORJRR0);
+
+	return ret;
+}
+
+static int do_cfg_jrqueue(void)
+{
+	u32 value = 0;
+	phys_addr_t ip_base;
+	phys_addr_t op_base;
+
+	/* check if already configured after relocation */
+	if (g_jrdata.status == RING_RELOC_INIT)
+		return 0;
+
+	/*
+	 * jr configuration needs to be updated once, after relocation to ensure
+	 * using the right buffers.
+	 * When buffers are updated after relocation the flag RING_RELOC_INIT
+	 * is used to prevent extra updates
+	 */
+	if (gd->flags & GD_FLG_RELOC) {
+		g_jrdata.inrings  = (struct inring_entry *)
+				    memalign(ARCH_DMA_MINALIGN,
+					     ARCH_DMA_MINALIGN);
+		g_jrdata.outrings = (struct outring_entry *)
+				    memalign(ARCH_DMA_MINALIGN,
+					     ARCH_DMA_MINALIGN);
+		g_jrdata.desc = (u32 *)
+				memalign(ARCH_DMA_MINALIGN, ARCH_DMA_MINALIGN);
+		g_jrdata.status = RING_RELOC_INIT;
+	} else {
+		u32 align_idx = 0;
+
+		/* Ensure 64bits buffers addresses alignment */
+		if ((uintptr_t)g_jrdata.raw_addr & 0x7)
+			align_idx = 1;
+		g_jrdata.inrings  = (struct inring_entry *)
+				    (&g_jrdata.raw_addr[align_idx]);
+		g_jrdata.outrings = (struct outring_entry *)
+				    (&g_jrdata.raw_addr[align_idx + 2]);
+		g_jrdata.desc = (u32 *)(&g_jrdata.raw_addr[align_idx + 4]);
+		g_jrdata.status = RING_EARLY_INIT;
+	}
+
+	if (!g_jrdata.inrings || !g_jrdata.outrings)
+		return ERROR_ANY;
+
+	/* Configure the HW Job Rings */
+	ip_base = virt_to_phys((void *)g_jrdata.inrings);
+	op_base = virt_to_phys((void *)g_jrdata.outrings);
+	__raw_writel(ip_base, CAAM_IRBAR0);
+	__raw_writel(1, CAAM_IRSR0);
+
+	__raw_writel(op_base, CAAM_ORBAR0);
+	__raw_writel(1, CAAM_ORSR0);
+
+	setbits_le32(CAAM_JRINTR0, JRINTR_JRI);
+
+	/*
+	 * Configure interrupts but disable it:
+	 * Optimization to generate an interrupt either when there are
+	 * half of the job done or when there is a job done and
+	 * 10 clock cycles elapse without new job complete
+	 */
+	value = 10 << BS_JRCFGR_LS_ICTT;
+	value |= (1 << BS_JRCFGR_LS_ICDCT) & BM_JRCFGR_LS_ICDCT;
+	value |= BM_JRCFGR_LS_ICEN;
+	value |= BM_JRCFGR_LS_IMSK;
+	__raw_writel(value, CAAM_JRCFGR0_LS);
+
+	/* Enable deco watchdog */
+	setbits_le32(CAAM_MCFGR, BM_MCFGR_WDE);
+
+	return 0;
+}
+
+static void do_clear_rng_error(void)
+{
+	u32 val;
+
+	val = __raw_readl(CAAM_RTMCTL);
+
+	if (val & (RTMCTL_ERR | RTMCTL_FCT_FAIL)) {
+		setbits_le32(CAAM_RTMCTL, RTMCTL_ERR);
+	val = __raw_readl(CAAM_RTMCTL);
+	}
+}
+
+static int do_instantiation(void)
+{
+	int ret = ERROR_ANY;
+	u32 cha_vid_ls;
+	u32 ent_delay;
+	u32 status;
+
+	if (!g_jrdata.desc) {
+		printf("%d: CAAM Descriptor allocation error\n", __LINE__);
+		return ERROR_ANY;
+	}
+
+	cha_vid_ls = __raw_readl(CAAM_CHAVID_LS);
+
+	/*
+	 * If SEC has RNG version >= 4 and RNG state handle has not been
+	 * already instantiated, do RNG instantiation
+	 */
+	if (((cha_vid_ls & BM_CHAVID_LS_RNGVID) >> BS_CHAVID_LS_RNGVID) < 4) {
+		printf("%d: RNG already instantiated\n", __LINE__);
+		return 0;
+	}
+
+	ent_delay = TRNG_SDCTL_ENT_DLY_MIN;
+
+	do {
+		/* Read the CAAM RNG status */
+		status = __raw_readl(CAAM_RDSTA);
+
+		if ((status & RDSTA_IF0) != RDSTA_IF0) {
+			/* Configure the RNG entropy delay */
+			kick_trng(ent_delay);
+			ent_delay += 400;
+		}
+
+		do_clear_rng_error();
+
+		if ((status & (RDSTA_IF0 | RDSTA_IF1)) !=
+				(RDSTA_IF0 | RDSTA_IF1)) {
+			/* Prepare the instantiation descriptor */
+			do_inst_desc(g_jrdata.desc, status);
+
+			/* Run Job */
+			ret = do_job(g_jrdata.desc);
+
+			if (ret == ERROR_ANY) {
+				/* CAAM JR failure ends here */
+				printf("RNG Instantiation error\n");
+				goto end_instantation;
+			}
+		} else {
+			ret = SUCCESS;
+			printf("RNG instantiation done (%d)\n", ent_delay);
+			goto end_instantation;
+		}
+	} while (ent_delay < TRNG_SDCTL_ENT_DLY_MAX);
+
+	printf("RNG Instantation Failure - Entropy delay (%d)\n", ent_delay);
+	ret = ERROR_ANY;
+
+end_instantation:
+	return ret;
+}
+
+static void rng_init(void)
+{
+	int  ret;
+
+	ret = jr_reset();
+	if (ret != SUCCESS) {
+		printf("Error CAAM JR reset\n");
+		return;
+	}
+
+	ret = do_instantiation();
+
+	if (ret != SUCCESS)
+		printf("Error do_instantiation\n");
+
+	jr_reset();
+
+	return;
+}
+
diff --git a/drivers/crypto/fsl_caam_internal.h b/drivers/crypto/fsl_caam_internal.h
new file mode 100644
index 0000000000..837562d3c4
--- /dev/null
+++ b/drivers/crypto/fsl_caam_internal.h
@@ -0,0 +1,229 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2012-2016, Freescale Semiconductor, Inc.
+ * Copyright 2018 NXP
+ */
+
+#ifndef __CAAM_INTERNAL_H__
+#define __CAAM_INTERNAL_H__
+
+/* 4kbyte pages */
+#define CAAM_SEC_RAM_START_ADDR CAAM_ARB_BASE_ADDR
+
+#define SEC_MEM_PAGE0       CAAM_SEC_RAM_START_ADDR
+#define SEC_MEM_PAGE1       (CAAM_SEC_RAM_START_ADDR + 0x1000)
+#define SEC_MEM_PAGE2       (CAAM_SEC_RAM_START_ADDR + 0x2000)
+#define SEC_MEM_PAGE3       (CAAM_SEC_RAM_START_ADDR + 0x3000)
+
+/* Configuration and special key registers */
+#define CAAM_MCFGR          (CONFIG_SYS_FSL_SEC_ADDR + 0x0004)
+#define CAAM_SCFGR          (CONFIG_SYS_FSL_SEC_ADDR + 0x000c)
+#define CAAM_JR0MIDR        (CONFIG_SYS_FSL_SEC_ADDR + 0x0010)
+#define CAAM_JR1MIDR        (CONFIG_SYS_FSL_SEC_ADDR + 0x0018)
+#define CAAM_DECORR         (CONFIG_SYS_FSL_SEC_ADDR + 0x009c)
+#define CAAM_DECO0MID       (CONFIG_SYS_FSL_SEC_ADDR + 0x00a0)
+#define CAAM_DAR            (CONFIG_SYS_FSL_SEC_ADDR + 0x0120)
+#define CAAM_DRR            (CONFIG_SYS_FSL_SEC_ADDR + 0x0124)
+#define CAAM_JDKEKR         (CONFIG_SYS_FSL_SEC_ADDR + 0x0400)
+#define CAAM_TDKEKR         (CONFIG_SYS_FSL_SEC_ADDR + 0x0420)
+#define CAAM_TDSKR          (CONFIG_SYS_FSL_SEC_ADDR + 0x0440)
+#define CAAM_SKNR           (CONFIG_SYS_FSL_SEC_ADDR + 0x04e0)
+#define CAAM_SMSTA          (CONFIG_SYS_FSL_SEC_ADDR + 0x0FB4)
+#define CAAM_STA            (CONFIG_SYS_FSL_SEC_ADDR + 0x0FD4)
+#define CAAM_SMPO_0         (CONFIG_SYS_FSL_SEC_ADDR + 0x1FBC)
+#define CAAM_CHAVID_LS      (CONFIG_SYS_FSL_SEC_ADDR + 0x0FEC)
+#define CAAM_FAR            (CONFIG_SYS_FSL_SEC_ADDR + 0x0FC0)
+#define CAAM_FAMR           (CONFIG_SYS_FSL_SEC_ADDR + 0x0FC8)
+#define CAAM_FADR           (CONFIG_SYS_FSL_SEC_ADDR + 0x0FCC)
+
+/* RNG registers */
+#define CAAM_RTMCTL         (CONFIG_SYS_FSL_SEC_ADDR + 0x0600)
+#define CAAM_RTSCMISC       (CONFIG_SYS_FSL_SEC_ADDR + 0x0604)
+#define CAAM_RTPKRRNG       (CONFIG_SYS_FSL_SEC_ADDR + 0x0608)
+#define CAAM_RTPKRMAX       (CONFIG_SYS_FSL_SEC_ADDR + 0x060C)
+#define CAAM_RTSDCTL        (CONFIG_SYS_FSL_SEC_ADDR + 0x0610)
+#define CAAM_RTFRQMIN       (CONFIG_SYS_FSL_SEC_ADDR + 0x0618)
+#define CAAM_RTFRQMAX       (CONFIG_SYS_FSL_SEC_ADDR + 0x061C)
+#define CAAM_RTSCML         (CONFIG_SYS_FSL_SEC_ADDR + 0x0620)
+#define CAAM_RTSCR1L        (CONFIG_SYS_FSL_SEC_ADDR + 0x0624)
+#define CAAM_RTSCR2L        (CONFIG_SYS_FSL_SEC_ADDR + 0x0628)
+#define CAAM_RTSCR3L        (CONFIG_SYS_FSL_SEC_ADDR + 0x062C)
+#define CAAM_RTSCR4L        (CONFIG_SYS_FSL_SEC_ADDR + 0x0630)
+#define CAAM_RTSCR5L        (CONFIG_SYS_FSL_SEC_ADDR + 0x0634)
+#define CAAM_RTSCR6PL       (CONFIG_SYS_FSL_SEC_ADDR + 0x0638)
+#define CAAM_RTSTATUS       (CONFIG_SYS_FSL_SEC_ADDR + 0x063C)
+#define CAAM_RDSTA          (CONFIG_SYS_FSL_SEC_ADDR + 0x06C0)
+
+/* Job Ring 0 registers */
+#define CAAM_IRBAR0         (CONFIG_SYS_FSL_SEC_ADDR + 0x1004)
+#define CAAM_IRSR0          (CONFIG_SYS_FSL_SEC_ADDR + 0x100c)
+#define CAAM_IRSAR0         (CONFIG_SYS_FSL_SEC_ADDR + 0x1014)
+#define CAAM_IRJAR0         (CONFIG_SYS_FSL_SEC_ADDR + 0x101c)
+#define CAAM_ORBAR0         (CONFIG_SYS_FSL_SEC_ADDR + 0x1024)
+#define CAAM_ORSR0          (CONFIG_SYS_FSL_SEC_ADDR + 0x102c)
+#define CAAM_ORJRR0         (CONFIG_SYS_FSL_SEC_ADDR + 0x1034)
+#define CAAM_ORSFR0         (CONFIG_SYS_FSL_SEC_ADDR + 0x103c)
+#define CAAM_JRSTAR0        (CONFIG_SYS_FSL_SEC_ADDR + 0x1044)
+#define CAAM_JRINTR0        (CONFIG_SYS_FSL_SEC_ADDR + 0x104c)
+#define CAAM_JRCFGR0_MS     (CONFIG_SYS_FSL_SEC_ADDR + 0x1050)
+#define CAAM_JRCFGR0_LS     (CONFIG_SYS_FSL_SEC_ADDR + 0x1054)
+#define CAAM_IRRIR0         (CONFIG_SYS_FSL_SEC_ADDR + 0x105c)
+#define CAAM_ORWIR0         (CONFIG_SYS_FSL_SEC_ADDR + 0x1064)
+#define CAAM_JRCR0          (CONFIG_SYS_FSL_SEC_ADDR + 0x106c)
+#define CAAM_SMCJR0         (CONFIG_SYS_FSL_SEC_ADDR + 0x10f4)
+#define CAAM_SMCSJR0        (CONFIG_SYS_FSL_SEC_ADDR + 0x10fc)
+#define CAAM_SMAPJR0(y)     (CONFIG_SYS_FSL_SEC_ADDR + 0x1104 + y * 16)
+#define CAAM_SMAG2JR0(y)    (CONFIG_SYS_FSL_SEC_ADDR + 0x1108 + y * 16)
+#define CAAM_SMAG1JR0(y)    (CONFIG_SYS_FSL_SEC_ADDR + 0x110C + y * 16)
+#define CAAM_SMAPJR0_PRTN1  (CONFIG_SYS_FSL_SEC_ADDR + 0x1114)
+#define CAAM_SMAG2JR0_PRTN1 (CONFIG_SYS_FSL_SEC_ADDR + 0x1118)
+#define CAAM_SMAG1JR0_PRTN1 (CONFIG_SYS_FSL_SEC_ADDR + 0x111c)
+#define CAAM_SMPO           (CONFIG_SYS_FSL_SEC_ADDR + 0x1fbc)
+
+#define DESC_MAX_SIZE       (0x40)        /* Descriptor max size */
+#define JRCFG_LS_IMSK       (0x01)        /* Interrupt Mask */
+#define JR_MID              (0x02)        /* Matches ROM configuration */
+#define KS_G1               BIT(JR_MID)   /* CAAM only */
+#define PERM                (0x0000B008)  /* Clear on release, lock SMAP,
+					   * lock SMAG and group 1 Blob
+					   */
+
+#define CMD_PAGE_ALLOC      (0x1)
+#define CMD_PAGE_DEALLOC    (0x2)
+#define CMD_PART_DEALLOC    (0x3)
+#define CMD_INQUIRY         (0x5)
+#define PAGE(x)             ((x) << 16)
+#define PARTITION(x)        ((x) << 8)
+
+#define SMCSJR_AERR         (3 << 12)
+#define SMCSJR_CERR         (3 << 14)
+#define CMD_COMPLETE        (3 << 14)
+
+#define SMCSJR_PO           (3 << 6)
+#define PAGE_AVAILABLE      (0)
+#define PAGE_OWNED          (3 << 6)
+
+#define PARTITION_OWNER(x)  (0x3 << ((x) * 2))
+
+#define CAAM_BUSY_MASK      (0x00000001) /* BUSY from status reg */
+#define CAAM_IDLE_MASK      (0x00000002) /* IDLE from status reg */
+#define CAAM_MCFGR_SWRST    BIT(31)      /* CAAM SW reset */
+#define CAAM_MCFGR_DMARST   BIT(28)      /* CAAM DMA reset */
+
+#define JOB_RING_ENTRIES    (1)
+#define JOB_RING_STS        (0xF << 28)
+
+/** OSC_DIV in RNG trim fuses */
+#define RNG_TRIM_OSC_DIV    (0)
+/** ENT_DLY multiplier in RNG trim fuses */
+#define TRNG_SDCTL_ENT_DLY_MIN (3200)
+#define TRNG_SDCTL_ENT_DLY_MAX (4800)
+
+#define RTMCTL_PGM       BIT(16)
+#define RTMCTL_ERR       BIT(12)
+#define RTMCTL_RST       BIT(6)
+#define RDSTA_IF0        (1)
+#define RDSTA_IF1        (2)
+#define RDSTA_SKVN       BIT(30)
+#define JRCR_RESET       (1)
+#define RTMCTL_FCT_FAIL  BIT(8)
+
+#define BS_TRNG_ENT_DLY     (16)
+#define BM_TRNG_ENT_DLY     (0xffff << BS_TRNG_ENT_DLY)
+#define BM_TRNG_SAMP_MODE   (3)
+#define TRNG_SAMP_MODE_RAW_ES_SC (1)
+#define BS_JRINTR_HALT      (2)
+#define BM_JRINTR_HALT      (0x3 << BS_JRINTR_HALT)
+#define JRINTR_HALT_ONGOING (0x1 << BS_JRINTR_HALT)
+#define JRINTR_HALT_DONE    (0x2 << BS_JRINTR_HALT)
+#define JRINTR_JRI          (0x1)
+#define BS_JRCFGR_LS_ICTT   (16)
+#define BM_JRCFGR_LS_ICTT   (0xFFFF << BS_JRCFGR_LS_ICTT)
+#define BS_JRCFGR_LS_ICDCT  (8)
+#define BM_JRCFGR_LS_ICDCT  (0xFF << BS_JRCFGR_LS_ICDCT)
+#define BS_JRCFGR_LS_ICEN   (1)
+#define BM_JRCFGR_LS_ICEN   (0x1 << BS_JRCFGR_LS_ICEN)
+#define BS_JRCFGR_LS_IMSK   (0)
+#define BM_JRCFGR_LS_IMSK   (0x1 << BS_JRCFGR_LS_IMSK)
+#define BS_CHAVID_LS_RNGVID (16)
+#define BM_CHAVID_LS_RNGVID (0xF << BS_CHAVID_LS_RNGVID)
+#define BS_MCFGR_WDE        (30)
+#define BM_MCFGR_WDE        (0x1 << BS_MCFGR_WDE)
+
+typedef enum {
+	PAGE_0,
+	PAGE_1,
+	PAGE_2,
+	PAGE_3,
+} page_num_e;
+
+typedef enum {
+	PARTITION_0,
+	PARTITION_1,
+	PARTITION_2,
+	PARTITION_3,
+	PARTITION_4,
+	PARTITION_5,
+	PARTITION_6,
+	PARTITION_7,
+} partition_num_e;
+
+/*
+ * Local defines
+ */
+/* arm v7 need 64 align */
+#define ALIGN_MASK     ~(ARCH_DMA_MINALIGN - 1)
+/* caam dma and pointer conversion for arm and arm64 architectures */
+#ifdef CONFIG_IMX_CONFIG
+  #define PTR2CAAMDMA(x)  (u32)((uintptr_t)(x) & 0xffffffff)
+  #define CAAMDMA2PTR(x)  (uintptr_t)((x) & 0xffffffff)
+#else
+  #define PTR2CAAMDMA(x)  (uintptr_t)(x)
+  #define CAAMDMA2PTR(x)  (uintptr_t)(x)
+#endif
+#define RING_EARLY_INIT   (0x01)
+#define RING_RELOC_INIT   (0x02)
+
+#define CAAM_HDR_CTYPE            (0x16u << 27)
+#define CAAM_HDR_ONE              BIT(23)
+#define CAAM_HDR_START_INDEX(x)   (((x) & 0x3F) << 16)
+#define CAAM_HDR_DESCLEN(x)       ((x) & 0x3F)
+#define CAAM_PROTOP_CTYPE         (0x10u << 27)
+
+/* State Handle */
+#define BS_ALGO_RNG_SH            (4)
+#define BM_ALGO_RNG_SH            (0x3 << BS_ALGO_RNG_SH)
+#define ALGO_RNG_SH(id)           (((id) << BS_ALGO_RNG_SH) & BM_ALGO_RNG_SH)
+
+/* Secure Key */
+#define BS_ALGO_RNG_SK            (12)
+#define BM_ALGO_RNG_SK            BIT(BS_ALGO_RNG_SK)
+
+/* State */
+#define BS_ALGO_RNG_AS            (2)
+#define BM_ALGO_RNG_AS            (0x3 << BS_ALGO_RNG_AS)
+#define ALGO_RNG_GENERATE         (0x0 << BS_ALGO_RNG_AS)
+#define ALGO_RNG_INSTANTIATE      BIT(BS_ALGO_RNG_AS)
+
+#define CAAM_C1_RNG               ((0x50 << 16) | (2 << 24))
+
+#define BS_JUMP_LOCAL_OFFSET      (0)
+#define BM_JUMP_LOCAL_OFFSET      (0xFF << BS_JUMP_LOCAL_OFFSET)
+
+#define CAAM_C1_JUMP              ((0x14u << 27) | (1 << 25))
+#define CAAM_JUMP_LOCAL           (0 << 20)
+#define CAAM_JUMP_TST_ALL_COND_TRUE (0 << 16)
+#define CAAM_JUMP_OFFSET(off)     (((off) << BS_JUMP_LOCAL_OFFSET) \
+				& BM_JUMP_LOCAL_OFFSET)
+
+#define CAAM_C0_LOAD_IMM          ((0x2 << 27) | (1 << 23))
+#define CAAM_DST_CLEAR_WRITTEN    (0x8 << 16)
+
+#define RNG_DESC_SH0_SIZE   (ARRAY_SIZE(rng_inst_sh0_desc))
+#define RNG_DESC_SH1_SIZE   (ARRAY_SIZE(rng_inst_sh1_desc))
+#define RNG_DESC_KEYS_SIZE  (ARRAY_SIZE(rng_inst_load_keys))
+#define RNG_DESC_MAX_SIZE   (RNG_DESC_SH0_SIZE + \
+			RNG_DESC_SH1_SIZE + \
+			RNG_DESC_KEYS_SIZE)
+
+#endif /* __CAAM_INTERNAL_H__ */
diff --git a/include/fsl_caam.h b/include/fsl_caam.h
new file mode 100644
index 0000000000..c4345ae2b6
--- /dev/null
+++ b/include/fsl_caam.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2012-2016, Freescale Semiconductor, Inc.
+ * Copyright 2018 NXP
+ */
+
+#ifndef __CAAM_H__
+#define	__CAAM_H__
+
+#if !defined(SUCCESS)
+#define SUCCESS (0)
+#endif
+
+#define ERROR_ANY           (-1)
+#define ERROR_IN_PAGE_ALLOC (1)
+
+void caam_open(void);
+
+u32 caam_gen_blob(u32 plain_data_addr, u32 blob_addr, u32 size);
+
+u32 caam_decap_blob(u32 plain_text, u32 blob_addr, u32 size);
+u32 caam_hwrng(uint8_t *output_ptr, u32 output_len);
+
+#endif /* __CAAM_H__ */
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH 32/37] crypto: caam: RNG4 TRNG errata
  2021-03-25  9:29 [PATCH 00/37] imx: hab/caam new feature and update Peng Fan
                   ` (30 preceding siblings ...)
  2021-03-25  9:30 ` [PATCH 31/37] crypto: caam: Add fsl caam driver Peng Fan
@ 2021-03-25  9:30 ` Peng Fan
  2021-03-25  9:30 ` [PATCH 33/37] imx: caam: new u-boot command to set PRIBLOB bitfield from CAAM SCFGR register to 0x3 Peng Fan
                   ` (5 subsequent siblings)
  37 siblings, 0 replies; 42+ messages in thread
From: Peng Fan @ 2021-03-25  9:30 UTC (permalink / raw)
  To: u-boot

From: Aymen Sghaier <aymen.sghaier@nxp.com>

The TRNG as used in RNG4, used in CAAM has a documentation issue. The
effect is that it is possible that the entropy used to instantiate the
DRBG may be old entropy, rather than newly generated entropy. There is
proper programming guidance, but it is not in the documentation.

Signed-off-by: Aymen Sghaier <aymen.sghaier@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 drivers/crypto/fsl_caam.c          | 11 ++++++++---
 drivers/crypto/fsl_caam_internal.h |  1 +
 2 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/crypto/fsl_caam.c b/drivers/crypto/fsl_caam.c
index ccdf131635..092635123d 100644
--- a/drivers/crypto/fsl_caam.c
+++ b/drivers/crypto/fsl_caam.c
@@ -315,7 +315,12 @@ static void kick_trng(u32 ent_delay)
 	u32 val;
 
 	/* Put RNG in program mode */
-	setbits_le32(CAAM_RTMCTL, RTMCTL_PGM);
+	/* Setting both RTMCTL:PRGM and RTMCTL:TRNG_ACC causes TRNG to
+	 * properly invalidate the entropy in the entropy register and
+	 * force re-generation.
+	 */
+	setbits_le32(CAAM_RTMCTL, RTMCTL_PGM | RTMCTL_ACC);
+
 	/* Configure the RNG Entropy Delay
 	 * Performance-wise, it does not make sense to
 	 * set the delay to a value that is lower
@@ -329,7 +334,7 @@ static void kick_trng(u32 ent_delay)
 	val >>= BS_TRNG_ENT_DLY;
 	if (ent_delay < val) {
 		/* Put RNG4 into run mode */
-		clrbits_le32(CAAM_RTMCTL, RTMCTL_PGM);
+		clrbits_le32(CAAM_RTMCTL, RTMCTL_PGM | RTMCTL_ACC);
 		return;
 	}
 
@@ -361,7 +366,7 @@ static void kick_trng(u32 ent_delay)
 	val &= ~BM_TRNG_SAMP_MODE;
 	val |= TRNG_SAMP_MODE_RAW_ES_SC;
 	/* Put RNG4 into run mode */
-	val &= ~RTMCTL_PGM;
+	val &= ~(RTMCTL_PGM | RTMCTL_ACC);
 /*test with sample mode only */
 	__raw_writel(val, CAAM_RTMCTL);
 
diff --git a/drivers/crypto/fsl_caam_internal.h b/drivers/crypto/fsl_caam_internal.h
index 837562d3c4..553bb4cd10 100644
--- a/drivers/crypto/fsl_caam_internal.h
+++ b/drivers/crypto/fsl_caam_internal.h
@@ -122,6 +122,7 @@
 #define RTMCTL_PGM       BIT(16)
 #define RTMCTL_ERR       BIT(12)
 #define RTMCTL_RST       BIT(6)
+#define RTMCTL_ACC       BIT(5)
 #define RDSTA_IF0        (1)
 #define RDSTA_IF1        (2)
 #define RDSTA_SKVN       BIT(30)
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH 33/37] imx: caam: new u-boot command to set PRIBLOB bitfield from CAAM SCFGR register to 0x3
  2021-03-25  9:29 [PATCH 00/37] imx: hab/caam new feature and update Peng Fan
                   ` (31 preceding siblings ...)
  2021-03-25  9:30 ` [PATCH 32/37] crypto: caam: RNG4 TRNG errata Peng Fan
@ 2021-03-25  9:30 ` Peng Fan
  2021-03-25  9:30 ` [PATCH 34/37] imx8m: Add DEK blob encapsulation for imx8m Peng Fan
                   ` (4 subsequent siblings)
  37 siblings, 0 replies; 42+ messages in thread
From: Peng Fan @ 2021-03-25  9:30 UTC (permalink / raw)
  To: u-boot

From: Clement Le Marquis <clement.lemarquis@nxp.com>

It is highly recommended to set the PRIBLOB bitfield to 0x3 once your
encrypted boot image has booted up, this prevents the generation of new
blobs that can be used to decrypt an encrypted boot image. The PRIBLOB is
a sticky type bit and cannot be changed until the next power on reset.

Add the set_priblob_bitfield U-Boot command to prevent the generation of
new blobs.

Signed-off-by: Clement Le Marquis <clement.lemarquis@nxp.com>
Acked-by: Ye Li <Ye.Li@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 arch/arm/mach-imx/Kconfig   |  7 +++++++
 arch/arm/mach-imx/Makefile  |  1 +
 arch/arm/mach-imx/priblob.c | 33 +++++++++++++++++++++++++++++++++
 3 files changed, 41 insertions(+)
 create mode 100644 arch/arm/mach-imx/priblob.c

diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index ca06c1eaaf..27b0b081ad 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -81,6 +81,13 @@ config CMD_DEKBLOB
 	  creates a blob of data. See also CMD_BLOB and doc/imx/habv4/* for
 	  more information.
 
+config CMD_PRIBLOB
+	bool "Support the set_priblob_bitfield command"
+	depends on HAS_CAAM && IMX_HAB
+	help
+	  This option enables the priblob command which can be used
+		to set the priblob setting to 0x3.
+
 config CMD_HDMIDETECT
 	bool "Support the 'hdmidet' command"
 	help
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index 63b3549d20..82aa39dee7 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -30,6 +30,7 @@ obj-$(CONFIG_SYS_I2C_MXC) += i2c-mxv7.o
 endif
 ifeq ($(SOC),$(filter $(SOC),mx7 mx6 mxs imx8m imx8 imxrt))
 obj-y	+= misc.o
+obj-$(CONFIG_CMD_PRIBLOB) += priblob.o
 obj-$(CONFIG_SPL_BUILD)	+= spl.o
 endif
 ifeq ($(SOC),$(filter $(SOC),mx7))
diff --git a/arch/arm/mach-imx/priblob.c b/arch/arm/mach-imx/priblob.c
new file mode 100644
index 0000000000..e253eddfdc
--- /dev/null
+++ b/arch/arm/mach-imx/priblob.c
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2018 NXP
+ */
+
+/*
+ * Boot command to get and set the PRIBLOB bitfield form the SCFGR register
+ * of the CAAM IP. It is recommended to set this bitfield to 3 once your
+ * encrypted boot image is ready, to prevent the generation of blobs usable
+ * to decrypt an encrypted boot image.
+ */
+
+#include <asm/io.h>
+#include <common.h>
+#include <command.h>
+#include "../drivers/crypto/fsl_caam_internal.h"
+
+int do_priblob_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	writel((readl(CAAM_SCFGR) & 0xFFFFFFFC) | 3, CAAM_SCFGR);
+	printf("New priblob setting = 0x%x\n", readl(CAAM_SCFGR) & 0x3);
+
+	return 0;
+}
+
+U_BOOT_CMD(
+	set_priblob_bitfield, 1, 0, do_priblob_write,
+	"Set the PRIBLOB bitfield to 3",
+	"<value>\n"
+	"    - Write 3 in PRIBLOB bitfield of SCFGR regiter of CAAM IP.\n"
+	"    Prevent the generation of blobs usable to decrypt an\n"
+	"    encrypted boot image."
+);
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH 34/37] imx8m: Add DEK blob encapsulation for imx8m
  2021-03-25  9:29 [PATCH 00/37] imx: hab/caam new feature and update Peng Fan
                   ` (32 preceding siblings ...)
  2021-03-25  9:30 ` [PATCH 33/37] imx: caam: new u-boot command to set PRIBLOB bitfield from CAAM SCFGR register to 0x3 Peng Fan
@ 2021-03-25  9:30 ` Peng Fan
  2021-03-25  9:30 ` [PATCH 35/37] imx8: Add DEK blob encapsulation Peng Fan
                   ` (3 subsequent siblings)
  37 siblings, 0 replies; 42+ messages in thread
From: Peng Fan @ 2021-03-25  9:30 UTC (permalink / raw)
  To: u-boot

From: Clement Faure <clement.faure@nxp.com>

Add DEK blob encapsulation support for IMX8M through "dek_blob" command.
On ARMv8, u-boot runs in non-secure, thus cannot encapsulate a DEK blob
for encrypted boot.
The DEK blob is encapsulated by OP-TEE through a trusted application call.
U-boot sends and receives the DEK and the DEK blob binaries through OP-TEE
dynamic shared memory.

To enable the DEK blob encapsulation, add to the defconfig:
CONFIG_SECURE_BOOT=y
CONFIG_FAT_WRITE=y
CONFIG_CMD_DEKBLOB=y

Signed-off-by: Clement Faure <clement.faure@nxp.com>
Reviewed-by: Ye Li <ye.li@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 arch/arm/dts/imx8mm-evk-u-boot.dtsi      |   7 ++
 arch/arm/dts/imx8mn-ddr4-evk-u-boot.dtsi |   6 ++
 arch/arm/dts/imx8mp-evk-u-boot.dtsi      |   6 ++
 arch/arm/mach-imx/Kconfig                |  17 ++++
 arch/arm/mach-imx/cmd_dek.c              | 100 ++++++++++++++++++++---
 drivers/crypto/fsl/Makefile              |   3 +-
 include/fsl_sec.h                        |   4 +-
 7 files changed, 128 insertions(+), 15 deletions(-)

diff --git a/arch/arm/dts/imx8mm-evk-u-boot.dtsi b/arch/arm/dts/imx8mm-evk-u-boot.dtsi
index 7f48912b49..6d204526af 100644
--- a/arch/arm/dts/imx8mm-evk-u-boot.dtsi
+++ b/arch/arm/dts/imx8mm-evk-u-boot.dtsi
@@ -9,6 +9,13 @@
 		wdt = <&wdog1>;
 		u-boot,dm-spl;
 	};
+
+	firmware {
+		optee {
+			compatible = "linaro,optee-tz";
+			method = "smc";
+		};
+	};
 };
 
 &{/soc at 0} {
diff --git a/arch/arm/dts/imx8mn-ddr4-evk-u-boot.dtsi b/arch/arm/dts/imx8mn-ddr4-evk-u-boot.dtsi
index 8cd15be7a8..a0fd2a3098 100644
--- a/arch/arm/dts/imx8mn-ddr4-evk-u-boot.dtsi
+++ b/arch/arm/dts/imx8mn-ddr4-evk-u-boot.dtsi
@@ -9,6 +9,12 @@
 		wdt = <&wdog1>;
 		u-boot,dm-spl;
 	};
+	firmware {
+		optee {
+			compatible = "linaro,optee-tz";
+			method = "smc";
+		};
+	};
 };
 
 &{/soc at 0} {
diff --git a/arch/arm/dts/imx8mp-evk-u-boot.dtsi b/arch/arm/dts/imx8mp-evk-u-boot.dtsi
index 6a91404d7b..27075c5217 100644
--- a/arch/arm/dts/imx8mp-evk-u-boot.dtsi
+++ b/arch/arm/dts/imx8mp-evk-u-boot.dtsi
@@ -9,6 +9,12 @@
 		wdt = <&wdog1>;
 		u-boot,dm-spl;
 	};
+	firmware {
+		optee {
+			compatible = "linaro,optee-tz";
+			method = "smc";
+		};
+	};
 };
 
 &{/soc at 0} {
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 27b0b081ad..3bcfced8f0 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -75,12 +75,29 @@ config CMD_BMODE
 
 config CMD_DEKBLOB
 	bool "Support the 'dek_blob' command"
+	select IMX_CAAM_DEK_ENCAP if ARCH_MX6 || ARCH_MX7 || ARCH_MX7ULP
+	select IMX_OPTEE_DEK_ENCAP if ARCH_IMX8M
 	help
 	  This enables the 'dek_blob' command which is used with the
 	  Freescale secure boot mechanism. This command encapsulates and
 	  creates a blob of data. See also CMD_BLOB and doc/imx/habv4/* for
 	  more information.
 
+config IMX_CAAM_DEK_ENCAP
+	bool "Support the DEK blob encapsulation with CAAM U-Boot driver"
+	help
+	  This enables the DEK blob encapsulation with the U-Boot CAAM driver.
+	  This option is only available on imx6, imx7 and imx7ulp.
+
+config IMX_OPTEE_DEK_ENCAP
+	select TEE
+	select OPTEE
+	bool "Support the DEK blob encapsulation with OP-TEE"
+	help
+	  This enabled the DEK blob encapsulation with OP-TEE. The communication
+	  with OP-TEE is done through a SMC call and OP-TEE shared memory. This
+	  option is available on imx8mm.
+
 config CMD_PRIBLOB
 	bool "Support the set_priblob_bitfield command"
 	depends on HAS_CAAM && IMX_HAB
diff --git a/arch/arm/mach-imx/cmd_dek.c b/arch/arm/mach-imx/cmd_dek.c
index bd380429c0..75aec2cef0 100644
--- a/arch/arm/mach-imx/cmd_dek.c
+++ b/arch/arm/mach-imx/cmd_dek.c
@@ -14,6 +14,7 @@
 #include <fsl_sec.h>
 #include <asm/arch/clock.h>
 #include <mapmem.h>
+#include <tee.h>
 
 /**
 * blob_dek() - Encapsulate the DEK as a blob using CAM's Key
@@ -23,9 +24,13 @@
 *
 * Returns zero on success,and negative on error.
 */
-static int blob_encap_dek(const u8 *src, u8 *dst, u32 len)
+#ifdef CONFIG_IMX_CAAM_DEK_ENCAP
+static int blob_encap_dek(u32 src_addr, u32 dst_addr, u32 len)
 {
-	int ret = 0;
+	u8 *src_ptr, *dst_ptr;
+
+	src_ptr = map_sysmem(src_addr, len / 8);
+	dst_ptr = map_sysmem(dst_addr, BLOB_SIZE(len / 8));
 
 	hab_caam_clock_enable(1);
 
@@ -40,10 +45,90 @@ static int blob_encap_dek(const u8 *src, u8 *dst, u32 len)
 	}
 
 	len /= 8;
-	ret = blob_dek(src, dst, len);
+	return blob_dek(src_ptr, dst_ptr, len);
+}
+#endif /* CONFIG_IMX_CAAM_DEK_ENCAP */
+
+#ifdef CONFIG_IMX_OPTEE_DEK_ENCAP
+
+#define PTA_DEK_BLOB_PTA_UUID {0xef477737, 0x0db1, 0x4a9d, \
+	{0x84, 0x37, 0xf2, 0xf5, 0x35, 0xc0, 0xbd, 0x92} }
+
+#define OPTEE_BLOB_HDR_SIZE		8
+
+static int blob_encap_dek(u32 src_addr, u32 dst_addr, u32 len)
+{
+	struct udevice *dev = NULL;
+	struct tee_shm *shm_input, *shm_output;
+	struct tee_open_session_arg arg = {0};
+	struct tee_invoke_arg arg_func = {0};
+	const struct tee_optee_ta_uuid uuid = PTA_DEK_BLOB_PTA_UUID;
+	struct tee_param param[4] = {0};
+	int ret;
+
+	/* Get tee device */
+	dev = tee_find_device(NULL, NULL, NULL, NULL);
+	if (!dev) {
+		printf("Cannot get OP-TEE device\n");
+		return -1;
+	}
+
+	/* Set TA UUID */
+	tee_optee_ta_uuid_to_octets(arg.uuid, &uuid);
+
+	/* Open TA session */
+	ret = tee_open_session(dev, &arg, 0, NULL);
+	if (ret < 0) {
+		printf("Cannot open session with PTA Blob 0x%X\n", ret);
+		return -1;
+	}
+
+	/* Allocate shared input and output buffers for TA */
+	ret = tee_shm_register(dev, (void *)(ulong)src_addr, len / 8, 0x0, &shm_input);
+	if (ret < 0) {
+		printf("Cannot register input shared memory 0x%X\n", ret);
+		goto error;
+	}
+
+	ret = tee_shm_register(dev, (void *)(ulong)dst_addr,
+			       BLOB_SIZE(len / 8) + OPTEE_BLOB_HDR_SIZE,
+			       0x0, &shm_output);
+	if (ret < 0) {
+		printf("Cannot register output shared memory 0x%X\n", ret);
+		goto error;
+	}
+
+	param[0].u.memref.shm	= shm_input;
+	param[0].u.memref.size	= shm_input->size;
+	param[0].attr		= TEE_PARAM_ATTR_TYPE_MEMREF_INPUT;
+	param[1].u.memref.shm	= shm_output;
+	param[1].u.memref.size	= shm_output->size;
+	param[1].attr		= TEE_PARAM_ATTR_TYPE_MEMREF_OUTPUT;
+	param[2].attr		= TEE_PARAM_ATTR_TYPE_NONE;
+	param[3].attr		= TEE_PARAM_ATTR_TYPE_NONE;
+
+	arg_func.func = 0;
+	arg_func.session = arg.session;
+
+	/* Generate DEK blob */
+	arg_func.session = arg.session;
+	ret = tee_invoke_func(dev, &arg_func, 4, param);
+	if (ret < 0)
+		printf("Cannot generate Blob with PTA DEK Blob 0x%X\n", ret);
+
+error:
+	/* Free shared memory */
+	tee_shm_free(shm_input);
+	tee_shm_free(shm_output);
+
+	/* Close session */
+	ret = tee_close_session(dev, arg.session);
+	if (ret < 0)
+		printf("Cannot close session with PTA DEK Blob 0x%X\n", ret);
 
 	return ret;
 }
+#endif /* CONFIG_IMX_OPTEE_DEK_ENCAP */
 
 /**
  * do_dek_blob() - Handle the "dek_blob" command-line command
@@ -59,8 +144,6 @@ static int do_dek_blob(struct cmd_tbl *cmdtp, int flag, int argc,
 		       char *const argv[])
 {
 	uint32_t src_addr, dst_addr, len;
-	uint8_t *src_ptr, *dst_ptr;
-	int ret = 0;
 
 	if (argc != 4)
 		return CMD_RET_USAGE;
@@ -69,12 +152,7 @@ static int do_dek_blob(struct cmd_tbl *cmdtp, int flag, int argc,
 	dst_addr = simple_strtoul(argv[2], NULL, 16);
 	len = simple_strtoul(argv[3], NULL, 10);
 
-	src_ptr = map_sysmem(src_addr, len/8);
-	dst_ptr = map_sysmem(dst_addr, BLOB_SIZE(len/8));
-
-	ret = blob_encap_dek(src_ptr, dst_ptr, len);
-
-	return ret;
+	return blob_encap_dek(src_addr, dst_addr, len);
 }
 
 /***************************************************/
diff --git a/drivers/crypto/fsl/Makefile b/drivers/crypto/fsl/Makefile
index eb689c1b9f..f9c3ccecfc 100644
--- a/drivers/crypto/fsl/Makefile
+++ b/drivers/crypto/fsl/Makefile
@@ -4,8 +4,7 @@
 
 obj-y += sec.o
 obj-$(CONFIG_FSL_CAAM) += jr.o fsl_hash.o jobdesc.o error.o
-obj-$(CONFIG_CMD_BLOB) += fsl_blob.o
-obj-$(CONFIG_CMD_DEKBLOB) += fsl_blob.o
+obj-$(CONFIG_CMD_BLOB)$(CONFIG_IMX_CAAM_DEK_ENCAP) += fsl_blob.o
 obj-$(CONFIG_RSA_FREESCALE_EXP) += fsl_rsa.o
 obj-$(CONFIG_FSL_CAAM_RNG) += rng.o
 obj-$(CONFIG_FSL_MFGPROT) += fsl_mfgprot.o
diff --git a/include/fsl_sec.h b/include/fsl_sec.h
index 09ce916297..c4121696f8 100644
--- a/include/fsl_sec.h
+++ b/include/fsl_sec.h
@@ -28,6 +28,8 @@
 #error Neither CONFIG_SYS_FSL_SEC_LE nor CONFIG_SYS_FSL_SEC_BE is defined
 #endif
 
+#define BLOB_SIZE(x)		((x) + 32 + 16) /* Blob buffer size */
+
 /* Security Engine Block (MS = Most Sig., LS = Least Sig.) */
 #if CONFIG_SYS_FSL_SEC_COMPAT >= 4
 /* RNG4 TRNG test registers */
@@ -265,8 +267,6 @@ struct sg_entry {
 #define SG_ENTRY_OFFSET_SHIFT	0
 };
 
-#define BLOB_SIZE(x)		((x) + 32 + 16) /* Blob buffer size */
-
 #if defined(CONFIG_MX6) || defined(CONFIG_MX7) || \
 	defined(CONFIG_MX7ULP) || defined(CONFIG_IMX8M)
 /* Job Ring Base Address */
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH 35/37] imx8: Add DEK blob encapsulation
  2021-03-25  9:29 [PATCH 00/37] imx: hab/caam new feature and update Peng Fan
                   ` (33 preceding siblings ...)
  2021-03-25  9:30 ` [PATCH 34/37] imx8m: Add DEK blob encapsulation for imx8m Peng Fan
@ 2021-03-25  9:30 ` Peng Fan
  2021-03-25  9:30 ` [PATCH 36/37] fsl_mfgprot: Fix typo in sign_mppubk() Peng Fan
                   ` (2 subsequent siblings)
  37 siblings, 0 replies; 42+ messages in thread
From: Peng Fan @ 2021-03-25  9:30 UTC (permalink / raw)
  To: u-boot

From: Clement Faure <clement.faure@nxp.com>

Add DEK encapsulation support for imx8. The DEK blob is generated by the
SECO through the SCFW API.

Signed-off-by: Clement Faure <clement.faure@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 arch/arm/include/asm/arch-imx8/image.h |  11 ++
 arch/arm/mach-imx/Kconfig              |   7 ++
 arch/arm/mach-imx/cmd_dek.c            | 152 +++++++++++++++++++++++++
 arch/arm/mach-imx/imx8/Kconfig         |   1 +
 4 files changed, 171 insertions(+)

diff --git a/arch/arm/include/asm/arch-imx8/image.h b/arch/arm/include/asm/arch-imx8/image.h
index c1e5700859..547beeb986 100644
--- a/arch/arm/include/asm/arch-imx8/image.h
+++ b/arch/arm/include/asm/arch-imx8/image.h
@@ -53,4 +53,15 @@ struct signature_block_hdr {
 	u16 signature_offset;
 	u32 reserved;
 } __packed;
+
+struct generate_key_blob_hdr {
+	u8 version;
+	u8 length_lsb;
+	u8 length_msb;
+	u8 tag;
+	u8 flags;
+	u8 size;
+	u8 algorithm;
+	u8 mode;
+} __packed;
 #endif
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 3bcfced8f0..26bfc5ccc4 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -77,6 +77,7 @@ config CMD_DEKBLOB
 	bool "Support the 'dek_blob' command"
 	select IMX_CAAM_DEK_ENCAP if ARCH_MX6 || ARCH_MX7 || ARCH_MX7ULP
 	select IMX_OPTEE_DEK_ENCAP if ARCH_IMX8M
+	select IMX_SECO_DEK_ENCAP if ARCH_IMX8
 	help
 	  This enables the 'dek_blob' command which is used with the
 	  Freescale secure boot mechanism. This command encapsulates and
@@ -98,6 +99,12 @@ config IMX_OPTEE_DEK_ENCAP
 	  with OP-TEE is done through a SMC call and OP-TEE shared memory. This
 	  option is available on imx8mm.
 
+config IMX_SECO_DEK_ENCAP
+	bool "Support the DEK blob encapsulation with SECO"
+	help
+	  This enabled the DEK blob encapsulation with the SECO API. This option
+	  is only available on imx8.
+
 config CMD_PRIBLOB
 	bool "Support the set_priblob_bitfield command"
 	depends on HAS_CAAM && IMX_HAB
diff --git a/arch/arm/mach-imx/cmd_dek.c b/arch/arm/mach-imx/cmd_dek.c
index 75aec2cef0..b10ead1942 100644
--- a/arch/arm/mach-imx/cmd_dek.c
+++ b/arch/arm/mach-imx/cmd_dek.c
@@ -15,6 +15,11 @@
 #include <asm/arch/clock.h>
 #include <mapmem.h>
 #include <tee.h>
+#ifdef CONFIG_IMX_SECO_DEK_ENCAP
+#include <asm/arch/sci/sci.h>
+#include <asm/arch/image.h>
+#endif
+#include <cpu_func.h>
 
 /**
 * blob_dek() - Encapsulate the DEK as a blob using CAM's Key
@@ -129,6 +134,153 @@ error:
 	return ret;
 }
 #endif /* CONFIG_IMX_OPTEE_DEK_ENCAP */
+#ifdef CONFIG_IMX_SECO_DEK_ENCAP
+
+#define DEK_BLOB_KEY_ID				0x0
+
+#define AHAB_PRIVATE_KEY			0x81
+#define AHAB_VERSION				0x00
+#define AHAB_MODE_CBC				0x67
+#define AHAB_ALG_AES				0x55
+#define AHAB_128_AES_KEY			0x10
+#define AHAB_192_AES_KEY			0x18
+#define AHAB_256_AES_KEY			0x20
+#define AHAB_FLAG_KEK				0x80
+#define AHAB_DEK_BLOB				0x01
+
+#define DEK_BLOB_HDR_SIZE			8
+#define SECO_PT					2U
+
+static int blob_encap_dek(u32 src_addr, u32 dst_addr, u32 len)
+{
+	sc_err_t err;
+	sc_rm_mr_t mr_input, mr_output;
+	struct generate_key_blob_hdr hdr;
+	u8 in_size, out_size;
+	u8 *src_ptr, *dst_ptr;
+	int ret = 0;
+	int i;
+
+	/* Set sizes */
+	in_size = sizeof(struct generate_key_blob_hdr) + len / 8;
+	out_size = BLOB_SIZE(len / 8) + DEK_BLOB_HDR_SIZE;
+
+	/* Get src and dst virtual addresses */
+	src_ptr = map_sysmem(src_addr, in_size);
+	dst_ptr = map_sysmem(dst_addr, out_size);
+
+	/* Check addr input */
+	if (!(src_ptr && dst_ptr)) {
+		debug("src_addr or dst_addr invalid\n");
+		return -1;
+	}
+
+	/* Build key header */
+	hdr.version = AHAB_VERSION;
+	hdr.length_lsb = sizeof(struct generate_key_blob_hdr) + len / 8;
+	hdr.length_msb = 0x00;
+	hdr.tag = AHAB_PRIVATE_KEY;
+	hdr.flags = AHAB_DEK_BLOB;
+	hdr.algorithm = AHAB_ALG_AES;
+	hdr.mode = AHAB_MODE_CBC;
+
+	switch (len) {
+	case 128:
+		hdr.size = AHAB_128_AES_KEY;
+		break;
+	case 192:
+		hdr.size = AHAB_192_AES_KEY;
+		break;
+	case 256:
+		hdr.size = AHAB_256_AES_KEY;
+		break;
+	default:
+		/* Not supported */
+		debug("Invalid DEK size. Valid sizes are 128, 192 and 256b\n");
+		return -1;
+	}
+
+	/* Build input message */
+	memmove((void *)(src_ptr + sizeof(struct generate_key_blob_hdr)),
+		(void *)src_ptr, len / 8);
+	memcpy((void *)src_ptr, (void *)&hdr,
+	       sizeof(struct generate_key_blob_hdr));
+
+	/* Flush the cache before triggering the CAAM DMA */
+	flush_dcache_range(src_addr, src_addr + in_size);
+
+	/* Find input memory region */
+	err = sc_rm_find_memreg((-1), &mr_input, src_addr & ~(CONFIG_SYS_CACHELINE_SIZE - 1),
+				ALIGN(src_addr + in_size, CONFIG_SYS_CACHELINE_SIZE));
+	if (err) {
+		printf("Error: find memory region 0x%X\n", src_addr);
+		return -ENOMEM;
+	}
+
+	/* Find output memory region */
+	err = sc_rm_find_memreg((-1), &mr_output, dst_addr & ~(CONFIG_SYS_CACHELINE_SIZE - 1),
+				ALIGN(dst_addr + out_size, CONFIG_SYS_CACHELINE_SIZE));
+	if (err) {
+		printf("Error: find memory region 0x%X\n", dst_addr);
+		return -ENOMEM;
+	}
+
+	/* Set memory region permissions for SECO */
+	err = sc_rm_set_memreg_permissions(-1, mr_input, SECO_PT,
+					   SC_RM_PERM_FULL);
+	if (err) {
+		printf("Set permission failed for input memory region\n");
+		ret = -EPERM;
+		goto error;
+	}
+
+	err = sc_rm_set_memreg_permissions(-1, mr_output, SECO_PT,
+					   SC_RM_PERM_FULL);
+	if (err) {
+		printf("Set permission failed for output memory region\n");
+		ret = -EPERM;
+		goto error;
+	}
+
+	/* Flush output data before SECO operation */
+	flush_dcache_range((ulong)dst_ptr, (ulong)(dst_ptr +
+			roundup(out_size, ARCH_DMA_MINALIGN)));
+
+	/* Generate DEK blob */
+	err = sc_seco_gen_key_blob((-1), 0x0, src_addr, dst_addr, out_size);
+	if (err) {
+		ret = -EPERM;
+		goto error;
+	}
+
+	/* Invalidate output buffer */
+	invalidate_dcache_range((ulong)dst_ptr, (ulong)(dst_ptr +
+			roundup(out_size, ARCH_DMA_MINALIGN)));
+
+	printf("DEK Blob\n");
+	for (i = 0; i < DEK_BLOB_HDR_SIZE + BLOB_SIZE(len / 8); i++)
+		printf("%02X", dst_ptr[i]);
+	printf("\n");
+
+error:
+	/* Remove memory region permission to SECO */
+	err = sc_rm_set_memreg_permissions(-1, mr_input, SECO_PT,
+					   SC_RM_PERM_NONE);
+	if (err) {
+		printf("Error: remove permission failed for input\n");
+		ret = -EPERM;
+	}
+
+	err = sc_rm_set_memreg_permissions(-1, mr_output, SECO_PT,
+					   SC_RM_PERM_NONE);
+	if (err) {
+		printf("Error: remove permission failed for output\n");
+		ret = -EPERM;
+	}
+
+	return ret;
+}
+#endif /* CONFIG_IMX_SECO_DEK_ENCAP */
 
 /**
  * do_dek_blob() - Handle the "dek_blob" command-line command
diff --git a/arch/arm/mach-imx/imx8/Kconfig b/arch/arm/mach-imx/imx8/Kconfig
index 04b9729109..4e76612d05 100644
--- a/arch/arm/mach-imx/imx8/Kconfig
+++ b/arch/arm/mach-imx/imx8/Kconfig
@@ -2,6 +2,7 @@ if ARCH_IMX8
 
 config AHAB_BOOT
 	bool "Support i.MX8 AHAB features"
+	imply CMD_DEKBLOB
 	help
 	  This option enables the support for AHAB secure boot.
 
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH 36/37] fsl_mfgprot: Fix typo in sign_mppubk()
  2021-03-25  9:29 [PATCH 00/37] imx: hab/caam new feature and update Peng Fan
                   ` (34 preceding siblings ...)
  2021-03-25  9:30 ` [PATCH 35/37] imx8: Add DEK blob encapsulation Peng Fan
@ 2021-03-25  9:30 ` Peng Fan
  2021-03-25  9:30 ` [PATCH 37/37] crypto: fsl: refactor for 32 bit version CAAM support on ARM64 Peng Fan
  2021-03-31 12:32 ` [PATCH 00/37] imx: hab/caam new feature and update Horia Geantă
  37 siblings, 0 replies; 42+ messages in thread
From: Peng Fan @ 2021-03-25  9:30 UTC (permalink / raw)
  To: u-boot

From: Breno Lima <breno.lima@nxp.com>

The signature is generated using manufacturing protection private key.

Fix typo in fsl_mfgprot.c.

Signed-off-by: Breno Lima <breno.lima@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 drivers/crypto/fsl/fsl_mfgprot.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/crypto/fsl/fsl_mfgprot.c b/drivers/crypto/fsl/fsl_mfgprot.c
index fa874e7a9b..29af79f577 100644
--- a/drivers/crypto/fsl/fsl_mfgprot.c
+++ b/drivers/crypto/fsl/fsl_mfgprot.c
@@ -138,7 +138,7 @@ int sign_mppubk(const u8 *m, int data_size, u8 *dgst, u8 *c, u8 *d)
 	flush_dcache_range((unsigned long)d, (unsigned long)d + size);
 
 	/* Execute Job Descriptor */
-	puts("\nSigning message with Manufacturing Protection Public Key\n");
+	puts("\nSigning message with Manufacturing Protection Private Key\n");
 
 	ret = run_descriptor_jr(dsc);
 	if (ret) {
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH 37/37] crypto: fsl: refactor for 32 bit version CAAM support on ARM64
  2021-03-25  9:29 [PATCH 00/37] imx: hab/caam new feature and update Peng Fan
                   ` (35 preceding siblings ...)
  2021-03-25  9:30 ` [PATCH 36/37] fsl_mfgprot: Fix typo in sign_mppubk() Peng Fan
@ 2021-03-25  9:30 ` Peng Fan
  2021-03-31 12:32 ` [PATCH 00/37] imx: hab/caam new feature and update Horia Geantă
  37 siblings, 0 replies; 42+ messages in thread
From: Peng Fan @ 2021-03-25  9:30 UTC (permalink / raw)
  To: u-boot

From: Ye Li <ye.li@nxp.com>

Previous patch "MLK-18044-4: crypto: caam: Fix pointer size to 32bit
for i.MX8M" breaks the 64 bits CAAM.

Since i.MX CAAM are all 32 bits no matter the ARM arch (32 or 64),
to adapt and not break 64 bits CAAM support,  add a new config
CONFIG_CAAM_64BIT and new relevant type "caam_dma_addr_t".

This config is default enabled when CONFIG_PHYS_64BIT is set except
for iMX8M.

Signed-off-by: Ye Li <ye.li@nxp.com>
Reviewed-by: Horia Geant? <horia.geanta@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 drivers/crypto/fsl/Kconfig       |  6 ++++
 drivers/crypto/fsl/desc.h        | 48 +++++++++++++++++---------------
 drivers/crypto/fsl/desc_constr.h | 29 ++++++++++---------
 drivers/crypto/fsl/fsl_hash.c    |  7 ++---
 drivers/crypto/fsl/jobdesc.c     | 13 ++++-----
 drivers/crypto/fsl/jr.c          | 36 ++++++++++++------------
 drivers/crypto/fsl/jr.h          | 10 +++----
 drivers/crypto/fsl/type.h        | 16 +++++++++++
 8 files changed, 93 insertions(+), 72 deletions(-)
 create mode 100644 drivers/crypto/fsl/type.h

diff --git a/drivers/crypto/fsl/Kconfig b/drivers/crypto/fsl/Kconfig
index 5ed6140da3..1f5dfb94bb 100644
--- a/drivers/crypto/fsl/Kconfig
+++ b/drivers/crypto/fsl/Kconfig
@@ -7,6 +7,12 @@ config FSL_CAAM
 	  Module (CAAM), also known as the SEC version 4 (SEC4). The driver uses
 	  Job Ring as interface to communicate with CAAM.
 
+config CAAM_64BIT
+	bool
+	default y if PHYS_64BIT && !ARCH_IMX8M
+	help
+	  Select Crypto driver for 64 bits CAAM version
+
 config SYS_FSL_HAS_SEC
 	bool
 	help
diff --git a/drivers/crypto/fsl/desc.h b/drivers/crypto/fsl/desc.h
index 9d1ae059a7..5705c4f944 100644
--- a/drivers/crypto/fsl/desc.h
+++ b/drivers/crypto/fsl/desc.h
@@ -11,6 +11,8 @@
 #ifndef DESC_H
 #define DESC_H
 
+#include "type.h"
+
 #define KEY_BLOB_SIZE		32
 #define MAC_SIZE			16
 
@@ -693,29 +695,29 @@
 /* Structures for Protocol Data Blocks */
 struct __packed pdb_ecdsa_verify {
 	uint32_t pdb_hdr;
-	dma_addr_t dma_q;	/* Pointer to q (elliptic curve) */
-	dma_addr_t dma_r;	/* Pointer to r (elliptic curve) */
-	dma_addr_t dma_g_xy;	/* Pointer to Gx,y (elliptic curve) */
-	dma_addr_t dma_pkey;	/* Pointer to Wx,y (public key) */
-	dma_addr_t dma_hash;	/* Pointer to hash input */
-	dma_addr_t dma_c;	/* Pointer to C_signature */
-	dma_addr_t dma_d;	/* Pointer to D_signature */
-	dma_addr_t dma_buf;	/* Pointer to 64-byte temp buffer */
-	dma_addr_t dma_ab;	/* Pointer to a,b (elliptic curve ) */
+	caam_dma_addr_t dma_q;	/* Pointer to q (elliptic curve) */
+	caam_dma_addr_t dma_r;	/* Pointer to r (elliptic curve) */
+	caam_dma_addr_t dma_g_xy;	/* Pointer to Gx,y (elliptic curve) */
+	caam_dma_addr_t dma_pkey;	/* Pointer to Wx,y (public key) */
+	caam_dma_addr_t dma_hash;	/* Pointer to hash input */
+	caam_dma_addr_t dma_c;	/* Pointer to C_signature */
+	caam_dma_addr_t dma_d;	/* Pointer to D_signature */
+	caam_dma_addr_t dma_buf;	/* Pointer to 64-byte temp buffer */
+	caam_dma_addr_t dma_ab;	/* Pointer to a,b (elliptic curve ) */
 	uint32_t img_size;	/* Length of Message */
 };
 
 struct __packed pdb_ecdsa_sign {
 	uint32_t pdb_hdr;
-	dma_addr_t dma_q;	/* Pointer to q (elliptic curve) */
-	dma_addr_t dma_r;	/* Pointer to r (elliptic curve) */
-	dma_addr_t dma_g_xy;	/* Pointer to Gx,y (elliptic curve) */
-	dma_addr_t dma_pri_key;	/* Pointer to S (Private key) */
-	dma_addr_t dma_hash;	/* Pointer to hash input */
-	dma_addr_t dma_c;	/* Pointer to C_signature */
-	dma_addr_t dma_d;	/* Pointer to D_signature */
-	dma_addr_t dma_ab;	/* Pointer to a,b (elliptic curve ) */
-	dma_addr_t dma_u;	/* Pointer to Per Message Random */
+	caam_dma_addr_t dma_q;	/* Pointer to q (elliptic curve) */
+	caam_dma_addr_t dma_r;	/* Pointer to r (elliptic curve) */
+	caam_dma_addr_t dma_g_xy;	/* Pointer to Gx,y (elliptic curve) */
+	caam_dma_addr_t dma_pri_key;	/* Pointer to S (Private key) */
+	caam_dma_addr_t dma_hash;	/* Pointer to hash input */
+	caam_dma_addr_t dma_c;	/* Pointer to C_signature */
+	caam_dma_addr_t dma_d;	/* Pointer to D_signature */
+	caam_dma_addr_t dma_ab;	/* Pointer to a,b (elliptic curve ) */
+	caam_dma_addr_t dma_u;	/* Pointer to Per Message Random */
 	uint32_t img_size;	/* Length of Message */
 };
 
@@ -726,16 +728,16 @@ struct __packed pdb_ecdsa_sign {
 struct __packed pdb_mp_pub_k {
 	uint32_t pdb_hdr;
 	#define PDB_MP_PUB_K_SGF_SHIFT		31
-	dma_addr_t dma_pkey;	/* Pointer to Wx,y (public key) */
+	caam_dma_addr_t dma_pkey;	/* Pointer to Wx,y (public key) */
 };
 
 struct __packed pdb_mp_sign {
 	uint32_t pdb_hdr;
 	#define PDB_MP_SIGN_SGF_SHIFT		28
-	dma_addr_t dma_addr_msg;	/* Pointer to Message */
-	dma_addr_t dma_addr_hash;	/* Pointer to hash output */
-	dma_addr_t dma_addr_c_sig;	/* Pointer to C_signature */
-	dma_addr_t dma_addr_d_sig;	/* Pointer to D_signature */
+	caam_dma_addr_t dma_addr_msg;	/* Pointer to Message */
+	caam_dma_addr_t dma_addr_hash;	/* Pointer to hash output */
+	caam_dma_addr_t dma_addr_c_sig;	/* Pointer to C_signature */
+	caam_dma_addr_t dma_addr_d_sig;	/* Pointer to D_signature */
 	uint32_t img_size;		/* Length of Message */
 };
 
diff --git a/drivers/crypto/fsl/desc_constr.h b/drivers/crypto/fsl/desc_constr.h
index 9edb8dc64a..209557c4ff 100644
--- a/drivers/crypto/fsl/desc_constr.h
+++ b/drivers/crypto/fsl/desc_constr.h
@@ -3,7 +3,6 @@
  * caam descriptor construction helper functions
  *
  * Copyright 2008-2014 Freescale Semiconductor, Inc.
- * Copyright 2018 NXP
  *
  * Based on desc_constr.h file in linux drivers/crypto/caam
  */
@@ -13,7 +12,7 @@
 
 #define IMMEDIATE (1 << 23)
 #define CAAM_CMD_SZ sizeof(u32)
-#define CAAM_PTR_SZ sizeof(u32)
+#define CAAM_PTR_SZ sizeof(caam_dma_addr_t)
 #define CAAM_DESC_BYTES_MAX (CAAM_CMD_SZ * MAX_CAAM_DESCSIZE)
 #define DESC_JOB_IO_LEN (CAAM_CMD_SZ * 5 + CAAM_PTR_SZ * 3)
 
@@ -36,7 +35,7 @@
 			       LDST_SRCDST_WORD_DECOCTRL | \
 			       (LDOFF_ENABLE_AUTO_NFIFO << LDST_OFFSET_SHIFT))
 
-#if defined(CONFIG_PHYS_64BIT) && !defined(CONFIG_IMX8M)
+#ifdef CONFIG_CAAM_64BIT
 struct ptr_addr_t {
 #ifdef CONFIG_SYS_FSL_SEC_LE
 	u32 low;
@@ -50,9 +49,9 @@ struct ptr_addr_t {
 };
 #endif
 
-static inline void pdb_add_ptr(u32 *offset, u32 ptr)
+static inline void pdb_add_ptr(caam_dma_addr_t *offset, caam_dma_addr_t ptr)
 {
-#if defined(CONFIG_PHYS_64BIT) && !defined(CONFIG_IMX8M)
+#ifdef CONFIG_CAAM_64BIT
 	/* The Position of low and high part of 64 bit address
 	 * will depend on the endianness of CAAM Block */
 	struct ptr_addr_t *ptr_addr = (struct ptr_addr_t *)offset;
@@ -103,11 +102,11 @@ static inline void init_job_desc_pdb(u32 *desc, u32 options, size_t pdb_bytes)
 		       options);
 }
 
-static inline void append_ptr(u32 *desc, uint32_t ptr)
+static inline void append_ptr(u32 *desc, caam_dma_addr_t ptr)
 {
-	u32 *offset = (u32 *)desc_end(desc);
+	caam_dma_addr_t *offset = (caam_dma_addr_t *)desc_end(desc);
 
-#if defined(CONFIG_PHYS_64BIT) && !defined(CONFIG_IMX8M)
+#ifdef CONFIG_CAAM_64BIT
 	/* The Position of low and high part of 64 bit address
 	 * will depend on the endianness of CAAM Block */
 	struct ptr_addr_t *ptr_addr = (struct ptr_addr_t *)offset;
@@ -160,7 +159,7 @@ static inline u32 *write_cmd(u32 *desc, u32 command)
 	return desc + 1;
 }
 
-static inline void append_cmd_ptr(u32 *desc, uint32_t ptr, int len,
+static inline void append_cmd_ptr(u32 *desc, caam_dma_addr_t ptr, int len,
 				  u32 command)
 {
 	append_cmd(desc, command | len);
@@ -168,7 +167,7 @@ static inline void append_cmd_ptr(u32 *desc, uint32_t ptr, int len,
 }
 
 /* Write length after pointer, rather than inside command */
-static inline void append_cmd_ptr_extlen(u32 *desc, uint32_t ptr,
+static inline void append_cmd_ptr_extlen(u32 *desc, caam_dma_addr_t ptr,
 					 unsigned int len, u32 command)
 {
 	append_cmd(desc, command);
@@ -226,7 +225,7 @@ APPEND_CMD_LEN(seq_fifo_load, SEQ_FIFO_LOAD)
 APPEND_CMD_LEN(seq_fifo_store, SEQ_FIFO_STORE)
 
 #define APPEND_CMD_PTR(cmd, op) \
-static inline void append_##cmd(u32 *desc, uint32_t ptr, unsigned int len, \
+static inline void append_##cmd(u32 *desc, caam_dma_addr_t ptr, unsigned int len, \
 				u32 options) \
 { \
 	PRINT_POS; \
@@ -237,7 +236,7 @@ APPEND_CMD_PTR(load, LOAD)
 APPEND_CMD_PTR(fifo_load, FIFO_LOAD)
 APPEND_CMD_PTR(fifo_store, FIFO_STORE)
 
-static inline void append_store(u32 *desc, uint32_t ptr, unsigned int len,
+static inline void append_store(u32 *desc, caam_dma_addr_t ptr, unsigned int len,
 				u32 options)
 {
 	u32 cmd_src;
@@ -255,7 +254,7 @@ static inline void append_store(u32 *desc, uint32_t ptr, unsigned int len,
 }
 
 #define APPEND_SEQ_PTR_INTLEN(cmd, op) \
-static inline void append_seq_##cmd##_ptr_intlen(u32 *desc, uint32_t ptr, \
+static inline void append_seq_##cmd##_ptr_intlen(u32 *desc, caam_dma_addr_t ptr, \
 						 unsigned int len, \
 						 u32 options) \
 { \
@@ -279,7 +278,7 @@ APPEND_CMD_PTR_TO_IMM(load, LOAD);
 APPEND_CMD_PTR_TO_IMM(fifo_load, FIFO_LOAD);
 
 #define APPEND_CMD_PTR_EXTLEN(cmd, op) \
-static inline void append_##cmd##_extlen(u32 *desc, uint32_t ptr, \
+static inline void append_##cmd##_extlen(u32 *desc, caam_dma_addr_t ptr, \
 					 unsigned int len, u32 options) \
 { \
 	PRINT_POS; \
@@ -293,7 +292,7 @@ APPEND_CMD_PTR_EXTLEN(seq_out_ptr, SEQ_OUT_PTR)
  * the size of its type
  */
 #define APPEND_CMD_PTR_LEN(cmd, op, type) \
-static inline void append_##cmd(u32 *desc, uint32_t ptr, \
+static inline void append_##cmd(u32 *desc, caam_dma_addr_t ptr, \
 				type len, u32 options) \
 { \
 	PRINT_POS; \
diff --git a/drivers/crypto/fsl/fsl_hash.c b/drivers/crypto/fsl/fsl_hash.c
index 75500a621f..8b5c26db07 100644
--- a/drivers/crypto/fsl/fsl_hash.c
+++ b/drivers/crypto/fsl/fsl_hash.c
@@ -1,7 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
  * Copyright 2014 Freescale Semiconductor, Inc.
- * Copyright 2018 NXP
  *
  */
 
@@ -88,7 +87,7 @@ static int caam_hash_update(void *hash_ctx, const void *buf,
 			    enum caam_hash_algos caam_algo)
 {
 	uint32_t final;
-	phys_addr_t addr = virt_to_phys((void *)buf);
+	caam_dma_addr_t addr = virt_to_phys((void *)buf);
 	struct sha_ctx *ctx = hash_ctx;
 
 	if (ctx->sg_num >= MAX_SG_32) {
@@ -96,12 +95,12 @@ static int caam_hash_update(void *hash_ctx, const void *buf,
 		return -EINVAL;
 	}
 
-#if defined(CONFIG_PHYS_64BIT) && !defined(CONFIG_IMX8M)
+#ifdef CONFIG_CAAM_64BIT
 	sec_out32(&ctx->sg_tbl[ctx->sg_num].addr_hi, (uint32_t)(addr >> 32));
 #else
 	sec_out32(&ctx->sg_tbl[ctx->sg_num].addr_hi, 0x0);
 #endif
-	sec_out32(&ctx->sg_tbl[ctx->sg_num].addr_lo, (uint32_t)addr);
+	sec_out32(&ctx->sg_tbl[ctx->sg_num].addr_lo, (caam_dma_addr_t)addr);
 
 	sec_out32(&ctx->sg_tbl[ctx->sg_num].len_flag,
 		  (size & SG_ENTRY_LENGTH_MASK));
diff --git a/drivers/crypto/fsl/jobdesc.c b/drivers/crypto/fsl/jobdesc.c
index cd9d064657..d235415531 100644
--- a/drivers/crypto/fsl/jobdesc.c
+++ b/drivers/crypto/fsl/jobdesc.c
@@ -165,10 +165,9 @@ int inline_cnstr_jobdesc_blob_dek(uint32_t *desc, const uint8_t *plain_txt,
 
 	append_u32(desc, aad_w2);
 
-	append_cmd_ptr(desc, (uint32_t)SEC_MEM_PAGE1, in_sz, CMD_SEQ_IN_PTR);
+	append_cmd_ptr(desc, (caam_dma_addr_t)SEC_MEM_PAGE1, in_sz, CMD_SEQ_IN_PTR);
 
-	append_cmd_ptr(desc, (uint32_t)((ulong)dek_blob + 8),
-		       out_sz, CMD_SEQ_OUT_PTR);
+	append_cmd_ptr(desc, (caam_dma_addr_t)(ulong)(dek_blob + 8), out_sz, CMD_SEQ_OUT_PTR);
 
 	append_operation(desc, OP_TYPE_ENCAP_PROTOCOL | OP_PCLID_BLOB |
 						OP_PCLID_SECMEM);
@@ -184,7 +183,7 @@ void inline_cnstr_jobdesc_hash(uint32_t *desc,
 	/* SHA 256 , output is of length 32 words */
 	uint32_t storelen = alg_size;
 	u32 options;
-	u32 dma_addr_in, dma_addr_out;
+	caam_dma_addr_t dma_addr_in, dma_addr_out;
 
 	dma_addr_in = virt_to_phys((void *)msg);
 	dma_addr_out = virt_to_phys((void *)digest);
@@ -213,7 +212,7 @@ void inline_cnstr_jobdesc_blob_encap(uint32_t *desc, uint8_t *key_idnfr,
 				     uint8_t *plain_txt, uint8_t *enc_blob,
 				     uint32_t in_sz)
 {
-	u32 dma_addr_key_idnfr, dma_addr_in, dma_addr_out;
+	caam_dma_addr_t dma_addr_key_idnfr, dma_addr_in, dma_addr_out;
 	uint32_t key_sz = KEY_IDNFR_SZ_BYTES;
 	/* output blob will have 32 bytes key blob in beginning and
 	 * 16 byte HMAC identifier at end of data blob */
@@ -238,7 +237,7 @@ void inline_cnstr_jobdesc_blob_decap(uint32_t *desc, uint8_t *key_idnfr,
 				     uint8_t *enc_blob, uint8_t *plain_txt,
 				     uint32_t out_sz)
 {
-	u32 dma_addr_key_idnfr, dma_addr_in, dma_addr_out;
+	caam_dma_addr_t dma_addr_key_idnfr, dma_addr_in, dma_addr_out;
 	uint32_t key_sz = KEY_IDNFR_SZ_BYTES;
 	uint32_t in_sz = out_sz + KEY_BLOB_SIZE + MAC_SIZE;
 
@@ -314,7 +313,7 @@ void inline_cnstr_jobdesc_pkha_rsaexp(uint32_t *desc,
 				      struct pk_in_params *pkin, uint8_t *out,
 				      uint32_t out_siz)
 {
-	u32 dma_addr_e, dma_addr_a, dma_addr_n, dma_addr_out;
+	caam_dma_addr_t dma_addr_e, dma_addr_a, dma_addr_n, dma_addr_out;
 
 	dma_addr_e = virt_to_phys((void *)pkin->e);
 	dma_addr_a = virt_to_phys((void *)pkin->a);
diff --git a/drivers/crypto/fsl/jr.c b/drivers/crypto/fsl/jr.c
index 060a012eb2..22b649219e 100644
--- a/drivers/crypto/fsl/jr.c
+++ b/drivers/crypto/fsl/jr.c
@@ -84,16 +84,16 @@ static void jr_initregs(uint8_t sec_idx)
 {
 	struct jr_regs *regs = (struct jr_regs *)SEC_JR0_ADDR(sec_idx);
 	struct jobring *jr = &jr0[sec_idx];
-	phys_addr_t ip_base = virt_to_phys((void *)jr->input_ring);
-	phys_addr_t op_base = virt_to_phys((void *)jr->output_ring);
+	caam_dma_addr_t ip_base = virt_to_phys((void *)jr->input_ring);
+	caam_dma_addr_t op_base = virt_to_phys((void *)jr->output_ring);
 
-#if defined(CONFIG_PHYS_64BIT) && !defined(CONFIG_IMX8M)
+#ifdef CONFIG_CAAM_64BIT
 	sec_out32(&regs->irba_h, ip_base >> 32);
 #else
 	sec_out32(&regs->irba_h, 0x0);
 #endif
 	sec_out32(&regs->irba_l, (uint32_t)ip_base);
-#if defined(CONFIG_PHYS_64BIT) && !defined(CONFIG_IMX8M)
+#ifdef CONFIG_CAAM_64BIT
 	sec_out32(&regs->orba_h, op_base >> 32);
 #else
 	sec_out32(&regs->orba_h, 0x0);
@@ -119,8 +119,8 @@ static int jr_init(uint8_t sec_idx)
 	jr->liodn = DEFAULT_JR_LIODN;
 #endif
 	jr->size = JR_SIZE;
-	jr->input_ring = (uint32_t *)memalign(ARCH_DMA_MINALIGN,
-				JR_SIZE * sizeof(dma_addr_t));
+	jr->input_ring = (caam_dma_addr_t *)memalign(ARCH_DMA_MINALIGN,
+				JR_SIZE * sizeof(caam_dma_addr_t));
 	if (!jr->input_ring)
 		return -1;
 
@@ -131,7 +131,7 @@ static int jr_init(uint8_t sec_idx)
 	if (!jr->output_ring)
 		return -1;
 
-	memset(jr->input_ring, 0, JR_SIZE * sizeof(dma_addr_t));
+	memset(jr->input_ring, 0, JR_SIZE * sizeof(caam_dma_addr_t));
 	memset(jr->output_ring, 0, jr->op_size);
 
 	start_jr0(sec_idx);
@@ -150,7 +150,7 @@ static int jr_sw_cleanup(uint8_t sec_idx)
 	jr->read_idx = 0;
 	jr->write_idx = 0;
 	memset(jr->info, 0, sizeof(jr->info));
-	memset(jr->input_ring, 0, jr->size * sizeof(dma_addr_t));
+	memset(jr->input_ring, 0, jr->size * sizeof(caam_dma_addr_t));
 	memset(jr->output_ring, 0, jr->size * sizeof(struct op_ring));
 
 	return 0;
@@ -196,7 +196,7 @@ static int jr_enqueue(uint32_t *desc_addr,
 	uint32_t desc_word;
 	int length = desc_len(desc_addr);
 	int i;
-#if defined(CONFIG_PHYS_64BIT) && !defined(CONFIG_IMX8M)
+#ifdef CONFIG_CAAM_64BIT
 	uint32_t *addr_hi, *addr_lo;
 #endif
 
@@ -210,7 +210,7 @@ static int jr_enqueue(uint32_t *desc_addr,
 		sec_out32((uint32_t *)&desc_addr[i], desc_word);
 	}
 
-	phys_addr_t desc_phys_addr = virt_to_phys(desc_addr);
+	caam_dma_addr_t desc_phys_addr = virt_to_phys(desc_addr);
 
 	jr->info[head].desc_phys_addr = desc_phys_addr;
 	jr->info[head].callback = (void *)callback;
@@ -223,7 +223,7 @@ static int jr_enqueue(uint32_t *desc_addr,
 				  sizeof(struct jr_info), ARCH_DMA_MINALIGN);
 	flush_dcache_range(start, end);
 
-#if defined(CONFIG_PHYS_64BIT) && !defined(CONFIG_IMX8M)
+#ifdef CONFIG_CAAM_64BIT
 	/* Write the 64 bit Descriptor address on Input Ring.
 	 * The 32 bit hign and low part of the address will
 	 * depend on endianness of SEC block.
@@ -242,11 +242,11 @@ static int jr_enqueue(uint32_t *desc_addr,
 #else
 	/* Write the 32 bit Descriptor address on Input Ring. */
 	sec_out32(&jr->input_ring[head], desc_phys_addr);
-#endif /* ifdef CONFIG_PHYS_64BIT */
+#endif /* ifdef CONFIG_CAAM_64BIT */
 
 	start = (unsigned long)&jr->input_ring[head] & ~(ARCH_DMA_MINALIGN - 1);
 	end = ALIGN((unsigned long)&jr->input_ring[head] +
-		     sizeof(dma_addr_t), ARCH_DMA_MINALIGN);
+		     sizeof(caam_dma_addr_t), ARCH_DMA_MINALIGN);
 	flush_dcache_range(start, end);
 
 	jr->head = (head + 1) & (jr->size - 1);
@@ -272,7 +272,7 @@ static int jr_dequeue(int sec_idx)
 	int idx, i, found;
 	void (*callback)(uint32_t status, void *arg);
 	void *arg = NULL;
-#if defined(CONFIG_PHYS_64BIT) && !defined(CONFIG_IMX8M)
+#ifdef CONFIG_CAAM_64BIT
 	uint32_t *addr_hi, *addr_lo;
 #else
 	uint32_t *addr;
@@ -283,8 +283,8 @@ static int jr_dequeue(int sec_idx)
 
 		found = 0;
 
-		phys_addr_t op_desc;
-	#if defined(CONFIG_PHYS_64BIT) && !defined(CONFIG_IMX8M)
+		caam_dma_addr_t op_desc;
+	#ifdef CONFIG_CAAM_64BIT
 		/* Read the 64 bit Descriptor address from Output Ring.
 		 * The 32 bit hign and low part of the address will
 		 * depend on endianness of SEC block.
@@ -304,7 +304,7 @@ static int jr_dequeue(int sec_idx)
 		/* Read the 32 bit Descriptor address from Output Ring. */
 		addr = (uint32_t *)&jr->output_ring[jr->tail].desc;
 		op_desc = sec_in32(addr);
-	#endif /* ifdef CONFIG_PHYS_64BIT */
+	#endif /* ifdef CONFIG_CAAM_64BIT */
 
 		uint32_t status = sec_in32(&jr->output_ring[jr->tail].status);
 
@@ -678,7 +678,7 @@ int sec_init_idx(uint8_t sec_idx)
 	mcr = (mcr & ~MCFGR_AWCACHE_MASK) | (0x2 << MCFGR_AWCACHE_SHIFT);
 #endif
 
-#if defined(CONFIG_PHYS_64BIT) && !defined(CONFIG_IMX8M)
+#ifdef CONFIG_CAAM_64BIT
 	mcr |= (1 << MCFGR_PS_SHIFT);
 #endif
 	sec_out32(&sec->mcfgr, mcr);
diff --git a/drivers/crypto/fsl/jr.h b/drivers/crypto/fsl/jr.h
index 92566dd2d6..1047aa772c 100644
--- a/drivers/crypto/fsl/jr.h
+++ b/drivers/crypto/fsl/jr.h
@@ -1,7 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * Copyright 2008-2014 Freescale Semiconductor, Inc.
- * Copyright 2018 NXP
  *
  */
 
@@ -9,6 +8,7 @@
 #define __JR_H
 
 #include <linux/compiler.h>
+#include "type.h"
 
 #define JR_SIZE 4
 /* Timeout currently defined as 10 sec */
@@ -42,13 +42,13 @@
 #define RNG4_MAX_HANDLES	2
 
 struct op_ring {
-	u32 desc;
-	u32 status;
+	caam_dma_addr_t desc;
+	uint32_t status;
 } __packed;
 
 struct jr_info {
 	void (*callback)(uint32_t status, void *arg);
-	phys_addr_t desc_phys_addr;
+	caam_dma_addr_t desc_phys_addr;
 	uint32_t desc_len;
 	uint32_t op_done;
 	void *arg;
@@ -84,7 +84,7 @@ struct jobring {
 	 * by SEC
 	 */
 	/*Circular  Ring of i/p descriptors */
-	u32 *input_ring;
+	caam_dma_addr_t *input_ring;
 	/* Circular Ring of o/p descriptors */
 	/* Circula Ring containing info regarding descriptors in i/p
 	 * and o/p ring
diff --git a/drivers/crypto/fsl/type.h b/drivers/crypto/fsl/type.h
new file mode 100644
index 0000000000..b7031a60fd
--- /dev/null
+++ b/drivers/crypto/fsl/type.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2020 NXP
+ *
+ */
+
+#ifndef CRYPTO_FSL_TYPE_H
+#define CRYPTO_FSL_TYPE_H
+
+#ifdef CONFIG_CAAM_64BIT
+typedef unsigned long long caam_dma_addr_t;
+#else
+typedef u32 caam_dma_addr_t;
+#endif
+
+#endif
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH 00/37] imx: hab/caam new feature and update
  2021-03-25  9:29 [PATCH 00/37] imx: hab/caam new feature and update Peng Fan
                   ` (36 preceding siblings ...)
  2021-03-25  9:30 ` [PATCH 37/37] crypto: fsl: refactor for 32 bit version CAAM support on ARM64 Peng Fan
@ 2021-03-31 12:32 ` Horia Geantă
  37 siblings, 0 replies; 42+ messages in thread
From: Horia Geantă @ 2021-03-31 12:32 UTC (permalink / raw)
  To: u-boot

On 3/25/2021 11:32 AM, Peng Fan (OSS) wrote:
> From: Peng <peng.fan@nxp.com>
> 
> This patchset is to upstream NXP downstream caam, hab features

I don't think adding yet another caam driver (drivers/crypto/fsl_caam.c)
is a good idea.
Instead existing driver (drivers/crypto/fsl/*) should be extended / modified.

> One more patch is to update maintainer for imx8mn_evk board.
> 
> Aymen Sghaier (6):
>   crypto: caam: Add CAAM support to i.MX8M platforms
>   crypto: caam: Fix build warnings pointer casting
>   crypto: Add blob command support for i.MX8M platforms
>   crypto: caam: Fix pointer size to 32bit for i.MX8M
>   crypto: caam: Add secure memory vid 3 support
>   crypto: caam: RNG4 TRNG errata
> 
> Breno Lima (13):
>   imx: imx7 Support for Manufacturing Protection
>   imx: Avoid hardcoded output ring size register offset (ORSR)
>   imx: Ensure CAAM clock is enabled prior getting out_jr_size
>   imx: Avoid hardcoded Job Ring Max size
>   imx: hab: Enable hab.c to authenticate additional images in open
>     configuration
>   imx: hab: Check if IVT header is HABv4
>   mx7ulp: hab: Add hab_status command for HABv4 M4 boot
>   imx: hab: Fix build warnings in 32-bit targets
>   crypto: fsl: blob: Flush dcache range for destination address
>   mx6dq: hab: Fix chip version in hab.h code
>   cmd: blob: Add IMX_HAB and CAAM supported SoCs as dependency
>   cmd: blob: Instantiate RNG before running CMD_BLOB
>   fsl_mfgprot: Fix typo in sign_mppubk()
> 
> Clement Faure (2):
>   imx8m: Add DEK blob encapsulation for imx8m
>   imx8: Add DEK blob encapsulation
> 
> Clement Le Marquis (1):
>   imx: caam: new u-boot command to set PRIBLOB bitfield from CAAM SCFGR
>     register to 0x3
> 
> Franck LENORMAND (3):
>   crypto: caam: change JR running loop
>   caam: enable support for iMX7ULP
>   imx7ulp: Enable support for cmd blob
> 
> Peng (1):
>   imx8mn: evk: update MAINTAINERS
> 
> Peng Fan (2):
>   imx8m: add regs used by CAAM
>   imx: HAB: Update hab codes to support ARM64 and i.MX8M
> 
> Utkarsh Gupta (2):
>   imx: HAB: Validate IVT before authenticating image
>   imx: hab: Display All HAB events via hab_status command
> 
> Ye Li (7):
>   imx: hab: Add function to authenticate kernel image
>   hab: Change calling to ROM API failsafe
>   imx: HAB: Add support for iMX8MM
>   iMX8M: Add support to enable CONFIG_IMX_HAB
>   imx: cmd_dek: Enable DEK only for chips supporting CAAM
>   crypto: caam: Add fsl caam driver
>   crypto: fsl: refactor for 32 bit version CAAM support on ARM64
> 
There are several patches fixing newly added code.
Internal development history is of little value, fixes should be squashed.

Horia

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH 31/37] crypto: caam: Add fsl caam driver
  2021-03-25  9:30 ` [PATCH 31/37] crypto: caam: Add fsl caam driver Peng Fan
@ 2021-04-08 18:24   ` Stefano Babic
  2021-07-08  8:02     ` Peng Fan (OSS)
  0 siblings, 1 reply; 42+ messages in thread
From: Stefano Babic @ 2021-04-08 18:24 UTC (permalink / raw)
  To: u-boot

Hi Peng,

On 25.03.21 10:30, Peng Fan (OSS) wrote:
> From: Ye Li <ye.li@nxp.com>
> 
> Add the fsl CAAM driver and new commands to implement DEK blob operations,
> like "caam genblob" to generate encrypted blob and "caam decap" to output
> orignal plain data.
> 
>   The following reasons lead to instantiate the TRNG into U-Boot/SPL:
> 
>   - On some i.MX platforms Linux Kernel could not instantiate RNG
>   - RNG could be used/needed by M4/M0 cores before Kernel stage
>   - Having the RNG instantiation implemented only once for
>     almost i.MX platforms

Is this a CAAM driver ? But we have already drivers/crypto/fsl for CAAM. 
Which is the reason for it and why it is not merged with the existing 
driver ?

Best regards,
Stefano Babic

> 
> Signed-off-by: Aymen Sghaier <aymen.sghaier@nxp.com>
> Signed-off-by: Ye Li <ye.li@nxp.com>
> Signed-off-by: Peng Fan <peng.fan@nxp.com>
> ---
>   arch/arm/include/asm/arch-mx7/crm_regs.h |   8 +
>   cmd/Kconfig                              |   6 +
>   cmd/Makefile                             |   1 +
>   cmd/cmd_fsl_caam.c                       |  88 +++
>   drivers/crypto/Makefile                  |   1 +
>   drivers/crypto/fsl_caam.c                | 715 +++++++++++++++++++++++
>   drivers/crypto/fsl_caam_internal.h       | 229 ++++++++
>   include/fsl_caam.h                       |  24 +
>   8 files changed, 1072 insertions(+)
>   create mode 100644 cmd/cmd_fsl_caam.c
>   create mode 100644 drivers/crypto/fsl_caam.c
>   create mode 100644 drivers/crypto/fsl_caam_internal.h
>   create mode 100644 include/fsl_caam.h
> 
> diff --git a/arch/arm/include/asm/arch-mx7/crm_regs.h b/arch/arm/include/asm/arch-mx7/crm_regs.h
> index bfa68a9d2a..a000ae05d7 100644
> --- a/arch/arm/include/asm/arch-mx7/crm_regs.h
> +++ b/arch/arm/include/asm/arch-mx7/crm_regs.h
> @@ -1998,6 +1998,14 @@ struct mxc_ccm_anatop_reg {
>   #define TEMPMON_HW_ANADIG_TEMPSENSE_TRIM_TOG_T_MUX_ADDR_SHIFT 29
>   #define TEMPMON_HW_ANADIG_TEMPSENSE_TRIM_TOG_T_MUX_ADDR(x) (((uint32_t)(((uint32_t)(x))<<TEMPMON_HW_ANADIG_TEMPSENSE_TRIM_TOG_T_MUX_ADDR_SHIFT))&TEMPMON_HW_ANADIG_TEMPSENSE_TRIM_TOG_T_MUX_ADDR_MASK)
>   
> +#define MXC_CCM_CCGR36_CAAM_DOMAIN3_OFFSET                     12
> +#define MXC_CCM_CCGR36_CAAM_DOMAIN3_MASK                       (3 << MXC_CCM_CCGR36_CAAM_DOMAIN3_OFFSET)
> +#define MXC_CCM_CCGR36_CAAM_DOMAIN2_OFFSET                     8
> +#define MXC_CCM_CCGR36_CAAM_DOMAIN2_MASK                       (3 << MXC_CCM_CCGR36_CAAM_DOMAIN2_OFFSET)
> +#define MXC_CCM_CCGR36_CAAM_DOMAIN1_OFFSET                     4
> +#define MXC_CCM_CCGR36_CAAM_DOMAIN1_MASK                       (3 << MXC_CCM_CCGR36_CAAM_DOMAIN1_OFFSET)
> +#define MXC_CCM_CCGR36_CAAM_DOMAIN0_OFFSET                     0
> +#define MXC_CCM_CCGR36_CAAM_DOMAIN0_MASK                       (3 << MXC_CCM_CCGR36_CAAM_DOMAIN0_OFFSET)
>   
>   #define CCM_GPR(i)		(CCM_BASE_ADDR + CCM_GPR0_OFFSET + 0x10 * (i))
>   #define CCM_OBSERVE(i)		(CCM_BASE_ADDR + CCM_OBSERVE0_OFFSET + 0x10 * (i))
> diff --git a/cmd/Kconfig b/cmd/Kconfig
> index f73de2d75a..aeecfed974 100644
> --- a/cmd/Kconfig
> +++ b/cmd/Kconfig
> @@ -397,6 +397,12 @@ config CMD_SPL_WRITE_SIZE
>   	  flash used by Falcon-mode boot. See the documentation until CMD_SPL
>   	  for detail.
>   
> +config CMD_FSL_CAAM_KB
> +	bool "Freescale i.MX CAAM command"
> +	help
> +	  Implement the "caam" command to generate DEK blob for one block of data
> +	  or decap the DEK blob to its original data.
> +
>   config CMD_THOR_DOWNLOAD
>   	bool "thor - TIZEN 'thor' download"
>   	select DFU
> diff --git a/cmd/Makefile b/cmd/Makefile
> index 567e2b79d2..d46ffd7021 100644
> --- a/cmd/Makefile
> +++ b/cmd/Makefile
> @@ -70,6 +70,7 @@ obj-$(CONFIG_CMD_FLASH) += flash.o
>   obj-$(CONFIG_CMD_FPGA) += fpga.o
>   obj-$(CONFIG_CMD_FPGAD) += fpgad.o
>   obj-$(CONFIG_CMD_FS_GENERIC) += fs.o
> +obj-$(CONFIG_CMD_FSL_CAAM_KB) += cmd_fsl_caam.o
>   obj-$(CONFIG_CMD_FUSE) += fuse.o
>   obj-$(CONFIG_CMD_GETTIME) += gettime.o
>   obj-$(CONFIG_CMD_GPIO) += gpio.o
> diff --git a/cmd/cmd_fsl_caam.c b/cmd/cmd_fsl_caam.c
> new file mode 100644
> index 0000000000..d41d672320
> --- /dev/null
> +++ b/cmd/cmd_fsl_caam.c
> @@ -0,0 +1,88 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2012-2016 Freescale Semiconductor, Inc.
> + */
> +
> +#include <common.h>
> +#include <command.h>
> +#include <fsl_caam.h>
> +
> +static int do_caam(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
> +{
> +	int ret, i;
> +
> +	if (argc < 2)
> +		return CMD_RET_USAGE;
> +
> +	if (strcmp(argv[1], "genblob") == 0) {
> +		if (argc != 5)
> +			return CMD_RET_USAGE;
> +
> +		void *data_addr;
> +		void *blob_addr;
> +		int size;
> +
> +		data_addr = (void *)simple_strtoul(argv[2], NULL, 16);
> +		blob_addr = (void *)simple_strtoul(argv[3], NULL, 16);
> +		size = simple_strtoul(argv[4], NULL, 10);
> +		if (size <= 48)
> +			return CMD_RET_USAGE;
> +
> +		caam_open();
> +		ret = caam_gen_blob((uint32_t)data_addr, (uint32_t)blob_addr, (uint32_t)size);
> +
> +		if (ret != SUCCESS) {
> +			printf("Error during blob encap operation: 0x%x\n", ret);
> +			return 0;
> +		}
> +
> +		/* Print the generated DEK blob */
> +		printf("DEK blob is available at 0x%08X and equals:\n", (unsigned int)blob_addr);
> +		for (i = 0; i < size; i++)
> +			printf("%02X ", ((uint8_t *)blob_addr)[i]);
> +		printf("\n\n");
> +
> +		return 1;
> +	} else if (strcmp(argv[1], "decap") == 0) {
> +		if (argc != 5)
> +			return CMD_RET_USAGE;
> +
> +		void *blob_addr;
> +		void *data_addr;
> +		int size;
> +
> +		blob_addr = (void *)simple_strtoul(argv[2], NULL, 16);
> +		data_addr = (void *)simple_strtoul(argv[3], NULL, 16);
> +		size      = simple_strtoul(argv[4], NULL, 10);
> +		if (size <= 48)
> +			return CMD_RET_USAGE;
> +
> +		caam_open();
> +		ret = caam_decap_blob((uint32_t)(data_addr), (uint32_t)(blob_addr), (uint32_t)size);
> +		if (ret != SUCCESS) {
> +			printf("Error during blob decap operation: 0x%x\n", ret);
> +		} else {
> +			printf("Success, blob decap at SM PAGE1 original data is:\n");
> +			int i = 0;
> +
> +			for (i = 0; i < size; i++) {
> +				printf("0x%x  ", *(unsigned char *)(data_addr + i));
> +				if (i % 16 == 0)
> +					printf("\n");
> +			}
> +			printf("\n");
> +		}
> +
> +		return 1;
> +	}
> +
> +	return CMD_RET_USAGE;
> +}
> +
> +U_BOOT_CMD(
> +	caam, 5, 1, do_caam,
> +	"Freescale i.MX CAAM command",
> +	"caam genblob data_addr blob_addr data_size\n \
> +	caam decap blobaddr data_addr data_size\n \
> +	\n "
> +	);
> diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
> index efbd1d3fca..6069dd5b29 100644
> --- a/drivers/crypto/Makefile
> +++ b/drivers/crypto/Makefile
> @@ -4,5 +4,6 @@
>   # 	http://www.samsung.com
>   
>   obj-$(CONFIG_EXYNOS_ACE_SHA)	+= ace_sha.o
> +obj-$(CONFIG_FSL_CAAM_KB)      += fsl_caam.o
>   obj-y += rsa_mod_exp/
>   obj-y += fsl/
> diff --git a/drivers/crypto/fsl_caam.c b/drivers/crypto/fsl_caam.c
> new file mode 100644
> index 0000000000..ccdf131635
> --- /dev/null
> +++ b/drivers/crypto/fsl_caam.c
> @@ -0,0 +1,715 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (c) 2012-2016, Freescale Semiconductor, Inc.
> + */
> +
> +#include <common.h>
> +#include <malloc.h>
> +#include <memalign.h>
> +#include <asm/io.h>
> +#ifndef CONFIG_ARCH_MX7ULP
> +#include <asm/arch/crm_regs.h>
> +#else
> +#include <asm/arch/pcc.h>
> +#endif /* CONFIG_ARCH_MX7ULP */
> +#include "fsl_caam_internal.h"
> +#include "fsl/desc_constr.h"
> +#include <fsl_caam.h>
> +#include <cpu_func.h>
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +static void rng_init(void);
> +static void caam_clock_enable(void);
> +static int do_cfg_jrqueue(void);
> +static int do_job(u32 *desc);
> +static int jr_reset(void);
> +
> +/*
> + * Structures
> + */
> +/* Definition of input ring object */
> +struct inring_entry {
> +	u32 desc; /* Pointer to input descriptor */
> +};
> +
> +/* Definition of output ring object */
> +struct outring_entry {
> +	u32 desc;   /* Pointer to output descriptor */
> +	u32 status; /* Status of the Job Ring       */
> +};
> +
> +/* Main job ring data structure */
> +struct jr_data_st {
> +	struct inring_entry  *inrings;
> +	struct outring_entry *outrings;
> +	u32 status;  /* Ring buffers init status */
> +	u32 *desc;   /* Pointer to output descriptor */
> +	u32 raw_addr[DESC_MAX_SIZE * 2];
> +};
> +
> +/*
> + * Global variables
> + */
> +#if defined(CONFIG_SPL_BUILD)
> +static struct jr_data_st g_jrdata = {0};
> +#else
> +static struct jr_data_st g_jrdata = {0, 0, 0xFFFFFFFF};
> +#endif
> +
> +static u8 skeymod[] = {
> +	0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08,
> +	0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00
> +};
> +
> +/*
> + * Local functions
> + */
> +static void dump_error(void)
> +{
> +	int i;
> +
> +	debug("Dump CAAM Error\n");
> +	debug("MCFGR 0x%08X\n", __raw_readl(CAAM_MCFGR));
> +	debug("FAR  0x%08X\n", __raw_readl(CAAM_FAR));
> +	debug("FAMR 0x%08X\n", __raw_readl(CAAM_FAMR));
> +	debug("FADR 0x%08X\n", __raw_readl(CAAM_FADR));
> +	debug("CSTA 0x%08X\n", __raw_readl(CAAM_STA));
> +	debug("RTMCTL 0x%X\n", __raw_readl(CAAM_RTMCTL));
> +	debug("RTSTATUS 0x%X\n", __raw_readl(CAAM_RTSTATUS));
> +	debug("RDSTA 0x%X\n", __raw_readl(CAAM_RDSTA));
> +
> +	for (i = 0; i < desc_len(g_jrdata.desc); i++)
> +		debug("desc[%d]: 0x%08x\n", i, g_jrdata.desc[i]);
> +}
> +
> +/*!
> + * Secure memory run command.
> + *
> + * @param   sec_mem_cmd  Secure memory command register
> + * @return  cmd_status  Secure memory command status register
> + */
> +u32 secmem_set_cmd_1(u32 sec_mem_cmd)
> +{
> +	u32 temp_reg;
> +
> +	__raw_writel(sec_mem_cmd, CAAM_SMCJR0);
> +	do {
> +		temp_reg = __raw_readl(CAAM_SMCSJR0);
> +	} while (temp_reg & CMD_COMPLETE);
> +
> +	return temp_reg;
> +}
> +
> +/*!
> + * Use CAAM to decapsulate a blob to secure memory.
> + * Such blob of secret key cannot be read once decrypted,
> + * but can still be used for enc/dec operation of user's data.
> + *
> + * @param   blob_addr  Location address of the blob.
> + *
> + * @return  SUCCESS or ERROR_XXX
> + */
> +u32 caam_decap_blob(u32 plain_text, u32 blob_addr, u32 size)
> +{
> +	u32 ret = SUCCESS;
> +	u32 key_sz = sizeof(skeymod);
> +	u32 *decap_desc = g_jrdata.desc;
> +
> +	/* prepare job descriptor */
> +	init_job_desc(decap_desc, 0);
> +	append_load(decap_desc, PTR2CAAMDMA(skeymod), key_sz,
> +		    LDST_CLASS_2_CCB | LDST_SRCDST_BYTE_KEY);
> +	append_seq_in_ptr_intlen(decap_desc, blob_addr, size + 48, 0);
> +	append_seq_out_ptr_intlen(decap_desc, plain_text, size, 0);
> +	append_operation(decap_desc, OP_TYPE_DECAP_PROTOCOL | OP_PCLID_BLOB);
> +
> +	flush_dcache_range((uintptr_t)blob_addr & ALIGN_MASK,
> +			   ((uintptr_t)blob_addr & ALIGN_MASK)
> +			    + ROUND(2 * size, ARCH_DMA_MINALIGN));
> +	flush_dcache_range((uintptr_t)plain_text & ALIGN_MASK,
> +			   (plain_text & ALIGN_MASK)
> +			   + ROUND(2 * size, ARCH_DMA_MINALIGN));
> +
> +	/* Run descriptor with result written to blob buffer */
> +	ret = do_job(decap_desc);
> +
> +	if (ret != SUCCESS)
> +		printf("Error: blob decap job failed 0x%x\n", ret);
> +
> +	return ret;
> +}
> +
> +/*!
> + * Use CAAM to generate a blob.
> + *
> + * @param   plain_data_addr  Location address of the plain data.
> + * @param   blob_addr  Location address of the blob.
> + *
> + * @return  SUCCESS or ERROR_XXX
> + */
> +u32 caam_gen_blob(u32 plain_data_addr, u32 blob_addr, u32 size)
> +{
> +	u32 ret = SUCCESS;
> +	u32 key_sz = sizeof(skeymod);
> +	u32 *encap_desc = g_jrdata.desc;
> +	/* Buffer to hold the resulting blob */
> +	u8 *blob = (u8 *)CAAMDMA2PTR(blob_addr);
> +
> +	/* initialize the blob array */
> +	memset(blob, 0, size);
> +
> +	/* prepare job descriptor */
> +	init_job_desc(encap_desc, 0);
> +	append_load(encap_desc, PTR2CAAMDMA(skeymod), key_sz,
> +		    LDST_CLASS_2_CCB | LDST_SRCDST_BYTE_KEY);
> +	append_seq_in_ptr_intlen(encap_desc, plain_data_addr, size, 0);
> +	append_seq_out_ptr_intlen(encap_desc, PTR2CAAMDMA(blob), size + 48, 0);
> +	append_operation(encap_desc, OP_TYPE_ENCAP_PROTOCOL | OP_PCLID_BLOB);
> +
> +	flush_dcache_range((uintptr_t)plain_data_addr & ALIGN_MASK,
> +			   (plain_data_addr & ALIGN_MASK)
> +			   + ROUND(2 * size, ARCH_DMA_MINALIGN));
> +	flush_dcache_range((uintptr_t)blob & ALIGN_MASK,
> +			   ((uintptr_t)blob & ALIGN_MASK)
> +			   + ROUND(2 * size, ARCH_DMA_MINALIGN));
> +
> +	ret = do_job(encap_desc);
> +
> +	if (ret != SUCCESS)
> +		printf("Error: blob encap job failed 0x%x\n", ret);
> +
> +	return ret;
> +}
> +
> +u32 caam_hwrng(u8 *output_ptr, u32 output_len)
> +{
> +	u32 ret = SUCCESS;
> +	u32 *hwrng_desc = g_jrdata.desc;
> +	/* Buffer to hold the resulting output*/
> +	u8 *output = (u8 *)output_ptr;
> +
> +	/* initialize the output array */
> +	memset(output, 0, output_len);
> +
> +	/* prepare job descriptor */
> +	init_job_desc(hwrng_desc, 0);
> +	append_operation(hwrng_desc, OP_ALG_ALGSEL_RNG | OP_TYPE_CLASS1_ALG);
> +	append_fifo_store(hwrng_desc, PTR2CAAMDMA(output),
> +			  output_len, FIFOST_TYPE_RNGSTORE);
> +
> +	/* flush cache */
> +	flush_dcache_range((uintptr_t)hwrng_desc & ALIGN_MASK,
> +			   ((uintptr_t)hwrng_desc & ALIGN_MASK)
> +			   + ROUND(DESC_MAX_SIZE, ARCH_DMA_MINALIGN));
> +
> +	ret = do_job(hwrng_desc);
> +
> +	flush_dcache_range((uintptr_t)output & ALIGN_MASK,
> +			   ((uintptr_t)output & ALIGN_MASK)
> +			   + ROUND(2 * output_len, ARCH_DMA_MINALIGN));
> +
> +	if (ret != SUCCESS)
> +		printf("Error: RNG generate failed 0x%x\n", ret);
> +
> +	return ret;
> +}
> +
> +/*!
> + * Initialize the CAAM.
> + *
> + */
> +void caam_open(void)
> +{
> +	u32 temp_reg;
> +	int ret;
> +
> +	/* switch on the clock */
> +#ifndef CONFIG_ARCH_IMX8
> +	caam_clock_enable();
> +#endif
> +
> +	/* reset the CAAM */
> +	temp_reg = __raw_readl(CAAM_MCFGR) |
> +			CAAM_MCFGR_DMARST | CAAM_MCFGR_SWRST;
> +	__raw_writel(temp_reg,  CAAM_MCFGR);
> +	while (__raw_readl(CAAM_MCFGR) & CAAM_MCFGR_DMARST)
> +		;
> +
> +	jr_reset();
> +	ret = do_cfg_jrqueue();
> +
> +	if (ret != SUCCESS) {
> +		printf("Error CAAM JR initialization\n");
> +		return;
> +	}
> +
> +	/* Check if the RNG is already instantiated */
> +	temp_reg = __raw_readl(CAAM_RDSTA);
> +	if (temp_reg == (RDSTA_IF0 | RDSTA_IF1 | RDSTA_SKVN)) {
> +		printf("RNG already instantiated 0x%X\n", temp_reg);
> +		return;
> +	}
> +
> +	rng_init();
> +}
> +
> +static void caam_clock_enable(void)
> +{
> +#if defined(CONFIG_ARCH_MX6)
> +	struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
> +	u32 reg;
> +
> +	reg = __raw_readl(&mxc_ccm->CCGR0);
> +
> +	reg |= (MXC_CCM_CCGR0_CAAM_SECURE_MEM_MASK |
> +		MXC_CCM_CCGR0_CAAM_WRAPPER_ACLK_MASK |
> +		MXC_CCM_CCGR0_CAAM_WRAPPER_IPG_MASK);
> +
> +	__raw_writel(reg, &mxc_ccm->CCGR0);
> +
> +#ifndef CONFIG_MX6UL
> +	/* EMI slow clk */
> +	reg = __raw_readl(&mxc_ccm->CCGR6);
> +	reg |= MXC_CCM_CCGR6_EMI_SLOW_MASK;
> +
> +	__raw_writel(reg, &mxc_ccm->CCGR6);
> +#endif
> +
> +#elif defined(CONFIG_ARCH_MX7)
> +	HW_CCM_CCGR_SET(36, MXC_CCM_CCGR36_CAAM_DOMAIN0_MASK);
> +#elif defined(CONFIG_ARCH_MX7ULP)
> +	pcc_clock_enable(PER_CLK_CAAM, true);
> +#endif
> +}
> +
> +static void kick_trng(u32 ent_delay)
> +{
> +	u32 samples  = 512; /* number of bits to generate and test */
> +	u32 mono_min = 195;
> +	u32 mono_max = 317;
> +	u32 mono_range  = mono_max - mono_min;
> +	u32 poker_min = 1031;
> +	u32 poker_max = 1600;
> +	u32 poker_range = poker_max - poker_min + 1;
> +	u32 retries    = 2;
> +	u32 lrun_max   = 32;
> +	s32 run_1_min   = 27;
> +	s32 run_1_max   = 107;
> +	s32 run_1_range = run_1_max - run_1_min;
> +	s32 run_2_min   = 7;
> +	s32 run_2_max   = 62;
> +	s32 run_2_range = run_2_max - run_2_min;
> +	s32 run_3_min   = 0;
> +	s32 run_3_max   = 39;
> +	s32 run_3_range = run_3_max - run_3_min;
> +	s32 run_4_min   = -1;
> +	s32 run_4_max   = 26;
> +	s32 run_4_range = run_4_max - run_4_min;
> +	s32 run_5_min   = -1;
> +	s32 run_5_max   = 18;
> +	s32 run_5_range = run_5_max - run_5_min;
> +	s32 run_6_min   = -1;
> +	s32 run_6_max   = 17;
> +	s32 run_6_range = run_6_max - run_6_min;
> +	u32 val;
> +
> +	/* Put RNG in program mode */
> +	setbits_le32(CAAM_RTMCTL, RTMCTL_PGM);
> +	/* Configure the RNG Entropy Delay
> +	 * Performance-wise, it does not make sense to
> +	 * set the delay to a value that is lower
> +	 * than the last one that worked (i.e. the state handles
> +	 * were instantiated properly. Thus, instead of wasting
> +	 * time trying to set the values controlling the sample
> +	 * frequency, the function simply returns.
> +	 */
> +	val = __raw_readl(CAAM_RTSDCTL);
> +	val &= BM_TRNG_ENT_DLY;
> +	val >>= BS_TRNG_ENT_DLY;
> +	if (ent_delay < val) {
> +		/* Put RNG4 into run mode */
> +		clrbits_le32(CAAM_RTMCTL, RTMCTL_PGM);
> +		return;
> +	}
> +
> +	val = (ent_delay << BS_TRNG_ENT_DLY) | samples;
> +	__raw_writel(val, CAAM_RTSDCTL);
> +
> +	/* min. freq. count, equal to 1/2 of the entropy sample length */
> +	__raw_writel(ent_delay >> 1, CAAM_RTFRQMIN);
> +
> +	/* max. freq. count, equal to 32 times the entropy sample length */
> +	__raw_writel(ent_delay << 5, CAAM_RTFRQMAX);
> +
> +	__raw_writel((retries << 16) | lrun_max, CAAM_RTSCMISC);
> +	__raw_writel(poker_max, CAAM_RTPKRMAX);
> +	__raw_writel(poker_range, CAAM_RTPKRRNG);
> +	__raw_writel((mono_range << 16) | mono_max, CAAM_RTSCML);
> +	__raw_writel((run_1_range << 16) | run_1_max, CAAM_RTSCR1L);
> +	__raw_writel((run_2_range << 16) | run_2_max, CAAM_RTSCR2L);
> +	__raw_writel((run_3_range << 16) | run_3_max, CAAM_RTSCR3L);
> +	__raw_writel((run_4_range << 16) | run_4_max, CAAM_RTSCR4L);
> +	__raw_writel((run_5_range << 16) | run_5_max, CAAM_RTSCR5L);
> +	__raw_writel((run_6_range << 16) | run_6_max, CAAM_RTSCR6PL);
> +
> +	val = __raw_readl(CAAM_RTMCTL);
> +	/*
> +	 * Select raw sampling in both entropy shifter
> +	 * and statistical checker
> +	 */
> +	val &= ~BM_TRNG_SAMP_MODE;
> +	val |= TRNG_SAMP_MODE_RAW_ES_SC;
> +	/* Put RNG4 into run mode */
> +	val &= ~RTMCTL_PGM;
> +/*test with sample mode only */
> +	__raw_writel(val, CAAM_RTMCTL);
> +
> +	/* Clear the ERR bit in RTMCTL if set. The TRNG error can occur when the
> +	 * RNG clock is not within 1/2x to 8x the system clock.
> +	 * This error is possible if ROM code does not initialize the system PLLs
> +	 * immediately after PoR.
> +	 */
> +	/* setbits_le32(CAAM_RTMCTL, RTMCTL_ERR); */
> +}
> +
> +/*
> + *  Descriptors to instantiate SH0, SH1, load the keys
> + */
> +static const u32 rng_inst_sh0_desc[] = {
> +	/* Header, don't setup the size */
> +	CAAM_HDR_CTYPE | CAAM_HDR_ONE | CAAM_HDR_START_INDEX(0),
> +	/* Operation instantiation (sh0) */
> +	CAAM_PROTOP_CTYPE | CAAM_C1_RNG | ALGO_RNG_SH(0) | ALGO_RNG_INSTANTIATE,
> +};
> +
> +static const u32 rng_inst_sh1_desc[] = {
> +	/* wait for done - Jump to next entry */
> +	CAAM_C1_JUMP | CAAM_JUMP_LOCAL | CAAM_JUMP_TST_ALL_COND_TRUE
> +		| CAAM_JUMP_OFFSET(1),
> +	/* Clear written register (write 1) */
> +	CAAM_C0_LOAD_IMM | CAAM_DST_CLEAR_WRITTEN | sizeof(u32),
> +	0x00000001,
> +	/* Operation instantiation (sh1) */
> +	CAAM_PROTOP_CTYPE | CAAM_C1_RNG | ALGO_RNG_SH(1)
> +		| ALGO_RNG_INSTANTIATE,
> +};
> +
> +static const u32 rng_inst_load_keys[] = {
> +	/* wait for done - Jump to next entry */
> +	CAAM_C1_JUMP | CAAM_JUMP_LOCAL | CAAM_JUMP_TST_ALL_COND_TRUE
> +		| CAAM_JUMP_OFFSET(1),
> +	/* Clear written register (write 1) */
> +	CAAM_C0_LOAD_IMM | CAAM_DST_CLEAR_WRITTEN | sizeof(u32),
> +	0x00000001,
> +	/* Generate the Key */
> +	CAAM_PROTOP_CTYPE | CAAM_C1_RNG | BM_ALGO_RNG_SK | ALGO_RNG_GENERATE,
> +};
> +
> +static void do_inst_desc(u32 *desc, u32 status)
> +{
> +	u32 *pdesc = desc;
> +	u8  desc_len;
> +	bool add_sh0   = false;
> +	bool add_sh1   = false;
> +	bool load_keys = false;
> +
> +	/*
> +	 * Modify the the descriptor to remove if necessary:
> +	 *  - The key loading
> +	 *  - One of the SH already instantiated
> +	 */
> +	desc_len = RNG_DESC_SH0_SIZE;
> +	if ((status & RDSTA_IF0) != RDSTA_IF0)
> +		add_sh0 = true;
> +
> +	if ((status & RDSTA_IF1) != RDSTA_IF1) {
> +		add_sh1 = true;
> +		if (add_sh0)
> +			desc_len += RNG_DESC_SH1_SIZE;
> +	}
> +
> +	if ((status & RDSTA_SKVN) != RDSTA_SKVN) {
> +		load_keys = true;
> +		desc_len += RNG_DESC_KEYS_SIZE;
> +	}
> +
> +	/* Copy the SH0 descriptor anyway */
> +	memcpy(pdesc, rng_inst_sh0_desc, sizeof(rng_inst_sh0_desc));
> +	pdesc += RNG_DESC_SH0_SIZE;
> +
> +	if (load_keys) {
> +		debug("RNG - Load keys\n");
> +		memcpy(pdesc, rng_inst_load_keys, sizeof(rng_inst_load_keys));
> +		pdesc += RNG_DESC_KEYS_SIZE;
> +	}
> +
> +	if (add_sh1) {
> +		if (add_sh0) {
> +			debug("RNG - Instantiation of SH0 and SH1\n");
> +			/* Add the sh1 descriptor */
> +			memcpy(pdesc, rng_inst_sh1_desc,
> +			       sizeof(rng_inst_sh1_desc));
> +		} else {
> +			debug("RNG - Instantiation of SH1 only\n");
> +			/* Modify the SH0 descriptor to instantiate only SH1 */
> +			desc[1] &= ~BM_ALGO_RNG_SH;
> +			desc[1] |= ALGO_RNG_SH(1);
> +		}
> +	}
> +
> +	/* Setup the descriptor size */
> +	desc[0] &= ~(0x3F);
> +	desc[0] |= CAAM_HDR_DESCLEN(desc_len);
> +}
> +
> +static int jr_reset(void)
> +{
> +	/*
> +	 * Function reset the Job Ring HW
> +	 * Reset is done in 2 steps:
> +	 *  - Flush all pending jobs (Set RESET bit)
> +	 *  - Reset the Job Ring (Set RESET bit second time)
> +	 */
> +	u16 timeout = 10000;
> +	u32 reg_val;
> +
> +	/* Mask interrupts to poll for reset completion status */
> +	setbits_le32(CAAM_JRCFGR0_LS, BM_JRCFGR_LS_IMSK);
> +
> +	/* Initiate flush (required prior to reset) */
> +	__raw_writel(JRCR_RESET, CAAM_JRCR0);
> +	do {
> +		reg_val = __raw_readl(CAAM_JRINTR0);
> +		reg_val &= BM_JRINTR_HALT;
> +	} while ((reg_val == JRINTR_HALT_ONGOING) && --timeout);
> +
> +	if (!timeout  || reg_val != JRINTR_HALT_DONE) {
> +		printf("Failed to flush job ring\n");
> +		return ERROR_ANY;
> +	}
> +
> +	/* Initiate reset */
> +	timeout = 100;
> +	__raw_writel(JRCR_RESET, CAAM_JRCR0);
> +	do {
> +		reg_val = __raw_readl(CAAM_JRCR0);
> +	} while ((reg_val & JRCR_RESET) && --timeout);
> +
> +	if (!timeout) {
> +		printf("Failed to reset job ring\n");
> +		return ERROR_ANY;
> +	}
> +
> +	return 0;
> +}
> +
> +static int do_job(u32 *desc)
> +{
> +	int ret;
> +	phys_addr_t p_desc = virt_to_phys(desc);
> +
> +	if (__raw_readl(CAAM_IRSAR0) == 0)
> +		return ERROR_ANY;
> +	g_jrdata.inrings[0].desc = p_desc;
> +
> +	flush_dcache_range((uintptr_t)g_jrdata.inrings & ALIGN_MASK,
> +			   ((uintptr_t)g_jrdata.inrings & ALIGN_MASK)
> +			   + ROUND(DESC_MAX_SIZE, ARCH_DMA_MINALIGN));
> +	flush_dcache_range((uintptr_t)desc & ALIGN_MASK,
> +			   ((uintptr_t)desc & ALIGN_MASK)
> +			   + ROUND(DESC_MAX_SIZE, ARCH_DMA_MINALIGN));
> +
> +	/* Inform HW that a new JR is available */
> +	__raw_writel(1, CAAM_IRJAR0);
> +	while (__raw_readl(CAAM_ORSFR0) == 0)
> +		;
> +
> +	flush_dcache_range((uintptr_t)g_jrdata.outrings & ALIGN_MASK,
> +			   ((uintptr_t)g_jrdata.outrings & ALIGN_MASK)
> +			   + ROUND(DESC_MAX_SIZE, ARCH_DMA_MINALIGN));
> +
> +	if (PTR2CAAMDMA(desc) == g_jrdata.outrings[0].desc) {
> +		ret = g_jrdata.outrings[0].status;
> +	} else {
> +		dump_error();
> +		ret = ERROR_ANY;
> +	}
> +
> +	/* Acknowledge interrupt */
> +	setbits_le32(CAAM_JRINTR0, JRINTR_JRI);
> +
> +	/* Remove the JR from the output list even if no JR caller found */
> +	__raw_writel(1, CAAM_ORJRR0);
> +
> +	return ret;
> +}
> +
> +static int do_cfg_jrqueue(void)
> +{
> +	u32 value = 0;
> +	phys_addr_t ip_base;
> +	phys_addr_t op_base;
> +
> +	/* check if already configured after relocation */
> +	if (g_jrdata.status == RING_RELOC_INIT)
> +		return 0;
> +
> +	/*
> +	 * jr configuration needs to be updated once, after relocation to ensure
> +	 * using the right buffers.
> +	 * When buffers are updated after relocation the flag RING_RELOC_INIT
> +	 * is used to prevent extra updates
> +	 */
> +	if (gd->flags & GD_FLG_RELOC) {
> +		g_jrdata.inrings  = (struct inring_entry *)
> +				    memalign(ARCH_DMA_MINALIGN,
> +					     ARCH_DMA_MINALIGN);
> +		g_jrdata.outrings = (struct outring_entry *)
> +				    memalign(ARCH_DMA_MINALIGN,
> +					     ARCH_DMA_MINALIGN);
> +		g_jrdata.desc = (u32 *)
> +				memalign(ARCH_DMA_MINALIGN, ARCH_DMA_MINALIGN);
> +		g_jrdata.status = RING_RELOC_INIT;
> +	} else {
> +		u32 align_idx = 0;
> +
> +		/* Ensure 64bits buffers addresses alignment */
> +		if ((uintptr_t)g_jrdata.raw_addr & 0x7)
> +			align_idx = 1;
> +		g_jrdata.inrings  = (struct inring_entry *)
> +				    (&g_jrdata.raw_addr[align_idx]);
> +		g_jrdata.outrings = (struct outring_entry *)
> +				    (&g_jrdata.raw_addr[align_idx + 2]);
> +		g_jrdata.desc = (u32 *)(&g_jrdata.raw_addr[align_idx + 4]);
> +		g_jrdata.status = RING_EARLY_INIT;
> +	}
> +
> +	if (!g_jrdata.inrings || !g_jrdata.outrings)
> +		return ERROR_ANY;
> +
> +	/* Configure the HW Job Rings */
> +	ip_base = virt_to_phys((void *)g_jrdata.inrings);
> +	op_base = virt_to_phys((void *)g_jrdata.outrings);
> +	__raw_writel(ip_base, CAAM_IRBAR0);
> +	__raw_writel(1, CAAM_IRSR0);
> +
> +	__raw_writel(op_base, CAAM_ORBAR0);
> +	__raw_writel(1, CAAM_ORSR0);
> +
> +	setbits_le32(CAAM_JRINTR0, JRINTR_JRI);
> +
> +	/*
> +	 * Configure interrupts but disable it:
> +	 * Optimization to generate an interrupt either when there are
> +	 * half of the job done or when there is a job done and
> +	 * 10 clock cycles elapse without new job complete
> +	 */
> +	value = 10 << BS_JRCFGR_LS_ICTT;
> +	value |= (1 << BS_JRCFGR_LS_ICDCT) & BM_JRCFGR_LS_ICDCT;
> +	value |= BM_JRCFGR_LS_ICEN;
> +	value |= BM_JRCFGR_LS_IMSK;
> +	__raw_writel(value, CAAM_JRCFGR0_LS);
> +
> +	/* Enable deco watchdog */
> +	setbits_le32(CAAM_MCFGR, BM_MCFGR_WDE);
> +
> +	return 0;
> +}
> +
> +static void do_clear_rng_error(void)
> +{
> +	u32 val;
> +
> +	val = __raw_readl(CAAM_RTMCTL);
> +
> +	if (val & (RTMCTL_ERR | RTMCTL_FCT_FAIL)) {
> +		setbits_le32(CAAM_RTMCTL, RTMCTL_ERR);
> +	val = __raw_readl(CAAM_RTMCTL);
> +	}
> +}
> +
> +static int do_instantiation(void)
> +{
> +	int ret = ERROR_ANY;
> +	u32 cha_vid_ls;
> +	u32 ent_delay;
> +	u32 status;
> +
> +	if (!g_jrdata.desc) {
> +		printf("%d: CAAM Descriptor allocation error\n", __LINE__);
> +		return ERROR_ANY;
> +	}
> +
> +	cha_vid_ls = __raw_readl(CAAM_CHAVID_LS);
> +
> +	/*
> +	 * If SEC has RNG version >= 4 and RNG state handle has not been
> +	 * already instantiated, do RNG instantiation
> +	 */
> +	if (((cha_vid_ls & BM_CHAVID_LS_RNGVID) >> BS_CHAVID_LS_RNGVID) < 4) {
> +		printf("%d: RNG already instantiated\n", __LINE__);
> +		return 0;
> +	}
> +
> +	ent_delay = TRNG_SDCTL_ENT_DLY_MIN;
> +
> +	do {
> +		/* Read the CAAM RNG status */
> +		status = __raw_readl(CAAM_RDSTA);
> +
> +		if ((status & RDSTA_IF0) != RDSTA_IF0) {
> +			/* Configure the RNG entropy delay */
> +			kick_trng(ent_delay);
> +			ent_delay += 400;
> +		}
> +
> +		do_clear_rng_error();
> +
> +		if ((status & (RDSTA_IF0 | RDSTA_IF1)) !=
> +				(RDSTA_IF0 | RDSTA_IF1)) {
> +			/* Prepare the instantiation descriptor */
> +			do_inst_desc(g_jrdata.desc, status);
> +
> +			/* Run Job */
> +			ret = do_job(g_jrdata.desc);
> +
> +			if (ret == ERROR_ANY) {
> +				/* CAAM JR failure ends here */
> +				printf("RNG Instantiation error\n");
> +				goto end_instantation;
> +			}
> +		} else {
> +			ret = SUCCESS;
> +			printf("RNG instantiation done (%d)\n", ent_delay);
> +			goto end_instantation;
> +		}
> +	} while (ent_delay < TRNG_SDCTL_ENT_DLY_MAX);
> +
> +	printf("RNG Instantation Failure - Entropy delay (%d)\n", ent_delay);
> +	ret = ERROR_ANY;
> +
> +end_instantation:
> +	return ret;
> +}
> +
> +static void rng_init(void)
> +{
> +	int  ret;
> +
> +	ret = jr_reset();
> +	if (ret != SUCCESS) {
> +		printf("Error CAAM JR reset\n");
> +		return;
> +	}
> +
> +	ret = do_instantiation();
> +
> +	if (ret != SUCCESS)
> +		printf("Error do_instantiation\n");
> +
> +	jr_reset();
> +
> +	return;
> +}
> +
> diff --git a/drivers/crypto/fsl_caam_internal.h b/drivers/crypto/fsl_caam_internal.h
> new file mode 100644
> index 0000000000..837562d3c4
> --- /dev/null
> +++ b/drivers/crypto/fsl_caam_internal.h
> @@ -0,0 +1,229 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright (c) 2012-2016, Freescale Semiconductor, Inc.
> + * Copyright 2018 NXP
> + */
> +
> +#ifndef __CAAM_INTERNAL_H__
> +#define __CAAM_INTERNAL_H__
> +
> +/* 4kbyte pages */
> +#define CAAM_SEC_RAM_START_ADDR CAAM_ARB_BASE_ADDR
> +
> +#define SEC_MEM_PAGE0       CAAM_SEC_RAM_START_ADDR
> +#define SEC_MEM_PAGE1       (CAAM_SEC_RAM_START_ADDR + 0x1000)
> +#define SEC_MEM_PAGE2       (CAAM_SEC_RAM_START_ADDR + 0x2000)
> +#define SEC_MEM_PAGE3       (CAAM_SEC_RAM_START_ADDR + 0x3000)
> +
> +/* Configuration and special key registers */
> +#define CAAM_MCFGR          (CONFIG_SYS_FSL_SEC_ADDR + 0x0004)
> +#define CAAM_SCFGR          (CONFIG_SYS_FSL_SEC_ADDR + 0x000c)
> +#define CAAM_JR0MIDR        (CONFIG_SYS_FSL_SEC_ADDR + 0x0010)
> +#define CAAM_JR1MIDR        (CONFIG_SYS_FSL_SEC_ADDR + 0x0018)
> +#define CAAM_DECORR         (CONFIG_SYS_FSL_SEC_ADDR + 0x009c)
> +#define CAAM_DECO0MID       (CONFIG_SYS_FSL_SEC_ADDR + 0x00a0)
> +#define CAAM_DAR            (CONFIG_SYS_FSL_SEC_ADDR + 0x0120)
> +#define CAAM_DRR            (CONFIG_SYS_FSL_SEC_ADDR + 0x0124)
> +#define CAAM_JDKEKR         (CONFIG_SYS_FSL_SEC_ADDR + 0x0400)
> +#define CAAM_TDKEKR         (CONFIG_SYS_FSL_SEC_ADDR + 0x0420)
> +#define CAAM_TDSKR          (CONFIG_SYS_FSL_SEC_ADDR + 0x0440)
> +#define CAAM_SKNR           (CONFIG_SYS_FSL_SEC_ADDR + 0x04e0)
> +#define CAAM_SMSTA          (CONFIG_SYS_FSL_SEC_ADDR + 0x0FB4)
> +#define CAAM_STA            (CONFIG_SYS_FSL_SEC_ADDR + 0x0FD4)
> +#define CAAM_SMPO_0         (CONFIG_SYS_FSL_SEC_ADDR + 0x1FBC)
> +#define CAAM_CHAVID_LS      (CONFIG_SYS_FSL_SEC_ADDR + 0x0FEC)
> +#define CAAM_FAR            (CONFIG_SYS_FSL_SEC_ADDR + 0x0FC0)
> +#define CAAM_FAMR           (CONFIG_SYS_FSL_SEC_ADDR + 0x0FC8)
> +#define CAAM_FADR           (CONFIG_SYS_FSL_SEC_ADDR + 0x0FCC)
> +
> +/* RNG registers */
> +#define CAAM_RTMCTL         (CONFIG_SYS_FSL_SEC_ADDR + 0x0600)
> +#define CAAM_RTSCMISC       (CONFIG_SYS_FSL_SEC_ADDR + 0x0604)
> +#define CAAM_RTPKRRNG       (CONFIG_SYS_FSL_SEC_ADDR + 0x0608)
> +#define CAAM_RTPKRMAX       (CONFIG_SYS_FSL_SEC_ADDR + 0x060C)
> +#define CAAM_RTSDCTL        (CONFIG_SYS_FSL_SEC_ADDR + 0x0610)
> +#define CAAM_RTFRQMIN       (CONFIG_SYS_FSL_SEC_ADDR + 0x0618)
> +#define CAAM_RTFRQMAX       (CONFIG_SYS_FSL_SEC_ADDR + 0x061C)
> +#define CAAM_RTSCML         (CONFIG_SYS_FSL_SEC_ADDR + 0x0620)
> +#define CAAM_RTSCR1L        (CONFIG_SYS_FSL_SEC_ADDR + 0x0624)
> +#define CAAM_RTSCR2L        (CONFIG_SYS_FSL_SEC_ADDR + 0x0628)
> +#define CAAM_RTSCR3L        (CONFIG_SYS_FSL_SEC_ADDR + 0x062C)
> +#define CAAM_RTSCR4L        (CONFIG_SYS_FSL_SEC_ADDR + 0x0630)
> +#define CAAM_RTSCR5L        (CONFIG_SYS_FSL_SEC_ADDR + 0x0634)
> +#define CAAM_RTSCR6PL       (CONFIG_SYS_FSL_SEC_ADDR + 0x0638)
> +#define CAAM_RTSTATUS       (CONFIG_SYS_FSL_SEC_ADDR + 0x063C)
> +#define CAAM_RDSTA          (CONFIG_SYS_FSL_SEC_ADDR + 0x06C0)
> +
> +/* Job Ring 0 registers */
> +#define CAAM_IRBAR0         (CONFIG_SYS_FSL_SEC_ADDR + 0x1004)
> +#define CAAM_IRSR0          (CONFIG_SYS_FSL_SEC_ADDR + 0x100c)
> +#define CAAM_IRSAR0         (CONFIG_SYS_FSL_SEC_ADDR + 0x1014)
> +#define CAAM_IRJAR0         (CONFIG_SYS_FSL_SEC_ADDR + 0x101c)
> +#define CAAM_ORBAR0         (CONFIG_SYS_FSL_SEC_ADDR + 0x1024)
> +#define CAAM_ORSR0          (CONFIG_SYS_FSL_SEC_ADDR + 0x102c)
> +#define CAAM_ORJRR0         (CONFIG_SYS_FSL_SEC_ADDR + 0x1034)
> +#define CAAM_ORSFR0         (CONFIG_SYS_FSL_SEC_ADDR + 0x103c)
> +#define CAAM_JRSTAR0        (CONFIG_SYS_FSL_SEC_ADDR + 0x1044)
> +#define CAAM_JRINTR0        (CONFIG_SYS_FSL_SEC_ADDR + 0x104c)
> +#define CAAM_JRCFGR0_MS     (CONFIG_SYS_FSL_SEC_ADDR + 0x1050)
> +#define CAAM_JRCFGR0_LS     (CONFIG_SYS_FSL_SEC_ADDR + 0x1054)
> +#define CAAM_IRRIR0         (CONFIG_SYS_FSL_SEC_ADDR + 0x105c)
> +#define CAAM_ORWIR0         (CONFIG_SYS_FSL_SEC_ADDR + 0x1064)
> +#define CAAM_JRCR0          (CONFIG_SYS_FSL_SEC_ADDR + 0x106c)
> +#define CAAM_SMCJR0         (CONFIG_SYS_FSL_SEC_ADDR + 0x10f4)
> +#define CAAM_SMCSJR0        (CONFIG_SYS_FSL_SEC_ADDR + 0x10fc)
> +#define CAAM_SMAPJR0(y)     (CONFIG_SYS_FSL_SEC_ADDR + 0x1104 + y * 16)
> +#define CAAM_SMAG2JR0(y)    (CONFIG_SYS_FSL_SEC_ADDR + 0x1108 + y * 16)
> +#define CAAM_SMAG1JR0(y)    (CONFIG_SYS_FSL_SEC_ADDR + 0x110C + y * 16)
> +#define CAAM_SMAPJR0_PRTN1  (CONFIG_SYS_FSL_SEC_ADDR + 0x1114)
> +#define CAAM_SMAG2JR0_PRTN1 (CONFIG_SYS_FSL_SEC_ADDR + 0x1118)
> +#define CAAM_SMAG1JR0_PRTN1 (CONFIG_SYS_FSL_SEC_ADDR + 0x111c)
> +#define CAAM_SMPO           (CONFIG_SYS_FSL_SEC_ADDR + 0x1fbc)
> +
> +#define DESC_MAX_SIZE       (0x40)        /* Descriptor max size */
> +#define JRCFG_LS_IMSK       (0x01)        /* Interrupt Mask */
> +#define JR_MID              (0x02)        /* Matches ROM configuration */
> +#define KS_G1               BIT(JR_MID)   /* CAAM only */
> +#define PERM                (0x0000B008)  /* Clear on release, lock SMAP,
> +					   * lock SMAG and group 1 Blob
> +					   */
> +
> +#define CMD_PAGE_ALLOC      (0x1)
> +#define CMD_PAGE_DEALLOC    (0x2)
> +#define CMD_PART_DEALLOC    (0x3)
> +#define CMD_INQUIRY         (0x5)
> +#define PAGE(x)             ((x) << 16)
> +#define PARTITION(x)        ((x) << 8)
> +
> +#define SMCSJR_AERR         (3 << 12)
> +#define SMCSJR_CERR         (3 << 14)
> +#define CMD_COMPLETE        (3 << 14)
> +
> +#define SMCSJR_PO           (3 << 6)
> +#define PAGE_AVAILABLE      (0)
> +#define PAGE_OWNED          (3 << 6)
> +
> +#define PARTITION_OWNER(x)  (0x3 << ((x) * 2))
> +
> +#define CAAM_BUSY_MASK      (0x00000001) /* BUSY from status reg */
> +#define CAAM_IDLE_MASK      (0x00000002) /* IDLE from status reg */
> +#define CAAM_MCFGR_SWRST    BIT(31)      /* CAAM SW reset */
> +#define CAAM_MCFGR_DMARST   BIT(28)      /* CAAM DMA reset */
> +
> +#define JOB_RING_ENTRIES    (1)
> +#define JOB_RING_STS        (0xF << 28)
> +
> +/** OSC_DIV in RNG trim fuses */
> +#define RNG_TRIM_OSC_DIV    (0)
> +/** ENT_DLY multiplier in RNG trim fuses */
> +#define TRNG_SDCTL_ENT_DLY_MIN (3200)
> +#define TRNG_SDCTL_ENT_DLY_MAX (4800)
> +
> +#define RTMCTL_PGM       BIT(16)
> +#define RTMCTL_ERR       BIT(12)
> +#define RTMCTL_RST       BIT(6)
> +#define RDSTA_IF0        (1)
> +#define RDSTA_IF1        (2)
> +#define RDSTA_SKVN       BIT(30)
> +#define JRCR_RESET       (1)
> +#define RTMCTL_FCT_FAIL  BIT(8)
> +
> +#define BS_TRNG_ENT_DLY     (16)
> +#define BM_TRNG_ENT_DLY     (0xffff << BS_TRNG_ENT_DLY)
> +#define BM_TRNG_SAMP_MODE   (3)
> +#define TRNG_SAMP_MODE_RAW_ES_SC (1)
> +#define BS_JRINTR_HALT      (2)
> +#define BM_JRINTR_HALT      (0x3 << BS_JRINTR_HALT)
> +#define JRINTR_HALT_ONGOING (0x1 << BS_JRINTR_HALT)
> +#define JRINTR_HALT_DONE    (0x2 << BS_JRINTR_HALT)
> +#define JRINTR_JRI          (0x1)
> +#define BS_JRCFGR_LS_ICTT   (16)
> +#define BM_JRCFGR_LS_ICTT   (0xFFFF << BS_JRCFGR_LS_ICTT)
> +#define BS_JRCFGR_LS_ICDCT  (8)
> +#define BM_JRCFGR_LS_ICDCT  (0xFF << BS_JRCFGR_LS_ICDCT)
> +#define BS_JRCFGR_LS_ICEN   (1)
> +#define BM_JRCFGR_LS_ICEN   (0x1 << BS_JRCFGR_LS_ICEN)
> +#define BS_JRCFGR_LS_IMSK   (0)
> +#define BM_JRCFGR_LS_IMSK   (0x1 << BS_JRCFGR_LS_IMSK)
> +#define BS_CHAVID_LS_RNGVID (16)
> +#define BM_CHAVID_LS_RNGVID (0xF << BS_CHAVID_LS_RNGVID)
> +#define BS_MCFGR_WDE        (30)
> +#define BM_MCFGR_WDE        (0x1 << BS_MCFGR_WDE)
> +
> +typedef enum {
> +	PAGE_0,
> +	PAGE_1,
> +	PAGE_2,
> +	PAGE_3,
> +} page_num_e;
> +
> +typedef enum {
> +	PARTITION_0,
> +	PARTITION_1,
> +	PARTITION_2,
> +	PARTITION_3,
> +	PARTITION_4,
> +	PARTITION_5,
> +	PARTITION_6,
> +	PARTITION_7,
> +} partition_num_e;
> +
> +/*
> + * Local defines
> + */
> +/* arm v7 need 64 align */
> +#define ALIGN_MASK     ~(ARCH_DMA_MINALIGN - 1)
> +/* caam dma and pointer conversion for arm and arm64 architectures */
> +#ifdef CONFIG_IMX_CONFIG
> +  #define PTR2CAAMDMA(x)  (u32)((uintptr_t)(x) & 0xffffffff)
> +  #define CAAMDMA2PTR(x)  (uintptr_t)((x) & 0xffffffff)
> +#else
> +  #define PTR2CAAMDMA(x)  (uintptr_t)(x)
> +  #define CAAMDMA2PTR(x)  (uintptr_t)(x)
> +#endif
> +#define RING_EARLY_INIT   (0x01)
> +#define RING_RELOC_INIT   (0x02)
> +
> +#define CAAM_HDR_CTYPE            (0x16u << 27)
> +#define CAAM_HDR_ONE              BIT(23)
> +#define CAAM_HDR_START_INDEX(x)   (((x) & 0x3F) << 16)
> +#define CAAM_HDR_DESCLEN(x)       ((x) & 0x3F)
> +#define CAAM_PROTOP_CTYPE         (0x10u << 27)
> +
> +/* State Handle */
> +#define BS_ALGO_RNG_SH            (4)
> +#define BM_ALGO_RNG_SH            (0x3 << BS_ALGO_RNG_SH)
> +#define ALGO_RNG_SH(id)           (((id) << BS_ALGO_RNG_SH) & BM_ALGO_RNG_SH)
> +
> +/* Secure Key */
> +#define BS_ALGO_RNG_SK            (12)
> +#define BM_ALGO_RNG_SK            BIT(BS_ALGO_RNG_SK)
> +
> +/* State */
> +#define BS_ALGO_RNG_AS            (2)
> +#define BM_ALGO_RNG_AS            (0x3 << BS_ALGO_RNG_AS)
> +#define ALGO_RNG_GENERATE         (0x0 << BS_ALGO_RNG_AS)
> +#define ALGO_RNG_INSTANTIATE      BIT(BS_ALGO_RNG_AS)
> +
> +#define CAAM_C1_RNG               ((0x50 << 16) | (2 << 24))
> +
> +#define BS_JUMP_LOCAL_OFFSET      (0)
> +#define BM_JUMP_LOCAL_OFFSET      (0xFF << BS_JUMP_LOCAL_OFFSET)
> +
> +#define CAAM_C1_JUMP              ((0x14u << 27) | (1 << 25))
> +#define CAAM_JUMP_LOCAL           (0 << 20)
> +#define CAAM_JUMP_TST_ALL_COND_TRUE (0 << 16)
> +#define CAAM_JUMP_OFFSET(off)     (((off) << BS_JUMP_LOCAL_OFFSET) \
> +				& BM_JUMP_LOCAL_OFFSET)
> +
> +#define CAAM_C0_LOAD_IMM          ((0x2 << 27) | (1 << 23))
> +#define CAAM_DST_CLEAR_WRITTEN    (0x8 << 16)
> +
> +#define RNG_DESC_SH0_SIZE   (ARRAY_SIZE(rng_inst_sh0_desc))
> +#define RNG_DESC_SH1_SIZE   (ARRAY_SIZE(rng_inst_sh1_desc))
> +#define RNG_DESC_KEYS_SIZE  (ARRAY_SIZE(rng_inst_load_keys))
> +#define RNG_DESC_MAX_SIZE   (RNG_DESC_SH0_SIZE + \
> +			RNG_DESC_SH1_SIZE + \
> +			RNG_DESC_KEYS_SIZE)
> +
> +#endif /* __CAAM_INTERNAL_H__ */
> diff --git a/include/fsl_caam.h b/include/fsl_caam.h
> new file mode 100644
> index 0000000000..c4345ae2b6
> --- /dev/null
> +++ b/include/fsl_caam.h
> @@ -0,0 +1,24 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright (c) 2012-2016, Freescale Semiconductor, Inc.
> + * Copyright 2018 NXP
> + */
> +
> +#ifndef __CAAM_H__
> +#define	__CAAM_H__
> +
> +#if !defined(SUCCESS)
> +#define SUCCESS (0)
> +#endif
> +
> +#define ERROR_ANY           (-1)
> +#define ERROR_IN_PAGE_ALLOC (1)
> +
> +void caam_open(void);
> +
> +u32 caam_gen_blob(u32 plain_data_addr, u32 blob_addr, u32 size);
> +
> +u32 caam_decap_blob(u32 plain_text, u32 blob_addr, u32 size);
> +u32 caam_hwrng(uint8_t *output_ptr, u32 output_len);
> +
> +#endif /* __CAAM_H__ */
> 

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH 31/37] crypto: caam: Add fsl caam driver
  2021-04-08 18:24   ` Stefano Babic
@ 2021-07-08  8:02     ` Peng Fan (OSS)
  2021-07-08  8:28       ` Stefano Babic
  0 siblings, 1 reply; 42+ messages in thread
From: Peng Fan (OSS) @ 2021-07-08  8:02 UTC (permalink / raw)
  To: Stefano Babic, festevam; +Cc: uboot-imx, u-boot, Ye Li, Aymen Sghaier, Peng Fan

Hi Stefano,

On 2021/4/9 2:24, Stefano Babic wrote:
> Hi Peng,
> 
> On 25.03.21 10:30, Peng Fan (OSS) wrote:
>> From: Ye Li <ye.li@nxp.com>
>>
>> Add the fsl CAAM driver and new commands to implement DEK blob 
>> operations,
>> like "caam genblob" to generate encrypted blob and "caam decap" to output
>> orignal plain data.
>>
>>   The following reasons lead to instantiate the TRNG into U-Boot/SPL:
>>
>>   - On some i.MX platforms Linux Kernel could not instantiate RNG
>>   - RNG could be used/needed by M4/M0 cores before Kernel stage
>>   - Having the RNG instantiation implemented only once for
>>     almost i.MX platforms
> 
> Is this a CAAM driver ? But we have already drivers/crypto/fsl for CAAM. 
> Which is the reason for it and why it is not merged with the existing 
> driver ?

I missed this email, just check my mailbox and see this.
My bad. I'll NXP people to merge the driver.

Thanks,
Peng.

> 
> Best regards,
> Stefano Babic
> 
>>
>> Signed-off-by: Aymen Sghaier <aymen.sghaier@nxp.com>
>> Signed-off-by: Ye Li <ye.li@nxp.com>
>> Signed-off-by: Peng Fan <peng.fan@nxp.com>
>> ---
>>   arch/arm/include/asm/arch-mx7/crm_regs.h |   8 +
>>   cmd/Kconfig                              |   6 +
>>   cmd/Makefile                             |   1 +
>>   cmd/cmd_fsl_caam.c                       |  88 +++
>>   drivers/crypto/Makefile                  |   1 +
>>   drivers/crypto/fsl_caam.c                | 715 +++++++++++++++++++++++
>>   drivers/crypto/fsl_caam_internal.h       | 229 ++++++++
>>   include/fsl_caam.h                       |  24 +
>>   8 files changed, 1072 insertions(+)
>>   create mode 100644 cmd/cmd_fsl_caam.c
>>   create mode 100644 drivers/crypto/fsl_caam.c
>>   create mode 100644 drivers/crypto/fsl_caam_internal.h
>>   create mode 100644 include/fsl_caam.h
>>
>> diff --git a/arch/arm/include/asm/arch-mx7/crm_regs.h 
>> b/arch/arm/include/asm/arch-mx7/crm_regs.h
>> index bfa68a9d2a..a000ae05d7 100644
>> --- a/arch/arm/include/asm/arch-mx7/crm_regs.h
>> +++ b/arch/arm/include/asm/arch-mx7/crm_regs.h
>> @@ -1998,6 +1998,14 @@ struct mxc_ccm_anatop_reg {
>>   #define TEMPMON_HW_ANADIG_TEMPSENSE_TRIM_TOG_T_MUX_ADDR_SHIFT 29
>>   #define TEMPMON_HW_ANADIG_TEMPSENSE_TRIM_TOG_T_MUX_ADDR(x) 
>> (((uint32_t)(((uint32_t)(x))<<TEMPMON_HW_ANADIG_TEMPSENSE_TRIM_TOG_T_MUX_ADDR_SHIFT))&TEMPMON_HW_ANADIG_TEMPSENSE_TRIM_TOG_T_MUX_ADDR_MASK) 
>>
>> +#define MXC_CCM_CCGR36_CAAM_DOMAIN3_OFFSET                     12
>> +#define MXC_CCM_CCGR36_CAAM_DOMAIN3_MASK                       (3 << 
>> MXC_CCM_CCGR36_CAAM_DOMAIN3_OFFSET)
>> +#define MXC_CCM_CCGR36_CAAM_DOMAIN2_OFFSET                     8
>> +#define MXC_CCM_CCGR36_CAAM_DOMAIN2_MASK                       (3 << 
>> MXC_CCM_CCGR36_CAAM_DOMAIN2_OFFSET)
>> +#define MXC_CCM_CCGR36_CAAM_DOMAIN1_OFFSET                     4
>> +#define MXC_CCM_CCGR36_CAAM_DOMAIN1_MASK                       (3 << 
>> MXC_CCM_CCGR36_CAAM_DOMAIN1_OFFSET)
>> +#define MXC_CCM_CCGR36_CAAM_DOMAIN0_OFFSET                     0
>> +#define MXC_CCM_CCGR36_CAAM_DOMAIN0_MASK                       (3 << 
>> MXC_CCM_CCGR36_CAAM_DOMAIN0_OFFSET)
>>   #define CCM_GPR(i)        (CCM_BASE_ADDR + CCM_GPR0_OFFSET + 0x10 * 
>> (i))
>>   #define CCM_OBSERVE(i)        (CCM_BASE_ADDR + CCM_OBSERVE0_OFFSET + 
>> 0x10 * (i))
>> diff --git a/cmd/Kconfig b/cmd/Kconfig
>> index f73de2d75a..aeecfed974 100644
>> --- a/cmd/Kconfig
>> +++ b/cmd/Kconfig
>> @@ -397,6 +397,12 @@ config CMD_SPL_WRITE_SIZE
>>         flash used by Falcon-mode boot. See the documentation until 
>> CMD_SPL
>>         for detail.
>> +config CMD_FSL_CAAM_KB
>> +    bool "Freescale i.MX CAAM command"
>> +    help
>> +      Implement the "caam" command to generate DEK blob for one block 
>> of data
>> +      or decap the DEK blob to its original data.
>> +
>>   config CMD_THOR_DOWNLOAD
>>       bool "thor - TIZEN 'thor' download"
>>       select DFU
>> diff --git a/cmd/Makefile b/cmd/Makefile
>> index 567e2b79d2..d46ffd7021 100644
>> --- a/cmd/Makefile
>> +++ b/cmd/Makefile
>> @@ -70,6 +70,7 @@ obj-$(CONFIG_CMD_FLASH) += flash.o
>>   obj-$(CONFIG_CMD_FPGA) += fpga.o
>>   obj-$(CONFIG_CMD_FPGAD) += fpgad.o
>>   obj-$(CONFIG_CMD_FS_GENERIC) += fs.o
>> +obj-$(CONFIG_CMD_FSL_CAAM_KB) += cmd_fsl_caam.o
>>   obj-$(CONFIG_CMD_FUSE) += fuse.o
>>   obj-$(CONFIG_CMD_GETTIME) += gettime.o
>>   obj-$(CONFIG_CMD_GPIO) += gpio.o
>> diff --git a/cmd/cmd_fsl_caam.c b/cmd/cmd_fsl_caam.c
>> new file mode 100644
>> index 0000000000..d41d672320
>> --- /dev/null
>> +++ b/cmd/cmd_fsl_caam.c
>> @@ -0,0 +1,88 @@
>> +// SPDX-License-Identifier: GPL-2.0+
>> +/*
>> + * Copyright (C) 2012-2016 Freescale Semiconductor, Inc.
>> + */
>> +
>> +#include <common.h>
>> +#include <command.h>
>> +#include <fsl_caam.h>
>> +
>> +static int do_caam(cmd_tbl_t *cmdtp, int flag, int argc, char * const 
>> argv[])
>> +{
>> +    int ret, i;
>> +
>> +    if (argc < 2)
>> +        return CMD_RET_USAGE;
>> +
>> +    if (strcmp(argv[1], "genblob") == 0) {
>> +        if (argc != 5)
>> +            return CMD_RET_USAGE;
>> +
>> +        void *data_addr;
>> +        void *blob_addr;
>> +        int size;
>> +
>> +        data_addr = (void *)simple_strtoul(argv[2], NULL, 16);
>> +        blob_addr = (void *)simple_strtoul(argv[3], NULL, 16);
>> +        size = simple_strtoul(argv[4], NULL, 10);
>> +        if (size <= 48)
>> +            return CMD_RET_USAGE;
>> +
>> +        caam_open();
>> +        ret = caam_gen_blob((uint32_t)data_addr, (uint32_t)blob_addr, 
>> (uint32_t)size);
>> +
>> +        if (ret != SUCCESS) {
>> +            printf("Error during blob encap operation: 0x%x\n", ret);
>> +            return 0;
>> +        }
>> +
>> +        /* Print the generated DEK blob */
>> +        printf("DEK blob is available at 0x%08X and equals:\n", 
>> (unsigned int)blob_addr);
>> +        for (i = 0; i < size; i++)
>> +            printf("%02X ", ((uint8_t *)blob_addr)[i]);
>> +        printf("\n\n");
>> +
>> +        return 1;
>> +    } else if (strcmp(argv[1], "decap") == 0) {
>> +        if (argc != 5)
>> +            return CMD_RET_USAGE;
>> +
>> +        void *blob_addr;
>> +        void *data_addr;
>> +        int size;
>> +
>> +        blob_addr = (void *)simple_strtoul(argv[2], NULL, 16);
>> +        data_addr = (void *)simple_strtoul(argv[3], NULL, 16);
>> +        size      = simple_strtoul(argv[4], NULL, 10);
>> +        if (size <= 48)
>> +            return CMD_RET_USAGE;
>> +
>> +        caam_open();
>> +        ret = caam_decap_blob((uint32_t)(data_addr), 
>> (uint32_t)(blob_addr), (uint32_t)size);
>> +        if (ret != SUCCESS) {
>> +            printf("Error during blob decap operation: 0x%x\n", ret);
>> +        } else {
>> +            printf("Success, blob decap at SM PAGE1 original data 
>> is:\n");
>> +            int i = 0;
>> +
>> +            for (i = 0; i < size; i++) {
>> +                printf("0x%x  ", *(unsigned char *)(data_addr + i));
>> +                if (i % 16 == 0)
>> +                    printf("\n");
>> +            }
>> +            printf("\n");
>> +        }
>> +
>> +        return 1;
>> +    }
>> +
>> +    return CMD_RET_USAGE;
>> +}
>> +
>> +U_BOOT_CMD(
>> +    caam, 5, 1, do_caam,
>> +    "Freescale i.MX CAAM command",
>> +    "caam genblob data_addr blob_addr data_size\n \
>> +    caam decap blobaddr data_addr data_size\n \
>> +    \n "
>> +    );
>> diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
>> index efbd1d3fca..6069dd5b29 100644
>> --- a/drivers/crypto/Makefile
>> +++ b/drivers/crypto/Makefile
>> @@ -4,5 +4,6 @@
>>   #     http://www.samsung.com
>>   obj-$(CONFIG_EXYNOS_ACE_SHA)    += ace_sha.o
>> +obj-$(CONFIG_FSL_CAAM_KB)      += fsl_caam.o
>>   obj-y += rsa_mod_exp/
>>   obj-y += fsl/
>> diff --git a/drivers/crypto/fsl_caam.c b/drivers/crypto/fsl_caam.c
>> new file mode 100644
>> index 0000000000..ccdf131635
>> --- /dev/null
>> +++ b/drivers/crypto/fsl_caam.c
>> @@ -0,0 +1,715 @@
>> +// SPDX-License-Identifier: GPL-2.0+
>> +/*
>> + * Copyright (c) 2012-2016, Freescale Semiconductor, Inc.
>> + */
>> +
>> +#include <common.h>
>> +#include <malloc.h>
>> +#include <memalign.h>
>> +#include <asm/io.h>
>> +#ifndef CONFIG_ARCH_MX7ULP
>> +#include <asm/arch/crm_regs.h>
>> +#else
>> +#include <asm/arch/pcc.h>
>> +#endif /* CONFIG_ARCH_MX7ULP */
>> +#include "fsl_caam_internal.h"
>> +#include "fsl/desc_constr.h"
>> +#include <fsl_caam.h>
>> +#include <cpu_func.h>
>> +
>> +DECLARE_GLOBAL_DATA_PTR;
>> +
>> +static void rng_init(void);
>> +static void caam_clock_enable(void);
>> +static int do_cfg_jrqueue(void);
>> +static int do_job(u32 *desc);
>> +static int jr_reset(void);
>> +
>> +/*
>> + * Structures
>> + */
>> +/* Definition of input ring object */
>> +struct inring_entry {
>> +    u32 desc; /* Pointer to input descriptor */
>> +};
>> +
>> +/* Definition of output ring object */
>> +struct outring_entry {
>> +    u32 desc;   /* Pointer to output descriptor */
>> +    u32 status; /* Status of the Job Ring       */
>> +};
>> +
>> +/* Main job ring data structure */
>> +struct jr_data_st {
>> +    struct inring_entry  *inrings;
>> +    struct outring_entry *outrings;
>> +    u32 status;  /* Ring buffers init status */
>> +    u32 *desc;   /* Pointer to output descriptor */
>> +    u32 raw_addr[DESC_MAX_SIZE * 2];
>> +};
>> +
>> +/*
>> + * Global variables
>> + */
>> +#if defined(CONFIG_SPL_BUILD)
>> +static struct jr_data_st g_jrdata = {0};
>> +#else
>> +static struct jr_data_st g_jrdata = {0, 0, 0xFFFFFFFF};
>> +#endif
>> +
>> +static u8 skeymod[] = {
>> +    0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08,
>> +    0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00
>> +};
>> +
>> +/*
>> + * Local functions
>> + */
>> +static void dump_error(void)
>> +{
>> +    int i;
>> +
>> +    debug("Dump CAAM Error\n");
>> +    debug("MCFGR 0x%08X\n", __raw_readl(CAAM_MCFGR));
>> +    debug("FAR  0x%08X\n", __raw_readl(CAAM_FAR));
>> +    debug("FAMR 0x%08X\n", __raw_readl(CAAM_FAMR));
>> +    debug("FADR 0x%08X\n", __raw_readl(CAAM_FADR));
>> +    debug("CSTA 0x%08X\n", __raw_readl(CAAM_STA));
>> +    debug("RTMCTL 0x%X\n", __raw_readl(CAAM_RTMCTL));
>> +    debug("RTSTATUS 0x%X\n", __raw_readl(CAAM_RTSTATUS));
>> +    debug("RDSTA 0x%X\n", __raw_readl(CAAM_RDSTA));
>> +
>> +    for (i = 0; i < desc_len(g_jrdata.desc); i++)
>> +        debug("desc[%d]: 0x%08x\n", i, g_jrdata.desc[i]);
>> +}
>> +
>> +/*!
>> + * Secure memory run command.
>> + *
>> + * @param   sec_mem_cmd  Secure memory command register
>> + * @return  cmd_status  Secure memory command status register
>> + */
>> +u32 secmem_set_cmd_1(u32 sec_mem_cmd)
>> +{
>> +    u32 temp_reg;
>> +
>> +    __raw_writel(sec_mem_cmd, CAAM_SMCJR0);
>> +    do {
>> +        temp_reg = __raw_readl(CAAM_SMCSJR0);
>> +    } while (temp_reg & CMD_COMPLETE);
>> +
>> +    return temp_reg;
>> +}
>> +
>> +/*!
>> + * Use CAAM to decapsulate a blob to secure memory.
>> + * Such blob of secret key cannot be read once decrypted,
>> + * but can still be used for enc/dec operation of user's data.
>> + *
>> + * @param   blob_addr  Location address of the blob.
>> + *
>> + * @return  SUCCESS or ERROR_XXX
>> + */
>> +u32 caam_decap_blob(u32 plain_text, u32 blob_addr, u32 size)
>> +{
>> +    u32 ret = SUCCESS;
>> +    u32 key_sz = sizeof(skeymod);
>> +    u32 *decap_desc = g_jrdata.desc;
>> +
>> +    /* prepare job descriptor */
>> +    init_job_desc(decap_desc, 0);
>> +    append_load(decap_desc, PTR2CAAMDMA(skeymod), key_sz,
>> +            LDST_CLASS_2_CCB | LDST_SRCDST_BYTE_KEY);
>> +    append_seq_in_ptr_intlen(decap_desc, blob_addr, size + 48, 0);
>> +    append_seq_out_ptr_intlen(decap_desc, plain_text, size, 0);
>> +    append_operation(decap_desc, OP_TYPE_DECAP_PROTOCOL | 
>> OP_PCLID_BLOB);
>> +
>> +    flush_dcache_range((uintptr_t)blob_addr & ALIGN_MASK,
>> +               ((uintptr_t)blob_addr & ALIGN_MASK)
>> +                + ROUND(2 * size, ARCH_DMA_MINALIGN));
>> +    flush_dcache_range((uintptr_t)plain_text & ALIGN_MASK,
>> +               (plain_text & ALIGN_MASK)
>> +               + ROUND(2 * size, ARCH_DMA_MINALIGN));
>> +
>> +    /* Run descriptor with result written to blob buffer */
>> +    ret = do_job(decap_desc);
>> +
>> +    if (ret != SUCCESS)
>> +        printf("Error: blob decap job failed 0x%x\n", ret);
>> +
>> +    return ret;
>> +}
>> +
>> +/*!
>> + * Use CAAM to generate a blob.
>> + *
>> + * @param   plain_data_addr  Location address of the plain data.
>> + * @param   blob_addr  Location address of the blob.
>> + *
>> + * @return  SUCCESS or ERROR_XXX
>> + */
>> +u32 caam_gen_blob(u32 plain_data_addr, u32 blob_addr, u32 size)
>> +{
>> +    u32 ret = SUCCESS;
>> +    u32 key_sz = sizeof(skeymod);
>> +    u32 *encap_desc = g_jrdata.desc;
>> +    /* Buffer to hold the resulting blob */
>> +    u8 *blob = (u8 *)CAAMDMA2PTR(blob_addr);
>> +
>> +    /* initialize the blob array */
>> +    memset(blob, 0, size);
>> +
>> +    /* prepare job descriptor */
>> +    init_job_desc(encap_desc, 0);
>> +    append_load(encap_desc, PTR2CAAMDMA(skeymod), key_sz,
>> +            LDST_CLASS_2_CCB | LDST_SRCDST_BYTE_KEY);
>> +    append_seq_in_ptr_intlen(encap_desc, plain_data_addr, size, 0);
>> +    append_seq_out_ptr_intlen(encap_desc, PTR2CAAMDMA(blob), size + 
>> 48, 0);
>> +    append_operation(encap_desc, OP_TYPE_ENCAP_PROTOCOL | 
>> OP_PCLID_BLOB);
>> +
>> +    flush_dcache_range((uintptr_t)plain_data_addr & ALIGN_MASK,
>> +               (plain_data_addr & ALIGN_MASK)
>> +               + ROUND(2 * size, ARCH_DMA_MINALIGN));
>> +    flush_dcache_range((uintptr_t)blob & ALIGN_MASK,
>> +               ((uintptr_t)blob & ALIGN_MASK)
>> +               + ROUND(2 * size, ARCH_DMA_MINALIGN));
>> +
>> +    ret = do_job(encap_desc);
>> +
>> +    if (ret != SUCCESS)
>> +        printf("Error: blob encap job failed 0x%x\n", ret);
>> +
>> +    return ret;
>> +}
>> +
>> +u32 caam_hwrng(u8 *output_ptr, u32 output_len)
>> +{
>> +    u32 ret = SUCCESS;
>> +    u32 *hwrng_desc = g_jrdata.desc;
>> +    /* Buffer to hold the resulting output*/
>> +    u8 *output = (u8 *)output_ptr;
>> +
>> +    /* initialize the output array */
>> +    memset(output, 0, output_len);
>> +
>> +    /* prepare job descriptor */
>> +    init_job_desc(hwrng_desc, 0);
>> +    append_operation(hwrng_desc, OP_ALG_ALGSEL_RNG | 
>> OP_TYPE_CLASS1_ALG);
>> +    append_fifo_store(hwrng_desc, PTR2CAAMDMA(output),
>> +              output_len, FIFOST_TYPE_RNGSTORE);
>> +
>> +    /* flush cache */
>> +    flush_dcache_range((uintptr_t)hwrng_desc & ALIGN_MASK,
>> +               ((uintptr_t)hwrng_desc & ALIGN_MASK)
>> +               + ROUND(DESC_MAX_SIZE, ARCH_DMA_MINALIGN));
>> +
>> +    ret = do_job(hwrng_desc);
>> +
>> +    flush_dcache_range((uintptr_t)output & ALIGN_MASK,
>> +               ((uintptr_t)output & ALIGN_MASK)
>> +               + ROUND(2 * output_len, ARCH_DMA_MINALIGN));
>> +
>> +    if (ret != SUCCESS)
>> +        printf("Error: RNG generate failed 0x%x\n", ret);
>> +
>> +    return ret;
>> +}
>> +
>> +/*!
>> + * Initialize the CAAM.
>> + *
>> + */
>> +void caam_open(void)
>> +{
>> +    u32 temp_reg;
>> +    int ret;
>> +
>> +    /* switch on the clock */
>> +#ifndef CONFIG_ARCH_IMX8
>> +    caam_clock_enable();
>> +#endif
>> +
>> +    /* reset the CAAM */
>> +    temp_reg = __raw_readl(CAAM_MCFGR) |
>> +            CAAM_MCFGR_DMARST | CAAM_MCFGR_SWRST;
>> +    __raw_writel(temp_reg,  CAAM_MCFGR);
>> +    while (__raw_readl(CAAM_MCFGR) & CAAM_MCFGR_DMARST)
>> +        ;
>> +
>> +    jr_reset();
>> +    ret = do_cfg_jrqueue();
>> +
>> +    if (ret != SUCCESS) {
>> +        printf("Error CAAM JR initialization\n");
>> +        return;
>> +    }
>> +
>> +    /* Check if the RNG is already instantiated */
>> +    temp_reg = __raw_readl(CAAM_RDSTA);
>> +    if (temp_reg == (RDSTA_IF0 | RDSTA_IF1 | RDSTA_SKVN)) {
>> +        printf("RNG already instantiated 0x%X\n", temp_reg);
>> +        return;
>> +    }
>> +
>> +    rng_init();
>> +}
>> +
>> +static void caam_clock_enable(void)
>> +{
>> +#if defined(CONFIG_ARCH_MX6)
>> +    struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
>> +    u32 reg;
>> +
>> +    reg = __raw_readl(&mxc_ccm->CCGR0);
>> +
>> +    reg |= (MXC_CCM_CCGR0_CAAM_SECURE_MEM_MASK |
>> +        MXC_CCM_CCGR0_CAAM_WRAPPER_ACLK_MASK |
>> +        MXC_CCM_CCGR0_CAAM_WRAPPER_IPG_MASK);
>> +
>> +    __raw_writel(reg, &mxc_ccm->CCGR0);
>> +
>> +#ifndef CONFIG_MX6UL
>> +    /* EMI slow clk */
>> +    reg = __raw_readl(&mxc_ccm->CCGR6);
>> +    reg |= MXC_CCM_CCGR6_EMI_SLOW_MASK;
>> +
>> +    __raw_writel(reg, &mxc_ccm->CCGR6);
>> +#endif
>> +
>> +#elif defined(CONFIG_ARCH_MX7)
>> +    HW_CCM_CCGR_SET(36, MXC_CCM_CCGR36_CAAM_DOMAIN0_MASK);
>> +#elif defined(CONFIG_ARCH_MX7ULP)
>> +    pcc_clock_enable(PER_CLK_CAAM, true);
>> +#endif
>> +}
>> +
>> +static void kick_trng(u32 ent_delay)
>> +{
>> +    u32 samples  = 512; /* number of bits to generate and test */
>> +    u32 mono_min = 195;
>> +    u32 mono_max = 317;
>> +    u32 mono_range  = mono_max - mono_min;
>> +    u32 poker_min = 1031;
>> +    u32 poker_max = 1600;
>> +    u32 poker_range = poker_max - poker_min + 1;
>> +    u32 retries    = 2;
>> +    u32 lrun_max   = 32;
>> +    s32 run_1_min   = 27;
>> +    s32 run_1_max   = 107;
>> +    s32 run_1_range = run_1_max - run_1_min;
>> +    s32 run_2_min   = 7;
>> +    s32 run_2_max   = 62;
>> +    s32 run_2_range = run_2_max - run_2_min;
>> +    s32 run_3_min   = 0;
>> +    s32 run_3_max   = 39;
>> +    s32 run_3_range = run_3_max - run_3_min;
>> +    s32 run_4_min   = -1;
>> +    s32 run_4_max   = 26;
>> +    s32 run_4_range = run_4_max - run_4_min;
>> +    s32 run_5_min   = -1;
>> +    s32 run_5_max   = 18;
>> +    s32 run_5_range = run_5_max - run_5_min;
>> +    s32 run_6_min   = -1;
>> +    s32 run_6_max   = 17;
>> +    s32 run_6_range = run_6_max - run_6_min;
>> +    u32 val;
>> +
>> +    /* Put RNG in program mode */
>> +    setbits_le32(CAAM_RTMCTL, RTMCTL_PGM);
>> +    /* Configure the RNG Entropy Delay
>> +     * Performance-wise, it does not make sense to
>> +     * set the delay to a value that is lower
>> +     * than the last one that worked (i.e. the state handles
>> +     * were instantiated properly. Thus, instead of wasting
>> +     * time trying to set the values controlling the sample
>> +     * frequency, the function simply returns.
>> +     */
>> +    val = __raw_readl(CAAM_RTSDCTL);
>> +    val &= BM_TRNG_ENT_DLY;
>> +    val >>= BS_TRNG_ENT_DLY;
>> +    if (ent_delay < val) {
>> +        /* Put RNG4 into run mode */
>> +        clrbits_le32(CAAM_RTMCTL, RTMCTL_PGM);
>> +        return;
>> +    }
>> +
>> +    val = (ent_delay << BS_TRNG_ENT_DLY) | samples;
>> +    __raw_writel(val, CAAM_RTSDCTL);
>> +
>> +    /* min. freq. count, equal to 1/2 of the entropy sample length */
>> +    __raw_writel(ent_delay >> 1, CAAM_RTFRQMIN);
>> +
>> +    /* max. freq. count, equal to 32 times the entropy sample length */
>> +    __raw_writel(ent_delay << 5, CAAM_RTFRQMAX);
>> +
>> +    __raw_writel((retries << 16) | lrun_max, CAAM_RTSCMISC);
>> +    __raw_writel(poker_max, CAAM_RTPKRMAX);
>> +    __raw_writel(poker_range, CAAM_RTPKRRNG);
>> +    __raw_writel((mono_range << 16) | mono_max, CAAM_RTSCML);
>> +    __raw_writel((run_1_range << 16) | run_1_max, CAAM_RTSCR1L);
>> +    __raw_writel((run_2_range << 16) | run_2_max, CAAM_RTSCR2L);
>> +    __raw_writel((run_3_range << 16) | run_3_max, CAAM_RTSCR3L);
>> +    __raw_writel((run_4_range << 16) | run_4_max, CAAM_RTSCR4L);
>> +    __raw_writel((run_5_range << 16) | run_5_max, CAAM_RTSCR5L);
>> +    __raw_writel((run_6_range << 16) | run_6_max, CAAM_RTSCR6PL);
>> +
>> +    val = __raw_readl(CAAM_RTMCTL);
>> +    /*
>> +     * Select raw sampling in both entropy shifter
>> +     * and statistical checker
>> +     */
>> +    val &= ~BM_TRNG_SAMP_MODE;
>> +    val |= TRNG_SAMP_MODE_RAW_ES_SC;
>> +    /* Put RNG4 into run mode */
>> +    val &= ~RTMCTL_PGM;
>> +/*test with sample mode only */
>> +    __raw_writel(val, CAAM_RTMCTL);
>> +
>> +    /* Clear the ERR bit in RTMCTL if set. The TRNG error can occur 
>> when the
>> +     * RNG clock is not within 1/2x to 8x the system clock.
>> +     * This error is possible if ROM code does not initialize the 
>> system PLLs
>> +     * immediately after PoR.
>> +     */
>> +    /* setbits_le32(CAAM_RTMCTL, RTMCTL_ERR); */
>> +}
>> +
>> +/*
>> + *  Descriptors to instantiate SH0, SH1, load the keys
>> + */
>> +static const u32 rng_inst_sh0_desc[] = {
>> +    /* Header, don't setup the size */
>> +    CAAM_HDR_CTYPE | CAAM_HDR_ONE | CAAM_HDR_START_INDEX(0),
>> +    /* Operation instantiation (sh0) */
>> +    CAAM_PROTOP_CTYPE | CAAM_C1_RNG | ALGO_RNG_SH(0) | 
>> ALGO_RNG_INSTANTIATE,
>> +};
>> +
>> +static const u32 rng_inst_sh1_desc[] = {
>> +    /* wait for done - Jump to next entry */
>> +    CAAM_C1_JUMP | CAAM_JUMP_LOCAL | CAAM_JUMP_TST_ALL_COND_TRUE
>> +        | CAAM_JUMP_OFFSET(1),
>> +    /* Clear written register (write 1) */
>> +    CAAM_C0_LOAD_IMM | CAAM_DST_CLEAR_WRITTEN | sizeof(u32),
>> +    0x00000001,
>> +    /* Operation instantiation (sh1) */
>> +    CAAM_PROTOP_CTYPE | CAAM_C1_RNG | ALGO_RNG_SH(1)
>> +        | ALGO_RNG_INSTANTIATE,
>> +};
>> +
>> +static const u32 rng_inst_load_keys[] = {
>> +    /* wait for done - Jump to next entry */
>> +    CAAM_C1_JUMP | CAAM_JUMP_LOCAL | CAAM_JUMP_TST_ALL_COND_TRUE
>> +        | CAAM_JUMP_OFFSET(1),
>> +    /* Clear written register (write 1) */
>> +    CAAM_C0_LOAD_IMM | CAAM_DST_CLEAR_WRITTEN | sizeof(u32),
>> +    0x00000001,
>> +    /* Generate the Key */
>> +    CAAM_PROTOP_CTYPE | CAAM_C1_RNG | BM_ALGO_RNG_SK | 
>> ALGO_RNG_GENERATE,
>> +};
>> +
>> +static void do_inst_desc(u32 *desc, u32 status)
>> +{
>> +    u32 *pdesc = desc;
>> +    u8  desc_len;
>> +    bool add_sh0   = false;
>> +    bool add_sh1   = false;
>> +    bool load_keys = false;
>> +
>> +    /*
>> +     * Modify the the descriptor to remove if necessary:
>> +     *  - The key loading
>> +     *  - One of the SH already instantiated
>> +     */
>> +    desc_len = RNG_DESC_SH0_SIZE;
>> +    if ((status & RDSTA_IF0) != RDSTA_IF0)
>> +        add_sh0 = true;
>> +
>> +    if ((status & RDSTA_IF1) != RDSTA_IF1) {
>> +        add_sh1 = true;
>> +        if (add_sh0)
>> +            desc_len += RNG_DESC_SH1_SIZE;
>> +    }
>> +
>> +    if ((status & RDSTA_SKVN) != RDSTA_SKVN) {
>> +        load_keys = true;
>> +        desc_len += RNG_DESC_KEYS_SIZE;
>> +    }
>> +
>> +    /* Copy the SH0 descriptor anyway */
>> +    memcpy(pdesc, rng_inst_sh0_desc, sizeof(rng_inst_sh0_desc));
>> +    pdesc += RNG_DESC_SH0_SIZE;
>> +
>> +    if (load_keys) {
>> +        debug("RNG - Load keys\n");
>> +        memcpy(pdesc, rng_inst_load_keys, sizeof(rng_inst_load_keys));
>> +        pdesc += RNG_DESC_KEYS_SIZE;
>> +    }
>> +
>> +    if (add_sh1) {
>> +        if (add_sh0) {
>> +            debug("RNG - Instantiation of SH0 and SH1\n");
>> +            /* Add the sh1 descriptor */
>> +            memcpy(pdesc, rng_inst_sh1_desc,
>> +                   sizeof(rng_inst_sh1_desc));
>> +        } else {
>> +            debug("RNG - Instantiation of SH1 only\n");
>> +            /* Modify the SH0 descriptor to instantiate only SH1 */
>> +            desc[1] &= ~BM_ALGO_RNG_SH;
>> +            desc[1] |= ALGO_RNG_SH(1);
>> +        }
>> +    }
>> +
>> +    /* Setup the descriptor size */
>> +    desc[0] &= ~(0x3F);
>> +    desc[0] |= CAAM_HDR_DESCLEN(desc_len);
>> +}
>> +
>> +static int jr_reset(void)
>> +{
>> +    /*
>> +     * Function reset the Job Ring HW
>> +     * Reset is done in 2 steps:
>> +     *  - Flush all pending jobs (Set RESET bit)
>> +     *  - Reset the Job Ring (Set RESET bit second time)
>> +     */
>> +    u16 timeout = 10000;
>> +    u32 reg_val;
>> +
>> +    /* Mask interrupts to poll for reset completion status */
>> +    setbits_le32(CAAM_JRCFGR0_LS, BM_JRCFGR_LS_IMSK);
>> +
>> +    /* Initiate flush (required prior to reset) */
>> +    __raw_writel(JRCR_RESET, CAAM_JRCR0);
>> +    do {
>> +        reg_val = __raw_readl(CAAM_JRINTR0);
>> +        reg_val &= BM_JRINTR_HALT;
>> +    } while ((reg_val == JRINTR_HALT_ONGOING) && --timeout);
>> +
>> +    if (!timeout  || reg_val != JRINTR_HALT_DONE) {
>> +        printf("Failed to flush job ring\n");
>> +        return ERROR_ANY;
>> +    }
>> +
>> +    /* Initiate reset */
>> +    timeout = 100;
>> +    __raw_writel(JRCR_RESET, CAAM_JRCR0);
>> +    do {
>> +        reg_val = __raw_readl(CAAM_JRCR0);
>> +    } while ((reg_val & JRCR_RESET) && --timeout);
>> +
>> +    if (!timeout) {
>> +        printf("Failed to reset job ring\n");
>> +        return ERROR_ANY;
>> +    }
>> +
>> +    return 0;
>> +}
>> +
>> +static int do_job(u32 *desc)
>> +{
>> +    int ret;
>> +    phys_addr_t p_desc = virt_to_phys(desc);
>> +
>> +    if (__raw_readl(CAAM_IRSAR0) == 0)
>> +        return ERROR_ANY;
>> +    g_jrdata.inrings[0].desc = p_desc;
>> +
>> +    flush_dcache_range((uintptr_t)g_jrdata.inrings & ALIGN_MASK,
>> +               ((uintptr_t)g_jrdata.inrings & ALIGN_MASK)
>> +               + ROUND(DESC_MAX_SIZE, ARCH_DMA_MINALIGN));
>> +    flush_dcache_range((uintptr_t)desc & ALIGN_MASK,
>> +               ((uintptr_t)desc & ALIGN_MASK)
>> +               + ROUND(DESC_MAX_SIZE, ARCH_DMA_MINALIGN));
>> +
>> +    /* Inform HW that a new JR is available */
>> +    __raw_writel(1, CAAM_IRJAR0);
>> +    while (__raw_readl(CAAM_ORSFR0) == 0)
>> +        ;
>> +
>> +    flush_dcache_range((uintptr_t)g_jrdata.outrings & ALIGN_MASK,
>> +               ((uintptr_t)g_jrdata.outrings & ALIGN_MASK)
>> +               + ROUND(DESC_MAX_SIZE, ARCH_DMA_MINALIGN));
>> +
>> +    if (PTR2CAAMDMA(desc) == g_jrdata.outrings[0].desc) {
>> +        ret = g_jrdata.outrings[0].status;
>> +    } else {
>> +        dump_error();
>> +        ret = ERROR_ANY;
>> +    }
>> +
>> +    /* Acknowledge interrupt */
>> +    setbits_le32(CAAM_JRINTR0, JRINTR_JRI);
>> +
>> +    /* Remove the JR from the output list even if no JR caller found */
>> +    __raw_writel(1, CAAM_ORJRR0);
>> +
>> +    return ret;
>> +}
>> +
>> +static int do_cfg_jrqueue(void)
>> +{
>> +    u32 value = 0;
>> +    phys_addr_t ip_base;
>> +    phys_addr_t op_base;
>> +
>> +    /* check if already configured after relocation */
>> +    if (g_jrdata.status == RING_RELOC_INIT)
>> +        return 0;
>> +
>> +    /*
>> +     * jr configuration needs to be updated once, after relocation to 
>> ensure
>> +     * using the right buffers.
>> +     * When buffers are updated after relocation the flag 
>> RING_RELOC_INIT
>> +     * is used to prevent extra updates
>> +     */
>> +    if (gd->flags & GD_FLG_RELOC) {
>> +        g_jrdata.inrings  = (struct inring_entry *)
>> +                    memalign(ARCH_DMA_MINALIGN,
>> +                         ARCH_DMA_MINALIGN);
>> +        g_jrdata.outrings = (struct outring_entry *)
>> +                    memalign(ARCH_DMA_MINALIGN,
>> +                         ARCH_DMA_MINALIGN);
>> +        g_jrdata.desc = (u32 *)
>> +                memalign(ARCH_DMA_MINALIGN, ARCH_DMA_MINALIGN);
>> +        g_jrdata.status = RING_RELOC_INIT;
>> +    } else {
>> +        u32 align_idx = 0;
>> +
>> +        /* Ensure 64bits buffers addresses alignment */
>> +        if ((uintptr_t)g_jrdata.raw_addr & 0x7)
>> +            align_idx = 1;
>> +        g_jrdata.inrings  = (struct inring_entry *)
>> +                    (&g_jrdata.raw_addr[align_idx]);
>> +        g_jrdata.outrings = (struct outring_entry *)
>> +                    (&g_jrdata.raw_addr[align_idx + 2]);
>> +        g_jrdata.desc = (u32 *)(&g_jrdata.raw_addr[align_idx + 4]);
>> +        g_jrdata.status = RING_EARLY_INIT;
>> +    }
>> +
>> +    if (!g_jrdata.inrings || !g_jrdata.outrings)
>> +        return ERROR_ANY;
>> +
>> +    /* Configure the HW Job Rings */
>> +    ip_base = virt_to_phys((void *)g_jrdata.inrings);
>> +    op_base = virt_to_phys((void *)g_jrdata.outrings);
>> +    __raw_writel(ip_base, CAAM_IRBAR0);
>> +    __raw_writel(1, CAAM_IRSR0);
>> +
>> +    __raw_writel(op_base, CAAM_ORBAR0);
>> +    __raw_writel(1, CAAM_ORSR0);
>> +
>> +    setbits_le32(CAAM_JRINTR0, JRINTR_JRI);
>> +
>> +    /*
>> +     * Configure interrupts but disable it:
>> +     * Optimization to generate an interrupt either when there are
>> +     * half of the job done or when there is a job done and
>> +     * 10 clock cycles elapse without new job complete
>> +     */
>> +    value = 10 << BS_JRCFGR_LS_ICTT;
>> +    value |= (1 << BS_JRCFGR_LS_ICDCT) & BM_JRCFGR_LS_ICDCT;
>> +    value |= BM_JRCFGR_LS_ICEN;
>> +    value |= BM_JRCFGR_LS_IMSK;
>> +    __raw_writel(value, CAAM_JRCFGR0_LS);
>> +
>> +    /* Enable deco watchdog */
>> +    setbits_le32(CAAM_MCFGR, BM_MCFGR_WDE);
>> +
>> +    return 0;
>> +}
>> +
>> +static void do_clear_rng_error(void)
>> +{
>> +    u32 val;
>> +
>> +    val = __raw_readl(CAAM_RTMCTL);
>> +
>> +    if (val & (RTMCTL_ERR | RTMCTL_FCT_FAIL)) {
>> +        setbits_le32(CAAM_RTMCTL, RTMCTL_ERR);
>> +    val = __raw_readl(CAAM_RTMCTL);
>> +    }
>> +}
>> +
>> +static int do_instantiation(void)
>> +{
>> +    int ret = ERROR_ANY;
>> +    u32 cha_vid_ls;
>> +    u32 ent_delay;
>> +    u32 status;
>> +
>> +    if (!g_jrdata.desc) {
>> +        printf("%d: CAAM Descriptor allocation error\n", __LINE__);
>> +        return ERROR_ANY;
>> +    }
>> +
>> +    cha_vid_ls = __raw_readl(CAAM_CHAVID_LS);
>> +
>> +    /*
>> +     * If SEC has RNG version >= 4 and RNG state handle has not been
>> +     * already instantiated, do RNG instantiation
>> +     */
>> +    if (((cha_vid_ls & BM_CHAVID_LS_RNGVID) >> BS_CHAVID_LS_RNGVID) < 
>> 4) {
>> +        printf("%d: RNG already instantiated\n", __LINE__);
>> +        return 0;
>> +    }
>> +
>> +    ent_delay = TRNG_SDCTL_ENT_DLY_MIN;
>> +
>> +    do {
>> +        /* Read the CAAM RNG status */
>> +        status = __raw_readl(CAAM_RDSTA);
>> +
>> +        if ((status & RDSTA_IF0) != RDSTA_IF0) {
>> +            /* Configure the RNG entropy delay */
>> +            kick_trng(ent_delay);
>> +            ent_delay += 400;
>> +        }
>> +
>> +        do_clear_rng_error();
>> +
>> +        if ((status & (RDSTA_IF0 | RDSTA_IF1)) !=
>> +                (RDSTA_IF0 | RDSTA_IF1)) {
>> +            /* Prepare the instantiation descriptor */
>> +            do_inst_desc(g_jrdata.desc, status);
>> +
>> +            /* Run Job */
>> +            ret = do_job(g_jrdata.desc);
>> +
>> +            if (ret == ERROR_ANY) {
>> +                /* CAAM JR failure ends here */
>> +                printf("RNG Instantiation error\n");
>> +                goto end_instantation;
>> +            }
>> +        } else {
>> +            ret = SUCCESS;
>> +            printf("RNG instantiation done (%d)\n", ent_delay);
>> +            goto end_instantation;
>> +        }
>> +    } while (ent_delay < TRNG_SDCTL_ENT_DLY_MAX);
>> +
>> +    printf("RNG Instantation Failure - Entropy delay (%d)\n", 
>> ent_delay);
>> +    ret = ERROR_ANY;
>> +
>> +end_instantation:
>> +    return ret;
>> +}
>> +
>> +static void rng_init(void)
>> +{
>> +    int  ret;
>> +
>> +    ret = jr_reset();
>> +    if (ret != SUCCESS) {
>> +        printf("Error CAAM JR reset\n");
>> +        return;
>> +    }
>> +
>> +    ret = do_instantiation();
>> +
>> +    if (ret != SUCCESS)
>> +        printf("Error do_instantiation\n");
>> +
>> +    jr_reset();
>> +
>> +    return;
>> +}
>> +
>> diff --git a/drivers/crypto/fsl_caam_internal.h 
>> b/drivers/crypto/fsl_caam_internal.h
>> new file mode 100644
>> index 0000000000..837562d3c4
>> --- /dev/null
>> +++ b/drivers/crypto/fsl_caam_internal.h
>> @@ -0,0 +1,229 @@
>> +/* SPDX-License-Identifier: GPL-2.0+ */
>> +/*
>> + * Copyright (c) 2012-2016, Freescale Semiconductor, Inc.
>> + * Copyright 2018 NXP
>> + */
>> +
>> +#ifndef __CAAM_INTERNAL_H__
>> +#define __CAAM_INTERNAL_H__
>> +
>> +/* 4kbyte pages */
>> +#define CAAM_SEC_RAM_START_ADDR CAAM_ARB_BASE_ADDR
>> +
>> +#define SEC_MEM_PAGE0       CAAM_SEC_RAM_START_ADDR
>> +#define SEC_MEM_PAGE1       (CAAM_SEC_RAM_START_ADDR + 0x1000)
>> +#define SEC_MEM_PAGE2       (CAAM_SEC_RAM_START_ADDR + 0x2000)
>> +#define SEC_MEM_PAGE3       (CAAM_SEC_RAM_START_ADDR + 0x3000)
>> +
>> +/* Configuration and special key registers */
>> +#define CAAM_MCFGR          (CONFIG_SYS_FSL_SEC_ADDR + 0x0004)
>> +#define CAAM_SCFGR          (CONFIG_SYS_FSL_SEC_ADDR + 0x000c)
>> +#define CAAM_JR0MIDR        (CONFIG_SYS_FSL_SEC_ADDR + 0x0010)
>> +#define CAAM_JR1MIDR        (CONFIG_SYS_FSL_SEC_ADDR + 0x0018)
>> +#define CAAM_DECORR         (CONFIG_SYS_FSL_SEC_ADDR + 0x009c)
>> +#define CAAM_DECO0MID       (CONFIG_SYS_FSL_SEC_ADDR + 0x00a0)
>> +#define CAAM_DAR            (CONFIG_SYS_FSL_SEC_ADDR + 0x0120)
>> +#define CAAM_DRR            (CONFIG_SYS_FSL_SEC_ADDR + 0x0124)
>> +#define CAAM_JDKEKR         (CONFIG_SYS_FSL_SEC_ADDR + 0x0400)
>> +#define CAAM_TDKEKR         (CONFIG_SYS_FSL_SEC_ADDR + 0x0420)
>> +#define CAAM_TDSKR          (CONFIG_SYS_FSL_SEC_ADDR + 0x0440)
>> +#define CAAM_SKNR           (CONFIG_SYS_FSL_SEC_ADDR + 0x04e0)
>> +#define CAAM_SMSTA          (CONFIG_SYS_FSL_SEC_ADDR + 0x0FB4)
>> +#define CAAM_STA            (CONFIG_SYS_FSL_SEC_ADDR + 0x0FD4)
>> +#define CAAM_SMPO_0         (CONFIG_SYS_FSL_SEC_ADDR + 0x1FBC)
>> +#define CAAM_CHAVID_LS      (CONFIG_SYS_FSL_SEC_ADDR + 0x0FEC)
>> +#define CAAM_FAR            (CONFIG_SYS_FSL_SEC_ADDR + 0x0FC0)
>> +#define CAAM_FAMR           (CONFIG_SYS_FSL_SEC_ADDR + 0x0FC8)
>> +#define CAAM_FADR           (CONFIG_SYS_FSL_SEC_ADDR + 0x0FCC)
>> +
>> +/* RNG registers */
>> +#define CAAM_RTMCTL         (CONFIG_SYS_FSL_SEC_ADDR + 0x0600)
>> +#define CAAM_RTSCMISC       (CONFIG_SYS_FSL_SEC_ADDR + 0x0604)
>> +#define CAAM_RTPKRRNG       (CONFIG_SYS_FSL_SEC_ADDR + 0x0608)
>> +#define CAAM_RTPKRMAX       (CONFIG_SYS_FSL_SEC_ADDR + 0x060C)
>> +#define CAAM_RTSDCTL        (CONFIG_SYS_FSL_SEC_ADDR + 0x0610)
>> +#define CAAM_RTFRQMIN       (CONFIG_SYS_FSL_SEC_ADDR + 0x0618)
>> +#define CAAM_RTFRQMAX       (CONFIG_SYS_FSL_SEC_ADDR + 0x061C)
>> +#define CAAM_RTSCML         (CONFIG_SYS_FSL_SEC_ADDR + 0x0620)
>> +#define CAAM_RTSCR1L        (CONFIG_SYS_FSL_SEC_ADDR + 0x0624)
>> +#define CAAM_RTSCR2L        (CONFIG_SYS_FSL_SEC_ADDR + 0x0628)
>> +#define CAAM_RTSCR3L        (CONFIG_SYS_FSL_SEC_ADDR + 0x062C)
>> +#define CAAM_RTSCR4L        (CONFIG_SYS_FSL_SEC_ADDR + 0x0630)
>> +#define CAAM_RTSCR5L        (CONFIG_SYS_FSL_SEC_ADDR + 0x0634)
>> +#define CAAM_RTSCR6PL       (CONFIG_SYS_FSL_SEC_ADDR + 0x0638)
>> +#define CAAM_RTSTATUS       (CONFIG_SYS_FSL_SEC_ADDR + 0x063C)
>> +#define CAAM_RDSTA          (CONFIG_SYS_FSL_SEC_ADDR + 0x06C0)
>> +
>> +/* Job Ring 0 registers */
>> +#define CAAM_IRBAR0         (CONFIG_SYS_FSL_SEC_ADDR + 0x1004)
>> +#define CAAM_IRSR0          (CONFIG_SYS_FSL_SEC_ADDR + 0x100c)
>> +#define CAAM_IRSAR0         (CONFIG_SYS_FSL_SEC_ADDR + 0x1014)
>> +#define CAAM_IRJAR0         (CONFIG_SYS_FSL_SEC_ADDR + 0x101c)
>> +#define CAAM_ORBAR0         (CONFIG_SYS_FSL_SEC_ADDR + 0x1024)
>> +#define CAAM_ORSR0          (CONFIG_SYS_FSL_SEC_ADDR + 0x102c)
>> +#define CAAM_ORJRR0         (CONFIG_SYS_FSL_SEC_ADDR + 0x1034)
>> +#define CAAM_ORSFR0         (CONFIG_SYS_FSL_SEC_ADDR + 0x103c)
>> +#define CAAM_JRSTAR0        (CONFIG_SYS_FSL_SEC_ADDR + 0x1044)
>> +#define CAAM_JRINTR0        (CONFIG_SYS_FSL_SEC_ADDR + 0x104c)
>> +#define CAAM_JRCFGR0_MS     (CONFIG_SYS_FSL_SEC_ADDR + 0x1050)
>> +#define CAAM_JRCFGR0_LS     (CONFIG_SYS_FSL_SEC_ADDR + 0x1054)
>> +#define CAAM_IRRIR0         (CONFIG_SYS_FSL_SEC_ADDR + 0x105c)
>> +#define CAAM_ORWIR0         (CONFIG_SYS_FSL_SEC_ADDR + 0x1064)
>> +#define CAAM_JRCR0          (CONFIG_SYS_FSL_SEC_ADDR + 0x106c)
>> +#define CAAM_SMCJR0         (CONFIG_SYS_FSL_SEC_ADDR + 0x10f4)
>> +#define CAAM_SMCSJR0        (CONFIG_SYS_FSL_SEC_ADDR + 0x10fc)
>> +#define CAAM_SMAPJR0(y)     (CONFIG_SYS_FSL_SEC_ADDR + 0x1104 + y * 16)
>> +#define CAAM_SMAG2JR0(y)    (CONFIG_SYS_FSL_SEC_ADDR + 0x1108 + y * 16)
>> +#define CAAM_SMAG1JR0(y)    (CONFIG_SYS_FSL_SEC_ADDR + 0x110C + y * 16)
>> +#define CAAM_SMAPJR0_PRTN1  (CONFIG_SYS_FSL_SEC_ADDR + 0x1114)
>> +#define CAAM_SMAG2JR0_PRTN1 (CONFIG_SYS_FSL_SEC_ADDR + 0x1118)
>> +#define CAAM_SMAG1JR0_PRTN1 (CONFIG_SYS_FSL_SEC_ADDR + 0x111c)
>> +#define CAAM_SMPO           (CONFIG_SYS_FSL_SEC_ADDR + 0x1fbc)
>> +
>> +#define DESC_MAX_SIZE       (0x40)        /* Descriptor max size */
>> +#define JRCFG_LS_IMSK       (0x01)        /* Interrupt Mask */
>> +#define JR_MID              (0x02)        /* Matches ROM 
>> configuration */
>> +#define KS_G1               BIT(JR_MID)   /* CAAM only */
>> +#define PERM                (0x0000B008)  /* Clear on release, lock 
>> SMAP,
>> +                       * lock SMAG and group 1 Blob
>> +                       */
>> +
>> +#define CMD_PAGE_ALLOC      (0x1)
>> +#define CMD_PAGE_DEALLOC    (0x2)
>> +#define CMD_PART_DEALLOC    (0x3)
>> +#define CMD_INQUIRY         (0x5)
>> +#define PAGE(x)             ((x) << 16)
>> +#define PARTITION(x)        ((x) << 8)
>> +
>> +#define SMCSJR_AERR         (3 << 12)
>> +#define SMCSJR_CERR         (3 << 14)
>> +#define CMD_COMPLETE        (3 << 14)
>> +
>> +#define SMCSJR_PO           (3 << 6)
>> +#define PAGE_AVAILABLE      (0)
>> +#define PAGE_OWNED          (3 << 6)
>> +
>> +#define PARTITION_OWNER(x)  (0x3 << ((x) * 2))
>> +
>> +#define CAAM_BUSY_MASK      (0x00000001) /* BUSY from status reg */
>> +#define CAAM_IDLE_MASK      (0x00000002) /* IDLE from status reg */
>> +#define CAAM_MCFGR_SWRST    BIT(31)      /* CAAM SW reset */
>> +#define CAAM_MCFGR_DMARST   BIT(28)      /* CAAM DMA reset */
>> +
>> +#define JOB_RING_ENTRIES    (1)
>> +#define JOB_RING_STS        (0xF << 28)
>> +
>> +/** OSC_DIV in RNG trim fuses */
>> +#define RNG_TRIM_OSC_DIV    (0)
>> +/** ENT_DLY multiplier in RNG trim fuses */
>> +#define TRNG_SDCTL_ENT_DLY_MIN (3200)
>> +#define TRNG_SDCTL_ENT_DLY_MAX (4800)
>> +
>> +#define RTMCTL_PGM       BIT(16)
>> +#define RTMCTL_ERR       BIT(12)
>> +#define RTMCTL_RST       BIT(6)
>> +#define RDSTA_IF0        (1)
>> +#define RDSTA_IF1        (2)
>> +#define RDSTA_SKVN       BIT(30)
>> +#define JRCR_RESET       (1)
>> +#define RTMCTL_FCT_FAIL  BIT(8)
>> +
>> +#define BS_TRNG_ENT_DLY     (16)
>> +#define BM_TRNG_ENT_DLY     (0xffff << BS_TRNG_ENT_DLY)
>> +#define BM_TRNG_SAMP_MODE   (3)
>> +#define TRNG_SAMP_MODE_RAW_ES_SC (1)
>> +#define BS_JRINTR_HALT      (2)
>> +#define BM_JRINTR_HALT      (0x3 << BS_JRINTR_HALT)
>> +#define JRINTR_HALT_ONGOING (0x1 << BS_JRINTR_HALT)
>> +#define JRINTR_HALT_DONE    (0x2 << BS_JRINTR_HALT)
>> +#define JRINTR_JRI          (0x1)
>> +#define BS_JRCFGR_LS_ICTT   (16)
>> +#define BM_JRCFGR_LS_ICTT   (0xFFFF << BS_JRCFGR_LS_ICTT)
>> +#define BS_JRCFGR_LS_ICDCT  (8)
>> +#define BM_JRCFGR_LS_ICDCT  (0xFF << BS_JRCFGR_LS_ICDCT)
>> +#define BS_JRCFGR_LS_ICEN   (1)
>> +#define BM_JRCFGR_LS_ICEN   (0x1 << BS_JRCFGR_LS_ICEN)
>> +#define BS_JRCFGR_LS_IMSK   (0)
>> +#define BM_JRCFGR_LS_IMSK   (0x1 << BS_JRCFGR_LS_IMSK)
>> +#define BS_CHAVID_LS_RNGVID (16)
>> +#define BM_CHAVID_LS_RNGVID (0xF << BS_CHAVID_LS_RNGVID)
>> +#define BS_MCFGR_WDE        (30)
>> +#define BM_MCFGR_WDE        (0x1 << BS_MCFGR_WDE)
>> +
>> +typedef enum {
>> +    PAGE_0,
>> +    PAGE_1,
>> +    PAGE_2,
>> +    PAGE_3,
>> +} page_num_e;
>> +
>> +typedef enum {
>> +    PARTITION_0,
>> +    PARTITION_1,
>> +    PARTITION_2,
>> +    PARTITION_3,
>> +    PARTITION_4,
>> +    PARTITION_5,
>> +    PARTITION_6,
>> +    PARTITION_7,
>> +} partition_num_e;
>> +
>> +/*
>> + * Local defines
>> + */
>> +/* arm v7 need 64 align */
>> +#define ALIGN_MASK     ~(ARCH_DMA_MINALIGN - 1)
>> +/* caam dma and pointer conversion for arm and arm64 architectures */
>> +#ifdef CONFIG_IMX_CONFIG
>> +  #define PTR2CAAMDMA(x)  (u32)((uintptr_t)(x) & 0xffffffff)
>> +  #define CAAMDMA2PTR(x)  (uintptr_t)((x) & 0xffffffff)
>> +#else
>> +  #define PTR2CAAMDMA(x)  (uintptr_t)(x)
>> +  #define CAAMDMA2PTR(x)  (uintptr_t)(x)
>> +#endif
>> +#define RING_EARLY_INIT   (0x01)
>> +#define RING_RELOC_INIT   (0x02)
>> +
>> +#define CAAM_HDR_CTYPE            (0x16u << 27)
>> +#define CAAM_HDR_ONE              BIT(23)
>> +#define CAAM_HDR_START_INDEX(x)   (((x) & 0x3F) << 16)
>> +#define CAAM_HDR_DESCLEN(x)       ((x) & 0x3F)
>> +#define CAAM_PROTOP_CTYPE         (0x10u << 27)
>> +
>> +/* State Handle */
>> +#define BS_ALGO_RNG_SH            (4)
>> +#define BM_ALGO_RNG_SH            (0x3 << BS_ALGO_RNG_SH)
>> +#define ALGO_RNG_SH(id)           (((id) << BS_ALGO_RNG_SH) & 
>> BM_ALGO_RNG_SH)
>> +
>> +/* Secure Key */
>> +#define BS_ALGO_RNG_SK            (12)
>> +#define BM_ALGO_RNG_SK            BIT(BS_ALGO_RNG_SK)
>> +
>> +/* State */
>> +#define BS_ALGO_RNG_AS            (2)
>> +#define BM_ALGO_RNG_AS            (0x3 << BS_ALGO_RNG_AS)
>> +#define ALGO_RNG_GENERATE         (0x0 << BS_ALGO_RNG_AS)
>> +#define ALGO_RNG_INSTANTIATE      BIT(BS_ALGO_RNG_AS)
>> +
>> +#define CAAM_C1_RNG               ((0x50 << 16) | (2 << 24))
>> +
>> +#define BS_JUMP_LOCAL_OFFSET      (0)
>> +#define BM_JUMP_LOCAL_OFFSET      (0xFF << BS_JUMP_LOCAL_OFFSET)
>> +
>> +#define CAAM_C1_JUMP              ((0x14u << 27) | (1 << 25))
>> +#define CAAM_JUMP_LOCAL           (0 << 20)
>> +#define CAAM_JUMP_TST_ALL_COND_TRUE (0 << 16)
>> +#define CAAM_JUMP_OFFSET(off)     (((off) << BS_JUMP_LOCAL_OFFSET) \
>> +                & BM_JUMP_LOCAL_OFFSET)
>> +
>> +#define CAAM_C0_LOAD_IMM          ((0x2 << 27) | (1 << 23))
>> +#define CAAM_DST_CLEAR_WRITTEN    (0x8 << 16)
>> +
>> +#define RNG_DESC_SH0_SIZE   (ARRAY_SIZE(rng_inst_sh0_desc))
>> +#define RNG_DESC_SH1_SIZE   (ARRAY_SIZE(rng_inst_sh1_desc))
>> +#define RNG_DESC_KEYS_SIZE  (ARRAY_SIZE(rng_inst_load_keys))
>> +#define RNG_DESC_MAX_SIZE   (RNG_DESC_SH0_SIZE + \
>> +            RNG_DESC_SH1_SIZE + \
>> +            RNG_DESC_KEYS_SIZE)
>> +
>> +#endif /* __CAAM_INTERNAL_H__ */
>> diff --git a/include/fsl_caam.h b/include/fsl_caam.h
>> new file mode 100644
>> index 0000000000..c4345ae2b6
>> --- /dev/null
>> +++ b/include/fsl_caam.h
>> @@ -0,0 +1,24 @@
>> +/* SPDX-License-Identifier: GPL-2.0+ */
>> +/*
>> + * Copyright (c) 2012-2016, Freescale Semiconductor, Inc.
>> + * Copyright 2018 NXP
>> + */
>> +
>> +#ifndef __CAAM_H__
>> +#define    __CAAM_H__
>> +
>> +#if !defined(SUCCESS)
>> +#define SUCCESS (0)
>> +#endif
>> +
>> +#define ERROR_ANY           (-1)
>> +#define ERROR_IN_PAGE_ALLOC (1)
>> +
>> +void caam_open(void);
>> +
>> +u32 caam_gen_blob(u32 plain_data_addr, u32 blob_addr, u32 size);
>> +
>> +u32 caam_decap_blob(u32 plain_text, u32 blob_addr, u32 size);
>> +u32 caam_hwrng(uint8_t *output_ptr, u32 output_len);
>> +
>> +#endif /* __CAAM_H__ */
>>
> 
> 

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH 31/37] crypto: caam: Add fsl caam driver
  2021-07-08  8:02     ` Peng Fan (OSS)
@ 2021-07-08  8:28       ` Stefano Babic
  0 siblings, 0 replies; 42+ messages in thread
From: Stefano Babic @ 2021-07-08  8:28 UTC (permalink / raw)
  To: Peng Fan (OSS), Stefano Babic, festevam
  Cc: uboot-imx, u-boot, Ye Li, Aymen Sghaier, Peng Fan

On 08.07.21 10:02, Peng Fan (OSS) wrote:
> Hi Stefano,
> 
> On 2021/4/9 2:24, Stefano Babic wrote:
>> Hi Peng,
>>
>> On 25.03.21 10:30, Peng Fan (OSS) wrote:
>>> From: Ye Li <ye.li@nxp.com>
>>>
>>> Add the fsl CAAM driver and new commands to implement DEK blob 
>>> operations,
>>> like "caam genblob" to generate encrypted blob and "caam decap" to 
>>> output
>>> orignal plain data.
>>>
>>>   The following reasons lead to instantiate the TRNG into U-Boot/SPL:
>>>
>>>   - On some i.MX platforms Linux Kernel could not instantiate RNG
>>>   - RNG could be used/needed by M4/M0 cores before Kernel stage
>>>   - Having the RNG instantiation implemented only once for
>>>     almost i.MX platforms
>>
>> Is this a CAAM driver ? But we have already drivers/crypto/fsl for 
>> CAAM. Which is the reason for it and why it is not merged with the 
>> existing driver ?
> 
> I missed this email, just check my mailbox and see this.
> My bad. I'll NXP people to merge the driver.

No problem. Patch was orthogonal, I merged the whole series but two 
patches related to the driver.

Regards,
Stefano

> 
> Thanks,
> Peng.
> 
>>
>> Best regards,
>> Stefano Babic
>>
>>>
>>> Signed-off-by: Aymen Sghaier <aymen.sghaier@nxp.com>
>>> Signed-off-by: Ye Li <ye.li@nxp.com>
>>> Signed-off-by: Peng Fan <peng.fan@nxp.com>
>>> ---
>>>   arch/arm/include/asm/arch-mx7/crm_regs.h |   8 +
>>>   cmd/Kconfig                              |   6 +
>>>   cmd/Makefile                             |   1 +
>>>   cmd/cmd_fsl_caam.c                       |  88 +++
>>>   drivers/crypto/Makefile                  |   1 +
>>>   drivers/crypto/fsl_caam.c                | 715 +++++++++++++++++++++++
>>>   drivers/crypto/fsl_caam_internal.h       | 229 ++++++++
>>>   include/fsl_caam.h                       |  24 +
>>>   8 files changed, 1072 insertions(+)
>>>   create mode 100644 cmd/cmd_fsl_caam.c
>>>   create mode 100644 drivers/crypto/fsl_caam.c
>>>   create mode 100644 drivers/crypto/fsl_caam_internal.h
>>>   create mode 100644 include/fsl_caam.h
>>>
>>> diff --git a/arch/arm/include/asm/arch-mx7/crm_regs.h 
>>> b/arch/arm/include/asm/arch-mx7/crm_regs.h
>>> index bfa68a9d2a..a000ae05d7 100644
>>> --- a/arch/arm/include/asm/arch-mx7/crm_regs.h
>>> +++ b/arch/arm/include/asm/arch-mx7/crm_regs.h
>>> @@ -1998,6 +1998,14 @@ struct mxc_ccm_anatop_reg {
>>>   #define TEMPMON_HW_ANADIG_TEMPSENSE_TRIM_TOG_T_MUX_ADDR_SHIFT 29
>>>   #define TEMPMON_HW_ANADIG_TEMPSENSE_TRIM_TOG_T_MUX_ADDR(x) 
>>> (((uint32_t)(((uint32_t)(x))<<TEMPMON_HW_ANADIG_TEMPSENSE_TRIM_TOG_T_MUX_ADDR_SHIFT))&TEMPMON_HW_ANADIG_TEMPSENSE_TRIM_TOG_T_MUX_ADDR_MASK) 
>>>
>>> +#define MXC_CCM_CCGR36_CAAM_DOMAIN3_OFFSET                     12
>>> +#define MXC_CCM_CCGR36_CAAM_DOMAIN3_MASK                       (3 << 
>>> MXC_CCM_CCGR36_CAAM_DOMAIN3_OFFSET)
>>> +#define MXC_CCM_CCGR36_CAAM_DOMAIN2_OFFSET                     8
>>> +#define MXC_CCM_CCGR36_CAAM_DOMAIN2_MASK                       (3 << 
>>> MXC_CCM_CCGR36_CAAM_DOMAIN2_OFFSET)
>>> +#define MXC_CCM_CCGR36_CAAM_DOMAIN1_OFFSET                     4
>>> +#define MXC_CCM_CCGR36_CAAM_DOMAIN1_MASK                       (3 << 
>>> MXC_CCM_CCGR36_CAAM_DOMAIN1_OFFSET)
>>> +#define MXC_CCM_CCGR36_CAAM_DOMAIN0_OFFSET                     0
>>> +#define MXC_CCM_CCGR36_CAAM_DOMAIN0_MASK                       (3 << 
>>> MXC_CCM_CCGR36_CAAM_DOMAIN0_OFFSET)
>>>   #define CCM_GPR(i)        (CCM_BASE_ADDR + CCM_GPR0_OFFSET + 0x10 * 
>>> (i))
>>>   #define CCM_OBSERVE(i)        (CCM_BASE_ADDR + CCM_OBSERVE0_OFFSET 
>>> + 0x10 * (i))
>>> diff --git a/cmd/Kconfig b/cmd/Kconfig
>>> index f73de2d75a..aeecfed974 100644
>>> --- a/cmd/Kconfig
>>> +++ b/cmd/Kconfig
>>> @@ -397,6 +397,12 @@ config CMD_SPL_WRITE_SIZE
>>>         flash used by Falcon-mode boot. See the documentation until 
>>> CMD_SPL
>>>         for detail.
>>> +config CMD_FSL_CAAM_KB
>>> +    bool "Freescale i.MX CAAM command"
>>> +    help
>>> +      Implement the "caam" command to generate DEK blob for one 
>>> block of data
>>> +      or decap the DEK blob to its original data.
>>> +
>>>   config CMD_THOR_DOWNLOAD
>>>       bool "thor - TIZEN 'thor' download"
>>>       select DFU
>>> diff --git a/cmd/Makefile b/cmd/Makefile
>>> index 567e2b79d2..d46ffd7021 100644
>>> --- a/cmd/Makefile
>>> +++ b/cmd/Makefile
>>> @@ -70,6 +70,7 @@ obj-$(CONFIG_CMD_FLASH) += flash.o
>>>   obj-$(CONFIG_CMD_FPGA) += fpga.o
>>>   obj-$(CONFIG_CMD_FPGAD) += fpgad.o
>>>   obj-$(CONFIG_CMD_FS_GENERIC) += fs.o
>>> +obj-$(CONFIG_CMD_FSL_CAAM_KB) += cmd_fsl_caam.o
>>>   obj-$(CONFIG_CMD_FUSE) += fuse.o
>>>   obj-$(CONFIG_CMD_GETTIME) += gettime.o
>>>   obj-$(CONFIG_CMD_GPIO) += gpio.o
>>> diff --git a/cmd/cmd_fsl_caam.c b/cmd/cmd_fsl_caam.c
>>> new file mode 100644
>>> index 0000000000..d41d672320
>>> --- /dev/null
>>> +++ b/cmd/cmd_fsl_caam.c
>>> @@ -0,0 +1,88 @@
>>> +// SPDX-License-Identifier: GPL-2.0+
>>> +/*
>>> + * Copyright (C) 2012-2016 Freescale Semiconductor, Inc.
>>> + */
>>> +
>>> +#include <common.h>
>>> +#include <command.h>
>>> +#include <fsl_caam.h>
>>> +
>>> +static int do_caam(cmd_tbl_t *cmdtp, int flag, int argc, char * 
>>> const argv[])
>>> +{
>>> +    int ret, i;
>>> +
>>> +    if (argc < 2)
>>> +        return CMD_RET_USAGE;
>>> +
>>> +    if (strcmp(argv[1], "genblob") == 0) {
>>> +        if (argc != 5)
>>> +            return CMD_RET_USAGE;
>>> +
>>> +        void *data_addr;
>>> +        void *blob_addr;
>>> +        int size;
>>> +
>>> +        data_addr = (void *)simple_strtoul(argv[2], NULL, 16);
>>> +        blob_addr = (void *)simple_strtoul(argv[3], NULL, 16);
>>> +        size = simple_strtoul(argv[4], NULL, 10);
>>> +        if (size <= 48)
>>> +            return CMD_RET_USAGE;
>>> +
>>> +        caam_open();
>>> +        ret = caam_gen_blob((uint32_t)data_addr, 
>>> (uint32_t)blob_addr, (uint32_t)size);
>>> +
>>> +        if (ret != SUCCESS) {
>>> +            printf("Error during blob encap operation: 0x%x\n", ret);
>>> +            return 0;
>>> +        }
>>> +
>>> +        /* Print the generated DEK blob */
>>> +        printf("DEK blob is available at 0x%08X and equals:\n", 
>>> (unsigned int)blob_addr);
>>> +        for (i = 0; i < size; i++)
>>> +            printf("%02X ", ((uint8_t *)blob_addr)[i]);
>>> +        printf("\n\n");
>>> +
>>> +        return 1;
>>> +    } else if (strcmp(argv[1], "decap") == 0) {
>>> +        if (argc != 5)
>>> +            return CMD_RET_USAGE;
>>> +
>>> +        void *blob_addr;
>>> +        void *data_addr;
>>> +        int size;
>>> +
>>> +        blob_addr = (void *)simple_strtoul(argv[2], NULL, 16);
>>> +        data_addr = (void *)simple_strtoul(argv[3], NULL, 16);
>>> +        size      = simple_strtoul(argv[4], NULL, 10);
>>> +        if (size <= 48)
>>> +            return CMD_RET_USAGE;
>>> +
>>> +        caam_open();
>>> +        ret = caam_decap_blob((uint32_t)(data_addr), 
>>> (uint32_t)(blob_addr), (uint32_t)size);
>>> +        if (ret != SUCCESS) {
>>> +            printf("Error during blob decap operation: 0x%x\n", ret);
>>> +        } else {
>>> +            printf("Success, blob decap at SM PAGE1 original data 
>>> is:\n");
>>> +            int i = 0;
>>> +
>>> +            for (i = 0; i < size; i++) {
>>> +                printf("0x%x  ", *(unsigned char *)(data_addr + i));
>>> +                if (i % 16 == 0)
>>> +                    printf("\n");
>>> +            }
>>> +            printf("\n");
>>> +        }
>>> +
>>> +        return 1;
>>> +    }
>>> +
>>> +    return CMD_RET_USAGE;
>>> +}
>>> +
>>> +U_BOOT_CMD(
>>> +    caam, 5, 1, do_caam,
>>> +    "Freescale i.MX CAAM command",
>>> +    "caam genblob data_addr blob_addr data_size\n \
>>> +    caam decap blobaddr data_addr data_size\n \
>>> +    \n "
>>> +    );
>>> diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
>>> index efbd1d3fca..6069dd5b29 100644
>>> --- a/drivers/crypto/Makefile
>>> +++ b/drivers/crypto/Makefile
>>> @@ -4,5 +4,6 @@
>>>   #     http://www.samsung.com
>>>   obj-$(CONFIG_EXYNOS_ACE_SHA)    += ace_sha.o
>>> +obj-$(CONFIG_FSL_CAAM_KB)      += fsl_caam.o
>>>   obj-y += rsa_mod_exp/
>>>   obj-y += fsl/
>>> diff --git a/drivers/crypto/fsl_caam.c b/drivers/crypto/fsl_caam.c
>>> new file mode 100644
>>> index 0000000000..ccdf131635
>>> --- /dev/null
>>> +++ b/drivers/crypto/fsl_caam.c
>>> @@ -0,0 +1,715 @@
>>> +// SPDX-License-Identifier: GPL-2.0+
>>> +/*
>>> + * Copyright (c) 2012-2016, Freescale Semiconductor, Inc.
>>> + */
>>> +
>>> +#include <common.h>
>>> +#include <malloc.h>
>>> +#include <memalign.h>
>>> +#include <asm/io.h>
>>> +#ifndef CONFIG_ARCH_MX7ULP
>>> +#include <asm/arch/crm_regs.h>
>>> +#else
>>> +#include <asm/arch/pcc.h>
>>> +#endif /* CONFIG_ARCH_MX7ULP */
>>> +#include "fsl_caam_internal.h"
>>> +#include "fsl/desc_constr.h"
>>> +#include <fsl_caam.h>
>>> +#include <cpu_func.h>
>>> +
>>> +DECLARE_GLOBAL_DATA_PTR;
>>> +
>>> +static void rng_init(void);
>>> +static void caam_clock_enable(void);
>>> +static int do_cfg_jrqueue(void);
>>> +static int do_job(u32 *desc);
>>> +static int jr_reset(void);
>>> +
>>> +/*
>>> + * Structures
>>> + */
>>> +/* Definition of input ring object */
>>> +struct inring_entry {
>>> +    u32 desc; /* Pointer to input descriptor */
>>> +};
>>> +
>>> +/* Definition of output ring object */
>>> +struct outring_entry {
>>> +    u32 desc;   /* Pointer to output descriptor */
>>> +    u32 status; /* Status of the Job Ring       */
>>> +};
>>> +
>>> +/* Main job ring data structure */
>>> +struct jr_data_st {
>>> +    struct inring_entry  *inrings;
>>> +    struct outring_entry *outrings;
>>> +    u32 status;  /* Ring buffers init status */
>>> +    u32 *desc;   /* Pointer to output descriptor */
>>> +    u32 raw_addr[DESC_MAX_SIZE * 2];
>>> +};
>>> +
>>> +/*
>>> + * Global variables
>>> + */
>>> +#if defined(CONFIG_SPL_BUILD)
>>> +static struct jr_data_st g_jrdata = {0};
>>> +#else
>>> +static struct jr_data_st g_jrdata = {0, 0, 0xFFFFFFFF};
>>> +#endif
>>> +
>>> +static u8 skeymod[] = {
>>> +    0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08,
>>> +    0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00
>>> +};
>>> +
>>> +/*
>>> + * Local functions
>>> + */
>>> +static void dump_error(void)
>>> +{
>>> +    int i;
>>> +
>>> +    debug("Dump CAAM Error\n");
>>> +    debug("MCFGR 0x%08X\n", __raw_readl(CAAM_MCFGR));
>>> +    debug("FAR  0x%08X\n", __raw_readl(CAAM_FAR));
>>> +    debug("FAMR 0x%08X\n", __raw_readl(CAAM_FAMR));
>>> +    debug("FADR 0x%08X\n", __raw_readl(CAAM_FADR));
>>> +    debug("CSTA 0x%08X\n", __raw_readl(CAAM_STA));
>>> +    debug("RTMCTL 0x%X\n", __raw_readl(CAAM_RTMCTL));
>>> +    debug("RTSTATUS 0x%X\n", __raw_readl(CAAM_RTSTATUS));
>>> +    debug("RDSTA 0x%X\n", __raw_readl(CAAM_RDSTA));
>>> +
>>> +    for (i = 0; i < desc_len(g_jrdata.desc); i++)
>>> +        debug("desc[%d]: 0x%08x\n", i, g_jrdata.desc[i]);
>>> +}
>>> +
>>> +/*!
>>> + * Secure memory run command.
>>> + *
>>> + * @param   sec_mem_cmd  Secure memory command register
>>> + * @return  cmd_status  Secure memory command status register
>>> + */
>>> +u32 secmem_set_cmd_1(u32 sec_mem_cmd)
>>> +{
>>> +    u32 temp_reg;
>>> +
>>> +    __raw_writel(sec_mem_cmd, CAAM_SMCJR0);
>>> +    do {
>>> +        temp_reg = __raw_readl(CAAM_SMCSJR0);
>>> +    } while (temp_reg & CMD_COMPLETE);
>>> +
>>> +    return temp_reg;
>>> +}
>>> +
>>> +/*!
>>> + * Use CAAM to decapsulate a blob to secure memory.
>>> + * Such blob of secret key cannot be read once decrypted,
>>> + * but can still be used for enc/dec operation of user's data.
>>> + *
>>> + * @param   blob_addr  Location address of the blob.
>>> + *
>>> + * @return  SUCCESS or ERROR_XXX
>>> + */
>>> +u32 caam_decap_blob(u32 plain_text, u32 blob_addr, u32 size)
>>> +{
>>> +    u32 ret = SUCCESS;
>>> +    u32 key_sz = sizeof(skeymod);
>>> +    u32 *decap_desc = g_jrdata.desc;
>>> +
>>> +    /* prepare job descriptor */
>>> +    init_job_desc(decap_desc, 0);
>>> +    append_load(decap_desc, PTR2CAAMDMA(skeymod), key_sz,
>>> +            LDST_CLASS_2_CCB | LDST_SRCDST_BYTE_KEY);
>>> +    append_seq_in_ptr_intlen(decap_desc, blob_addr, size + 48, 0);
>>> +    append_seq_out_ptr_intlen(decap_desc, plain_text, size, 0);
>>> +    append_operation(decap_desc, OP_TYPE_DECAP_PROTOCOL | 
>>> OP_PCLID_BLOB);
>>> +
>>> +    flush_dcache_range((uintptr_t)blob_addr & ALIGN_MASK,
>>> +               ((uintptr_t)blob_addr & ALIGN_MASK)
>>> +                + ROUND(2 * size, ARCH_DMA_MINALIGN));
>>> +    flush_dcache_range((uintptr_t)plain_text & ALIGN_MASK,
>>> +               (plain_text & ALIGN_MASK)
>>> +               + ROUND(2 * size, ARCH_DMA_MINALIGN));
>>> +
>>> +    /* Run descriptor with result written to blob buffer */
>>> +    ret = do_job(decap_desc);
>>> +
>>> +    if (ret != SUCCESS)
>>> +        printf("Error: blob decap job failed 0x%x\n", ret);
>>> +
>>> +    return ret;
>>> +}
>>> +
>>> +/*!
>>> + * Use CAAM to generate a blob.
>>> + *
>>> + * @param   plain_data_addr  Location address of the plain data.
>>> + * @param   blob_addr  Location address of the blob.
>>> + *
>>> + * @return  SUCCESS or ERROR_XXX
>>> + */
>>> +u32 caam_gen_blob(u32 plain_data_addr, u32 blob_addr, u32 size)
>>> +{
>>> +    u32 ret = SUCCESS;
>>> +    u32 key_sz = sizeof(skeymod);
>>> +    u32 *encap_desc = g_jrdata.desc;
>>> +    /* Buffer to hold the resulting blob */
>>> +    u8 *blob = (u8 *)CAAMDMA2PTR(blob_addr);
>>> +
>>> +    /* initialize the blob array */
>>> +    memset(blob, 0, size);
>>> +
>>> +    /* prepare job descriptor */
>>> +    init_job_desc(encap_desc, 0);
>>> +    append_load(encap_desc, PTR2CAAMDMA(skeymod), key_sz,
>>> +            LDST_CLASS_2_CCB | LDST_SRCDST_BYTE_KEY);
>>> +    append_seq_in_ptr_intlen(encap_desc, plain_data_addr, size, 0);
>>> +    append_seq_out_ptr_intlen(encap_desc, PTR2CAAMDMA(blob), size + 
>>> 48, 0);
>>> +    append_operation(encap_desc, OP_TYPE_ENCAP_PROTOCOL | 
>>> OP_PCLID_BLOB);
>>> +
>>> +    flush_dcache_range((uintptr_t)plain_data_addr & ALIGN_MASK,
>>> +               (plain_data_addr & ALIGN_MASK)
>>> +               + ROUND(2 * size, ARCH_DMA_MINALIGN));
>>> +    flush_dcache_range((uintptr_t)blob & ALIGN_MASK,
>>> +               ((uintptr_t)blob & ALIGN_MASK)
>>> +               + ROUND(2 * size, ARCH_DMA_MINALIGN));
>>> +
>>> +    ret = do_job(encap_desc);
>>> +
>>> +    if (ret != SUCCESS)
>>> +        printf("Error: blob encap job failed 0x%x\n", ret);
>>> +
>>> +    return ret;
>>> +}
>>> +
>>> +u32 caam_hwrng(u8 *output_ptr, u32 output_len)
>>> +{
>>> +    u32 ret = SUCCESS;
>>> +    u32 *hwrng_desc = g_jrdata.desc;
>>> +    /* Buffer to hold the resulting output*/
>>> +    u8 *output = (u8 *)output_ptr;
>>> +
>>> +    /* initialize the output array */
>>> +    memset(output, 0, output_len);
>>> +
>>> +    /* prepare job descriptor */
>>> +    init_job_desc(hwrng_desc, 0);
>>> +    append_operation(hwrng_desc, OP_ALG_ALGSEL_RNG | 
>>> OP_TYPE_CLASS1_ALG);
>>> +    append_fifo_store(hwrng_desc, PTR2CAAMDMA(output),
>>> +              output_len, FIFOST_TYPE_RNGSTORE);
>>> +
>>> +    /* flush cache */
>>> +    flush_dcache_range((uintptr_t)hwrng_desc & ALIGN_MASK,
>>> +               ((uintptr_t)hwrng_desc & ALIGN_MASK)
>>> +               + ROUND(DESC_MAX_SIZE, ARCH_DMA_MINALIGN));
>>> +
>>> +    ret = do_job(hwrng_desc);
>>> +
>>> +    flush_dcache_range((uintptr_t)output & ALIGN_MASK,
>>> +               ((uintptr_t)output & ALIGN_MASK)
>>> +               + ROUND(2 * output_len, ARCH_DMA_MINALIGN));
>>> +
>>> +    if (ret != SUCCESS)
>>> +        printf("Error: RNG generate failed 0x%x\n", ret);
>>> +
>>> +    return ret;
>>> +}
>>> +
>>> +/*!
>>> + * Initialize the CAAM.
>>> + *
>>> + */
>>> +void caam_open(void)
>>> +{
>>> +    u32 temp_reg;
>>> +    int ret;
>>> +
>>> +    /* switch on the clock */
>>> +#ifndef CONFIG_ARCH_IMX8
>>> +    caam_clock_enable();
>>> +#endif
>>> +
>>> +    /* reset the CAAM */
>>> +    temp_reg = __raw_readl(CAAM_MCFGR) |
>>> +            CAAM_MCFGR_DMARST | CAAM_MCFGR_SWRST;
>>> +    __raw_writel(temp_reg,  CAAM_MCFGR);
>>> +    while (__raw_readl(CAAM_MCFGR) & CAAM_MCFGR_DMARST)
>>> +        ;
>>> +
>>> +    jr_reset();
>>> +    ret = do_cfg_jrqueue();
>>> +
>>> +    if (ret != SUCCESS) {
>>> +        printf("Error CAAM JR initialization\n");
>>> +        return;
>>> +    }
>>> +
>>> +    /* Check if the RNG is already instantiated */
>>> +    temp_reg = __raw_readl(CAAM_RDSTA);
>>> +    if (temp_reg == (RDSTA_IF0 | RDSTA_IF1 | RDSTA_SKVN)) {
>>> +        printf("RNG already instantiated 0x%X\n", temp_reg);
>>> +        return;
>>> +    }
>>> +
>>> +    rng_init();
>>> +}
>>> +
>>> +static void caam_clock_enable(void)
>>> +{
>>> +#if defined(CONFIG_ARCH_MX6)
>>> +    struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
>>> +    u32 reg;
>>> +
>>> +    reg = __raw_readl(&mxc_ccm->CCGR0);
>>> +
>>> +    reg |= (MXC_CCM_CCGR0_CAAM_SECURE_MEM_MASK |
>>> +        MXC_CCM_CCGR0_CAAM_WRAPPER_ACLK_MASK |
>>> +        MXC_CCM_CCGR0_CAAM_WRAPPER_IPG_MASK);
>>> +
>>> +    __raw_writel(reg, &mxc_ccm->CCGR0);
>>> +
>>> +#ifndef CONFIG_MX6UL
>>> +    /* EMI slow clk */
>>> +    reg = __raw_readl(&mxc_ccm->CCGR6);
>>> +    reg |= MXC_CCM_CCGR6_EMI_SLOW_MASK;
>>> +
>>> +    __raw_writel(reg, &mxc_ccm->CCGR6);
>>> +#endif
>>> +
>>> +#elif defined(CONFIG_ARCH_MX7)
>>> +    HW_CCM_CCGR_SET(36, MXC_CCM_CCGR36_CAAM_DOMAIN0_MASK);
>>> +#elif defined(CONFIG_ARCH_MX7ULP)
>>> +    pcc_clock_enable(PER_CLK_CAAM, true);
>>> +#endif
>>> +}
>>> +
>>> +static void kick_trng(u32 ent_delay)
>>> +{
>>> +    u32 samples  = 512; /* number of bits to generate and test */
>>> +    u32 mono_min = 195;
>>> +    u32 mono_max = 317;
>>> +    u32 mono_range  = mono_max - mono_min;
>>> +    u32 poker_min = 1031;
>>> +    u32 poker_max = 1600;
>>> +    u32 poker_range = poker_max - poker_min + 1;
>>> +    u32 retries    = 2;
>>> +    u32 lrun_max   = 32;
>>> +    s32 run_1_min   = 27;
>>> +    s32 run_1_max   = 107;
>>> +    s32 run_1_range = run_1_max - run_1_min;
>>> +    s32 run_2_min   = 7;
>>> +    s32 run_2_max   = 62;
>>> +    s32 run_2_range = run_2_max - run_2_min;
>>> +    s32 run_3_min   = 0;
>>> +    s32 run_3_max   = 39;
>>> +    s32 run_3_range = run_3_max - run_3_min;
>>> +    s32 run_4_min   = -1;
>>> +    s32 run_4_max   = 26;
>>> +    s32 run_4_range = run_4_max - run_4_min;
>>> +    s32 run_5_min   = -1;
>>> +    s32 run_5_max   = 18;
>>> +    s32 run_5_range = run_5_max - run_5_min;
>>> +    s32 run_6_min   = -1;
>>> +    s32 run_6_max   = 17;
>>> +    s32 run_6_range = run_6_max - run_6_min;
>>> +    u32 val;
>>> +
>>> +    /* Put RNG in program mode */
>>> +    setbits_le32(CAAM_RTMCTL, RTMCTL_PGM);
>>> +    /* Configure the RNG Entropy Delay
>>> +     * Performance-wise, it does not make sense to
>>> +     * set the delay to a value that is lower
>>> +     * than the last one that worked (i.e. the state handles
>>> +     * were instantiated properly. Thus, instead of wasting
>>> +     * time trying to set the values controlling the sample
>>> +     * frequency, the function simply returns.
>>> +     */
>>> +    val = __raw_readl(CAAM_RTSDCTL);
>>> +    val &= BM_TRNG_ENT_DLY;
>>> +    val >>= BS_TRNG_ENT_DLY;
>>> +    if (ent_delay < val) {
>>> +        /* Put RNG4 into run mode */
>>> +        clrbits_le32(CAAM_RTMCTL, RTMCTL_PGM);
>>> +        return;
>>> +    }
>>> +
>>> +    val = (ent_delay << BS_TRNG_ENT_DLY) | samples;
>>> +    __raw_writel(val, CAAM_RTSDCTL);
>>> +
>>> +    /* min. freq. count, equal to 1/2 of the entropy sample length */
>>> +    __raw_writel(ent_delay >> 1, CAAM_RTFRQMIN);
>>> +
>>> +    /* max. freq. count, equal to 32 times the entropy sample length */
>>> +    __raw_writel(ent_delay << 5, CAAM_RTFRQMAX);
>>> +
>>> +    __raw_writel((retries << 16) | lrun_max, CAAM_RTSCMISC);
>>> +    __raw_writel(poker_max, CAAM_RTPKRMAX);
>>> +    __raw_writel(poker_range, CAAM_RTPKRRNG);
>>> +    __raw_writel((mono_range << 16) | mono_max, CAAM_RTSCML);
>>> +    __raw_writel((run_1_range << 16) | run_1_max, CAAM_RTSCR1L);
>>> +    __raw_writel((run_2_range << 16) | run_2_max, CAAM_RTSCR2L);
>>> +    __raw_writel((run_3_range << 16) | run_3_max, CAAM_RTSCR3L);
>>> +    __raw_writel((run_4_range << 16) | run_4_max, CAAM_RTSCR4L);
>>> +    __raw_writel((run_5_range << 16) | run_5_max, CAAM_RTSCR5L);
>>> +    __raw_writel((run_6_range << 16) | run_6_max, CAAM_RTSCR6PL);
>>> +
>>> +    val = __raw_readl(CAAM_RTMCTL);
>>> +    /*
>>> +     * Select raw sampling in both entropy shifter
>>> +     * and statistical checker
>>> +     */
>>> +    val &= ~BM_TRNG_SAMP_MODE;
>>> +    val |= TRNG_SAMP_MODE_RAW_ES_SC;
>>> +    /* Put RNG4 into run mode */
>>> +    val &= ~RTMCTL_PGM;
>>> +/*test with sample mode only */
>>> +    __raw_writel(val, CAAM_RTMCTL);
>>> +
>>> +    /* Clear the ERR bit in RTMCTL if set. The TRNG error can occur 
>>> when the
>>> +     * RNG clock is not within 1/2x to 8x the system clock.
>>> +     * This error is possible if ROM code does not initialize the 
>>> system PLLs
>>> +     * immediately after PoR.
>>> +     */
>>> +    /* setbits_le32(CAAM_RTMCTL, RTMCTL_ERR); */
>>> +}
>>> +
>>> +/*
>>> + *  Descriptors to instantiate SH0, SH1, load the keys
>>> + */
>>> +static const u32 rng_inst_sh0_desc[] = {
>>> +    /* Header, don't setup the size */
>>> +    CAAM_HDR_CTYPE | CAAM_HDR_ONE | CAAM_HDR_START_INDEX(0),
>>> +    /* Operation instantiation (sh0) */
>>> +    CAAM_PROTOP_CTYPE | CAAM_C1_RNG | ALGO_RNG_SH(0) | 
>>> ALGO_RNG_INSTANTIATE,
>>> +};
>>> +
>>> +static const u32 rng_inst_sh1_desc[] = {
>>> +    /* wait for done - Jump to next entry */
>>> +    CAAM_C1_JUMP | CAAM_JUMP_LOCAL | CAAM_JUMP_TST_ALL_COND_TRUE
>>> +        | CAAM_JUMP_OFFSET(1),
>>> +    /* Clear written register (write 1) */
>>> +    CAAM_C0_LOAD_IMM | CAAM_DST_CLEAR_WRITTEN | sizeof(u32),
>>> +    0x00000001,
>>> +    /* Operation instantiation (sh1) */
>>> +    CAAM_PROTOP_CTYPE | CAAM_C1_RNG | ALGO_RNG_SH(1)
>>> +        | ALGO_RNG_INSTANTIATE,
>>> +};
>>> +
>>> +static const u32 rng_inst_load_keys[] = {
>>> +    /* wait for done - Jump to next entry */
>>> +    CAAM_C1_JUMP | CAAM_JUMP_LOCAL | CAAM_JUMP_TST_ALL_COND_TRUE
>>> +        | CAAM_JUMP_OFFSET(1),
>>> +    /* Clear written register (write 1) */
>>> +    CAAM_C0_LOAD_IMM | CAAM_DST_CLEAR_WRITTEN | sizeof(u32),
>>> +    0x00000001,
>>> +    /* Generate the Key */
>>> +    CAAM_PROTOP_CTYPE | CAAM_C1_RNG | BM_ALGO_RNG_SK | 
>>> ALGO_RNG_GENERATE,
>>> +};
>>> +
>>> +static void do_inst_desc(u32 *desc, u32 status)
>>> +{
>>> +    u32 *pdesc = desc;
>>> +    u8  desc_len;
>>> +    bool add_sh0   = false;
>>> +    bool add_sh1   = false;
>>> +    bool load_keys = false;
>>> +
>>> +    /*
>>> +     * Modify the the descriptor to remove if necessary:
>>> +     *  - The key loading
>>> +     *  - One of the SH already instantiated
>>> +     */
>>> +    desc_len = RNG_DESC_SH0_SIZE;
>>> +    if ((status & RDSTA_IF0) != RDSTA_IF0)
>>> +        add_sh0 = true;
>>> +
>>> +    if ((status & RDSTA_IF1) != RDSTA_IF1) {
>>> +        add_sh1 = true;
>>> +        if (add_sh0)
>>> +            desc_len += RNG_DESC_SH1_SIZE;
>>> +    }
>>> +
>>> +    if ((status & RDSTA_SKVN) != RDSTA_SKVN) {
>>> +        load_keys = true;
>>> +        desc_len += RNG_DESC_KEYS_SIZE;
>>> +    }
>>> +
>>> +    /* Copy the SH0 descriptor anyway */
>>> +    memcpy(pdesc, rng_inst_sh0_desc, sizeof(rng_inst_sh0_desc));
>>> +    pdesc += RNG_DESC_SH0_SIZE;
>>> +
>>> +    if (load_keys) {
>>> +        debug("RNG - Load keys\n");
>>> +        memcpy(pdesc, rng_inst_load_keys, sizeof(rng_inst_load_keys));
>>> +        pdesc += RNG_DESC_KEYS_SIZE;
>>> +    }
>>> +
>>> +    if (add_sh1) {
>>> +        if (add_sh0) {
>>> +            debug("RNG - Instantiation of SH0 and SH1\n");
>>> +            /* Add the sh1 descriptor */
>>> +            memcpy(pdesc, rng_inst_sh1_desc,
>>> +                   sizeof(rng_inst_sh1_desc));
>>> +        } else {
>>> +            debug("RNG - Instantiation of SH1 only\n");
>>> +            /* Modify the SH0 descriptor to instantiate only SH1 */
>>> +            desc[1] &= ~BM_ALGO_RNG_SH;
>>> +            desc[1] |= ALGO_RNG_SH(1);
>>> +        }
>>> +    }
>>> +
>>> +    /* Setup the descriptor size */
>>> +    desc[0] &= ~(0x3F);
>>> +    desc[0] |= CAAM_HDR_DESCLEN(desc_len);
>>> +}
>>> +
>>> +static int jr_reset(void)
>>> +{
>>> +    /*
>>> +     * Function reset the Job Ring HW
>>> +     * Reset is done in 2 steps:
>>> +     *  - Flush all pending jobs (Set RESET bit)
>>> +     *  - Reset the Job Ring (Set RESET bit second time)
>>> +     */
>>> +    u16 timeout = 10000;
>>> +    u32 reg_val;
>>> +
>>> +    /* Mask interrupts to poll for reset completion status */
>>> +    setbits_le32(CAAM_JRCFGR0_LS, BM_JRCFGR_LS_IMSK);
>>> +
>>> +    /* Initiate flush (required prior to reset) */
>>> +    __raw_writel(JRCR_RESET, CAAM_JRCR0);
>>> +    do {
>>> +        reg_val = __raw_readl(CAAM_JRINTR0);
>>> +        reg_val &= BM_JRINTR_HALT;
>>> +    } while ((reg_val == JRINTR_HALT_ONGOING) && --timeout);
>>> +
>>> +    if (!timeout  || reg_val != JRINTR_HALT_DONE) {
>>> +        printf("Failed to flush job ring\n");
>>> +        return ERROR_ANY;
>>> +    }
>>> +
>>> +    /* Initiate reset */
>>> +    timeout = 100;
>>> +    __raw_writel(JRCR_RESET, CAAM_JRCR0);
>>> +    do {
>>> +        reg_val = __raw_readl(CAAM_JRCR0);
>>> +    } while ((reg_val & JRCR_RESET) && --timeout);
>>> +
>>> +    if (!timeout) {
>>> +        printf("Failed to reset job ring\n");
>>> +        return ERROR_ANY;
>>> +    }
>>> +
>>> +    return 0;
>>> +}
>>> +
>>> +static int do_job(u32 *desc)
>>> +{
>>> +    int ret;
>>> +    phys_addr_t p_desc = virt_to_phys(desc);
>>> +
>>> +    if (__raw_readl(CAAM_IRSAR0) == 0)
>>> +        return ERROR_ANY;
>>> +    g_jrdata.inrings[0].desc = p_desc;
>>> +
>>> +    flush_dcache_range((uintptr_t)g_jrdata.inrings & ALIGN_MASK,
>>> +               ((uintptr_t)g_jrdata.inrings & ALIGN_MASK)
>>> +               + ROUND(DESC_MAX_SIZE, ARCH_DMA_MINALIGN));
>>> +    flush_dcache_range((uintptr_t)desc & ALIGN_MASK,
>>> +               ((uintptr_t)desc & ALIGN_MASK)
>>> +               + ROUND(DESC_MAX_SIZE, ARCH_DMA_MINALIGN));
>>> +
>>> +    /* Inform HW that a new JR is available */
>>> +    __raw_writel(1, CAAM_IRJAR0);
>>> +    while (__raw_readl(CAAM_ORSFR0) == 0)
>>> +        ;
>>> +
>>> +    flush_dcache_range((uintptr_t)g_jrdata.outrings & ALIGN_MASK,
>>> +               ((uintptr_t)g_jrdata.outrings & ALIGN_MASK)
>>> +               + ROUND(DESC_MAX_SIZE, ARCH_DMA_MINALIGN));
>>> +
>>> +    if (PTR2CAAMDMA(desc) == g_jrdata.outrings[0].desc) {
>>> +        ret = g_jrdata.outrings[0].status;
>>> +    } else {
>>> +        dump_error();
>>> +        ret = ERROR_ANY;
>>> +    }
>>> +
>>> +    /* Acknowledge interrupt */
>>> +    setbits_le32(CAAM_JRINTR0, JRINTR_JRI);
>>> +
>>> +    /* Remove the JR from the output list even if no JR caller found */
>>> +    __raw_writel(1, CAAM_ORJRR0);
>>> +
>>> +    return ret;
>>> +}
>>> +
>>> +static int do_cfg_jrqueue(void)
>>> +{
>>> +    u32 value = 0;
>>> +    phys_addr_t ip_base;
>>> +    phys_addr_t op_base;
>>> +
>>> +    /* check if already configured after relocation */
>>> +    if (g_jrdata.status == RING_RELOC_INIT)
>>> +        return 0;
>>> +
>>> +    /*
>>> +     * jr configuration needs to be updated once, after relocation 
>>> to ensure
>>> +     * using the right buffers.
>>> +     * When buffers are updated after relocation the flag 
>>> RING_RELOC_INIT
>>> +     * is used to prevent extra updates
>>> +     */
>>> +    if (gd->flags & GD_FLG_RELOC) {
>>> +        g_jrdata.inrings  = (struct inring_entry *)
>>> +                    memalign(ARCH_DMA_MINALIGN,
>>> +                         ARCH_DMA_MINALIGN);
>>> +        g_jrdata.outrings = (struct outring_entry *)
>>> +                    memalign(ARCH_DMA_MINALIGN,
>>> +                         ARCH_DMA_MINALIGN);
>>> +        g_jrdata.desc = (u32 *)
>>> +                memalign(ARCH_DMA_MINALIGN, ARCH_DMA_MINALIGN);
>>> +        g_jrdata.status = RING_RELOC_INIT;
>>> +    } else {
>>> +        u32 align_idx = 0;
>>> +
>>> +        /* Ensure 64bits buffers addresses alignment */
>>> +        if ((uintptr_t)g_jrdata.raw_addr & 0x7)
>>> +            align_idx = 1;
>>> +        g_jrdata.inrings  = (struct inring_entry *)
>>> +                    (&g_jrdata.raw_addr[align_idx]);
>>> +        g_jrdata.outrings = (struct outring_entry *)
>>> +                    (&g_jrdata.raw_addr[align_idx + 2]);
>>> +        g_jrdata.desc = (u32 *)(&g_jrdata.raw_addr[align_idx + 4]);
>>> +        g_jrdata.status = RING_EARLY_INIT;
>>> +    }
>>> +
>>> +    if (!g_jrdata.inrings || !g_jrdata.outrings)
>>> +        return ERROR_ANY;
>>> +
>>> +    /* Configure the HW Job Rings */
>>> +    ip_base = virt_to_phys((void *)g_jrdata.inrings);
>>> +    op_base = virt_to_phys((void *)g_jrdata.outrings);
>>> +    __raw_writel(ip_base, CAAM_IRBAR0);
>>> +    __raw_writel(1, CAAM_IRSR0);
>>> +
>>> +    __raw_writel(op_base, CAAM_ORBAR0);
>>> +    __raw_writel(1, CAAM_ORSR0);
>>> +
>>> +    setbits_le32(CAAM_JRINTR0, JRINTR_JRI);
>>> +
>>> +    /*
>>> +     * Configure interrupts but disable it:
>>> +     * Optimization to generate an interrupt either when there are
>>> +     * half of the job done or when there is a job done and
>>> +     * 10 clock cycles elapse without new job complete
>>> +     */
>>> +    value = 10 << BS_JRCFGR_LS_ICTT;
>>> +    value |= (1 << BS_JRCFGR_LS_ICDCT) & BM_JRCFGR_LS_ICDCT;
>>> +    value |= BM_JRCFGR_LS_ICEN;
>>> +    value |= BM_JRCFGR_LS_IMSK;
>>> +    __raw_writel(value, CAAM_JRCFGR0_LS);
>>> +
>>> +    /* Enable deco watchdog */
>>> +    setbits_le32(CAAM_MCFGR, BM_MCFGR_WDE);
>>> +
>>> +    return 0;
>>> +}
>>> +
>>> +static void do_clear_rng_error(void)
>>> +{
>>> +    u32 val;
>>> +
>>> +    val = __raw_readl(CAAM_RTMCTL);
>>> +
>>> +    if (val & (RTMCTL_ERR | RTMCTL_FCT_FAIL)) {
>>> +        setbits_le32(CAAM_RTMCTL, RTMCTL_ERR);
>>> +    val = __raw_readl(CAAM_RTMCTL);
>>> +    }
>>> +}
>>> +
>>> +static int do_instantiation(void)
>>> +{
>>> +    int ret = ERROR_ANY;
>>> +    u32 cha_vid_ls;
>>> +    u32 ent_delay;
>>> +    u32 status;
>>> +
>>> +    if (!g_jrdata.desc) {
>>> +        printf("%d: CAAM Descriptor allocation error\n", __LINE__);
>>> +        return ERROR_ANY;
>>> +    }
>>> +
>>> +    cha_vid_ls = __raw_readl(CAAM_CHAVID_LS);
>>> +
>>> +    /*
>>> +     * If SEC has RNG version >= 4 and RNG state handle has not been
>>> +     * already instantiated, do RNG instantiation
>>> +     */
>>> +    if (((cha_vid_ls & BM_CHAVID_LS_RNGVID) >> BS_CHAVID_LS_RNGVID) 
>>> < 4) {
>>> +        printf("%d: RNG already instantiated\n", __LINE__);
>>> +        return 0;
>>> +    }
>>> +
>>> +    ent_delay = TRNG_SDCTL_ENT_DLY_MIN;
>>> +
>>> +    do {
>>> +        /* Read the CAAM RNG status */
>>> +        status = __raw_readl(CAAM_RDSTA);
>>> +
>>> +        if ((status & RDSTA_IF0) != RDSTA_IF0) {
>>> +            /* Configure the RNG entropy delay */
>>> +            kick_trng(ent_delay);
>>> +            ent_delay += 400;
>>> +        }
>>> +
>>> +        do_clear_rng_error();
>>> +
>>> +        if ((status & (RDSTA_IF0 | RDSTA_IF1)) !=
>>> +                (RDSTA_IF0 | RDSTA_IF1)) {
>>> +            /* Prepare the instantiation descriptor */
>>> +            do_inst_desc(g_jrdata.desc, status);
>>> +
>>> +            /* Run Job */
>>> +            ret = do_job(g_jrdata.desc);
>>> +
>>> +            if (ret == ERROR_ANY) {
>>> +                /* CAAM JR failure ends here */
>>> +                printf("RNG Instantiation error\n");
>>> +                goto end_instantation;
>>> +            }
>>> +        } else {
>>> +            ret = SUCCESS;
>>> +            printf("RNG instantiation done (%d)\n", ent_delay);
>>> +            goto end_instantation;
>>> +        }
>>> +    } while (ent_delay < TRNG_SDCTL_ENT_DLY_MAX);
>>> +
>>> +    printf("RNG Instantation Failure - Entropy delay (%d)\n", 
>>> ent_delay);
>>> +    ret = ERROR_ANY;
>>> +
>>> +end_instantation:
>>> +    return ret;
>>> +}
>>> +
>>> +static void rng_init(void)
>>> +{
>>> +    int  ret;
>>> +
>>> +    ret = jr_reset();
>>> +    if (ret != SUCCESS) {
>>> +        printf("Error CAAM JR reset\n");
>>> +        return;
>>> +    }
>>> +
>>> +    ret = do_instantiation();
>>> +
>>> +    if (ret != SUCCESS)
>>> +        printf("Error do_instantiation\n");
>>> +
>>> +    jr_reset();
>>> +
>>> +    return;
>>> +}
>>> +
>>> diff --git a/drivers/crypto/fsl_caam_internal.h 
>>> b/drivers/crypto/fsl_caam_internal.h
>>> new file mode 100644
>>> index 0000000000..837562d3c4
>>> --- /dev/null
>>> +++ b/drivers/crypto/fsl_caam_internal.h
>>> @@ -0,0 +1,229 @@
>>> +/* SPDX-License-Identifier: GPL-2.0+ */
>>> +/*
>>> + * Copyright (c) 2012-2016, Freescale Semiconductor, Inc.
>>> + * Copyright 2018 NXP
>>> + */
>>> +
>>> +#ifndef __CAAM_INTERNAL_H__
>>> +#define __CAAM_INTERNAL_H__
>>> +
>>> +/* 4kbyte pages */
>>> +#define CAAM_SEC_RAM_START_ADDR CAAM_ARB_BASE_ADDR
>>> +
>>> +#define SEC_MEM_PAGE0       CAAM_SEC_RAM_START_ADDR
>>> +#define SEC_MEM_PAGE1       (CAAM_SEC_RAM_START_ADDR + 0x1000)
>>> +#define SEC_MEM_PAGE2       (CAAM_SEC_RAM_START_ADDR + 0x2000)
>>> +#define SEC_MEM_PAGE3       (CAAM_SEC_RAM_START_ADDR + 0x3000)
>>> +
>>> +/* Configuration and special key registers */
>>> +#define CAAM_MCFGR          (CONFIG_SYS_FSL_SEC_ADDR + 0x0004)
>>> +#define CAAM_SCFGR          (CONFIG_SYS_FSL_SEC_ADDR + 0x000c)
>>> +#define CAAM_JR0MIDR        (CONFIG_SYS_FSL_SEC_ADDR + 0x0010)
>>> +#define CAAM_JR1MIDR        (CONFIG_SYS_FSL_SEC_ADDR + 0x0018)
>>> +#define CAAM_DECORR         (CONFIG_SYS_FSL_SEC_ADDR + 0x009c)
>>> +#define CAAM_DECO0MID       (CONFIG_SYS_FSL_SEC_ADDR + 0x00a0)
>>> +#define CAAM_DAR            (CONFIG_SYS_FSL_SEC_ADDR + 0x0120)
>>> +#define CAAM_DRR            (CONFIG_SYS_FSL_SEC_ADDR + 0x0124)
>>> +#define CAAM_JDKEKR         (CONFIG_SYS_FSL_SEC_ADDR + 0x0400)
>>> +#define CAAM_TDKEKR         (CONFIG_SYS_FSL_SEC_ADDR + 0x0420)
>>> +#define CAAM_TDSKR          (CONFIG_SYS_FSL_SEC_ADDR + 0x0440)
>>> +#define CAAM_SKNR           (CONFIG_SYS_FSL_SEC_ADDR + 0x04e0)
>>> +#define CAAM_SMSTA          (CONFIG_SYS_FSL_SEC_ADDR + 0x0FB4)
>>> +#define CAAM_STA            (CONFIG_SYS_FSL_SEC_ADDR + 0x0FD4)
>>> +#define CAAM_SMPO_0         (CONFIG_SYS_FSL_SEC_ADDR + 0x1FBC)
>>> +#define CAAM_CHAVID_LS      (CONFIG_SYS_FSL_SEC_ADDR + 0x0FEC)
>>> +#define CAAM_FAR            (CONFIG_SYS_FSL_SEC_ADDR + 0x0FC0)
>>> +#define CAAM_FAMR           (CONFIG_SYS_FSL_SEC_ADDR + 0x0FC8)
>>> +#define CAAM_FADR           (CONFIG_SYS_FSL_SEC_ADDR + 0x0FCC)
>>> +
>>> +/* RNG registers */
>>> +#define CAAM_RTMCTL         (CONFIG_SYS_FSL_SEC_ADDR + 0x0600)
>>> +#define CAAM_RTSCMISC       (CONFIG_SYS_FSL_SEC_ADDR + 0x0604)
>>> +#define CAAM_RTPKRRNG       (CONFIG_SYS_FSL_SEC_ADDR + 0x0608)
>>> +#define CAAM_RTPKRMAX       (CONFIG_SYS_FSL_SEC_ADDR + 0x060C)
>>> +#define CAAM_RTSDCTL        (CONFIG_SYS_FSL_SEC_ADDR + 0x0610)
>>> +#define CAAM_RTFRQMIN       (CONFIG_SYS_FSL_SEC_ADDR + 0x0618)
>>> +#define CAAM_RTFRQMAX       (CONFIG_SYS_FSL_SEC_ADDR + 0x061C)
>>> +#define CAAM_RTSCML         (CONFIG_SYS_FSL_SEC_ADDR + 0x0620)
>>> +#define CAAM_RTSCR1L        (CONFIG_SYS_FSL_SEC_ADDR + 0x0624)
>>> +#define CAAM_RTSCR2L        (CONFIG_SYS_FSL_SEC_ADDR + 0x0628)
>>> +#define CAAM_RTSCR3L        (CONFIG_SYS_FSL_SEC_ADDR + 0x062C)
>>> +#define CAAM_RTSCR4L        (CONFIG_SYS_FSL_SEC_ADDR + 0x0630)
>>> +#define CAAM_RTSCR5L        (CONFIG_SYS_FSL_SEC_ADDR + 0x0634)
>>> +#define CAAM_RTSCR6PL       (CONFIG_SYS_FSL_SEC_ADDR + 0x0638)
>>> +#define CAAM_RTSTATUS       (CONFIG_SYS_FSL_SEC_ADDR + 0x063C)
>>> +#define CAAM_RDSTA          (CONFIG_SYS_FSL_SEC_ADDR + 0x06C0)
>>> +
>>> +/* Job Ring 0 registers */
>>> +#define CAAM_IRBAR0         (CONFIG_SYS_FSL_SEC_ADDR + 0x1004)
>>> +#define CAAM_IRSR0          (CONFIG_SYS_FSL_SEC_ADDR + 0x100c)
>>> +#define CAAM_IRSAR0         (CONFIG_SYS_FSL_SEC_ADDR + 0x1014)
>>> +#define CAAM_IRJAR0         (CONFIG_SYS_FSL_SEC_ADDR + 0x101c)
>>> +#define CAAM_ORBAR0         (CONFIG_SYS_FSL_SEC_ADDR + 0x1024)
>>> +#define CAAM_ORSR0          (CONFIG_SYS_FSL_SEC_ADDR + 0x102c)
>>> +#define CAAM_ORJRR0         (CONFIG_SYS_FSL_SEC_ADDR + 0x1034)
>>> +#define CAAM_ORSFR0         (CONFIG_SYS_FSL_SEC_ADDR + 0x103c)
>>> +#define CAAM_JRSTAR0        (CONFIG_SYS_FSL_SEC_ADDR + 0x1044)
>>> +#define CAAM_JRINTR0        (CONFIG_SYS_FSL_SEC_ADDR + 0x104c)
>>> +#define CAAM_JRCFGR0_MS     (CONFIG_SYS_FSL_SEC_ADDR + 0x1050)
>>> +#define CAAM_JRCFGR0_LS     (CONFIG_SYS_FSL_SEC_ADDR + 0x1054)
>>> +#define CAAM_IRRIR0         (CONFIG_SYS_FSL_SEC_ADDR + 0x105c)
>>> +#define CAAM_ORWIR0         (CONFIG_SYS_FSL_SEC_ADDR + 0x1064)
>>> +#define CAAM_JRCR0          (CONFIG_SYS_FSL_SEC_ADDR + 0x106c)
>>> +#define CAAM_SMCJR0         (CONFIG_SYS_FSL_SEC_ADDR + 0x10f4)
>>> +#define CAAM_SMCSJR0        (CONFIG_SYS_FSL_SEC_ADDR + 0x10fc)
>>> +#define CAAM_SMAPJR0(y)     (CONFIG_SYS_FSL_SEC_ADDR + 0x1104 + y * 16)
>>> +#define CAAM_SMAG2JR0(y)    (CONFIG_SYS_FSL_SEC_ADDR + 0x1108 + y * 16)
>>> +#define CAAM_SMAG1JR0(y)    (CONFIG_SYS_FSL_SEC_ADDR + 0x110C + y * 16)
>>> +#define CAAM_SMAPJR0_PRTN1  (CONFIG_SYS_FSL_SEC_ADDR + 0x1114)
>>> +#define CAAM_SMAG2JR0_PRTN1 (CONFIG_SYS_FSL_SEC_ADDR + 0x1118)
>>> +#define CAAM_SMAG1JR0_PRTN1 (CONFIG_SYS_FSL_SEC_ADDR + 0x111c)
>>> +#define CAAM_SMPO           (CONFIG_SYS_FSL_SEC_ADDR + 0x1fbc)
>>> +
>>> +#define DESC_MAX_SIZE       (0x40)        /* Descriptor max size */
>>> +#define JRCFG_LS_IMSK       (0x01)        /* Interrupt Mask */
>>> +#define JR_MID              (0x02)        /* Matches ROM 
>>> configuration */
>>> +#define KS_G1               BIT(JR_MID)   /* CAAM only */
>>> +#define PERM                (0x0000B008)  /* Clear on release, lock 
>>> SMAP,
>>> +                       * lock SMAG and group 1 Blob
>>> +                       */
>>> +
>>> +#define CMD_PAGE_ALLOC      (0x1)
>>> +#define CMD_PAGE_DEALLOC    (0x2)
>>> +#define CMD_PART_DEALLOC    (0x3)
>>> +#define CMD_INQUIRY         (0x5)
>>> +#define PAGE(x)             ((x) << 16)
>>> +#define PARTITION(x)        ((x) << 8)
>>> +
>>> +#define SMCSJR_AERR         (3 << 12)
>>> +#define SMCSJR_CERR         (3 << 14)
>>> +#define CMD_COMPLETE        (3 << 14)
>>> +
>>> +#define SMCSJR_PO           (3 << 6)
>>> +#define PAGE_AVAILABLE      (0)
>>> +#define PAGE_OWNED          (3 << 6)
>>> +
>>> +#define PARTITION_OWNER(x)  (0x3 << ((x) * 2))
>>> +
>>> +#define CAAM_BUSY_MASK      (0x00000001) /* BUSY from status reg */
>>> +#define CAAM_IDLE_MASK      (0x00000002) /* IDLE from status reg */
>>> +#define CAAM_MCFGR_SWRST    BIT(31)      /* CAAM SW reset */
>>> +#define CAAM_MCFGR_DMARST   BIT(28)      /* CAAM DMA reset */
>>> +
>>> +#define JOB_RING_ENTRIES    (1)
>>> +#define JOB_RING_STS        (0xF << 28)
>>> +
>>> +/** OSC_DIV in RNG trim fuses */
>>> +#define RNG_TRIM_OSC_DIV    (0)
>>> +/** ENT_DLY multiplier in RNG trim fuses */
>>> +#define TRNG_SDCTL_ENT_DLY_MIN (3200)
>>> +#define TRNG_SDCTL_ENT_DLY_MAX (4800)
>>> +
>>> +#define RTMCTL_PGM       BIT(16)
>>> +#define RTMCTL_ERR       BIT(12)
>>> +#define RTMCTL_RST       BIT(6)
>>> +#define RDSTA_IF0        (1)
>>> +#define RDSTA_IF1        (2)
>>> +#define RDSTA_SKVN       BIT(30)
>>> +#define JRCR_RESET       (1)
>>> +#define RTMCTL_FCT_FAIL  BIT(8)
>>> +
>>> +#define BS_TRNG_ENT_DLY     (16)
>>> +#define BM_TRNG_ENT_DLY     (0xffff << BS_TRNG_ENT_DLY)
>>> +#define BM_TRNG_SAMP_MODE   (3)
>>> +#define TRNG_SAMP_MODE_RAW_ES_SC (1)
>>> +#define BS_JRINTR_HALT      (2)
>>> +#define BM_JRINTR_HALT      (0x3 << BS_JRINTR_HALT)
>>> +#define JRINTR_HALT_ONGOING (0x1 << BS_JRINTR_HALT)
>>> +#define JRINTR_HALT_DONE    (0x2 << BS_JRINTR_HALT)
>>> +#define JRINTR_JRI          (0x1)
>>> +#define BS_JRCFGR_LS_ICTT   (16)
>>> +#define BM_JRCFGR_LS_ICTT   (0xFFFF << BS_JRCFGR_LS_ICTT)
>>> +#define BS_JRCFGR_LS_ICDCT  (8)
>>> +#define BM_JRCFGR_LS_ICDCT  (0xFF << BS_JRCFGR_LS_ICDCT)
>>> +#define BS_JRCFGR_LS_ICEN   (1)
>>> +#define BM_JRCFGR_LS_ICEN   (0x1 << BS_JRCFGR_LS_ICEN)
>>> +#define BS_JRCFGR_LS_IMSK   (0)
>>> +#define BM_JRCFGR_LS_IMSK   (0x1 << BS_JRCFGR_LS_IMSK)
>>> +#define BS_CHAVID_LS_RNGVID (16)
>>> +#define BM_CHAVID_LS_RNGVID (0xF << BS_CHAVID_LS_RNGVID)
>>> +#define BS_MCFGR_WDE        (30)
>>> +#define BM_MCFGR_WDE        (0x1 << BS_MCFGR_WDE)
>>> +
>>> +typedef enum {
>>> +    PAGE_0,
>>> +    PAGE_1,
>>> +    PAGE_2,
>>> +    PAGE_3,
>>> +} page_num_e;
>>> +
>>> +typedef enum {
>>> +    PARTITION_0,
>>> +    PARTITION_1,
>>> +    PARTITION_2,
>>> +    PARTITION_3,
>>> +    PARTITION_4,
>>> +    PARTITION_5,
>>> +    PARTITION_6,
>>> +    PARTITION_7,
>>> +} partition_num_e;
>>> +
>>> +/*
>>> + * Local defines
>>> + */
>>> +/* arm v7 need 64 align */
>>> +#define ALIGN_MASK     ~(ARCH_DMA_MINALIGN - 1)
>>> +/* caam dma and pointer conversion for arm and arm64 architectures */
>>> +#ifdef CONFIG_IMX_CONFIG
>>> +  #define PTR2CAAMDMA(x)  (u32)((uintptr_t)(x) & 0xffffffff)
>>> +  #define CAAMDMA2PTR(x)  (uintptr_t)((x) & 0xffffffff)
>>> +#else
>>> +  #define PTR2CAAMDMA(x)  (uintptr_t)(x)
>>> +  #define CAAMDMA2PTR(x)  (uintptr_t)(x)
>>> +#endif
>>> +#define RING_EARLY_INIT   (0x01)
>>> +#define RING_RELOC_INIT   (0x02)
>>> +
>>> +#define CAAM_HDR_CTYPE            (0x16u << 27)
>>> +#define CAAM_HDR_ONE              BIT(23)
>>> +#define CAAM_HDR_START_INDEX(x)   (((x) & 0x3F) << 16)
>>> +#define CAAM_HDR_DESCLEN(x)       ((x) & 0x3F)
>>> +#define CAAM_PROTOP_CTYPE         (0x10u << 27)
>>> +
>>> +/* State Handle */
>>> +#define BS_ALGO_RNG_SH            (4)
>>> +#define BM_ALGO_RNG_SH            (0x3 << BS_ALGO_RNG_SH)
>>> +#define ALGO_RNG_SH(id)           (((id) << BS_ALGO_RNG_SH) & 
>>> BM_ALGO_RNG_SH)
>>> +
>>> +/* Secure Key */
>>> +#define BS_ALGO_RNG_SK            (12)
>>> +#define BM_ALGO_RNG_SK            BIT(BS_ALGO_RNG_SK)
>>> +
>>> +/* State */
>>> +#define BS_ALGO_RNG_AS            (2)
>>> +#define BM_ALGO_RNG_AS            (0x3 << BS_ALGO_RNG_AS)
>>> +#define ALGO_RNG_GENERATE         (0x0 << BS_ALGO_RNG_AS)
>>> +#define ALGO_RNG_INSTANTIATE      BIT(BS_ALGO_RNG_AS)
>>> +
>>> +#define CAAM_C1_RNG               ((0x50 << 16) | (2 << 24))
>>> +
>>> +#define BS_JUMP_LOCAL_OFFSET      (0)
>>> +#define BM_JUMP_LOCAL_OFFSET      (0xFF << BS_JUMP_LOCAL_OFFSET)
>>> +
>>> +#define CAAM_C1_JUMP              ((0x14u << 27) | (1 << 25))
>>> +#define CAAM_JUMP_LOCAL           (0 << 20)
>>> +#define CAAM_JUMP_TST_ALL_COND_TRUE (0 << 16)
>>> +#define CAAM_JUMP_OFFSET(off)     (((off) << BS_JUMP_LOCAL_OFFSET) \
>>> +                & BM_JUMP_LOCAL_OFFSET)
>>> +
>>> +#define CAAM_C0_LOAD_IMM          ((0x2 << 27) | (1 << 23))
>>> +#define CAAM_DST_CLEAR_WRITTEN    (0x8 << 16)
>>> +
>>> +#define RNG_DESC_SH0_SIZE   (ARRAY_SIZE(rng_inst_sh0_desc))
>>> +#define RNG_DESC_SH1_SIZE   (ARRAY_SIZE(rng_inst_sh1_desc))
>>> +#define RNG_DESC_KEYS_SIZE  (ARRAY_SIZE(rng_inst_load_keys))
>>> +#define RNG_DESC_MAX_SIZE   (RNG_DESC_SH0_SIZE + \
>>> +            RNG_DESC_SH1_SIZE + \
>>> +            RNG_DESC_KEYS_SIZE)
>>> +
>>> +#endif /* __CAAM_INTERNAL_H__ */
>>> diff --git a/include/fsl_caam.h b/include/fsl_caam.h
>>> new file mode 100644
>>> index 0000000000..c4345ae2b6
>>> --- /dev/null
>>> +++ b/include/fsl_caam.h
>>> @@ -0,0 +1,24 @@
>>> +/* SPDX-License-Identifier: GPL-2.0+ */
>>> +/*
>>> + * Copyright (c) 2012-2016, Freescale Semiconductor, Inc.
>>> + * Copyright 2018 NXP
>>> + */
>>> +
>>> +#ifndef __CAAM_H__
>>> +#define    __CAAM_H__
>>> +
>>> +#if !defined(SUCCESS)
>>> +#define SUCCESS (0)
>>> +#endif
>>> +
>>> +#define ERROR_ANY           (-1)
>>> +#define ERROR_IN_PAGE_ALLOC (1)
>>> +
>>> +void caam_open(void);
>>> +
>>> +u32 caam_gen_blob(u32 plain_data_addr, u32 blob_addr, u32 size);
>>> +
>>> +u32 caam_decap_blob(u32 plain_text, u32 blob_addr, u32 size);
>>> +u32 caam_hwrng(uint8_t *output_ptr, u32 output_len);
>>> +
>>> +#endif /* __CAAM_H__ */
>>>
>>
>>


-- 
=====================================================================
DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic@denx.de
=====================================================================

^ permalink raw reply	[flat|nested] 42+ messages in thread

end of thread, other threads:[~2021-07-08  8:29 UTC | newest]

Thread overview: 42+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-25  9:29 [PATCH 00/37] imx: hab/caam new feature and update Peng Fan
2021-03-25  9:30 ` [PATCH 01/37] imx8mn: evk: update MAINTAINERS Peng Fan
2021-03-25  9:30 ` [PATCH 02/37] imx8m: add regs used by CAAM Peng Fan
2021-03-25  9:30 ` [PATCH 03/37] imx: imx7 Support for Manufacturing Protection Peng Fan
2021-03-25  9:30 ` [PATCH 04/37] imx: Avoid hardcoded output ring size register offset (ORSR) Peng Fan
2021-03-25  9:30 ` [PATCH 05/37] imx: Ensure CAAM clock is enabled prior getting out_jr_size Peng Fan
2021-03-25  9:30 ` [PATCH 06/37] imx: Avoid hardcoded Job Ring Max size Peng Fan
2021-03-25  9:30 ` [PATCH 07/37] imx: hab: Add function to authenticate kernel image Peng Fan
2021-03-25  9:30 ` [PATCH 08/37] imx: HAB: Update hab codes to support ARM64 and i.MX8M Peng Fan
2021-03-25  9:30 ` [PATCH 09/37] imx: HAB: Validate IVT before authenticating image Peng Fan
2021-03-25  9:30 ` [PATCH 10/37] hab: Change calling to ROM API failsafe Peng Fan
2021-03-25  9:30 ` [PATCH 11/37] imx: hab: Enable hab.c to authenticate additional images in open configuration Peng Fan
2021-03-25  9:30 ` [PATCH 12/37] imx: hab: Display All HAB events via hab_status command Peng Fan
2021-03-25  9:30 ` [PATCH 13/37] imx: hab: Check if IVT header is HABv4 Peng Fan
2021-03-25  9:30 ` [PATCH 14/37] mx7ulp: hab: Add hab_status command for HABv4 M4 boot Peng Fan
2021-03-25  9:30 ` [PATCH 15/37] imx: hab: Fix build warnings in 32-bit targets Peng Fan
2021-03-25  9:30 ` [PATCH 16/37] imx: HAB: Add support for iMX8MM Peng Fan
2021-03-25  9:30 ` [PATCH 17/37] crypto: fsl: blob: Flush dcache range for destination address Peng Fan
2021-03-25  9:30 ` [PATCH 18/37] iMX8M: Add support to enable CONFIG_IMX_HAB Peng Fan
2021-03-25  9:30 ` [PATCH 19/37] imx: cmd_dek: Enable DEK only for chips supporting CAAM Peng Fan
2021-03-25  9:30 ` [PATCH 20/37] mx6dq: hab: Fix chip version in hab.h code Peng Fan
2021-03-25  9:30 ` [PATCH 21/37] cmd: blob: Add IMX_HAB and CAAM supported SoCs as dependency Peng Fan
2021-03-25  9:30 ` [PATCH 22/37] cmd: blob: Instantiate RNG before running CMD_BLOB Peng Fan
2021-03-25  9:30 ` [PATCH 23/37] crypto: caam: change JR running loop Peng Fan
2021-03-25  9:30 ` [PATCH 24/37] caam: enable support for iMX7ULP Peng Fan
2021-03-25  9:30 ` [PATCH 25/37] imx7ulp: Enable support for cmd blob Peng Fan
2021-03-25  9:30 ` [PATCH 26/37] crypto: caam: Add CAAM support to i.MX8M platforms Peng Fan
2021-03-25  9:30 ` [PATCH 27/37] crypto: caam: Fix build warnings pointer casting Peng Fan
2021-03-25  9:30 ` [PATCH 28/37] crypto: Add blob command support for i.MX8M platforms Peng Fan
2021-03-25  9:30 ` [PATCH 29/37] crypto: caam: Fix pointer size to 32bit for i.MX8M Peng Fan
2021-03-25  9:30 ` [PATCH 30/37] crypto: caam: Add secure memory vid 3 support Peng Fan
2021-03-25  9:30 ` [PATCH 31/37] crypto: caam: Add fsl caam driver Peng Fan
2021-04-08 18:24   ` Stefano Babic
2021-07-08  8:02     ` Peng Fan (OSS)
2021-07-08  8:28       ` Stefano Babic
2021-03-25  9:30 ` [PATCH 32/37] crypto: caam: RNG4 TRNG errata Peng Fan
2021-03-25  9:30 ` [PATCH 33/37] imx: caam: new u-boot command to set PRIBLOB bitfield from CAAM SCFGR register to 0x3 Peng Fan
2021-03-25  9:30 ` [PATCH 34/37] imx8m: Add DEK blob encapsulation for imx8m Peng Fan
2021-03-25  9:30 ` [PATCH 35/37] imx8: Add DEK blob encapsulation Peng Fan
2021-03-25  9:30 ` [PATCH 36/37] fsl_mfgprot: Fix typo in sign_mppubk() Peng Fan
2021-03-25  9:30 ` [PATCH 37/37] crypto: fsl: refactor for 32 bit version CAAM support on ARM64 Peng Fan
2021-03-31 12:32 ` [PATCH 00/37] imx: hab/caam new feature and update Horia Geantă

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.