summaryrefslogtreecommitdiff
path: root/drivers/crypto/fsl/jr.c
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2020-07-27 15:18:15 -0400
committerTom Rini <trini@konsulko.com>2020-07-27 15:18:15 -0400
commit8d1fc6fb89826efb6bbbedb57862496e18737877 (patch)
tree8418e5d212ff4f5dfbfaad4eb9c21a63a83e3d9b /drivers/crypto/fsl/jr.c
parentfc3414212effcdd18a7382ffa9e654441bed30a4 (diff)
parent636999f21cdd901f1d78323456447ce956410776 (diff)
Merge https://gitlab.denx.de/u-boot/custodians/u-boot-fsl-qoriq
- Bug fixes and updates on ls2088a,ls1028a, ls1046a, ls1043a, ls1012a - lx2-watchdog support - layerscape: pci-endpoint support, spin table relocation fixes and cleanups - fsl-crypto: RNG support and bug fixes
Diffstat (limited to 'drivers/crypto/fsl/jr.c')
-rw-r--r--drivers/crypto/fsl/jr.c111
1 files changed, 92 insertions, 19 deletions
diff --git a/drivers/crypto/fsl/jr.c b/drivers/crypto/fsl/jr.c
index e2d9216cfc7..44273c345f9 100644
--- a/drivers/crypto/fsl/jr.c
+++ b/drivers/crypto/fsl/jr.c
@@ -7,6 +7,7 @@
#include <common.h>
#include <cpu_func.h>
+#include <linux/kernel.h>
#include <log.h>
#include <malloc.h>
#include "fsl_sec.h"
@@ -19,6 +20,7 @@
#include <asm/cache.h>
#include <asm/fsl_pamu.h>
#endif
+#include <dm/lists.h>
#define CIRC_CNT(head, tail, size) (((head) - (tail)) & (size - 1))
#define CIRC_SPACE(head, tail, size) CIRC_CNT((tail), (head) + 1, (size))
@@ -446,7 +448,52 @@ int sec_reset(void)
return sec_reset_idx(0);
}
#ifndef CONFIG_SPL_BUILD
-static int instantiate_rng(uint8_t sec_idx)
+static int deinstantiate_rng(u8 sec_idx, int state_handle_mask)
+{
+ u32 *desc;
+ int sh_idx, ret = 0;
+ int desc_size = ALIGN(sizeof(u32) * 2, ARCH_DMA_MINALIGN);
+
+ desc = memalign(ARCH_DMA_MINALIGN, desc_size);
+ if (!desc) {
+ debug("cannot allocate RNG init descriptor memory\n");
+ return -ENOMEM;
+ }
+
+ for (sh_idx = 0; sh_idx < RNG4_MAX_HANDLES; sh_idx++) {
+ /*
+ * If the corresponding bit is set, then it means the state
+ * handle was initialized by us, and thus it needs to be
+ * deinitialized as well
+ */
+
+ if (state_handle_mask & RDSTA_IF(sh_idx)) {
+ /*
+ * Create the descriptor for deinstantating this state
+ * handle.
+ */
+ inline_cnstr_jobdesc_rng_deinstantiation(desc, sh_idx);
+ flush_dcache_range((unsigned long)desc,
+ (unsigned long)desc + desc_size);
+
+ ret = run_descriptor_jr_idx(desc, sec_idx);
+ if (ret) {
+ printf("SEC%u: RNG4 SH%d deinstantiation failed with error 0x%x\n",
+ sec_idx, sh_idx, ret);
+ ret = -EIO;
+ break;
+ }
+
+ printf("SEC%u: Deinstantiated RNG4 SH%d\n",
+ sec_idx, sh_idx);
+ }
+ }
+
+ free(desc);
+ return ret;
+}
+
+static int instantiate_rng(u8 sec_idx, int gen_sk)
{
u32 *desc;
u32 rdsta_val;
@@ -466,11 +513,20 @@ static int instantiate_rng(uint8_t sec_idx)
* If the corresponding bit is set, this state handle
* was initialized by somebody else, so it's left alone.
*/
- rdsta_val = sec_in32(&rng->rdsta) & RNG_STATE_HANDLE_MASK;
- if (rdsta_val & (1 << sh_idx))
- continue;
+ rdsta_val = sec_in32(&rng->rdsta);
+ if (rdsta_val & (RDSTA_IF(sh_idx))) {
+ if (rdsta_val & RDSTA_PR(sh_idx))
+ continue;
+
+ printf("SEC%u: RNG4 SH%d was instantiated w/o prediction resistance. Tearing it down\n",
+ sec_idx, sh_idx);
- inline_cnstr_jobdesc_rng_instantiation(desc, sh_idx);
+ ret = deinstantiate_rng(sec_idx, RDSTA_IF(sh_idx));
+ if (ret)
+ break;
+ }
+
+ inline_cnstr_jobdesc_rng_instantiation(desc, sh_idx, gen_sk);
size = roundup(sizeof(uint32_t) * 6, ARCH_DMA_MINALIGN);
flush_dcache_range((unsigned long)desc,
(unsigned long)desc + size);
@@ -478,11 +534,11 @@ static int instantiate_rng(uint8_t sec_idx)
ret = run_descriptor_jr_idx(desc, sec_idx);
if (ret)
- printf("RNG: Instantiation failed with error 0x%x\n",
- ret);
+ printf("SEC%u: RNG4 SH%d instantiation failed with error 0x%x\n",
+ sec_idx, sh_idx, ret);
- rdsta_val = sec_in32(&rng->rdsta) & RNG_STATE_HANDLE_MASK;
- if (!(rdsta_val & (1 << sh_idx))) {
+ rdsta_val = sec_in32(&rng->rdsta);
+ if (!(rdsta_val & RDSTA_IF(sh_idx))) {
free(desc);
return -1;
}
@@ -498,9 +554,17 @@ static int instantiate_rng(uint8_t sec_idx)
static u8 get_rng_vid(uint8_t sec_idx)
{
ccsr_sec_t *sec = (void *)SEC_ADDR(sec_idx);
- u32 cha_vid = sec_in32(&sec->chavid_ls);
+ u8 vid;
+
+ if (caam_get_era() < 10) {
+ vid = (sec_in32(&sec->chavid_ls) & SEC_CHAVID_RNG_LS_MASK)
+ >> SEC_CHAVID_LS_RNG_SHIFT;
+ } else {
+ vid = (sec_in32(&sec->vreg.rng) & CHA_VER_VID_MASK)
+ >> CHA_VER_VID_SHIFT;
+ }
- return (cha_vid & SEC_CHAVID_RNG_LS_MASK) >> SEC_CHAVID_LS_RNG_SHIFT;
+ return vid;
}
/*
@@ -538,14 +602,15 @@ static void kick_trng(int ent_delay, uint8_t sec_idx)
static int rng_init(uint8_t sec_idx)
{
- int ret, ent_delay = RTSDCTL_ENT_DLY_MIN;
+ int ret, gen_sk, ent_delay = RTSDCTL_ENT_DLY_MIN;
ccsr_sec_t __iomem *sec = (ccsr_sec_t __iomem *)SEC_ADDR(sec_idx);
struct rng4tst __iomem *rng =
(struct rng4tst __iomem *)&sec->rng;
u32 inst_handles;
+ gen_sk = !(sec_in32(&rng->rdsta) & RDSTA_SKVN);
do {
- inst_handles = sec_in32(&rng->rdsta) & RNG_STATE_HANDLE_MASK;
+ inst_handles = sec_in32(&rng->rdsta) & RDSTA_MASK;
/*
* If either of the SH's were instantiated by somebody else
@@ -566,10 +631,10 @@ static int rng_init(uint8_t sec_idx)
* interval, leading to a sucessful initialization of
* the RNG.
*/
- ret = instantiate_rng(sec_idx);
+ ret = instantiate_rng(sec_idx, gen_sk);
} while ((ret == -1) && (ent_delay < RTSDCTL_ENT_DLY_MAX));
if (ret) {
- printf("RNG: Failed to instantiate RNG\n");
+ printf("SEC%u: Failed to instantiate RNG\n", sec_idx);
return ret;
}
@@ -592,7 +657,7 @@ int sec_init_idx(uint8_t sec_idx)
#endif
if (!(sec_idx < CONFIG_SYS_FSL_MAX_NUM_OF_SEC)) {
- printf("SEC initialization failed\n");
+ printf("SEC%u: initialization failed\n", sec_idx);
return -1;
}
@@ -640,7 +705,7 @@ int sec_init_idx(uint8_t sec_idx)
ret = jr_init(sec_idx);
if (ret < 0) {
- printf("SEC initialization failed\n");
+ printf("SEC%u: initialization failed\n", sec_idx);
return -1;
}
@@ -654,10 +719,18 @@ int sec_init_idx(uint8_t sec_idx)
#ifndef CONFIG_SPL_BUILD
if (get_rng_vid(sec_idx) >= 4) {
if (rng_init(sec_idx) < 0) {
- printf("SEC%u: RNG instantiation failed\n", sec_idx);
+ printf("SEC%u: RNG instantiation failed\n", sec_idx);
return -1;
}
- printf("SEC%u: RNG instantiated\n", sec_idx);
+
+ if (IS_ENABLED(CONFIG_DM_RNG)) {
+ ret = device_bind_driver(NULL, "caam-rng", "caam-rng",
+ NULL);
+ if (ret)
+ printf("Couldn't bind rng driver (%d)\n", ret);
+ }
+
+ printf("SEC%u: RNG instantiated\n", sec_idx);
}
#endif
return ret;