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

Ruchika Gupta ruchika.gupta at nxp.com
Mon Feb 15 11:14:13 CET 2016


> 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 0000000..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 <common.h>
> +#include <malloc.h>
> +#include <fsl_sec.h>
> +#include <asm-generic/errno.h>
> +#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(&pdb->dma_q, virt_to_phys((void *)q_curve));
      pdb_add_ptr(&pdb->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_MPPUBK        0x86140000UL
#define HAB_ENG_CAAM_CMD_PROTOCOL_MPSIGN        0x86150000UL

> +
> +	/*** 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 */
> +	dst_addr = 0x80100000;
> +	dst = map_physmem(dst_addr, HAB_ENG_MFG_PUBK_BYTES,
> MAP_NOCACHE);
> +	memset(dst, 0, HAB_ENG_MFG_PUBK_BYTES);
> +
> +
> 	/********************************************************
> ********
> +	 * Job Descriptor initialization
> +
> ****************************************************************
> /
> +	dsc = memalign(ARCH_DMA_MINALIGN,
> +			sizeof(uint32_t) * MFG_PUBK_DSC_WORDS);
> +	if (!dsc) {
> +		debug("Not enough memory for descriptor allocation\n");
> +		return -ENOMEM;
> +	}
> +
> +	mfg_build_pubk_dsc(dsc, dst);
> +
> +	size = roundup(sizeof(uint32_t) * MFG_PUBK_DSC_WORDS,
> +			ARCH_DMA_MINALIGN);
> +	flush_dcache_range((unsigned long)dsc, (unsigned long)dsc + size);
> +
> +	size = roundup(HAB_ENG_MFG_PUBK_BYTES,
> ARCH_DMA_MINALIGN);
> +	flush_dcache_range((unsigned long)dst, (unsigned long)dst + size);
> +
> +
> 	/********************************************************
> ********
> +	 * Execute Job Descriptor
> +
> ****************************************************************
> /
> +	puts("\nGenerating Manufacturing Protection Public Key\n");
> +
> +	ret = run_descriptor_jr(dsc);
> +	if (ret) {
> +		debug("Error in public key generation %d\n", ret);
> +	   goto err;
> +	}
> +
> +	size = roundup(HAB_ENG_MFG_PUBK_BYTES,
> ARCH_DMA_MINALIGN);
> +	invalidate_dcache_range((unsigned long)dst, (unsigned
> long)dst+size);
> +
> +
> 	/********************************************************
> ********
> +	 * Output results
> +
> ****************************************************************
> /
> +	puts("Public key:\n");
> +	for (i = 0; i < HAB_ENG_MFG_PUBK_BYTES; i++)
> +		printf("%02X", ((u8 *)dst)[i]);
> +	printf("\n");
> +
> +err:
> +	free(dsc);
> +	unmap_sysmem(dst);
> +	return ret;
> +}
> +
> +int sign_mppubk(const u8 *m, int data_size, u8 *dgst, u8 *c, u8 *d) {
> +	int ret;
> +	int size, i;
> +
> +	u32 *dsc;
> +
> +
> 	/********************************************************
> ********
> +	 * Allocation & Initialization
> +
> ****************************************************************
> /
> +	ret = 0;
> +
> +	memset(dgst, 0, HAB_MES_RESP_DGST_BYTES);
> +	memset(d, 0, HAB_ENG_MFG_PRVK_BYTES);
> +	memset(c, 0, HAB_ENG_MFG_PRVK_BYTES);
> +
> +
> 	/********************************************************
> ********
> +	 * Job Descriptor initialization
> +
> ****************************************************************
> /
> +	dsc = memalign(ARCH_DMA_MINALIGN,
> +			sizeof(uint32_t) * MFG_SIGN_DSC_WORDS);
> +	if (!dsc) {
> +		debug("Not enough memory for descriptor allocation\n");
> +		return -ENOMEM;
> +	}
> +
> +	mfg_build_sign_dsc(dsc, m, data_size, dgst, c, d);
> +
> +	size = roundup(sizeof(uint32_t) * MFG_SIGN_DSC_WORDS,
> +			ARCH_DMA_MINALIGN);
> +	flush_dcache_range((unsigned long)dsc, (unsigned long)dsc + size);
> +
> +	size = roundup(data_size, ARCH_DMA_MINALIGN);
> +	flush_dcache_range((unsigned long)m, (unsigned long)m + size);
> +
> +	size = roundup(HAB_MES_RESP_DGST_BYTES,
> ARCH_DMA_MINALIGN);
> +	flush_dcache_range((unsigned long)dgst, (unsigned long)dgst + size);
> +
> +	size = roundup(HAB_ENG_MFG_PRVK_BYTES,
> ARCH_DMA_MINALIGN);
> +	flush_dcache_range((unsigned long)c, (unsigned long)c + size);
> +	flush_dcache_range((unsigned long)d, (unsigned long)d + size);
> +
> +
> 	/********************************************************
> ********
> +	 * Execute Job Descriptor
> +
> ****************************************************************
> /
> +	puts("\nSiging message with Manufacturing Protection Public
> Key\n");
> +
> +	ret = run_descriptor_jr(dsc);
> +	if (ret) {
> +		debug("Error in public key generation %d\n", ret);
> +	   goto err;
> +	}
> +
> +	size = roundup(HAB_MES_RESP_DGST_BYTES,
> ARCH_DMA_MINALIGN);
> +	invalidate_dcache_range((unsigned long)dgst, (unsigned
> +long)dgst+size);
> +
> +	size = roundup(HAB_ENG_MFG_PRVK_BYTES,
> ARCH_DMA_MINALIGN);
> +	invalidate_dcache_range((unsigned long)c, (unsigned long)c+size);
> +	invalidate_dcache_range((unsigned long)d, (unsigned long)d+size);
> +
> +
> 	/********************************************************
> ********
> +	 * Output results
> +
> ****************************************************************
> /
> +	puts("Message: ");
> +	for (i = 0; i < data_size; i++)
> +		printf("%02X ", ((uint8_t *)m)[i]);
> +	printf("\n");
> +
> +	puts("Message Representative Digest(SHA-256):\n");
> +	for (i = 0; i < HAB_MES_RESP_DGST_BYTES; i++)
> +		printf("%02X", ((uint8_t *)dgst)[i]);
> +	printf("\n");
> +
> +	puts("Signature:\n");
> +	puts("D:\n");
> +	for (i = 0; i < HAB_ENG_MFG_PRVK_BYTES; i++)
> +		printf("%02X", ((uint8_t *)c)[i]);
> +	printf("\n");
> +
> +	puts("d:\n");
> +	for (i = 0; i < HAB_ENG_MFG_PRVK_BYTES; i++)
> +		printf("%02X", ((uint8_t *)d)[i]);
> +	printf("\n");
> +
> +err:
> +	free(dsc);
> +	return ret;
> +}
> diff --git a/include/fsl_sec.h b/include/fsl_sec.h index 2ddced3..6fe02e9
> 100644
> --- a/include/fsl_sec.h
> +++ b/include/fsl_sec.h
> @@ -270,9 +270,33 @@ struct sg_entry {
> 
>  #define ERROR_IN_PAGE_ALLOC	1
>  #define ECONSTRJDESC   -1
> -
>  #endif
> 
> +#ifdef CONFIG_MX7
> +/* Security level index in #mfg_curve */ #define MFG_SEC_LVL_256 0
> +#define MFG_SEC_LVL_384 1 #define MFG_SEC_LVL_521 2
> +
> +/* Job Descriptor Header command - add length in words */
> +#define HAB_ENG_CAAM_CMD_JOBHDR                 0xB0800000UL
> +#define HAB_ENG_CAAM_CMD_JOBHDR_START_SHIFT     16 /**< START
> INDEX field */
> +#define HAB_ENG_CAAM_CMD_JOBHDR_START_WIDTH     6 /**< START
> INDEX field */
> +#define HAB_ENG_CAAM_MPPUBK_SGF         (1UL<<31)       /**< Message SG
> flag */
> +#define HAB_ENG_CAAM_MPPUBK_CSEL_SHIFT  17              /**< Curve
> selection */
> +#define HAB_ENG_CAAM_MPPUBK_CSEL_WIDTH  4               /**< Curve
> selection */
> +#define HAB_ENG_CAAM_MPPUBK_CSEL_P256   0x3             /**< P-256 */
> +#define HAB_ENG_CAAM_MPPUBK_CSEL_P384   0x4             /**< P-384 */
> +#define HAB_ENG_CAAM_MPPUBK_CSEL_P521   0x5             /**< P-521 */
> +
> +/** PROTOCOL MPPubKGen command */
> +#define HAB_ENG_CAAM_CMD_PROTOCOL_MPPUBK        0x86140000UL
> +#define HAB_ENG_CAAM_CMD_PROTOCOL_MPSIGN        0x86150000UL

This should not be hardcoded. 

> +
> +#define HAB_ENG_MFG_PUBK_BYTES  64
> +#define HAB_ENG_MFG_PRVK_BYTES  32
> +#define HAB_MES_RESP_DGST_BYTES 32

All the above should move to desc.h.  Change HAB to 


Regards,
Ruchika


More information about the U-Boot mailing list