Message ID | 20210325093036.3270101-1-peng.fan@oss.nxp.com |
---|---|
Headers | show |
Series | imx: hab/caam new feature and update | expand |
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
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__ */ >
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__ */ >> > >
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 =====================================================================
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