MLK-22907-2 imx8: Add SECO manufacturing protection command support
authorBreno Lima <breno.lima@nxp.com>
Sat, 19 Oct 2019 01:24:26 +0000 (22:24 -0300)
committerYe Li <ye.li@nxp.com>
Thu, 29 Apr 2021 07:56:35 +0000 (00:56 -0700)
i.MX8/8x devices support CAAM manufacturing protection through SECO
APIs, SECO FW generates P-384 private key in every OEM closed boot.

Add support for SECO enabled devices in mfgprot U-Boot command, the
following commands are available:

=> mfgprot pubk
=> mfgprot sign <data_addr> <size>

Signed-off-by: Breno Lima <breno.lima@nxp.com>
(cherry picked from commit 1fdb9726fdc4642d0f24104ec2e4099d59569468)
(cherry picked from commit 18b06286d28d78b04fcef7a4b3bd8324f789bf32)

arch/arm/mach-imx/Kconfig
arch/arm/mach-imx/Makefile
arch/arm/mach-imx/cmd_mfgprot.c
drivers/crypto/fsl/Makefile

index 72ac39c..4b13015 100644 (file)
@@ -168,13 +168,27 @@ config CMD_NANDBCB
 
 config FSL_MFGPROT
        bool "Support the 'mfgprot' command"
-       depends on IMX_HAB && ARCH_MX7
+       depends on IMX_HAB || AHAB_BOOT
+       select IMX_CAAM_MFG_PROT if ARCH_MX7
+       select IMX_SECO_MFG_PROT if ARCH_IMX8
        help
          This option enables the manufacturing protection command
          which can be used has a protection feature for Manufacturing
          process. With this tool is possible to authenticate the
          chip to the OEM's server.
 
+config IMX_CAAM_MFG_PROT
+       bool "Support the manufacturing protection with CAAM U-Boot driver"
+       help
+         This enables the manufacturing protection feature with the U-Boot
+         CAAM driver. This option is only available on iMX7D/S.
+
+config IMX_SECO_MFG_PROT
+       bool "Support the manufacturing protection with SECO API"
+       help
+         This enables the manufacturing protection feature with the SECO API.
+         This option is only available on iMX8/8x series.
+
 config DBG_MONITOR
        bool "Enable the AXI debug monitor"
        depends on ARCH_MX6 || ARCH_MX7
index d7c0d3b..2369635 100644 (file)
@@ -37,6 +37,8 @@ ifeq ($(SOC),$(filter $(SOC),mx7))
 obj-y  += cpu.o
 obj-$(CONFIG_SYS_I2C_MXC) += i2c-mxv7.o
 obj-y += mmc_env.o
+endif
+ifeq ($(SOC),$(filter $(SOC),mx7 imx8))
 obj-$(CONFIG_FSL_MFGPROT) += cmd_mfgprot.o
 endif
 ifeq ($(SOC),$(filter $(SOC),mx5 mx6 mx7))
index de846ab..34a2c2f 100644 (file)
@@ -8,15 +8,19 @@
  * functions in supported i.MX devices.
  */
 
-#include <asm/byteorder.h>
-#include <asm/arch/clock.h>
-#include <linux/compiler.h>
 #include <command.h>
 #include <common.h>
 #include <environment.h>
-#include <fsl_sec.h>
 #include <mapmem.h>
 #include <memalign.h>
+#ifdef CONFIG_IMX_CAAM_MFG_PROT
+#include <asm/arch/clock.h>
+#include <fsl_sec.h>
+#endif
+#ifdef CONFIG_IMX_SECO_MFG_PROT
+#include <asm/io.h>
+#include <asm/arch/sci/sci.h>
+#endif
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -30,6 +34,8 @@ DECLARE_GLOBAL_DATA_PTR;
  * Returns zero on success, CMD_RET_USAGE in case of misuse and negative
  * on error.
  */
+#ifdef CONFIG_IMX_CAAM_MFG_PROT
+
 static int do_mfgprot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
 {
        u8 *m_ptr, *dgst_ptr, *c_ptr, *d_ptr, *dst_ptr;
@@ -135,6 +141,121 @@ free_m:
        }
        return ret;
 }
