Re: [U-Boot] [PATCH v3] imx: imx7 Support for Manufacturing Protection

2016-02-15 Thread Ruchika Gupta
> diff --git a/drivers/crypto/fsl/Makefile b/drivers/crypto/fsl/Makefile index
> fd736cf..6d6903b 100644
> --- a/drivers/crypto/fsl/Makefile
> +++ b/drivers/crypto/fsl/Makefile
> @@ -8,3 +8,7 @@ obj-y += sec.o
>  obj-$(CONFIG_FSL_CAAM) += jr.o fsl_hash.o jobdesc.o error.o
>  obj-$(CONFIG_CMD_BLOB)$(CONFIG_CMD_DEKBLOB) += fsl_blob.o
>  obj-$(CONFIG_RSA_FREESCALE_EXP) += fsl_rsa.o
> +
> +ifdef CONFIG_MX7
> +obj-$(CONFIG_CMD_MFGPROT) += fsl_mfgprot.o endif
> diff --git a/drivers/crypto/fsl/fsl_mfgprot.c 
> b/drivers/crypto/fsl/fsl_mfgprot.c
> new file mode 100644
> index 000..fe89be7
> --- /dev/null
> +++ b/drivers/crypto/fsl/fsl_mfgprot.c
> @@ -0,0 +1,236 @@
> +/*
> + * Copyright 2014 Freescale Semiconductor, Inc.
> + *
> + * SPDX-License-Identifier:  GPL-2.0+
> + *
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include "jobdesc.h"
> +#include "desc.h"
> +#include "jr.h"
> +
> +#define HAB_MASK(LBL)\
> + uint32_t)1 << (LBL##_WIDTH)) - 1) << (LBL##_SHIFT))
Please use generic names like FSL_CAAM_* instead of HAB_ throughout
The same mfg protection is also available in some other FSL SoC's also and use 
of HAB should be avoided here.

> +
> +#define HAB_INSERT_BITS(val, LBL)\
> + (((uint32_t)(val) << LBL##_SHIFT) & HAB_MASK(LBL))
> +
> +/* Size of MFG descriptor */
> +#define MFG_PUBK_DSC_WORDS 4
> +#define MFG_SIGN_DSC_WORDS 8
> +
> +/* Size of MFG protocol data block */
> +#define MFG_PUBK_PDB_WORDS 2
> +#define MFG_SIGN_PDB_WORDS 6
> +
> +void mfg_build_sign_dsc(u32 *dsc_ptr, const u8 *m, int size,
> + u8 *dgst, u8 *c, u8 *d)
> +{
> + u32 *dsc = dsc_ptr;
> + *dsc++ = (HAB_ENG_CAAM_CMD_JOBHDR
> +   | HAB_INSERT_BITS(
> + MFG_SIGN_PDB_WORDS + 1,
> + HAB_ENG_CAAM_CMD_JOBHDR_START)
> +   | MFG_SIGN_DSC_WORDS);
The construction of descriptor should be using constructs in desc_constr.h. The 
approach below has limitation for hard-coded descriptor sizes. Pdb size can 
vary depending on PS bit in MCFGR. Based on it, you may have dma addr ptr as 32 
bit or 64 bit.

We have recently submitted patches for adding constructs for pdb support. 
Please refer to the patchwork link below

http://patchwork.ozlabs.org/patch/582789/
http://patchwork.ozlabs.org/patch/582790/

Example of adding a pdb descriptor :
(Example for ecdsa verify descriptor given below. You can use the same 
reference to develop the mfg protection descriptor)

  struct pdb_ecdsa_verify *pdb;
  init_job_desc_pdb(desc, 0, sizeof(struct pdb_ecdsa_verify));

  pdb = (struct pdb_ecdsa_verify *)desc_pdb(desc);

/* Populate the field of pdb. Reference pdb structs for pdb_mp_pub_k, 
pdb_mp_sign available in desc.h  in above patch-set*/
  pdb->pdb_hdr = (0x20 << PDB_ECDSA_L_SHIFT) |
   (0x20 << PDB_ECDSA_N_SHIFT);
  pdb_add_ptr(>dma_q, virt_to_phys((void *)q_curve));
  pdb_add_ptr(>dma_r, virt_to_phys((void *)r_curve));
   

  pdb->img_size = (uint32_t)img_size;

  append_operation(desc, OP_TYPE_UNI_PROTOCOL | OP_PCLID_DSA_VERIFY |
  OP_PROTINFO_ECC_DL);
You can convert the hardcoded protocol below using append_operation
#define HAB_ENG_CAAM_CMD_PROTOCOL_MPPUBK0x8614UL
#define HAB_ENG_CAAM_CMD_PROTOCOL_MPSIGN0x8615UL

> +
> + /*** MFG PubK PDB ***/
> + /* Curve */
> + *dsc++ = HAB_INSERT_BITS(HAB_ENG_CAAM_MPPUBK_CSEL_P256,
> +  HAB_ENG_CAAM_MPPUBK_CSEL);
> + /* Message Pointer */
> + *dsc++ = (dma_addr_t)m;
> +
> + /* mes-resp Pointer */
> + *dsc++ = (dma_addr_t)dgst;
> +
> + /* C Pointer */
> + *dsc++ = (dma_addr_t)c;
> +
> + /* d Pointer */
> + *dsc++ = (dma_addr_t)d;
> +
> + /* Message Size */
> + *dsc++ = size;
> +
> + /* MP PubK generate key command */
> + *dsc = HAB_ENG_CAAM_CMD_PROTOCOL_MPSIGN; }
> +
> +void mfg_build_pubk_dsc(u32 *dsc_ptr, u8 *dst) {
> + u32 *dsc = dsc_ptr;
> + *dsc++ = (HAB_ENG_CAAM_CMD_JOBHDR
> +  | HAB_INSERT_BITS(
> + MFG_PUBK_PDB_WORDS + 1,
> + HAB_ENG_CAAM_CMD_JOBHDR_START)
> +  | MFG_PUBK_DSC_WORDS);
> +
> + /*** MFG PubK PDB ***/
> + /* Curve */
> + *dsc++ = HAB_INSERT_BITS(HAB_ENG_CAAM_MPPUBK_CSEL_P256,
> +  HAB_ENG_CAAM_MPPUBK_CSEL);
> + /* Message Pointer */
> + *dsc++ = (dma_addr_t)dst;
> +
> + /* MP PubK generate key command */
> + *dsc = HAB_ENG_CAAM_CMD_PROTOCOL_MPPUBK; }
> +
> +int gen_mppubk(void)
> +{
> + int ret;
> + int size, i;
> +
> + u32 *dsc;
> + uint32_t dst_addr;
> + u8 *dst;
> +
> +
>   /
> 
> +  * Allocation & Initialization
> +
> 
> /
> + ret = 0;
> +
> + /* Memory addresses for output */
> + 

[U-Boot] [PATCH v3] imx: imx7 Support for Manufacturing Protection

2016-02-11 Thread Ulises Cardenas
i.MX7 has an a protection feature for Manufacturing process.
This feature uses assymetric encryption to sign and verify
authenticated software handled between parties. This command
enables the use of such feature.

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

Command usage:

Print the public key for the device.
- mfgprot pubk

Generates Signature over given data.
- mfgprot sign 

Signed-off-by: Raul Ulises Cardenas 
---

Changes for v2:
- removed genenerate_mppubk and generate_mpsign
due to redundancy

Changes for v3:
- typo correction description
- extended mfgprot command from an MPSing function example to a fully
functional command, providing the ability of signing given data

 arch/arm/imx-common/Makefile  |   1 +
 arch/arm/imx-common/cmd_mfgprot.c | 102 
 drivers/crypto/fsl/Makefile   |   4 +
 drivers/crypto/fsl/fsl_mfgprot.c  | 236 ++
 include/fsl_sec.h |  45 +++-
 5 files changed, 387 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/imx-common/cmd_mfgprot.c
 create mode 100644 drivers/crypto/fsl/fsl_mfgprot.c

diff --git a/arch/arm/imx-common/Makefile b/arch/arm/imx-common/Makefile
index e7190c3..8563150 100644
--- a/arch/arm/imx-common/Makefile
+++ b/arch/arm/imx-common/Makefile
@@ -22,6 +22,7 @@ ifeq ($(SOC),$(filter $(SOC),mx7))
 obj-y  += cpu.o
 obj-$(CONFIG_SYS_I2C_MXC) += i2c-mxv7.o
 obj-$(CONFIG_SYSCOUNTER_TIMER) += syscounter.o
+obj-$(CONFIG_CMD_MFGPROT) += cmd_mfgprot.o
 endif
 ifeq ($(SOC),$(filter $(SOC),mx6 mx7))
 obj-y  += cache.o init.o
diff --git a/arch/arm/imx-common/cmd_mfgprot.c 
b/arch/arm/imx-common/cmd_mfgprot.c
new file mode 100644
index 000..3a6e7cb
--- /dev/null
+++ b/arch/arm/imx-common/cmd_mfgprot.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2016 NXP Semiconductors.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ *
+ * Command for manufacturing protection
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/**
+ * do_mfgprot() - Handle the "mfgprogt" command-line command
+ * @cmdtp:  Command data struct pointer
+ * @flag:   Command flag
+ * @argc:   Command-line argument count
+ * @argv:   Array of command-line arguments
+ *
+ * Returns zero on success, CMD_RET_USAGE in case of misuse and negative
+ * on error.
+ */
+static int do_mfgprot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+   uint32_t m_addr, dgst_addr, c_addr, d_addr;
+   u8 *m_ptr, *dgst_ptr, *c_ptr, *d_ptr;
+   int m_size;
+   int ret;
+   char *pubk, *sign, *sel;
+
+   pubk = "pubk";
+   sign = "sign";
+   sel = argv[1];
+
+   ret = 0;
+
+   /* Enable HAB clock */
+   u32 jr_size = 4;
+   u32 out_jr_size = sec_in32(CONFIG_SYS_FSL_JR0_ADDR + 0x102c);
+   if (out_jr_size != jr_size) {
+   hab_caam_clock_enable(1);
+   sec_init();
+   }
+
+   if (strcmp(sel, pubk) == 0) {
+   ret = gen_mppubk();
+   } else if (strcmp(sel, sign) == 0) {
+   if (argc != 7)
+   return CMD_RET_USAGE;
+
+   m_addr = simple_strtoul(argv[2], NULL, 16);
+   m_size = simple_strtoul(argv[3], NULL, 10);
+   dgst_addr = simple_strtoul(argv[4], NULL, 16);
+   c_addr = simple_strtoul(argv[5], NULL, 16);
+   d_addr = simple_strtoul(argv[6], NULL, 16);
+
+
+   m_ptr = map_physmem(m_addr, m_size, MAP_NOCACHE);
+   dgst_ptr = map_physmem(dgst_addr, HAB_MES_RESP_DGST_BYTES,
+   MAP_NOCACHE);
+   c_ptr = map_physmem(c_addr, HAB_ENG_MFG_PRVK_BYTES,
+   MAP_NOCACHE);
+   d_ptr = map_physmem(d_addr, HAB_ENG_MFG_PRVK_BYTES,
+   MAP_NOCACHE);
+
+   memset(dgst_ptr, 0, HAB_MES_RESP_DGST_BYTES);
+   memset(c_ptr, 0, HAB_ENG_MFG_PRVK_BYTES);
+   memset(d_ptr, 0, HAB_ENG_MFG_PRVK_BYTES);
+
+   ret = sign_mppubk(m_ptr, m_size, dgst_ptr, c_ptr, d_ptr);
+   } else {
+   return CMD_RET_USAGE;
+   }
+
+   unmap_sysmem(m_ptr);
+   unmap_sysmem(dgst_ptr);
+   unmap_sysmem(c_ptr);
+   unmap_sysmem(d_ptr);
+
+   return ret;
+}
+
+/***/
+static char mfgprot_help_text[] =
+   "Usage:\n"
+"Print the public key for Manufacturing Protection\n"
+"\tmfgprot pubk\n"
+"Generates a Manufacturing Protection signature\n"
+"\tmfgprot sign ";
+
+U_BOOT_CMD(
+   mfgprot, 7, 1, do_mfgprot,
+   "Manufacturing Protection\n",
+   mfgprot_help_text
+);
diff --git