diff options
author | Winter Wang <wente.wang@nxp.com> | 2016-11-30 16:12:57 +0800 |
---|---|---|
committer | Winter Wang <wente.wang@nxp.com> | 2016-12-01 10:21:43 +0800 |
commit | 6c5665fe850ad293342e6000827065290a79beba (patch) | |
tree | d8af09e7627bdaa4b8a762ede290d881cf6bd977 /drivers | |
parent | a442e4e7b50f52be3940d6bd885bbbff51171f05 (diff) | |
download | u-boot-imx-6c5665fe850ad293342e6000827065290a79beba.zip u-boot-imx-6c5665fe850ad293342e6000827065290a79beba.tar.gz u-boot-imx-6c5665fe850ad293342e6000827065290a79beba.tar.bz2 |
MA-9077 caam: add hwrng
add caam based hwrng
Change-Id: Ifabc4ec9da5531e1f1804587901a5dc438db99df
Signed-off-by: Winter Wang <wente.wang@nxp.com>
Diffstat (limited to 'drivers')
-rwxr-xr-x | drivers/crypto/fsl_caam.c | 134 |
1 files changed, 101 insertions, 33 deletions
diff --git a/drivers/crypto/fsl_caam.c b/drivers/crypto/fsl_caam.c index 3ae9bf7..ebba87c 100755 --- a/drivers/crypto/fsl_caam.c +++ b/drivers/crypto/fsl_caam.c @@ -39,10 +39,10 @@ uint32_t g_input_ring[JOB_RING_ENTRIES] = {0}; -/* Output job ring - single entry output ring (consists of two words) */ +/* Output job ring - single entry output ring (consists of two words) */ uint32_t g_output_ring[2*JOB_RING_ENTRIES] = {0, 0}; -uint32_t decap_dsc[] = +uint32_t decap_dsc[] = { DECAP_BLOB_DESC1, DECAP_BLOB_DESC2, @@ -55,7 +55,7 @@ uint32_t decap_dsc[] = DECAP_BLOB_DESC9 }; -uint32_t encap_dsc[] = +uint32_t encap_dsc[] = { ENCAP_BLOB_DESC1, ENCAP_BLOB_DESC2, @@ -68,7 +68,8 @@ uint32_t encap_dsc[] = ENCAP_BLOB_DESC9 }; -uint32_t rng_inst_dsc[] = +uint32_t hwrng_dsc[6] = {0}; +uint32_t rng_inst_dsc[] = { RNG_INST_DESC1, RNG_INST_DESC2, @@ -146,7 +147,7 @@ uint32_t caam_decap_blob(uint32_t plain_text, uint32_t blob_addr, uint32_t size) /* uncomment when using descriptor from "fsl_caam_internal.h" does not use key modifier. */ -#if 0 +#if 0 /* Fill in input blob addr in decap_dsc */ decap_dsc[5] = (uint32_t)blob; /* Fill in the address where to decrypt the blob */ @@ -157,14 +158,19 @@ uint32_t caam_decap_blob(uint32_t plain_text, uint32_t blob_addr, uint32_t size) /* Add job to input ring */ g_input_ring[0] = (uint32_t)decap_dsc; - flush_dcache_range((uint32_t)blob_addr & ALIGN_MASK, - ((uint32_t)blob_addr & ALIGN_MASK) + 2*size); - flush_dcache_range((uint32_t)plain_text & ALIGN_MASK, - ((uint32_t)plain_text & ALIGN_MASK) + 2*size); flush_dcache_range((uint32_t)decap_dsc & ALIGN_MASK, ((uint32_t)decap_dsc & ALIGN_MASK) + 128); flush_dcache_range((uint32_t)g_input_ring & ALIGN_MASK, ((uint32_t)g_input_ring & ALIGN_MASK) + 128); + invalidate_dcache_range((uint32_t)decap_dsc & ALIGN_MASK, + ((uint32_t)decap_dsc & ALIGN_MASK) + 128); + invalidate_dcache_range((uint32_t)g_input_ring & ALIGN_MASK, + ((uint32_t)g_input_ring & ALIGN_MASK) + 128); + invalidate_dcache_range((uint32_t)blob_addr & ALIGN_MASK, + (((uint32_t)blob_addr + 2 * size + 64) & ALIGN_MASK)); + invalidate_dcache_range((uint32_t)plain_text & ALIGN_MASK, + (((uint32_t)plain_text + 2 * size + 64) & ALIGN_MASK)); + /* Increment jobs added */ __raw_writel(1, CAAM_IRJAR0); @@ -172,7 +178,7 @@ uint32_t caam_decap_blob(uint32_t plain_text, uint32_t blob_addr, uint32_t size) while(__raw_readl(CAAM_ORSFR0) != 1); // TODO: check if Secure memory is cacheable. - invalidate_dcache_range((uint32_t)g_output_ring & ALIGN_MASK, + flush_dcache_range((uint32_t)g_output_ring & ALIGN_MASK, ((uint32_t)g_output_ring & ALIGN_MASK) + 128); /* check that descriptor address is the one expected in the output ring */ if(g_output_ring[0] == (uint32_t)decap_dsc) @@ -189,9 +195,6 @@ uint32_t caam_decap_blob(uint32_t plain_text, uint32_t blob_addr, uint32_t size) printf("Error: blob decap job output ring descriptor address does" \ " not match\n"); } - flush_dcache_range((uint32_t)plain_text & ALIGN_MASK, - ((uint32_t)plain_text & ALIGN_MASK) + 2*size); - /* Remove job from Job Ring Output Queue */ __raw_writel(1, CAAM_ORJRR0); @@ -239,15 +242,15 @@ uint32_t caam_gen_blob(uint32_t plain_data_addr, uint32_t blob_addr, uint32_t si encap_dsc[3] = (uint32_t)0xF0000000 | (0x0000ffff & (size)); encap_dsc[4] = (uint32_t)plain_data_addr; encap_dsc[5] = (uint32_t)0xF8000000 | (0x0000ffff & (size+48)); - encap_dsc[6] = (uint32_t)blob; + encap_dsc[6] = (uint32_t)blob; encap_dsc[7] = (uint32_t)0x870D0000; // uncomment when using descriptor from "fsl_caam_internal.h" - // does not use key modifier. + // does not use key modifier. #if 0 // /* Fill in the address where the DEK resides */ - encap_dsc[5] = (uint32_t)SEC_MEM_PAGE1; + encap_dsc[5] = (uint32_t)SEC_MEM_PAGE1; /* Fill in output blob addr in encap_dsc */ encap_dsc[7] = (uint32_t)blob; #endif @@ -256,12 +259,18 @@ uint32_t caam_gen_blob(uint32_t plain_data_addr, uint32_t blob_addr, uint32_t si /* Add job to input ring */ g_input_ring[0] = (uint32_t)encap_dsc; - flush_dcache_range((uint32_t)plain_data_addr & ALIGN_MASK, - ((uint32_t)plain_data_addr & ALIGN_MASK) + size); flush_dcache_range((uint32_t)encap_dsc & ALIGN_MASK, ((uint32_t)encap_dsc & ALIGN_MASK) + 128); - flush_dcache_range((uint32_t)blob & ALIGN_MASK, - ((uint32_t)g_input_ring & ALIGN_MASK) + 2 * size); + flush_dcache_range((uint32_t)g_input_ring & ALIGN_MASK, + ((uint32_t)g_input_ring & ALIGN_MASK) + 128); + invalidate_dcache_range((uint32_t)encap_dsc & ALIGN_MASK, + ((uint32_t)encap_dsc & ALIGN_MASK) + 128); + invalidate_dcache_range((uint32_t)g_input_ring & ALIGN_MASK, + ((uint32_t)g_input_ring & ALIGN_MASK) + 128); + invalidate_dcache_range((uint32_t)plain_data_addr & ALIGN_MASK, + (((uint32_t)plain_data_addr + 2 * size + 64) & ALIGN_MASK)); + invalidate_dcache_range((uint32_t)blob & ALIGN_MASK, + (((uint32_t)blob + 2 * size + 64) & ALIGN_MASK)); /* Increment jobs added */ __raw_writel(1, CAAM_IRJAR0); @@ -269,9 +278,7 @@ uint32_t caam_gen_blob(uint32_t plain_data_addr, uint32_t blob_addr, uint32_t si while(__raw_readl(CAAM_ORSFR0) != 1); // flush cache - invalidate_dcache_range((uint32_t)g_output_ring & ALIGN_MASK, - ((uint32_t)g_output_ring & ALIGN_MASK) + 128); - invalidate_dcache_range((uint32_t)g_output_ring & ALIGN_MASK, + flush_dcache_range((uint32_t)g_output_ring & ALIGN_MASK, ((uint32_t)g_output_ring & ALIGN_MASK) + 128); /* check that descriptor address is the one expected in the output ring */ if(g_output_ring[0] == (uint32_t)encap_dsc) @@ -295,6 +302,67 @@ uint32_t caam_gen_blob(uint32_t plain_data_addr, uint32_t blob_addr, uint32_t si return ret; } +uint32_t caam_hwrng(uint8_t *output_ptr, uint32_t output_len) { + uint32_t ret = SUCCESS; + + /* Buffer to hold the resulting output*/ + uint8_t *output = (uint8_t *)output_ptr; + + /* initialize the output array */ + memset(output,0,output_len); + + int n = 0; + hwrng_dsc[n++] = (uint32_t)0xB0800004; + hwrng_dsc[n++] = (uint32_t)0x82500000; + hwrng_dsc[n++] = (uint32_t)0x60340000| (0x0000ffff & output_len); + hwrng_dsc[n++] = (uint32_t)output; + + /* Run descriptor with result written to blob buffer */ + /* Add job to input ring */ + // flush cache + g_input_ring[0] = (uint32_t)hwrng_dsc; + + flush_dcache_range((uint32_t)hwrng_dsc & ALIGN_MASK, + ((uint32_t)hwrng_dsc & ALIGN_MASK) + 128); + flush_dcache_range((uint32_t)g_input_ring & ALIGN_MASK, + ((uint32_t)g_input_ring & ALIGN_MASK) + 128); + invalidate_dcache_range((uint32_t)hwrng_dsc & ALIGN_MASK, + ((uint32_t)hwrng_dsc & ALIGN_MASK) + 128); + invalidate_dcache_range((uint32_t)g_input_ring & ALIGN_MASK, + ((uint32_t)g_input_ring & ALIGN_MASK) + 128); + invalidate_dcache_range((uint32_t)output & ALIGN_MASK, + (((uint32_t)output + 2 * output_len + 64) & ALIGN_MASK)); + /* Increment jobs added */ + __raw_writel(1, CAAM_IRJAR0); + + /* Wait for job ring to complete the job: 1 completed job expected */ + size_t timeout = 100000; + while(__raw_readl(CAAM_ORSFR0) != 1 && timeout--); + flush_dcache_range((uint32_t)g_output_ring & ALIGN_MASK, + ((uint32_t)g_output_ring & ALIGN_MASK) + 128); + + /* check that descriptor address is the one expected in the output ring */ + if(g_output_ring[0] == (uint32_t)hwrng_dsc) { + /* check if any error is reported in the output ring */ + if ((g_output_ring[1] & JOB_RING_STS) != 0) { + printf("Error: RNG job completed with errors 0x%X\n", + g_output_ring[1]); + ret = -1; + } + } else { + printf("Error: RNG output ring descriptor address does" \ + " not match\n"); + ret = -1; + + } + + /* Remove job from Job Ring Output Queue */ + __raw_writel(1, CAAM_ORJRR0); + + return ret; +} + + /*! * Initialize the CAAM. * @@ -307,8 +375,8 @@ void caam_open(void) /* switch on the clock */ temp_reg = __raw_readl(&mxc_ccm->CCGR0); - temp_reg |= MXC_CCM_CCGR0_CAAM_SECURE_MEM_MASK | - MXC_CCM_CCGR0_CAAM_WRAPPER_ACLK_MASK | + temp_reg |= MXC_CCM_CCGR0_CAAM_SECURE_MEM_MASK | + MXC_CCM_CCGR0_CAAM_WRAPPER_ACLK_MASK | MXC_CCM_CCGR0_CAAM_WRAPPER_IPG_MASK; __raw_writel(temp_reg, &mxc_ccm->CCGR0); @@ -318,7 +386,7 @@ void caam_open(void) * * However, still need to initialize Job Rings as these are torn * down by HAB for each command - */ + */ /* Initialize job ring addresses */ __raw_writel((uint32_t)g_input_ring, CAAM_IRBAR0); // input ring address @@ -330,7 +398,7 @@ void caam_open(void) /* HAB disables interrupts for JR0 so do the same here */ temp_reg = __raw_readl(CAAM_JRCFGR0_LS) | JRCFG_LS_IMSK; - __raw_writel(temp_reg, CAAM_JRCFGR0_LS); + __raw_writel(temp_reg, CAAM_JRCFGR0_LS); /********* Initialize and instantiate the RNG *******************/ /* if RNG already instantiated then skip it */ @@ -344,13 +412,13 @@ void caam_open(void) __raw_writel(temp_reg, CAAM_RTMCTL); /* Set delay */ - __raw_writel(((RNG_TRIM_ENT_DLY << 16) | 0x09C4), CAAM_RTSDCTL); + __raw_writel(((RNG_TRIM_ENT_DLY << 16) | 0x09C4), CAAM_RTSDCTL); __raw_writel((RNG_TRIM_ENT_DLY >> 1), CAAM_RTFRQMIN); __raw_writel((RNG_TRIM_ENT_DLY << 4), CAAM_RTFRQMAX); /* Resume TRNG Run mode */ temp_reg = __raw_readl(CAAM_RTMCTL) ^ RTMCTL_PGM; - __raw_writel(temp_reg, CAAM_RTMCTL); + __raw_writel(temp_reg, 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. @@ -367,7 +435,7 @@ void caam_open(void) flush_dcache_range((uint32_t)g_input_ring & ALIGN_MASK, ((uint32_t)g_input_ring & ALIGN_MASK) + 128); /* Increment jobs added */ - __raw_writel(1, CAAM_IRJAR0); + __raw_writel(1, CAAM_IRJAR0); /* Wait for job ring to complete the job: 1 completed job expected */ while(__raw_readl(CAAM_ORSFR0) != 1); @@ -399,13 +467,13 @@ void caam_open(void) temp_reg = __raw_readl(CAAM_RDSTA); if (temp_reg != (RDSTA_IF0 | RDSTA_SKVN)) { - + printf("Error: RNG instantiation failed 0x%X\n", temp_reg); } - + /* Remove job from Job Ring Output Queue */ __raw_writel(1, CAAM_ORJRR0); } - + return; } |