+#endif /* CONFIG_IMX_CAAM_MFG_PROT */
+
+#ifdef CONFIG_IMX_SECO_MFG_PROT
+
+#define FSL_CAAM_MP_PUBK_BYTES                 96
+#define FSL_CAAM_MP_SIGN_BYTES                 96
+#define SCU_SEC_SECURE_RAM_BASE                        (0x20800000UL)
+#define SEC_SECURE_RAM_BASE                    (0x31800000UL)
+
+static int do_mfgprot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+       u8 *m_ptr, *sign_ptr, *dst_ptr;
+       char *pubk, *sign, *sel;
+       int m_size, i, ret;
+       u32 m_addr;
+
+       pubk = "pubk";
+       sign = "sign";
+       sel = argv[1];
+
+       if (!sel)
+               return CMD_RET_USAGE;
+
+       if (strcmp(sel, pubk) == 0) {
+               dst_ptr = malloc_cache_aligned(FSL_CAAM_MP_PUBK_BYTES);
+               if (!dst_ptr)
+                       return -ENOMEM;
+
+               puts("\nGenerating Manufacturing Protection Public Key\n");
+
+               ret = sc_seco_get_mp_key(-1, SCU_SEC_SECURE_RAM_BASE,
+                                        FSL_CAAM_MP_PUBK_BYTES);
+               if (ret) {
+                       printf("SECO get MP key failed, return %d\n", ret);
+                       ret = -EIO;
+                       free(dst_ptr);
+                       return ret;
+               }
+
+               memcpy((void *)dst_ptr, (const void *)SEC_SECURE_RAM_BASE,
+                       ALIGN(FSL_CAAM_MP_PUBK_BYTES,
+                       CONFIG_SYS_CACHELINE_SIZE));
+
+               /* Output results */
+               puts("\nPublic key:\n");
+               for (i = 0; i < FSL_CAAM_MP_PUBK_BYTES; i++)
+                       printf("%02X", (dst_ptr)[i]);
+               puts("\n");
+               free(dst_ptr);
+
+       } else if (strcmp(sel, sign) == 0) {
+               if (argc != 4)
+                       return CMD_RET_USAGE;
+
+               m_addr = simple_strtoul(argv[2], NULL, 16);
+               m_size = simple_strtoul(argv[3], NULL, 10);
+               m_ptr = map_physmem(m_addr, m_size, MAP_NOCACHE);
+               if (!m_ptr)
+                       return -ENOMEM;
+
+               sign_ptr = malloc_cache_aligned(FSL_CAAM_MP_SIGN_BYTES);
+               if (!sign_ptr) {
+                       ret = -ENOMEM;
+                       goto free_m;
+               }
+
+               memcpy((void *)SEC_SECURE_RAM_BASE, (const void *)m_ptr,
+                       ALIGN(m_size, CONFIG_SYS_CACHELINE_SIZE));
+
+               puts("\nSigning message with SECO MP signature function\n");
+
+               ret = sc_seco_get_mp_sign(-1, SCU_SEC_SECURE_RAM_BASE, m_size,
+                                         SCU_SEC_SECURE_RAM_BASE + 0x1000,
+                                         FSL_CAAM_MP_SIGN_BYTES);
+
+               if (ret) {
+                       printf("SECO get MP signature failed, return %d\n",
+                              ret);
+                       ret = -EIO;
+                       goto free_sign;
+               }
+
+               memcpy((void *)sign_ptr, (const void *)SEC_SECURE_RAM_BASE
+                       + 0x1000, ALIGN(FSL_CAAM_MP_SIGN_BYTES,
+                       CONFIG_SYS_CACHELINE_SIZE));
+
+               /* Output results */
+               puts("\nMessage: ");
+               for (i = 0; i < m_size; i++)
+                       printf("%02X", (m_ptr)[i]);
+               puts("\n");
+
+               puts("\nSignature:\n");
+               puts("c:\n");
+               for (i = 0; i < FSL_CAAM_MP_SIGN_BYTES / 2; i++)
+                       printf("%02X", (sign_ptr)[i]);
+               puts("\n");
+
+               puts("d:\n");
+               for (i = FSL_CAAM_MP_SIGN_BYTES / 2; i < FSL_CAAM_MP_SIGN_BYTES;
+                    i++)
+                       printf("%02X", (sign_ptr)[i]);
+               puts("\n");
+
+free_sign:
+       free(sign_ptr);
+free_m:
+       unmap_sysmem(m_ptr);
+
+       } else {
+               return CMD_RET_USAGE;
+       }
+       return ret;
+}
+#endif /* CONFIG_IMX_SECO_MFG_PROT */
 
 /***************************************************/
 static char mfgprot_help_text[] =
index f9c3cce..0db41d6 100644 (file)
@@ -7,4 +7,4 @@ obj-$(CONFIG_FSL_CAAM) += jr.o fsl_hash.o jobdesc.o error.o
 obj-$(CONFIG_CMD_BLOB)$(CONFIG_IMX_CAAM_DEK_ENCAP) += fsl_blob.o
 obj-$(CONFIG_RSA_FREESCALE_EXP) += fsl_rsa.o
 obj-$(CONFIG_FSL_CAAM_RNG) += rng.o
-obj-$(CONFIG_FSL_MFGPROT) += fsl_mfgprot.o
+obj-$(CONFIG_IMX_CAAM_MFG_PROT) += fsl_mfgprot.o