diff options
Diffstat (limited to 'roms/u-boot/drivers/crypto/fsl/fsl_mfgprot.c')
-rw-r--r-- | roms/u-boot/drivers/crypto/fsl/fsl_mfgprot.c | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/roms/u-boot/drivers/crypto/fsl/fsl_mfgprot.c b/roms/u-boot/drivers/crypto/fsl/fsl_mfgprot.c new file mode 100644 index 000000000..29af79f57 --- /dev/null +++ b/roms/u-boot/drivers/crypto/fsl/fsl_mfgprot.c @@ -0,0 +1,160 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2014-2016 Freescale Semiconductor, Inc. + * Copyright 2017 NXP + */ + +#include <common.h> +#include <errno.h> +#include <fsl_sec.h> +#include <memalign.h> +#include "desc.h" +#include "desc_constr.h" +#include "jobdesc.h" +#include "jr.h" + +/* Size of MFG descriptor */ +#define MFG_PUBK_DSC_WORDS 4 +#define MFG_SIGN_DSC_WORDS 8 + +static void mfg_build_sign_dsc(u32 *dsc_ptr, const u8 *m, int size, + u8 *dgst, u8 *c, u8 *d) +{ + u32 *dsc = dsc_ptr; + struct pdb_mp_sign *pdb; + + init_job_desc_pdb(dsc, 0, sizeof(struct pdb_mp_sign)); + + pdb = (struct pdb_mp_sign *)desc_pdb(dsc); + + /* Curve */ + pdb->pdb_hdr = (PDB_MP_CSEL_P256); + + /* Message Pointer */ + pdb_add_ptr(&pdb->dma_addr_msg, virt_to_phys((void *)m)); + + /* mes-resp Pointer */ + pdb_add_ptr(&pdb->dma_addr_hash, virt_to_phys((void *)dgst)); + + /* C Pointer */ + pdb_add_ptr(&pdb->dma_addr_c_sig, virt_to_phys((void *)c)); + + /* d Pointer */ + pdb_add_ptr(&pdb->dma_addr_d_sig, virt_to_phys((void *)d)); + + /* Message Size */ + pdb->img_size = size; + + /* MP PubK generate key command */ + append_cmd(dsc, (CMD_OPERATION | OP_TYPE_DECAP_PROTOCOL | + OP_PCLID_MP_SIGN)); +} + +static void mfg_build_pubk_dsc(u32 *dsc_ptr, u8 *dst) +{ + u32 *dsc = dsc_ptr; + struct pdb_mp_pub_k *pdb; + + init_job_desc_pdb(dsc, 0, sizeof(struct pdb_mp_pub_k)); + + pdb = (struct pdb_mp_pub_k *)desc_pdb(dsc); + + /* Curve */ + pdb->pdb_hdr = (PDB_MP_CSEL_P256); + + /* Message Pointer */ + pdb_add_ptr(&pdb->dma_pkey, virt_to_phys((void *)dst)); + + /* MP Sign key command */ + append_cmd(dsc, (CMD_OPERATION | OP_TYPE_DECAP_PROTOCOL | + OP_PCLID_MP_PUB_KEY)); +} + +int gen_mppubk(u8 *dst) +{ + int size, ret; + u32 *dsc; + + /* Job Descriptor initialization */ + dsc = memalign(ARCH_DMA_MINALIGN, + sizeof(uint32_t) * MFG_PUBK_DSC_WORDS); + if (!dsc) { + debug("Not enough memory for descriptor allocation\n"); + return -ENOMEM; + } + + mfg_build_pubk_dsc(dsc, dst); + + size = roundup(sizeof(uint32_t) * MFG_PUBK_DSC_WORDS, + ARCH_DMA_MINALIGN); + flush_dcache_range((unsigned long)dsc, (unsigned long)dsc + size); + + size = roundup(FSL_CAAM_MP_PUBK_BYTES, ARCH_DMA_MINALIGN); + flush_dcache_range((unsigned long)dst, (unsigned long)dst + size); + + /* Execute Job Descriptor */ + puts("\nGenerating Manufacturing Protection Public Key\n"); + + ret = run_descriptor_jr(dsc); + if (ret) { + debug("Error in public key generation %d\n", ret); + goto err; + } + + size = roundup(FSL_CAAM_MP_PUBK_BYTES, ARCH_DMA_MINALIGN); + invalidate_dcache_range((unsigned long)dst, (unsigned long)dst + size); +err: + free(dsc); + return ret; +} + +int sign_mppubk(const u8 *m, int data_size, u8 *dgst, u8 *c, u8 *d) +{ + int size, ret; + u32 *dsc; + + /* Job Descriptor initialization */ + dsc = memalign(ARCH_DMA_MINALIGN, + sizeof(uint32_t) * MFG_SIGN_DSC_WORDS); + if (!dsc) { + debug("Not enough memory for descriptor allocation\n"); + return -ENOMEM; + } + + mfg_build_sign_dsc(dsc, m, data_size, dgst, c, d); + + size = roundup(sizeof(uint32_t) * MFG_SIGN_DSC_WORDS, + ARCH_DMA_MINALIGN); + flush_dcache_range((unsigned long)dsc, (unsigned long)dsc + size); + + size = roundup(data_size, ARCH_DMA_MINALIGN); + flush_dcache_range((unsigned long)m, (unsigned long)m + size); + + size = roundup(FSL_CAAM_MP_MES_DGST_BYTES, ARCH_DMA_MINALIGN); + flush_dcache_range((unsigned long)dgst, (unsigned long)dgst + size); + + size = roundup(FSL_CAAM_MP_PRVK_BYTES, ARCH_DMA_MINALIGN); + flush_dcache_range((unsigned long)c, (unsigned long)c + size); + flush_dcache_range((unsigned long)d, (unsigned long)d + size); + + /* Execute Job Descriptor */ + puts("\nSigning message with Manufacturing Protection Private Key\n"); + + ret = run_descriptor_jr(dsc); + if (ret) { + debug("Error in public key generation %d\n", ret); + goto err; + } + + size = roundup(FSL_CAAM_MP_MES_DGST_BYTES, ARCH_DMA_MINALIGN); + invalidate_dcache_range((unsigned long)dgst, + (unsigned long)dgst + size); + + size = roundup(FSL_CAAM_MP_PRVK_BYTES, ARCH_DMA_MINALIGN); + invalidate_dcache_range((unsigned long)c, (unsigned long)c + size); + invalidate_dcache_range((unsigned long)d, (unsigned long)d + size); + +err: + free(dsc); + return ret; +} |